Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: webrtc/video/video_quality_test.cc

Issue 2257413002: Replace interface VideoCapturerInput with VideoSinkInterface. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: git cl format Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 37
38 namespace webrtc { 38 namespace webrtc {
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 static const size_t kMaxComparisons = 10; 44 static const size_t kMaxComparisons = 10;
45 45
46 class VideoAnalyzer : public PacketReceiver, 46 class VideoAnalyzer : public PacketReceiver,
47 public Transport, 47 public Transport,
48 public rtc::VideoSinkInterface<VideoFrame>, 48 public rtc::VideoSinkInterface<VideoFrame>,
49 public VideoCaptureInput,
50 public EncodedFrameObserver { 49 public EncodedFrameObserver {
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 : transport_(transport),
61 transport_(transport),
62 receiver_(nullptr), 60 receiver_(nullptr),
63 send_stream_(nullptr), 61 send_stream_(nullptr),
62 captured_frame_forwarder_(this),
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),
68 pre_encode_proxy_(this), 67 pre_encode_proxy_(this),
69 encode_timing_proxy_(this), 68 encode_timing_proxy_(this),
70 frames_to_process_(duration_frames), 69 frames_to_process_(duration_frames),
71 frames_recorded_(0), 70 frames_recorded_(0),
72 frames_processed_(0), 71 frames_processed_(0),
73 dropped_frames_(0), 72 dropped_frames_(0),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 108
110 ~VideoAnalyzer() { 109 ~VideoAnalyzer() {
111 for (rtc::PlatformThread* thread : comparison_thread_pool_) { 110 for (rtc::PlatformThread* thread : comparison_thread_pool_) {
112 thread->Stop(); 111 thread->Stop();
113 delete thread; 112 delete thread;
114 } 113 }
115 } 114 }
116 115
117 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } 116 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; }
118 117
118 void SetSendSendStream(VideoSendStream* stream) {
119 rtc::CritScope lock(&crit_);
120 RTC_DCHECK(!send_stream_);
121 send_stream_ = stream;
122 }
123
124 rtc::VideoSinkInterface<VideoFrame>* InputInterface() {
125 return &captured_frame_forwarder_;
126 }
127 rtc::VideoSourceInterface<VideoFrame>* OutputInterface() {
128 return &captured_frame_forwarder_;
129 }
130
119 DeliveryStatus DeliverPacket(MediaType media_type, 131 DeliveryStatus DeliverPacket(MediaType media_type,
120 const uint8_t* packet, 132 const uint8_t* packet,
121 size_t length, 133 size_t length,
122 const PacketTime& packet_time) override { 134 const PacketTime& packet_time) override {
123 // Ignore timestamps of RTCP packets. They're not synchronized with 135 // Ignore timestamps of RTCP packets. They're not synchronized with
124 // RTP packet timestamps and so they would confuse wrap_handler_. 136 // RTP packet timestamps and so they would confuse wrap_handler_.
125 if (RtpHeaderParser::IsRtcp(packet, length)) { 137 if (RtpHeaderParser::IsRtcp(packet, length)) {
126 return receiver_->DeliverPacket(media_type, packet, length, packet_time); 138 return receiver_->DeliverPacket(media_type, packet, length, packet_time);
127 } 139 }
128 140
129 RtpUtility::RtpHeaderParser parser(packet, length); 141 RtpUtility::RtpHeaderParser parser(packet, length);
130 RTPHeader header; 142 RTPHeader header;
131 parser.Parse(&header); 143 parser.Parse(&header);
132 { 144 {
133 rtc::CritScope lock(&crit_); 145 rtc::CritScope lock(&crit_);
134 int64_t timestamp = 146 int64_t timestamp =
135 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); 147 wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_);
136 recv_times_[timestamp] = 148 recv_times_[timestamp] =
137 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds(); 149 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
138 } 150 }
139 151
140 return receiver_->DeliverPacket(media_type, packet, length, packet_time); 152 return receiver_->DeliverPacket(media_type, packet, length, packet_time);
141 } 153 }
142 154
143 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) { 155 void MeasuredEncodeTiming(int64_t ntp_time_ms, int encode_time_ms) {
144 rtc::CritScope crit(&comparison_lock_); 156 rtc::CritScope crit(&comparison_lock_);
145 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms; 157 samples_encode_time_ms_[ntp_time_ms] = encode_time_ms;
146 } 158 }
147 159
148 void IncomingCapturedFrame(const VideoFrame& video_frame) override {
149 VideoFrame copy = video_frame;
150 copy.set_timestamp(copy.ntp_time_ms() * 90);
151 {
152 rtc::CritScope lock(&crit_);
153 frames_.push_back(copy);
154 }
155
156 input_->IncomingCapturedFrame(video_frame);
157 }
158
159 void PreEncodeOnFrame(const VideoFrame& video_frame) { 160 void PreEncodeOnFrame(const VideoFrame& video_frame) {
160 rtc::CritScope lock(&crit_); 161 rtc::CritScope lock(&crit_);
161 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) { 162 if (!first_send_timestamp_ && rtp_timestamp_delta_ == 0) {
162 while (frames_.front().timestamp() != video_frame.timestamp()) { 163 while (frames_.front().timestamp() != video_frame.timestamp()) {
163 ++dropped_frames_before_first_encode_; 164 ++dropped_frames_before_first_encode_;
164 frames_.pop_front(); 165 frames_.pop_front();
165 RTC_CHECK(!frames_.empty()); 166 RTC_CHECK(!frames_.empty());
166 } 167 }
167 first_send_timestamp_ = rtc::Optional<uint32_t>(video_frame.timestamp()); 168 first_send_timestamp_ = rtc::Optional<uint32_t>(video_frame.timestamp());
168 } 169 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 printf("- Farewell, sweet Concorde!\n"); 287 printf("- Farewell, sweet Concorde!\n");
287 288
288 stats_polling_thread_.Stop(); 289 stats_polling_thread_.Stop();
289 } 290 }
290 291
291 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() { 292 rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy() {
292 return &pre_encode_proxy_; 293 return &pre_encode_proxy_;
293 } 294 }
294 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; } 295 EncodedFrameObserver* encode_timing_proxy() { return &encode_timing_proxy_; }
295 296
296 VideoCaptureInput* input_;
297 test::LayerFilteringTransport* const transport_; 297 test::LayerFilteringTransport* const transport_;
298 PacketReceiver* receiver_; 298 PacketReceiver* receiver_;
299 VideoSendStream* send_stream_;
300 299
301 private: 300 private:
302 struct FrameComparison { 301 struct FrameComparison {
303 FrameComparison() 302 FrameComparison()
304 : dropped(false), 303 : dropped(false),
305 send_time_ms(0), 304 send_time_ms(0),
306 recv_time_ms(0), 305 recv_time_ms(0),
307 render_time_ms(0), 306 render_time_ms(0),
308 encoded_frame_size(0) {} 307 encoded_frame_size(0) {}
309 308
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 sample.encoded_frame_size, sample.psnr, sample.ssim, 636 sample.encoded_frame_size, sample.psnr, sample.ssim,
638 encode_time_ms); 637 encode_time_ms);
639 } 638 }
640 if (missing_encode_time_samples) { 639 if (missing_encode_time_samples) {
641 fprintf(stderr, 640 fprintf(stderr,
642 "Warning: Missing encode_time_ms samples for %d frame(s).\n", 641 "Warning: Missing encode_time_ms samples for %d frame(s).\n",
643 missing_encode_time_samples); 642 missing_encode_time_samples);
644 } 643 }
645 } 644 }
646 645
646 // Implements VideoSinkInterface to receive captured frames from a
647 // FrameGeneratorCapturer. Implements VideoSourceInterface to be able to act
648 // as a source to VideoSendStream.
649 // It forwards all input frames to the VideoAnalyser for later comparison and
650 // forwards the captured frames to the VideoSendStream.
651 class CapturedFrameForwarder : public rtc::VideoSinkInterface<VideoFrame>,
652 public rtc::VideoSourceInterface<VideoFrame> {
653 public:
654 explicit CapturedFrameForwarder(VideoAnalyzer* analyzer)
655 : analyzer_(analyzer), send_stream_input_(nullptr) {}
656
657 private:
658 void OnFrame(const VideoFrame& video_frame) override {
659 VideoFrame copy = video_frame;
660 copy.set_timestamp(copy.ntp_time_ms() * 90);
661
662 analyzer_->AddCapturedFrameForComparison(video_frame);
663 rtc::CritScope lock(&crit_);
664 if (send_stream_input_)
665 send_stream_input_->OnFrame(video_frame);
666 }
667 // Called when |send_stream_.SetSource()| is called.
668 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
669 const rtc::VideoSinkWants& wants) override {
670 rtc::CritScope lock(&crit_);
671 RTC_DCHECK(!send_stream_input_ || send_stream_input_ == sink);
672 send_stream_input_ = sink;
673 }
674
675 // Called by |send_stream_| when |send_stream_.SetSource()| is called.
676 void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {
677 rtc::CritScope lock(&crit_);
678 RTC_DCHECK(sink == send_stream_input_);
679 send_stream_input_ = nullptr;
680 }
681
682 VideoAnalyzer* const analyzer_;
683 rtc::CriticalSection crit_;
684 rtc::VideoSinkInterface<VideoFrame>* send_stream_input_ GUARDED_BY(crit_);
685 };
686
687 void AddCapturedFrameForComparison(const VideoFrame& video_frame) {
688 rtc::CritScope lock(&crit_);
689 frames_.push_back(video_frame);
690 }
691
692 VideoSendStream* send_stream_;
693 CapturedFrameForwarder captured_frame_forwarder_;
647 const std::string test_label_; 694 const std::string test_label_;
648 FILE* const graph_data_output_file_; 695 FILE* const graph_data_output_file_;
649 const std::string graph_title_; 696 const std::string graph_title_;
650 const uint32_t ssrc_to_analyze_; 697 const uint32_t ssrc_to_analyze_;
651 PreEncodeProxy pre_encode_proxy_; 698 PreEncodeProxy pre_encode_proxy_;
652 OnEncodeTimingProxy encode_timing_proxy_; 699 OnEncodeTimingProxy encode_timing_proxy_;
653 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_); 700 std::vector<Sample> samples_ GUARDED_BY(comparison_lock_);
654 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_); 701 std::map<int64_t, int> samples_encode_time_ms_ GUARDED_BY(comparison_lock_);
655 test::Statistics sender_time_ GUARDED_BY(comparison_lock_); 702 test::Statistics sender_time_ GUARDED_BY(comparison_lock_);
656 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_); 703 test::Statistics receiver_time_ GUARDED_BY(comparison_lock_);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 params_.screenshare.slide_change_interval); 1015 params_.screenshare.slide_change_interval);
969 1016
970 frame_generator_.reset( 1017 frame_generator_.reset(
971 test::FrameGenerator::CreateScrollingInputFromYuvFiles( 1018 test::FrameGenerator::CreateScrollingInputFromYuvFiles(
972 clock_, slides, kWidth, kHeight, params_.common.width, 1019 clock_, slides, kWidth, kHeight, params_.common.width,
973 params_.common.height, params_.screenshare.scroll_duration * 1000, 1020 params_.common.height, params_.screenshare.scroll_duration * 1000,
974 kPauseDurationMs)); 1021 kPauseDurationMs));
975 } 1022 }
976 } 1023 }
977 1024
978 void VideoQualityTest::CreateCapturer(VideoCaptureInput* input) { 1025 void VideoQualityTest::CreateCapturer() {
979 if (params_.screenshare.enabled) { 1026 if (params_.screenshare.enabled) {
980 test::FrameGeneratorCapturer* frame_generator_capturer = 1027 test::FrameGeneratorCapturer* frame_generator_capturer =
981 new test::FrameGeneratorCapturer( 1028 new test::FrameGeneratorCapturer(clock_, frame_generator_.release(),
982 clock_, input, frame_generator_.release(), params_.common.fps); 1029 params_.common.fps);
983 EXPECT_TRUE(frame_generator_capturer->Init()); 1030 EXPECT_TRUE(frame_generator_capturer->Init());
984 capturer_.reset(frame_generator_capturer); 1031 capturer_.reset(frame_generator_capturer);
985 } else { 1032 } else {
986 if (params_.video.clip_name.empty()) { 1033 if (params_.video.clip_name.empty()) {
987 capturer_.reset(test::VideoCapturer::Create(input, params_.common.width, 1034 capturer_.reset(test::VcmCapturer::Create(
988 params_.common.height, 1035 params_.common.width, params_.common.height, params_.common.fps));
989 params_.common.fps, clock_));
990 } else { 1036 } else {
991 capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile( 1037 capturer_.reset(test::FrameGeneratorCapturer::CreateFromYuvFile(
992 input, test::ResourcePath(params_.video.clip_name, "yuv"), 1038 test::ResourcePath(params_.video.clip_name, "yuv"),
993 params_.common.width, params_.common.height, params_.common.fps, 1039 params_.common.width, params_.common.height, params_.common.fps,
994 clock_)); 1040 clock_));
995 ASSERT_TRUE(capturer_) << "Could not create capturer for " 1041 ASSERT_TRUE(capturer_) << "Could not create capturer for "
996 << params_.video.clip_name 1042 << params_.video.clip_name
997 << ".yuv. Is this resource file present?"; 1043 << ".yuv. Is this resource file present?";
998 } 1044 }
999 } 1045 }
1000 } 1046 }
1001 1047
1002 void VideoQualityTest::RunWithAnalyzer(const Params& params) { 1048 void VideoQualityTest::RunWithAnalyzer(const Params& params) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy(); 1112 video_send_config_.pre_encode_callback = analyzer.pre_encode_proxy();
1067 for (auto& config : video_receive_configs_) 1113 for (auto& config : video_receive_configs_)
1068 config.pre_decode_callback = &analyzer; 1114 config.pre_decode_callback = &analyzer;
1069 RTC_DCHECK(!video_send_config_.post_encode_callback); 1115 RTC_DCHECK(!video_send_config_.post_encode_callback);
1070 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy(); 1116 video_send_config_.post_encode_callback = analyzer.encode_timing_proxy();
1071 1117
1072 if (params_.screenshare.enabled) 1118 if (params_.screenshare.enabled)
1073 SetupScreenshare(); 1119 SetupScreenshare();
1074 1120
1075 CreateVideoStreams(); 1121 CreateVideoStreams();
1076 analyzer.input_ = video_send_stream_->Input(); 1122 analyzer.SetSendSendStream(video_send_stream_);
1077 analyzer.send_stream_ = video_send_stream_; 1123 video_send_stream_->SetSource(analyzer.OutputInterface());
1078 1124
1079 CreateCapturer(&analyzer); 1125 CreateCapturer();
1126 rtc::VideoSinkWants wants;
1127 capturer_->AddOrUpdateSink(analyzer.InputInterface(), wants);
1080 1128
1081 video_send_stream_->Start(); 1129 video_send_stream_->Start();
1082 for (VideoReceiveStream* receive_stream : video_receive_streams_) 1130 for (VideoReceiveStream* receive_stream : video_receive_streams_)
1083 receive_stream->Start(); 1131 receive_stream->Start();
1084 capturer_->Start(); 1132 capturer_->Start();
1085 1133
1086 analyzer.Wait(); 1134 analyzer.Wait();
1087 1135
1088 send_transport.StopSending(); 1136 send_transport.StopSending();
1089 recv_transport.StopSending(); 1137 recv_transport.StopSending();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 kUlpfecPayloadType; 1198 kUlpfecPayloadType;
1151 } 1199 }
1152 1200
1153 if (params_.screenshare.enabled) 1201 if (params_.screenshare.enabled)
1154 SetupScreenshare(); 1202 SetupScreenshare();
1155 1203
1156 video_send_stream_ = call->CreateVideoSendStream( 1204 video_send_stream_ = call->CreateVideoSendStream(
1157 video_send_config_.Copy(), video_encoder_config_.Copy()); 1205 video_send_config_.Copy(), video_encoder_config_.Copy());
1158 VideoReceiveStream* receive_stream = 1206 VideoReceiveStream* receive_stream =
1159 call->CreateVideoReceiveStream(video_receive_configs_[stream_id].Copy()); 1207 call->CreateVideoReceiveStream(video_receive_configs_[stream_id].Copy());
1160 CreateCapturer(video_send_stream_->Input()); 1208 CreateCapturer();
1209 video_send_stream_->SetSource(capturer_.get());
1161 1210
1162 receive_stream->Start(); 1211 receive_stream->Start();
1163 video_send_stream_->Start(); 1212 video_send_stream_->Start();
1164 capturer_->Start(); 1213 capturer_->Start();
1165 1214
1166 test::PressEnterToContinue(); 1215 test::PressEnterToContinue();
1167 1216
1168 capturer_->Stop(); 1217 capturer_->Stop();
1169 video_send_stream_->Stop(); 1218 video_send_stream_->Stop();
1170 receive_stream->Stop(); 1219 receive_stream->Stop();
1171 1220
1172 call->DestroyVideoReceiveStream(receive_stream); 1221 call->DestroyVideoReceiveStream(receive_stream);
1173 call->DestroyVideoSendStream(video_send_stream_); 1222 call->DestroyVideoSendStream(video_send_stream_);
1174 1223
1175 transport.StopSending(); 1224 transport.StopSending();
1176 } 1225 }
1177 1226
1178 } // namespace webrtc 1227 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698