| 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_recorder/video_track_recorder.h" | 5 #include "content/renderer/media_recorder/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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // Shared memory buffers for output with the VEA as FIFO. | 458 // Shared memory buffers for output with the VEA as FIFO. |
| 459 std::queue<std::unique_ptr<base::SharedMemory>> input_buffers_; | 459 std::queue<std::unique_ptr<base::SharedMemory>> input_buffers_; |
| 460 | 460 |
| 461 // Tracks error status. | 461 // Tracks error status. |
| 462 bool error_notified_; | 462 bool error_notified_; |
| 463 | 463 |
| 464 // Tracks the last frame that we delay the encode. | 464 // Tracks the last frame that we delay the encode. |
| 465 std::unique_ptr<VideoFrameAndTimestamp> last_frame_; | 465 std::unique_ptr<VideoFrameAndTimestamp> last_frame_; |
| 466 | 466 |
| 467 // Size used to initialize encoder. | 467 // Size used to initialize encoder. |
| 468 gfx::Size input_size_; | 468 gfx::Size input_visible_size_; |
| 469 | 469 |
| 470 // Coded size that encoder requests as input. | 470 // Coded size that encoder requests as input. |
| 471 gfx::Size vea_requested_input_size_; | 471 gfx::Size vea_requested_input_coded_size_; |
| 472 | 472 |
| 473 // Frames and corresponding timestamps in encode as FIFO. | 473 // Frames and corresponding timestamps in encode as FIFO. |
| 474 std::queue<VideoParamsAndTimestamp> frames_in_encode_; | 474 std::queue<VideoParamsAndTimestamp> frames_in_encode_; |
| 475 }; | 475 }; |
| 476 | 476 |
| 477 // Class encapsulating all libvpx interactions for VP8/VP9 encoding. | 477 // Class encapsulating all libvpx interactions for VP8/VP9 encoding. |
| 478 class VpxEncoder final : public VideoTrackRecorder::Encoder { | 478 class VpxEncoder final : public VideoTrackRecorder::Encoder { |
| 479 public: | 479 public: |
| 480 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, | 480 static void ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread, |
| 481 ScopedVpxCodecCtxPtr encoder); | 481 ScopedVpxCodecCtxPtr encoder); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 base::Unretained(this), &release_waiter)); | 623 base::Unretained(this), &release_waiter)); |
| 624 release_waiter.Wait(); | 624 release_waiter.Wait(); |
| 625 } | 625 } |
| 626 | 626 |
| 627 void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/, | 627 void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/, |
| 628 const gfx::Size& input_coded_size, | 628 const gfx::Size& input_coded_size, |
| 629 size_t output_buffer_size) { | 629 size_t output_buffer_size) { |
| 630 DVLOG(3) << __func__; | 630 DVLOG(3) << __func__; |
| 631 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 631 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
| 632 | 632 |
| 633 vea_requested_input_size_ = input_coded_size; | 633 vea_requested_input_coded_size_ = input_coded_size; |
| 634 output_buffers_.clear(); | 634 output_buffers_.clear(); |
| 635 std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_); | 635 std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_); |
| 636 | 636 |
| 637 for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) { | 637 for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) { |
| 638 std::unique_ptr<base::SharedMemory> shm = | 638 std::unique_ptr<base::SharedMemory> shm = |
| 639 gpu_factories_->CreateSharedMemory(output_buffer_size); | 639 gpu_factories_->CreateSharedMemory(output_buffer_size); |
| 640 if (shm) | 640 if (shm) |
| 641 output_buffers_.push_back(base::WrapUnique(shm.release())); | 641 output_buffers_.push_back(base::WrapUnique(shm.release())); |
| 642 } | 642 } |
| 643 | 643 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 689 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
| 690 input_buffers_.push(std::move(shm)); | 690 input_buffers_.push(std::move(shm)); |
| 691 } | 691 } |
| 692 | 692 |
| 693 void VEAEncoder::EncodeOnEncodingTaskRunner( | 693 void VEAEncoder::EncodeOnEncodingTaskRunner( |
| 694 scoped_refptr<VideoFrame> frame, | 694 scoped_refptr<VideoFrame> frame, |
| 695 base::TimeTicks capture_timestamp) { | 695 base::TimeTicks capture_timestamp) { |
| 696 DVLOG(3) << __func__; | 696 DVLOG(3) << __func__; |
| 697 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 697 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
| 698 | 698 |
| 699 if (input_size_ != frame->visible_rect().size() && video_encoder_) | 699 if (input_visible_size_ != frame->visible_rect().size() && video_encoder_) |
| 700 video_encoder_.reset(); | 700 video_encoder_.reset(); |
| 701 | 701 |
| 702 if (!video_encoder_) | 702 if (!video_encoder_) |
| 703 ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); | 703 ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); |
| 704 | 704 |
| 705 if (error_notified_) { | 705 if (error_notified_) { |
| 706 DVLOG(3) << "An error occurred in VEA encoder"; | 706 DVLOG(3) << "An error occurred in VEA encoder"; |
| 707 return; | 707 return; |
| 708 } | 708 } |
| 709 | 709 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 723 EncodeOnEncodingTaskRunner(last_frame->first, last_frame->second); | 723 EncodeOnEncodingTaskRunner(last_frame->first, last_frame->second); |
| 724 } | 724 } |
| 725 | 725 |
| 726 // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac. | 726 // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac. |
| 727 // In that case, the encoder expects more frames before returning result. | 727 // In that case, the encoder expects more frames before returning result. |
| 728 // Therefore, a copy is necessary to release the current frame. | 728 // Therefore, a copy is necessary to release the current frame. |
| 729 // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore | 729 // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore |
| 730 // a copy is required for other storage types. | 730 // a copy is required for other storage types. |
| 731 scoped_refptr<media::VideoFrame> video_frame = frame; | 731 scoped_refptr<media::VideoFrame> video_frame = frame; |
| 732 if (video_frame->storage_type() != VideoFrame::STORAGE_SHMEM || | 732 if (video_frame->storage_type() != VideoFrame::STORAGE_SHMEM || |
| 733 vea_requested_input_size_ != input_size_ || | 733 vea_requested_input_coded_size_ != frame->coded_size() || |
| 734 input_size_.width() < kVEAEncoderMinResolutionWidth || | 734 input_visible_size_.width() < kVEAEncoderMinResolutionWidth || |
| 735 input_size_.height() < kVEAEncoderMinResolutionHeight) { | 735 input_visible_size_.height() < kVEAEncoderMinResolutionHeight) { |
| 736 // Create SharedMemory backed input buffers as necessary. These SharedMemory | 736 // Create SharedMemory backed input buffers as necessary. These SharedMemory |
| 737 // instances will be shared with GPU process. | 737 // instances will be shared with GPU process. |
| 738 std::unique_ptr<base::SharedMemory> input_buffer; | 738 std::unique_ptr<base::SharedMemory> input_buffer; |
| 739 const size_t desired_mapped_size = media::VideoFrame::AllocationSize( | 739 const size_t desired_mapped_size = media::VideoFrame::AllocationSize( |
| 740 media::PIXEL_FORMAT_I420, vea_requested_input_size_); | 740 media::PIXEL_FORMAT_I420, vea_requested_input_coded_size_); |
| 741 if (input_buffers_.empty()) { | 741 if (input_buffers_.empty()) { |
| 742 input_buffer = gpu_factories_->CreateSharedMemory(desired_mapped_size); | 742 input_buffer = gpu_factories_->CreateSharedMemory(desired_mapped_size); |
| 743 } else { | 743 } else { |
| 744 do { | 744 do { |
| 745 input_buffer = std::move(input_buffers_.front()); | 745 input_buffer = std::move(input_buffers_.front()); |
| 746 input_buffers_.pop(); | 746 input_buffers_.pop(); |
| 747 } while (!input_buffers_.empty() && | 747 } while (!input_buffers_.empty() && |
| 748 input_buffer->mapped_size() < desired_mapped_size); | 748 input_buffer->mapped_size() < desired_mapped_size); |
| 749 if (!input_buffer || input_buffer->mapped_size() < desired_mapped_size) | 749 if (!input_buffer || input_buffer->mapped_size() < desired_mapped_size) |
| 750 return; | 750 return; |
| 751 } | 751 } |
| 752 | 752 |
| 753 video_frame = media::VideoFrame::WrapExternalSharedMemory( | 753 video_frame = media::VideoFrame::WrapExternalSharedMemory( |
| 754 media::PIXEL_FORMAT_I420, vea_requested_input_size_, | 754 media::PIXEL_FORMAT_I420, vea_requested_input_coded_size_, |
| 755 gfx::Rect(input_size_), input_size_, | 755 gfx::Rect(input_visible_size_), input_visible_size_, |
| 756 reinterpret_cast<uint8_t*>(input_buffer->memory()), | 756 reinterpret_cast<uint8_t*>(input_buffer->memory()), |
| 757 input_buffer->mapped_size(), input_buffer->handle(), 0, | 757 input_buffer->mapped_size(), input_buffer->handle(), 0, |
| 758 frame->timestamp()); | 758 frame->timestamp()); |
| 759 video_frame->AddDestructionObserver(media::BindToCurrentLoop( | 759 video_frame->AddDestructionObserver(media::BindToCurrentLoop( |
| 760 base::Bind(&VEAEncoder::FrameFinished, this, | 760 base::Bind(&VEAEncoder::FrameFinished, this, |
| 761 base::Passed(std::move(input_buffer))))); | 761 base::Passed(std::move(input_buffer))))); |
| 762 libyuv::I420Copy(frame->visible_data(media::VideoFrame::kYPlane), | 762 libyuv::I420Copy(frame->visible_data(media::VideoFrame::kYPlane), |
| 763 frame->stride(media::VideoFrame::kYPlane), | 763 frame->stride(media::VideoFrame::kYPlane), |
| 764 frame->visible_data(media::VideoFrame::kUPlane), | 764 frame->visible_data(media::VideoFrame::kUPlane), |
| 765 frame->stride(media::VideoFrame::kUPlane), | 765 frame->stride(media::VideoFrame::kUPlane), |
| 766 frame->visible_data(media::VideoFrame::kVPlane), | 766 frame->visible_data(media::VideoFrame::kVPlane), |
| 767 frame->stride(media::VideoFrame::kVPlane), | 767 frame->stride(media::VideoFrame::kVPlane), |
| 768 video_frame->visible_data(media::VideoFrame::kYPlane), | 768 video_frame->visible_data(media::VideoFrame::kYPlane), |
| 769 video_frame->stride(media::VideoFrame::kYPlane), | 769 video_frame->stride(media::VideoFrame::kYPlane), |
| 770 video_frame->visible_data(media::VideoFrame::kUPlane), | 770 video_frame->visible_data(media::VideoFrame::kUPlane), |
| 771 video_frame->stride(media::VideoFrame::kUPlane), | 771 video_frame->stride(media::VideoFrame::kUPlane), |
| 772 video_frame->visible_data(media::VideoFrame::kVPlane), | 772 video_frame->visible_data(media::VideoFrame::kVPlane), |
| 773 video_frame->stride(media::VideoFrame::kVPlane), | 773 video_frame->stride(media::VideoFrame::kVPlane), |
| 774 input_size_.width(), input_size_.height()); | 774 input_visible_size_.width(), input_visible_size_.height()); |
| 775 } | 775 } |
| 776 frames_in_encode_.push(std::make_pair( | 776 frames_in_encode_.push(std::make_pair( |
| 777 media::WebmMuxer::VideoParameters(frame), capture_timestamp)); | 777 media::WebmMuxer::VideoParameters(frame), capture_timestamp)); |
| 778 | 778 |
| 779 video_encoder_->Encode(video_frame, false); | 779 video_encoder_->Encode(video_frame, false); |
| 780 } | 780 } |
| 781 | 781 |
| 782 void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { | 782 void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { |
| 783 DVLOG(3) << __func__; | 783 DVLOG(3) << __func__; |
| 784 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 784 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
| 785 DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); | 785 DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); |
| 786 DCHECK_GT(bits_per_second_, 0); | 786 DCHECK_GT(bits_per_second_, 0); |
| 787 | 787 |
| 788 input_size_ = size; | 788 input_visible_size_ = size; |
| 789 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); | 789 video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); |
| 790 if (!video_encoder_ || | 790 if (!video_encoder_ || |
| 791 !video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_size_, codec_, | 791 !video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_visible_size_, |
| 792 bits_per_second_, this)) { | 792 codec_, bits_per_second_, this)) { |
| 793 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 793 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 794 } | 794 } |
| 795 } | 795 } |
| 796 | 796 |
| 797 void VEAEncoder::DestroyOnEncodingTaskRunner( | 797 void VEAEncoder::DestroyOnEncodingTaskRunner( |
| 798 base::WaitableEvent* async_waiter) { | 798 base::WaitableEvent* async_waiter) { |
| 799 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); | 799 DCHECK(encoding_task_runner_->BelongsToCurrentThread()); |
| 800 video_encoder_.reset(); | 800 video_encoder_.reset(); |
| 801 async_waiter->Signal(); | 801 async_waiter->Signal(); |
| 802 } | 802 } |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), | 1336 base::Bind(&VideoTrackRecorder::Encoder::StartFrameEncode, encoder_), |
| 1337 false); | 1337 false); |
| 1338 } | 1338 } |
| 1339 | 1339 |
| 1340 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() { | 1340 bool VideoTrackRecorder::CanEncodeAlphaChannelForTesting() { |
| 1341 DCHECK(encoder_); | 1341 DCHECK(encoder_); |
| 1342 return encoder_->CanEncodeAlphaChannel(); | 1342 return encoder_->CanEncodeAlphaChannel(); |
| 1343 } | 1343 } |
| 1344 | 1344 |
| 1345 } // namespace content | 1345 } // namespace content |
| OLD | NEW |