Closed
Bug 1186804
Opened 9 years ago
Closed 9 years ago
Refactor the NotifyDataArrival code path at MediaResource.cpp and MediaDecoderReader.cpp
Categories
(Core :: Audio/Video: Playback, defect, P2)
Core
Audio/Video: Playback
Tracking
()
RESOLVED
WORKSFORME
Tracking | Status | |
---|---|---|
firefox42 | --- | affected |
People
(Reporter: bechen, Assigned: bechen)
References
Details
Attachments
(1 file)
33.28 KB,
patch
|
jya
:
feedback-
|
Details | Diff | Splinter Review |
see Bug 1184429. Because the SilentReadAt will fall back to MediaReadAt, the issue of duplicate |NotifyDataArrival| still exist. For example: STR: seek after metadataloaded cache block size is 32k 1. At beginning, http download 8k data contains medatada, and fire metadataloaded. (Dispatch a 0~8k NotifyDataArrival task) 2. JS seek to 100k, since 8k < 32k , the first block will drop. 3. NotifyDataArrival wants to parse 0~8k data, trigger "seek to 0" -> "read 0~8k" -> "seek back to 100k" 4. "seek to 0" dispatch a 0~8k |NotifyDataArrival| task again. So the same offset appears repeatedly until the playback end.... I know the new WebMReadear won't have the problem because the |WebMBufferedState::UpdateIndex| had already record the offset which had processed. But the other reader such as Gstreamer and DirectShowReader are suffered if play a mp3, their parser doesn't record the offset, they just call |SilentReadAt|. Now we have some solution: 1. At ChannelMediaResource::CopySegmentToCache, we copy the data into nsRefPtr<MediaByteBuffer>, and send to each reader (change the NotifyDataArrived to carry it), so we need one extra memcpy on main thread, nut the parser still rins on other thread. 2. Replace the arg |const char *aFromSegment| to |readonly nsRefPtr<xxx>| so that we might keep main thread to do nothing like the current code.
Comment 1•9 years ago
|
||
(In reply to Benjamin Chen [:bechen] from comment #0) > see Bug 1184429. > > Because the SilentReadAt will fall back to MediaReadAt, the issue of > duplicate |NotifyDataArrival| still exist. While yes, the code path exist, and we could logically address. I've ran for a few days a modified SilentReadAt that assert if the data isn't fully cached. Not once have I entered that code path. And that makes sense as SilentReadAt is currently always called following a NotifyDataArrived() which indicates that the data hit the cache.
Assignee | ||
Comment 2•9 years ago
|
||
(In reply to Jean-Yves Avenard [:jya] from comment #1) > (In reply to Benjamin Chen [:bechen] from comment #0) > > see Bug 1184429. > > > > Because the SilentReadAt will fall back to MediaReadAt, the issue of > > duplicate |NotifyDataArrival| still exist. > > While yes, the code path exist, and we could logically address. > > I've ran for a few days a modified SilentReadAt that assert if the data > isn't fully cached. Not once have I entered that code path. > And that makes sense as SilentReadAt is currently always called following a > NotifyDataArrived() which indicates that the data hit the cache. I think because my pc runs slowly (vmware 9) so I always hit the code path. And I guess the tryserver are more slower that cause the testcase timeout.
Assignee | ||
Updated•9 years ago
|
Summary: Reface the NotifyDataArrival code path MediaResource.cpp and MediadecoderReader.cpp . → Refact the NotifyDataArrival code path at MediaResource.cpp and MediaDecoderReader.cpp .
Comment 3•9 years ago
|
||
It also depends on the download speed. If you seek before gathering 32k bytes (a full media cache block), the metadata will be discarded when seeking happens.
Assignee | ||
Updated•9 years ago
|
Assignee: nobody → bechen
Assignee | ||
Comment 4•9 years ago
|
||
The root change of the patch is : AbstractMediaDecoder.h virtual void NotifyDataArrived(uint32_t aLength, int64_t aOffset, MediaByteBuffer* aBuffer, bool aThrottleUpdates) = 0; Now, only ChannelMediaResource will call the function with a non-null |MediaByteBuffer*| in |ChannelMediaResource::CopySegmentToCache|.
Attachment #8640941 -
Flags: feedback?(jyavenard)
Attachment #8640941 -
Flags: feedback?(jwwang)
Comment 5•9 years ago
|
||
Can you describe the purpose of this patch?
Comment 6•9 years ago
|
||
Comment on attachment 8640941 [details] [diff] [review] bug-1186804.v01.patch Review of attachment 8640941 [details] [diff] [review]: ----------------------------------------------------------------- Yes, I'd like some background on why you felt that it was necessary. But at first glance, I don't like it. First, we're going to allocate memory *very* often, even though the majority of readers make no use NotifyDataArrived ; that alone is a big regression. My understanding of NotifyDataArrived() is to tell the reader that there's new data in the cache, at that particular offset. As such, it doesn't need a copy *again* of the data that we know is in the mediaresource cache. On fast networks, we're now talking about having temporarily *twice* the video in ram: one in the mediaresourcecache, and in the MediaByteBuffer. Your original aim was to not have NotifyDataArrived unnecessarily be called because SilentReadAt() performed a seek. I don't see how this change aims to do that. The various MP3Reader are going (except maybe the gstreamer one for now), the WebMReader is going ; both already have replacement making use of the MediaFormatReader new architecture, and none of them making use of SilentReadAt. Once those twos are removed, SilentReadAt can also be removed. I'd prefer to focus on getting this done first . Or fix SilentReadAt() ::: dom/media/MediaResource.cpp @@ +458,5 @@ > CopySegmentClosure* closure = static_cast<CopySegmentClosure*>(aClosure); > > + nsRefPtr<MediaByteBuffer> buf = new MediaByteBuffer(aCount); > + buf->SetLength(aCount); > + memcpy(buf->Elements(), aFromSegment, aCount); AppendElements
Attachment #8640941 -
Flags: feedback?(jyavenard) → feedback-
Comment 7•9 years ago
|
||
If SilentReadAt() is gonna to be removed, I think we will be fine without this bug and comment 0 will not be an issue anymore.
Assignee | ||
Comment 8•9 years ago
|
||
(In reply to JW Wang [:jwwang] from comment #5) > Can you describe the purpose of this patch? The purpose of the patch is to eliminate the redundant NotifyDataArrived/RecreateChannel due to the seek operation (detail in comment 0). At the worst case, the redundant NotifyDataArrived/RecreateChannel will repeatedly appear until playback end. In the patch, each reader can fall back to SilentReadAt if the MediaByteBuffer* arg is null. nsRefPtr<MediaByteBuffer> bytes = aBuffer ? aBuffer : mDecoder->GetResource()->SilentReadAt(aOffset, aLength); (In reply to Jean-Yves Avenard [:jya] from comment #6) > Comment on attachment 8640941 [details] [diff] [review] > bug-1186804.v01.patch > > Review of attachment 8640941 [details] [diff] [review]: > ----------------------------------------------------------------- > > Yes, I'd like some background on why you felt that it was necessary. > The redundant NotifyDataArrived/RecreateChannel make the playback performane very worse. Just like an infinite loop, do the NotifyDataArrived/RecreateChannel again and again. > > First, we're going to allocate memory *very* often, even though the majority > of readers make no use NotifyDataArrived ; that alone is a big regression. > Yes, agree. So, is it good we create a query method on MediaDecoderReader that tell us the reader needs the data for parser or not? > > The various MP3Reader are going (except maybe the gstreamer one for now), > the WebMReader is going ; both already have replacement making use of the > MediaFormatReader new architecture, and none of them making use of > SilentReadAt. Once those twos are removed, SilentReadAt can also be removed. > > I'd prefer to focus on getting this done first . > > Or fix SilentReadAt() > When we move some readers into MediaFormatReader, there are still 3 readers we need to fix SilentReadAt(). dom/media/apple/AppleMP3Reader.cpp dom/media/directshow/DirectShowReader.cpp dom/media/gstreamer/GStreamerReader.cpp Now I don't have the idea how to fix SilentReadAt().
Comment 9•9 years ago
|
||
dom/media/apple/AppleMP3Reader.cpp can already be removed, it's redundant with the new MP3 player. I'll create a bug to remove it. (In reply to Benjamin Chen [:bechen] from comment #8) > Now I don't have the idea how to fix SilentReadAt(). I think it's the only good solution to the problem you are trying to solve... If you want to wrap the problem so it's not important, I feel that patching up the piece of code using SilentReadAt() to dismiss the NotifyDataArrived() if it has already describe an area is a much better approach. Much simpler for a start, and want mess the current architecture (which I think is very nice :))
Comment 10•9 years ago
|
||
maybe the solution is a silentseek instead?
Comment 11•9 years ago
|
||
Seek is never exposed to the client code of MediaResource. It is done when necessary in response to Read() or ReadAt().
Comment 12•9 years ago
|
||
After discussing with Anthony; were going to take a different approach. We're going to remove MediaResource::Read/Tell/Seek so we only have MediaResource::ReadAt And instead have a MediaResource wrapper class that keeps an index and that will offer Read/Seek/Tell access. You will use this class to access the MediaResource . This will remove the need for SilentReadAt. It shouldn't take long to implement
Updated•9 years ago
|
Attachment #8640941 -
Flags: feedback?(jwwang)
Comment 13•9 years ago
|
||
I don't think bug 1168435 should be blocking this, the frame parser is independent from MediaResource and the MP3 demuxer only uses MediaResource::ReadAt.
Comment 14•9 years ago
|
||
I've started working on bug 1190238. This will replace all use of Read/Seek/Tell in all the MP3 and other MediaDecoderReader making use of those. I will aim to get this uplifted to 41.
Comment 15•9 years ago
|
||
(In reply to Eugen Sawin [:esawin] from comment #13) > I don't think bug 1168435 should be blocking this, the frame parser is > independent from MediaResource and the MP3 demuxer only uses > MediaResource::ReadAt. That's exactly why it's blocking this bug... Should me moved all MP3 reader to the MP3Demuxer/MediaFormatReader there would be no issue anymore, precisely because it's using ReadAt. So moving to it would automatically fix part of this bug
Comment 16•9 years ago
|
||
Benjamin, would you be able to test if you can reproduce the issue with the old webm reader now that bug 1190238 has landed: You'll have to set media.format-reader.webm to false as the new webm reader didn't check for content like the WebMReader did
Flags: needinfo?(bechen)
Updated•9 years ago
|
Priority: -- → P2
Summary: Refact the NotifyDataArrival code path at MediaResource.cpp and MediaDecoderReader.cpp . → Refactor the NotifyDataArrival code path at MediaResource.cpp and MediaDecoderReader.cpp
Assignee | ||
Updated•9 years ago
|
Status: NEW → RESOLVED
Closed: 9 years ago
Flags: needinfo?(bechen)
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•