Chromium Code Reviews| 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 |