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 28 matching lines...) Expand all Loading... |
39 | 39 |
40 static const int kSendStatsPollingIntervalMs = 1000; | 40 static const int kSendStatsPollingIntervalMs = 1000; |
41 static const int kPayloadTypeH264 = 122; | 41 static const int kPayloadTypeH264 = 122; |
42 static const int kPayloadTypeVP8 = 123; | 42 static const int kPayloadTypeVP8 = 123; |
43 static const int kPayloadTypeVP9 = 124; | 43 static const int kPayloadTypeVP9 = 124; |
44 | 44 |
45 class VideoAnalyzer : public PacketReceiver, | 45 class VideoAnalyzer : public PacketReceiver, |
46 public Transport, | 46 public Transport, |
47 public VideoRenderer, | 47 public VideoRenderer, |
48 public VideoCaptureInput, | 48 public VideoCaptureInput, |
49 public EncodedFrameObserver, | 49 public EncodedFrameObserver { |
50 public EncodingTimeObserver { | |
51 public: | 50 public: |
52 VideoAnalyzer(test::LayerFilteringTransport* transport, | 51 VideoAnalyzer(test::LayerFilteringTransport* transport, |
53 const std::string& test_label, | 52 const std::string& test_label, |
54 double avg_psnr_threshold, | 53 double avg_psnr_threshold, |
55 double avg_ssim_threshold, | 54 double avg_ssim_threshold, |
56 int duration_frames, | 55 int duration_frames, |
57 FILE* graph_data_output_file, | 56 FILE* graph_data_output_file, |
58 const std::string& graph_title, | 57 const std::string& graph_title, |
59 uint32_t ssrc_to_analyze) | 58 uint32_t ssrc_to_analyze) |
60 : input_(nullptr), | 59 : input_(nullptr), |
61 transport_(transport), | 60 transport_(transport), |
62 receiver_(nullptr), | 61 receiver_(nullptr), |
63 send_stream_(nullptr), | 62 send_stream_(nullptr), |
64 test_label_(test_label), | 63 test_label_(test_label), |
65 graph_data_output_file_(graph_data_output_file), | 64 graph_data_output_file_(graph_data_output_file), |
66 graph_title_(graph_title), | 65 graph_title_(graph_title), |
67 ssrc_to_analyze_(ssrc_to_analyze), | 66 ssrc_to_analyze_(ssrc_to_analyze), |
| 67 encode_timing_proxy_(this), |
68 frames_to_process_(duration_frames), | 68 frames_to_process_(duration_frames), |
69 frames_recorded_(0), | 69 frames_recorded_(0), |
70 frames_processed_(0), | 70 frames_processed_(0), |
71 dropped_frames_(0), | 71 dropped_frames_(0), |
72 last_render_time_(0), | 72 last_render_time_(0), |
73 rtp_timestamp_delta_(0), | 73 rtp_timestamp_delta_(0), |
74 avg_psnr_threshold_(avg_psnr_threshold), | 74 avg_psnr_threshold_(avg_psnr_threshold), |
75 avg_ssim_threshold_(avg_ssim_threshold), | 75 avg_ssim_threshold_(avg_ssim_threshold), |
76 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), | 76 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), |
77 comparison_available_event_(false, false), | 77 comparison_available_event_(false, false), |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 { | 122 { |
123 rtc::CritScope lock(&crit_); | 123 rtc::CritScope lock(&crit_); |
124 int64_t timestamp = wrap_handler_.Unwrap(header.timestamp); | 124 int64_t timestamp = wrap_handler_.Unwrap(header.timestamp); |
125 recv_times_[timestamp - rtp_timestamp_delta_] = | 125 recv_times_[timestamp - rtp_timestamp_delta_] = |
126 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); | 126 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); |
127 } | 127 } |
128 | 128 |
129 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 129 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
130 } | 130 } |
131 | 131 |
132 // EncodingTimeObserver. | 132 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { |
133 void OnReportEncodedTime(int64_t ntp_time_ms, int encode_time_ms) override { | |
134 rtc::CritScope crit(&comparison_lock_); | 133 rtc::CritScope crit(&comparison_lock_); |
135 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; | 134 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; |
136 } | 135 } |
137 | 136 |
138 void IncomingCapturedFrame(const VideoFrame& video_frame) override { | 137 void IncomingCapturedFrame(const VideoFrame& video_frame) override { |
139 VideoFrame copy = video_frame; | 138 VideoFrame copy = video_frame; |
140 copy.set_timestamp(copy.ntp_time_ms() * 90); | 139 copy.set_timestamp(copy.ntp_time_ms() * 90); |
141 | 140 |
142 { | 141 { |
143 rtc::CritScope lock(&crit_); | 142 rtc::CritScope lock(&crit_); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 AddFrameComparison(frames_.front(), last_rendered_frame_, true, | 200 AddFrameComparison(frames_.front(), last_rendered_frame_, true, |
202 render_time_ms); | 201 render_time_ms); |
203 frames_.pop_front(); | 202 frames_.pop_front(); |
204 } | 203 } |
205 | 204 |
206 VideoFrame reference_frame = frames_.front(); | 205 VideoFrame reference_frame = frames_.front(); |
207 frames_.pop_front(); | 206 frames_.pop_front(); |
208 assert(!reference_frame.IsZeroSize()); | 207 assert(!reference_frame.IsZeroSize()); |
209 if (send_timestamp == reference_frame.timestamp() - 1) { | 208 if (send_timestamp == reference_frame.timestamp() - 1) { |
210 // TODO(ivica): Make this work for > 2 streams. | 209 // TODO(ivica): Make this work for > 2 streams. |
211 // Look at rtp_sender.c:RTPSender::BuildRTPHeader. | 210 // Look at RTPSender::BuildRTPHeader. |
212 ++send_timestamp; | 211 ++send_timestamp; |
213 } | 212 } |
214 EXPECT_EQ(reference_frame.timestamp(), send_timestamp); | 213 EXPECT_EQ(reference_frame.timestamp(), send_timestamp); |
215 assert(reference_frame.timestamp() == send_timestamp); | 214 assert(reference_frame.timestamp() == send_timestamp); |
216 | 215 |
217 AddFrameComparison(reference_frame, video_frame, false, render_time_ms); | 216 AddFrameComparison(reference_frame, video_frame, false, render_time_ms); |
218 | 217 |
219 last_rendered_frame_ = video_frame; | 218 last_rendered_frame_ = video_frame; |
220 } | 219 } |
221 | 220 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 255 } |
257 last_frames_processed = frames_processed; | 256 last_frames_processed = frames_processed; |
258 } | 257 } |
259 | 258 |
260 if (iteration > 0) | 259 if (iteration > 0) |
261 printf("- Farewell, sweet Concorde!\n"); | 260 printf("- Farewell, sweet Concorde!\n"); |
262 | 261 |
263 stats_polling_thread_.Stop(); | 262 stats_polling_thread_.Stop(); |
264 } | 263 } |
265 | 264 |
| 265 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } |
| 266 |
266 VideoCaptureInput* input_; | 267 VideoCaptureInput* input_; |
267 test::LayerFilteringTransport* const transport_; | 268 test::LayerFilteringTransport* const transport_; |
268 PacketReceiver* receiver_; | 269 PacketReceiver* receiver_; |
269 VideoSendStream* send_stream_; | 270 VideoSendStream* send_stream_; |
270 | 271 |
271 private: | 272 private: |
272 struct FrameComparison { | 273 struct FrameComparison { |
273 FrameComparison() | 274 FrameComparison() |
274 : dropped(false), | 275 : dropped(false), |
275 send_time_ms(0), | 276 send_time_ms(0), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 int dropped; | 323 int dropped; |
323 int64_t input_time_ms; | 324 int64_t input_time_ms; |
324 int64_t send_time_ms; | 325 int64_t send_time_ms; |
325 int64_t recv_time_ms; | 326 int64_t recv_time_ms; |
326 int64_t render_time_ms; | 327 int64_t render_time_ms; |
327 size_t encoded_frame_size; | 328 size_t encoded_frame_size; |
328 double psnr; | 329 double psnr; |
329 double ssim; | 330 double ssim; |
330 }; | 331 }; |
331 | 332 |
| 333 // This class receives the send-side OnEncodeTiming and is provided to not |
| 334 // conflict with the receiver-side pre_decode_callback. |
| 335 class OnEncodeTimingProxy : public EncodedFrameObserver { |
| 336 public: |
| 337 explicit OnEncodeTimingProxy(VideoAnalyzer* parent) : parent_(parent) {} |
| 338 |
| 339 void OnEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) override { |
| 340 parent_->MeasuredEncodeTiming(ntp_time_ms, encode_time_ms); |
| 341 } |
| 342 void EncodedFrameCallback(const EncodedFrame& frame) override {} |
| 343 |
| 344 private: |
| 345 VideoAnalyzer* const parent_; |
| 346 }; |
| 347 |
332 void AddFrameComparison(const VideoFrame& reference, | 348 void AddFrameComparison(const VideoFrame& reference, |
333 const VideoFrame& render, | 349 const VideoFrame& render, |
334 bool dropped, | 350 bool dropped, |
335 int64_t render_time_ms) | 351 int64_t render_time_ms) |
336 EXCLUSIVE_LOCKS_REQUIRED(crit_) { | 352 EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
337 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); | 353 int64_t reference_timestamp = wrap_handler_.Unwrap(reference.timestamp()); |
338 int64_t send_time_ms = send_times_[reference_timestamp]; | 354 int64_t send_time_ms = send_times_[reference_timestamp]; |
339 send_times_.erase(reference_timestamp); | 355 send_times_.erase(reference_timestamp); |
340 int64_t recv_time_ms = recv_times_[reference_timestamp]; | 356 int64_t recv_time_ms = recv_times_[reference_timestamp]; |
341 recv_times_.erase(reference_timestamp); | 357 recv_times_.erase(reference_timestamp); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 fprintf(stderr, | 575 fprintf(stderr, |
560 "Warning: Missing encode_time_ms samples for %d frame(s).\n", | 576 "Warning: Missing encode_time_ms samples for %d frame(s).\n", |
561 missing_encode_time_samples); | 577 missing_encode_time_samples); |
562 } | 578 } |
563 } | 579 } |
564 | 580 |
565 const std::string test_label_; | 581 const std::string test_label_; |
566 FILE* const graph_data_output_file_; | 582 FILE* const graph_data_output_file_; |
567 const std::string graph_title_; | 583 const std::string graph_title_; |
568 const uint32_t ssrc_to_analyze_; | 584 const uint32_t ssrc_to_analyze_; |
| 585 OnEncodeTimingProxy encode_timing_proxy_; |
569 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); | 586 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); |
570 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); | 587 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); |
571 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); | 588 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); |
572 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); | 589 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); |
573 test::Statistics psnr_ GUARDED_BY(comparison_lock_); | 590 test::Statistics psnr_ GUARDED_BY(comparison_lock_); |
574 test::Statistics ssim_ GUARDED_BY(comparison_lock_); | 591 test::Statistics ssim_ GUARDED_BY(comparison_lock_); |
575 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); | 592 test::Statistics end_to_end_ GUARDED_BY(comparison_lock_); |
576 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); | 593 test::Statistics rendered_delta_ GUARDED_BY(comparison_lock_); |
577 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); | 594 test::Statistics encoded_frame_size_ GUARDED_BY(comparison_lock_); |
578 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); | 595 test::Statistics encode_frame_rate_ GUARDED_BY(comparison_lock_); |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 disable_quality_check ? -1.1 : params_.analyzer.avg_ssim_threshold, | 986 disable_quality_check ? -1.1 : params_.analyzer.avg_ssim_threshold, |
970 params_.analyzer.test_durations_secs * params_.common.fps, | 987 params_.analyzer.test_durations_secs * params_.common.fps, |
971 graph_data_output_file, graph_title, | 988 graph_data_output_file, graph_title, |
972 kVideoSendSsrcs[params_.ss.selected_stream]); | 989 kVideoSendSsrcs[params_.ss.selected_stream]); |
973 | 990 |
974 analyzer.SetReceiver(receiver_call_->Receiver()); | 991 analyzer.SetReceiver(receiver_call_->Receiver()); |
975 send_transport.SetReceiver(&analyzer); | 992 send_transport.SetReceiver(&analyzer); |
976 recv_transport.SetReceiver(sender_call_->Receiver()); | 993 recv_transport.SetReceiver(sender_call_->Receiver()); |
977 | 994 |
978 SetupCommon(&analyzer, &recv_transport); | 995 SetupCommon(&analyzer, &recv_transport); |
979 video_send_config_.encoding_time_observer = &analyzer; | |
980 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; | 996 video_receive_configs_[params_.ss.selected_stream].renderer = &analyzer; |
981 for (auto& config : video_receive_configs_) | 997 for (auto& config : video_receive_configs_) |
982 config.pre_decode_callback = &analyzer; | 998 config.pre_decode_callback = &analyzer; |
| 999 RTC_DCHECK(!video_send_config_.post_encode_callback); |
| 1000 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); |
983 | 1001 |
984 if (params_.screenshare.enabled) | 1002 if (params_.screenshare.enabled) |
985 SetupScreenshare(); | 1003 SetupScreenshare(); |
986 | 1004 |
987 CreateVideoStreams(); | 1005 CreateVideoStreams(); |
988 analyzer.input_ = video_send_stream_->Input(); | 1006 analyzer.input_ = video_send_stream_->Input(); |
989 analyzer.send_stream_ = video_send_stream_; | 1007 analyzer.send_stream_ = video_send_stream_; |
990 | 1008 |
991 CreateCapturer(&analyzer); | 1009 CreateCapturer(&analyzer); |
992 | 1010 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 video_send_stream_->Stop(); | 1087 video_send_stream_->Stop(); |
1070 receive_stream->Stop(); | 1088 receive_stream->Stop(); |
1071 | 1089 |
1072 call->DestroyVideoReceiveStream(receive_stream); | 1090 call->DestroyVideoReceiveStream(receive_stream); |
1073 call->DestroyVideoSendStream(video_send_stream_); | 1091 call->DestroyVideoSendStream(video_send_stream_); |
1074 | 1092 |
1075 transport.StopSending(); | 1093 transport.StopSending(); |
1076 } | 1094 } |
1077 | 1095 |
1078 } // namespace webrtc | 1096 } // namespace webrtc |
OLD | NEW |