| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/cast/sender/external_video_encoder.h" | 5 #include "media/cast/sender/external_video_encoder.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 // methods must be called on the thread associated with the given | 117 // methods must be called on the thread associated with the given |
| 118 // SingleThreadTaskRunner, except for the task_runner() accessor. | 118 // SingleThreadTaskRunner, except for the task_runner() accessor. |
| 119 class ExternalVideoEncoder::VEAClientImpl | 119 class ExternalVideoEncoder::VEAClientImpl |
| 120 : public VideoEncodeAccelerator::Client, | 120 : public VideoEncodeAccelerator::Client, |
| 121 public base::RefCountedThreadSafe<VEAClientImpl> { | 121 public base::RefCountedThreadSafe<VEAClientImpl> { |
| 122 public: | 122 public: |
| 123 VEAClientImpl( | 123 VEAClientImpl( |
| 124 const scoped_refptr<CastEnvironment>& cast_environment, | 124 const scoped_refptr<CastEnvironment>& cast_environment, |
| 125 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, | 125 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, |
| 126 std::unique_ptr<media::VideoEncodeAccelerator> vea, | 126 std::unique_ptr<media::VideoEncodeAccelerator> vea, |
| 127 double max_frame_rate, | 127 int max_frame_rate, |
| 128 const StatusChangeCallback& status_change_cb, | 128 const StatusChangeCallback& status_change_cb, |
| 129 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 129 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 130 : cast_environment_(cast_environment), | 130 : cast_environment_(cast_environment), |
| 131 task_runner_(encoder_task_runner), | 131 task_runner_(encoder_task_runner), |
| 132 max_frame_rate_(max_frame_rate), | 132 max_frame_rate_(max_frame_rate), |
| 133 status_change_cb_(status_change_cb), | 133 status_change_cb_(status_change_cb), |
| 134 create_video_encode_memory_cb_(create_video_encode_memory_cb), | 134 create_video_encode_memory_cb_(create_video_encode_memory_cb), |
| 135 video_encode_accelerator_(std::move(vea)), | 135 video_encode_accelerator_(std::move(vea)), |
| 136 backlog_redline_threshold_(GetConfiguredBacklogRedline()), | 136 backlog_redline_threshold_(GetConfiguredBacklogRedline()), |
| 137 encoder_active_(false), | 137 encoder_active_(false), |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 FROM_HERE, | 169 FROM_HERE, |
| 170 base::Bind(status_change_cb_, | 170 base::Bind(status_change_cb_, |
| 171 encoder_active_ ? STATUS_INITIALIZED : | 171 encoder_active_ ? STATUS_INITIALIZED : |
| 172 STATUS_CODEC_INIT_FAILED)); | 172 STATUS_CODEC_INIT_FAILED)); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void SetBitRate(int bit_rate) { | 175 void SetBitRate(int bit_rate) { |
| 176 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 176 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 177 | 177 |
| 178 requested_bit_rate_ = bit_rate; | 178 requested_bit_rate_ = bit_rate; |
| 179 video_encode_accelerator_->RequestEncodingParametersChange( | 179 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, |
| 180 bit_rate, static_cast<uint32_t>(max_frame_rate_ + 0.5)); | 180 max_frame_rate_); |
| 181 } | 181 } |
| 182 | 182 |
| 183 // The destruction call back of the copied video frame to free its use of | 183 // The destruction call back of the copied video frame to free its use of |
| 184 // the input buffer. | 184 // the input buffer. |
| 185 void ReturnInputBufferToPool(int index) { | 185 void ReturnInputBufferToPool(int index) { |
| 186 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 186 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 187 DCHECK_GE(index, 0); | 187 DCHECK_GE(index, 0); |
| 188 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); | 188 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); |
| 189 free_input_buffer_index_.push_back(index); | 189 free_input_buffer_index_.push_back(index); |
| 190 } | 190 } |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 default: | 585 default: |
| 586 // Skip other NALUs. | 586 // Skip other NALUs. |
| 587 break; | 587 break; |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); | 590 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); |
| 591 } | 591 } |
| 592 | 592 |
| 593 const scoped_refptr<CastEnvironment> cast_environment_; | 593 const scoped_refptr<CastEnvironment> cast_environment_; |
| 594 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 594 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 595 const double max_frame_rate_; | 595 const int max_frame_rate_; |
| 596 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. | 596 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. |
| 597 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; | 597 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; |
| 598 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; | 598 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; |
| 599 const int backlog_redline_threshold_; | 599 const int backlog_redline_threshold_; |
| 600 bool encoder_active_; | 600 bool encoder_active_; |
| 601 FrameId next_frame_id_; | 601 FrameId next_frame_id_; |
| 602 bool key_frame_encountered_; | 602 bool key_frame_encountered_; |
| 603 std::string stream_header_; | 603 std::string stream_header_; |
| 604 VideoCodecProfile codec_profile_; | 604 VideoCodecProfile codec_profile_; |
| 605 bool key_frame_quantizer_parsable_; | 605 bool key_frame_quantizer_parsable_; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 size_t max_allowed_input_buffers_; | 640 size_t max_allowed_input_buffers_; |
| 641 | 641 |
| 642 // Set to true when the allocation of an input buffer is in progress, and | 642 // Set to true when the allocation of an input buffer is in progress, and |
| 643 // reset to false after the allocated buffer is received. | 643 // reset to false after the allocated buffer is received. |
| 644 bool allocate_input_buffer_in_progress_; | 644 bool allocate_input_buffer_in_progress_; |
| 645 | 645 |
| 646 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); | 646 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); |
| 647 }; | 647 }; |
| 648 | 648 |
| 649 // static | 649 // static |
| 650 bool ExternalVideoEncoder::IsSupported(const FrameSenderConfig& video_config) { | 650 bool ExternalVideoEncoder::IsSupported(const VideoSenderConfig& video_config) { |
| 651 if (video_config.codec != CODEC_VIDEO_VP8 && | 651 if (video_config.codec != CODEC_VIDEO_VP8 && |
| 652 video_config.codec != CODEC_VIDEO_H264) | 652 video_config.codec != CODEC_VIDEO_H264) |
| 653 return false; | 653 return false; |
| 654 | 654 |
| 655 // TODO(miu): "Layering hooks" are needed to be able to query outside of | 655 // TODO(miu): "Layering hooks" are needed to be able to query outside of |
| 656 // libmedia, to determine whether the system provides a hardware encoder. For | 656 // libmedia, to determine whether the system provides a hardware encoder. For |
| 657 // now, assume that this was already checked by this point. | 657 // now, assume that this was already checked by this point. |
| 658 // http://crbug.com/454029 | 658 // http://crbug.com/454029 |
| 659 return video_config.use_external_encoder; | 659 return video_config.use_external_encoder; |
| 660 } | 660 } |
| 661 | 661 |
| 662 ExternalVideoEncoder::ExternalVideoEncoder( | 662 ExternalVideoEncoder::ExternalVideoEncoder( |
| 663 const scoped_refptr<CastEnvironment>& cast_environment, | 663 const scoped_refptr<CastEnvironment>& cast_environment, |
| 664 const FrameSenderConfig& video_config, | 664 const VideoSenderConfig& video_config, |
| 665 const gfx::Size& frame_size, | 665 const gfx::Size& frame_size, |
| 666 FrameId first_frame_id, | 666 FrameId first_frame_id, |
| 667 const StatusChangeCallback& status_change_cb, | 667 const StatusChangeCallback& status_change_cb, |
| 668 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 668 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 669 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 669 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 670 : cast_environment_(cast_environment), | 670 : cast_environment_(cast_environment), |
| 671 create_video_encode_memory_cb_(create_video_encode_memory_cb), | 671 create_video_encode_memory_cb_(create_video_encode_memory_cb), |
| 672 frame_size_(frame_size), | 672 frame_size_(frame_size), |
| 673 bit_rate_(video_config.start_bitrate), | 673 bit_rate_(video_config.start_bitrate), |
| 674 key_frame_requested_(false), | 674 key_frame_requested_(false), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 client_->task_runner()->PostTask( | 723 client_->task_runner()->PostTask( |
| 724 FROM_HERE, base::Bind(&VEAClientImpl::SetBitRate, client_, bit_rate_)); | 724 FROM_HERE, base::Bind(&VEAClientImpl::SetBitRate, client_, bit_rate_)); |
| 725 } | 725 } |
| 726 | 726 |
| 727 void ExternalVideoEncoder::GenerateKeyFrame() { | 727 void ExternalVideoEncoder::GenerateKeyFrame() { |
| 728 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 728 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 729 key_frame_requested_ = true; | 729 key_frame_requested_ = true; |
| 730 } | 730 } |
| 731 | 731 |
| 732 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( | 732 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( |
| 733 const FrameSenderConfig& video_config, | 733 const VideoSenderConfig& video_config, |
| 734 FrameId first_frame_id, | 734 FrameId first_frame_id, |
| 735 const StatusChangeCallback& status_change_cb, | 735 const StatusChangeCallback& status_change_cb, |
| 736 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, | 736 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 737 std::unique_ptr<media::VideoEncodeAccelerator> vea) { | 737 std::unique_ptr<media::VideoEncodeAccelerator> vea) { |
| 738 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 738 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 739 | 739 |
| 740 // The callback will be invoked with null pointers in the case where the | 740 // The callback will be invoked with null pointers in the case where the |
| 741 // system does not support or lacks the resources to provide GPU-accelerated | 741 // system does not support or lacks the resources to provide GPU-accelerated |
| 742 // video encoding. | 742 // video encoding. |
| 743 if (!encoder_task_runner || !vea) { | 743 if (!encoder_task_runner || !vea) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 base::Bind(&VEAClientImpl::Initialize, | 775 base::Bind(&VEAClientImpl::Initialize, |
| 776 client_, | 776 client_, |
| 777 frame_size_, | 777 frame_size_, |
| 778 codec_profile, | 778 codec_profile, |
| 779 bit_rate_, | 779 bit_rate_, |
| 780 first_frame_id)); | 780 first_frame_id)); |
| 781 } | 781 } |
| 782 | 782 |
| 783 SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder( | 783 SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder( |
| 784 const scoped_refptr<CastEnvironment>& cast_environment, | 784 const scoped_refptr<CastEnvironment>& cast_environment, |
| 785 const FrameSenderConfig& video_config, | 785 const VideoSenderConfig& video_config, |
| 786 const StatusChangeCallback& status_change_cb, | 786 const StatusChangeCallback& status_change_cb, |
| 787 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 787 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 788 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 788 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 789 : SizeAdaptableVideoEncoderBase(cast_environment, | 789 : SizeAdaptableVideoEncoderBase(cast_environment, |
| 790 video_config, | 790 video_config, |
| 791 status_change_cb), | 791 status_change_cb), |
| 792 create_vea_cb_(create_vea_cb), | 792 create_vea_cb_(create_vea_cb), |
| 793 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} | 793 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} |
| 794 | 794 |
| 795 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} | 795 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 const double kEntropyAtMaxQuantizer = 7.5; | 951 const double kEntropyAtMaxQuantizer = 7.5; |
| 952 const double slope = | 952 const double slope = |
| 953 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; | 953 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; |
| 954 const double quantizer = std::min<double>( | 954 const double quantizer = std::min<double>( |
| 955 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); | 955 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); |
| 956 return quantizer; | 956 return quantizer; |
| 957 } | 957 } |
| 958 | 958 |
| 959 } // namespace cast | 959 } // namespace cast |
| 960 } // namespace media | 960 } // namespace media |
| OLD | NEW |