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

Side by Side Diff: content/renderer/media_recorder/video_track_recorder.cc

Issue 2805353002: Merge 58: Handle HW encoder errors in VideoTrackRecorder (Closed)
Patch Set: Created 3 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_recorder/video_track_recorder.h" 5 #include "content/renderer/media_recorder/video_track_recorder.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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 403 }
404 404
405 // Class encapsulating VideoEncodeAccelerator interactions. 405 // Class encapsulating VideoEncodeAccelerator interactions.
406 // This class is created and destroyed in its owner thread. All other methods 406 // This class is created and destroyed in its owner thread. All other methods
407 // operate on the task runner pointed by GpuFactories. 407 // operate on the task runner pointed by GpuFactories.
408 class VEAEncoder final : public VideoTrackRecorder::Encoder, 408 class VEAEncoder final : public VideoTrackRecorder::Encoder,
409 public media::VideoEncodeAccelerator::Client { 409 public media::VideoEncodeAccelerator::Client {
410 public: 410 public:
411 VEAEncoder( 411 VEAEncoder(
412 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 412 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
413 const VideoTrackRecorder::OnErrorCB& on_error_callback,
413 int32_t bits_per_second, 414 int32_t bits_per_second,
414 media::VideoCodecProfile codec, 415 media::VideoCodecProfile codec,
415 const gfx::Size& size); 416 const gfx::Size& size);
416 417
417 // media::VideoEncodeAccelerator::Client implementation. 418 // media::VideoEncodeAccelerator::Client implementation.
418 void RequireBitstreamBuffers(unsigned int input_count, 419 void RequireBitstreamBuffers(unsigned int input_count,
419 const gfx::Size& input_coded_size, 420 const gfx::Size& input_coded_size,
420 size_t output_buffer_size) override; 421 size_t output_buffer_size) override;
421 void BitstreamBufferReady(int32_t bitstream_buffer_id, 422 void BitstreamBufferReady(int32_t bitstream_buffer_id,
422 size_t payload_size, 423 size_t payload_size,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 std::unique_ptr<VideoFrameAndTimestamp> last_frame_; 462 std::unique_ptr<VideoFrameAndTimestamp> last_frame_;
462 463
463 // Size used to initialize encoder. 464 // Size used to initialize encoder.
464 gfx::Size input_visible_size_; 465 gfx::Size input_visible_size_;
465 466
466 // Coded size that encoder requests as input. 467 // Coded size that encoder requests as input.
467 gfx::Size vea_requested_input_coded_size_; 468 gfx::Size vea_requested_input_coded_size_;
468 469
469 // Frames and corresponding timestamps in encode as FIFO. 470 // Frames and corresponding timestamps in encode as FIFO.
470 std::queue<VideoParamsAndTimestamp> frames_in_encode_; 471 std::queue<VideoParamsAndTimestamp> frames_in_encode_;
472
473 // This callback can be exercised on any thread.
474 const VideoTrackRecorder::OnErrorCB on_error_callback_;
471 }; 475 };
472 476
473 // Class encapsulating all libvpx interactions for VP8/VP9 encoding. 477 // Class encapsulating all libvpx interactions for VP8/VP9 encoding.
474 class VpxEncoder final : public VideoTrackRecorder::Encoder { 478 class VpxEncoder final : public VideoTrackRecorder::Encoder {
475 public: 479 public:
476 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, 480 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread,
477 ScopedVpxCodecCtxPtr encoder); 481 ScopedVpxCodecCtxPtr encoder);
478 482
479 VpxEncoder( 483 VpxEncoder(
480 bool use_vp9, 484 bool use_vp9,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 // |encoding_thread_|. 554 // |encoding_thread_|.
551 base::TimeTicks first_frame_timestamp_; 555 base::TimeTicks first_frame_timestamp_;
552 556
553 DISALLOW_COPY_AND_ASSIGN(H264Encoder); 557 DISALLOW_COPY_AND_ASSIGN(H264Encoder);
554 }; 558 };
555 559
556 #endif // #if BUILDFLAG(RTC_USE_H264) 560 #endif // #if BUILDFLAG(RTC_USE_H264)
557 561
558 VEAEncoder::VEAEncoder( 562 VEAEncoder::VEAEncoder(
559 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback, 563 const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
564 const VideoTrackRecorder::OnErrorCB& on_error_callback,
560 int32_t bits_per_second, 565 int32_t bits_per_second,
561 media::VideoCodecProfile codec, 566 media::VideoCodecProfile codec,
562 const gfx::Size& size) 567 const gfx::Size& size)
563 : Encoder(on_encoded_video_callback, 568 : Encoder(on_encoded_video_callback,
564 bits_per_second > 0 ? bits_per_second 569 bits_per_second > 0 ? bits_per_second
565 : size.GetArea() * kVEADefaultBitratePerPixel, 570 : size.GetArea() * kVEADefaultBitratePerPixel,
566 RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()), 571 RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()),
567 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), 572 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()),
568 codec_(codec), 573 codec_(codec),
569 error_notified_(false) { 574 error_notified_(false),
575 on_error_callback_(on_error_callback) {
570 DCHECK(gpu_factories_); 576 DCHECK(gpu_factories_);
571 DCHECK_GE(size.width(), kVEAEncoderMinResolutionWidth); 577 DCHECK_GE(size.width(), kVEAEncoderMinResolutionWidth);
572 DCHECK_GE(size.height(), kVEAEncoderMinResolutionHeight); 578 DCHECK_GE(size.height(), kVEAEncoderMinResolutionHeight);
573 579
574 encoding_task_runner_->PostTask( 580 encoding_task_runner_->PostTask(
575 FROM_HERE, base::Bind(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner, 581 FROM_HERE, base::Bind(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner,
576 this, size)); 582 this, size));
577 } 583 }
578 584
579 VEAEncoder::~VEAEncoder() { 585 VEAEncoder::~VEAEncoder() {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 origin_task_runner_->PostTask( 638 origin_task_runner_->PostTask(
633 FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_, 639 FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_,
634 front_frame.first, base::Passed(&data), 640 front_frame.first, base::Passed(&data),
635 front_frame.second, keyframe)); 641 front_frame.second, keyframe));
636 UseOutputBitstreamBufferId(bitstream_buffer_id); 642 UseOutputBitstreamBufferId(bitstream_buffer_id);
637 } 643 }
638 644
639 void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) { 645 void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) {
640 DVLOG(3) << __func__; 646 DVLOG(3) << __func__;
641 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); 647 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
642 648 on_error_callback_.Run();
643 // TODO(emircan): Notify the owner via a callback.
644 error_notified_ = true; 649 error_notified_ = true;
645 } 650 }
646 651
647 void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) { 652 void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) {
648 DVLOG(3) << __func__; 653 DVLOG(3) << __func__;
649 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); 654 DCHECK(encoding_task_runner_->BelongsToCurrentThread());
650 655
651 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( 656 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
652 bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(), 657 bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(),
653 output_buffers_[bitstream_buffer_id]->mapped_size())); 658 output_buffers_[bitstream_buffer_id]->mapped_size()));
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 1154 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1150 DCHECK(!track_.isNull()); 1155 DCHECK(!track_.isNull());
1151 DCHECK(track_.getTrackData()); 1156 DCHECK(track_.getTrackData());
1152 1157
1153 initialize_encoder_callback_ = base::Bind( 1158 initialize_encoder_callback_ = base::Bind(
1154 &VideoTrackRecorder::InitializeEncoder, weak_ptr_factory_.GetWeakPtr(), 1159 &VideoTrackRecorder::InitializeEncoder, weak_ptr_factory_.GetWeakPtr(),
1155 codec, on_encoded_video_callback, bits_per_second); 1160 codec, on_encoded_video_callback, bits_per_second);
1156 1161
1157 // InitializeEncoder() will be called on Render Main thread. 1162 // InitializeEncoder() will be called on Render Main thread.
1158 MediaStreamVideoSink::ConnectToTrack( 1163 MediaStreamVideoSink::ConnectToTrack(
1159 track_, media::BindToCurrentLoop(initialize_encoder_callback_), false); 1164 track_,
1165 media::BindToCurrentLoop(base::Bind(initialize_encoder_callback_,
1166 true /* allow_vea_encoder */)),
1167 false);
1160 } 1168 }
1161 1169
1162 VideoTrackRecorder::~VideoTrackRecorder() { 1170 VideoTrackRecorder::~VideoTrackRecorder() {
1163 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 1171 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1164 MediaStreamVideoSink::DisconnectFromTrack(); 1172 MediaStreamVideoSink::DisconnectFromTrack();
1165 track_.reset(); 1173 track_.reset();
1166 } 1174 }
1167 1175
1168 void VideoTrackRecorder::Pause() { 1176 void VideoTrackRecorder::Pause() {
1169 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 1177 DCHECK(main_render_thread_checker_.CalledOnValidThread());
(...skipping 11 matching lines...) Expand all
1181 paused_before_init_ = false; 1189 paused_before_init_ = false;
1182 } 1190 }
1183 1191
1184 void VideoTrackRecorder::OnVideoFrameForTesting( 1192 void VideoTrackRecorder::OnVideoFrameForTesting(
1185 const scoped_refptr<media::VideoFrame>& frame, 1193 const scoped_refptr<media::VideoFrame>& frame,
1186 base::TimeTicks timestamp) { 1194 base::TimeTicks timestamp) {
1187 DVLOG(3) << __func__; 1195 DVLOG(3) << __func__;
1188 1196
1189 if (!encoder_) { 1197 if (!encoder_) {
1190 DCHECK(!initialize_encoder_callback_.is_null()); 1198 DCHECK(!initialize_encoder_callback_.is_null());
1191 initialize_encoder_callback_.Run(frame, timestamp); 1199 initialize_encoder_callback_.Run(true /* allow_vea_encoder */, frame,
1200 timestamp);
1192 } 1201 }
1193 1202
1194 encoder_->StartFrameEncode(frame, timestamp); 1203 encoder_->StartFrameEncode(frame, timestamp);
1195 } 1204 }
1196 1205
1197 void VideoTrackRecorder::InitializeEncoder( 1206 void VideoTrackRecorder::InitializeEncoder(
1198 CodecId codec, 1207 CodecId codec,
1199 const OnEncodedVideoCB& on_encoded_video_callback, 1208 const OnEncodedVideoCB& on_encoded_video_callback,
1200 int32_t bits_per_second, 1209 int32_t bits_per_second,
1210 bool allow_vea_encoder,
1201 const scoped_refptr<media::VideoFrame>& frame, 1211 const scoped_refptr<media::VideoFrame>& frame,
1202 base::TimeTicks capture_time) { 1212 base::TimeTicks capture_time) {
1203 DVLOG(3) << __func__ << frame->visible_rect().size().ToString(); 1213 DVLOG(3) << __func__ << frame->visible_rect().size().ToString();
1204 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 1214 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1205 1215
1206 MediaStreamVideoSink::DisconnectFromTrack(); 1216 MediaStreamVideoSink::DisconnectFromTrack();
1207 1217
1208 const gfx::Size& input_size = frame->visible_rect().size(); 1218 const gfx::Size& input_size = frame->visible_rect().size();
1209 const auto& vea_supported_profile = 1219 const auto& vea_supported_profile =
1210 GetCodecEnumerator()->CodecIdToVEAProfile(codec); 1220 GetCodecEnumerator()->CodecIdToVEAProfile(codec);
1211 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN && 1221 if (allow_vea_encoder &&
1222 vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN &&
1212 input_size.width() >= kVEAEncoderMinResolutionWidth && 1223 input_size.width() >= kVEAEncoderMinResolutionWidth &&
1213 input_size.height() >= kVEAEncoderMinResolutionHeight) { 1224 input_size.height() >= kVEAEncoderMinResolutionHeight) {
1214 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second, 1225 encoder_ = new VEAEncoder(
1215 vea_supported_profile, input_size); 1226 on_encoded_video_callback,
1227 media::BindToCurrentLoop(base::Bind(&VideoTrackRecorder::OnError,
1228 weak_ptr_factory_.GetWeakPtr())),
1229 bits_per_second, vea_supported_profile, input_size);
1216 } else { 1230 } else {
1217 switch (codec) { 1231 switch (codec) {
1218 #if BUILDFLAG(RTC_USE_H264) 1232 #if BUILDFLAG(RTC_USE_H264)
1219 case CodecId::H264: 1233 case CodecId::H264:
1220 encoder_ = 1234 encoder_ =
1221 new H264Encoder(on_encoded_video_callback, bits_per_second); 1235 new H264Encoder(on_encoded_video_callback, bits_per_second);
1222 break; 1236 break;
1223 #endif 1237 #endif
1224 case CodecId::VP8: 1238 case CodecId::VP8:
1225 case CodecId::VP9: 1239 case CodecId::VP9:
1226 encoder_ = new VpxEncoder(codec == CodecId::VP9, 1240 encoder_ = new VpxEncoder(codec == CodecId::VP9,
1227 on_encoded_video_callback, bits_per_second); 1241 on_encoded_video_callback, bits_per_second);
1228 break; 1242 break;
1229 default: 1243 default:
1230 NOTREACHED() << "Unsupported codec " << static_cast<int>(codec); 1244 NOTREACHED() << "Unsupported codec " << static_cast<int>(codec);
1231 } 1245 }
1232 } 1246 }
1233 1247
1234 if (paused_before_init_) 1248 if (paused_before_init_)
1235 encoder_->SetPaused(paused_before_init_); 1249 encoder_->SetPaused(paused_before_init_);
1236 1250
1237 // StartFrameEncode() will be called on Render IO thread. 1251 // StartFrameEncode() will be called on Render IO thread.
1238 MediaStreamVideoSink::ConnectToTrack( 1252 MediaStreamVideoSink::ConnectToTrack(
1239 track_, 1253 track_,
1240 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), 1254 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_),
1241 false); 1255 false);
1242 } 1256 }
1243 1257
1258 void VideoTrackRecorder::OnError() {
1259 DVLOG(3) << __func__;
1260 DCHECK(main_render_thread_checker_.CalledOnValidThread());
1261
1262 // InitializeEncoder() will be called to reinitialize encoder on Render Main
1263 // thread.
1264 MediaStreamVideoSink::DisconnectFromTrack();
1265 encoder_ = nullptr;
1266 MediaStreamVideoSink::ConnectToTrack(
1267 track_,
1268 media::BindToCurrentLoop(base::Bind(initialize_encoder_callback_,
1269 false /*allow_vea_encoder*/)),
1270 false);
1271 }
1272
1244 } // namespace content 1273 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698