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