video_replay: add support for IVF file output

adding a -decoder_ivf_filename command line flag.

BUG=none

Change-Id: I895a6bf8093d5f36c17462d97240b17ada4dc9f1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/201560
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33077}
This commit is contained in:
Philipp Hancke
2021-01-26 18:05:56 +01:00
committed by Commit Bot
parent 1d77c3ef17
commit fae4fb1345
3 changed files with 58 additions and 4 deletions

View File

@ -210,11 +210,13 @@ if (!is_component_build) {
"../api/task_queue:default_task_queue_factory",
"../api/test/video:function_video_factory",
"../api/transport:field_trial_based_config",
"../api/video:video_frame",
"../api/video_codecs:video_codecs_api",
"../call",
"../call:call_interfaces",
"../common_video",
"../media:rtc_internal_video_codecs",
"../modules/video_coding:video_coding_utility",
"../rtc_base:checks",
"../rtc_base:rtc_json",
"../rtc_base:stringutils",

View File

@ -29,4 +29,7 @@ specific_include_rules = {
"+modules/video_coding/utility/ivf_file_writer.h",
"+modules/video_coding/codecs/h264/include/h264.h",
],
".*video_replay\.cc": [
"+modules/video_coding/utility/ivf_file_writer.h",
],
}

View File

@ -20,10 +20,12 @@
#include "api/task_queue/default_task_queue_factory.h"
#include "api/test/video/function_video_decoder_factory.h"
#include "api/transport/field_trial_based_config.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/video_decoder.h"
#include "call/call.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "media/engine/internal_decoder_factory.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_to_number.h"
#include "rtc_base/strings/json.h"
@ -112,6 +114,8 @@ ABSL_FLAG(std::string,
"",
"Decoder bitstream output file");
ABSL_FLAG(std::string, decoder_ivf_filename, "", "Decoder ivf output file");
// Flag for video codec.
ABSL_FLAG(std::string, codec, "VP8", "Video codec");
@ -189,6 +193,10 @@ static std::string DecoderBitstreamFilename() {
return absl::GetFlag(FLAGS_decoder_bitstream_filename);
}
static std::string IVFFilename() {
return absl::GetFlag(FLAGS_decoder_ivf_filename);
}
static std::string Codec() {
return absl::GetFlag(FLAGS_codec);
}
@ -255,6 +263,39 @@ class DecoderBitstreamFileWriter : public test::FakeDecoder {
FILE* file_;
};
class DecoderIvfFileWriter : public test::FakeDecoder {
public:
explicit DecoderIvfFileWriter(const char* filename, const std::string& codec)
: file_writer_(
IvfFileWriter::Wrap(FileWrapper::OpenWriteOnly(filename), 0)) {
RTC_DCHECK(file_writer_.get());
if (codec == "VP8") {
video_codec_type_ = VideoCodecType::kVideoCodecVP8;
} else if (codec == "VP9") {
video_codec_type_ = VideoCodecType::kVideoCodecVP9;
} else if (codec == "H264") {
video_codec_type_ = VideoCodecType::kVideoCodecH264;
} else {
RTC_LOG(LS_ERROR) << "Unsupported video codec " << codec;
RTC_DCHECK(false);
}
}
~DecoderIvfFileWriter() override { file_writer_->Close(); }
int32_t Decode(const EncodedImage& encoded_frame,
bool /* missing_frames */,
int64_t render_time_ms) override {
if (!file_writer_->WriteFrame(encoded_frame, video_codec_type_)) {
return WEBRTC_VIDEO_CODEC_ERROR;
}
return WEBRTC_VIDEO_CODEC_OK;
}
private:
std::unique_ptr<IvfFileWriter> file_writer_;
VideoCodecType video_codec_type_;
};
// The RtpReplayer is responsible for parsing the configuration provided by the
// user, setting up the windows, recieve streams and decoders and then replaying
// the provided RTP dump.
@ -419,10 +460,7 @@ class RtpReplayer final {
// Setup the receiving stream
VideoReceiveStream::Decoder decoder;
decoder = test::CreateMatchingDecoder(MediaPayloadType(), Codec());
if (DecoderBitstreamFilename().empty()) {
stream_state->decoder_factory =
std::make_unique<InternalDecoderFactory>();
} else {
if (!DecoderBitstreamFilename().empty()) {
// Replace decoder with file writer if we're writing the bitstream to a
// file instead.
stream_state->decoder_factory =
@ -430,6 +468,17 @@ class RtpReplayer final {
return std::make_unique<DecoderBitstreamFileWriter>(
DecoderBitstreamFilename().c_str());
});
} else if (!IVFFilename().empty()) {
// Replace decoder with file writer if we're writing the ivf to a
// file instead.
stream_state->decoder_factory =
std::make_unique<test::FunctionVideoDecoderFactory>([]() {
return std::make_unique<DecoderIvfFileWriter>(IVFFilename().c_str(),
Codec());
});
} else {
stream_state->decoder_factory =
std::make_unique<InternalDecoderFactory>();
}
receive_config.decoder_factory = stream_state->decoder_factory.get();
receive_config.decoders.push_back(decoder);