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, | |
|
mcasas
2016/03/23 18:29:56
Shouldn't we make sure that the
|state_ = RESETTIN
emircan
2016/03/25 02:33:31
Agreed. I will set it here(a) since all |state_| m
| |
| 167 weak_factory_.GetWeakPtr())); | |
| 163 return WEBRTC_VIDEO_CODEC_ERROR; | 168 return WEBRTC_VIDEO_CODEC_ERROR; |
|
mcasas
2016/03/23 18:29:56
Following offline conversation, please add
some ki
emircan
2016/03/25 02:33:31
Done.
| |
| 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 |
| 173 // Most platforms' VDA implementations support mid-stream resolution change | 178 // Most platforms' VDA implementations support mid-stream resolution change |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 if (!shm_buffer) | 604 if (!shm_buffer) |
| 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"; |
|
mcasas
2016/03/23 18:29:56
nit: Move this to before the DCHECK
and use DVLOG(
emircan
2016/03/25 02:33:31
Done.
| |
| 615 | |
| 610 if (vda_) | 616 if (vda_) |
| 611 vda_->Reset(); | 617 vda_->Reset(); |
| 618 else | |
|
pbos
2016/03/22 21:20:43
{}s for if-elses
mcasas
2016/03/23 18:29:56
Not for both bodies being one-liners.
https://goo
| |
| 619 CreateVDA(vda_codec_profile_, nullptr); | |
| 612 } | 620 } |
| 613 | 621 |
| 614 // static | 622 // static |
| 615 void RTCVideoDecoder::ReleaseMailbox( | 623 void RTCVideoDecoder::ReleaseMailbox( |
| 616 base::WeakPtr<RTCVideoDecoder> decoder, | 624 base::WeakPtr<RTCVideoDecoder> decoder, |
| 617 media::GpuVideoAcceleratorFactories* factories, | 625 media::GpuVideoAcceleratorFactories* factories, |
| 618 int64_t picture_buffer_id, | 626 int64_t picture_buffer_id, |
| 619 uint32_t texture_id, | 627 uint32_t texture_id, |
| 620 const gpu::SyncToken& release_sync_token) { | 628 const gpu::SyncToken& release_sync_token) { |
| 621 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); | 629 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 681 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 674 | 682 |
| 675 if (!IsProfileSupported(profile)) { | 683 if (!IsProfileSupported(profile)) { |
| 676 DVLOG(1) << "Unsupported profile " << profile; | 684 DVLOG(1) << "Unsupported profile " << profile; |
| 677 } else { | 685 } else { |
| 678 vda_ = factories_->CreateVideoDecodeAccelerator(); | 686 vda_ = factories_->CreateVideoDecodeAccelerator(); |
| 679 | 687 |
| 680 media::VideoDecodeAccelerator::Config config(profile); | 688 media::VideoDecodeAccelerator::Config config(profile); |
| 681 if (vda_ && !vda_->Initialize(config, this)) | 689 if (vda_ && !vda_->Initialize(config, this)) |
| 682 vda_.release()->Destroy(); | 690 vda_.release()->Destroy(); |
| 691 vda_codec_profile_ = profile; | |
| 683 } | 692 } |
| 684 | 693 |
| 685 waiter->Signal(); | 694 if (waiter) |
| 695 waiter->Signal(); | |
| 686 } | 696 } |
| 687 | 697 |
| 688 void RTCVideoDecoder::DestroyTextures() { | 698 void RTCVideoDecoder::DestroyTextures() { |
| 689 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 699 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 690 | 700 |
| 691 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since | 701 // Not destroying PictureBuffers in |picture_buffers_at_display_| yet, since |
| 692 // their textures may still be in use by the user of this RTCVideoDecoder. | 702 // 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_) | 703 for (const auto& picture_buffer_at_display : picture_buffers_at_display_) |
| 694 assigned_picture_buffers_.erase(picture_buffer_at_display.first); | 704 assigned_picture_buffers_.erase(picture_buffer_at_display.first); |
| 695 | 705 |
| 696 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) | 706 for (const auto& assigned_picture_buffer : assigned_picture_buffers_) |
| 697 factories_->DeleteTexture(assigned_picture_buffer.second.texture_id()); | 707 factories_->DeleteTexture(assigned_picture_buffer.second.texture_id()); |
| 698 | 708 |
| 699 assigned_picture_buffers_.clear(); | 709 assigned_picture_buffers_.clear(); |
| 700 } | 710 } |
| 701 | 711 |
| 702 void RTCVideoDecoder::DestroyVDA() { | 712 void RTCVideoDecoder::DestroyVDA() { |
| 703 DVLOG(2) << "DestroyVDA"; | 713 DVLOG(2) << "DestroyVDA"; |
| 704 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 714 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 705 if (vda_) | 715 if (vda_) |
| 706 vda_.release()->Destroy(); | 716 vda_.release()->Destroy(); |
| 707 DestroyTextures(); | 717 DestroyTextures(); |
| 718 | |
| 708 base::AutoLock auto_lock(lock_); | 719 base::AutoLock auto_lock(lock_); |
| 720 | |
| 721 // Put the buffers back in case we restart the decoder. | |
| 722 for (const auto& buffer : bitstream_buffers_in_decoder_) | |
| 723 PutSHM_Locked(scoped_ptr<base::SharedMemory>(buffer.second)); | |
|
mcasas
2016/03/23 18:29:57
nit: totally not your problem and prob
beyond this
emircan
2016/03/25 02:33:31
I agree the name is confusing. They specify "lock_
| |
| 724 bitstream_buffers_in_decoder_.clear(); | |
| 725 | |
| 709 state_ = UNINITIALIZED; | 726 state_ = UNINITIALIZED; |
| 710 } | 727 } |
| 711 | 728 |
| 712 scoped_ptr<base::SharedMemory> RTCVideoDecoder::GetSHM_Locked(size_t min_size) { | 729 scoped_ptr<base::SharedMemory> RTCVideoDecoder::GetSHM_Locked(size_t min_size) { |
| 713 // Reuse a SHM if possible. | 730 // Reuse a SHM if possible. |
| 714 if (!available_shm_segments_.empty() && | 731 if (!available_shm_segments_.empty() && |
| 715 available_shm_segments_.back()->mapped_size() >= min_size) { | 732 available_shm_segments_.back()->mapped_size() >= min_size) { |
| 716 scoped_ptr<base::SharedMemory> buffer(available_shm_segments_.back()); | 733 scoped_ptr<base::SharedMemory> buffer(available_shm_segments_.back()); |
| 717 available_shm_segments_.pop_back(); | 734 available_shm_segments_.pop_back(); |
| 718 return buffer; | 735 return buffer; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 } | 824 } |
| 808 | 825 |
| 809 void RTCVideoDecoder::ClearPendingBuffers() { | 826 void RTCVideoDecoder::ClearPendingBuffers() { |
| 810 // Delete WebRTC input buffers. | 827 // Delete WebRTC input buffers. |
| 811 for (const auto& pending_buffer : pending_buffers_) | 828 for (const auto& pending_buffer : pending_buffers_) |
| 812 delete[] pending_buffer.first._buffer; | 829 delete[] pending_buffer.first._buffer; |
| 813 pending_buffers_.clear(); | 830 pending_buffers_.clear(); |
| 814 } | 831 } |
| 815 | 832 |
| 816 } // namespace content | 833 } // namespace content |
| OLD | NEW |