Dump codec input

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 <ssilkin@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39626}
This commit is contained in:
Sergey Silkin 2023-03-21 11:03:28 +01:00 committed by WebRTC LUCI CQ
parent 62dc65b537
commit ebb5383fd8
3 changed files with 81 additions and 45 deletions

View File

@ -47,12 +47,14 @@ class VideoCodecTester {
struct DecoderSettings {
PacingSettings pacing;
absl::optional<std::string> decoded_y4m_base_path;
absl::optional<std::string> decoder_input_base_path;
absl::optional<std::string> decoder_output_base_path;
};
struct EncoderSettings {
PacingSettings pacing;
absl::optional<std::string> encoded_ivf_base_path;
absl::optional<std::string> encoder_input_base_path;
absl::optional<std::string> encoder_output_base_path;
};
virtual ~VideoCodecTester() = default;

View File

@ -457,6 +457,7 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
const VideoInfo& video_info,
const std::map<int, EncodingSettings>& frame_settings,
int num_frames,
bool save_codec_input,
bool save_codec_output) {
std::unique_ptr<TestRawVideoSource> video_source =
CreateVideoSource(video_info, frame_settings, num_frames);
@ -479,10 +480,14 @@ std::unique_ptr<VideoCodecStats> 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<VideoCodecTester> tester = CreateVideoCodecTester();
@ -497,6 +502,7 @@ std::unique_ptr<VideoCodecStats> RunEncodeTest(
const VideoInfo& video_info,
const std::map<int, EncodingSettings>& frame_settings,
int num_frames,
bool save_codec_input,
bool save_codec_output) {
std::unique_ptr<TestRawVideoSource> video_source =
CreateVideoSource(video_info, frame_settings, num_frames);
@ -510,8 +516,12 @@ std::unique_ptr<VideoCodecStats> 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<VideoCodecTester> 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<VideoCodecStats> stats =
RunEncodeDecodeTest(codec_type, codec_impl, video_info, frame_settings,
num_frames, /*save_codec_output=*/false);
std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
codec_type, codec_impl, video_info, frame_settings, num_frames,
/*save_codec_input=*/false, /*save_codec_output=*/false);
std::vector<VideoCodecStats::Frame> 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<VideoCodecStats> stats =
RunEncodeTest(codec_type, codec_impl, video_info, frame_settings,
num_frames, /*save_codec_output=*/false);
std::unique_ptr<VideoCodecStats> stats = RunEncodeTest(
codec_type, codec_impl, video_info, frame_settings, num_frames,
/*save_codec_input=*/false, /*save_codec_output=*/false);
std::vector<VideoCodecStats::Frame> 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<VideoCodecStats> stats =
RunEncodeTest(codec_type, codec_impl, video_info, frame_settings,
num_frames, /*save_codec_output=*/false);
std::unique_ptr<VideoCodecStats> stats = RunEncodeTest(
codec_type, codec_impl, video_info, frame_settings, num_frames,
/*save_codec_input=*/false, /*save_codec_output=*/false);
std::vector<VideoCodecStats::Frame> frames =
stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame});

View File

@ -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<TesterY4mWriter>(*settings.decoded_y4m_base_path);
if (settings.decoder_input_base_path) {
input_writer_ =
std::make_unique<TesterIvfWriter>(*settings.decoder_input_base_path);
}
if (settings.decoder_output_base_path) {
output_writer_ =
std::make_unique<TesterY4mWriter>(*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<TesterY4mWriter> y4m_writer_;
std::unique_ptr<TesterIvfWriter> input_writer_;
std::unique_ptr<TesterY4mWriter> 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<TesterIvfWriter>(*settings.encoded_ivf_base_path);
if (settings.encoder_input_base_path) {
input_writer_ =
std::make_unique<TesterY4mWriter>(*settings.encoder_input_base_path);
}
if (settings.encoder_output_base_path) {
output_writer_ =
std::make_unique<TesterIvfWriter>(*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<TesterIvfWriter> ivf_writer_;
std::unique_ptr<TesterY4mWriter> input_writer_;
std::unique_ptr<TesterIvfWriter> output_writer_;
Pacer pacer_;
LimitedTaskQueue task_queue_;
};