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