OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 20 matching lines...) Expand all Loading... | |
31 #include "webrtc/video/overuse_frame_detector.h" | 31 #include "webrtc/video/overuse_frame_detector.h" |
32 #include "webrtc/video/payload_router.h" | 32 #include "webrtc/video/payload_router.h" |
33 #include "webrtc/video/send_statistics_proxy.h" | 33 #include "webrtc/video/send_statistics_proxy.h" |
34 #include "webrtc/video_frame.h" | 34 #include "webrtc/video_frame.h" |
35 | 35 |
36 namespace webrtc { | 36 namespace webrtc { |
37 | 37 |
38 static const float kStopPaddingThresholdMs = 2000; | 38 static const float kStopPaddingThresholdMs = 2000; |
39 static const int kMinKeyFrameRequestIntervalMs = 300; | 39 static const int kMinKeyFrameRequestIntervalMs = 300; |
40 | 40 |
41 std::vector<uint32_t> AllocateStreamBitrates( | |
42 uint32_t total_bitrate, | |
43 const SimulcastStream* stream_configs, | |
44 size_t number_of_streams) { | |
45 if (number_of_streams == 0) { | |
46 std::vector<uint32_t> stream_bitrates(1, 0); | |
47 stream_bitrates[0] = total_bitrate; | |
48 return stream_bitrates; | |
49 } | |
50 std::vector<uint32_t> stream_bitrates(number_of_streams, 0); | |
51 uint32_t bitrate_remainder = total_bitrate; | |
52 for (size_t i = 0; i < stream_bitrates.size() && bitrate_remainder > 0; ++i) { | |
53 if (stream_configs[i].maxBitrate * 1000 > bitrate_remainder) { | |
54 stream_bitrates[i] = bitrate_remainder; | |
55 } else { | |
56 stream_bitrates[i] = stream_configs[i].maxBitrate * 1000; | |
57 } | |
58 bitrate_remainder -= stream_bitrates[i]; | |
59 } | |
60 return stream_bitrates; | |
61 } | |
62 | |
63 class QMVideoSettingsCallback : public VCMQMSettingsCallback { | 41 class QMVideoSettingsCallback : public VCMQMSettingsCallback { |
64 public: | 42 public: |
65 explicit QMVideoSettingsCallback(VideoProcessing* vpm); | 43 explicit QMVideoSettingsCallback(VideoProcessing* vpm); |
66 | 44 |
67 ~QMVideoSettingsCallback(); | 45 ~QMVideoSettingsCallback(); |
68 | 46 |
69 // Update VPM with QM (quality modes: frame size & frame rate) settings. | 47 // Update VPM with QM (quality modes: frame size & frame rate) settings. |
70 int32_t SetVideoQMSettings(const uint32_t frame_rate, | 48 int32_t SetVideoQMSettings(const uint32_t frame_rate, |
71 const uint32_t width, | 49 const uint32_t width, |
72 const uint32_t height); | 50 const uint32_t height); |
73 | 51 |
74 // Update target frame rate. | 52 // Update target frame rate. |
75 void SetTargetFramerate(int frame_rate); | 53 void SetTargetFramerate(int frame_rate); |
76 | 54 |
77 private: | 55 private: |
78 VideoProcessing* vp_; | 56 VideoProcessing* vp_; |
79 }; | 57 }; |
80 | 58 |
81 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 59 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
82 const std::vector<uint32_t>& ssrcs, | 60 const std::vector<uint32_t>& ssrcs, |
83 ProcessThread* module_process_thread, | 61 ProcessThread* module_process_thread, |
84 SendStatisticsProxy* stats_proxy, | 62 SendStatisticsProxy* stats_proxy, |
85 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, | 63 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, |
86 OveruseFrameDetector* overuse_detector, | 64 OveruseFrameDetector* overuse_detector, |
87 PacedSender* pacer, | 65 PacedSender* pacer) |
88 PayloadRouter* payload_router, | |
89 EncodedImageCallback* post_encode_callback) | |
90 : number_of_cores_(number_of_cores), | 66 : number_of_cores_(number_of_cores), |
91 ssrcs_(ssrcs), | 67 ssrcs_(ssrcs), |
92 vp_(VideoProcessing::Create()), | 68 vp_(VideoProcessing::Create()), |
93 qm_callback_(new QMVideoSettingsCallback(vp_.get())), | 69 qm_callback_(new QMVideoSettingsCallback(vp_.get())), |
94 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), | 70 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), |
95 this, | 71 this, |
96 qm_callback_.get())), | 72 qm_callback_.get())), |
97 stats_proxy_(stats_proxy), | 73 stats_proxy_(stats_proxy), |
98 pre_encode_callback_(pre_encode_callback), | 74 pre_encode_callback_(pre_encode_callback), |
99 overuse_detector_(overuse_detector), | 75 overuse_detector_(overuse_detector), |
100 pacer_(pacer), | 76 pacer_(pacer), |
101 send_payload_router_(payload_router), | |
102 post_encode_callback_(post_encode_callback), | |
103 time_of_last_frame_activity_ms_(0), | 77 time_of_last_frame_activity_ms_(0), |
104 encoder_config_(), | 78 encoder_config_(), |
105 min_transmit_bitrate_bps_(0), | 79 min_transmit_bitrate_bps_(0), |
106 last_observed_bitrate_bps_(0), | 80 last_observed_bitrate_bps_(0), |
107 network_is_transmitting_(true), | 81 network_is_transmitting_(true), |
108 encoder_paused_(false), | 82 encoder_paused_(true), |
109 encoder_paused_and_dropped_frame_(false), | 83 encoder_paused_and_dropped_frame_(false), |
110 time_last_intra_request_ms_(ssrcs.size(), -1), | 84 time_last_intra_request_ms_(ssrcs.size(), -1), |
111 module_process_thread_(module_process_thread), | 85 module_process_thread_(module_process_thread), |
112 has_received_sli_(false), | 86 has_received_sli_(false), |
113 picture_id_sli_(0), | 87 picture_id_sli_(0), |
114 has_received_rpsi_(false), | 88 has_received_rpsi_(false), |
115 picture_id_rpsi_(0), | 89 picture_id_rpsi_(0), |
116 video_suspended_(false) { | 90 video_suspended_(false) { |
117 module_process_thread_->RegisterModule(vcm_.get()); | 91 module_process_thread_->RegisterModule(vcm_.get()); |
118 } | 92 } |
(...skipping 30 matching lines...) Expand all Loading... | |
149 rtc::CritScope lock(&data_cs_); | 123 rtc::CritScope lock(&data_cs_); |
150 network_is_transmitting_ = is_transmitting; | 124 network_is_transmitting_ = is_transmitting; |
151 } | 125 } |
152 } | 126 } |
153 | 127 |
154 void ViEEncoder::Pause() { | 128 void ViEEncoder::Pause() { |
155 rtc::CritScope lock(&data_cs_); | 129 rtc::CritScope lock(&data_cs_); |
156 encoder_paused_ = true; | 130 encoder_paused_ = true; |
157 } | 131 } |
158 | 132 |
159 void ViEEncoder::Restart() { | 133 void ViEEncoder::Start() { |
160 rtc::CritScope lock(&data_cs_); | 134 rtc::CritScope lock(&data_cs_); |
161 encoder_paused_ = false; | 135 encoder_paused_ = false; |
162 } | 136 } |
163 | 137 |
164 int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, | 138 int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, |
165 uint8_t pl_type, | 139 uint8_t pl_type, |
166 bool internal_source) { | 140 bool internal_source) { |
167 if (vcm_->RegisterExternalEncoder(encoder, pl_type, internal_source) != | 141 if (vcm_->RegisterExternalEncoder(encoder, pl_type, internal_source) != |
168 VCM_OK) { | 142 VCM_OK) { |
169 return -1; | 143 return -1; |
170 } | 144 } |
171 return 0; | 145 return 0; |
172 } | 146 } |
173 | 147 |
174 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { | 148 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { |
175 if (vcm_->RegisterExternalEncoder(nullptr, pl_type) != VCM_OK) { | 149 if (vcm_->RegisterExternalEncoder(nullptr, pl_type) != VCM_OK) { |
176 return -1; | 150 return -1; |
177 } | 151 } |
178 return 0; | 152 return 0; |
179 } | 153 } |
180 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, | 154 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, |
181 int min_transmit_bitrate_bps) { | 155 int min_transmit_bitrate_bps, |
182 RTC_DCHECK(send_payload_router_); | 156 size_t max_data_payload_length, |
157 EncodedImageCallback* sink) { | |
183 // Setting target width and height for VPM. | 158 // Setting target width and height for VPM. |
184 RTC_CHECK_EQ(VPM_OK, | 159 RTC_CHECK_EQ(VPM_OK, |
185 vp_->SetTargetResolution(video_codec.width, video_codec.height, | 160 vp_->SetTargetResolution(video_codec.width, video_codec.height, |
186 video_codec.maxFramerate)); | 161 video_codec.maxFramerate)); |
187 | 162 |
188 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated | 163 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated |
189 // that makes use of the number of simulcast streams configured). | 164 // that makes use of the number of simulcast streams configured). |
190 { | 165 { |
191 rtc::CritScope lock(&data_cs_); | 166 rtc::CritScope lock(&data_cs_); |
192 encoder_config_ = video_codec; | 167 encoder_config_ = video_codec; |
193 encoder_paused_ = true; | |
194 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps; | 168 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps; |
195 } | 169 } |
170 { | |
171 rtc::CritScope lock(&sink_cs_); | |
172 sink_ = sink; | |
173 } | |
196 | 174 |
197 size_t max_data_payload_length = send_payload_router_->MaxPayloadLength(); | |
198 bool success = vcm_->RegisterSendCodec( | 175 bool success = vcm_->RegisterSendCodec( |
199 &video_codec, number_of_cores_, | 176 &video_codec, number_of_cores_, |
200 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; | 177 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; |
201 if (!success) { | 178 if (!success) { |
202 LOG(LS_ERROR) << "Failed to configure encoder."; | 179 LOG(LS_ERROR) << "Failed to configure encoder."; |
203 RTC_DCHECK(success); | 180 RTC_DCHECK(success); |
204 } | 181 } |
205 | 182 |
206 send_payload_router_->SetSendingRtpModules( | |
207 video_codec.numberOfSimulcastStreams); | |
208 | |
209 // Restart the media flow | |
210 Restart(); | |
211 if (stats_proxy_) { | 183 if (stats_proxy_) { |
212 // Clear stats for disabled layers. | 184 // Clear stats for disabled layers. |
213 for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size(); | 185 for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size(); |
214 ++i) { | 186 ++i) { |
215 stats_proxy_->OnInactiveSsrc(ssrcs_[i]); | 187 stats_proxy_->OnInactiveSsrc(ssrcs_[i]); |
216 } | 188 } |
217 VideoEncoderConfig::ContentType content_type = | 189 VideoEncoderConfig::ContentType content_type = |
218 VideoEncoderConfig::ContentType::kRealtimeVideo; | 190 VideoEncoderConfig::ContentType::kRealtimeVideo; |
219 switch (video_codec.mode) { | 191 switch (video_codec.mode) { |
220 case kRealtimeVideo: | 192 case kRealtimeVideo: |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 | 284 |
313 void ViEEncoder::TraceFrameDropEnd() { | 285 void ViEEncoder::TraceFrameDropEnd() { |
314 // End trace event on first frame after encoder resumes, if frame was dropped. | 286 // End trace event on first frame after encoder resumes, if frame was dropped. |
315 if (encoder_paused_and_dropped_frame_) { | 287 if (encoder_paused_and_dropped_frame_) { |
316 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); | 288 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); |
317 } | 289 } |
318 encoder_paused_and_dropped_frame_ = false; | 290 encoder_paused_and_dropped_frame_ = false; |
319 } | 291 } |
320 | 292 |
321 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) { | 293 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) { |
322 if (!send_payload_router_->active()) { | |
323 // We've paused or we have no channels attached, don't waste resources on | |
324 // encoding. | |
325 return; | |
326 } | |
327 VideoCodecType codec_type; | 294 VideoCodecType codec_type; |
328 { | 295 { |
329 rtc::CritScope lock(&data_cs_); | 296 rtc::CritScope lock(&data_cs_); |
330 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); | 297 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); |
331 if (EncoderPaused()) { | 298 if (EncoderPaused()) { |
332 TraceFrameDropStart(); | 299 TraceFrameDropStart(); |
333 return; | 300 return; |
334 } | 301 } |
335 TraceFrameDropEnd(); | 302 TraceFrameDropEnd(); |
336 codec_type = encoder_config_.codecType; | 303 codec_type = encoder_config_.codecType; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 } | 377 } |
411 | 378 |
412 void ViEEncoder::OnEncoderImplementationName(const char* implementation_name) { | 379 void ViEEncoder::OnEncoderImplementationName(const char* implementation_name) { |
413 if (stats_proxy_) | 380 if (stats_proxy_) |
414 stats_proxy_->OnEncoderImplementationName(implementation_name); | 381 stats_proxy_->OnEncoderImplementationName(implementation_name); |
415 } | 382 } |
416 | 383 |
417 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image, | 384 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image, |
418 const CodecSpecificInfo* codec_specific_info, | 385 const CodecSpecificInfo* codec_specific_info, |
419 const RTPFragmentationHeader* fragmentation) { | 386 const RTPFragmentationHeader* fragmentation) { |
420 RTC_DCHECK(send_payload_router_); | |
421 | |
422 { | 387 { |
423 rtc::CritScope lock(&data_cs_); | 388 rtc::CritScope lock(&data_cs_); |
424 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); | 389 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); |
425 } | 390 } |
426 | |
427 if (post_encode_callback_) { | |
428 post_encode_callback_->Encoded(encoded_image, codec_specific_info, | |
429 fragmentation); | |
430 } | |
431 | |
432 if (stats_proxy_) { | 391 if (stats_proxy_) { |
433 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); | 392 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); |
434 } | 393 } |
435 int success = send_payload_router_->Encoded( | 394 |
436 encoded_image, codec_specific_info, fragmentation); | 395 int success = 0; |
396 { | |
397 rtc::CritScope lock(&sink_cs_); | |
398 sink_->Encoded(encoded_image, codec_specific_info, fragmentation); | |
sprang_webrtc
2016/04/22 11:38:20
succeess = sink_->Encoded() ?
Or remove success if
perkj_webrtc
2016/04/27 08:00:57
oops. I think it one day should be removed.
| |
399 } | |
400 | |
437 overuse_detector_->FrameSent(encoded_image._timeStamp); | 401 overuse_detector_->FrameSent(encoded_image._timeStamp); |
438 | |
439 if (kEnableFrameRecording) { | 402 if (kEnableFrameRecording) { |
440 int layer = codec_specific_info->codecType == kVideoCodecVP8 | 403 int layer = codec_specific_info->codecType == kVideoCodecVP8 |
441 ? codec_specific_info->codecSpecific.VP8.simulcastIdx | 404 ? codec_specific_info->codecSpecific.VP8.simulcastIdx |
442 : 0; | 405 : 0; |
443 IvfFileWriter* file_writer; | 406 IvfFileWriter* file_writer; |
444 { | 407 { |
445 rtc::CritScope lock(&data_cs_); | 408 rtc::CritScope lock(&data_cs_); |
446 if (file_writers_[layer] == nullptr) { | 409 if (file_writers_[layer] == nullptr) { |
447 std::ostringstream oss; | 410 std::ostringstream oss; |
448 oss << "send_bitstream_ssrc"; | 411 oss << "send_bitstream_ssrc"; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 } | 468 } |
506 RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs."; | 469 RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs."; |
507 } | 470 } |
508 | 471 |
509 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps, | 472 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps, |
510 uint8_t fraction_lost, | 473 uint8_t fraction_lost, |
511 int64_t round_trip_time_ms) { | 474 int64_t round_trip_time_ms) { |
512 LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate" << bitrate_bps | 475 LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate" << bitrate_bps |
513 << " packet loss " << static_cast<int>(fraction_lost) | 476 << " packet loss " << static_cast<int>(fraction_lost) |
514 << " rtt " << round_trip_time_ms; | 477 << " rtt " << round_trip_time_ms; |
515 RTC_DCHECK(send_payload_router_); | |
516 vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); | 478 vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); |
517 bool video_is_suspended = vcm_->VideoSuspended(); | 479 bool video_is_suspended = vcm_->VideoSuspended(); |
518 bool video_suspension_changed; | 480 bool video_suspension_changed; |
519 VideoCodec send_codec; | |
520 { | 481 { |
521 rtc::CritScope lock(&data_cs_); | 482 rtc::CritScope lock(&data_cs_); |
522 last_observed_bitrate_bps_ = bitrate_bps; | 483 last_observed_bitrate_bps_ = bitrate_bps; |
523 video_suspension_changed = video_suspended_ != video_is_suspended; | 484 video_suspension_changed = video_suspended_ != video_is_suspended; |
524 video_suspended_ = video_is_suspended; | 485 video_suspended_ = video_is_suspended; |
525 send_codec = encoder_config_; | |
526 } | 486 } |
527 | 487 |
528 SimulcastStream* stream_configs = send_codec.simulcastStream; | |
529 // Allocate the bandwidth between the streams. | |
530 std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates( | |
531 bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams); | |
532 send_payload_router_->SetTargetSendBitrates(stream_bitrates); | |
533 | |
534 if (!video_suspension_changed) | 488 if (!video_suspension_changed) |
535 return; | 489 return; |
536 // Video suspend-state changed, inform codec observer. | 490 // Video suspend-state changed, inform codec observer. |
537 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended | 491 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended |
538 << " for ssrc " << ssrcs_[0]; | 492 << " for ssrc " << ssrcs_[0]; |
539 if (stats_proxy_) | 493 if (stats_proxy_) |
540 stats_proxy_->OnSuspendChange(video_is_suspended); | 494 stats_proxy_->OnSuspendChange(video_is_suspended); |
541 } | 495 } |
542 | 496 |
543 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm) | 497 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm) |
544 : vp_(vpm) { | 498 : vp_(vpm) { |
545 } | 499 } |
546 | 500 |
547 QMVideoSettingsCallback::~QMVideoSettingsCallback() { | 501 QMVideoSettingsCallback::~QMVideoSettingsCallback() { |
548 } | 502 } |
549 | 503 |
550 int32_t QMVideoSettingsCallback::SetVideoQMSettings( | 504 int32_t QMVideoSettingsCallback::SetVideoQMSettings( |
551 const uint32_t frame_rate, | 505 const uint32_t frame_rate, |
552 const uint32_t width, | 506 const uint32_t width, |
553 const uint32_t height) { | 507 const uint32_t height) { |
554 return vp_->SetTargetResolution(width, height, frame_rate); | 508 return vp_->SetTargetResolution(width, height, frame_rate); |
555 } | 509 } |
556 | 510 |
557 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { | 511 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { |
558 vp_->SetTargetFramerate(frame_rate); | 512 vp_->SetTargetFramerate(frame_rate); |
559 } | 513 } |
560 | 514 |
561 } // namespace webrtc | 515 } // namespace webrtc |
OLD | NEW |