• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vector>
17 #include <mutex>
18 #include <gtest/gtest.h>
19 #include <iostream>
20 #include <unistd.h>
21 #include <atomic>
22 #include <fstream>
23 #include <queue>
24 #include <string>
25 #include <thread>
26 #include <multimedia/av_codec/native_avcodec_audiocodec.h>
27 #include <multimedia/media_foundation/native_audio_channel_layout.h>
28 #include <multimedia/av_codec/native_avcapability.h>
29 #include <multimedia/av_codec/native_avcodec_base.h>
30 #include <multimedia/media_foundation/native_avformat.h>
31 #include <multimedia/media_foundation/native_avbuffer.h>
32 #include "securec.h"
33 
34 using namespace std;
35 using namespace testing::ext;
36 
37 namespace {
38 constexpr uint32_t CHANNEL_COUNT = 2;
39 constexpr uint32_t SAMPLE_RATE = 44100;
40 constexpr int64_t BITS_RATE = 261000;
41 constexpr uint32_t FRAME_DURATION_US = 33000;
42 constexpr uint32_t AAC_DEFAULT_FRAME_BYTES = 2 * 1024 * 4;
43 
44 constexpr string_view AAC_INPUT_FILE_PATH = "/data/test/media/aac_2c_44100hz_199k.pcm";
45 constexpr string_view AAC_OUTPUT_FILE_PATH = "/data/test/media/aac_2c_44100hz_encode.aac";
46 } // namespace
47 
48 namespace OHOS {
49 
50 class AEncSignalAv {
51 public:
52     std::mutex inMutex_;
53     std::mutex outMutex_;
54     std::mutex startMutex_;
55     std::condition_variable inCond_;
56     std::condition_variable outCond_;
57     std::condition_variable startCond_;
58     std::queue<uint32_t> inQueue_;
59     std::queue<uint32_t> outQueue_;
60     std::queue<OH_AVBuffer*> inBufferQueue_;
61     std::queue<OH_AVBuffer*> outBufferQueue_;
62 };
63 
OnError(OH_AVCodec * codec,int32_t errorCode,void * userData)64 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
65 {
66     (void)codec;
67     (void)errorCode;
68     (void)userData;
69     cout << "Error received, errorCode:" << errorCode << endl;
70 }
71 
OnOutputFormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)72 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
73 {
74     (void)codec;
75     (void)format;
76     (void)userData;
77     cout << "OnOutputFormatChanged received" << endl;
78 }
79 
OnInputBufferAvailableAv(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)80 static void OnInputBufferAvailableAv(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
81 {
82     (void)codec;
83     AEncSignalAv *signal = static_cast<AEncSignalAv *>(userData);
84     unique_lock<mutex> lock(signal->inMutex_);
85     signal->inQueue_.push(index);
86     signal->inBufferQueue_.push(data);
87     signal->inCond_.notify_all();
88 }
89 
OnOutputBufferAvailableAv(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)90 static void OnOutputBufferAvailableAv(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
91 {
92     (void)codec;
93     AEncSignalAv *signal = static_cast<AEncSignalAv *>(userData);
94     unique_lock<mutex> lock(signal->outMutex_);
95     signal->outQueue_.push(index);
96     signal->outBufferQueue_.push(data);
97     if (data) {
98     } else {
99         cout << "OnOutputBufferAvailable error, attr is nullptr!" << endl;
100     }
101     signal->outCond_.notify_all();
102 }
103 
104 class AudioCodeCapiEncoderNdkTest : public testing::Test {
105 public:
106     static void SetUpTestCase(void);
107     static void TearDownTestCase(void);
108     void SetUp();
109     void TearDown();
110     int32_t ProceByMimeFunc(const std::string mime, bool isEncoder);
111     int32_t ProceByCapabilityFunc(const std::string mime, bool isEncoder);
112     void InputFuncAv();
113     void OutputFuncAv();
114     void HeAACSampleRateTest(int32_t profile);
115     void ChannelLayoutTest(map<OH_AudioChannelLayout, int32_t> &supportedLayoutMap, int32_t profile);
116     void ChannelCountTest(set<int32_t> &supportedChannelCntSet, int32_t profile);
117     bool IsSupportHeAac();
118 protected:
119     std::atomic<bool> isRunning_ = false;
120     std::unique_ptr<std::ifstream> inputFile_;
121     std::unique_ptr<std::thread> inputLoop_;
122     std::unique_ptr<std::thread> outputLoop_;
123     int32_t index_;
124     uint32_t frameBytes_ = AAC_DEFAULT_FRAME_BYTES;
125     std::string inputFilePath_ = AAC_INPUT_FILE_PATH.data();
126     std::string outputFilePath_ = AAC_OUTPUT_FILE_PATH.data();
127     struct OH_AVCodecCallback avcb_;
128     AEncSignalAv *signalAv_ = nullptr;
129     OH_AVCodec *audioEnc_;
130     OH_AVFormat *format;
131     bool isFirstFrame_ = true;
132     int64_t timeStamp_ = 0;
133 };
134 
SetUpTestCase(void)135 void AudioCodeCapiEncoderNdkTest::SetUpTestCase(void)
136 {
137     cout << "[SetUpTestCase]: " << endl;
138 }
139 
TearDownTestCase(void)140 void AudioCodeCapiEncoderNdkTest::TearDownTestCase(void)
141 {
142     cout << "[TearDownTestCase]: " << endl;
143 }
144 
SetUp(void)145 void AudioCodeCapiEncoderNdkTest::SetUp(void)
146 {
147     cout << "[SetUp]: SetUp!!!" << endl;
148 }
149 
TearDown(void)150 void AudioCodeCapiEncoderNdkTest::TearDown(void)
151 {
152     if (signalAv_ != nullptr) {
153         delete signalAv_;
154         signalAv_ = nullptr;
155     }
156     cout << "[TearDown]: over!!!" << endl;
157 }
158 
ProceByMimeFunc(const std::string mime,bool isEncoder)159 int32_t AudioCodeCapiEncoderNdkTest::ProceByMimeFunc(const std::string mime, bool isEncoder)
160 {
161     audioEnc_ = OH_AudioCodec_CreateByMime(mime.c_str(), isEncoder);
162     EXPECT_NE((OH_AVCodec *)nullptr, audioEnc_);
163 
164     signalAv_ = new AEncSignalAv();
165     EXPECT_NE(nullptr, signal);
166 
167     avcb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailableAv, &OnOutputBufferAvailableAv};
168     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_RegisterCallback(audioEnc_, avcb_, signalAv_));
169 
170     format = OH_AVFormat_Create();
171     return AV_ERR_OK;
172 }
173 
ProceByCapabilityFunc(const std::string mime,bool isEncoder)174 int32_t AudioCodeCapiEncoderNdkTest::ProceByCapabilityFunc(const std::string mime, bool isEncoder)
175 {
176     OH_AVCapability *cap = OH_AVCodec_GetCapability(mime.c_str(), isEncoder);
177     const char *name = OH_AVCapability_GetName(cap);
178     audioEnc_ = OH_AudioCodec_CreateByName(name);
179     EXPECT_NE((OH_AVCodec *)nullptr, audioEnc_);
180 
181     signalAv_ = new AEncSignalAv();
182     EXPECT_NE(nullptr, signal);
183 
184     avcb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailableAv, &OnOutputBufferAvailableAv};
185     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_RegisterCallback(audioEnc_, avcb_, signalAv_));
186 
187     format = OH_AVFormat_Create();
188     return AV_ERR_OK;
189 }
190 
InputFuncAv()191 void AudioCodeCapiEncoderNdkTest::InputFuncAv()
192 {
193     OH_AVCodecBufferAttr info = {};
194     bool isEos = false;
195     inputFile_ = std::make_unique<std::ifstream>(inputFilePath_, std::ios::binary);
196     if (!inputFile_->is_open()) {
197         std::cout << "open file failed, path: " << inputFilePath_ << std::endl;
198         return;
199     }
200     while (isRunning_.load()) {
201         unique_lock<mutex> lock(signalAv_->inMutex_);
202         signalAv_->inCond_.wait(lock, [this]() { return (signalAv_->inQueue_.size() > 0 || !isRunning_.load()); });
203         if (!isRunning_.load()) {
204             break;
205         }
206         uint32_t index = signalAv_->inQueue_.front();
207         auto buffer = signalAv_->inBufferQueue_.front();
208         isEos = !inputFile_->eof();
209         if (!isEos) {
210             inputFile_->read((char *)OH_AVBuffer_GetAddr(buffer), frameBytes_);
211         }
212         info.size = frameBytes_;
213         info.flags = AVCODEC_BUFFER_FLAGS_NONE;
214         if (isEos) {
215             info.size = 0;
216             info.flags = AVCODEC_BUFFER_FLAGS_EOS;
217         } else if (isFirstFrame_) {
218             info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
219             isFirstFrame_ = false;
220         }
221         info.offset = 0;
222         OH_AVBuffer_SetBufferAttr(buffer, &info);
223         int32_t ret = OH_AudioCodec_PushInputBuffer(audioEnc_, index);
224         signalAv_->inQueue_.pop();
225         signalAv_->inBufferQueue_.pop();
226         if (ret != AV_ERR_OK) {
227             isRunning_ = false;
228             break;
229         }
230         if (isEos) {
231             break;
232         }
233         timeStamp_ += FRAME_DURATION_US;
234     }
235     inputFile_->close();
236 }
237 
OutputFuncAv()238 void AudioCodeCapiEncoderNdkTest::OutputFuncAv()
239 {
240     std::ofstream outputFile;
241     outputFile.open(outputFilePath_, std::ios::out | std::ios::binary);
242     if (!outputFile.is_open()) {
243         std::cout << "open file failed, path: " << outputFilePath_ << std::endl;
244         return;
245     }
246 
247     while (isRunning_.load()) {
248         unique_lock<mutex> lock(signalAv_->outMutex_);
249         signalAv_->outCond_.wait(lock, [this]() { return (signalAv_->outQueue_.size() > 0 || !isRunning_.load()); });
250 
251         if (!isRunning_.load()) {
252             cout << "wait to stop, exit" << endl;
253             break;
254         }
255 
256         uint32_t index = signalAv_->outQueue_.front();
257         auto *data = signalAv_->outBufferQueue_.front();
258         OH_AVCodecBufferAttr attr;
259         OH_AVBuffer_GetBufferAttr(data, &attr);
260         if (data != nullptr) {
261             outputFile.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)), attr.size);
262         }
263         if (data != nullptr && (attr.flags == AVCODEC_BUFFER_FLAGS_EOS || attr.size == 0)) {
264             cout << "encode eos" << endl;
265             isRunning_.store(false);
266             signalAv_->startCond_.notify_all();
267         }
268         signalAv_->outBufferQueue_.pop();
269         signalAv_->outQueue_.pop();
270         if (OH_AudioCodec_FreeOutputBuffer(audioEnc_, index) != AV_ERR_OK) {
271             cout << "Fatal: FreeOutputData fail" << endl;
272             break;
273         }
274     }
275     outputFile.close();
276 }
277 
HeAACSampleRateTest(int32_t profile)278 void AudioCodeCapiEncoderNdkTest::HeAACSampleRateTest(int32_t profile)
279 {
280     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
281     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
282     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
283     OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile);
284     set<uint32_t> supportedSampleRateSet = {
285         16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000,
286     };
287     for (const uint32_t rate : supportedSampleRateSet) {
288         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, rate);
289         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
290         EXPECT_EQ(OH_AudioCodec_Reset(audioEnc_), AV_ERR_OK);
291     }
292 }
293 
ChannelCountTest(set<int32_t> & supportedChannelCntSet,int32_t profile)294 void AudioCodeCapiEncoderNdkTest::ChannelCountTest(set<int32_t> &supportedChannelCntSet, int32_t profile)
295 {
296     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
297     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
298     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
299     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
300     OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile);
301     for (const int32_t cnt : supportedChannelCntSet) {
302         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, cnt);
303         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
304         EXPECT_EQ(OH_AudioCodec_Reset(audioEnc_), AV_ERR_OK);
305     }
306 }
307 
ChannelLayoutTest(map<OH_AudioChannelLayout,int32_t> & supportedLayoutMap,int32_t profile)308 void AudioCodeCapiEncoderNdkTest::ChannelLayoutTest(map<OH_AudioChannelLayout, int32_t> &supportedLayoutMap,
309                                                     int32_t profile)
310 {
311     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
312     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
313     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
314     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
315     OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile);
316     map<OH_AudioChannelLayout, int32_t>::iterator iter;
317     for (iter = supportedLayoutMap.begin(); iter != supportedLayoutMap.end(); iter++) {
318         OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, iter->second);
319         OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, iter->first);
320         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
321         EXPECT_EQ(OH_AudioCodec_Reset(audioEnc_), AV_ERR_OK);
322     }
323 }
324 
IsSupportHeAac()325 bool AudioCodeCapiEncoderNdkTest::IsSupportHeAac()
326 {
327     OH_AVCapability *cap = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
328     const int32_t *profiles = nullptr;
329     uint32_t profileNum = 0;
330     OH_AVCapability_GetSupportedProfiles(cap, &profiles, &profileNum);
331     for (uint32_t i = 0; i < profileNum; i++) {
332         if (profiles[i] == AAC_PROFILE_HE) {
333             cout << "support HE-AAC" << endl;
334             return true;
335         }
336     }
337     cout << "not support HE-AAC" << endl;
338     return false;
339 }
340 
341 HWTEST_F(AudioCodeCapiEncoderNdkTest, EncoderConfigureLCAAC, TestSize.Level1)
342 {
343     inputFilePath_ = AAC_INPUT_FILE_PATH;
344     outputFilePath_ = AAC_OUTPUT_FILE_PATH;
345     frameBytes_ = AAC_DEFAULT_FRAME_BYTES;
346     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
347     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
348     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
349     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
350     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
351     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
352     isRunning_.store(true);
353 
354     inputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::InputFuncAv, this);
355     EXPECT_NE(nullptr, inputLoop_);
356     outputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::OutputFuncAv, this);
357     EXPECT_NE(nullptr, outputLoop_);
358 
359     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Start(audioEnc_));
360     while (isRunning_.load()) {
361         sleep(1); // sleep 1s
362     }
363 
364     isRunning_.store(false);
365     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
366         {
367             unique_lock<mutex> lock(signalAv_->inMutex_);
368             signalAv_->inCond_.notify_all();
369         }
370         inputLoop_->join();
371     }
372 
373     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
374         {
375             unique_lock<mutex> lock(signalAv_->outMutex_);
376             signalAv_->outCond_.notify_all();
377         }
378         outputLoop_->join();
379     }
380     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_));
381     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
382 }
383 
384 HWTEST_F(AudioCodeCapiEncoderNdkTest, EncoderConfigureHEAAC, TestSize.Level1)
385 {
386     inputFilePath_ = AAC_INPUT_FILE_PATH;
387     outputFilePath_ = AAC_OUTPUT_FILE_PATH;
388     frameBytes_ = AAC_DEFAULT_FRAME_BYTES;
389     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
390     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
391     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
392     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
393     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
394     OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE);
395     if (IsSupportHeAac()) {
396         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
397     } else {
398         EXPECT_NE(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
399         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
400         return;
401     }
402 
403     isRunning_.store(true);
404 
405     inputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::InputFuncAv, this);
406     EXPECT_NE(nullptr, inputLoop_);
407     outputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::OutputFuncAv, this);
408     EXPECT_NE(nullptr, outputLoop_);
409 
410     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Start(audioEnc_));
411     while (isRunning_.load()) {
412         sleep(1); // sleep 1s
413     }
414 
415     isRunning_.store(false);
416     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
417         {
418             unique_lock<mutex> lock(signalAv_->inMutex_);
419             signalAv_->inCond_.notify_all();
420         }
421         inputLoop_->join();
422     }
423 
424     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
425         {
426             unique_lock<mutex> lock(signalAv_->outMutex_);
427             signalAv_->outCond_.notify_all();
428         }
429         outputLoop_->join();
430     }
431     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_));
432     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
433 }
434 
435 HWTEST_F(AudioCodeCapiEncoderNdkTest, EncoderConfigureHEAACv2, TestSize.Level1)
436 {
437     inputFilePath_ = AAC_INPUT_FILE_PATH;
438     outputFilePath_ = AAC_OUTPUT_FILE_PATH;
439     frameBytes_ = AAC_DEFAULT_FRAME_BYTES;
440     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
441     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
442     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
443     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
444     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
445     OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE_V2);
446     if (IsSupportHeAac()) {
447         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
448     } else {
449         EXPECT_NE(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
450         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
451         return;
452     }
453     isRunning_.store(true);
454 
455     inputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::InputFuncAv, this);
456     EXPECT_NE(nullptr, inputLoop_);
457     outputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::OutputFuncAv, this);
458     EXPECT_NE(nullptr, outputLoop_);
459     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Start(audioEnc_));
460     while (isRunning_.load()) {
461         sleep(1); // sleep 1s
462     }
463 
464     isRunning_.store(false);
465     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
466         {
467             unique_lock<mutex> lock(signalAv_->inMutex_);
468             signalAv_->inCond_.notify_all();
469         }
470         inputLoop_->join();
471     }
472 
473     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
474         {
475             unique_lock<mutex> lock(signalAv_->outMutex_);
476             signalAv_->outCond_.notify_all();
477         }
478         outputLoop_->join();
479     }
480     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_));
481     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
482 }
483 
484 HWTEST_F(AudioCodeCapiEncoderNdkTest, EncoderConfigureByCap, TestSize.Level1)
485 {
486     inputFilePath_ = AAC_INPUT_FILE_PATH;
487     outputFilePath_ = AAC_OUTPUT_FILE_PATH;
488     frameBytes_ = AAC_DEFAULT_FRAME_BYTES;
489     ProceByCapabilityFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
490     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
491     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
492     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
493     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
494     if (IsSupportHeAac()) {
495         OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, AAC_PROFILE_HE);
496     }
497     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
498     isRunning_.store(true);
499 
500     inputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::InputFuncAv, this);
501     EXPECT_NE(nullptr, inputLoop_);
502     outputLoop_ = make_unique<thread>(&AudioCodeCapiEncoderNdkTest::OutputFuncAv, this);
503     EXPECT_NE(nullptr, outputLoop_);
504     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Start(audioEnc_));
505     while (isRunning_.load()) {
506         sleep(1); // sleep 1s
507     }
508 
509     isRunning_.store(false);
510     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
511         {
512             unique_lock<mutex> lock(signalAv_->inMutex_);
513             signalAv_->inCond_.notify_all();
514         }
515         inputLoop_->join();
516     }
517 
518     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
519         {
520             unique_lock<mutex> lock(signalAv_->outMutex_);
521             signalAv_->outCond_.notify_all();
522         }
523         outputLoop_->join();
524     }
525     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Flush(audioEnc_));
526     EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Destroy(audioEnc_));
527 }
528 
529 HWTEST_F(AudioCodeCapiEncoderNdkTest, sample_rate, TestSize.Level1)
530 {
531     if (!IsSupportHeAac()) {
532         return;
533     }
534     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
535     HeAACSampleRateTest(AAC_PROFILE_HE);
536     HeAACSampleRateTest(AAC_PROFILE_HE_V2);
537 }
538 
539 HWTEST_F(AudioCodeCapiEncoderNdkTest, channel_count_v1, TestSize.Level1)
540 {
541     if (!IsSupportHeAac()) {
542         return;
543     }
544     set<int32_t> supportedChannelCntSet = {1, 2, 3, 4, 5, 6, 8};
545     ChannelCountTest(supportedChannelCntSet, AAC_PROFILE_HE);
546 }
547 
548 HWTEST_F(AudioCodeCapiEncoderNdkTest, channel_count_v2, TestSize.Level1)
549 {
550     if (!IsSupportHeAac()) {
551         return;
552     }
553     set<int32_t> supportedChannelCntSet = {2};
554     ChannelCountTest(supportedChannelCntSet, AAC_PROFILE_HE_V2);
555 }
556 
557 HWTEST_F(AudioCodeCapiEncoderNdkTest, channel_layout_v1, TestSize.Level1)
558 {
559     if (!IsSupportHeAac()) {
560         return;
561     }
562     map<OH_AudioChannelLayout, int32_t> supportedLayoutMap = {
563         {CH_LAYOUT_MONO, 1},
564         {CH_LAYOUT_STEREO, 2},
565         {CH_LAYOUT_SURROUND, 3},
566         {CH_LAYOUT_4POINT0, 4},
567         {CH_LAYOUT_5POINT0_BACK, 5},
568         {CH_LAYOUT_5POINT1_BACK, 6},
569         {CH_LAYOUT_7POINT1_WIDE_BACK, 8},
570         {CH_LAYOUT_7POINT1, 8},
571     };
572     ChannelLayoutTest(supportedLayoutMap, AAC_PROFILE_HE);
573 }
574 
575 HWTEST_F(AudioCodeCapiEncoderNdkTest, channel_layout_v2, TestSize.Level1)
576 {
577     if (!IsSupportHeAac()) {
578         return;
579     }
580     map<OH_AudioChannelLayout, int32_t> supportedLayoutMap = {
581         {CH_LAYOUT_STEREO, 2},
582     };
583     ChannelLayoutTest(supportedLayoutMap, AAC_PROFILE_HE_V2);
584 }
585 
586 HWTEST_F(AudioCodeCapiEncoderNdkTest, aac_profile, TestSize.Level1)
587 {
588     ProceByMimeFunc(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
589     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, OH_BitsPerSample::SAMPLE_S16LE);
590     OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, BITS_RATE);
591     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, SAMPLE_RATE);
592     OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, CHANNEL_COUNT);
593     set<int32_t> supportedAacProfile = {AAC_PROFILE_LC};
594     if (IsSupportHeAac()) {
595         supportedAacProfile = {AAC_PROFILE_LC, AAC_PROFILE_HE, AAC_PROFILE_HE_V2};
596     }
597     for (const int32_t profile : supportedAacProfile) {
598         OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile);
599         EXPECT_EQ(AV_ERR_OK, OH_AudioCodec_Configure(audioEnc_, format));
600         EXPECT_EQ(OH_AudioCodec_Reset(audioEnc_), AV_ERR_OK);
601     }
602 }
603 
604 } // namespace OHOS
605