[go: nahoru, domu]

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