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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 } else { | 65 } else { |
66 stream_bitrates[i] = stream_configs[i].maxBitrate * 1000; | 66 stream_bitrates[i] = stream_configs[i].maxBitrate * 1000; |
67 } | 67 } |
68 bitrate_remainder -= stream_bitrates[i]; | 68 bitrate_remainder -= stream_bitrates[i]; |
69 } | 69 } |
70 return stream_bitrates; | 70 return stream_bitrates; |
71 } | 71 } |
72 | 72 |
73 class QMVideoSettingsCallback : public VCMQMSettingsCallback { | 73 class QMVideoSettingsCallback : public VCMQMSettingsCallback { |
74 public: | 74 public: |
75 explicit QMVideoSettingsCallback(VideoProcessingModule* vpm); | 75 explicit QMVideoSettingsCallback(VideoProcessing* vpm); |
76 | 76 |
77 ~QMVideoSettingsCallback(); | 77 ~QMVideoSettingsCallback(); |
78 | 78 |
79 // Update VPM with QM (quality modes: frame size & frame rate) settings. | 79 // Update VPM with QM (quality modes: frame size & frame rate) settings. |
80 int32_t SetVideoQMSettings(const uint32_t frame_rate, | 80 int32_t SetVideoQMSettings(const uint32_t frame_rate, |
81 const uint32_t width, | 81 const uint32_t width, |
82 const uint32_t height); | 82 const uint32_t height); |
83 | 83 |
84 // Update target frame rate. | 84 // Update target frame rate. |
85 void SetTargetFramerate(int frame_rate); | 85 void SetTargetFramerate(int frame_rate); |
86 | 86 |
87 private: | 87 private: |
88 VideoProcessingModule* vpm_; | 88 VideoProcessing* vp_; |
89 }; | 89 }; |
90 | 90 |
91 class ViEBitrateObserver : public BitrateObserver { | 91 class ViEBitrateObserver : public BitrateObserver { |
92 public: | 92 public: |
93 explicit ViEBitrateObserver(ViEEncoder* owner) | 93 explicit ViEBitrateObserver(ViEEncoder* owner) |
94 : owner_(owner) { | 94 : owner_(owner) { |
95 } | 95 } |
96 virtual ~ViEBitrateObserver() {} | 96 virtual ~ViEBitrateObserver() {} |
97 // Implements BitrateObserver. | 97 // Implements BitrateObserver. |
98 virtual void OnNetworkChanged(uint32_t bitrate_bps, | 98 virtual void OnNetworkChanged(uint32_t bitrate_bps, |
99 uint8_t fraction_lost, | 99 uint8_t fraction_lost, |
100 int64_t rtt) { | 100 int64_t rtt) { |
101 owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); | 101 owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); |
102 } | 102 } |
103 private: | 103 private: |
104 ViEEncoder* owner_; | 104 ViEEncoder* owner_; |
105 }; | 105 }; |
106 | 106 |
107 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 107 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
108 ProcessThread* module_process_thread, | 108 ProcessThread* module_process_thread, |
109 SendStatisticsProxy* stats_proxy, | 109 SendStatisticsProxy* stats_proxy, |
110 I420FrameCallback* pre_encode_callback, | 110 I420FrameCallback* pre_encode_callback, |
111 PacedSender* pacer, | 111 PacedSender* pacer, |
112 BitrateAllocator* bitrate_allocator) | 112 BitrateAllocator* bitrate_allocator) |
113 : number_of_cores_(number_of_cores), | 113 : number_of_cores_(number_of_cores), |
114 vpm_(VideoProcessingModule::Create()), | 114 vp_(VideoProcessing::Create()), |
115 qm_callback_(new QMVideoSettingsCallback(vpm_.get())), | 115 qm_callback_(new QMVideoSettingsCallback(vp_.get())), |
116 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), | 116 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), |
117 this, | 117 this, |
118 qm_callback_.get())), | 118 qm_callback_.get())), |
119 send_payload_router_(NULL), | 119 send_payload_router_(NULL), |
120 data_cs_(CriticalSectionWrapper::CreateCriticalSection()), | 120 data_cs_(CriticalSectionWrapper::CreateCriticalSection()), |
121 stats_proxy_(stats_proxy), | 121 stats_proxy_(stats_proxy), |
122 pre_encode_callback_(pre_encode_callback), | 122 pre_encode_callback_(pre_encode_callback), |
123 pacer_(pacer), | 123 pacer_(pacer), |
124 bitrate_allocator_(bitrate_allocator), | 124 bitrate_allocator_(bitrate_allocator), |
125 time_of_last_frame_activity_ms_(0), | 125 time_of_last_frame_activity_ms_(0), |
126 encoder_config_(), | 126 encoder_config_(), |
127 min_transmit_bitrate_kbps_(0), | 127 min_transmit_bitrate_kbps_(0), |
128 last_observed_bitrate_bps_(0), | 128 last_observed_bitrate_bps_(0), |
129 target_delay_ms_(0), | 129 target_delay_ms_(0), |
130 network_is_transmitting_(true), | 130 network_is_transmitting_(true), |
131 encoder_paused_(false), | 131 encoder_paused_(false), |
132 encoder_paused_and_dropped_frame_(false), | 132 encoder_paused_and_dropped_frame_(false), |
133 module_process_thread_(module_process_thread), | 133 module_process_thread_(module_process_thread), |
134 has_received_sli_(false), | 134 has_received_sli_(false), |
135 picture_id_sli_(0), | 135 picture_id_sli_(0), |
136 has_received_rpsi_(false), | 136 has_received_rpsi_(false), |
137 picture_id_rpsi_(0), | 137 picture_id_rpsi_(0), |
138 video_suspended_(false) { | 138 video_suspended_(false) { |
139 bitrate_observer_.reset(new ViEBitrateObserver(this)); | 139 bitrate_observer_.reset(new ViEBitrateObserver(this)); |
140 } | 140 } |
141 | 141 |
142 bool ViEEncoder::Init() { | 142 bool ViEEncoder::Init() { |
143 vpm_->EnableTemporalDecimation(true); | 143 vp_->EnableTemporalDecimation(true); |
144 | 144 |
145 // Enable/disable content analysis: off by default for now. | 145 // Enable/disable content analysis: off by default for now. |
146 vpm_->EnableContentAnalysis(false); | 146 vp_->EnableContentAnalysis(false); |
147 | 147 |
148 if (vcm_->RegisterTransportCallback(this) != 0) { | 148 if (vcm_->RegisterTransportCallback(this) != 0) { |
149 return false; | 149 return false; |
150 } | 150 } |
151 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { | 151 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { |
152 return false; | 152 return false; |
153 } | 153 } |
154 return true; | 154 return true; |
155 } | 155 } |
156 | 156 |
157 void ViEEncoder::StartThreadsAndSetSharedMembers( | 157 void ViEEncoder::StartThreadsAndSetSharedMembers( |
158 rtc::scoped_refptr<PayloadRouter> send_payload_router, | 158 rtc::scoped_refptr<PayloadRouter> send_payload_router, |
159 VCMProtectionCallback* vcm_protection_callback) { | 159 VCMProtectionCallback* vcm_protection_callback) { |
160 RTC_DCHECK(send_payload_router_ == NULL); | 160 RTC_DCHECK(send_payload_router_ == NULL); |
161 | 161 |
162 send_payload_router_ = send_payload_router; | 162 send_payload_router_ = send_payload_router; |
163 vcm_->RegisterProtectionCallback(vcm_protection_callback); | 163 vcm_->RegisterProtectionCallback(vcm_protection_callback); |
164 module_process_thread_->RegisterModule(vcm_.get()); | 164 module_process_thread_->RegisterModule(vcm_.get()); |
165 } | 165 } |
166 | 166 |
167 void ViEEncoder::StopThreadsAndRemoveSharedMembers() { | 167 void ViEEncoder::StopThreadsAndRemoveSharedMembers() { |
168 if (bitrate_allocator_) | 168 if (bitrate_allocator_) |
169 bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); | 169 bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); |
170 module_process_thread_->DeRegisterModule(vcm_.get()); | 170 module_process_thread_->DeRegisterModule(vcm_.get()); |
171 module_process_thread_->DeRegisterModule(vpm_.get()); | |
172 } | 171 } |
173 | 172 |
174 ViEEncoder::~ViEEncoder() { | 173 ViEEncoder::~ViEEncoder() { |
175 } | 174 } |
176 | 175 |
177 void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) { | 176 void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) { |
178 { | 177 { |
179 CriticalSectionScoped cs(data_cs_.get()); | 178 CriticalSectionScoped cs(data_cs_.get()); |
180 network_is_transmitting_ = is_transmitting; | 179 network_is_transmitting_ = is_transmitting; |
181 } | 180 } |
(...skipping 22 matching lines...) Expand all Loading... | |
204 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { | 203 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { |
205 if (vcm_->RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { | 204 if (vcm_->RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { |
206 return -1; | 205 return -1; |
207 } | 206 } |
208 return 0; | 207 return 0; |
209 } | 208 } |
210 | 209 |
211 int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) { | 210 int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) { |
212 RTC_DCHECK(send_payload_router_ != NULL); | 211 RTC_DCHECK(send_payload_router_ != NULL); |
213 // Setting target width and height for VPM. | 212 // Setting target width and height for VPM. |
214 if (vpm_->SetTargetResolution(video_codec.width, video_codec.height, | 213 if (vp_->SetTargetResolution(video_codec.width, video_codec.height, |
215 video_codec.maxFramerate) != VPM_OK) { | 214 video_codec.maxFramerate) != VPM_OK) { |
216 return -1; | 215 return -1; |
217 } | 216 } |
218 | 217 |
219 // Cache codec before calling AddBitrateObserver (which calls OnNetworkChanged | 218 // Cache codec before calling AddBitrateObserver (which calls OnNetworkChanged |
220 // that makes use of the number of simulcast streams configured). | 219 // that makes use of the number of simulcast streams configured). |
221 { | 220 { |
222 CriticalSectionScoped cs(data_cs_.get()); | 221 CriticalSectionScoped cs(data_cs_.get()); |
223 encoder_config_ = video_codec; | 222 encoder_config_ = video_codec; |
224 } | 223 } |
225 | 224 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
351 if (EncoderPaused()) { | 350 if (EncoderPaused()) { |
352 TraceFrameDropStart(); | 351 TraceFrameDropStart(); |
353 return; | 352 return; |
354 } | 353 } |
355 TraceFrameDropEnd(); | 354 TraceFrameDropEnd(); |
356 codec_type = encoder_config_.codecType; | 355 codec_type = encoder_config_.codecType; |
357 } | 356 } |
358 | 357 |
359 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), | 358 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), |
360 "Encode"); | 359 "Encode"); |
361 VideoFrame* decimated_frame = NULL; | 360 const VideoFrame* frame_to_send = &video_frame; |
362 // TODO(wuchengli): support texture frames. | 361 // TODO(wuchengli): support texture frames. |
363 if (video_frame.native_handle() == NULL) { | 362 if (video_frame.native_handle() == NULL) { |
364 // Pass frame via preprocessor. | 363 // Pass frame via preprocessor. |
365 const int ret = vpm_->PreprocessFrame(video_frame, &decimated_frame); | 364 frame_to_send = vp_->PreprocessFrame(video_frame); |
366 if (ret == 1) { | 365 if (frame_to_send == nullptr) { |
pbos-webrtc
2015/11/30 11:51:58
!frame_to_send pref
mflodman
2015/12/04 15:01:08
Done.
| |
367 // Drop this frame. | 366 // Drop this frame, or there was an error processing it. |
368 return; | |
369 } | |
370 if (ret != VPM_OK) { | |
371 return; | 367 return; |
372 } | 368 } |
373 } | 369 } |
374 | 370 |
375 // If we haven't resampled the frame and we have a FrameCallback, we need to | 371 // If we haven't resampled the frame and we have a FrameCallback, we need to |
376 // make a deep copy of |video_frame|. | 372 // make a deep copy of |video_frame|. |
377 VideoFrame copied_frame; | 373 VideoFrame copied_frame; |
378 if (pre_encode_callback_) { | 374 if (pre_encode_callback_) { |
379 // If the frame was not resampled or scaled => use copy of original. | 375 copied_frame.CopyFrame(video_frame); |
pbos-webrtc
2015/11/30 11:51:58
Base this on the preprocessed frame?
mflodman
2015/12/04 15:01:08
Done.
| |
380 if (decimated_frame == NULL) { | 376 pre_encode_callback_->FrameCallback(&copied_frame); |
381 copied_frame.CopyFrame(video_frame); | 377 frame_to_send = &copied_frame; |
382 decimated_frame = &copied_frame; | |
383 } | |
384 pre_encode_callback_->FrameCallback(decimated_frame); | |
385 } | 378 } |
386 | 379 |
387 // If the frame was not resampled, scaled, or touched by FrameCallback => use | |
388 // original. The frame is const from here. | |
389 const VideoFrame* output_frame = | |
390 (decimated_frame != NULL) ? decimated_frame : &video_frame; | |
391 | |
392 if (codec_type == webrtc::kVideoCodecVP8) { | 380 if (codec_type == webrtc::kVideoCodecVP8) { |
393 webrtc::CodecSpecificInfo codec_specific_info; | 381 webrtc::CodecSpecificInfo codec_specific_info; |
394 codec_specific_info.codecType = webrtc::kVideoCodecVP8; | 382 codec_specific_info.codecType = webrtc::kVideoCodecVP8; |
395 { | 383 { |
396 CriticalSectionScoped cs(data_cs_.get()); | 384 CriticalSectionScoped cs(data_cs_.get()); |
397 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = | 385 codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = |
398 has_received_rpsi_; | 386 has_received_rpsi_; |
399 codec_specific_info.codecSpecific.VP8.hasReceivedSLI = | 387 codec_specific_info.codecSpecific.VP8.hasReceivedSLI = |
400 has_received_sli_; | 388 has_received_sli_; |
401 codec_specific_info.codecSpecific.VP8.pictureIdRPSI = | 389 codec_specific_info.codecSpecific.VP8.pictureIdRPSI = |
402 picture_id_rpsi_; | 390 picture_id_rpsi_; |
403 codec_specific_info.codecSpecific.VP8.pictureIdSLI = | 391 codec_specific_info.codecSpecific.VP8.pictureIdSLI = |
404 picture_id_sli_; | 392 picture_id_sli_; |
405 has_received_sli_ = false; | 393 has_received_sli_ = false; |
406 has_received_rpsi_ = false; | 394 has_received_rpsi_ = false; |
407 } | 395 } |
408 | 396 |
409 vcm_->AddVideoFrame(*output_frame, vpm_->ContentMetrics(), | 397 vcm_->AddVideoFrame(*frame_to_send, vp_->GetContentMetrics(), |
410 &codec_specific_info); | 398 &codec_specific_info); |
411 return; | 399 return; |
412 } | 400 } |
413 vcm_->AddVideoFrame(*output_frame); | 401 vcm_->AddVideoFrame(*frame_to_send); |
414 } | 402 } |
415 | 403 |
416 int ViEEncoder::SendKeyFrame() { | 404 int ViEEncoder::SendKeyFrame() { |
417 return vcm_->IntraFrameRequest(0); | 405 return vcm_->IntraFrameRequest(0); |
418 } | 406 } |
419 | 407 |
420 uint32_t ViEEncoder::LastObservedBitrateBps() const { | 408 uint32_t ViEEncoder::LastObservedBitrateBps() const { |
421 CriticalSectionScoped cs(data_cs_.get()); | 409 CriticalSectionScoped cs(data_cs_.get()); |
422 return last_observed_bitrate_bps_; | 410 return last_observed_bitrate_bps_; |
423 } | 411 } |
(...skipping 17 matching lines...) Expand all Loading... | |
441 } | 429 } |
442 | 430 |
443 void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) { | 431 void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) { |
444 { | 432 { |
445 CriticalSectionScoped cs(data_cs_.get()); | 433 CriticalSectionScoped cs(data_cs_.get()); |
446 target_delay_ms_ = target_delay_ms; | 434 target_delay_ms_ = target_delay_ms; |
447 } | 435 } |
448 if (target_delay_ms > 0) { | 436 if (target_delay_ms > 0) { |
449 // Disable external frame-droppers. | 437 // Disable external frame-droppers. |
450 vcm_->EnableFrameDropper(false); | 438 vcm_->EnableFrameDropper(false); |
451 vpm_->EnableTemporalDecimation(false); | 439 vp_->EnableTemporalDecimation(false); |
452 } else { | 440 } else { |
453 // Real-time mode - enable frame droppers. | 441 // Real-time mode - enable frame droppers. |
454 vpm_->EnableTemporalDecimation(true); | 442 vp_->EnableTemporalDecimation(true); |
455 vcm_->EnableFrameDropper(true); | 443 vcm_->EnableFrameDropper(true); |
456 } | 444 } |
457 } | 445 } |
458 | 446 |
459 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { | 447 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { |
460 if (stats_proxy_) | 448 if (stats_proxy_) |
461 stats_proxy_->OnSetRates(bitrate_bps, framerate); | 449 stats_proxy_->OnSetRates(bitrate_bps, framerate); |
462 } | 450 } |
463 | 451 |
464 int32_t ViEEncoder::SendData( | 452 int32_t ViEEncoder::SendData( |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 void ViEEncoder::SuspendBelowMinBitrate() { | 600 void ViEEncoder::SuspendBelowMinBitrate() { |
613 vcm_->SuspendBelowMinBitrate(); | 601 vcm_->SuspendBelowMinBitrate(); |
614 bitrate_allocator_->EnforceMinBitrate(false); | 602 bitrate_allocator_->EnforceMinBitrate(false); |
615 } | 603 } |
616 | 604 |
617 void ViEEncoder::RegisterPostEncodeImageCallback( | 605 void ViEEncoder::RegisterPostEncodeImageCallback( |
618 EncodedImageCallback* post_encode_callback) { | 606 EncodedImageCallback* post_encode_callback) { |
619 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); | 607 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); |
620 } | 608 } |
621 | 609 |
622 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm) | 610 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm) |
623 : vpm_(vpm) { | 611 : vp_(vpm) { |
624 } | 612 } |
625 | 613 |
626 QMVideoSettingsCallback::~QMVideoSettingsCallback() { | 614 QMVideoSettingsCallback::~QMVideoSettingsCallback() { |
627 } | 615 } |
628 | 616 |
629 int32_t QMVideoSettingsCallback::SetVideoQMSettings( | 617 int32_t QMVideoSettingsCallback::SetVideoQMSettings( |
630 const uint32_t frame_rate, | 618 const uint32_t frame_rate, |
631 const uint32_t width, | 619 const uint32_t width, |
632 const uint32_t height) { | 620 const uint32_t height) { |
633 return vpm_->SetTargetResolution(width, height, frame_rate); | 621 return vp_->SetTargetResolution(width, height, frame_rate); |
634 } | 622 } |
635 | 623 |
636 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { | 624 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { |
637 vpm_->SetTargetFramerate(frame_rate); | 625 vp_->SetTargetFramerate(frame_rate); |
638 } | 626 } |
639 | 627 |
640 } // namespace webrtc | 628 } // namespace webrtc |
OLD | NEW |