| 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/gpu/rtc_video_decoder.h" | 5 #include "content/renderer/media/gpu/rtc_video_decoder.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 gfx::Size prev_frame_size = frame_size_; | 229 gfx::Size prev_frame_size = frame_size_; |
| 230 frame_size_ = new_frame_size; | 230 frame_size_ = new_frame_size; |
| 231 if (!kVDACanHandleMidstreamResize && !prev_frame_size.IsEmpty() && | 231 if (!kVDACanHandleMidstreamResize && !prev_frame_size.IsEmpty() && |
| 232 prev_frame_size != frame_size_) { | 232 prev_frame_size != frame_size_) { |
| 233 need_to_reset_for_midstream_resize = true; | 233 need_to_reset_for_midstream_resize = true; |
| 234 } | 234 } |
| 235 } else if (IsFirstBufferAfterReset(next_bitstream_buffer_id_, | 235 } else if (IsFirstBufferAfterReset(next_bitstream_buffer_id_, |
| 236 reset_bitstream_buffer_id_)) { | 236 reset_bitstream_buffer_id_)) { |
| 237 // TODO(wuchengli): VDA should handle it. Remove this when | 237 // TODO(wuchengli): VDA should handle it. Remove this when |
| 238 // http://crosbug.com/p/21913 is fixed. | 238 // http://crosbug.com/p/21913 is fixed. |
| 239 |
| 240 // If we're are in an error condition, increase the counter. |
| 241 vda_error_counter_ += vda_error_counter_ ? 1 : 0; |
| 242 |
| 239 DVLOG(1) << "The first frame should be a key frame. Drop this."; | 243 DVLOG(1) << "The first frame should be a key frame. Drop this."; |
| 240 return WEBRTC_VIDEO_CODEC_ERROR; | 244 return WEBRTC_VIDEO_CODEC_ERROR; |
| 241 } | 245 } |
| 242 | 246 |
| 243 // Create buffer metadata. | 247 // Create buffer metadata. |
| 244 BufferData buffer_data(next_bitstream_buffer_id_, | 248 BufferData buffer_data(next_bitstream_buffer_id_, |
| 245 inputImage._timeStamp, | 249 inputImage._timeStamp, |
| 246 inputImage._length, | 250 inputImage._length, |
| 247 gfx::Rect(frame_size_)); | 251 gfx::Rect(frame_size_)); |
| 248 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. | 252 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 262 // Better to drop any pending buffers and start afresh to catch up faster. | 266 // Better to drop any pending buffers and start afresh to catch up faster. |
| 263 DVLOG(1) << "Exceeded maximum pending buffer count, dropping"; | 267 DVLOG(1) << "Exceeded maximum pending buffer count, dropping"; |
| 264 ClearPendingBuffers(); | 268 ClearPendingBuffers(); |
| 265 return WEBRTC_VIDEO_CODEC_ERROR; | 269 return WEBRTC_VIDEO_CODEC_ERROR; |
| 266 } | 270 } |
| 267 | 271 |
| 268 if (need_to_reset_for_midstream_resize) { | 272 if (need_to_reset_for_midstream_resize) { |
| 269 base::AutoUnlock auto_unlock(lock_); | 273 base::AutoUnlock auto_unlock(lock_); |
| 270 Release(); | 274 Release(); |
| 271 } | 275 } |
| 272 | |
| 273 TryResetVDAErrorCounter_Locked(); | |
| 274 return WEBRTC_VIDEO_CODEC_OK; | 276 return WEBRTC_VIDEO_CODEC_OK; |
| 275 } | 277 } |
| 276 | 278 |
| 277 SaveToDecodeBuffers_Locked(inputImage, std::move(shm_buffer), buffer_data); | 279 SaveToDecodeBuffers_Locked(inputImage, std::move(shm_buffer), buffer_data); |
| 278 factories_->GetTaskRunner()->PostTask( | 280 factories_->GetTaskRunner()->PostTask( |
| 279 FROM_HERE, | 281 FROM_HERE, |
| 280 base::Bind(&RTCVideoDecoder::RequestBufferDecode, | 282 base::Bind(&RTCVideoDecoder::RequestBufferDecode, |
| 281 weak_factory_.GetWeakPtr())); | 283 weak_factory_.GetWeakPtr())); |
| 282 TryResetVDAErrorCounter_Locked(); | |
| 283 return WEBRTC_VIDEO_CODEC_OK; | 284 return WEBRTC_VIDEO_CODEC_OK; |
| 284 } | 285 } |
| 285 | 286 |
| 286 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback( | 287 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback( |
| 287 webrtc::DecodedImageCallback* callback) { | 288 webrtc::DecodedImageCallback* callback) { |
| 288 DVLOG(2) << "RegisterDecodeCompleteCallback"; | 289 DVLOG(2) << "RegisterDecodeCompleteCallback"; |
| 289 DCHECK(callback); | 290 DCHECK(callback); |
| 290 base::AutoLock auto_lock(lock_); | 291 base::AutoLock auto_lock(lock_); |
| 291 decode_complete_callback_ = callback; | 292 decode_complete_callback_ = callback; |
| 292 return WEBRTC_VIDEO_CODEC_OK; | 293 return WEBRTC_VIDEO_CODEC_OK; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 webrtc::kVideoRotation_0); | 437 webrtc::kVideoRotation_0); |
| 437 | 438 |
| 438 // Invoke decode callback. WebRTC expects no callback after Release. | 439 // Invoke decode callback. WebRTC expects no callback after Release. |
| 439 { | 440 { |
| 440 base::AutoLock auto_lock(lock_); | 441 base::AutoLock auto_lock(lock_); |
| 441 DCHECK(decode_complete_callback_); | 442 DCHECK(decode_complete_callback_); |
| 442 if (IsBufferAfterReset(picture.bitstream_buffer_id(), | 443 if (IsBufferAfterReset(picture.bitstream_buffer_id(), |
| 443 reset_bitstream_buffer_id_)) { | 444 reset_bitstream_buffer_id_)) { |
| 444 decode_complete_callback_->Decoded(decoded_image); | 445 decode_complete_callback_->Decoded(decoded_image); |
| 445 } | 446 } |
| 447 // Reset error counter as we successfully decoded a frame. |
| 448 vda_error_counter_ = 0; |
| 446 } | 449 } |
| 447 } | 450 } |
| 448 | 451 |
| 449 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( | 452 scoped_refptr<media::VideoFrame> RTCVideoDecoder::CreateVideoFrame( |
| 450 const media::Picture& picture, | 453 const media::Picture& picture, |
| 451 const media::PictureBuffer& pb, | 454 const media::PictureBuffer& pb, |
| 452 uint32_t timestamp, | 455 uint32_t timestamp, |
| 453 const gfx::Rect& visible_rect, | 456 const gfx::Rect& visible_rect, |
| 454 media::VideoPixelFormat pixel_format) { | 457 media::VideoPixelFormat pixel_format) { |
| 455 DCHECK(decoder_texture_target_); | 458 DCHECK(decoder_texture_target_); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 885 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 883 } | 886 } |
| 884 | 887 |
| 885 void RTCVideoDecoder::ClearPendingBuffers() { | 888 void RTCVideoDecoder::ClearPendingBuffers() { |
| 886 // Delete WebRTC input buffers. | 889 // Delete WebRTC input buffers. |
| 887 for (const auto& pending_buffer : pending_buffers_) | 890 for (const auto& pending_buffer : pending_buffers_) |
| 888 delete[] pending_buffer.first._buffer; | 891 delete[] pending_buffer.first._buffer; |
| 889 pending_buffers_.clear(); | 892 pending_buffers_.clear(); |
| 890 } | 893 } |
| 891 | 894 |
| 892 void RTCVideoDecoder::TryResetVDAErrorCounter_Locked() { | |
| 893 lock_.AssertAcquired(); | |
| 894 | |
| 895 if (vda_error_counter_ == 0) | |
| 896 return; | |
| 897 vda_error_counter_ = 0; | |
| 898 } | |
| 899 | |
| 900 } // namespace content | 895 } // namespace content |
| OLD | NEW |