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 "napi/native_api.h"
17 #include <exception>
18 #include <multimedia/player_framework/native_avcapability.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <multimedia/player_framework/native_avcodec_audiocodec.h>
22 #include <multimedia/player_framework/native_avcodec_base.h>
23 #include <multimedia/player_framework/native_avformat.h>
24 #include <multimedia/player_framework/native_avcodec_base.h>
25 #include <multimedia/player_framework/native_avformat.h>
26 #include <multimedia/player_framework/native_avcodec_audiodecoder.h>
27 #include <js_native_api_types.h>
28 #include <unistd.h>
29 #include <iostream>
30 #include "hilog/log.h"
31
32 #define FAIL (-1)
33 #define SUCCESS 0
34
35 constexpr uint32_t DEFAULT_SAMPLERATE = 44100;
36 constexpr uint32_t DEFAULT_BITRATE_MIN = 8000;
37 constexpr uint32_t DEFAULT_CHANNEL_MIN = 1;
38 constexpr uint32_t DEFAULT_CHANNEL_MAX = 2;
39 constexpr uint32_t DEFAULT_SAMPLE_RATE_8 = 8000;
40 constexpr uint32_t DEFAULT_SAMPLE_RATE_16 = 16000;
41 constexpr uint32_t DEFAULT_SAMPLE_RATE_441 = 44100;
42 constexpr uint32_t DEFAULT_SAMPLE_RATE_48 = 48000;
43 constexpr uint32_t DEFAULT_BITRATE_MAX = 320000;
44 constexpr uint32_t DEFAULT_CHANNEL_COUNT_ONE = 1;
45 constexpr uint32_t DEFAULT_CHANNEL_COUNT_TWO = 1;
46 constexpr uint32_t DEFAULT_MAX_INPUT_SIZE = 1152;
47 constexpr uint32_t DEFAULT_AAC_TYPE = 1;
48 constexpr uint8_t DEFAULT_VORBIS_TYPE = 10;
49 constexpr uint8_t DEFAULT_VORBISTWO_TYPE = 20;
50 const int GLOBAL_RESMGR = 0xFF00;
51 const int SD_HEIGHT = 480;
52 const int HD_WIDTH = 1280;
53 const int HD_HEIGHT = 720;
54 const char *TAG = "[pcsAudioTest]";
55
56
isSupportRate(OH_AVCapability * capability)57 bool isSupportRate(OH_AVCapability *capability)
58 {
59 // 1. 确认待配置采样率是否支持
60 const int32_t *sampleRates = nullptr;
61 bool isSupper16K = false;
62 bool isSupper441K = false;
63 bool isSupper48k = false;
64 uint32_t sampleRateNum = 0;
65 int32_t ret = OH_AVCapability_GetAudioSupportedSampleRates(capability, &sampleRates, &sampleRateNum);
66 if (ret != AV_ERR_OK || sampleRates == nullptr || sampleRateNum == 0) {
67 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " ret is : %{public}d ", ret);
68 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCapability_GetAudioSupportedSampleRates fail");
69 return true;
70 }
71 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRateNum end: %{public}d ", sampleRateNum);
72 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRates is: %{public}d", sampleRates);
73 for (int i = 0; i < sampleRateNum; i++) {
74 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRate is: %{public}d ", sampleRates[i]);
75 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_16) {
76 isSupper16K = true;
77 continue;
78 }
79 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_441) {
80 isSupper441K = true;
81 continue;
82 }
83 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_48) {
84 isSupper48k = true;
85 continue;
86 }
87 }
88 return isSupper16K && isSupper48k && isSupper441K;
89 }
isSupportRateAll(OH_AVCapability * capability)90 bool isSupportRateAll(OH_AVCapability *capability)
91 {
92 // 1. 确认待配置采样率是否支持
93 const int32_t *sampleRates = nullptr;
94 bool isSupper8K = false;
95 bool isSupper16K = false;
96 bool isSupper441K = false;
97 bool isSupper48k = false;
98 uint32_t sampleRateNum = 0;
99 int32_t ret = OH_AVCapability_GetAudioSupportedSampleRates(capability, &sampleRates, &sampleRateNum);
100 if (ret != AV_ERR_OK || sampleRates == nullptr || sampleRateNum == 0) {
101 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " ret is : %{public}d ", ret);
102 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCapability_GetAudioSupportedSampleRates fail");
103 return true;
104 }
105 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRateNum end: %{public}d ", sampleRateNum);
106 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRates is: %{public}d", sampleRates);
107 for (int i = 0; i < sampleRateNum; i++) {
108 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, " sampleRate is: %{public}d ", sampleRates[i]);
109 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_8) {
110 isSupper8K = true;
111 continue;
112 }
113 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_16) {
114 isSupper16K = true;
115 continue;
116 }
117 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_441) {
118 isSupper441K = true;
119 continue;
120 }
121 if (sampleRates[i] == DEFAULT_SAMPLE_RATE_48) {
122 isSupper48k = true;
123 continue;
124 }
125 }
126 return isSupper16K && isSupper48k && isSupper441K;
127 }
AudioDecoderFlushFirst(napi_env env,napi_callback_info info)128 static napi_value AudioDecoderFlushFirst(napi_env env, napi_callback_info info)
129 {
130 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderFlushFirst called");
131
132 int backParam = FAIL;
133 napi_value result = nullptr;
134 OH_AVErrCode checkParam;
135 OH_AVFormat *format = nullptr;
136 format = OH_AVFormat_Create();
137 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE);
138 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE_MIN);
139 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT_ONE);
140 OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE, DEFAULT_MAX_INPUT_SIZE);
141 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE);
142 OH_AVCodec *audioDec = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_MPEG, false);
143 OH_AudioCodec_Configure(audioDec, format);
144 OH_AudioCodec_Prepare(audioDec);
145 if (OH_AudioCodec_Start(audioDec) == AV_ERR_OK) {
146 checkParam = OH_AudioCodec_Flush(audioDec);
147 if (checkParam == AV_ERR_OK) {
148 backParam = SUCCESS;
149 OH_AudioCodec_Stop(audioDec);
150 }
151 }
152
153 napi_create_int32(env, backParam, &result);
154 return result;
155 }
156
AudioDecoderFlushSecond(napi_env env,napi_callback_info info)157 static napi_value AudioDecoderFlushSecond(napi_env env, napi_callback_info info)
158 {
159 int backParam = FAIL;
160 napi_value result = nullptr;
161 OH_AVErrCode checkParam;
162 OH_AVFormat *format = nullptr;
163 format = OH_AVFormat_Create();
164 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE);
165 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE_MAX);
166 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT_TWO);
167 OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE, DEFAULT_MAX_INPUT_SIZE);
168 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE);
169 OH_AVCodec *audioDec = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_MPEG, false);
170 OH_AudioCodec_Configure(audioDec, format);
171 OH_AudioCodec_Prepare(audioDec);
172 if (OH_AudioCodec_Start(audioDec) == AV_ERR_OK) {
173 checkParam = OH_AudioCodec_Flush(audioDec);
174 if (checkParam == AV_ERR_OK) {
175 backParam = SUCCESS;
176 OH_AudioCodec_Stop(audioDec);
177 }
178 }
179 napi_create_int32(env, backParam, &result);
180 return result;
181 }
182
183 // FLAC编码验证
AudioEncoderFlac(napi_env env,napi_callback_info info)184 static napi_value AudioEncoderFlac(napi_env env, napi_callback_info info)
185 {
186 using namespace std;
187 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderFlac call start");
188 int backParam = FAIL;
189 napi_value result = nullptr;
190 // 获取AAC的编码器对象。
191 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_FLAC, true);
192 if (capability == nullptr) {
193 backParam = SUCCESS;
194 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCodec_GetCapability failed");
195 napi_create_int32(env, backParam, &result);
196 return result;
197 }
198 bool isSupport = isSupportRateAll(capability);
199 if (isSupport) {
200 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderFlac SUCCESS end");
201 backParam = SUCCESS;
202 napi_create_int32(env, backParam, &result);
203 return result;
204 }
205
206 backParam = FAIL;
207 napi_create_int32(env, backParam, &result);
208 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderFlac failed end");
209 return result;
210 }
211
212 // AAC编码验证
AudioEncoderAAc(napi_env env,napi_callback_info info)213 static napi_value AudioEncoderAAc(napi_env env, napi_callback_info info)
214 {
215 using namespace std;
216 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderAAc call start");
217 int backParam = FAIL;
218 napi_value result = nullptr;
219 // 获取AAC的编码器对象。
220 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true);
221 if (capability == nullptr) {
222 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCodec_GetCapability failed");
223 backParam = SUCCESS;
224 napi_create_int32(env, backParam, &result);
225 return result;
226 }
227 bool isSupper16LC = false;
228 bool isSupported = isSupportRate(capability);
229 const int32_t *profiles = nullptr;
230 uint32_t profileNum = 0;
231 int32_t ret = OH_AVCapability_GetSupportedProfiles(capability, &profiles, &profileNum);
232 if (ret != AV_ERR_OK || profiles == nullptr || profileNum == 0) {
233 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCapability_GetSupportedProfiles failed");
234 backParam = SUCCESS;
235 napi_create_int32(env, backParam, &result);
236 return result;
237 }
238 for (int i = 0; i < profileNum; i++) {
239 if (profiles[i] == AAC_PROFILE_LC) {
240 isSupper16LC = true;
241 break;
242 }
243 }
244 if (isSupper16LC && isSupported) {
245 backParam = SUCCESS;
246 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderAAc SUCCESS end");
247 napi_create_int32(env, backParam, &result);
248 return result;
249 }
250
251 backParam = FAIL;
252 napi_create_int32(env, backParam, &result);
253 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderAAc failed end");
254 return result;
255 }
256
257 // aac解码验证
AudioDecoderAAc(napi_env env,napi_callback_info info)258 static napi_value AudioDecoderAAc(napi_env env, napi_callback_info info)
259 {
260 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderAAc call start");
261 int backParam = FAIL;
262 napi_value result = nullptr;
263 // 获取AAC的解码器对象。
264 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, false);
265 if (capability == nullptr) {
266 backParam = SUCCESS;
267 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCodec_GetCapability failed");
268 napi_create_int32(env, backParam, &result);
269 return result;
270 }
271 // 1. 确认待配置采样率是否支持
272 const int32_t *sampleRates = nullptr;
273 bool isSupportChannelRange = false;
274 bool isSupportBitrateRange = false;
275 uint32_t sampleRateNum = 0;
276 int32_t ret = OH_AVCapability_GetAudioSupportedSampleRates(capability, &sampleRates, &sampleRateNum);
277 if (ret != AV_ERR_OK || sampleRates == nullptr || sampleRateNum == 0) {
278 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCapability_GetAudioSupportedSampleRates failed");
279 backParam = SUCCESS;
280 napi_create_int32(env, backParam, &result);
281 return result;
282 }
283 OH_AVRange bitR;
284 int32_t ret1 = OH_AVCapability_GetEncoderBitrateRange(capability, &bitR);
285 if (ret1 != AV_ERR_OK || bitR.maxVal <= 0) {
286 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCapability_GetEncoderBitrateRange failed");
287 backParam = SUCCESS;
288 napi_create_int32(env, backParam, &result);
289 return result;
290 }
291 if (bitR.minVal <= DEFAULT_BITRATE_MIN && bitR.maxVal>= DEFAULT_BITRATE_MAX) {
292 isSupportBitrateRange = true;
293 }
294 // 3. 获取通道数范围,判断待配置通道数参数是否在范围内
295 OH_AVRange channelRange = {-1, -1};
296 ret = OH_AVCapability_GetAudioChannelCountRange(capability, &channelRange);
297 if (channelRange.minVal <= DEFAULT_CHANNEL_MIN && channelRange.maxVal>= DEFAULT_CHANNEL_MAX) {
298 isSupportChannelRange = true;
299 }
300 backParam = FAIL;
301 bool isSupported = isSupportRateAll(capability);
302 if (isSupportChannelRange && isSupportBitrateRange && isSupported) {
303 backParam = SUCCESS;
304 }
305 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderAAc end");
306 napi_create_int32(env, backParam, &result);
307 return result;
308 }
309
310 // H264编码
AudioEncoderH264(napi_env env,napi_callback_info info)311 static napi_value AudioEncoderH264(napi_env env, napi_callback_info info)
312 {
313 using namespace std;
314 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderH264 call start");
315 int backParam = FAIL;
316 napi_value result = nullptr;
317 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
318 if (capability == nullptr) {
319 // 异常处理
320 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCodec_GetCapability failed");
321 backParam = SUCCESS;
322 napi_create_int32(env, backParam, &result);
323 return result;
324 }
325 // 2. 查询编码档次和级别是否支持
326 bool isSupportedLevel3 = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_MAIN, AVC_LEVEL_12);
327 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "isSupportedLevel3 end----------%{public}d", isSupportedLevel3);
328 int32_t videoWidth = HD_HEIGHT;
329 int32_t videoHeight = SD_HEIGHT;
330 // 1. 确认视频宽高是否支持
331 bool isSupportedSD = OH_AVCapability_IsVideoSizeSupported(capability, videoWidth, videoHeight);
332 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "isSupportedSD end----------%{public}d", isSupportedSD);
333 videoWidth = HD_WIDTH;
334 videoHeight = HD_HEIGHT;
335 // 1. 确认视频宽高是否支持
336 bool isSupportedSHD = OH_AVCapability_IsVideoSizeSupported(capability, videoWidth, videoHeight);
337 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "isSupportedSHD end----------%{public}d", isSupportedSHD);
338 if (isSupportedLevel3 && isSupportedSD && isSupportedSHD) {
339 backParam = SUCCESS;
340 }
341 napi_create_int32(env, backParam, &result);
342 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioEncoderH264 call end");
343 return result;
344 }
345
346 // H264解码
AudioDecoderH264(napi_env env,napi_callback_info info)347 static napi_value AudioDecoderH264(napi_env env, napi_callback_info info)
348 {
349 using namespace std;
350 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderH264 call start");
351 int backParam = FAIL;
352 napi_value result = nullptr;
353 // 1. 获取H.264软件解码器能力实例
354 OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE);
355 if (capability == nullptr) {
356 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_AVCodec_GetCapabilityByCategory failed");
357 backParam = SUCCESS;
358 napi_create_int32(env, backParam, &result);
359 return result;
360 }
361 // 2. 查询编码档次和级别是否支持
362 bool isSupportedBase = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_BASELINE, AVC_LEVEL_51);
363 bool isSupportedMain = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_MAIN, AVC_LEVEL_51);
364 bool isSupportedHigh = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_HIGH, AVC_LEVEL_51);
365 if (isSupportedBase && isSupportedMain && isSupportedHigh) {
366 backParam = SUCCESS;
367 napi_create_int32(env, backParam, &result);
368 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderH264 success end");
369 return result;
370 }
371
372 backParam = FAIL;
373 napi_create_int32(env, backParam, &result);
374 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "AudioDecoderH264 fail end");
375 return result;
376 }
377
378 EXTERN_C_START
Init(napi_env env,napi_value exports)379 static napi_value Init(napi_env env, napi_value exports)
380 {
381 napi_property_descriptor desc[] = {
382 {"OH_AudioCodec_Flush_First", nullptr, AudioDecoderFlushFirst, nullptr, nullptr, nullptr, napi_default,
383 nullptr},
384 {"OH_AudioCodec_Flush_Second", nullptr, AudioDecoderFlushSecond, nullptr, nullptr, nullptr, napi_default,
385 nullptr},
386 {"OH_AudioEncoderAAc", nullptr, AudioEncoderAAc, nullptr, nullptr, nullptr, napi_default,
387 nullptr},
388 {"OH_AudioEncoderFlac", nullptr, AudioEncoderFlac, nullptr, nullptr, nullptr, napi_default,
389 nullptr},
390 {"OH_AudioEncoderH264", nullptr, AudioEncoderH264, nullptr, nullptr, nullptr, napi_default,
391 nullptr},
392 {"OH_AudioDecoderH264", nullptr, AudioDecoderH264, nullptr, nullptr, nullptr, napi_default,
393 nullptr},
394 {"OH_AudioDecoderAAc", nullptr, AudioDecoderAAc, nullptr, nullptr, nullptr, napi_default,
395 nullptr},
396
397 };
398 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
399 return exports;
400 }
401 EXTERN_C_END
402
403 static napi_module demoModule = {
404 .nm_version = 1,
405 .nm_flags = 0,
406 .nm_filename = nullptr,
407 .nm_register_func = Init,
408 .nm_modname = "pcsAudioTest",
409 .nm_priv = ((void *)0),
410 .reserved = {0},
411 };
412
RegisterEntryModule(void)413 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
414