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_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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 | 153 |
| 154 base::AutoLock auto_lock(lock_); | 154 base::AutoLock auto_lock(lock_); |
| 155 | 155 |
| 156 if (state_ == UNINITIALIZED || !decode_complete_callback_) { | 156 if (state_ == UNINITIALIZED || !decode_complete_callback_) { |
| 157 LOG(ERROR) << "The decoder has not initialized."; | 157 LOG(ERROR) << "The decoder has not initialized."; |
| 158 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 158 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 159 } | 159 } |
| 160 | 160 |
| 161 if (state_ == DECODE_ERROR) { | 161 if (state_ == DECODE_ERROR) { |
| 162 LOG(ERROR) << "Decoding error occurred."; | 162 LOG(ERROR) << "Decoding error occurred."; |
| 163 // Try restarting the session. It is OK to drop the frames until a keyframe | |
| 164 // is received. | |
| 165 factories_->GetTaskRunner()->PostTask( | |
| 166 FROM_HERE, base::Bind(&RTCVideoDecoder::ResetInternal, | |
| 167 weak_factory_.GetWeakPtr())); | |
| 163 return WEBRTC_VIDEO_CODEC_ERROR; | 168 return WEBRTC_VIDEO_CODEC_ERROR; |
| 164 } | 169 } |
| 165 | 170 |
| 166 if (missingFrames || !inputImage._completeFrame) { | 171 if (missingFrames || !inputImage._completeFrame) { |
| 167 DLOG(ERROR) << "Missing or incomplete frames."; | 172 DLOG(ERROR) << "Missing or incomplete frames."; |
| 168 // Unlike the SW decoder in libvpx, hw decoder cannot handle broken frames. | 173 // Unlike the SW decoder in libvpx, hw decoder cannot handle broken frames. |
| 169 // Return an error to request a key frame. | 174 // Return an error to request a key frame. |
| 170 return WEBRTC_VIDEO_CODEC_ERROR; | 175 return WEBRTC_VIDEO_CODEC_ERROR; |
| 171 } | 176 } |
| 172 | 177 |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 return; | 605 return; |
| 601 SaveToDecodeBuffers_Locked(input_image, std::move(shm_buffer), buffer_data); | 606 SaveToDecodeBuffers_Locked(input_image, std::move(shm_buffer), buffer_data); |
| 602 delete[] input_image._buffer; | 607 delete[] input_image._buffer; |
| 603 pending_buffers_.pop_front(); | 608 pending_buffers_.pop_front(); |
| 604 } | 609 } |
| 605 } | 610 } |
| 606 | 611 |
| 607 void RTCVideoDecoder::ResetInternal() { | 612 void RTCVideoDecoder::ResetInternal() { |
| 608 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 613 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 609 DVLOG(2) << "ResetInternal"; | 614 DVLOG(2) << "ResetInternal"; |
| 615 | |
| 616 if (!vda_) { | |
| 617 base::WaitableEvent waiter(true, false); | |
| 618 CreateVDA(vda_codec_profile_, &waiter); | |
| 619 waiter.Wait();; | |
|
tommi (sloooow) - chröme
2016/03/19 09:25:49
One semicolon.
Can we avoid waiting?
emircan
2016/03/21 19:25:09
Done.
| |
| 620 } | |
| 621 | |
| 610 if (vda_) | 622 if (vda_) |
|
tommi (sloooow) - chröme
2016/03/19 09:25:49
Turn this into an else?
emircan
2016/03/21 19:25:09
Done.
| |
| 611 vda_->Reset(); | 623 vda_->Reset(); |
| 612 } | 624 } |
| 613 | 625 |
| 614 // static | 626 // static |
| 615 void RTCVideoDecoder::ReleaseMailbox( | 627 void RTCVideoDecoder::ReleaseMailbox( |
| 616 base::WeakPtr<RTCVideoDecoder> decoder, | 628 base::WeakPtr<RTCVideoDecoder> decoder, |
| 617 media::GpuVideoAcceleratorFactories* factories, | 629 media::GpuVideoAcceleratorFactories* factories, |
| 618 int64_t picture_buffer_id, | 630 int64_t picture_buffer_id, |
| 619 uint32_t texture_id, | 631 uint32_t texture_id, |
| 620 const gpu::SyncToken& release_sync_token) { | 632 const gpu::SyncToken& release_sync_token) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 685 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 674 | 686 |
| 675 if (!IsProfileSupported(profile)) { | 687 if (!IsProfileSupported(profile)) { |
| 676 DVLOG(1) << "Unsupported profile " << profile; | 688 DVLOG(1) << "Unsupported profile " << profile; |
| 677 } else { | 689 } else { |
| 678 vda_ = factories_->CreateVideoDecodeAccelerator(); | 690 vda_ = factories_->CreateVideoDecodeAccelerator(); |
| 679 | 691 |
| 680 media::VideoDecodeAccelerator::Config config(profile); | 692 media::VideoDecodeAccelerator::Config config(profile); |
| 681 if (vda_ && !vda_->Initialize(config, this)) | 693 if (vda_ && !vda_->Initialize(config, this)) |
| 682 vda_.release()->Destroy(); | 694 vda_.release()->Destroy(); |
| 695 vda_codec_profile_ = profile; | |
| 683 } | 696 } |
| 684 | 697 |
| 685 waiter->Signal(); | 698 waiter->Signal(); |
| 686 } | 699 } |
| 687 | 700 |
| 688 void RTCVideoDecoder::DestroyTextures() { | 701 void RTCVideoDecoder::DestroyTextures() { |
| 689 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 702 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 690 | 703 |
| 691 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since | 704 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since |
| 692 // their textures may still be in use by the user of this RTCVideoDecoder. | 705 // their textures may still be in use by the user of this RTCVideoDecoder. |
| 693 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) | 706 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) |
| 694 assigned_picture_buffers_.erase(picture_buffer_at_display.first); | 707 assigned_picture_buffers_.erase(picture_buffer_at_display.first); |
| 695 | 708 |
| 696 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) | 709 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) |
| 697 factories_->DeleteTexture(assigned_picture_buffer.second.texture_id()); | 710 factories_->DeleteTexture(assigned_picture_buffer.second.texture_id()); |
| 698 | 711 |
| 699 assigned_picture_buffers_.clear(); | 712 assigned_picture_buffers_.clear(); |
| 700 } | 713 } |
| 701 | 714 |
| 702 void RTCVideoDecoder::DestroyVDA() { | 715 void RTCVideoDecoder::DestroyVDA() { |
| 703 DVLOG(2) << "DestroyVDA"; | 716 DVLOG(2) << "DestroyVDA"; |
| 704 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 717 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 705 if (vda_) | 718 if (vda_) |
| 706 vda_.release()->Destroy(); | 719 vda_.release()->Destroy(); |
| 707 DestroyTextures(); | 720 DestroyTextures(); |
| 721 | |
| 708 base::AutoLock auto_lock(lock_); | 722 base::AutoLock auto_lock(lock_); |
| 723 | |
| 724 // Put the buffers back in case we restart the decoder. | |
| 725 for (const auto& buffer : bitstream_buffers_in_decoder_) | |
| 726 PutSHM_Locked(scoped_ptr<base::SharedMemory>(buffer.second)); | |
| 727 bitstream_buffers_in_decoder_.clear(); | |
| 728 | |
| 709 state_ = UNINITIALIZED; | 729 state_ = UNINITIALIZED; |
| 710 } | 730 } |
| 711 | 731 |
| 712 scoped_ptr<base::SharedMemory> RTCVideoDecoder::GetSHM_Locked(size_t min_size) { | 732 scoped_ptr<base::SharedMemory> RTCVideoDecoder::GetSHM_Locked(size_t min_size) { |
| 713 // Reuse a SHM if possible. | 733 // Reuse a SHM if possible. |
| 714 if (!available_shm_segments_.empty() && | 734 if (!available_shm_segments_.empty() && |
| 715 available_shm_segments_.back()->mapped_size() >= min_size) { | 735 available_shm_segments_.back()->mapped_size() >= min_size) { |
| 716 scoped_ptr<base::SharedMemory> buffer(available_shm_segments_.back()); | 736 scoped_ptr<base::SharedMemory> buffer(available_shm_segments_.back()); |
| 717 available_shm_segments_.pop_back(); | 737 available_shm_segments_.pop_back(); |
| 718 return buffer; | 738 return buffer; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 } | 827 } |
| 808 | 828 |
| 809 void RTCVideoDecoder::ClearPendingBuffers() { | 829 void RTCVideoDecoder::ClearPendingBuffers() { |
| 810 // Delete WebRTC input buffers. | 830 // Delete WebRTC input buffers. |
| 811 for (const auto& pending_buffer : pending_buffers_) | 831 for (const auto& pending_buffer : pending_buffers_) |
| 812 delete[] pending_buffer.first._buffer; | 832 delete[] pending_buffer.first._buffer; |
| 813 pending_buffers_.clear(); | 833 pending_buffers_.clear(); |
| 814 } | 834 } |
| 815 | 835 |
| 816 } // namespace content | 836 } // namespace content |
| OLD | NEW |