| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 // methods must be called on the thread associated with the given | 80 // methods must be called on the thread associated with the given |
| 81 // SingleThreadTaskRunner, except for the task_runner() accessor. | 81 // SingleThreadTaskRunner, except for the task_runner() accessor. |
| 82 class ExternalVideoEncoder::VEAClientImpl | 82 class ExternalVideoEncoder::VEAClientImpl |
| 83 : public VideoEncodeAccelerator::Client, | 83 : public VideoEncodeAccelerator::Client, |
| 84 public base::RefCountedThreadSafe<VEAClientImpl> { | 84 public base::RefCountedThreadSafe<VEAClientImpl> { |
| 85 public: | 85 public: |
| 86 VEAClientImpl( | 86 VEAClientImpl( |
| 87 const scoped_refptr<CastEnvironment>& cast_environment, | 87 const scoped_refptr<CastEnvironment>& cast_environment, |
| 88 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, | 88 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, |
| 89 std::unique_ptr<media::VideoEncodeAccelerator> vea, | 89 std::unique_ptr<media::VideoEncodeAccelerator> vea, |
| 90 int max_frame_rate, | 90 double max_frame_rate, |
| 91 const StatusChangeCallback& status_change_cb, | 91 const StatusChangeCallback& status_change_cb, |
| 92 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 92 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 93 : cast_environment_(cast_environment), | 93 : cast_environment_(cast_environment), |
| 94 task_runner_(encoder_task_runner), | 94 task_runner_(encoder_task_runner), |
| 95 max_frame_rate_(max_frame_rate), | 95 max_frame_rate_(max_frame_rate), |
| 96 status_change_cb_(status_change_cb), | 96 status_change_cb_(status_change_cb), |
| 97 create_video_encode_memory_cb_(create_video_encode_memory_cb), | 97 create_video_encode_memory_cb_(create_video_encode_memory_cb), |
| 98 video_encode_accelerator_(std::move(vea)), | 98 video_encode_accelerator_(std::move(vea)), |
| 99 encoder_active_(false), | 99 encoder_active_(false), |
| 100 next_frame_id_(FrameId::first()), | 100 next_frame_id_(FrameId::first()), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 131 FROM_HERE, | 131 FROM_HERE, |
| 132 base::Bind(status_change_cb_, | 132 base::Bind(status_change_cb_, |
| 133 encoder_active_ ? STATUS_INITIALIZED : | 133 encoder_active_ ? STATUS_INITIALIZED : |
| 134 STATUS_CODEC_INIT_FAILED)); | 134 STATUS_CODEC_INIT_FAILED)); |
| 135 } | 135 } |
| 136 | 136 |
| 137 void SetBitRate(int bit_rate) { | 137 void SetBitRate(int bit_rate) { |
| 138 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 138 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 139 | 139 |
| 140 requested_bit_rate_ = bit_rate; | 140 requested_bit_rate_ = bit_rate; |
| 141 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, | 141 video_encode_accelerator_->RequestEncodingParametersChange( |
| 142 max_frame_rate_); | 142 bit_rate, static_cast<uint32_t>(max_frame_rate_ + 0.5)); |
| 143 } | 143 } |
| 144 | 144 |
| 145 // The destruction call back of the copied video frame to free its use of | 145 // The destruction call back of the copied video frame to free its use of |
| 146 // the input buffer. | 146 // the input buffer. |
| 147 void ReturnInputBufferToPool(int index) { | 147 void ReturnInputBufferToPool(int index) { |
| 148 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 148 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 149 DCHECK_GE(index, 0); | 149 DCHECK_GE(index, 0); |
| 150 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); | 150 DCHECK_LT(index, static_cast<int>(input_buffers_.size())); |
| 151 free_input_buffer_index_.push_back(index); | 151 free_input_buffer_index_.push_back(index); |
| 152 } | 152 } |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 default: | 529 default: |
| 530 // Skip other NALUs. | 530 // Skip other NALUs. |
| 531 break; | 531 break; |
| 532 } | 532 } |
| 533 } | 533 } |
| 534 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); | 534 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); |
| 535 } | 535 } |
| 536 | 536 |
| 537 const scoped_refptr<CastEnvironment> cast_environment_; | 537 const scoped_refptr<CastEnvironment> cast_environment_; |
| 538 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 538 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 539 const int max_frame_rate_; | 539 const double max_frame_rate_; |
| 540 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. | 540 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. |
| 541 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; | 541 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; |
| 542 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; | 542 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; |
| 543 bool encoder_active_; | 543 bool encoder_active_; |
| 544 FrameId next_frame_id_; | 544 FrameId next_frame_id_; |
| 545 bool key_frame_encountered_; | 545 bool key_frame_encountered_; |
| 546 std::string stream_header_; | 546 std::string stream_header_; |
| 547 VideoCodecProfile codec_profile_; | 547 VideoCodecProfile codec_profile_; |
| 548 bool key_frame_quantizer_parsable_; | 548 bool key_frame_quantizer_parsable_; |
| 549 H264Parser h264_parser_; | 549 H264Parser h264_parser_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 size_t max_allowed_input_buffers_; | 583 size_t max_allowed_input_buffers_; |
| 584 | 584 |
| 585 // Set to true when the allocation of an input buffer is in progress, and | 585 // Set to true when the allocation of an input buffer is in progress, and |
| 586 // reset to false after the allocated buffer is received. | 586 // reset to false after the allocated buffer is received. |
| 587 bool allocate_input_buffer_in_progress_; | 587 bool allocate_input_buffer_in_progress_; |
| 588 | 588 |
| 589 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); | 589 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); |
| 590 }; | 590 }; |
| 591 | 591 |
| 592 // static | 592 // static |
| 593 bool ExternalVideoEncoder::IsSupported(const VideoSenderConfig& video_config) { | 593 bool ExternalVideoEncoder::IsSupported(const FrameSenderConfig& video_config) { |
| 594 if (video_config.codec != CODEC_VIDEO_VP8 && | 594 if (video_config.codec != CODEC_VIDEO_VP8 && |
| 595 video_config.codec != CODEC_VIDEO_H264) | 595 video_config.codec != CODEC_VIDEO_H264) |
| 596 return false; | 596 return false; |
| 597 | 597 |
| 598 // TODO(miu): "Layering hooks" are needed to be able to query outside of | 598 // TODO(miu): "Layering hooks" are needed to be able to query outside of |
| 599 // libmedia, to determine whether the system provides a hardware encoder. For | 599 // libmedia, to determine whether the system provides a hardware encoder. For |
| 600 // now, assume that this was already checked by this point. | 600 // now, assume that this was already checked by this point. |
| 601 // http://crbug.com/454029 | 601 // http://crbug.com/454029 |
| 602 return video_config.use_external_encoder; | 602 return video_config.use_external_encoder; |
| 603 } | 603 } |
| 604 | 604 |
| 605 ExternalVideoEncoder::ExternalVideoEncoder( | 605 ExternalVideoEncoder::ExternalVideoEncoder( |
| 606 const scoped_refptr<CastEnvironment>& cast_environment, | 606 const scoped_refptr<CastEnvironment>& cast_environment, |
| 607 const VideoSenderConfig& video_config, | 607 const FrameSenderConfig& video_config, |
| 608 const gfx::Size& frame_size, | 608 const gfx::Size& frame_size, |
| 609 FrameId first_frame_id, | 609 FrameId first_frame_id, |
| 610 const StatusChangeCallback& status_change_cb, | 610 const StatusChangeCallback& status_change_cb, |
| 611 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 611 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 612 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 612 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 613 : cast_environment_(cast_environment), | 613 : cast_environment_(cast_environment), |
| 614 create_video_encode_memory_cb_(create_video_encode_memory_cb), | 614 create_video_encode_memory_cb_(create_video_encode_memory_cb), |
| 615 frame_size_(frame_size), | 615 frame_size_(frame_size), |
| 616 bit_rate_(video_config.start_bitrate), | 616 bit_rate_(video_config.codec_specific_params.start_bitrate), |
| 617 key_frame_requested_(false), | 617 key_frame_requested_(false), |
| 618 weak_factory_(this) { | 618 weak_factory_(this) { |
| 619 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 619 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 620 DCHECK_GT(video_config.max_frame_rate, 0); | 620 DCHECK_GT(video_config.max_frame_rate, 0); |
| 621 DCHECK(!frame_size_.IsEmpty()); | 621 DCHECK(!frame_size_.IsEmpty()); |
| 622 DCHECK(!status_change_cb.is_null()); | 622 DCHECK(!status_change_cb.is_null()); |
| 623 DCHECK(!create_vea_cb.is_null()); | 623 DCHECK(!create_vea_cb.is_null()); |
| 624 DCHECK(!create_video_encode_memory_cb_.is_null()); | 624 DCHECK(!create_video_encode_memory_cb_.is_null()); |
| 625 DCHECK_GT(bit_rate_, 0); | 625 DCHECK_GT(bit_rate_, 0); |
| 626 | 626 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 client_->task_runner()->PostTask( | 666 client_->task_runner()->PostTask( |
| 667 FROM_HERE, base::Bind(&VEAClientImpl::SetBitRate, client_, bit_rate_)); | 667 FROM_HERE, base::Bind(&VEAClientImpl::SetBitRate, client_, bit_rate_)); |
| 668 } | 668 } |
| 669 | 669 |
| 670 void ExternalVideoEncoder::GenerateKeyFrame() { | 670 void ExternalVideoEncoder::GenerateKeyFrame() { |
| 671 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 671 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 672 key_frame_requested_ = true; | 672 key_frame_requested_ = true; |
| 673 } | 673 } |
| 674 | 674 |
| 675 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( | 675 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( |
| 676 const VideoSenderConfig& video_config, | 676 const FrameSenderConfig& video_config, |
| 677 FrameId first_frame_id, | 677 FrameId first_frame_id, |
| 678 const StatusChangeCallback& status_change_cb, | 678 const StatusChangeCallback& status_change_cb, |
| 679 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, | 679 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 680 std::unique_ptr<media::VideoEncodeAccelerator> vea) { | 680 std::unique_ptr<media::VideoEncodeAccelerator> vea) { |
| 681 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 681 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 682 | 682 |
| 683 // The callback will be invoked with null pointers in the case where the | 683 // The callback will be invoked with null pointers in the case where the |
| 684 // system does not support or lacks the resources to provide GPU-accelerated | 684 // system does not support or lacks the resources to provide GPU-accelerated |
| 685 // video encoding. | 685 // video encoding. |
| 686 if (!encoder_task_runner || !vea) { | 686 if (!encoder_task_runner || !vea) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 base::Bind(&VEAClientImpl::Initialize, | 718 base::Bind(&VEAClientImpl::Initialize, |
| 719 client_, | 719 client_, |
| 720 frame_size_, | 720 frame_size_, |
| 721 codec_profile, | 721 codec_profile, |
| 722 bit_rate_, | 722 bit_rate_, |
| 723 first_frame_id)); | 723 first_frame_id)); |
| 724 } | 724 } |
| 725 | 725 |
| 726 SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder( | 726 SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder( |
| 727 const scoped_refptr<CastEnvironment>& cast_environment, | 727 const scoped_refptr<CastEnvironment>& cast_environment, |
| 728 const VideoSenderConfig& video_config, | 728 const FrameSenderConfig& video_config, |
| 729 const StatusChangeCallback& status_change_cb, | 729 const StatusChangeCallback& status_change_cb, |
| 730 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 730 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 731 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 731 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 732 : SizeAdaptableVideoEncoderBase(cast_environment, | 732 : SizeAdaptableVideoEncoderBase(cast_environment, |
| 733 video_config, | 733 video_config, |
| 734 status_change_cb), | 734 status_change_cb), |
| 735 create_vea_cb_(create_vea_cb), | 735 create_vea_cb_(create_vea_cb), |
| 736 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} | 736 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} |
| 737 | 737 |
| 738 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} | 738 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 const double kEntropyAtMaxQuantizer = 7.5; | 894 const double kEntropyAtMaxQuantizer = 7.5; |
| 895 const double slope = | 895 const double slope = |
| 896 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; | 896 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; |
| 897 const double quantizer = std::min<double>( | 897 const double quantizer = std::min<double>( |
| 898 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); | 898 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); |
| 899 return quantizer; | 899 return quantizer; |
| 900 } | 900 } |
| 901 | 901 |
| 902 } // namespace cast | 902 } // namespace cast |
| 903 } // namespace media | 903 } // namespace media |
| OLD | NEW |