Bug 1272565 - draw a blank image when no frames in the video track.
MozReview-Commit-ID: 1Kijn00XAnQ
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2031,17 +2031,17 @@ MediaDecoderStateMachine::IsDecodingFirs
void
MediaDecoderStateMachine::FinishDecodeFirstFrame()
{
MOZ_ASSERT(OnTaskQueue());
DECODER_LOG("FinishDecodeFirstFrame");
if (!IsRealTime() && !mSentFirstFrameLoadedEvent) {
- mMediaSink->Redraw();
+ mMediaSink->Redraw(mInfo.mVideo);
}
// If we don't know the duration by this point, we assume infinity, per spec.
if (mDuration.Ref().isNothing()) {
mDuration = Some(TimeUnit::FromInfinity());
}
DECODER_LOG("Media duration %lld, "
@@ -2143,17 +2143,17 @@ MediaDecoderStateMachine::SeekCompleted(
// Reset quick buffering status. This ensures that if we began the
// seek while quick-buffering, we won't bypass quick buffering mode
// if we need to buffer after the seek.
mQuickBuffering = false;
ScheduleStateMachine();
if (video) {
- mMediaSink->Redraw();
+ mMediaSink->Redraw(mInfo.mVideo);
mOnPlaybackEvent.Notify(MediaEventType::Invalidate);
}
}
RefPtr<ShutdownPromise>
MediaDecoderStateMachine::BeginShutdown()
{
return InvokeAsync(OwnerThread(), this, __func__,
--- a/dom/media/mediasink/MediaSink.h
+++ b/dom/media/mediasink/MediaSink.h
@@ -91,17 +91,17 @@ public:
virtual void SetPreservesPitch(bool aPreservesPitch) {}
// Pause/resume the playback. Only work after playback starts.
virtual void SetPlaying(bool aPlaying) = 0;
// Single frame rendering operation may need to be done before playback
// started (1st frame) or right after seek completed or playback stopped.
// Do nothing if this sink has no video track. Can be called in any state.
- virtual void Redraw() {};
+ virtual void Redraw(const VideoInfo& aInfo) {};
// Begin a playback session with the provided start time and media info.
// Must be called when playback is stopped.
virtual void Start(int64_t aStartTime, const MediaInfo& aInfo) = 0;
// Finish a playback session.
// Must be called after playback starts.
virtual void Stop() = 0;
--- a/dom/media/mediasink/VideoSink.cpp
+++ b/dom/media/mediasink/VideoSink.cpp
@@ -259,20 +259,36 @@ VideoSink::OnVideoQueueFinished()
if (!mUpdateScheduler.IsScheduled() &&
mAudioSink->IsPlaying() &&
!mEndPromiseHolder.IsEmpty()) {
UpdateRenderedVideoFrames();
}
}
void
-VideoSink::Redraw()
+VideoSink::Redraw(const VideoInfo& aInfo)
{
AssertOwnerThread();
- RenderVideoFrames(1);
+
+ // No video track, nothing to draw.
+ if (!aInfo.IsValid() || !mContainer) {
+ return;
+ }
+
+ if (VideoQueue().GetSize() > 0) {
+ RenderVideoFrames(1);
+ return;
+ }
+
+ // When we reach here, it means there are no frames in this video track.
+ // Draw a blank frame to ensure there is something in the image container
+ // to fire 'loadeddata'.
+ RefPtr<Image> blank =
+ mContainer->GetImageContainer()->CreatePlanarYCbCrImage();
+ mContainer->SetCurrentFrame(aInfo.mDisplay, blank, TimeStamp::Now());
}
void
VideoSink::TryUpdateRenderedVideoFrames()
{
AssertOwnerThread();
if (!mUpdateScheduler.IsScheduled() && VideoQueue().GetSize() >= 1 &&
mAudioSink->IsPlaying()) {
--- a/dom/media/mediasink/VideoSink.h
+++ b/dom/media/mediasink/VideoSink.h
@@ -51,17 +51,17 @@ public:
void SetPlaybackRate(double aPlaybackRate) override;
void SetVolume(double aVolume) override;
void SetPreservesPitch(bool aPreservesPitch) override;
void SetPlaying(bool aPlaying) override;
- void Redraw() override;
+ void Redraw(const VideoInfo& aInfo) override;
void Start(int64_t aStartTime, const MediaInfo& aInfo) override;
void Stop() override;
bool IsStarted() const override;
bool IsPlaying() const override;