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