1f6603c60Sopenharmony_ci/*
2f6603c60Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3f6603c60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f6603c60Sopenharmony_ci * you may not use this file except in compliance with the License.
5f6603c60Sopenharmony_ci * You may obtain a copy of the License at
6f6603c60Sopenharmony_ci *
7f6603c60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8f6603c60Sopenharmony_ci *
9f6603c60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f6603c60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f6603c60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f6603c60Sopenharmony_ci * See the License for the specific language governing permissions and
13f6603c60Sopenharmony_ci * limitations under the License.
14f6603c60Sopenharmony_ci */
15f6603c60Sopenharmony_ci
16f6603c60Sopenharmony_ci#include "napi/native_api.h"
17f6603c60Sopenharmony_ci#include "node_api.h"
18f6603c60Sopenharmony_ci#include <fcntl.h>
19f6603c60Sopenharmony_ci#include <linux/usb/charger.h>
20f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avcodec_audiodecoder.h>
21f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avcodec_base.h>
22f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avdemuxer.h>
23f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_averrors.h>
24f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avmuxer.h>
25f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avsource.h>
26f6603c60Sopenharmony_ci#include <multimedia/player_framework/native_avformat.h>
27f6603c60Sopenharmony_ci#include <sys/stat.h>
28f6603c60Sopenharmony_ci#include <unistd.h>
29f6603c60Sopenharmony_ci
30f6603c60Sopenharmony_ci#define MUNUSONE (-1)
31f6603c60Sopenharmony_ci#define ZEROVAL 0
32f6603c60Sopenharmony_ci#define BIGVAL (2160*3840)
33f6603c60Sopenharmony_ci#define TWOVAL 2
34f6603c60Sopenharmony_ci#define ONEONEVAL 11
35f6603c60Sopenharmony_ci#define PARAM_1 1
36f6603c60Sopenharmony_ci#define TWOTWOVAL 23
37f6603c60Sopenharmony_ci#define SUCCESS 0
38f6603c60Sopenharmony_ci#define FAIL (-1)
39f6603c60Sopenharmony_ci#define DENSITY 240
40f6603c60Sopenharmony_ci#define ONEHUNVAL 100
41f6603c60Sopenharmony_ci#define PARAM_0666 0666
42f6603c60Sopenharmony_ci#define PARAM_0 0
43f6603c60Sopenharmony_ci#define PATH "/data/storage/el2/base/files/demo.mp4"
44f6603c60Sopenharmony_ci#define FILESIZE 1046987
45f6603c60Sopenharmony_ci
46f6603c60Sopenharmony_cistatic int64_t GetFileSize(const char *fileName)
47f6603c60Sopenharmony_ci{
48f6603c60Sopenharmony_ci    int64_t fileSize = ZEROVAL;
49f6603c60Sopenharmony_ci    if (fileName != nullptr) {
50f6603c60Sopenharmony_ci        struct stat fileStatus;
51f6603c60Sopenharmony_ci        fileSize = static_cast<size_t>(fileStatus.st_size);
52f6603c60Sopenharmony_ci    }
53f6603c60Sopenharmony_ci    return fileSize;
54f6603c60Sopenharmony_ci}
55f6603c60Sopenharmony_ci
56f6603c60Sopenharmony_cistatic OH_AVSource *GetSource()
57f6603c60Sopenharmony_ci{
58f6603c60Sopenharmony_ci    char fileName[] = {"/data/storage/el2/base/files/demo.mp4"};
59f6603c60Sopenharmony_ci    int fd = open(fileName, O_RDWR, PARAM_0666);
60f6603c60Sopenharmony_ci    OH_AVSource *source;
61f6603c60Sopenharmony_ci    int64_t offset = ZEROVAL;
62f6603c60Sopenharmony_ci    source = OH_AVSource_CreateWithFD(fd, offset, FILESIZE);
63f6603c60Sopenharmony_ci    close(fd);
64f6603c60Sopenharmony_ci    return source;
65f6603c60Sopenharmony_ci}
66f6603c60Sopenharmony_ci
67f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerCreateWithSource(napi_env env, napi_callback_info info)
68f6603c60Sopenharmony_ci{
69f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer = nullptr;
70f6603c60Sopenharmony_ci    OH_AVSource *source = GetSource();
71f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(source);
72f6603c60Sopenharmony_ci    int returnValue = FAIL;
73f6603c60Sopenharmony_ci    if (demuxer != nullptr) {
74f6603c60Sopenharmony_ci        returnValue = SUCCESS;
75f6603c60Sopenharmony_ci    } else if (demuxer == nullptr) {
76f6603c60Sopenharmony_ci        returnValue = ONEHUNVAL;
77f6603c60Sopenharmony_ci    }
78f6603c60Sopenharmony_ci    napi_value result = nullptr;
79f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
80f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
81f6603c60Sopenharmony_ci    return result;
82f6603c60Sopenharmony_ci}
83f6603c60Sopenharmony_ci
84f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerDestroy(napi_env env, napi_callback_info info)
85f6603c60Sopenharmony_ci{
86f6603c60Sopenharmony_ci    OH_AVErrCode backInfo;
87f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer = nullptr;
88f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(GetSource());
89f6603c60Sopenharmony_ci    int returnValue = FAIL;
90f6603c60Sopenharmony_ci    backInfo = OH_AVDemuxer_Destroy(demuxer);
91f6603c60Sopenharmony_ci    if (backInfo == AV_ERR_OK) {
92f6603c60Sopenharmony_ci        returnValue = SUCCESS;
93f6603c60Sopenharmony_ci    }
94f6603c60Sopenharmony_ci    demuxer = nullptr;
95f6603c60Sopenharmony_ci    napi_value result = nullptr;
96f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
97f6603c60Sopenharmony_ci    return result;
98f6603c60Sopenharmony_ci}
99f6603c60Sopenharmony_ci
100f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerUnselectTrackByID(napi_env env, napi_callback_info info)
101f6603c60Sopenharmony_ci{
102f6603c60Sopenharmony_ci    OH_AVErrCode backInfo = AV_ERR_OK;
103f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer = nullptr;
104f6603c60Sopenharmony_ci    uint32_t audioTrackIndex = ZEROVAL;
105f6603c60Sopenharmony_ci    uint32_t videoTrackIndex = ZEROVAL;
106f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(GetSource());
107f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex);
108f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, videoTrackIndex);
109f6603c60Sopenharmony_ci    backInfo = OH_AVDemuxer_UnselectTrackByID(demuxer, audioTrackIndex);
110f6603c60Sopenharmony_ci    int returnValue = FAIL;
111f6603c60Sopenharmony_ci    if (backInfo == AV_ERR_OK) {
112f6603c60Sopenharmony_ci        returnValue = SUCCESS;
113f6603c60Sopenharmony_ci    } else if (demuxer == nullptr) {
114f6603c60Sopenharmony_ci        returnValue = ONEHUNVAL;
115f6603c60Sopenharmony_ci    }
116f6603c60Sopenharmony_ci    napi_value result = nullptr;
117f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
118f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
119f6603c60Sopenharmony_ci    return result;
120f6603c60Sopenharmony_ci}
121f6603c60Sopenharmony_ci
122f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerSeekToTime(napi_env env, napi_callback_info info)
123f6603c60Sopenharmony_ci{
124f6603c60Sopenharmony_ci    OH_AVErrCode backInfo = AV_ERR_OK;
125f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer = nullptr;
126f6603c60Sopenharmony_ci    uint32_t audioTrackIndex = ZEROVAL;
127f6603c60Sopenharmony_ci    uint32_t videoTrackIndex = ZEROVAL;
128f6603c60Sopenharmony_ci    char fileName[] = {"/data/storage/el2/base/files/demo.mp4"};
129f6603c60Sopenharmony_ci    int fd = open(fileName, O_RDWR, PARAM_0666);
130f6603c60Sopenharmony_ci    OH_AVSource *source;
131f6603c60Sopenharmony_ci    int64_t offset = ZEROVAL;
132f6603c60Sopenharmony_ci    source = OH_AVSource_CreateWithFD(fd, offset, FILESIZE);
133f6603c60Sopenharmony_ci    close(fd);
134f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(source);
135f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex);
136f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, videoTrackIndex);
137f6603c60Sopenharmony_ci    int returnValue = FAIL;
138f6603c60Sopenharmony_ci    backInfo = OH_AVDemuxer_SeekToTime(demuxer, ZEROVAL, OH_AVSeekMode::SEEK_MODE_NEXT_SYNC);
139f6603c60Sopenharmony_ci    if (backInfo == AV_ERR_OK) {
140f6603c60Sopenharmony_ci        returnValue = SUCCESS;
141f6603c60Sopenharmony_ci    }
142f6603c60Sopenharmony_ci    if (demuxer == nullptr) {
143f6603c60Sopenharmony_ci        returnValue = ONEHUNVAL;
144f6603c60Sopenharmony_ci    }
145f6603c60Sopenharmony_ci    napi_value result = nullptr;
146f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
147f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
148f6603c60Sopenharmony_ci    return result;
149f6603c60Sopenharmony_ci}
150f6603c60Sopenharmony_ci
151f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerSelectTrackByID(napi_env env, napi_callback_info info)
152f6603c60Sopenharmony_ci{
153f6603c60Sopenharmony_ci    OH_AVErrCode backInfo = AV_ERR_OK;
154f6603c60Sopenharmony_ci    OH_AVErrCode backInfoo = AV_ERR_OK;
155f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer = nullptr;
156f6603c60Sopenharmony_ci    uint32_t audioTrackIndex = ZEROVAL;
157f6603c60Sopenharmony_ci    uint32_t videoTrackIndex = ZEROVAL;
158f6603c60Sopenharmony_ci    char fileName[] = {"/data/storage/el2/base/files/demo.mp4"};
159f6603c60Sopenharmony_ci    int fd = open(fileName, O_RDWR, PARAM_0666);
160f6603c60Sopenharmony_ci    OH_AVSource *source;
161f6603c60Sopenharmony_ci    int64_t offset = ZEROVAL;
162f6603c60Sopenharmony_ci    source = OH_AVSource_CreateWithFD(fd, offset, FILESIZE);
163f6603c60Sopenharmony_ci    close(fd);
164f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(source);
165f6603c60Sopenharmony_ci    int returnValue = FAIL;
166f6603c60Sopenharmony_ci    backInfo = OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex);
167f6603c60Sopenharmony_ci    backInfoo = OH_AVDemuxer_SelectTrackByID(demuxer, videoTrackIndex);
168f6603c60Sopenharmony_ci
169f6603c60Sopenharmony_ci    int32_t isHDRVivid = 0;
170f6603c60Sopenharmony_ci    OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(GetSource(), videoTrackIndex);
171f6603c60Sopenharmony_ci    OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_VIDEO_IS_HDR_VIVID, &isHDRVivid);
172f6603c60Sopenharmony_ci
173f6603c60Sopenharmony_ci    if (backInfo == AV_ERR_OK) {
174f6603c60Sopenharmony_ci        returnValue = SUCCESS;
175f6603c60Sopenharmony_ci    }
176f6603c60Sopenharmony_ci    if (backInfoo == AV_ERR_OK) {
177f6603c60Sopenharmony_ci        returnValue = SUCCESS;
178f6603c60Sopenharmony_ci    }
179f6603c60Sopenharmony_ci    if (demuxer == nullptr) {
180f6603c60Sopenharmony_ci        returnValue = ONEHUNVAL;
181f6603c60Sopenharmony_ci    }
182f6603c60Sopenharmony_ci    napi_value result = nullptr;
183f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
184f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
185f6603c60Sopenharmony_ci    return result;
186f6603c60Sopenharmony_ci}
187f6603c60Sopenharmony_ci
188f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerReadSample(napi_env env, napi_callback_info info)
189f6603c60Sopenharmony_ci{
190f6603c60Sopenharmony_ci    OH_AVSource *oH_AVSource = GetSource();
191f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer;
192f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(oH_AVSource);
193f6603c60Sopenharmony_ci    int returnValue = FAIL;
194f6603c60Sopenharmony_ci    OH_AVMemory *buffer = OH_AVMemory_Create(TWOTWOVAL);
195f6603c60Sopenharmony_ci    uint32_t audioTrackIndex = ZEROVAL;
196f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex);
197f6603c60Sopenharmony_ci    OH_AVCodecBufferAttr attrInfo;
198f6603c60Sopenharmony_ci    attrInfo.pts = ZEROVAL;
199f6603c60Sopenharmony_ci    attrInfo.size = ZEROVAL;
200f6603c60Sopenharmony_ci    attrInfo.offset = ZEROVAL;
201f6603c60Sopenharmony_ci    attrInfo.flags |= AVCODEC_BUFFER_FLAGS_SYNC_FRAME;
202f6603c60Sopenharmony_ci    OH_AVDemuxer_SeekToTime(demuxer, ZEROVAL, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
203f6603c60Sopenharmony_ci    if (OH_AVDemuxer_ReadSample(demuxer, audioTrackIndex, buffer, &attrInfo) == AV_ERR_OK) {
204f6603c60Sopenharmony_ci        returnValue = SUCCESS;
205f6603c60Sopenharmony_ci    }
206f6603c60Sopenharmony_ci    napi_value result = nullptr;
207f6603c60Sopenharmony_ci    OH_AVMemory_Destroy(buffer);
208f6603c60Sopenharmony_ci    if (oH_AVSource == nullptr) {
209f6603c60Sopenharmony_ci        returnValue = PARAM_1;
210f6603c60Sopenharmony_ci    }
211f6603c60Sopenharmony_ci    if (demuxer == nullptr) {
212f6603c60Sopenharmony_ci        returnValue = TWOTWOVAL;
213f6603c60Sopenharmony_ci    }
214f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
215f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
216f6603c60Sopenharmony_ci    return result;
217f6603c60Sopenharmony_ci}
218f6603c60Sopenharmony_ci
219f6603c60Sopenharmony_cistatic napi_value OHAVDemuxerReadSampleBuffer(napi_env env, napi_callback_info info)
220f6603c60Sopenharmony_ci{
221f6603c60Sopenharmony_ci    OH_AVSource *oH_AVSource = GetSource();
222f6603c60Sopenharmony_ci    OH_AVDemuxer *demuxer;
223f6603c60Sopenharmony_ci    demuxer = OH_AVDemuxer_CreateWithSource(oH_AVSource);
224f6603c60Sopenharmony_ci    int returnValue = FAIL;
225f6603c60Sopenharmony_ci    OH_AVBuffer *buffer = OH_AVBuffer_Create(TWOTWOVAL);
226f6603c60Sopenharmony_ci    uint32_t audioTrackIndex = ZEROVAL;
227f6603c60Sopenharmony_ci    OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex);
228f6603c60Sopenharmony_ci    OH_AVDemuxer_SeekToTime(demuxer, ZEROVAL, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
229f6603c60Sopenharmony_ci    if (OH_AVDemuxer_ReadSampleBuffer(demuxer, audioTrackIndex, buffer) == AV_ERR_OK) {
230f6603c60Sopenharmony_ci        returnValue = SUCCESS;
231f6603c60Sopenharmony_ci    }
232f6603c60Sopenharmony_ci    napi_value result = nullptr;
233f6603c60Sopenharmony_ci    OH_AVBuffer_Destroy(buffer);
234f6603c60Sopenharmony_ci    if (oH_AVSource == nullptr) {
235f6603c60Sopenharmony_ci        returnValue = PARAM_1;
236f6603c60Sopenharmony_ci    }
237f6603c60Sopenharmony_ci    if (demuxer == nullptr) {
238f6603c60Sopenharmony_ci        returnValue = TWOTWOVAL;
239f6603c60Sopenharmony_ci    }
240f6603c60Sopenharmony_ci    napi_create_int32(env, returnValue, &result);
241f6603c60Sopenharmony_ci    OH_AVDemuxer_Destroy(demuxer);
242f6603c60Sopenharmony_ci    return result;
243f6603c60Sopenharmony_ci}
244f6603c60Sopenharmony_ci
245f6603c60Sopenharmony_ciEXTERN_C_START
246f6603c60Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports)
247f6603c60Sopenharmony_ci{
248f6603c60Sopenharmony_ci    napi_property_descriptor desc[] = {
249f6603c60Sopenharmony_ci        {"oHAVDemuxerCreateWithSource", nullptr, OHAVDemuxerCreateWithSource, nullptr, nullptr, nullptr, napi_default,
250f6603c60Sopenharmony_ci         nullptr},
251f6603c60Sopenharmony_ci        {"oHAVDemuxerDestroy", nullptr, OHAVDemuxerDestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
252f6603c60Sopenharmony_ci        {"oHAVDemuxerUnselectTrackByID", nullptr, OHAVDemuxerUnselectTrackByID, nullptr, nullptr, nullptr, napi_default,
253f6603c60Sopenharmony_ci         nullptr},
254f6603c60Sopenharmony_ci        {"oHAVDemuxerReadSample", nullptr, OHAVDemuxerReadSample, nullptr, nullptr, nullptr, napi_default, nullptr},
255f6603c60Sopenharmony_ci        {"oHAVDemuxerSeekToTime", nullptr, OHAVDemuxerSeekToTime, nullptr, nullptr, nullptr, napi_default, nullptr},
256f6603c60Sopenharmony_ci        {"oHAVDemuxerSelectTrackByID", nullptr, OHAVDemuxerSelectTrackByID, nullptr, nullptr, nullptr, napi_default,
257f6603c60Sopenharmony_ci         nullptr},
258f6603c60Sopenharmony_ci        {"oHAVDemuxerReadSampleBuffer", nullptr, OHAVDemuxerReadSampleBuffer, nullptr, nullptr, nullptr, napi_default,
259f6603c60Sopenharmony_ci         nullptr},
260f6603c60Sopenharmony_ci
261f6603c60Sopenharmony_ci    };
262f6603c60Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
263f6603c60Sopenharmony_ci    return exports;
264f6603c60Sopenharmony_ci}
265f6603c60Sopenharmony_ci
266f6603c60Sopenharmony_ciEXTERN_C_END
267f6603c60Sopenharmony_ci
268f6603c60Sopenharmony_cistatic napi_module demoModule = {
269f6603c60Sopenharmony_ci    .nm_version = 1,
270f6603c60Sopenharmony_ci    .nm_flags = 0,
271f6603c60Sopenharmony_ci    .nm_filename = nullptr,
272f6603c60Sopenharmony_ci    .nm_register_func = Init,
273f6603c60Sopenharmony_ci    .nm_modname = "nativeavdemuxer",
274f6603c60Sopenharmony_ci    .nm_priv = ((void *)0),
275f6603c60Sopenharmony_ci    .reserved = { 0 },
276f6603c60Sopenharmony_ci};
277f6603c60Sopenharmony_ci
278f6603c60Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void)
279f6603c60Sopenharmony_ci{
280f6603c60Sopenharmony_ci    napi_module_register(&demoModule);
281f6603c60Sopenharmony_ci}
282