Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: content/renderer/media/rtc_video_decoder.cc

Issue 1817573004: Handle HW decode failures in RTCVideoDecoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tommi@ comments. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698