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