• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "media_audio_encoder.h"
17 #include <filesystem>
18 #include <sstream>
19 #include <map>
20 #include <sys/stat.h>
21 #include "log.h"
22 #include "securec.h"
23 #include "monitor_error.h"
24 #include "monitor_utils.h"
25 #include "string_converter.h"
26 
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FOUNDATION, "HiStreamer"};
29 }
30 
31 namespace OHOS {
32 namespace Media {
33 namespace MediaMonitor {
34 
35 const int MAX_AUDIO_ARGS = 3;
36 const int ARGS_SAMPLERATE_POS = 3;
37 const int ARGS_CHANNEL_POS = 2;
38 const int ARGS_SAMPLEFORMAT_POS = 1;
39 const uint32_t DEFAULT_SAMPLERATE = 48000;
40 const uint32_t DEFAULT_CHANNELS = 1;
41 
42 const int S24LE_SAMPLESIZE = 3;
43 const int S24LE_BYTE_SHIFT_8 = 8;
44 const int S24LE_BYTE_SHIFT_16 = 16;
45 const int S24LE_BYTE_SHIFT_24 = 24;
46 const int S24LE_BYTE_INDEX_0 = 0;
47 const int S24LE_BYTE_INDEX_1 = 1;
48 const int S24LE_BYTE_INDEX_2 = 2;
49 
50 const mode_t MODE = 0775;
51 const std::string PCM_FILE = ".pcm";
52 const std::string FLAC_FILE = ".flac";
53 const std::string BLUETOOTCH_FILE = "bluetooth";
54 const uint8_t BLUETOOTH_SAMPLE_FORMAT_OFFSET = 1;
55 // samples(flac: 4608) * formatSize(f32: 4) * channles(6)
56 constexpr size_t MAX_BUFFER_LEN = 4608 * 4 * 6;
57 // samples(flac: 4608) * formatSize(s16: 2) * channles(2)
58 constexpr size_t DEFALUT_BUFFER_LEN = 4608 * 2 * 2;
59 
60 static std::map<SampleFormat, AVSampleFormat> AudioSampleMap = {
61     {SampleFormat::U8, AV_SAMPLE_FMT_U8},
62     {SampleFormat::S16LE, AV_SAMPLE_FMT_S16},
63     {SampleFormat::S24LE, AV_SAMPLE_FMT_S32},
64     {SampleFormat::S32LE, AV_SAMPLE_FMT_S32},
65     {SampleFormat::F32LE, AV_SAMPLE_FMT_FLT}
66 };
67 // encoder support sample rate
68 const std::vector<std::string> SupportedSampleRates = {
69     "8000", "11025", "12000", "16000", "22050", "24000", "32000",
70     "44100", "48000", "64000", "88200", "96000", "192000"
71 };
72 // encoder support audio channels
73 const std::vector<std::string> SupportedChannels = {"1", "2", "3", "4", "5", "6"};
74 // encoder support sample format 1 S16le, 2 S24le, 3 S32le, 4 F32le
75 const std::vector<std::string> SupportedSampleFormats = {"1", "2", "3", "4"};
76 
SampleConvert(std::shared_ptr<FFmpegApiWrap> apiWrap)77 SampleConvert::SampleConvert(std::shared_ptr<FFmpegApiWrap> apiWrap)
78     : apiWrap_(apiWrap)
79 {
80 }
81 
~SampleConvert()82 SampleConvert::~SampleConvert()
83 {
84     Release();
85 }
86 
Init(const ResamplePara & param)87 int32_t SampleConvert::Init(const ResamplePara &param)
88 {
89     resamplePara_ = param;
90     if (apiWrap_ == nullptr) {
91         MEDIA_LOG_E("api load failed");
92         return ERROR;
93     }
94     auto swrContext = apiWrap_->SwrAlloc();
95     if (swrContext == nullptr) {
96         MEDIA_LOG_E("cannot allocate swr context");
97         return ERROR;
98     }
99     swrContext = apiWrap_->SwrSetOpts(swrContext,
100         resamplePara_.channelLayout, resamplePara_.destFmt, resamplePara_.sampleRate,
101         resamplePara_.channelLayout, resamplePara_.srcFfFmt, resamplePara_.sampleRate,
102         0, nullptr);
103     if (apiWrap_->SwrInit(swrContext) != 0) {
104         MEDIA_LOG_E("swr init error");
105         return ERROR;
106     }
107     swrCtx_ = std::shared_ptr<SwrContext>(swrContext, [this](SwrContext* ptr) {
108         apiWrap_->SwrFree(&ptr);
109     });
110     isInit_ = true;
111     return SUCCESS;
112 }
113 
Convert(const uint8_t * src,size_t size,AVFrame * dstFrame)114 int32_t SampleConvert::Convert(const uint8_t *src, size_t size, AVFrame *dstFrame)
115 {
116     FALSE_RETURN_V_MSG_E(isInit_ == true, ERROR, "init error convert failed");
117     FALSE_RETURN_V_MSG_E(dstFrame != nullptr, ERROR, "dst frame is nullptr");
118     size_t lineSize = size / resamplePara_.channels;
119     std::vector<const uint8_t*> tmpInput(resamplePara_.channels);
120     tmpInput[0] = src;
121     if (apiWrap_->SampleFmtIsPlannar(resamplePara_.srcFfFmt)) {
122         for (size_t i = 1; i < tmpInput.size(); ++i) {
123             tmpInput[i] = tmpInput[i-1] + lineSize;
124         }
125     }
126     auto res = apiWrap_->SwrConvert(swrCtx_.get(),
127         dstFrame->extended_data, dstFrame->nb_samples,
128         tmpInput.data(), dstFrame->nb_samples);
129     if (res < 0) {
130         MEDIA_LOG_E("resample input failed");
131         return ERROR;
132     }
133     return SUCCESS;
134 }
135 
Release()136 void SampleConvert::Release()
137 {
138     swrCtx_ = nullptr;
139     isInit_ = false;
140 }
141 
EncodePcmFiles(const std::string & fileDir)142 int32_t MediaAudioEncoder::EncodePcmFiles(const std::string &fileDir)
143 {
144     int32_t status = SUCCESS;
145     apiWrap_ = std::make_shared<FFmpegApiWrap>();
146     if (!apiWrap_->Open()) {
147         apiWrap_->Close();
148         MEDIA_LOG_E("load encoder api failed");
149         apiWrap_ = nullptr;
150         return ERROR;
151     }
152 
153     std::error_code errorCode;
154     std::filesystem::directory_iterator iter(fileDir, errorCode);
155     if (errorCode) {
156         MEDIA_LOG_E("get file failed");
157         return ERROR;
158     }
159     for (const auto &elem : iter) {
160         if (std::filesystem::is_regular_file(elem.status())) {
161             if (elem.path().extension() != PCM_FILE) {
162                 continue;
163             }
164             std::string in = elem.path();
165             status = EncodePcmToFlac(in);
166             if (status == SUCCESS) {
167                 DeleteSrcFile(in);
168             }
169         }
170     }
171 
172     apiWrap_->Close();
173     apiWrap_ = nullptr;
174     return SUCCESS;
175 }
176 
EncodePcmToFlac(const std::string & in)177 int32_t MediaAudioEncoder::EncodePcmToFlac(const std::string &in)
178 {
179     int32_t status = SUCCESS;
180     FALSE_RETURN_V_MSG_E(IsRealPath(in), ERROR, "check path failed");
181     status = Init(in);
182     if (status != SUCCESS) {
183         Release();
184         return ERROR;
185     }
186     size_t bufferLen = PcmDataSize();
187     if (bufferLen <= 0 || bufferLen > MAX_BUFFER_LEN) {
188         Release();
189         return ERROR;
190     }
191     uint8_t *buffer = reinterpret_cast<uint8_t *>(malloc(bufferLen));
192     if (buffer == nullptr) {
193         Release();
194         return ERROR;
195     }
196     FILE *pcmFile = fopen(in.c_str(), "rb");
197     if (pcmFile == nullptr) {
198         free(buffer);
199         Release();
200         return ERROR;
201     }
202     while (!feof(pcmFile)) {
203         errno_t err = memset_s(static_cast<void *>(buffer), bufferLen, 0, bufferLen);
204         if (err != EOK) {
205             status = ERROR;
206             break;
207         }
208         size_t bytesToWrite = fread(buffer, 1, bufferLen, pcmFile);
209         if (bytesToWrite <= 0) {
210             status = ERROR;
211             break;
212         }
213         status = WritePcm(buffer, bufferLen);
214         if (status != SUCCESS) {
215             break;
216         }
217     }
218     (void)fclose(pcmFile);
219     free(buffer);
220     Release();
221     return status;
222 }
223 
Init(const std::string & inputFile)224 int32_t MediaAudioEncoder::Init(const std::string &inputFile)
225 {
226     FALSE_RETURN_V_MSG_E(apiWrap_ != nullptr, ERROR, "load wrap api failed");
227     int32_t ret = SUCCESS;
228     AudioEncodeConfig config;
229     ret = GetAudioConfig(inputFile, config);
230     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "get audio config failed");
231     ret = InitAudioEncode(config);
232     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "init encoder failed");
233     ret = InitMux();
234     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "init muxer failed");
235     ret = InitFrame();
236     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "init frame failed");
237     ret = InitPacket();
238     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "init packet failed");
239     ret = InitSampleConvert();
240     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ret, "init convert failed");
241     isInit_ = true;
242     return ret;
243 }
244 
IsSupportAudioArgs(std::string & audioArg,const std::vector<std::string> & supportList)245 bool MediaAudioEncoder::IsSupportAudioArgs(std::string &audioArg, const std::vector<std::string> &supportList)
246 {
247     for (auto &arg : supportList) {
248         if (audioArg == arg) {
249             return true;
250         }
251     }
252     return false;
253 }
254 
ParseAudioArgs(const std::string & fileName,AudioEncodeConfig & config)255 int32_t MediaAudioEncoder::ParseAudioArgs(const std::string &fileName, AudioEncodeConfig &config)
256 {
257     std::string sampleRate;
258     std::string channel;
259     std::string sampleFormat;
260 
261     std::vector<std::string> res;
262     std::string nameStr = fileName.substr(0, fileName.rfind("."));
263     std::istringstream iss(nameStr);
264     std::string str;
265     while (std::getline(iss, str, '_')) {
266         res.push_back(str);
267     }
268     FALSE_RETURN_V_MSG_E(res.size() >= MAX_AUDIO_ARGS, ERROR,
269         "parse args error, %{public}s", fileName.c_str());
270     // xxx_sampleRate_channel_sampleFormat.flac
271     sampleRate = res[res.size() - ARGS_SAMPLERATE_POS];
272     channel = res[res.size() - ARGS_CHANNEL_POS];
273     sampleFormat = res[res.size() - ARGS_SAMPLEFORMAT_POS];
274     if (IsSupportAudioArgs(sampleRate, SupportedSampleRates) &&
275         IsSupportAudioArgs(channel, SupportedChannels) &&
276         IsSupportAudioArgs(sampleFormat, SupportedSampleFormats)) {
277         FALSE_RETURN_V_MSG_E(StringConverter(sampleRate, config.sampleRate), ERROR,
278             "parse sampleRate error, %{public}s", sampleRate.c_str());
279         FALSE_RETURN_V_MSG_E(StringConverter(channel, config.channels), ERROR,
280             "parse channel error, %{public}s", channel.c_str());
281         uint8_t sampleFormatValue = 0;
282         FALSE_RETURN_V_MSG_E(StringConverter(sampleFormat, sampleFormatValue), ERROR,
283             "parse sampleFormat error, %{public}s", sampleFormat.c_str());
284         config.sampleFmt = static_cast<SampleFormat>(sampleFormatValue);
285         MEDIA_LOG_I("parser success %{public}s %{public}s %{public}s",
286             sampleRate.c_str(), channel.c_str(), sampleFormat.c_str());
287     } else {
288         MEDIA_LOG_I("parser error filename: %{public}s", fileName.c_str());
289         return ERROR;
290     }
291     if (fileName.find(BLUETOOTCH_FILE) != std::string::npos) {
292         uint8_t sampleFormatValue = 0;
293         FALSE_RETURN_V_MSG_E(StringConverter(sampleFormat, sampleFormatValue), ERROR,
294             "parse sampleFormat error, %{public}s", sampleFormat.c_str());
295         config.sampleFmt = static_cast<SampleFormat>(sampleFormatValue - BLUETOOTH_SAMPLE_FORMAT_OFFSET);
296     }
297     return SUCCESS;
298 }
299 
GetAudioConfig(const std::string & inFullName,AudioEncodeConfig & config)300 int32_t MediaAudioEncoder::GetAudioConfig(const std::string &inFullName, AudioEncodeConfig &config)
301 {
302     fileName_ = inFullName.substr(0, inFullName.length() - PCM_FILE.length()) + FLAC_FILE;
303     std::string filename = std::filesystem::path(fileName_).filename().string();
304     config.bitRate = 0;
305     config.sampleRate = DEFAULT_SAMPLERATE;
306     config.channels = DEFAULT_CHANNELS;
307     config.sampleFmt = S16LE;
308     config.audioCodecId = AV_CODEC_ID_FLAC;
309     int32_t ret = ParseAudioArgs(filename, config);
310     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ERROR, "parse args error");
311     srcSampleFormat_ = config.sampleFmt;
312     return ret;
313 }
314 
InitMux()315 int32_t MediaAudioEncoder::InitMux()
316 {
317     int32_t ret = SUCCESS;
318     AVFormatContext *formatCtx = nullptr;
319     ret = apiWrap_->FormatAllocOutputContext(&formatCtx, nullptr, nullptr, fileName_.c_str());
320     if (formatCtx == nullptr) {
321         MEDIA_LOG_E("could not deduce output format from file extension %{public}s", fileName_.c_str());
322         return ERROR;
323     }
324     formatContext_ = std::shared_ptr<AVFormatContext>(formatCtx, [this](AVFormatContext* ptr) {
325         apiWrap_->FormatFreeContext(ptr);
326     });
327     if (audioCodecContext_ != nullptr) {
328         AVStream *audioStream = nullptr;
329         audioStream = apiWrap_->FormatNewStream(formatContext_.get(), nullptr);
330         FALSE_RETURN_V_MSG_E(audioStream != nullptr, ERROR, "new audio stream error");
331         ret = apiWrap_->CodecParamFromContext(audioStream->codecpar, audioCodecContext_.get());
332         FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "could not copy the stream parameters");
333         audioStream->codecpar->codec_tag = 0;
334     }
335     if (videoCodecContext_ != nullptr) {
336         AVStream *videoStream = nullptr;
337         videoStream = apiWrap_->FormatNewStream(formatContext_.get(), nullptr);
338         FALSE_RETURN_V_MSG_E(videoStream != nullptr, ERROR, "new video stream error");
339         ret = apiWrap_->CodecParamFromContext(videoStream->codecpar, videoCodecContext_.get());
340         FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "could not copy the stream parameters");
341         videoStream->codecpar->codec_tag = 0;
342     }
343     unsigned int formatCtxFlag = static_cast<unsigned int>(formatContext_->oformat->flags);
344     if (!(formatCtxFlag & AVFMT_NOFILE)) {
345         ret = apiWrap_->IoOpen(&formatContext_->pb, fileName_.c_str(), AVIO_FLAG_WRITE,
346             &formatContext_->interrupt_callback, nullptr);
347         FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "open fail %{public}s", fileName_.c_str());
348     }
349     ret = apiWrap_->FormatWriteHeader(formatContext_.get(), nullptr);
350     if (ret < 0) {
351         MEDIA_LOG_E("error occurred when write header: %{public}d", ret);
352         return ERROR;
353     }
354     return SUCCESS;
355 }
356 
InitAudioEncode(const AudioEncodeConfig & audioConfig)357 int32_t MediaAudioEncoder::InitAudioEncode(const AudioEncodeConfig &audioConfig)
358 {
359     int32_t ret = SUCCESS;
360     const AVCodec *codec = nullptr;
361     codec = apiWrap_->CodecFindEncoder(audioConfig.audioCodecId);
362     FALSE_RETURN_V_MSG_E(codec != nullptr, ERROR, "find audio codec failed");
363     AVCodecContext *context = nullptr;
364     context = apiWrap_->CodecAllocContext(codec);
365     FALSE_RETURN_V_MSG_E(context != nullptr, ERROR, "alloc audio encode context failed");
366 
367     audioCodecContext_ = std::shared_ptr<AVCodecContext>(context, [this](AVCodecContext* ptr) {
368         apiWrap_->CodecFreeContext(&ptr);
369     });
370 
371     audioCodecContext_->sample_fmt = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_S16;
372     if (srcSampleFormat_ > SampleFormat::S16LE && audioConfig.audioCodecId == AV_CODEC_ID_FLAC) {
373         audioCodecContext_->sample_fmt = AV_SAMPLE_FMT_S32;
374     }
375     audioCodecContext_->bit_rate = audioConfig.bitRate;
376     audioCodecContext_->sample_rate = audioConfig.sampleRate;
377     audioCodecContext_->channels = audioConfig.channels;
378     audioCodecContext_->channel_layout = static_cast<uint64_t>(apiWrap_->GetChannelLayout(audioConfig.channels));
379 
380     unsigned int codecCtxFlag = static_cast<unsigned int>(audioCodecContext_->flags);
381     codecCtxFlag |= AV_CODEC_FLAG_GLOBAL_HEADER;
382     audioCodecContext_->flags = static_cast<int>(codecCtxFlag);
383     ret = apiWrap_->CodecOpen(audioCodecContext_.get(), codec, nullptr);
384     FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "could not open audio codec %{public}d", ret);
385     return SUCCESS;
386 }
387 
InitFrame()388 int32_t MediaAudioEncoder::InitFrame()
389 {
390     AVFrame* frame = apiWrap_->FrameAlloc();
391     FALSE_RETURN_V_MSG_E(frame != nullptr, ERROR, "alloc frame failed");
392     avFrame_ = std::shared_ptr<AVFrame>(frame, [this](AVFrame* frame) {
393         apiWrap_->FrameFree(&frame);
394     });
395 
396     avFrame_->format = audioCodecContext_->sample_fmt;
397     avFrame_->nb_samples = audioCodecContext_->frame_size;
398     avFrame_->channel_layout = audioCodecContext_->channel_layout;
399     avFrame_->sample_rate = audioCodecContext_->sample_rate;
400     avFrame_->channels = audioCodecContext_->channels;
401     int32_t ret = apiWrap_->FrameGetBuffer(avFrame_.get(), 0);
402     FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "get frame buffer failed %{public}d", ret);
403     return SUCCESS;
404 }
405 
InitPacket()406 int32_t MediaAudioEncoder::InitPacket()
407 {
408     AVPacket *packet = apiWrap_->PacketAlloc();
409     FALSE_RETURN_V_MSG_E(packet != nullptr, ERROR, "alloc packet failed");
410     avPacket_ = std::shared_ptr<AVPacket>(packet, [this](AVPacket *packet) {
411         apiWrap_->PacketFree(&packet);
412     });
413     return SUCCESS;
414 }
415 
InitSampleConvert()416 int32_t MediaAudioEncoder::InitSampleConvert()
417 {
418     FALSE_RETURN_V_MSG_E(avFrame_ != nullptr, ERROR, "frame error.");
419     if (srcSampleFormat_ > SampleFormat::U8 && srcSampleFormat_ < SampleFormat::F32LE) {
420         MEDIA_LOG_I("in sample format no need convert %{public}d", srcSampleFormat_);
421         sampleConvert_ = nullptr;
422         return SUCCESS;
423     }
424 
425     sampleConvert_ = std::make_shared<SampleConvert>(apiWrap_);
426     ResamplePara param {
427             avFrame_->channels,
428             avFrame_->sample_rate,
429             avFrame_->channel_layout,
430             AudioSampleMap[srcSampleFormat_],
431             (AVSampleFormat)avFrame_->format,
432     };
433     int32_t ret = sampleConvert_->Init(param);
434     return ret;
435 }
436 
CopyS24ToS32(int32_t * dst,const uint8_t * src,size_t count)437 void MediaAudioEncoder::CopyS24ToS32(int32_t *dst, const uint8_t *src, size_t count)
438 {
439     if (dst == nullptr || src == nullptr) {
440         return;
441     }
442 
443     dst += count;
444     src += count * S24LE_SAMPLESIZE;
445     for (; count > 0; --count) {
446         src -= S24LE_SAMPLESIZE;
447         *--dst = (int32_t)((src[S24LE_BYTE_INDEX_0] << S24LE_BYTE_SHIFT_8) |
448             (src[S24LE_BYTE_INDEX_1] << S24LE_BYTE_SHIFT_16) |
449             (src[S24LE_BYTE_INDEX_2] << S24LE_BYTE_SHIFT_24));
450     }
451 }
452 
FillFrameFromBuffer(const uint8_t * buffer,size_t size)453 int32_t MediaAudioEncoder::FillFrameFromBuffer(const uint8_t *buffer, size_t size)
454 {
455     FALSE_RETURN_V_MSG_E(avFrame_->linesize[0] >= static_cast<int>(size), ERROR, "frame size error");
456     if (srcSampleFormat_ == SampleFormat::S24LE) {
457         size_t count = size / S24LE_SAMPLESIZE;
458         CopyS24ToS32(reinterpret_cast<int32_t*>(avFrame_->data[0]), buffer, count);
459     } else {
460         errno_t err = memcpy_s(avFrame_->data[0], avFrame_->linesize[0], buffer, size);
461         FALSE_RETURN_V_MSG_E(err == EOK, ERROR, "memcpy error");
462     }
463     return SUCCESS;
464 }
465 
WritePcm(const uint8_t * buffer,size_t size)466 int32_t MediaAudioEncoder::WritePcm(const uint8_t *buffer, size_t size)
467 {
468     int32_t ret = SUCCESS;
469     FALSE_RETURN_V_MSG_E(isInit_ == true, ERROR, "init error");
470     FALSE_RETURN_V_MSG_E(buffer != nullptr, ERROR, "buffer nullptr");
471     FALSE_RETURN_V_MSG_E(avFrame_ != nullptr, ERROR, "frame nullptr");
472     if (sampleConvert_ != nullptr) {
473         ret = sampleConvert_->Convert(buffer, size, avFrame_.get());
474         FALSE_RETURN_V_MSG_E(ret == SUCCESS, ERROR, "resample frame error");
475     } else {
476         ret = FillFrameFromBuffer(buffer, size);
477         FALSE_RETURN_V_MSG_E(ret == SUCCESS, ERROR, "fill frame error");
478     }
479     ret = WriteFrame();
480     return ret;
481 }
482 
WriteFrame()483 int32_t MediaAudioEncoder::WriteFrame()
484 {
485     int32_t ret = SUCCESS;
486     FALSE_RETURN_V_MSG_E(avFrame_ != nullptr, ERROR, "frame nullptr");
487     FALSE_RETURN_V_MSG_E(avPacket_ != nullptr, ERROR, "packet nullptr");
488     ret = apiWrap_->CodecSendFrame(audioCodecContext_.get(), avFrame_.get());
489     FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "send frame failed %{public}d", ret);
490     while (true) {
491         ret = apiWrap_->CodecRecvPacket(audioCodecContext_.get(), avPacket_.get());
492         if (ret == 0) {
493             ret = apiWrap_->FormatWriteFrame(formatContext_.get(), avPacket_.get());
494             apiWrap_->PacketUnref(avPacket_.get());
495             FALSE_RETURN_V_MSG_E(ret >= 0, ERROR, "write packet error");
496             continue;
497         } else if ((ret == AVERROR(EAGAIN)) || (ret == AVERROR_EOF)) {
498             ret = SUCCESS;
499         } else {
500             MEDIA_LOG_E("receive packet error");
501         }
502         break;
503     }
504     FALSE_RETURN_V_MSG_E(ret == SUCCESS, ERROR, "write packet error");
505     return SUCCESS;
506 }
507 
ResetEncoderCtx()508 void MediaAudioEncoder::ResetEncoderCtx()
509 {
510     avPacket_ = nullptr;
511     avFrame_ = nullptr;
512     audioCodecContext_ = nullptr;
513     videoCodecContext_ = nullptr;
514     formatContext_ = nullptr;
515     sampleConvert_ = nullptr;
516 }
517 
Release()518 void MediaAudioEncoder::Release()
519 {
520     FALSE_RETURN_MSG(apiWrap_ != nullptr, "load api error");
521     if (formatContext_ == nullptr) {
522         ResetEncoderCtx();
523         isInit_ = false;
524         return;
525     }
526     if (isInit_) {
527         apiWrap_->FormatWriteTrailer(formatContext_.get());
528         apiWrap_->IoFlush(formatContext_->pb);
529         unsigned int formatCtxFlag = static_cast<unsigned int>(formatContext_->oformat->flags);
530         if (!(formatCtxFlag & AVFMT_NOFILE)) {
531             (void)apiWrap_->IoClose(formatContext_->pb);
532             formatContext_->pb = nullptr;
533         }
534         (void)apiWrap_->FormatFlush(formatContext_.get());
535     }
536     ResetEncoderCtx();
537     isInit_ = false;
538     return;
539 }
540 
PcmDataSize()541 size_t MediaAudioEncoder::PcmDataSize()
542 {
543     size_t size = DEFALUT_BUFFER_LEN;
544     if (audioCodecContext_ == nullptr) {
545         return size;
546     }
547 
548     int bytesPerSample = 0;
549     if (srcSampleFormat_ == SampleFormat::S24LE) {
550         bytesPerSample = S24LE_SAMPLESIZE;
551     } else {
552         bytesPerSample = apiWrap_->GetBytesPerSample(AudioSampleMap[srcSampleFormat_]);
553     }
554 
555     size = static_cast<size_t>(audioCodecContext_->frame_size
556         * audioCodecContext_->channels
557         * bytesPerSample);
558     return size;
559 }
560 
DeleteSrcFile(const std::string & filePath)561 bool MediaAudioEncoder::DeleteSrcFile(const std::string &filePath)
562 {
563     if (!IsRealPath(filePath)) {
564         return false;
565     }
566     (void)chmod(filePath.c_str(), MODE);
567     if (remove(filePath.c_str()) != 0) {
568         MEDIA_LOG_E("remove file %{public}s failed ", filePath.c_str());
569         return false;
570     }
571     return true;
572 }
573 } // namespace MediaMonitor
574 } // namespace Media
575 } // namespace OHOS