OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... |
33 _encoder(nullptr), | 33 _encoder(nullptr), |
34 _encodedFrameCallback(post_encode_callback), | 34 _encodedFrameCallback(post_encode_callback), |
35 _nextFrameTypes(1, kVideoFrameDelta), | 35 _nextFrameTypes(1, kVideoFrameDelta), |
36 _mediaOpt(clock_), | 36 _mediaOpt(clock_), |
37 _sendStatsCallback(nullptr), | 37 _sendStatsCallback(nullptr), |
38 _codecDataBase(encoder_rate_observer), | 38 _codecDataBase(encoder_rate_observer), |
39 frame_dropper_enabled_(true), | 39 frame_dropper_enabled_(true), |
40 _sendStatsTimer(1000, clock_), | 40 _sendStatsTimer(1000, clock_), |
41 current_codec_(), | 41 current_codec_(), |
42 qm_settings_callback_(qm_settings_callback), | 42 qm_settings_callback_(qm_settings_callback), |
43 protection_callback_(nullptr) { | 43 protection_callback_(nullptr), |
44 encoder_params_ = {0, 0, 0, 0, false}; | 44 encoder_params_({0, 0, 0, 0}) { |
45 // Allow VideoSender to be created on one thread but used on another, post | 45 // Allow VideoSender to be created on one thread but used on another, post |
46 // construction. This is currently how this class is being used by at least | 46 // construction. This is currently how this class is being used by at least |
47 // one external project (diffractor). | 47 // one external project (diffractor). |
48 _mediaOpt.EnableQM(qm_settings_callback_ != nullptr); | 48 _mediaOpt.EnableQM(qm_settings_callback_ != nullptr); |
49 _mediaOpt.Reset(); | 49 _mediaOpt.Reset(); |
50 main_thread_.DetachFromThread(); | 50 main_thread_.DetachFromThread(); |
51 } | 51 } |
52 | 52 |
53 VideoSender::~VideoSender() {} | 53 VideoSender::~VideoSender() {} |
54 | 54 |
55 int32_t VideoSender::Process() { | 55 int32_t VideoSender::Process() { |
56 int32_t returnValue = VCM_OK; | 56 int32_t returnValue = VCM_OK; |
57 | 57 |
58 if (_sendStatsTimer.TimeUntilProcess() == 0) { | 58 if (_sendStatsTimer.TimeUntilProcess() == 0) { |
59 _sendStatsTimer.Processed(); | 59 _sendStatsTimer.Processed(); |
60 CriticalSectionScoped cs(process_crit_sect_.get()); | 60 CriticalSectionScoped cs(process_crit_sect_.get()); |
61 if (_sendStatsCallback != nullptr) { | 61 if (_sendStatsCallback != nullptr) { |
62 uint32_t bitRate = _mediaOpt.SentBitRate(); | 62 uint32_t bitRate = _mediaOpt.SentBitRate(); |
63 uint32_t frameRate = _mediaOpt.SentFrameRate(); | 63 uint32_t frameRate = _mediaOpt.SentFrameRate(); |
64 _sendStatsCallback->SendStatistics(bitRate, frameRate); | 64 _sendStatsCallback->SendStatistics(bitRate, frameRate); |
65 } | 65 } |
66 } | 66 } |
67 | 67 |
68 { | 68 { |
69 rtc::CritScope cs(¶ms_lock_); | 69 rtc::CritScope cs(¶ms_lock_); |
70 // Force an encoder parameters update, so that incoming frame rate is | 70 // Force an encoder parameters update, so that incoming frame rate is |
71 // updated even if bandwidth hasn't changed. | 71 // updated even if bandwidth hasn't changed. |
72 encoder_params_.input_frame_rate = _mediaOpt.InputFrameRate(); | 72 encoder_params_.input_frame_rate = _mediaOpt.InputFrameRate(); |
73 encoder_params_.updated = true; | |
74 } | 73 } |
75 | 74 |
76 return returnValue; | 75 return returnValue; |
77 } | 76 } |
78 | 77 |
79 int64_t VideoSender::TimeUntilNextProcess() { | 78 int64_t VideoSender::TimeUntilNextProcess() { |
80 return _sendStatsTimer.TimeUntilProcess(); | 79 return _sendStatsTimer.TimeUntilProcess(); |
81 } | 80 } |
82 | 81 |
83 // Register the send codec to be used. | 82 // Register the send codec to be used. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 // Make sure the VCM doesn't use the de-registered codec | 172 // Make sure the VCM doesn't use the de-registered codec |
174 _encoder = nullptr; | 173 _encoder = nullptr; |
175 } | 174 } |
176 return ret ? 0 : -1; | 175 return ret ? 0 : -1; |
177 } | 176 } |
178 _codecDataBase.RegisterExternalEncoder( | 177 _codecDataBase.RegisterExternalEncoder( |
179 externalEncoder, payloadType, internalSource); | 178 externalEncoder, payloadType, internalSource); |
180 return 0; | 179 return 0; |
181 } | 180 } |
182 | 181 |
183 // Get codec config parameters | |
184 int32_t VideoSender::CodecConfigParameters(uint8_t* buffer, | |
185 int32_t size) const { | |
186 rtc::CritScope lock(&send_crit_); | |
187 if (_encoder != nullptr) { | |
188 return _encoder->CodecConfigParameters(buffer, size); | |
189 } | |
190 return VCM_UNINITIALIZED; | |
191 } | |
192 | |
193 // Get encode bitrate | 182 // Get encode bitrate |
194 int VideoSender::Bitrate(unsigned int* bitrate) const { | 183 int VideoSender::Bitrate(unsigned int* bitrate) const { |
195 RTC_DCHECK(main_thread_.CalledOnValidThread()); | 184 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
196 // Since we're running on the thread that's the only thread known to modify | 185 // Since we're running on the thread that's the only thread known to modify |
197 // the value of _encoder, we don't need to grab the lock here. | 186 // the value of _encoder, we don't need to grab the lock here. |
198 | 187 |
199 // return the bit rate which the encoder is set to | 188 if (!_encoder) |
200 if (!_encoder) { | |
201 return VCM_UNINITIALIZED; | 189 return VCM_UNINITIALIZED; |
202 } | 190 *bitrate = _encoder->GetEncoderParameters().target_bitrate; |
203 *bitrate = _encoder->BitRate(); | |
204 return 0; | 191 return 0; |
205 } | 192 } |
206 | 193 |
207 // Get encode frame rate | 194 // Get encode frame rate |
208 int VideoSender::FrameRate(unsigned int* framerate) const { | 195 int VideoSender::FrameRate(unsigned int* framerate) const { |
209 RTC_DCHECK(main_thread_.CalledOnValidThread()); | 196 RTC_DCHECK(main_thread_.CalledOnValidThread()); |
210 // Since we're running on the thread that's the only thread known to modify | 197 // Since we're running on the thread that's the only thread known to modify |
211 // the value of _encoder, we don't need to grab the lock here. | 198 // the value of _encoder, we don't need to grab the lock here. |
212 | 199 |
213 // input frame rate, not compensated | 200 if (!_encoder) |
214 if (!_encoder) { | |
215 return VCM_UNINITIALIZED; | 201 return VCM_UNINITIALIZED; |
216 } | 202 |
217 *framerate = _encoder->FrameRate(); | 203 *framerate = _encoder->GetEncoderParameters().input_frame_rate; |
218 return 0; | 204 return 0; |
219 } | 205 } |
220 | 206 |
221 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, | 207 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, |
222 uint8_t lossRate, | 208 uint8_t lossRate, |
223 int64_t rtt) { | 209 int64_t rtt) { |
224 uint32_t target_rate = | 210 uint32_t target_rate = |
225 _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt, | 211 _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt, |
226 protection_callback_, qm_settings_callback_); | 212 protection_callback_, qm_settings_callback_); |
227 | 213 |
228 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); | 214 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); |
229 | 215 |
230 rtc::CritScope cs(¶ms_lock_); | 216 rtc::CritScope cs(¶ms_lock_); |
231 encoder_params_ = | 217 encoder_params_ = {target_rate, lossRate, rtt, input_frame_rate}; |
232 EncoderParameters{target_rate, lossRate, rtt, input_frame_rate, true}; | |
233 | 218 |
234 return VCM_OK; | 219 return VCM_OK; |
235 } | 220 } |
236 | 221 |
237 void VideoSender::SetEncoderParameters(EncoderParameters params) { | 222 void VideoSender::SetEncoderParameters(EncoderParameters params) { |
238 if (!params.updated || params.target_bitrate == 0) | 223 if (params.target_bitrate == 0) |
239 return; | 224 return; |
240 | 225 |
241 if (params.input_frame_rate == 0) { | 226 if (params.input_frame_rate == 0) { |
242 // No frame rate estimate available, use default. | 227 // No frame rate estimate available, use default. |
243 params.input_frame_rate = current_codec_.maxFramerate; | 228 params.input_frame_rate = current_codec_.maxFramerate; |
244 } | 229 } |
245 if (_encoder != nullptr) { | 230 if (_encoder != nullptr) |
246 _encoder->SetChannelParameters(params.loss_rate, params.rtt); | 231 _encoder->SetEncoderParameters(params); |
247 _encoder->SetRates(params.target_bitrate, params.input_frame_rate); | |
248 } | |
249 return; | |
250 } | 232 } |
251 | 233 |
252 int32_t VideoSender::RegisterTransportCallback( | 234 int32_t VideoSender::RegisterTransportCallback( |
253 VCMPacketizationCallback* transport) { | 235 VCMPacketizationCallback* transport) { |
254 rtc::CritScope lock(&send_crit_); | 236 rtc::CritScope lock(&send_crit_); |
255 _encodedFrameCallback.SetMediaOpt(&_mediaOpt); | 237 _encodedFrameCallback.SetMediaOpt(&_mediaOpt); |
256 _encodedFrameCallback.SetTransportCallback(transport); | 238 _encodedFrameCallback.SetTransportCallback(transport); |
257 return VCM_OK; | 239 return VCM_OK; |
258 } | 240 } |
259 | 241 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 279 } |
298 } | 280 } |
299 // Add one raw video frame to the encoder, blocking. | 281 // Add one raw video frame to the encoder, blocking. |
300 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame, | 282 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame, |
301 const VideoContentMetrics* contentMetrics, | 283 const VideoContentMetrics* contentMetrics, |
302 const CodecSpecificInfo* codecSpecificInfo) { | 284 const CodecSpecificInfo* codecSpecificInfo) { |
303 EncoderParameters encoder_params; | 285 EncoderParameters encoder_params; |
304 { | 286 { |
305 rtc::CritScope lock(¶ms_lock_); | 287 rtc::CritScope lock(¶ms_lock_); |
306 encoder_params = encoder_params_; | 288 encoder_params = encoder_params_; |
307 encoder_params_.updated = false; | |
308 } | 289 } |
309 rtc::CritScope lock(&send_crit_); | 290 rtc::CritScope lock(&send_crit_); |
| 291 if (_encoder == nullptr) |
| 292 return VCM_UNINITIALIZED; |
310 SetEncoderParameters(encoder_params); | 293 SetEncoderParameters(encoder_params); |
311 if (_encoder == nullptr) { | |
312 return VCM_UNINITIALIZED; | |
313 } | |
314 // TODO(holmer): Add support for dropping frames per stream. Currently we | 294 // TODO(holmer): Add support for dropping frames per stream. Currently we |
315 // only have one frame dropper for all streams. | 295 // only have one frame dropper for all streams. |
316 if (_nextFrameTypes[0] == kEmptyFrame) { | 296 if (_nextFrameTypes[0] == kEmptyFrame) { |
317 return VCM_OK; | 297 return VCM_OK; |
318 } | 298 } |
319 if (_mediaOpt.DropFrame()) { | 299 if (_mediaOpt.DropFrame()) { |
320 _encoder->OnDroppedFrame(); | 300 _encoder->OnDroppedFrame(); |
321 return VCM_OK; | 301 return VCM_OK; |
322 } | 302 } |
323 _mediaOpt.UpdateContentData(contentMetrics); | 303 _mediaOpt.UpdateContentData(contentMetrics); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 int window_bps = std::max(threshold_bps / 10, 10000); | 367 int window_bps = std::max(threshold_bps / 10, 10000); |
388 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); | 368 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); |
389 } | 369 } |
390 | 370 |
391 bool VideoSender::VideoSuspended() const { | 371 bool VideoSender::VideoSuspended() const { |
392 rtc::CritScope lock(&send_crit_); | 372 rtc::CritScope lock(&send_crit_); |
393 return _mediaOpt.IsVideoSuspended(); | 373 return _mediaOpt.IsVideoSuspended(); |
394 } | 374 } |
395 } // namespace vcm | 375 } // namespace vcm |
396 } // namespace webrtc | 376 } // namespace webrtc |
OLD | NEW |