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

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: 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,
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698