From ebb5383fd8cc5f0187ec17e21b0aa1e042a7a871 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Tue, 21 Mar 2023 11:03:28 +0100 Subject: [PATCH] Dump codec input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add functionality for dumping encoder and decoder input to file in video codec test. Bug: b/261160916, webrtc:14852 Change-Id: I49a84a886d87903c601cf5c35bd723b6393c2a75 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298051 Commit-Queue: Sergey Silkin Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#39626} --- api/test/video_codec_tester.h | 6 +- .../codecs/test/video_codec_test.cc | 36 +++++--- .../codecs/test/video_codec_tester_impl.cc | 84 ++++++++++++------- 3 files changed, 81 insertions(+), 45 deletions(-) diff --git a/api/test/video_codec_tester.h b/api/test/video_codec_tester.h index 1bd341c05b..c2fb89e2cb 100644 --- a/api/test/video_codec_tester.h +++ b/api/test/video_codec_tester.h @@ -47,12 +47,14 @@ class VideoCodecTester { struct DecoderSettings { PacingSettings pacing; - absl::optional decoded_y4m_base_path; + absl::optional decoder_input_base_path; + absl::optional decoder_output_base_path; }; struct EncoderSettings { PacingSettings pacing; - absl::optional encoded_ivf_base_path; + absl::optional encoder_input_base_path; + absl::optional encoder_output_base_path; }; virtual ~VideoCodecTester() = default; diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index e260cb77ee..a0d3a5a41b 100644 --- a/modules/video_coding/codecs/test/video_codec_test.cc +++ b/modules/video_coding/codecs/test/video_codec_test.cc @@ -457,6 +457,7 @@ std::unique_ptr RunEncodeDecodeTest( const VideoInfo& video_info, const std::map& frame_settings, int num_frames, + bool save_codec_input, bool save_codec_output) { std::unique_ptr video_source = CreateVideoSource(video_info, frame_settings, num_frames); @@ -479,10 +480,14 @@ std::unique_ptr RunEncodeDecodeTest( ? PacingMode::kRealTime : PacingMode::kNoPacing; + std::string output_path = TestOutputPath(); + if (save_codec_input) { + encoder_settings.encoder_input_base_path = output_path + "_enc_input"; + decoder_settings.decoder_input_base_path = output_path + "_dec_input"; + } if (save_codec_output) { - std::string output_path = TestOutputPath(); - encoder_settings.encoded_ivf_base_path = output_path; - decoder_settings.decoded_y4m_base_path = output_path; + encoder_settings.encoder_output_base_path = output_path + "_enc_output"; + decoder_settings.decoder_output_base_path = output_path + "_dec_output"; } std::unique_ptr tester = CreateVideoCodecTester(); @@ -497,6 +502,7 @@ std::unique_ptr RunEncodeTest( const VideoInfo& video_info, const std::map& frame_settings, int num_frames, + bool save_codec_input, bool save_codec_output) { std::unique_ptr video_source = CreateVideoSource(video_info, frame_settings, num_frames); @@ -510,8 +516,12 @@ std::unique_ptr RunEncodeTest( ? PacingMode::kRealTime : PacingMode::kNoPacing; + std::string output_path = TestOutputPath(); + if (save_codec_input) { + encoder_settings.encoder_input_base_path = output_path + "_enc_input"; + } if (save_codec_output) { - encoder_settings.encoded_ivf_base_path = TestOutputPath(); + encoder_settings.encoder_output_base_path = output_path + "_enc_output"; } std::unique_ptr tester = CreateVideoCodecTester(); @@ -557,9 +567,9 @@ TEST_P(SpatialQualityTest, DISABLED_SpatialQuality) { int duration_s = 10; int num_frames = duration_s * framerate_fps; - std::unique_ptr stats = - RunEncodeDecodeTest(codec_type, codec_impl, video_info, frame_settings, - num_frames, /*save_codec_output=*/false); + std::unique_ptr stats = RunEncodeDecodeTest( + codec_type, codec_impl, video_info, frame_settings, num_frames, + /*save_codec_input=*/false, /*save_codec_output=*/false); std::vector frames = stats->Slice(); SetTargetRates(frame_settings, frames); @@ -636,9 +646,9 @@ TEST_P(BitrateAdaptationTest, DISABLED_BitrateAdaptation) { .framerate = video_info.framerate, .bitrate = DataRate::KilobitsPerSec(bitrate_kbps.second)}}}}}}; - std::unique_ptr stats = - RunEncodeTest(codec_type, codec_impl, video_info, frame_settings, - num_frames, /*save_codec_output=*/false); + std::unique_ptr stats = RunEncodeTest( + codec_type, codec_impl, video_info, frame_settings, num_frames, + /*save_codec_input=*/false, /*save_codec_output=*/false); std::vector frames = stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); @@ -710,9 +720,9 @@ TEST_P(FramerateAdaptationTest, DISABLED_FramerateAdaptation) { .framerate = Frequency::MilliHertz(1000 * framerate_fps.second), .bitrate = DataRate::KilobitsPerSec(512)}}}}}}; - std::unique_ptr stats = - RunEncodeTest(codec_type, codec_impl, video_info, frame_settings, - num_frames, /*save_codec_output=*/false); + std::unique_ptr stats = RunEncodeTest( + codec_type, codec_impl, video_info, frame_settings, num_frames, + /*save_codec_input=*/false, /*save_codec_output=*/false); std::vector frames = stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); diff --git a/modules/video_coding/codecs/test/video_codec_tester_impl.cc b/modules/video_coding/codecs/test/video_codec_tester_impl.cc index cccecf14b4..fdfee3d028 100644 --- a/modules/video_coding/codecs/test/video_codec_tester_impl.cc +++ b/modules/video_coding/codecs/test/video_codec_tester_impl.cc @@ -236,9 +236,14 @@ class TesterDecoder { pacer_(settings.pacing) { RTC_CHECK(analyzer_) << "Analyzer must be provided"; - if (settings.decoded_y4m_base_path) { - y4m_writer_ = - std::make_unique(*settings.decoded_y4m_base_path); + if (settings.decoder_input_base_path) { + input_writer_ = + std::make_unique(*settings.decoder_input_base_path); + } + + if (settings.decoder_output_base_path) { + output_writer_ = + std::make_unique(*settings.decoder_output_base_path); } } @@ -248,22 +253,28 @@ class TesterDecoder { task_queue_.WaitForPreviouslyPostedTasks(); } - void Decode(const EncodedImage& frame) { - Timestamp timestamp = Timestamp::Micros((frame.Timestamp() / k90kHz).us()); + void Decode(const EncodedImage& input_frame) { + Timestamp timestamp = + Timestamp::Micros((input_frame.Timestamp() / k90kHz).us()); task_queue_.PostScheduledTask( - [this, frame] { - analyzer_->StartDecode(frame); + [this, input_frame] { + analyzer_->StartDecode(input_frame); decoder_->Decode( - frame, [this, spatial_idx = frame.SpatialIndex().value_or(0)]( - const VideoFrame& decoded_frame) { - analyzer_->FinishDecode(decoded_frame, spatial_idx); + input_frame, + [this, spatial_idx = input_frame.SpatialIndex().value_or(0)]( + const VideoFrame& output_frame) { + analyzer_->FinishDecode(output_frame, spatial_idx); - if (y4m_writer_) { - y4m_writer_->Write(decoded_frame, spatial_idx); + if (output_writer_) { + output_writer_->Write(output_frame, spatial_idx); } }); + + if (input_writer_) { + input_writer_->Write(input_frame); + } }, pacer_.Schedule(timestamp)); } @@ -280,7 +291,8 @@ class TesterDecoder { const DecoderSettings& settings_; Pacer pacer_; LimitedTaskQueue task_queue_; - std::unique_ptr y4m_writer_; + std::unique_ptr input_writer_; + std::unique_ptr output_writer_; }; class TesterEncoder { @@ -295,9 +307,14 @@ class TesterEncoder { settings_(settings), pacer_(settings.pacing) { RTC_CHECK(analyzer_) << "Analyzer must be provided"; - if (settings.encoded_ivf_base_path) { - ivf_writer_ = - std::make_unique(*settings.encoded_ivf_base_path); + if (settings.encoder_input_base_path) { + input_writer_ = + std::make_unique(*settings.encoder_input_base_path); + } + + if (settings.encoder_output_base_path) { + output_writer_ = + std::make_unique(*settings.encoder_output_base_path); } } @@ -307,23 +324,29 @@ class TesterEncoder { task_queue_.WaitForPreviouslyPostedTasks(); } - void Encode(const VideoFrame& frame) { - Timestamp timestamp = Timestamp::Micros((frame.timestamp() / k90kHz).us()); + void Encode(const VideoFrame& input_frame) { + Timestamp timestamp = + Timestamp::Micros((input_frame.timestamp() / k90kHz).us()); task_queue_.PostScheduledTask( - [this, frame] { - analyzer_->StartEncode(frame); - encoder_->Encode(frame, [this](const EncodedImage& encoded_frame) { - analyzer_->FinishEncode(encoded_frame); + [this, input_frame] { + analyzer_->StartEncode(input_frame); + encoder_->Encode(input_frame, + [this](const EncodedImage& encoded_frame) { + analyzer_->FinishEncode(encoded_frame); - if (decoder_ != nullptr) { - decoder_->Decode(encoded_frame); - } + if (decoder_ != nullptr) { + decoder_->Decode(encoded_frame); + } - if (ivf_writer_ != nullptr) { - ivf_writer_->Write(encoded_frame); - } - }); + if (output_writer_ != nullptr) { + output_writer_->Write(encoded_frame); + } + }); + + if (input_writer_) { + input_writer_->Write(input_frame, /*spatial_idx=*/0); + } }, pacer_.Schedule(timestamp)); } @@ -339,7 +362,8 @@ class TesterEncoder { TesterDecoder* const decoder_; VideoCodecAnalyzer* const analyzer_; const EncoderSettings& settings_; - std::unique_ptr ivf_writer_; + std::unique_ptr input_writer_; + std::unique_ptr output_writer_; Pacer pacer_; LimitedTaskQueue task_queue_; };