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