From 9cf5c06a442c4f354099939cb10f7bd262d15164 Mon Sep 17 00:00:00 2001 From: jwcullen Date: Fri, 19 Jul 2024 15:05:07 -0400 Subject: [PATCH] Break out and test `AacDecoderConfig::Validate`. - Replace some test fixture tests with this more focused test. PiperOrigin-RevId: 654082857 --- iamf/obu/decoder_config/aac_decoder_config.cc | 42 ++-- iamf/obu/decoder_config/aac_decoder_config.h | 15 +- .../tests/aac_decoder_config_test.cc | 196 +++++++++++------- 3 files changed, 155 insertions(+), 98 deletions(-) diff --git a/iamf/obu/decoder_config/aac_decoder_config.cc b/iamf/obu/decoder_config/aac_decoder_config.cc index 3fb902fe..b07e9543 100644 --- a/iamf/obu/decoder_config/aac_decoder_config.cc +++ b/iamf/obu/decoder_config/aac_decoder_config.cc @@ -26,26 +26,36 @@ namespace iamf_tools { namespace { -// Validates the `AacDecoderConfig`. -absl::Status ValidatePayload(const AacDecoderConfig& decoder_config) { - RETURN_IF_NOT_OK(ValidateEqual(decoder_config.decoder_config_descriptor_tag_, + +absl::Status ValidateAudioRollDistance(int16_t audio_roll_distance) { + if (audio_roll_distance != -1) { + return absl::InvalidArgumentError( + absl::StrCat("Invalid audio_roll_distance= ", audio_roll_distance)); + } + return absl::OkStatus(); +} + +} // namespace + +absl::Status AacDecoderConfig::Validate() const { + RETURN_IF_NOT_OK(ValidateEqual(decoder_config_descriptor_tag_, AacDecoderConfig::kDecoderConfigDescriptorTag, "decoder_config_descriptor_tag")); // IAMF restricts several fields. - RETURN_IF_NOT_OK(ValidateEqual(decoder_config.object_type_indication_, + RETURN_IF_NOT_OK(ValidateEqual(object_type_indication_, AacDecoderConfig::kObjectTypeIndication, "object_type_indication")); - RETURN_IF_NOT_OK(ValidateEqual(decoder_config.stream_type_, - AacDecoderConfig::kStreamType, "stream_type")); - RETURN_IF_NOT_OK(ValidateEqual(decoder_config.upstream_, - AacDecoderConfig::kUpstream, "upstream")); + RETURN_IF_NOT_OK(ValidateEqual(stream_type_, AacDecoderConfig::kStreamType, + "stream_type")); + RETURN_IF_NOT_OK( + ValidateEqual(upstream_, AacDecoderConfig::kUpstream, "upstream")); RETURN_IF_NOT_OK(ValidateEqual( - decoder_config.decoder_specific_info_.decoder_specific_info_tag, + decoder_specific_info_.decoder_specific_info_tag, AacDecoderConfig::DecoderSpecificInfo::kDecoderSpecificInfoTag, "decoder_specific_info_tag")); const AudioSpecificConfig& audio_specific_config = - decoder_config.decoder_specific_info_.audio_specific_config; + decoder_specific_info_.audio_specific_config; RETURN_IF_NOT_OK(ValidateEqual(audio_specific_config.audio_object_type_, AudioSpecificConfig::kAudioObjectType, @@ -67,16 +77,6 @@ absl::Status ValidatePayload(const AacDecoderConfig& decoder_config) { return absl::OkStatus(); } -absl::Status ValidateAudioRollDistance(int16_t audio_roll_distance) { - if (audio_roll_distance != -1) { - return absl::InvalidArgumentError( - absl::StrCat("Invalid audio_roll_distance= ", audio_roll_distance)); - } - return absl::OkStatus(); -} - -} // namespace - absl::Status AudioSpecificConfig::ValidateAndWrite(WriteBitBuffer& wb) const { RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(audio_object_type_, 5)); RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral( @@ -100,7 +100,7 @@ absl::Status AudioSpecificConfig::ValidateAndWrite(WriteBitBuffer& wb) const { absl::Status AacDecoderConfig::ValidateAndWrite(int16_t audio_roll_distance, WriteBitBuffer& wb) const { RETURN_IF_NOT_OK(ValidateAudioRollDistance(audio_roll_distance)); - RETURN_IF_NOT_OK(ValidatePayload(*this)); + RETURN_IF_NOT_OK(Validate()); // Write top-level fields. RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(decoder_config_descriptor_tag_, 8)); diff --git a/iamf/obu/decoder_config/aac_decoder_config.h b/iamf/obu/decoder_config/aac_decoder_config.h index ee26e8e2..48a45ae1 100644 --- a/iamf/obu/decoder_config/aac_decoder_config.h +++ b/iamf/obu/decoder_config/aac_decoder_config.h @@ -86,7 +86,13 @@ class AudioSpecificConfig { } ga_specific_config_; }; -/*!\brief The `CodecConfig` `decoder_config` field for AAC. */ +/*!\brief The `CodecConfig` `decoder_config` field for AAC. + * + * As defined in IAMF v1.0.0-errata section 3.11.2 + * https://aomediacodec.github.io/iamf/#aac-lc-specific. Many fields are fixed + * by the IAMF spec and should typically never be changed from their default + * values. + */ class AacDecoderConfig { public: static constexpr uint8_t kDecoderConfigDescriptorTag = 0x04; @@ -97,6 +103,13 @@ class AacDecoderConfig { friend bool operator==(const AacDecoderConfig& lhs, const AacDecoderConfig& rhs) = default; + /*!\brief Validates the `AacDecoderConfig`. + * + * \return `absl::OkStatus()` if the decoder config is valid. A specific + * status on failure. + */ + absl::Status Validate() const; + /*!\brief Validates and writes the `AacDecoderConfig` to a buffer. * * \param audio_roll_distance `audio_roll_distance` in the associated Codec diff --git a/iamf/obu/decoder_config/tests/aac_decoder_config_test.cc b/iamf/obu/decoder_config/tests/aac_decoder_config_test.cc index 2d2c4fda..5e4c2f6c 100644 --- a/iamf/obu/decoder_config/tests/aac_decoder_config_test.cc +++ b/iamf/obu/decoder_config/tests/aac_decoder_config_test.cc @@ -34,19 +34,128 @@ constexpr uint8_t kChannelConfigurationAndGaSpecificConfigMask = AudioSpecificConfig::GaSpecificConfig::kDependsOnCoreCoder << 1 | // 1 bit. AudioSpecificConfig::GaSpecificConfig::kExtensionFlag << 0; // 1 bit. +AacDecoderConfig GetAacDecoderConfig() { + return AacDecoderConfig{ + .reserved_ = 0, + .buffer_size_db_ = 0, + .max_bitrate_ = 0, + .average_bit_rate_ = 0, + .decoder_specific_info_ = + {.audio_specific_config = + {.sample_frequency_index_ = AudioSpecificConfig:: + AudioSpecificConfig::kSampleFrequencyIndex64000}}, + }; +} + +TEST(AacDecoderConfig, ValidateWithCommonValues) { + EXPECT_THAT(GetAacDecoderConfig().Validate(), IsOk()); +} + +TEST(AacDecoderConfig, ValidateWithManyVaryingValues) { + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.reserved_ = 1; + aac_decoder_config.buffer_size_db_ = 1; + aac_decoder_config.max_bitrate_ = 1; + aac_decoder_config.average_bit_rate_ = 1; + aac_decoder_config.decoder_specific_info_.audio_specific_config + .sample_frequency_index_ = + AudioSpecificConfig::kSampleFrequencyIndexEscapeValue; + aac_decoder_config.decoder_specific_info_.audio_specific_config + .sampling_frequency_ = 48; + + EXPECT_THAT(GetAacDecoderConfig().Validate(), IsOk()); +} + +TEST(AacDecoderConfig, ValidatesDecoderConfigDescriptorTag) { + constexpr uint8_t kInvalidDecoderConfigDescriptorTag = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_config_descriptor_tag_ = + kInvalidDecoderConfigDescriptorTag; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesObjectTypeIndication) { + constexpr uint8_t kInvalidObjectTypeIndication = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.object_type_indication_ = kInvalidObjectTypeIndication; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesStreamType) { + constexpr uint8_t kInvalidStreamType = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.stream_type_ = kInvalidStreamType; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesUpstream) { + constexpr bool kInvalidUpstream = true; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.upstream_ = kInvalidUpstream; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesDecoderSpecificInfoTag) { + constexpr uint8_t kInvalidDecoderSpecificInfoTag = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.decoder_specific_info_tag = + kInvalidDecoderSpecificInfoTag; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesAudioObjectType) { + constexpr uint8_t kInvalidAudioObjectType = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.audio_specific_config + .audio_object_type_ = kInvalidAudioObjectType; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesChannelConfiguration) { + constexpr uint8_t kInvalidChannelConfiguration = 0; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.audio_specific_config + .channel_configuration_ = kInvalidChannelConfiguration; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesFrameLengthFlag) { + constexpr bool kInvalidFrameLengthFlag = true; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.audio_specific_config + .ga_specific_config_.frame_length_flag = kInvalidFrameLengthFlag; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesDepenedsOnCoreCoder) { + constexpr bool kInvalidDependsOnCoreCoder = true; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.audio_specific_config + .ga_specific_config_.depends_on_core_coder = kInvalidDependsOnCoreCoder; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + +TEST(AacDecoderConfig, ValidatesExtensionFlag) { + constexpr bool kInvalidExtensionFlag = true; + auto aac_decoder_config = GetAacDecoderConfig(); + aac_decoder_config.decoder_specific_info_.audio_specific_config + .ga_specific_config_.extension_flag = kInvalidExtensionFlag; + + EXPECT_FALSE(aac_decoder_config.Validate().ok()); +} + class AacTest : public testing::Test { public: - AacTest() - : aac_decoder_config_({ - .reserved_ = 0, - .buffer_size_db_ = 0, - .max_bitrate_ = 0, - .average_bit_rate_ = 0, - .decoder_specific_info_ = - {.audio_specific_config = - {.sample_frequency_index_ = AudioSpecificConfig:: - AudioSpecificConfig::kSampleFrequencyIndex64000}}, - }) {} + AacTest() : aac_decoder_config_(GetAacDecoderConfig()) {} ~AacTest() = default; @@ -194,30 +303,6 @@ TEST_F(AacTest, IllegalAudioRollDistanceMustBeNegativeOne) { TestWriteDecoderConfig(); } -TEST_F(AacTest, IllegalDecoderConfigDescriptorTag) { - aac_decoder_config_.decoder_config_descriptor_tag_ = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalObjectTypeIndication) { - aac_decoder_config_.object_type_indication_ = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalStreamType) { - aac_decoder_config_.stream_type_ = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalUpstream) { - aac_decoder_config_.upstream_ = true; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - TEST_F(AacTest, MaxBufferSizeDb) { aac_decoder_config_.buffer_size_db_ = (1 << 24) - 1; @@ -257,47 +342,6 @@ TEST_F(AacTest, OverflowBufferSizeDbOver24Bits) { TestWriteDecoderConfig(); } -TEST_F(AacTest, IllegalDecoderSpecificInfoTag) { - aac_decoder_config_.decoder_specific_info_.decoder_specific_info_tag = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalAudioObjectType) { - aac_decoder_config_.decoder_specific_info_.audio_specific_config - .audio_object_type_ = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalChannelConfiguration) { - aac_decoder_config_.decoder_specific_info_.audio_specific_config - .channel_configuration_ = 0; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalFrameLengthFlag) { - aac_decoder_config_.decoder_specific_info_.audio_specific_config - .ga_specific_config_.frame_length_flag = true; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalDependsOnCoreCoder) { - aac_decoder_config_.decoder_specific_info_.audio_specific_config - .ga_specific_config_.depends_on_core_coder = true; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - -TEST_F(AacTest, IllegalExtensionFlag) { - aac_decoder_config_.decoder_specific_info_.audio_specific_config - .ga_specific_config_.extension_flag = true; - expected_write_is_ok_ = false; - TestWriteDecoderConfig(); -} - TEST_F(AacTest, GetImplicitSampleRate) { aac_decoder_config_.decoder_specific_info_.audio_specific_config .sample_frequency_index_ =