OLD | NEW |
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/video_track_recorder.h" | 5 #include "content/renderer/media/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 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 518 |
519 VEAEncoder::~VEAEncoder() { | 519 VEAEncoder::~VEAEncoder() { |
520 encoding_task_runner_->PostTask( | 520 encoding_task_runner_->PostTask( |
521 FROM_HERE, base::Bind(&media::VideoEncodeAccelerator::Destroy, | 521 FROM_HERE, base::Bind(&media::VideoEncodeAccelerator::Destroy, |
522 base::Unretained(video_encoder_.release()))); | 522 base::Unretained(video_encoder_.release()))); |
523 } | 523 } |
524 | 524 |
525 void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/, | 525 void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/, |
526 const gfx::Size& input_coded_size, | 526 const gfx::Size& input_coded_size, |
527 size_t output_buffer_size) { | 527 size_t output_buffer_size) { |
528 DVLOG(3) << __FUNCTION__; | 528 DVLOG(3) << __func__; |
529 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 529 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
530 | 530 |
531 vea_requested_input_size_ = input_coded_size; | 531 vea_requested_input_size_ = input_coded_size; |
532 output_buffers_.clear(); | 532 output_buffers_.clear(); |
533 std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_); | 533 std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_); |
534 | 534 |
535 for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) { | 535 for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) { |
536 std::unique_ptr<base::SharedMemory> shm = | 536 std::unique_ptr<base::SharedMemory> shm = |
537 gpu_factories_->CreateSharedMemory(output_buffer_size); | 537 gpu_factories_->CreateSharedMemory(output_buffer_size); |
538 if (shm) | 538 if (shm) |
539 output_buffers_.push_back(base::WrapUnique(shm.release())); | 539 output_buffers_.push_back(base::WrapUnique(shm.release())); |
540 } | 540 } |
541 | 541 |
542 for (size_t i = 0; i < output_buffers_.size(); ++i) | 542 for (size_t i = 0; i < output_buffers_.size(); ++i) |
543 UseOutputBitstreamBufferId(i); | 543 UseOutputBitstreamBufferId(i); |
544 } | 544 } |
545 | 545 |
546 void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id, | 546 void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id, |
547 size_t payload_size, | 547 size_t payload_size, |
548 bool keyframe, | 548 bool keyframe, |
549 base::TimeDelta timestamp) { | 549 base::TimeDelta timestamp) { |
550 DVLOG(3) << __FUNCTION__; | 550 DVLOG(3) << __func__; |
551 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 551 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
552 | 552 |
553 base::SharedMemory* output_buffer = | 553 base::SharedMemory* output_buffer = |
554 output_buffers_[bitstream_buffer_id].get(); | 554 output_buffers_[bitstream_buffer_id].get(); |
555 | 555 |
556 std::unique_ptr<std::string> data(new std::string); | 556 std::unique_ptr<std::string> data(new std::string); |
557 data->append(reinterpret_cast<char*>(output_buffer->memory()), payload_size); | 557 data->append(reinterpret_cast<char*>(output_buffer->memory()), payload_size); |
558 | 558 |
559 const auto front_frame = frames_in_encode_.front(); | 559 const auto front_frame = frames_in_encode_.front(); |
560 frames_in_encode_.pop(); | 560 frames_in_encode_.pop(); |
561 origin_task_runner_->PostTask( | 561 origin_task_runner_->PostTask( |
562 FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_, | 562 FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_, |
563 front_frame.first, base::Passed(&data), | 563 front_frame.first, base::Passed(&data), |
564 front_frame.second, keyframe)); | 564 front_frame.second, keyframe)); |
565 UseOutputBitstreamBufferId(bitstream_buffer_id); | 565 UseOutputBitstreamBufferId(bitstream_buffer_id); |
566 } | 566 } |
567 | 567 |
568 void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) { | 568 void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) { |
569 DVLOG(3) << __FUNCTION__; | 569 DVLOG(3) << __func__; |
570 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 570 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
571 | 571 |
572 // TODO(emircan): Notify the owner via a callback. | 572 // TODO(emircan): Notify the owner via a callback. |
573 error_notified_ = true; | 573 error_notified_ = true; |
574 } | 574 } |
575 | 575 |
576 void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) { | 576 void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) { |
577 DVLOG(3) << __FUNCTION__; | 577 DVLOG(3) << __func__; |
578 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 578 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
579 | 579 |
580 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( | 580 video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer( |
581 bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(), | 581 bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(), |
582 output_buffers_[bitstream_buffer_id]->mapped_size())); | 582 output_buffers_[bitstream_buffer_id]->mapped_size())); |
583 } | 583 } |
584 | 584 |
585 void VEAEncoder::FrameFinished(std::unique_ptr<base::SharedMemory> shm) { | 585 void VEAEncoder::FrameFinished(std::unique_ptr<base::SharedMemory> shm) { |
586 DVLOG(3) << __FUNCTION__; | 586 DVLOG(3) << __func__; |
587 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 587 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
588 input_buffers_.push(std::move(shm)); | 588 input_buffers_.push(std::move(shm)); |
589 } | 589 } |
590 | 590 |
591 void VEAEncoder::EncodeOnEncodingTaskRunner( | 591 void VEAEncoder::EncodeOnEncodingTaskRunner( |
592 const scoped_refptr<VideoFrame>& frame, | 592 const scoped_refptr<VideoFrame>& frame, |
593 base::TimeTicks capture_timestamp) { | 593 base::TimeTicks capture_timestamp) { |
594 DVLOG(3) << __FUNCTION__; | 594 DVLOG(3) << __func__; |
595 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 595 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
596 | 596 |
597 if (input_size_ != frame->visible_rect().size() && video_encoder_) { | 597 if (input_size_ != frame->visible_rect().size() && video_encoder_) { |
598 video_encoder_->Destroy(); | 598 video_encoder_->Destroy(); |
599 video_encoder_.reset(); | 599 video_encoder_.reset(); |
600 } | 600 } |
601 | 601 |
602 if (!video_encoder_) | 602 if (!video_encoder_) |
603 ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); | 603 ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); |
604 | 604 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 } | 672 } |
673 frames_in_encode_.push(std::make_pair(video_frame, capture_timestamp)); | 673 frames_in_encode_.push(std::make_pair(video_frame, capture_timestamp)); |
674 | 674 |
675 encoding_task_runner_->PostTask( | 675 encoding_task_runner_->PostTask( |
676 FROM_HERE, | 676 FROM_HERE, |
677 base::Bind(&media::VideoEncodeAccelerator::Encode, | 677 base::Bind(&media::VideoEncodeAccelerator::Encode, |
678 base::Unretained(video_encoder_.get()), video_frame, false)); | 678 base::Unretained(video_encoder_.get()), video_frame, false)); |
679 } | 679 } |
680 | 680 |
681 void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { | 681 void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { |
682 DVLOG(3) << __FUNCTION__; | 682 DVLOG(3) << __func__; |
683 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 683 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
684 DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); | 684 DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); |
685 | 685 |
686 input_size_ = size; | 686 input_size_ = size; |
687 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); | 687 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); |
688 if (!video_encoder_ || | 688 if (!video_encoder_ || |
689 !video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_size_, codec_, | 689 !video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_size_, codec_, |
690 bits_per_second_, this)) { | 690 bits_per_second_, this)) { |
691 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 691 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
692 } | 692 } |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 1083 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
1084 if (encoder_) | 1084 if (encoder_) |
1085 encoder_->SetPaused(false); | 1085 encoder_->SetPaused(false); |
1086 else | 1086 else |
1087 paused_before_init_ = false; | 1087 paused_before_init_ = false; |
1088 } | 1088 } |
1089 | 1089 |
1090 void VideoTrackRecorder::OnVideoFrameForTesting( | 1090 void VideoTrackRecorder::OnVideoFrameForTesting( |
1091 const scoped_refptr<media::VideoFrame>& frame, | 1091 const scoped_refptr<media::VideoFrame>& frame, |
1092 base::TimeTicks timestamp) { | 1092 base::TimeTicks timestamp) { |
1093 DVLOG(3) << __FUNCTION__; | 1093 DVLOG(3) << __func__; |
1094 | 1094 |
1095 if (!encoder_) { | 1095 if (!encoder_) { |
1096 DCHECK(!initialize_encoder_callback_.is_null()); | 1096 DCHECK(!initialize_encoder_callback_.is_null()); |
1097 initialize_encoder_callback_.Run(frame, timestamp); | 1097 initialize_encoder_callback_.Run(frame, timestamp); |
1098 } | 1098 } |
1099 | 1099 |
1100 encoder_->StartFrameEncode(frame, timestamp); | 1100 encoder_->StartFrameEncode(frame, timestamp); |
1101 } | 1101 } |
1102 | 1102 |
1103 void VideoTrackRecorder::InitializeEncoder( | 1103 void VideoTrackRecorder::InitializeEncoder( |
1104 CodecId codec, | 1104 CodecId codec, |
1105 const OnEncodedVideoCB& on_encoded_video_callback, | 1105 const OnEncodedVideoCB& on_encoded_video_callback, |
1106 int32_t bits_per_second, | 1106 int32_t bits_per_second, |
1107 const scoped_refptr<media::VideoFrame>& frame, | 1107 const scoped_refptr<media::VideoFrame>& frame, |
1108 base::TimeTicks capture_time) { | 1108 base::TimeTicks capture_time) { |
1109 DVLOG(3) << __FUNCTION__ << frame->visible_rect().size().ToString(); | 1109 DVLOG(3) << __func__ << frame->visible_rect().size().ToString(); |
1110 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 1110 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
1111 | 1111 |
1112 MediaStreamVideoSink::DisconnectFromTrack(); | 1112 MediaStreamVideoSink::DisconnectFromTrack(); |
1113 | 1113 |
1114 const gfx::Size& input_size = frame->visible_rect().size(); | 1114 const gfx::Size& input_size = frame->visible_rect().size(); |
1115 const auto& vea_supported_profile = CodecIdToVEAProfile(codec); | 1115 const auto& vea_supported_profile = CodecIdToVEAProfile(codec); |
1116 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN && | 1116 if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN && |
1117 input_size.width() >= kVEAEncoderMinResolutionWidth && | 1117 input_size.width() >= kVEAEncoderMinResolutionWidth && |
1118 input_size.height() >= kVEAEncoderMinResolutionHeight) { | 1118 input_size.height() >= kVEAEncoderMinResolutionHeight) { |
1119 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second, | 1119 encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second, |
(...skipping 20 matching lines...) Expand all Loading... |
1140 encoder_->SetPaused(paused_before_init_); | 1140 encoder_->SetPaused(paused_before_init_); |
1141 | 1141 |
1142 // StartFrameEncode() will be called on Render IO thread. | 1142 // StartFrameEncode() will be called on Render IO thread. |
1143 MediaStreamVideoSink::ConnectToTrack( | 1143 MediaStreamVideoSink::ConnectToTrack( |
1144 track_, | 1144 track_, |
1145 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), | 1145 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), |
1146 false); | 1146 false); |
1147 } | 1147 } |
1148 | 1148 |
1149 } // namespace content | 1149 } // namespace content |
OLD | NEW |