Skip to content

Commit

Permalink
AddScalableAudioElementWithSubstreamIds: take in the layout and use…
Browse files Browse the repository at this point in the history
… the audio element builder.

  - b/309658744: Previously this helper test function did not work too well. It did not fill in the layers. Users had to fill in duplicate layer code, and it was often omitted.
  - We now have `AudioElementMetadataBuilder` to handle the minutia. Dispatch to it to get a one layer audio elements, and overwrite with the requested substreams.
  - Remove some downstream code, that was filling in layers manually.
  - Fold in uses that just want a stock one layer stereo audio element as proto to go through the builder.

PiperOrigin-RevId: 707925191
  • Loading branch information
jwcullen committed Dec 19, 2024
1 parent b2d4aa0 commit 42e1cd7
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 114 deletions.
3 changes: 3 additions & 0 deletions iamf/cli/proto_to_obu/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ cc_test(
"//iamf/cli/proto_to_obu:audio_frame_generator",
"//iamf/cli/proto_to_obu:codec_config_generator",
"//iamf/cli/tests:cli_test_utils",
"//iamf/cli/user_metadata_builder:audio_element_metadata_builder",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/common:obu_util",
"//iamf/obu:audio_frame",
"//iamf/obu:codec_config",
Expand Down Expand Up @@ -141,6 +143,7 @@ cc_test(
"//iamf/cli/proto:user_metadata_cc_proto",
"//iamf/cli/proto_to_obu:parameter_block_generator",
"//iamf/cli/tests:cli_test_utils",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/obu:audio_element",
"//iamf/obu:codec_config",
"//iamf/obu:param_definitions",
Expand Down
41 changes: 13 additions & 28 deletions iamf/cli/proto_to_obu/tests/audio_frame_generator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "iamf/cli/proto_to_obu/audio_element_generator.h"
#include "iamf/cli/proto_to_obu/codec_config_generator.h"
#include "iamf/cli/tests/cli_test_utils.h"
#include "iamf/cli/user_metadata_builder/audio_element_metadata_builder.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/common/obu_util.h"
#include "iamf/obu/audio_frame.h"
#include "iamf/obu/codec_config.h"
Expand Down Expand Up @@ -429,39 +431,22 @@ void AddStereoAudioElementAndAudioFrameMetadata(
audio_frame_metadata));
audio_frame_metadata->set_audio_element_id(audio_element_id);

auto* audio_element_metadata = user_metadata.add_audio_element_metadata();
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
R"pb(
audio_element_type: AUDIO_ELEMENT_CHANNEL_BASED
reserved: 0
codec_config_id: 200
num_substreams: 1
num_parameters: 0
scalable_channel_layout_config {
num_layers: 1
reserved: 0
channel_audio_layer_configs:
[ {
loudspeaker_layout: LOUDSPEAKER_LAYOUT_STEREO
output_gain_is_present_flag: 0
recon_gain_is_present_flag: 0
reserved_a: 0
substream_count: 1
coupled_substream_count: 1
}]
}
)pb",
audio_element_metadata));
audio_element_metadata->set_audio_element_id(audio_element_id);
audio_element_metadata->mutable_audio_substream_ids()->Add(
audio_substream_id);
AudioElementMetadataBuilder builder;
auto& audio_element_metadata = *user_metadata.add_audio_element_metadata();
ASSERT_THAT(builder.PopulateAudioElementMetadata(
audio_element_id, kCodecConfigId, IamfInputLayout::kStereo,
audio_element_metadata),
IsOk());
// Override with the custom substream ID.
audio_element_metadata.mutable_audio_substream_ids()->Set(0,
audio_substream_id);
}

void ConfigureAacCodecConfigMetadata(
iamf_tools_cli_proto::CodecConfigObuMetadata& codec_config_metadata) {
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
R"pb(
codec_config_id: 200
codec_config_id: 99
codec_config {
codec_id: CODEC_ID_AAC_LC
automatically_override_audio_roll_distance: true
Expand Down Expand Up @@ -490,7 +475,7 @@ void ConfigureOneStereoSubstreamLittleEndian(
iamf_tools_cli_proto::UserMetadata& user_metadata) {
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
R"pb(
codec_config_id: 200
codec_config_id: 99
codec_config {
codec_id: CODEC_ID_LPCM
num_samples_per_frame: 8
Expand Down
24 changes: 13 additions & 11 deletions iamf/cli/proto_to_obu/tests/parameter_block_generator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "iamf/cli/proto/parameter_block.pb.h"
#include "iamf/cli/proto/user_metadata.pb.h"
#include "iamf/cli/tests/cli_test_utils.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/obu/audio_element.h"
#include "iamf/obu/codec_config.h"
#include "iamf/obu/demixing_info_parameter_data.h"
Expand Down Expand Up @@ -112,15 +113,16 @@ void ConfigureDemixingParameterBlocks(
}

void InitializePrerequisiteObus(
IamfInputLayout input_layout,
absl::Span<const DecodedUleb128> substream_ids,
absl::flat_hash_map<DecodedUleb128, CodecConfigObu>& codec_config_obus,
absl::flat_hash_map<DecodedUleb128, AudioElementWithData>& audio_elements) {
constexpr uint32_t kSampleRate = 48000;
AddLpcmCodecConfigWithIdAndSampleRate(kCodecConfigId, kSampleRate,
codec_config_obus);
AddScalableAudioElementWithSubstreamIds(kAudioElementId, kCodecConfigId,
substream_ids, codec_config_obus,
audio_elements);
AddScalableAudioElementWithSubstreamIds(input_layout, kAudioElementId,
kCodecConfigId, substream_ids,
codec_config_obus, audio_elements);
}

void ValidateParameterBlocksCommon(
Expand Down Expand Up @@ -156,8 +158,8 @@ TEST(ParameterBlockGeneratorTest, GenerateTwoDemixingParameterBlocks) {
// Initialize pre-requisite OBUs.
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
InitializePrerequisiteObus(kOneSubstreamId, codec_config_obus,
audio_elements);
InitializePrerequisiteObus(IamfInputLayout::kStereo, kOneSubstreamId,
codec_config_obus, audio_elements);

// Add a demixing parameter definition inside the Audio Element OBU.
absl::flat_hash_map<DecodedUleb128, const ParamDefinition*> param_definitions;
Expand Down Expand Up @@ -271,8 +273,8 @@ TEST(ParameterBlockGeneratorTest, GenerateMixGainParameterBlocks) {
// Initialize pre-requisite OBUs.
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
InitializePrerequisiteObus(kOneSubstreamId, codec_config_obus,
audio_elements);
InitializePrerequisiteObus(IamfInputLayout::kStereo, kOneSubstreamId,
codec_config_obus, audio_elements);

// Add param definition. It would normally be owned by a Mix Presentation OBU.
MixGainParamDefinition param_definition;
Expand Down Expand Up @@ -431,8 +433,8 @@ TEST(ParameterBlockGeneratorTest, GenerateReconGainParameterBlocks) {
// Initialize pre-requisite OBUs.
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
InitializePrerequisiteObus(kFourSubtreamIds, codec_config_obus,
audio_elements);
InitializePrerequisiteObus(IamfInputLayout::k5_1, kFourSubtreamIds,
codec_config_obus, audio_elements);

// Extra data needed to compute recon gain.
PrepareAudioElementWithDataForReconGain(audio_elements.begin()->second);
Expand Down Expand Up @@ -489,8 +491,8 @@ TEST(Initialize, FailsWhenThereAreStrayParameterBlocks) {
ConfigureDemixingParameterBlocks(user_metadata);
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
InitializePrerequisiteObus(kFourSubtreamIds, codec_config_obus,
audio_elements);
InitializePrerequisiteObus(IamfInputLayout::k5_1, kFourSubtreamIds,
codec_config_obus, audio_elements);

// Construct and initialize.
ParameterBlockGenerator generator(kOverrideComputedReconGains,
Expand Down
7 changes: 7 additions & 0 deletions iamf/cli/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ cc_library(
"//iamf/cli/proto_to_obu:audio_element_generator",
"//iamf/cli/proto_to_obu:mix_presentation_generator",
"//iamf/cli/renderer:audio_element_renderer_base",
"//iamf/cli/user_metadata_builder:audio_element_metadata_builder",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/common:obu_util",
"//iamf/obu:audio_element",
"//iamf/obu:codec_config",
Expand Down Expand Up @@ -95,6 +97,7 @@ cc_test(
"//iamf/cli/proto:obu_header_cc_proto",
"//iamf/cli/proto:parameter_data_cc_proto",
"//iamf/cli/proto_to_obu:audio_element_generator",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/obu:audio_element",
"//iamf/obu:audio_frame",
"//iamf/obu:codec_config",
Expand Down Expand Up @@ -213,6 +216,8 @@ cc_test(
"//iamf/cli/proto:mix_presentation_cc_proto",
"//iamf/cli/proto:test_vector_metadata_cc_proto",
"//iamf/cli/proto:user_metadata_cc_proto",
"//iamf/cli/user_metadata_builder:audio_element_metadata_builder",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/obu:codec_config",
"//iamf/obu:ia_sequence_header",
"//iamf/obu:mix_presentation",
Expand Down Expand Up @@ -383,6 +388,7 @@ cc_test(
"//iamf/cli:wav_reader",
"//iamf/cli:wav_writer",
"//iamf/cli/renderer:audio_element_renderer_base",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/obu:audio_element",
"//iamf/obu:codec_config",
"//iamf/obu:mix_presentation",
Expand Down Expand Up @@ -462,6 +468,7 @@ cc_test(
"//iamf/cli/proto:audio_element_cc_proto",
"//iamf/cli/proto:audio_frame_cc_proto",
"//iamf/cli/proto:user_metadata_cc_proto",
"//iamf/cli/user_metadata_builder:iamf_input_layout",
"//iamf/obu:codec_config",
"//iamf/obu:types",
"@com_google_absl//absl/container:flat_hash_map",
Expand Down
48 changes: 26 additions & 22 deletions iamf/cli/tests/cli_test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include "iamf/cli/proto_to_obu/audio_element_generator.h"
#include "iamf/cli/proto_to_obu/mix_presentation_generator.h"
#include "iamf/cli/renderer/audio_element_renderer_base.h"
#include "iamf/cli/user_metadata_builder/audio_element_metadata_builder.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/cli/wav_reader.h"
#include "iamf/obu/audio_element.h"
#include "iamf/obu/codec_config.h"
Expand All @@ -59,6 +61,7 @@
#include "iamf/obu/param_definitions.h"
#include "iamf/obu/types.h"
#include "src/google/protobuf/io/zero_copy_stream_impl.h"
#include "src/google/protobuf/repeated_ptr_field.h"
#include "src/google/protobuf/text_format.h"

namespace iamf_tools {
Expand Down Expand Up @@ -225,33 +228,34 @@ void AddAmbisonicsMonoAudioElementWithSubstreamIds(
audio_elements.emplace(audio_element_id, std::move(audio_element));
}

// TODO(b/309658744): Populate the rest of `ScalableChannelLayout`.
// Adds a scalable Audio Element OBU based on the input arguments.
void AddScalableAudioElementWithSubstreamIds(
DecodedUleb128 audio_element_id, uint32_t codec_config_id,
absl::Span<const DecodedUleb128> substream_ids,
IamfInputLayout input_layout, DecodedUleb128 audio_element_id,
uint32_t codec_config_id, absl::Span<const DecodedUleb128> substream_ids,
const absl::flat_hash_map<uint32_t, CodecConfigObu>& codec_config_obus,
absl::flat_hash_map<DecodedUleb128, AudioElementWithData>& audio_elements) {
// Check the `codec_config_id` is known and this is a new
// `audio_element_id`.
auto codec_config_iter = codec_config_obus.find(codec_config_id);
ASSERT_NE(codec_config_iter, codec_config_obus.end());
ASSERT_EQ(audio_elements.find(audio_element_id), audio_elements.end());

// Initialize the Audio Element OBU without any parameters and a single layer.
AudioElementObu obu(ObuHeader(), audio_element_id,
AudioElementObu::kAudioElementChannelBased, 0,
codec_config_id);
obu.InitializeAudioSubstreams(substream_ids.size());
obu.audio_substream_ids_.assign(substream_ids.begin(), substream_ids.end());
obu.InitializeParams(0);

EXPECT_THAT(obu.InitializeScalableChannelLayout(1, 0), IsOk());

AudioElementWithData audio_element = {
.obu = std::move(obu), .codec_config = &codec_config_iter->second};
google::protobuf::RepeatedPtrField<
iamf_tools_cli_proto::AudioElementObuMetadata>
audio_element_metadatas;
AudioElementMetadataBuilder builder;

auto& new_audio_element_metadata = *audio_element_metadatas.Add();
ASSERT_THAT(builder.PopulateAudioElementMetadata(
audio_element_id, codec_config_id, input_layout,
new_audio_element_metadata),
IsOk());
// Check that this is a scalable Audio Element, and override the substream
// IDs.
ASSERT_TRUE(new_audio_element_metadata.has_scalable_channel_layout_config());
ASSERT_EQ(new_audio_element_metadata.num_substreams(), substream_ids.size());
for (int i = 0; i < substream_ids.size(); ++i) {
new_audio_element_metadata.mutable_audio_substream_ids()->Set(
i, substream_ids[i]);
}

audio_elements.emplace(audio_element_id, std::move(audio_element));
// Generate the Audio Element OBU.
AudioElementGenerator generator(audio_element_metadatas);
ASSERT_THAT(generator.Generate(codec_config_obus, audio_elements), IsOk());
}

void AddMixPresentationObuWithAudioElementIds(
Expand Down
6 changes: 4 additions & 2 deletions iamf/cli/tests/cli_test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "iamf/cli/proto/user_metadata.pb.h"
#include "iamf/cli/renderer/audio_element_renderer_base.h"
#include "iamf/cli/resampler_base.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/cli/wav_reader.h"
#include "iamf/common/obu_util.h"
#include "iamf/obu/audio_element.h"
Expand Down Expand Up @@ -105,15 +106,16 @@ void AddAmbisonicsMonoAudioElementWithSubstreamIds(

/*!\brief Adds a configurable scalable `AudioElementObu` to the output argument.
*
* \param input_layout `input_layout` of the OBU to create.
* \param audio_element_id `audio_element_id` of the OBU to create.
* \param codec_config_id `codec_config_id` of the OBU to create.
* \param substream_ids `substream_ids` of the OBU to create.
* \param codec_config_obus Codec Config OBUs containing the associated OBU.
* \param audio_elements Map to add the OBU to keyed by `audio_element_id`.
*/
void AddScalableAudioElementWithSubstreamIds(
DecodedUleb128 audio_element_id, uint32_t codec_config_id,
absl::Span<const DecodedUleb128> substream_ids,
IamfInputLayout input_layout, DecodedUleb128 audio_element_id,
uint32_t codec_config_id, absl::Span<const DecodedUleb128> substream_ids,
const absl::flat_hash_map<uint32_t, CodecConfigObu>& codec_config_obus,
absl::flat_hash_map<DecodedUleb128, AudioElementWithData>& audio_elements);

Expand Down
5 changes: 3 additions & 2 deletions iamf/cli/tests/cli_util_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "iamf/cli/proto/parameter_data.pb.h"
#include "iamf/cli/proto_to_obu/audio_element_generator.h"
#include "iamf/cli/tests/cli_test_utils.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/obu/audio_element.h"
#include "iamf/obu/audio_frame.h"
#include "iamf/obu/codec_config.h"
Expand Down Expand Up @@ -675,8 +676,8 @@ TEST(GenerateParamIdToMetadataMapTest,
absl::flat_hash_map<DecodedUleb128, AudioElementWithData>
audio_elements_with_data;
AddScalableAudioElementWithSubstreamIds(
kAudioElementId, kCodecConfigId, {kFirstSubstreamId}, input_codec_configs,
audio_elements_with_data);
IamfInputLayout::kMono, kAudioElementId, kCodecConfigId,
{kFirstSubstreamId}, input_codec_configs, audio_elements_with_data);

auto param_definition = ReconGainParamDefinition(kSecondAudioElementId);
param_definition.parameter_id_ = kParameterId;
Expand Down
32 changes: 8 additions & 24 deletions iamf/cli/tests/iamf_encoder_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "iamf/cli/proto/mix_presentation.pb.h"
#include "iamf/cli/proto/test_vector_metadata.pb.h"
#include "iamf/cli/proto/user_metadata.pb.h"
#include "iamf/cli/user_metadata_builder/audio_element_metadata_builder.h"
#include "iamf/cli/user_metadata_builder/iamf_input_layout.h"
#include "iamf/obu/codec_config.h"
#include "iamf/obu/ia_sequence_header.h"
#include "iamf/obu/mix_presentation.h"
Expand All @@ -35,6 +37,7 @@ namespace {
using ::absl_testing::IsOk;
using ::iamf_tools_cli_proto::UserMetadata;

constexpr DecodedUleb128 kCodecConfigId = 200;
constexpr DecodedUleb128 kAudioElementId = 300;
constexpr uint32_t kNumSamplesPerFrame = 8;

Expand Down Expand Up @@ -66,30 +69,11 @@ void AddCodecConfig(UserMetadata& user_metadata) {
}

void AddAudioElement(UserMetadata& user_metadata) {
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
R"pb(
audio_element_id: 300
audio_element_type: AUDIO_ELEMENT_CHANNEL_BASED
reserved: 0
codec_config_id: 200
num_substreams: 1
audio_substream_ids: [ 0 ]
num_parameters: 0
scalable_channel_layout_config {
num_layers: 1
reserved: 0
channel_audio_layer_configs:
[ {
loudspeaker_layout: LOUDSPEAKER_LAYOUT_STEREO
output_gain_is_present_flag: 0
recon_gain_is_present_flag: 0
reserved_a: 0
substream_count: 1
coupled_substream_count: 1
}]
}
)pb",
user_metadata.add_audio_element_metadata()));
AudioElementMetadataBuilder builder;
ASSERT_THAT(builder.PopulateAudioElementMetadata(
kAudioElementId, kCodecConfigId, IamfInputLayout::kStereo,
*user_metadata.add_audio_element_metadata()),
IsOk());
}

void AddMixPresentation(UserMetadata& user_metadata) {
Expand Down
Loading

0 comments on commit 42e1cd7

Please sign in to comment.