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 #ifndef OBU_PARAMETER_BLOCK_H_ 13 #define OBU_PARAMETER_BLOCK_H_ 14 15 #include <cstdint> 16 #include <memory> 17 #include <optional> 18 #include <vector> 19 20 #include "absl/container/flat_hash_map.h" 21 #include "absl/status/status.h" 22 #include "absl/status/statusor.h" 23 #include "iamf/common/read_bit_buffer.h" 24 #include "iamf/common/write_bit_buffer.h" 25 #include "iamf/obu/mix_gain_parameter_data.h" 26 #include "iamf/obu/obu_base.h" 27 #include "iamf/obu/obu_header.h" 28 #include "iamf/obu/param_definition_variant.h" 29 #include "iamf/obu/param_definitions.h" 30 #include "iamf/obu/parameter_data.h" 31 #include "iamf/obu/types.h" 32 33 namespace iamf_tools { 34 35 /*!\brief An element of the Parameter Block OBU's `subblocks` vector. */ 36 struct ParameterSubblock { 37 /*!\brief Reads and validates the parameter subblock. 38 * 39 * \param param_definition Parameter definition. 40 * \param rb Buffer to read from. 41 * \return `absl::OkStatus()`. Or a specific error code on failure. 42 */ 43 absl::Status ReadAndValidate(const ParamDefinition& param_definition, 44 ReadBitBuffer& rb); 45 46 /*!\brief Validates and writes to a buffer. 47 * 48 * \param wb Buffer to write to. 49 * \return `absl::OkStatus()` if successful. A specific status on failure. 50 */ 51 absl::Status Write(WriteBitBuffer& wb) const; 52 53 /*!\brief Prints the parameter subblock. 54 */ 55 void Print() const; 56 57 // `subblock_duration` is conditionally included based on 58 // `param_definition_mode` and `constant_subblock_duration`. 59 std::optional<DecodedUleb128> subblock_duration; 60 61 // The active field depends on `param_definition_type` in the metadata. 62 std::unique_ptr<ParameterData> param_data; 63 }; 64 65 /*!\brief A Parameter Block OBU. 66 * 67 * The metadata specified in this OBU defines the parameter values for an 68 * algorithm for an indicated duration, including any animation of the parameter 69 * values over this duration. 70 */ 71 class ParameterBlockObu : public ObuBase { 72 public: 73 /*!\brief Creates a `ParameterBlockObu` from a `ReadBitBuffer`. 74 * 75 * This function is designed to be used from the perspective of the decoder. 76 * It will call `ReadAndValidatePayload` in order to read from the buffer; 77 * therefore it can fail. 78 * 79 * \param header `ObuHeader` of the OBU. 80 * \param payload_size Size of the obu payload in bytes. 81 * \param param_definition_variants Mapping from parameter IDs to param 82 * definitions. 83 * \param rb `ReadBitBuffer` where the `ParameterBlockObu` data is stored. 84 * Data read from the buffer is consumed. 85 * \return Unique pointer to a `ParameterBlockObu` on success. A specific 86 * status on failure. 87 */ 88 static absl::StatusOr<std::unique_ptr<ParameterBlockObu>> CreateFromBuffer( 89 const ObuHeader& header, int64_t payload_size, 90 const absl::flat_hash_map<DecodedUleb128, ParamDefinitionVariant>& 91 param_definition_variants, 92 ReadBitBuffer& rb); 93 94 /*!\brief Constructor. 95 * 96 * After constructing `InitializeSubblocks()` MUST be called and return 97 * successfully before using most functionality of the OBU. 98 * 99 * \param header `ObuHeader` of the OBU. 100 * \param parameter_id Parameter ID. 101 * \param param_definition Parameter definition. 102 */ 103 ParameterBlockObu(const ObuHeader& header, DecodedUleb128 parameter_id, 104 const ParamDefinition& param_definition); 105 106 /*!\brief Destructor. */ 107 ~ParameterBlockObu() override = default; 108 109 /*!\brief Interpolate the value of a `MixGainParameterData`. 110 * 111 * \param mix_gain_parameter_data `MixGainParameterData` to interpolate. 112 * \param start_time Start time of the `MixGainParameterData`. 113 * \param end_time End time of the `MixGainParameterData`. 114 * \param target_time Target time to get the interpolated value of. 115 * \param target_mix_gain_db Output inteprolated mix gain value in dB. 116 * \return `absl::OkStatus()` on success. A specific status on failure. 117 */ 118 static absl::Status InterpolateMixGainParameterData( 119 const MixGainParameterData* mix_gain_parameter_data, 120 InternalTimestamp start_time, InternalTimestamp end_time, 121 InternalTimestamp target_time, float& target_mix_gain_db); 122 123 /*!\brief Gets the duration of the parameter block. 124 * 125 * \return Duration of the OBU. 126 */ 127 DecodedUleb128 GetDuration() const; 128 129 /*!\brief Gest the constant subblock interval of the OBU. 130 * 131 * \return Constant subblock duration of the OBU. 132 */ 133 DecodedUleb128 GetConstantSubblockDuration() const; 134 135 /*!\brief Gets the number of subblocks of the OBU. 136 * 137 * \return Number of subblocks of the OBU. 138 */ 139 DecodedUleb128 GetNumSubblocks() const; 140 141 /*!\brief Gets the duration of the subblock. 142 * 143 * \param subblock_index Index of the subblock to get the duration of. 144 * \return Duration of the subblock or `absl::InvalidArgumentError()` on 145 * failure. 146 */ 147 absl::StatusOr<DecodedUleb128> GetSubblockDuration(int subblock_index) const; 148 149 /*!\brief Sets the `duration` of a subblock in the output OBU or metadata. 150 * 151 * May modify the metadata or the OBU as required by `param_definition_mode`. 152 * The duration field within the subblock of a `ParameterBlockObu` only has 153 * semantic meaning and is serialized with the OBU when 154 * `param_definition_mode == 1 && constant_subblock_duration != 0` as per the 155 * IAMF spec. This function zeroes out the duration field within the subblock 156 * of a `ParameterBlockObu` when it has no semantic meaning. 157 * 158 * \param subblock_index Index of the subblock to set. 159 * \param duration `duration` to set. 160 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` on 161 * failure. 162 */ 163 absl::Status SetSubblockDuration(int subblock_index, DecodedUleb128 duration); 164 165 /*!\brief Outputs the linear mix gain at the target time. 166 * 167 * \param obu_relative_time Time relative to the start of the OBU to get the 168 * mix gain of. 169 * \param linear_mix_gain Output linear mix gain converted from a dB value 170 * stored as Q7.8. 171 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` on 172 * failure. 173 */ 174 absl::Status GetLinearMixGain(InternalTimestamp obu_relative_time, 175 float& linear_mix_gain) const; 176 177 /*!\brief Initialize the vector of subblocks. 178 * 179 * \param duration Duration of the parameter block. 180 * \param constant_subblock_duration Constant subblock duration. 181 * \param num_subblocks Number of subblocks. 182 * \return `absl::OkStatus()` if successful. A specific status on failure. 183 */ 184 absl::Status InitializeSubblocks(DecodedUleb128 duration, 185 DecodedUleb128 constant_subblock_duration, 186 DecodedUleb128 num_subblocks); 187 188 /*!\brief Initialize the vector of subblocks using existing information. 189 * 190 * This should only be called if the `param_definition_mode == 0`, 191 * and the `duration`, `constant_subblock_duration`, and `num_subblocks` 192 * defined in the `metadata_.param_definition` are already correct. 193 * 194 * \return `absl::OkStatus()` if successful. A specific status on failure. 195 */ 196 absl::Status InitializeSubblocks(); 197 198 /*!\brief Prints logging information about the OBU.*/ 199 void PrintObu() const override; 200 201 // Mapped from an Audio Element or Mix Presentation OBU parameter ID. 202 const DecodedUleb128 parameter_id_; 203 204 // Length `num_subblocks_`. 205 std::vector<ParameterSubblock> subblocks_; 206 207 private: 208 /*!\brief Sets the `duration` of the output OBU or metadata. 209 * 210 * May modify the metadata or the OBU as required by `param_definition_mode`. 211 * 212 * \param duration `duration` to set. 213 */ 214 void SetDuration(DecodedUleb128 duration); 215 216 /*!\brief Sets the `constant_subblock_duration` of the output OBU or metadata. 217 * 218 * May modify the metadata or the OBU as required by `param_definition_mode`. 219 * 220 * \param constant_subblock_duration `constant_subblock_duration` to set. 221 */ 222 void SetConstantSubblockDuration(DecodedUleb128 constant_subblock_duration); 223 224 /*!\brief Sets the `num_subblocks` of the output OBU or metadata. 225 * 226 * May modify the metadata or the OBU as required by `param_definition_mode`. 227 * 228 * \param num_subblocks `num_subblocks` to set. 229 */ 230 void SetNumSubblocks(DecodedUleb128 num_subblocks); 231 232 /*!\brief Writes the OBU payload to the buffer. 233 * 234 * \param wb Buffer to write to. 235 * \return `absl::OkStatus()` if the payload is valid. A specific status on 236 * failure. 237 */ 238 absl::Status ValidateAndWritePayload(WriteBitBuffer& wb) const override; 239 240 /*!\brief Reads the OBU payload from the buffer. 241 * 242 * \param payload_size Size of the obu payload in bytes. 243 * \param rb Buffer to read from. 244 * \return `absl::OkStatus()` if the payload is valid. A specific status on 245 * failure. 246 */ 247 absl::Status ReadAndValidatePayloadDerived(int64_t payload_size, 248 ReadBitBuffer& rb) override; 249 250 // `duration` and `constant_subblock_duration` are conditionally included 251 // based on `param_definition_mode`. 252 DecodedUleb128 duration_; 253 DecodedUleb128 constant_subblock_duration_; 254 255 // `num_subblocks` is only included if `param_definition_mode == 0` and 256 // `constant_subblock_duration_ == 0`. 257 DecodedUleb128 num_subblocks_; 258 259 // Parameter definition corresponding to this parameter block. 260 const ParamDefinition& param_definition_; 261 262 // Tracks whether the OBU was initialized correctly. 263 absl::Status init_status_ = 264 absl::UnknownError("Parameter Block OBU was not initialized correctly"); 265 }; 266 267 } // namespace iamf_tools 268 269 #endif // OBU_PARAMETER_BLOCK_H_ 270