• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 3-Clause Clear License
5  * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6  * License was not distributed with this source code in the LICENSE file, you
7  * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8  * Alliance for Open Media Patent License 1.0 was not distributed with this
9  * source code in the PATENTS file, you can obtain it at
10  * www.aomedia.org/license/patent.
11  */
12 
13 #include "iamf/cli/obu_with_data_generator.h"
14 
15 #include <array>
16 #include <cstdint>
17 #include <limits>
18 #include <list>
19 #include <memory>
20 #include <optional>
21 #include <utility>
22 #include <variant>
23 #include <vector>
24 
25 #include "absl/container/flat_hash_map.h"
26 #include "absl/container/node_hash_map.h"
27 #include "absl/status/status_matchers.h"
28 #include "absl/status/statusor.h"
29 #include "gmock/gmock.h"
30 #include "gtest/gtest.h"
31 #include "iamf/cli/audio_element_with_data.h"
32 #include "iamf/cli/audio_frame_with_data.h"
33 #include "iamf/cli/channel_label.h"
34 #include "iamf/cli/global_timing_module.h"
35 #include "iamf/cli/parameter_block_with_data.h"
36 #include "iamf/cli/parameters_manager.h"
37 #include "iamf/cli/tests/cli_test_utils.h"
38 #include "iamf/obu/audio_element.h"
39 #include "iamf/obu/audio_frame.h"
40 #include "iamf/obu/codec_config.h"
41 #include "iamf/obu/demixing_info_parameter_data.h"
42 #include "iamf/obu/demixing_param_definition.h"
43 #include "iamf/obu/obu_header.h"
44 #include "iamf/obu/param_definition_variant.h"
45 #include "iamf/obu/param_definitions.h"
46 #include "iamf/obu/parameter_block.h"
47 #include "iamf/obu/recon_gain_info_parameter_data.h"
48 #include "iamf/obu/types.h"
49 
50 namespace iamf_tools {
51 namespace {
52 
53 using ::absl_testing::IsOk;
54 using ::testing::ElementsAreArray;
55 using ::testing::NotNull;
56 
57 using enum ChannelLabel::Label;
58 
59 constexpr DecodedUleb128 kFirstAudioElementId = DecodedUleb128(1);
60 constexpr DecodedUleb128 kSecondAudioElementId = DecodedUleb128(2);
61 constexpr DecodedUleb128 kFirstCodecConfigId = DecodedUleb128(11);
62 constexpr DecodedUleb128 kSecondCodecConfigId = DecodedUleb128(12);
63 constexpr DecodedUleb128 kFirstSubstreamId = DecodedUleb128(21);
64 constexpr DecodedUleb128 kSecondSubstreamId = DecodedUleb128(22);
65 constexpr DecodedUleb128 kFirstParameterId = DecodedUleb128(31);
66 constexpr DecodedUleb128 kSecondParameterId = DecodedUleb128(32);
67 constexpr std::array<uint8_t, 12> kFirstReconGainValues = {
68     255, 0, 125, 200, 150, 255, 255, 255, 255, 255, 255, 255};
69 constexpr std::array<uint8_t, 12> kSecondReconGainValues = {
70     0, 1, 2, 3, 4, 255, 255, 255, 255, 255, 255, 255};
71 
72 // Based on `output_gain_flags` in
73 // https://aomediacodec.github.io/iamf/#syntax-scalable-channel-layout-config.
74 constexpr uint8_t kApplyOutputGainToLeftChannel = 0x20;
75 
76 const ScalableChannelLayoutConfig kOneLayerStereoConfig{
77     .num_layers = 1,
78     .channel_audio_layer_configs = {
79         {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
80          .output_gain_is_present_flag = false,
81          .substream_count = 1,
82          .coupled_substream_count = 1}}};
83 
84 constexpr int32_t kStartTimestamp = 0;
85 constexpr int32_t kEndTimestamp = 8;
86 constexpr int32_t kDuration = 8;
87 
TEST(GenerateAudioElementWithData,ValidAudioElementWithCodecConfig)88 TEST(GenerateAudioElementWithData, ValidAudioElementWithCodecConfig) {
89   absl::flat_hash_map<DecodedUleb128, AudioElementObu> audio_element_obus;
90   audio_element_obus.emplace(
91       kFirstAudioElementId,
92       AudioElementObu(
93           ObuHeader(), kFirstAudioElementId,
94           AudioElementObu::AudioElementType::kAudioElementChannelBased,
95           /*reserved=*/0, kFirstCodecConfigId));
96   absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
97   codec_config_obus.emplace(
98       kFirstCodecConfigId,
99       CodecConfigObu(ObuHeader(), kFirstCodecConfigId, CodecConfig()));
100   absl::StatusOr<absl::flat_hash_map<DecodedUleb128, AudioElementWithData>>
101       audio_element_with_data_map =
102           ObuWithDataGenerator::GenerateAudioElementsWithData(
103               codec_config_obus, audio_element_obus);
104   EXPECT_THAT(audio_element_with_data_map, IsOk());
105   EXPECT_EQ((*audio_element_with_data_map).size(), 1);
106 
107   auto iter = codec_config_obus.find(kFirstCodecConfigId);
108   const CodecConfigObu* expected_codec_config_obu = &iter->second;
109   absl::flat_hash_map<DecodedUleb128, AudioElementWithData>
110       expected_audio_element_with_data_map;
111   expected_audio_element_with_data_map.emplace(
112       kFirstAudioElementId,
113       AudioElementWithData{
114           .obu = AudioElementObu(
115               ObuHeader(), kFirstAudioElementId,
116               AudioElementObu::AudioElementType::kAudioElementChannelBased,
117               /*reserved=*/0, kFirstCodecConfigId),
118           .codec_config = expected_codec_config_obu,
119           .substream_id_to_labels = {},
120           .label_to_output_gain = {},
121           .channel_numbers_for_layers = {}});
122   EXPECT_EQ(expected_audio_element_with_data_map,
123             audio_element_with_data_map.value());
124 }
125 
TEST(GenerateAudioElementWithData,MultipleAudioElementsWithOneCodecConfig)126 TEST(GenerateAudioElementWithData, MultipleAudioElementsWithOneCodecConfig) {
127   absl::flat_hash_map<DecodedUleb128, AudioElementObu> audio_element_obus;
128   audio_element_obus.emplace(
129       kFirstAudioElementId,
130       AudioElementObu(
131           ObuHeader(), kFirstAudioElementId,
132           AudioElementObu::AudioElementType::kAudioElementChannelBased,
133           /*reserved=*/0, kFirstCodecConfigId));
134   audio_element_obus.emplace(
135       kSecondAudioElementId,
136       AudioElementObu(
137           ObuHeader(), kSecondAudioElementId,
138           AudioElementObu::AudioElementType::kAudioElementChannelBased,
139           /*reserved=*/0, kFirstCodecConfigId));
140   absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
141   codec_config_obus.emplace(
142       kFirstCodecConfigId,
143       CodecConfigObu(ObuHeader(), kFirstCodecConfigId, CodecConfig()));
144   absl::StatusOr<absl::flat_hash_map<DecodedUleb128, AudioElementWithData>>
145       audio_element_with_data_map =
146           ObuWithDataGenerator::GenerateAudioElementsWithData(
147               codec_config_obus, audio_element_obus);
148   EXPECT_THAT(audio_element_with_data_map, IsOk());
149   EXPECT_EQ((*audio_element_with_data_map).size(), 2);
150 
151   auto iter = codec_config_obus.find(kFirstCodecConfigId);
152   const CodecConfigObu* expected_codec_config_obu = &iter->second;
153   absl::flat_hash_map<DecodedUleb128, AudioElementWithData>
154       expected_audio_element_with_data_map;
155   expected_audio_element_with_data_map.emplace(
156       kFirstAudioElementId,
157       AudioElementWithData{
158           .obu = AudioElementObu(
159               ObuHeader(), kFirstAudioElementId,
160               AudioElementObu::AudioElementType::kAudioElementChannelBased,
161               /*reserved=*/0, kFirstCodecConfigId),
162           .codec_config = expected_codec_config_obu,
163           .substream_id_to_labels{},
164           .label_to_output_gain{},
165           .channel_numbers_for_layers{}});
166   expected_audio_element_with_data_map.emplace(
167       kSecondAudioElementId,
168       AudioElementWithData{
169           .obu = AudioElementObu(
170               ObuHeader(), kSecondAudioElementId,
171               AudioElementObu::AudioElementType::kAudioElementChannelBased,
172               /*reserved=*/0, kFirstCodecConfigId),
173           .codec_config = expected_codec_config_obu,
174           .substream_id_to_labels = {},
175           .label_to_output_gain = {},
176           .channel_numbers_for_layers = {}});
177   EXPECT_EQ(expected_audio_element_with_data_map,
178             audio_element_with_data_map.value());
179 }
180 
TEST(GenerateAudioElementWithData,InvalidCodecConfigId)181 TEST(GenerateAudioElementWithData, InvalidCodecConfigId) {
182   absl::flat_hash_map<DecodedUleb128, AudioElementObu> audio_element_obus;
183   audio_element_obus.emplace(
184       kFirstAudioElementId,
185       AudioElementObu(
186           ObuHeader(), kFirstAudioElementId,
187           AudioElementObu::AudioElementType::kAudioElementChannelBased,
188           /*reserved=*/0, kSecondCodecConfigId));
189   absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
190   codec_config_obus.emplace(
191       kFirstCodecConfigId,
192       CodecConfigObu(ObuHeader(), kFirstCodecConfigId, CodecConfig()));
193   absl::StatusOr<absl::flat_hash_map<DecodedUleb128, AudioElementWithData>>
194       audio_element_with_data_map =
195           ObuWithDataGenerator::GenerateAudioElementsWithData(
196               codec_config_obus, audio_element_obus);
197   EXPECT_FALSE(audio_element_with_data_map.ok());
198 }
199 
200 // TODO(b/377772983): `ObuWithDataGenerator::GenerateAudioFrameWithData()` works
201 //                    on individual frames and may not have the knowledge of
202 //                    the "global state" of the whole bitstream. So any test
203 //                    that tests the global state should be moved to the user
204 //                    of the function, namely `ObuProcessor`.
205 class GenerateAudioFrameWithDataTest : public testing::Test {
206  public:
207   // Used to compare down mixing params.
208   struct AlphaBetaGammaDelta {
209     const double alpha;
210     const double beta;
211     const double gamma;
212     const double delta;
213   };
214 
GenerateAudioFrameWithDataTest()215   GenerateAudioFrameWithDataTest()
216       : kObuHeader{.obu_type = kObuIaAudioFrame,
217                    .num_samples_to_trim_at_end = 1,
218                    .num_samples_to_trim_at_start = 1},
219         kAudioFrameData{1, 2, 3},
220         kFirstSubstreamAudioFrameObu(kObuHeader, kFirstSubstreamId,
221                                      kAudioFrameData),
222         kSecondSubstreamAudioFrameObu(kObuHeader, kSecondSubstreamId,
223                                       kAudioFrameData) {}
224 
225  protected:
SetUpObus(const std::vector<DecodedUleb128> & substream_ids,const std::vector<AudioFrameObu> & audio_frame_obus_per_substream,int num_frames_per_substream)226   void SetUpObus(
227       const std::vector<DecodedUleb128>& substream_ids,
228       const std::vector<AudioFrameObu>& audio_frame_obus_per_substream,
229       int num_frames_per_substream) {
230     AddOpusCodecConfigWithId(kFirstCodecConfigId, codec_config_obus_);
231     AddAmbisonicsMonoAudioElementWithSubstreamIds(
232         kFirstAudioElementId, kFirstCodecConfigId, substream_ids,
233         codec_config_obus_, audio_elements_with_data_);
234 
235     ASSERT_EQ(substream_ids.size(), audio_frame_obus_per_substream.size());
236     for (int j = 0; j < num_frames_per_substream; j++) {
237       for (int i = 0; i < substream_ids.size(); i++) {
238         audio_frame_obus_.push_back(audio_frame_obus_per_substream[i]);
239       }
240     }
241   }
242 
AddDemixingAudioParam(DemixingInfoParameterData::DMixPMode dmixp_mode,DecodedUleb128 parameter_id)243   void AddDemixingAudioParam(DemixingInfoParameterData::DMixPMode dmixp_mode,
244                              DecodedUleb128 parameter_id) {
245     DemixingParamDefinition param_definition;
246     FillCommonParamDefinition(parameter_id, param_definition);
247 
248     param_definition.default_demixing_info_parameter_data_.dmixp_mode =
249         dmixp_mode;
250     param_definition.default_demixing_info_parameter_data_.default_w = 0;
251     AudioElementParam param = {.param_definition = param_definition};
252     AddAudioParam(parameter_id, param_definition, std::move(param));
253   }
254 
AddReconGainAudioParam(DecodedUleb128 parameter_id)255   void AddReconGainAudioParam(DecodedUleb128 parameter_id) {
256     ReconGainParamDefinition param_definition =
257         ReconGainParamDefinition(kFirstAudioElementId);
258     FillCommonParamDefinition(parameter_id, param_definition);
259 
260     AudioElementParam param = {.param_definition = param_definition};
261     AddAudioParam(parameter_id, param_definition, std::move(param));
262   }
263 
SetUpModules()264   void SetUpModules() {
265     // Set up the global timing module.
266     global_timing_module_ = GlobalTimingModule::Create(
267         audio_elements_with_data_, param_definition_variants_);
268     ASSERT_THAT(global_timing_module_, NotNull());
269 
270     // Set up the parameters manager.
271     parameters_manager_ =
272         std::make_unique<ParametersManager>(audio_elements_with_data_);
273     ASSERT_THAT(parameters_manager_->Initialize(), IsOk());
274   }
275 
SetUpParameterBlockWithData(const std::optional<DecodedUleb128> & recon_gain_parameter_id,const std::vector<std::array<uint8_t,12>> & recon_gain_values_vector,const std::optional<DecodedUleb128> & demixing_parameter_id,const std::vector<DemixingInfoParameterData::DMixPMode> & dmixp_mode_vector)276   void SetUpParameterBlockWithData(
277       const std::optional<DecodedUleb128>& recon_gain_parameter_id,
278       const std::vector<std::array<uint8_t, 12>>& recon_gain_values_vector,
279       const std::optional<DecodedUleb128>& demixing_parameter_id,
280       const std::vector<DemixingInfoParameterData::DMixPMode>&
281           dmixp_mode_vector) {
282     std::list<std::unique_ptr<ParameterBlockObu>> parameter_block_obus;
283     const int num_ids = (recon_gain_parameter_id.has_value() ? 1 : 0) +
284                         (demixing_parameter_id.has_value() ? 1 : 0);
285 
286     // Add parameter block OBUs in temporal order.
287     for (int i = 0;
288          i < recon_gain_values_vector.size() || i < dmixp_mode_vector.size();
289          i++) {
290       if (recon_gain_parameter_id.has_value()) {
291         parameter_block_obus.push_back(std::make_unique<ParameterBlockObu>(
292             ObuHeader(), *recon_gain_parameter_id,
293             std::get<ReconGainParamDefinition>(
294                 param_definition_variants_.at(*recon_gain_parameter_id))));
295         EXPECT_THAT(parameter_block_obus.back()->InitializeSubblocks(), IsOk());
296 
297         // Data specific to recon gain parameter blocks.
298         auto recon_gain_info_parameter_data =
299             std::make_unique<ReconGainInfoParameterData>();
300         recon_gain_info_parameter_data->recon_gain_elements.push_back(
301             ReconGainElement{.recon_gain_flag = DecodedUleb128(1),
302                              .recon_gain = recon_gain_values_vector[i]});
303         parameter_block_obus.back()->subblocks_[0].param_data =
304             std::move(recon_gain_info_parameter_data);
305       }
306       if (demixing_parameter_id.has_value()) {
307         parameter_block_obus.push_back(std::make_unique<ParameterBlockObu>(
308             ObuHeader(), *demixing_parameter_id,
309             std::get<DemixingParamDefinition>(
310                 param_definition_variants_.at(*demixing_parameter_id))));
311         EXPECT_THAT(parameter_block_obus.back()->InitializeSubblocks(), IsOk());
312 
313         // Data specific to demixing parameter blocks.
314         auto demixing_parameter_data =
315             std::make_unique<DemixingInfoParameterData>();
316         demixing_parameter_data->dmixp_mode = dmixp_mode_vector[i];
317         demixing_parameter_data->reserved = 0;
318         parameter_block_obus.back()->subblocks_[0].param_data =
319             std::move(demixing_parameter_data);
320       }
321     }
322 
323     // Call `GenerateParameterBlockWithData()` iteratively with one OBU at a
324     // time.
325     absl::flat_hash_map<DecodedUleb128, int32_t>
326         parameter_id_to_last_end_timestamp;
327     absl::flat_hash_map<DecodedUleb128, int> parameter_blocks_count;
328     for (auto& parameter_block_obu : parameter_block_obus) {
329       const auto& parameter_id = parameter_block_obu->parameter_id_;
330       auto [last_end_timestamp_iter, unused_inserted] =
331           parameter_id_to_last_end_timestamp.insert(
332               {parameter_id, kStartTimestamp});
333       auto parameter_block_with_data =
334           ObuWithDataGenerator::GenerateParameterBlockWithData(
335               last_end_timestamp_iter->second, *global_timing_module_,
336               std::move(parameter_block_obu));
337       ASSERT_THAT(parameter_block_with_data, IsOk());
338       last_end_timestamp_iter->second =
339           parameter_block_with_data->end_timestamp;
340       parameter_blocks_with_data_.push_back(
341           std::move(*parameter_block_with_data));
342       parameter_blocks_count[parameter_id]++;
343     }
344 
345     ASSERT_EQ(parameter_blocks_count.size(), num_ids);
346     if (recon_gain_parameter_id.has_value()) {
347       auto iter = parameter_blocks_count.find(*recon_gain_parameter_id);
348       ASSERT_NE(iter, parameter_blocks_count.end());
349       ASSERT_EQ(iter->second, recon_gain_values_vector.size());
350     }
351     if (demixing_parameter_id.has_value()) {
352       auto iter = parameter_blocks_count.find(*demixing_parameter_id);
353       ASSERT_NE(iter, parameter_blocks_count.end());
354       ASSERT_EQ(iter->second, dmixp_mode_vector.size());
355     }
356   }
357 
358   // Add parameter blocks with data belonging to the same temporal unit to
359   // the parameters manager.
AddCurrentParameterBlocksToParametersManager(std::list<ParameterBlockWithData>::iterator & parameter_block_iter)360   void AddCurrentParameterBlocksToParametersManager(
361       std::list<ParameterBlockWithData>::iterator& parameter_block_iter) {
362     std::optional<int32_t> global_timestamp = std::nullopt;
363     ASSERT_THAT(
364         global_timing_module_->GetGlobalAudioFrameTimestamp(global_timestamp),
365         IsOk());
366     for (; parameter_block_iter != parameter_blocks_with_data_.end();
367          parameter_block_iter++) {
368       const auto& parameter_block = *parameter_block_iter;
369       if (!global_timestamp.has_value() ||
370           parameter_block.start_timestamp != *global_timestamp) {
371         return;
372       }
373       auto param_definition_type = std::visit(
374           [](const auto& param_definition) {
375             return param_definition.GetType();
376           },
377           param_definition_variants_.at(parameter_block.obu->parameter_id_));
378       if (param_definition_type ==
379           ParamDefinition::kParameterDefinitionDemixing) {
380         parameters_manager_->AddDemixingParameterBlock(&parameter_block);
381       } else if (param_definition_type ==
382                  ParamDefinition::kParameterDefinitionReconGain) {
383         parameters_manager_->AddReconGainParameterBlock(&parameter_block);
384       }
385     }
386   }
387 
UpdateParameterStatesIfNeeded()388   void UpdateParameterStatesIfNeeded() {
389     std::optional<int32_t> global_timestamp = std::nullopt;
390     EXPECT_THAT(
391         global_timing_module_->GetGlobalAudioFrameTimestamp(global_timestamp),
392         IsOk());
393     if (!global_timestamp.has_value()) {
394       return;
395     }
396     EXPECT_THAT(parameters_manager_->UpdateDemixingState(kFirstAudioElementId,
397                                                          *global_timestamp),
398                 IsOk());
399     EXPECT_THAT(parameters_manager_->UpdateReconGainState(kFirstAudioElementId,
400                                                           *global_timestamp),
401                 IsOk());
402   }
403 
ValidateAudioFrameWithData(const AudioFrameWithData & audio_frame_with_data,const AudioFrameObu & expected_audio_frame_obu,int32_t expected_start_timestamp,int32_t expected_end_timestamp,DecodedUleb128 audio_element_id)404   void ValidateAudioFrameWithData(
405       const AudioFrameWithData& audio_frame_with_data,
406       const AudioFrameObu& expected_audio_frame_obu,
407       int32_t expected_start_timestamp, int32_t expected_end_timestamp,
408       DecodedUleb128 audio_element_id) {
409     EXPECT_EQ(audio_frame_with_data.obu, expected_audio_frame_obu);
410     EXPECT_EQ(audio_frame_with_data.start_timestamp, expected_start_timestamp);
411     EXPECT_EQ(audio_frame_with_data.end_timestamp, expected_end_timestamp);
412     EXPECT_FALSE(audio_frame_with_data.pcm_samples.has_value());
413     EXPECT_EQ(audio_frame_with_data.audio_element_with_data,
414               &audio_elements_with_data_.at(audio_element_id));
415   }
416 
ValidateDownMimxingParams(const DownMixingParams & down_mixing_params,const AlphaBetaGammaDelta & expected_params)417   void ValidateDownMimxingParams(const DownMixingParams& down_mixing_params,
418                                  const AlphaBetaGammaDelta& expected_params) {
419     EXPECT_TRUE(down_mixing_params.in_bitstream);
420     EXPECT_FLOAT_EQ(down_mixing_params.alpha, expected_params.alpha);
421     EXPECT_FLOAT_EQ(down_mixing_params.beta, expected_params.beta);
422     EXPECT_FLOAT_EQ(down_mixing_params.gamma, expected_params.gamma);
423     EXPECT_FLOAT_EQ(down_mixing_params.delta, expected_params.delta);
424   }
425 
ValidateReconGainParameters(const ReconGainInfoParameterData & recon_gain_info_parameter_data,const std::array<uint8_t,12> & expected_recon_gain_values)426   void ValidateReconGainParameters(
427       const ReconGainInfoParameterData& recon_gain_info_parameter_data,
428       const std::array<uint8_t, 12>& expected_recon_gain_values) {
429     EXPECT_EQ(recon_gain_info_parameter_data.recon_gain_elements.size(), 1);
430     const auto& recon_gain_element =
431         recon_gain_info_parameter_data.recon_gain_elements[0];
432     ASSERT_TRUE(recon_gain_element.has_value());
433     EXPECT_EQ(recon_gain_element->recon_gain_flag, DecodedUleb128(1));
434     EXPECT_THAT(recon_gain_element->recon_gain,
435                 ElementsAreArray(expected_recon_gain_values));
436   }
437 
438   const ObuHeader kObuHeader;
439   const std::vector<uint8_t> kAudioFrameData;
440   const AudioFrameObu kFirstSubstreamAudioFrameObu;
441   const AudioFrameObu kSecondSubstreamAudioFrameObu;
442   absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus_;
443   absl::flat_hash_map<DecodedUleb128, AudioElementWithData>
444       audio_elements_with_data_;
445 
446   std::list<AudioFrameObu> audio_frame_obus_;
447   absl::flat_hash_map<DecodedUleb128, ParamDefinitionVariant>
448       param_definition_variants_;
449   std::list<ParameterBlockWithData> parameter_blocks_with_data_;
450   std::unique_ptr<GlobalTimingModule> global_timing_module_;
451   std::unique_ptr<ParametersManager> parameters_manager_;
452 
453  private:
FillCommonParamDefinition(DecodedUleb128 parameter_id,ParamDefinition & param_definition)454   void FillCommonParamDefinition(DecodedUleb128 parameter_id,
455                                  ParamDefinition& param_definition) {
456     param_definition.parameter_id_ = parameter_id;
457     param_definition.param_definition_mode_ = 0;
458     param_definition.duration_ = 8;
459     param_definition.parameter_rate_ = 1;
460     param_definition.InitializeSubblockDurations(1);
461   }
462 
AddAudioParam(DecodedUleb128 parameter_id,const ParamDefinitionVariant & param_definition_variant,AudioElementParam && param)463   void AddAudioParam(DecodedUleb128 parameter_id,
464                      const ParamDefinitionVariant& param_definition_variant,
465                      AudioElementParam&& param) {
466     auto& audio_element_obu =
467         audio_elements_with_data_.at(kFirstAudioElementId).obu;
468     audio_element_obu.num_parameters_++;
469     audio_element_obu.audio_element_params_.push_back(std::move(param));
470     param_definition_variants_.emplace(parameter_id, param_definition_variant);
471   }
472 };
473 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFrame)474 TEST_F(GenerateAudioFrameWithDataTest, ValidAudioFrame) {
475   // Set up inputs.
476   SetUpObus({kFirstSubstreamId}, {kFirstSubstreamAudioFrameObu}, 1);
477   SetUpModules();
478 
479   // Call `GenerateAudioFrameWithData()`.
480   std::list<AudioFrameWithData> audio_frames_with_data;
481   for (const auto& audio_frame_obu : audio_frame_obus_) {
482     auto audio_frame_with_data =
483         ObuWithDataGenerator::GenerateAudioFrameWithData(
484             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
485             *global_timing_module_, *parameters_manager_);
486     ASSERT_THAT(audio_frame_with_data, IsOk());
487     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
488   }
489 
490   // Expectations.
491   const auto& first_audio_frame_with_data = audio_frames_with_data.front();
492   ValidateAudioFrameWithData(first_audio_frame_with_data,
493                              kFirstSubstreamAudioFrameObu, kStartTimestamp,
494                              kEndTimestamp, kFirstAudioElementId);
495 
496   // The audio element has no down mixing params. IAMF provides no guidance when
497   // they are not present, but make sure they are sane in case they are used.
498   // Check they generally near the range of pre-defined `dmixp_mode`s from
499   // IAMF v1.1.0.
500   EXPECT_FALSE(first_audio_frame_with_data.down_mixing_params.in_bitstream);
501   EXPECT_GE(first_audio_frame_with_data.down_mixing_params.alpha, 0.5);
502   EXPECT_LE(first_audio_frame_with_data.down_mixing_params.alpha, 1.0);
503   EXPECT_GE(first_audio_frame_with_data.down_mixing_params.beta, 0.5);
504   EXPECT_LE(first_audio_frame_with_data.down_mixing_params.beta, 1.0);
505   EXPECT_GE(first_audio_frame_with_data.down_mixing_params.gamma, 0.5);
506   EXPECT_LE(first_audio_frame_with_data.down_mixing_params.gamma, 1.0);
507   EXPECT_GE(first_audio_frame_with_data.down_mixing_params.delta, 0.5);
508   EXPECT_LE(first_audio_frame_with_data.down_mixing_params.delta, 1.0);
509 }
510 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFrameWithParamDefinitionDownMixingParams)511 TEST_F(GenerateAudioFrameWithDataTest,
512        ValidAudioFrameWithParamDefinitionDownMixingParams) {
513   // Set up inputs.
514   SetUpObus({kFirstSubstreamId}, {kFirstSubstreamAudioFrameObu}, 1);
515   AddDemixingAudioParam(DemixingInfoParameterData::kDMixPMode2,
516                         kFirstParameterId);
517   SetUpModules();
518 
519   // Call `GenerateAudioFrameWithData()`.
520   std::list<AudioFrameWithData> audio_frames_with_data;
521   for (const auto& audio_frame_obu : audio_frame_obus_) {
522     auto audio_frame_with_data =
523         ObuWithDataGenerator::GenerateAudioFrameWithData(
524             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
525             *global_timing_module_, *parameters_manager_);
526     EXPECT_THAT(audio_frame_with_data, IsOk());
527     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
528   }
529 
530   // Expectations.
531   const auto& first_audio_frame_with_data = audio_frames_with_data.front();
532   ValidateAudioFrameWithData(first_audio_frame_with_data,
533                              kFirstSubstreamAudioFrameObu, kStartTimestamp,
534                              kEndTimestamp, kFirstAudioElementId);
535   ValidateDownMimxingParams(first_audio_frame_with_data.down_mixing_params,
536                             {0.707, 0.707, 0.707, 0.707});
537 }
538 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFramesWithMultipleParameterBlockDownMixingParams)539 TEST_F(GenerateAudioFrameWithDataTest,
540        ValidAudioFramesWithMultipleParameterBlockDownMixingParams) {
541   // 1 audio element with 1 substream and 2 audio frames, as there are 2
542   // temporal units. The audio element had 1 param definition for demixing
543   // params. There are 2 parameter blocks, one for each temporal unit. We
544   // should generate 2 `AudioFramesWithData`, since there are 2 temporal units.
545 
546   // Set up inputs.
547   SetUpObus({kFirstSubstreamId}, {kFirstSubstreamAudioFrameObu}, 2);
548   AddDemixingAudioParam(DemixingInfoParameterData::kDMixPMode1,
549                         kFirstParameterId);
550   SetUpModules();
551   SetUpParameterBlockWithData(
552       /*recon_gain_parameter_id=*/std::nullopt,
553       /*recon_gain_values_vector=*/{},
554       /*demixing_parameter_id=*/kFirstParameterId,
555       /*dmixp_mode_vector=*/
556       {DemixingInfoParameterData::kDMixPMode2,
557        DemixingInfoParameterData::kDMixPMode3});
558 
559   // Call `GenerateAudioFrameWithData()`.
560   std::list<AudioFrameWithData> audio_frames_with_data;
561   auto parameter_block_iter = parameter_blocks_with_data_.begin();
562   for (const auto& audio_frame_obu : audio_frame_obus_) {
563     AddCurrentParameterBlocksToParametersManager(parameter_block_iter);
564     auto audio_frame_with_data =
565         ObuWithDataGenerator::GenerateAudioFrameWithData(
566             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
567             *global_timing_module_, *parameters_manager_);
568     EXPECT_THAT(audio_frame_with_data, IsOk());
569     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
570     UpdateParameterStatesIfNeeded();
571   }
572 
573   // Expectations.
574   EXPECT_EQ(audio_frames_with_data.size(), 2);
575   int32_t expected_start_timestamp = kStartTimestamp;
576   int32_t expected_end_timestamp = kEndTimestamp;
577   const std::vector<AlphaBetaGammaDelta> expected_alpha_beta_gamma_delta{
578       AlphaBetaGammaDelta{0.707, 0.707, 0.707, 0.707},  // `kDMixPMode2`.
579       AlphaBetaGammaDelta{1.0, 0.866, 0.866, 0.866}     // `kDMixPMode3`.
580   };
581   int frame_index = 0;
582   for (const auto& audio_frame_with_data : audio_frames_with_data) {
583     ValidateAudioFrameWithData(
584         audio_frame_with_data, kFirstSubstreamAudioFrameObu,
585         expected_start_timestamp, expected_end_timestamp, kFirstAudioElementId);
586     ValidateDownMimxingParams(audio_frame_with_data.down_mixing_params,
587                               expected_alpha_beta_gamma_delta[frame_index++]);
588     expected_start_timestamp += 8;
589     expected_end_timestamp += 8;
590   }
591 }
592 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFramesInMultipleSubstreamsWithSameDownMixingParams)593 TEST_F(GenerateAudioFrameWithDataTest,
594        ValidAudioFramesInMultipleSubstreamsWithSameDownMixingParams) {
595   // Multiple substreams should be in the same audio element.
596   // That same audio element should have one param definition with the down
597   // mixing param id. We should have 2 audio frames in each substream. This is
598   // a total of 4 audio frames.
599   // We will have 1 parameter block for each time stamp. This is a total of 2
600   // parameter blocks. The same parameter block at a given timestamp should be
601   // used for both substreams. This is a total of 2 temporal units.
602 
603   // Set up inputs.
604   SetUpObus({kFirstSubstreamId, kSecondSubstreamId},
605             {kFirstSubstreamAudioFrameObu, kSecondSubstreamAudioFrameObu}, 2);
606   AddDemixingAudioParam(DemixingInfoParameterData::kDMixPMode1,
607                         kFirstParameterId);
608   SetUpModules();
609 
610   SetUpParameterBlockWithData(
611       /*recon_gain_parameter_id=*/std::nullopt,
612       /*recon_gain_values_vector=*/{},
613       /*demixing_parameter_id=*/kFirstParameterId,
614       /*dmixp_mode_vector=*/
615       {DemixingInfoParameterData::kDMixPMode2,
616        DemixingInfoParameterData::kDMixPMode3});
617 
618   // Call `GenerateAudioFrameWithData()`.
619   std::list<AudioFrameWithData> audio_frames_with_data;
620   auto parameter_block_iter = parameter_blocks_with_data_.begin();
621   for (const auto& audio_frame_obu : audio_frame_obus_) {
622     AddCurrentParameterBlocksToParametersManager(parameter_block_iter);
623     auto audio_frame_with_data =
624         ObuWithDataGenerator::GenerateAudioFrameWithData(
625             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
626             *global_timing_module_, *parameters_manager_);
627     EXPECT_THAT(audio_frame_with_data, IsOk());
628     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
629     UpdateParameterStatesIfNeeded();
630   }
631 
632   // Expectations.
633   // We should generate 4 `AudioFramesWithData`.
634   EXPECT_EQ(audio_frames_with_data.size(), 4);
635 
636   // We will validate frames in the two substreams independently.
637   // Frame indices corresponding to the two substreams.
638   std::vector<int> frame_index_for_substreams = {0, 0};
639 
640   // Expected audio frame OBU corresponding to the two substreams.
641   const std::vector<AudioFrameObu> expected_audio_frame_obu_for_substreams = {
642       kFirstSubstreamAudioFrameObu, kSecondSubstreamAudioFrameObu};
643 
644   // Expected timestamps for successive temporal units. Same for both
645   // substreams.
646   const std::vector<int32_t> expected_start_timestamps = {kStartTimestamp,
647                                                           kStartTimestamp + 8};
648   const std::vector<int32_t> expected_end_timestamps = {kEndTimestamp,
649                                                         kEndTimestamp + 8};
650 
651   // Expected {alpha, beta, gamma, delta} for successive temporal units. Same
652   // for both substreams.
653   const std::vector<AlphaBetaGammaDelta> expected_alpha_beta_gamma_delta{
654       AlphaBetaGammaDelta{0.707, 0.707, 0.707, 0.707},  // `kDMixPMode2`.
655       AlphaBetaGammaDelta{1.0, 0.866, 0.866, 0.866}     // `kDMixPMode3`.
656   };
657   for (auto& audio_frame_with_data : audio_frames_with_data) {
658     int substream_index =
659         (audio_frame_with_data.obu.GetSubstreamId() == kFirstSubstreamId) ? 0
660                                                                           : 1;
661     int& frame_index = frame_index_for_substreams[substream_index];
662     ValidateAudioFrameWithData(
663         audio_frame_with_data,
664         expected_audio_frame_obu_for_substreams[substream_index],
665         expected_start_timestamps[frame_index],
666         expected_end_timestamps[frame_index], kFirstAudioElementId);
667     ValidateDownMimxingParams(audio_frame_with_data.down_mixing_params,
668                               expected_alpha_beta_gamma_delta[frame_index]);
669     frame_index++;
670   }
671 }
672 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFrameWithMultipleReconGainParams)673 TEST_F(GenerateAudioFrameWithDataTest,
674        ValidAudioFrameWithMultipleReconGainParams) {
675   // 1 audio element with 1 substream and 2 audio frames, as there are 2
676   // temporal units. The audio element had 1 param definition for recon gain
677   // params. There are 2 parameter blocks, one for each temporal unit. We should
678   // generate 2 `AudioFramesWithData`, since there are 2 temporal units.
679 
680   // Set up inputs.
681   SetUpObus({kFirstSubstreamId}, {kFirstSubstreamAudioFrameObu}, 2);
682   AddReconGainAudioParam(kFirstParameterId);
683   SetUpModules();
684   SetUpParameterBlockWithData(
685       /*recon_gain_parameter_id=*/kFirstParameterId,
686       /*recon_gain_values_vector=*/
687       {kFirstReconGainValues, kSecondReconGainValues},
688       /*demixing_parameter_id=*/std::nullopt,
689       /*dmixp_mode_vector=*/{});
690 
691   // Call `GenerateAudioFrameWithData()`.
692   std::list<AudioFrameWithData> audio_frames_with_data;
693   auto parameter_block_iter = parameter_blocks_with_data_.begin();
694   for (const auto& audio_frame_obu : audio_frame_obus_) {
695     AddCurrentParameterBlocksToParametersManager(parameter_block_iter);
696     auto audio_frame_with_data =
697         ObuWithDataGenerator::GenerateAudioFrameWithData(
698             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
699             *global_timing_module_, *parameters_manager_);
700     EXPECT_THAT(audio_frame_with_data, IsOk());
701     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
702     UpdateParameterStatesIfNeeded();
703   }
704 
705   // Expectations.
706   EXPECT_EQ(audio_frames_with_data.size(), 2);
707   int32_t expected_start_timestamp = kStartTimestamp;
708   int32_t expected_end_timestamp = kEndTimestamp;
709   const std::vector<std::array<uint8_t, 12>> expected_recon_gain_values = {
710       kFirstReconGainValues, kSecondReconGainValues};
711   int frame_index = 0;
712   for (const auto& audio_frame_with_data : audio_frames_with_data) {
713     ValidateAudioFrameWithData(
714         audio_frame_with_data, kFirstSubstreamAudioFrameObu,
715         expected_start_timestamp, expected_end_timestamp, kFirstAudioElementId);
716     ValidateReconGainParameters(
717         audio_frame_with_data.recon_gain_info_parameter_data,
718         expected_recon_gain_values[frame_index++]);
719     expected_start_timestamp += 8;
720     expected_end_timestamp += 8;
721   }
722 }
723 
TEST_F(GenerateAudioFrameWithDataTest,ValidAudioFrameWithMultipleReconGainAndDemixingParams)724 TEST_F(GenerateAudioFrameWithDataTest,
725        ValidAudioFrameWithMultipleReconGainAndDemixingParams) {
726   // 1 audio element with 1 substream and 2 audio frames, as there are 2
727   // temporal units. The audio element had 1 param definition for recon gain
728   // parameters and 1 param definition for demixing parameters. There are 4
729   // parameter blocks, two for each temporal unit (one recon gain and one
730   // demixing). We should generate 2 `AudioFramesWithData`, since there are 2
731   // temporal units.
732 
733   // Set up inputs.
734   SetUpObus({kFirstSubstreamId}, {kFirstSubstreamAudioFrameObu}, 2);
735   AddReconGainAudioParam(kFirstParameterId);
736   AddDemixingAudioParam(DemixingInfoParameterData::kDMixPMode1,
737                         kSecondParameterId);
738   SetUpModules();
739   SetUpParameterBlockWithData(
740       /*recon_gain_parameter_id=*/kFirstParameterId,
741       /*recon_gain_values_vector=*/
742       {kFirstReconGainValues, kSecondReconGainValues},
743       /*demixing_parameter_id=*/kSecondParameterId,
744       /*dmixp_mode_vector=*/
745       {DemixingInfoParameterData::kDMixPMode2,
746        DemixingInfoParameterData::kDMixPMode3});
747 
748   // Call `GenerateAudioFrameWithData()`.
749   std::list<AudioFrameWithData> audio_frames_with_data;
750   auto parameter_block_iter = parameter_blocks_with_data_.begin();
751   for (const auto& audio_frame_obu : audio_frame_obus_) {
752     AddCurrentParameterBlocksToParametersManager(parameter_block_iter);
753     auto audio_frame_with_data =
754         ObuWithDataGenerator::GenerateAudioFrameWithData(
755             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
756             *global_timing_module_, *parameters_manager_);
757     EXPECT_THAT(audio_frame_with_data, IsOk());
758     audio_frames_with_data.push_back(std::move(*audio_frame_with_data));
759     UpdateParameterStatesIfNeeded();
760   }
761 
762   // Expectations.
763   EXPECT_EQ(audio_frames_with_data.size(), 2);
764   int32_t expected_start_timestamp = kStartTimestamp;
765   int32_t expected_end_timestamp = kEndTimestamp;
766   const std::vector<std::array<uint8_t, 12>> expected_recon_gain_values = {
767       kFirstReconGainValues, kSecondReconGainValues};
768   const std::vector<AlphaBetaGammaDelta> expected_alpha_beta_gamma_delta = {
769       {0.707, 0.707, 0.707, 0.707},  // `kDMixPMode2`.
770       {1.0, 0.866, 0.866, 0.866},    // `kDMixPMode3`.
771   };
772   int frame_index = 0;
773   for (const auto& audio_frame_with_data : audio_frames_with_data) {
774     ValidateAudioFrameWithData(
775         audio_frame_with_data, kFirstSubstreamAudioFrameObu,
776         expected_start_timestamp, expected_end_timestamp, kFirstAudioElementId);
777     ValidateDownMimxingParams(audio_frame_with_data.down_mixing_params,
778                               expected_alpha_beta_gamma_delta[frame_index]);
779     ValidateReconGainParameters(
780         audio_frame_with_data.recon_gain_info_parameter_data,
781         expected_recon_gain_values[frame_index]);
782     expected_start_timestamp += 8;
783     expected_end_timestamp += 8;
784     frame_index++;
785   }
786 }
787 
TEST_F(GenerateAudioFrameWithDataTest,RejectMismatchingAudioElement)788 TEST_F(GenerateAudioFrameWithDataTest, RejectMismatchingAudioElement) {
789   // Set up inputs. Notice that the substream ID recorded in the audio element
790   // (`kSecondSubstreamId`) is different from that in the audio frame OBU
791   // (`kFirstSubstreamId`). This will cause `GenerateAudioFrameWithData()`
792   // to fail, because it cannot find the corresponding audio element of the
793   // audio frame being processed.
794   SetUpObus({kSecondSubstreamId}, {kFirstSubstreamAudioFrameObu}, 1);
795   SetUpModules();
796 
797   // Call `GenerateAudioFrameWithData()`.
798   for (const auto& audio_frame_obu : audio_frame_obus_) {
799     auto audio_frame_with_data =
800         ObuWithDataGenerator::GenerateAudioFrameWithData(
801             audio_elements_with_data_.at(kFirstAudioElementId), audio_frame_obu,
802             *global_timing_module_, *parameters_manager_);
803     EXPECT_FALSE(audio_frame_with_data.ok());
804   }
805 }
806 
TEST(GenerateParameterBlockWithData,ValidParameterBlock)807 TEST(GenerateParameterBlockWithData, ValidParameterBlock) {
808   // Set up inputs.
809   absl::flat_hash_map<DecodedUleb128, CodecConfigObu> codec_config_obus;
810   absl::flat_hash_map<DecodedUleb128, AudioElementWithData>
811       audio_elements_with_data;
812   AddOpusCodecConfigWithId(kFirstCodecConfigId, codec_config_obus);
813   AddAmbisonicsMonoAudioElementWithSubstreamIds(
814       kFirstAudioElementId, kFirstCodecConfigId,
815       /*substream_ids=*/{kFirstSubstreamId}, codec_config_obus,
816       audio_elements_with_data);
817 
818   absl::flat_hash_map<DecodedUleb128, ParamDefinitionVariant>
819       param_definition_variants;
820   DemixingParamDefinition param_definition;
821   param_definition.param_definition_mode_ = 0;
822   param_definition.duration_ = static_cast<DecodedUleb128>(kDuration);
823   param_definition.parameter_rate_ = 1;
824   param_definition_variants.emplace(kFirstParameterId, param_definition);
825   auto global_timing_module = GlobalTimingModule::Create(
826       audio_elements_with_data, param_definition_variants);
827   ASSERT_THAT(global_timing_module, NotNull());
828   std::list<std::unique_ptr<ParameterBlockObu>> parameter_block_obus;
829   parameter_block_obus.push_back(std::make_unique<ParameterBlockObu>(
830       ObuHeader(), kFirstParameterId, param_definition));
831 
832   // Call `GenerateParameterBlockWithData()` iteratively with one OBU at a time.
833   auto start_timestamp = kStartTimestamp;
834   std::list<ParameterBlockWithData> parameter_blocks_with_data;
835   for (auto& parameter_block_obu : parameter_block_obus) {
836     auto parameter_block_with_data =
837         ObuWithDataGenerator::GenerateParameterBlockWithData(
838             start_timestamp, *global_timing_module,
839             std::move(parameter_block_obu));
840     EXPECT_THAT(parameter_block_with_data, IsOk());
841     start_timestamp += kDuration;
842     parameter_blocks_with_data.push_back(std::move(*parameter_block_with_data));
843   }
844 
845   // Set up expected output.
846   EXPECT_EQ(parameter_blocks_with_data.size(), 1);
847   EXPECT_EQ(parameter_blocks_with_data.front().obu->parameter_id_,
848             kFirstParameterId);
849   EXPECT_EQ(parameter_blocks_with_data.front().start_timestamp,
850             kStartTimestamp);
851   EXPECT_EQ(parameter_blocks_with_data.front().end_timestamp, kEndTimestamp);
852 }
853 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForOneLayerStereo)854 TEST(FinalizeScalableChannelLayoutConfig,
855      FillsExpectedOutputForForOneLayerStereo) {
856   const std::vector<DecodedUleb128> kSubstreamIds = {99};
857   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
858       {kSubstreamIds[0], {kL2, kR2}}};
859   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
860       {.surround = 2, .lfe = 0, .height = 0}};
861 
862   SubstreamIdLabelsMap output_substream_id_to_labels;
863   LabelGainMap output_label_to_output_gain;
864   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
865 
866   EXPECT_THAT(
867       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
868           kSubstreamIds, kOneLayerStereoConfig, output_substream_id_to_labels,
869           output_label_to_output_gain, output_channel_numbers_for_layer),
870       IsOk());
871 
872   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
873   EXPECT_TRUE(output_label_to_output_gain.empty());
874   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
875 }
876 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenThereAreTooFewAudioSubstreamIds)877 TEST(FinalizeScalableChannelLayoutConfig,
878      InvalidWhenThereAreTooFewAudioSubstreamIds) {
879   const std::vector<DecodedUleb128> kTooFewSubstreamIdsForOneLayerStereo = {};
880 
881   SubstreamIdLabelsMap output_substream_id_to_labels;
882   LabelGainMap output_label_to_output_gain;
883   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
884 
885   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
886                    kTooFewSubstreamIdsForOneLayerStereo, kOneLayerStereoConfig,
887                    output_substream_id_to_labels, output_label_to_output_gain,
888                    output_channel_numbers_for_layer)
889                    .ok());
890 }
891 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenThereAreTooManyAudioSubstreamIds)892 TEST(FinalizeScalableChannelLayoutConfig,
893      InvalidWhenThereAreTooManyAudioSubstreamIds) {
894   const std::vector<DecodedUleb128> kTooManySubstreamIdsForOneLayerStereo = {
895       99, 100};
896 
897   SubstreamIdLabelsMap output_substream_id_to_labels;
898   LabelGainMap output_label_to_output_gain;
899   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
900 
901   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
902                    kTooManySubstreamIdsForOneLayerStereo, kOneLayerStereoConfig,
903                    output_substream_id_to_labels, output_label_to_output_gain,
904                    output_channel_numbers_for_layer)
905                    .ok());
906 }
907 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenSubstreamIdsAreNotUnique)908 TEST(FinalizeScalableChannelLayoutConfig, InvalidWhenSubstreamIdsAreNotUnique) {
909   const std::vector<DecodedUleb128> kNonUniqueSubstreamIds = {1, 2, 99, 99};
910 
911   const ScalableChannelLayoutConfig k3_1_2Config{
912       .num_layers = 1,
913       .channel_audio_layer_configs = {
914           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout3_1_2_ch,
915            .output_gain_is_present_flag = false,
916            .substream_count = 4,
917            .coupled_substream_count = 2}}};
918   SubstreamIdLabelsMap output_substream_id_to_labels;
919   LabelGainMap output_label_to_output_gain;
920   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
921 
922   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
923                    kNonUniqueSubstreamIds, k3_1_2Config,
924                    output_substream_id_to_labels, output_label_to_output_gain,
925                    output_channel_numbers_for_layer)
926                    .ok());
927 }
928 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenSubstreamCountIsInconsistent)929 TEST(FinalizeScalableChannelLayoutConfig,
930      InvalidWhenSubstreamCountIsInconsistent) {
931   constexpr uint8_t kInvalidOneLayerStereoSubstreamCount = 2;
932   const std::vector<DecodedUleb128> kSubstreamIds = {0};
933   const ScalableChannelLayoutConfig
934       kInvalidOneLayerStereoWithoutCoupledSubstreams{
935           .num_layers = 1,
936           .channel_audio_layer_configs = {
937               {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
938                .output_gain_is_present_flag = false,
939                .substream_count = kInvalidOneLayerStereoSubstreamCount,
940                .coupled_substream_count = 1}}};
941   SubstreamIdLabelsMap unused_substream_id_to_labels;
942   LabelGainMap unused_label_to_output_gain;
943   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
944 
945   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
946                    kSubstreamIds,
947                    kInvalidOneLayerStereoWithoutCoupledSubstreams,
948                    unused_substream_id_to_labels, unused_label_to_output_gain,
949                    unused_channel_numbers_for_layer)
950                    .ok());
951 }
952 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenCoupledSubstreamCountIsInconsistent)953 TEST(FinalizeScalableChannelLayoutConfig,
954      InvalidWhenCoupledSubstreamCountIsInconsistent) {
955   constexpr uint8_t kInvalidOneLayerStereoCoupledSubstreamCount = 0;
956   const std::vector<DecodedUleb128> kSubstreamIds = {0};
957   const ScalableChannelLayoutConfig
958       kInvalidOneLayerStereoWithoutCoupledSubstreams{
959           .num_layers = 1,
960           .channel_audio_layer_configs = {
961               {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
962                .output_gain_is_present_flag = false,
963                .substream_count = 1,
964                .coupled_substream_count =
965                    kInvalidOneLayerStereoCoupledSubstreamCount}}};
966   SubstreamIdLabelsMap unused_substream_id_to_labels;
967   LabelGainMap unused_label_to_output_gain;
968   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
969 
970   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
971                    kSubstreamIds,
972                    kInvalidOneLayerStereoWithoutCoupledSubstreams,
973                    unused_substream_id_to_labels, unused_label_to_output_gain,
974                    unused_channel_numbers_for_layer)
975                    .ok());
976 }
977 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayerMonoStereo)978 TEST(FinalizeScalableChannelLayoutConfig,
979      FillsExpectedOutputForForTwoLayerMonoStereo) {
980   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
981   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{0, {kMono}},
982                                                              {1, {kL2}}};
983   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
984       {.surround = 1, .lfe = 0, .height = 0},
985       {.surround = 2, .lfe = 0, .height = 0}};
986   const ScalableChannelLayoutConfig kTwoLayerMonoStereoConfig{
987       .num_layers = 2,
988       .channel_audio_layer_configs = {
989           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutMono,
990            .output_gain_is_present_flag = false,
991            .substream_count = 1,
992            .coupled_substream_count = 0},
993           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
994            .output_gain_is_present_flag = false,
995            .substream_count = 1,
996            .coupled_substream_count = 0},
997       }};
998   SubstreamIdLabelsMap output_substream_id_to_labels;
999   LabelGainMap output_label_to_output_gain;
1000   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1001 
1002   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1003                   kSubstreamIds, kTwoLayerMonoStereoConfig,
1004                   output_substream_id_to_labels, output_label_to_output_gain,
1005                   output_channel_numbers_for_layer),
1006               IsOk());
1007 
1008   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1009   EXPECT_TRUE(output_label_to_output_gain.empty());
1010   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1011 }
1012 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenSubsequenceLayersAreLower)1013 TEST(FinalizeScalableChannelLayoutConfig,
1014      InvalidWhenSubsequenceLayersAreLower) {
1015   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1016   const ScalableChannelLayoutConfig kInvalidWithMonoLayerAfterStereo{
1017       .num_layers = 2,
1018       .channel_audio_layer_configs = {
1019           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
1020            .output_gain_is_present_flag = false,
1021            .substream_count = 1,
1022            .coupled_substream_count = 0},
1023           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutMono,
1024            .output_gain_is_present_flag = false,
1025            .substream_count = 1,
1026            .coupled_substream_count = 0},
1027       }};
1028   SubstreamIdLabelsMap unused_substream_id_to_labels;
1029   LabelGainMap unused_label_to_output_gain;
1030   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
1031 
1032   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1033                    kSubstreamIds, kInvalidWithMonoLayerAfterStereo,
1034                    unused_substream_id_to_labels, unused_label_to_output_gain,
1035                    unused_channel_numbers_for_layer)
1036                    .ok());
1037 }
1038 
TEST(FinalizeScalableChannelLayoutConfig,FillsOutputGainMap)1039 TEST(FinalizeScalableChannelLayoutConfig, FillsOutputGainMap) {
1040   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1041   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{0, {kMono}},
1042                                                              {1, {kL2}}};
1043   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1044       {.surround = 1, .lfe = 0, .height = 0},
1045       {.surround = 2, .lfe = 0, .height = 0}};
1046   const ScalableChannelLayoutConfig kTwoLayerStereoConfig{
1047       .num_layers = 2,
1048       .channel_audio_layer_configs = {
1049           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutMono,
1050            .output_gain_is_present_flag = false,
1051            .substream_count = 1,
1052            .coupled_substream_count = 0},
1053           {
1054               .loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
1055               .output_gain_is_present_flag = true,
1056               .substream_count = 1,
1057               .coupled_substream_count = 0,
1058               .output_gain_flag = kApplyOutputGainToLeftChannel,
1059               .reserved_b = 0,
1060               .output_gain = std::numeric_limits<int16_t>::min(),
1061           },
1062       }};
1063   SubstreamIdLabelsMap output_substream_id_to_labels;
1064   LabelGainMap output_label_to_output_gain;
1065   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1066 
1067   EXPECT_THAT(
1068       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1069           kSubstreamIds, kTwoLayerStereoConfig, output_substream_id_to_labels,
1070           output_label_to_output_gain, output_channel_numbers_for_layer),
1071       IsOk());
1072 
1073   ASSERT_TRUE(output_label_to_output_gain.contains(kL2));
1074   EXPECT_FLOAT_EQ(output_label_to_output_gain.at(kL2), -128.0);
1075 }
1076 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayerStereo3_1_2)1077 TEST(FinalizeScalableChannelLayoutConfig,
1078      FillsExpectedOutputForForTwoLayerStereo3_1_2) {
1079   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1, 2, 3};
1080   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1081       {0, {kL2, kR2}},
1082       {1, {kLtf3, kRtf3}},
1083       {2, {kCentre}},
1084       {3, {kLFE}},
1085   };
1086   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1087       {.surround = 2, .lfe = 0, .height = 0},
1088       {.surround = 3, .lfe = 1, .height = 2}};
1089   const ScalableChannelLayoutConfig kTwoLayerStereo3_1_2Config{
1090       .num_layers = 2,
1091       .channel_audio_layer_configs = {
1092           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
1093            .output_gain_is_present_flag = false,
1094            .substream_count = 1,
1095            .coupled_substream_count = 1},
1096           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout3_1_2_ch,
1097            .output_gain_is_present_flag = false,
1098            .substream_count = 3,
1099            .coupled_substream_count = 1},
1100       }};
1101   SubstreamIdLabelsMap output_substream_id_to_labels;
1102   LabelGainMap output_label_to_output_gain;
1103   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1104 
1105   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1106                   kSubstreamIds, kTwoLayerStereo3_1_2Config,
1107                   output_substream_id_to_labels, output_label_to_output_gain,
1108                   output_channel_numbers_for_layer),
1109               IsOk());
1110 
1111   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1112   EXPECT_TRUE(output_label_to_output_gain.empty());
1113   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1114 }
1115 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayer3_1_2And5_1_2)1116 TEST(FinalizeScalableChannelLayoutConfig,
1117      FillsExpectedOutputForForTwoLayer3_1_2And5_1_2) {
1118   const std::vector<DecodedUleb128> kSubstreamIds = {300, 301, 302, 303, 514};
1119   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1120       {300, {kL3, kR3}}, {301, {kLtf3, kRtf3}}, {302, {kCentre}},
1121       {303, {kLFE}},     {514, {kL5, kR5}},
1122   };
1123   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1124       {.surround = 3, .lfe = 1, .height = 2},
1125       {.surround = 5, .lfe = 1, .height = 2}};
1126   const ScalableChannelLayoutConfig kTwoLayer3_1_2_and_5_1_2Config{
1127       .num_layers = 2,
1128       .channel_audio_layer_configs = {
1129           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout3_1_2_ch,
1130            .output_gain_is_present_flag = false,
1131            .substream_count = 4,
1132            .coupled_substream_count = 2},
1133           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout5_1_2_ch,
1134            .output_gain_is_present_flag = false,
1135            .substream_count = 1,
1136            .coupled_substream_count = 1},
1137       }};
1138   SubstreamIdLabelsMap output_substream_id_to_labels;
1139   LabelGainMap output_label_to_output_gain;
1140   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1141 
1142   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1143                   kSubstreamIds, kTwoLayer3_1_2_and_5_1_2Config,
1144                   output_substream_id_to_labels, output_label_to_output_gain,
1145                   output_channel_numbers_for_layer),
1146               IsOk());
1147 
1148   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1149   EXPECT_TRUE(output_label_to_output_gain.empty());
1150   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1151 }
1152 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayer5_1_0And7_1_0)1153 TEST(FinalizeScalableChannelLayoutConfig,
1154      FillsExpectedOutputForForTwoLayer5_1_0And7_1_0) {
1155   const std::vector<DecodedUleb128> kSubstreamIds = {500, 501, 502, 503, 704};
1156   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1157       {500, {kL5, kR5}}, {501, {kLs5, kRs5}},   {502, {kCentre}},
1158       {503, {kLFE}},     {704, {kLss7, kRss7}},
1159   };
1160   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1161       {.surround = 5, .lfe = 1, .height = 0},
1162       {.surround = 7, .lfe = 1, .height = 0}};
1163   const ScalableChannelLayoutConfig kTwoLayer5_1_0_and_7_1_0Config{
1164       .num_layers = 2,
1165       .channel_audio_layer_configs = {
1166           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout5_1_ch,
1167            .output_gain_is_present_flag = false,
1168            .substream_count = 4,
1169            .coupled_substream_count = 2},
1170           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout7_1_ch,
1171            .output_gain_is_present_flag = false,
1172            .substream_count = 1,
1173            .coupled_substream_count = 1},
1174       }};
1175   SubstreamIdLabelsMap output_substream_id_to_labels;
1176   LabelGainMap output_label_to_output_gain;
1177   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1178 
1179   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1180                   kSubstreamIds, kTwoLayer5_1_0_and_7_1_0Config,
1181                   output_substream_id_to_labels, output_label_to_output_gain,
1182                   output_channel_numbers_for_layer),
1183               IsOk());
1184 
1185   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1186   EXPECT_TRUE(output_label_to_output_gain.empty());
1187   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1188 }
1189 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForOneLayer5_1_4)1190 TEST(FinalizeScalableChannelLayoutConfig,
1191      FillsExpectedOutputForForOneLayer5_1_4) {
1192   const std::vector<DecodedUleb128> kSubstreamIds = {55, 77, 66, 11, 22, 88};
1193   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1194       {55, {kL5, kR5}},     {77, {kLs5, kRs5}}, {66, {kLtf4, kRtf4}},
1195       {11, {kLtb4, kRtb4}}, {22, {kCentre}},    {88, {kLFE}}};
1196 
1197   const LabelGainMap kExpectedLabelToOutputGain = {};
1198   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1199       {.surround = 5, .lfe = 1, .height = 4}};
1200   const std::vector<DecodedUleb128> kAudioSubstreamIds = kSubstreamIds;
1201   const ScalableChannelLayoutConfig kOneLayer5_1_4Config{
1202       .num_layers = 1,
1203       .channel_audio_layer_configs = {
1204           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout5_1_4_ch,
1205            .output_gain_is_present_flag = false,
1206            .substream_count = 6,
1207            .coupled_substream_count = 4}}};
1208   SubstreamIdLabelsMap output_substream_id_to_labels;
1209   LabelGainMap output_label_to_output_gain;
1210   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1211 
1212   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1213                   kAudioSubstreamIds, kOneLayer5_1_4Config,
1214                   output_substream_id_to_labels, output_label_to_output_gain,
1215                   output_channel_numbers_for_layer),
1216               IsOk());
1217 
1218   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1219   EXPECT_TRUE(output_label_to_output_gain.empty());
1220   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1221 }
1222 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayer5_1_2And5_1_4)1223 TEST(FinalizeScalableChannelLayoutConfig,
1224      FillsExpectedOutputForForTwoLayer5_1_2And5_1_4) {
1225   const std::vector<DecodedUleb128> kSubstreamIds = {520, 521, 522,
1226                                                      523, 524, 540};
1227   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1228       {520, {kL5, kR5}}, {521, {kLs5, kRs5}}, {522, {kLtf2, kRtf2}},
1229       {523, {kCentre}},  {524, {kLFE}},       {540, {kLtf4, kRtf4}},
1230   };
1231   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1232       {.surround = 5, .lfe = 1, .height = 2},
1233       {.surround = 5, .lfe = 1, .height = 4}};
1234   const ScalableChannelLayoutConfig kTwoLayer5_1_2_and_5_1_4Config{
1235       .num_layers = 2,
1236       .channel_audio_layer_configs = {
1237           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout5_1_2_ch,
1238            .output_gain_is_present_flag = false,
1239            .substream_count = 5,
1240            .coupled_substream_count = 3},
1241           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout5_1_4_ch,
1242            .output_gain_is_present_flag = false,
1243            .substream_count = 1,
1244            .coupled_substream_count = 1},
1245       }};
1246   SubstreamIdLabelsMap output_substream_id_to_labels;
1247   LabelGainMap output_label_to_output_gain;
1248   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1249 
1250   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1251                   kSubstreamIds, kTwoLayer5_1_2_and_5_1_4Config,
1252                   output_substream_id_to_labels, output_label_to_output_gain,
1253                   output_channel_numbers_for_layer),
1254               IsOk());
1255 
1256   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1257   EXPECT_TRUE(output_label_to_output_gain.empty());
1258   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1259 }
1260 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForTwoLayer7_1_0And7_1_4)1261 TEST(FinalizeScalableChannelLayoutConfig,
1262      FillsExpectedOutputForForTwoLayer7_1_0And7_1_4) {
1263   const std::vector<DecodedUleb128> kSubstreamIds = {700, 701, 702, 703,
1264                                                      704, 740, 741};
1265   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1266       {700, {kL7, kR7}},     {701, {kLss7, kRss7}}, {702, {kLrs7, kRrs7}},
1267       {703, {kCentre}},      {704, {kLFE}},         {740, {kLtf4, kRtf4}},
1268       {741, {kLtb4, kRtb4}},
1269   };
1270   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1271       {.surround = 7, .lfe = 1, .height = 0},
1272       {.surround = 7, .lfe = 1, .height = 4}};
1273   const ScalableChannelLayoutConfig kTwoLayer7_1_0_and_7_1_4Config{
1274       .num_layers = 2,
1275       .channel_audio_layer_configs = {
1276           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout7_1_ch,
1277            .output_gain_is_present_flag = false,
1278            .substream_count = 5,
1279            .coupled_substream_count = 3},
1280           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout7_1_4_ch,
1281            .output_gain_is_present_flag = false,
1282 
1283            .substream_count = 2,
1284            .coupled_substream_count = 2},
1285       }};
1286   SubstreamIdLabelsMap output_substream_id_to_labels;
1287   LabelGainMap output_label_to_output_gain;
1288   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1289 
1290   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1291                   kSubstreamIds, kTwoLayer7_1_0_and_7_1_4Config,
1292                   output_substream_id_to_labels, output_label_to_output_gain,
1293                   output_channel_numbers_for_layer),
1294               IsOk());
1295 
1296   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1297   EXPECT_TRUE(output_label_to_output_gain.empty());
1298   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1299 }
1300 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForForOneLayer7_1_4)1301 TEST(FinalizeScalableChannelLayoutConfig,
1302      FillsExpectedOutputForForOneLayer7_1_4) {
1303   const std::vector<DecodedUleb128> kSubstreamIds = {6, 5, 4, 3, 2, 1, 0};
1304   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1305       {6, {kL7, kR7}},     {5, {kLss7, kRss7}}, {4, {kLrs7, kRrs7}},
1306       {3, {kLtf4, kRtf4}}, {2, {kLtb4, kRtb4}}, {1, {kCentre}},
1307       {0, {kLFE}}};
1308   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1309       {.surround = 7, .lfe = 1, .height = 4}};
1310   const std::vector<DecodedUleb128> kAudioSubstreamIds = kSubstreamIds;
1311   const ScalableChannelLayoutConfig kOneLayer7_1_4Config{
1312       .num_layers = 1,
1313       .channel_audio_layer_configs = {
1314           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayout7_1_4_ch,
1315            .output_gain_is_present_flag = false,
1316            .substream_count = 7,
1317            .coupled_substream_count = 5}}};
1318   SubstreamIdLabelsMap output_substream_id_to_labels;
1319   LabelGainMap output_label_to_output_gain;
1320   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1321 
1322   EXPECT_THAT(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1323                   kAudioSubstreamIds, kOneLayer7_1_4Config,
1324                   output_substream_id_to_labels, output_label_to_output_gain,
1325                   output_channel_numbers_for_layer),
1326               IsOk());
1327 
1328   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1329   EXPECT_TRUE(output_label_to_output_gain.empty());
1330   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1331 }
1332 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWithReservedLayout14)1333 TEST(FinalizeScalableChannelLayoutConfig, InvalidWithReservedLayout14) {
1334   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1335   const ScalableChannelLayoutConfig kOneLayerReserved14Layout{
1336       .num_layers = 1,
1337       .channel_audio_layer_configs = {
1338           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutReserved14,
1339            .output_gain_is_present_flag = false,
1340            .substream_count = 1,
1341            .coupled_substream_count = 1}}};
1342   SubstreamIdLabelsMap unused_substream_id_to_labels;
1343   LabelGainMap unused_label_to_output_gain;
1344   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
1345 
1346   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1347                    kSubstreamIds, kOneLayerReserved14Layout,
1348                    unused_substream_id_to_labels, unused_label_to_output_gain,
1349                    unused_channel_numbers_for_layer)
1350                    .ok());
1351 }
1352 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutLFE)1353 TEST(FinalizeScalableChannelLayoutConfig,
1354      FillsExpectedOutputForExpandedLoudspeakerLayoutLFE) {
1355   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{0, {kLFE}}};
1356   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1357       {.surround = 0, .lfe = 1, .height = 0}};
1358   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1359   const ScalableChannelLayoutConfig kLFELayout{
1360       .num_layers = 1,
1361       .channel_audio_layer_configs = {
1362           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1363            .output_gain_is_present_flag = false,
1364            .substream_count = 1,
1365            .coupled_substream_count = 0,
1366            .expanded_loudspeaker_layout =
1367                ChannelAudioLayerConfig::kExpandedLayoutLFE}}};
1368   SubstreamIdLabelsMap output_substream_id_to_labels;
1369   LabelGainMap output_label_to_output_gain;
1370   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1371 
1372   EXPECT_THAT(
1373       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1374           kSubstreamIds, kLFELayout, output_substream_id_to_labels,
1375           output_label_to_output_gain, output_channel_numbers_for_layer),
1376       IsOk());
1377 
1378   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1379   EXPECT_TRUE(output_label_to_output_gain.empty());
1380   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1381 }
1382 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutStereoS)1383 TEST(FinalizeScalableChannelLayoutConfig,
1384      FillsExpectedOutputForExpandedLoudspeakerLayoutStereoS) {
1385   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{0, {kLs5, kRs5}}};
1386   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1387       {.surround = 2, .lfe = 0, .height = 0}};
1388   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1389   const ScalableChannelLayoutConfig kStereoSSLayout{
1390       .num_layers = 1,
1391       .channel_audio_layer_configs = {
1392           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1393            .output_gain_is_present_flag = false,
1394            .substream_count = 1,
1395            .coupled_substream_count = 1,
1396            .expanded_loudspeaker_layout =
1397                ChannelAudioLayerConfig::kExpandedLayoutStereoS}}};
1398   SubstreamIdLabelsMap output_substream_id_to_labels;
1399   LabelGainMap output_label_to_output_gain;
1400   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1401 
1402   EXPECT_THAT(
1403       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1404           kSubstreamIds, kStereoSSLayout, output_substream_id_to_labels,
1405           output_label_to_output_gain, output_channel_numbers_for_layer),
1406       IsOk());
1407 
1408   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1409   EXPECT_TRUE(output_label_to_output_gain.empty());
1410   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1411 }
1412 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutStereoSS)1413 TEST(FinalizeScalableChannelLayoutConfig,
1414      FillsExpectedOutputForExpandedLoudspeakerLayoutStereoSS) {
1415   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1416       {0, {kLss7, kRss7}}};
1417   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1418       {.surround = 2, .lfe = 0, .height = 0}};
1419   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1420   const ScalableChannelLayoutConfig kStereoSSLayout{
1421       .num_layers = 1,
1422       .channel_audio_layer_configs = {
1423           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1424            .output_gain_is_present_flag = false,
1425            .substream_count = 1,
1426            .coupled_substream_count = 1,
1427            .expanded_loudspeaker_layout =
1428                ChannelAudioLayerConfig::kExpandedLayoutStereoSS}}};
1429   SubstreamIdLabelsMap output_substream_id_to_labels;
1430   LabelGainMap output_label_to_output_gain;
1431   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1432 
1433   EXPECT_THAT(
1434       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1435           kSubstreamIds, kStereoSSLayout, output_substream_id_to_labels,
1436           output_label_to_output_gain, output_channel_numbers_for_layer),
1437       IsOk());
1438 
1439   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1440   EXPECT_TRUE(output_label_to_output_gain.empty());
1441   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1442 }
1443 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTf)1444 TEST(FinalizeScalableChannelLayoutConfig,
1445      FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTf) {
1446   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1447       {0, {kLtf4, kRtf4}}};
1448   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1449       {.surround = 0, .lfe = 0, .height = 2}};
1450   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1451   const ScalableChannelLayoutConfig kStereoTfLayout{
1452       .num_layers = 1,
1453       .channel_audio_layer_configs = {
1454           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1455            .output_gain_is_present_flag = false,
1456            .substream_count = 1,
1457            .coupled_substream_count = 1,
1458            .expanded_loudspeaker_layout =
1459                ChannelAudioLayerConfig::kExpandedLayoutStereoTF}}};
1460   SubstreamIdLabelsMap output_substream_id_to_labels;
1461   LabelGainMap output_label_to_output_gain;
1462   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1463 
1464   EXPECT_THAT(
1465       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1466           kSubstreamIds, kStereoTfLayout, output_substream_id_to_labels,
1467           output_label_to_output_gain, output_channel_numbers_for_layer),
1468       IsOk());
1469 
1470   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1471   EXPECT_TRUE(output_label_to_output_gain.empty());
1472   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1473 }
1474 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTB)1475 TEST(FinalizeScalableChannelLayoutConfig,
1476      FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTB) {
1477   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1478       {0, {kLtb4, kRtb4}}};
1479   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1480       {.surround = 0, .lfe = 0, .height = 2}};
1481   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1482   const ScalableChannelLayoutConfig kStereoTBLayout{
1483       .num_layers = 1,
1484       .channel_audio_layer_configs = {
1485           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1486            .output_gain_is_present_flag = false,
1487            .substream_count = 1,
1488            .coupled_substream_count = 1,
1489            .expanded_loudspeaker_layout =
1490                ChannelAudioLayerConfig::kExpandedLayoutStereoTB}}};
1491   SubstreamIdLabelsMap output_substream_id_to_labels;
1492   LabelGainMap output_label_to_output_gain;
1493   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1494 
1495   EXPECT_THAT(
1496       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1497           kSubstreamIds, kStereoTBLayout, output_substream_id_to_labels,
1498           output_label_to_output_gain, output_channel_numbers_for_layer),
1499       IsOk());
1500 
1501   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1502   EXPECT_TRUE(output_label_to_output_gain.empty());
1503   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1504 }
1505 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutTop4Ch)1506 TEST(FinalizeScalableChannelLayoutConfig,
1507      FillsExpectedOutputForExpandedLoudspeakerLayoutTop4Ch) {
1508   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1509       {0, {kLtf4, kRtf4}}, {1, {kLtb4, kRtb4}}};
1510   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1511       {.surround = 0, .lfe = 0, .height = 4}};
1512   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1513   const ScalableChannelLayoutConfig kTop4ChLayout{
1514       .num_layers = 1,
1515       .channel_audio_layer_configs = {
1516           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1517            .output_gain_is_present_flag = false,
1518            .substream_count = 2,
1519            .coupled_substream_count = 2,
1520            .expanded_loudspeaker_layout =
1521                ChannelAudioLayerConfig::kExpandedLayoutTop4Ch}}};
1522   SubstreamIdLabelsMap output_substream_id_to_labels;
1523   LabelGainMap output_label_to_output_gain;
1524   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1525 
1526   EXPECT_THAT(
1527       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1528           kSubstreamIds, kTop4ChLayout, output_substream_id_to_labels,
1529           output_label_to_output_gain, output_channel_numbers_for_layer),
1530       IsOk());
1531 
1532   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1533   EXPECT_TRUE(output_label_to_output_gain.empty());
1534   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1535 }
1536 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayout3_0_Ch)1537 TEST(FinalizeScalableChannelLayoutConfig,
1538      FillsExpectedOutputForExpandedLoudspeakerLayout3_0_Ch) {
1539   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {{0, {kL7, kR7}},
1540                                                              {1, {kCentre}}};
1541   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1542       {.surround = 3, .lfe = 0, .height = 0}};
1543   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1544   const ScalableChannelLayoutConfig k3_0_ChLayout{
1545       .num_layers = 1,
1546       .channel_audio_layer_configs = {
1547           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1548            .output_gain_is_present_flag = false,
1549            .substream_count = 2,
1550            .coupled_substream_count = 1,
1551            .expanded_loudspeaker_layout =
1552                ChannelAudioLayerConfig::kExpandedLayout3_0_ch}}};
1553   SubstreamIdLabelsMap output_substream_id_to_labels;
1554   LabelGainMap output_label_to_output_gain;
1555   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1556 
1557   EXPECT_THAT(
1558       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1559           kSubstreamIds, k3_0_ChLayout, output_substream_id_to_labels,
1560           output_label_to_output_gain, output_channel_numbers_for_layer),
1561       IsOk());
1562 
1563   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1564   EXPECT_TRUE(output_label_to_output_gain.empty());
1565   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1566 }
1567 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayout9_1_6)1568 TEST(FinalizeScalableChannelLayoutConfig,
1569      FillsExpectedOutputForExpandedLoudspeakerLayout9_1_6) {
1570   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1571       {0, {kFLc, kFRc}},   {1, {kFL, kFR}},     {2, {kSiL, kSiR}},
1572       {3, {kBL, kBR}},     {4, {kTpFL, kTpFR}}, {5, {kTpSiL, kTpSiR}},
1573       {6, {kTpBL, kTpBR}}, {7, {kFC}},          {8, {kLFE}}};
1574   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1575       {.surround = 9, .lfe = 1, .height = 6}};
1576   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1577   const ScalableChannelLayoutConfig k9_1_6Layout{
1578       .num_layers = 1,
1579       .channel_audio_layer_configs = {
1580           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1581            .output_gain_is_present_flag = false,
1582            .substream_count = 9,
1583            .coupled_substream_count = 7,
1584            .expanded_loudspeaker_layout =
1585                ChannelAudioLayerConfig::kExpandedLayout9_1_6_ch}}};
1586   SubstreamIdLabelsMap output_substream_id_to_labels;
1587   LabelGainMap output_label_to_output_gain;
1588   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1589 
1590   EXPECT_THAT(
1591       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1592           kSubstreamIds, k9_1_6Layout, output_substream_id_to_labels,
1593           output_label_to_output_gain, output_channel_numbers_for_layer),
1594       IsOk());
1595 
1596   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1597   EXPECT_TRUE(output_label_to_output_gain.empty());
1598   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1599 }
1600 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTpSi)1601 TEST(FinalizeScalableChannelLayoutConfig,
1602      FillsExpectedOutputForExpandedLoudspeakerLayoutStereoTpSi) {
1603   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1604       {0, {kTpSiL, kTpSiR}}};
1605   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1606       {.surround = 0, .lfe = 0, .height = 2}};
1607   const std::vector<DecodedUleb128> kSubstreamIds = {0};
1608   const ScalableChannelLayoutConfig kTpSiLayout{
1609       .num_layers = 1,
1610       .channel_audio_layer_configs = {
1611           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1612            .output_gain_is_present_flag = false,
1613            .substream_count = 1,
1614            .coupled_substream_count = 1,
1615            .expanded_loudspeaker_layout =
1616                ChannelAudioLayerConfig::kExpandedLayoutStereoTpSi}}};
1617   SubstreamIdLabelsMap output_substream_id_to_labels;
1618   LabelGainMap output_label_to_output_gain;
1619   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1620 
1621   EXPECT_THAT(
1622       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1623           kSubstreamIds, kTpSiLayout, output_substream_id_to_labels,
1624           output_label_to_output_gain, output_channel_numbers_for_layer),
1625       IsOk());
1626 
1627   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1628   EXPECT_TRUE(output_label_to_output_gain.empty());
1629   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1630 }
1631 
TEST(FinalizeScalableChannelLayoutConfig,FillsExpectedOutputForExpandedLoudspeakerLayoutTop6_Ch)1632 TEST(FinalizeScalableChannelLayoutConfig,
1633      FillsExpectedOutputForExpandedLoudspeakerLayoutTop6_Ch) {
1634   const SubstreamIdLabelsMap kExpectedSubstreamIdToLabels = {
1635       {0, {kTpFL, kTpFR}}, {1, {kTpSiL, kTpSiR}}, {2, {kTpBL, kTpBR}}};
1636   const std::vector<ChannelNumbers> kExpectedChannelNumbersForLayer = {
1637       {.surround = 0, .lfe = 0, .height = 6}};
1638   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1, 2};
1639   const ScalableChannelLayoutConfig kTop6ChLayout{
1640       .num_layers = 1,
1641       .channel_audio_layer_configs = {
1642           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1643            .output_gain_is_present_flag = false,
1644            .substream_count = 3,
1645            .coupled_substream_count = 3,
1646            .expanded_loudspeaker_layout =
1647                ChannelAudioLayerConfig::kExpandedLayoutTop6Ch}}};
1648   SubstreamIdLabelsMap output_substream_id_to_labels;
1649   LabelGainMap output_label_to_output_gain;
1650   std::vector<ChannelNumbers> output_channel_numbers_for_layer;
1651 
1652   EXPECT_THAT(
1653       ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1654           kSubstreamIds, kTop6ChLayout, output_substream_id_to_labels,
1655           output_label_to_output_gain, output_channel_numbers_for_layer),
1656       IsOk());
1657 
1658   EXPECT_EQ(output_substream_id_to_labels, kExpectedSubstreamIdToLabels);
1659   EXPECT_TRUE(output_label_to_output_gain.empty());
1660   EXPECT_EQ(output_channel_numbers_for_layer, kExpectedChannelNumbersForLayer);
1661 }
1662 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenThereAreTwoLayersWithExpandedLoudspeakerLayout)1663 TEST(FinalizeScalableChannelLayoutConfig,
1664      InvalidWhenThereAreTwoLayersWithExpandedLoudspeakerLayout) {
1665   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1666   const ScalableChannelLayoutConfig
1667       kInvalidWithFirstLayerExpandedAndAnotherSecondLayer{
1668           .num_layers = 2,
1669           .channel_audio_layer_configs = {
1670               {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1671                .output_gain_is_present_flag = false,
1672                .substream_count = 1,
1673                .coupled_substream_count = 0,
1674                .expanded_loudspeaker_layout =
1675                    ChannelAudioLayerConfig::kExpandedLayoutLFE},
1676               {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
1677                .output_gain_is_present_flag = false,
1678                .substream_count = 1,
1679                .coupled_substream_count = 1}}};
1680   SubstreamIdLabelsMap unused_substream_id_to_labels;
1681   LabelGainMap unused_label_to_output_gain;
1682   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
1683 
1684   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1685                    kSubstreamIds,
1686                    kInvalidWithFirstLayerExpandedAndAnotherSecondLayer,
1687                    unused_substream_id_to_labels, unused_label_to_output_gain,
1688                    unused_channel_numbers_for_layer)
1689                    .ok());
1690 }
1691 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWhenSecondLayerIsExpandedLayout)1692 TEST(FinalizeScalableChannelLayoutConfig,
1693      InvalidWhenSecondLayerIsExpandedLayout) {
1694   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1};
1695   const ScalableChannelLayoutConfig kInvalidWithSecondLayerExpandedLayout{
1696       .num_layers = 2,
1697       .channel_audio_layer_configs = {
1698           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutStereo,
1699            .output_gain_is_present_flag = false,
1700            .substream_count = 1,
1701            .coupled_substream_count = 1},
1702           {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1703            .output_gain_is_present_flag = false,
1704            .substream_count = 1,
1705            .coupled_substream_count = 0,
1706            .expanded_loudspeaker_layout =
1707                ChannelAudioLayerConfig::kExpandedLayoutLFE}}};
1708   SubstreamIdLabelsMap unused_substream_id_to_labels;
1709   LabelGainMap unused_label_to_output_gain;
1710   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
1711 
1712   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1713                    kSubstreamIds, kInvalidWithSecondLayerExpandedLayout,
1714                    unused_substream_id_to_labels, unused_label_to_output_gain,
1715                    unused_channel_numbers_for_layer)
1716                    .ok());
1717 }
1718 
TEST(FinalizeScalableChannelLayoutConfig,InvalidWithExpandedLoudspeakerLayoutIsInconsistent)1719 TEST(FinalizeScalableChannelLayoutConfig,
1720      InvalidWithExpandedLoudspeakerLayoutIsInconsistent) {
1721   const std::vector<DecodedUleb128> kSubstreamIds = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1722   const ScalableChannelLayoutConfig
1723       kInvaliWithInconsistentExpandedLoudspeakerLayout{
1724           .num_layers = 1,
1725           .channel_audio_layer_configs = {
1726               {.loudspeaker_layout = ChannelAudioLayerConfig::kLayoutExpanded,
1727                .output_gain_is_present_flag = false,
1728                .substream_count = 9,
1729                .coupled_substream_count = 7,
1730                .expanded_loudspeaker_layout = std::nullopt}}};
1731   SubstreamIdLabelsMap unused_substream_id_to_labels;
1732   LabelGainMap unused_label_to_output_gain;
1733   std::vector<ChannelNumbers> unused_channel_numbers_for_layer;
1734 
1735   EXPECT_FALSE(ObuWithDataGenerator::FinalizeScalableChannelLayoutConfig(
1736                    kSubstreamIds,
1737                    kInvaliWithInconsistentExpandedLoudspeakerLayout,
1738                    unused_substream_id_to_labels, unused_label_to_output_gain,
1739                    unused_channel_numbers_for_layer)
1740                    .ok());
1741 }
1742 
1743 }  // namespace
1744 }  // namespace iamf_tools
1745