1 /* 2 * Copyright (c) 2024, 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 13 #ifndef CLI_CODEC_FLAC_DECODER_H_ 14 #define CLI_CODEC_FLAC_DECODER_H_ 15 16 #include <cstddef> 17 #include <cstdint> 18 #include <vector> 19 20 #include "absl/status/status.h" 21 #include "iamf/cli/codec/decoder_base.h" 22 #include "include/FLAC/format.h" 23 #include "include/FLAC/ordinals.h" 24 #include "include/FLAC/stream_decoder.h" 25 namespace iamf_tools { 26 27 /*!brief Decoder for FLAC audio streams. 28 */ 29 class FlacDecoder : public DecoderBase { 30 public: 31 /*!brief Constructor. 32 * 33 * \param num_channels Number of channels for this stream. 34 * \param num_samples_per_frame Number of samples per frame. 35 */ 36 FlacDecoder(int num_channels, uint32_t num_samples_per_frame); 37 38 ~FlacDecoder() override; 39 40 /*!\brief Initializes the underlying libflac decoder. 41 * 42 * \return `absl::OkStatus()` on success. A specific status on failure. 43 */ 44 absl::Status Initialize() override; 45 46 /*!\brief Gets the number of samples per channel. 47 * 48 * \return Number of samples per channel. 49 */ GetNumSamplesPerChannel()50 int GetNumSamplesPerChannel() { return num_samples_per_channel_; } 51 52 /*!\brief Finalizes the underlying libflac decoder. 53 * 54 * \return `absl::OkStatus()` on success. A specific status on failure. 55 */ 56 absl::Status Finalize(); 57 58 /*!\brief Decodes a FLAC audio frame. 59 * 60 * \param encoded_frame Frame to decode. 61 * \return `absl::OkStatus()` on success. A specific status on failure. 62 */ 63 absl::Status DecodeAudioFrame( 64 const std::vector<uint8_t>& encoded_frame) override; 65 66 /*!\brief Sets an encoded FLAC frame in decoder.encoded_frame_. 67 * 68 * \param encoded_frame Encoded FLAC frame. 69 */ SetEncodedFrame(const std::vector<uint8_t> & encoded_frame)70 void SetEncodedFrame(const std::vector<uint8_t>& encoded_frame) { 71 encoded_frame_ = encoded_frame; 72 } 73 74 /*!\brief Retrieves the encoded frame in decoder.encoded_frame_. 75 * 76 * \return Vector of encoded FLAC bytes representing a single frame. 77 */ GetEncodedFrame()78 std::vector<uint8_t> GetEncodedFrame() const { return encoded_frame_; } 79 80 /*!\brief Sets a decoded FLAC frame in decoder.decoded_frame_. 81 * 82 * \param decoded_frame Decoded FLAC frame. 83 */ SetDecodedFrame(const std::vector<std::vector<int32_t>> & decoded_frame)84 void SetDecodedFrame(const std::vector<std::vector<int32_t>>& decoded_frame) { 85 decoded_frame_ = decoded_frame; 86 } 87 88 /*!\brief Retrieves the decoded FLAC frame in decoder.decoded_frame_. 89 * 90 * \return Vector of decoded FLAC samples. 91 */ GetDecodedFrame()92 std::vector<std::vector<int32_t>> GetDecodedFrame() const { 93 return decoded_frame_; 94 } 95 96 /*!\brief Reads an encoded flac frame into the libflac decoder 97 * 98 * This callback function is used whenever the decoder needs more input data. 99 * 100 * \param decoder Unused libflac stream decoder. This parameter is not used in 101 * this implementation, but is included to override the libflac 102 * signature. 103 * \param buffer Output buffer for the encoded frame. 104 * \param bytes Maximum size of the buffer; in the case of a successful read, 105 * this will be set to the actual number of bytes read. 106 * \param client_data universal pointer, which in this case should point to 107 * FlacDecoder. 108 * 109 * \return A libflac read status indicating whether the read was successful. 110 */ 111 static FLAC__StreamDecoderReadStatus LibFlacReadCallback( 112 const FLAC__StreamDecoder* /*decoder*/, FLAC__byte buffer[], 113 size_t* bytes, void* client_data); 114 115 /*!\brief Writes a decoded flac frame to an instance of FlacDecoder. 116 * 117 * This callback function is used to write out a decoded frame from the 118 * libflac decoder. 119 * 120 * \param decoder Unused libflac stream decoder. This parameter is not used in 121 * this implementation, but is included to override the libflac 122 * signature. 123 * \param frame libflac encoded frame metadata. 124 * \param buffer Array of pointers to decoded channels of data. Each pointer 125 * will point to an array of signed samples of length 126 * `frame->header.blocksize`. Channels will be ordered according to the 127 * FLAC specification. 128 * \param client_data Universal pointer, which in this case should point to 129 * FlacDecoder. 130 * 131 * \return A libflac write status indicating whether the write was successful. 132 */ 133 static FLAC__StreamDecoderWriteStatus LibFlacWriteCallback( 134 const FLAC__StreamDecoder* /*decoder*/, const FLAC__Frame* frame, 135 const FLAC__int32* const buffer[], void* client_data); 136 137 /*!\brief Logs an error from the libflac decoder. 138 * 139 * This function will be called whenever an error occurs during libflac 140 * decoding. 141 * 142 * \param decoder Unused libflac stream decoder. This parameter is not used in 143 * this implementation, but is included to override the libflac 144 * signature. 145 * \param status The error encountered by the decoder. 146 * \param client_data Universal pointer, which in this case should point to 147 * FlacDecoder. Unused in this implementation. 148 */ 149 static void LibFlacErrorCallback(const FLAC__StreamDecoder* /*decoder*/, 150 FLAC__StreamDecoderErrorStatus status, 151 void* /*client_data*/); 152 153 private: 154 std::vector<uint8_t> encoded_frame_ = {}; 155 std::vector<std::vector<int32_t>> decoded_frame_ = {}; 156 // A pointer to the `libflac` decoder. 157 FLAC__StreamDecoder* decoder_ = nullptr; 158 }; 159 160 } // namespace iamf_tools 161 162 #endif // CLI_CODEC_FLAC_DECODER_H_ 163