Skip to content

Commit

Permalink
ChannelAudioLayerConfig: Refactor existing read/write functionality…
Browse files Browse the repository at this point in the history
… into `Read` and `Write` functions.

  - There is nothing being validated at the single-layer level - so these functions do not have `Validate` in the name.
  - Increase coverage here which was otherwise very light - add some tests adjacent to planned features regarding `expanded_loudspeaker_layout`.

PiperOrigin-RevId: 654013559
  • Loading branch information
jwcullen committed Jul 19, 2024
1 parent df2ff29 commit b77fc64
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 52 deletions.
74 changes: 37 additions & 37 deletions iamf/obu/audio_element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,23 +194,7 @@ absl::Status ValidateAndWriteScalableChannelLayout(

// Loop to write the `channel_audio_layer_configs` array.
for (const auto& layer_config : layout.channel_audio_layer_configs) {
RETURN_IF_NOT_OK(
wb.WriteUnsignedLiteral(layer_config.loudspeaker_layout, 4));
RETURN_IF_NOT_OK(
wb.WriteUnsignedLiteral(layer_config.output_gain_is_present_flag, 1));
RETURN_IF_NOT_OK(
wb.WriteUnsignedLiteral(layer_config.recon_gain_is_present_flag, 1));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(layer_config.reserved_a, 2));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(layer_config.substream_count, 8));
RETURN_IF_NOT_OK(
wb.WriteUnsignedLiteral(layer_config.coupled_substream_count, 8));

if (layer_config.output_gain_is_present_flag == 1) {
RETURN_IF_NOT_OK(
wb.WriteUnsignedLiteral(layer_config.output_gain_flag, 6));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(layer_config.reserved_b, 2));
RETURN_IF_NOT_OK(wb.WriteSigned16(layer_config.output_gain));
}
RETURN_IF_NOT_OK(layer_config.Write(wb));
}

return absl::OkStatus();
Expand All @@ -226,26 +210,7 @@ absl::Status ReadAndValidateScalableChannelLayout(

for (int i = 0; i < layout.num_layers; ++i) {
ChannelAudioLayerConfig layer_config;
uint8_t loudspeaker_layout;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(4, loudspeaker_layout));
layer_config.loudspeaker_layout =
static_cast<ChannelAudioLayerConfig::LoudspeakerLayout>(
loudspeaker_layout);
RETURN_IF_NOT_OK(
rb.ReadUnsignedLiteral(1, layer_config.output_gain_is_present_flag));
RETURN_IF_NOT_OK(
rb.ReadUnsignedLiteral(1, layer_config.recon_gain_is_present_flag));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, layer_config.reserved_a));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, layer_config.substream_count));
RETURN_IF_NOT_OK(
rb.ReadUnsignedLiteral(8, layer_config.coupled_substream_count));

if (layer_config.output_gain_is_present_flag == 1) {
RETURN_IF_NOT_OK(
rb.ReadUnsignedLiteral(6, layer_config.output_gain_flag));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, layer_config.reserved_b));
RETURN_IF_NOT_OK(rb.ReadSigned16(layer_config.output_gain));
}
RETURN_IF_NOT_OK(layer_config.Read(rb));
layout.channel_audio_layer_configs.push_back(layer_config);
}

Expand Down Expand Up @@ -414,6 +379,41 @@ absl::Status AudioElementParam::ReadAndValidate(uint32_t audio_element_id,
}
}

absl::Status ChannelAudioLayerConfig::Write(WriteBitBuffer& wb) const {
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(loudspeaker_layout, 4));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(output_gain_is_present_flag, 1));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(recon_gain_is_present_flag, 1));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(reserved_a, 2));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(substream_count, 8));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(coupled_substream_count, 8));

if (output_gain_is_present_flag == 1) {
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(output_gain_flag, 6));
RETURN_IF_NOT_OK(wb.WriteUnsignedLiteral(reserved_b, 2));
RETURN_IF_NOT_OK(wb.WriteSigned16(output_gain));
}
return absl::OkStatus();
}

absl::Status ChannelAudioLayerConfig::Read(ReadBitBuffer& rb) {
uint8_t loudspeaker_layout_uint8;
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(4, loudspeaker_layout_uint8));
loudspeaker_layout = static_cast<ChannelAudioLayerConfig::LoudspeakerLayout>(
loudspeaker_layout_uint8);
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(1, output_gain_is_present_flag));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(1, recon_gain_is_present_flag));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, reserved_a));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, substream_count));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(8, coupled_substream_count));

if (output_gain_is_present_flag == 1) {
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(6, output_gain_flag));
RETURN_IF_NOT_OK(rb.ReadUnsignedLiteral(2, reserved_b));
RETURN_IF_NOT_OK(rb.ReadSigned16(output_gain));
}
return absl::OkStatus();
}

absl::Status ScalableChannelLayoutConfig::Validate(
DecodedUleb128 num_substreams_in_audio_element) const {
if (num_layers == 0 || num_layers > 6) {
Expand Down
21 changes: 20 additions & 1 deletion iamf/obu/audio_element.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ struct AudioElementParam {
std::unique_ptr<ParamDefinition> param_definition;
};

/*!\brief An element of the `ScalableChannelLayoutConfig` vector. */
/*!\brief An element of the `ScalableChannelLayoutConfig` vector.
*
* Implements the `ChannelAudioLayerConfig` as defined by section 3.6.2 of
* https://aomediacodec.github.io/iamf/v1.0.0-errata.html.
*/
struct ChannelAudioLayerConfig {
/*!\brief A 4-bit enum for the type of layout. */
enum LoudspeakerLayout : uint8_t {
Expand All @@ -75,6 +79,21 @@ struct ChannelAudioLayerConfig {
friend bool operator==(const ChannelAudioLayerConfig& lhs,
const ChannelAudioLayerConfig& rhs) = default;

/*!\brief Writes the `ChannelAudioLayerConfig` payload to the buffer.
*
* \param wb Buffer to write to.
* \return `absl::OkStatus()` if the payload is valid. A specific status on
* failure.
*/
absl::Status Write(WriteBitBuffer& wb) const;

/*!\brief Reads the `ChannelAudioLayerConfig` payload from the buffer.
*
* \param rb Buffer to read from.
* \return `absl::OkStatus()` if successful. A specific status on failure.
*/
absl::Status Read(ReadBitBuffer& rb);

LoudspeakerLayout loudspeaker_layout; // 4 bits.
uint8_t output_gain_is_present_flag; // 1 bit.
uint8_t recon_gain_is_present_flag; // 1 bit.
Expand Down
1 change: 1 addition & 0 deletions iamf/obu/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ cc_test(
"//iamf/cli:leb_generator",
"//iamf/common:read_bit_buffer",
"//iamf/common:write_bit_buffer",
"//iamf/common/tests:test_utils",
"//iamf/obu:audio_element",
"//iamf/obu:demixing_info_param_data",
"//iamf/obu:leb128",
Expand Down
Loading

0 comments on commit b77fc64

Please sign in to comment.