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