| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/rtc_video_encoder.h" | 5 #include "content/renderer/media/rtc_video_encoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
| 14 #include "content/renderer/media/renderer_gpu_video_accelerator_factories.h" |
| 14 #include "media/base/bitstream_buffer.h" | 15 #include "media/base/bitstream_buffer.h" |
| 15 #include "media/base/video_frame.h" | 16 #include "media/base/video_frame.h" |
| 16 #include "media/base/video_util.h" | 17 #include "media/base/video_util.h" |
| 17 #include "media/filters/gpu_video_accelerator_factories.h" | 18 #include "media/filters/gpu_video_accelerator_factories.h" |
| 18 #include "media/video/video_encode_accelerator.h" | 19 #include "media/video/video_encode_accelerator.h" |
| 19 #include "third_party/webrtc/system_wrappers/interface/tick_util.h" | 20 #include "third_party/webrtc/system_wrappers/interface/tick_util.h" |
| 20 | 21 |
| 21 #define NOTIFY_ERROR(x) \ | 22 #define NOTIFY_ERROR(x) \ |
| 22 do { \ | 23 do { \ |
| 23 DLOG(ERROR) << "calling NotifyError(): " << x; \ | 24 DLOG(ERROR) << "calling NotifyError(): " << x; \ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 34 // | 35 // |
| 35 // This class separates state related to the thread that RTCVideoEncoder | 36 // This class separates state related to the thread that RTCVideoEncoder |
| 36 // operates on (presently the libjingle worker thread) from the thread that | 37 // operates on (presently the libjingle worker thread) from the thread that |
| 37 // |gpu_factories_| provides for accelerator operations (presently the media | 38 // |gpu_factories_| provides for accelerator operations (presently the media |
| 38 // thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while | 39 // thread). The RTCVideoEncoder class can be deleted directly by WebRTC, while |
| 39 // RTCVideoEncoder::Impl stays around long enough to properly shut down the VEA. | 40 // RTCVideoEncoder::Impl stays around long enough to properly shut down the VEA. |
| 40 class RTCVideoEncoder::Impl | 41 class RTCVideoEncoder::Impl |
| 41 : public media::VideoEncodeAccelerator::Client, | 42 : public media::VideoEncodeAccelerator::Client, |
| 42 public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> { | 43 public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> { |
| 43 public: | 44 public: |
| 44 Impl(const base::WeakPtr<RTCVideoEncoder>& weak_encoder, | 45 Impl( |
| 45 const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories); | 46 const base::WeakPtr<RTCVideoEncoder>& weak_encoder, |
| 47 const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories); |
| 46 | 48 |
| 47 // Create the VEA and call Initialize() on it. Called once per instantiation, | 49 // Create the VEA and call Initialize() on it. Called once per instantiation, |
| 48 // and then the instance is bound forevermore to whichever thread made the | 50 // and then the instance is bound forevermore to whichever thread made the |
| 49 // call. | 51 // call. |
| 50 // RTCVideoEncoder expects to be able to call this function synchronously from | 52 // RTCVideoEncoder expects to be able to call this function synchronously from |
| 51 // its own thread, hence the |async_waiter| and |async_retval| arguments. | 53 // its own thread, hence the |async_waiter| and |async_retval| arguments. |
| 52 void CreateAndInitializeVEA(const gfx::Size& input_visible_size, | 54 void CreateAndInitializeVEA(const gfx::Size& input_visible_size, |
| 53 uint32 bitrate, | 55 uint32 bitrate, |
| 54 media::VideoCodecProfile profile, | 56 media::VideoCodecProfile profile, |
| 55 base::WaitableEvent* async_waiter, | 57 base::WaitableEvent* async_waiter, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 base::ThreadChecker thread_checker_; | 112 base::ThreadChecker thread_checker_; |
| 111 | 113 |
| 112 // Weak pointer to the parent RTCVideoEncoder, for posting back VEA::Client | 114 // Weak pointer to the parent RTCVideoEncoder, for posting back VEA::Client |
| 113 // notifications. | 115 // notifications. |
| 114 const base::WeakPtr<RTCVideoEncoder> weak_encoder_; | 116 const base::WeakPtr<RTCVideoEncoder> weak_encoder_; |
| 115 | 117 |
| 116 // The message loop on which to post callbacks to |weak_encoder_|. | 118 // The message loop on which to post callbacks to |weak_encoder_|. |
| 117 const scoped_refptr<base::MessageLoopProxy> encoder_message_loop_proxy_; | 119 const scoped_refptr<base::MessageLoopProxy> encoder_message_loop_proxy_; |
| 118 | 120 |
| 119 // Factory for creating VEAs, shared memory buffers, etc. | 121 // Factory for creating VEAs, shared memory buffers, etc. |
| 120 const scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories_; | 122 const scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories_; |
| 121 | 123 |
| 122 // webrtc::VideoEncoder expects InitEncode() and Encode() to be synchronous. | 124 // webrtc::VideoEncoder expects InitEncode() and Encode() to be synchronous. |
| 123 // Do this by waiting on the |async_waiter_| and returning the return value in | 125 // Do this by waiting on the |async_waiter_| and returning the return value in |
| 124 // |async_retval_| when initialization completes, encoding completes, or | 126 // |async_retval_| when initialization completes, encoding completes, or |
| 125 // an error occurs. | 127 // an error occurs. |
| 126 base::WaitableEvent* async_waiter_; | 128 base::WaitableEvent* async_waiter_; |
| 127 int32_t* async_retval_; | 129 int32_t* async_retval_; |
| 128 | 130 |
| 129 // The underlying VEA to perform encoding on. | 131 // The underlying VEA to perform encoding on. |
| 130 scoped_ptr<media::VideoEncodeAccelerator> video_encoder_; | 132 scoped_ptr<media::VideoEncodeAccelerator> video_encoder_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 146 | 148 |
| 147 // Input buffers ready to be filled with input from Encode(). As a LIFO since | 149 // Input buffers ready to be filled with input from Encode(). As a LIFO since |
| 148 // we don't care about ordering. | 150 // we don't care about ordering. |
| 149 std::vector<int> input_buffers_free_; | 151 std::vector<int> input_buffers_free_; |
| 150 | 152 |
| 151 DISALLOW_COPY_AND_ASSIGN(Impl); | 153 DISALLOW_COPY_AND_ASSIGN(Impl); |
| 152 }; | 154 }; |
| 153 | 155 |
| 154 RTCVideoEncoder::Impl::Impl( | 156 RTCVideoEncoder::Impl::Impl( |
| 155 const base::WeakPtr<RTCVideoEncoder>& weak_encoder, | 157 const base::WeakPtr<RTCVideoEncoder>& weak_encoder, |
| 156 const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories) | 158 const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) |
| 157 : weak_encoder_(weak_encoder), | 159 : weak_encoder_(weak_encoder), |
| 158 encoder_message_loop_proxy_(base::MessageLoopProxy::current()), | 160 encoder_message_loop_proxy_(base::MessageLoopProxy::current()), |
| 159 gpu_factories_(gpu_factories), | 161 gpu_factories_(gpu_factories), |
| 160 async_waiter_(NULL), | 162 async_waiter_(NULL), |
| 161 async_retval_(NULL), | 163 async_retval_(NULL), |
| 162 input_next_frame_(NULL), | 164 input_next_frame_(NULL), |
| 163 input_next_frame_keyframe_(false) { | 165 input_next_frame_keyframe_(false) { |
| 164 thread_checker_.DetachFromThread(); | 166 thread_checker_.DetachFromThread(); |
| 165 } | 167 } |
| 166 | 168 |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 | 464 |
| 463 //////////////////////////////////////////////////////////////////////////////// | 465 //////////////////////////////////////////////////////////////////////////////// |
| 464 // | 466 // |
| 465 // RTCVideoEncoder | 467 // RTCVideoEncoder |
| 466 // | 468 // |
| 467 //////////////////////////////////////////////////////////////////////////////// | 469 //////////////////////////////////////////////////////////////////////////////// |
| 468 | 470 |
| 469 RTCVideoEncoder::RTCVideoEncoder( | 471 RTCVideoEncoder::RTCVideoEncoder( |
| 470 webrtc::VideoCodecType type, | 472 webrtc::VideoCodecType type, |
| 471 media::VideoCodecProfile profile, | 473 media::VideoCodecProfile profile, |
| 472 const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories) | 474 const scoped_refptr<RendererGpuVideoAcceleratorFactories>& gpu_factories) |
| 473 : video_codec_type_(type), | 475 : video_codec_type_(type), |
| 474 video_codec_profile_(profile), | 476 video_codec_profile_(profile), |
| 475 gpu_factories_(gpu_factories), | 477 gpu_factories_(gpu_factories), |
| 476 encoded_image_callback_(NULL), | 478 encoded_image_callback_(NULL), |
| 477 impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED), | 479 impl_status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED), |
| 478 weak_this_factory_(this) { | 480 weak_this_factory_(this) { |
| 479 DVLOG(1) << "RTCVideoEncoder(): profile=" << profile; | 481 DVLOG(1) << "RTCVideoEncoder(): profile=" << profile; |
| 480 } | 482 } |
| 481 | 483 |
| 482 RTCVideoEncoder::~RTCVideoEncoder() { | 484 RTCVideoEncoder::~RTCVideoEncoder() { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 556 } |
| 555 | 557 |
| 556 encoded_image_callback_ = callback; | 558 encoded_image_callback_ = callback; |
| 557 return WEBRTC_VIDEO_CODEC_OK; | 559 return WEBRTC_VIDEO_CODEC_OK; |
| 558 } | 560 } |
| 559 | 561 |
| 560 int32_t RTCVideoEncoder::Release() { | 562 int32_t RTCVideoEncoder::Release() { |
| 561 DVLOG(3) << "Release()"; | 563 DVLOG(3) << "Release()"; |
| 562 DCHECK(thread_checker_.CalledOnValidThread()); | 564 DCHECK(thread_checker_.CalledOnValidThread()); |
| 563 | 565 |
| 566 // Reset the gpu_factory_, in case we reuse this encoder. |
| 567 gpu_factories_->Abort(); |
| 568 gpu_factories_ = gpu_factories_->Clone(); |
| 564 if (impl_) { | 569 if (impl_) { |
| 565 gpu_factories_->GetTaskRunner()->PostTask( | 570 gpu_factories_->GetTaskRunner()->PostTask( |
| 566 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); | 571 FROM_HERE, base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_)); |
| 567 impl_ = NULL; | 572 impl_ = NULL; |
| 568 weak_this_factory_.InvalidateWeakPtrs(); | 573 weak_this_factory_.InvalidateWeakPtrs(); |
| 569 impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 574 impl_status_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 570 } | 575 } |
| 571 return WEBRTC_VIDEO_CODEC_OK; | 576 return WEBRTC_VIDEO_CODEC_OK; |
| 572 } | 577 } |
| 573 | 578 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", | 658 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", |
| 654 init_retval == WEBRTC_VIDEO_CODEC_OK); | 659 init_retval == WEBRTC_VIDEO_CODEC_OK); |
| 655 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { | 660 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { |
| 656 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", | 661 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", |
| 657 video_codec_profile_, | 662 video_codec_profile_, |
| 658 media::VIDEO_CODEC_PROFILE_MAX); | 663 media::VIDEO_CODEC_PROFILE_MAX); |
| 659 } | 664 } |
| 660 } | 665 } |
| 661 | 666 |
| 662 } // namespace content | 667 } // namespace content |
| OLD | NEW |