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