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 "webrtc/video/video_quality_test.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "webrtc/rtc_base/memory_usage.h" | 39 #include "webrtc/rtc_base/memory_usage.h" |
40 #include "webrtc/rtc_base/optional.h" | 40 #include "webrtc/rtc_base/optional.h" |
41 #include "webrtc/rtc_base/pathutils.h" | 41 #include "webrtc/rtc_base/pathutils.h" |
42 #include "webrtc/rtc_base/platform_file.h" | 42 #include "webrtc/rtc_base/platform_file.h" |
43 #include "webrtc/rtc_base/ptr_util.h" | 43 #include "webrtc/rtc_base/ptr_util.h" |
44 #include "webrtc/rtc_base/timeutils.h" | 44 #include "webrtc/rtc_base/timeutils.h" |
45 #include "webrtc/system_wrappers/include/cpu_info.h" | 45 #include "webrtc/system_wrappers/include/cpu_info.h" |
46 #include "webrtc/system_wrappers/include/field_trial.h" | 46 #include "webrtc/system_wrappers/include/field_trial.h" |
47 #include "webrtc/test/gtest.h" | 47 #include "webrtc/test/gtest.h" |
48 #include "webrtc/test/layer_filtering_transport.h" | 48 #include "webrtc/test/layer_filtering_transport.h" |
| 49 #include "webrtc/test/rtp_file_writer.h" |
49 #include "webrtc/test/run_loop.h" | 50 #include "webrtc/test/run_loop.h" |
50 #include "webrtc/test/statistics.h" | 51 #include "webrtc/test/statistics.h" |
51 #include "webrtc/test/testsupport/fileutils.h" | 52 #include "webrtc/test/testsupport/fileutils.h" |
52 #include "webrtc/test/testsupport/frame_writer.h" | 53 #include "webrtc/test/testsupport/frame_writer.h" |
53 #include "webrtc/test/testsupport/test_output.h" | 54 #include "webrtc/test/testsupport/test_output.h" |
54 #include "webrtc/test/vcm_capturer.h" | 55 #include "webrtc/test/vcm_capturer.h" |
55 #include "webrtc/test/video_renderer.h" | 56 #include "webrtc/test/video_renderer.h" |
56 #include "webrtc/voice_engine/include/voe_base.h" | 57 #include "webrtc/voice_engine/include/voe_base.h" |
57 | 58 |
58 #include "webrtc/test/rtp_file_writer.h" | |
59 | |
60 DEFINE_bool(save_worst_frame, | 59 DEFINE_bool(save_worst_frame, |
61 false, | 60 false, |
62 "Enable saving a frame with the lowest PSNR to a jpeg file in the " | 61 "Enable saving a frame with the lowest PSNR to a jpeg file in the " |
63 "test_output_dir"); | 62 "test_output_dir"); |
64 | 63 |
65 namespace { | 64 namespace { |
66 | 65 |
67 constexpr int kSendStatsPollingIntervalMs = 1000; | 66 constexpr int kSendStatsPollingIntervalMs = 1000; |
68 | 67 |
69 constexpr size_t kMaxComparisons = 10; | 68 constexpr size_t kMaxComparisons = 10; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 double avg_ssim_threshold, | 154 double avg_ssim_threshold, |
156 int duration_frames, | 155 int duration_frames, |
157 FILE* graph_data_output_file, | 156 FILE* graph_data_output_file, |
158 const std::string& graph_title, | 157 const std::string& graph_title, |
159 uint32_t ssrc_to_analyze, | 158 uint32_t ssrc_to_analyze, |
160 uint32_t rtx_ssrc_to_analyze, | 159 uint32_t rtx_ssrc_to_analyze, |
161 size_t selected_stream, | 160 size_t selected_stream, |
162 int selected_sl, | 161 int selected_sl, |
163 int selected_tl, | 162 int selected_tl, |
164 bool is_quick_test_enabled, | 163 bool is_quick_test_enabled, |
165 Clock* clock, | 164 Clock* clock) |
166 std::string rtp_dump_name) | |
167 : transport_(transport), | 165 : transport_(transport), |
168 receiver_(nullptr), | 166 receiver_(nullptr), |
169 call_(nullptr), | 167 call_(nullptr), |
170 send_stream_(nullptr), | 168 send_stream_(nullptr), |
171 receive_stream_(nullptr), | 169 receive_stream_(nullptr), |
172 captured_frame_forwarder_(this, clock), | 170 captured_frame_forwarder_(this, clock), |
173 test_label_(test_label), | 171 test_label_(test_label), |
174 graph_data_output_file_(graph_data_output_file), | 172 graph_data_output_file_(graph_data_output_file), |
175 graph_title_(graph_title), | 173 graph_title_(graph_title), |
176 ssrc_to_analyze_(ssrc_to_analyze), | 174 ssrc_to_analyze_(ssrc_to_analyze), |
(...skipping 15 matching lines...) Expand all Loading... |
192 total_media_bytes_(0), | 190 total_media_bytes_(0), |
193 first_sending_time_(0), | 191 first_sending_time_(0), |
194 last_sending_time_(0), | 192 last_sending_time_(0), |
195 cpu_time_(0), | 193 cpu_time_(0), |
196 wallclock_time_(0), | 194 wallclock_time_(0), |
197 avg_psnr_threshold_(avg_psnr_threshold), | 195 avg_psnr_threshold_(avg_psnr_threshold), |
198 avg_ssim_threshold_(avg_ssim_threshold), | 196 avg_ssim_threshold_(avg_ssim_threshold), |
199 is_quick_test_enabled_(is_quick_test_enabled), | 197 is_quick_test_enabled_(is_quick_test_enabled), |
200 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), | 198 stats_polling_thread_(&PollStatsThread, this, "StatsPoller"), |
201 comparison_available_event_(false, false), | 199 comparison_available_event_(false, false), |
202 done_(true, false), | 200 done_(true, false) { |
203 clock_(clock), | |
204 start_ms_(clock->TimeInMilliseconds()) { | |
205 // Create thread pool for CPU-expensive PSNR/SSIM calculations. | 201 // Create thread pool for CPU-expensive PSNR/SSIM calculations. |
206 | 202 |
207 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, | 203 // Try to use about as many threads as cores, but leave kMinCoresLeft alone, |
208 // so that we don't accidentally starve "real" worker threads (codec etc). | 204 // so that we don't accidentally starve "real" worker threads (codec etc). |
209 // Also, don't allocate more than kMaxComparisonThreads, even if there are | 205 // Also, don't allocate more than kMaxComparisonThreads, even if there are |
210 // spare cores. | 206 // spare cores. |
211 | 207 |
212 uint32_t num_cores = CpuInfo::DetectNumberOfCores(); | 208 uint32_t num_cores = CpuInfo::DetectNumberOfCores(); |
213 RTC_DCHECK_GE(num_cores, 1); | 209 RTC_DCHECK_GE(num_cores, 1); |
214 static const uint32_t kMinCoresLeft = 4; | 210 static const uint32_t kMinCoresLeft = 4; |
215 static const uint32_t kMaxComparisonThreads = 8; | 211 static const uint32_t kMaxComparisonThreads = 8; |
216 | 212 |
217 if (num_cores <= kMinCoresLeft) { | 213 if (num_cores <= kMinCoresLeft) { |
218 num_cores = 1; | 214 num_cores = 1; |
219 } else { | 215 } else { |
220 num_cores -= kMinCoresLeft; | 216 num_cores -= kMinCoresLeft; |
221 num_cores = std::min(num_cores, kMaxComparisonThreads); | 217 num_cores = std::min(num_cores, kMaxComparisonThreads); |
222 } | 218 } |
223 | 219 |
224 for (uint32_t i = 0; i < num_cores; ++i) { | 220 for (uint32_t i = 0; i < num_cores; ++i) { |
225 rtc::PlatformThread* thread = | 221 rtc::PlatformThread* thread = |
226 new rtc::PlatformThread(&FrameComparisonThread, this, "Analyzer"); | 222 new rtc::PlatformThread(&FrameComparisonThread, this, "Analyzer"); |
227 thread->Start(); | 223 thread->Start(); |
228 comparison_thread_pool_.push_back(thread); | 224 comparison_thread_pool_.push_back(thread); |
229 } | 225 } |
230 | |
231 if (!rtp_dump_name.empty()) { | |
232 fprintf(stdout, "Writing rtp dump to %s\n", rtp_dump_name.c_str()); | |
233 rtp_file_writer_.reset(test::RtpFileWriter::Create( | |
234 test::RtpFileWriter::kRtpDump, rtp_dump_name)); | |
235 } | |
236 } | 226 } |
237 | 227 |
238 ~VideoAnalyzer() { | 228 ~VideoAnalyzer() { |
239 for (rtc::PlatformThread* thread : comparison_thread_pool_) { | 229 for (rtc::PlatformThread* thread : comparison_thread_pool_) { |
240 thread->Stop(); | 230 thread->Stop(); |
241 delete thread; | 231 delete thread; |
242 } | 232 } |
243 } | 233 } |
244 | 234 |
245 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } | 235 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 DeliveryStatus DeliverPacket(MediaType media_type, | 269 DeliveryStatus DeliverPacket(MediaType media_type, |
280 const uint8_t* packet, | 270 const uint8_t* packet, |
281 size_t length, | 271 size_t length, |
282 const PacketTime& packet_time) override { | 272 const PacketTime& packet_time) override { |
283 // Ignore timestamps of RTCP packets. They're not synchronized with | 273 // Ignore timestamps of RTCP packets. They're not synchronized with |
284 // RTP packet timestamps and so they would confuse wrap_handler_. | 274 // RTP packet timestamps and so they would confuse wrap_handler_. |
285 if (RtpHeaderParser::IsRtcp(packet, length)) { | 275 if (RtpHeaderParser::IsRtcp(packet, length)) { |
286 return receiver_->DeliverPacket(media_type, packet, length, packet_time); | 276 return receiver_->DeliverPacket(media_type, packet, length, packet_time); |
287 } | 277 } |
288 | 278 |
289 if (rtp_file_writer_) { | |
290 test::RtpPacket p; | |
291 memcpy(p.data, packet, length); | |
292 p.length = length; | |
293 p.original_length = length; | |
294 p.time_ms = clock_->TimeInMilliseconds() - start_ms_; | |
295 rtp_file_writer_->WritePacket(&p); | |
296 } | |
297 | |
298 RtpUtility::RtpHeaderParser parser(packet, length); | 279 RtpUtility::RtpHeaderParser parser(packet, length); |
299 RTPHeader header; | 280 RTPHeader header; |
300 parser.Parse(&header); | 281 parser.Parse(&header); |
301 if (!IsFlexfec(header.payloadType) && | 282 if (!IsFlexfec(header.payloadType) && |
302 (header.ssrc == ssrc_to_analyze_ || | 283 (header.ssrc == ssrc_to_analyze_ || |
303 header.ssrc == rtx_ssrc_to_analyze_)) { | 284 header.ssrc == rtx_ssrc_to_analyze_)) { |
304 // Ignore FlexFEC timestamps, to avoid collisions with media timestamps. | 285 // Ignore FlexFEC timestamps, to avoid collisions with media timestamps. |
305 // (FlexFEC and media are sent on different SSRCs, which have different | 286 // (FlexFEC and media are sent on different SSRCs, which have different |
306 // timestamps spaces.) | 287 // timestamps spaces.) |
307 // Also ignore packets from wrong SSRC, but include retransmits. | 288 // Also ignore packets from wrong SSRC, but include retransmits. |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 const double avg_psnr_threshold_; | 1094 const double avg_psnr_threshold_; |
1114 const double avg_ssim_threshold_; | 1095 const double avg_ssim_threshold_; |
1115 bool is_quick_test_enabled_; | 1096 bool is_quick_test_enabled_; |
1116 | 1097 |
1117 rtc::CriticalSection comparison_lock_; | 1098 rtc::CriticalSection comparison_lock_; |
1118 std::vector<rtc::PlatformThread*> comparison_thread_pool_; | 1099 std::vector<rtc::PlatformThread*> comparison_thread_pool_; |
1119 rtc::PlatformThread stats_polling_thread_; | 1100 rtc::PlatformThread stats_polling_thread_; |
1120 rtc::Event comparison_available_event_; | 1101 rtc::Event comparison_available_event_; |
1121 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); | 1102 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_); |
1122 rtc::Event done_; | 1103 rtc::Event done_; |
1123 | |
1124 std::unique_ptr<test::RtpFileWriter> rtp_file_writer_; | |
1125 Clock* const clock_; | |
1126 const int64_t start_ms_; | |
1127 }; | 1104 }; |
1128 | 1105 |
1129 class Vp8EncoderFactory : public cricket::WebRtcVideoEncoderFactory { | 1106 class Vp8EncoderFactory : public cricket::WebRtcVideoEncoderFactory { |
1130 public: | 1107 public: |
1131 Vp8EncoderFactory() { | 1108 Vp8EncoderFactory() { |
1132 supported_codecs_.push_back(cricket::VideoCodec("VP8")); | 1109 supported_codecs_.push_back(cricket::VideoCodec("VP8")); |
1133 } | 1110 } |
1134 ~Vp8EncoderFactory() override { RTC_CHECK(live_encoders_.empty()); } | 1111 ~Vp8EncoderFactory() override { RTC_CHECK(live_encoders_.empty()); } |
1135 | 1112 |
1136 const std::vector<cricket::VideoCodec>& supported_codecs() const override { | 1113 const std::vector<cricket::VideoCodec>& supported_codecs() const override { |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 RTC_DCHECK(event_log_started); | 1778 RTC_DCHECK(event_log_started); |
1802 } | 1779 } |
1803 | 1780 |
1804 Call::Config call_config(event_log_.get()); | 1781 Call::Config call_config(event_log_.get()); |
1805 call_config.bitrate_config = params.call.call_bitrate_config; | 1782 call_config.bitrate_config = params.call.call_bitrate_config; |
1806 | 1783 |
1807 task_queue_.SendTask([this, &call_config, &send_transport, | 1784 task_queue_.SendTask([this, &call_config, &send_transport, |
1808 &recv_transport]() { | 1785 &recv_transport]() { |
1809 CreateCalls(call_config, call_config); | 1786 CreateCalls(call_config, call_config); |
1810 | 1787 |
| 1788 std::unique_ptr<test::RtpFileWriter> rtp_file_writer; |
| 1789 if (!params_.logging.rtp_dump_name.empty()) { |
| 1790 LOG(LS_INFO) << "Writing rtp dump to " << params_.logging.rtp_dump_name; |
| 1791 rtp_file_writer.reset(test::RtpFileWriter::Create( |
| 1792 test::RtpFileWriter::kRtpDump, params_.logging.rtp_dump_name)); |
| 1793 } |
| 1794 |
1811 send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( | 1795 send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( |
1812 &task_queue_, params_.pipe, sender_call_.get(), kPayloadTypeVP8, | 1796 &task_queue_, params_.pipe, sender_call_.get(), kPayloadTypeVP8, |
1813 kPayloadTypeVP9, params_.video.selected_tl, params_.ss.selected_sl, | 1797 kPayloadTypeVP9, params_.video.selected_tl, params_.ss.selected_sl, |
1814 payload_type_map_); | 1798 payload_type_map_, std::move(rtp_file_writer)); |
1815 | 1799 |
1816 recv_transport = rtc::MakeUnique<test::DirectTransport>( | 1800 recv_transport = rtc::MakeUnique<test::DirectTransport>( |
1817 &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_); | 1801 &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_, |
| 1802 std::unique_ptr<test::RtpFileWriter>()); |
1818 }); | 1803 }); |
1819 | 1804 |
1820 std::string graph_title = params_.analyzer.graph_title; | 1805 std::string graph_title = params_.analyzer.graph_title; |
1821 if (graph_title.empty()) | 1806 if (graph_title.empty()) |
1822 graph_title = VideoQualityTest::GenerateGraphTitle(); | 1807 graph_title = VideoQualityTest::GenerateGraphTitle(); |
1823 bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest"); | 1808 bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest"); |
1824 analyzer = rtc::MakeUnique<VideoAnalyzer>( | 1809 analyzer = rtc::MakeUnique<VideoAnalyzer>( |
1825 send_transport.get(), params_.analyzer.test_label, | 1810 send_transport.get(), params_.analyzer.test_label, |
1826 params_.analyzer.avg_psnr_threshold, params_.analyzer.avg_ssim_threshold, | 1811 params_.analyzer.avg_psnr_threshold, params_.analyzer.avg_ssim_threshold, |
1827 is_quick_test_enabled | 1812 is_quick_test_enabled |
1828 ? kFramesSentInQuickTest | 1813 ? kFramesSentInQuickTest |
1829 : params_.analyzer.test_durations_secs * params_.video.fps, | 1814 : params_.analyzer.test_durations_secs * params_.video.fps, |
1830 graph_data_output_file, graph_title, | 1815 graph_data_output_file, graph_title, |
1831 kVideoSendSsrcs[params_.ss.selected_stream], | 1816 kVideoSendSsrcs[params_.ss.selected_stream], |
1832 kSendRtxSsrcs[params_.ss.selected_stream], | 1817 kSendRtxSsrcs[params_.ss.selected_stream], |
1833 static_cast<size_t>(params_.ss.selected_stream), params.ss.selected_sl, | 1818 static_cast<size_t>(params_.ss.selected_stream), params.ss.selected_sl, |
1834 params_.video.selected_tl, is_quick_test_enabled, clock_, | 1819 params_.video.selected_tl, is_quick_test_enabled, clock_); |
1835 params_.logging.rtp_dump_name); | |
1836 | 1820 |
1837 task_queue_.SendTask([&]() { | 1821 task_queue_.SendTask([&]() { |
1838 analyzer->SetCall(sender_call_.get()); | 1822 analyzer->SetCall(sender_call_.get()); |
1839 analyzer->SetReceiver(receiver_call_->Receiver()); | 1823 analyzer->SetReceiver(receiver_call_->Receiver()); |
1840 send_transport->SetReceiver(analyzer.get()); | 1824 send_transport->SetReceiver(analyzer.get()); |
1841 recv_transport->SetReceiver(sender_call_->Receiver()); | 1825 recv_transport->SetReceiver(sender_call_->Receiver()); |
1842 | 1826 |
1843 SetupVideo(analyzer.get(), recv_transport.get()); | 1827 SetupVideo(analyzer.get(), recv_transport.get()); |
1844 SetupThumbnails(analyzer.get(), recv_transport.get()); | 1828 SetupThumbnails(analyzer.get(), recv_transport.get()); |
1845 video_receive_configs_[params_.ss.selected_stream].renderer = | 1829 video_receive_configs_[params_.ss.selected_stream].renderer = |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 CreateVoiceEngine(&voe, audio_processing.get(), decoder_factory_); | 1971 CreateVoiceEngine(&voe, audio_processing.get(), decoder_factory_); |
1988 AudioState::Config audio_state_config; | 1972 AudioState::Config audio_state_config; |
1989 audio_state_config.voice_engine = voe.voice_engine; | 1973 audio_state_config.voice_engine = voe.voice_engine; |
1990 audio_state_config.audio_mixer = AudioMixerImpl::Create(); | 1974 audio_state_config.audio_mixer = AudioMixerImpl::Create(); |
1991 audio_state_config.audio_processing = audio_processing; | 1975 audio_state_config.audio_processing = audio_processing; |
1992 call_config.audio_state = AudioState::Create(audio_state_config); | 1976 call_config.audio_state = AudioState::Create(audio_state_config); |
1993 } | 1977 } |
1994 | 1978 |
1995 CreateCalls(call_config, call_config); | 1979 CreateCalls(call_config, call_config); |
1996 | 1980 |
| 1981 std::unique_ptr<test::RtpFileWriter> rtp_file_writer; |
| 1982 if (!params_.logging.rtp_dump_name.empty()) { |
| 1983 LOG(LS_INFO) << "Writing rtp dump to " << params_.logging.rtp_dump_name; |
| 1984 rtp_file_writer.reset(test::RtpFileWriter::Create( |
| 1985 test::RtpFileWriter::kRtpDump, params_.logging.rtp_dump_name)); |
| 1986 } |
| 1987 |
1997 // TODO(minyue): consider if this is a good transport even for audio only | 1988 // TODO(minyue): consider if this is a good transport even for audio only |
1998 // calls. | 1989 // calls. |
1999 send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( | 1990 send_transport = rtc::MakeUnique<test::LayerFilteringTransport>( |
2000 &task_queue_, params.pipe, sender_call_.get(), kPayloadTypeVP8, | 1991 &task_queue_, params.pipe, sender_call_.get(), kPayloadTypeVP8, |
2001 kPayloadTypeVP9, params.video.selected_tl, params_.ss.selected_sl, | 1992 kPayloadTypeVP9, params.video.selected_tl, params_.ss.selected_sl, |
2002 payload_type_map_); | 1993 payload_type_map_, std::move(rtp_file_writer)); |
2003 | 1994 |
2004 recv_transport = rtc::MakeUnique<test::DirectTransport>( | 1995 recv_transport = rtc::MakeUnique<test::DirectTransport>( |
2005 &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_); | 1996 &task_queue_, params_.pipe, receiver_call_.get(), payload_type_map_, |
| 1997 std::unique_ptr<test::RtpFileWriter>()); |
2006 | 1998 |
2007 // TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at | 1999 // TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at |
2008 // least share as much code as possible. That way this test would also match | 2000 // least share as much code as possible. That way this test would also match |
2009 // the full stack tests better. | 2001 // the full stack tests better. |
2010 send_transport->SetReceiver(receiver_call_->Receiver()); | 2002 send_transport->SetReceiver(receiver_call_->Receiver()); |
2011 recv_transport->SetReceiver(sender_call_->Receiver()); | 2003 recv_transport->SetReceiver(sender_call_->Receiver()); |
2012 | 2004 |
2013 if (params_.video.enabled) { | 2005 if (params_.video.enabled) { |
2014 // Create video renderers. | 2006 // Create video renderers. |
2015 local_preview.reset(test::VideoRenderer::Create( | 2007 local_preview.reset(test::VideoRenderer::Create( |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 if (!params_.logging.encoded_frame_base_path.empty()) { | 2148 if (!params_.logging.encoded_frame_base_path.empty()) { |
2157 std::ostringstream str; | 2149 std::ostringstream str; |
2158 str << receive_logs_++; | 2150 str << receive_logs_++; |
2159 std::string path = | 2151 std::string path = |
2160 params_.logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; | 2152 params_.logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; |
2161 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), | 2153 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), |
2162 100000000); | 2154 100000000); |
2163 } | 2155 } |
2164 } | 2156 } |
2165 } // namespace webrtc | 2157 } // namespace webrtc |
OLD | NEW |