• 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_DECODER_CONFIG_AAC_DECODER_CONFIG_H_
13 #define OBU_DECODER_CONFIG_AAC_DECODER_CONFIG_H_
14 
15 #include <cstdint>
16 #include <vector>
17 
18 #include "absl/status/status.h"
19 #include "iamf/common/read_bit_buffer.h"
20 #include "iamf/common/write_bit_buffer.h"
21 
22 namespace iamf_tools {
23 
24 /*!\brief `AudioSpecificConfig` as defined in ISO 14496-3. */
25 class AudioSpecificConfig {
26  public:
27   /*!\brief A 4-bit enum to describe the sampling frequency.
28    *
29    * See `extensionSamplingFrequencyIndex` in ISO-14496.
30    */
31   enum class SampleFrequencyIndex {
32     k96000 = 0,
33     k88200 = 1,
34     k64000 = 2,
35     k48000 = 3,
36     k44100 = 4,
37     k32000 = 5,
38     k24000 = 6,
39     k22050 = 7,
40     k16000 = 8,
41     k12000 = 9,
42     k11025 = 10,
43     k8000 = 11,
44     k7350 = 12,
45     kReservedA = 13,
46     kReservedB = 14,
47     kEscapeValue = 15
48   };
49 
50   static constexpr uint8_t kAudioObjectType = 2;
51   static constexpr uint8_t kChannelConfiguration = 2;
52 
53   friend bool operator==(const AudioSpecificConfig& lhs,
54                          const AudioSpecificConfig& rhs) = default;
55 
56   /*!\brief Validates and writes the `AudioSpecificConfig` to a buffer.
57    *
58    * \return `absl::OkStatus()` if the `AudioSpecificConfig` is valid. A
59    *         specific status on failure.
60    */
61   absl::Status ValidateAndWrite(WriteBitBuffer& wb) const;
62 
63   /*!\brief Reads the `AudioSpecificConfig` from a buffer.
64    *
65    * \param rb Buffer to read from.
66    * \return `absl::OkStatus()` on success. A specific error code on failure.
67    */
68   absl::Status Read(ReadBitBuffer& rb);
69 
70   /*!\brief Prints logging information about the audio specific config.
71    */
72   void Print() const;
73 
74   uint8_t audio_object_type_ = kAudioObjectType;  // 5 bits.
75   SampleFrequencyIndex sample_frequency_index_;   // 4 bits.
76   // if(sample_frequency_index == kSampleFrequencyIndexEscapeValue) {
77   uint32_t sampling_frequency_ = 0;  // 24 bits.
78   // }
79   uint8_t channel_configuration_ = kChannelConfiguration;  // 4 bits.
80 
81   // The ISO spec allows several different types of configs to follow depending
82   // on `audio_object_type`. Valid IAMF streams always use the general audio
83   // specific config because of the fixed `audio_object_type == 2`.
84   struct GaSpecificConfig {
85     static constexpr bool kFrameLengthFlag = false;
86     static constexpr bool kDependsOnCoreCoder = false;
87     static constexpr bool kExtensionFlag = false;
88 
89     friend bool operator==(const GaSpecificConfig& lhs,
90                            const GaSpecificConfig& rhs) = default;
91 
92     bool frame_length_flag = kFrameLengthFlag;
93     bool depends_on_core_coder = kDependsOnCoreCoder;
94     bool extension_flag = kExtensionFlag;
95   } ga_specific_config_;
96 };
97 
98 /*!\brief The `CodecConfig` `decoder_config` field for AAC.
99  *
100  * As defined in IAMF v1.1.0 section 3.11.2
101  * https://aomediacodec.github.io/iamf/#aac-lc-specific. Many fields are fixed
102  * by the IAMF spec and should typically never be changed from their default
103  * values.
104  */
105 class AacDecoderConfig {
106  public:
107   static constexpr uint8_t kDecoderConfigDescriptorTag = 0x04;
108   static constexpr uint8_t kObjectTypeIndication = 0x40;
109   static constexpr uint8_t kStreamType = 0x05;
110   static constexpr bool kUpstream = false;
111   static constexpr bool kReserved = true;
112 
113   friend bool operator==(const AacDecoderConfig& lhs,
114                          const AacDecoderConfig& rhs) = default;
115 
116   /*!\brief Returns the required audio roll distance.
117    *
118    * \return Audio roll distance required by the IAMF spec.
119    */
GetRequiredAudioRollDistance()120   static int16_t GetRequiredAudioRollDistance() { return -1; }
121 
122   /*!\brief Validates the `AacDecoderConfig`.
123    *
124    * \return `absl::OkStatus()` if the decoder config is valid. A specific
125    *         status on failure.
126    */
127   absl::Status Validate() const;
128 
129   /*!\brief Validates and writes the `AacDecoderConfig` to a buffer.
130    *
131    * \param audio_roll_distance `audio_roll_distance` in the associated Codec
132    *        Config OBU.
133    * \param wb Buffer to write to.
134    * \return `absl::OkStatus()` if the decoder config is valid. A specific
135    *         status on failure.
136    */
137   absl::Status ValidateAndWrite(int16_t audio_roll_distance,
138                                 WriteBitBuffer& wb) const;
139 
140   /*!\brief Validates and reads the `AacDecoderConfig` from a buffer.
141    *
142    * \param audio_roll_distance `audio_roll_distance` in the associated Codec
143    *        Config OBU.
144    * \param rb Buffer to read from.
145    * \return `absl::OkStatus()` if the decoder config is valid. A specific error
146    *         code on failure.
147    */
148   absl::Status ReadAndValidate(int16_t audio_roll_distance, ReadBitBuffer& rb);
149 
150   /*!\brief Gets the output sample rate of the `AacDecoderConfig`.
151    *
152    * This sample rate is used for timing and offset calculations.
153    *
154    * IAMF v1.1.0 section 3.11.2 specifies:
155    *  > "The sample rate used for computing offsets SHALL be the rate indicated
156    *     by the samplingFrequencyIndex in GASpecificConfig()."
157    *
158    * \param output_sample_rate Output sample rate.
159    * \return `absl::OkStatus()` if successful. `absl::InvalidArgumentError()`
160    *         if the metadata is an unrecognized type.
161    */
162   absl::Status GetOutputSampleRate(uint32_t& output_sample_rate) const;
163 
164   /*!\brief Gets the bit-depth of the PCM to be used to measure loudness.
165    *
166    * This typically is the highest bit-depth associated substreams should be
167    * decoded to.
168    *
169    * \return Bit-depth of the PCM which will be used to measure loudness if the
170    *         OBU was initialized successfully.
171    */
172   static uint8_t GetBitDepthToMeasureLoudness();
173 
174   /*!\brief Prints logging information about the decoder config.
175    */
176   void Print() const;
177 
178   uint8_t decoder_config_descriptor_tag_ = kDecoderConfigDescriptorTag;
179   // ISO 14496-1 8.3.3 expandable field is inserted automatically.
180   uint8_t object_type_indication_ = kObjectTypeIndication;
181   uint8_t stream_type_ = kStreamType;  // 6 bits.
182   bool upstream_ = kUpstream;
183   bool reserved_ = kReserved;
184   uint32_t buffer_size_db_;  // 24 bits.
185   uint32_t max_bitrate_;
186   uint32_t average_bit_rate_;
187 
188   struct DecoderSpecificInfo {
189     static constexpr uint8_t kDecoderSpecificInfoTag = 0x05;
190 
191     friend bool operator==(const DecoderSpecificInfo& lhs,
192                            const DecoderSpecificInfo& rhs) = default;
193 
194     uint8_t decoder_specific_info_tag = kDecoderSpecificInfoTag;
195     // ISO 14496-1 8.3.3 expandable field is inserted automatically.
196     AudioSpecificConfig audio_specific_config;
197     std::vector<uint8_t> decoder_specific_info_extension;
198   } decoder_specific_info_;
199 
200   std::vector<uint8_t> decoder_config_extension_;
201   // ProfileLevelIndicationIndexDescriptor is an extension in the original
202   // message, but is unused in IAMF.
203 };
204 
205 }  // namespace iamf_tools
206 
207 #endif  // OBU_DECODER_CONFIG_AAC_DECODER_CONFIG_H_
208