Skip to content

Commit

Permalink
Increase conformance regarding v1.0.0-errata reserved param_definitio…
Browse files Browse the repository at this point in the history
…n types.

  - `test_000121`: Uses a reserved parameter type that must be gracefully ignored.
  - `cli_util`: Gracefully ignore the extension parameter types - it is not possible to determine the `parameter_id` and verify it is equivalent to others with the same ID.

PiperOrigin-RevId: 653425792
  • Loading branch information
jwcullen committed Jul 18, 2024
1 parent 33d66b1 commit 02d6318
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 16 deletions.
27 changes: 17 additions & 10 deletions iamf/cli/cli_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,21 +203,28 @@ absl::Status CollectAndValidateParamDefinitions(

// Collect all `param_definition`s in Audio Element and Mix Presentation
// OBUs.
for (const auto& [unused_id, audio_element] : audio_elements) {
for (const auto& [audio_element_id_for_debugging, audio_element] :
audio_elements) {
for (const auto& audio_element_param :
audio_element.obu.audio_element_params_) {
const auto param_definition_type =
audio_element_param.param_definition_type;
if (param_definition_type !=
ParamDefinition::kParameterDefinitionDemixing &&
param_definition_type !=
ParamDefinition::kParameterDefinitionReconGain) {
return absl::InvalidArgumentError(
absl::StrCat("Param definition type = ", param_definition_type,
" not allowed in an audio element"));
switch (param_definition_type) {
case ParamDefinition::kParameterDefinitionDemixing:
case ParamDefinition::kParameterDefinitionReconGain:
RETURN_IF_NOT_OK(insert_and_check_equivalence(
audio_element_param.param_definition.get()));
break;
case ParamDefinition::kParameterDefinitionMixGain:
return absl::InvalidArgumentError(absl::StrCat(
"Mix gain parameters are not allowed in an audio element= ",
audio_element_id_for_debugging));
default:
LOG(WARNING) << "Ignoring parameter definition of type= "
<< param_definition_type << " in audio element= "
<< audio_element_id_for_debugging;
continue;
}
RETURN_IF_NOT_OK(insert_and_check_equivalence(
audio_element_param.param_definition.get()));
}
}

Expand Down
150 changes: 150 additions & 0 deletions iamf/cli/testdata/test_000121.textproto
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Copyright (c) 2024, Alliance for Open Media. All rights reserved
#
# This source code is subject to the terms of the BSD 3-Clause Clear License
# and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
# License was not distributed with this source code in the LICENSE file, you
# can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
# Alliance for Open Media Patent License 1.0 was not distributed with this
# source code in the PATENTS file, you can obtain it at
# www.aomedia.org/license/patent.

# proto-file: iamf/cli/proto/user_metadata.proto
# proto-message: UserMetadata

test_vector_metadata {
human_readable_description:
"A Simple profile IAMF stream which uses a reserved parameter type that "
"must be ignored."
file_name_prefix: "test_000121"
is_valid: true
validate_user_loudness: true
mp4_fixed_timestamp: "2024-07-17 00:00:00"
primary_tested_spec_sections: ["3.6/param_definition_type"]
base_test: "test_000005"
}

ia_sequence_header_metadata {
primary_profile: PROFILE_VERSION_SIMPLE
additional_profile: PROFILE_VERSION_SIMPLE
}

codec_config_metadata {
codec_config_id: 200
codec_config {
codec_id: CODEC_ID_LPCM
num_samples_per_frame: 64
audio_roll_distance: 0
decoder_config_lpcm {
sample_format_flags: LPCM_LITTLE_ENDIAN
sample_size: 16
sample_rate: 16000
}
}
}

audio_element_metadata {
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: 1
audio_element_params: {
param_definition_type: PARAM_DEFINITION_TYPE_RESERVED_3
param_definition_extension: {
param_definition_size: 7
param_definition_bytes: "ignored"
}
}
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
}
]
}
}

mix_presentation_metadata {
mix_presentation_id: 42
count_label: 1
language_labels: ["en-us"]
mix_presentation_annotations_array: [
{
mix_presentation_friendly_label: "test_mix_pres"
}
]
num_sub_mixes: 1
sub_mixes {
num_audio_elements: 1
audio_elements {
audio_element_id: 300
mix_presentation_element_annotations_array: [
{
audio_element_friendly_label: "test_sub_mix_0_audio_element_0"
}
]
rendering_config {
headphones_rendering_mode: HEADPHONES_RENDERING_MODE_STEREO
}
element_mix_config {
mix_gain {
param_definition {
parameter_id: 100
parameter_rate: 16000
param_definition_mode: 1
reserved: 0
}
default_mix_gain: 0
}
}
}
output_mix_config {
output_mix_gain {
param_definition {
parameter_id: 100
parameter_rate: 16000
param_definition_mode: 1
reserved: 0
}
default_mix_gain: 0
}
}
num_layouts: 1
layouts {
loudness_layout {
layout_type: LAYOUT_TYPE_LOUDSPEAKERS_SS_CONVENTION
ss_layout {
sound_system: SOUND_SYSTEM_A_0_2_0
reserved: 0
}
}
loudness {
info_type_bit_masks: []
integrated_loudness: -13733
digital_peak: -12879
}
}
}
}

audio_frame_metadata {
wav_filename: "sawtooth_100_stereo.wav"
samples_to_trim_at_end: 0
samples_to_trim_at_start: 0
audio_element_id: 300
channel_ids: [0, 1]
channel_labels: ["L2", "R2"]
}

temporal_delimiter_metadata {
enable_temporal_delimiters: false
}
63 changes: 57 additions & 6 deletions iamf/cli/tests/cli_util_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <cstddef>
#include <cstdint>
#include <list>
#include <memory>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -518,7 +519,8 @@ TEST(CopyObuHeader, MostValuesModified) {
(std::vector<uint8_t>{'e', 'x', 't', 'r', 'a'}));
}

TEST(CollectAndValidateParamDefinitions, IdenticalMixGain) {
TEST(CollectAndValidateParamDefinitions,
ReturnsOneUniqueParamDefinitionWhenTheyAreIdentical) {
// Initialize prerequisites.
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements = {};

Expand All @@ -544,7 +546,7 @@ TEST(CollectAndValidateParamDefinitions, IdenticalMixGain) {
}

TEST(CollectAndValidateParamDefinitions,
InvalidParametersWithSameIdHaveDifferentDefaultValues) {
IsInvalidWhenParamDefinitionsAreNotEquivalent) {
// Initialize prerequisites.
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements = {};

Expand All @@ -565,10 +567,59 @@ TEST(CollectAndValidateParamDefinitions,
output_mix_gain);

absl::flat_hash_map<DecodedUleb128, const ParamDefinition*> result;
EXPECT_EQ(CollectAndValidateParamDefinitions(audio_elements,
mix_presentation_obus, result)
.code(),
absl::StatusCode::kInvalidArgument);
EXPECT_FALSE(CollectAndValidateParamDefinitions(audio_elements,
mix_presentation_obus, result)
.ok());
}

TEST(CollectAndValidateParamDefinitions,
IsInvalidWhenMixGainParamDefinitionIsPresentInAudioElement) {
// Initialize prerequisites.
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> input_codec_configs;
AddOpusCodecConfigWithId(kCodecConfigId, input_codec_configs);
const std::list<MixPresentationObu> kNoMixPresentationObus = {};
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
AddAmbisonicsMonoAudioElementWithSubstreamIds(
kAudioElementId, kCodecConfigId, {kFirstSubstreamId}, input_codec_configs,
audio_elements);
auto& audio_element = audio_elements.at(kAudioElementId);
audio_element.obu.InitializeParams(1);
audio_element.obu.audio_element_params_[0] = AudioElementParam{
.param_definition_type = ParamDefinition::kParameterDefinitionMixGain,
.param_definition = std::make_unique<MixGainParamDefinition>()};

absl::flat_hash_map<DecodedUleb128, const ParamDefinition*> result;
EXPECT_FALSE(CollectAndValidateParamDefinitions(
audio_elements, kNoMixPresentationObus, result)
.ok());
}

TEST(CollectAndValidateParamDefinitions,
DoesNotCollectParamDefinitionsFromExtensionParamDefinitions) {
// Initialize prerequisites.
absl::flat_hash_map<DecodedUleb128, CodecConfigObu> input_codec_configs;
AddOpusCodecConfigWithId(kCodecConfigId, input_codec_configs);
const std::list<MixPresentationObu> kNoMixPresentationObus = {};
absl::flat_hash_map<DecodedUleb128, AudioElementWithData> audio_elements;
AddAmbisonicsMonoAudioElementWithSubstreamIds(
kAudioElementId, kCodecConfigId, {kFirstSubstreamId}, input_codec_configs,
audio_elements);

// Add an extension param definition to the audio element. It is not possible
// to determine the ID to store it or to use further processing.
auto& audio_element = audio_elements.at(kAudioElementId);
audio_element.obu.InitializeParams(1);
audio_element.obu.audio_element_params_[0] = AudioElementParam{
.param_definition_type =
ParamDefinition::kParameterDefinitionReservedStart,
.param_definition = std::make_unique<ExtendedParamDefinition>(
ParamDefinition::kParameterDefinitionReservedStart)};

absl::flat_hash_map<DecodedUleb128, const ParamDefinition*> result;
EXPECT_THAT(CollectAndValidateParamDefinitions(
audio_elements, kNoMixPresentationObus, result),
IsOk());
EXPECT_TRUE(result.empty());
}

TEST(GenerateParamIdToMetadataMapTest, MixGainParamDefinition) {
Expand Down

0 comments on commit 02d6318

Please sign in to comment.