• 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 <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     ClearQueue();
727     return ret;
728 }
729 
IsValid(OH_AVCodec * codec,bool * isValid)730 OH_AVErrCode ADecBufferDemo::IsValid(OH_AVCodec *codec, bool *isValid)
731 {
732     return OH_AudioCodec_IsValid(codec, isValid);
733 }
734 
Prepare(OH_AVCodec * codec)735 OH_AVErrCode ADecBufferDemo::Prepare(OH_AVCodec *codec)
736 {
737     return OH_AudioCodec_Prepare(codec);
738 }
739 
Start(OH_AVCodec * codec)740 OH_AVErrCode ADecBufferDemo::Start(OH_AVCodec *codec)
741 {
742     return OH_AudioCodec_Start(codec);
743 }
744 
Stop(OH_AVCodec * codec)745 OH_AVErrCode ADecBufferDemo::Stop(OH_AVCodec *codec)
746 {
747     OH_AVErrCode ret = OH_AudioCodec_Stop(codec);
748     ClearQueue();
749     return ret;
750 }
751 
Flush(OH_AVCodec * codec)752 OH_AVErrCode ADecBufferDemo::Flush(OH_AVCodec *codec)
753 {
754     OH_AVErrCode ret = OH_AudioCodec_Flush(codec);
755     ClearQueue();
756     return ret;
757 }
758 
Reset(OH_AVCodec * codec)759 OH_AVErrCode ADecBufferDemo::Reset(OH_AVCodec *codec)
760 {
761     return OH_AudioCodec_Reset(codec);
762 }
763 
GetOutputDescription(OH_AVCodec * codec)764 OH_AVFormat *ADecBufferDemo::GetOutputDescription(OH_AVCodec *codec)
765 {
766     return OH_AudioCodec_GetOutputDescription(codec);
767 }
768 
FreeOutputData(OH_AVCodec * codec,uint32_t index)769 OH_AVErrCode ADecBufferDemo::FreeOutputData(OH_AVCodec *codec, uint32_t index)
770 {
771     return OH_AudioCodec_FreeOutputBuffer(codec, index);
772 }
773 
PushInputData(OH_AVCodec * codec,uint32_t index)774 OH_AVErrCode ADecBufferDemo::PushInputData(OH_AVCodec *codec, uint32_t index)
775 {
776     OH_AVCodecBufferAttr info;
777 
778     if (!signal_->inBufferQueue_.empty()) {
779         unique_lock<mutex> lock(signal_->inMutex_);
780         auto buffer = signal_->inBufferQueue_.front();
781         OH_AVErrCode ret = OH_AVBuffer_GetBufferAttr(buffer, &info);
782         if (ret != AV_ERR_OK) {
783             return ret;
784         }
785         ret = OH_AVBuffer_SetBufferAttr(buffer, &info);
786         if (ret != AV_ERR_OK) {
787             return ret;
788         }
789     }
790 
791     return OH_AudioCodec_PushInputBuffer(codec, index);
792 }
793 
GetInputIndex()794 uint32_t ADecBufferDemo::GetInputIndex()
795 {
796     int32_t sleep_time = 0;
797     uint32_t index;
798     while (signal_->inQueue_.empty() && sleep_time < 5) { // time 5
799         sleep(1);
800         sleep_time++;
801     }
802     if (sleep_time >= 5) {  // time 5
803         return 0;
804     } else {
805         lock_guard<mutex> lock(signal_->inMutex_);
806         index = signal_->inQueue_.front();
807         signal_->inQueue_.pop();
808     }
809     return index;
810 }
811 
GetOutputIndex()812 uint32_t ADecBufferDemo::GetOutputIndex()
813 {
814     int32_t sleep_time = 0;
815     uint32_t index;
816     while (signal_->outQueue_.empty() && sleep_time < 5) {  // time 5
817         sleep(1);
818         sleep_time++;
819     }
820     if (sleep_time >= 5) {  // time 5
821         return 0;
822     } else {
823         index = signal_->outQueue_.front();
824         signal_->outQueue_.pop();
825     }
826     return index;
827 }
828 
PushInputDataEOS(OH_AVCodec * codec,uint32_t index)829 OH_AVErrCode ADecBufferDemo::PushInputDataEOS(OH_AVCodec *codec, uint32_t index)
830 {
831     OH_AVCodecBufferAttr info;
832     info.size = 0;
833     info.offset = 0;
834     info.pts = 0;
835     info.flags = AVCODEC_BUFFER_FLAGS_EOS;
836 
837     if (!signal_->inBufferQueue_.empty()) {
838         unique_lock<mutex> lock(signal_->inMutex_);
839         auto buffer = signal_->inBufferQueue_.front();
840         OH_AVBuffer_SetBufferAttr(buffer, &info);
841         signal_->inBufferQueue_.pop();
842     }
843     return OH_AudioCodec_PushInputBuffer(codec, index);
844 }
845 
Configure(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)846 OH_AVErrCode ADecBufferDemo::Configure(OH_AVCodec *codec, OH_AVFormat *format, int32_t channel, int32_t sampleRate)
847 {
848     if (format == nullptr) {
849         return OH_AudioCodec_Configure(codec, format);
850     }
851     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
852     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
853     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
854         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
855     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
856     }
857     OH_AVErrCode ret = OH_AudioCodec_Configure(codec, format);
858     return ret;
859 }
860 
SetParameter(OH_AVCodec * codec,OH_AVFormat * format,int32_t channel,int32_t sampleRate)861 OH_AVErrCode ADecBufferDemo::SetParameter(OH_AVCodec *codec, OH_AVFormat *format, int32_t channel, int32_t sampleRate)
862 {
863     if (format == nullptr) {
864         return OH_AudioCodec_SetParameter(codec, format);
865     }
866     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channel);
867     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate);
868     if (audioType_ == AudioBufferFormatType::TYPE_AAC) {
869         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, 1);
870     } else if (audioType_ == AudioBufferFormatType::TYPE_FLAC) {
871     }
872     OH_AVErrCode ret = OH_AudioCodec_SetParameter(codec, format);
873     return ret;
874 }
875 
ClearQueue()876 void ADecBufferDemo::ClearQueue()
877 {
878     while (!signal_->inQueue_.empty())
879         signal_->inQueue_.pop();
880     while (!signal_->outQueue_.empty())
881         signal_->outQueue_.pop();
882     while (!signal_->inBufferQueue_.empty())
883         signal_->inBufferQueue_.pop();
884     while (!signal_->outBufferQueue_.empty())
885         signal_->outBufferQueue_.pop();
886 }
887