| 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/gpu/rtc_video_encoder.h" | 5 #include "content/renderer/media/gpu/rtc_video_encoder.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <deque> | 9 #include <deque> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 struct RTCTimestamps { | 40 struct RTCTimestamps { |
| 41 RTCTimestamps(const base::TimeDelta& media_timestamp, int32_t rtp_timestamp) | 41 RTCTimestamps(const base::TimeDelta& media_timestamp, int32_t rtp_timestamp) |
| 42 : media_timestamp_(media_timestamp), rtp_timestamp(rtp_timestamp) {} | 42 : media_timestamp_(media_timestamp), rtp_timestamp(rtp_timestamp) {} |
| 43 const base::TimeDelta media_timestamp_; | 43 const base::TimeDelta media_timestamp_; |
| 44 const int32_t rtp_timestamp; | 44 const int32_t rtp_timestamp; |
| 45 | 45 |
| 46 private: | 46 private: |
| 47 DISALLOW_IMPLICIT_CONSTRUCTORS(RTCTimestamps); | 47 DISALLOW_IMPLICIT_CONSTRUCTORS(RTCTimestamps); |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 webrtc::VideoCodecType ProfileToWebRtcVideoCodecType( | 50 // Translate from webrtc::VideoCodecType and webrtc::VideoCodec to |
| 51 media::VideoCodecProfile profile) { | 51 // media::VideoCodecProfile. |
| 52 if (profile >= media::VP8PROFILE_MIN && profile <= media::VP8PROFILE_MAX) { | 52 media::VideoCodecProfile WebRTCVideoCodecToVideoCodecProfile( |
| 53 return webrtc::kVideoCodecVP8; | 53 webrtc::VideoCodecType type, |
| 54 } else if (profile >= media::H264PROFILE_MIN && | 54 const webrtc::VideoCodec* codec_settings) { |
| 55 profile <= media::H264PROFILE_MAX) { | 55 DCHECK_EQ(type, codec_settings->codecType); |
| 56 return webrtc::kVideoCodecH264; | 56 switch (type) { |
| 57 case webrtc::kVideoCodecVP8: |
| 58 return media::VP8PROFILE_ANY; |
| 59 case webrtc::kVideoCodecVP9: |
| 60 return media::VP9PROFILE_MIN; |
| 61 case webrtc::kVideoCodecH264: |
| 62 // TODO(magjed): WebRTC is only using Baseline profile for now. Update |
| 63 // once http://crbug/webrtc/6337 is fixed. |
| 64 return media::H264PROFILE_BASELINE; |
| 65 default: |
| 66 NOTREACHED() << "Unrecognized video codec type"; |
| 67 return media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| 57 } | 68 } |
| 58 NOTREACHED() << "Invalid profile " << GetProfileName(profile); | |
| 59 return webrtc::kVideoCodecUnknown; | |
| 60 } | 69 } |
| 61 | 70 |
| 62 // Populates struct webrtc::RTPFragmentationHeader for H264 codec. | 71 // Populates struct webrtc::RTPFragmentationHeader for H264 codec. |
| 63 // Each entry specifies the offset and length (excluding start code) of a NALU. | 72 // Each entry specifies the offset and length (excluding start code) of a NALU. |
| 64 // Returns true if successful. | 73 // Returns true if successful. |
| 65 bool GetRTPFragmentationHeaderH264(webrtc::RTPFragmentationHeader* header, | 74 bool GetRTPFragmentationHeaderH264(webrtc::RTPFragmentationHeader* header, |
| 66 const uint8_t* data, uint32_t length) { | 75 const uint8_t* data, uint32_t length) { |
| 67 media::H264Parser parser; | 76 media::H264Parser parser; |
| 68 parser.SetStream(data, length); | 77 parser.SetStream(data, length); |
| 69 | 78 |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 if (result.error != webrtc::EncodedImageCallback::Result::OK) { | 785 if (result.error != webrtc::EncodedImageCallback::Result::OK) { |
| 777 DVLOG(2) | 786 DVLOG(2) |
| 778 << "ReturnEncodedImage(): webrtc::EncodedImageCallback::Result.error = " | 787 << "ReturnEncodedImage(): webrtc::EncodedImageCallback::Result.error = " |
| 779 << result.error; | 788 << result.error; |
| 780 } | 789 } |
| 781 | 790 |
| 782 UseOutputBitstreamBufferId(bitstream_buffer_id); | 791 UseOutputBitstreamBufferId(bitstream_buffer_id); |
| 783 } | 792 } |
| 784 | 793 |
| 785 RTCVideoEncoder::RTCVideoEncoder( | 794 RTCVideoEncoder::RTCVideoEncoder( |
| 786 media::VideoCodecProfile profile, | 795 webrtc::VideoCodecType type, |
| 787 media::GpuVideoAcceleratorFactories* gpu_factories) | 796 media::GpuVideoAcceleratorFactories* gpu_factories) |
| 788 : profile_(profile), | 797 : video_codec_type_(type), |
| 789 gpu_factories_(gpu_factories), | 798 gpu_factories_(gpu_factories), |
| 790 gpu_task_runner_(gpu_factories->GetTaskRunner()) { | 799 gpu_task_runner_(gpu_factories->GetTaskRunner()) { |
| 791 DVLOG(1) << "RTCVideoEncoder(): profile=" << GetProfileName(profile); | 800 DVLOG(1) << "RTCVideoEncoder(): codec type=" << type; |
| 792 } | 801 } |
| 793 | 802 |
| 794 RTCVideoEncoder::~RTCVideoEncoder() { | 803 RTCVideoEncoder::~RTCVideoEncoder() { |
| 795 DVLOG(3) << "~RTCVideoEncoder"; | 804 DVLOG(3) << "~RTCVideoEncoder"; |
| 796 Release(); | 805 Release(); |
| 797 DCHECK(!impl_.get()); | 806 DCHECK(!impl_.get()); |
| 798 } | 807 } |
| 799 | 808 |
| 800 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, | 809 int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings, |
| 801 int32_t number_of_cores, | 810 int32_t number_of_cores, |
| 802 size_t max_payload_size) { | 811 size_t max_payload_size) { |
| 803 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType | 812 DVLOG(1) << "InitEncode(): codecType=" << codec_settings->codecType |
| 804 << ", width=" << codec_settings->width | 813 << ", width=" << codec_settings->width |
| 805 << ", height=" << codec_settings->height | 814 << ", height=" << codec_settings->height |
| 806 << ", startBitrate=" << codec_settings->startBitrate; | 815 << ", startBitrate=" << codec_settings->startBitrate; |
| 807 if (impl_) { | 816 if (impl_) { |
| 808 DVLOG(1) << "Release because of reinitialization"; | 817 DVLOG(1) << "Release because of reinitialization"; |
| 809 Release(); | 818 Release(); |
| 810 } | 819 } |
| 811 | 820 |
| 812 impl_ = new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_)); | 821 impl_ = new Impl(gpu_factories_, video_codec_type_); |
| 822 const media::VideoCodecProfile profile = WebRTCVideoCodecToVideoCodecProfile( |
| 823 impl_->video_codec_type(), codec_settings); |
| 813 | 824 |
| 814 base::WaitableEvent initialization_waiter( | 825 base::WaitableEvent initialization_waiter( |
| 815 base::WaitableEvent::ResetPolicy::MANUAL, | 826 base::WaitableEvent::ResetPolicy::MANUAL, |
| 816 base::WaitableEvent::InitialState::NOT_SIGNALED); | 827 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 817 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 828 int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 818 gpu_task_runner_->PostTask( | 829 gpu_task_runner_->PostTask( |
| 819 FROM_HERE, | 830 FROM_HERE, |
| 820 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, impl_, | 831 base::Bind(&RTCVideoEncoder::Impl::CreateAndInitializeVEA, |
| 832 impl_, |
| 821 gfx::Size(codec_settings->width, codec_settings->height), | 833 gfx::Size(codec_settings->width, codec_settings->height), |
| 822 codec_settings->startBitrate, profile_, &initialization_waiter, | 834 codec_settings->startBitrate, |
| 835 profile, |
| 836 &initialization_waiter, |
| 823 &initialization_retval)); | 837 &initialization_retval)); |
| 824 | 838 |
| 825 // webrtc::VideoEncoder expects this call to be synchronous. | 839 // webrtc::VideoEncoder expects this call to be synchronous. |
| 826 initialization_waiter.Wait(); | 840 initialization_waiter.Wait(); |
| 827 RecordInitEncodeUMA(initialization_retval, profile_); | 841 RecordInitEncodeUMA(initialization_retval, profile); |
| 828 return initialization_retval; | 842 return initialization_retval; |
| 829 } | 843 } |
| 830 | 844 |
| 831 int32_t RTCVideoEncoder::Encode( | 845 int32_t RTCVideoEncoder::Encode( |
| 832 const webrtc::VideoFrame& input_image, | 846 const webrtc::VideoFrame& input_image, |
| 833 const webrtc::CodecSpecificInfo* codec_specific_info, | 847 const webrtc::CodecSpecificInfo* codec_specific_info, |
| 834 const std::vector<webrtc::FrameType>* frame_types) { | 848 const std::vector<webrtc::FrameType>* frame_types) { |
| 835 DVLOG(3) << "Encode()"; | 849 DVLOG(3) << "Encode()"; |
| 836 if (!impl_.get()) { | 850 if (!impl_.get()) { |
| 837 DVLOG(3) << "Encoder is not initialized"; | 851 DVLOG(3) << "Encoder is not initialized"; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", | 949 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoEncoderInitEncodeSuccess", |
| 936 init_retval == WEBRTC_VIDEO_CODEC_OK); | 950 init_retval == WEBRTC_VIDEO_CODEC_OK); |
| 937 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { | 951 if (init_retval == WEBRTC_VIDEO_CODEC_OK) { |
| 938 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", | 952 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoEncoderProfile", |
| 939 profile, | 953 profile, |
| 940 media::VIDEO_CODEC_PROFILE_MAX + 1); | 954 media::VIDEO_CODEC_PROFILE_MAX + 1); |
| 941 } | 955 } |
| 942 } | 956 } |
| 943 | 957 |
| 944 } // namespace content | 958 } // namespace content |
| OLD | NEW |