void VideoSink::UpdateRenderedVideoFramesByTimer() { AssertOwnerThread(); mUpdateScheduler.CompleteRequest(); UpdateRenderedVideoFrames(); }
void VideoSink::TryUpdateRenderedVideoFrames() { AssertOwnerThread(); if (!mUpdateScheduler.IsScheduled() && VideoQueue().GetSize() >= 1 && mAudioSink->IsPlaying()) { UpdateRenderedVideoFrames(); } }
void VideoSink::OnVideoQueueFinished() { AssertOwnerThread(); // Run render loop if the end promise is not resolved yet. if (!mUpdateScheduler.IsScheduled() && mAudioSink->IsPlaying() && !mEndPromiseHolder.IsEmpty()) { UpdateRenderedVideoFrames(); } }
void VideoSink::Start(int64_t aStartTime, const MediaInfo& aInfo) { AssertOwnerThread(); VSINK_LOG("[%s]", __func__); mAudioSink->Start(aStartTime, aInfo); mHasVideo = aInfo.HasVideo(); if (mHasVideo) { mEndPromise = mEndPromiseHolder.Ensure(__func__); // If the underlying MediaSink has an end promise for the video track (which // happens when mAudioSink refers to a DecodedStream), we must wait for it // to complete before resolving our own end promise. Otherwise, MDSM might // stop playback before DecodedStream plays to the end and cause // test_streams_element_capture.html to time out. RefPtr<GenericPromise> p = mAudioSink->OnEnded(TrackInfo::kVideoTrack); if (p) { RefPtr<VideoSink> self = this; mVideoSinkEndRequest.Begin(p->Then(mOwnerThread, __func__, [self] () { self->mVideoSinkEndRequest.Complete(); self->TryUpdateRenderedVideoFrames(); // It is possible the video queue size is 0 and we have no frames to // render. However, we need to call MaybeResolveEndPromise() to ensure // mEndPromiseHolder is resolved. self->MaybeResolveEndPromise(); }, [self] () { self->mVideoSinkEndRequest.Complete(); self->TryUpdateRenderedVideoFrames(); self->MaybeResolveEndPromise(); })); } ConnectListener(); // Run the render loop at least once so we can resolve the end promise // when video duration is 0. UpdateRenderedVideoFrames(); } }