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 |
11 #include "webrtc/video/vie_encoder.h" | 11 #include "webrtc/video/vie_encoder.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 | 16 |
17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
19 #include "webrtc/base/trace_event.h" | 19 #include "webrtc/base/trace_event.h" |
20 #include "webrtc/call/bitrate_allocator.h" | |
21 #include "webrtc/common_video/include/video_image.h" | 20 #include "webrtc/common_video/include/video_image.h" |
22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
23 #include "webrtc/frame_callback.h" | 22 #include "webrtc/frame_callback.h" |
24 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | |
25 #include "webrtc/modules/pacing/paced_sender.h" | 23 #include "webrtc/modules/pacing/paced_sender.h" |
26 #include "webrtc/modules/utility/include/process_thread.h" | 24 #include "webrtc/modules/utility/include/process_thread.h" |
27 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 25 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
28 #include "webrtc/modules/video_coding/include/video_coding.h" | 26 #include "webrtc/modules/video_coding/include/video_coding.h" |
29 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | 27 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
30 #include "webrtc/system_wrappers/include/clock.h" | 28 #include "webrtc/system_wrappers/include/clock.h" |
31 #include "webrtc/system_wrappers/include/metrics.h" | 29 #include "webrtc/system_wrappers/include/metrics.h" |
32 #include "webrtc/system_wrappers/include/tick_util.h" | 30 #include "webrtc/system_wrappers/include/tick_util.h" |
33 #include "webrtc/video/overuse_frame_detector.h" | 31 #include "webrtc/video/overuse_frame_detector.h" |
34 #include "webrtc/video/payload_router.h" | 32 #include "webrtc/video/payload_router.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 const uint32_t width, | 71 const uint32_t width, |
74 const uint32_t height); | 72 const uint32_t height); |
75 | 73 |
76 // Update target frame rate. | 74 // Update target frame rate. |
77 void SetTargetFramerate(int frame_rate); | 75 void SetTargetFramerate(int frame_rate); |
78 | 76 |
79 private: | 77 private: |
80 VideoProcessing* vp_; | 78 VideoProcessing* vp_; |
81 }; | 79 }; |
82 | 80 |
83 class ViEBitrateObserver : public BitrateObserver { | |
84 public: | |
85 explicit ViEBitrateObserver(ViEEncoder* owner) | |
86 : owner_(owner) { | |
87 } | |
88 virtual ~ViEBitrateObserver() {} | |
89 // Implements BitrateObserver. | |
90 virtual void OnNetworkChanged(uint32_t bitrate_bps, | |
91 uint8_t fraction_lost, | |
92 int64_t rtt) { | |
93 owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); | |
94 } | |
95 private: | |
96 ViEEncoder* owner_; | |
97 }; | |
98 | |
99 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 81 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
100 const std::vector<uint32_t>& ssrcs, | 82 const std::vector<uint32_t>& ssrcs, |
101 ProcessThread* module_process_thread, | 83 ProcessThread* module_process_thread, |
102 SendStatisticsProxy* stats_proxy, | 84 SendStatisticsProxy* stats_proxy, |
103 I420FrameCallback* pre_encode_callback, | 85 I420FrameCallback* pre_encode_callback, |
104 OveruseFrameDetector* overuse_detector, | 86 OveruseFrameDetector* overuse_detector, |
105 PacedSender* pacer, | 87 PacedSender* pacer, |
106 PayloadRouter* payload_router, | 88 PayloadRouter* payload_router) |
107 BitrateAllocator* bitrate_allocator) | |
108 : number_of_cores_(number_of_cores), | 89 : number_of_cores_(number_of_cores), |
109 ssrcs_(ssrcs), | 90 ssrcs_(ssrcs), |
110 vp_(VideoProcessing::Create()), | 91 vp_(VideoProcessing::Create()), |
111 qm_callback_(new QMVideoSettingsCallback(vp_.get())), | 92 qm_callback_(new QMVideoSettingsCallback(vp_.get())), |
112 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), | 93 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), |
113 this, | 94 this, |
114 qm_callback_.get())), | 95 qm_callback_.get())), |
115 stats_proxy_(stats_proxy), | 96 stats_proxy_(stats_proxy), |
116 pre_encode_callback_(pre_encode_callback), | 97 pre_encode_callback_(pre_encode_callback), |
117 overuse_detector_(overuse_detector), | 98 overuse_detector_(overuse_detector), |
118 pacer_(pacer), | 99 pacer_(pacer), |
119 send_payload_router_(payload_router), | 100 send_payload_router_(payload_router), |
120 bitrate_allocator_(bitrate_allocator), | |
121 time_of_last_frame_activity_ms_(0), | 101 time_of_last_frame_activity_ms_(0), |
122 encoder_config_(), | 102 encoder_config_(), |
123 min_transmit_bitrate_bps_(0), | 103 min_transmit_bitrate_bps_(0), |
124 last_observed_bitrate_bps_(0), | 104 last_observed_bitrate_bps_(0), |
125 network_is_transmitting_(true), | 105 network_is_transmitting_(true), |
126 encoder_paused_(false), | 106 encoder_paused_(false), |
127 encoder_paused_and_dropped_frame_(false), | 107 encoder_paused_and_dropped_frame_(false), |
128 time_last_intra_request_ms_(ssrcs.size(), -1), | 108 time_last_intra_request_ms_(ssrcs.size(), -1), |
129 module_process_thread_(module_process_thread), | 109 module_process_thread_(module_process_thread), |
130 has_received_sli_(false), | 110 has_received_sli_(false), |
131 picture_id_sli_(0), | 111 picture_id_sli_(0), |
132 has_received_rpsi_(false), | 112 has_received_rpsi_(false), |
133 picture_id_rpsi_(0), | 113 picture_id_rpsi_(0), |
134 video_suspended_(false) { | 114 video_suspended_(false) { |
135 bitrate_observer_.reset(new ViEBitrateObserver(this)); | |
136 module_process_thread_->RegisterModule(vcm_.get()); | 115 module_process_thread_->RegisterModule(vcm_.get()); |
137 } | 116 } |
138 | 117 |
139 bool ViEEncoder::Init() { | 118 bool ViEEncoder::Init() { |
140 vp_->EnableTemporalDecimation(true); | 119 vp_->EnableTemporalDecimation(true); |
141 | 120 |
142 // Enable/disable content analysis: off by default for now. | 121 // Enable/disable content analysis: off by default for now. |
143 vp_->EnableContentAnalysis(false); | 122 vp_->EnableContentAnalysis(false); |
144 | 123 |
145 if (vcm_->RegisterTransportCallback(this) != 0) { | 124 if (vcm_->RegisterTransportCallback(this) != 0) { |
146 return false; | 125 return false; |
147 } | 126 } |
148 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { | 127 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { |
149 return false; | 128 return false; |
150 } | 129 } |
151 return true; | 130 return true; |
152 } | 131 } |
153 | 132 |
154 VideoCodingModule* ViEEncoder::vcm() const { | 133 VideoCodingModule* ViEEncoder::vcm() const { |
155 return vcm_.get(); | 134 return vcm_.get(); |
156 } | 135 } |
157 | 136 |
158 ViEEncoder::~ViEEncoder() { | 137 ViEEncoder::~ViEEncoder() { |
159 module_process_thread_->DeRegisterModule(vcm_.get()); | 138 module_process_thread_->DeRegisterModule(vcm_.get()); |
160 if (bitrate_allocator_) | |
161 bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); | |
162 } | 139 } |
163 | 140 |
164 void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) { | 141 void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) { |
165 { | 142 { |
166 rtc::CritScope lock(&data_cs_); | 143 rtc::CritScope lock(&data_cs_); |
167 network_is_transmitting_ = is_transmitting; | 144 network_is_transmitting_ = is_transmitting; |
168 } | 145 } |
169 } | 146 } |
170 | 147 |
171 void ViEEncoder::Pause() { | 148 void ViEEncoder::Pause() { |
(...skipping 23 matching lines...) Expand all Loading... |
195 return 0; | 172 return 0; |
196 } | 173 } |
197 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, | 174 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, |
198 int min_transmit_bitrate_bps) { | 175 int min_transmit_bitrate_bps) { |
199 RTC_DCHECK(send_payload_router_ != NULL); | 176 RTC_DCHECK(send_payload_router_ != NULL); |
200 // Setting target width and height for VPM. | 177 // Setting target width and height for VPM. |
201 RTC_CHECK_EQ(VPM_OK, | 178 RTC_CHECK_EQ(VPM_OK, |
202 vp_->SetTargetResolution(video_codec.width, video_codec.height, | 179 vp_->SetTargetResolution(video_codec.width, video_codec.height, |
203 video_codec.maxFramerate)); | 180 video_codec.maxFramerate)); |
204 | 181 |
205 // Cache codec before calling AddBitrateObserver (which calls OnNetworkChanged | 182 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated |
206 // that makes use of the number of simulcast streams configured). | 183 // that makes use of the number of simulcast streams configured). |
207 { | 184 { |
208 rtc::CritScope lock(&data_cs_); | 185 rtc::CritScope lock(&data_cs_); |
209 encoder_config_ = video_codec; | 186 encoder_config_ = video_codec; |
210 encoder_paused_ = true; | 187 encoder_paused_ = true; |
211 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps; | 188 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps; |
212 } | 189 } |
213 | 190 |
214 // Add a bitrate observer to the allocator and update the start, max and | |
215 // min bitrates of the bitrate controller as needed. | |
216 int allocated_bitrate_bps = bitrate_allocator_->AddBitrateObserver( | |
217 bitrate_observer_.get(), video_codec.minBitrate * 1000, | |
218 video_codec.maxBitrate * 1000); | |
219 | |
220 webrtc::VideoCodec modified_video_codec = video_codec; | |
221 modified_video_codec.startBitrate = allocated_bitrate_bps / 1000; | |
222 | |
223 size_t max_data_payload_length = send_payload_router_->MaxPayloadLength(); | 191 size_t max_data_payload_length = send_payload_router_->MaxPayloadLength(); |
224 bool success = vcm_->RegisterSendCodec( | 192 bool success = vcm_->RegisterSendCodec( |
225 &modified_video_codec, number_of_cores_, | 193 &video_codec, number_of_cores_, |
226 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; | 194 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; |
227 if (!success) { | 195 if (!success) { |
228 LOG(LS_ERROR) << "Failed to configure encoder."; | 196 LOG(LS_ERROR) << "Failed to configure encoder."; |
229 RTC_DCHECK(success); | 197 RTC_DCHECK(success); |
230 } | 198 } |
231 | 199 |
232 send_payload_router_->SetSendingRtpModules( | 200 send_payload_router_->SetSendingRtpModules( |
233 video_codec.numberOfSimulcastStreams); | 201 video_codec.numberOfSimulcastStreams); |
234 | 202 |
235 // Restart the media flow | 203 // Restart the media flow |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 return; | 472 return; |
505 } | 473 } |
506 time_last_intra_request_ms_[i] = now_ms; | 474 time_last_intra_request_ms_[i] = now_ms; |
507 } | 475 } |
508 vcm_->IntraFrameRequest(static_cast<int>(i)); | 476 vcm_->IntraFrameRequest(static_cast<int>(i)); |
509 return; | 477 return; |
510 } | 478 } |
511 RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs."; | 479 RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs."; |
512 } | 480 } |
513 | 481 |
514 // Called from ViEBitrateObserver. | 482 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps, |
515 void ViEEncoder::OnNetworkChanged(uint32_t bitrate_bps, | |
516 uint8_t fraction_lost, | 483 uint8_t fraction_lost, |
517 int64_t round_trip_time_ms) { | 484 int64_t round_trip_time_ms) { |
518 LOG(LS_VERBOSE) << "OnNetworkChanged, bitrate" << bitrate_bps | 485 LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate" << bitrate_bps |
519 << " packet loss " << static_cast<int>(fraction_lost) | 486 << " packet loss " << static_cast<int>(fraction_lost) |
520 << " rtt " << round_trip_time_ms; | 487 << " rtt " << round_trip_time_ms; |
521 RTC_DCHECK(send_payload_router_ != NULL); | 488 RTC_DCHECK(send_payload_router_ != NULL); |
522 vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); | 489 vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); |
523 bool video_is_suspended = vcm_->VideoSuspended(); | 490 bool video_is_suspended = vcm_->VideoSuspended(); |
524 bool video_suspension_changed; | 491 bool video_suspension_changed; |
525 VideoCodec send_codec; | 492 VideoCodec send_codec; |
526 { | 493 { |
527 rtc::CritScope lock(&data_cs_); | 494 rtc::CritScope lock(&data_cs_); |
528 last_observed_bitrate_bps_ = bitrate_bps; | 495 last_observed_bitrate_bps_ = bitrate_bps; |
(...skipping 10 matching lines...) Expand all Loading... |
539 | 506 |
540 if (!video_suspension_changed) | 507 if (!video_suspension_changed) |
541 return; | 508 return; |
542 // Video suspend-state changed, inform codec observer. | 509 // Video suspend-state changed, inform codec observer. |
543 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended | 510 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended |
544 << " for ssrc " << ssrcs_[0]; | 511 << " for ssrc " << ssrcs_[0]; |
545 if (stats_proxy_) | 512 if (stats_proxy_) |
546 stats_proxy_->OnSuspendChange(video_is_suspended); | 513 stats_proxy_->OnSuspendChange(video_is_suspended); |
547 } | 514 } |
548 | 515 |
549 void ViEEncoder::SuspendBelowMinBitrate() { | |
550 vcm_->SuspendBelowMinBitrate(); | |
551 bitrate_allocator_->EnforceMinBitrate(false); | |
552 } | |
553 | |
554 void ViEEncoder::RegisterPostEncodeImageCallback( | 516 void ViEEncoder::RegisterPostEncodeImageCallback( |
555 EncodedImageCallback* post_encode_callback) { | 517 EncodedImageCallback* post_encode_callback) { |
556 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); | 518 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); |
557 } | 519 } |
558 | 520 |
559 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm) | 521 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm) |
560 : vp_(vpm) { | 522 : vp_(vpm) { |
561 } | 523 } |
562 | 524 |
563 QMVideoSettingsCallback::~QMVideoSettingsCallback() { | 525 QMVideoSettingsCallback::~QMVideoSettingsCallback() { |
564 } | 526 } |
565 | 527 |
566 int32_t QMVideoSettingsCallback::SetVideoQMSettings( | 528 int32_t QMVideoSettingsCallback::SetVideoQMSettings( |
567 const uint32_t frame_rate, | 529 const uint32_t frame_rate, |
568 const uint32_t width, | 530 const uint32_t width, |
569 const uint32_t height) { | 531 const uint32_t height) { |
570 return vp_->SetTargetResolution(width, height, frame_rate); | 532 return vp_->SetTargetResolution(width, height, frame_rate); |
571 } | 533 } |
572 | 534 |
573 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { | 535 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { |
574 vp_->SetTargetFramerate(frame_rate); | 536 vp_->SetTargetFramerate(frame_rate); |
575 } | 537 } |
576 | 538 |
577 } // namespace webrtc | 539 } // namespace webrtc |
OLD | NEW |