• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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