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 }