OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 #include "webrtc/video/video_quality_test.h" | 10 #include <stdio.h> |
11 | 11 |
12 #include <stdio.h> | |
13 #include <algorithm> | 12 #include <algorithm> |
14 #include <deque> | 13 #include <deque> |
15 #include <map> | 14 #include <map> |
16 #include <sstream> | 15 #include <sstream> |
17 #include <string> | 16 #include <string> |
18 #include <vector> | 17 #include <vector> |
19 | 18 |
20 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 |
21 #include "webrtc/base/checks.h" | 21 #include "webrtc/base/checks.h" |
22 #include "webrtc/base/event.h" | 22 #include "webrtc/base/event.h" |
23 #include "webrtc/base/format_macros.h" | 23 #include "webrtc/base/format_macros.h" |
24 #include "webrtc/base/optional.h" | 24 #include "webrtc/base/optional.h" |
25 #include "webrtc/base/timeutils.h" | 25 #include "webrtc/base/timeutils.h" |
26 #include "webrtc/call.h" | 26 #include "webrtc/call.h" |
27 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 27 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
28 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 28 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 29 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
30 #include "webrtc/system_wrappers/include/cpu_info.h" | 30 #include "webrtc/system_wrappers/include/cpu_info.h" |
31 #include "webrtc/test/layer_filtering_transport.h" | 31 #include "webrtc/test/layer_filtering_transport.h" |
32 #include "webrtc/test/run_loop.h" | 32 #include "webrtc/test/run_loop.h" |
33 #include "webrtc/test/statistics.h" | 33 #include "webrtc/test/statistics.h" |
34 #include "webrtc/test/testsupport/fileutils.h" | 34 #include "webrtc/test/testsupport/fileutils.h" |
35 #include "webrtc/test/vcm_capturer.h" | |
36 #include "webrtc/test/video_renderer.h" | 35 #include "webrtc/test/video_renderer.h" |
| 36 #include "webrtc/video/video_quality_test.h" |
37 #include "webrtc/voice_engine/include/voe_base.h" | 37 #include "webrtc/voice_engine/include/voe_base.h" |
38 #include "webrtc/voice_engine/include/voe_codec.h" | 38 #include "webrtc/voice_engine/include/voe_codec.h" |
39 | 39 |
40 namespace { | 40 namespace { |
41 | 41 |
42 constexpr int kSendStatsPollingIntervalMs = 1000; | 42 constexpr int kSendStatsPollingIntervalMs = 1000; |
43 constexpr int kPayloadTypeH264 = 122; | 43 constexpr int kPayloadTypeH264 = 122; |
44 constexpr int kPayloadTypeVP8 = 123; | 44 constexpr int kPayloadTypeVP8 = 123; |
45 constexpr int kPayloadTypeVP9 = 124; | 45 constexpr int kPayloadTypeVP9 = 124; |
46 constexpr size_t kMaxComparisons = 10; | 46 constexpr size_t kMaxComparisons = 10; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 voe->voice_engine = nullptr; | 92 voe->voice_engine = nullptr; |
93 } | 93 } |
94 | 94 |
95 } // namespace | 95 } // namespace |
96 | 96 |
97 namespace webrtc { | 97 namespace webrtc { |
98 | 98 |
99 class VideoAnalyzer : public PacketReceiver, | 99 class VideoAnalyzer : public PacketReceiver, |
100 public Transport, | 100 public Transport, |
101 public rtc::VideoSinkInterface<VideoFrame>, | 101 public rtc::VideoSinkInterface<VideoFrame>, |
| 102 public VideoCaptureInput, |
102 public EncodedFrameObserver { | 103 public EncodedFrameObserver { |
103 public: | 104 public: |
104 VideoAnalyzer(test::LayerFilteringTransport* transport, | 105 VideoAnalyzer(test::LayerFilteringTransport* transport, |
105 const std::string& test_label, | 106 const std::string& test_label, |
106 double avg_psnr_threshold, | 107 double avg_psnr_threshold, |
107 double avg_ssim_threshold, | 108 double avg_ssim_threshold, |
108 int duration_frames, | 109 int duration_frames, |
109 FILE* graph_data_output_file, | 110 FILE* graph_data_output_file, |
110 const std::string& graph_title, | 111 const std::string& graph_title, |
111 uint32_t ssrc_to_analyze) | 112 uint32_t ssrc_to_analyze) |
112 : transport_(transport), | 113 : input_(nullptr), |
| 114 transport_(transport), |
113 receiver_(nullptr), | 115 receiver_(nullptr), |
114 send_stream_(nullptr), | 116 send_stream_(nullptr), |
115 captured_frame_forwarder_(this), | |
116 test_label_(test_label), | 117 test_label_(test_label), |
117 graph_data_output_file_(graph_data_output_file), | 118 graph_data_output_file_(graph_data_output_file), |
118 graph_title_(graph_title), | 119 graph_title_(graph_title), |
119 ssrc_to_analyze_(ssrc_to_analyze), | 120 ssrc_to_analyze_(ssrc_to_analyze), |
120 pre_encode_proxy_(this), | 121 pre_encode_proxy_(this), |
121 encode_timing_proxy_(this), | 122 encode_timing_proxy_(this), |
122 frames_to_process_(duration_frames), | 123 frames_to_process_(duration_frames), |
123 frames_recorded_(0), | 124 frames_recorded_(0), |
124 frames_processed_(0), | 125 frames_processed_(0), |
125 dropped_frames_(0), | 126 dropped_frames_(0), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 162 |
162 ~VideoAnalyzer() { | 163 ~VideoAnalyzer() { |
163 for (rtc::PlatformThread* thread : comparison_thread_pool_) { | 164 for (rtc::PlatformThread* thread : comparison_thread_pool_) { |
164 thread->Stop(); | 165 thread->Stop(); |
165 delete thread; | 166 delete thread; |
166 } | 167 } |
167 } | 168 } |
168 | 169 |
169 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } | 170 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } |
170 | 171 |
171 void SetSendStream(VideoSendStream* stream) { | |
172 rtc::CritScope lock(&crit_); | |
173 RTC_DCHECK(!send_stream_); | |
174 send_stream_ = stream; | |
175 } | |
176 | |
177 rtc::VideoSinkInterface<VideoFrame>* InputInterface() { | |
178 return &captured_frame_forwarder_; | |
179 } | |
180 rtc::VideoSourceInterface<VideoFrame>* OutputInterface() { | |
181 return &captured_frame_forwarder_; | |
182 } | |
183 | |
184 DeliveryStatus DeliverPacket(MediaType media_type, | 172 DeliveryStatus DeliverPacket(MediaType media_type, |
185 const uint8_t* packet, | 173 const uint8_t* packet, |
186 size_t length, | 174 size_t length, |
187 const PacketTime& packet_time) override { | 175 const PacketTime& packet_time) override { |
188 // Ignore timestamps of RTCP packets. They're not synchronized with | 176 // Ignore timestamps of RTCP packets. They're not synchronized with |
189 // RTP packet timestamps and so they would confuse wrap_handler_. | 177 // RTP packet timestamps and so they would confuse wrap_handler_. |
190 if (RtpHeaderParser::IsRtcp(packet, length)) { | 178 if (RtpHeaderParser::IsRtcp(packet, length)) { |
191 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 179 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
192 } | 180 } |
193 | 181 |
194 RtpUtility::RtpHeaderParser parser(packet, length); | 182 RtpUtility::RtpHeaderParser parser(packet, length); |
195 RTPHeader header; | 183 RTPHeader header; |
196 parser.Parse(&header); | 184 parser.Parse(&header); |
197 { | 185 { |
198 rtc::CritScope lock(&crit_); | 186 rtc::CritScope lock(&crit_); |
199 int64_t timestamp = | 187 int64_t timestamp = |
200 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); | 188 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); |
201 recv_times_[timestamp] = | 189 recv_times_[timestamp] = |
202 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); | 190 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); |
203 } | 191 } |
204 | 192 |
205 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 193 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
206 } | 194 } |
207 | 195 |
208 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { | 196 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { |
209 rtc::CritScope crit(&comparison_lock_); | 197 rtc::CritScope crit(&comparison_lock_); |
210 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; | 198 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; |
211 } | 199 } |
212 | 200 |
| 201 void IncomingCapturedFrame(const VideoFrame& video_frame) override { |
| 202 VideoFrame copy = video_frame; |
| 203 copy.set_timestamp(copy.ntp_time_ms() * 90); |
| 204 { |
| 205 rtc::CritScope lock(&crit_); |
| 206 frames_.push_back(copy); |
| 207 } |
| 208 |
| 209 input_->IncomingCapturedFrame(video_frame); |
| 210 } |
| 211 |
213 void PreEncodeOnFrame(const VideoFrame& video_frame) { | 212 void PreEncodeOnFrame(const VideoFrame& video_frame) { |
214 rtc::CritScope lock(&crit_); | 213 rtc::CritScope lock(&crit_); |
215 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) { | 214 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) { |
216 while (frames_.front().timestamp() != video_frame.timestamp()) { | 215 while (frames_.front().timestamp() != video_frame.timestamp()) { |
217 ++dropped_frames_before_first_encode_; | 216 ++dropped_frames_before_first_encode_; |
218 frames_.pop_front(); | 217 frames_.pop_front(); |
219 RTC_CHECK(!frames_.empty()); | 218 RTC_CHECK(!frames_.empty()); |
220 } | 219 } |
221 first_send_timestamp_ = rtc::Optional<uint32_t>(video_frame.timestamp()); | 220 first_send_timestamp_ = rtc::Optional<uint32_t>(video_frame.timestamp()); |
222 } | 221 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 printf("- Farewell, sweet Concorde!\n"); | 339 printf("- Farewell, sweet Concorde!\n"); |
341 | 340 |
342 stats_polling_thread_.Stop(); | 341 stats_polling_thread_.Stop(); |
343 } | 342 } |
344 | 343 |
345 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() { | 344 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() { |
346 return &pre_encode_proxy_; | 345 return &pre_encode_proxy_; |
347 } | 346 } |
348 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } | 347 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } |
349 | 348 |
| 349 VideoCaptureInput* input_; |
350 test::LayerFilteringTransport* const transport_; | 350 test::LayerFilteringTransport* const transport_; |
351 PacketReceiver* receiver_; | 351 PacketReceiver* receiver_; |
| 352 VideoSendStream* send_stream_; |
352 | 353 |
353 private: | 354 private: |
354 struct FrameComparison { | 355 struct FrameComparison { |
355 FrameComparison() | 356 FrameComparison() |
356 : dropped(false), | 357 : dropped(false), |
357 send_time_ms(0), | 358 send_time_ms(0), |
358 recv_time_ms(0), | 359 recv_time_ms(0), |
359 render_time_ms(0), | 360 render_time_ms(0), |
360 encoded_frame_size(0) {} | 361 encoded_frame_size(0) {} |
361 | 362 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 sample.encoded_frame_size, sample.psnr, sample.ssim, | 690 sample.encoded_frame_size, sample.psnr, sample.ssim, |
690 encode_time_ms); | 691 encode_time_ms); |
691 } | 692 } |
692 if (missing_encode_time_samples) { | 693 if (missing_encode_time_samples) { |
693 fprintf(stderr, | 694 fprintf(stderr, |
694 "Warning: Missing encode_time_ms samples for %d frame(s).\n", | 695 "Warning: Missing encode_time_ms samples for %d frame(s).\n", |
695 missing_encode_time_samples); | 696 missing_encode_time_samples); |
696 } | 697 } |
697 } | 698 } |
698 | 699 |
699 // Implements VideoSinkInterface to receive captured frames from a | |
700 // FrameGeneratorCapturer. Implements VideoSourceInterface to be able to act | |
701 // as a source to VideoSendStream. | |
702 // It forwards all input frames to the VideoAnalyzer for later comparison and | |
703 // forwards the captured frames to the VideoSendStream. | |
704 class CapturedFrameForwarder : public rtc::VideoSinkInterface<VideoFrame>, | |
705 public rtc::VideoSourceInterface<VideoFrame> { | |
706 public: | |
707 explicit CapturedFrameForwarder(VideoAnalyzer* analyzer) | |
708 : analyzer_(analyzer), send_stream_input_(nullptr) {} | |
709 | |
710 private: | |
711 void OnFrame(const VideoFrame& video_frame) override { | |
712 VideoFrame copy = video_frame; | |
713 copy.set_timestamp(copy.ntp_time_ms() * 90); | |
714 | |
715 analyzer_->AddCapturedFrameForComparison(video_frame); | |
716 rtc::CritScope lock(&crit_); | |
717 if (send_stream_input_) | |
718 send_stream_input_->OnFrame(video_frame); | |
719 } | |
720 | |
721 // Called when |send_stream_.SetSource()| is called. | |
722 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink, | |
723 const rtc::VideoSinkWants& wants) override { | |
724 rtc::CritScope lock(&crit_); | |
725 RTC_DCHECK(!send_stream_input_ || send_stream_input_ == sink); | |
726 send_stream_input_ = sink; | |
727 } | |
728 | |
729 // Called by |send_stream_| when |send_stream_.SetSource()| is called. | |
730 void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override { | |
731 rtc::CritScope lock(&crit_); | |
732 RTC_DCHECK(sink == send_stream_input_); | |
733 send_stream_input_ = nullptr; | |
734 } | |
735 | |
736 VideoAnalyzer* const analyzer_; | |
737 rtc::CriticalSection crit_; | |
738 rtc::VideoSinkInterface<VideoFrame>* send_stream_input_ GUARDED_BY(crit_); | |
739 }; | |
740 | |
741 void AddCapturedFrameForComparison(const VideoFrame& video_frame) { | |
742 rtc::CritScope lock(&crit_); | |
743 frames_.push_back(video_frame); | |
744 } | |
745 | |
746 VideoSendStream* send_stream_; | |
747 CapturedFrameForwarder captured_frame_forwarder_; | |
748 const std::string test_label_; | 700 const std::string test_label_; |
749 FILE* const graph_data_output_file_; | 701 FILE* const graph_data_output_file_; |
750 const std::string graph_title_; | 702 const std::string graph_title_; |
751 const uint32_t ssrc_to_analyze_; | 703 const uint32_t ssrc_to_analyze_; |
752 PreEncodeProxy pre_encode_proxy_; | 704 PreEncodeProxy pre_encode_proxy_; |
753 OnEncodeTimingProxy encode_timing_proxy_; | 705 OnEncodeTimingProxy encode_timing_proxy_; |
754 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 706 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); |
755 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); | 707 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); |
756 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 708 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); |
757 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 709 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 params_.screenshare.slide_change_interval); | 1021 params_.screenshare.slide_change_interval); |
1070 | 1022 |
1071 frame_generator_.reset( | 1023 frame_generator_.reset( |
1072 test::FrameGenerator::CreateScrollingInputFromYuvFiles( | 1024 test::FrameGenerator::CreateScrollingInputFromYuvFiles( |
1073 clock_, slides, kWidth, kHeight, params_.common.width, | 1025 clock_, slides, kWidth, kHeight, params_.common.width, |
1074 params_.common.height, params_.screenshare.scroll_duration * 1000, | 1026 params_.common.height, params_.screenshare.scroll_duration * 1000, |
1075 kPauseDurationMs)); | 1027 kPauseDurationMs)); |
1076 } | 1028 } |
1077 } | 1029 } |
1078 | 1030 |
1079 void VideoQualityTest::CreateCapturer() { | 1031 void VideoQualityTest::CreateCapturer(VideoCaptureInput* input) { |
1080 if (params_.screenshare.enabled) { | 1032 if (params_.screenshare.enabled) { |
1081 test::FrameGeneratorCapturer* frame_generator_capturer = | 1033 test::FrameGeneratorCapturer* frame_generator_capturer = |
1082 new test::FrameGeneratorCapturer(clock_, frame_generator_.release(), | 1034 new test::FrameGeneratorCapturer( |
1083 params_.common.fps); | 1035 clock_, input, frame_generator_.release(), params_.common.fps); |
1084 EXPECT_TRUE(frame_generator_capturer->Init()); | 1036 EXPECT_TRUE(frame_generator_capturer->Init()); |
1085 capturer_.reset(frame_generator_capturer); | 1037 capturer_.reset(frame_generator_capturer); |
1086 } else { | 1038 } else { |
1087 if (params_.video.clip_name.empty()) { | 1039 if (params_.video.clip_name.empty()) { |
1088 capturer_.reset(test::VcmCapturer::Create( | 1040 capturer_.reset(test::VideoCapturer::Create(input, params_.common.width, |
1089 params_.common.width, params_.common.height, params_.common.fps)); | 1041 params_.common.height, |
| 1042 params_.common.fps, clock_)); |
1090 } else { | 1043 } else { |
1091 capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile( | 1044 capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile( |
1092 test::ResourcePath(params_.video.clip_name, "yuv"), | 1045 input, test::ResourcePath(params_.video.clip_name, "yuv"), |
1093 params_.common.width, params_.common.height, params_.common.fps, | 1046 params_.common.width, params_.common.height, params_.common.fps, |
1094 clock_)); | 1047 clock_)); |
1095 ASSERT_TRUE(capturer_) << "Could not create capturer for " | 1048 ASSERT_TRUE(capturer_) << "Could not create capturer for " |
1096 << params_.video.clip_name | 1049 << params_.video.clip_name |
1097 << ".yuv. Is this resource file present?"; | 1050 << ".yuv. Is this resource file present?"; |
1098 } | 1051 } |
1099 } | 1052 } |
1100 } | 1053 } |
1101 | 1054 |
1102 void VideoQualityTest::RunWithAnalyzer(const Params& params) { | 1055 void VideoQualityTest::RunWithAnalyzer(const Params& params) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); | 1120 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); |
1168 for (auto& config : video_receive_configs_) | 1121 for (auto& config : video_receive_configs_) |
1169 config.pre_decode_callback = &analyzer; | 1122 config.pre_decode_callback = &analyzer; |
1170 RTC_DCHECK(!video_send_config_.post_encode_callback); | 1123 RTC_DCHECK(!video_send_config_.post_encode_callback); |
1171 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); | 1124 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); |
1172 | 1125 |
1173 if (params_.screenshare.enabled) | 1126 if (params_.screenshare.enabled) |
1174 SetupScreenshare(); | 1127 SetupScreenshare(); |
1175 | 1128 |
1176 CreateVideoStreams(); | 1129 CreateVideoStreams(); |
1177 analyzer.SetSendStream(video_send_stream_); | 1130 analyzer.input_ = video_send_stream_->Input(); |
1178 video_send_stream_->SetSource(analyzer.OutputInterface()); | 1131 analyzer.send_stream_ = video_send_stream_; |
1179 | 1132 |
1180 CreateCapturer(); | 1133 CreateCapturer(&analyzer); |
1181 rtc::VideoSinkWants wants; | |
1182 capturer_->AddOrUpdateSink(analyzer.InputInterface(), wants); | |
1183 | 1134 |
1184 video_send_stream_->Start(); | 1135 video_send_stream_->Start(); |
1185 for (VideoReceiveStream* receive_stream : video_receive_streams_) | 1136 for (VideoReceiveStream* receive_stream : video_receive_streams_) |
1186 receive_stream->Start(); | 1137 receive_stream->Start(); |
1187 capturer_->Start(); | 1138 capturer_->Start(); |
1188 | 1139 |
1189 analyzer.Wait(); | 1140 analyzer.Wait(); |
1190 | 1141 |
1191 send_transport.StopSending(); | 1142 send_transport.StopSending(); |
1192 recv_transport.StopSending(); | 1143 recv_transport.StopSending(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 kUlpfecPayloadType; | 1215 kUlpfecPayloadType; |
1265 } | 1216 } |
1266 | 1217 |
1267 if (params_.screenshare.enabled) | 1218 if (params_.screenshare.enabled) |
1268 SetupScreenshare(); | 1219 SetupScreenshare(); |
1269 | 1220 |
1270 video_send_stream_ = call->CreateVideoSendStream( | 1221 video_send_stream_ = call->CreateVideoSendStream( |
1271 video_send_config_.Copy(), video_encoder_config_.Copy()); | 1222 video_send_config_.Copy(), video_encoder_config_.Copy()); |
1272 VideoReceiveStream* video_receive_stream = | 1223 VideoReceiveStream* video_receive_stream = |
1273 call->CreateVideoReceiveStream(video_receive_configs_[stream_id].Copy()); | 1224 call->CreateVideoReceiveStream(video_receive_configs_[stream_id].Copy()); |
1274 CreateCapturer(); | 1225 CreateCapturer(video_send_stream_->Input()); |
1275 video_send_stream_->SetSource(capturer_.get()); | |
1276 | 1226 |
1277 AudioReceiveStream* audio_receive_stream = nullptr; | 1227 AudioReceiveStream* audio_receive_stream = nullptr; |
1278 if (params_.audio) { | 1228 if (params_.audio) { |
1279 audio_send_config_ = AudioSendStream::Config(&transport); | 1229 audio_send_config_ = AudioSendStream::Config(&transport); |
1280 audio_send_config_.voe_channel_id = voe.send_channel_id; | 1230 audio_send_config_.voe_channel_id = voe.send_channel_id; |
1281 audio_send_config_.rtp.ssrc = kAudioSendSsrc; | 1231 audio_send_config_.rtp.ssrc = kAudioSendSsrc; |
1282 | 1232 |
1283 // Add extension to enable audio send side BWE, and allow audio bit rate | 1233 // Add extension to enable audio send side BWE, and allow audio bit rate |
1284 // adaptation. | 1234 // adaptation. |
1285 audio_send_config_.rtp.extensions.clear(); | 1235 audio_send_config_.rtp.extensions.clear(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 call->DestroyAudioSendStream(audio_send_stream_); | 1301 call->DestroyAudioSendStream(audio_send_stream_); |
1352 call->DestroyAudioReceiveStream(audio_receive_stream); | 1302 call->DestroyAudioReceiveStream(audio_receive_stream); |
1353 } | 1303 } |
1354 | 1304 |
1355 transport.StopSending(); | 1305 transport.StopSending(); |
1356 if (params_.audio) | 1306 if (params_.audio) |
1357 DestroyVoiceEngine(&voe); | 1307 DestroyVoiceEngine(&voe); |
1358 } | 1308 } |
1359 | 1309 |
1360 } // namespace webrtc | 1310 } // namespace webrtc |
OLD | NEW |