Closed
Bug 1140995
Opened 10 years ago
Closed 10 years ago
mochitest test_bug1113600.html and test_bug879717.html timeout.
Categories
(Core :: Audio/Video, defect)
Tracking
()
RESOLVED
FIXED
mozilla40
People
(Reporter: bechen, Assigned: bechen)
References
Details
Attachments
(2 files, 10 obsolete files)
4.95 KB,
patch
|
bechen
:
review+
|
Details | Diff | Splinter Review |
3.31 KB,
patch
|
bechen
:
review+
|
Details | Diff | Splinter Review |
Now, I'm trying to enable MediaCodec on emulator-kk build.
The mochitest testcase test_bug1113600 usually timeout on my emulator-kk build.
Assignee | ||
Comment 1•10 years ago
|
||
The root cause is that because there exists deviation in MicrosecondsToStreamTimeRoundDown() function, so
the GetClock() function doesn't go forward enough. Cause the MediaDecoderStateMachine::AdvanceFrame() function can't render or drop the last video frame, keeps in DECODER_STATE_COMPLETED state infinitely.
Assignee | ||
Comment 2•10 years ago
|
||
part 1: fix the timeout by adding deviation clocktime at the end of stream.
The timeout case usually happened at video only captured stream. The deviation between the MicrosecondsToStreamTimeRoundDown() and GetClock() make the MDSM falls into infinite loop (DECODER_STATE_COMPLETED and VideoQueue is always not empty)
Assignee | ||
Comment 3•10 years ago
|
||
part 2: fix the timeout by check the audio/video sample's timestamp.
This timeout usually happened at b2g-emulator, because the OMXCodec/MediaCodec decode a audio sample with a back-forward timestamp cause the timeout.
STR: when running the testcase test_bug879717.html, the gizmo.mp4 "sometimes" timeout because there is some audio samples still in the AudioQueue.
The audio clock doesn't go forward enough to finish the testcase. That is because there is a invalid audio sample in the AudioQueue.
For example: the timestamp in AudioQueue are:
1,2,3,4, ... 7,8,9,10,5 (the last audio sample's ts is 5)
Then looks these two functions
https://dxr.mozilla.org/mozilla-central/source/dom/media/MediaQueue.h#127
https://dxr.mozilla.org/mozilla-central/source/dom/media/MediaDecoderStateMachine.cpp#519
GetElementsAfter()'s implementation start the search from the end of the queue.
But the while loop in MediaDecoderStateMachine::SendStreamData() drops the audio sample from the head of the queue. So the invalid audio sample(5s timestamp) might make the 6~10 samples can not be sent to the DecodedStream => audio clock doens't go forward => MDSM falls in infinite loop.
Assignee | ||
Updated•10 years ago
|
Attachment #8577923 -
Flags: review?(jwwang)
Attachment #8577923 -
Flags: review?(cpearce)
Assignee | ||
Updated•10 years ago
|
Attachment #8577933 -
Flags: review?(jwwang)
Attachment #8577933 -
Flags: review?(cpearce)
Comment 4•10 years ago
|
||
Comment on attachment 8577923 [details] [diff] [review]
bug-1140995-timeout-part1.v01.patch
Review of attachment 8577923 [details] [diff] [review]:
-----------------------------------------------------------------
You should add comment for this adjustment is for B2G only where VideoData.mDuration is 1. Also, the fuzzy value should be used for comparison only, not to alter the result of clock time. (See also ESTIMATED_DURATION_FUZZ_FACTOR_USECS).
::: dom/media/MediaDecoderStateMachine.cpp
@@ +3112,5 @@
> } else {
> if (mAudioCaptured) {
> clock_time = mStartTime + mDecoder->GetDecodedStream()->GetClock();
> + if (mState == DECODER_STATE_COMPLETED) {
> + clock_time += mDeviationClockTimeFromDecodedStream_usec;
This will result in wrong end time.
Attachment #8577923 -
Flags: review?(jwwang) → review-
Comment 5•10 years ago
|
||
Comment on attachment 8577933 [details] [diff] [review]
bug-1140995-timeout-part2.v01.patch
Review of attachment 8577933 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +718,5 @@
> nsRefPtr<AudioData> audio(aAudioSample);
> MOZ_ASSERT(audio);
> mAudioDataRequest.Complete();
> + if (audio->GetEndTime() <= mDecodedAudioEndTime) {
> + DECODER_WARN("Illegal audio sample, audio->GetEndTime() < mDecodedAudioEndTime");
Please print the begin/end time of |audio| for easier debugging.
Attachment #8577933 -
Flags: review?(jwwang) → review+
Comment 6•10 years ago
|
||
Comment on attachment 8577923 [details] [diff] [review]
bug-1140995-timeout-part1.v01.patch
Review of attachment 8577923 [details] [diff] [review]:
-----------------------------------------------------------------
This is MSG related code, roc should review it.
Attachment #8577923 -
Flags: review?(cpearce) → review?(roc)
Comment 7•10 years ago
|
||
Comment on attachment 8577933 [details] [diff] [review]
bug-1140995-timeout-part2.v01.patch
Review of attachment 8577933 [details] [diff] [review]:
-----------------------------------------------------------------
This won't work. Sometimes on Mac and Windows the first audio sample output has a negative timestam. Those samples are valid, and we can play them. The first time OnAudioDecoded() runs mDecodedAudioEndTime will be -1, so we'll reject those samples with this change here.
You may need a flag to denote whether mDecodedAudioEndTime is valid, or you could make it an Optional<int64_t> to represent that.
Attachment #8577933 -
Flags: review?(cpearce) → review-
Assignee | ||
Comment 8•10 years ago
|
||
(In reply to Chris Pearce (:cpearce) from comment #7)
> Comment on attachment 8577933 [details] [diff] [review]
> bug-1140995-timeout-part2.v01.patch
>
> Review of attachment 8577933 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> This won't work. Sometimes on Mac and Windows the first audio sample output
> has a negative timestam. Those samples are valid, and we can play them. The
> first time OnAudioDecoded() runs mDecodedAudioEndTime will be -1, so we'll
> reject those samples with this change here.
>
> You may need a flag to denote whether mDecodedAudioEndTime is valid, or you
> could make it an Optional<int64_t> to represent that.
How about set the initial value of mDecodedAudioEndTime to INT64_MIN? So that I can still check the timestamp is monotonic increasing or not.
Comment 9•10 years ago
|
||
It should work. But I think Optional<> is clearer for sometimes I am confused by the sentinel value.
Assignee | ||
Comment 10•10 years ago
|
||
Now the part2 patch reject the audio/video samples with reorder timestamp fails on the chain.ogg because the chained audio/video will repeat the timestamp from the 0.
It is a problem if we still want to support chained audio/video..
Assignee | ||
Comment 11•10 years ago
|
||
Address comment 4.
Attachment #8577923 -
Attachment is obsolete: true
Attachment #8577923 -
Flags: review?(roc)
Attachment #8587142 -
Flags: review?(jwwang)
Assignee | ||
Comment 12•10 years ago
|
||
The version 2 patch was skipped because I found if I reject the audio/video data at MDSM, it breaks the chained ogg/ogv playback. And since I found the invalid timestamp data only occurs on device and emulator, patch version 3 fix the bug at MediaCodecReader only.
Attachment #8577933 -
Attachment is obsolete: true
Attachment #8587166 -
Flags: review?(cpearce)
Assignee | ||
Comment 13•10 years ago
|
||
(In reply to Benjamin Chen [:bechen] from comment #11)
> Created attachment 8587142 [details] [diff] [review]
> bug-1140995-timeout-part1.v02.patch
>
> Address comment 4.
Another approach is to fix the videoData's duration.
It depends on bug 1146729, enable the MP4Reader for local playback. Since bug 1020679 add the duration field for video sample, the videoData should have duration for mp4 file.
Updated•10 years ago
|
Attachment #8587166 -
Flags: review?(cpearce) → review+
Assignee | ||
Comment 14•10 years ago
|
||
Attachment #8587142 -
Attachment is obsolete: true
Attachment #8587142 -
Flags: review?(jwwang)
Attachment #8591539 -
Flags: review?(jwwang)
Comment 15•10 years ago
|
||
Comment on attachment 8591539 [details] [diff] [review]
bug-1140995-timeout-part1.v03.patch
Review of attachment 8591539 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +505,5 @@
> + // Send the mLastVideoImage till the end of stream, if there is no
> + // duration for the stream, we send it a deviation clock.
> + VideoSegment endSegment;
> + int64_t endtime = GetEndTime();
> + if (endtime == INT64_MAX) {
What does |endtime == -1| mean?
@@ +510,5 @@
> + //Calculate the deviation clock time from DecodedStream.
> + TrackRate rate = stream->mStream->GraphRate();
> + uint64_t deviation_usec = 0;
> + if (rate > 0) {
> + deviation_usec = (1000000 / rate) + 1;
deviation_usec = stream->mStream->StreamTimeToMicroseconds(1) + 1;
@@ +515,5 @@
> + }
> + endtime = stream->mNextVideoTime + deviation_usec;
> + }
> + WriteVideoToMediaStream(mediaStream, stream->mLastVideoImage,
> + endtime, stream->mNextVideoTime, stream->mLastVideoImageDisplaySize,
check |endtime > stream->mNextVideoTime|
Attachment #8591539 -
Flags: review?(jwwang) → review-
Assignee | ||
Comment 16•10 years ago
|
||
(In reply to JW Wang [:jwwang] from comment #15)
> Comment on attachment 8591539 [details] [diff] [review]
> bug-1140995-timeout-part1.v03.patch
>
> Review of attachment 8591539 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: dom/media/MediaDecoderStateMachine.cpp
> @@ +505,5 @@
> > + // Send the mLastVideoImage till the end of stream, if there is no
> > + // duration for the stream, we send it a deviation clock.
> > + VideoSegment endSegment;
> > + int64_t endtime = GetEndTime();
> > + if (endtime == INT64_MAX) {
>
> What does |endtime == -1| mean?
>
If the value is -1, that means the SetDuration() function is never called from MediaDecoder or MDSM. It should be a bug. So here I only check the value is INT64_MAX or not.
Assignee | ||
Updated•10 years ago
|
Summary: mochitest test_bug1113600.html timeout. → mochitest test_bug1113600.html and test_bug879717.html timeout.
Assignee | ||
Comment 17•10 years ago
|
||
Address comment 15.
Attachment #8591539 -
Attachment is obsolete: true
Attachment #8592073 -
Flags: review?(jwwang)
Comment 18•10 years ago
|
||
Comment on attachment 8592073 [details] [diff] [review]
bug-1140995-timeout-part1.v03.patch
Review of attachment 8592073 [details] [diff] [review]:
-----------------------------------------------------------------
Better but still have some problems to fix.
::: dom/media/MediaDecoderStateMachine.cpp
@@ +507,5 @@
> + VideoSegment endSegment;
> + int64_t endtime = GetEndTime();
> + if (endtime == INT64_MAX) {
> + // Calculate the deviation clock time from DecodedStream.
> + int64_t deviation_usec = mediaStream->StreamTimeToMicroseconds(1) + 1;
In fact, I think it should be enough to just compensate |mediaStream->StreamTimeToMicroseconds(1)| us instead of |mediaStream->StreamTimeToMicroseconds(1) + 1| us.
The problem here is that if the duration is very short, we could have
stream->MicrosecondsToStreamTimeRoundDown(v->mTime) == stream->MicrosecondsToStreamTimeRoundDown(v->GetEndTime()) and it contributes zero ticks to the stream time.
Therefore the last video frame will never be popped in AdvanceFrame() since the clock time is always smaller than v->mTime for the last frame.
Doing some simple math, we can prove stream->MicrosecondsToStreamTimeRoundDown(v->GetEndTime() + mediaStream->StreamTimeToMicroseconds(1)) - stream->MicrosecondsToStreamTimeRoundDown(v->mTime) >= 1. Therefore, mediaStream->StreamTimeToMicroseconds(1) is the smallest duration we need to compensate in order for last video to contribute at least one tick.
@@ +510,5 @@
> + // Calculate the deviation clock time from DecodedStream.
> + int64_t deviation_usec = mediaStream->StreamTimeToMicroseconds(1) + 1;
> + endtime = stream->mNextVideoTime + deviation_usec;
> + }
> + if (stream->mNextVideoTime < endtime) {
What if endtime is very close to stream->mNextVideoTime and we still contribute zero ticks to the stream time?
@@ +515,5 @@
> + WriteVideoToMediaStream(mediaStream, stream->mLastVideoImage,
> + endtime, stream->mNextVideoTime, stream->mLastVideoImageDisplaySize,
> + &endSegment);
> + stream->mNextVideoTime = endtime;
> + if (endSegment.GetDuration() > 0) {
Assert |endSegment.GetDuration() > 0| to make sure we compensate enough ticks fix the problem mentioned above.
Attachment #8592073 -
Flags: review?(jwwang) → review-
Assignee | ||
Comment 19•10 years ago
|
||
Address comment 18.
Attachment #8592073 -
Attachment is obsolete: true
Attachment #8592611 -
Flags: review?(jwwang)
Comment 20•10 years ago
|
||
Comment on attachment 8592611 [details] [diff] [review]
bug-1140995-timeout-part1.v03.patch
Review of attachment 8592611 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +518,5 @@
> + endtime, stream->mNextVideoTime, stream->mLastVideoImageDisplaySize,
> + &endSegment);
> + stream->mNextVideoTime = endtime;
> + MOZ_ASSERT(endSegment.GetDuration() > 0);
> + if (endSegment.GetDuration() > 0) {
Since you assert it above, you don't need to check it again.
Attachment #8592611 -
Flags: review?(jwwang) → review+
Comment 21•10 years ago
|
||
Comment on attachment 8592611 [details] [diff] [review]
bug-1140995-timeout-part1.v03.patch
Review of attachment 8592611 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +509,5 @@
> + int64_t endtime = GetEndTime();
> + // Calculate the deviation clock time from DecodedStream.
> + int64_t deviation_usec = mediaStream->StreamTimeToMicroseconds(1);
> + if (endtime == INT64_MAX ||
> + (endtime - stream->mNextVideoTime) < deviation_usec) {
Also you need to check if the duration of last video frame is more than 1 tick, you don't need this compensation.
Assignee | ||
Comment 22•10 years ago
|
||
Attachment #8592611 -
Attachment is obsolete: true
Attachment #8593837 -
Flags: review?(jwwang)
Comment 23•10 years ago
|
||
Comment on attachment 8593837 [details] [diff] [review]
bug-1140995-timeout-part1.v04.patch
Review of attachment 8593837 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +501,5 @@
> &output);
> stream->mNextVideoTime = v->GetEndTime();
> stream->mLastVideoImage = v->mImage;
> stream->mLastVideoImageDisplaySize = v->mDisplay;
> + if (i == video.Length() - 1) { // The end of for-loop
You don't need this if statement. All you need to do is keep updating
StreamTime lastFrameDuration =
mediaStream->MicrosecondsToStreamTimeRoundDown(v->mTime) -
mediaStream->MicrosecondsToStreamTimeRoundDown(v->GetEndTime())
in the for loop.
|lastFrameDuration| will be the duration of last frame in |if (stream->mEOSVideoCompensation)|.
@@ +502,5 @@
> stream->mNextVideoTime = v->GetEndTime();
> stream->mLastVideoImage = v->mImage;
> stream->mLastVideoImageDisplaySize = v->mDisplay;
> + if (i == video.Length() - 1) { // The end of for-loop
> + stream->mEOSVideoCompensation = ZeroDurationAtLastChunk(output);
It is wrong because output could contain data from other frames.
@@ +513,5 @@
> if (output.GetDuration() > 0) {
> mediaStream->AppendToTrack(videoTrackId, &output);
> }
> if (VideoQueue().IsFinished() && !stream->mHaveSentFinishVideo) {
> + if (stream->mEOSVideoCompensation) {
mEOSVideoCompensation is only read/written here. It can be a local variable instead of a member.
Attachment #8593837 -
Flags: review?(jwwang) → review-
Comment 24•10 years ago
|
||
Comment on attachment 8593837 [details] [diff] [review]
bug-1140995-timeout-part1.v04.patch
Review of attachment 8593837 [details] [diff] [review]:
-----------------------------------------------------------------
::: dom/media/MediaDecoderStateMachine.cpp
@@ +393,5 @@
> +static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
> +{
> + StreamTime lastVideoStratTime;
> + aInput.GetLastFrame(&lastVideoStratTime);
> + return lastVideoStratTime == aInput.GetDuration();
The code is tricky. Please put a comment to explain it.
Assignee | ||
Comment 25•10 years ago
|
||
Address comment 23, comment 24.
Attachment #8593837 -
Attachment is obsolete: true
Attachment #8595891 -
Flags: review?(jwwang)
Updated•10 years ago
|
Attachment #8595891 -
Flags: review?(jwwang) → review+
Assignee | ||
Comment 26•10 years ago
|
||
part2 patch, r=cpearce
try server:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=bc18122e02d9
Attachment #8587166 -
Attachment is obsolete: true
Attachment #8596386 -
Flags: review+
Assignee | ||
Updated•10 years ago
|
Keywords: checkin-needed
Comment 27•10 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/e73f7d6a138d
https://hg.mozilla.org/integration/mozilla-inbound/rev/e428ba6470b9
Keywords: checkin-needed
Comment 28•10 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/e73f7d6a138d
https://hg.mozilla.org/mozilla-central/rev/e428ba6470b9
Status: NEW → RESOLVED
Closed: 10 years ago
status-firefox40:
--- → fixed
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla40
Backed out this bug and bug 1153690 for causing bug 1157654.
Status: RESOLVED → REOPENED
Flags: needinfo?(bechen)
Resolution: FIXED → ---
Assignee | ||
Comment 30•10 years ago
|
||
Rebase.
Attachment #8595891 -
Attachment is obsolete: true
Flags: needinfo?(bechen)
Attachment #8603968 -
Flags: review+
Assignee | ||
Comment 31•10 years ago
|
||
Rebase.
try server:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=5f05567c53ef
Attachment #8596386 -
Attachment is obsolete: true
Attachment #8603969 -
Flags: review+
Assignee | ||
Updated•10 years ago
|
Keywords: checkin-needed
Comment 32•10 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/a50fbea53921
https://hg.mozilla.org/integration/mozilla-inbound/rev/3dee2a2ce28b
Keywords: checkin-needed
Comment 33•10 years ago
|
||
Comment 34•10 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/a50fbea53921
https://hg.mozilla.org/mozilla-central/rev/3dee2a2ce28b
Status: REOPENED → RESOLVED
Closed: 10 years ago → 10 years ago
status-firefox41:
--- → fixed
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•