| 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_decoder.h" | 5 #include "content/renderer/media/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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 // Since we are returning ERROR, WebRTC will not be interested in the | 228 // Since we are returning ERROR, WebRTC will not be interested in the |
| 229 // remaining buffers, and will provide us with a new keyframe instead. | 229 // remaining buffers, and will provide us with a new keyframe instead. |
| 230 // Better to drop any pending buffers and start afresh to catch up faster. | 230 // Better to drop any pending buffers and start afresh to catch up faster. |
| 231 DVLOG(1) << "Exceeded maximum pending buffer count, dropping"; | 231 DVLOG(1) << "Exceeded maximum pending buffer count, dropping"; |
| 232 ClearPendingBuffers(); | 232 ClearPendingBuffers(); |
| 233 return WEBRTC_VIDEO_CODEC_ERROR; | 233 return WEBRTC_VIDEO_CODEC_ERROR; |
| 234 } | 234 } |
| 235 | 235 |
| 236 if (need_to_reset_for_midstream_resize) { | 236 if (need_to_reset_for_midstream_resize) { |
| 237 base::AutoUnlock auto_unlock(lock_); | 237 base::AutoUnlock auto_unlock(lock_); |
| 238 Reset(); | 238 Release(); |
| 239 } | 239 } |
| 240 | 240 |
| 241 return WEBRTC_VIDEO_CODEC_OK; | 241 return WEBRTC_VIDEO_CODEC_OK; |
| 242 } | 242 } |
| 243 | 243 |
| 244 SaveToDecodeBuffers_Locked(inputImage, std::move(shm_buffer), buffer_data); | 244 SaveToDecodeBuffers_Locked(inputImage, std::move(shm_buffer), buffer_data); |
| 245 factories_->GetTaskRunner()->PostTask( | 245 factories_->GetTaskRunner()->PostTask( |
| 246 FROM_HERE, | 246 FROM_HERE, |
| 247 base::Bind(&RTCVideoDecoder::RequestBufferDecode, | 247 base::Bind(&RTCVideoDecoder::RequestBufferDecode, |
| 248 weak_factory_.GetWeakPtr())); | 248 weak_factory_.GetWeakPtr())); |
| 249 return WEBRTC_VIDEO_CODEC_OK; | 249 return WEBRTC_VIDEO_CODEC_OK; |
| 250 } | 250 } |
| 251 | 251 |
| 252 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback( | 252 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback( |
| 253 webrtc::DecodedImageCallback* callback) { | 253 webrtc::DecodedImageCallback* callback) { |
| 254 DVLOG(2) << "RegisterDecodeCompleteCallback"; | 254 DVLOG(2) << "RegisterDecodeCompleteCallback"; |
| 255 DCHECK(callback); | 255 DCHECK(callback); |
| 256 base::AutoLock auto_lock(lock_); | 256 base::AutoLock auto_lock(lock_); |
| 257 decode_complete_callback_ = callback; | 257 decode_complete_callback_ = callback; |
| 258 return WEBRTC_VIDEO_CODEC_OK; | 258 return WEBRTC_VIDEO_CODEC_OK; |
| 259 } | 259 } |
| 260 | 260 |
| 261 int32_t RTCVideoDecoder::Release() { | 261 int32_t RTCVideoDecoder::Release() { |
| 262 DVLOG(2) << "Release"; | 262 DVLOG(2) << "Release"; |
| 263 // Do not destroy VDA because WebRTC can call InitDecode and start decoding | 263 // Do not destroy VDA because WebRTC can call InitDecode and start decoding |
| 264 // again. | 264 // again. |
| 265 return Reset(); | |
| 266 } | |
| 267 | |
| 268 int32_t RTCVideoDecoder::Reset() { | |
| 269 DVLOG(2) << "Reset"; | |
| 270 base::AutoLock auto_lock(lock_); | 265 base::AutoLock auto_lock(lock_); |
| 271 if (state_ == UNINITIALIZED) { | 266 if (state_ == UNINITIALIZED) { |
| 272 LOG(ERROR) << "Decoder not initialized."; | 267 LOG(ERROR) << "Decoder not initialized."; |
| 273 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 268 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 274 } | 269 } |
| 275 if (next_bitstream_buffer_id_ != 0) | 270 if (next_bitstream_buffer_id_ != 0) |
| 276 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1; | 271 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1; |
| 277 else | 272 else |
| 278 reset_bitstream_buffer_id_ = ID_LAST; | 273 reset_bitstream_buffer_id_ = ID_LAST; |
| 279 // If VDA is already resetting, no need to request the reset again. | 274 // If VDA is already resetting, no need to request the reset again. |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 picture_buffers_at_display_.insert(std::make_pair( | 375 picture_buffers_at_display_.insert(std::make_pair( |
| 381 picture.picture_buffer_id(), | 376 picture.picture_buffer_id(), |
| 382 pb.texture_id())).second; | 377 pb.texture_id())).second; |
| 383 DCHECK(inserted); | 378 DCHECK(inserted); |
| 384 | 379 |
| 385 // Create a WebRTC video frame. | 380 // Create a WebRTC video frame. |
| 386 webrtc::VideoFrame decoded_image( | 381 webrtc::VideoFrame decoded_image( |
| 387 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), timestamp, 0, | 382 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame), timestamp, 0, |
| 388 webrtc::kVideoRotation_0); | 383 webrtc::kVideoRotation_0); |
| 389 | 384 |
| 390 // Invoke decode callback. WebRTC expects no callback after Reset or Release. | 385 // Invoke decode callback. WebRTC expects no callback after Release. |
| 391 { | 386 { |
| 392 base::AutoLock auto_lock(lock_); | 387 base::AutoLock auto_lock(lock_); |
| 393 DCHECK(decode_complete_callback_); | 388 DCHECK(decode_complete_callback_); |
| 394 if (IsBufferAfterReset(picture.bitstream_buffer_id(), | 389 if (IsBufferAfterReset(picture.bitstream_buffer_id(), |
| 395 reset_bitstream_buffer_id_)) { | 390 reset_bitstream_buffer_id_)) { |
| 396 decode_complete_callback_->Decoded(decoded_image); | 391 decode_complete_callback_->Decoded(decoded_image); |
| 397 } | 392 } |
| 398 } | 393 } |
| 399 } | 394 } |
| 400 | 395 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 scoped_ptr<base::SharedMemory> shm_buffer; | 490 scoped_ptr<base::SharedMemory> shm_buffer; |
| 496 BufferData buffer_data; | 491 BufferData buffer_data; |
| 497 { | 492 { |
| 498 base::AutoLock auto_lock(lock_); | 493 base::AutoLock auto_lock(lock_); |
| 499 // Do not request decode if VDA is resetting. | 494 // Do not request decode if VDA is resetting. |
| 500 if (decode_buffers_.empty() || state_ == RESETTING) | 495 if (decode_buffers_.empty() || state_ == RESETTING) |
| 501 return; | 496 return; |
| 502 shm_buffer.reset(decode_buffers_.front().first); | 497 shm_buffer.reset(decode_buffers_.front().first); |
| 503 buffer_data = decode_buffers_.front().second; | 498 buffer_data = decode_buffers_.front().second; |
| 504 decode_buffers_.pop_front(); | 499 decode_buffers_.pop_front(); |
| 505 // Drop the buffers before Reset or Release is called. | 500 // Drop the buffers before Release is called. |
| 506 if (!IsBufferAfterReset(buffer_data.bitstream_buffer_id, | 501 if (!IsBufferAfterReset(buffer_data.bitstream_buffer_id, |
| 507 reset_bitstream_buffer_id_)) { | 502 reset_bitstream_buffer_id_)) { |
| 508 PutSHM_Locked(std::move(shm_buffer)); | 503 PutSHM_Locked(std::move(shm_buffer)); |
| 509 continue; | 504 continue; |
| 510 } | 505 } |
| 511 } | 506 } |
| 512 | 507 |
| 513 // Create a BitstreamBuffer and send to VDA to decode. | 508 // Create a BitstreamBuffer and send to VDA to decode. |
| 514 media::BitstreamBuffer bitstream_buffer( | 509 media::BitstreamBuffer bitstream_buffer( |
| 515 buffer_data.bitstream_buffer_id, shm_buffer->handle(), buffer_data.size, | 510 buffer_data.bitstream_buffer_id, shm_buffer->handle(), buffer_data.size, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 return true; | 579 return true; |
| 585 } | 580 } |
| 586 | 581 |
| 587 void RTCVideoDecoder::MovePendingBuffersToDecodeBuffers() { | 582 void RTCVideoDecoder::MovePendingBuffersToDecodeBuffers() { |
| 588 base::AutoLock auto_lock(lock_); | 583 base::AutoLock auto_lock(lock_); |
| 589 while (pending_buffers_.size() > 0) { | 584 while (pending_buffers_.size() > 0) { |
| 590 // Get a pending buffer from the queue. | 585 // Get a pending buffer from the queue. |
| 591 const webrtc::EncodedImage& input_image = pending_buffers_.front().first; | 586 const webrtc::EncodedImage& input_image = pending_buffers_.front().first; |
| 592 const BufferData& buffer_data = pending_buffers_.front().second; | 587 const BufferData& buffer_data = pending_buffers_.front().second; |
| 593 | 588 |
| 594 // Drop the frame if it comes before Reset or Release. | 589 // Drop the frame if it comes before Release. |
| 595 if (!IsBufferAfterReset(buffer_data.bitstream_buffer_id, | 590 if (!IsBufferAfterReset(buffer_data.bitstream_buffer_id, |
| 596 reset_bitstream_buffer_id_)) { | 591 reset_bitstream_buffer_id_)) { |
| 597 delete[] input_image._buffer; | 592 delete[] input_image._buffer; |
| 598 pending_buffers_.pop_front(); | 593 pending_buffers_.pop_front(); |
| 599 continue; | 594 continue; |
| 600 } | 595 } |
| 601 // Get shared memory and save it to decode buffers. | 596 // Get shared memory and save it to decode buffers. |
| 602 scoped_ptr<base::SharedMemory> shm_buffer = | 597 scoped_ptr<base::SharedMemory> shm_buffer = |
| 603 GetSHM_Locked(input_image._length); | 598 GetSHM_Locked(input_image._length); |
| 604 if (!shm_buffer) | 599 if (!shm_buffer) |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 } | 807 } |
| 813 | 808 |
| 814 void RTCVideoDecoder::ClearPendingBuffers() { | 809 void RTCVideoDecoder::ClearPendingBuffers() { |
| 815 // Delete WebRTC input buffers. | 810 // Delete WebRTC input buffers. |
| 816 for (const auto& pending_buffer : pending_buffers_) | 811 for (const auto& pending_buffer : pending_buffers_) |
| 817 delete[] pending_buffer.first._buffer; | 812 delete[] pending_buffer.first._buffer; |
| 818 pending_buffers_.clear(); | 813 pending_buffers_.clear(); |
| 819 } | 814 } |
| 820 | 815 |
| 821 } // namespace content | 816 } // namespace content |
| OLD | NEW |