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