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_FLAC_DECODER_CONFIG_H_ 13 #define OBU_DECODER_CONFIG_FLAC_DECODER_CONFIG_H_ 14 15 #include <array> 16 #include <cstdint> 17 #include <variant> 18 #include <vector> 19 20 #include "absl/status/status.h" 21 #include "iamf/common/read_bit_buffer.h" 22 #include "iamf/common/write_bit_buffer.h" 23 24 namespace iamf_tools { 25 26 struct FlacStreamInfoConstraints { 27 // Required 0 audio_roll_distance as per IAMF spec. 28 static constexpr int16_t kAudioRollDistance = 0; 29 30 // Block size must be equal to num_samples_per_frame and at least 16, as per 31 // FLAC spec. 32 static constexpr uint16_t kMinMinAndMaxBlockSize = 16; 33 34 // IAMF requires frame_size fields to have fixed values. 35 static constexpr uint32_t kMinFrameSize = 0; 36 static constexpr uint32_t kMaxFrameSize = 0; 37 38 // In IAMF the number_of_channels is fixed to `1`, but can be ignored when 39 // reading / decoding. The actual number of channels is determined on a 40 // per-substream basis based on the audio element. 41 static constexpr uint8_t kNumberOfChannels = 1; 42 43 // Required signature, as per IAMF spec. 44 static constexpr std::array<uint8_t, 16> kMd5Signature = {0}; 45 46 // Acceptable ranges for sample_rate, bits_per_sample, and 47 // totals_samples_in_stream from the FLAC documentation. 48 static constexpr uint32_t kMinSampleRate = 1; 49 static constexpr uint32_t kMaxSampleRate = 655350; 50 static constexpr uint8_t kMinBitsPerSample = 3; 51 static constexpr uint8_t kMaxBitsPerSample = 31; 52 // FLAC allows a value of 0 to represent an unknown total number of samples. 53 static constexpr uint64_t kMinTotalSamplesInStream = 0; 54 static constexpr uint64_t kMaxTotalSamplesInStream = 0xfffffffff; 55 }; 56 57 struct FlacMetaBlockStreamInfo { 58 friend bool operator==(const FlacMetaBlockStreamInfo& lhs, 59 const FlacMetaBlockStreamInfo& rhs) = default; 60 61 uint16_t minimum_block_size; 62 uint16_t maximum_block_size; 63 uint32_t minimum_frame_size = 64 FlacStreamInfoConstraints::kMinFrameSize; // 24 bits. 65 uint32_t maximum_frame_size = 66 FlacStreamInfoConstraints::kMaxFrameSize; // 24 bits. 67 uint32_t sample_rate; // 20 bits. 68 uint8_t number_of_channels = 69 FlacStreamInfoConstraints::kNumberOfChannels; // 3 bits. 70 uint8_t bits_per_sample; // 5 bits. 71 uint64_t total_samples_in_stream; // 36 bits. 72 std::array<uint8_t, 16> md5_signature = 73 FlacStreamInfoConstraints::kMd5Signature; 74 }; 75 76 /*!\brief The header portion of a metadata block described in the FLAC spec. */ 77 struct FlacMetaBlockHeader { 78 /*!\brief An 8-bit enum for the type of FLAC block. 79 * 80 * See `BLOCK_TYPE` in the FLAC spec. 81 */ 82 enum FlacBlockType : uint8_t { 83 kFlacStreamInfo = 0, 84 kFlacPadding = 1, 85 kFlacApplication = 2, 86 kFlacSeektable = 3, 87 kFlacVorbisComment = 4, 88 kFlacCuesheet = 5, 89 kFlacPicture = 6, 90 // 7 - 126 are reserved. 91 kFlacInvalid = 127, 92 }; 93 94 friend bool operator==(const FlacMetaBlockHeader& lhs, 95 const FlacMetaBlockHeader& rhs) = default; 96 97 bool last_metadata_block_flag; 98 FlacBlockType block_type; // 7 bits. 99 uint32_t metadata_data_block_length; // 24 bits. 100 }; 101 102 struct FlacMetadataBlock { 103 friend bool operator==(const FlacMetadataBlock& lhs, 104 const FlacMetadataBlock& rhs) = default; 105 106 FlacMetaBlockHeader header; 107 108 // When `header.block_type == kFlacStreamInfo` this is 109 // `FlacMetaBlockStreamInfo`. Otherwise IAMF just passes along the data. 110 std::variant<FlacMetaBlockStreamInfo, std::vector<uint8_t> > payload; 111 }; 112 /*!\brief The `CodecConfig` `decoder_config` field for FLAC.*/ 113 class FlacDecoderConfig { 114 public: 115 friend bool operator==(const FlacDecoderConfig& lhs, 116 const FlacDecoderConfig& rhs) = default; 117 118 /*!\brief Returns the required audio roll distance. 119 * 120 * \return Audio roll distance required by the IAMF spec. 121 */ GetRequiredAudioRollDistance()122 static int16_t GetRequiredAudioRollDistance() { 123 return FlacStreamInfoConstraints::kAudioRollDistance; 124 } 125 126 /*!\brief Validates and writes the `FlacDecoderConfig` to a buffer. 127 * 128 * \param num_samples_per_frame `num_samples_per_frame` in the associated 129 * Codec Config OBU. 130 * \param audio_roll_distance `audio_roll_distance` in the associated Codec 131 * Config OBU. 132 * \param wb Buffer to write to. 133 * \return `absl::OkStatus()` if the decoder config is valid. A specific 134 * status on failure. 135 */ 136 absl::Status ValidateAndWrite(uint32_t num_samples_per_frame, 137 int16_t audio_roll_distance, 138 WriteBitBuffer& wb) const; 139 140 /*!\brief Reads and validates the `FlacDecoderConfig` from a buffer. 141 * 142 * \param num_samples_per_frame `num_samples_per_frame` in the associated 143 * Codec Config OBU. 144 * \param audio_roll_distance `audio_roll_distance` in the associated Codec 145 * Config OBU. 146 * \param rb Buffer to read from. 147 * \return `absl::OkStatus()` if the decoder config is valid. A specific error 148 * code on failure. 149 */ 150 absl::Status ReadAndValidate(uint32_t num_samples_per_frame, 151 int16_t audio_roll_distance, ReadBitBuffer& rb); 152 153 /*!\brief Gets the output sample rate represented within the decoder config. 154 * 155 * This sample rate is used for timing and offset calculations. 156 * 157 * IAMF v1.1.0 section 3.11.3 specifies: 158 * > "The sample rate used for computing offsets SHALL be the sampling rate 159 * indicated in the METADATA_BLOCK." 160 * 161 * \param output_sample_rate Output sample rate. 162 * \return `absl::OkStatus()` if successful. `absl::InvalidArgumentError()` 163 * if the `FlacMetaBlockStreamInfo` cannot be found or if the 164 * retrieved value is invalid. 165 */ 166 absl::Status GetOutputSampleRate(uint32_t& output_sample_rate) const; 167 168 /*!\brief Gets the bit-depth of the PCM to be used to measure loudness. 169 * 170 * This typically is the highest bit-depth the user should decode the signal 171 * to. 172 * 173 * \param bit_depth_to_measure_loudness Bit-depth of the PCM which will be 174 * used to measure loudness. 175 * \return `absl::OkStatus()` if successful. `absl::InvalidArgumentError()` 176 * if the `FlacMetaBlockStreamInfo` cannot be found or if the 177 * retrieved value is invalid. 178 */ 179 absl::Status GetBitDepthToMeasureLoudness( 180 uint8_t& bit_depth_to_measure_loudness) const; 181 182 /*!\brief Gets the `total_samples_in_stream` from a `FlacDecoderConfig`. 183 * 184 * \param total_samples_in_stream Total samples in stream. 185 * \return `absl::OkStatus()` if successful. `absl::InvalidArgumentError()` 186 * if the `FlacMetaBlockStreamInfo` cannot be found or if the 187 * retrieved value is invalid. 188 */ 189 absl::Status GetTotalSamplesInStream(uint64_t& total_samples_in_stream) const; 190 191 /*!\brief Prints logging information about the decoder config. 192 */ 193 void Print() const; 194 195 std::vector<FlacMetadataBlock> metadata_blocks_; 196 }; 197 198 } // namespace iamf_tools 199 200 #endif // OBU_DECODER_CONFIG_FLAC_DECODER_CONFIG_H_ 201