1/*
2 * Copyright (c) 2023 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 <js_native_api.h>
18#include <multimedia/player_framework/native_avcapability.h>
19#include <multimedia/player_framework/native_avcodec_audiodecoder.h>
20#include <multimedia/player_framework/native_avcodec_base.h>
21#include <multimedia/player_framework/native_avdemuxer.h>
22#include <multimedia/player_framework/native_avformat.h>
23#include <multimedia/player_framework/native_avsource.h>
24
25#define FAIL (-1)
26#define SUCCESS 0
27#define WIDTH 1920
28#define HEIGHT 1080
29#define PARAM_0 0
30#define PARAM_1 1
31#define PARAM_2 2
32#define PARAM_3 3
33#define PARAM_4 4
34#define PARAM_5 5
35#define PARAM_6 6
36#define PARAM_7 7
37#define PARAM_8 8
38#define PARAM_9 9
39#define PARAM_10 10
40#define PARAM_11 11
41#define PARAM_12 12
42#define PARAM_13 13
43#define PARAM_14 14
44#define PARAM_15 15
45
46static OH_AVCapability *CreateCapability(napi_env env, napi_callback_info info)
47{
48    size_t argc = PARAM_6;
49    napi_value args[PARAM_6] = {nullptr};
50    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
51    int firstParam;
52    int secondParam;
53    int thirdParam;
54    int fourthParam;
55    const char *mimeType;
56    bool coder;
57    OH_AVCodecCategory category;
58    napi_get_value_int32(env, args[PARAM_0], &firstParam);
59    napi_get_value_int32(env, args[PARAM_1], &secondParam);
60    napi_get_value_int32(env, args[PARAM_2], &thirdParam);
61    napi_get_value_int32(env, args[PARAM_3], &fourthParam);
62    OH_AVCapability *capability;
63    if (secondParam == PARAM_1) {
64        coder = true;
65    } else {
66        coder = false;
67    }
68
69    if (firstParam == PARAM_1) {
70        mimeType = OH_AVCODEC_MIMETYPE_VIDEO_AVC;
71    } else if (firstParam == PARAM_2) {
72        mimeType = OH_AVCODEC_MIMETYPE_AUDIO_AAC;
73    } else if (firstParam == PARAM_3) {
74        mimeType = OH_AVCODEC_MIMETYPE_AUDIO_FLAC;
75    } else if (firstParam == PARAM_4) {
76        mimeType = OH_AVCODEC_MIMETYPE_AUDIO_VORBIS;
77    } else if (firstParam == PARAM_5) {
78        mimeType = OH_AVCODEC_MIMETYPE_AUDIO_MPEG;
79    } else if (firstParam == PARAM_6) {
80        mimeType = OH_AVCODEC_MIMETYPE_VIDEO_HEVC;
81    } else if (firstParam == PARAM_7) {
82        mimeType = OH_AVCODEC_MIMETYPE_VIDEO_MPEG4;
83    } else if (firstParam == PARAM_8) {
84        mimeType = nullptr;
85    } else {
86        mimeType = OH_AVCODEC_MIMETYPE_VIDEO_AVC;
87    }
88
89    if (fourthParam == PARAM_1) {
90        capability = OH_AVCodec_GetCapability(mimeType, coder);
91    } else {
92        if (thirdParam == PARAM_1) {
93            category = HARDWARE;
94        } else {
95            category = SOFTWARE;
96        }
97        capability = OH_AVCodec_GetCapabilityByCategory(mimeType, coder, category);
98    }
99
100    return capability;
101}
102
103static napi_value TestInitAVErrCode(napi_env env, napi_callback_info info, OH_AVCapability *capability)
104{
105    napi_value result;
106    size_t argc = PARAM_6;
107    napi_value args[PARAM_6] = {nullptr};
108    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
109    int firstParam;
110    napi_get_value_int32(env, args[PARAM_0], &firstParam);
111    if (firstParam == PARAM_8) {
112        if (capability == nullptr) {
113            napi_create_int32(env, SUCCESS, &result);
114        } else {
115            napi_create_int32(env, FAIL, &result);
116        }
117    } else {
118        if (capability != nullptr) {
119            napi_create_int32(env, SUCCESS, &result);
120        } else {
121            napi_create_int32(env, FAIL, &result);
122        }
123    }
124
125    return result;
126}
127
128static napi_value OHAVCapabilityIsHardware(OH_AVCapability *capability, napi_env env, napi_callback_info info)
129{
130    bool checkParam = false;
131    checkParam = OH_AVCapability_IsHardware(capability);
132    napi_value result = nullptr;
133    int backParam = FAIL;
134    if (checkParam == true) {
135        backParam = SUCCESS;
136    }
137    napi_create_int32(env, backParam, &result);
138    return result;
139}
140
141static napi_value OHAVCapabilityGetName(OH_AVCapability *capability, napi_env env, napi_callback_info info)
142{
143    const char *codecName = OH_AVCapability_GetName(capability);
144    napi_value result = nullptr;
145    int backParam = FAIL;
146    if (codecName != nullptr) {
147        backParam = SUCCESS;
148    }
149    napi_create_int32(env, backParam, &result);
150    return result;
151}
152
153static napi_value OHAVCapabilityGetMaxSupportedInstances(OH_AVCapability *capability, napi_env env,
154                                                         napi_callback_info info)
155{
156    int32_t checkParam = PARAM_0;
157    checkParam = OH_AVCapability_GetMaxSupportedInstances(capability);
158    napi_value result = nullptr;
159    int backParam = FAIL;
160    if (checkParam >= PARAM_0) {
161        backParam = SUCCESS;
162    }
163    napi_create_int32(env, backParam, &result);
164    return result;
165}
166
167static napi_value OHAVCapabilityGetEncoderBitrateRange(OH_AVCapability *capability, napi_env env,
168                                                       napi_callback_info info)
169{
170    OH_AVErrCode checkParam;
171    OH_AVRange bitrateRange;
172    checkParam = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange);
173    napi_value result = nullptr;
174    int backParam = FAIL;
175    if (checkParam == AV_ERR_OK) {
176        backParam = SUCCESS;
177    }
178    napi_create_int32(env, backParam, &result);
179    return result;
180}
181
182static napi_value OHAVCapabilityGetEncoderBitrateRangeAbnormal(OH_AVCapability *capability, napi_env env,
183                                                               napi_callback_info info)
184{
185    OH_AVErrCode checkParam;
186    checkParam = OH_AVCapability_GetEncoderBitrateRange(capability, nullptr);
187    napi_value result = nullptr;
188    int backParam = FAIL;
189    if (checkParam == AV_ERR_INVALID_VAL) {
190        backParam = SUCCESS;
191    }
192    napi_create_int32(env, backParam, &result);
193    return result;
194}
195
196static napi_value OHAVCapabilityIsEncoderBitrateModeSupporteda(OH_AVCapability *capability, napi_env env,
197                                                               napi_callback_info info)
198{
199    bool checkParam = false;
200    checkParam = OH_AVCapability_IsEncoderBitrateModeSupported(capability, BITRATE_MODE_CBR);
201    napi_value result = nullptr;
202    int backParam = FAIL;
203    if (checkParam != false) {
204        backParam = SUCCESS;
205    }
206    napi_create_int32(env, backParam, &result);
207    return result;
208}
209
210static napi_value OHAVCapabilityIsEncoderBitrateModeSupportedb(OH_AVCapability *capability, napi_env env,
211                                                               napi_callback_info info)
212{
213    bool checkParam = false;
214    checkParam = OH_AVCapability_IsEncoderBitrateModeSupported(capability, BITRATE_MODE_VBR);
215    napi_value result = nullptr;
216    int backParam = FAIL;
217    if (checkParam != false) {
218        backParam = SUCCESS;
219    }
220    napi_create_int32(env, backParam, &result);
221    return result;
222}
223
224static napi_value OHAVCapabilityIsEncoderBitrateModeSupportedc(OH_AVCapability *capability, napi_env env,
225                                                               napi_callback_info info)
226{
227    bool checkParam = false;
228    checkParam = OH_AVCapability_IsEncoderBitrateModeSupported(capability, BITRATE_MODE_CQ);
229    napi_value result = nullptr;
230    int backParam = FAIL;
231    if (checkParam != false) {
232        backParam = SUCCESS;
233    }
234    napi_create_int32(env, backParam, &result);
235    return result;
236}
237
238static napi_value OHAVCapabilityGetVideoWidthRangeForHeighta(OH_AVCapability *capability, napi_env env,
239                                                             napi_callback_info info)
240{
241    int32_t height = HEIGHT;
242    OH_AVRange widthRange;
243    OH_AVErrCode checkParam;
244    checkParam = OH_AVCapability_GetVideoWidthRangeForHeight(capability, height, &widthRange);
245    napi_value result = nullptr;
246    int backParam = FAIL;
247    if (checkParam == AV_ERR_OK) {
248        backParam = SUCCESS;
249    }
250    napi_create_int32(env, backParam, &result);
251    return result;
252}
253
254static napi_value OHAVCapabilityGetVideoWidthRangeForHeightb(OH_AVCapability *capability, napi_env env,
255                                                             napi_callback_info info)
256{
257    int32_t height = HEIGHT;
258    OH_AVErrCode checkParam;
259    checkParam = OH_AVCapability_GetVideoWidthRangeForHeight(capability, height, nullptr);
260    napi_value result = nullptr;
261    int backParam = FAIL;
262    if (checkParam == AV_ERR_INVALID_VAL) {
263        backParam = SUCCESS;
264    }
265    napi_create_int32(env, backParam, &result);
266    return result;
267}
268
269static napi_value OHAVCapabilityGetVideoHeightRangeForWidtha(OH_AVCapability *capability, napi_env env,
270                                                             napi_callback_info info)
271{
272    int32_t width = WIDTH;
273    OH_AVRange heightRange;
274    OH_AVErrCode checkParam;
275    checkParam = OH_AVCapability_GetVideoHeightRangeForWidth(capability, width, &heightRange);
276    napi_value result = nullptr;
277    int backParam = FAIL;
278    if (checkParam == AV_ERR_OK) {
279        backParam = SUCCESS;
280    }
281    napi_create_int32(env, backParam, &result);
282    return result;
283}
284
285static napi_value OHAVCapabilityGetVideoHeightRangeForWidthb(OH_AVCapability *capability, napi_env env,
286                                                             napi_callback_info info)
287{
288    int32_t width = WIDTH;
289    OH_AVErrCode checkParam;
290    checkParam = OH_AVCapability_GetVideoHeightRangeForWidth(capability, width, nullptr);
291    napi_value result = nullptr;
292    int backParam = FAIL;
293    if (checkParam == AV_ERR_INVALID_VAL) {
294        backParam = SUCCESS;
295    }
296    napi_create_int32(env, backParam, &result);
297    return result;
298}
299
300static napi_value OHAVCapabilityAreProfileAndLevelSupporteda(OH_AVCapability *capability, napi_env env,
301                                                             napi_callback_info info)
302{
303
304    bool checkParam = false;
305    checkParam = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_BASELINE, PARAM_1);
306    napi_value result = nullptr;
307    int backParam = FAIL;
308    if (checkParam != false) {
309        backParam = SUCCESS;
310    }
311    napi_create_int32(env, backParam, &result);
312    return result;
313}
314
315static napi_value OHAVCapabilityAreProfileAndLevelSupportedb(OH_AVCapability *capability, napi_env env,
316                                                             napi_callback_info info)
317{
318    bool checkParam = false;
319    checkParam = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_HIGH, PARAM_1);
320    napi_value result = nullptr;
321    int backParam = FAIL;
322    if (checkParam != false) {
323        backParam = SUCCESS;
324    }
325    napi_create_int32(env, backParam, &result);
326    return result;
327}
328
329static napi_value OHAVCapabilityAreProfileAndLevelSupportedc(OH_AVCapability *capability, napi_env env,
330                                                             napi_callback_info info)
331{
332    bool checkParam = false;
333    checkParam = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_MAIN, PARAM_1);
334    napi_value result = nullptr;
335    int backParam = FAIL;
336    if (checkParam != false) {
337        backParam = SUCCESS;
338    }
339    napi_create_int32(env, backParam, &result);
340    return result;
341}
342
343
344static napi_value TestForCallTiming(OH_AVCapability *capability, napi_env env, napi_callback_info info)
345{
346    size_t argc = PARAM_6;
347    napi_value args[PARAM_6] = {nullptr};
348    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
349    int sixParam;
350    napi_get_value_int32(env, args[PARAM_5], &sixParam);
351    if (sixParam == PARAM_1) {
352        return OHAVCapabilityIsHardware(capability, env, info);
353    } else if (sixParam == PARAM_2) {
354        return OHAVCapabilityGetName(capability, env, info);
355    } else if (sixParam == PARAM_3) {
356        return OHAVCapabilityGetMaxSupportedInstances(capability, env, info);
357    } else if (sixParam == PARAM_4) {
358        return OHAVCapabilityGetEncoderBitrateRange(capability, env, info);
359    } else if (sixParam == PARAM_5) {
360        return OHAVCapabilityGetEncoderBitrateRangeAbnormal(capability, env, info);
361    } else if (sixParam == PARAM_6) {
362        return OHAVCapabilityIsEncoderBitrateModeSupporteda(capability, env, info);
363    } else if (sixParam == PARAM_7) {
364        return OHAVCapabilityIsEncoderBitrateModeSupportedb(capability, env, info);
365    } else if (sixParam == PARAM_8) {
366        return OHAVCapabilityIsEncoderBitrateModeSupportedc(capability, env, info);
367    } else if (sixParam == PARAM_9) {
368        return OHAVCapabilityGetVideoWidthRangeForHeighta(capability, env, info);
369    } else if (sixParam == PARAM_10) {
370        return OHAVCapabilityGetVideoWidthRangeForHeightb(capability, env, info);
371    } else if (sixParam == PARAM_11) {
372        return OHAVCapabilityGetVideoHeightRangeForWidtha(capability, env, info);
373    } else if (sixParam == PARAM_12) {
374        return OHAVCapabilityGetVideoHeightRangeForWidthb(capability, env, info);
375    } else if (sixParam == PARAM_13) {
376        return OHAVCapabilityAreProfileAndLevelSupporteda(capability, env, info);
377    } else if (sixParam == PARAM_14) {
378        return OHAVCapabilityAreProfileAndLevelSupportedb(capability, env, info);
379    } else if (sixParam == PARAM_15) {
380        return OHAVCapabilityAreProfileAndLevelSupportedc(capability, env, info);
381    } else {
382        napi_value result = nullptr;
383        napi_create_int32(env, FAIL, &result);
384        return result;
385    }
386}
387
388static bool isNeedCallTiming(napi_env env, napi_callback_info info)
389{
390    size_t argc = PARAM_6;
391    napi_value args[PARAM_6] = {nullptr};
392    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
393    int fiveParam;
394    napi_get_value_int32(env, args[PARAM_4], &fiveParam);
395    if (fiveParam == PARAM_1) {
396        return true;
397    } else {
398        return false;
399    }
400}
401
402static napi_value DecodeMainProcess(napi_env env, napi_callback_info info)
403{
404    OH_AVCapability *capability = CreateCapability(env, info);
405    if (isNeedCallTiming(env, info)) {
406        return TestForCallTiming(capability, env, info);
407    } else {
408        return TestInitAVErrCode(env, info, capability);
409    }
410}
411
412static napi_value AVCapabilityIsHardware(napi_env env, napi_callback_info info)
413{
414    napi_value result = nullptr;
415    int backParam = FAIL;
416    OH_AVCapability *capability = nullptr;
417    bool checkParam = false;
418    capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, false, HARDWARE);
419    checkParam = OH_AVCapability_IsHardware(capability);
420    if (checkParam != false) {
421        backParam = SUCCESS;
422    }
423    napi_create_int32(env, backParam, &result);
424    return result;
425}
426
427static napi_value AVCapabilityGetName(napi_env env, napi_callback_info info)
428{
429    napi_value result = nullptr;
430    int backParam = FAIL;
431    OH_AVCapability *capability = nullptr;
432    capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_MPEG4, false);
433    const char *codecName = OH_AVCapability_GetName(capability);
434    if (codecName != nullptr) {
435        backParam = SUCCESS;
436    }
437    napi_create_int32(env, backParam, &result);
438    return result;
439}
440
441static napi_value AVCapabilityGetMaxSupportedInstances(napi_env env, napi_callback_info info)
442{
443    napi_value result = nullptr;
444    int backParam = FAIL;
445    OH_AVCapability *capability = nullptr;
446    int32_t checkParam;
447    capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false);
448    checkParam = OH_AVCapability_GetMaxSupportedInstances(capability);
449    if (checkParam != FAIL) {
450        backParam = SUCCESS;
451    }
452    napi_create_int32(env, backParam, &result);
453    return result;
454
455}
456
457static napi_value AVCapabilityGetEncoderBitrateRange(napi_env env, napi_callback_info info)
458{
459    napi_value result = nullptr;
460    int backParam = FAIL;
461    OH_AVCapability *capability = nullptr;
462    OH_AVRange bitrateRange;
463    OH_AVErrCode checkParam;
464    capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true, HARDWARE);
465    checkParam = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange);
466    if (checkParam == AV_ERR_OK) {
467        backParam = SUCCESS;
468    }
469    napi_create_int32(env, backParam, &result);
470    return result;
471}
472
473static napi_value AVCapabilityIsEncoderBitrateModeSupported(napi_env env, napi_callback_info info)
474{
475    napi_value result = nullptr;
476    int backParam = FAIL;
477    OH_AVCapability *capability = nullptr;
478    bool checkParam = false;
479    capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
480    checkParam = OH_AVCapability_IsEncoderBitrateModeSupported(capability, BITRATE_MODE_CBR);
481    if (checkParam != false) {
482        backParam = SUCCESS;
483    }
484    napi_create_int32(env, backParam, &result);
485    return result;
486}
487
488static napi_value AVCapabilityGetVideoWidthRangeForHeight(napi_env env, napi_callback_info info)
489{
490    napi_value result = nullptr;
491    int backParam = FAIL;
492    OH_AVCapability *capability = nullptr;
493    int32_t height = HEIGHT;
494    OH_AVRange widthRange;
495    OH_AVErrCode checkParam;
496    capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE);
497    checkParam = OH_AVCapability_GetVideoWidthRangeForHeight(capability, height, &widthRange);
498    if (checkParam == AV_ERR_OK) {
499        backParam = SUCCESS;
500    }
501    napi_create_int32(env, backParam, &result);
502    return result;
503}
504
505static napi_value AVCapabilityGetVideoHeightRangeForWidth(napi_env env, napi_callback_info info)
506{
507    napi_value result = nullptr;
508    int backParam = FAIL;
509    OH_AVCapability *capability = nullptr;
510    int32_t width = WIDTH;
511    OH_AVRange heightRange;
512    OH_AVErrCode checkParam;
513    capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
514    checkParam = OH_AVCapability_GetVideoHeightRangeForWidth(capability, width, &heightRange);
515    if (checkParam == AV_ERR_OK) {
516        backParam = SUCCESS;
517    }
518    napi_create_int32(env, backParam, &result);
519    return result;
520}
521
522static napi_value AVCapabilityAreProfileAndLevelSupported(napi_env env, napi_callback_info info)
523{
524    napi_value result = nullptr;
525    int backParam = FAIL;
526    OH_AVCapability *capability = nullptr;
527    bool checkParam = false;
528    capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false);
529    checkParam = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_BASELINE, PARAM_1);
530    if (checkParam != false) {
531        backParam = SUCCESS;
532    }
533    napi_create_int32(env, backParam, &result);
534    return result;
535}
536
537EXTERN_C_START
538static napi_value Init(napi_env env, napi_value exports)
539{
540    napi_property_descriptor desc[] = {
541        {"decodeMainProcess", nullptr, DecodeMainProcess, nullptr, nullptr, nullptr, napi_default, nullptr},
542        {"OH_AVCapability_IsHardware", nullptr, AVCapabilityIsHardware, nullptr, nullptr,
543            nullptr,napi_default, nullptr},
544        {"OH_AVCapability_GetName", nullptr, AVCapabilityGetName, nullptr, nullptr, nullptr, napi_default, nullptr},
545        {"OH_AVCapability_GetMaxSupportedInstances", nullptr, AVCapabilityGetMaxSupportedInstances,
546            nullptr, nullptr, nullptr, napi_default, nullptr},
547        {"OH_AVCapability_GetEncoderBitrateRange", nullptr, AVCapabilityGetEncoderBitrateRange,
548            nullptr, nullptr, nullptr, napi_default, nullptr},
549        {"OH_AVCapability_IsEncoderBitrateModeSupported", nullptr, AVCapabilityIsEncoderBitrateModeSupported,
550            nullptr, nullptr, nullptr, napi_default, nullptr},
551        {"OH_AVCapability_GetVideoWidthRangeForHeight", nullptr, AVCapabilityGetVideoWidthRangeForHeight,
552            nullptr, nullptr, nullptr, napi_default, nullptr},
553        {"OH_AVCapability_GetVideoHeightRangeForWidth", nullptr, AVCapabilityGetVideoHeightRangeForWidth,
554            nullptr, nullptr, nullptr, napi_default, nullptr},
555        {"OH_AVCapability_AreProfileAndLevelSupported", nullptr, AVCapabilityAreProfileAndLevelSupported,
556            nullptr, nullptr, nullptr, napi_default, nullptr},
557    };
558    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
559    return exports;
560}
561
562EXTERN_C_END
563
564static napi_module demoModule = {
565    .nm_version = 1,
566    .nm_flags = 0,
567    .nm_filename = nullptr,
568    .nm_register_func = Init,
569    .nm_modname = "native",
570    .nm_priv = ((void *)0),
571    .reserved = {0},
572};
573
574extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }