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 |
11 | 11 |
12 #include <algorithm> // std::max | 12 #include <algorithm> // std::max |
13 | 13 |
14 #include "webrtc/base/checks.h" | 14 #include "webrtc/base/checks.h" |
15 #include "webrtc/base/logging.h" | 15 #include "webrtc/base/logging.h" |
16 #include "webrtc/common_types.h" | 16 #include "webrtc/common_types.h" |
17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
19 #include "webrtc/modules/video_coding/encoded_frame.h" | 19 #include "webrtc/modules/video_coding/encoded_frame.h" |
20 #include "webrtc/modules/video_coding/utility/quality_scaler.h" | 20 #include "webrtc/modules/video_coding/utility/quality_scaler.h" |
21 #include "webrtc/modules/video_coding/video_coding_impl.h" | 21 #include "webrtc/modules/video_coding/video_coding_impl.h" |
22 #include "webrtc/system_wrappers/include/clock.h" | 22 #include "webrtc/system_wrappers/include/clock.h" |
23 | 23 |
24 namespace webrtc { | 24 namespace webrtc { |
25 namespace vcm { | 25 namespace vcm { |
26 | 26 |
27 VideoSender::VideoSender(Clock* clock, | 27 VideoSender::VideoSender(Clock* clock, |
28 EncodedImageCallback* post_encode_callback, | 28 EncodedImageCallback* post_encode_callback, |
29 VideoEncoderRateObserver* encoder_rate_observer, | 29 VideoEncoderRateObserver* encoder_rate_observer, |
30 VCMQMSettingsCallback* qm_settings_callback, | |
31 VCMSendStatisticsCallback* send_stats_callback) | 30 VCMSendStatisticsCallback* send_stats_callback) |
32 : clock_(clock), | 31 : clock_(clock), |
33 _encoder(nullptr), | 32 _encoder(nullptr), |
34 _mediaOpt(clock_), | 33 _mediaOpt(clock_), |
35 _encodedFrameCallback(post_encode_callback, &_mediaOpt), | 34 _encodedFrameCallback(post_encode_callback, &_mediaOpt), |
36 send_stats_callback_(send_stats_callback), | 35 send_stats_callback_(send_stats_callback), |
37 _codecDataBase(encoder_rate_observer, &_encodedFrameCallback), | 36 _codecDataBase(encoder_rate_observer, &_encodedFrameCallback), |
38 frame_dropper_enabled_(true), | 37 frame_dropper_enabled_(true), |
39 _sendStatsTimer(1000, clock_), | 38 _sendStatsTimer(1000, clock_), |
40 current_codec_(), | 39 current_codec_(), |
41 qm_settings_callback_(qm_settings_callback), | |
42 protection_callback_(nullptr), | 40 protection_callback_(nullptr), |
43 encoder_params_({0, 0, 0, 0}), | 41 encoder_params_({0, 0, 0, 0}), |
44 encoder_has_internal_source_(false), | 42 encoder_has_internal_source_(false), |
45 next_frame_types_(1, kVideoFrameDelta) { | 43 next_frame_types_(1, kVideoFrameDelta) { |
| 44 _mediaOpt.Reset(); |
46 // 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 |
47 // 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 |
48 // one external project (diffractor). | 47 // one external project (diffractor). |
49 _mediaOpt.EnableQM(qm_settings_callback_ != nullptr); | |
50 _mediaOpt.Reset(); | |
51 main_thread_.DetachFromThread(); | 48 main_thread_.DetachFromThread(); |
52 } | 49 } |
53 | 50 |
54 VideoSender::~VideoSender() {} | 51 VideoSender::~VideoSender() {} |
55 | 52 |
56 void VideoSender::Process() { | 53 void VideoSender::Process() { |
57 if (_sendStatsTimer.TimeUntilProcess() == 0) { | 54 if (_sendStatsTimer.TimeUntilProcess() == 0) { |
58 // |_sendStatsTimer.Processed()| must be called. Otherwise | 55 // |_sendStatsTimer.Processed()| must be called. Otherwise |
59 // VideoSender::Process() will be called in an infinite loop. | 56 // VideoSender::Process() will be called in an infinite loop. |
60 _sendStatsTimer.Processed(); | 57 _sendStatsTimer.Processed(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 if (!_encoder) | 193 if (!_encoder) |
197 return VCM_UNINITIALIZED; | 194 return VCM_UNINITIALIZED; |
198 | 195 |
199 *framerate = _encoder->GetEncoderParameters().input_frame_rate; | 196 *framerate = _encoder->GetEncoderParameters().input_frame_rate; |
200 return 0; | 197 return 0; |
201 } | 198 } |
202 | 199 |
203 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, | 200 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, |
204 uint8_t lossRate, | 201 uint8_t lossRate, |
205 int64_t rtt) { | 202 int64_t rtt) { |
206 uint32_t target_rate = | 203 uint32_t target_rate = _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt, |
207 _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt, | 204 protection_callback_); |
208 protection_callback_, qm_settings_callback_); | |
209 | 205 |
210 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); | 206 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); |
211 | 207 |
212 EncoderParameters encoder_params = {target_rate, lossRate, rtt, | 208 EncoderParameters encoder_params = {target_rate, lossRate, rtt, |
213 input_frame_rate}; | 209 input_frame_rate}; |
214 bool encoder_has_internal_source; | 210 bool encoder_has_internal_source; |
215 { | 211 { |
216 rtc::CritScope cs(¶ms_crit_); | 212 rtc::CritScope cs(¶ms_crit_); |
217 encoder_params_ = encoder_params; | 213 encoder_params_ = encoder_params; |
218 encoder_has_internal_source = encoder_has_internal_source_; | 214 encoder_has_internal_source = encoder_has_internal_source_; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 case kProtectionNackFEC: | 263 case kProtectionNackFEC: |
268 _mediaOpt.SetProtectionMethod(media_optimization::kNackFec); | 264 _mediaOpt.SetProtectionMethod(media_optimization::kNackFec); |
269 break; | 265 break; |
270 case kProtectionFEC: | 266 case kProtectionFEC: |
271 _mediaOpt.SetProtectionMethod(media_optimization::kFec); | 267 _mediaOpt.SetProtectionMethod(media_optimization::kFec); |
272 break; | 268 break; |
273 } | 269 } |
274 } | 270 } |
275 // Add one raw video frame to the encoder, blocking. | 271 // Add one raw video frame to the encoder, blocking. |
276 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame, | 272 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame, |
277 const VideoContentMetrics* contentMetrics, | |
278 const CodecSpecificInfo* codecSpecificInfo) { | 273 const CodecSpecificInfo* codecSpecificInfo) { |
279 EncoderParameters encoder_params; | 274 EncoderParameters encoder_params; |
280 std::vector<FrameType> next_frame_types; | 275 std::vector<FrameType> next_frame_types; |
281 { | 276 { |
282 rtc::CritScope lock(¶ms_crit_); | 277 rtc::CritScope lock(¶ms_crit_); |
283 encoder_params = encoder_params_; | 278 encoder_params = encoder_params_; |
284 next_frame_types = next_frame_types_; | 279 next_frame_types = next_frame_types_; |
285 } | 280 } |
286 rtc::CritScope lock(&encoder_crit_); | 281 rtc::CritScope lock(&encoder_crit_); |
287 if (_encoder == nullptr) | 282 if (_encoder == nullptr) |
288 return VCM_UNINITIALIZED; | 283 return VCM_UNINITIALIZED; |
289 SetEncoderParameters(encoder_params); | 284 SetEncoderParameters(encoder_params); |
290 if (_mediaOpt.DropFrame()) { | 285 if (_mediaOpt.DropFrame()) { |
291 LOG(LS_VERBOSE) << "Drop Frame " | 286 LOG(LS_VERBOSE) << "Drop Frame " |
292 << "target bitrate " << encoder_params.target_bitrate | 287 << "target bitrate " << encoder_params.target_bitrate |
293 << " loss rate " << encoder_params.loss_rate << " rtt " | 288 << " loss rate " << encoder_params.loss_rate << " rtt " |
294 << encoder_params.rtt << " input frame rate " | 289 << encoder_params.rtt << " input frame rate " |
295 << encoder_params.input_frame_rate; | 290 << encoder_params.input_frame_rate; |
296 _encoder->OnDroppedFrame(); | 291 _encoder->OnDroppedFrame(); |
297 return VCM_OK; | 292 return VCM_OK; |
298 } | 293 } |
299 _mediaOpt.UpdateContentData(contentMetrics); | |
300 // TODO(pbos): Make sure setting send codec is synchronized with video | 294 // TODO(pbos): Make sure setting send codec is synchronized with video |
301 // processing so frame size always matches. | 295 // processing so frame size always matches. |
302 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(), | 296 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(), |
303 videoFrame.height())) { | 297 videoFrame.height())) { |
304 LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping."; | 298 LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping."; |
305 return VCM_PARAMETER_ERROR; | 299 return VCM_PARAMETER_ERROR; |
306 } | 300 } |
307 VideoFrame converted_frame = videoFrame; | 301 VideoFrame converted_frame = videoFrame; |
308 if (converted_frame.video_frame_buffer()->native_handle() && | 302 if (converted_frame.video_frame_buffer()->native_handle() && |
309 !_encoder->SupportsNativeHandle()) { | 303 !_encoder->SupportsNativeHandle()) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 // 10 kbps. | 378 // 10 kbps. |
385 int window_bps = std::max(threshold_bps / 10, 10000); | 379 int window_bps = std::max(threshold_bps / 10, 10000); |
386 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); | 380 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); |
387 } | 381 } |
388 | 382 |
389 bool VideoSender::VideoSuspended() const { | 383 bool VideoSender::VideoSuspended() const { |
390 return _mediaOpt.IsVideoSuspended(); | 384 return _mediaOpt.IsVideoSuspended(); |
391 } | 385 } |
392 } // namespace vcm | 386 } // namespace vcm |
393 } // namespace webrtc | 387 } // namespace webrtc |
OLD | NEW |