| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/rtc_video_encoder.h" | 5 #include "content/renderer/media/rtc_video_encoder.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned " | 708 DVLOG(2) << "ReturnEncodedImage(): encoded_image_callback_ returned " |
| 709 << retval; | 709 << retval; |
| 710 } | 710 } |
| 711 | 711 |
| 712 UseOutputBitstreamBufferId(bitstream_buffer_id); | 712 UseOutputBitstreamBufferId(bitstream_buffer_id); |
| 713 } | 713 } |
| 714 | 714 |
| 715 RTCVideoEncoder::RTCVideoEncoder( | 715 RTCVideoEncoder::RTCVideoEncoder( |
| 716 webrtc::VideoCodecType type, | 716 webrtc::VideoCodecType type, |
| 717 media::GpuVideoAcceleratorFactories* gpu_factories) | 717 media::GpuVideoAcceleratorFactories* gpu_factories) |
| 718 : gpu_factories_(gpu_factories), | 718 : video_codec_type_(type), |
| 719 gpu_task_runner_(gpu_factories->GetTaskRunner()), | 719 gpu_factories_(gpu_factories), |
| 720 impl_(new Impl(gpu_factories_, type)) { | 720 gpu_task_runner_(gpu_factories->GetTaskRunner()) { |
| 721 DVLOG(1) << "RTCVideoEncoder(): codec type=" << type; | 721 DVLOG(1) << "RTCVideoEncoder(): codec type=" << type; |
| 722 } | 722 } |
| 723 | 723 |
| 724 RTCVideoEncoder::~RTCVideoEncoder() { | 724 RTCVideoEncoder::~RTCVideoEncoder() { |
| 725 DVLOG(3) << "~RTCVideoEncoder"; | 725 DVLOG(3) << "~RTCVideoEncoder"; |
| 726 Release(); | 726 Release(); |
| 727 DCHECK(!impl_.get()); |
| 727 } | 728 } |
| 728 | 729 |
| 729 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, | 730 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, |
| 730 int32_t number_of_cores, | 731 int32_t number_of_cores, |
| 731 size_t max_payload_size) { | 732 size_t max_payload_size) { |
| 732 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType | 733 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType |
| 733 << ", width=" << codec_settings->width | 734 << ", width=" << codec_settings->width |
| 734 << ", height=" << codec_settings->height | 735 << ", height=" << codec_settings->height |
| 735 << ", startBitrate=" << codec_settings->startBitrate; | 736 << ", startBitrate=" << codec_settings->startBitrate; |
| 737 DCHECK(!impl_.get()); |
| 736 | 738 |
| 739 impl_ = new Impl(gpu_factories_, video_codec_type_); |
| 737 const media::VideoCodecProfile profile = WebRTCVideoCodecToVideoCodecProfile( | 740 const media::VideoCodecProfile profile = WebRTCVideoCodecToVideoCodecProfile( |
| 738 impl_->video_codec_type(), codec_settings); | 741 impl_->video_codec_type(), codec_settings); |
| 739 | 742 |
| 740 base::WaitableEvent initialization_waiter(true, false); | 743 base::WaitableEvent initialization_waiter(true, false); |
| 741 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 744 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 742 gpu_task_runner_->PostTask( | 745 gpu_task_runner_->PostTask( |
| 743 FROM_HERE, | 746 FROM_HERE, |
| 744 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, | 747 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, |
| 745 impl_, | 748 impl_, |
| 746 gfx::Size(codec_settings->width, codec_settings->height), | 749 gfx::Size(codec_settings->width, codec_settings->height), |
| 747 codec_settings->startBitrate, | 750 codec_settings->startBitrate, |
| 748 profile, | 751 profile, |
| 749 &initialization_waiter, | 752 &initialization_waiter, |
| 750 &initialization_retval)); | 753 &initialization_retval)); |
| 751 | 754 |
| 752 // webrtc::VideoEncoder expects this call to be synchronous. | 755 // webrtc::VideoEncoder expects this call to be synchronous. |
| 753 initialization_waiter.Wait(); | 756 initialization_waiter.Wait(); |
| 754 RecordInitEncodeUMA(initialization_retval, profile); | 757 RecordInitEncodeUMA(initialization_retval, profile); |
| 755 return initialization_retval; | 758 return initialization_retval; |
| 756 } | 759 } |
| 757 | 760 |
| 758 int32_t RTCVideoEncoder::Encode( | 761 int32_t RTCVideoEncoder::Encode( |
| 759 const webrtc::VideoFrame& input_image, | 762 const webrtc::VideoFrame& input_image, |
| 760 const webrtc::CodecSpecificInfo* codec_specific_info, | 763 const webrtc::CodecSpecificInfo* codec_specific_info, |
| 761 const std::vector<webrtc::FrameType>* frame_types) { | 764 const std::vector<webrtc::FrameType>* frame_types) { |
| 762 DVLOG(3) << "Encode()"; | 765 DVLOG(3) << "Encode()"; |
| 766 if (!impl_.get()) { |
| 767 DVLOG(3) << "Encoder is not initialized"; |
| 768 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 769 } |
| 763 | 770 |
| 764 const bool want_key_frame = frame_types && frame_types->size() && | 771 const bool want_key_frame = frame_types && frame_types->size() && |
| 765 frame_types->front() == webrtc::kVideoFrameKey; | 772 frame_types->front() == webrtc::kVideoFrameKey; |
| 766 base::WaitableEvent encode_waiter(true, false); | 773 base::WaitableEvent encode_waiter(true, false); |
| 767 int32_t encode_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 774 int32_t encode_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 768 gpu_task_runner_->PostTask( | 775 gpu_task_runner_->PostTask( |
| 769 FROM_HERE, | 776 FROM_HERE, |
| 770 base::Bind(&RTCVideoEncoder::Impl::Enqueue, | 777 base::Bind(&RTCVideoEncoder::Impl::Enqueue, |
| 771 impl_, | 778 impl_, |
| 772 &input_image, | 779 &input_image, |
| 773 want_key_frame, | 780 want_key_frame, |
| 774 &encode_waiter, | 781 &encode_waiter, |
| 775 &encode_retval)); | 782 &encode_retval)); |
| 776 | 783 |
| 777 // webrtc::VideoEncoder expects this call to be synchronous. | 784 // webrtc::VideoEncoder expects this call to be synchronous. |
| 778 encode_waiter.Wait(); | 785 encode_waiter.Wait(); |
| 779 DVLOG(3) << "Encode(): returning encode_retval=" << encode_retval; | 786 DVLOG(3) << "Encode(): returning encode_retval=" << encode_retval; |
| 780 return encode_retval; | 787 return encode_retval; |
| 781 } | 788 } |
| 782 | 789 |
| 783 int32_t RTCVideoEncoder::RegisterEncodeCompleteCallback( | 790 int32_t RTCVideoEncoder::RegisterEncodeCompleteCallback( |
| 784 webrtc::EncodedImageCallback* callback) { | 791 webrtc::EncodedImageCallback* callback) { |
| 785 DVLOG(3) << "RegisterEncodeCompleteCallback()"; | 792 DVLOG(3) << "RegisterEncodeCompleteCallback()"; |
| 793 if (!impl_.get()) { |
| 794 DVLOG(3) << "Encoder is not initialized"; |
| 795 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 796 } |
| 797 |
| 786 base::WaitableEvent register_waiter(true, false); | 798 base::WaitableEvent register_waiter(true, false); |
| 787 int32_t register_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 799 int32_t register_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 788 gpu_task_runner_->PostTask( | 800 gpu_task_runner_->PostTask( |
| 789 FROM_HERE, | 801 FROM_HERE, |
| 790 base::Bind(&RTCVideoEncoder::Impl::RegisterEncodeCompleteCallback, impl_, | 802 base::Bind(&RTCVideoEncoder::Impl::RegisterEncodeCompleteCallback, impl_, |
| 791 ®ister_waiter, ®ister_retval, callback)); | 803 ®ister_waiter, ®ister_retval, callback)); |
| 792 register_waiter.Wait(); | 804 register_waiter.Wait(); |
| 793 return register_retval; | 805 return register_retval; |
| 794 } | 806 } |
| 795 | 807 |
| 796 int32_t RTCVideoEncoder::Release() { | 808 int32_t RTCVideoEncoder::Release() { |
| 797 DVLOG(3) << "Release()"; | 809 DVLOG(3) << "Release()"; |
| 810 if (!impl_.get()) |
| 811 return WEBRTC_VIDEO_CODEC_OK; |
| 798 | 812 |
| 799 base::WaitableEvent release_waiter(true, false); | 813 base::WaitableEvent release_waiter(true, false); |
| 800 gpu_task_runner_->PostTask( | 814 gpu_task_runner_->PostTask( |
| 801 FROM_HERE, | 815 FROM_HERE, |
| 802 base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_, &release_waiter)); | 816 base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_, &release_waiter)); |
| 803 release_waiter.Wait(); | 817 release_waiter.Wait(); |
| 818 impl_ = NULL; |
| 804 return WEBRTC_VIDEO_CODEC_OK; | 819 return WEBRTC_VIDEO_CODEC_OK; |
| 805 } | 820 } |
| 806 | 821 |
| 807 int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, | 822 int32_t RTCVideoEncoder::SetChannelParameters(uint32_t packet_loss, |
| 808 int64_t rtt) { | 823 int64_t rtt) { |
| 809 DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss | 824 DVLOG(3) << "SetChannelParameters(): packet_loss=" << packet_loss |
| 810 << ", rtt=" << rtt; | 825 << ", rtt=" << rtt; |
| 811 // Ignored. | 826 // Ignored. |
| 812 return WEBRTC_VIDEO_CODEC_OK; | 827 return WEBRTC_VIDEO_CODEC_OK; |
| 813 } | 828 } |
| 814 | 829 |
| 815 int32_t RTCVideoEncoder::SetRates(uint32_t new_bit_rate, uint32_t frame_rate) { | 830 int32_t RTCVideoEncoder::SetRates(uint32_t new_bit_rate, uint32_t frame_rate) { |
| 816 DVLOG(3) << "SetRates(): new_bit_rate=" << new_bit_rate | 831 DVLOG(3) << "SetRates(): new_bit_rate=" << new_bit_rate |
| 817 << ", frame_rate=" << frame_rate; | 832 << ", frame_rate=" << frame_rate; |
| 833 if (!impl_.get()) { |
| 834 DVLOG(3) << "Encoder is not initialized"; |
| 835 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 836 } |
| 837 |
| 818 const int32_t retval = impl_->GetStatus(); | 838 const int32_t retval = impl_->GetStatus(); |
| 819 if (retval != WEBRTC_VIDEO_CODEC_OK) { | 839 if (retval != WEBRTC_VIDEO_CODEC_OK) { |
| 820 DVLOG(3) << "SetRates(): returning " << retval; | 840 DVLOG(3) << "SetRates(): returning " << retval; |
| 821 return retval; | 841 return retval; |
| 822 } | 842 } |
| 823 | 843 |
| 824 gpu_task_runner_->PostTask( | 844 gpu_task_runner_->PostTask( |
| 825 FROM_HERE, | 845 FROM_HERE, |
| 826 base::Bind(&RTCVideoEncoder::Impl::RequestEncodingParametersChange, | 846 base::Bind(&RTCVideoEncoder::Impl::RequestEncodingParametersChange, |
| 827 impl_, | 847 impl_, |
| 828 new_bit_rate, | 848 new_bit_rate, |
| 829 frame_rate)); | 849 frame_rate)); |
| 830 return WEBRTC_VIDEO_CODEC_OK; | 850 return WEBRTC_VIDEO_CODEC_OK; |
| 831 } | 851 } |
| 832 | 852 |
| 833 void RTCVideoEncoder::RecordInitEncodeUMA( | 853 void RTCVideoEncoder::RecordInitEncodeUMA( |
| 834 int32_t init_retval, media::VideoCodecProfile profile) { | 854 int32_t init_retval, media::VideoCodecProfile profile) { |
| 835 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", | 855 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", |
| 836 init_retval == WEBRTC_VIDEO_CODEC_OK); | 856 init_retval == WEBRTC_VIDEO_CODEC_OK); |
| 837 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { | 857 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { |
| 838 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", | 858 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", |
| 839 profile, | 859 profile, |
| 840 media::VIDEO_CODEC_PROFILE_MAX + 1); | 860 media::VIDEO_CODEC_PROFILE_MAX + 1); |
| 841 } | 861 } |
| 842 } | 862 } |
| 843 | 863 |
| 844 } // namespace content | 864 } // namespace content |
| OLD | NEW |