author | Jean-Yves Avenard <jyavenard@mozilla.com> |
Thu, 11 Jun 2015 16:27:08 +1000 | |
changeset 248277 | d3f99ebe7c888182b6734ac82e94e3c341252dcf |
parent 248276 | d62627bbe3b24fa92aef8aa9b3fa86a39bbcfb32 |
child 248278 | 06f657ea41601a67abfdc7e5f7b15c22c904d977 |
push id | 28893 |
push user | kwierso@gmail.com |
push date | Fri, 12 Jun 2015 00:02:58 +0000 |
treeherder | autoland@8cf9d3e497f9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cajbir |
bugs | 1171330 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/media/mediasource/TrackBuffersManager.cpp | file | annotate | diff | comparison | revisions | |
dom/media/mediasource/TrackBuffersManager.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -258,16 +258,17 @@ TrackBuffersManager::CompleteResetParser // 4. Unset the highest end timestamp on all track buffers. track->mHighestEndTimestamp.reset(); // 5. Set the need random access point flag on all track buffers to true. track->mNeedRandomAccessPoint = true; // if we have been aborted, we may have pending frames that we are going // to discard now. track->mQueuedSamples.Clear(); + track->mLongestFrameDuration.reset(); } // 6. Remove all bytes from the input buffer. mIncomingBuffers.Clear(); mInputBuffer->Clear(); if (mCurrentInputBuffer) { mCurrentInputBuffer->EvictAll(); mCurrentInputBuffer = new SourceBufferResource(mType); } @@ -694,16 +695,19 @@ TrackBuffersManager::OnDemuxerInitDone(n // then the Track IDs match the ones in the first initialization segment. // TODO // 2. Add the appropriate track descriptions from this initialization // segment to each of the track buffers. // TODO // 3. Set the need random access point flag on all track buffers to true. mVideoTracks.mNeedRandomAccessPoint = true; mAudioTracks.mNeedRandomAccessPoint = true; + + mVideoTracks.mLongestFrameDuration = mVideoTracks.mLastFrameDuration; + mAudioTracks.mLongestFrameDuration = mAudioTracks.mLastFrameDuration; } // 4. Let active track flag equal false. mActiveTrack = false; // 5. If the first initialization segment received flag is false, then run the following steps: if (!mFirstInitializationSegmentReceived) { mAudioTracks.mNumTracks = numAudios; @@ -1049,20 +1053,25 @@ TrackBuffersManager::ProcessFrame(MediaR auto& trackBuffer = aTrackData; // 6. If last decode timestamp for track buffer is set and decode timestamp is less than last decode timestamp: // OR // If last decode timestamp for track buffer is set and the difference between decode timestamp and last decode timestamp is greater than 2 times last frame duration: // TODO: Maybe we should be using TimeStamp and TimeDuration instead? + // Some MP4 content may exhibit an extremely short frame duration. + // As such, we can't use the last frame duration as a way to detect + // discontinuities as required per step 6 above. + // Instead we use the biggest duration seen so far in this run (init + media + // segment). if ((trackBuffer.mLastDecodeTimestamp.isSome() && decodeTimestamp < trackBuffer.mLastDecodeTimestamp.ref()) || (trackBuffer.mLastDecodeTimestamp.isSome() && - decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLastFrameDuration.ref())) { + decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLongestFrameDuration.ref())) { // 1a. If mode equals "segments": if (mParent->mAppendMode == SourceBufferAppendMode::Segments) { // Set group end timestamp to presentation timestamp. mGroupEndTimestamp = presentationTimestamp; } // 1b. If mode equals "sequence": if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) { @@ -1073,16 +1082,18 @@ TrackBuffersManager::ProcessFrame(MediaR // 2. Unset the last decode timestamp on all track buffers. track->mLastDecodeTimestamp.reset(); // 3. Unset the last frame duration on all track buffers. track->mLastFrameDuration.reset(); // 4. Unset the highest end timestamp on all track buffers. track->mHighestEndTimestamp.reset(); // 5. Set the need random access point flag on all track buffers to true. track->mNeedRandomAccessPoint = true; + + trackBuffer.mLongestFrameDuration.reset(); } MSE_DEBUG("Detected discontinuity. Restarting process"); // 6. Jump to the Loop Top step above to restart processing of the current coded frame. return true; } // 7. Let frame end timestamp equal the sum of presentation timestamp and frame duration. TimeUnit frameEndTimestamp = presentationTimestamp + frameDuration; @@ -1203,17 +1214,27 @@ TrackBuffersManager::ProcessFrame(MediaR } } } trackBuffer.mSizeBuffer += sizeof(*aSample) + aSample->mSize; // 17. Set last decode timestamp for track buffer to decode timestamp. trackBuffer.mLastDecodeTimestamp = Some(decodeTimestamp); // 18. Set last frame duration for track buffer to frame duration. - trackBuffer.mLastFrameDuration = Some(TimeUnit::FromMicroseconds(aSample->mDuration)); + trackBuffer.mLastFrameDuration = + Some(TimeUnit::FromMicroseconds(aSample->mDuration)); + + if (trackBuffer.mLongestFrameDuration.isNothing()) { + trackBuffer.mLongestFrameDuration = trackBuffer.mLastFrameDuration; + } else { + trackBuffer.mLongestFrameDuration = + Some(std::max(trackBuffer.mLongestFrameDuration.ref(), + trackBuffer.mLastFrameDuration.ref())); + } + // 19. If highest end timestamp for track buffer is unset or frame end timestamp is greater than highest end timestamp, then set highest end timestamp for track buffer to frame end timestamp. if (trackBuffer.mHighestEndTimestamp.isNothing() || frameEndTimestamp > trackBuffer.mHighestEndTimestamp.ref()) { trackBuffer.mHighestEndTimestamp = Some(frameEndTimestamp); } // 20. If frame end timestamp is greater than group end timestamp, then set group end timestamp equal to frame end timestamp. if (frameEndTimestamp > mGroupEndTimestamp) { mGroupEndTimestamp = frameEndTimestamp;
--- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -166,16 +166,18 @@ private: : mNumTracks(0) , mNeedRandomAccessPoint(true) , mSizeBuffer(0) {} uint32_t mNumTracks; Maybe<TimeUnit> mLastDecodeTimestamp; Maybe<TimeUnit> mLastFrameDuration; Maybe<TimeUnit> mHighestEndTimestamp; + // Longest frame duration seen in a coded frame group. + Maybe<TimeUnit> mLongestFrameDuration; bool mNeedRandomAccessPoint; nsRefPtr<MediaTrackDemuxer> mDemuxer; TrackBuffer mQueuedSamples; MediaPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest; UniquePtr<TrackInfo> mInfo; // We only manage a single track of each type at this time. nsTArray<TrackBuffer> mBuffers; TimeIntervals mBufferedRanges;