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