Add ability to enable frame dumping decoder via field trial.
--force_fieldtrial=/WebRTC-DecoderDataDumpDirectory/./ will create a
file ./webrtc_receive_stream_[ssrc].ivf containing the exact data that
is fed to the decoder.
Bug: None
Change-Id: I4042298c9b851fc4b61c417652315fa2610de1ed
Reviewed-on: https://webrtc-review.googlesource.com/c/107644
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25467}
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 33dcbe6..e6a39e7 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -52,6 +52,7 @@
}
deps = [
+ ":frame_dumping_decoder",
"..:webrtc_common",
"../api:fec_controller_api",
"../api:libjingle_peerconnection_api",
@@ -133,6 +134,25 @@
]
}
+rtc_source_set("frame_dumping_decoder") {
+ visibility = [ "*" ]
+
+ sources = [
+ "frame_dumping_decoder.cc",
+ "frame_dumping_decoder.h",
+ ]
+
+ deps = [
+ "../api/video:encoded_frame",
+ "../api/video_codecs:video_codecs_api",
+ "../modules/video_coding:video_codec_interface",
+ "../modules/video_coding:video_coding",
+ "../modules/video_coding:video_coding_utility",
+ "../rtc_base:rtc_base_approved",
+ "//third_party/abseil-cpp/absl/memory",
+ ]
+}
+
rtc_source_set("video_stream_encoder_impl") {
visibility = [ "*" ]
@@ -204,6 +224,7 @@
"video_quality_test.h",
]
deps = [
+ ":frame_dumping_decoder",
"../api:fec_controller_api",
"../api:test_dependency_factory",
"../api:video_quality_test_fixture_api",
diff --git a/video/frame_dumping_decoder.cc b/video/frame_dumping_decoder.cc
new file mode 100644
index 0000000..7798511
--- /dev/null
+++ b/video/frame_dumping_decoder.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "video/frame_dumping_decoder.h"
+
+#include <utility>
+
+#include "modules/video_coding/include/video_codec_interface.h"
+
+namespace webrtc {
+
+FrameDumpingDecoder::FrameDumpingDecoder(std::unique_ptr<VideoDecoder> decoder,
+ rtc::PlatformFile file)
+ : decoder_(std::move(decoder)),
+ writer_(IvfFileWriter::Wrap(rtc::File(file),
+ /* byte_limit= */ 100000000)) {}
+
+FrameDumpingDecoder::~FrameDumpingDecoder() = default;
+
+int32_t FrameDumpingDecoder::InitDecode(const VideoCodec* codec_settings,
+ int32_t number_of_cores) {
+ return decoder_->InitDecode(codec_settings, number_of_cores);
+}
+
+int32_t FrameDumpingDecoder::Decode(
+ const EncodedImage& input_image,
+ bool missing_frames,
+ const CodecSpecificInfo* codec_specific_info,
+ int64_t render_time_ms) {
+ int32_t ret = decoder_->Decode(input_image, missing_frames,
+ codec_specific_info, render_time_ms);
+ writer_->WriteFrame(input_image, codec_specific_info->codecType);
+
+ return ret;
+}
+
+int32_t FrameDumpingDecoder::RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) {
+ return decoder_->RegisterDecodeCompleteCallback(callback);
+}
+
+int32_t FrameDumpingDecoder::Release() {
+ return decoder_->Release();
+}
+
+bool FrameDumpingDecoder::PrefersLateDecoding() const {
+ return decoder_->PrefersLateDecoding();
+}
+
+const char* FrameDumpingDecoder::ImplementationName() const {
+ return decoder_->ImplementationName();
+}
+
+} // namespace webrtc
diff --git a/video/frame_dumping_decoder.h b/video/frame_dumping_decoder.h
new file mode 100644
index 0000000..e19e9b4
--- /dev/null
+++ b/video/frame_dumping_decoder.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VIDEO_FRAME_DUMPING_DECODER_H_
+#define VIDEO_FRAME_DUMPING_DECODER_H_
+
+#include <memory>
+
+#include "api/video_codecs/video_decoder.h"
+#include "modules/video_coding/utility/ivf_file_writer.h"
+#include "rtc_base/platform_file.h"
+
+namespace webrtc {
+
+// A decoder wrapper that writes the encoded frames to a file.
+class FrameDumpingDecoder : public VideoDecoder {
+ public:
+ FrameDumpingDecoder(std::unique_ptr<VideoDecoder> decoder,
+ rtc::PlatformFile file);
+ ~FrameDumpingDecoder() override;
+
+ int32_t InitDecode(const VideoCodec* codec_settings,
+ int32_t number_of_cores) override;
+ int32_t Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ const CodecSpecificInfo* codec_specific_info,
+ int64_t render_time_ms) override;
+ int32_t RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) override;
+ int32_t Release() override;
+ bool PrefersLateDecoding() const override;
+ const char* ImplementationName() const override;
+
+ private:
+ std::unique_ptr<VideoDecoder> decoder_;
+ std::unique_ptr<IvfFileWriter> writer_;
+};
+
+} // namespace webrtc
+
+#endif // VIDEO_FRAME_DUMPING_DECODER_H_
diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc
index 15579d8..6517c97 100644
--- a/video/video_quality_test.cc
+++ b/video/video_quality_test.cc
@@ -35,6 +35,7 @@
#include "test/run_loop.h"
#include "test/testsupport/fileutils.h"
#include "test/video_renderer.h"
+#include "video/frame_dumping_decoder.h"
#ifdef WEBRTC_WIN
#include "modules/audio_device/include/audio_device_factory.h"
#endif
@@ -74,54 +75,6 @@
std::vector<VideoStream> streams_;
};
-// A decoder wrapper that writes the encoded frames to a file.
-class FrameDumpingDecoder : public VideoDecoder {
- public:
- FrameDumpingDecoder(std::unique_ptr<VideoDecoder> decoder,
- rtc::PlatformFile file)
- : decoder_(std::move(decoder)),
- writer_(IvfFileWriter::Wrap(rtc::File(file),
- /* byte_limit= */ 100000000)) {}
-
- int32_t InitDecode(const VideoCodec* codec_settings,
- int32_t number_of_cores) override {
- return decoder_->InitDecode(codec_settings, number_of_cores);
- }
-
- int32_t Decode(const EncodedImage& input_image,
- bool missing_frames,
- const CodecSpecificInfo* codec_specific_info,
- int64_t render_time_ms) override {
- int32_t ret = decoder_->Decode(input_image, missing_frames,
- codec_specific_info, render_time_ms);
- writer_->WriteFrame(input_image, codec_specific_info->codecType);
-
- return ret;
- }
-
- int32_t RegisterDecodeCompleteCallback(
- DecodedImageCallback* callback) override {
- return decoder_->RegisterDecodeCompleteCallback(callback);
- }
-
- int32_t Release() override { return decoder_->Release(); }
-
- // Returns true if the decoder prefer to decode frames late.
- // That is, it can not decode infinite number of frames before the decoded
- // frame is consumed.
- bool PrefersLateDecoding() const override {
- return decoder_->PrefersLateDecoding();
- }
-
- const char* ImplementationName() const override {
- return decoder_->ImplementationName();
- }
-
- private:
- std::unique_ptr<VideoDecoder> decoder_;
- std::unique_ptr<IvfFileWriter> writer_;
-};
-
// This wrapper provides two features needed by the video quality tests:
// 1. Invoke VideoAnalyzer callbacks before and after encoding each frame.
// 2. Write the encoded frames to file, one file per simulcast layer.
@@ -285,7 +238,8 @@
}),
receive_logs_(0),
send_logs_(0),
- injection_components_(std::move(injection_components)) {
+ injection_components_(std::move(injection_components)),
+ num_video_streams_(0) {
if (injection_components_ == nullptr) {
injection_components_ = absl::make_unique<InjectionComponents>();
}
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 9ffd278..2f78a80 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -35,10 +35,13 @@
#include "rtc_base/checks.h"
#include "rtc_base/location.h"
#include "rtc_base/logging.h"
+#include "rtc_base/platform_file.h"
+#include "rtc_base/strings/string_builder.h"
#include "rtc_base/trace_event.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
#include "video/call_stats.h"
+#include "video/frame_dumping_decoder.h"
#include "video/receive_statistics_proxy.h"
namespace webrtc {
@@ -246,6 +249,18 @@
if (!video_decoder) {
video_decoder = absl::make_unique<NullVideoDecoder>();
}
+
+ std::string decoded_output_file =
+ field_trial::FindFullName("WebRTC-DecoderDataDumpDirectory");
+ if (!decoded_output_file.empty()) {
+ char filename_buffer[256];
+ rtc::SimpleStringBuilder ssb(filename_buffer);
+ ssb << decoded_output_file << "/webrtc_receive_stream_"
+ << this->config_.rtp.local_ssrc << ".ivf";
+ video_decoder = absl::make_unique<FrameDumpingDecoder>(
+ std::move(video_decoder), rtc::CreatePlatformFile(ssb.str()));
+ }
+
video_decoders_.push_back(std::move(video_decoder));
video_receiver_.RegisterExternalDecoder(video_decoders_.back().get(),