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 "acodec_mock.h"
17 #include <sync_fence.h>
18 #include "avcodec_common.h"
19 #include "media_errors.h"
20
21 using namespace std;
22 using namespace OHOS::Media::ACodecTestParam;
23
24 namespace OHOS {
25 namespace Media {
ADecCallbackTest(std::shared_ptr<ACodecSignal> signal)26 ADecCallbackTest::ADecCallbackTest(std::shared_ptr<ACodecSignal> signal)
27 : acodecSignal_(signal)
28 {
29 }
30
~ADecCallbackTest()31 ADecCallbackTest::~ADecCallbackTest()
32 {
33 }
34
OnError(int32_t errorCode)35 void ADecCallbackTest::OnError(int32_t errorCode)
36 {
37 cout << "DEC Error errorCode=" << errorCode << endl;
38 if (acodecSignal_ == nullptr) {
39 return;
40 }
41 acodecSignal_->errorNum_ += 1;
42 }
43
OnStreamChanged(std::shared_ptr<FormatMock> format)44 void ADecCallbackTest::OnStreamChanged(std::shared_ptr<FormatMock> format)
45 {
46 cout << "DEC Format Changed" << endl;
47 }
48
OnNeedInputData(uint32_t index,std::shared_ptr<AVMemoryMock> data)49 void ADecCallbackTest::OnNeedInputData(uint32_t index, std::shared_ptr<AVMemoryMock> data)
50 {
51 if (acodecSignal_ == nullptr) {
52 return;
53 }
54 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
55 if (acodecSignal_->isFlushing_.load()) {
56 return;
57 }
58 acodecSignal_->inQueueDec_.push(index);
59 acodecSignal_->inBufferQueueDec_.push(data);
60 acodecSignal_->inCondDec_.notify_all();
61 }
62
OnNewOutputData(uint32_t index,std::shared_ptr<AVMemoryMock> data,AVCodecBufferAttrMock attr)63 void ADecCallbackTest::OnNewOutputData(uint32_t index, std::shared_ptr<AVMemoryMock> data, AVCodecBufferAttrMock attr)
64 {
65 if (acodecSignal_ == nullptr) {
66 return;
67 }
68 unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
69 if (acodecSignal_->isFlushing_.load()) {
70 cout << "DEC OutputAvailable: isFlushing_.load() is true, return" << endl;
71 return;
72 }
73 acodecSignal_->outQueueDec_.push(index);
74 acodecSignal_->sizeQueueDec_.push(attr.size);
75 acodecSignal_->flagQueueDec_.push(attr.flags);
76 acodecSignal_->outBufferQueueDec_.push(data);
77 acodecSignal_->inCondEnc_.notify_all();
78 }
79
AEncCallbackTest(std::shared_ptr<ACodecSignal> signal)80 AEncCallbackTest::AEncCallbackTest(std::shared_ptr<ACodecSignal> signal)
81 : acodecSignal_(signal)
82 {
83 }
84
~AEncCallbackTest()85 AEncCallbackTest::~AEncCallbackTest()
86 {
87 }
88
OnError(int32_t errorCode)89 void AEncCallbackTest::OnError(int32_t errorCode)
90 {
91 cout << "ENC Error errorCode=" << errorCode << endl;
92 }
93
OnStreamChanged(std::shared_ptr<FormatMock> format)94 void AEncCallbackTest::OnStreamChanged(std::shared_ptr<FormatMock> format)
95 {
96 cout << "ENC Format Changed" << endl;
97 }
98
OnNeedInputData(uint32_t index,std::shared_ptr<AVMemoryMock> data)99 void AEncCallbackTest::OnNeedInputData(uint32_t index, std::shared_ptr<AVMemoryMock> data)
100 {
101 if (acodecSignal_ == nullptr) {
102 return;
103 }
104 unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
105 if (acodecSignal_->isFlushing_.load()) {
106 return;
107 }
108 acodecSignal_->inQueueEnc_.push(index);
109 acodecSignal_->inBufferQueueEnc_.push(data);
110 acodecSignal_->inCondEnc_.notify_all();
111 }
112
OnNewOutputData(uint32_t index,std::shared_ptr<AVMemoryMock> data,AVCodecBufferAttrMock attr)113 void AEncCallbackTest::OnNewOutputData(uint32_t index, std::shared_ptr<AVMemoryMock> data, AVCodecBufferAttrMock attr)
114 {
115 if (acodecSignal_ == nullptr) {
116 return;
117 }
118 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
119 if (acodecSignal_->isFlushing_.load()) {
120 return;
121 }
122 acodecSignal_->outQueueEnc_.push(index);
123 acodecSignal_->sizeQueueEnc_.push(attr.size);
124 acodecSignal_->flagQueueEnc_.push(attr.flags);
125 acodecSignal_->outBufferQueueEnc_.push(data);
126 acodecSignal_->outCondEnc_.notify_all();
127 }
128
clearIntQueue(std::queue<uint32_t> & q)129 void ACodecMock::clearIntQueue (std::queue<uint32_t>& q)
130 {
131 std::queue<uint32_t> empty;
132 swap(empty, q);
133 }
134
clearBufferQueue(std::queue<std::shared_ptr<AVMemoryMock>> & q)135 void ACodecMock::clearBufferQueue (std::queue<std::shared_ptr<AVMemoryMock>>& q)
136 {
137 std::queue<std::shared_ptr<AVMemoryMock>> empty;
138 swap(empty, q);
139 }
140
ACodecMock(std::shared_ptr<ACodecSignal> signal)141 ACodecMock::ACodecMock(std::shared_ptr<ACodecSignal> signal)
142 : acodecSignal_(signal)
143 {
144 }
145
~ACodecMock()146 ACodecMock::~ACodecMock()
147 {
148 }
149
CreateAudioDecMockByMime(const std::string & mime)150 bool ACodecMock::CreateAudioDecMockByMime(const std::string &mime)
151 {
152 audioDec_ = AVCodecMockFactory::CreateAudioDecMockByMime(mime);
153 return audioDec_ != nullptr;
154 }
155
CreateAudioDecMockByName(const std::string & name)156 bool ACodecMock::CreateAudioDecMockByName(const std::string &name)
157 {
158 audioDec_ = AVCodecMockFactory::CreateAudioDecMockByName(name);
159 return audioDec_ != nullptr;
160 }
161
SetCallbackDec(std::shared_ptr<AVCodecCallbackMock> cb)162 int32_t ACodecMock::SetCallbackDec(std::shared_ptr<AVCodecCallbackMock> cb)
163 {
164 if (audioDec_ == nullptr) {
165 return MSERR_INVALID_VAL;
166 }
167 return audioDec_->SetCallback(cb);
168 }
169
ConfigureDec(std::shared_ptr<FormatMock> format)170 int32_t ACodecMock::ConfigureDec(std::shared_ptr<FormatMock> format)
171 {
172 if (audioDec_ == nullptr) {
173 return MSERR_INVALID_VAL;
174 }
175 return audioDec_->Configure(format);
176 }
177
PrepareDec()178 int32_t ACodecMock::PrepareDec()
179 {
180 if (audioDec_ == nullptr) {
181 return MSERR_INVALID_VAL;
182 }
183 return audioDec_->Prepare();
184 }
185
StartDec()186 int32_t ACodecMock::StartDec()
187 {
188 if (audioDec_ == nullptr) {
189 return MSERR_INVALID_VAL;
190 }
191 isDecRunning_.store(true);
192
193 if (testFile_ == nullptr) {
194 testFile_ = std::make_unique<std::ifstream>();
195 UNITTEST_CHECK_AND_RETURN_RET_LOG(testFile_ != nullptr, MSERR_OK, "Fatal: No memory");
196 testFile_->open("/data/test/media/AAC_48000_32_1.aac", std::ios::in | std::ios::binary);
197 }
198 if (inputLoopDec_ == nullptr) {
199 inputLoopDec_ = make_unique<thread>(&ACodecMock::InputFuncDec, this);
200 UNITTEST_CHECK_AND_RETURN_RET_LOG(inputLoopDec_ != nullptr, MSERR_OK, "Fatal: No memory");
201 }
202 return audioDec_->Start();
203 }
204
StopDec()205 int32_t ACodecMock::StopDec()
206 {
207 if (acodecSignal_ == nullptr || audioDec_ == nullptr) {
208 return MSERR_INVALID_VAL;
209 }
210 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
211 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
212 acodecSignal_->isFlushing_.store(true);
213 lock.unlock();
214 lock2.unlock();
215 int32_t ret = audioDec_->Stop();
216 unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
217 clearIntQueue(acodecSignal_->inQueueDec_);
218 clearBufferQueue(acodecSignal_->inBufferQueueDec_);
219 acodecSignal_->inCondDec_.notify_all();
220 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
221 clearIntQueue(acodecSignal_->outQueueDec_);
222 clearIntQueue(acodecSignal_->sizeQueueDec_);
223 clearIntQueue(acodecSignal_->flagQueueDec_);
224 clearBufferQueue(acodecSignal_->outBufferQueueDec_);
225 acodecSignal_->inCondEnc_.notify_all();
226 acodecSignal_->isFlushing_.store(false);
227 lockIn.unlock();
228 lockOut.unlock();
229 return ret;
230 }
231
FlushDec()232 int32_t ACodecMock::FlushDec()
233 {
234 if (acodecSignal_ == nullptr || audioDec_ == nullptr) {
235 return MSERR_INVALID_VAL;
236 }
237 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
238 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
239 acodecSignal_->isFlushing_.store(true);
240 lock.unlock();
241 lock2.unlock();
242 int32_t ret = audioDec_->Flush();
243 unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
244 clearIntQueue(acodecSignal_->inQueueDec_);
245 clearBufferQueue(acodecSignal_->inBufferQueueDec_);
246 acodecSignal_->inCondDec_.notify_all();
247 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
248 clearIntQueue(acodecSignal_->outQueueDec_);
249 clearIntQueue(acodecSignal_->sizeQueueDec_);
250 clearIntQueue(acodecSignal_->flagQueueDec_);
251 clearBufferQueue(acodecSignal_->outBufferQueueDec_);
252 acodecSignal_->inCondEnc_.notify_all();
253 acodecSignal_->isFlushing_.store(false);
254 lockIn.unlock();
255 lockOut.unlock();
256 return ret;
257 }
258
ResetDec()259 int32_t ACodecMock::ResetDec()
260 {
261 if (acodecSignal_ == nullptr || audioDec_ == nullptr) {
262 return MSERR_INVALID_VAL;
263 }
264 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
265 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
266 acodecSignal_->isFlushing_.store(true);
267 lock.unlock();
268 lock2.unlock();
269 int32_t ret = audioDec_->Reset();
270 unique_lock<mutex> lockIn(acodecSignal_->inMutexDec_);
271 clearIntQueue(acodecSignal_->inQueueDec_);
272 clearBufferQueue(acodecSignal_->inBufferQueueDec_);
273 acodecSignal_->inCondDec_.notify_all();
274 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
275 clearIntQueue(acodecSignal_->outQueueDec_);
276 clearIntQueue(acodecSignal_->sizeQueueDec_);
277 clearIntQueue(acodecSignal_->flagQueueDec_);
278 clearBufferQueue(acodecSignal_->outBufferQueueDec_);
279 acodecSignal_->inCondEnc_.notify_all();
280 acodecSignal_->isFlushing_.store(false);
281 lockIn.unlock();
282 lockOut.unlock();
283 return ret;
284 }
285
ReleaseDec()286 int32_t ACodecMock::ReleaseDec()
287 {
288 if (acodecSignal_ == nullptr || audioDec_ == nullptr) {
289 return MSERR_INVALID_VAL;
290 }
291 isDecRunning_.store(false);
292 isEncRunning_.store(false);
293 if (inputLoopDec_ != nullptr && inputLoopDec_->joinable()) {
294 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
295 acodecSignal_->inQueueDec_.push(10000); // push 10000 to stop queue
296 acodecSignal_->inCondDec_.notify_all();
297 lock.unlock();
298 inputLoopDec_->join();
299 inputLoopDec_.reset();
300 }
301 return audioDec_->Release();
302 }
303
GetOutputMediaDescriptionDec()304 std::shared_ptr<FormatMock> ACodecMock::GetOutputMediaDescriptionDec()
305 {
306 if (audioDec_ == nullptr) {
307 return nullptr;
308 }
309 return audioDec_->GetOutputMediaDescription();
310 }
311
SetParameterDec(std::shared_ptr<FormatMock> format)312 int32_t ACodecMock::SetParameterDec(std::shared_ptr<FormatMock> format)
313 {
314 if (audioDec_ == nullptr) {
315 return MSERR_INVALID_VAL;
316 }
317 return audioDec_->SetParameter(format);
318 }
319
PushInputDataDec(uint32_t index,AVCodecBufferAttrMock & attr)320 int32_t ACodecMock::PushInputDataDec(uint32_t index, AVCodecBufferAttrMock &attr)
321 {
322 if (audioDec_ == nullptr) {
323 return MSERR_INVALID_VAL;
324 }
325 return audioDec_->PushInputData(index, attr);
326 }
327
FreeOutputDataDec(uint32_t index)328 int32_t ACodecMock::FreeOutputDataDec(uint32_t index)
329 {
330 if (audioDec_ == nullptr) {
331 return MSERR_INVALID_VAL;
332 }
333 return audioDec_->FreeOutputData(index);
334 }
335
SetOutPath(const std::string & path)336 void ACodecMock::SetOutPath(const std::string &path)
337 {
338 outPath_ = path;
339 }
340
PopOutQueueDec()341 void ACodecMock::PopOutQueueDec()
342 {
343 if (acodecSignal_ == nullptr) {
344 return;
345 }
346 acodecSignal_->outQueueDec_.pop();
347 acodecSignal_->sizeQueueDec_.pop();
348 acodecSignal_->flagQueueDec_.pop();
349 acodecSignal_->outBufferQueueDec_.pop();
350 }
351
PopInQueueDec()352 void ACodecMock::PopInQueueDec()
353 {
354 if (acodecSignal_ == nullptr) {
355 return;
356 }
357 acodecSignal_->inQueueDec_.pop();
358 acodecSignal_->inBufferQueueDec_.pop();
359 }
360
PushInputDataDecInner(uint32_t index,uint32_t bufferSize)361 int32_t ACodecMock::PushInputDataDecInner(uint32_t index, uint32_t bufferSize)
362 {
363 if (audioDec_ == nullptr) {
364 return MSERR_INVALID_VAL;
365 }
366 struct AVCodecBufferAttrMock attr;
367 attr.offset = 0;
368 attr.flags = AVCODEC_BUFFER_FLAG_NONE;
369 if (decInCnt_ == ES_LENGTH) {
370 cout << "DEC input: set EOS" << endl;
371 attr.flags = AVCODEC_BUFFER_FLAG_EOS;
372 attr.pts = 0;
373 attr.size = 0;
374 attr.offset = 0;
375 isDecInputEOS_ = true;
376 } else {
377 attr.pts = timeStampDec_;
378 attr.size = bufferSize;
379 attr.offset = 0;
380 if (decInCnt_ == 0 && MIME_TYPE == "audio/vorbis") {
381 attr.flags = AVCODEC_BUFFER_FLAG_CODEC_DATA;
382 } else {
383 attr.flags = AVCODEC_BUFFER_FLAG_NONE;
384 }
385 }
386 return audioDec_->PushInputData(index, attr);
387 }
388
InputFuncDec()389 void ACodecMock::InputFuncDec()
390 {
391 if (acodecSignal_ == nullptr || audioDec_ == nullptr) {
392 return;
393 }
394 while (true) {
395 if (!isDecRunning_.load()) {
396 break;
397 }
398
399 unique_lock<mutex> lock(acodecSignal_->inMutexDec_);
400 acodecSignal_->inCondDec_.wait(lock, [this]() { return acodecSignal_->inQueueDec_.size() > 0; });
401
402 if (!isDecRunning_.load()) {
403 break;
404 }
405
406 uint32_t index = acodecSignal_->inQueueDec_.front();
407 std::shared_ptr<AVMemoryMock> buffer = acodecSignal_->inBufferQueueDec_.front();
408 if (acodecSignal_->isFlushing_.load() || isDecInputEOS_ || buffer == nullptr) {
409 PopInQueueDec();
410 continue;
411 }
412 UNITTEST_CHECK_AND_RETURN_LOG(testFile_ != nullptr && testFile_->is_open(), "Fatal: open file fail");
413
414 uint32_t bufferSize = 0; // replace with the actual size
415 if (decInCnt_ < ES_LENGTH) {
416 bufferSize = ES[decInCnt_];
417 char *fileBuffer = static_cast<char *>(malloc(sizeof(char) * bufferSize + 1));
418 UNITTEST_CHECK_AND_RETURN_LOG(fileBuffer != nullptr, "Fatal: malloc fail");
419
420 (void)testFile_->read(fileBuffer, bufferSize);
421 if (testFile_->eof()) {
422 free(fileBuffer);
423 break;
424 }
425 if (memcpy_s(buffer->GetAddr(), buffer->GetSize(), fileBuffer, bufferSize) != EOK) {
426 free(fileBuffer);
427 PopInQueueDec();
428 break;
429 }
430 free(fileBuffer);
431 }
432 if (PushInputDataDecInner(index, bufferSize) != MSERR_OK) {
433 acodecSignal_->errorNum_ += 1;
434 } else {
435 decInCnt_ ++;
436 }
437 timeStampDec_ += SAMPLE_DURATION_US;
438 PopInQueueDec();
439 }
440 }
441
CreateAudioEncMockByMime(const std::string & mime)442 bool ACodecMock::CreateAudioEncMockByMime(const std::string &mime)
443 {
444 audioEnc_ = AVCodecMockFactory::CreateAudioEncMockByMime(mime);
445 return audioEnc_ != nullptr;
446 }
447
CreateAudioEncMockByName(const std::string & name)448 bool ACodecMock::CreateAudioEncMockByName(const std::string &name)
449 {
450 audioEnc_ = AVCodecMockFactory::CreateAudioEncMockByName(name);
451 return audioEnc_ != nullptr;
452 }
453
SetCallbackEnc(std::shared_ptr<AVCodecCallbackMock> cb)454 int32_t ACodecMock::SetCallbackEnc(std::shared_ptr<AVCodecCallbackMock> cb)
455 {
456 if (audioEnc_ == nullptr) {
457 return MSERR_INVALID_VAL;
458 }
459 return audioEnc_->SetCallback(cb);
460 }
461
ConfigureEnc(std::shared_ptr<FormatMock> format)462 int32_t ACodecMock::ConfigureEnc(std::shared_ptr<FormatMock> format)
463 {
464 if (audioEnc_ == nullptr) {
465 return MSERR_INVALID_VAL;
466 }
467 return audioEnc_->Configure(format);
468 }
469
PrepareEnc()470 int32_t ACodecMock::PrepareEnc()
471 {
472 if (audioEnc_ == nullptr) {
473 return MSERR_INVALID_VAL;
474 }
475 return audioEnc_->Prepare();
476 }
477
StartEnc()478 int32_t ACodecMock::StartEnc()
479 {
480 if (audioEnc_ == nullptr) {
481 return MSERR_INVALID_VAL;
482 }
483
484 isEncRunning_.store(true);
485 if (inputLoopEnc_ == nullptr) {
486 inputLoopEnc_ = make_unique<thread>(&ACodecMock::InputFuncEnc, this);
487 UNITTEST_CHECK_AND_RETURN_RET_LOG(inputLoopEnc_ != nullptr, MSERR_OK, "Fatal: No memory");
488 }
489
490 if (outputLoopEnc_ == nullptr) {
491 outputLoopEnc_ = make_unique<thread>(&ACodecMock::OutputFuncEnc, this);
492 UNITTEST_CHECK_AND_RETURN_RET_LOG(outputLoopEnc_ != nullptr, MSERR_OK, "Fatal: No memory");
493 }
494 return audioEnc_->Start();
495 }
496
StopEnc()497 int32_t ACodecMock::StopEnc()
498 {
499 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
500 return MSERR_INVALID_VAL;
501 }
502 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
503 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
504 acodecSignal_->isFlushing_.store(true);
505 lock.unlock();
506 lock2.unlock();
507 int32_t ret = audioEnc_->Stop();
508 unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
509 clearIntQueue(acodecSignal_->outQueueEnc_);
510 clearIntQueue(acodecSignal_->sizeQueueEnc_);
511 clearIntQueue(acodecSignal_->flagQueueEnc_);
512 clearBufferQueue(acodecSignal_->outBufferQueueEnc_);
513 acodecSignal_->outCondEnc_.notify_all();
514 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
515 clearIntQueue(acodecSignal_->inQueueEnc_);
516 clearBufferQueue(acodecSignal_->inBufferQueueEnc_);
517 acodecSignal_->inCondEnc_.notify_all();
518 acodecSignal_->isFlushing_.store(false);
519 lockIn.unlock();
520 lockOut.unlock();
521 return ret;
522 }
523
FlushEnc()524 int32_t ACodecMock::FlushEnc()
525 {
526 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
527 return MSERR_INVALID_VAL;
528 }
529 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
530 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
531 acodecSignal_->isFlushing_.store(true);
532 lock.unlock();
533 lock2.unlock();
534 int32_t ret = audioEnc_->Flush();
535 unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
536 clearIntQueue(acodecSignal_->outQueueEnc_);
537 clearIntQueue(acodecSignal_->sizeQueueEnc_);
538 clearIntQueue(acodecSignal_->flagQueueEnc_);
539 clearBufferQueue(acodecSignal_->outBufferQueueEnc_);
540 acodecSignal_->outCondEnc_.notify_all();
541 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
542 clearIntQueue(acodecSignal_->inQueueEnc_);
543 clearBufferQueue(acodecSignal_->inBufferQueueEnc_);
544 acodecSignal_->inCondEnc_.notify_all();
545 acodecSignal_->isFlushing_.store(false);
546 lockIn.unlock();
547 lockOut.unlock();
548 return ret;
549 }
550
ResetEnc()551 int32_t ACodecMock::ResetEnc()
552 {
553 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
554 return MSERR_INVALID_VAL;
555 }
556 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
557 unique_lock<mutex> lock2(acodecSignal_->inMutexEnc_);
558 acodecSignal_->isFlushing_.store(true);
559 lock.unlock();
560 lock2.unlock();
561 int32_t ret = audioEnc_->Reset();
562 unique_lock<mutex> lockIn(acodecSignal_->outMutexEnc_);
563 clearIntQueue(acodecSignal_->outQueueEnc_);
564 clearIntQueue(acodecSignal_->sizeQueueEnc_);
565 clearIntQueue(acodecSignal_->flagQueueEnc_);
566 clearBufferQueue(acodecSignal_->outBufferQueueEnc_);
567 acodecSignal_->outCondEnc_.notify_all();
568 unique_lock<mutex> lockOut(acodecSignal_->inMutexEnc_);
569 clearIntQueue(acodecSignal_->inQueueEnc_);
570 clearBufferQueue(acodecSignal_->inBufferQueueEnc_);
571 acodecSignal_->inCondEnc_.notify_all();
572 acodecSignal_->isFlushing_.store(false);
573 lockIn.unlock();
574 lockOut.unlock();
575 return ret;
576 }
577
ReleaseEnc()578 int32_t ACodecMock::ReleaseEnc()
579 {
580 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
581 return MSERR_INVALID_VAL;
582 }
583 isEncRunning_.store(false);
584 if (inputLoopEnc_ != nullptr && inputLoopEnc_->joinable()) {
585 unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
586 acodecSignal_->outQueueDec_.push(10000); // push 10000 to stop queue
587 acodecSignal_->inQueueEnc_.push(10000); // push 10000 to stop queue
588 acodecSignal_->inCondEnc_.notify_all();
589 lock.unlock();
590 inputLoopEnc_->join();
591 inputLoopEnc_.reset();
592 }
593 if (outputLoopEnc_ != nullptr && outputLoopEnc_->joinable()) {
594 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
595 acodecSignal_->outQueueEnc_.push(10000); // push 10000 to stop queue
596 acodecSignal_->outCondEnc_.notify_all();
597 lock.unlock();
598 outputLoopEnc_->join();
599 outputLoopEnc_.reset();
600 }
601 return audioEnc_->Release();
602 }
603
GetOutputMediaDescriptionEnc()604 std::shared_ptr<FormatMock> ACodecMock::GetOutputMediaDescriptionEnc()
605 {
606 if (audioEnc_ == nullptr) {
607 return nullptr;
608 }
609 return audioEnc_->GetOutputMediaDescription();
610 }
611
SetParameterEnc(std::shared_ptr<FormatMock> format)612 int32_t ACodecMock::SetParameterEnc(std::shared_ptr<FormatMock> format)
613 {
614 if (audioEnc_ == nullptr) {
615 return MSERR_INVALID_VAL;
616 }
617 return audioEnc_->SetParameter(format);
618 }
619
PushInputDataEnc(uint32_t index,AVCodecBufferAttrMock & attr)620 int32_t ACodecMock::PushInputDataEnc(uint32_t index, AVCodecBufferAttrMock &attr)
621 {
622 if (audioEnc_ == nullptr) {
623 return MSERR_INVALID_VAL;
624 }
625 return audioEnc_->PushInputData(index, attr);
626 }
627
FreeOutputDataEnc(uint32_t index)628 int32_t ACodecMock::FreeOutputDataEnc(uint32_t index)
629 {
630 if (audioEnc_ == nullptr) {
631 return MSERR_INVALID_VAL;
632 }
633 return audioEnc_->FreeOutputData(index);
634 }
635
PopInQueueEnc()636 void ACodecMock::PopInQueueEnc()
637 {
638 if (acodecSignal_ == nullptr) {
639 return;
640 }
641 acodecSignal_->inQueueEnc_.pop();
642 acodecSignal_->inBufferQueueEnc_.pop();
643 }
644
PushInputDataEncInner()645 int32_t ACodecMock::PushInputDataEncInner()
646 {
647 uint32_t indexEnc = acodecSignal_->inQueueEnc_.front();
648 std::shared_ptr<AVMemoryMock> bufferEnc = acodecSignal_->inBufferQueueEnc_.front();
649 UNITTEST_CHECK_AND_RETURN_RET_LOG(bufferEnc != nullptr, MSERR_INVALID_VAL, "Fatal: GetEncInputBuffer fail");
650
651 uint32_t indexDec = acodecSignal_->outQueueDec_.front();
652 std::shared_ptr<AVMemoryMock> bufferDec = acodecSignal_->outBufferQueueDec_.front();
653 uint32_t sizeDecOut = acodecSignal_->sizeQueueDec_.front();
654 uint32_t flagDecOut = acodecSignal_->flagQueueDec_.front();
655 struct AVCodecBufferAttrMock attr;
656 attr.offset = 0;
657 attr.size = sizeDecOut;
658 attr.pts = timeStampEnc_;
659 attr.flags = 0;
660 if (flagDecOut == 1) {
661 cout << "DEC output EOS " << endl;
662 isDecOutputEOS_ = true;
663 isEncInputEOS_ = true;
664 attr.flags = 1;
665 } else {
666 if (memcpy_s(bufferEnc->GetAddr(), bufferEnc->GetSize(), bufferDec->GetAddr(), sizeDecOut) != MSERR_OK) {
667 cout << "Fatal: memcpy fail" << endl;
668 acodecSignal_->errorNum_ += 1;
669 PopOutQueueDec();
670 PopInQueueEnc();
671 return MSERR_INVALID_VAL;
672 }
673 if (audioDec_->FreeOutputData(indexDec) != MSERR_OK) {
674 cout << "Fatal: FreeOutputData fail" << endl;
675 acodecSignal_->errorNum_ += 1;
676 } else {
677 decOutCnt_ += 1;
678 }
679 }
680
681 PopOutQueueDec();
682 PopInQueueEnc();
683 return audioEnc_->PushInputData(indexEnc, attr);
684 }
685
InputFuncEnc()686 void ACodecMock::InputFuncEnc()
687 {
688 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
689 return;
690 }
691 while (true) {
692 if (!isEncRunning_.load()) {
693 break;
694 }
695
696 unique_lock<mutex> lock(acodecSignal_->inMutexEnc_);
697 acodecSignal_->inCondEnc_.wait(lock, [this]() { return acodecSignal_->inQueueEnc_.size() > 0; });
698 acodecSignal_->inCondEnc_.wait(lock, [this]() { return acodecSignal_->outQueueDec_.size() > 0; });
699
700 if (!isEncRunning_.load()) {
701 break;
702 }
703 if (acodecSignal_->isFlushing_.load() || isDecOutputEOS_) {
704 PopOutQueueDec();
705 PopInQueueEnc();
706 continue;
707 }
708 if (PushInputDataEncInner() != MSERR_OK) {
709 cout << "Fatal: PushInputData fail, exit" << endl;
710 acodecSignal_->errorNum_ += 1;
711 break;
712 }
713 timeStampEnc_ += SAMPLE_DURATION_US;
714 }
715 }
716
OutputFuncEnc()717 void ACodecMock::OutputFuncEnc()
718 {
719 if (acodecSignal_ == nullptr || audioEnc_ == nullptr) {
720 return;
721 }
722 while (!isEncOutputEOS_) {
723 if (!isEncRunning_.load()) {
724 break;
725 }
726
727 unique_lock<mutex> lock(acodecSignal_->outMutexEnc_);
728 acodecSignal_->outCondEnc_.wait(lock, [this]() { return acodecSignal_->outQueueEnc_.size() > 0; });
729
730 if (!isEncRunning_.load()) {
731 break;
732 }
733 if (acodecSignal_->isFlushing_.load() || isEncOutputEOS_) {
734 acodecSignal_->outQueueEnc_.pop();
735 acodecSignal_->sizeQueueEnc_.pop();
736 acodecSignal_->flagQueueEnc_.pop();
737 acodecSignal_->outBufferQueueEnc_.pop();
738 continue;
739 }
740 uint32_t index = acodecSignal_->outQueueEnc_.front();
741 auto buffer = acodecSignal_->outBufferQueueEnc_.front();
742 uint32_t size = acodecSignal_->sizeQueueEnc_.front();
743 uint32_t encOutflag = acodecSignal_->flagQueueEnc_.front();
744 if (encOutflag == 1) {
745 cout << "ENC get output EOS" << endl;
746 isEncOutputEOS_ = true;
747 } else {
748 FILE *outFile;
749 const char *savepath = outPath_.c_str();
750 outFile = fopen(savepath, "a");
751 if (outFile == nullptr) {
752 cout << "dump data fail" << endl;
753 } else {
754 fwrite(buffer->GetAddr(), 1, size, outFile);
755 fclose(outFile);
756 }
757 if (audioEnc_->FreeOutputData(index) != MSERR_OK) {
758 cout << "Fatal: FreeOutputData fail" << endl;
759 acodecSignal_->errorNum_ += 1;
760 }
761 }
762 acodecSignal_->outQueueEnc_.pop();
763 acodecSignal_->sizeQueueEnc_.pop();
764 acodecSignal_->flagQueueEnc_.pop();
765 acodecSignal_->outBufferQueueEnc_.pop();
766 }
767 }
768 }
769 }
770
771