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