| 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 |