Bug 1309516 part 4 - always notify LoadedMetadataEvent before decoding first frame;r?jwwang
MozReview-Commit-ID: 4VcmELgvAjC
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1248,54 +1248,34 @@ DecodeMetadataState::OnMetadataRead(Meta
mMaster->mInfo = Some(aMetadata->mInfo);
mMaster->mMetadataTags = aMetadata->mTags.forget();
mMaster->mMediaSeekable = Info().mMediaSeekable;
mMaster->mMediaSeekableOnlyInBufferedRanges = Info().mMediaSeekableOnlyInBufferedRanges;
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();
- }
-
- if (waitingForCDM) {
+ MOZ_ASSERT(mMaster->mDuration.Ref().isSome());
+
+ mMaster->EnqueueLoadedMetadataEvent();
+
+ 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<WaitForCDMState>();
} else {
SetState<DecodingFirstFrameState>(SeekJob{});
}
}
@@ -1694,17 +1674,16 @@ MediaDecoderStateMachine::MediaDecoderSt
mFragmentEndTime(-1),
mReader(new MediaDecoderReaderWrapper(mTaskQueue, aReader)),
mDecodedAudioEndTime(0),
mDecodedVideoEndTime(0),
mPlaybackRate(1.0),
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
mAudioCaptured(false),
- mNotifyMetadataBeforeFirstFrame(false),
mMinimizePreroll(false),
mSentLoadedMetadataEvent(false),
mSentFirstFrameLoadedEvent(false),
mVideoDecodeSuspended(false),
mVideoDecodeSuspendTimer(mTaskQueue),
mOutputStreamManager(new OutputStreamManager()),
mResource(aDecoder->GetResource()),
mAudioOffloading(false),
@@ -2813,21 +2792,16 @@ MediaDecoderStateMachine::FinishDecodeFi
DECODER_LOG("Media duration %lld, "
"transportSeekable=%d, mediaSeekable=%d",
Duration().ToMicroseconds(), mResource->IsTransportSeekable(), mMediaSeekable);
// 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
@@ -680,24 +680,16 @@ private:
bool mAudioCaptured;
// True if all audio frames are already rendered.
bool mAudioCompleted = false;
// True if all video frames are already rendered.
bool mVideoCompleted = false;
- // 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