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_stream_callbacks.h"
14
15 #include <cstddef>
16 #include <cstdint>
17 #include <vector>
18
19 #include "absl/log/log.h"
20 #include "iamf/cli/codec/flac_decoder.h"
21 #include "include/FLAC/format.h"
22 #include "include/FLAC/ordinals.h"
23 #include "include/FLAC/stream_decoder.h"
24
25 namespace iamf_tools {
26
LibFlacReadCallback(const FLAC__StreamDecoder *,FLAC__byte buffer[],size_t * bytes,void * client_data)27 FLAC__StreamDecoderReadStatus LibFlacReadCallback(
28 const FLAC__StreamDecoder* /*decoder*/, FLAC__byte buffer[], size_t* bytes,
29 void* client_data) {
30 auto flac_decoder = static_cast<FlacDecoder*>(client_data);
31 const auto& encoded_frame = flac_decoder->GetEncodedFrame();
32 if (encoded_frame.empty()) {
33 // No more data to read.
34 *bytes = 0;
35 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
36 }
37 if (encoded_frame.size() > *bytes) {
38 LOG(ERROR) << "Encoded frame size " << encoded_frame.size()
39 << " is larger than the libflac buffer size " << *bytes;
40 *bytes = 0;
41 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
42 }
43 for (int i = 0; i < encoded_frame.size(); ++i) {
44 buffer[i] = encoded_frame[i];
45 }
46 *bytes = encoded_frame.size();
47 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
48 }
49
LibFlacWriteCallback(const FLAC__StreamDecoder *,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)50 FLAC__StreamDecoderWriteStatus LibFlacWriteCallback(
51 const FLAC__StreamDecoder* /*decoder*/, const FLAC__Frame* frame,
52 const FLAC__int32* const buffer[], void* client_data) {
53 std::vector<std::vector<int32_t>> decoded_samples(frame->header.channels);
54 auto* flac_decoder = static_cast<FlacDecoder*>(client_data);
55 const auto num_samples_per_channel = frame->header.blocksize;
56 // Note: libFLAC represents data in a planar fashion, so each channel is
57 // stored in a separate array.
58 for (int i = 0; i < frame->header.channels; ++i) {
59 decoded_samples[i].resize(num_samples_per_channel);
60 const FLAC__int32* const channel_buffer = buffer[i];
61 for (int j = 0; j < num_samples_per_channel; ++j) {
62 decoded_samples[i][j] = static_cast<int32_t>(channel_buffer[j]);
63 }
64 }
65 flac_decoder->SetDecodedFrame(decoded_samples);
66 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
67 }
68
LibFlacErrorCallback(const FLAC__StreamDecoder *,FLAC__StreamDecoderErrorStatus status,void *)69 void LibFlacErrorCallback(const FLAC__StreamDecoder* /*decoder*/,
70 FLAC__StreamDecoderErrorStatus status,
71 void* /*client_data*/) {
72 switch (status) {
73 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
74 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC";
75 break;
76 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
77 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER";
78 break;
79 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
80 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH";
81 break;
82 case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
83 LOG(ERROR) << "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM";
84 break;
85 default:
86 LOG(ERROR) << "Unknown error";
87 break;
88 }
89 }
90
91 } // namespace iamf_tools
92