• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "avcodec_audio_avbuffer_decoder_demo.h"
17 #include <iostream>
18 #include <unistd.h>
19 #include <chrono>
20 #include "avcodec_codec_name.h"
21 #include "avcodec_common.h"
22 #include "avcodec_errors.h"
23 #include "demo_log.h"
24 #include "media_description.h"
25 #include "native_avcodec_base.h"
26 #include "native_avformat.h"
27 #include "native_avbuffer.h"
28 #include "native_avmemory.h"
29 #include "securec.h"
30 #ifdef SUPPORT_DRM
31 #include "native_mediakeysession.h"
32 #include "native_mediakeysystem.h"
33 #endif
34 
35 using namespace OHOS;
36 using namespace OHOS::MediaAVCodec;
37 using namespace OHOS::MediaAVCodec::AudioBufferDemo;
38 using namespace std;
39 namespace {
40 constexpr uint32_t CHANNEL_COUNT = 2;
41 constexpr uint32_t SAMPLE_RATE = 44100;
42 constexpr uint32_t DEFAULT_AAC_TYPE = 1;
43 constexpr int64_t BITS_RATE[static_cast<uint32_t>(AudioBufferFormatType::TYPE_MAX)] = {199000, 261000, 60000, 320000};
44 constexpr uint32_t AMRWB_SAMPLE_RATE = 16000;
45 constexpr uint32_t AMRNB_SAMPLE_RATE = 8000;
46 constexpr string_view INPUT_AAC_FILE_PATH = "/data/test/media/aac_2c_44100hz_199k.dat";
47 constexpr string_view OUTPUT_AAC_PCM_FILE_PATH = "/data/test/media/aac_2c_44100hz_199k_dec.pcm";
48 constexpr string_view INPUT_FLAC_FILE_PATH = "/data/test/media/flac_2c_44100hz_261k.dat";
49 constexpr string_view OUTPUT_FLAC_PCM_FILE_PATH = "/data/test/media/flac_2c_44100hz_261k.pcm";
50 constexpr string_view INPUT_MP3_FILE_PATH = "/data/test/media/mp3_2c_44100hz_60k.dat";
51 constexpr string_view OUTPUT_MP3_PCM_FILE_PATH = "/data/test/media/mp3_2c_44100hz_60k.pcm";
52 constexpr string_view INPUT_VORBIS_FILE_PATH = "/data/test/media/vorbis_2c_44100hz_320k.dat";
53 constexpr string_view OUTPUT_VORBIS_PCM_FILE_PATH = "/data/test/media/vorbis_2c_44100hz_320k.pcm";
54 constexpr string_view INPUT_AMRNB_FILE_PATH = "/data/test/media/voice_amrnb_10200.dat";
55 constexpr string_view OUTPUT_AMRNB_PCM_FILE_PATH = "/data/test/media/voice_amrnb_10200.pcm";
56 constexpr string_view INPUT_AMRWB_FILE_PATH = "/data/test/media/voice_amrwb_23850.dat";
57 constexpr string_view OUTPUT_AMRWB_PCM_FILE_PATH = "/data/test/media/voice_amrwb_23850.pcm";
58 constexpr string_view INPUT_G711MU_FILE_PATH = "/data/test/media/g711mu_8kHz.dat";
59 constexpr string_view OUTPUT_G711MU_PCM_FILE_PATH = "/data/test/media/g711mu_8kHz_decode.pcm";
60 constexpr string_view INPUT_APE_FILE_PATH = "/data/test/media/ape.dat";
61 constexpr string_view OUTPUT_APE_PCM_FILE_PATH = "/data/test/media/ape_decode.pcm";
62 constexpr string_view INPUT_G711A_FILE_PATH = "/data/test/media/g711a_1c_8000.dat";
63 constexpr string_view OUTPUT_G711A_PCM_FILE_PATH = "/data/test/media/g711a_1c_8000_decode.pcm";
64 } // namespace
65 
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)66 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
67 {
68     (void)codec;
69     (void)errorCode;
70     (void)userData;
71     cout << "Error received, errorCode:" << errorCode << endl;
72 }
73 
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)74 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
75 {
76     (void)codec;
77     (void)format;
78     (void)userData;
79     cout << "OnOutputFormatChanged received" << endl;
80 }
81 
OnInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)82 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
83 {
84     (void)codec;
85     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
86     unique_lock<mutex> lock(signal->inMutex_);
87     signal->inQueue_.push(index);
88     signal->inBufferQueue_.push(data);
89     signal->inCond_.notify_all();
90 }
91 
OnOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)92 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
93 {
94     (void)codec;
95     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
96     unique_lock<mutex> lock(signal->outMutex_);
97     signal->outQueue_.push(index);
98     signal->outBufferQueue_.push(data);
99     signal->outCond_.notify_all();
100 }
101 
InitFile(AudioBufferFormatType audioType)102 bool ADecBufferDemo::InitFile(AudioBufferFormatType audioType)
103 {
104     if (audioType == AudioBufferFormatType::TYPE_AAC) {
105         inputFile_.open(INPUT_AAC_FILE_PATH, std::ios::binary);
106         pcmOutputFile_.open(OUTPUT_AAC_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
107     } else if (audioType == AudioBufferFormatType::TYPE_FLAC) {
108         inputFile_.open(INPUT_FLAC_FILE_PATH, std::ios::binary);
109         pcmOutputFile_.open(OUTPUT_FLAC_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
110     } else if (audioType == AudioBufferFormatType::TYPE_MP3) {
111         inputFile_.open(INPUT_MP3_FILE_PATH, std::ios::binary);
112         pcmOutputFile_.open(OUTPUT_MP3_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
113     } else if (audioType == AudioBufferFormatType::TYPE_VORBIS) {
114         inputFile_.open(INPUT_VORBIS_FILE_PATH, std::ios::binary);
115         pcmOutputFile_.open(OUTPUT_VORBIS_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
116     } else if (audioType == AudioBufferFormatType::TYPE_AMRNB) {
117         inputFile_.open(INPUT_AMRNB_FILE_PATH, std::ios::binary);
118         pcmOutputFile_.open(OUTPUT_AMRNB_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
119     } else if (audioType == AudioBufferFormatType::TYPE_AMRWB) {
120         inputFile_.open(INPUT_AMRWB_FILE_PATH, std::ios::binary);
121         pcmOutputFile_.open(OUTPUT_AMRWB_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
122     } else if (audioType == AudioBufferFormatType::TYPE_G711MU) {
123         inputFile_.open(INPUT_G711MU_FILE_PATH, std::ios::binary);
124         pcmOutputFile_.open(OUTPUT_G711MU_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
125     } else if (audioType == AudioBufferFormatType::TYPE_APE) {
126         inputFile_.open(INPUT_APE_FILE_PATH, std::ios::binary);
127         pcmOutputFile_.open(OUTPUT_APE_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
128     } else if (audioType == AudioBufferFormatType::TYPE_G711A) {
129         inputFile_.open(INPUT_G711A_FILE_PATH, std::ios::binary);
130         pcmOutputFile_.open(OUTPUT_G711A_PCM_FILE_PATH.data(), std::ios::out | std::ios::binary);
131     } else {
132         std::cout << "audio format type not support\n";
133         return false;
134     }
135     DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.is_open(), false, "Fatal: open input file failed");
136     DEMO_CHECK_AND_RETURN_RET_LOG(pcmOutputFile_.is_open(), false, "Fatal: open output file failed");
137     return true;
138 }
139 
RunCase(AudioBufferFormatType audioType)140 void ADecBufferDemo::RunCase(AudioBufferFormatType audioType)
141 {
142     DEMO_CHECK_AND_RETURN_LOG(InitFile(audioType), "Fatal: InitFile file failed");
143     audioType_ = audioType;
144     DEMO_CHECK_AND_RETURN_LOG(CreateDec() == AVCS_ERR_OK, "Fatal: CreateDec fail");
145     OH_AVFormat *format = OH_AVFormat_Create();
146     int32_t channelCount = CHANNEL_COUNT;
147     int32_t sampleRate = SAMPLE_RATE;
148     if (audioType == AudioBufferFormatType::TYPE_AAC) {
149         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AAC_IS_ADTS.data(), DEFAULT_AAC_TYPE);
150         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
151                                 OH_BitsPerSample::SAMPLE_S16LE);
152     } else if (audioType == AudioBufferFormatType::TYPE_AMRNB || audioType == AudioBufferFormatType::TYPE_G711MU ||
153         audioType == AudioBufferFormatType::TYPE_G711A) {
154         channelCount = 1;
155         sampleRate = AMRNB_SAMPLE_RATE;
156     } else if (audioType == AudioBufferFormatType::TYPE_AMRWB || audioType == AudioBufferFormatType::TYPE_APE) {
157         channelCount = 1;
158         sampleRate = AMRWB_SAMPLE_RATE;
159         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
160                                 OH_BitsPerSample::SAMPLE_S16LE);
161         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_BITS_PER_CODED_SAMPLE.data(),
162                                 16); // 16 bit pre code
163     }
164     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount);
165     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate);
166     OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BITS_RATE[(uint32_t)audioType]);
167     if (audioType == AudioBufferFormatType::TYPE_VORBIS) {
168         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
169                                 OH_BitsPerSample::SAMPLE_S16LE);
170         int64_t extradataSize;
171         DEMO_CHECK_AND_RETURN_LOG(inputFile_.is_open(), "Fatal: file is not open");
172         inputFile_.read(reinterpret_cast<char *>(&extradataSize), sizeof(int64_t));
173         DEMO_CHECK_AND_RETURN_LOG(inputFile_.gcount() == sizeof(int64_t), "Fatal: read extradataSize bytes error");
174         if (extradataSize < 0) {
175             return;
176         }
177         char buffer[extradataSize];
178         inputFile_.read(buffer, extradataSize);
179         DEMO_CHECK_AND_RETURN_LOG(inputFile_.gcount() == extradataSize, "Fatal: read extradata bytes error");
180         OH_AVFormat_SetBuffer(format, MediaDescriptionKey::MD_KEY_CODEC_CONFIG.data(),
181                               reinterpret_cast<uint8_t *>(buffer), extradataSize);
182     }
183     DEMO_CHECK_AND_RETURN_LOG(Configure(format) == AVCS_ERR_OK, "Fatal: Configure fail");
184     DEMO_CHECK_AND_RETURN_LOG(Start() == AVCS_ERR_OK, "Fatal: Start fail");
185 
186     unique_lock<mutex> lock(signal_->startMutex_);
187     signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); });
188 
189     DEMO_CHECK_AND_RETURN_LOG(Stop() == AVCS_ERR_OK, "Fatal: Stop fail");
190     DEMO_CHECK_AND_RETURN_LOG(Release() == AVCS_ERR_OK, "Fatal: Release fail");
191 }
192 
RunDrmCase(AudioBufferFormatType audioType)193 void ADecBufferDemo::RunDrmCase(AudioBufferFormatType audioType)
194 {
195     std::cout << "ADecBufferDemo::RunDrmCase" <<std::endl;
196 #ifdef SUPPORT_DRM
197     audioType_ = audioType;
198     DEMO_CHECK_AND_RETURN_LOG(CreateDec() == AVCS_ERR_OK, "Fatal: CreateDec fail");
199 
200     // test 1:create mediakeysystem
201     std::cout << "Test OH_MediaKeySystem_Create" << std::endl;
202     MediaKeySystem *system = NULL;
203     uint32_t errNo = OH_MediaKeySystem_Create("com.clearplay.drm", &system);
204     std::cout << "Test OH_MediaKeySystem_Create result" << system <<"and ret" << errNo << std::endl;
205 
206     // test 2:create mediakeysystem
207     std::cout << "Test OH_MediaKeySystem_CreateMediaKeySession" <<std::endl;
208     DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO;
209     MediaKeySession *session = NULL;
210     errNo = OH_MediaKeySystem_CreateMediaKeySession(system, &contentProtectionLevel, &session);
211     std::cout <<"Test OH_MediaKeySystem_CreateMediaKeySession result" << session << "and ret" << errNo << std::endl;
212 
213     // test 3:SetDecryptConfigTest
214     std::cout <<"Test OH_AudioCodec_SetDecryptionConfig"<<std::endl;
215     errNo = OH_AudioCodec_SetDecryptionConfig(audioDec_, session, false);
216     std::cout <<"Test OH_AudioCodec_SetDecryptionConfig result"<<session<<"and ret"<<errNo<<std::endl;
217 #endif
218 }
219 
ADecBufferDemo()220 ADecBufferDemo::ADecBufferDemo() : audioDec_(nullptr), signal_(nullptr), audioType_(AudioBufferFormatType::TYPE_AAC) {}
221 
~ADecBufferDemo()222 ADecBufferDemo::~ADecBufferDemo()
223 {
224     if (signal_) {
225         delete signal_;
226         signal_ = nullptr;
227     }
228     if (inputFile_.is_open()) {
229         inputFile_.close();
230     }
231     if (pcmOutputFile_.is_open()) {
232         pcmOutputFile_.close();
233     }
234 }
235 
CreateDec()236 int32_t ADecBufferDemo::CreateDec()
237 {
238     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
239         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
240     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
241         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_FLAC_NAME).data());
242     } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
243         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_MP3_NAME).data());
244     } else if (audioType_ == AudioBufferFormatType::TYPE_VORBIS) {
245         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_VORBIS_NAME).data());
246     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
247         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRNB_NAME).data());
248     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
249         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRWB_NAME).data());
250     } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
251         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_G711MU_NAME).data());
252     } else if (audioType_ == AudioBufferFormatType::TYPE_APE) {
253         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_APE_NAME).data());
254     } else if (audioType_ == AudioBufferFormatType::TYPE_G711A) {
255         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_G711A_NAME).data());
256     } else {
257         return AVCS_ERR_INVALID_VAL;
258     }
259     DEMO_CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
260 
261     signal_ = new ADecBufferSignal();
262     DEMO_CHECK_AND_RETURN_RET_LOG(signal_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
263 
264     cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
265     int32_t ret = OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_);
266     DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
267 
268     return AVCS_ERR_OK;
269 }
270 
Configure(OH_AVFormat * format)271 int32_t ADecBufferDemo::Configure(OH_AVFormat *format)
272 {
273     return OH_AudioCodec_Configure(audioDec_, format);
274 }
275 
Start()276 int32_t ADecBufferDemo::Start()
277 {
278     isRunning_.store(true);
279 
280     inputLoop_ = make_unique<thread>(&ADecBufferDemo::InputFunc, this);
281     DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
282 
283     outputLoop_ = make_unique<thread>(&ADecBufferDemo::OutputFunc, this);
284     DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
285 
286     return OH_AudioCodec_Start(audioDec_);
287 }
288 
Stop()289 int32_t ADecBufferDemo::Stop()
290 {
291     isRunning_.store(false);
292     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
293         {
294             unique_lock<mutex> lock(signal_->inMutex_);
295             signal_->inCond_.notify_all();
296         }
297         inputLoop_->join();
298         inputLoop_ = nullptr;
299         while (!signal_->inQueue_.empty()) {
300             signal_->inQueue_.pop();
301         }
302         while (!signal_->inBufferQueue_.empty()) {
303             signal_->inBufferQueue_.pop();
304         }
305     }
306 
307     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
308         {
309             unique_lock<mutex> lock(signal_->outMutex_);
310             signal_->outCond_.notify_all();
311         }
312         outputLoop_->join();
313         outputLoop_ = nullptr;
314         while (!signal_->outQueue_.empty()) {
315             signal_->outQueue_.pop();
316         }
317         while (!signal_->outBufferQueue_.empty()) {
318             signal_->outBufferQueue_.pop();
319         }
320     }
321     std::cout << "start stop!\n";
322     return OH_AudioCodec_Stop(audioDec_);
323 }
324 
Flush()325 int32_t ADecBufferDemo::Flush()
326 {
327     isRunning_.store(false);
328     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
329         {
330             unique_lock<mutex> lock(signal_->inMutex_);
331             signal_->inCond_.notify_all();
332         }
333         inputLoop_->join();
334         inputLoop_ = nullptr;
335         while (!signal_->inQueue_.empty()) {
336             signal_->inQueue_.pop();
337         }
338         while (!signal_->inBufferQueue_.empty()) {
339             signal_->inBufferQueue_.pop();
340         }
341         std::cout << "clear input buffer!\n";
342     }
343 
344     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
345         {
346             unique_lock<mutex> lock(signal_->outMutex_);
347             signal_->outCond_.notify_all();
348         }
349         outputLoop_->join();
350         outputLoop_ = nullptr;
351         while (!signal_->outQueue_.empty()) {
352             signal_->outQueue_.pop();
353         }
354         while (!signal_->outBufferQueue_.empty()) {
355             signal_->outBufferQueue_.pop();
356         }
357         std::cout << "clear output buffer!\n";
358     }
359     return OH_AudioCodec_Flush(audioDec_);
360 }
361 
Reset()362 int32_t ADecBufferDemo::Reset()
363 {
364     return OH_AudioCodec_Reset(audioDec_);
365 }
366 
Release()367 int32_t ADecBufferDemo::Release()
368 {
369     return OH_AudioCodec_Destroy(audioDec_);
370 }
371 
HandleInputEOS(const uint32_t index)372 void ADecBufferDemo::HandleInputEOS(const uint32_t index)
373 {
374     std::cout << "end buffer\n";
375     OH_AudioCodec_PushInputBuffer(audioDec_, index);
376     signal_->inBufferQueue_.pop();
377     signal_->inQueue_.pop();
378 }
379 
InputFunc()380 void ADecBufferDemo::InputFunc()
381 {
382     int64_t size;
383     int64_t pts;
384 
385     while (isRunning_.load()) {
386         unique_lock<mutex> lock(signal_->inMutex_);
387         signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
388 
389         if (!isRunning_.load()) {
390             break;
391         }
392 
393         uint32_t index = signal_->inQueue_.front();
394         auto buffer = signal_->inBufferQueue_.front();
395         DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail");
396         inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size));
397         if (inputFile_.eof() || inputFile_.gcount() == 0 || size == 0) {
398             buffer->buffer_->memory_->SetSize(1);
399             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_EOS;
400             HandleInputEOS(index);
401             cout << "Set EOS" << endl;
402             break;
403         }
404         DEMO_CHECK_AND_BREAK_LOG(inputFile_.gcount() == sizeof(size), "Fatal: read size fail");
405         inputFile_.read(reinterpret_cast<char *>(&buffer->buffer_->pts_), sizeof(buffer->buffer_->pts_));
406         DEMO_CHECK_AND_BREAK_LOG(inputFile_.gcount() == sizeof(pts), "Fatal: read pts fail");
407         inputFile_.read(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(buffer)), size);
408         buffer->buffer_->memory_->SetSize(size);
409         DEMO_CHECK_AND_BREAK_LOG(inputFile_.gcount() == size, "Fatal: read buffer fail");
410 
411         cout << "SetSize: " << size << endl;
412         int32_t ret;
413         if (isFirstFrame_) {
414             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
415             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
416             isFirstFrame_ = false;
417         } else {
418             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_NONE;
419             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
420         }
421         signal_->inQueue_.pop();
422         signal_->inBufferQueue_.pop();
423         frameCount_++;
424         if (ret != AVCS_ERR_OK) {
425             cout << "Fatal error, exit " << ret <<endl;
426             break;
427         }
428     }
429     cout << "stop, exit" << endl;
430     inputFile_.close();
431 }
432 
OutputFunc()433 void ADecBufferDemo::OutputFunc()
434 {
435     DEMO_CHECK_AND_RETURN_LOG(pcmOutputFile_.is_open(), "Fatal: output file failedis not open");
436     while (isRunning_.load()) {
437         unique_lock<mutex> lock(signal_->outMutex_);
438         signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
439 
440         if (!isRunning_.load()) {
441             cout << "wait to stop, exit" << endl;
442             break;
443         }
444 
445         uint32_t index = signal_->outQueue_.front();
446         OH_AVBuffer *data = signal_->outBufferQueue_.front();
447         if (data == nullptr) {
448             cout << "OutputFunc OH_AVBuffer is nullptr" << endl;
449             continue;
450         }
451         pcmOutputFile_.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)), data->buffer_->memory_->GetSize());
452 
453         if (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS || data->buffer_->memory_->GetSize() == 0) {
454             cout << "decode eos 1" << endl;
455             isRunning_.store(false);
456             signal_->startCond_.notify_all();
457         }
458         signal_->outBufferQueue_.pop();
459         signal_->outQueue_.pop();
460         if (OH_AudioCodec_FreeOutputBuffer(audioDec_, index) != AV_ERR_OK) {
461             cout << "Fatal: FreeOutputData fail" << endl;
462             break;
463         }
464         if (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS) {
465             cout << "decode eos 2" << endl;
466             isRunning_.store(false);
467             signal_->startCond_.notify_all();
468         }
469     }
470     cout << "stop, exit" << endl;
471     pcmOutputFile_.close();
472 }
473