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