• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "ADecEncNdkSample.h"
17 #include "native_avmemory.h"
18 #include "native_averrors.h"
19 #include "native_avcodec_base.h"
20 
21 using namespace OHOS;
22 using namespace OHOS::Media;
23 using namespace std;
24 
25 namespace {
26     constexpr uint32_t SAMPLE_DURATION_US = 23000;
27     constexpr uint32_t STOPNUM = 10000;
28 
AdecAsyncError(OH_AVCodec * codec,int32_t errorCode,void * userData)29     void AdecAsyncError(OH_AVCodec *codec, int32_t errorCode, void *userData)
30     {
31         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
32         cout << "DEC Error errorCode=" << errorCode << endl;
33         acodecSignal_->errorNum_ += 1;
34     }
35 
AdecAsyncStreamChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)36     void AdecAsyncStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
37     {
38         cout << "DEC Format Changed" << endl;
39     }
40 
AdecAsyncNeedInputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,void * userData)41     void AdecAsyncNeedInputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData)
42     {
43         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
44         unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
45         if (acodecSignal_->isFlushing_.load()) {
46             return;
47         }
48         acodecSignal_->inQueueDec_.push(index);
49         acodecSignal_->inBufferQueueDec_.push(data);
50         acodecSignal_->inCondDec_.notify_all();
51     }
52 
AdecAsyncNewOutputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)53     void AdecAsyncNewOutputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data,
54                                 OH_AVCodecBufferAttr *attr, void *userData)
55     {
56         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
57         unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
58         if (acodecSignal_->isFlushing_.load()) {
59             cout << "DEC OutputAvailable: isFlushing_.load() is true, return" << endl;
60             return;
61         }
62         acodecSignal_->outQueueDec_.push(index);
63         acodecSignal_->sizeQueueDec_.push(attr->size);
64         acodecSignal_->flagQueueDec_.push(attr->flags);
65         acodecSignal_->outBufferQueueDec_.push(data);
66         acodecSignal_->inCondEnc_.notify_all();
67     }
68 
AencAsyncError(OH_AVCodec * codec,int32_t errorCode,void * userData)69     void AencAsyncError(OH_AVCodec *codec, int32_t errorCode, void *userData)
70     {
71         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
72         cout << "ENC Error errorCode=" << errorCode << endl;
73         acodecSignal_->errorNum_ += 1;
74     }
75 
AencAsyncStreamChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)76     void AencAsyncStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
77     {
78         cout << "ENC Format Changed" << endl;
79     }
80 
AencAsyncNeedInputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,void * userData)81     void AencAsyncNeedInputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData)
82     {
83         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
84         unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
85         if (acodecSignal_->isFlushing_.load()) {
86             return;
87         }
88         acodecSignal_->inQueueEnc_.push(index);
89         acodecSignal_->inBufferQueueEnc_.push(data);
90         acodecSignal_->inCondEnc_.notify_all();
91     }
92 
AencAsyncNewOutputData(OH_AVCodec * codec,uint32_t index,OH_AVMemory * data,OH_AVCodecBufferAttr * attr,void * userData)93     void AencAsyncNewOutputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data,
94                                 OH_AVCodecBufferAttr *attr, void *userData)
95     {
96         ADecEncSignal* acodecSignal_ = static_cast<ADecEncSignal *>(userData);
97         unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
98         if (acodecSignal_->isFlushing_.load()) {
99             return;
100         }
101         acodecSignal_->outQueueEnc_.push(index);
102         acodecSignal_->sizeQueueEnc_.push(attr->size);
103         acodecSignal_->flagQueueEnc_.push(attr->flags);
104         acodecSignal_->outBufferQueueEnc_.push(data);
105         acodecSignal_->outCondEnc_.notify_all();
106     }
107 
clearIntqueue(std::queue<uint32_t> & q)108     void clearIntqueue (std::queue<uint32_t>& q)
109     {
110         std::queue<uint32_t> empty;
111         swap(empty, q);
112     }
113 
clearBufferqueue(std::queue<OH_AVMemory * > & q)114     void clearBufferqueue (std::queue<OH_AVMemory *>& q)
115     {
116         std::queue<OH_AVMemory *> empty;
117         swap(empty, q);
118     }
119 }
120 
~ADecEncNdkSample()121 ADecEncNdkSample::~ADecEncNdkSample()
122 {
123     OH_AudioDecoder_Destroy(adec_);
124     OH_AudioEncoder_Destroy(aenc_);
125     delete acodecSignal_;
126     acodecSignal_ = nullptr;
127 }
128 
CreateAudioDecoderByMime(std::string mimetype)129 struct OH_AVCodec* ADecEncNdkSample::CreateAudioDecoderByMime(std::string mimetype)
130 {
131     if (mimetype == "audio/mp4a-latm") {
132         adec_ = OH_AudioDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC);
133     } else {
134         adec_ = OH_AudioDecoder_CreateByMime(mimetype.c_str());
135     }
136     NDK_CHECK_AND_RETURN_RET_LOG(adec_ != nullptr, nullptr, "Fatal: OH_AudioDecoder_CreateByMime");
137 
138     acodecSignal_ = new ADecEncSignal();
139     NDK_CHECK_AND_RETURN_RET_LOG(acodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
140 
141     cbDec_.onError = AdecAsyncError;
142     cbDec_.onStreamChanged = AdecAsyncStreamChanged;
143     cbDec_.onNeedInputData = AdecAsyncNeedInputData;
144     cbDec_.onNeedOutputData = AdecAsyncNewOutputData;
145     int32_t ret = OH_AudioDecoder_SetCallback(adec_, cbDec_, static_cast<void *>(acodecSignal_));
146     NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_AudioDecoder_SetCallback");
147     return adec_;
148 }
149 
CreateAudioDecoderByName(std::string name)150 struct OH_AVCodec* ADecEncNdkSample::CreateAudioDecoderByName(std::string name)
151 {
152     adec_ = OH_AudioDecoder_CreateByName(name.c_str());
153     NDK_CHECK_AND_RETURN_RET_LOG(adec_ != nullptr, nullptr, "Fatal: OH_AudioDecoder_CreateByName");
154 
155     acodecSignal_ = new ADecEncSignal();
156     NDK_CHECK_AND_RETURN_RET_LOG(acodecSignal_ != nullptr, nullptr, "Fatal: No Memory");
157 
158     cbDec_.onError = AdecAsyncError;
159     cbDec_.onStreamChanged = AdecAsyncStreamChanged;
160     cbDec_.onNeedInputData = AdecAsyncNeedInputData;
161     cbDec_.onNeedOutputData = AdecAsyncNewOutputData;
162     int32_t ret = OH_AudioDecoder_SetCallback(adec_, cbDec_, static_cast<void *>(acodecSignal_));
163     NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_AudioDecoder_SetCallback");
164     return adec_;
165 }
166 
ConfigureDec(struct OH_AVFormat * format)167 int32_t ADecEncNdkSample::ConfigureDec(struct OH_AVFormat *format)
168 {
169     return OH_AudioDecoder_Configure(adec_, format);
170 }
171 
SetParameterDec(struct OH_AVFormat * format)172 int32_t ADecEncNdkSample::SetParameterDec(struct OH_AVFormat *format)
173 {
174     return OH_AudioDecoder_SetParameter(adec_, format);
175 }
176 
PrepareDec()177 int32_t ADecEncNdkSample::PrepareDec()
178 {
179     return OH_AudioDecoder_Prepare(adec_);
180 }
181 
StartDec()182 int32_t ADecEncNdkSample::StartDec()
183 {
184     cout << "Enter start dec" << endl;
185     isDecRunning_.store(true);
186     if (testFile_ == nullptr) {
187         testFile_ = std::make_unique<std::ifstream>();
188         NDK_CHECK_AND_RETURN_RET_LOG(testFile_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
189         testFile_->open(INP_FILE, std::ios::in | std::ios::binary);
190     }
191     if (inputLoopDec_ == nullptr) {
192         inputLoopDec_ = make_unique<thread>(&ADecEncNdkSample::InputFuncDec, this);
193         NDK_CHECK_AND_RETURN_RET_LOG(inputLoopDec_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
194     }
195     cout << "Exit start dec" << endl;
196     return OH_AudioDecoder_Start(adec_);
197 }
198 
ResetDecParam()199 void ADecEncNdkSample::ResetDecParam()
200 {
201     isDecInputEOS = false;
202     isDecOutputEOS = false;
203     decInCnt_ = 0;
204     decOutCnt_ = 0;
205     acodecSignal_->isFlushing_.store(true);
206     unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
207     clearIntqueue(acodecSignal_->inQueueDec_);
208     clearBufferqueue(acodecSignal_->inBufferQueueDec_);
209     acodecSignal_->inCondDec_.notify_all();
210     lock.unlock();
211     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
212     clearIntqueue(acodecSignal_->outQueueDec_);
213     clearIntqueue(acodecSignal_->sizeQueueDec_);
214     clearIntqueue(acodecSignal_->flagQueueDec_);
215     clearBufferqueue(acodecSignal_->outBufferQueueDec_);
216     acodecSignal_->inCondEnc_.notify_all();
217     lock2.unlock();
218     acodecSignal_->isFlushing_.store(false);
219     isDecRunning_.store(true);
220 }
221 
ResetEncParam()222 void ADecEncNdkSample::ResetEncParam()
223 {
224     isEncInputEOS = false;
225     isEncOutputEOS = false;
226     encInCnt_ = 0;
227     encOutCnt_ = 0;
228     acodecSignal_->isFlushing_.store(true);
229     unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
230     clearIntqueue(acodecSignal_->inQueueEnc_);
231     clearBufferqueue(acodecSignal_->inBufferQueueEnc_);
232     acodecSignal_->inCondEnc_.notify_all();
233     lock.unlock();
234     unique_lock<mutex> lock2(acodecSignal_->outMutexEnc_);
235     clearIntqueue(acodecSignal_->outQueueEnc_);
236     clearIntqueue(acodecSignal_->sizeQueueEnc_);
237     clearIntqueue(acodecSignal_->flagQueueEnc_);
238     clearBufferqueue(acodecSignal_->outBufferQueueEnc_);
239     acodecSignal_->outCondEnc_.notify_all();
240     lock2.unlock();
241     acodecSignal_->isFlushing_.store(false);
242     isEncRunning_.store(true);
243 }
244 
StopDec()245 int32_t ADecEncNdkSample::StopDec()
246 {
247     cout << "ENTER DEC STOP" << endl;
248     unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
249     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
250     acodecSignal_->isFlushing_.store(true);
251     lock.unlock();
252     lock2.unlock();
253     int32_t ret = OH_AudioDecoder_Stop(adec_);
254     unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
255     clearIntqueue(acodecSignal_->inQueueDec_);
256     clearBufferqueue(acodecSignal_->inBufferQueueDec_);
257     acodecSignal_->inCondDec_.notify_all();
258     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
259     clearIntqueue(acodecSignal_->outQueueDec_);
260     clearIntqueue(acodecSignal_->sizeQueueDec_);
261     clearIntqueue(acodecSignal_->flagQueueDec_);
262     clearBufferqueue(acodecSignal_->outBufferQueueDec_);
263     acodecSignal_->inCondEnc_.notify_all();
264     acodecSignal_->isFlushing_.store(false);
265     lockIn.unlock();
266     lockOut.unlock();
267     cout << "EXIT DEC STOP" << endl;
268     return ret;
269 }
270 
FlushDec()271 int32_t ADecEncNdkSample::FlushDec()
272 {
273     cout << "ENTER DEC FLUSH" << endl;
274     unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
275     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
276     acodecSignal_->isFlushing_.store(true);
277     lock.unlock();
278     lock2.unlock();
279     int32_t ret = OH_AudioDecoder_Flush(adec_);
280     unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
281     clearIntqueue(acodecSignal_->inQueueDec_);
282     clearBufferqueue(acodecSignal_->inBufferQueueDec_);
283     acodecSignal_->inCondDec_.notify_all();
284     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
285     clearIntqueue(acodecSignal_->outQueueDec_);
286     clearIntqueue(acodecSignal_->sizeQueueDec_);
287     clearIntqueue(acodecSignal_->flagQueueDec_);
288     clearBufferqueue(acodecSignal_->outBufferQueueDec_);
289     acodecSignal_->inCondEnc_.notify_all();
290     acodecSignal_->isFlushing_.store(false);
291     lockIn.unlock();
292     lockOut.unlock();
293     cout << "EXIT DEC FLUSH" << endl;
294     return ret;
295 }
296 
ResetDec()297 int32_t ADecEncNdkSample::ResetDec()
298 {
299     cout << "enter Reset DEC" << endl;
300     unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
301     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
302     acodecSignal_->isFlushing_.store(true);
303     lock.unlock();
304     lock2.unlock();
305     int32_t ret = OH_AudioDecoder_Reset(adec_);
306     unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
307     clearIntqueue(acodecSignal_->inQueueDec_);
308     clearBufferqueue(acodecSignal_->inBufferQueueDec_);
309     acodecSignal_->inCondDec_.notify_all();
310     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
311     clearIntqueue(acodecSignal_->outQueueDec_);
312     clearIntqueue(acodecSignal_->sizeQueueDec_);
313     clearIntqueue(acodecSignal_->flagQueueDec_);
314     clearBufferqueue(acodecSignal_->outBufferQueueDec_);
315     acodecSignal_->inCondEnc_.notify_all();
316     acodecSignal_->isFlushing_.store(false);
317     lockIn.unlock();
318     lockOut.unlock();
319     cout << "exit Reset DEC" << endl;
320     return ret;
321 }
322 
ReleaseDec()323 int32_t ADecEncNdkSample::ReleaseDec()
324 {
325     cout << "enter Release DEC" << endl;
326     isDecRunning_.store(false);
327     isEncRunning_.store(false);
328     cout << "isDecRunning_ set false" << endl;
329     if (inputLoopDec_ != nullptr && inputLoopDec_->joinable()) {
330         unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
331         acodecSignal_->inQueueDec_.push(STOPNUM);
332         acodecSignal_->inCondDec_.notify_all();
333         lock.unlock();
334         inputLoopDec_->join();
335         inputLoopDec_.reset();
336     }
337     OH_AudioDecoder_Destroy(adec_);
338     cout << "exit Release DEC" << endl;
339     return AV_ERR_OK;
340 }
341 
PopInqueueDec()342 void ADecEncNdkSample::PopInqueueDec()
343 {
344     if (acodecSignal_ == nullptr) {
345         return;
346     }
347     acodecSignal_->inQueueDec_.pop();
348     acodecSignal_->inBufferQueueDec_.pop();
349 }
350 
PushInbufferDec(uint32_t index,uint32_t bufferSize)351 int32_t ADecEncNdkSample::PushInbufferDec(uint32_t index, uint32_t bufferSize)
352 {
353     struct OH_AVCodecBufferAttr attr;
354     attr.offset = 0;
355     attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
356     if (decInCnt_ == ES_LENGTH) {
357         cout << "DEC input: set EOS" << endl;
358         attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
359         attr.pts = 0;
360         attr.size = 0;
361         isDecInputEOS = true;
362     } else {
363         attr.pts = timeStampDec_;
364         attr.size = bufferSize;
365     }
366     return OH_AudioDecoder_PushInputData(adec_, index, attr);
367 }
368 
InputFuncDec()369 void ADecEncNdkSample::InputFuncDec()
370 {
371     while (true) {
372         if (!isDecRunning_.load()) {
373             break;
374         }
375         unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
376         acodecSignal_->inCondDec_.wait(lock, [this]() {return acodecSignal_->inQueueDec_.size() > 0; });
377         if (!isDecRunning_.load()) {
378             break;
379         }
380         uint32_t index = acodecSignal_->inQueueDec_.front();
381         OH_AVMemory *buffer = reinterpret_cast<OH_AVMemory *>(acodecSignal_->inBufferQueueDec_.front());
382         if (acodecSignal_->isFlushing_.load() || isDecInputEOS || buffer == nullptr) {
383             PopInqueueDec();
384             continue;
385         }
386         NDK_CHECK_AND_RETURN_LOG(testFile_ != nullptr && testFile_->is_open(), "Fatal: open file fail");
387         uint32_t bufferSize = 0;
388         if (decInCnt_ < ES_LENGTH) {
389             bufferSize = ES[decInCnt_];
390             char *fileBuffer = (char *)malloc(sizeof(char) * bufferSize + 1);
391             NDK_CHECK_AND_RETURN_LOG(fileBuffer != nullptr, "Fatal: malloc fail");
392             (void)testFile_->read(fileBuffer, bufferSize);
393             if (testFile_->eof()) {
394                 free(fileBuffer);
395                 break;
396             }
397             if (memcpy_s(OH_AVMemory_GetAddr(buffer), OH_AVMemory_GetSize(buffer),
398                 fileBuffer, bufferSize) != EOK) {
399                 free(fileBuffer);
400                 PopInqueueDec();
401                 break;
402             }
403             free(fileBuffer);
404         }
405         if (PushInbufferDec(index, bufferSize) != AV_ERR_OK) {
406             cout << "Fatal: OH_AudioDecoder_PushInputData fail" << endl;
407             acodecSignal_->errorNum_ += 1;
408         } else {
409             decInCnt_++;
410         }
411         timeStampDec_ += SAMPLE_DURATION_US;
412         PopInqueueDec();
413     }
414 }
415 
CreateAudioEncoderByMime(std::string mimetype)416 struct OH_AVCodec* ADecEncNdkSample::CreateAudioEncoderByMime(std::string mimetype)
417 {
418     if (mimetype == "audio/mp4a-latm") {
419         aenc_ = OH_AudioEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC);
420     } else {
421         aenc_ = OH_AudioEncoder_CreateByMime(mimetype.c_str());
422     }
423     NDK_CHECK_AND_RETURN_RET_LOG(aenc_ != nullptr, nullptr, "Fatal: OH_AudioEncoder_CreateByMime");
424     cbEnc_.onError = AencAsyncError;
425     cbEnc_.onStreamChanged = AencAsyncStreamChanged;
426     cbEnc_.onNeedInputData = AencAsyncNeedInputData;
427     cbEnc_.onNeedOutputData = AencAsyncNewOutputData;
428     int32_t ret = OH_AudioEncoder_SetCallback(aenc_, cbEnc_, static_cast<void *>(acodecSignal_));
429     NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_AudioEncoder_SetCallback");
430     return aenc_;
431 }
432 
CreateAudioEncoderByName(std::string name)433 struct OH_AVCodec* ADecEncNdkSample::CreateAudioEncoderByName(std::string name)
434 {
435     aenc_ = OH_AudioEncoder_CreateByName(name.c_str());
436     NDK_CHECK_AND_RETURN_RET_LOG(aenc_ != nullptr, nullptr, "Fatal: OH_AudioEncoder_CreateByName");
437     cbEnc_.onError = AencAsyncError;
438     cbEnc_.onStreamChanged = AencAsyncStreamChanged;
439     cbEnc_.onNeedInputData = AencAsyncNeedInputData;
440     cbEnc_.onNeedOutputData = AencAsyncNewOutputData;
441     int32_t ret = OH_AudioEncoder_SetCallback(aenc_, cbEnc_, static_cast<void *>(acodecSignal_));
442     NDK_CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, NULL, "Fatal: OH_AudioEncoder_SetCallback");
443     return aenc_;
444 }
445 
ConfigureEnc(struct OH_AVFormat * format)446 int32_t ADecEncNdkSample::ConfigureEnc(struct OH_AVFormat *format)
447 {
448     return OH_AudioEncoder_Configure(aenc_, format);
449 }
450 
SetParameterEnc(struct OH_AVFormat * format)451 int32_t ADecEncNdkSample::SetParameterEnc(struct OH_AVFormat *format)
452 {
453     return OH_AudioEncoder_SetParameter(aenc_, format);
454 }
455 
PrepareEnc()456 int32_t ADecEncNdkSample::PrepareEnc()
457 {
458     return OH_AudioEncoder_Prepare(aenc_);
459 }
460 
StartEnc()461 int32_t ADecEncNdkSample::StartEnc()
462 {
463     isEncRunning_.store(true);
464     if (inputLoopEnc_ == nullptr) {
465         inputLoopEnc_ = make_unique<thread>(&ADecEncNdkSample::InputFuncEnc, this);
466         NDK_CHECK_AND_RETURN_RET_LOG(inputLoopEnc_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
467     }
468     if (outputLoopEnc_ == nullptr) {
469         outputLoopEnc_ = make_unique<thread>(&ADecEncNdkSample::OutputFuncEnc, this);
470         NDK_CHECK_AND_RETURN_RET_LOG(outputLoopEnc_ != nullptr, AV_ERR_UNKNOWN, "Fatal: No memory");
471     }
472     return OH_AudioEncoder_Start(aenc_);
473 }
474 
StopEnc()475 int32_t ADecEncNdkSample::StopEnc()
476 {
477     cout << "ENTER ENC STOP" << endl;
478     unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
479     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
480     acodecSignal_->isFlushing_.store(true);
481     lock.unlock();
482     lock2.unlock();
483     int32_t ret = OH_AudioEncoder_Stop(aenc_);
484     unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
485     clearIntqueue(acodecSignal_->outQueueEnc_);
486     clearIntqueue(acodecSignal_->sizeQueueEnc_);
487     clearIntqueue(acodecSignal_->flagQueueEnc_);
488     clearBufferqueue(acodecSignal_->outBufferQueueEnc_);
489     acodecSignal_->outCondEnc_.notify_all();
490     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
491     clearIntqueue(acodecSignal_->inQueueEnc_);
492     clearBufferqueue(acodecSignal_->inBufferQueueEnc_);
493     acodecSignal_->inCondEnc_.notify_all();
494     acodecSignal_->isFlushing_.store(false);
495     lockIn.unlock();
496     lockOut.unlock();
497     cout << "EXIT ENC STOP" << endl;
498     return ret;
499 }
500 
FlushEnc()501 int32_t ADecEncNdkSample::FlushEnc()
502 {
503     cout << "ENTER ENC FLUSH" << endl;
504     unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
505     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
506     acodecSignal_->isFlushing_.store(true);
507     lock.unlock();
508     lock2.unlock();
509     int32_t ret = OH_AudioEncoder_Flush(aenc_);
510     unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
511     clearIntqueue(acodecSignal_->outQueueEnc_);
512     clearIntqueue(acodecSignal_->sizeQueueEnc_);
513     clearIntqueue(acodecSignal_->flagQueueEnc_);
514     clearBufferqueue(acodecSignal_->outBufferQueueEnc_);
515     acodecSignal_->outCondEnc_.notify_all();
516     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
517     clearIntqueue(acodecSignal_->inQueueEnc_);
518     clearBufferqueue(acodecSignal_->inBufferQueueEnc_);
519     acodecSignal_->inCondEnc_.notify_all();
520     acodecSignal_->isFlushing_.store(false);
521     lockIn.unlock();
522     lockOut.unlock();
523     cout << "EXIT ENC FLUSH" << endl;
524     return ret;
525 }
526 
ResetEnc()527 int32_t ADecEncNdkSample::ResetEnc()
528 {
529     cout << "enter Reset ENC" << endl;
530     unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
531     unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
532     acodecSignal_->isFlushing_.store(true);
533     lock.unlock();
534     lock2.unlock();
535     int32_t ret = OH_AudioEncoder_Reset(aenc_);
536     unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
537     clearIntqueue(acodecSignal_->outQueueEnc_);
538     clearIntqueue(acodecSignal_->sizeQueueEnc_);
539     clearIntqueue(acodecSignal_->flagQueueEnc_);
540     clearBufferqueue(acodecSignal_->outBufferQueueEnc_);
541     acodecSignal_->outCondEnc_.notify_all();
542     unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
543     clearIntqueue(acodecSignal_->inQueueEnc_);
544     clearBufferqueue(acodecSignal_->inBufferQueueEnc_);
545     acodecSignal_->inCondEnc_.notify_all();
546     acodecSignal_->isFlushing_.store(false);
547     lockIn.unlock();
548     lockOut.unlock();
549     cout << "exit Reset ENC" << endl;
550     return ret;
551 }
552 
ReleaseEnc()553 int32_t ADecEncNdkSample::ReleaseEnc()
554 {
555     cout << "enter Release ENC" << endl;
556     isEncRunning_.store(false);
557     cout << "set isEncRunning_ false success" << endl;
558     if (inputLoopEnc_ != nullptr && inputLoopEnc_->joinable()) {
559         cout << "enter inputLoopEnc_ set function " << endl;
560         unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
561         acodecSignal_->outQueueDec_.push(STOPNUM);
562         acodecSignal_->inQueueEnc_.push(STOPNUM);
563         acodecSignal_->inCondEnc_.notify_all();
564         lock.unlock();
565         inputLoopEnc_->join();
566         inputLoopEnc_.reset();
567     }
568     cout << "set inputLoopEnc_ release success" << endl;
569     if (outputLoopEnc_ != nullptr && outputLoopEnc_->joinable()) {
570         unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
571         acodecSignal_->outQueueEnc_.push(STOPNUM);
572         acodecSignal_->outCondEnc_.notify_all();
573         lock.unlock();
574         outputLoopEnc_->join();
575         outputLoopEnc_.reset();
576     }
577     OH_AudioEncoder_Destroy(aenc_);
578     cout << "exit RELEASE ENC" << endl;
579     return AV_ERR_OK;
580 }
581 
PopOutqueueDec()582 void ADecEncNdkSample::PopOutqueueDec()
583 {
584     if (acodecSignal_ == nullptr) {
585         return;
586     }
587     acodecSignal_->outQueueDec_.pop();
588     acodecSignal_->sizeQueueDec_.pop();
589     acodecSignal_->flagQueueDec_.pop();
590     acodecSignal_->outBufferQueueDec_.pop();
591 }
592 
PopInqueueEnc()593 void ADecEncNdkSample::PopInqueueEnc()
594 {
595     if (acodecSignal_ == nullptr) {
596         return;
597     }
598     acodecSignal_->inQueueEnc_.pop();
599     acodecSignal_->inBufferQueueEnc_.pop();
600 }
601 
PushInbufferEnc()602 int32_t ADecEncNdkSample::PushInbufferEnc()
603 {
604     uint32_t indexEnc = acodecSignal_->inQueueEnc_.front();
605     OH_AVMemory *bufferEnc = reinterpret_cast<OH_AVMemory *>(acodecSignal_->inBufferQueueEnc_.front());
606     if (bufferEnc == nullptr) {
607         cout << "Fatal: GetEncInputBuffer fail" << endl;
608         return AV_ERR_NO_MEMORY;
609     }
610     uint32_t indexDec = acodecSignal_->outQueueDec_.front();
611     OH_AVMemory *bufferDec = acodecSignal_->outBufferQueueDec_.front();
612     uint32_t sizeDecOut = acodecSignal_->sizeQueueDec_.front();
613     uint32_t flagDecOut = acodecSignal_->flagQueueDec_.front();
614 
615     struct OH_AVCodecBufferAttr attr;
616     attr.offset = 0;
617     attr.size = sizeDecOut;
618     attr.pts = timeStampEnc_;
619     attr.flags = 0;
620     if (flagDecOut == 1) {
621         cout << "DEC output EOS " << endl;
622         isDecOutputEOS = true;
623         cout << "set isDecOutputEOS = true " << endl;
624         if (setEos) {
625             isEncInputEOS = true;
626             attr.flags = 1;
627         }
628     } else {
629         if (memcpy_s(OH_AVMemory_GetAddr(bufferEnc), OH_AVMemory_GetSize(bufferEnc),
630             OH_AVMemory_GetAddr(bufferDec), sizeDecOut) != EOK) {
631             cout << "ENC input Fatal: memcpy fail" << endl;
632             PopOutqueueDec();
633             PopInqueueEnc();
634             return AV_ERR_OPERATE_NOT_PERMIT;
635         }
636         if (OH_AudioDecoder_FreeOutputData(adec_, indexDec) != AV_ERR_OK) {
637             cout << "Fatal: DEC ReleaseDecOutputBuffer fail" << endl;
638             acodecSignal_->errorNum_ += 1;
639         } else {
640             decOutCnt_ += 1;
641         }
642     }
643     return OH_AudioEncoder_PushInputData(aenc_, indexEnc, attr);
644 }
645 
InputFuncEnc()646 void ADecEncNdkSample::InputFuncEnc()
647 {
648     while (true) {
649         cout << "DEC enter InputFuncEnc()" << endl;
650         if (!isEncRunning_.load()) {
651             break;
652         }
653         unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
654         acodecSignal_->inCondEnc_.wait(lock, [this]() {
655             return (acodecSignal_->inQueueEnc_.size() > 0 && acodecSignal_->outQueueDec_.size() > 0);
656         });
657 
658         if (!isEncRunning_.load()) {
659             break;
660         }
661         if (acodecSignal_->isFlushing_.load() || isDecOutputEOS) {
662             PopOutqueueDec();
663             PopInqueueEnc();
664             continue;
665         }
666         if (PushInbufferEnc() != AV_ERR_OK) {
667             cout << "Fatal error, exit" << endl;
668             acodecSignal_->errorNum_ += 1;
669         } else {
670             encInCnt_++;
671         }
672         timeStampEnc_ += SAMPLE_DURATION_US;
673         PopOutqueueDec();
674         PopInqueueEnc();
675     }
676 }
677 
PopOutqueueEnc()678 void ADecEncNdkSample::PopOutqueueEnc()
679 {
680     if (acodecSignal_ == nullptr) {
681         return;
682     }
683     acodecSignal_->outQueueEnc_.pop();
684     acodecSignal_->sizeQueueEnc_.pop();
685     acodecSignal_->flagQueueEnc_.pop();
686     acodecSignal_->outBufferQueueEnc_.pop();
687 }
688 
WriteToFile()689 int32_t ADecEncNdkSample::WriteToFile()
690 {
691     auto buffer = acodecSignal_->outBufferQueueEnc_.front();
692     if (buffer == nullptr) {
693         cout << "getOutPut Buffer fail" << endl;
694         return AV_ERR_INVALID_VAL;
695     }
696     uint32_t size = acodecSignal_->sizeQueueEnc_.front();
697     FILE *outFile = fopen(OUT_FILE, "a");
698     if (outFile == nullptr) {
699         cout << "dump data fail" << endl;
700         return AV_ERR_INVALID_VAL;
701     } else {
702         fwrite(OH_AVMemory_GetAddr(buffer), 1, size, outFile);
703     }
704     return fclose(outFile);
705 }
706 
OutputFuncEnc()707 void ADecEncNdkSample::OutputFuncEnc()
708 {
709     while (true) {
710         if (!isEncRunning_.load()) {
711             break;
712         }
713         unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
714         acodecSignal_->outCondEnc_.wait(lock, [this]() { return acodecSignal_->outQueueEnc_.size() > 0; });
715         if (!isEncRunning_.load()) {
716             break;
717         }
718         if (acodecSignal_->isFlushing_.load() || isEncOutputEOS) {
719             PopOutqueueEnc();
720             continue;
721         }
722         uint32_t index = acodecSignal_->outQueueEnc_.front();
723         uint32_t encOutflag = acodecSignal_->flagQueueEnc_.front();
724         if (encOutflag == 1) {
725             cout << "ENC get output EOS" << endl;
726             isEncOutputEOS = true;
727         } else {
728             if (WriteToFile() != 0) {
729                 PopOutqueueEnc();
730                 continue;
731             }
732             if (OH_AudioEncoder_FreeOutputData(aenc_, index) != AV_ERR_OK) {
733                 cout << "Fatal: ReleaseOutputBuffer fail" << endl;
734                 acodecSignal_->errorNum_ += 1;
735             } else {
736                 encOutCnt_ += 1;
737                 cout << "ENC output cnt: " << encOutCnt_ << endl;
738             }
739         }
740         PopOutqueueEnc();
741     }
742 }
743 
SetReadPath(const char * inp_path,uint32_t es[],uint32_t length)744 void ADecEncNdkSample::SetReadPath(const char * inp_path, uint32_t es[], uint32_t length)
745 {
746     INP_FILE = inp_path;
747     ES = es;
748     ES_LENGTH = length;
749 }
750 
ReRead()751 void ADecEncNdkSample::ReRead()
752 {
753     if (testFile_ != nullptr) {
754         testFile_->close();
755         cout << "ReRead close before file success " << endl;
756     }
757     cout << "ReRead INP_FILE is " << INP_FILE << endl;
758     testFile_->open(INP_FILE, std::ios::in | std::ios::binary);
759     if (testFile_ != nullptr) {
760         cout << "testFile open success" << endl;
761     }
762     decInCnt_ = 0;
763 }
764 
SetEosState(bool needSetEos)765 void ADecEncNdkSample::SetEosState(bool needSetEos)
766 {
767     setEos = needSetEos;
768 }
769 
SetSavePath(const char * outp_path)770 void ADecEncNdkSample::SetSavePath(const char * outp_path)
771 {
772     OUT_FILE = outp_path;
773 }
774 
CalcuError()775 int32_t ADecEncNdkSample::CalcuError()
776 {
777     cout << "errorNum_ is :" << acodecSignal_->errorNum_ << endl;
778     cout << "decInCnt_ is :" << decInCnt_ << endl;
779     cout << "decOutCnt_ is :" << decOutCnt_ << endl;
780     cout << "encInCnt_ is :" << encInCnt_ << endl;
781     cout << "encOutCnt_ is :" << encOutCnt_ << endl;
782     cout << "acodecSignal_->inQueueDec_.size() is :" << acodecSignal_->inQueueDec_.size() << endl;
783     cout << "acodecSignal_->outQueueDec_.size() is :" << acodecSignal_->outQueueDec_.size() << endl;
784     cout << "acodecSignal_->inQueueEnc_.size() is :" << acodecSignal_->inQueueEnc_.size() << endl;
785     cout << "acodecSignal_->outQueueEnc_.size() is :" << acodecSignal_->outQueueEnc_.size() << endl;
786     return acodecSignal_->errorNum_ ;
787 }
788 
GetFrameCount()789 int32_t ADecEncNdkSample::GetFrameCount()
790 {
791     return encOutCnt_;
792 }
793 
GetEncEosState()794 bool ADecEncNdkSample::GetEncEosState()
795 {
796     return isEncOutputEOS;
797 }
798 
GetDecEosState()799 bool ADecEncNdkSample::GetDecEosState()
800 {
801     return isDecOutputEOS;
802 }