Bug 1309516 part 4 - always notify LoadedMetadataEvent before decoding first frame;r?jwwang
MozReview-Commit-ID: EwSJLjjLBaJ
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -305,60 +305,40 @@ private:
Resource()->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
mMaster->mInfo = Some(aMetadata->mInfo);
mMaster->mMetadataTags = aMetadata->mTags.forget();
if (Info().mMetadataDuration.isSome()) {
mMaster->RecomputeDuration();
} else if (Info().mUnadjustedMetadataEndTime.isSome()) {
- RefPtr<Master> master = mMaster;
- Reader()->AwaitStartTime()->Then(OwnerThread(), __func__,
- [master] () {
- NS_ENSURE_TRUE_VOID(!master->IsShutdown());
- auto& info = master->mInfo.ref();
- TimeUnit unadjusted = info.mUnadjustedMetadataEndTime.ref();
- TimeUnit adjustment = master->mReader->StartTime();
- info.mMetadataDuration.emplace(unadjusted - adjustment);
- master->RecomputeDuration();
- }, [master, this] () {
- SWARN("Adjusting metadata end time failed");
- }
- );
+ const TimeUnit unadjusted = Info().mUnadjustedMetadataEndTime.ref();
+ const TimeUnit adjustment = Info().mStartTime;
+ mMaster->mInfo->mMetadataDuration.emplace(unadjusted - adjustment);
+ mMaster->RecomputeDuration();
}
if (mMaster->HasVideo()) {
SLOG("Video decode isAsync=%d HWAccel=%d videoQueueSize=%d",
Reader()->IsAsync(),
Reader()->VideoIsHardwareAccelerated(),
mMaster->GetAmpleVideoFrames());
}
- // In general, we wait until we know the duration before notifying the decoder.
- // However, we notify unconditionally in this case without waiting for the start
- // time, since the caller might be waiting on metadataloaded to be fired before
- // feeding in the CDM, which we need to decode the first frame (and
- // thus get the metadata). We could fix this if we could compute the start
- // time by demuxing without necessaring decoding.
- bool waitingForCDM = Info().IsEncrypted() && !mMaster->mCDMProxy;
-
- mMaster->mNotifyMetadataBeforeFirstFrame =
- mMaster->mDuration.Ref().isSome() || waitingForCDM;
-
- if (mMaster->mNotifyMetadataBeforeFirstFrame) {
- mMaster->EnqueueLoadedMetadataEvent();
- }
+ MOZ_ASSERT(mMaster->mDuration.Ref().isSome());
+
+ mMaster->EnqueueLoadedMetadataEvent();
if (mPendingDormant) {
// No need to store mQueuedSeek because we are at position 0.
SetState(DECODER_STATE_DORMANT);
return;
}
- if (waitingForCDM) {
+ if (Info().IsEncrypted() && !mMaster->mCDMProxy) {
// Metadata parsing was successful but we're still waiting for CDM caps
// to become available so that we can build the correct decryptor/decoder.
SetState(DECODER_STATE_WAIT_FOR_CDM);
return;
}
SetState(DECODER_STATE_DECODING_FIRSTFRAME);
}
@@ -1250,17 +1230,16 @@ MediaDecoderStateMachine::MediaDecoderSt
mDecodedAudioEndTime(0),
mDecodedVideoEndTime(0),
mPlaybackRate(1.0),
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
mAudioCaptured(false),
INIT_WATCHABLE(mAudioCompleted, false),
INIT_WATCHABLE(mVideoCompleted, false),
- mNotifyMetadataBeforeFirstFrame(false),
mMinimizePreroll(false),
mSentLoadedMetadataEvent(false),
mSentFirstFrameLoadedEvent(false),
mVideoDecodeSuspended(false),
mVideoDecodeSuspendTimer(mTaskQueue),
mOutputStreamManager(new OutputStreamManager()),
mResource(aDecoder->GetResource()),
mAudioOffloading(false),
@@ -2661,21 +2640,16 @@ MediaDecoderStateMachine::FinishDecodeFi
DECODER_LOG("Media duration %lld, "
"transportSeekable=%d, mediaSeekable=%d",
Duration().ToMicroseconds(), mResource->IsTransportSeekable(), mMediaSeekable.Ref());
// Get potentially updated metadata
mReader->ReadUpdatedMetadata(mInfo.ptr());
- if (!mNotifyMetadataBeforeFirstFrame) {
- // If we didn't have duration and/or start time before, we should now.
- EnqueueLoadedMetadataEvent();
- }
-
EnqueueFirstFrameLoadedEvent();
}
RefPtr<ShutdownPromise>
MediaDecoderStateMachine::BeginShutdown()
{
return InvokeAsync(OwnerThread(), this, __func__,
&MediaDecoderStateMachine::Shutdown);
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -703,24 +703,16 @@ private:
// the state machine thread. Synchronised via decoder monitor.
// When data is being sent to a MediaStream, this is true when all data has
// been written to the MediaStream.
Watchable<bool> mAudioCompleted;
// True if all video frames are already rendered.
Watchable<bool> mVideoCompleted;
- // Flag whether we notify metadata before decoding the first frame or after.
- //
- // Note that the odd semantics here are designed to replicate the current
- // behavior where we notify the decoder each time we come out of dormant, but
- // send suppressed event visibility for those cases. This code can probably be
- // simplified.
- bool mNotifyMetadataBeforeFirstFrame;
-
// True if we should not decode/preroll unnecessary samples, unless we're
// played. "Prerolling" in this context refers to when we decode and
// buffer decoded samples in advance of when they're needed for playback.
// This flag is set for preload=metadata media, and means we won't
// decode more than the first video frame and first block of audio samples
// for that media when we startup, or after a seek. When Play() is called,
// we reset this flag, as we assume the user is playing the media, so
// prerolling is appropriate then. This flag is used to reduce the overhead