Pass |paint_cb| through media::Renderer::Initialize().
This provides a common path for a media::Renderer implementation to paint video
frames through the render process' CC code. There are several options how this
callback could be used (or not used):
- Call |paint_cb| periodically to render normal video frames.
- Call |paint_cb| with a HOLE_FRAME during initialization and during frame size
change to support hold punching.
- Ignore |paint_cb| if there is no video stream, or if video renderering is
handled by the media::Renderer implementation entirely.
BUG=432796
Review URL: https://codereview.chromium.org/725573003
Cr-Commit-Position: refs/heads/master@{#304074}
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index d2b9bd6c..0c9dba45 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -119,11 +119,12 @@
virtual ~MockVideoRenderer();
// VideoRenderer implementation.
- MOCK_METHOD8(Initialize, void(DemuxerStream* stream,
+ MOCK_METHOD9(Initialize, void(DemuxerStream* stream,
bool low_delay,
const PipelineStatusCB& init_cb,
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const TimeDeltaCB& get_time_cb));
@@ -161,12 +162,13 @@
virtual ~MockRenderer();
// Renderer implementation.
- MOCK_METHOD6(Initialize, void(DemuxerStreamProvider* demuxer_stream_provider,
+ MOCK_METHOD7(Initialize, void(DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb));
+ const PipelineStatusCB& error_cb));
MOCK_METHOD1(Flush, void(const base::Closure& flush_cb));
MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta timestamp));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 0597105..7534688 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -68,6 +68,7 @@
const PipelineStatusCB& seek_cb,
const PipelineMetadataCB& metadata_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& duration_change_cb,
const AddTextTrackCB& add_text_track_cb) {
DCHECK(!ended_cb.is_null());
@@ -75,6 +76,7 @@
DCHECK(!seek_cb.is_null());
DCHECK(!metadata_cb.is_null());
DCHECK(!buffering_state_cb.is_null());
+ DCHECK(!paint_cb.is_null());
base::AutoLock auto_lock(lock_);
CHECK(!running_) << "Media pipeline is already running";
@@ -87,6 +89,7 @@
seek_cb_ = seek_cb;
metadata_cb_ = metadata_cb;
buffering_state_cb_ = buffering_state_cb;
+ paint_cb_ = paint_cb;
duration_change_cb_ = duration_change_cb;
add_text_track_cb_ = add_text_track_cb;
@@ -694,9 +697,10 @@
demuxer_,
done_cb,
base::Bind(&Pipeline::OnUpdateStatistics, weak_this),
+ base::Bind(&Pipeline::BufferingStateChanged, weak_this),
+ base::ResetAndReturn(&paint_cb_),
base::Bind(&Pipeline::OnRendererEnded, weak_this),
- base::Bind(&Pipeline::OnError, weak_this),
- base::Bind(&Pipeline::BufferingStateChanged, weak_this));
+ base::Bind(&Pipeline::OnError, weak_this));
}
void Pipeline::ReportMetadata() {
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 71c16e1..2fef5d0 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -6,6 +6,7 @@
#define MEDIA_BASE_PIPELINE_H_
#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
@@ -32,6 +33,7 @@
class TextRenderer;
class TextTrackConfig;
class TimeDeltaInterpolator;
+class VideoFrame;
// Metadata describing a pipeline once it has been initialized.
struct PipelineMetadata {
@@ -76,6 +78,9 @@
// "Stopped" state.
class MEDIA_EXPORT Pipeline : public DemuxerHost {
public:
+ // Used to paint VideoFrame.
+ typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
+
// Constructs a media pipeline that will execute on |task_runner|.
Pipeline(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
MediaLog* media_log);
@@ -94,6 +99,8 @@
// video in supported formats are known.
// |buffering_state_cb| will be executed whenever there are changes in the
// overall buffering state of the pipeline.
+ // |paint_cb| will be executed whenever there is a VideoFrame to be painted.
+ // It's safe to call this callback from any thread.
// |duration_change_cb| optional callback that will be executed whenever the
// presentation duration changes.
// |add_text_track_cb| will be executed whenever a text track is added.
@@ -105,6 +112,7 @@
const PipelineStatusCB& seek_cb,
const PipelineMetadataCB& metadata_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& duration_change_cb,
const AddTextTrackCB& add_text_track_cb);
@@ -342,6 +350,7 @@
PipelineStatusCB error_cb_;
PipelineMetadataCB metadata_cb_;
BufferingStateCB buffering_state_cb_;
+ PaintCB paint_cb_;
base::Closure duration_change_cb_;
AddTextTrackCB add_text_track_cb_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 5bb48ad..2f6cdf4 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -77,6 +77,7 @@
MOCK_METHOD1(OnError, void(PipelineStatus));
MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
+ MOCK_METHOD1(OnVideoFramePaint, void(const scoped_refptr<VideoFrame>&));
MOCK_METHOD0(OnDurationChange, void());
private:
@@ -165,9 +166,9 @@
// Sets up expectations to allow the video renderer to initialize.
void SetRendererExpectations() {
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
- .WillOnce(DoAll(SaveArg<3>(&ended_cb_),
- SaveArg<5>(&buffering_state_cb_),
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_),
+ SaveArg<5>(&ended_cb_),
RunCallback<1>()));
EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream()));
EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream()));
@@ -183,14 +184,15 @@
void StartPipeline() {
pipeline_->Start(
- demuxer_.get(),
- scoped_renderer_.Pass(),
+ demuxer_.get(), scoped_renderer_.Pass(),
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnBufferingStateChange,
base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnVideoFramePaint,
+ base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnDurationChange,
base::Unretained(&callbacks_)),
base::Bind(&PipelineTest::OnAddTextTrack, base::Unretained(this)));
@@ -847,22 +849,22 @@
if (state == kInitRenderer) {
if (stop_or_error == kStop) {
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
.WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
RunCallback<1>()));
ExpectPipelineStopAndDestroyPipeline();
} else {
status = PIPELINE_ERROR_INITIALIZATION_FAILED;
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
- .WillOnce(DoAll(RunCallback<4>(status), RunCallback<1>()));
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ .WillOnce(DoAll(RunCallback<6>(status), RunCallback<1>()));
}
EXPECT_CALL(*demuxer_, Stop());
return status;
}
- EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
- .WillOnce(DoAll(SaveArg<5>(&buffering_state_cb_),
+ EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_),
RunCallback<1>()));
EXPECT_CALL(callbacks_, OnMetadata(_));
diff --git a/media/base/renderer.h b/media/base/renderer.h
index 78ae043..d6cb74a 100644
--- a/media/base/renderer.h
+++ b/media/base/renderer.h
@@ -6,6 +6,7 @@
#define MEDIA_BASE_RENDERER_H_
#include "base/callback.h"
+#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "media/base/buffering_state.h"
#include "media/base/media_export.h"
@@ -13,11 +14,13 @@
namespace media {
-class MediaKeys;
class DemuxerStreamProvider;
+class MediaKeys;
+class VideoFrame;
class MEDIA_EXPORT Renderer {
public:
+ typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
typedef base::Callback<base::TimeDelta()> TimeDeltaCB;
Renderer();
@@ -32,15 +35,19 @@
//
// Permanent callbacks:
// - |statistics_cb|: Executed periodically with rendering statistics.
- // - |time_cb|: Executed whenever time has advanced through rendering.
+ // - |buffering_state_cb|: Executed when buffering state is changed.
+ // - |paint_cb|: Executed when there is a VideoFrame ready to paint. Can be
+ // ignored if the Renderer handles the painting by itself. Can
+ // be called from any thread.
// - |ended_cb|: Executed when rendering has reached the end of stream.
// - |error_cb|: Executed if any error was encountered during rendering.
virtual void Initialize(DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb) = 0;
+ const PipelineStatusCB& error_cb) = 0;
// The following functions must be called after Initialize().
diff --git a/media/base/video_renderer.h b/media/base/video_renderer.h
index fc544bc2..714a25a 100644
--- a/media/base/video_renderer.h
+++ b/media/base/video_renderer.h
@@ -16,9 +16,13 @@
class DemuxerStream;
class VideoDecoder;
+class VideoFrame;
class MEDIA_EXPORT VideoRenderer {
public:
+ // Used to paint VideoFrame.
+ typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
+
// Used to query the current time or duration of the media.
typedef base::Callback<base::TimeDelta()> TimeDeltaCB;
@@ -36,6 +40,9 @@
// |buffering_state_cb| is executed when video rendering has either run out of
// data or has enough data to continue playback.
//
+ // |paint_cb| is executed on the video frame timing thread whenever a new
+ // frame is available for painting. Can be called from any thread.
+ //
// |ended_cb| is executed when video rendering has reached the end of stream.
//
// |error_cb| is executed if an error was encountered.
@@ -46,6 +53,7 @@
const PipelineStatusCB& init_cb,
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const TimeDeltaCB& get_time_cb) = 0;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index d5a411f..0aaf1f0 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -875,7 +875,6 @@
media_task_runner_,
video_decoders.Pass(),
set_decryptor_ready_cb,
- base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
true,
media_log_));
@@ -932,6 +931,7 @@
BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged),
+ base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack));
}
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index bd026da..57a2858 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -568,6 +568,8 @@
base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnBufferingStateChanged,
base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTest::OnVideoFramePaint,
+ base::Unretained(this)),
base::Closure(),
base::Bind(&PipelineIntegrationTest::OnAddTextTrack,
base::Unretained(this)));
@@ -599,6 +601,8 @@
base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnBufferingStateChanged,
base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTest::OnVideoFramePaint,
+ base::Unretained(this)),
base::Closure(),
base::Bind(&PipelineIntegrationTest::OnAddTextTrack,
base::Unretained(this)));
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index dcd5065..7b861f5 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -116,8 +116,7 @@
.Times(AtMost(1));
CreateDemuxer(file_path);
pipeline_->Start(
- demuxer_.get(),
- CreateRenderer(NULL),
+ demuxer_.get(), CreateRenderer(NULL),
base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
QuitOnStatusCB(expected_status),
@@ -125,9 +124,10 @@
base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnBufferingStateChanged,
base::Unretained(this)),
- base::Closure(),
- base::Bind(&PipelineIntegrationTestBase::OnAddTextTrack,
- base::Unretained(this)));
+ base::Bind(&PipelineIntegrationTestBase::OnVideoFramePaint,
+ base::Unretained(this)),
+ base::Closure(), base::Bind(&PipelineIntegrationTestBase::OnAddTextTrack,
+ base::Unretained(this)));
message_loop_.Run();
return (pipeline_status_ == PIPELINE_OK);
}
@@ -164,6 +164,8 @@
base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnBufferingStateChanged,
base::Unretained(this)),
+ base::Bind(&PipelineIntegrationTestBase::OnVideoFramePaint,
+ base::Unretained(this)),
base::Closure(),
base::Bind(&PipelineIntegrationTestBase::OnAddTextTrack,
base::Unretained(this)));
@@ -261,8 +263,6 @@
base::Bind(&PipelineIntegrationTestBase::SetDecryptor,
base::Unretained(this),
decryptor),
- base::Bind(&PipelineIntegrationTestBase::OnVideoRendererPaint,
- base::Unretained(this)),
false,
new MediaLog()));
@@ -324,7 +324,7 @@
EXPECT_CALL(*this, DecryptorAttached(true));
}
-void PipelineIntegrationTestBase::OnVideoRendererPaint(
+void PipelineIntegrationTestBase::OnVideoFramePaint(
const scoped_refptr<VideoFrame>& frame) {
last_video_frame_format_ = frame->format();
if (!hashing_enabled_)
diff --git a/media/filters/pipeline_integration_test_base.h b/media/filters/pipeline_integration_test_base.h
index a0f25c3..3db6efa 100644
--- a/media/filters/pipeline_integration_test_base.h
+++ b/media/filters/pipeline_integration_test_base.h
@@ -136,7 +136,7 @@
void SetDecryptor(Decryptor* decryptor,
const DecryptorReadyCB& decryptor_ready_cb);
- void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame);
+ void OnVideoFramePaint(const scoped_refptr<VideoFrame>& frame);
MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
MOCK_METHOD1(OnBufferingStateChanged, void(BufferingState));
diff --git a/media/filters/renderer_impl.cc b/media/filters/renderer_impl.cc
index 6416a3d..12674d1 100644
--- a/media/filters/renderer_impl.cc
+++ b/media/filters/renderer_impl.cc
@@ -54,25 +54,28 @@
void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb) {
+ const PipelineStatusCB& error_cb) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_;
DCHECK(!init_cb.is_null());
DCHECK(!statistics_cb.is_null());
+ DCHECK(!buffering_state_cb.is_null());
+ DCHECK(!paint_cb.is_null());
DCHECK(!ended_cb.is_null());
DCHECK(!error_cb.is_null());
- DCHECK(!buffering_state_cb.is_null());
DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) ||
demuxer_stream_provider->GetStream(DemuxerStream::VIDEO));
demuxer_stream_provider_ = demuxer_stream_provider;
statistics_cb_ = statistics_cb;
+ buffering_state_cb_ = buffering_state_cb;
+ paint_cb_ = paint_cb;
ended_cb_ = ended_cb;
error_cb_ = error_cb;
- buffering_state_cb_ = buffering_state_cb;
init_cb_ = init_cb;
state_ = STATE_INITIALIZING;
@@ -244,6 +247,7 @@
base::Bind(&RendererImpl::OnBufferingStateChanged,
weak_this_,
&video_buffering_state_),
+ base::ResetAndReturn(&paint_cb_),
base::Bind(&RendererImpl::OnVideoRendererEnded, weak_this_),
base::Bind(&RendererImpl::OnError, weak_this_),
base::Bind(&RendererImpl::GetMediaTimeForSyncingVideo,
diff --git a/media/filters/renderer_impl.h b/media/filters/renderer_impl.h
index 67902d0..734113b8 100644
--- a/media/filters/renderer_impl.h
+++ b/media/filters/renderer_impl.h
@@ -45,9 +45,10 @@
void Initialize(DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb) override;
+ const PipelineStatusCB& error_cb) override;
void Flush(const base::Closure& flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(float playback_rate) override;
@@ -125,6 +126,7 @@
base::Closure ended_cb_;
PipelineStatusCB error_cb_;
BufferingStateCB buffering_state_cb_;
+ PaintCB paint_cb_;
// Temporary callback used for Initialize() and Flush().
base::Closure init_cb_;
diff --git a/media/filters/renderer_impl_unittest.cc b/media/filters/renderer_impl_unittest.cc
index 5db6205..8cd5675b 100644
--- a/media/filters/renderer_impl_unittest.cc
+++ b/media/filters/renderer_impl_unittest.cc
@@ -49,6 +49,7 @@
MOCK_METHOD1(OnError, void(PipelineStatus));
MOCK_METHOD1(OnUpdateStatistics, void(const PipelineStatistics&));
MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
+ MOCK_METHOD1(OnVideoFramePaint, void(const scoped_refptr<VideoFrame>&));
private:
DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
@@ -99,9 +100,9 @@
// Sets up expectations to allow the video renderer to initialize.
void SetVideoRendererInitializeExpectations(PipelineStatus status) {
EXPECT_CALL(*video_renderer_,
- Initialize(video_stream_.get(), _, _, _, _, _, _, _))
+ Initialize(video_stream_.get(), _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&video_buffering_state_cb_),
- SaveArg<5>(&video_ended_cb_),
+ SaveArg<6>(&video_ended_cb_),
RunCallback<2>(status)));
}
@@ -122,10 +123,12 @@
base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnUpdateStatistics,
base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnBufferingStateChange,
- base::Unretained(&callbacks_)));
+ base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnVideoFramePaint,
+ base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)));
base::RunLoop().RunUntilIdle();
}
diff --git a/media/filters/video_renderer_impl.cc b/media/filters/video_renderer_impl.cc
index 1bd3f270..6cd1607 100644
--- a/media/filters/video_renderer_impl.cc
+++ b/media/filters/video_renderer_impl.cc
@@ -23,7 +23,6 @@
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
ScopedVector<VideoDecoder> decoders,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const PaintCB& paint_cb,
bool drop_frames,
const scoped_refptr<MediaLog>& media_log)
: task_runner_(task_runner),
@@ -40,14 +39,12 @@
pending_read_(false),
drop_frames_(drop_frames),
buffering_state_(BUFFERING_HAVE_NOTHING),
- paint_cb_(paint_cb),
last_timestamp_(kNoTimestamp()),
last_painted_timestamp_(kNoTimestamp()),
frames_decoded_(0),
frames_dropped_(0),
is_shutting_down_(false),
weak_factory_(this) {
- DCHECK(!paint_cb_.is_null());
}
VideoRendererImpl::~VideoRendererImpl() {
@@ -111,6 +108,7 @@
const PipelineStatusCB& init_cb,
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const TimeDeltaCB& get_time_cb) {
@@ -121,6 +119,7 @@
DCHECK(!init_cb.is_null());
DCHECK(!statistics_cb.is_null());
DCHECK(!buffering_state_cb.is_null());
+ DCHECK(!paint_cb.is_null());
DCHECK(!ended_cb.is_null());
DCHECK(!get_time_cb.is_null());
DCHECK_EQ(kUninitialized, state_);
@@ -133,6 +132,7 @@
statistics_cb_ = statistics_cb;
buffering_state_cb_ = buffering_state_cb;
+ paint_cb_ = paint_cb,
ended_cb_ = ended_cb;
error_cb_ = error_cb;
get_time_cb_ = get_time_cb;
diff --git a/media/filters/video_renderer_impl.h b/media/filters/video_renderer_impl.h
index 557a884..f319c6e2 100644
--- a/media/filters/video_renderer_impl.h
+++ b/media/filters/video_renderer_impl.h
@@ -37,12 +37,8 @@
: public VideoRenderer,
public base::PlatformThread::Delegate {
public:
- typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
-
// |decoders| contains the VideoDecoders to use when initializing.
//
- // |paint_cb| is executed on the video frame timing thread whenever a new
- // frame is available for painting.
//
// Implementors should avoid doing any sort of heavy work in this method and
// instead post a task to a common/worker thread to handle rendering. Slowing
@@ -53,7 +49,6 @@
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
ScopedVector<VideoDecoder> decoders,
const SetDecryptorReadyCB& set_decryptor_ready_cb,
- const PaintCB& paint_cb,
bool drop_frames,
const scoped_refptr<MediaLog>& media_log);
~VideoRendererImpl() override;
@@ -64,6 +59,7 @@
const PipelineStatusCB& init_cb,
const StatisticsCB& statistics_cb,
const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb,
const TimeDeltaCB& get_time_cb) override;
diff --git a/media/filters/video_renderer_impl_unittest.cc b/media/filters/video_renderer_impl_unittest.cc
index 1a26f0c..feae22b 100644
--- a/media/filters/video_renderer_impl_unittest.cc
+++ b/media/filters/video_renderer_impl_unittest.cc
@@ -54,7 +54,6 @@
message_loop_.message_loop_proxy(),
decoders.Pass(),
media::SetDecryptorReadyCB(),
- base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)),
true,
new MediaLog()));
@@ -104,6 +103,7 @@
base::Unretained(this)),
base::Bind(&StrictMock<MockCB>::BufferingStateChange,
base::Unretained(&mock_cb_)),
+ base::Bind(&StrictMock<MockCB>::Display, base::Unretained(&mock_cb_)),
ended_event_.GetClosure(),
error_event_.GetPipelineStatusCB(),
base::Bind(&VideoRendererImplTest::GetTime, base::Unretained(this)));
diff --git a/media/mojo/services/media_renderer_apptest.cc b/media/mojo/services/media_renderer_apptest.cc
index 7c88ad87..60d3bd3b 100644
--- a/media/mojo/services/media_renderer_apptest.cc
+++ b/media/mojo/services/media_renderer_apptest.cc
@@ -150,8 +150,9 @@
PipelineStatus expected_error(PIPELINE_OK);
mojo_renderer_impl.Initialize(
stream_provider(), base::MessageLoop::current()->QuitClosure(),
- media::StatisticsCB(), base::Closure(),
- base::Bind(&ErrorCallback, &expected_error), media::BufferingStateCB());
+ media::StatisticsCB(), media::BufferingStateCB(),
+ media::Renderer::PaintCB(), base::Closure(),
+ base::Bind(&ErrorCallback, &expected_error));
base::MessageLoop::current()->Run();
// We expect an error during initialization because MojoRendererService
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc
index 9ed903f..f93bfe1 100644
--- a/media/mojo/services/mojo_renderer_impl.cc
+++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -35,13 +35,15 @@
// Connection to |remote_audio_renderer_| will error-out here.
}
+// TODO(xhwang): Support |paint_cb| if needed.
void MojoRendererImpl::Initialize(
DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& /* paint_cb */,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb) {
+ const PipelineStatusCB& error_cb) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(demuxer_stream_provider);
diff --git a/media/mojo/services/mojo_renderer_impl.h b/media/mojo/services/mojo_renderer_impl.h
index 24a319b..4b033d8 100644
--- a/media/mojo/services/mojo_renderer_impl.h
+++ b/media/mojo/services/mojo_renderer_impl.h
@@ -43,9 +43,10 @@
void Initialize(DemuxerStreamProvider* demuxer_stream_provider,
const base::Closure& init_cb,
const StatisticsCB& statistics_cb,
+ const BufferingStateCB& buffering_state_cb,
+ const PaintCB& paint_cb,
const base::Closure& ended_cb,
- const PipelineStatusCB& error_cb,
- const BufferingStateCB& buffering_state_cb) override;
+ const PipelineStatusCB& error_cb) override;
void Flush(const base::Closure& flush_cb) override;
void StartPlayingFrom(base::TimeDelta time) override;
void SetPlaybackRate(float playback_rate) override;
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index 60266c4..25a812b 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -89,7 +89,6 @@
task_runner,
base::Bind(&LogMediaSourceError, media_log)).Pass(),
SetDecryptorReadyCB(),
- base::Bind(&PaintNothing),
true,
media_log));
@@ -149,9 +148,10 @@
base::Bind(
&MojoRendererService::OnRendererInitializeDone, weak_this_, callback),
base::Bind(&MojoRendererService::OnUpdateStatistics, weak_this_),
+ base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_),
+ base::Bind(&PaintNothing),
base::Bind(&MojoRendererService::OnRendererEnded, weak_this_),
- base::Bind(&MojoRendererService::OnError, weak_this_),
- base::Bind(&MojoRendererService::OnBufferingStateChanged, weak_this_));
+ base::Bind(&MojoRendererService::OnError, weak_this_));
}
void MojoRendererService::OnRendererInitializeDone(
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index ded465c..9dfe601c 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -120,7 +120,6 @@
new media::VideoRendererImpl(task_runner,
video_decoders.Pass(),
media::SetDecryptorReadyCB(),
- paint_cb,
true,
new media::MediaLog()));
@@ -156,6 +155,7 @@
base::Bind(&SaveStatusAndSignal, &event, &status),
base::Bind(&OnMetadata),
base::Bind(&OnBufferingStateChanged),
+ paint_cb,
base::Bind(&DoNothing),
base::Bind(&OnAddTextTrack));