mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1163719 - Store startup cache entries in loading order; r=nfroyd (410ef75ff) - Bug 1072313: P1. Make MacIOSurface refcount thread-safe. r=mattwoodrow (3be93ce91) - Bug 1072313: P2 Prevent instanciating MacIOSurfaceLib directly. r=mattwoodrow (8d5d7e2e5) - Bug 1178513 - Export libxul symbols needed by ACL. r=mattwoodrow (b01035079) - Bug 1143575. Remove unused CompositableClient::OnTransaction. r=nical (8901f1fe8) - Bug 1143575. Convert SetCurrentImage(nullptr) callers to call ClearAllImages instead. r=nical (1a89f04f0) - Bug 1143575. Fix indent. r=cpearce (6b8f4e725) - Bug 1179111 part 1 - Implement CSSAnimation.animationName; r=smaug, r=jwatt (0d27b5d2e) - Bug 1179111 part 2 - Implement CSSTransition.transitionProperty; r=smaug, r=jwatt (f395dfc55) - Bug 1144615 - 2 - Adds a playbackRate selector widget to the animation panel; r=vporof (d538eb734) - Bug 1144615 - 1 - Minor css fixes in animation panel; r=bgrins (661a6feab) - Bug 1144615 - 3 - Tests for the playbackRate selection UI in the animation panel; r=vporof (82a4b4f91) - Bug 1120833 - 3 - Refresh the list of animation widgets when new animations are added; r=miker (f833abeb2) - Bug 1153903 - Get rid of logspam during devtools talos test runs;r=pbrosset (77f1968d2) - Bug 1155653 - Preview animation target nodes in animationinspector panel; r=bgrins (61f197d75) - Bug 1151018 - Refresh the list of Animation widgets when the animation panel loads; r=bgrins (9351a0b64) - Bug 1155663 - Show animations as synchronized time blocks in animation inspector; r=bgrins (66f544aea) - Bug 1149999 - 2 - Send animation removed events to the animation-panel for re-starting transitions; r=past (2913b4d4b) - Bug 1179111 part 3 - Make DevTools read the appropriate name property; r=pbrosset (6dfecd643) - Bug 1179111 part 4 - Remove KeyframeEffectReadOnly.name; r=smaug (85894f42f) - Bug 1004383 follow-up: Mark ElementPropertyTransition::AsTransition() as override (f37e36e8a) - Bug 1179111 part 5 - Remove Name() methods; r=jwatt (8909c4781) - Bug 1143575. Remove Theora-only duplicate frame optimization. r=cpearce (fe53385ec) - Bug 1172825 - MDSM playback should depend on IsPlaying() instead of |mPlayState|. r=cpearce. (9a9cf656d) - Bug 1163223 - Switch test_buffered to use timeupdate rather than loadedmetadata. r=cpearce (b91463faf) - Bug 1163223 - Move bailout case in GetBuffered into the readers. r=jww (c875c1d71) - Bug 1161901 - Dispatch MediaDecoderReader::SetIdle directly. r=jww (a9ad2582d) - Bug 1161901 - Use ProxyMediaCall instead of MDSM::ShutdownReader. r=jww (c866b524c) - Bug 1161901 - Hoist MDSM shutdown logic into MDSM::Shutdown and remove brittle requirement that RunStateMachine only happen once in SHUTDOWN state. r=jww (0d81368d6) - Bug 1153149 - Remove IsWaitingMediaResources() from PlatformDecoderModule. r=jya (70bd67ee3) - Bug 1161984 - Get rid of IsWaitingMediaResources() in MP4Reader. r=jya (94dd1f58c) - Bug 1163223 - Introduce StartTimeRendezvous and route samples through it. r=jww (b2a80c47a) - Bug 1163223 - Use AwaitStartTime to handle metadata end time. r=jww (8e22fc3fd) - Bug 1163223 - Use AwaitStartTime to invoke MediaDecoderReader::SetStartTime. r=jww (6141f5303) - Bug 1172387 - Clean up code of MediaDecoderStateMachine::StopAudioThread. r=kinetik. (717640128) - Bug 1163223 - Adjust incoming samples for start time. r=jww (c4029f934)
This commit is contained in:
@@ -56,8 +56,6 @@ using namespace mozilla::media;
|
||||
#undef DECODER_LOG
|
||||
#undef VERBOSE_LOG
|
||||
|
||||
extern PRLogModuleInfo* gMediaDecoderLog;
|
||||
extern PRLogModuleInfo* gMediaSampleLog;
|
||||
#define LOG(m, l, x, ...) \
|
||||
MOZ_LOG(m, l, ("Decoder=%p " x, mDecoder.get(), ##__VA_ARGS__))
|
||||
#define DECODER_LOG(x, ...) \
|
||||
@@ -227,9 +225,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mAudioCaptured(false),
|
||||
mPositionChangeQueued(false),
|
||||
mAudioCompleted(false, "MediaDecoderStateMachine::mAudioCompleted"),
|
||||
mGotDurationFromMetaData(false),
|
||||
mNotifyMetadataBeforeFirstFrame(false),
|
||||
mDispatchedEventToDecode(false),
|
||||
mStopAudioThread(true),
|
||||
mQuickBuffering(false),
|
||||
mMinimizePreroll(false),
|
||||
mDecodeThreadWaiting(false),
|
||||
@@ -776,6 +773,7 @@ MediaDecoderStateMachine::OnAudioDecoded(AudioData* aAudioSample)
|
||||
nsRefPtr<AudioData> audio(aAudioSample);
|
||||
MOZ_ASSERT(audio);
|
||||
mAudioDataRequest.Complete();
|
||||
aAudioSample->AdjustForStartTime(StartTime());
|
||||
mDecodedAudioEndTime = audio->GetEndTime();
|
||||
|
||||
SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
|
||||
@@ -1050,7 +1048,9 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
nsRefPtr<VideoData> video(aVideoSample);
|
||||
MOZ_ASSERT(video);
|
||||
mVideoDataRequest.Complete();
|
||||
aVideoSample->AdjustForStartTime(StartTime());
|
||||
mDecodedVideoEndTime = video ? video->GetEndTime() : mDecodedVideoEndTime;
|
||||
|
||||
SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
|
||||
@@ -1435,8 +1435,6 @@ void MediaDecoderStateMachine::RecomputeDuration()
|
||||
fireDurationChanged = true;
|
||||
} else if (mInfo.mMetadataDuration.isSome()) {
|
||||
duration = mInfo.mMetadataDuration.ref();
|
||||
} else if (mInfo.mMetadataEndTime.isSome() && mStartTime >= 0) {
|
||||
duration = mInfo.mMetadataEndTime.ref() - TimeUnit::FromMicroseconds(mStartTime);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -1461,11 +1459,10 @@ void MediaDecoderStateMachine::SetDuration(TimeUnit aDuration)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(aDuration.ToMicroseconds() >= 0);
|
||||
mDurationSet = true;
|
||||
|
||||
if (mStartTime == -1) {
|
||||
SetStartTime(0);
|
||||
}
|
||||
mDurationSet = true;
|
||||
|
||||
if (aDuration.IsInfinite()) {
|
||||
mEndTime = -1;
|
||||
@@ -1565,7 +1562,29 @@ void MediaDecoderStateMachine::Shutdown()
|
||||
if (mAudioSink) {
|
||||
mAudioSink->PrepareToShutdown();
|
||||
}
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
|
||||
mQueuedSeek.RejectIfExists(__func__);
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mCurrentSeek.RejectIfExists(__func__);
|
||||
|
||||
if (IsPlaying()) {
|
||||
StopPlayback();
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
// Shut down our start time rendezvous.
|
||||
if (mStartTimeRendezvous) {
|
||||
mStartTimeRendezvous->Destroy();
|
||||
}
|
||||
|
||||
// Put a task in the decode queue to shutdown the reader.
|
||||
// the queue to spin down.
|
||||
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, &MediaDecoderReader::Shutdown)
|
||||
->Then(TaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::FinishShutdown,
|
||||
&MediaDecoderStateMachine::FinishShutdown);
|
||||
DECODER_LOG("Shutdown started");
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::StartDecoding()
|
||||
@@ -1738,17 +1757,6 @@ void MediaDecoderStateMachine::StopAudioThread()
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
if (mStopAudioThread) {
|
||||
// Audio sink is being stopped in another thread. Wait until finished.
|
||||
while (mAudioSink) {
|
||||
mDecoder->GetReentrantMonitor().Wait();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mStopAudioThread = true;
|
||||
// Wake up audio sink so that it can reach the finish line.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
if (mAudioSink) {
|
||||
DECODER_LOG("Shutdown audio thread");
|
||||
mAudioSink->PrepareToShutdown();
|
||||
@@ -1758,8 +1766,6 @@ void MediaDecoderStateMachine::StopAudioThread()
|
||||
}
|
||||
mAudioSink = nullptr;
|
||||
}
|
||||
// Wake up those waiting for audio sink to finish.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -1775,14 +1781,6 @@ MediaDecoderStateMachine::EnqueueDecodeFirstFrameTask()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::SetReaderIdle()
|
||||
{
|
||||
MOZ_ASSERT(OnDecodeTaskQueue());
|
||||
DECODER_LOG("Invoking SetReaderIdle()");
|
||||
mReader->SetIdle();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
|
||||
{
|
||||
@@ -1840,11 +1838,10 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
|
||||
}
|
||||
|
||||
if (needIdle) {
|
||||
DECODER_LOG("Dispatching SetReaderIdle() audioQueue=%lld videoQueue=%lld",
|
||||
DECODER_LOG("Dispatching SetIdle() audioQueue=%lld videoQueue=%lld",
|
||||
GetDecodedAudioDuration(),
|
||||
VideoQueue().Duration());
|
||||
nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(
|
||||
this, &MediaDecoderStateMachine::SetReaderIdle);
|
||||
nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(mReader, &MediaDecoderReader::SetIdle);
|
||||
DecodeTaskQueue()->Dispatch(task.forget());
|
||||
}
|
||||
}
|
||||
@@ -2039,11 +2036,10 @@ MediaDecoderStateMachine::StartAudioThread()
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
if (mAudioCaptured) {
|
||||
NS_ASSERTION(mStopAudioThread, "mStopAudioThread must always be true if audio is captured");
|
||||
MOZ_ASSERT(!mAudioSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mStopAudioThread = false;
|
||||
if (HasAudio() && !mAudioSink) {
|
||||
// The audio end time should always be at least the audio start time.
|
||||
mAudioEndTime = mAudioStartTime;
|
||||
@@ -2188,9 +2184,36 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
|
||||
mDecoder->SetMediaSeekable(mReader->IsMediaSeekable());
|
||||
mInfo = aMetadata->mInfo;
|
||||
mMetadataTags = aMetadata->mTags.forget();
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
|
||||
if (mInfo.mMetadataDuration.isSome() || mInfo.mMetadataEndTime.isSome()) {
|
||||
// Set up the start time rendezvous if it doesn't already exist (which is
|
||||
// generally the case, unless we're coming out of dormant mode).
|
||||
if (!mStartTimeRendezvous) {
|
||||
mStartTimeRendezvous = new StartTimeRendezvous(TaskQueue(), HasAudio(), HasVideo(),
|
||||
mReader->ForceZeroStartTime() || IsRealTime());
|
||||
|
||||
mStartTimeRendezvous->AwaitStartTime()->Then(TaskQueue(), __func__,
|
||||
[self] () -> void {
|
||||
NS_ENSURE_TRUE_VOID(!self->IsShutdown());
|
||||
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
|
||||
self->mReader->SetStartTime(self->StartTime());
|
||||
},
|
||||
[] () -> void { NS_WARNING("Setting start time on reader failed"); }
|
||||
);
|
||||
}
|
||||
|
||||
if (mInfo.mMetadataDuration.isSome()) {
|
||||
RecomputeDuration();
|
||||
} else if (mInfo.mUnadjustedMetadataEndTime.isSome()) {
|
||||
mStartTimeRendezvous->AwaitStartTime()->Then(TaskQueue(), __func__,
|
||||
[self] () -> void {
|
||||
NS_ENSURE_TRUE_VOID(!self->IsShutdown());
|
||||
TimeUnit unadjusted = self->mInfo.mUnadjustedMetadataEndTime.ref();
|
||||
TimeUnit adjustment = TimeUnit::FromMicroseconds(self->StartTime());
|
||||
self->mInfo.mMetadataDuration.emplace(unadjusted - adjustment);
|
||||
self->RecomputeDuration();
|
||||
}, [] () -> void { NS_WARNING("Adjusting metadata end time failed"); }
|
||||
);
|
||||
}
|
||||
|
||||
if (HasVideo()) {
|
||||
@@ -2204,11 +2227,15 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
|
||||
}
|
||||
|
||||
mDecoder->StartProgressUpdates();
|
||||
mGotDurationFromMetaData = (GetDuration() != -1) || mDurationSet;
|
||||
|
||||
if (mGotDurationFromMetaData) {
|
||||
// We have all the information required: duration and size
|
||||
// Inform the element that we've loaded the metadata.
|
||||
// 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.
|
||||
mNotifyMetadataBeforeFirstFrame = mDurationSet || mReader->IsWaitingOnCDMResource();
|
||||
if (mNotifyMetadataBeforeFirstFrame) {
|
||||
EnqueueLoadedMetadataEvent();
|
||||
}
|
||||
|
||||
@@ -2317,17 +2344,27 @@ MediaDecoderStateMachine::DecodeFirstFrame()
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
} else {
|
||||
if (HasAudio()) {
|
||||
mAudioDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
|
||||
__func__, &MediaDecoderReader::RequestAudioData)
|
||||
mAudioDataRequest.Begin(
|
||||
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestAudioData)
|
||||
->Then(TaskQueue(), __func__, mStartTimeRendezvous.get(),
|
||||
&StartTimeRendezvous::ProcessFirstSample<AudioDataPromise>,
|
||||
&StartTimeRendezvous::FirstSampleRejected<AudioData>)
|
||||
->CompletionPromise()
|
||||
->Then(TaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioDecoded,
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded));
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded)
|
||||
);
|
||||
}
|
||||
if (HasVideo()) {
|
||||
mVideoDecodeStartTime = TimeStamp::Now();
|
||||
mVideoDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
|
||||
__func__, &MediaDecoderReader::RequestVideoData, false,
|
||||
int64_t(0))
|
||||
mVideoDataRequest.Begin(
|
||||
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestVideoData, false, int64_t(0))
|
||||
->Then(TaskQueue(), __func__, mStartTimeRendezvous.get(),
|
||||
&StartTimeRendezvous::ProcessFirstSample<VideoDataPromise>,
|
||||
&StartTimeRendezvous::FirstSampleRejected<VideoData>)
|
||||
->CompletionPromise()
|
||||
->Then(TaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnVideoDecoded,
|
||||
&MediaDecoderStateMachine::OnVideoNotDecoded));
|
||||
@@ -2384,15 +2421,11 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
||||
|
||||
nsAutoPtr<MediaInfo> info(new MediaInfo());
|
||||
*info = mInfo;
|
||||
if (!mGotDurationFromMetaData) {
|
||||
// We now have a duration, we can fire the LoadedMetadata and
|
||||
// FirstFrame event.
|
||||
if (!mNotifyMetadataBeforeFirstFrame) {
|
||||
// If we didn't have duration and/or start time before, we should now.
|
||||
EnqueueLoadedMetadataEvent();
|
||||
EnqueueFirstFrameLoadedEvent();
|
||||
} else {
|
||||
// Inform the element that we've loaded the first frame.
|
||||
EnqueueFirstFrameLoadedEvent();
|
||||
}
|
||||
EnqueueFirstFrameLoadedEvent();
|
||||
|
||||
if (mState == DECODER_STATE_DECODING_FIRSTFRAME) {
|
||||
StartDecoding();
|
||||
@@ -2508,15 +2541,6 @@ private:
|
||||
nsRefPtr<MediaDecoderStateMachine> mStateMachine;
|
||||
};
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::ShutdownReader()
|
||||
{
|
||||
MOZ_ASSERT(OnDecodeTaskQueue());
|
||||
mReader->Shutdown()->Then(TaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::FinishShutdown,
|
||||
&MediaDecoderStateMachine::FinishShutdown);
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::FinishShutdown()
|
||||
{
|
||||
@@ -2588,40 +2612,12 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
NS_ENSURE_TRUE(resource, NS_ERROR_NULL_POINTER);
|
||||
|
||||
switch (mState) {
|
||||
case DECODER_STATE_ERROR: {
|
||||
// Just wait for MediaDecoder::DecodeError to shut us down.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case DECODER_STATE_SHUTDOWN: {
|
||||
mQueuedSeek.RejectIfExists(__func__);
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mCurrentSeek.RejectIfExists(__func__);
|
||||
|
||||
if (IsPlaying()) {
|
||||
StopPlayback();
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
// Put a task in the decode queue to shutdown the reader.
|
||||
// the queue to spin down.
|
||||
nsCOMPtr<nsIRunnable> task
|
||||
= NS_NewRunnableMethod(this, &MediaDecoderStateMachine::ShutdownReader);
|
||||
DecodeTaskQueue()->Dispatch(task.forget());
|
||||
|
||||
DECODER_LOG("Shutdown started");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case DECODER_STATE_DORMANT: {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case DECODER_STATE_ERROR:
|
||||
case DECODER_STATE_SHUTDOWN:
|
||||
case DECODER_STATE_DORMANT:
|
||||
case DECODER_STATE_WAIT_FOR_CDM:
|
||||
case DECODER_STATE_WAIT_FOR_RESOURCES: {
|
||||
case DECODER_STATE_WAIT_FOR_RESOURCES:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case DECODER_STATE_DECODING_NONE: {
|
||||
SetState(DECODER_STATE_DECODING_METADATA);
|
||||
@@ -2658,7 +2654,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
MaybeStartPlayback();
|
||||
|
||||
AdvanceFrame();
|
||||
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
NS_ASSERTION(!IsPlaying() ||
|
||||
mLogicallySeeking ||
|
||||
IsStateMachineScheduled() ||
|
||||
mPlaybackRate == 0.0, "Must have timer scheduled");
|
||||
@@ -2719,6 +2715,9 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
}
|
||||
|
||||
case DECODER_STATE_COMPLETED: {
|
||||
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying()) {
|
||||
StopPlayback();
|
||||
}
|
||||
// Play the remaining media. We want to run AdvanceFrame() at least
|
||||
// once to ensure the current playback position is advanced to the
|
||||
// end of the media, and so that we update the readyState.
|
||||
@@ -2726,8 +2725,10 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
(HasAudio() && !mAudioCompleted) ||
|
||||
(mAudioCaptured && !GetDecodedStream()->IsFinished()))
|
||||
{
|
||||
// Start playback if necessary to play the remaining media.
|
||||
MaybeStartPlayback();
|
||||
AdvanceFrame();
|
||||
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
NS_ASSERTION(!IsPlaying() ||
|
||||
mLogicallySeeking ||
|
||||
mPlaybackRate == 0 || IsStateMachineScheduled(),
|
||||
"Must have timer scheduled");
|
||||
@@ -2819,10 +2820,6 @@ void MediaDecoderStateMachine::RenderVideoFrame(VideoData* aData,
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
|
||||
|
||||
if (aData->mDuplicate) {
|
||||
return;
|
||||
}
|
||||
|
||||
VERBOSE_LOG("playing video frame %lld (queued=%i, state-machine=%i, decoder-queued=%i)",
|
||||
aData->mTime, VideoQueue().GetSize() + mReader->SizeOfVideoQueueInFrames(),
|
||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames());
|
||||
@@ -2929,7 +2926,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
|
||||
NS_ASSERTION(!HasAudio() || mAudioStartTime != -1,
|
||||
"Should know audio start time if we have audio.");
|
||||
|
||||
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING || mLogicallySeeking) {
|
||||
if (!IsPlaying() || mLogicallySeeking) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3040,13 +3037,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
|
||||
// duration.
|
||||
RenderVideoFrame(currentFrame, presTime);
|
||||
}
|
||||
// If we're no longer playing after dropping and reacquiring the lock,
|
||||
// playback must've been stopped on the decode thread (by a seek, for
|
||||
// example). In that case, the current frame is probably out of date.
|
||||
if (!IsPlaying()) {
|
||||
ScheduleStateMachine();
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(IsPlaying());
|
||||
MediaDecoder::FrameStatistics& frameStats = mDecoder->GetFrameStatistics();
|
||||
frameStats.NotifyPresentedFrame();
|
||||
remainingTime = currentFrame->GetEndTime() - clock_time;
|
||||
@@ -3083,27 +3074,11 @@ MediaDecoderStateMachine::DropVideoUpToSeekTarget(VideoData* aSample)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
nsRefPtr<VideoData> video(aSample);
|
||||
MOZ_ASSERT(video);
|
||||
DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld] dup=%d",
|
||||
video->mTime, video->GetEndTime(), video->mDuplicate);
|
||||
DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld]",
|
||||
video->mTime, video->GetEndTime());
|
||||
MOZ_ASSERT(mCurrentSeek.Exists());
|
||||
const int64_t target = mCurrentSeek.mTarget.mTime;
|
||||
|
||||
// Duplicate handling: if we're dropping frames up the seek target, we must
|
||||
// be wary of Theora duplicate frames. They don't have an image, so if the
|
||||
// target frame is in a run of duplicates, we won't have an image to draw
|
||||
// after the seek. So store the last frame encountered while dropping, and
|
||||
// copy its Image forward onto duplicate frames, so that every frame has
|
||||
// an Image.
|
||||
if (video->mDuplicate &&
|
||||
mFirstVideoFrameAfterSeek &&
|
||||
!mFirstVideoFrameAfterSeek->mDuplicate) {
|
||||
nsRefPtr<VideoData> temp =
|
||||
VideoData::ShallowCopyUpdateTimestampAndDuration(mFirstVideoFrameAfterSeek,
|
||||
video->mTime,
|
||||
video->mDuration);
|
||||
video = temp;
|
||||
}
|
||||
|
||||
// If the frame end time is less than the seek target, we won't want
|
||||
// to display this frame after the seek, so discard it.
|
||||
if (target >= video->GetEndTime()) {
|
||||
@@ -3211,7 +3186,8 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
|
||||
mStartTime = 0;
|
||||
if (aStartTimeUsecs != 0) {
|
||||
mStartTime = aStartTimeUsecs;
|
||||
if (mGotDurationFromMetaData && GetEndTime() != INT64_MAX) {
|
||||
// XXXbholley - this whole method goes away in the upcoming patches.
|
||||
if (mDurationSet && GetEndTime() != INT64_MAX) {
|
||||
NS_ASSERTION(mEndTime != -1,
|
||||
"We should have mEndTime as supplied duration here");
|
||||
// We were specified a duration from a Content-Duration HTTP header.
|
||||
@@ -3221,17 +3197,11 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
|
||||
}
|
||||
}
|
||||
|
||||
// Pass along this immutable value to the reader so that it can make
|
||||
// calculations independently of the state machine.
|
||||
mReader->SetStartTime(mStartTime);
|
||||
|
||||
// Set the audio start time to be start of media. If this lies before the
|
||||
// first actual audio frame we have, we'll inject silence during playback
|
||||
// to ensure the audio starts at the correct time.
|
||||
mAudioStartTime = mStartTime;
|
||||
DECODER_LOG("Set media start time to %lld", mStartTime);
|
||||
|
||||
RecomputeDuration();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdateNextFrameStatus()
|
||||
@@ -3334,11 +3304,6 @@ void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
|
||||
void
|
||||
MediaDecoderStateMachine::ScheduleStateMachine() {
|
||||
AssertCurrentThreadInMonitor();
|
||||
if (mState == DECODER_STATE_SHUTDOWN) {
|
||||
NS_WARNING("Refusing to schedule shutdown state machine");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDispatchedStateMachine) {
|
||||
return;
|
||||
}
|
||||
@@ -3357,11 +3322,6 @@ MediaDecoderStateMachine::ScheduleStateMachineIn(int64_t aMicroseconds)
|
||||
// the promise, which must happen on the state
|
||||
// machine task queue.
|
||||
MOZ_ASSERT(aMicroseconds > 0);
|
||||
if (mState == DECODER_STATE_SHUTDOWN) {
|
||||
NS_WARNING("Refusing to schedule shutdown state machine");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDispatchedStateMachine) {
|
||||
return;
|
||||
}
|
||||
@@ -3432,7 +3392,6 @@ void MediaDecoderStateMachine::PreservesPitchChanged()
|
||||
|
||||
bool MediaDecoderStateMachine::IsShutdown()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
return mState == DECODER_STATE_ERROR ||
|
||||
mState == DECODER_STATE_SHUTDOWN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user