`audio_element.proto`: Deprecate several num* fields.

  - Similar to the rationale of AOMediaCodec/iamf_tools@d6e92ac9 and AOMediaCodec/iamf_tools@@822154612.
  - The fields are useless and hold no real information and only make the proto more complicated.

PiperOrigin-RevId: 770193247
diff --git a/iamf/cli/proto/audio_element.proto b/iamf/cli/proto/audio_element.proto
index 9b29fa1..aaaeabe 100644
--- a/iamf/cli/proto/audio_element.proto
+++ b/iamf/cli/proto/audio_element.proto
@@ -24,7 +24,9 @@
 }
 
 message ParamDefinitionExtension {
-  uint32 param_definition_size = 1;
+  // `param_definition_size` is ignored. The value in the bitstream is inferred
+  // based on the size of `param_definition_bytes`.
+  uint32 param_definition_size = 1 [deprecated = true];
   bytes param_definition_bytes = 2;
 }
 
@@ -96,7 +98,9 @@
 }
 
 message ScalableChannelLayoutConfig {
-  uint32 num_layers = 1;
+  // `num_layers` is ignored. The value in the bitstream is inferred based on
+  // the number of `channel_audio_layer_configs`.
+  uint32 num_layers = 1 [deprecated = true];
   uint32 reserved = 2;
   repeated ChannelAudioLayerConfig channel_audio_layer_configs = 3;
 }
@@ -130,7 +134,9 @@
 }
 
 message AudioElementConfigExtension {
-  uint32 audio_element_config_size = 1;
+  // `audio_element_config_size` is ignored. The value in the bitstream is
+  // inferred based on the size of `audio_element_config_bytes`.
+  uint32 audio_element_config_size = 1 [deprecated = true];
   bytes audio_element_config_bytes = 2;
 }
 
@@ -139,9 +145,13 @@
   AudioElementType audio_element_type = 2;
   uint32 reserved = 3;
   uint32 codec_config_id = 4;
-  uint32 num_substreams = 5;
+  // `num_substreams` is ignored. The value in the bitstream is inferred based
+  // on the number of `audio_substream_ids`.
+  uint32 num_substreams = 5 [deprecated = true];
   repeated uint32 audio_substream_ids = 6;
-  uint32 num_parameters = 7;
+  // `num_parameters` is ignored. The value in the bitstream is inferred based
+  // on the number of `audio_element_params`.
+  uint32 num_parameters = 7 [deprecated = true];
   repeated AudioElementParam audio_element_params = 8;
 
   oneof config {
diff --git a/iamf/cli/proto_conversion/proto_to_obu/audio_element_generator.cc b/iamf/cli/proto_conversion/proto_to_obu/audio_element_generator.cc
index 37337c5..69c43be 100644
--- a/iamf/cli/proto_conversion/proto_to_obu/audio_element_generator.cc
+++ b/iamf/cli/proto_conversion/proto_to_obu/audio_element_generator.cc
@@ -88,42 +88,34 @@
   }
 }
 
-absl::Status GenerateAudioSubstreams(
+void GenerateAudioSubstreams(
     const iamf_tools_cli_proto::AudioElementObuMetadata& audio_element_metadata,
     AudioElementObu& audio_element_obu) {
-  if (audio_element_metadata.num_substreams() !=
-      audio_element_metadata.audio_substream_ids_size()) {
-    return InvalidArgumentError(
-        StrCat("User data has inconsistent `num_substreams` and "
-               "`audio_substream_ids`. User provided ",
-               audio_element_metadata.audio_substream_ids_size(),
-               " substreams in `audio_substream_ids`, and `num_substreams`= ",
-               audio_element_metadata.num_substreams()));
+  if (audio_element_metadata.has_num_substreams()) {
+    LOG(WARNING) << "Ignoring deprecated `num_substreams` field. "
+                    "Please remove it.";
   }
 
   audio_element_obu.InitializeAudioSubstreams(
-      audio_element_metadata.num_substreams());
-  for (int i = 0; i < audio_element_metadata.num_substreams(); ++i) {
+      audio_element_metadata.audio_substream_ids_size());
+  for (int i = 0; i < audio_element_metadata.audio_substream_ids_size(); ++i) {
     audio_element_obu.audio_substream_ids_[i] =
         audio_element_metadata.audio_substream_ids(i);
   }
-  return absl::OkStatus();
 }
 
 absl::Status GenerateParameterDefinitions(
     const iamf_tools_cli_proto::AudioElementObuMetadata& audio_element_metadata,
     const CodecConfigObu& codec_config_obu,
     AudioElementObu& audio_element_obu) {
-  if (audio_element_metadata.num_parameters() !=
-      audio_element_metadata.audio_element_params_size()) {
-    return InvalidArgumentError(StrCat(
-        "User data has inconsistent `num_parameters`. Found: ",
-        audio_element_metadata.audio_element_params_size(),
-        " parameters, expected: ", audio_element_metadata.num_parameters()));
+  if (audio_element_metadata.has_num_parameters()) {
+    LOG(WARNING) << "Ignoring deprecated `num_parameters` field. "
+                    "Please remove it.";
   }
 
-  audio_element_obu.InitializeParams(audio_element_metadata.num_parameters());
-  for (int i = 0; i < audio_element_metadata.num_parameters(); ++i) {
+  audio_element_obu.InitializeParams(
+      audio_element_metadata.audio_element_params_size());
+  for (int i = 0; i < audio_element_metadata.audio_element_params_size(); ++i) {
     const auto& user_data_parameter =
         audio_element_metadata.audio_element_params(i);
 
@@ -193,10 +185,14 @@
         ExtendedParamDefinition extended_param_definition(
             copied_param_definition_type);
         // Copy the extension bytes.
+        if (user_param_definition.has_param_definition_size()) {
+          LOG(WARNING) << "Ignoring deprecated `param_definition_size` field. "
+                          "Please remove it.";
+        }
         extended_param_definition.param_definition_size_ =
-            user_param_definition.param_definition_size();
+            user_param_definition.param_definition_bytes().size();
         extended_param_definition.param_definition_bytes_.resize(
-            user_param_definition.param_definition_size());
+            extended_param_definition.param_definition_size_);
         RETURN_IF_NOT_OK(StaticCastSpanIfInRange(
             "param_definition_bytes",
             absl::MakeConstSpan(user_param_definition.param_definition_bytes()),
@@ -360,15 +356,15 @@
 
   const auto& input_config =
       audio_element_metadata.scalable_channel_layout_config();
+  if (input_config.has_num_layers()) {
+    LOG(WARNING) << "Ignoring deprecated `num_layers` field. Please remove it.";
+  }
+
   RETURN_IF_NOT_OK(audio_element.obu.InitializeScalableChannelLayout(
-      input_config.num_layers(), input_config.reserved()));
+      input_config.channel_audio_layer_configs_size(),
+      input_config.reserved()));
   auto& config =
       std::get<ScalableChannelLayoutConfig>(audio_element.obu.config_);
-  if (config.num_layers != input_config.channel_audio_layer_configs_size()) {
-    return InvalidArgumentError(StrCat(
-        "Expected ", config.num_layers, " layers in the metadata. Found ",
-        input_config.channel_audio_layer_configs_size(), " layers."));
-  }
   for (int i = 0; i < config.num_layers; ++i) {
     ChannelAudioLayerConfig* const layer_config =
         &config.channel_audio_layer_configs[i];
@@ -597,8 +593,7 @@
         audio_element_id, audio_element_type, reserved, codec_config_id);
 
     // Audio Substreams.
-    RETURN_IF_NOT_OK(
-        GenerateAudioSubstreams(audio_element_metadata, audio_element_obu));
+    GenerateAudioSubstreams(audio_element_metadata, audio_element_obu);
 
     // Parameter definitions.
     if (!codec_configs.contains(audio_element_metadata.codec_config_id())) {
diff --git a/iamf/cli/proto_conversion/proto_to_obu/tests/BUILD b/iamf/cli/proto_conversion/proto_to_obu/tests/BUILD
index 6fd1b9e..6dc17c9 100644
--- a/iamf/cli/proto_conversion/proto_to_obu/tests/BUILD
+++ b/iamf/cli/proto_conversion/proto_to_obu/tests/BUILD
@@ -21,6 +21,7 @@
         "//iamf/cli:audio_element_with_data",
         "//iamf/cli:channel_label",
         "//iamf/cli/proto:audio_element_cc_proto",
+        "//iamf/cli/proto:param_definitions_cc_proto",
         "//iamf/cli/proto_conversion/proto_to_obu:audio_element_generator",
         "//iamf/cli/tests:cli_test_utils",
         "//iamf/obu:audio_element",
@@ -29,6 +30,7 @@
         "//iamf/obu:parameter_data",
         "//iamf/obu:types",
         "@com_google_absl//absl/container:flat_hash_map",
+        "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:status_matchers",
         "@com_google_googletest//:gtest_main",
         "@com_google_protobuf//:protobuf",
diff --git a/iamf/cli/proto_conversion/proto_to_obu/tests/audio_element_generator_test.cc b/iamf/cli/proto_conversion/proto_to_obu/tests/audio_element_generator_test.cc
index 1ad1be0..3a93b1c 100644
--- a/iamf/cli/proto_conversion/proto_to_obu/tests/audio_element_generator_test.cc
+++ b/iamf/cli/proto_conversion/proto_to_obu/tests/audio_element_generator_test.cc
@@ -17,12 +17,14 @@
 #include <vector>
 
 #include "absl/container/flat_hash_map.h"
+#include "absl/status/status.h"
 #include "absl/status/status_matchers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "iamf/cli/audio_element_with_data.h"
 #include "iamf/cli/channel_label.h"
 #include "iamf/cli/proto/audio_element.pb.h"
+#include "iamf/cli/proto/param_definitions.pb.h"
 #include "iamf/cli/tests/cli_test_utils.h"
 #include "iamf/obu/audio_element.h"
 #include "iamf/obu/codec_config.h"
@@ -48,6 +50,9 @@
 constexpr DecodedUleb128 kAudioElementId = 300;
 constexpr uint32_t kSampleRate = 48000;
 
+constexpr DecodedUleb128 kMonoSubstreamId = 99;
+constexpr DecodedUleb128 kL2SubstreamId = 100;
+
 const ScalableChannelLayoutConfig kOneLayerStereoConfig{
     .num_layers = 1,
     .channel_audio_layer_configs = {
@@ -69,6 +74,70 @@
       output_scalable_channel_layout_config);
 }
 
+void AddFirstOrderAmbisonicsMetadata(
+    AudioElementObuMetadatas& audio_element_metadatas) {
+  ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
+      R"pb(
+        audio_element_id: 300
+        audio_element_type: AUDIO_ELEMENT_SCENE_BASED
+        reserved: 0
+        codec_config_id: 200
+        num_substreams: 4
+        audio_substream_ids: [ 0, 1, 2, 3 ]
+        num_parameters: 0
+        ambisonics_config {
+          ambisonics_mode: AMBISONICS_MODE_MONO
+          ambisonics_mono_config {
+            output_channel_count: 4
+            substream_count: 4
+            channel_mapping: [ 0, 1, 2, 3 ]
+          }
+        }
+      )pb",
+      audio_element_metadatas.Add()));
+}
+
+void AddTwoLayerStereoMetadata(
+    AudioElementObuMetadatas& audio_element_metadatas) {
+  auto* new_audio_element_metadata = audio_element_metadatas.Add();
+  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: 2
+        num_parameters: 0
+        scalable_channel_layout_config {
+          num_layers: 2
+          reserved: 0
+          channel_audio_layer_configs {
+            loudspeaker_layout: LOUDSPEAKER_LAYOUT_MONO
+            output_gain_is_present_flag: 0
+            recon_gain_is_present_flag: 0
+            reserved_a: 0
+            substream_count: 1
+            coupled_substream_count: 0
+          }
+          channel_audio_layer_configs {
+            loudspeaker_layout: LOUDSPEAKER_LAYOUT_STEREO
+            output_gain_is_present_flag: 1
+            recon_gain_is_present_flag: 0
+            reserved_a: 0
+            substream_count: 1
+            coupled_substream_count: 0
+            output_gain_flag: 32
+            output_gain: 32767
+          }
+        }
+      )pb",
+      new_audio_element_metadata));
+  new_audio_element_metadata->mutable_audio_substream_ids()->Add(
+      kMonoSubstreamId);
+  new_audio_element_metadata->mutable_audio_substream_ids()->Add(
+      kL2SubstreamId);
+}
+
 TEST(Generate, PopulatesExpandedLoudspeakerLayout) {
   AudioElementObuMetadatas audio_element_metadatas;
   ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
@@ -230,26 +299,7 @@
 TEST_F(AudioElementGeneratorTest, NoAudioElementObus) { InitAndTestGenerate(); }
 
 TEST_F(AudioElementGeneratorTest, FirstOrderMonoAmbisonicsNumericalOrder) {
-  ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
-      R"pb(
-        audio_element_id: 300
-        audio_element_type: AUDIO_ELEMENT_SCENE_BASED
-        reserved: 0
-        codec_config_id: 200
-        num_substreams: 4
-        audio_substream_ids: [ 0, 1, 2, 3 ]
-        num_parameters: 0
-        ambisonics_config {
-          ambisonics_mode: AMBISONICS_MODE_MONO
-          ambisonics_mono_config {
-            output_channel_count: 4
-            substream_count: 4
-            channel_mapping: [ 0, 1, 2, 3 ]
-          }
-        }
-      )pb",
-      audio_element_metadata_.Add()));
-
+  AddFirstOrderAmbisonicsMetadata(audio_element_metadata_);
   AddAmbisonicsMonoAudioElementWithSubstreamIds(
       kAudioElementId, kCodecConfigId, {0, 1, 2, 3}, codec_config_obus_,
       expected_obus_);
@@ -461,44 +511,12 @@
 }
 
 TEST_F(AudioElementGeneratorTest, FillsAudioElementWithDataFields) {
-  const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{99, {kMono}},
-                                                             {100, {kL2}}};
+  const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
+      {kMonoSubstreamId, {kMono}}, {kL2SubstreamId, {kL2}}};
   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
       {.surround = 1, .lfe = 0, .height = 0},
       {.surround = 2, .lfe = 0, .height = 0}};
-  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: 2
-        audio_substream_ids: [ 99, 100 ]
-        num_parameters: 0
-        scalable_channel_layout_config {
-          num_layers: 2
-          reserved: 0
-          channel_audio_layer_configs {
-            loudspeaker_layout: LOUDSPEAKER_LAYOUT_MONO
-            output_gain_is_present_flag: 0
-            recon_gain_is_present_flag: 0
-            reserved_a: 0
-            substream_count: 1
-            coupled_substream_count: 0
-          }
-          channel_audio_layer_configs {
-            loudspeaker_layout: LOUDSPEAKER_LAYOUT_STEREO
-            output_gain_is_present_flag: 1
-            recon_gain_is_present_flag: 0
-            reserved_a: 0
-            substream_count: 1
-            coupled_substream_count: 0
-            output_gain_flag: 32
-            output_gain: 32767
-          }
-        }
-      )pb",
-      audio_element_metadata_.Add()));
+  AddTwoLayerStereoMetadata(audio_element_metadata_);
   AudioElementGenerator generator(audio_element_metadata_);
 
   EXPECT_THAT(generator.Generate(codec_config_obus_, output_obus_), IsOk());
@@ -748,5 +766,107 @@
             kExpectedAudioElementParam);
 }
 
+TEST_F(AudioElementGeneratorTest, IgnoresDeprecatedNumSubstreamsField) {
+  AddFirstOrderAmbisonicsMetadata(audio_element_metadata_);
+  auto& first_order_ambisonics_metadata = audio_element_metadata_.at(0);
+  // Normally first-order ambisonics has four substreams.
+  constexpr DecodedUleb128 kExpectedNumSubstreams = 4;
+  // Corrupt the `num_substreams` field.
+  const auto kIgnoredNumSubstreams = 9999;
+  first_order_ambisonics_metadata.set_num_substreams(kIgnoredNumSubstreams);
+  AudioElementGenerator generator(audio_element_metadata_);
+
+  EXPECT_THAT(generator.Generate(codec_config_obus_, output_obus_), IsOk());
+
+  // The field is deprecatred and ignored, the actual number of substreams are
+  // set based on the `audio_substream_ids` field.
+  ASSERT_TRUE(output_obus_.contains(kAudioElementId));
+  EXPECT_EQ(output_obus_.at(kAudioElementId).obu.audio_substream_ids_.size(),
+            kExpectedNumSubstreams);
+  EXPECT_EQ(output_obus_.at(kAudioElementId).obu.num_substreams_,
+            kExpectedNumSubstreams);
+}
+
+TEST_F(AudioElementGeneratorTest, IgnoresDeprecatedNumParametersField) {
+  AddFirstOrderAmbisonicsMetadata(audio_element_metadata_);
+  auto& first_order_ambisonics_metadata = audio_element_metadata_.at(0);
+  constexpr DecodedUleb128 kExpectedNumParameters = 0;
+  // Corrupt the `num_parameters` field.
+  const auto kIgnoredNumParameters = 9999;
+  first_order_ambisonics_metadata.set_num_parameters(kIgnoredNumParameters);
+  AudioElementGenerator generator(audio_element_metadata_);
+
+  EXPECT_THAT(generator.Generate(codec_config_obus_, output_obus_), IsOk());
+
+  // The field is deprecatred and ignored, the actual number of parameters are
+  // set based on the `audio_element_params` field.
+  ASSERT_TRUE(output_obus_.contains(kAudioElementId));
+  EXPECT_EQ(output_obus_.at(kAudioElementId).obu.num_parameters_,
+            kExpectedNumParameters);
+  EXPECT_EQ(output_obus_.at(kAudioElementId).obu.audio_element_params_.size(),
+            kExpectedNumParameters);
+}
+
+TEST_F(AudioElementGeneratorTest, IgnoresDeprecatedParamDefinitionSizeField) {
+  AddFirstOrderAmbisonicsMetadata(audio_element_metadata_);
+  auto& first_order_ambisonics_metadata = audio_element_metadata_.at(0);
+  auto* audio_element_param =
+      first_order_ambisonics_metadata.mutable_audio_element_params()->Add();
+  audio_element_param->set_param_definition_type(
+      iamf_tools_cli_proto::PARAM_DEFINITION_TYPE_RESERVED_3);
+  // Corrupt the `num_parameters` field.
+  constexpr absl::string_view kParamDefinitionBytes = "abc";
+  constexpr DecodedUleb128 kExpectedParamDefinitionSize =
+      kParamDefinitionBytes.size();
+  const auto kInconsistentParamDefinitionSize = 9999;
+  audio_element_param->mutable_param_definition_extension()
+      ->set_param_definition_size(kInconsistentParamDefinitionSize);
+  audio_element_param->mutable_param_definition_extension()
+      ->set_param_definition_bytes(kParamDefinitionBytes);
+  AudioElementGenerator generator(audio_element_metadata_);
+
+  EXPECT_THAT(generator.Generate(codec_config_obus_, output_obus_), IsOk());
+
+  // The field is deprecatred and ignored, the actual number of parameters are
+  // set based on the `param_definition_bytes` field.
+  ASSERT_TRUE(output_obus_.contains(kAudioElementId));
+  ASSERT_FALSE(
+      output_obus_.at(kAudioElementId).obu.audio_element_params_.empty());
+  const auto* extended_param_definition = std::get_if<ExtendedParamDefinition>(
+      &output_obus_.at(kAudioElementId)
+           .obu.audio_element_params_.front()
+           .param_definition);
+  ASSERT_NE(extended_param_definition, nullptr);
+  EXPECT_EQ(extended_param_definition->param_definition_size_,
+            kExpectedParamDefinitionSize);
+  EXPECT_EQ(extended_param_definition->param_definition_bytes_.size(),
+            kExpectedParamDefinitionSize);
+}
+
+TEST_F(AudioElementGeneratorTest, IgnoresDeprecatedNumLayers) {
+  AddTwoLayerStereoMetadata(audio_element_metadata_);
+  auto& first_order_ambisonics_metadata = audio_element_metadata_.at(0);
+  // Two layers are set in the metadata.
+  constexpr uint8_t kExpectedNumLayers = 2;
+  // Corrupt the `num_layers` field.
+  const auto kIgnoredNumLayers = 7;
+  first_order_ambisonics_metadata.mutable_scalable_channel_layout_config()
+      ->set_num_layers(kIgnoredNumLayers);
+  AudioElementGenerator generator(audio_element_metadata_);
+
+  EXPECT_THAT(generator.Generate(codec_config_obus_, output_obus_), IsOk());
+
+  // The corrupted value is ignored, and the actual number of parameters are set
+  // correctly.
+  ASSERT_TRUE(output_obus_.contains(kAudioElementId));
+  const auto* scalable_channel_layout_config =
+      std::get_if<ScalableChannelLayoutConfig>(
+          &output_obus_.at(kAudioElementId).obu.config_);
+  ASSERT_NE(scalable_channel_layout_config, nullptr);
+  EXPECT_EQ(scalable_channel_layout_config->num_layers, kExpectedNumLayers);
+  EXPECT_EQ(scalable_channel_layout_config->channel_audio_layer_configs.size(),
+            kExpectedNumLayers);
+}
+
 }  // namespace
 }  // namespace iamf_tools