OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/media/rtc_encoding_video_capturer.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "media/base/encoded_bitstream_buffer.h" | |
9 | |
10 namespace content { | |
11 | |
12 // Client of EncodedVideoSource. | |
13 class RtcEncodingVideoCapturer::EncodedVideoSourceClient : | |
14 public media::EncodedVideoSource::Client { | |
15 public: | |
16 EncodedVideoSourceClient( | |
17 media::EncodedVideoSource* encoded_video_source, | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
doco lifetime
hshi1
2013/06/13 22:03:46
Done.
| |
18 media::VideoEncodingParameters params, | |
19 webrtc::VideoCodecType rtc_codec_type); | |
20 virtual ~EncodedVideoSourceClient(); | |
21 | |
22 // media::EncodedVideoSource::Client implementation. | |
23 virtual void OnStreaming( | |
24 const media::VideoEncodingParameters& params) OVERRIDE; | |
25 virtual void OnClosed() OVERRIDE; | |
26 virtual void OnBufferReady( | |
27 scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE; | |
28 virtual void OnConfigChanged( | |
29 const media::RuntimeVideoEncodingParameters& params) OVERRIDE; | |
30 | |
31 // Getters and setters for bitstream properties. | |
32 bool finished() const; | |
33 media::RuntimeVideoEncodingParameters runtime_params() const; | |
34 void set_round_trip_time(base::TimeDelta round_trip_time); | |
35 void set_callback(webrtc::EncodedImageCallback* callback); | |
36 | |
37 private: | |
38 // Convert buffer to webrtc types and invoke encode complete callback. | |
39 void ReportEncodedFrame( | |
40 scoped_refptr<const media::EncodedBitstreamBuffer> buffer); | |
41 | |
42 media::VideoEncodingParameters params_; | |
43 webrtc::VideoCodecType rtc_codec_type_; | |
44 bool finished_; | |
45 | |
46 base::Time time_base_; | |
47 base::TimeDelta round_trip_time_; | |
48 media::EncodedVideoSource* encoded_video_source_; | |
49 webrtc::EncodedImageCallback* callback_; | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(EncodedVideoSourceClient); | |
52 }; | |
53 | |
54 RtcEncodingVideoCapturer::EncodedVideoSourceClient::EncodedVideoSourceClient( | |
55 media::EncodedVideoSource* encoded_video_source, | |
56 media::VideoEncodingParameters params, | |
57 webrtc::VideoCodecType rtc_codec_type) | |
58 : params_(params), | |
59 rtc_codec_type_(rtc_codec_type), | |
60 finished_(false), | |
61 encoded_video_source_(encoded_video_source), | |
62 callback_(NULL) { | |
63 DCHECK(encoded_video_source_); | |
64 encoded_video_source_->OpenBitstream(this, params); | |
65 } | |
66 | |
67 RtcEncodingVideoCapturer::EncodedVideoSourceClient::~EncodedVideoSourceClient() { | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
80-cols
hshi1
2013/06/12 17:52:39
Done.
| |
68 encoded_video_source_->CloseBitstream(); | |
69 } | |
70 | |
71 bool RtcEncodingVideoCapturer::EncodedVideoSourceClient::finished() const { | |
72 return finished_; | |
73 } | |
74 | |
75 media::RuntimeVideoEncodingParameters | |
76 RtcEncodingVideoCapturer::EncodedVideoSourceClient::runtime_params() const { | |
77 return params_.runtime_params; | |
78 } | |
79 | |
80 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::set_round_trip_time( | |
81 base::TimeDelta round_trip_time) { | |
82 round_trip_time_ = round_trip_time; | |
83 } | |
84 | |
85 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::set_callback( | |
86 webrtc::EncodedImageCallback* callback) { | |
87 DCHECK(!callback_); | |
88 callback_ = callback; | |
89 } | |
90 | |
91 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnStreaming( | |
92 const media::VideoEncodingParameters& params) { | |
93 params_ = params; | |
94 } | |
95 | |
96 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnClosed() { | |
97 finished_ = true; | |
98 } | |
99 | |
100 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnBufferReady( | |
101 scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { | |
102 DCHECK(buffer); | |
103 | |
104 // First buffer constitutes the origin of the time for this bitstream context. | |
105 if (time_base_.is_null()) | |
106 time_base_ = buffer->metadata().timestamp; | |
107 | |
108 ReportEncodedFrame(buffer); | |
109 encoded_video_source_->ReturnBitstreamBuffer(buffer); | |
110 } | |
111 | |
112 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::OnConfigChanged( | |
113 const media::RuntimeVideoEncodingParameters& params) { | |
114 params_.runtime_params = params; | |
115 } | |
116 | |
117 void RtcEncodingVideoCapturer::EncodedVideoSourceClient::ReportEncodedFrame( | |
118 scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { | |
119 if (!callback_) | |
120 return; | |
121 | |
122 webrtc::EncodedImage image; | |
123 webrtc::CodecSpecificInfo codecInfo; | |
124 webrtc::RTPFragmentationHeader fragHeader; | |
125 | |
126 // TODO(hshi): remove this const_cast. Unfortunately webrtc::EncodedImage | |
127 // defines member |_buffer| of type uint8_t* even though webrtc never modifies | |
128 // the buffer contents. | |
129 image._buffer = const_cast<uint8_t*>(buffer->buffer()); | |
130 image._length = buffer->size(); | |
131 image._size = image._length; | |
132 | |
133 const media::BufferEncodingMetadata& metadata = buffer->metadata(); | |
134 base::TimeDelta capture_time = metadata.timestamp - time_base_; | |
135 image.capture_time_ms_ = capture_time.InMilliseconds(); | |
136 // Convert capture time to 90 kHz RTP timestamp. | |
137 image._timeStamp = (capture_time * 90000).InSeconds(); | |
138 if (metadata.key_frame) { | |
139 image._frameType = webrtc::kKeyFrame; | |
140 } else { | |
141 image._frameType = webrtc::kDeltaFrame; | |
142 } | |
143 image._completeFrame = true; | |
144 image._encodedWidth = params_.resolution.width(); | |
145 image._encodedHeight = params_.resolution.height(); | |
146 | |
147 // TODO(hshi): generate codec specific info for VP8. | |
148 codecInfo.codecType = rtc_codec_type_; | |
149 | |
150 // Generate header containing a single fragmentation. | |
151 fragHeader.VerifyAndAllocateFragmentationHeader(1); | |
152 fragHeader.fragmentationOffset[0] = 0; | |
153 fragHeader.fragmentationLength[0] = buffer->size(); | |
154 fragHeader.fragmentationPlType[0] = 0; | |
155 fragHeader.fragmentationTimeDiff[0] = 0; | |
156 | |
157 callback_->Encoded(image, &codecInfo, &fragHeader); | |
158 } | |
159 | |
160 // RtcEncodingVideoCapturer | |
161 RtcEncodingVideoCapturer::RtcEncodingVideoCapturer( | |
162 media::EncodedVideoSource* encoded_video_source, | |
163 webrtc::VideoCodecType codec_type) | |
164 : encoded_video_source_(encoded_video_source), | |
165 rtc_codec_type_(codec_type) { | |
166 } | |
167 | |
168 RtcEncodingVideoCapturer::~RtcEncodingVideoCapturer() { | |
169 } | |
170 | |
171 int32_t RtcEncodingVideoCapturer::InitEncode( | |
172 const webrtc::VideoCodec* codecSettings, | |
173 int32_t numberOfCores, | |
174 uint32_t maxPayloadSize) { | |
175 DCHECK(!encoded_video_source_client_); | |
176 if (codecSettings->codecType != rtc_codec_type_) | |
177 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | |
178 | |
179 // Convert |codecSettings| to |params|. | |
180 media::VideoEncodingParameters params; | |
181 params.codec_name = codecSettings->plName; | |
182 params.resolution = gfx::Size(codecSettings->width, codecSettings->height); | |
183 params.runtime_params.target_bitrate = codecSettings->startBitrate; | |
184 params.runtime_params.max_bitrate = codecSettings->maxBitrate; | |
185 params.runtime_params.frames_per_second = codecSettings->maxFramerate; | |
186 encoded_video_source_client_.reset(new EncodedVideoSourceClient( | |
187 encoded_video_source_, params, rtc_codec_type_)); | |
188 return WEBRTC_VIDEO_CODEC_OK; | |
189 } | |
190 | |
191 int32_t RtcEncodingVideoCapturer::Encode( | |
192 const webrtc::I420VideoFrame& /* inputImage */, | |
193 const webrtc::CodecSpecificInfo* codecSpecificInfo, | |
194 const std::vector<webrtc::VideoFrameType>* frame_types) { | |
195 // TODO(hshi): request specific frame type. | |
196 return WEBRTC_VIDEO_CODEC_OK; | |
197 } | |
198 | |
199 int32_t RtcEncodingVideoCapturer::RegisterEncodeCompleteCallback( | |
200 webrtc::EncodedImageCallback* callback) { | |
201 DCHECK(encoded_video_source_client_); | |
202 encoded_video_source_client_->set_callback(callback); | |
203 return WEBRTC_VIDEO_CODEC_OK; | |
204 } | |
205 | |
206 int32_t RtcEncodingVideoCapturer::Release() { | |
207 DCHECK(encoded_video_source_client_); | |
208 encoded_video_source_client_.reset(NULL); | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
I think you missed:
Are you relying on this movin
hshi1
2013/06/13 22:03:46
This will invoke the dtor of the EVSClient (see En
| |
209 return WEBRTC_VIDEO_CODEC_OK; | |
210 } | |
211 | |
212 int32_t RtcEncodingVideoCapturer::SetChannelParameters( | |
213 uint32_t /* packetLoss */, | |
214 int rtt_in_ms) { | |
215 if (!encoded_video_source_client_) | |
216 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | |
217 encoded_video_source_client_->set_round_trip_time( | |
218 base::TimeDelta::FromMilliseconds(rtt_in_ms)); | |
219 return WEBRTC_VIDEO_CODEC_OK; | |
220 } | |
221 | |
222 int32_t RtcEncodingVideoCapturer::SetRates(uint32_t newBitRate, | |
223 uint32_t frameRate) { | |
224 if (!encoded_video_source_client_) | |
225 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | |
226 // TODO(hshi): wire up runtime rate control. | |
227 return WEBRTC_VIDEO_CODEC_OK; | |
228 } | |
229 | |
230 } // namespace content | |
OLD | NEW |