From c0d60b0ca6f5e60d343ba774c2069f23af8be480 Mon Sep 17 00:00:00 2001 From: jwcullen Date: Wed, 23 Oct 2024 10:49:37 -0400 Subject: [PATCH] Refactor to use a customized and unified "Mix Presentation Finalizer". - Previously we had separate finalizers. But now we have one finalizer that can be configured with custom rendering and loudness calculating behavior. - Now that we only need one finalizer, it is better to have a single implementation. The different behaviors can be configured at construction time. - `MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer` behavior is mimicked by configuring it with `nullptr` factories. - `iamf/cli/iamf_components.cc`: Return `nullptr` factories to match the long-standing behavior; bypass rendering and trust the user-provided loudness. - Clean up related cruft. PiperOrigin-RevId: 688961745 --- iamf/cli/BUILD | 23 +-- iamf/cli/encoder_main_lib.cc | 8 +- iamf/cli/iamf_components.cc | 24 +-- iamf/cli/iamf_components.h | 32 ++-- iamf/cli/mix_presentation_finalizer.cc | 51 ------ iamf/cli/mix_presentation_finalizer.h | 125 -------------- .../rendering_mix_presentation_finalizer.cc | 4 +- .../rendering_mix_presentation_finalizer.h | 40 ++++- iamf/cli/tests/BUILD | 14 -- iamf/cli/tests/iamf_components_test.cc | 22 +-- .../tests/mix_presentation_finalizer_test.cc | 160 ------------------ 11 files changed, 70 insertions(+), 433 deletions(-) delete mode 100644 iamf/cli/mix_presentation_finalizer.cc delete mode 100644 iamf/cli/mix_presentation_finalizer.h delete mode 100644 iamf/cli/tests/mix_presentation_finalizer_test.cc diff --git a/iamf/cli/BUILD b/iamf/cli/BUILD index 5ac7f2dd..00f069d0 100644 --- a/iamf/cli/BUILD +++ b/iamf/cli/BUILD @@ -153,6 +153,7 @@ cc_library( ":obu_sequencer", ":parameter_block_partitioner", ":parameter_block_with_data", + ":rendering_mix_presentation_finalizer", ":wav_sample_provider", ":wav_writer", "//iamf/cli/proto:test_vector_metadata_cc_proto", @@ -202,10 +203,8 @@ cc_library( deps = [ ":leb_generator", ":loudness_calculator_factory_base", - ":mix_presentation_finalizer", ":obu_sequencer", ":renderer_factory", - ":rendering_mix_presentation_finalizer", "//iamf/cli/proto:mix_presentation_cc_proto", "//iamf/cli/proto:test_vector_metadata_cc_proto", "//iamf/cli/proto:user_metadata_cc_proto", @@ -285,25 +284,6 @@ cc_library( ], ) -cc_library( - name = "mix_presentation_finalizer", - srcs = ["mix_presentation_finalizer.cc"], - hdrs = ["mix_presentation_finalizer.h"], - deps = [ - ":audio_element_with_data", - ":demixing_module", - ":parameter_block_with_data", - ":wav_writer", - "//iamf/cli/proto:mix_presentation_cc_proto", - "//iamf/obu:mix_presentation", - "//iamf/obu:types", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/functional:any_invocable", - "@com_google_absl//absl/log", - "@com_google_absl//absl/status", - ], -) - cc_library( name = "obu_sequencer", srcs = ["obu_sequencer.cc"], @@ -440,7 +420,6 @@ cc_library( ":demixing_module", ":loudness_calculator_base", ":loudness_calculator_factory_base", - ":mix_presentation_finalizer", ":parameter_block_with_data", ":renderer_factory", ":wav_writer", diff --git a/iamf/cli/encoder_main_lib.cc b/iamf/cli/encoder_main_lib.cc index 6d0cad9b..59b74b9c 100644 --- a/iamf/cli/encoder_main_lib.cc +++ b/iamf/cli/encoder_main_lib.cc @@ -36,6 +36,7 @@ #include "iamf/cli/proto/test_vector_metadata.pb.h" #include "iamf/cli/proto/user_metadata.pb.h" #include "iamf/cli/proto_to_obu/arbitrary_obu_generator.h" +#include "iamf/cli/rendering_mix_presentation_finalizer.h" #include "iamf/cli/wav_sample_provider.h" #include "iamf/cli/wav_writer.h" #include "iamf/common/macros.h" @@ -288,10 +289,11 @@ absl::Status GenerateObus( user_metadata.test_vector_metadata().file_name_prefix()) .string(); LOG(INFO) << "output_wav_file_prefix = " << output_wav_file_prefix; - auto mix_presentation_finalizer = CreateMixPresentationFinalizer( + RenderingMixPresentationFinalizer mix_presentation_finalizer( output_wav_file_prefix, output_wav_file_bit_depth_override, - user_metadata.test_vector_metadata().validate_user_loudness()); - RETURN_IF_NOT_OK(mix_presentation_finalizer->Finalize( + user_metadata.test_vector_metadata().validate_user_loudness(), + CreateRendererFactory(), CreateLoudnessCalculatorFactory()); + RETURN_IF_NOT_OK(mix_presentation_finalizer.Finalize( audio_elements, id_to_time_to_labeled_frame, parameter_blocks, ProduceAllWavWriters, mix_presentation_obus)); diff --git a/iamf/cli/iamf_components.cc b/iamf/cli/iamf_components.cc index 69d8df4e..53e14096 100644 --- a/iamf/cli/iamf_components.cc +++ b/iamf/cli/iamf_components.cc @@ -11,12 +11,9 @@ */ #include "iamf/cli/iamf_components.h" -#include #include #include -#include #include -#include #include #include "absl/log/log.h" @@ -24,12 +21,10 @@ #include "absl/strings/string_view.h" #include "iamf/cli/leb_generator.h" #include "iamf/cli/loudness_calculator_factory_base.h" -#include "iamf/cli/mix_presentation_finalizer.h" #include "iamf/cli/obu_sequencer.h" #include "iamf/cli/proto/test_vector_metadata.pb.h" #include "iamf/cli/proto/user_metadata.pb.h" #include "iamf/cli/renderer_factory.h" -#include "iamf/cli/rendering_mix_presentation_finalizer.h" namespace iamf_tools { @@ -39,16 +34,15 @@ constexpr absl::string_view kOmitIamfFile = ""; } -std::unique_ptr CreateMixPresentationFinalizer( - const std::string& file_name_prefix, - std::optional output_wav_file_bit_depth_override, - bool validate_loudness) { - std::unique_ptr skip_rendering = nullptr; - std::unique_ptr preserve_user_loudness = - nullptr; - return std::make_unique( - file_name_prefix, output_wav_file_bit_depth_override, validate_loudness, - std::move(skip_rendering), std::move(preserve_user_loudness)); +std::unique_ptr CreateRendererFactory() { + // Skip rendering. + return nullptr; +} + +std::unique_ptr +CreateLoudnessCalculatorFactory() { + // Skip loudness calculation. + return nullptr; } std::vector> CreateObuSequencers( diff --git a/iamf/cli/iamf_components.h b/iamf/cli/iamf_components.h index 8b61d322..1cfb7f65 100644 --- a/iamf/cli/iamf_components.h +++ b/iamf/cli/iamf_components.h @@ -13,34 +13,36 @@ #ifndef CLI_IAMF_COMPONENTS_H_ #define CLI_IAMF_COMPONENTS_H_ -#include #include -#include #include #include -#include "iamf/cli/mix_presentation_finalizer.h" +#include "iamf/cli/loudness_calculator_factory_base.h" #include "iamf/cli/obu_sequencer.h" #include "iamf/cli/proto/mix_presentation.pb.h" #include "iamf/cli/proto/user_metadata.pb.h" +#include "iamf/cli/renderer_factory.h" namespace iamf_tools { -/*!\brief Creates an instance of `MixPresentationFinalizerBase`. +/*!\brief Creates an instance of `RendererFactoryBase`. * - * This is useful for binding different kinds of finalizers in an IAMF Encoder. + * This is useful for binding different kinds of renderer factories in an IAMF + * Encoder. * - * \param file_name_prefix Prefix of output file name. - * \param output_wav_file_bit_depth_override Override for the bit-depth of - * the rendered wav file. - * \param validate_loudness Whether to validate computed loudness matches the - * user-provided loudness. - * \return Unique pointer to the created Mix Presentation finalizer. + * \return Unique pointer to the created renderer factory */ -std::unique_ptr CreateMixPresentationFinalizer( - const std::string& file_name_prefix, - std::optional output_wav_file_bit_depth_override, - bool validate_loudness); +std::unique_ptr CreateRendererFactory(); + +/*!\brief Creates an instance of `LoudnessCalculatorFactoryBase`. + * + * This is useful for binding different kinds of loudness calculator factories + * in an IAMF Encoder. + * + * \return Unique pointer to the created loudness calculator factory. + */ +std::unique_ptr +CreateLoudnessCalculatorFactory(); /*!\brief Creates instances of `ObuSequencerBase`. * diff --git a/iamf/cli/mix_presentation_finalizer.cc b/iamf/cli/mix_presentation_finalizer.cc deleted file mode 100644 index 4ebd1bdd..00000000 --- a/iamf/cli/mix_presentation_finalizer.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2023, Alliance for Open Media. All rights reserved - * - * This source code is subject to the terms of the BSD 3-Clause Clear License - * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear - * License was not distributed with this source code in the LICENSE file, you - * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the - * Alliance for Open Media Patent License 1.0 was not distributed with this - * source code in the PATENTS file, you can obtain it at - * www.aomedia.org/license/patent. - */ -#include "iamf/cli/mix_presentation_finalizer.h" - -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/log/log.h" -#include "absl/status/status.h" -#include "iamf/cli/audio_element_with_data.h" -#include "iamf/cli/demixing_module.h" -#include "iamf/cli/parameter_block_with_data.h" -#include "iamf/cli/proto/mix_presentation.pb.h" -#include "iamf/obu/mix_presentation.h" - -namespace iamf_tools { - -absl::Status -MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer::Finalize( - const absl::flat_hash_map&, - const IdTimeLabeledFrameMap&, const std::list&, - const WavWriterFactory&, - std::list& mix_presentation_obus) { - LOG(INFO) << "Calling " - "MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer" - "::Finalize():"; - LOG(INFO) << " Loudness information may be copied from user " - << "provided values."; - - // TODO(b/332567539): Use `RendererFactory` to render certain layouts. - // TODO(b/302273947): Once layouts are rendered and mixed then use a - // `LoudnessCalculatorFactory` to measure loudness. - - // Examine Mix Presentation OBUs. - for (const auto& mix_presentation_obu : mix_presentation_obus) { - mix_presentation_obu.PrintObu(); - } - return absl::OkStatus(); -} - -} // namespace iamf_tools diff --git a/iamf/cli/mix_presentation_finalizer.h b/iamf/cli/mix_presentation_finalizer.h deleted file mode 100644 index 08ad9a23..00000000 --- a/iamf/cli/mix_presentation_finalizer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2023, Alliance for Open Media. All rights reserved - * - * This source code is subject to the terms of the BSD 3-Clause Clear License - * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear - * License was not distributed with this source code in the LICENSE file, you - * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the - * Alliance for Open Media Patent License 1.0 was not distributed with this - * source code in the PATENTS file, you can obtain it at - * www.aomedia.org/license/patent. - */ - -#ifndef CLI_MIX_PRESENTATION_FINALIZER_H_ -#define CLI_MIX_PRESENTATION_FINALIZER_H_ - -#include -#include -#include -#include - -#include "absl/container/flat_hash_map.h" -#include "absl/functional/any_invocable.h" -#include "absl/status/status.h" -#include "iamf/cli/audio_element_with_data.h" -#include "iamf/cli/demixing_module.h" -#include "iamf/cli/parameter_block_with_data.h" -#include "iamf/cli/proto/mix_presentation.pb.h" -#include "iamf/cli/wav_writer.h" -#include "iamf/obu/mix_presentation.h" -#include "iamf/obu/types.h" - -namespace iamf_tools { - -class MixPresentationFinalizerBase { - public: - /*!\brief Factory for a wav writer. - * - * Used to control whether or not wav writers are created and control their - * filenames. - * - * For example, if the user only wants a particular layout (e.g. stereo), or a - * particular mix presentation to be rendered, then a factory could filter out - * irrelevant mix presentations or layouts. - * - * \param mix_presentation_id Mix presentation ID. - * \param sub_mix_index Index of the sub mix within the mix presentation. - * \param layout_index Index of the layout within the sub mix. - * \param layout Associated layout. - * \param prefix Prefix for the output file. - * \param num_channels Number of channels. - * \param sample_rate Sample rate. - * \param bit_depth Bit depth. - * \return Unique pointer to a wav writer or `nullptr` if none is desired. - */ - typedef absl::AnyInvocable( - DecodedUleb128 mix_presentation_id, int sub_mix_index, int layout_index, - const Layout& layout, const std::filesystem::path& prefix, - int num_channels, int sample_rate, int bit_depth) const> - WavWriterFactory; - - /*!\brief Constructor. */ - MixPresentationFinalizerBase() {} - - /*!\brief Destructor. - */ - virtual ~MixPresentationFinalizerBase() = default; - - /*!\brief Finalizes the list of Mix Presentation OBUs. - * - * Populates the loudness information for each Mix Presentation OBU. - * - * \param audio_elements Input Audio Element OBUs with data. - * \param id_to_time_to_labeled_frame Data structure of samples, keyed by - * audio element ID, starting timestamp, and channel label. - * \param parameter_blocks Input Parameter Block OBUs. - * \param wav_writer_factory Factory for creating output rendered wav files. - * \param mix_presentation_obus Output list of OBUs to finalize. - * \return `absl::OkStatus()` on success. A specific status on failure. - */ - virtual absl::Status Finalize( - const absl::flat_hash_map& audio_elements, - const IdTimeLabeledFrameMap& id_to_time_to_labeled_frame, - const std::list& parameter_blocks, - const WavWriterFactory& wav_writer_factory, - std::list& mix_presentation_obus) = 0; -}; - -/*!\brief Finalizer that measures loudness or echoes user provided loudness. */ -class MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer - : public MixPresentationFinalizerBase { - public: - /*!\brief Constructor. */ - MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer() - : MixPresentationFinalizerBase() {} - - /*!\brief Destructor. - */ - ~MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer() override = - default; - - /*!\brief Finalizes the list of Mix Presentation OBUs. - * - * Attempt to render the layouts associated with the mix presentation OBU and - * populate the `LoudnessInfo` accurately. May fall back to simply copying - * user provided loudness information for any number of layouts. - * - * \param audio_elements Input Audio Element OBUs with data. - * \param id_to_time_to_labeled_frame Data structure of samples. - * \param parameter_blocks Input Parameter Block OBUs. - * \param wav_writer_factory Factory for creating output rendered wav files - * when the rendering succeeds. - * \param mix_presentation_obus Output list of OBUs to finalize. - * \return `absl::OkStatus()` on success. A specific status on failure. - */ - absl::Status Finalize( - const absl::flat_hash_map& audio_elements, - const IdTimeLabeledFrameMap& id_to_time_to_labeled_frame, - const std::list& parameter_blocks, - const MixPresentationFinalizerBase::WavWriterFactory& wav_writer_factory, - std::list& mix_presentation_obus) override; -}; - -} // namespace iamf_tools - -#endif // CLI_MIX_PRESENTATION_FINALIZER_H_ diff --git a/iamf/cli/rendering_mix_presentation_finalizer.cc b/iamf/cli/rendering_mix_presentation_finalizer.cc index 160cc134..4a1f576f 100644 --- a/iamf/cli/rendering_mix_presentation_finalizer.cc +++ b/iamf/cli/rendering_mix_presentation_finalizer.cc @@ -38,7 +38,6 @@ #include "iamf/cli/demixing_module.h" #include "iamf/cli/loudness_calculator_base.h" #include "iamf/cli/loudness_calculator_factory_base.h" -#include "iamf/cli/mix_presentation_finalizer.h" #include "iamf/cli/parameter_block_with_data.h" #include "iamf/cli/proto/mix_presentation.pb.h" #include "iamf/cli/proto/test_vector_metadata.pb.h" @@ -474,7 +473,8 @@ absl::Status ValidateUserLoudness(const LoudnessInfo& user_loudness, absl::Status FillLoudnessInfo( bool validate_loudness, const RendererFactoryBase& renderer_factory, const LoudnessCalculatorFactoryBase* loudness_calculator_factory, - const MixPresentationFinalizerBase::WavWriterFactory& wav_writer_factory, + const RenderingMixPresentationFinalizer::WavWriterFactory& + wav_writer_factory, const std::filesystem::path& file_path_prefix, const absl::flat_hash_map& audio_elements, const IdTimeLabeledFrameMap& id_to_time_to_labeled_frame, diff --git a/iamf/cli/rendering_mix_presentation_finalizer.h b/iamf/cli/rendering_mix_presentation_finalizer.h index 68beac91..8314790d 100644 --- a/iamf/cli/rendering_mix_presentation_finalizer.h +++ b/iamf/cli/rendering_mix_presentation_finalizer.h @@ -21,20 +21,47 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" #include "absl/status/status.h" #include "iamf/cli/audio_element_with_data.h" #include "iamf/cli/demixing_module.h" #include "iamf/cli/loudness_calculator_factory_base.h" -#include "iamf/cli/mix_presentation_finalizer.h" #include "iamf/cli/parameter_block_with_data.h" #include "iamf/cli/proto/mix_presentation.pb.h" #include "iamf/cli/renderer_factory.h" +#include "iamf/cli/wav_writer.h" #include "iamf/obu/mix_presentation.h" +#include "iamf/obu/types.h" namespace iamf_tools { -class RenderingMixPresentationFinalizer : public MixPresentationFinalizerBase { +class RenderingMixPresentationFinalizer { public: + /*!\brief Factory for a wav writer. + * + * Used to control whether or not wav writers are created and control their + * filenames. + * + * For example, if the user only wants a particular layout (e.g. stereo), or a + * particular mix presentation to be rendered, then a factory could filter out + * irrelevant mix presentations or layouts. + * + * \param mix_presentation_id Mix presentation ID. + * \param sub_mix_index Index of the sub mix within the mix presentation. + * \param layout_index Index of the layout within the sub mix. + * \param layout Associated layout. + * \param prefix Prefix for the output file. + * \param num_channels Number of channels. + * \param sample_rate Sample rate. + * \param bit_depth Bit depth. + * \return Unique pointer to a wav writer or `nullptr` if none is desired. + */ + typedef absl::AnyInvocable( + DecodedUleb128 mix_presentation_id, int sub_mix_index, int layout_index, + const Layout& layout, const std::filesystem::path& prefix, + int num_channels, int sample_rate, int bit_depth) const> + WavWriterFactory; + /*!\brief Constructor. * * \param mix_presentation_metadata Input mix presentation metadata. Only the @@ -55,17 +82,12 @@ class RenderingMixPresentationFinalizer : public MixPresentationFinalizerBase { std::unique_ptr renderer_factory, std::unique_ptr loudness_calculator_factory) - : MixPresentationFinalizerBase(), - file_path_prefix_(file_path_prefix), + : file_path_prefix_(file_path_prefix), output_wav_file_bit_depth_override_(output_wav_file_bit_depth_override), validate_loudness_(validate_loudness), renderer_factory_(std::move(renderer_factory)), loudness_calculator_factory_(std::move(loudness_calculator_factory)) {} - /*!\brief Destructor. - */ - ~RenderingMixPresentationFinalizer() override = default; - /*!\brief Finalizes the list of Mix Presentation OBUs. * * Populates the loudness information for each Mix Presentation OBU. This @@ -85,7 +107,7 @@ class RenderingMixPresentationFinalizer : public MixPresentationFinalizerBase { const IdTimeLabeledFrameMap& id_to_time_to_labeled_frame, const std::list& parameter_blocks, const WavWriterFactory& wav_writer_factory, - std::list& mix_presentation_obus) override; + std::list& mix_presentation_obus); private: const std::filesystem::path file_path_prefix_; diff --git a/iamf/cli/tests/BUILD b/iamf/cli/tests/BUILD index 7d142cd9..19e253a4 100644 --- a/iamf/cli/tests/BUILD +++ b/iamf/cli/tests/BUILD @@ -239,20 +239,6 @@ cc_test( ], ) -cc_test( - name = "mix_presentation_finalizer_test", - srcs = ["mix_presentation_finalizer_test.cc"], - deps = [ - ":cli_test_utils", - "//iamf/cli:mix_presentation_finalizer", - "//iamf/cli:wav_writer", - "//iamf/obu:mix_presentation", - "//iamf/obu:types", - "@com_google_absl//absl/status:status_matchers", - "@com_google_googletest//:gtest_main", - ], -) - cc_test( name = "obu_sequencer_test", srcs = ["obu_sequencer_test.cc"], diff --git a/iamf/cli/tests/iamf_components_test.cc b/iamf/cli/tests/iamf_components_test.cc index 63b0aac9..dcd1ff44 100644 --- a/iamf/cli/tests/iamf_components_test.cc +++ b/iamf/cli/tests/iamf_components_test.cc @@ -12,9 +12,6 @@ #include "iamf/cli/iamf_components.h" -#include -#include - #include "gtest/gtest.h" #include "iamf/cli/proto/test_vector_metadata.pb.h" #include "iamf/cli/proto/user_metadata.pb.h" @@ -24,14 +21,12 @@ namespace iamf_tools { namespace { -constexpr bool kValidateLoudness = true; +TEST(IamfComponentsTest, CreateRendererFactoryReturnsNull) { + EXPECT_EQ(CreateRendererFactory(), nullptr); +} -TEST(IamfComponentsTest, CreateMixPresentationFinalizerReturnsNonNull) { - EXPECT_NE(CreateMixPresentationFinalizer( - /*file_name_prefix=*/"", - /*output_wav_file_bit_depth_override=*/std::nullopt, - kValidateLoudness), - nullptr); +TEST(IamfComponentsTest, CreatreLoudnessCalculatorFactoryReturnsNull) { + EXPECT_EQ(CreateLoudnessCalculatorFactory(), nullptr); } TEST(IamfComponentsTest, @@ -65,13 +60,6 @@ TEST(IamfComponentsTest, CanBeConfiguredWithFixedSizeLebGenerator) { } } -TEST(IamfComponentsTest, CanBeConfiguredWithOutputWavFileBitDepthOverride) { - const uint8_t kOutputWavFileBitDepthOverride = 16; - EXPECT_NE(CreateMixPresentationFinalizer("", kOutputWavFileBitDepthOverride, - kValidateLoudness), - nullptr); -} - TEST(IamfComponentsTest, ReturnsEmptyListWhenLebGeneratorIsInvalid) { iamf_tools_cli_proto::UserMetadata user_metadata; diff --git a/iamf/cli/tests/mix_presentation_finalizer_test.cc b/iamf/cli/tests/mix_presentation_finalizer_test.cc deleted file mode 100644 index 98bc57d7..00000000 --- a/iamf/cli/tests/mix_presentation_finalizer_test.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2023, Alliance for Open Media. All rights reserved - * - * This source code is subject to the terms of the BSD 3-Clause Clear - * License and the Alliance for Open Media Patent License 1.0. If the BSD - * 3-Clause Clear License was not distributed with this source code in the - * LICENSE file, you can obtain it at - * www.aomedia.org/license/software-license/bsd-3-c-c. If the Alliance for - * Open Media Patent License 1.0 was not distributed with this source code - * in the PATENTS file, you can obtain it at www.aomedia.org/license/patent. - */ -#include "iamf/cli/mix_presentation_finalizer.h" - -#include -#include -#include -#include - -#include "absl/status/status_matchers.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "iamf/cli/tests/cli_test_utils.h" -#include "iamf/cli/wav_writer.h" -#include "iamf/obu/mix_presentation.h" -#include "iamf/obu/types.h" - -namespace iamf_tools { -namespace { - -using ::absl_testing::IsOk; - -constexpr DecodedUleb128 kMixPresentationId = 42; -constexpr DecodedUleb128 kAudioElementId = 300; -constexpr DecodedUleb128 kCommonParameterId = 999; -constexpr DecodedUleb128 kCommonParameterRate = 16000; - -std::unique_ptr ProduceNoWavWriters(DecodedUleb128, int, int, - const Layout&, - const std::filesystem::path&, - int, int, int) { - return nullptr; -} - -class MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest - : public ::testing::Test { - public: - MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest() { - // Initialize the input OBUs which will have loudness finalized. - AddMixPresentationObuWithAudioElementIds( - kMixPresentationId, {kAudioElementId}, kCommonParameterId, - kCommonParameterRate, obus_to_finalize_); - } - - void FinalizeExpectOk() { - MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizer finalizer; - - // `Finalize()` ignores most of the arguments. - EXPECT_THAT( - finalizer.Finalize({}, {}, {}, ProduceNoWavWriters, obus_to_finalize_), - IsOk()); - } - - protected: - std::list obus_to_finalize_; -}; - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - NoMixPresentationObus) { - obus_to_finalize_.clear(); - FinalizeExpectOk(); - EXPECT_TRUE(obus_to_finalize_.empty()); -} - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - CopiesIntegratedLoudnessAndDigitalPeak) { - const auto kLoudnessInfo = LoudnessInfo{ - .info_type = 0, .integrated_loudness = 99, .digital_peak = 100}; - obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness = kLoudnessInfo; - FinalizeExpectOk(); - - EXPECT_EQ(obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); -} - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - CopiesTruePeak) { - const auto kLoudnessInfo = LoudnessInfo{.info_type = LoudnessInfo::kTruePeak, - .integrated_loudness = 99, - .digital_peak = 100, - .true_peak = 101}; - obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness = kLoudnessInfo; - FinalizeExpectOk(); - - EXPECT_EQ(obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); -} - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - CopiesAnchoredLoudness) { - const auto kLoudnessInfo = - LoudnessInfo{.info_type = LoudnessInfo::kAnchoredLoudness, - .integrated_loudness = 99, - .digital_peak = 100, - .anchored_loudness{ - .num_anchored_loudness = 2, - .anchor_elements = { - {.anchor_element = - AnchoredLoudnessElement::kAnchorElementDialogue, - .anchored_loudness = 1000}, - {.anchor_element = - AnchoredLoudnessElement::kAnchorElementDialogue, - .anchored_loudness = 1001}}}}; - obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness = kLoudnessInfo; - FinalizeExpectOk(); - - EXPECT_EQ(obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); -} - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - CopiesExtensionLoudness) { - const auto kLoudnessInfo = LoudnessInfo{ - .info_type = LoudnessInfo::kAnyLayoutExtension, - .integrated_loudness = 99, - .digital_peak = 100, - .layout_extension = {.info_type_size = 1, .info_type_bytes = {'a'}}}; - obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness = kLoudnessInfo; - FinalizeExpectOk(); - - EXPECT_EQ(obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); -} - -TEST_F(MeasureLoudnessOrFallbackToUserLoudnessMixPresentationFinalizerTest, - CopiesMultipleObus) { - obus_to_finalize_.clear(); - const auto kLoudnessInfo = LoudnessInfo{ - .info_type = LoudnessInfo::kAnyLayoutExtension, - .integrated_loudness = 99, - .digital_peak = 100, - .layout_extension = {.info_type_size = 1, .info_type_bytes = {'a'}}}; - - // Initialize two user OBUs and the corresponding OBUs. - for (int i = 0; i < 2; i++) { - AddMixPresentationObuWithAudioElementIds( - kMixPresentationId, {kAudioElementId}, kCommonParameterId, - kCommonParameterRate, obus_to_finalize_); - obus_to_finalize_.back().sub_mixes_[0].layouts[0].loudness = kLoudnessInfo; - } - FinalizeExpectOk(); - - EXPECT_EQ(obus_to_finalize_.size(), 2); - EXPECT_EQ(obus_to_finalize_.front().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); - EXPECT_EQ(obus_to_finalize_.back().sub_mixes_[0].layouts[0].loudness, - kLoudnessInfo); -} - -} // namespace -} // namespace iamf_tools