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/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)));