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 ¶m)
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