зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1218311 - Port the fix of bug 1193614 to VideoSink. r=cpearce.
This commit is contained in:
Родитель
9e2043a953
Коммит
22151cf459
|
@ -392,7 +392,7 @@ MediaDecoderStateMachine::CreateMediaSink(bool aAudioCaptured)
|
|||
RefPtr<media::MediaSink> mediaSink =
|
||||
new VideoSink(mTaskQueue, audioSink, mVideoQueue,
|
||||
mDecoder->GetVideoFrameContainer(), mRealTime,
|
||||
mDecoder->GetFrameStatistics(), AUDIO_DURATION_USECS,
|
||||
mDecoder->GetFrameStatistics(),
|
||||
sVideoQueueSendToCompositorSize);
|
||||
return mediaSink.forget();
|
||||
}
|
||||
|
@ -894,19 +894,6 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample)
|
|||
StopPrerollingVideo();
|
||||
}
|
||||
|
||||
// Schedule the state machine to send stream data as soon as possible if
|
||||
// the VideoQueue() is empty or contains one frame before the Push().
|
||||
//
|
||||
// The state machine threads requires a frame in VideoQueue() that is `in
|
||||
// the future` to gather precise timing information. The head of
|
||||
// VideoQueue() is always `in the past`.
|
||||
//
|
||||
// Schedule the state machine as soon as possible to render the video
|
||||
// frame or delay the state machine thread accurately.
|
||||
if (VideoQueue().GetSize() <= 2) {
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
// For non async readers, if the requested video sample was slow to
|
||||
// arrive, increase the amount of audio we buffer to ensure that we
|
||||
// don't run out of audio. This is unnecessary for async readers,
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
MOZ_ASSERT(aItem);
|
||||
NS_ADDREF(aItem);
|
||||
nsDeque::Push(aItem);
|
||||
mPushEvent.Notify();
|
||||
mPushEvent.Notify(RefPtr<T>(aItem));
|
||||
}
|
||||
|
||||
inline void PushFront(T* aItem) {
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
MOZ_ASSERT(aItem);
|
||||
NS_ADDREF(aItem);
|
||||
nsDeque::PushFront(aItem);
|
||||
mPushEvent.Notify();
|
||||
mPushEvent.Notify(RefPtr<T>(aItem));
|
||||
}
|
||||
|
||||
inline already_AddRefed<T> PopFront() {
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
return mPopEvent;
|
||||
}
|
||||
|
||||
MediaEventSource<void>& PushEvent() {
|
||||
MediaEventSource<RefPtr<T>>& PushEvent() {
|
||||
return mPushEvent;
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ public:
|
|||
private:
|
||||
mutable ReentrantMonitor mReentrantMonitor;
|
||||
MediaEventProducer<RefPtr<T>> mPopEvent;
|
||||
MediaEventProducer<void> mPushEvent;
|
||||
MediaEventProducer<RefPtr<T>> mPushEvent;
|
||||
MediaEventProducer<void> mFinishEvent;
|
||||
// True when we've decoded the last frame of data in the
|
||||
// bitstream for which we're queueing frame data.
|
||||
|
|
|
@ -26,7 +26,6 @@ VideoSink::VideoSink(AbstractThread* aThread,
|
|||
VideoFrameContainer* aContainer,
|
||||
bool aRealTime,
|
||||
FrameStatistics& aFrameStats,
|
||||
int aDelayDuration,
|
||||
uint32_t aVQueueSentToCompositerSize)
|
||||
: mOwnerThread(aThread)
|
||||
, mAudioSink(aAudioSink)
|
||||
|
@ -38,7 +37,6 @@ VideoSink::VideoSink(AbstractThread* aThread,
|
|||
, mVideoFrameEndTime(-1)
|
||||
, mHasVideo(false)
|
||||
, mUpdateScheduler(aThread)
|
||||
, mDelayDuration(aDelayDuration)
|
||||
, mVideoQueueSendToCompositorSize(aVQueueSentToCompositerSize)
|
||||
{
|
||||
MOZ_ASSERT(mAudioSink, "AudioSink should exist.");
|
||||
|
@ -218,12 +216,18 @@ VideoSink::Shutdown()
|
|||
}
|
||||
|
||||
void
|
||||
VideoSink::OnVideoQueueEvent()
|
||||
VideoSink::OnVideoQueueEvent(RefPtr<MediaData>&& aSample)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
// Listen to push event, VideoSink should try rendering ASAP if first frame
|
||||
// arrives but update scheduler is not triggered yet.
|
||||
TryUpdateRenderedVideoFrames();
|
||||
VideoData* v = aSample->As<VideoData>();
|
||||
if (!v->mSentToCompositor) {
|
||||
// Since we push rendered frames back to the queue, we will receive
|
||||
// push events for them. We only need to trigger render loop
|
||||
// when this frame is not rendered yet.
|
||||
TryUpdateRenderedVideoFrames();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -338,7 +342,7 @@ VideoSink::UpdateRenderedVideoFrames()
|
|||
// the current frame.
|
||||
NS_ASSERTION(clockTime >= 0, "Should have positive clock time.");
|
||||
|
||||
int64_t remainingTime = mDelayDuration;
|
||||
int64_t remainingTime = -1;
|
||||
if (VideoQueue().GetSize() > 0) {
|
||||
RefPtr<MediaData> currentFrame = VideoQueue().PopFront();
|
||||
int32_t framesRemoved = 0;
|
||||
|
@ -365,7 +369,14 @@ VideoSink::UpdateRenderedVideoFrames()
|
|||
|
||||
RenderVideoFrames(mVideoQueueSendToCompositorSize, clockTime, nowTime);
|
||||
|
||||
TimeStamp target = nowTime + TimeDuration::FromMicroseconds(remainingTime);
|
||||
// No next fame to render. There is no need to schedule next render
|
||||
// loop. We will run render loops again upon incoming frames.
|
||||
if (remainingTime < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimeStamp target = nowTime + TimeDuration::FromMicroseconds(
|
||||
remainingTime / mAudioSink->GetPlaybackParams().mPlaybackRate);
|
||||
|
||||
RefPtr<VideoSink> self = this;
|
||||
mUpdateScheduler.Ensure(target, [self] () {
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
VideoFrameContainer* aContainer,
|
||||
bool aRealTime,
|
||||
FrameStatistics& aFrameStats,
|
||||
int aDelayDuration,
|
||||
uint32_t aVQueueSentToCompositerSize);
|
||||
|
||||
const PlaybackParams& GetPlaybackParams() const override;
|
||||
|
@ -74,7 +73,7 @@ private:
|
|||
virtual ~VideoSink();
|
||||
|
||||
// VideoQueue listener related.
|
||||
void OnVideoQueueEvent();
|
||||
void OnVideoQueueEvent(RefPtr<MediaData>&& aSample);
|
||||
void ConnectListener();
|
||||
void DisconnectListener();
|
||||
|
||||
|
@ -139,10 +138,6 @@ private:
|
|||
// Used to trigger another update of rendered frames in next round.
|
||||
DelayedScheduler mUpdateScheduler;
|
||||
|
||||
// A delay duration to trigger next time UpdateRenderedVideoFrames().
|
||||
// Based on the default value in MDSM.
|
||||
const int mDelayDuration;
|
||||
|
||||
// Max frame number sent to compositor at a time.
|
||||
// Based on the pref value obtained in MDSM.
|
||||
const uint32_t mVideoQueueSendToCompositorSize;
|
||||
|
|
Загрузка…
Ссылка в новой задаче