• 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 "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