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