/* * Copyright (c) 2024, Alliance for Open Media. All rights reserved * * This source code is subject to the terms of the BSD 3-Clause Clear License * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear * License was not distributed with this source code in the LICENSE file, you * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the * Alliance for Open Media Patent License 1.0 was not distributed with this * source code in the PATENTS file, you can obtain it at * www.aomedia.org/license/patent. */ #ifndef CLI_CODEC_FLAC_DECODER_H_ #define CLI_CODEC_FLAC_DECODER_H_ #include #include #include #include "absl/status/status.h" #include "iamf/cli/codec/decoder_base.h" #include "include/FLAC/format.h" #include "include/FLAC/ordinals.h" #include "include/FLAC/stream_decoder.h" namespace iamf_tools { /*!brief Decoder for FLAC audio streams. */ class FlacDecoder : public DecoderBase { public: /*!brief Constructor. * * \param num_channels Number of channels for this stream. * \param num_samples_per_frame Number of samples per frame. */ FlacDecoder(int num_channels, uint32_t num_samples_per_frame); ~FlacDecoder() override; /*!\brief Initializes the underlying libflac decoder. * * \return `absl::OkStatus()` on success. A specific status on failure. */ absl::Status Initialize() override; /*!\brief Gets the number of samples per channel. * * \return Number of samples per channel. */ int GetNumSamplesPerChannel() { return num_samples_per_channel_; } /*!\brief Finalizes the underlying libflac decoder. * * \return `absl::OkStatus()` on success. A specific status on failure. */ absl::Status Finalize(); /*!\brief Decodes a FLAC audio frame. * * \param encoded_frame Frame to decode. * \return `absl::OkStatus()` on success. A specific status on failure. */ absl::Status DecodeAudioFrame( const std::vector& encoded_frame) override; /*!\brief Sets an encoded FLAC frame in decoder.encoded_frame_. * * \param encoded_frame Encoded FLAC frame. */ void SetEncodedFrame(const std::vector& encoded_frame) { encoded_frame_ = encoded_frame; } /*!\brief Retrieves the encoded frame in decoder.encoded_frame_. * * \return Vector of encoded FLAC bytes representing a single frame. */ std::vector GetEncodedFrame() const { return encoded_frame_; } /*!\brief Sets a decoded FLAC frame in decoder.decoded_frame_. * * \param decoded_frame Decoded FLAC frame. */ void SetDecodedFrame(const std::vector>& decoded_frame) { decoded_frame_ = decoded_frame; } /*!\brief Retrieves the decoded FLAC frame in decoder.decoded_frame_. * * \return Vector of decoded FLAC samples. */ std::vector> GetDecodedFrame() const { return decoded_frame_; } /*!\brief Reads an encoded flac frame into the libflac decoder * * This callback function is used whenever the decoder needs more input data. * * \param decoder Unused libflac stream decoder. This parameter is not used in * this implementation, but is included to override the libflac * signature. * \param buffer Output buffer for the encoded frame. * \param bytes Maximum size of the buffer; in the case of a successful read, * this will be set to the actual number of bytes read. * \param client_data universal pointer, which in this case should point to * FlacDecoder. * * \return A libflac read status indicating whether the read was successful. */ static FLAC__StreamDecoderReadStatus LibFlacReadCallback( const FLAC__StreamDecoder* /*decoder*/, FLAC__byte buffer[], size_t* bytes, void* client_data); /*!\brief Writes a decoded flac frame to an instance of FlacDecoder. * * This callback function is used to write out a decoded frame from the * libflac decoder. * * \param decoder Unused libflac stream decoder. This parameter is not used in * this implementation, but is included to override the libflac * signature. * \param frame libflac encoded frame metadata. * \param buffer Array of pointers to decoded channels of data. Each pointer * will point to an array of signed samples of length * `frame->header.blocksize`. Channels will be ordered according to the * FLAC specification. * \param client_data Universal pointer, which in this case should point to * FlacDecoder. * * \return A libflac write status indicating whether the write was successful. */ static FLAC__StreamDecoderWriteStatus LibFlacWriteCallback( const FLAC__StreamDecoder* /*decoder*/, const FLAC__Frame* frame, const FLAC__int32* const buffer[], void* client_data); /*!\brief Logs an error from the libflac decoder. * * This function will be called whenever an error occurs during libflac * decoding. * * \param decoder Unused libflac stream decoder. This parameter is not used in * this implementation, but is included to override the libflac * signature. * \param status The error encountered by the decoder. * \param client_data Universal pointer, which in this case should point to * FlacDecoder. Unused in this implementation. */ static void LibFlacErrorCallback(const FLAC__StreamDecoder* /*decoder*/, FLAC__StreamDecoderErrorStatus status, void* /*client_data*/); private: std::vector encoded_frame_ = {}; std::vector> decoded_frame_ = {}; // A pointer to the `libflac` decoder. FLAC__StreamDecoder* decoder_ = nullptr; }; } // namespace iamf_tools #endif // CLI_CODEC_FLAC_DECODER_H_