1 /*
2 * Copyright (c) 2025, 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/proto_conversion/downmixing_reconstruction_util.h"
14
15 #include "absl/container/flat_hash_map.h"
16 #include "absl/container/flat_hash_set.h"
17 #include "absl/status/status.h"
18 #include "absl/status/statusor.h"
19 #include "absl/strings/str_cat.h"
20 #include "iamf/cli/audio_element_with_data.h"
21 #include "iamf/cli/channel_label.h"
22 #include "iamf/cli/demixing_module.h"
23 #include "iamf/cli/proto/user_metadata.pb.h"
24 #include "iamf/cli/proto_conversion/channel_label_utils.h"
25 #include "iamf/common/utils/macros.h"
26 #include "iamf/obu/types.h"
27
28 namespace iamf_tools {
29
30 absl::StatusOr<absl::flat_hash_map<
31 DecodedUleb128, DemixingModule::DownmixingAndReconstructionConfig>>
CreateAudioElementIdToDemixingMetadata(const iamf_tools_cli_proto::UserMetadata & user_metadata,const absl::flat_hash_map<DecodedUleb128,AudioElementWithData> & audio_elements)32 CreateAudioElementIdToDemixingMetadata(
33 const iamf_tools_cli_proto::UserMetadata& user_metadata,
34 const absl::flat_hash_map<DecodedUleb128, AudioElementWithData>&
35 audio_elements) {
36 absl::flat_hash_map<DecodedUleb128,
37 DemixingModule::DownmixingAndReconstructionConfig>
38 result;
39 // For each AudioFrameObuMetadata, we pull out the audio element ID, find
40 // the matching AudioElementWithData, and convert the proto labels to internal
41 // labels, and pair up the converted labels with `substream_id_to_labels` and
42 // `label_to_output_gain` from the AudioElementWithData.
43 for (const iamf_tools_cli_proto::AudioFrameObuMetadata&
44 user_audio_frame_metadata : user_metadata.audio_frame_metadata()) {
45 const auto audio_element_id = user_audio_frame_metadata.audio_element_id();
46 absl::flat_hash_map<DecodedUleb128, AudioElementWithData>::const_iterator
47 audio_element = audio_elements.find(audio_element_id);
48 if (audio_element == audio_elements.end()) {
49 return absl::InvalidArgumentError(
50 absl::StrCat("Audio Element ID= ", audio_element_id, " not found"));
51 }
52 absl::flat_hash_set<ChannelLabel::Label> user_channel_labels;
53 RETURN_IF_NOT_OK(ChannelLabelUtils::SelectConvertAndFillLabels(
54 user_audio_frame_metadata, user_channel_labels));
55 const auto& audio_element_with_data = audio_element->second;
56 result[audio_element_id] = {user_channel_labels,
57 audio_element_with_data.substream_id_to_labels,
58 audio_element_with_data.label_to_output_gain};
59 }
60
61 return result;
62 }
63
64 } // namespace iamf_tools
65