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 #include "iamf/cli/codec/flac_decoder.h"
14
15 #include <algorithm>
16 #include <cstddef>
17 #include <cstdint>
18 #include <vector>
19
20 #include "absl/log/log.h"
21 #include "absl/status/status.h"
22 #include "absl/strings/str_cat.h"
23 #include "iamf/cli/codec/decoder_base.h"
24 #include "include/FLAC/format.h"
25 #include "include/FLAC/ordinals.h"
26 #include "include/FLAC/stream_decoder.h"
27
28 namespace iamf_tools {
29
LibFlacReadCallback(const FLAC__StreamDecoder *,FLAC__byte buffer[],size_t * bytes,void * client_data)30 FLAC__StreamDecoderReadStatus FlacDecoder::LibFlacReadCallback(
31 const FLAC__StreamDecoder* /*decoder*/, FLAC__byte buffer[], size_t* bytes,
32 void* client_data) {
33 auto flac_decoder = static_cast<FlacDecoder*>(client_data);
34 auto encoded_frame = flac_decoder->GetEncodedFrame();
35 if (encoded_frame.empty()) {
36 // No more data to read.
37 *bytes = 0;
38 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
39 }
40 if (encoded_frame.size() > *bytes) {
41 LOG(ERROR) << "Encoded frame size " << encoded_frame.size()
42 << " is larger than the libflac buffer size " << *bytes;
43 *bytes = 0;
44 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
45 }
46 for (int i = 0; i < encoded_frame.size(); ++i) {
47 buffer[i] = encoded_frame[i];
48 }
49 *bytes = encoded_frame.size();
50 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
51 }
52
LibFlacWriteCallback(const FLAC__StreamDecoder *,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)53 FLAC__StreamDecoderWriteStatus FlacDecoder::LibFlacWriteCallback(
54 const FLAC__StreamDecoder* /*decoder*/, const FLAC__Frame* frame,
55 const FLAC__int32* const buffer[], void* client_data) {
56 auto* flac_decoder = static_cast<FlacDecoder*>(client_data);
57 const auto num_samples_per_channel = frame->header.blocksize;
58 if (flac_decoder->GetNumSamplesPerChannel() != frame->header.blocksize) {
59 LOG(ERROR) << "Frame blocksize " << frame->header.blocksize
60 << " does not match expected number of samples per channel "
61 << flac_decoder->GetNumSamplesPerChannel();
62 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
63 }
64 std::vector<std::vector<int32_t>> decoded_samples(
65 num_samples_per_channel, std::vector<int32_t>(frame->header.channels));
66 // Note: libFLAC represents data in a planar fashion, so each channel is
67 // stored in a separate array, and the elements within those arrays represent
68 // time ticks. However, we store samples in an interleaved fashion, which
69 // means that each outer entry in decoded_samples represents a time tick, and
70 // each element within represents a channel. So we need to transpose the data
71 // from libFLAC's planar format into our interleaved format.
72 for (int c = 0; c < frame->header.channels; ++c) {
73 const FLAC__int32* const channel_buffer = buffer[c];
74 for (int t = 0; t < num_samples_per_channel; ++t) {
75 decoded_samples[t][c] = channel_buffer[t]
76 << (32 - frame->header.bits_per_sample);
77 }
78 }
79 flac_decoder->SetDecodedFrame(decoded_samples);
80 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
81 }
82
LibFlacErrorCallback(const FLAC__StreamDecoder *,FLAC__StreamDecoderErrorStatus status,void *)83 void FlacDecoder::LibFlacErrorCallback(const FLAC__StreamDecoder* /*decoder*/,
84 FLAC__StreamDecoderErrorStatus status,
85 void* /*client_data*/) {
86 switch (status) {
87 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
88 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC";
89 break;
90 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
91 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER";
92 break;
93 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
94 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH";
95 break;
96 case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
97 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM";
98 break;
99 default:
100 LOG(ERROR) << "Unknown FLAC__StreamDecoderErrorStatus= " << status;
101 break;
102 }
103 }
104
FlacDecoder(int num_channels,uint32_t num_samples_per_frame)105 FlacDecoder::FlacDecoder(int num_channels, uint32_t num_samples_per_frame)
106 : DecoderBase(num_channels, num_samples_per_frame) {}
107
~FlacDecoder()108 FlacDecoder::~FlacDecoder() {
109 if (decoder_ != nullptr) {
110 FLAC__stream_decoder_delete(decoder_);
111 }
112 }
113
Initialize()114 absl::Status FlacDecoder::Initialize() {
115 decoder_ = FLAC__stream_decoder_new();
116 if (decoder_ == nullptr) {
117 return absl::InternalError("Failed to create FLAC stream decoder.");
118 }
119 FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_stream(
120 decoder_, LibFlacReadCallback, /*seek_callback=*/nullptr,
121 /*tell_callback=*/nullptr, /*length_callback=*/nullptr,
122 /*eof_callback=*/nullptr, LibFlacWriteCallback,
123 /*metadata_callback=*/nullptr, LibFlacErrorCallback,
124 static_cast<void*>(this));
125
126 if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
127 return absl::InternalError(
128 absl::StrCat("Failed to initialize FLAC stream decoder: ", status));
129 }
130 return absl::OkStatus();
131 }
132
Finalize()133 absl::Status FlacDecoder::Finalize() {
134 // Signal to `libflac` the decoder is finished.
135 if (!FLAC__stream_decoder_finish(decoder_)) {
136 return absl::InternalError("Failed to finalize Flac stream decoder.");
137 }
138 return absl::OkStatus();
139 }
140
DecodeAudioFrame(const std::vector<uint8_t> & encoded_frame)141 absl::Status FlacDecoder::DecodeAudioFrame(
142 const std::vector<uint8_t>& encoded_frame) {
143 num_valid_ticks_ = 0;
144
145 // Set the encoded frame to be decoded; the libflac decoder will copy the
146 // data using LibFlacReadCallback.
147 encoded_frame_ = encoded_frame;
148 if (!FLAC__stream_decoder_process_single(decoder_)) {
149 // More specific error information is logged in LibFlacErrorCallback.
150 return absl::InternalError("Failed to decode FLAC frame.");
151 }
152 // Get the decoded frame, which will have been set by LibFlacWriteCallback.
153 // Copy the first `num_valid_ticks_` time samples to `decoded_samples_`.
154 num_valid_ticks_ = decoded_frame_.size();
155 std::copy(decoded_frame_.begin(), decoded_frame_.begin() + num_valid_ticks_,
156 decoded_samples_.begin());
157 return absl::OkStatus();
158 }
159
160 } // namespace iamf_tools
161