1 /*
2  * Copyright (C) 2023 Huawei Device 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_ffmpeg_aac_encoder_plugin.h"
17 #include <set>
18 #include "avcodec_errors.h"
19 #include "avcodec_trace.h"
20 #include "avcodec_log.h"
21 #include "media_description.h"
22 #include "avcodec_mime_type.h"
23 #include "ffmpeg_converter.h"
24 #include "avcodec_audio_common.h"
25 #include "securec.h"
26 
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "AvCodec-AudioFFMpegAacEncoderPlugin"};
29 constexpr std::string_view AUDIO_CODEC_NAME = "aac";
30 constexpr int32_t INPUT_BUFFER_SIZE_DEFAULT = 4 * 1024 * 8;
31 constexpr int32_t OUTPUT_BUFFER_SIZE_DEFAULT = 8192;
32 constexpr uint32_t ADTS_HEADER_SIZE = 7;
33 constexpr uint8_t SAMPLE_FREQUENCY_INDEX_DEFAULT = 4;
34 constexpr int32_t MIN_CHANNELS = 1;
35 constexpr int32_t MAX_CHANNELS = 8;
36 constexpr int32_t INVALID_CHANNELS = 7;
37 static std::map<int32_t, uint8_t> sampleFreqMap = {{96000, 0},  {88200, 1}, {64000, 2}, {48000, 3}, {44100, 4},
38                                                    {32000, 5},  {24000, 6}, {22050, 7}, {16000, 8}, {12000, 9},
39                                                    {11025, 10}, {8000, 11}, {7350, 12}};
40 static std::set<OHOS::MediaAVCodec::AudioSampleFormat> supportedSampleFormats = {
41     OHOS::MediaAVCodec::AudioSampleFormat::SAMPLE_S16LE,
42     OHOS::MediaAVCodec::AudioSampleFormat::SAMPLE_F32LE,
43 };
44 static std::map<int32_t, int64_t> channelLayoutMap = {{1, AV_CH_LAYOUT_MONO},
45                                                       {2, AV_CH_LAYOUT_STEREO},
46                                                       {3, AV_CH_LAYOUT_SURROUND},
47                                                       {4, AV_CH_LAYOUT_4POINT0},
48                                                       {5, AV_CH_LAYOUT_5POINT0_BACK},
49                                                       {6, AV_CH_LAYOUT_5POINT1_BACK},
50                                                       {7, AV_CH_LAYOUT_7POINT0},
51                                                       {8, AV_CH_LAYOUT_7POINT1}};
52 }
53 
54 namespace OHOS {
55 namespace MediaAVCodec {
AudioFFMpegAacEncoderPlugin()56 AudioFFMpegAacEncoderPlugin::AudioFFMpegAacEncoderPlugin()
57     : maxInputSize_(-1), avCodec_(nullptr), avCodecContext_(nullptr), cachedFrame_(nullptr), avPacket_(nullptr),
58       prevPts_(0), resample_(nullptr), needResample_(false), srcFmt_(AVSampleFormat::AV_SAMPLE_FMT_NONE),
59       srcLayout_(-1), codecContextValid_(false)
60 {}
61 
~AudioFFMpegAacEncoderPlugin()62 AudioFFMpegAacEncoderPlugin::~AudioFFMpegAacEncoderPlugin()
63 {
64     Release();
65 }
66 
GetAdtsHeader(std::string & adtsHeader,int32_t & headerSize,std::shared_ptr<AVCodecContext> ctx,int aacLength)67 int32_t AudioFFMpegAacEncoderPlugin::GetAdtsHeader(std::string &adtsHeader, int32_t &headerSize,
68                                                    std::shared_ptr<AVCodecContext> ctx, int aacLength)
69 {
70     uint8_t freqIdx = SAMPLE_FREQUENCY_INDEX_DEFAULT; // 0: 96000 Hz  3: 48000 Hz 4: 44100 Hz
71     auto iter = sampleFreqMap.find(ctx->sample_rate);
72     if (iter != sampleFreqMap.end()) {
73         freqIdx = iter->second;
74     }
75     uint8_t chanCfg = static_cast<uint8_t>(ctx->channels);
76     uint32_t frameLength = static_cast<uint32_t>(aacLength) + ADTS_HEADER_SIZE;
77     uint8_t profile = static_cast<uint8_t>(ctx->profile);
78     adtsHeader += 0xFF;
79     adtsHeader += 0xF1;
80     adtsHeader += (profile << 0x6) + (freqIdx << 0x2) + (chanCfg >> 0x2);
81     adtsHeader += (((chanCfg & 0x3) << 0x6) + (frameLength >> 0xB));
82     adtsHeader += ((frameLength & 0x7FF) >> 0x3);
83     adtsHeader += (((frameLength & 0x7) << 0x5) + 0x1F);
84     adtsHeader += 0xFC;
85     headerSize = ADTS_HEADER_SIZE;
86 
87     return AVCodecServiceErrCode::AVCS_ERR_OK;
88 }
89 
CheckSampleRate(const int sampleRate)90 bool AudioFFMpegAacEncoderPlugin::CheckSampleRate(const int sampleRate)
91 {
92     return sampleFreqMap.find(sampleRate) != sampleFreqMap.end() ? true : false;
93 }
94 
CheckSampleFormat(const Format & format)95 bool AudioFFMpegAacEncoderPlugin::CheckSampleFormat(const Format &format)
96 {
97     int32_t sampleFormat;
98     format.GetIntValue(MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT, sampleFormat);
99     if (supportedSampleFormats.find(static_cast<AudioSampleFormat>(sampleFormat)) == supportedSampleFormats.end()) {
100         AVCODEC_LOGE("input sample format not supported");
101         return false;
102     }
103     srcFmt_ = FFMpegConverter::ConvertOHAudioFormatToFFMpeg(static_cast<AudioSampleFormat>(sampleFormat));
104     needResample_ = CheckResample();
105     return true;
106 }
107 
CheckChannelLayout(const Format & format,int channels)108 bool AudioFFMpegAacEncoderPlugin::CheckChannelLayout(const Format &format, int channels)
109 {
110     int64_t channelLayout;
111     if (format.GetLongValue(MediaDescriptionKey::MD_KEY_CHANNEL_LAYOUT, channelLayout)) {
112         srcLayout_ = static_cast<int64_t>(
113             FFMpegConverter::ConvertOHAudioChannelLayoutToFFMpeg(static_cast<AudioChannelLayout>(channelLayout)));
114         if (av_get_channel_layout_nb_channels(srcLayout_) != channels) {
115             AVCODEC_LOGE("channel layout channels mismatch");
116             return false;
117         }
118         return true;
119     }
120 
121     srcLayout_ = static_cast<AudioChannelLayout>(channelLayoutMap.at(channels));
122     return true;
123 }
124 
CheckBitRate(const Format & format) const125 bool AudioFFMpegAacEncoderPlugin::CheckBitRate(const Format &format) const
126 {
127     if (!format.ContainKey(MediaDescriptionKey::MD_KEY_BITRATE)) {
128         AVCODEC_LOGW("parameter bit_rate not available");
129         return true;
130     }
131     int64_t bitRate;
132     if (!format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, bitRate)) {
133         AVCODEC_LOGE("parameter bit_rate type invalid");
134         return false;
135     }
136     if (bitRate < 0) {
137         AVCODEC_LOGE("parameter bit_rate illegal");
138         return false;
139     }
140     return true;
141 }
142 
CheckFormat(const Format & format)143 bool AudioFFMpegAacEncoderPlugin::CheckFormat(const Format &format)
144 {
145     if (!format.ContainKey(MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT) ||
146         !format.ContainKey(MediaDescriptionKey::MD_KEY_SAMPLE_RATE) ||
147         !format.ContainKey(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT)) {
148         AVCODEC_LOGE("Format parameter missing");
149         return false;
150     }
151 
152     if (!CheckSampleFormat(format)) {
153         return false;
154     }
155 
156     if (!CheckBitRate(format)) {
157         return false;
158     }
159 
160     int sampleRate;
161     format.GetIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, sampleRate);
162     if (!CheckSampleRate(sampleRate)) {
163         AVCODEC_LOGE("Sample rate not supported");
164         return false;
165     }
166 
167     int channels;
168     format.GetIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, channels);
169     if (channels < MIN_CHANNELS || channels > MAX_CHANNELS || channels == INVALID_CHANNELS) {
170         return false;
171     }
172 
173     if (!CheckChannelLayout(format, channels)) {
174         return false;
175     }
176 
177     return true;
178 }
179 
SetFormat(const Format & format)180 void AudioFFMpegAacEncoderPlugin::SetFormat(const Format &format) noexcept
181 {
182     format_ = format;
183     format_.PutIntValue(MediaDescriptionKey::MD_KEY_AUDIO_SAMPLES_PER_FRAME, avCodecContext_->frame_size);
184     format_.PutStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AAC);
185 }
186 
Init(const Format & format)187 int32_t AudioFFMpegAacEncoderPlugin::Init(const Format &format)
188 {
189     int32_t ret = AllocateContext("aac");
190     CHECK_AND_RETURN_RET_LOG(ret == AVCodecServiceErrCode::AVCS_ERR_OK, ret,
191         "Allocat aac context failed, ret = %{public}d", ret);
192 
193     CHECK_AND_RETURN_RET_LOG(CheckFormat(format), AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT_AUD_PARAMS,
194         "Format check failed.");
195 
196     InitContext(format);
197 
198     ret = OpenContext();
199     CHECK_AND_RETURN_RET_LOG(ret == AVCodecServiceErrCode::AVCS_ERR_OK, ret,
200         "Open context failed, ret = %{public}d", ret);
201 
202     SetFormat(format);
203 
204     ret = InitFrame();
205     CHECK_AND_RETURN_RET_LOG(ret == AVCodecServiceErrCode::AVCS_ERR_OK, ret,
206         "Init frame failed, ret = %{public}d", ret);
207 
208     return AVCodecServiceErrCode::AVCS_ERR_OK;
209 }
210 
ProcessSendData(const std::shared_ptr<AudioBufferInfo> & inputBuffer)211 int32_t AudioFFMpegAacEncoderPlugin::ProcessSendData(const std::shared_ptr<AudioBufferInfo> &inputBuffer)
212 {
213     std::unique_lock lock(avMutext_);
214     if (avCodecContext_ == nullptr) {
215         AVCODEC_LOGE("avCodecContext_ is nullptr");
216         return AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION;
217     }
218     return SendBuffer(inputBuffer);
219 }
220 
ProcessRecieveData(std::shared_ptr<AudioBufferInfo> & outBuffer)221 int32_t AudioFFMpegAacEncoderPlugin::ProcessRecieveData(std::shared_ptr<AudioBufferInfo> &outBuffer)
222 {
223     if (!outBuffer) {
224         AVCODEC_LOGE("outBuffer is nullptr");
225         return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
226     }
227     int32_t status;
228     {
229         std::unique_lock l(avMutext_);
230         if (avCodecContext_ == nullptr) {
231             AVCODEC_LOGE("avCodecContext_ is nullptr");
232             return AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION;
233         }
234         status = ReceiveBuffer(outBuffer);
235     }
236     return status;
237 }
238 
Reset()239 int32_t AudioFFMpegAacEncoderPlugin::Reset()
240 {
241     std::unique_lock lock(avMutext_);
242     auto ret = CloseCtxLocked();
243     prevPts_ = 0;
244     return ret;
245 }
246 
Release()247 int32_t AudioFFMpegAacEncoderPlugin::Release()
248 {
249     std::unique_lock lock(avMutext_);
250     auto ret = CloseCtxLocked();
251     return ret;
252 }
253 
Flush()254 int32_t AudioFFMpegAacEncoderPlugin::Flush()
255 {
256     std::unique_lock lock(avMutext_);
257     if (avCodecContext_ != nullptr) {
258         avcodec_flush_buffers(avCodecContext_.get());
259     }
260     prevPts_ = 0;
261     return ReAllocateContext();
262 }
263 
GetInputBufferSize() const264 int32_t AudioFFMpegAacEncoderPlugin::GetInputBufferSize() const
265 {
266     if (maxInputSize_ < 0 || maxInputSize_ > INPUT_BUFFER_SIZE_DEFAULT) {
267         return INPUT_BUFFER_SIZE_DEFAULT;
268     }
269     return maxInputSize_;
270 }
271 
GetOutputBufferSize() const272 int32_t AudioFFMpegAacEncoderPlugin::GetOutputBufferSize() const
273 {
274     return OUTPUT_BUFFER_SIZE_DEFAULT;
275 }
276 
GetFormat() const277 Format AudioFFMpegAacEncoderPlugin::GetFormat() const noexcept
278 {
279     return format_;
280 }
281 
GetCodecType() const282 std::string_view AudioFFMpegAacEncoderPlugin::GetCodecType() const noexcept
283 {
284     return AUDIO_CODEC_NAME;
285 }
286 
AllocateContext(const std::string & name)287 int32_t AudioFFMpegAacEncoderPlugin::AllocateContext(const std::string &name)
288 {
289     {
290         std::unique_lock lock(avMutext_);
291         avCodec_ = std::shared_ptr<AVCodec>(const_cast<AVCodec *>(avcodec_find_encoder_by_name(name.c_str())),
292                                             [](AVCodec *ptr) {});
293         cachedFrame_ = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame *fp) { av_frame_free(&fp); });
294         avPacket_ = std::shared_ptr<AVPacket>(av_packet_alloc(), [](AVPacket *ptr) { av_packet_free(&ptr); });
295     }
296     if (avCodec_ == nullptr) {
297         return AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT_PROTOCOL_TYPE;
298     }
299     CHECK_AND_RETURN_RET_LOG(cachedFrame_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY,
300         "Allocate cachedFrame_ failed.");
301 
302     AVCodecContext *context = nullptr;
303     {
304         std::unique_lock lock(avMutext_);
305         context = avcodec_alloc_context3(avCodec_.get());
306         avCodecContext_ = std::shared_ptr<AVCodecContext>(context, [](AVCodecContext *ptr) {
307             if (ptr) {
308                 avcodec_free_context(&ptr);
309                 ptr = nullptr;
310             }
311         });
312         CHECK_AND_RETURN_RET_LOG(avCodecContext_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY,
313             "Allocate avCodecContext_ failed.");
314         av_log_set_level(AV_LOG_ERROR);
315     }
316     return AVCodecServiceErrCode::AVCS_ERR_OK;
317 }
318 
InitContext(const Format & format)319 int32_t AudioFFMpegAacEncoderPlugin::InitContext(const Format &format)
320 {
321     format.GetIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, avCodecContext_->channels);
322     format.GetIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, avCodecContext_->sample_rate);
323     format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, avCodecContext_->bit_rate);
324     format.GetIntValue(MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, maxInputSize_);
325     avCodecContext_->channel_layout = srcLayout_;
326     avCodecContext_->sample_fmt = srcFmt_;
327 
328     if (needResample_) {
329         avCodecContext_->sample_fmt = avCodec_->sample_fmts[0];
330     }
331     return AVCodecServiceErrCode::AVCS_ERR_OK;
332 }
333 
OpenContext()334 int32_t AudioFFMpegAacEncoderPlugin::OpenContext()
335 {
336     {
337         std::unique_lock lock(avMutext_);
338         auto res = avcodec_open2(avCodecContext_.get(), avCodec_.get(), nullptr);
339         if (res != 0) {
340             AVCODEC_LOGE("avcodec open error %{public}s", FFMpegConverter::AVStrError(res).c_str());
341             return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
342         }
343         codecContextValid_ = true;
344     }
345     if (avCodecContext_->frame_size <= 0) {
346         AVCODEC_LOGE("frame size invalid");
347     }
348 
349     if (needResample_) {
350         ResamplePara resamplePara = {
351             .channels = avCodecContext_->channels,
352             .sampleRate = avCodecContext_->sample_rate,
353             .bitsPerSample = 0,
354             .channelLayout = avCodecContext_->ch_layout,
355             .srcFmt = srcFmt_,
356             .destSamplesPerFrame = avCodecContext_->frame_size,
357             .destFmt = avCodecContext_->sample_fmt,
358         };
359         resample_ = std::make_shared<AudioResample>();
360         if (resample_->Init(resamplePara) != AVCodecServiceErrCode::AVCS_ERR_OK) {
361             AVCODEC_LOGE("Resmaple init failed.");
362             return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
363         }
364     }
365 
366     return AVCodecServiceErrCode::AVCS_ERR_OK;
367 }
368 
CheckResample() const369 bool AudioFFMpegAacEncoderPlugin::CheckResample() const
370 {
371     if (avCodec_ == nullptr || avCodecContext_ == nullptr) {
372         return false;
373     }
374     for (size_t index = 0; avCodec_->sample_fmts[index] != AV_SAMPLE_FMT_NONE; ++index) {
375         if (avCodec_->sample_fmts[index] == srcFmt_) {
376             return false;
377         }
378     }
379     return true;
380 }
381 
InitFrame()382 int32_t AudioFFMpegAacEncoderPlugin::InitFrame()
383 {
384     cachedFrame_->nb_samples = avCodecContext_->frame_size;
385     cachedFrame_->format = avCodecContext_->sample_fmt;
386     cachedFrame_->channel_layout = avCodecContext_->channel_layout;
387     cachedFrame_->channels = avCodecContext_->channels;
388     int ret = av_frame_get_buffer(cachedFrame_.get(), 0);
389     CHECK_AND_RETURN_RET_LOG(ret >= 0, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY,
390         "Get frame buffer failed: %{public}s", FFMpegConverter::AVStrError(ret).c_str());
391     return AVCodecServiceErrCode::AVCS_ERR_OK;
392 }
393 
SendBuffer(const std::shared_ptr<AudioBufferInfo> & inputBuffer)394 int32_t AudioFFMpegAacEncoderPlugin::SendBuffer(const std::shared_ptr<AudioBufferInfo> &inputBuffer)
395 {
396     if (!inputBuffer) {
397         AVCODEC_LOGE("inputBuffer is nullptr");
398         return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
399     }
400     int ret = av_frame_make_writable(cachedFrame_.get());
401     if (ret != 0) {
402         AVCODEC_LOGE("Frame make writable failed: %{public}s", FFMpegConverter::AVStrError(ret).c_str());
403         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
404     }
405 
406     auto attr = inputBuffer->GetBufferAttr();
407     bool isEos = inputBuffer->CheckIsEos();
408     if (!isEos) {
409         AVCODEC_LOGD("SendBuffer buffer size:%{public}d", attr.size);
410     } else {
411         AVCODEC_LOGD("SendBuffer EOS buffer size:%{public}d", attr.size);
412     }
413     if (!isEos) {
414         auto memory = inputBuffer->GetBuffer();
415         if (attr.size < 0) {
416             AVCODEC_LOGE("SendBuffer buffer size is less than 0. size : %{public}d", attr.size);
417             return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
418         }
419         if (attr.size > memory->GetSize()) {
420             AVCODEC_LOGE("send input buffer is > allocate size. size : %{public}d, allocate size : %{public}d",
421                 attr.size, memory->GetSize());
422             return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
423         }
424         auto errCode = PcmFillFrame(inputBuffer);
425         if (errCode != AVCodecServiceErrCode::AVCS_ERR_OK) {
426             return errCode;
427         }
428         ret = avcodec_send_frame(avCodecContext_.get(), cachedFrame_.get());
429     } else {
430         ret = avcodec_send_frame(avCodecContext_.get(), nullptr);
431     }
432     if (ret == 0) {
433         return AVCodecServiceErrCode::AVCS_ERR_OK;
434     } else if (ret == AVERROR(EAGAIN)) {
435         AVCODEC_LOGW("skip this frame because data not enough, msg:%{public}s",
436                      FFMpegConverter::AVStrError(ret).data());
437         return AVCodecServiceErrCode::AVCS_ERR_NOT_ENOUGH_DATA;
438     } else if (ret == AVERROR_EOF) {
439         AVCODEC_LOGW("eos send frame, msg:%{public}s", FFMpegConverter::AVStrError(ret).data());
440         return AVCodecServiceErrCode::AVCS_ERR_END_OF_STREAM;
441     } else {
442         AVCODEC_LOGE("Send frame unknown error: %{public}s", FFMpegConverter::AVStrError(ret).c_str());
443         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
444     }
445 }
446 
PcmFillFrame(const std::shared_ptr<AudioBufferInfo> & inputBuffer)447 int32_t AudioFFMpegAacEncoderPlugin::PcmFillFrame(const std::shared_ptr<AudioBufferInfo> &inputBuffer)
448 {
449     auto memory = inputBuffer->GetBuffer();
450     auto bytesPerSample = av_get_bytes_per_sample(avCodecContext_->sample_fmt);
451     const uint8_t *srcBuffer = memory->GetBase();
452     uint8_t *destBuffer = const_cast<uint8_t*>(srcBuffer);
453     size_t srcBufferSize = static_cast<size_t>(inputBuffer->GetBufferAttr().size);
454     size_t destBufferSize = srcBufferSize;
455     if (needResample_ && resample_ != nullptr) {
456         if (resample_->Convert(srcBuffer, srcBufferSize, destBuffer, destBufferSize) !=
457             AVCodecServiceErrCode::AVCS_ERR_OK) {
458             AVCODEC_LOGE("Convert sample format failed");
459         }
460     }
461 
462     cachedFrame_->nb_samples = static_cast<int>(destBufferSize) / (bytesPerSample * avCodecContext_->channels);
463     if (cachedFrame_->nb_samples > avCodecContext_->frame_size) {
464         AVCODEC_LOGE("Input frame size out of range, input smaples: %{public}d, frame_size: %{public}d",
465                      cachedFrame_->nb_samples, avCodecContext_->frame_size);
466         return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
467     }
468     if (!inputBuffer->CheckIsEos() && cachedFrame_->nb_samples != avCodecContext_->frame_size) {
469         AVCODEC_LOGW("Input frame size not enough, input smaples: %{public}d, frame_size: %{public}d",
470                      cachedFrame_->nb_samples, avCodecContext_->frame_size);
471     }
472 
473     cachedFrame_->extended_data = cachedFrame_->data;
474     cachedFrame_->extended_data[0] = destBuffer;
475     cachedFrame_->linesize[0] = cachedFrame_->nb_samples * bytesPerSample;
476     for (int i = 1; i < avCodecContext_->channels; i++) {
477         cachedFrame_->extended_data[i] = cachedFrame_->extended_data[i-1] + cachedFrame_->linesize[0];
478     }
479     return AVCodecServiceErrCode::AVCS_ERR_OK;
480 }
481 
ReceiveBuffer(std::shared_ptr<AudioBufferInfo> & outBuffer)482 int32_t AudioFFMpegAacEncoderPlugin::ReceiveBuffer(std::shared_ptr<AudioBufferInfo> &outBuffer)
483 {
484     (void)memset_s(avPacket_.get(), sizeof(AVPacket), 0, sizeof(AVPacket));
485     auto ret = avcodec_receive_packet(avCodecContext_.get(), avPacket_.get());
486     int32_t status;
487     if (ret >= 0) {
488         AVCODEC_LOGD("receive one packet");
489         status = ReceivePacketSucc(outBuffer);
490     } else if (ret == AVERROR_EOF) {
491         outBuffer->SetEos(true);
492         avcodec_flush_buffers(avCodecContext_.get());
493         status = AVCodecServiceErrCode::AVCS_ERR_END_OF_STREAM;
494     } else if (ret == AVERROR(EAGAIN)) {
495         status = AVCodecServiceErrCode::AVCS_ERR_NOT_ENOUGH_DATA;
496     } else {
497         AVCODEC_LOGE("audio encoder receive unknow error: %{public}s", FFMpegConverter::AVStrError(ret).c_str());
498         status = AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
499     }
500     av_packet_unref(avPacket_.get());
501     return status;
502 }
503 
ReceivePacketSucc(std::shared_ptr<AudioBufferInfo> & outBuffer)504 int32_t AudioFFMpegAacEncoderPlugin::ReceivePacketSucc(std::shared_ptr<AudioBufferInfo> &outBuffer)
505 {
506     int32_t headerSize = 0;
507     auto memory = outBuffer->GetBuffer();
508     std::string header;
509     GetAdtsHeader(header, headerSize, avCodecContext_, avPacket_->size);
510     if (headerSize == 0) {
511         AVCODEC_LOGE("Get header failed.");
512         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
513     }
514     int32_t writeBytes = memory->Write(reinterpret_cast<uint8_t *>(const_cast<char *>(header.c_str())), headerSize);
515     if (writeBytes < headerSize) {
516         AVCODEC_LOGE("Write header failed");
517         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
518     }
519 
520     int32_t outputSize = avPacket_->size + headerSize;
521     if (memory->GetSize() < outputSize) {
522         AVCODEC_LOGW("Output buffer capacity is not enough");
523         return AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY;
524     }
525 
526     auto len = memory->Write(avPacket_->data, avPacket_->size);
527     if (len < avPacket_->size) {
528         AVCODEC_LOGE("write packet data failed, len = %{public}d", len);
529         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
530     }
531 
532     auto attr = outBuffer->GetBufferAttr();
533     attr.size = static_cast<size_t>(avPacket_->size + headerSize);
534     prevPts_ += avPacket_->duration;
535     attr.presentationTimeUs = FFMpegConverter::ConvertAudioPtsToUs(prevPts_, avCodecContext_->time_base);
536     outBuffer->SetBufferAttr(attr);
537     return AVCodecServiceErrCode::AVCS_ERR_OK;
538 }
539 
CloseCtxLocked()540 int32_t AudioFFMpegAacEncoderPlugin::CloseCtxLocked()
541 {
542     if (avCodecContext_ != nullptr) {
543         avCodecContext_.reset();
544         avCodecContext_ = nullptr;
545     }
546     return AVCodecServiceErrCode::AVCS_ERR_OK;
547 }
548 
ReAllocateContext()549 int32_t AudioFFMpegAacEncoderPlugin::ReAllocateContext()
550 {
551     if (!codecContextValid_) {
552         AVCODEC_LOGD("Old avcodec context not valid, no need to reallocate");
553         return AVCodecServiceErrCode::AVCS_ERR_OK;
554     }
555 
556     AVCodecContext *context = avcodec_alloc_context3(avCodec_.get());
557     auto tmpContext = std::shared_ptr<AVCodecContext>(context, [](AVCodecContext *ptr) {
558         if (ptr) {
559             avcodec_free_context(&ptr);
560             ptr = nullptr;
561         }
562     });
563     CHECK_AND_RETURN_RET_LOG(tmpContext != nullptr, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY,
564         "Allocate tmpContext failed.");
565 
566     tmpContext->channels = avCodecContext_->channels;
567     tmpContext->sample_rate = avCodecContext_->sample_rate;
568     tmpContext->bit_rate = avCodecContext_->bit_rate;
569     tmpContext->channel_layout = avCodecContext_->channel_layout;
570     tmpContext->sample_fmt = avCodecContext_->sample_fmt;
571 
572     auto res = avcodec_open2(tmpContext.get(), avCodec_.get(), nullptr);
573     if (res != 0) {
574         AVCODEC_LOGE("avcodec reopen error %{public}s", FFMpegConverter::AVStrError(res).c_str());
575         return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
576     }
577     avCodecContext_ = tmpContext;
578 
579     return AVCodecServiceErrCode::AVCS_ERR_OK;
580 }
581 } // namespace MediaAVCodec
582 } // namespace OHOS
583