| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 // to encode media::VideoFrames and emit media::cast::EncodedFrames. All | 74 // to encode media::VideoFrames and emit media::cast::EncodedFrames. All |
| 75 // methods must be called on the thread associated with the given | 75 // methods must be called on the thread associated with the given |
| 76 // SingleThreadTaskRunner, except for the task_runner() accessor. | 76 // SingleThreadTaskRunner, except for the task_runner() accessor. |
| 77 class ExternalVideoEncoder::VEAClientImpl | 77 class ExternalVideoEncoder::VEAClientImpl |
| 78 : public VideoEncodeAccelerator::Client, | 78 : public VideoEncodeAccelerator::Client, |
| 79 public base::RefCountedThreadSafe<VEAClientImpl> { | 79 public base::RefCountedThreadSafe<VEAClientImpl> { |
| 80 public: | 80 public: |
| 81 VEAClientImpl( | 81 VEAClientImpl( |
| 82 const scoped_refptr<CastEnvironment>& cast_environment, | 82 const scoped_refptr<CastEnvironment>& cast_environment, |
| 83 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, | 83 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, |
| 84 scoped_ptr<media::VideoEncodeAccelerator> vea, | 84 std::unique_ptr<media::VideoEncodeAccelerator> vea, |
| 85 int max_frame_rate, | 85 int max_frame_rate, |
| 86 const StatusChangeCallback& status_change_cb, | 86 const StatusChangeCallback& status_change_cb, |
| 87 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 87 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 88 : cast_environment_(cast_environment), | 88 : cast_environment_(cast_environment), |
| 89 task_runner_(encoder_task_runner), | 89 task_runner_(encoder_task_runner), |
| 90 max_frame_rate_(max_frame_rate), | 90 max_frame_rate_(max_frame_rate), |
| 91 status_change_cb_(status_change_cb), | 91 status_change_cb_(status_change_cb), |
| 92 create_video_encode_memory_cb_(create_video_encode_memory_cb), | 92 create_video_encode_memory_cb_(create_video_encode_memory_cb), |
| 93 video_encode_accelerator_(std::move(vea)), | 93 video_encode_accelerator_(std::move(vea)), |
| 94 encoder_active_(false), | 94 encoder_active_(false), |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 // Save the bitstream buffer in |stream_header_| to be sent later along | 216 // Save the bitstream buffer in |stream_header_| to be sent later along |
| 217 // with the first key frame. | 217 // with the first key frame. |
| 218 // | 218 // |
| 219 // TODO(miu): Should |stream_header_| be an std::ostringstream for | 219 // TODO(miu): Should |stream_header_| be an std::ostringstream for |
| 220 // performance reasons? | 220 // performance reasons? |
| 221 stream_header_.append(static_cast<const char*>(output_buffer->memory()), | 221 stream_header_.append(static_cast<const char*>(output_buffer->memory()), |
| 222 payload_size); | 222 payload_size); |
| 223 } else if (!in_progress_frame_encodes_.empty()) { | 223 } else if (!in_progress_frame_encodes_.empty()) { |
| 224 const InProgressFrameEncode& request = in_progress_frame_encodes_.front(); | 224 const InProgressFrameEncode& request = in_progress_frame_encodes_.front(); |
| 225 | 225 |
| 226 scoped_ptr<SenderEncodedFrame> encoded_frame(new SenderEncodedFrame()); | 226 std::unique_ptr<SenderEncodedFrame> encoded_frame( |
| 227 new SenderEncodedFrame()); |
| 227 encoded_frame->dependency = key_frame ? EncodedFrame::KEY : | 228 encoded_frame->dependency = key_frame ? EncodedFrame::KEY : |
| 228 EncodedFrame::DEPENDENT; | 229 EncodedFrame::DEPENDENT; |
| 229 encoded_frame->frame_id = next_frame_id_++; | 230 encoded_frame->frame_id = next_frame_id_++; |
| 230 if (key_frame) | 231 if (key_frame) |
| 231 encoded_frame->referenced_frame_id = encoded_frame->frame_id; | 232 encoded_frame->referenced_frame_id = encoded_frame->frame_id; |
| 232 else | 233 else |
| 233 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1; | 234 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1; |
| 234 encoded_frame->rtp_timestamp = RtpTimeTicks::FromTimeDelta( | 235 encoded_frame->rtp_timestamp = RtpTimeTicks::FromTimeDelta( |
| 235 request.video_frame->timestamp(), kVideoFrequency); | 236 request.video_frame->timestamp(), kVideoFrequency); |
| 236 encoded_frame->reference_time = request.reference_time; | 237 encoded_frame->reference_time = request.reference_time; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 ~VEAClientImpl() final { | 355 ~VEAClientImpl() final { |
| 355 // According to the media::VideoEncodeAccelerator interface, Destroy() | 356 // According to the media::VideoEncodeAccelerator interface, Destroy() |
| 356 // should be called instead of invoking its private destructor. | 357 // should be called instead of invoking its private destructor. |
| 357 task_runner_->PostTask( | 358 task_runner_->PostTask( |
| 358 FROM_HERE, | 359 FROM_HERE, |
| 359 base::Bind(&media::VideoEncodeAccelerator::Destroy, | 360 base::Bind(&media::VideoEncodeAccelerator::Destroy, |
| 360 base::Unretained(video_encode_accelerator_.release()))); | 361 base::Unretained(video_encode_accelerator_.release()))); |
| 361 } | 362 } |
| 362 | 363 |
| 363 // Note: This method can be called on any thread. | 364 // Note: This method can be called on any thread. |
| 364 void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) { | 365 void OnCreateSharedMemory(std::unique_ptr<base::SharedMemory> memory) { |
| 365 task_runner_->PostTask(FROM_HERE, | 366 task_runner_->PostTask(FROM_HERE, |
| 366 base::Bind(&VEAClientImpl::OnReceivedSharedMemory, | 367 base::Bind(&VEAClientImpl::OnReceivedSharedMemory, |
| 367 this, | 368 this, |
| 368 base::Passed(&memory))); | 369 base::Passed(&memory))); |
| 369 } | 370 } |
| 370 | 371 |
| 371 void OnReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) { | 372 void OnReceivedSharedMemory(std::unique_ptr<base::SharedMemory> memory) { |
| 372 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 373 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 373 | 374 |
| 374 output_buffers_.push_back(std::move(memory)); | 375 output_buffers_.push_back(std::move(memory)); |
| 375 | 376 |
| 376 // Wait until all requested buffers are received. | 377 // Wait until all requested buffers are received. |
| 377 if (output_buffers_.size() < kOutputBufferCount) | 378 if (output_buffers_.size() < kOutputBufferCount) |
| 378 return; | 379 return; |
| 379 | 380 |
| 380 // Immediately provide all output buffers to the VEA. | 381 // Immediately provide all output buffers to the VEA. |
| 381 for (size_t i = 0; i < output_buffers_.size(); ++i) { | 382 for (size_t i = 0; i < output_buffers_.size(); ++i) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 } | 444 } |
| 444 } | 445 } |
| 445 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); | 446 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); |
| 446 } | 447 } |
| 447 | 448 |
| 448 const scoped_refptr<CastEnvironment> cast_environment_; | 449 const scoped_refptr<CastEnvironment> cast_environment_; |
| 449 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 450 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 450 const int max_frame_rate_; | 451 const int max_frame_rate_; |
| 451 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. | 452 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. |
| 452 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; | 453 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; |
| 453 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; | 454 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; |
| 454 bool encoder_active_; | 455 bool encoder_active_; |
| 455 uint32_t next_frame_id_; | 456 uint32_t next_frame_id_; |
| 456 bool key_frame_encountered_; | 457 bool key_frame_encountered_; |
| 457 std::string stream_header_; | 458 std::string stream_header_; |
| 458 VideoCodecProfile codec_profile_; | 459 VideoCodecProfile codec_profile_; |
| 459 bool key_frame_quantizer_parsable_; | 460 bool key_frame_quantizer_parsable_; |
| 460 H264Parser h264_parser_; | 461 H264Parser h264_parser_; |
| 461 | 462 |
| 462 // Shared memory buffers for output with the VideoAccelerator. | 463 // Shared memory buffers for output with the VideoAccelerator. |
| 463 ScopedVector<base::SharedMemory> output_buffers_; | 464 ScopedVector<base::SharedMemory> output_buffers_; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 void ExternalVideoEncoder::GenerateKeyFrame() { | 561 void ExternalVideoEncoder::GenerateKeyFrame() { |
| 561 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 562 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 562 key_frame_requested_ = true; | 563 key_frame_requested_ = true; |
| 563 } | 564 } |
| 564 | 565 |
| 565 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( | 566 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( |
| 566 const VideoSenderConfig& video_config, | 567 const VideoSenderConfig& video_config, |
| 567 uint32_t first_frame_id, | 568 uint32_t first_frame_id, |
| 568 const StatusChangeCallback& status_change_cb, | 569 const StatusChangeCallback& status_change_cb, |
| 569 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, | 570 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 570 scoped_ptr<media::VideoEncodeAccelerator> vea) { | 571 std::unique_ptr<media::VideoEncodeAccelerator> vea) { |
| 571 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 572 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 572 | 573 |
| 573 // The callback will be invoked with null pointers in the case where the | 574 // The callback will be invoked with null pointers in the case where the |
| 574 // system does not support or lacks the resources to provide GPU-accelerated | 575 // system does not support or lacks the resources to provide GPU-accelerated |
| 575 // video encoding. | 576 // video encoding. |
| 576 if (!encoder_task_runner || !vea) { | 577 if (!encoder_task_runner || !vea) { |
| 577 cast_environment_->PostTask( | 578 cast_environment_->PostTask( |
| 578 CastEnvironment::MAIN, | 579 CastEnvironment::MAIN, |
| 579 FROM_HERE, | 580 FROM_HERE, |
| 580 base::Bind(status_change_cb, STATUS_CODEC_INIT_FAILED)); | 581 base::Bind(status_change_cb, STATUS_CODEC_INIT_FAILED)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 621 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 621 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) | 622 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) |
| 622 : SizeAdaptableVideoEncoderBase(cast_environment, | 623 : SizeAdaptableVideoEncoderBase(cast_environment, |
| 623 video_config, | 624 video_config, |
| 624 status_change_cb), | 625 status_change_cb), |
| 625 create_vea_cb_(create_vea_cb), | 626 create_vea_cb_(create_vea_cb), |
| 626 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} | 627 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} |
| 627 | 628 |
| 628 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} | 629 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} |
| 629 | 630 |
| 630 scoped_ptr<VideoEncoder> SizeAdaptableExternalVideoEncoder::CreateEncoder() { | 631 std::unique_ptr<VideoEncoder> |
| 631 return scoped_ptr<VideoEncoder>(new ExternalVideoEncoder( | 632 SizeAdaptableExternalVideoEncoder::CreateEncoder() { |
| 632 cast_environment(), | 633 return std::unique_ptr<VideoEncoder>(new ExternalVideoEncoder( |
| 633 video_config(), | 634 cast_environment(), video_config(), frame_size(), last_frame_id() + 1, |
| 634 frame_size(), | 635 CreateEncoderStatusChangeCallback(), create_vea_cb_, |
| 635 last_frame_id() + 1, | |
| 636 CreateEncoderStatusChangeCallback(), | |
| 637 create_vea_cb_, | |
| 638 create_video_encode_memory_cb_)); | 636 create_video_encode_memory_cb_)); |
| 639 } | 637 } |
| 640 | 638 |
| 641 QuantizerEstimator::QuantizerEstimator() {} | 639 QuantizerEstimator::QuantizerEstimator() {} |
| 642 | 640 |
| 643 QuantizerEstimator::~QuantizerEstimator() {} | 641 QuantizerEstimator::~QuantizerEstimator() {} |
| 644 | 642 |
| 645 void QuantizerEstimator::Reset() { | 643 void QuantizerEstimator::Reset() { |
| 646 last_frame_pixel_buffer_.reset(); | 644 last_frame_pixel_buffer_.reset(); |
| 647 } | 645 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 const double kEntropyAtMaxQuantizer = 7.5; | 785 const double kEntropyAtMaxQuantizer = 7.5; |
| 788 const double slope = | 786 const double slope = |
| 789 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; | 787 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; |
| 790 const double quantizer = std::min<double>( | 788 const double quantizer = std::min<double>( |
| 791 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); | 789 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); |
| 792 return quantizer; | 790 return quantizer; |
| 793 } | 791 } |
| 794 | 792 |
| 795 } // namespace cast | 793 } // namespace cast |
| 796 } // namespace media | 794 } // namespace media |
| OLD | NEW |