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(¶meter_block);
381 } else if (param_definition_type ==
382 ParamDefinition::kParameterDefinitionReconGain) {
383 parameters_manager_->AddReconGainParameterBlock(¶meter_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