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 <fstream>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include <chrono>
22 #include <fcntl.h>
23 #include "avcodec_codec_name.h"
24 #include "avcodec_common.h"
25 #include "avcodec_errors.h"
26 #include "demo_log.h"
27 #include "media_description.h"
28 #include "native_avcodec_base.h"
29 #include "native_avformat.h"
30 #include "native_avbuffer.h"
31 #include "native_avmemory.h"
32 #include "securec.h"
33 
34 using namespace OHOS;
35 using namespace OHOS::MediaAVCodec;
36 using namespace OHOS::MediaAVCodec::AudioBufferDemo;
37 using namespace OHOS::AudioStandard;
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 uint32_t AMRWB_SAMPLE_RATE = 16000;
44 constexpr uint32_t AMRNB_SAMPLE_RATE = 8000;
45 
46 } // namespace
47 
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)48 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
49 {
50     (void)codec;
51     (void)errorCode;
52     (void)userData;
53     cout << "Error received, errorCode:" << errorCode << endl;
54 }
55 
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)56 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
57 {
58     (void)codec;
59     (void)format;
60     (void)userData;
61     cout << "OnOutputFormatChanged received" << endl;
62 }
63 
OnInputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)64 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
65 {
66     (void)codec;
67     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
68     unique_lock<mutex> lock(signal->inMutex_);
69     signal->inQueue_.push(index);
70     signal->inBufferQueue_.push(data);
71     signal->inCond_.notify_all();
72 }
73 
OnOutputBufferAvailable(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)74 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
75 {
76     (void)codec;
77     ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
78     unique_lock<mutex> lock(signal->outMutex_);
79     signal->outQueue_.push(index);
80     signal->outBufferQueue_.push(data);
81     signal->outCond_.notify_all();
82 }
83 
GetFileSize(const char * fileName)84 static int64_t GetFileSize(const char *fileName)
85 {
86     int64_t fileSize = 0;
87     if (fileName != nullptr) {
88         struct stat fileStatus {};
89         if (stat(fileName, &fileStatus) == 0) {
90             fileSize = static_cast<int64_t>(fileStatus.st_size);
91         }
92     }
93     return fileSize;
94 }
95 
SplitStringFully(const string & str,const string & separator)96 static vector<string> SplitStringFully(const string &str, const string &separator)
97 {
98     vector<string> dest;
99     string substring;
100     string::size_type start = 0;
101     string::size_type index = str.find_first_of(separator, start);
102 
103     while (index != string::npos) {
104         substring = str.substr(start, index - start);
105         dest.push_back(substring);
106         start = str.find_first_not_of(separator, index);
107         if (start == string::npos) {
108             return dest;
109         }
110         index = str.find_first_of(separator, start);
111     }
112     substring = str.substr(start);
113     dest.push_back(substring);
114 
115     return dest;
116 }
117 
StringReplace(std::string & strBig,const std::string & strsrc,const std::string & strdst)118 static void StringReplace(std::string &strBig, const std::string &strsrc, const std::string &strdst)
119 {
120     std::string::size_type pos = 0;
121     std::string::size_type srclen = strsrc.size();
122     std::string::size_type dstlen = strdst.size();
123 
124     while ((pos = strBig.find(strsrc, pos)) != std::string::npos) {
125         strBig.replace(pos, srclen, strdst);
126         pos += dstlen;
127     }
128 }
129 
GetParamsByName(string decoderName,string inputFile,int32_t & channelCount,int32_t & sampleRate,long & bitrate)130 static void GetParamsByName(string decoderName, string inputFile, int32_t &channelCount,
131     int32_t &sampleRate, long &bitrate)
132 {
133     int32_t opusNameSplitNum = 4;
134     vector<string> dest = SplitStringFully(inputFile, "_");
135     if (decoderName == "OH.Media.Codec.Encoder.Audio.Opus") {
136         if (dest.size() < opusNameSplitNum) {
137             cout << "split error !!!" << endl;
138             return;
139         }
140         channelCount = stoi(dest[3]);  // num 3
141         sampleRate = stoi(dest[1]);
142 
143         string bitStr = dest[2];
144         StringReplace(bitStr, "k", "000");
145         bitrate = atol(bitStr.c_str());
146     } else if (decoderName == "OH.Media.Codec.Decoder.Audio.vivid") {
147         if (dest.size() < opusNameSplitNum) {
148             cout << "split error !!!" << endl;
149             return;
150         }
151         channelCount = stoi(dest[3]);  // num 3
152         sampleRate = stoi(dest[1]);
153 
154         string bitStr = dest[2];
155         StringReplace(bitStr, "k", "000");
156         bitrate = atol(bitStr.c_str());
157     } else {
158         if (dest.size() < opusNameSplitNum) {
159             cout << "split error !!!" << endl;
160             return;
161         }
162         channelCount = stoi(dest[3]);  // num 3
163         sampleRate = stoi(dest[2]);    // 2nd parameter
164 
165         string bitStr = dest[1];
166         StringReplace(bitStr, "k", "000");
167         bitrate = atol(bitStr.c_str());
168     }
169 }
170 
RunCase(std::string inputFile,std::string outputFile)171 bool ADecBufferDemo::RunCase(std::string inputFile, std::string outputFile)
172 {
173     DEMO_CHECK_AND_RETURN_RET_LOG(InitFile(inputFile, outputFile), false, "Fatal: InitFile file failed");
174     if (audioType_ == AudioBufferFormatType::TYPE_vivid || audioType_ == AudioBufferFormatType::TYPE_AMRNB ||
175         audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
176         CreatDeMuxer(inputFile);
177     }
178     DEMO_CHECK_AND_RETURN_RET_LOG(CreateDec() == AVCS_ERR_OK, false, "Fatal: CreateDec fail");
179     std::cout << "CreateDec over " << std::endl;
180     OH_AVFormat *format = OH_AVFormat_Create();
181     int32_t channelCount = CHANNEL_COUNT;
182     int32_t sampleRate = SAMPLE_RATE;
183     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
184         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AAC_IS_ADTS.data(), DEFAULT_AAC_TYPE);
185         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
186                                 OH_BitsPerSample::SAMPLE_S16LE);
187     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB || audioType_ == AudioBufferFormatType::TYPE_G711MU) {
188         channelCount = 1;
189         sampleRate = AMRNB_SAMPLE_RATE;
190         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
191                                 OH_BitsPerSample::SAMPLE_S16LE);
192     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
193         channelCount = 1;
194         sampleRate = AMRWB_SAMPLE_RATE;
195         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
196                                 OH_BitsPerSample::SAMPLE_S16LE);
197     } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
198         int32_t channelCounttmp;
199         int32_t sampleRatetmp;
200         long bitrate;
201         GetParamsByName("OH.Media.Codec.Encoder.Audio.Opus", inputFile, channelCounttmp, sampleRatetmp, bitrate);
202         channelCount = channelCounttmp;
203         sampleRate = sampleRatetmp;
204         std::cout << "getParamsByName opus ok = " << std::endl;
205     }
206 
207     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount);
208     OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate);
209     if (audioType_ == AudioBufferFormatType::TYPE_VORBIS) {
210         OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
211                                 OH_BitsPerSample::SAMPLE_S16LE);
212         // extradata for vorbis
213         int64_t extradataSize;
214         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.is_open(), false, "Fatal: file is not open");
215         inputFile_.read(reinterpret_cast<char *>(&extradataSize), sizeof(int64_t));
216         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.gcount() == sizeof(int64_t), false,
217                                       "Fatal: read extradataSize bytes error");
218         if (extradataSize < 0) {
219             return false;
220         }
221         char buffer[extradataSize];
222         inputFile_.read(buffer, extradataSize);
223         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.gcount() == extradataSize, false, "Fatal: read extradata bytes error");
224         OH_AVFormat_SetBuffer(format, MediaDescriptionKey::MD_KEY_CODEC_CONFIG.data(), (uint8_t *)buffer,
225                               extradataSize);
226     }
227     if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
228         OH_AVFormat_SetIntValue(trackFormat, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(),
229                                 OH_BitsPerSample::SAMPLE_S16LE);
230         DEMO_CHECK_AND_RETURN_RET_LOG(Configure(trackFormat) == AVCS_ERR_OK, false, "Fatal: Configure fail");
231         std::cout << "Configure over " << std::endl;
232         audioRenderer->Start();
233         std::cout << "audioRenderer->Start over " << std::endl;
234     } else {
235         DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false, "Fatal: Configure fail");
236     }
237 
238     DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail");
239     std::cout << "Start over " << std::endl;
240     auto start = chrono::steady_clock::now();
241 
242     unique_lock<mutex> lock(signal_->startMutex_);
243     signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); });
244 
245     auto end = chrono::steady_clock::now();
246     std::cout << "decode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count()
247               << " ms" << std::endl;
248 
249     DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail");
250     DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail");
251     OH_AVFormat_Destroy(format);
252     if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
253         if (!audioRenderer->Drain()) {
254             std::cout << "audioRenderer->Drain fail = " << std::endl;
255         }
256         if (!audioRenderer->Release()) {
257             std::cout << "audioRenderer->Release fail = " << std::endl;
258         }
259     }
260 
261     return true;
262 }
263 
InitFile(std::string inputFile,std::string outputFile)264 bool ADecBufferDemo::InitFile(std::string inputFile, std::string outputFile)
265 {
266     if (inputFile_.is_open()) {
267         inputFile_.close();
268     }
269     if (inputFile.find("mp4") != std::string::npos || inputFile.find("m4a") != std::string::npos ||
270         inputFile.find("ts") != std::string::npos) {
271         audioType_ = AudioBufferFormatType::TYPE_vivid;
272     } else if (inputFile.find("opus") != std::string::npos) {
273         audioType_ = AudioBufferFormatType::TYPE_OPUS;
274         inputFile_.open(inputFile, std::ios::in | std::ios::binary);
275         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.is_open(), false, "Fatal: open input file failed");
276         std::cout << "InitFile ok = " << std::endl;
277     } else if (inputFile.find("g711") != std::string::npos) {
278         audioType_ = AudioBufferFormatType::TYPE_G711MU;
279         inputFile_.open(inputFile, std::ios::in | std::ios::binary);
280         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.is_open(), false, "Fatal: open input file failed");
281     } else if (inputFile.find("amrwb") != std::string::npos) {
282         audioType_ = AudioBufferFormatType::TYPE_AMRWB;
283     } else if (inputFile.find("amrnb") != std::string::npos) {
284         audioType_ = AudioBufferFormatType::TYPE_AMRNB;
285     } else {
286         audioType_ = AudioBufferFormatType::TYPE_AAC;
287         inputFile_.open(inputFile, std::ios::in | std::ios::binary);
288         DEMO_CHECK_AND_RETURN_RET_LOG(inputFile_.is_open(), false, "Fatal: open input file failed");
289     }
290 
291     pcmOutputFile_.open(outputFile, std::ios::out | std::ios::binary);
292     DEMO_CHECK_AND_RETURN_RET_LOG(pcmOutputFile_.is_open(), false, "Fatal: open output file failed");
293     inputFile_str = inputFile;
294     outputFile_str = outputFile;
295     return true;
296 }
297 
ADecBufferDemo()298 ADecBufferDemo::ADecBufferDemo() : audioDec_(nullptr), signal_(nullptr), audioType_(AudioBufferFormatType::TYPE_AAC)
299 {
300     signal_ = new ADecBufferSignal();
301     DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory");
302 }
303 
~ADecBufferDemo()304 ADecBufferDemo::~ADecBufferDemo()
305 {
306     if (signal_) {
307         delete signal_;
308         signal_ = nullptr;
309     }
310     if (inputFile_.is_open()) {
311         inputFile_.close();
312     }
313     if (pcmOutputFile_.is_open()) {
314         pcmOutputFile_.close();
315     }
316     if (trackFormat != nullptr) {
317         OH_AVFormat_Destroy(trackFormat);
318         trackFormat = nullptr;
319     }
320     if (avdemuxer_ != nullptr) {
321         OH_AVDemuxer_Destroy(avdemuxer_);
322         avdemuxer_ = nullptr;
323     }
324     if (avsource_ != nullptr) {
325         OH_AVSource_Destroy(avsource_);
326         avsource_ = nullptr;
327     }
328 }
329 
CreateDec()330 int32_t ADecBufferDemo::CreateDec()
331 {
332     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
333         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
334     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
335         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_FLAC_NAME).data());
336     } else if (audioType_ == AudioBufferFormatType::TYPE_MP3) {
337         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_MP3_NAME).data());
338     } else if (audioType_ == AudioBufferFormatType::TYPE_VORBIS) {
339         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_VORBIS_NAME).data());
340     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRNB) {
341         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRNB_NAME).data());
342     } else if (audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
343         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_AMRWB_NAME).data());
344     } else if (audioType_ == AudioBufferFormatType::TYPE_OPUS) {
345         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_OPUS_NAME).data());
346         std::cout << "CreateDec opus ok = " << std::endl;
347     } else if (audioType_ == AudioBufferFormatType::TYPE_G711MU) {
348         audioDec_ = OH_AudioCodec_CreateByName((AVCodecCodecName::AUDIO_DECODER_G711MU_NAME).data());
349     } else if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
350         audioDec_ = OH_AudioCodec_CreateByName("OH.Media.Codec.Decoder.Audio.Vivid");
351     } else {
352         return AVCS_ERR_INVALID_VAL;
353     }
354     DEMO_CHECK_AND_RETURN_RET_LOG(audioDec_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail");
355 
356     if (signal_ == nullptr) {
357         signal_ = new ADecBufferSignal();
358         DEMO_CHECK_AND_RETURN_RET_LOG(signal_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
359     }
360 
361     cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
362     int32_t ret = OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_);
363     DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail");
364 
365     return AVCS_ERR_OK;
366 }
367 
Configure(OH_AVFormat * format)368 int32_t ADecBufferDemo::Configure(OH_AVFormat *format)
369 {
370     return OH_AudioCodec_Configure(audioDec_, format);
371 }
372 
Start()373 int32_t ADecBufferDemo::Start()
374 {
375     isRunning_.store(true);
376 
377     inputLoop_ = make_unique<thread>(&ADecBufferDemo::InputFunc, this);
378     DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
379 
380     outputLoop_ = make_unique<thread>(&ADecBufferDemo::OutputFunc, this);
381     DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory");
382 
383     return OH_AudioCodec_Start(audioDec_);
384 }
385 
Stop()386 int32_t ADecBufferDemo::Stop()
387 {
388     isRunning_.store(false);
389     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
390         {
391             unique_lock<mutex> lock(signal_->inMutex_);
392             signal_->inCond_.notify_all();
393         }
394         inputLoop_->join();
395         inputLoop_ = nullptr;
396         while (!signal_->inQueue_.empty()) {
397             signal_->inQueue_.pop();
398         }
399         while (!signal_->inBufferQueue_.empty()) {
400             signal_->inBufferQueue_.pop();
401         }
402     }
403 
404     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
405         {
406             unique_lock<mutex> lock(signal_->outMutex_);
407             signal_->outCond_.notify_all();
408         }
409         outputLoop_->join();
410         outputLoop_ = nullptr;
411         while (!signal_->outQueue_.empty()) {
412             signal_->outQueue_.pop();
413         }
414         while (!signal_->outBufferQueue_.empty()) {
415             signal_->outBufferQueue_.pop();
416         }
417     }
418     std::cout << "start stop!\n";
419     if (inputFile_.is_open()) {
420         inputFile_.close();
421     }
422     if (pcmOutputFile_.is_open()) {
423         pcmOutputFile_.close();
424     }
425     return OH_AudioCodec_Stop(audioDec_);
426 }
427 
Flush()428 int32_t ADecBufferDemo::Flush()
429 {
430     isRunning_.store(false);
431     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
432         {
433             unique_lock<mutex> lock(signal_->inMutex_);
434             signal_->inCond_.notify_all();
435         }
436         inputLoop_->join();
437         inputLoop_ = nullptr;
438         while (!signal_->inQueue_.empty()) {
439             signal_->inQueue_.pop();
440         }
441         while (!signal_->inBufferQueue_.empty()) {
442             signal_->inBufferQueue_.pop();
443         }
444         std::cout << "clear input buffer!\n";
445     }
446 
447     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
448         {
449             unique_lock<mutex> lock(signal_->outMutex_);
450             signal_->outCond_.notify_all();
451         }
452         outputLoop_->join();
453         outputLoop_ = nullptr;
454         while (!signal_->outQueue_.empty()) {
455             signal_->outQueue_.pop();
456         }
457         while (!signal_->outBufferQueue_.empty()) {
458             signal_->outBufferQueue_.pop();
459         }
460         std::cout << "clear output buffer!\n";
461     }
462     return OH_AudioCodec_Flush(audioDec_);
463 }
464 
Reset()465 int32_t ADecBufferDemo::Reset()
466 {
467     return OH_AudioCodec_Reset(audioDec_);
468 }
469 
Release()470 int32_t ADecBufferDemo::Release()
471 {
472     return OH_AudioCodec_Destroy(audioDec_);
473 }
474 
HandleInputEOS(const uint32_t index)475 void ADecBufferDemo::HandleInputEOS(const uint32_t index)
476 {
477     std::cout << "end buffer\n";
478     OH_AudioCodec_PushInputBuffer(audioDec_, index);
479     signal_->inBufferQueue_.pop();
480     signal_->inQueue_.pop();
481 }
482 
ReadBuffer(OH_AVBuffer * buffer,uint32_t index)483 bool ADecBufferDemo::ReadBuffer(OH_AVBuffer *buffer, uint32_t index)
484 {
485     int64_t size;
486     inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size));
487     if (inputFile_.eof() || inputFile_.gcount() == 0 || size == 0) {
488         buffer->buffer_->memory_->SetSize(1);
489         buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_EOS;
490         HandleInputEOS(index);
491         cout << "Set EOS" << endl;
492         return false;
493     }
494 
495     if (inputFile_.gcount() != sizeof(size)) {
496         cout << "Fatal: read size fail" << endl;
497         return false;
498     }
499 
500     inputFile_.read(reinterpret_cast<char *>(&buffer->buffer_->pts_), sizeof(buffer->buffer_->pts_));
501     if (inputFile_.gcount() != sizeof(buffer->buffer_->pts_)) {
502         cout << "Fatal: read size fail" << endl;
503         return false;
504     }
505 
506     inputFile_.read((char *)OH_AVBuffer_GetAddr(buffer), size);
507     buffer->buffer_->memory_->SetSize(size);
508     if (inputFile_.gcount() != size) {
509         cout << "Fatal: read buffer fail" << endl;
510         return false;
511     }
512 
513     return true;
514 }
515 
InputFunc()516 void ADecBufferDemo::InputFunc()
517 {
518     uint32_t buffersize = 10 * 1024 * 1024;
519     OH_AVMemory *sampleMem = OH_AVMemory_Create(buffersize);
520     while (isRunning_.load()) {
521         if (!isRunning_.load()) {
522             break;
523         }
524         unique_lock<mutex> lock(signal_->inMutex_);
525         signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); });
526 
527         if (!isRunning_.load()) {
528             break;
529         }
530 
531         uint32_t index = signal_->inQueue_.front();
532         auto buffer = signal_->inBufferQueue_.front();
533         DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail");
534         int ret;
535         if (audioType_ == AudioBufferFormatType::TYPE_vivid || audioType_ == AudioBufferFormatType::TYPE_AMRNB ||
536             audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
537             ret = OH_AVDemuxer_ReadSampleBuffer(avdemuxer_, trackIndex_, buffer);
538             buffer->buffer_->dts_ = frameCount_;
539             if (buffer->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS) {
540                 buffer->buffer_->memory_->SetSize(1);
541                 HandleInputEOS(index);
542                 cout << "Set EOS" << endl;
543                 break;
544             }
545         } else {
546             if (ReadBuffer(buffer, index) == false) {
547                 break;
548             }
549         }
550 
551         cout << "InputFunc index:" << index << endl;
552 
553         if (isFirstFrame_) {
554             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
555             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
556             isFirstFrame_ = false;
557         } else {
558             buffer->buffer_->flag_ = AVCODEC_BUFFER_FLAGS_NONE;
559             ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
560         }
561         signal_->inQueue_.pop();
562         signal_->inBufferQueue_.pop();
563         frameCount_++;
564         if (ret != AVCS_ERR_OK) {
565             cout << "Fatal error, exit" << endl;
566             break;
567         }
568     }
569     if (audioType_ == AudioBufferFormatType::TYPE_vivid || audioType_ == AudioBufferFormatType::TYPE_AMRNB ||
570         audioType_ == AudioBufferFormatType::TYPE_AMRWB) {
571         if (fd >= 0) {
572             close(fd);
573             fd = -1;
574         }
575     } else {
576         if (inputFile_.is_open()) {
577             inputFile_.close();
578         }
579     }
580 
581     OH_AVMemory_Destroy(sampleMem);
582 }
583 
OutputFunc()584 void ADecBufferDemo::OutputFunc()
585 {
586     DEMO_CHECK_AND_RETURN_LOG(pcmOutputFile_.is_open(), "Fatal: output file failedis not open");
587     while (isRunning_.load()) {
588         if (!isRunning_.load()) {
589             break;
590         }
591         unique_lock<mutex> lock(signal_->outMutex_);
592         signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); });
593         if (!isRunning_.load()) {
594             break;
595         }
596         if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
597             if (audioRenderer == nullptr) {
598                 isRunning_ = false;
599                 break;
600             }
601         }
602         uint32_t index = signal_->outQueue_.front();
603         OH_AVBuffer* data = signal_->outBufferQueue_.front();
604         if (data == nullptr) {
605             continue;
606         }
607         pcmOutputFile_.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)), data->buffer_->memory_->GetSize());
608         if (data != nullptr &&
609             (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS || data->buffer_->memory_->GetSize() == 0)) {
610             isRunning_.store(false);
611             signal_->startCond_.notify_all();
612         } else {
613             if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
614                 OH_AVFormat *format = OH_AVBuffer_GetParameter(data);
615                 uint8_t *metadata = nullptr;
616                 size_t metasize;
617                 DEMO_CHECK_AND_RETURN_LOG(format != nullptr, "OH_AVBuffer_GetParameter format is nullptr");
618                 OH_AVFormat_GetBuffer(format, OH_MD_KEY_AUDIO_VIVID_METADATA, &metadata, &metasize);
619                 audioRenderer->Write(OH_AVBuffer_GetAddr(data), data->buffer_->memory_->GetSize(), metadata, metasize);
620             }
621         }
622         signal_->outBufferQueue_.pop();
623         signal_->outQueue_.pop();
624         if (OH_AudioCodec_FreeOutputBuffer(audioDec_, index) != AV_ERR_OK) {
625             break;
626         }
627         if (data->buffer_->flag_ == AVCODEC_BUFFER_FLAGS_EOS) {
628             isRunning_.store(false);
629             signal_->startCond_.notify_all();
630         }
631     }
632     pcmOutputFile_.close();
633 }
634 
CreatDeMuxer(const std::string inputFile)635 void ADecBufferDemo::CreatDeMuxer(const std::string inputFile)
636 {
637     fd = open(inputFile.c_str(), O_RDONLY);
638     int64_t size = GetFileSize(inputFile.c_str());
639     cout << inputFile << "----------------------" << fd << "---------" << size << endl;
640     avsource_ = OH_AVSource_CreateWithFD(fd, 0, size);
641     if (avsource_ == nullptr) {
642         cout << "avsource_ is null" << endl;
643         return;
644     }
645 
646     avdemuxer_ = OH_AVDemuxer_CreateWithSource(avsource_);
647     if (avdemuxer_ == nullptr) {
648         cout << "avdemuxer_ is null" << endl;
649         return;
650     }
651 
652     OH_AVFormat *sourceFormat = OH_AVSource_GetSourceFormat(avsource_);
653     int32_t g_trackCount;
654     int ret = OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &g_trackCount);
655     cout << "OH_AVFormat_GetIntValue ret is :" << ret << endl;
656     for (int32_t index = 0; index < g_trackCount; index++) {
657         trackFormat = OH_AVSource_GetTrackFormat(avsource_, index);
658         if (trackFormat == nullptr) {
659             cout << "trackFormat is null" << endl;
660             return;
661         }
662         int tarckType = -1;
663         OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &tarckType);
664         if (tarckType == 0) {
665             trackIndex_ = index;
666             cout << "OH_AVFormat_GetIntValue index is:" << index << endl;
667             break;
668         }
669     }
670     OH_AVFormat_SetIntValue(trackFormat, "audio.vivid.write.meta", 1);
671     OH_AVDemuxer_SelectTrackByID(avdemuxer_, trackIndex_);
672     if (sourceFormat != nullptr) {
673         OH_AVFormat_Destroy(sourceFormat);
674         sourceFormat = nullptr;
675     }
676     if (audioType_ == AudioBufferFormatType::TYPE_vivid) {
677         AudioRendererOptions rendererOptions;
678         int32_t channelNum_Get;
679         int32_t sampleRate_Get;
680         OH_AVFormat_GetIntValue(trackFormat, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), &channelNum_Get);
681         OH_AVFormat_GetIntValue(trackFormat, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), &sampleRate_Get);
682         rendererOptions.streamInfo.samplingRate = AudioSamplingRate(sampleRate_Get);
683         rendererOptions.streamInfo.encoding = AudioEncodingType::ENCODING_AUDIOVIVID;
684         rendererOptions.streamInfo.format = OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE;
685         rendererOptions.streamInfo.channels = AudioChannel(channelNum_Get);
686         rendererOptions.rendererInfo.contentType = ContentType::CONTENT_TYPE_MUSIC;
687         rendererOptions.rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
688         rendererOptions.rendererInfo.rendererFlags = 0;
689         cout << "rendererOptions channelNum_Get is:" << channelNum_Get << endl;
690         cout << "rendererOptions sampleRate_Get is:" << sampleRate_Get << endl;
691         audioRenderer = AudioRenderer::Create(rendererOptions);
692         if (audioRenderer != nullptr) {
693             cout << "audioRenderer is creat" << endl;
694         }
695     }
696 }
697 
SetCallback(OH_AVCodec * codec)698 OH_AVErrCode ADecBufferDemo::SetCallback(OH_AVCodec *codec)
699 {
700     cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
701     return OH_AudioCodec_RegisterCallback(codec, cb_, signal_);
702 }
703 
CreateByMime(const char * mime)704 OH_AVCodec *ADecBufferDemo::CreateByMime(const char *mime)
705 {
706     if (mime != nullptr) {
707         if (0 == strcmp(mime, "audio/mp4a-latm")) {
708             audioType_ = AudioBufferFormatType::TYPE_AAC;
709         } else if (0 == strcmp(mime, "audio/flac")) {
710             audioType_ = AudioBufferFormatType::TYPE_FLAC;
711         } else {
712             audioType_ = AudioBufferFormatType::TYPE_vivid;
713         }
714     }
715     return OH_AudioCodec_CreateByMime(mime, false);
716 }
717 
CreateByName(const char * name)718 OH_AVCodec *ADecBufferDemo::CreateByName(const char *name)
719 {
720     return OH_AudioCodec_CreateByName(name);
721 }
722 
Destroy(OH_AVCodec * codec)723 OH_AVErrCode ADecBufferDemo::Destroy(OH_AVCodec *codec)
724 {
725     OH_AVErrCode ret = OH_AudioCodec_Destroy(codec);
726     return ret;
727 }
728 
IsValid(OH_AVCodec * codec,bool * isValid)729 OH_AVErrCode ADecBufferDemo::IsValid(OH_AVCodec *codec, bool *isValid)
730 {
731     return OH_AudioCodec_IsValid(codec, isValid);
732 }
733 
Prepare(OH_AVCodec * codec)734 OH_AVErrCode ADecBufferDemo::Prepare(OH_AVCodec *codec)
735 {
736     return OH_AudioCodec_Prepare(codec);
737 }
738 
Start(OH_AVCodec * codec)739 OH_AVErrCode ADecBufferDemo::Start(OH_AVCodec *codec)
740 {
741     return OH_AudioCodec_Start(codec);
742 }
743 
Stop(OH_AVCodec * codec)744 OH_AVErrCode ADecBufferDemo::Stop(OH_AVCodec *codec)
745 {
746     OH_AVErrCode ret = OH_AudioCodec_Stop(codec);
747     return ret;
748 }
749 
Flush(OH_AVCodec * codec)750 OH_AVErrCode ADecBufferDemo::Flush(OH_AVCodec *codec)
751 {
752     OH_AVErrCode ret = OH_AudioCodec_Flush(codec);
753     return ret;
754 }
755 
Reset(OH_AVCodec * codec)756 OH_AVErrCode ADecBufferDemo::Reset(OH_AVCodec *codec)
757 {
758     return OH_AudioCodec_Reset(codec);
759 }
760 
GetOutputDescription(OH_AVCodec * codec)761 OH_AVFormat *ADecBufferDemo::GetOutputDescription(OH_AVCodec *codec)
762 {
763     return OH_AudioCodec_GetOutputDescription(codec);
764 }
765 
FreeOutputData(OH_AVCodec * codec,uint32_t index)766 OH_AVErrCode ADecBufferDemo::FreeOutputData(OH_AVCodec *codec, uint32_t index)
767 {
768     return OH_AudioCodec_FreeOutputBuffer(codec, index);
769 }
770 
PushInputData(OH_AVCodec * codec,uint32_t index)771 OH_AVErrCode ADecBufferDemo::PushInputData(OH_AVCodec *codec, uint32_t index)
772 {
773     OH_AVCodecBufferAttr info;
774 
775     if (!signal_->inBufferQueue_.empty()) {
776         unique_lock<mutex> lock(signal_->inMutex_);
777         auto buffer = signal_->inBufferQueue_.front();
778         OH_AVErrCode ret = OH_AVBuffer_GetBufferAttr(buffer, &info);
779         if (ret != AV_ERR_OK) {
780             return ret;
781         }
782         ret = OH_AVBuffer_SetBufferAttr(buffer, &info);
783         if (ret != AV_ERR_OK) {
784             return ret;
785         }
786     }
787 
788     return OH_AudioCodec_PushInputBuffer(codec, index);
789 }
790 
GetInputIndex()791 uint32_t ADecBufferDemo::GetInputIndex()
792 {
793     int32_t sleep_time = 0;
794     uint32_t index;
795     while (signal_->inQueue_.empty() && sleep_time < 5) { // time 5
796         sleep(1);
797         sleep_time++;
798     }
799     if (sleep_time >= 5) {  // time 5
800         return 0;
801     } else {
802         lock_guard<mutex> lock(signal_->inMutex_);
803         index = signal_->inQueue_.front();
804         signal_->inQueue_.pop();
805     }
806     return index;
807 }
808 
GetOutputIndex()809 uint32_t ADecBufferDemo::GetOutputIndex()
810 {
811     int32_t sleep_time = 0;
812     uint32_t index;
813     while (signal_->outQueue_.empty() && sleep_time < 5) {  // time 5
814         sleep(1);
815         sleep_time++;
816     }
817     if (sleep_time >= 5) {  // time 5
818         return 0;
819     } else {
820         index = signal_->outQueue_.front();
821         signal_->outQueue_.pop();
822     }
823     return index;
824 }
825 
PushInputDataEOS(OH_AVCodec * codec,uint32_t index)826 OH_AVErrCode ADecBufferDemo::PushInputDataEOS(OH_AVCodec *codec, uint32_t index)
827 {
828     OH_AVCodecBufferAttr info;
829     info.size = 0;
830     info.offset = 0;
831     info.pts = 0;
832     info.flags = AVCODEC_BUFFER_FLAGS_EOS;
833 
834     if (!signal_->inBufferQueue_.empty()) {
835         unique_lock<mutex> lock(signal_->inMutex_);
836         auto buffer = signal_->inBufferQueue_.front();
837         OH_AVBuffer_SetBufferAttr(buffer, &info);
838         signal_->inBufferQueue_.pop();
839     }
840     return OH_AudioCodec_PushInputBuffer(codec, index);
841 }
842 
Configure(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)843 OH_AVErrCode ADecBufferDemo::Configure(OH_AVCodec *codec, OH_AVFormat *format, int32_t channel, int32_t sampleRate)
844 {
845     if (format == nullptr) {
846         return OH_AudioCodec_Configure(codec, format);
847     }
848     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
849     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
850     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
851         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
852     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
853     }
854     OH_AVErrCode ret = OH_AudioCodec_Configure(codec, format);
855     return ret;
856 }
857 
SetParameter(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)858 OH_AVErrCode ADecBufferDemo::SetParameter(OH_AVCodec *codec, OH_AVFormat *format, int32_t channel, int32_t sampleRate)
859 {
860     if (format == nullptr) {
861         return OH_AudioCodec_SetParameter(codec, format);
862     }
863     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
864     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
865     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
866         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
867     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
868     }
869     OH_AVErrCode ret = OH_AudioCodec_SetParameter(codec, format);
870     return ret;
871 }
872