Skip to content

Commit

Permalink
Adds a separate Validate to LpcmDecoderConfig (without Write)
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 632532364
  • Loading branch information
trevorknight authored and jwcullen committed May 14, 2024
1 parent 6aaf77a commit d7008a4
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 69 deletions.
10 changes: 8 additions & 2 deletions iamf/obu/decoder_config/lpcm_decoder_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,16 @@ bool LpcmDecoderConfig::IsLittleEndian() const {
LpcmDecoderConfig::LpcmFormatFlagsBitmask::kLpcmLittleEndian;
}

absl::Status LpcmDecoderConfig::ValidateAndWrite(int16_t audio_roll_distance,
WriteBitBuffer& wb) const {
absl::Status LpcmDecoderConfig::Validate(int16_t audio_roll_distance) const {
RETURN_IF_NOT_OK(ValidateAudioRollDistance(audio_roll_distance));
RETURN_IF_NOT_OK(ValidatePayload(*this));

return absl::OkStatus();
}

absl::Status LpcmDecoderConfig::ValidateAndWrite(int16_t audio_roll_distance,
WriteBitBuffer& wb) const {
RETURN_IF_NOT_OK(Validate(audio_roll_distance));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(sample_format_flags_bitmask_, 8));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(sample_size_, 8));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(sample_rate_, 32));
Expand Down
9 changes: 9 additions & 0 deletions iamf/obu/decoder_config/lpcm_decoder_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ class LpcmDecoderConfig {
/*!\brief Returns true if the samples are encoded in little-endian format.*/
bool IsLittleEndian() const;

/*!\brief Validates the values in `LpcmDecoderConfig` and the roll distance.
*
* \param audio_roll_distance `audio_roll_distance` in the associated Codec
* Config OBU.
* \return `absl::OkStatus()` if the decoder config is valid. A specific error
* code on failure.
*/
absl::Status Validate(int16_t audio_roll_distance) const;

/*!\brief Validates and writes the `LpcmDecoderConfig` to a buffer.
*
* \param audio_roll_distance `audio_roll_distance` in the associated Codec
Expand Down
140 changes: 73 additions & 67 deletions iamf/obu/decoder_config/tests/lpcm_decoder_config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ TEST(LpcmDecoderConfigTest, IsLittleEndian_False) {
EXPECT_FALSE(lpcm_decoder_config.IsLittleEndian());
}

TEST(LpcmDecoderConfigTest, WriteValidLittleEndian) {
TEST(LpcmDecoderConfigTest, Validate_ValidLittleEndian) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -48,12 +48,10 @@ TEST(LpcmDecoderConfigTest, WriteValidLittleEndian) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteValidBigEndian) {
TEST(LpcmDecoderConfigTest, Validate_ValidBigEndian) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmBigEndian,
16, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -62,34 +60,27 @@ TEST(LpcmDecoderConfigTest, WriteValidBigEndian) {
0x00, 0x00, 0xbb, 0x80 // sample_rate
};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleFormatFlagsMin) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleFormatFlagsMin) {
LpcmDecoderConfig lpcm_decoder_config = {
LpcmDecoderConfig::kLpcmBeginReserved, 16, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleFormatFlagsMax) {
TEST(LpcmDecoderConfigTest, Validate_IllegalSampleFormatFlagsMax) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmEndReserved,
16, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteSampleSize24) {
TEST(LpcmDecoderConfigTest, Validate_SampleSize24) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
24, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -100,12 +91,10 @@ TEST(LpcmDecoderConfigTest, WriteSampleSize24) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteSampleSize32) {
TEST(LpcmDecoderConfigTest, Validate_SampleSize32) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
32, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -116,62 +105,50 @@ TEST(LpcmDecoderConfigTest, WriteSampleSize32) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, AudioRollDistanceMustBeZero_A) {
TEST(LpcmDecoderConfigTest, Validate_AudioRollDistanceMustBeZero_A) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 48000};
int16_t audio_roll_distance = -1;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, AudioRollDistanceMustBeZero_B) {
TEST(LpcmDecoderConfigTest, Validate_AudioRollDistanceMustBeZero_B) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 48000};
int16_t audio_roll_distance = 1;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleSizeZero) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeZero) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
0, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleSizeEight) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeEight) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
8, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleSizeOverMax) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeOverMax) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
40, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteSampleRateMin_16kHz) {
TEST(LpcmDecoderConfigTest, Validate_SampleRateMin_16kHz) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
32, 16000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -182,12 +159,10 @@ TEST(LpcmDecoderConfigTest, WriteSampleRateMin_16kHz) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteSampleRate44_1kHz) {
TEST(LpcmDecoderConfigTest, Validate_SampleRate44_1kHz) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
32, 44100};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -198,12 +173,10 @@ TEST(LpcmDecoderConfigTest, WriteSampleRate44_1kHz) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, WriteSampleRateMax_96kHz) {
TEST(LpcmDecoderConfigTest, Validate_SampleRateMax_96kHz) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
32, 96000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
Expand All @@ -214,37 +187,70 @@ TEST(LpcmDecoderConfigTest, WriteSampleRateMax_96kHz) {
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
EXPECT_TRUE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleRateZero) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRateZero) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 0};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleRate192kHz) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRate192kHz) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 192000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, IllegalSampleRateMax) {
TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRateMax) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16,
std::numeric_limits<int16_t>::max()};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size, we'll fail before writing.

EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
}

TEST(LpcmDecoderConfigTest, Write_AllValid) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
1, // sample_format_flags
16, // sample_size
0x00, 0x00, 0xbb, 0x80 // sample_rate
};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_TRUE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
ValidateWriteResults(wb, expected_decoder_config_payload_);
}

TEST(LpcmDecoderConfigTest, Write_InvalidDoesNotWrite) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
8, 48000};
int16_t audio_roll_distance = 0;
WriteBitBuffer wb(48); // Arbitrary size. We'll fail before writing.

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
}

TEST(LpcmDecoderConfigTest, Write_InvalidRollDistance) {
LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
16, 48000};
std::vector<uint8_t> expected_decoder_config_payload_ = {
1, // sample_format_flags
16, // sample_size
0x00, 0x00, 0xbb, 0x80 // sample_rate
};
int16_t audio_roll_distance = 1;
WriteBitBuffer wb(expected_decoder_config_payload_.size());

EXPECT_FALSE(
lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
Expand Down

0 comments on commit d7008a4

Please sign in to comment.