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