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