Skip to content

Commit

Permalink
Break out and test AacDecoderConfig::Validate.
Browse files Browse the repository at this point in the history
  - Replace some test fixture tests with this more focused test.

PiperOrigin-RevId: 654082857
  • Loading branch information
jwcullen committed Jul 19, 2024
1 parent 0cf574b commit 9cf5c06
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 98 deletions.
42 changes: 21 additions & 21 deletions iamf/obu/decoder_config/aac_decoder_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(
Expand All @@ -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));
Expand Down
15 changes: 14 additions & 1 deletion iamf/obu/decoder_config/aac_decoder_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
196 changes: 120 additions & 76 deletions iamf/obu/decoder_config/tests/aac_decoder_config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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_ =
Expand Down

0 comments on commit 9cf5c06

Please sign in to comment.