1 /*
2 * Copyright (c) 2023, 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 #include "iamf/cli/proto_conversion/proto_utils.h"
13
14 #include <algorithm>
15 #include <cstdint>
16 #include <memory>
17 #include <string>
18 #include <vector>
19
20 #include "absl/log/log.h"
21 #include "absl/status/status.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/string_view.h"
24 #include "iamf/cli/proto/obu_header.pb.h"
25 #include "iamf/cli/proto/param_definitions.pb.h"
26 #include "iamf/cli/proto/parameter_data.pb.h"
27 #include "iamf/cli/proto_conversion/lookup_tables.h"
28 #include "iamf/common/leb_generator.h"
29 #include "iamf/common/utils/macros.h"
30 #include "iamf/common/utils/map_utils.h"
31 #include "iamf/common/utils/numeric_utils.h"
32 #include "iamf/obu/demixing_info_parameter_data.h"
33 #include "iamf/obu/obu_header.h"
34 #include "iamf/obu/param_definitions.h"
35 #include "iamf/obu/types.h"
36
37 namespace iamf_tools {
38
CopyParamDefinition(const iamf_tools_cli_proto::ParamDefinition & input_param_definition,ParamDefinition & param_definition)39 absl::Status CopyParamDefinition(
40 const iamf_tools_cli_proto::ParamDefinition& input_param_definition,
41 ParamDefinition& param_definition) {
42 param_definition.parameter_id_ = input_param_definition.parameter_id();
43 param_definition.parameter_rate_ = input_param_definition.parameter_rate();
44
45 param_definition.param_definition_mode_ =
46 input_param_definition.param_definition_mode();
47 RETURN_IF_NOT_OK(StaticCastIfInRange<uint32_t, uint8_t>(
48 "ParamDefinition.reserved", input_param_definition.reserved(),
49 param_definition.reserved_));
50 param_definition.duration_ = input_param_definition.duration();
51 param_definition.constant_subblock_duration_ =
52 input_param_definition.constant_subblock_duration();
53
54 if (input_param_definition.constant_subblock_duration() != 0) {
55 // Nothing else to be done. Return.
56 return absl::OkStatus();
57 }
58
59 if (input_param_definition.num_subblocks() <
60 input_param_definition.subblock_durations_size()) {
61 return absl::InvalidArgumentError(absl::StrCat(
62 "Expected at least ", input_param_definition.num_subblocks(),
63 "subblock durations for parameter id = ",
64 input_param_definition.parameter_id()));
65 }
66
67 param_definition.InitializeSubblockDurations(
68 static_cast<DecodedUleb128>(input_param_definition.num_subblocks()));
69 for (int i = 0; i < input_param_definition.num_subblocks(); ++i) {
70 RETURN_IF_NOT_OK(param_definition.SetSubblockDuration(
71 i, input_param_definition.subblock_durations(i)));
72 }
73
74 return absl::OkStatus();
75 }
76
GetHeaderFromMetadata(const iamf_tools_cli_proto::ObuHeaderMetadata & input_obu_header)77 ObuHeader GetHeaderFromMetadata(
78 const iamf_tools_cli_proto::ObuHeaderMetadata& input_obu_header) {
79 std::vector<uint8_t> extension_header_bytes(
80 input_obu_header.extension_header_bytes().size());
81 std::transform(input_obu_header.extension_header_bytes().begin(),
82 input_obu_header.extension_header_bytes().end(),
83 extension_header_bytes.begin(),
84 [](char c) { return static_cast<uint8_t>(c); });
85
86 return ObuHeader{
87 .obu_redundant_copy = input_obu_header.obu_redundant_copy(),
88 .obu_trimming_status_flag = input_obu_header.obu_trimming_status_flag(),
89 .obu_extension_flag = input_obu_header.obu_extension_flag(),
90 .num_samples_to_trim_at_end =
91 input_obu_header.num_samples_to_trim_at_end(),
92 .num_samples_to_trim_at_start =
93 input_obu_header.num_samples_to_trim_at_start(),
94 .extension_header_size = input_obu_header.extension_header_size(),
95 .extension_header_bytes = extension_header_bytes};
96 }
97
CopyDemixingInfoParameterData(const iamf_tools_cli_proto::DemixingInfoParameterData & input_demixing_info_parameter_data,DemixingInfoParameterData & obu_demixing_param_data)98 absl::Status CopyDemixingInfoParameterData(
99 const iamf_tools_cli_proto::DemixingInfoParameterData&
100 input_demixing_info_parameter_data,
101 DemixingInfoParameterData& obu_demixing_param_data) {
102 static const auto kProtoToInternalDMixPMode =
103 BuildStaticMapFromPairs(LookupTables::kProtoAndInternalDMixPModes);
104
105 RETURN_IF_NOT_OK(CopyFromMap(*kProtoToInternalDMixPMode,
106 input_demixing_info_parameter_data.dmixp_mode(),
107 "Internal version of proto `dmixp_mode`",
108 obu_demixing_param_data.dmixp_mode));
109
110 RETURN_IF_NOT_OK(StaticCastIfInRange<uint32_t, uint8_t>(
111 "DemixingInfoParameterData.reserved",
112 input_demixing_info_parameter_data.reserved(),
113 obu_demixing_param_data.reserved));
114
115 return absl::OkStatus();
116 }
117
CopyDMixPMode(DemixingInfoParameterData::DMixPMode obu_dmixp_mode,iamf_tools_cli_proto::DMixPMode & dmixp_mode)118 absl::Status CopyDMixPMode(DemixingInfoParameterData::DMixPMode obu_dmixp_mode,
119 iamf_tools_cli_proto::DMixPMode& dmixp_mode) {
120 static const auto kInternalToProtoDMixPMode = BuildStaticMapFromInvertedPairs(
121 LookupTables::kProtoAndInternalDMixPModes);
122
123 return CopyFromMap(*kInternalToProtoDMixPMode, obu_dmixp_mode,
124 "Proto version of internal `DMixPMode`", dmixp_mode);
125 }
126
CreateLebGenerator(const iamf_tools_cli_proto::Leb128Generator & user_config)127 std::unique_ptr<LebGenerator> CreateLebGenerator(
128 const iamf_tools_cli_proto::Leb128Generator& user_config) {
129 // Transform the enum and possibly `fixed_size` to call LebGenerator::Create.
130 using enum iamf_tools_cli_proto::Leb128GeneratorMode;
131 switch (user_config.mode()) {
132 case GENERATE_LEB_MINIMUM:
133 return LebGenerator::Create(LebGenerator::GenerationMode::kMinimum);
134 case GENERATE_LEB_FIXED_SIZE: {
135 int8_t fixed_size_int8;
136 auto status =
137 StaticCastIfInRange("user_metadata.leb_generator.fixed_size",
138 user_config.fixed_size(), fixed_size_int8);
139 if (!status.ok()) {
140 LOG(ERROR) << status;
141 return nullptr;
142 }
143 return LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize,
144 fixed_size_int8);
145 }
146 default:
147 LOG(ERROR) << "Invalid generation mode: " << user_config.mode();
148 return nullptr;
149 }
150 }
151
152 } // namespace iamf_tools
153