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" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 void UseOutputBitstreamBufferId(int32 bitstream_buffer_id); | 68 void UseOutputBitstreamBufferId(int32 bitstream_buffer_id); |
69 | 69 |
70 // Request encoding parameter change for the underlying encoder. | 70 // Request encoding parameter change for the underlying encoder. |
71 void RequestEncodingParametersChange(uint32 bitrate, uint32 framerate); | 71 void RequestEncodingParametersChange(uint32 bitrate, uint32 framerate); |
72 | 72 |
73 // Destroy this Impl's encoder. The destructor is not explicitly called, as | 73 // Destroy this Impl's encoder. The destructor is not explicitly called, as |
74 // Impl is a base::RefCountedThreadSafe. | 74 // Impl is a base::RefCountedThreadSafe. |
75 void Destroy(); | 75 void Destroy(); |
76 | 76 |
77 // media::VideoEncodeAccelerator::Client implementation. | 77 // media::VideoEncodeAccelerator::Client implementation. |
78 virtual void NotifyInitializeDone() OVERRIDE; | |
79 virtual void RequireBitstreamBuffers(unsigned int input_count, | 78 virtual void RequireBitstreamBuffers(unsigned int input_count, |
80 const gfx::Size& input_coded_size, | 79 const gfx::Size& input_coded_size, |
81 size_t output_buffer_size) OVERRIDE; | 80 size_t output_buffer_size) OVERRIDE; |
82 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, | 81 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, |
83 size_t payload_size, | 82 size_t payload_size, |
84 bool key_frame) OVERRIDE; | 83 bool key_frame) OVERRIDE; |
85 virtual void NotifyError(media::VideoEncodeAccelerator::Error error) OVERRIDE; | 84 virtual void NotifyError(media::VideoEncodeAccelerator::Error error) OVERRIDE; |
86 | 85 |
87 private: | 86 private: |
88 friend class base::RefCountedThreadSafe<Impl>; | 87 friend class base::RefCountedThreadSafe<Impl>; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); | 184 NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); |
186 return; | 185 return; |
187 } | 186 } |
188 | 187 |
189 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator().Pass(); | 188 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator().Pass(); |
190 if (!video_encoder_) { | 189 if (!video_encoder_) { |
191 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); | 190 NOTIFY_ERROR(media::VideoEncodeAccelerator::kPlatformFailureError); |
192 return; | 191 return; |
193 } | 192 } |
194 input_visible_size_ = input_visible_size; | 193 input_visible_size_ = input_visible_size; |
195 video_encoder_->Initialize(media::VideoFrame::I420, | 194 if (!video_encoder_->Initialize(media::VideoFrame::I420, |
196 input_visible_size_, | 195 input_visible_size_, |
197 profile, | 196 profile, |
198 bitrate * 1000, | 197 bitrate * 1000, |
199 this); | 198 this)) { |
199 NOTIFY_ERROR(media::VideoEncodeAccelerator::kInvalidArgumentError); | |
200 return; | |
201 } | |
200 } | 202 } |
201 | 203 |
202 void RTCVideoEncoder::Impl::Enqueue(const webrtc::I420VideoFrame* input_frame, | 204 void RTCVideoEncoder::Impl::Enqueue(const webrtc::I420VideoFrame* input_frame, |
203 bool force_keyframe, | 205 bool force_keyframe, |
204 base::WaitableEvent* async_waiter, | 206 base::WaitableEvent* async_waiter, |
205 int32_t* async_retval) { | 207 int32_t* async_retval) { |
206 DVLOG(3) << "Impl::Enqueue()"; | 208 DVLOG(3) << "Impl::Enqueue()"; |
207 DCHECK(thread_checker_.CalledOnValidThread()); | 209 DCHECK(thread_checker_.CalledOnValidThread()); |
208 DCHECK(!input_next_frame_); | 210 DCHECK(!input_next_frame_); |
209 | 211 |
210 RegisterAsyncWaiter(async_waiter, async_retval); | 212 RegisterAsyncWaiter(async_waiter, async_retval); |
211 // If there are no free input and output buffers, drop the frame to avoid a | 213 // If there are no free input and output buffers, drop the frame to avoid a |
Ami GONE FROM CHROMIUM
2014/03/18 23:53:19
Didn't a brilliant (and handsome!) man once tell y
sheu
2014/03/19 20:38:24
:-(
Forgot about my Monday morning sync/rebase.
| |
212 // deadlock. If there is a free input buffer, EncodeOneFrame will run and | 214 // deadlock. If there is a free input buffer, EncodeOneFrame will run and |
213 // unblock Encode(). If there are no free input buffers but there is a free | 215 // unblock Encode(). If there are no free input buffers but there is a free |
214 // output buffer, EncodeFrameFinished will be called later to unblock | 216 // output buffer, EncodeFrameFinished will be called later to unblock |
215 // Encode(). | 217 // Encode(). |
216 // | 218 // |
217 // The caller of Encode() holds a webrtc lock. The deadlock happens when: | 219 // The caller of Encode() holds a webrtc lock. The deadlock happens when: |
218 // (1) Encode() is waiting for the frame to be encoded in EncodeOneFrame(). | 220 // (1) Encode() is waiting for the frame to be encoded in EncodeOneFrame(). |
219 // (2) There are no free input buffers and they cannot be freed because | 221 // (2) There are no free input buffers and they cannot be freed because |
220 // the encoder has no output buffers. | 222 // the encoder has no output buffers. |
221 // (3) Output buffers cannot be freed because ReturnEncodedImage is queued | 223 // (3) Output buffers cannot be freed because ReturnEncodedImage is queued |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 video_encoder_->RequestEncodingParametersChange(bitrate * 1000, framerate); | 270 video_encoder_->RequestEncodingParametersChange(bitrate * 1000, framerate); |
269 } | 271 } |
270 | 272 |
271 void RTCVideoEncoder::Impl::Destroy() { | 273 void RTCVideoEncoder::Impl::Destroy() { |
272 DVLOG(3) << "Impl::Destroy()"; | 274 DVLOG(3) << "Impl::Destroy()"; |
273 DCHECK(thread_checker_.CalledOnValidThread()); | 275 DCHECK(thread_checker_.CalledOnValidThread()); |
274 if (video_encoder_) | 276 if (video_encoder_) |
275 video_encoder_.release()->Destroy(); | 277 video_encoder_.release()->Destroy(); |
276 } | 278 } |
277 | 279 |
278 void RTCVideoEncoder::Impl::NotifyInitializeDone() { | |
279 DVLOG(3) << "Impl::NotifyInitializeDone()"; | |
280 DCHECK(thread_checker_.CalledOnValidThread()); | |
281 } | |
282 | |
283 void RTCVideoEncoder::Impl::RequireBitstreamBuffers( | 280 void RTCVideoEncoder::Impl::RequireBitstreamBuffers( |
284 unsigned int input_count, | 281 unsigned int input_count, |
285 const gfx::Size& input_coded_size, | 282 const gfx::Size& input_coded_size, |
286 size_t output_buffer_size) { | 283 size_t output_buffer_size) { |
287 DVLOG(3) << "Impl::RequireBitstreamBuffers(): input_count=" << input_count | 284 DVLOG(3) << "Impl::RequireBitstreamBuffers(): input_count=" << input_count |
288 << ", input_coded_size=" << input_coded_size.ToString() | 285 << ", input_coded_size=" << input_coded_size.ToString() |
289 << ", output_buffer_size=" << output_buffer_size; | 286 << ", output_buffer_size=" << output_buffer_size; |
290 DCHECK(thread_checker_.CalledOnValidThread()); | 287 DCHECK(thread_checker_.CalledOnValidThread()); |
291 | 288 |
292 if (!video_encoder_) | 289 if (!video_encoder_) |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
690 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", | 687 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", |
691 init_retval == WEBRTC_VIDEO_CODEC_OK); | 688 init_retval == WEBRTC_VIDEO_CODEC_OK); |
692 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { | 689 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { |
693 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", | 690 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", |
694 video_codec_profile_, | 691 video_codec_profile_, |
695 media::VIDEO_CODEC_PROFILE_MAX + 1); | 692 media::VIDEO_CODEC_PROFILE_MAX + 1); |
696 } | 693 } |
697 } | 694 } |
698 | 695 |
699 } // namespace content | 696 } // namespace content |
OLD | NEW |