• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023, 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 #include "iamf/cli/codec/aac_decoder.h"
13 
14 #include <algorithm>
15 #include <cstddef>
16 #include <cstdint>
17 #include <cstdlib>
18 #include <vector>
19 
20 #include "absl/functional/any_invocable.h"
21 #include "absl/types/span.h"
22 #include "iamf/common/utils/sample_processing_utils.h"
23 
24 // This symbol conflicts with `aacenc_lib.h` and `aacdecoder_lib.h`.
25 #ifdef IS_LITTLE_ENDIAN
26 #undef IS_LITTLE_ENDIAN
27 #endif
28 
29 #include "absl/log/log.h"
30 #include "absl/status/status.h"
31 #include "absl/strings/str_cat.h"
32 #include "absl/strings/string_view.h"
33 #include "iamf/cli/codec/aac_utils.h"
34 #include "iamf/cli/codec/decoder_base.h"
35 #include "iamf/common/utils/macros.h"
36 #include "iamf/common/write_bit_buffer.h"
37 #include "iamf/obu/codec_config.h"
38 #include "iamf/obu/decoder_config/aac_decoder_config.h"
39 #include "libAACdec/include/aacdecoder_lib.h"
40 #include "libSYS/include/machine_type.h"
41 
42 namespace iamf_tools {
43 
44 namespace {
45 
46 // Converts an AAC_DECODER_ERROR to an absl::Status.
AacDecoderErrorToAbslStatus(AAC_DECODER_ERROR aac_error_code,absl::string_view error_message)47 absl::Status AacDecoderErrorToAbslStatus(AAC_DECODER_ERROR aac_error_code,
48                                          absl::string_view error_message) {
49   absl::StatusCode status_code;
50   switch (aac_error_code) {
51     case AAC_DEC_OK:
52       return absl::OkStatus();
53     case AAC_DEC_OUT_OF_MEMORY:
54       status_code = absl::StatusCode::kResourceExhausted;
55       break;
56     case AAC_DEC_TRANSPORT_SYNC_ERROR:
57     case AAC_DEC_NOT_ENOUGH_BITS:
58     case AAC_DEC_INVALID_HANDLE:
59     case AAC_DEC_UNSUPPORTED_AOT:
60     case AAC_DEC_UNSUPPORTED_FORMAT:
61     case AAC_DEC_UNSUPPORTED_ER_FORMAT:
62     case AAC_DEC_UNSUPPORTED_EPCONFIG:
63     case AAC_DEC_UNSUPPORTED_MULTILAYER:
64     case AAC_DEC_UNSUPPORTED_CHANNELCONFIG:
65     case AAC_DEC_UNSUPPORTED_SAMPLINGRATE:
66     case AAC_DEC_INVALID_SBR_CONFIG:
67     case AAC_DEC_SET_PARAM_FAIL:
68     case AAC_DEC_OUTPUT_BUFFER_TOO_SMALL:
69     case AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD:
70     case AAC_DEC_UNSUPPORTED_SBA:
71     case AAC_DEC_ANC_DATA_ERROR:
72     case AAC_DEC_TOO_SMALL_ANC_BUFFER:
73     case AAC_DEC_TOO_MANY_ANC_ELEMENTS:
74       status_code = absl::StatusCode::kInvalidArgument;
75       break;
76     case AAC_DEC_NEED_TO_RESTART:
77       status_code = absl::StatusCode::kFailedPrecondition;
78       break;
79     // Several error codes usually imply that the bitstream is corrupt.
80     case AAC_DEC_TRANSPORT_ERROR:
81     case AAC_DEC_PARSE_ERROR:
82     case AAC_DEC_DECODE_FRAME_ERROR:
83     case AAC_DEC_INVALID_CODE_BOOK:
84     case AAC_DEC_UNSUPPORTED_PREDICTION:
85     case AAC_DEC_UNSUPPORTED_CCE:
86     case AAC_DEC_UNSUPPORTED_LFE:
87     case AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA:
88     case AAC_DEC_CRC_ERROR:
89     case AAC_DEC_RVLC_ERROR:
90     case AAC_DEC_TNS_READ_ERROR:
91       status_code = absl::StatusCode::kDataLoss;
92       break;
93     default:
94       status_code = absl::StatusCode::kUnknown;
95       break;
96   }
97 
98   return absl::Status(
99       status_code,
100       absl::StrCat(error_message, " AAC_DECODER_ERROR= ", aac_error_code));
101 }
102 
ConfigureAacDecoder(const AacDecoderConfig & raw_aac_decoder_config,int num_channels,AAC_DECODER_INSTANCE * decoder_)103 absl::Status ConfigureAacDecoder(const AacDecoderConfig& raw_aac_decoder_config,
104                                  int num_channels,
105                                  AAC_DECODER_INSTANCE* decoder_) {
106   // Configure `fdk_aac` with the audio specific config which has the correct
107   // number of channels in it. IAMF may share a decoder config for several
108   // substreams, so the raw value may not be accurate.
109   AudioSpecificConfig fdk_audio_specific_config =
110       raw_aac_decoder_config.decoder_specific_info_.audio_specific_config;
111   fdk_audio_specific_config.channel_configuration_ = num_channels;
112 
113   // Serialize the modified config. Assume a reasonable default size, but let
114   // the buffer be resizable to be safe.
115   const size_t kMaxAudioSpecificConfigSize = 5;
116   WriteBitBuffer wb(kMaxAudioSpecificConfigSize);
117   const absl::Status status = fdk_audio_specific_config.ValidateAndWrite(wb);
118 
119   if (status.ok() && wb.IsByteAligned()) {
120     // Transform data from `const uint_t*` to `UCHAR*` to match the `libaac`
121     // interface.
122     std::vector<UCHAR> libaac_audio_specific_config(wb.bit_buffer().size());
123     std::transform(wb.bit_buffer().begin(), wb.bit_buffer().end(),
124                    libaac_audio_specific_config.begin(),
125                    [](uint8_t c) { return static_cast<UCHAR>(c); });
126 
127     // Configure `decoder_` with the serialized data.
128     UCHAR* conf[] = {libaac_audio_specific_config.data()};
129     const UINT length[] = {static_cast<UINT>(wb.bit_offset() / 8)};
130     aacDecoder_ConfigRaw(decoder_, conf, length);
131   } else {
132     LOG(ERROR) << "Erroring writing audio specific config: " << status
133                << " wrote " << wb.bit_offset() << " bits.";
134   }
135 
136   return status;
137 }
138 
139 }  // namespace
140 
AacDecoder(const CodecConfigObu & codec_config_obu,int num_channels)141 AacDecoder::AacDecoder(const CodecConfigObu& codec_config_obu, int num_channels)
142     : DecoderBase(num_channels,
143                   static_cast<int>(codec_config_obu.GetNumSamplesPerFrame())),
144       aac_decoder_config_(std::get<AacDecoderConfig>(
145           codec_config_obu.GetCodecConfig().decoder_config)) {}
146 
~AacDecoder()147 AacDecoder::~AacDecoder() {
148   if (decoder_ != nullptr) {
149     aacDecoder_Close(decoder_);
150   }
151 }
152 
Initialize()153 absl::Status AacDecoder::Initialize() {
154   // Initialize the decoder.
155   decoder_ = aacDecoder_Open(GetAacTransportationType(), /*nrOfLayers=*/1);
156 
157   if (decoder_ == nullptr) {
158     return absl::UnknownError("Failed to initialize AAC decoder.");
159   }
160 
161   RETURN_IF_NOT_OK(
162       ConfigureAacDecoder(aac_decoder_config_, num_channels_, decoder_));
163 
164   const auto* stream_info = aacDecoder_GetStreamInfo(decoder_);
165   LOG_FIRST_N(INFO, 1) << "Created an AAC encoder with "
166                        << stream_info->numChannels << " channels.";
167 
168   return absl::OkStatus();
169 }
170 
DecodeAudioFrame(const std::vector<uint8_t> & encoded_frame)171 absl::Status AacDecoder::DecodeAudioFrame(
172     const std::vector<uint8_t>& encoded_frame) {
173   num_valid_ticks_ = 0;
174 
175   // Transform the data and feed it to the decoder.
176   std::vector<UCHAR> input_data(encoded_frame.size());
177   std::transform(encoded_frame.begin(), encoded_frame.end(), input_data.begin(),
178                  [](uint8_t c) { return static_cast<UCHAR>(c); });
179 
180   UCHAR* in_buffer[] = {input_data.data()};
181   const UINT buffer_size[] = {static_cast<UINT>(encoded_frame.size())};
182   UINT bytes_valid = static_cast<UINT>(encoded_frame.size());
183   RETURN_IF_NOT_OK(AacDecoderErrorToAbslStatus(
184       aacDecoder_Fill(decoder_, in_buffer, buffer_size, &bytes_valid),
185       "Failed on `aacDecoder_Fill`: "));
186   if (bytes_valid != 0) {
187     return absl::InvalidArgumentError(
188         "The input frame failed to decode. It may not have been a "
189         "complete AAC frame.");
190   }
191 
192   // Retrieve the decoded frame. `fdk_aac` decodes to INT_PCM (usually 16-bits)
193   // samples with channels interlaced.
194   std::vector<INT_PCM> output_pcm(num_samples_per_channel_ * num_channels_);
195   RETURN_IF_NOT_OK(AacDecoderErrorToAbslStatus(
196       aacDecoder_DecodeFrame(decoder_, output_pcm.data(), output_pcm.size(),
197                              /*flags=*/0),
198       "Failed on `aacDecoder_DecodeFrame`: "));
199 
200   // Arrange the interleaved data in (time, channel) axes with samples stored in
201   // the upper bytes of an `int32_t`.
202   const absl::AnyInvocable<absl::Status(INT_PCM, int32_t&) const>
203       kAacInternalTypeToInt32 = [](INT_PCM input, int32_t& output) {
204         output = static_cast<int32_t>(input) << (32 - GetFdkAacBitDepth());
205         return absl::OkStatus();
206       };
207   return ConvertInterleavedToTimeChannel(absl::MakeConstSpan(output_pcm),
208                                          num_channels_, kAacInternalTypeToInt32,
209                                          decoded_samples_, num_valid_ticks_);
210 }
211 
212 }  // namespace iamf_tools
213