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 <stdio.h> | 10 #include <stdio.h> |
(...skipping 81 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), |
117 test_label_(test_label), | 115 test_label_(test_label), |
118 graph_data_output_file_(graph_data_output_file), | 116 graph_data_output_file_(graph_data_output_file), |
119 graph_title_(graph_title), | 117 graph_title_(graph_title), |
120 ssrc_to_analyze_(ssrc_to_analyze), | 118 ssrc_to_analyze_(ssrc_to_analyze), |
121 pre_encode_proxy_(this), | 119 pre_encode_proxy_(this), |
120 input_capture_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), |
127 dropped_frames_before_first_encode_(0), | 126 dropped_frames_before_first_encode_(0), |
128 dropped_frames_before_rendering_(0), | 127 dropped_frames_before_rendering_(0), |
129 last_render_time_(0), | 128 last_render_time_(0), |
130 rtp_timestamp_delta_(0), | 129 rtp_timestamp_delta_(0), |
131 avg_psnr_threshold_(avg_psnr_threshold), | 130 avg_psnr_threshold_(avg_psnr_threshold), |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 } | 190 } |
192 | 191 |
193 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 192 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
194 } | 193 } |
195 | 194 |
196 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { | 195 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { |
197 rtc::CritScope crit(&comparison_lock_); | 196 rtc::CritScope crit(&comparison_lock_); |
198 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; | 197 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; |
199 } | 198 } |
200 | 199 |
201 void IncomingCapturedFrame(const VideoFrame& video_frame) override { | 200 void OnCapturedFrame(const VideoFrame& video_frame) { |
202 VideoFrame copy = video_frame; | 201 rtc::CritScope lock(&crit_); |
203 copy.set_timestamp(copy.ntp_time_ms() * 90); | 202 frames_.push_back(video_frame); |
stefan-webrtc
2016/09/13 07:19:53
Why did we have to use a copy before but not now?
sprang_webrtc
2016/09/13 08:35:26
Because we now call this method after all the time
| |
204 { | |
205 rtc::CritScope lock(&crit_); | |
206 frames_.push_back(copy); | |
207 } | |
208 | |
209 input_->IncomingCapturedFrame(video_frame); | |
210 } | 203 } |
211 | 204 |
212 void PreEncodeOnFrame(const VideoFrame& video_frame) { | 205 void PreEncodeOnFrame(const VideoFrame& video_frame) { |
213 rtc::CritScope lock(&crit_); | 206 rtc::CritScope lock(&crit_); |
214 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) { | 207 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) { |
215 while (frames_.front().timestamp() != video_frame.timestamp()) { | 208 while (frames_.front().timestamp() != video_frame.timestamp()) { |
216 ++dropped_frames_before_first_encode_; | 209 ++dropped_frames_before_first_encode_; |
217 frames_.pop_front(); | 210 frames_.pop_front(); |
218 RTC_CHECK(!frames_.empty()); | 211 RTC_CHECK(!frames_.empty()); |
219 } | 212 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 | 330 |
338 if (iteration > 0) | 331 if (iteration > 0) |
339 printf("- Farewell, sweet Concorde!\n"); | 332 printf("- Farewell, sweet Concorde!\n"); |
340 | 333 |
341 stats_polling_thread_.Stop(); | 334 stats_polling_thread_.Stop(); |
342 } | 335 } |
343 | 336 |
344 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() { | 337 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() { |
345 return &pre_encode_proxy_; | 338 return &pre_encode_proxy_; |
346 } | 339 } |
340 rtc::VideoSinkInterface<VideoFrame>* input_capture_proxy() { | |
341 return &input_capture_proxy_; | |
342 } | |
347 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } | 343 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } |
348 | 344 |
349 VideoCaptureInput* input_; | 345 VideoCaptureInput* input_; |
350 test::LayerFilteringTransport* const transport_; | 346 test::LayerFilteringTransport* const transport_; |
351 PacketReceiver* receiver_; | 347 PacketReceiver* receiver_; |
352 VideoSendStream* send_stream_; | 348 VideoSendStream* send_stream_; |
353 | 349 |
354 private: | 350 private: |
355 struct FrameComparison { | 351 struct FrameComparison { |
356 FrameComparison() | 352 FrameComparison() |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 | 416 |
421 void OnEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) override { | 417 void OnEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) override { |
422 parent_->MeasuredEncodeTiming(ntp_time_ms, encode_time_ms); | 418 parent_->MeasuredEncodeTiming(ntp_time_ms, encode_time_ms); |
423 } | 419 } |
424 void EncodedFrameCallback(const EncodedFrame& frame) override {} | 420 void EncodedFrameCallback(const EncodedFrame& frame) override {} |
425 | 421 |
426 private: | 422 private: |
427 VideoAnalyzer* const parent_; | 423 VideoAnalyzer* const parent_; |
428 }; | 424 }; |
429 | 425 |
430 // This class receives the send-side OnFrame callback and is provided to not | 426 // This class receives the send-side OnFrame callback triggered on the encoder |
427 // thread just before encoding the thread. It is provided as a proxy to not | |
431 // conflict with the receiver-side renderer callback. | 428 // conflict with the receiver-side renderer callback. |
432 class PreEncodeProxy : public rtc::VideoSinkInterface<VideoFrame> { | 429 class PreEncodeProxy : public rtc::VideoSinkInterface<VideoFrame> { |
433 public: | 430 public: |
434 explicit PreEncodeProxy(VideoAnalyzer* parent) : parent_(parent) {} | 431 explicit PreEncodeProxy(VideoAnalyzer* parent) : parent_(parent) {} |
435 | 432 |
436 void OnFrame(const VideoFrame& video_frame) override { | 433 void OnFrame(const VideoFrame& video_frame) override { |
437 parent_->PreEncodeOnFrame(video_frame); | 434 parent_->PreEncodeOnFrame(video_frame); |
438 } | 435 } |
439 | 436 |
440 private: | 437 private: |
441 VideoAnalyzer* const parent_; | 438 VideoAnalyzer* const parent_; |
442 }; | 439 }; |
443 | 440 |
441 // This class receives the send-side OnFrame callback triggered when the | |
442 // capturer receives a new frame. It is provided as a proxy to not conflict | |
443 // with the receiver-side renderer callback. | |
444 class InputCaptureProxy : public rtc::VideoSinkInterface<VideoFrame> { | |
445 public: | |
446 explicit InputCaptureProxy(VideoAnalyzer* parent) : parent_(parent) {} | |
447 | |
448 void OnFrame(const VideoFrame& video_frame) override { | |
449 parent_->OnCapturedFrame(video_frame); | |
450 } | |
451 | |
452 private: | |
453 VideoAnalyzer* const parent_; | |
454 }; | |
455 | |
444 void AddFrameComparison(const VideoFrame& reference, | 456 void AddFrameComparison(const VideoFrame& reference, |
445 const VideoFrame& render, | 457 const VideoFrame& render, |
446 bool dropped, | 458 bool dropped, |
447 int64_t render_time_ms) | 459 int64_t render_time_ms) |
448 EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 460 EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
449 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); | 461 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); |
450 int64_t send_time_ms = send_times_[reference_timestamp]; | 462 int64_t send_time_ms = send_times_[reference_timestamp]; |
451 send_times_.erase(reference_timestamp); | 463 send_times_.erase(reference_timestamp); |
452 int64_t recv_time_ms = recv_times_[reference_timestamp]; | 464 int64_t recv_time_ms = recv_times_[reference_timestamp]; |
453 recv_times_.erase(reference_timestamp); | 465 recv_times_.erase(reference_timestamp); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 "Warning: Missing encode_time_ms samples for %d frame(s).\n", | 707 "Warning: Missing encode_time_ms samples for %d frame(s).\n", |
696 missing_encode_time_samples); | 708 missing_encode_time_samples); |
697 } | 709 } |
698 } | 710 } |
699 | 711 |
700 const std::string test_label_; | 712 const std::string test_label_; |
701 FILE* const graph_data_output_file_; | 713 FILE* const graph_data_output_file_; |
702 const std::string graph_title_; | 714 const std::string graph_title_; |
703 const uint32_t ssrc_to_analyze_; | 715 const uint32_t ssrc_to_analyze_; |
704 PreEncodeProxy pre_encode_proxy_; | 716 PreEncodeProxy pre_encode_proxy_; |
717 InputCaptureProxy input_capture_proxy_; | |
705 OnEncodeTimingProxy encode_timing_proxy_; | 718 OnEncodeTimingProxy encode_timing_proxy_; |
706 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 719 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); |
707 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); | 720 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); |
708 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 721 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); |
709 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 722 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); |
710 test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 723 test::Statistics psnr_ GUARDED_BY(comparison_lock_); |
711 test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 724 test::Statistics ssim_ GUARDED_BY(comparison_lock_); |
712 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 725 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); |
713 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 726 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); |
714 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 727 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1111 graph_data_output_file, graph_title, | 1124 graph_data_output_file, graph_title, |
1112 kVideoSendSsrcs[params_.ss.selected_stream]); | 1125 kVideoSendSsrcs[params_.ss.selected_stream]); |
1113 | 1126 |
1114 analyzer.SetReceiver(receiver_call_->Receiver()); | 1127 analyzer.SetReceiver(receiver_call_->Receiver()); |
1115 send_transport.SetReceiver(&analyzer); | 1128 send_transport.SetReceiver(&analyzer); |
1116 recv_transport.SetReceiver(sender_call_->Receiver()); | 1129 recv_transport.SetReceiver(sender_call_->Receiver()); |
1117 | 1130 |
1118 SetupCommon(&analyzer, &recv_transport); | 1131 SetupCommon(&analyzer, &recv_transport); |
1119 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; | 1132 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; |
1120 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); | 1133 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); |
1134 video_send_config_.local_renderer = analyzer.input_capture_proxy(); | |
1121 for (auto& config : video_receive_configs_) | 1135 for (auto& config : video_receive_configs_) |
1122 config.pre_decode_callback = &analyzer; | 1136 config.pre_decode_callback = &analyzer; |
1123 RTC_DCHECK(!video_send_config_.post_encode_callback); | 1137 RTC_DCHECK(!video_send_config_.post_encode_callback); |
1124 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); | 1138 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); |
1125 | 1139 |
1126 if (params_.screenshare.enabled) | 1140 if (params_.screenshare.enabled) |
1127 SetupScreenshare(); | 1141 SetupScreenshare(); |
1128 | 1142 |
1129 CreateVideoStreams(); | 1143 CreateVideoStreams(); |
1130 analyzer.input_ = video_send_stream_->Input(); | |
1131 analyzer.send_stream_ = video_send_stream_; | 1144 analyzer.send_stream_ = video_send_stream_; |
1132 | 1145 |
1133 CreateCapturer(&analyzer); | 1146 CreateCapturer(video_send_stream_->Input()); |
1134 | 1147 |
1135 video_send_stream_->Start(); | 1148 video_send_stream_->Start(); |
1136 for (VideoReceiveStream* receive_stream : video_receive_streams_) | 1149 for (VideoReceiveStream* receive_stream : video_receive_streams_) |
1137 receive_stream->Start(); | 1150 receive_stream->Start(); |
1138 capturer_->Start(); | 1151 capturer_->Start(); |
1139 | 1152 |
1140 analyzer.Wait(); | 1153 analyzer.Wait(); |
1141 | 1154 |
1142 send_transport.StopSending(); | 1155 send_transport.StopSending(); |
1143 recv_transport.StopSending(); | 1156 recv_transport.StopSending(); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 call->DestroyAudioSendStream(audio_send_stream_); | 1314 call->DestroyAudioSendStream(audio_send_stream_); |
1302 call->DestroyAudioReceiveStream(audio_receive_stream); | 1315 call->DestroyAudioReceiveStream(audio_receive_stream); |
1303 } | 1316 } |
1304 | 1317 |
1305 transport.StopSending(); | 1318 transport.StopSending(); |
1306 if (params_.audio) | 1319 if (params_.audio) |
1307 DestroyVoiceEngine(&voe); | 1320 DestroyVoiceEngine(&voe); |
1308 } | 1321 } |
1309 | 1322 |
1310 } // namespace webrtc | 1323 } // namespace webrtc |
OLD | NEW |