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 |