| 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 |