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 <iostream>
17  #include <unistd.h>
18  #include <chrono>
19  #include "securec.h"
20  #include "avcodec_common.h"
21  #include "avcodec_errors.h"
22  #include "media_description.h"
23  #include "native_avformat.h"
24  #include "demo_log.h"
25  #include "avcodec_codec_name.h"
26  #include "native_avmemory.h"
27  #include "native_avbuffer.h"
28  #include "ffmpeg_converter.h"
29  #include "audio_encoder_demo.h"
30  
31  using namespace OHOS;
32  using namespace OHOS::MediaAVCodec;
33  using namespace OHOS::MediaAVCodec::AudioAacEncDemo;
34  using namespace std;
35  namespace {
36  constexpr uint32_t CHANNEL_COUNT_1 = 1;
37  constexpr uint32_t CHANNEL_COUNT = 2;
38  constexpr uint32_t BIT_RATE_6000 = 6000;
39  constexpr uint32_t BIT_RATE_6700 = 6700;
40  constexpr uint32_t BIT_RATE_8850 = 8850;
41  constexpr uint32_t BIT_RATE_64000 = 64000;
42  constexpr uint32_t BIT_RATE_96000 = 96000;
43  constexpr uint32_t SAMPLE_RATE_8000 = 8000;
44  constexpr uint32_t SAMPLE_RATE_16000 = 16000;
45  constexpr uint32_t SAMPLE_RATE = 44100;
46  constexpr uint32_t FRAME_DURATION_US = 33000;
47  constexpr int32_t SAMPLE_FORMAT_S16 = AudioSampleFormat::SAMPLE_S16LE;
48  constexpr int32_t SAMPLE_FORMAT_S32 = AudioSampleFormat::SAMPLE_S32LE;
49  constexpr int32_t BIT_PER_CODE_COUNT = 16;
50  constexpr int32_t COMPLEXITY_COUNT = 10;
51  constexpr int32_t CHANNEL_1 = 1;
52  constexpr int32_t CHANNEL_2 = 2;
53  constexpr int32_t CHANNEL_3 = 3;
54  constexpr int32_t CHANNEL_4 = 4;
55  constexpr int32_t CHANNEL_5 = 5;
56  constexpr int32_t CHANNEL_6 = 6;
57  constexpr int32_t CHANNEL_7 = 7;
58  constexpr int32_t CHANNEL_8 = 8;
59  } // namespace
60  
61  
GetChannelLayout(int32_t channel)62  static uint64_t GetChannelLayout(int32_t channel)
63  {
64      switch (channel) {
65          case CHANNEL_1:
66              return MONO;
67          case CHANNEL_2:
68              return STEREO;
69          case CHANNEL_3:
70              return CH_2POINT1;
71          case CHANNEL_4:
72              return CH_3POINT1;
73          case CHANNEL_5:
74              return CH_4POINT1;
75          case CHANNEL_6:
76              return CH_5POINT1;
77          case CHANNEL_7:
78              return CH_6POINT1;
79          case CHANNEL_8:
80              return CH_7POINT1;
81          default:
82              return UNKNOWN_CHANNEL_LAYOUT;
83      }
84  }
85  
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)86  static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
87  {
88      (void)codec;
89      (void)errorCode;
90      (void)userData;
91  }
92  
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)93  static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
94  {
95      (void)codec;
96      (void)format;
97      (void)userData;
98      cout << "OnOutputFormatChanged received" << endl;
99  }
100  
OnInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)101  static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
102  {
103      (void)codec;
104      AEncSignal *signal = static_cast<AEncSignal *>(userData);
105      unique_lock<mutex> lock(signal->inMutex_);
106      signal->inQueue_.push(index);
107      signal->inBufferQueue_.push(buffer);
108      signal->inCond_.notify_all();
109  }
110  
OnOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * buffer,void * userData)111  static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
112  {
113      (void)codec;
114      AEncSignal *signal = static_cast<AEncSignal *>(userData);
115      unique_lock<mutex> lock(signal->outMutex_);
116      signal->outQueue_.push(index);
117      signal->outBufferQueue_.push(buffer);
118      if (buffer) {
119          cout << "OnOutputBufferAvailable received, index:" << index << ", size:" << buffer->buffer_->memory_->GetSize()
120               << ", flags:" << buffer->buffer_->flag_ << ", pts: " << buffer->buffer_->pts_ << endl;
121      }
122      signal->outCond_.notify_all();
123  }
124  
InitFile(const std::string & inputFile)125  bool AudioBufferAacEncDemo::InitFile(const std::string& inputFile)
126  {
127      if (inputFile.find("mp4") != std::string::npos || inputFile.find("m4a") != std::string::npos ||
128          inputFile.find("vivid") != std::string::npos) {
129          audioType_ = AudioBufferFormatType::TYPE_VIVID;
130      } else if (inputFile.find("opus") != std::string::npos) {
131          audioType_ = AudioBufferFormatType::TYPE_OPUS;
132      } else if (inputFile.find("g711") != std::string::npos) {
133          audioType_ = AudioBufferFormatType::TYPE_G711MU;
134      } else if (inputFile.find("lbvc") != std::string::npos) {
135          audioType_ = AudioBufferFormatType::TYPE_LBVC;
136      } else if (inputFile.find("flac") != std::string::npos) {
137          audioType_ = AudioBufferFormatType::TYPE_FLAC;
138      } else if (inputFile.find("amrnb") != std::string::npos) {
139          audioType_ = AudioBufferFormatType::TYPE_AMRNB;
140      } else if (inputFile.find("amrwb") != std::string::npos) {
141          audioType_ = AudioBufferFormatType::TYPE_AMRWB;
142      } else if (inputFile.find("mp3") != std::string::npos) {
143          audioType_ = AudioBufferFormatType::TYPE_MP3;
144      } else {
145          audioType_ = AudioBufferFormatType::TYPE_AAC;
146      }
147  
148      return true;
149  }
150  
RunCase(const uint8_t * data,size_t size)151  bool AudioBufferAacEncDemo::RunCase(const uint8_t *data, size_t size)
152  {
153      std::string codecdata(reinterpret_cast<const char *>(data), size);
154      inputdata = codecdata;
155      inputdatasize = size;
156      DEMO_CHECK_AND_RETURN_RET_LOG(CreateEnc() == AVCS_ERR_OK, false, "Fatal: CreateEnc fail");
157      OH_AVFormat *format = OH_AVFormat_Create();
158      Setformat(format);
159      DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false, "Fatal: Configure fail");
160      DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail");
161      {
162          unique_lock<mutex> lock(signal_->startMutex_);
163          signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); });
164      }
165      DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail");
166      DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail");
167      OH_AVFormat_Destroy(format);
168      sleep(1);
169      return true;
170  }
171  
Setformat(OH_AVFormat * format)172  void AudioBufferAacEncDemo::Setformat(OH_AVFormat *format)
173  {
174      int32_t channelCount = CHANNEL_COUNT_1;
175      int32_t sampleRate = SAMPLE_RATE;
176      long bitrate = BIT_RATE_64000;
177      uint64_t channelLayout;
178      int32_t sampleFormat = SAMPLE_FORMAT_S16;
179      if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
180          channelCount = CHANNEL_COUNT;
181          sampleRate = SAMPLE_RATE;
182          bitrate = BIT_RATE_96000;
183          sampleFormat = SAMPLE_FORMAT_S32;
184      } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
185          sampleRate = SAMPLE_RATE_8000;
186          bitrate = BIT_RATE_64000;
187          OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_BITS_PER_CODED_SAMPLE.data(), BIT_PER_CODE_COUNT);
188          OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_COMPLIANCE_LEVEL.data(), COMPLEXITY_COUNT);
189      } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
190          sampleRate = SAMPLE_RATE_8000;
191          bitrate = BIT_RATE_64000;
192      } else if (audioType_ == AudioBufferFormatType::TYPE_LBVC) {
193          sampleRate = SAMPLE_RATE_16000; //采样率16000
194          bitrate = BIT_RATE_6000; // 码率 6000
195      } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
196          channelCount = CHANNEL_COUNT_1;
197          sampleRate = SAMPLE_RATE;
198          bitrate = BIT_RATE_64000;
199          OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_S16LE);
200      } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
201          sampleRate = SAMPLE_RATE_8000;
202          bitrate = BIT_RATE_6700;
203      } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
204          sampleRate = SAMPLE_RATE_16000;
205          bitrate = BIT_RATE_8850;
206      } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
207          sampleRate = SAMPLE_RATE;
208          bitrate = BIT_RATE_64000;
209      }
210      channelLayout = GetChannelLayout(channelCount);
211      OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, channelLayout);
212      OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount);
213      OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate);
214      OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), bitrate);
215      OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), sampleFormat);
216      return;
217  }
218  
AudioBufferAacEncDemo()219  AudioBufferAacEncDemo::AudioBufferAacEncDemo() : isRunning_(false), audioEnc_(nullptr), signal_(nullptr), frameCount_(0)
220  {
221      signal_ = new AEncSignal();
222      DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory");
223  }
224  
~AudioBufferAacEncDemo()225  AudioBufferAacEncDemo::~AudioBufferAacEncDemo()
226  {
227      if (signal_) {
228          delete signal_;
229          signal_ = nullptr;
230      }
231  }
232  
CreateEnc()233  int32_t AudioBufferAacEncDemo::CreateEnc()
234  {
235      if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
236          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_AAC_NAME).data());
237          cout << "CreateEnc aac!" << endl;
238      } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
239          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_FLAC_NAME).data());
240          cout << "CreateEnc flac!" << endl;
241      } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
242          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_OPUS_NAME).data());
243          cout << "CreateEnc opus!" << endl;
244      } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
245          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_G711MU_NAME).data());
246          cout << "CreateEnc g711!" << endl;
247      } else if (audioType_ == AudioBufferFormatType::TYPE_LBVC) {
248          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_LBVC_NAME).data());
249          cout << "CreateEnc lbvc!" << endl;
250      } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
251          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_AMRNB_NAME).data());
252          cout << "CreateEnc amrnb!" << endl;
253      } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
254          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_AMRWB_NAME).data());
255          cout << "CreateEnc amrwb!" << endl;
256      } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
257          audioEnc_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_ENCODER_MP3_NAME).data());
258          cout << "CreateEnc mp3!" << endl;
259      } else {
260          return AVCS_ERR_INVALID_VAL;
261      }
262      DEMO_CHECK_AND_RETURN_RET_LOG(audioEnc_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
263      if (signal_ == nullptr) {
264          signal_ = new AEncSignal();
265          DEMO_CHECK_AND_RETURN_RET_LOG(signal_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
266      }
267      cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
268      int32_t ret = OH_AudioCodec_RegisterCallback(audioEnc_, cb_, signal_);
269      DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
270  
271      return AVCS_ERR_OK;
272  }
273  
Configure(OH_AVFormat * format)274  int32_t AudioBufferAacEncDemo::Configure(OH_AVFormat *format)
275  {
276      int32_t ret = OH_AudioCodec_Configure(audioEnc_, format);
277      return ret;
278  }
279  
Start()280  int32_t AudioBufferAacEncDemo::Start()
281  {
282      isRunning_.store(true);
283  
284      inputLoop_ = make_unique<thread>(&AudioBufferAacEncDemo::InputFunc, this);
285      DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
286  
287      outputLoop_ = make_unique<thread>(&AudioBufferAacEncDemo::OutputFunc, this);
288      DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
289      return OH_AudioCodec_Start(audioEnc_);
290  }
291  
Stop()292  int32_t AudioBufferAacEncDemo::Stop()
293  {
294      isRunning_.store(false);
295  
296      if (inputLoop_ != nullptr && inputLoop_->joinable()) {
297          {
298              unique_lock<mutex> lock(signal_->inMutex_);
299              signal_->inCond_.notify_all();
300          }
301          inputLoop_->join();
302          inputLoop_ = nullptr;
303          while (!signal_->inQueue_.empty()) {
304              signal_->inQueue_.pop();
305          }
306          while (!signal_->inBufferQueue_.empty()) {
307              signal_->inBufferQueue_.pop();
308          }
309      }
310  
311      if (outputLoop_ != nullptr && outputLoop_->joinable()) {
312          {
313              unique_lock<mutex> lock(signal_->outMutex_);
314              signal_->outCond_.notify_all();
315          }
316          outputLoop_->join();
317          outputLoop_ = nullptr;
318          while (!signal_->outQueue_.empty()) {
319              signal_->outQueue_.pop();
320          }
321          while (!signal_->outBufferQueue_.empty()) {
322              signal_->outBufferQueue_.pop();
323          }
324      }
325  
326      return OH_AudioCodec_Stop(audioEnc_);
327  }
328  
Flush()329  int32_t AudioBufferAacEncDemo::Flush()
330  {
331      if (inputLoop_ != nullptr && inputLoop_->joinable()) {
332          {
333              unique_lock<mutex> lock(signal_->inMutex_);
334              signal_->inCond_.notify_all();
335          }
336          inputLoop_->join();
337          inputLoop_ = nullptr;
338          while (!signal_->inQueue_.empty()) {
339              signal_->inQueue_.pop();
340          }
341          while (!signal_->inBufferQueue_.empty()) {
342              signal_->inBufferQueue_.pop();
343          }
344      }
345  
346      if (outputLoop_ != nullptr && outputLoop_->joinable()) {
347          {
348              unique_lock<mutex> lock(signal_->outMutex_);
349              signal_->outCond_.notify_all();
350          }
351          outputLoop_->join();
352          outputLoop_ = nullptr;
353          while (!signal_->outQueue_.empty()) {
354              signal_->outQueue_.pop();
355          }
356          while (!signal_->outBufferQueue_.empty()) {
357              signal_->outBufferQueue_.pop();
358          }
359      }
360      return OH_AudioCodec_Flush(audioEnc_);
361  }
362  
Reset()363  int32_t AudioBufferAacEncDemo::Reset()
364  {
365      return OH_AudioCodec_Reset(audioEnc_);
366  }
367  
Release()368  int32_t AudioBufferAacEncDemo::Release()
369  {
370      return OH_AudioCodec_Destroy(audioEnc_);
371  }
372  
HandleEOS(const uint32_t & index)373  void AudioBufferAacEncDemo::HandleEOS(const uint32_t &index)
374  {
375      OH_AudioCodec_PushInputBuffer(audioEnc_, index);
376      signal_->inQueue_.pop();
377      signal_->inBufferQueue_.pop();
378  }
379  
InputFunc()380  void AudioBufferAacEncDemo::InputFunc()
381  {
382      size_t frameBytes = 1152;
383      if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
384          size_t opussize = 960;
385          frameBytes = opussize;
386      } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU || audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
387          size_t gmusize = 320;
388          frameBytes = gmusize;
389      } else if (audioType_ == AudioBufferFormatType::TYPE_LBVC || audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
390          size_t lbvcsize = 640;
391          frameBytes = lbvcsize;
392      } else if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
393          size_t aacsize = 1024;
394          frameBytes = aacsize;
395      }
396      size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes;
397      while (isRunning_.load()) {
398          unique_lock<mutex> lock(signal_->inMutex_);
399          signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
400          if (!isRunning_.load()) {
401              break;
402          }
403          uint32_t index = signal_->inQueue_.front();
404          auto buffer = signal_->inBufferQueue_.front();
405          DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail");
406          strncpy_s((char *)OH_AVBuffer_GetAddr(buffer), currentSize, inputdata.c_str(), currentSize);
407          buffer->buffer_->memory_->SetSize(currentSize);
408          int32_t ret = AVCS_ERR_OK;
409          if (isFirstFrame_) {
410              buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
411              ret = OH_AudioCodec_PushInputBuffer(audioEnc_, index);
412              isFirstFrame_ = false;
413          } else {
414              buffer->buffer_->memory_->SetSize(1);
415              buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_EOS;
416              HandleEOS(index);
417              isRunning_.store(false);
418              break;
419          }
420          timeStamp_ += FRAME_DURATION_US;
421          signal_->inQueue_.pop();
422          signal_->inBufferQueue_.pop();
423          frameCount_++;
424          if (ret != AVCS_ERR_OK) {
425              isRunning_.store(false);
426              break;
427          }
428      }
429      signal_->outCond_.notify_all();
430  }
431  
OutputFunc()432  void AudioBufferAacEncDemo::OutputFunc()
433  {
434      while (isRunning_.load()) {
435          unique_lock<mutex> lock(signal_->outMutex_);
436          signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
437  
438          if (!isRunning_.load()) {
439              cout << "wait to stop, exit" << endl;
440              break;
441          }
442  
443          uint32_t index = signal_->outQueue_.front();
444          OH_AVBuffer *avBuffer = signal_->outBufferQueue_.front();
445          if (avBuffer == nullptr) {
446              cout << "OutputFunc OH_AVBuffer is nullptr" << endl;
447              continue;
448          }
449          std::cout << "OutputFunc index:" << index << endl;
450          if (avBuffer != nullptr &&
451              (avBuffer->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS || avBuffer->buffer_->memory_->GetSize() == 0)) {
452              cout << "encode eos" << endl;
453              isRunning_.store(false);
454              signal_->startCond_.notify_all();
455          }
456  
457          signal_->outBufferQueue_.pop();
458          signal_->outQueue_.pop();
459          if (OH_AudioCodec_FreeOutputBuffer(audioEnc_, index) != AV_ERR_OK) {
460              cout << "Fatal: FreeOutputData fail" << endl;
461              break;
462          }
463      }
464      signal_->startCond_.notify_all();
465      cout << "stop, exit" << endl;
466  }
467  
CreateByMime(const char * mime)468  OH_AVCodec *AudioBufferAacEncDemo::CreateByMime(const char *mime)
469  {
470      if (mime != nullptr) {
471          if (strcmp(mime, "audio/mp4a-latm") == 0) {
472              audioType_ = AudioBufferFormatType::TYPE_AAC;
473              cout << "creat, aac" << endl;
474          } else if (strcmp(mime, "audio/flac") == 0) {
475              audioType_ = AudioBufferFormatType::TYPE_FLAC;
476              cout << "creat, flac" << endl;
477          } else if (strcmp(mime, "audio/lbvc") == 0) {
478              audioType_ = AudioBufferFormatType::TYPE_LBVC;
479              cout << "creat, LBVC" << endl;
480          } else {
481              audioType_ = AudioBufferFormatType::TYPE_G711MU;
482          }
483      }
484  
485      return OH_AudioCodec_CreateByMime(mime, true);
486  }
487  
CreateByName(const char * name)488  OH_AVCodec *AudioBufferAacEncDemo::CreateByName(const char *name)
489  {
490      return OH_AudioCodec_CreateByName(name);
491  }
492  
Destroy(OH_AVCodec * codec)493  OH_AVErrCode AudioBufferAacEncDemo::Destroy(OH_AVCodec *codec)
494  {
495      OH_AVErrCode ret = OH_AudioCodec_Destroy(codec);
496      ClearQueue();
497      return ret;
498  }
499  
SetCallback(OH_AVCodec * codec)500  OH_AVErrCode AudioBufferAacEncDemo::SetCallback(OH_AVCodec *codec)
501  {
502      if (codec == nullptr) {
503          cout << "SetCallback, codec null" << endl;
504      }
505      if (signal_ == nullptr) {
506          cout << "SetCallback, signal_ null" << endl;
507      }
508      cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
509      return OH_AudioCodec_RegisterCallback(codec, cb_, signal_);
510  }
511  
Prepare(OH_AVCodec * codec)512  OH_AVErrCode AudioBufferAacEncDemo::Prepare(OH_AVCodec *codec)
513  {
514      return OH_AudioCodec_Prepare(codec);
515  }
516  
Start(OH_AVCodec * codec)517  OH_AVErrCode AudioBufferAacEncDemo::Start(OH_AVCodec *codec)
518  {
519      return OH_AudioCodec_Start(codec);
520  }
521  
Stop(OH_AVCodec * codec)522  OH_AVErrCode AudioBufferAacEncDemo::Stop(OH_AVCodec *codec)
523  {
524      OH_AVErrCode ret = OH_AudioCodec_Stop(codec);
525      ClearQueue();
526      return ret;
527  }
528  
Flush(OH_AVCodec * codec)529  OH_AVErrCode AudioBufferAacEncDemo::Flush(OH_AVCodec *codec)
530  {
531      OH_AVErrCode ret = OH_AudioCodec_Flush(codec);
532      ClearQueue();
533      return ret;
534  }
535  
Reset(OH_AVCodec * codec)536  OH_AVErrCode AudioBufferAacEncDemo::Reset(OH_AVCodec *codec)
537  {
538      return OH_AudioCodec_Reset(codec);
539  }
540  
GetOutputDescription(OH_AVCodec * codec)541  OH_AVFormat *AudioBufferAacEncDemo::GetOutputDescription(OH_AVCodec *codec)
542  {
543      return OH_AudioCodec_GetOutputDescription(codec);
544  }
545  
PushInputData(OH_AVCodec * codec,uint32_t index)546  OH_AVErrCode AudioBufferAacEncDemo::PushInputData(OH_AVCodec *codec, uint32_t index)
547  {
548      OH_AVCodecBufferAttr info;
549      if (!signal_->inBufferQueue_.empty()) {
550          unique_lock<mutex> lock(signal_->inMutex_);
551          auto buffer = signal_->inBufferQueue_.front();
552          OH_AVBuffer_GetBufferAttr(buffer, &info);
553          info.size = 100; // size 100
554          OH_AVErrCode ret = OH_AVBuffer_SetBufferAttr(buffer, &info);
555          if (ret != AV_ERR_OK) {
556              return ret;
557          }
558          signal_->inBufferQueue_.pop();
559      }
560      return OH_AudioCodec_PushInputBuffer(codec, index);
561  }
562  
PushInputDataEOS(OH_AVCodec * codec,uint32_t index)563  OH_AVErrCode AudioBufferAacEncDemo::PushInputDataEOS(OH_AVCodec *codec, uint32_t index)
564  {
565      OH_AVCodecBufferAttr info;
566      info.size = 0;
567      info.offset = 0;
568      info.pts = 0;
569      info.flags = AVCODEC_BUFFER_FLAGS_EOS;
570      if (!signal_->inBufferQueue_.empty()) {
571          unique_lock<mutex> lock(signal_->inMutex_);
572          auto buffer = signal_->inBufferQueue_.front();
573          OH_AVBuffer_SetBufferAttr(buffer, &info);
574          signal_->inBufferQueue_.pop();
575      }
576      return OH_AudioCodec_PushInputBuffer(codec, index);
577  }
578  
FreeOutputData(OH_AVCodec * codec,uint32_t index)579  OH_AVErrCode AudioBufferAacEncDemo::FreeOutputData(OH_AVCodec *codec, uint32_t index)
580  {
581      return OH_AudioCodec_FreeOutputBuffer(codec, index);
582  }
583  
IsValid(OH_AVCodec * codec,bool * isValid)584  OH_AVErrCode AudioBufferAacEncDemo::IsValid(OH_AVCodec *codec, bool *isValid)
585  {
586      return OH_AudioCodec_IsValid(codec, isValid);
587  }
588  
GetInputIndex()589  uint32_t AudioBufferAacEncDemo::GetInputIndex()
590  {
591      uint32_t sleeptime = 0;
592      uint32_t index;
593      uint32_t timeout = 5;
594      while (signal_->inQueue_.empty() && sleeptime < timeout) {
595          sleep(1);
596          sleeptime++;
597      }
598      if (sleeptime >= timeout) {
599          return 0;
600      } else {
601          index = signal_->inQueue_.front();
602          signal_->inQueue_.pop();
603      }
604      return index;
605  }
606  
GetOutputIndex()607  uint32_t AudioBufferAacEncDemo::GetOutputIndex()
608  {
609      uint32_t sleeptime = 0;
610      uint32_t index;
611      uint32_t timeout = 5;
612      while (signal_->outQueue_.empty() && sleeptime < timeout) {
613          sleep(1);
614          sleeptime++;
615      }
616      if (sleeptime >= timeout) {
617          return 0;
618      } else {
619          index = signal_->outQueue_.front();
620          signal_->outQueue_.pop();
621      }
622      return index;
623  }
624  
ClearQueue()625  void AudioBufferAacEncDemo::ClearQueue()
626  {
627      while (!signal_->inQueue_.empty()) {
628          signal_->inQueue_.pop();
629      }
630  
631      while (!signal_->outQueue_.empty()) {
632          signal_->outQueue_.pop();
633      }
634  
635      while (!signal_->inBufferQueue_.empty()) {
636          signal_->inBufferQueue_.pop();
637      }
638  
639      while (!signal_->outBufferQueue_.empty()) {
640          signal_->outBufferQueue_.pop();
641      }
642  }