1 /*
2 * Copyright (c) 2023-2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_aac_codec.h"
17 #include <cstdint>
18 #include <libswresample/swresample.h>
19 #include <memory>
20 #include <securec.h>
21 #include "const_def.h"
22 #include "sharing_log.h"
23
24 namespace OHOS {
25 namespace Sharing {
26 constexpr uint32_t ADTS_HEADER_SIZE = 7;
27 constexpr uint32_t ADTS_HEADER_BEGIN = 0xFF;
28 constexpr uint32_t ADTS_HEADER_END = 0xFC;
29 constexpr uint32_t ADTS_HEADER_MPEG4_AACLC = 0xF1;
30 constexpr uint32_t ADTS_HEADER_PROFILE_SHIFT = 6;
31 constexpr uint32_t ADTS_HEADER_SAMPLE_MASK = 0x0F;
32 constexpr uint32_t ADTS_HEADER_SAMPLE_SHIFT = 2;
33 constexpr uint32_t ADTS_HEADER_CHANNEL_SHIFT = 2;
34 constexpr uint32_t ADTS_HEADER_CHANNEL_MASK = 0x01;
35 constexpr uint32_t ADTS_HEADER_CHANNEL_SHIFT1 = 6;
36 constexpr uint32_t ADTS_HEADER_CHANNEL_MASK1 = 0x03;
37 constexpr uint32_t ADTS_HEADER_DATA_SZIE_OFFSET = 7;
38 constexpr uint32_t ADTS_HEADER_DATA_SZIE_SHIFT = 11;
39 constexpr uint32_t ADTS_HEADER_DATA_SZIE_SHIFT1 = 3;
40 constexpr uint32_t ADTS_HEADER_DATA_SZIE_SHIFT2 = 5;
41 constexpr uint32_t ADTS_HEADER_DATA_SZIE_MASK = 0xFF;
42 constexpr uint32_t ADTS_HEADER_DATA_SZIE_MASK1 = 0x1F;
43 constexpr uint32_t ADTS_HEADER_INDEX_2 = 2;
44 constexpr uint32_t ADTS_HEADER_INDEX_3 = 3;
45 constexpr uint32_t ADTS_HEADER_INDEX_4 = 4;
46 constexpr uint32_t ADTS_HEADER_INDEX_5 = 5;
47 constexpr uint32_t ADTS_HEADER_INDEX_6 = 6;
48
AudioAACDecoder()49 AudioAACDecoder::AudioAACDecoder()
50 {
51 SHARING_LOGD("trace.");
52 }
53
~AudioAACDecoder()54 AudioAACDecoder::~AudioAACDecoder()
55 {
56 SHARING_LOGD("trace.");
57 if (avFrame_) {
58 av_frame_free(&avFrame_);
59 }
60
61 if (avPacket_) {
62 av_packet_free(&avPacket_);
63 }
64
65 if (swrContext_) {
66 swr_free(&swrContext_);
67 }
68
69 if (swrOutBuffer_) {
70 av_freep(&swrOutBuffer_);
71 }
72 }
73
Init()74 int32_t AudioAACDecoder::Init()
75 {
76 SHARING_LOGD("trace.");
77 const AVCodec *dec = avcodec_find_decoder(AV_CODEC_ID_AAC);
78 if (!dec) {
79 SHARING_LOGE("Failed to find codec.");
80 return -1;
81 }
82
83 codecCtx_ = avcodec_alloc_context3(dec);
84 if (!codecCtx_) {
85 SHARING_LOGE("Failed to allocate the codec context.");
86 return -1;
87 }
88
89 if (avcodec_open2(codecCtx_, dec, nullptr) < 0) {
90 SHARING_LOGE("Failed to open codec.");
91 return -1;
92 }
93
94 avPacket_ = av_packet_alloc();
95 if (avPacket_ == nullptr) {
96 SHARING_LOGE("Failed to alloc packet.");
97 return -1;
98 }
99
100 avFrame_ = av_frame_alloc();
101 if (avFrame_ == nullptr) {
102 SHARING_LOGE("Failed to alloc frame.");
103 return -1;
104 }
105 return 0;
106 }
107
OnFrame(const Frame::Ptr & frame)108 void AudioAACDecoder::OnFrame(const Frame::Ptr &frame)
109 {
110 if (frame == nullptr) {
111 SHARING_LOGE("frame is nullptr!");
112 return;
113 }
114
115 if (avPacket_ == nullptr || avFrame_ == nullptr) {
116 return;
117 }
118
119 av_packet_unref(avPacket_);
120 av_frame_unref(avFrame_);
121
122 avPacket_->data = frame->Data();
123 avPacket_->size = frame->Size();
124
125 avcodec_send_packet(codecCtx_, avPacket_);
126 avcodec_receive_frame(codecCtx_, avFrame_);
127
128 if (swrContext_ == nullptr) {
129 swrContext_ = swr_alloc_set_opts(nullptr, (int64_t)avFrame_->channel_layout, // out_ch_layout
130 AV_SAMPLE_FMT_S16, // out_sample_fmt
131 avFrame_->sample_rate, // out_sample_rate
132 (int64_t)avFrame_->channel_layout, // in_ch_layout
133 (AVSampleFormat)avFrame_->format, // AV_SAMPLE_FMT_FLTP
134 avFrame_->sample_rate, // out_sample_rate
135 0, nullptr);
136 if (swrContext_ == nullptr) {
137 SHARING_LOGE("swrContext_ alloc failed!");
138 return;
139 }
140
141 swr_init(swrContext_);
142
143 swrOutBufferSize_ =
144 av_samples_get_buffer_size(nullptr, avFrame_->channels, avFrame_->nb_samples, AV_SAMPLE_FMT_S16, 0);
145 swrOutBuffer_ = (uint8_t *)av_malloc(swrOutBufferSize_);
146 if (swrOutBuffer_ == nullptr) {
147 SHARING_LOGE("swrOutBuffer_ av_malloc failed!");
148 return;
149 }
150 }
151
152 int nbSamples = swr_convert(swrContext_, &swrOutBuffer_, avFrame_->nb_samples, (const uint8_t **)avFrame_->data,
153 avFrame_->nb_samples);
154 if (nbSamples != avFrame_->nb_samples) {
155 SHARING_LOGE("swr_convert failed!");
156 return;
157 }
158
159 auto pcmFrame = FrameImpl::Create();
160 pcmFrame->codecId_ = CODEC_PCM;
161 pcmFrame->Assign((char *)swrOutBuffer_, swrOutBufferSize_);
162 DeliverFrame(pcmFrame);
163 }
164
AudioAACEncoder()165 AudioAACEncoder::AudioAACEncoder()
166 {
167 SHARING_LOGD("trace.");
168 }
169
~AudioAACEncoder()170 AudioAACEncoder::~AudioAACEncoder()
171 {
172 SHARING_LOGD("trace.");
173 if (encFrame_) {
174 av_frame_free(&encFrame_);
175 }
176
177 if (encPacket_) {
178 av_packet_free(&encPacket_);
179 }
180
181 if (swr_) {
182 swr_free(&swr_);
183 }
184
185 if (swrData_) {
186 av_freep(&swrData_);
187 }
188 }
189
InitSwr()190 int AudioAACEncoder::InitSwr()
191 {
192 int64_t in_ch_layout = AV_CH_LAYOUT_STEREO;
193 if (inChannels_ == 1) {
194 in_ch_layout = AV_CH_LAYOUT_MONO;
195 }
196 AVSampleFormat in_sample_fmt = AV_SAMPLE_FMT_S16;
197 if (inSampleBit_ == AUDIO_SAMPLE_BIT_U8) {
198 in_sample_fmt = AV_SAMPLE_FMT_U8;
199 }
200 int in_sample_rate = inSampleRate_;
201 swr_ = swr_alloc_set_opts(NULL, enc_->channel_layout, enc_->sample_fmt, enc_->sample_rate, in_ch_layout,
202 in_sample_fmt, in_sample_rate, 0, NULL);
203 if (!swr_) {
204 SHARING_LOGE("alloc swr failed.");
205 }
206
207 int error;
208 char errBuf[AV_ERROR_MAX_STRING_SIZE] = {0};
209 if ((error = swr_init(swr_)) < 0) {
210 SHARING_LOGE("open swr(%{public}d:%{public}s)", error,
211 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
212 }
213
214 if (!(swrData_ = (uint8_t **)calloc(enc_->channels, sizeof(*swrData_)))) {
215 SHARING_LOGE("alloc swr buffer failed!");
216 }
217
218 if ((error = av_samples_alloc(swrData_, NULL, enc_->channels, enc_->frame_size, enc_->sample_fmt, 0)) < 0) {
219 SHARING_LOGE("alloc swr buffer(%{public}d:%{public}s)\n", error,
220 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
221 }
222
223 return 0;
224 }
225
InitEncoderCtx(uint32_t channels,uint32_t sampleBit,uint32_t sampleRate)226 void AudioAACEncoder::InitEncoderCtx(uint32_t channels, uint32_t sampleBit, uint32_t sampleRate)
227 {
228 enc_->sample_rate = sampleRate; // dst_samplerate;
229 enc_->channels = channels; // dst_channels;
230 enc_->channel_layout = av_get_default_channel_layout(channels);
231 enc_->bit_rate = AUDIO_BIT_RATE_12800;
232 enc_->time_base.num = 1;
233 enc_->time_base.den = sampleRate;
234 enc_->compression_level = 1;
235 enc_->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
236 }
237
Init(uint32_t channels,uint32_t sampleBit,uint32_t sampleRate)238 int32_t AudioAACEncoder::Init(uint32_t channels, uint32_t sampleBit, uint32_t sampleRate)
239 {
240 SHARING_LOGD("trace.");
241 inChannels_ = channels;
242 inSampleBit_ = sampleBit;
243 inSampleRate_ = sampleRate;
244 const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
245 if (!codec) {
246 SHARING_LOGE("Codec not found failed!");
247 return 1;
248 }
249
250 enc_ = avcodec_alloc_context3(codec);
251 if (!enc_) {
252 SHARING_LOGE("Could not allocate audio codec context ");
253 return 1;
254 }
255 enc_->sample_fmt = codec->sample_fmts[0]; // only supports AV_SAMPLE_FMT_FLTP
256 InitEncoderCtx(channels, sampleBit, sampleRate);
257
258 if (avcodec_open2(enc_, codec, NULL) < 0) {
259 SHARING_LOGE("Could not open codec");
260 }
261
262 encFrame_ = av_frame_alloc();
263 if (!encFrame_) {
264 SHARING_LOGE("Could not allocate audio encode in frame");
265 }
266 encFrame_->format = enc_->sample_fmt;
267 encFrame_->nb_samples = enc_->frame_size;
268 encFrame_->channel_layout = enc_->channel_layout;
269
270 if (av_frame_get_buffer(encFrame_, 0) < 0) {
271 SHARING_LOGE("Could not get audio frame buffer");
272 }
273 encPacket_ = av_packet_alloc();
274 if (!encPacket_) {
275 SHARING_LOGE("Could not allocate audio encode out packet");
276 }
277 if (!(fifo_ = av_audio_fifo_alloc(enc_->sample_fmt, enc_->channels, enc_->frame_size))) {
278 SHARING_LOGE("Could not allocate FIFO");
279 }
280 auto bufferSize = av_samples_get_buffer_size(nullptr, encFrame_->channels, encFrame_->nb_samples,
281 AVSampleFormat(encFrame_->format), 0);
282 outBuffer_ = (uint8_t *)av_malloc(bufferSize);
283
284 SHARING_LOGD("sample fmt: %{public}d, nb_samples: %{public}d, channels: %{public}d, outbuffer: %{public}d",
285 int(encFrame_->format), int(enc_->frame_size), int(enc_->channels), int(bufferSize));
286 if (outBuffer_ == nullptr) {
287 SHARING_LOGE("outBuffer_ av_malloc failed!");
288 }
289
290 return 0;
291 }
292
AddSamplesToFifo(uint8_t ** samples,int frame_size)293 int AudioAACEncoder::AddSamplesToFifo(uint8_t **samples, int frame_size)
294 {
295 char errBuf[AV_ERROR_MAX_STRING_SIZE] = {0};
296 int error;
297
298 if ((error = av_audio_fifo_realloc(fifo_, av_audio_fifo_size(fifo_) + frame_size)) < 0) {
299 SHARING_LOGE("Could not reallocate FIFO(%{public}d:%{public}s)", error,
300 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
301 }
302
303 if ((error = av_audio_fifo_write(fifo_, (void **)samples, frame_size)) < frame_size) {
304 SHARING_LOGE("Could not write data to FIFO(%{public}d:%{public}s)", error,
305 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
306 }
307
308 return 0;
309 }
310
AddAdtsHeader(uint8_t * data,int dataSize)311 void AddAdtsHeader(uint8_t *data, int dataSize)
312 {
313 // ADTS header format (7 or 9 bytes):
314 // 12 bits syncword (0xFFF)
315 // 1 bit MPEG version (0 for MPEG-4, 1 for MPEG-2)
316 // 2 bits layer (always 0 for MPEG-4)
317 // 1 bit protection absent
318 // 2 bits profile (audio object type)
319 // 4 bits sampling frequency index
320 // 1 bit private bit
321 // 3 bits channel configuration
322 // 1 bit original/copy
323 // 1 bit home
324 // variable bits variable header length
325 // 16 bits frame length
326 // 16 bits buffer fullness
327 // 1 bit number of raw data blocks in frame (set to 0)
328
329 uint8_t adtsHeader[ADTS_HEADER_SIZE];
330 int profile = 2; // 2: AAC LC
331 int samplingFrequencyIndex = 3; // 3: 48Khz, 4: 44.1kHz
332 int channelConfiguration = 2; // 2: Stereo
333
334 adtsHeader[0] = ADTS_HEADER_BEGIN;
335 adtsHeader[1] = ADTS_HEADER_MPEG4_AACLC;
336 adtsHeader[ADTS_HEADER_INDEX_2] =
337 ((profile - 1) << ADTS_HEADER_PROFILE_SHIFT) |
338 ((samplingFrequencyIndex & ADTS_HEADER_SAMPLE_MASK) << ADTS_HEADER_SAMPLE_SHIFT) |
339 ((channelConfiguration >> ADTS_HEADER_CHANNEL_SHIFT) & ADTS_HEADER_CHANNEL_MASK);
340 adtsHeader[ADTS_HEADER_INDEX_3] =
341 ((channelConfiguration & ADTS_HEADER_CHANNEL_MASK1) << ADTS_HEADER_CHANNEL_SHIFT1) |
342 ((dataSize + ADTS_HEADER_DATA_SZIE_OFFSET) >> ADTS_HEADER_DATA_SZIE_SHIFT);
343 adtsHeader[ADTS_HEADER_INDEX_4] =
344 ((dataSize + ADTS_HEADER_DATA_SZIE_OFFSET) >> ADTS_HEADER_DATA_SZIE_SHIFT1) & ADTS_HEADER_DATA_SZIE_MASK;
345 adtsHeader[ADTS_HEADER_INDEX_5] =
346 ((dataSize + ADTS_HEADER_DATA_SZIE_OFFSET) << ADTS_HEADER_DATA_SZIE_SHIFT2) | ADTS_HEADER_DATA_SZIE_MASK1;
347 adtsHeader[ADTS_HEADER_INDEX_6] = ADTS_HEADER_END;
348
349 if (memcpy_s(data, sizeof(adtsHeader), adtsHeader, sizeof(adtsHeader)) != EOK) {
350 SHARING_LOGE("copy adtsHeader failed!");
351 }
352 }
353
DoSwr(const Frame::Ptr & frame)354 void AudioAACEncoder::DoSwr(const Frame::Ptr &frame)
355 {
356 int err = 0;
357 int error = 0;
358 int in_samples = frame->Size();
359 uint8_t *in_sample[1];
360 in_sample[0] = frame->Data();
361 char errBuf[AV_ERROR_MAX_STRING_SIZE] = {0};
362
363 do {
364 int sample_size = inChannels_ * inSampleBit_ / 8;
365 in_samples = in_samples / sample_size;
366
367 int frame_size = swr_convert(swr_, swrData_, enc_->frame_size, (const uint8_t **)in_sample, in_samples);
368 if ((error = frame_size) < 0) {
369 SHARING_LOGE("Could not convert input samples(%{public}d:%{public}s)", error,
370 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
371 }
372
373 in_sample[0] = NULL;
374 in_samples = 0;
375 if ((err = AddSamplesToFifo(swrData_, frame_size)) != 0) {
376 SHARING_LOGE("write samples failed");
377 }
378 } while (swr_get_out_samples(swr_, in_samples) >= enc_->frame_size);
379 }
380
OnFrame(const Frame::Ptr & frame)381 void AudioAACEncoder::OnFrame(const Frame::Ptr &frame)
382 {
383 if (frame == nullptr) {
384 SHARING_LOGE("frame is nullptr!");
385 return;
386 }
387
388 int error = 0;
389 if (!swr_ && (error = InitSwr()) != 0) {
390 SHARING_LOGE("resample init failed!");
391 }
392 DoSwr(frame);
393
394 char errBuf[AV_ERROR_MAX_STRING_SIZE] = {0};
395 encFrame_->format = AV_SAMPLE_FMT_FLTP;
396 while (av_audio_fifo_size(fifo_) >= enc_->frame_size) {
397 if (av_frame_make_writable(encFrame_) < 0) {
398 SHARING_LOGE("Could not make writable frame");
399 }
400 if (av_audio_fifo_read(fifo_, (void **)encFrame_->data, enc_->frame_size) < enc_->frame_size) {
401 SHARING_LOGE("Could not read data from FIFO");
402 }
403 encFrame_->pts = nextOutPts_;
404 nextOutPts_ += enc_->frame_size;
405 error = avcodec_send_frame(enc_, encFrame_);
406 if (error < 0) {
407 SHARING_LOGE("Error sending the frame to the encoder(%{public}d:%{public}s)", error,
408 av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
409 }
410
411 av_init_packet(encPacket_);
412 encPacket_->data = NULL;
413 encPacket_->size = 0;
414 while (error >= 0) {
415 error = avcodec_receive_packet(enc_, encPacket_);
416 if (error == AVERROR(EAGAIN) || error == AVERROR_EOF) {
417 break;
418 } else if (error < 0) {
419 SHARING_LOGE("recv failed:%{public}s", av_make_error_string(errBuf, AV_ERROR_MAX_STRING_SIZE, error));
420 }
421
422 encPacket_->dts = av_rescale(encPacket_->dts, 1000, enc_->time_base.den); // rescale time base 1000.
423 encPacket_->pts = av_rescale(encPacket_->pts, 1000, enc_->time_base.den); // rescale time base 1000.
424 if (memcpy_s(outBuffer_ + ADTS_HEADER_SIZE, encPacket_->size, encPacket_->data, encPacket_->size) != EOK) {
425 SHARING_LOGE("copy data failed!");
426 break;
427 }
428 AddAdtsHeader((uint8_t *)outBuffer_, encPacket_->size);
429 auto aacFrame = FrameImpl::Create();
430 aacFrame->codecId_ = CODEC_AAC;
431 aacFrame->Assign((char *)outBuffer_, encPacket_->size + 7); // 7: size offset
432 DeliverFrame(aacFrame);
433 }
434 }
435 }
436 } // namespace Sharing
437 } // namespace OHOS
438