In IvfVideoFrameGenerator test helper allow to pass webrtc::Environment at construction

To reuse same environment in video encoder and thus avoid creating duplicated environment.

Bug: webrtc:15860, b/326933307
Change-Id: I1c56966301a9b453d615c45626407fede2a6d8b5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/344143
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41956}
This commit is contained in:
Danil Chapovalov 2024-03-22 14:54:48 +01:00 committed by WebRTC LUCI CQ
parent 8c3dc06544
commit c230da0f1b
8 changed files with 71 additions and 46 deletions

View file

@ -727,8 +727,14 @@ rtc_library("create_frame_generator") {
"../rtc_base:checks",
"../system_wrappers",
"../test:frame_generator_impl",
"environment",
"environment:environment_factory",
]
absl_deps = [
"//third_party/abseil-cpp/absl/base:nullability",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:optional",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("create_peer_connection_quality_test_frame_generator") {

View file

@ -13,6 +13,9 @@
#include <cstdio>
#include <utility>
#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment_factory.h"
#include "rtc_base/checks.h"
#include "test/frame_generator.h"
#include "test/testsupport/ivf_video_frame_generator.h"
@ -66,7 +69,13 @@ std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
std::unique_ptr<FrameGeneratorInterface> CreateFromIvfFileFrameGenerator(
std::string filename) {
return std::make_unique<IvfVideoFrameGenerator>(std::move(filename));
return CreateFromIvfFileFrameGenerator(CreateEnvironment(), filename);
}
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
CreateFromIvfFileFrameGenerator(const Environment& env,
absl::string_view filename) {
return std::make_unique<IvfVideoFrameGenerator>(env, filename);
}
std::unique_ptr<FrameGeneratorInterface>

View file

@ -15,7 +15,10 @@
#include <string>
#include <vector>
#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/environment/environment.h"
#include "api/test/frame_generator_interface.h"
#include "system_wrappers/include/clock.h"
@ -51,8 +54,12 @@ std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
int frame_repeat_count = 1);
// Creates a frame generator that repeatedly plays an ivf file.
std::unique_ptr<FrameGeneratorInterface> CreateFromIvfFileFrameGenerator(
std::string filename);
[[deprecated]] std::unique_ptr<FrameGeneratorInterface>
CreateFromIvfFileFrameGenerator(std::string filename);
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
CreateFromIvfFileFrameGenerator(const Environment& env,
absl::string_view filename);
// Creates a frame generator which takes a set of yuv files (wrapping a
// frame generator created by CreateFromYuvFile() above), but outputs frames

View file

@ -466,8 +466,7 @@ int main(int argc, char* argv[]) {
} else if (!ivf_input_file.empty()) {
// Use `IvfFileFrameGenerator` if specify `--ivf_input_file`.
frame_buffer_generator =
webrtc::test::CreateFromIvfFileFrameGenerator(ivf_input_file);
RTC_CHECK(frame_buffer_generator);
webrtc::test::CreateFromIvfFileFrameGenerator(env, ivf_input_file);
// Set width and height.
webrtc::test::FrameGeneratorInterface::Resolution resolution =

View file

@ -53,7 +53,7 @@ rtc_library("frame_generator_impl") {
"../api:frame_generator_api",
"../api:scoped_refptr",
"../api:sequence_checker",
"../api/environment:environment_factory",
"../api/environment",
"../api/video:encoded_image",
"../api/video:video_frame",
"../api/video:video_frame_i010",
@ -76,7 +76,10 @@ rtc_library("frame_generator_impl") {
"../rtc_base/system:file_wrapper",
"../system_wrappers",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("y4m_frame_generator") {

View file

@ -12,7 +12,7 @@
#include <limits>
#include "api/environment/environment_factory.h"
#include "api/environment/environment.h"
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video_codecs/video_codec.h"
@ -31,12 +31,32 @@ namespace {
constexpr TimeDelta kMaxNextFrameWaitTimeout = TimeDelta::Seconds(1);
std::unique_ptr<VideoDecoder> CreateDecoder(const Environment& env,
VideoCodecType codec_type) {
switch (codec_type) {
case VideoCodecType::kVideoCodecVP8:
return CreateVp8Decoder(env);
case VideoCodecType::kVideoCodecVP9:
return VP9Decoder::Create();
case VideoCodecType::kVideoCodecH264:
return H264Decoder::Create();
case VideoCodecType::kVideoCodecAV1:
return CreateDav1dDecoder();
case VideoCodecType::kVideoCodecH265:
// TODO: bugs.webrtc.org/13485 - implement H265 decoder
return nullptr;
default:
return nullptr;
}
}
} // namespace
IvfVideoFrameGenerator::IvfVideoFrameGenerator(const std::string& file_name)
IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env,
absl::string_view file_name)
: callback_(this),
file_reader_(IvfFileReader::Create(FileWrapper::OpenReadOnly(file_name))),
video_decoder_(CreateVideoDecoder(file_reader_->GetVideoCodecType())),
video_decoder_(CreateDecoder(env, file_reader_->GetVideoCodecType())),
width_(file_reader_->GetFrameWidth()),
height_(file_reader_->GetFrameHeight()) {
RTC_CHECK(video_decoder_) << "No decoder found for file's video codec type";
@ -135,27 +155,5 @@ void IvfVideoFrameGenerator::OnFrameDecoded(const VideoFrame& decoded_frame) {
next_frame_decoded_.Set();
}
std::unique_ptr<VideoDecoder> IvfVideoFrameGenerator::CreateVideoDecoder(
VideoCodecType codec_type) {
if (codec_type == VideoCodecType::kVideoCodecVP8) {
// Use a default environment for the VP8 decoder while there is no use case
// for a propagated environment in this test utility IvfVideoFrameGenerator.
return CreateVp8Decoder(CreateEnvironment());
}
if (codec_type == VideoCodecType::kVideoCodecVP9) {
return VP9Decoder::Create();
}
if (codec_type == VideoCodecType::kVideoCodecH264) {
return H264Decoder::Create();
}
if (codec_type == VideoCodecType::kVideoCodecAV1) {
return CreateDav1dDecoder();
}
if (codec_type == VideoCodecType::kVideoCodecH265) {
// TODO(bugs.webrtc.org/13485): implement H265 decoder
}
return nullptr;
}
} // namespace test
} // namespace webrtc

View file

@ -14,7 +14,9 @@
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/environment/environment.h"
#include "api/sequence_checker.h"
#include "api/test/frame_generator_interface.h"
#include "api/video/video_codec_type.h"
@ -30,7 +32,7 @@ namespace test {
// All methods except constructor must be used from the same thread.
class IvfVideoFrameGenerator : public FrameGeneratorInterface {
public:
explicit IvfVideoFrameGenerator(const std::string& file_name);
IvfVideoFrameGenerator(const Environment& env, absl::string_view file_name);
~IvfVideoFrameGenerator() override;
VideoFrameData NextFrame() override;
@ -56,8 +58,6 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface {
};
void OnFrameDecoded(const VideoFrame& decoded_frame);
static std::unique_ptr<VideoDecoder> CreateVideoDecoder(
VideoCodecType codec_type);
DecodedCallback callback_;
std::unique_ptr<IvfFileReader> file_reader_;

View file

@ -14,6 +14,8 @@
#include <vector>
#include "absl/types/optional.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/test/create_frame_generator.h"
#include "api/units/time_delta.h"
#include "api/video/encoded_image.h"
@ -158,6 +160,7 @@ class IvfVideoFrameGeneratorTest : public ::testing::Test {
kMaxFrameEncodeWaitTimeout));
}
Environment env_ = CreateEnvironment();
std::string file_name_;
std::vector<VideoFrame> video_frames_;
};
@ -165,14 +168,14 @@ class IvfVideoFrameGeneratorTest : public ::testing::Test {
} // namespace
TEST_F(IvfVideoFrameGeneratorTest, DoesNotKnowFps) {
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, VP8Encoder::Create());
IvfVideoFrameGenerator generator(file_name_);
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
IvfVideoFrameGenerator generator(env_, file_name_);
EXPECT_EQ(generator.fps(), absl::nullopt);
}
TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, VP8Encoder::Create());
IvfVideoFrameGenerator generator(file_name_);
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
IvfVideoFrameGenerator generator(env_, file_name_);
for (size_t i = 0; i < video_frames_.size(); ++i) {
auto& expected_frame = video_frames_[i];
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
@ -181,8 +184,8 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
}
TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) {
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, VP8Encoder::Create());
IvfVideoFrameGenerator generator(file_name_);
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
IvfVideoFrameGenerator generator(env_, file_name_);
for (size_t i = 0; i < video_frames_.size() * 2; ++i) {
auto& expected_frame = video_frames_[i % video_frames_.size()];
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
@ -191,8 +194,8 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) {
}
TEST_F(IvfVideoFrameGeneratorTest, Vp9) {
CreateTestVideoFile(VideoCodecType::kVideoCodecVP9, VP9Encoder::Create());
IvfVideoFrameGenerator generator(file_name_);
CreateTestVideoFile(VideoCodecType::kVideoCodecVP9, CreateVp9Encoder(env_));
IvfVideoFrameGenerator generator(env_, file_name_);
for (size_t i = 0; i < video_frames_.size(); ++i) {
auto& expected_frame = video_frames_[i];
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
@ -202,8 +205,8 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp9) {
#if defined(WEBRTC_USE_H264)
TEST_F(IvfVideoFrameGeneratorTest, H264) {
CreateTestVideoFile(VideoCodecType::kVideoCodecH264, H264Encoder::Create());
IvfVideoFrameGenerator generator(file_name_);
CreateTestVideoFile(VideoCodecType::kVideoCodecH264, CreateH264Encoder(env_));
IvfVideoFrameGenerator generator(env_, file_name_);
for (size_t i = 0; i < video_frames_.size(); ++i) {
auto& expected_frame = video_frames_[i];
VideoFrame actual_frame = BuildFrame(generator.NextFrame());