• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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