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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 uint8_t fraction_lost, | 97 uint8_t fraction_lost, |
98 int64_t rtt) { | 98 int64_t rtt) { |
99 owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); | 99 owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); |
100 } | 100 } |
101 private: | 101 private: |
102 ViEEncoder* owner_; | 102 ViEEncoder* owner_; |
103 }; | 103 }; |
104 | 104 |
105 ViEEncoder::ViEEncoder(int32_t channel_id, | 105 ViEEncoder::ViEEncoder(int32_t channel_id, |
106 uint32_t number_of_cores, | 106 uint32_t number_of_cores, |
107 ProcessThread& module_process_thread, | 107 ProcessThread* module_process_thread, |
| 108 SendStatisticsProxy* stats_proxy, |
| 109 I420FrameCallback* pre_encode_callback, |
108 PacedSender* pacer, | 110 PacedSender* pacer, |
109 BitrateAllocator* bitrate_allocator) | 111 BitrateAllocator* bitrate_allocator) |
110 : channel_id_(channel_id), | 112 : channel_id_(channel_id), |
111 number_of_cores_(number_of_cores), | 113 number_of_cores_(number_of_cores), |
112 vpm_(VideoProcessingModule::Create()), | 114 vpm_(VideoProcessingModule::Create()), |
113 qm_callback_(new QMVideoSettingsCallback(vpm_.get())), | 115 qm_callback_(new QMVideoSettingsCallback(vpm_.get())), |
114 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), | 116 vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), |
115 this, | 117 this, |
116 qm_callback_.get())), | 118 qm_callback_.get())), |
117 send_payload_router_(NULL), | 119 send_payload_router_(NULL), |
118 callback_cs_(CriticalSectionWrapper::CreateCriticalSection()), | |
119 data_cs_(CriticalSectionWrapper::CreateCriticalSection()), | 120 data_cs_(CriticalSectionWrapper::CreateCriticalSection()), |
| 121 stats_proxy_(stats_proxy), |
| 122 pre_encode_callback_(pre_encode_callback), |
120 pacer_(pacer), | 123 pacer_(pacer), |
121 bitrate_allocator_(bitrate_allocator), | 124 bitrate_allocator_(bitrate_allocator), |
122 time_of_last_frame_activity_ms_(0), | 125 time_of_last_frame_activity_ms_(0), |
123 simulcast_enabled_(false), | 126 simulcast_enabled_(false), |
124 min_transmit_bitrate_kbps_(0), | 127 min_transmit_bitrate_kbps_(0), |
125 last_observed_bitrate_bps_(0), | 128 last_observed_bitrate_bps_(0), |
126 target_delay_ms_(0), | 129 target_delay_ms_(0), |
127 network_is_transmitting_(true), | 130 network_is_transmitting_(true), |
128 encoder_paused_(false), | 131 encoder_paused_(false), |
129 encoder_paused_and_dropped_frame_(false), | 132 encoder_paused_and_dropped_frame_(false), |
130 fec_enabled_(false), | 133 fec_enabled_(false), |
131 nack_enabled_(false), | 134 nack_enabled_(false), |
132 codec_observer_(NULL), | |
133 module_process_thread_(module_process_thread), | 135 module_process_thread_(module_process_thread), |
134 has_received_sli_(false), | 136 has_received_sli_(false), |
135 picture_id_sli_(0), | 137 picture_id_sli_(0), |
136 has_received_rpsi_(false), | 138 has_received_rpsi_(false), |
137 picture_id_rpsi_(0), | 139 picture_id_rpsi_(0), |
138 video_suspended_(false), | 140 video_suspended_(false), |
139 pre_encode_callback_(NULL), | 141 start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()) { |
140 start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()), | |
141 send_statistics_proxy_(NULL) { | |
142 bitrate_observer_.reset(new ViEBitrateObserver(this)); | 142 bitrate_observer_.reset(new ViEBitrateObserver(this)); |
143 } | 143 } |
144 | 144 |
145 bool ViEEncoder::Init() { | 145 bool ViEEncoder::Init() { |
146 vpm_->EnableTemporalDecimation(true); | 146 vpm_->EnableTemporalDecimation(true); |
147 | 147 |
148 // Enable/disable content analysis: off by default for now. | 148 // Enable/disable content analysis: off by default for now. |
149 vpm_->EnableContentAnalysis(false); | 149 vpm_->EnableContentAnalysis(false); |
150 | 150 |
151 if (vcm_->RegisterTransportCallback(this) != 0) { | 151 if (vcm_->RegisterTransportCallback(this) != 0) { |
152 return false; | 152 return false; |
153 } | 153 } |
154 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { | 154 if (vcm_->RegisterSendStatisticsCallback(this) != 0) { |
155 return false; | 155 return false; |
156 } | 156 } |
157 return true; | 157 return true; |
158 } | 158 } |
159 | 159 |
160 void ViEEncoder::StartThreadsAndSetSharedMembers( | 160 void ViEEncoder::StartThreadsAndSetSharedMembers( |
161 rtc::scoped_refptr<PayloadRouter> send_payload_router, | 161 rtc::scoped_refptr<PayloadRouter> send_payload_router, |
162 VCMProtectionCallback* vcm_protection_callback) { | 162 VCMProtectionCallback* vcm_protection_callback) { |
163 RTC_DCHECK(send_payload_router_ == NULL); | 163 RTC_DCHECK(send_payload_router_ == NULL); |
164 | 164 |
165 send_payload_router_ = send_payload_router; | 165 send_payload_router_ = send_payload_router; |
166 vcm_->RegisterProtectionCallback(vcm_protection_callback); | 166 vcm_->RegisterProtectionCallback(vcm_protection_callback); |
167 module_process_thread_.RegisterModule(vcm_.get()); | 167 module_process_thread_->RegisterModule(vcm_.get()); |
168 } | 168 } |
169 | 169 |
170 void ViEEncoder::StopThreadsAndRemoveSharedMembers() { | 170 void ViEEncoder::StopThreadsAndRemoveSharedMembers() { |
171 if (bitrate_allocator_) | 171 if (bitrate_allocator_) |
172 bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); | 172 bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); |
173 module_process_thread_.DeRegisterModule(vcm_.get()); | 173 module_process_thread_->DeRegisterModule(vcm_.get()); |
174 module_process_thread_.DeRegisterModule(vpm_.get()); | 174 module_process_thread_->DeRegisterModule(vpm_.get()); |
175 } | 175 } |
176 | 176 |
177 ViEEncoder::~ViEEncoder() { | 177 ViEEncoder::~ViEEncoder() { |
178 UpdateHistograms(); | 178 UpdateHistograms(); |
179 } | 179 } |
180 | 180 |
181 void ViEEncoder::UpdateHistograms() { | 181 void ViEEncoder::UpdateHistograms() { |
182 int64_t elapsed_sec = | 182 int64_t elapsed_sec = |
183 (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 1000; | 183 (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 1000; |
184 if (elapsed_sec < metrics::kMinRunTimeInSeconds) { | 184 if (elapsed_sec < metrics::kMinRunTimeInSeconds) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 return; | 442 return; |
443 } | 443 } |
444 if (ret != VPM_OK) { | 444 if (ret != VPM_OK) { |
445 return; | 445 return; |
446 } | 446 } |
447 } | 447 } |
448 | 448 |
449 // If we haven't resampled the frame and we have a FrameCallback, we need to | 449 // If we haven't resampled the frame and we have a FrameCallback, we need to |
450 // make a deep copy of |video_frame|. | 450 // make a deep copy of |video_frame|. |
451 VideoFrame copied_frame; | 451 VideoFrame copied_frame; |
452 { | 452 if (pre_encode_callback_) { |
453 CriticalSectionScoped cs(callback_cs_.get()); | 453 // If the frame was not resampled or scaled => use copy of original. |
454 if (pre_encode_callback_) { | 454 if (decimated_frame == NULL) { |
455 // If the frame was not resampled or scaled => use copy of original. | 455 copied_frame.CopyFrame(video_frame); |
456 if (decimated_frame == NULL) { | 456 decimated_frame = &copied_frame; |
457 copied_frame.CopyFrame(video_frame); | |
458 decimated_frame = &copied_frame; | |
459 } | |
460 pre_encode_callback_->FrameCallback(decimated_frame); | |
461 } | 457 } |
| 458 pre_encode_callback_->FrameCallback(decimated_frame); |
462 } | 459 } |
463 | 460 |
464 // If the frame was not resampled, scaled, or touched by FrameCallback => use | 461 // If the frame was not resampled, scaled, or touched by FrameCallback => use |
465 // original. The frame is const from here. | 462 // original. The frame is const from here. |
466 const VideoFrame* output_frame = | 463 const VideoFrame* output_frame = |
467 (decimated_frame != NULL) ? decimated_frame : &video_frame; | 464 (decimated_frame != NULL) ? decimated_frame : &video_frame; |
468 | 465 |
469 #ifdef VIDEOCODEC_VP8 | 466 #ifdef VIDEOCODEC_VP8 |
470 if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) { | 467 if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) { |
471 webrtc::CodecSpecificInfo codec_specific_info; | 468 webrtc::CodecSpecificInfo codec_specific_info; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 vcm_->EnableFrameDropper(false); | 567 vcm_->EnableFrameDropper(false); |
571 vpm_->EnableTemporalDecimation(false); | 568 vpm_->EnableTemporalDecimation(false); |
572 } else { | 569 } else { |
573 // Real-time mode - enable frame droppers. | 570 // Real-time mode - enable frame droppers. |
574 vpm_->EnableTemporalDecimation(true); | 571 vpm_->EnableTemporalDecimation(true); |
575 vcm_->EnableFrameDropper(true); | 572 vcm_->EnableFrameDropper(true); |
576 } | 573 } |
577 } | 574 } |
578 | 575 |
579 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { | 576 void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) { |
580 CriticalSectionScoped cs(callback_cs_.get()); | 577 if (stats_proxy_) |
581 if (send_statistics_proxy_ != nullptr) | 578 stats_proxy_->OnSetRates(bitrate_bps, framerate); |
582 send_statistics_proxy_->OnSetRates(bitrate_bps, framerate); | |
583 } | 579 } |
584 | 580 |
585 int32_t ViEEncoder::SendData( | 581 int32_t ViEEncoder::SendData( |
586 const uint8_t payload_type, | 582 const uint8_t payload_type, |
587 const EncodedImage& encoded_image, | 583 const EncodedImage& encoded_image, |
588 const webrtc::RTPFragmentationHeader& fragmentation_header, | 584 const webrtc::RTPFragmentationHeader& fragmentation_header, |
589 const RTPVideoHeader* rtp_video_hdr) { | 585 const RTPVideoHeader* rtp_video_hdr) { |
590 RTC_DCHECK(send_payload_router_ != NULL); | 586 RTC_DCHECK(send_payload_router_ != NULL); |
591 | 587 |
592 { | 588 { |
593 CriticalSectionScoped cs(data_cs_.get()); | 589 CriticalSectionScoped cs(data_cs_.get()); |
594 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); | 590 time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp(); |
595 } | 591 } |
596 | 592 |
597 { | 593 if (stats_proxy_ != NULL) |
598 CriticalSectionScoped cs(callback_cs_.get()); | 594 stats_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr); |
599 if (send_statistics_proxy_ != NULL) | |
600 send_statistics_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr); | |
601 } | |
602 | 595 |
603 return send_payload_router_->RoutePayload( | 596 return send_payload_router_->RoutePayload( |
604 VCMEncodedFrame::ConvertFrameType(encoded_image._frameType), payload_type, | 597 VCMEncodedFrame::ConvertFrameType(encoded_image._frameType), payload_type, |
605 encoded_image._timeStamp, encoded_image.capture_time_ms_, | 598 encoded_image._timeStamp, encoded_image.capture_time_ms_, |
606 encoded_image._buffer, encoded_image._length, &fragmentation_header, | 599 encoded_image._buffer, encoded_image._length, &fragmentation_header, |
607 rtp_video_hdr) ? 0 : -1; | 600 rtp_video_hdr) ? 0 : -1; |
608 } | 601 } |
609 | 602 |
610 int32_t ViEEncoder::SendStatistics(const uint32_t bit_rate, | 603 int32_t ViEEncoder::SendStatistics(const uint32_t bit_rate, |
611 const uint32_t frame_rate) { | 604 const uint32_t frame_rate) { |
612 CriticalSectionScoped cs(callback_cs_.get()); | 605 if (stats_proxy_) |
613 if (codec_observer_) { | 606 stats_proxy_->OnOutgoingRate(frame_rate, bit_rate); |
614 codec_observer_->OutgoingRate(channel_id_, frame_rate, bit_rate); | |
615 } | |
616 return 0; | 607 return 0; |
617 } | 608 } |
618 | 609 |
619 int32_t ViEEncoder::RegisterCodecObserver(ViEEncoderObserver* observer) { | |
620 CriticalSectionScoped cs(callback_cs_.get()); | |
621 if (observer && codec_observer_) { | |
622 LOG_F(LS_ERROR) << "Observer already set."; | |
623 return -1; | |
624 } | |
625 codec_observer_ = observer; | |
626 return 0; | |
627 } | |
628 | |
629 void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/, | 610 void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/, |
630 uint8_t picture_id) { | 611 uint8_t picture_id) { |
631 CriticalSectionScoped cs(data_cs_.get()); | 612 CriticalSectionScoped cs(data_cs_.get()); |
632 picture_id_sli_ = picture_id; | 613 picture_id_sli_ = picture_id; |
633 has_received_sli_ = true; | 614 has_received_sli_ = true; |
634 } | 615 } |
635 | 616 |
636 void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/, | 617 void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/, |
637 uint64_t picture_id) { | 618 uint64_t picture_id) { |
638 CriticalSectionScoped cs(data_cs_.get()); | 619 CriticalSectionScoped cs(data_cs_.get()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates( | 717 std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates( |
737 bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams); | 718 bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams); |
738 send_payload_router_->SetTargetSendBitrates(stream_bitrates); | 719 send_payload_router_->SetTargetSendBitrates(stream_bitrates); |
739 | 720 |
740 { | 721 { |
741 CriticalSectionScoped cs(data_cs_.get()); | 722 CriticalSectionScoped cs(data_cs_.get()); |
742 last_observed_bitrate_bps_ = bitrate_bps; | 723 last_observed_bitrate_bps_ = bitrate_bps; |
743 if (video_suspended_ == video_is_suspended) | 724 if (video_suspended_ == video_is_suspended) |
744 return; | 725 return; |
745 video_suspended_ = video_is_suspended; | 726 video_suspended_ = video_is_suspended; |
| 727 LOG(LS_INFO) << "Video suspended " << video_is_suspended |
| 728 << " for channel " << channel_id_; |
746 } | 729 } |
747 // Video suspend-state changed, inform codec observer. | 730 // Video suspend-state changed, inform codec observer. |
748 CriticalSectionScoped crit(callback_cs_.get()); | 731 if (stats_proxy_) |
749 if (codec_observer_) { | 732 stats_proxy_->OnSuspendChange(video_is_suspended); |
750 LOG(LS_INFO) << "Video suspended " << video_is_suspended | |
751 << " for channel " << channel_id_; | |
752 codec_observer_->SuspendChange(channel_id_, video_is_suspended); | |
753 } | |
754 } | 733 } |
755 | 734 |
756 void ViEEncoder::SuspendBelowMinBitrate() { | 735 void ViEEncoder::SuspendBelowMinBitrate() { |
757 vcm_->SuspendBelowMinBitrate(); | 736 vcm_->SuspendBelowMinBitrate(); |
758 bitrate_allocator_->EnforceMinBitrate(false); | 737 bitrate_allocator_->EnforceMinBitrate(false); |
759 } | 738 } |
760 | 739 |
761 void ViEEncoder::RegisterPreEncodeCallback( | |
762 I420FrameCallback* pre_encode_callback) { | |
763 CriticalSectionScoped cs(callback_cs_.get()); | |
764 pre_encode_callback_ = pre_encode_callback; | |
765 } | |
766 | |
767 void ViEEncoder::RegisterPostEncodeImageCallback( | 740 void ViEEncoder::RegisterPostEncodeImageCallback( |
768 EncodedImageCallback* post_encode_callback) { | 741 EncodedImageCallback* post_encode_callback) { |
769 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); | 742 vcm_->RegisterPostEncodeImageCallback(post_encode_callback); |
770 } | 743 } |
771 | 744 |
772 void ViEEncoder::RegisterSendStatisticsProxy( | |
773 SendStatisticsProxy* send_statistics_proxy) { | |
774 CriticalSectionScoped cs(callback_cs_.get()); | |
775 send_statistics_proxy_ = send_statistics_proxy; | |
776 } | |
777 | |
778 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm) | 745 QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm) |
779 : vpm_(vpm) { | 746 : vpm_(vpm) { |
780 } | 747 } |
781 | 748 |
782 QMVideoSettingsCallback::~QMVideoSettingsCallback() { | 749 QMVideoSettingsCallback::~QMVideoSettingsCallback() { |
783 } | 750 } |
784 | 751 |
785 int32_t QMVideoSettingsCallback::SetVideoQMSettings( | 752 int32_t QMVideoSettingsCallback::SetVideoQMSettings( |
786 const uint32_t frame_rate, | 753 const uint32_t frame_rate, |
787 const uint32_t width, | 754 const uint32_t width, |
788 const uint32_t height) { | 755 const uint32_t height) { |
789 return vpm_->SetTargetResolution(width, height, frame_rate); | 756 return vpm_->SetTargetResolution(width, height, frame_rate); |
790 } | 757 } |
791 | 758 |
792 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { | 759 void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) { |
793 vpm_->SetTargetFramerate(frame_rate); | 760 vpm_->SetTargetFramerate(frame_rate); |
794 } | 761 } |
795 | 762 |
796 } // namespace webrtc | 763 } // namespace webrtc |
OLD | NEW |