@lumen5/beamcoder 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.circleci/config.yml +41 -0
  2. package/.circleci/images/testbeam10-4.1/Dockerfile +12 -0
  3. package/.circleci/test_image/Dockerfile +14 -0
  4. package/.circleci/test_image/build.md +13 -0
  5. package/.eslintrc.js +27 -0
  6. package/.github/workflows/publish-npm.yml +33 -0
  7. package/LICENSE +674 -0
  8. package/README.md +1221 -0
  9. package/beamstreams.js +692 -0
  10. package/binding.gyp +103 -0
  11. package/examples/encode_h264.js +92 -0
  12. package/examples/jpeg_app.js +55 -0
  13. package/examples/jpeg_filter_app.js +101 -0
  14. package/examples/make_mp4.js +123 -0
  15. package/images/beamcoder_small.jpg +0 -0
  16. package/index.d.ts +83 -0
  17. package/index.js +44 -0
  18. package/install_ffmpeg.js +240 -0
  19. package/package.json +45 -0
  20. package/scratch/decode_aac.js +38 -0
  21. package/scratch/decode_avci.js +50 -0
  22. package/scratch/decode_hevc.js +38 -0
  23. package/scratch/decode_pcm.js +39 -0
  24. package/scratch/make_a_mux.js +68 -0
  25. package/scratch/muxer.js +74 -0
  26. package/scratch/read_wav.js +35 -0
  27. package/scratch/simple_mux.js +39 -0
  28. package/scratch/stream_avci.js +127 -0
  29. package/scratch/stream_mp4.js +78 -0
  30. package/scratch/stream_mux.js +47 -0
  31. package/scratch/stream_pcm.js +82 -0
  32. package/scratch/stream_wav.js +62 -0
  33. package/scripts/install_beamcoder_dependencies.sh +25 -0
  34. package/src/adaptor.h +202 -0
  35. package/src/beamcoder.cc +937 -0
  36. package/src/beamcoder_util.cc +1129 -0
  37. package/src/beamcoder_util.h +206 -0
  38. package/src/codec.cc +7386 -0
  39. package/src/codec.h +44 -0
  40. package/src/codec_par.cc +1818 -0
  41. package/src/codec_par.h +40 -0
  42. package/src/decode.cc +569 -0
  43. package/src/decode.h +75 -0
  44. package/src/demux.cc +584 -0
  45. package/src/demux.h +88 -0
  46. package/src/encode.cc +496 -0
  47. package/src/encode.h +72 -0
  48. package/src/filter.cc +1888 -0
  49. package/src/filter.h +30 -0
  50. package/src/format.cc +5287 -0
  51. package/src/format.h +77 -0
  52. package/src/frame.cc +2681 -0
  53. package/src/frame.h +52 -0
  54. package/src/governor.cc +286 -0
  55. package/src/governor.h +30 -0
  56. package/src/hwcontext.cc +378 -0
  57. package/src/hwcontext.h +35 -0
  58. package/src/log.cc +186 -0
  59. package/src/log.h +20 -0
  60. package/src/mux.cc +834 -0
  61. package/src/mux.h +106 -0
  62. package/src/packet.cc +762 -0
  63. package/src/packet.h +49 -0
  64. package/test/codecParamsSpec.js +148 -0
  65. package/test/decoderSpec.js +56 -0
  66. package/test/demuxerSpec.js +41 -0
  67. package/test/encoderSpec.js +69 -0
  68. package/test/filtererSpec.js +47 -0
  69. package/test/formatSpec.js +343 -0
  70. package/test/frameSpec.js +145 -0
  71. package/test/introspectionSpec.js +73 -0
  72. package/test/muxerSpec.js +34 -0
  73. package/test/packetSpec.js +122 -0
  74. package/types/Beamstreams.d.ts +98 -0
  75. package/types/Codec.d.ts +123 -0
  76. package/types/CodecContext.d.ts +555 -0
  77. package/types/CodecPar.d.ts +108 -0
  78. package/types/Decoder.d.ts +137 -0
  79. package/types/Demuxer.d.ts +113 -0
  80. package/types/Encoder.d.ts +94 -0
  81. package/types/Filter.d.ts +324 -0
  82. package/types/FormatContext.d.ts +380 -0
  83. package/types/Frame.d.ts +295 -0
  84. package/types/HWContext.d.ts +62 -0
  85. package/types/Muxer.d.ts +121 -0
  86. package/types/Packet.d.ts +82 -0
  87. package/types/PrivClass.d.ts +25 -0
  88. package/types/Stream.d.ts +165 -0
package/src/frame.cc ADDED
@@ -0,0 +1,2681 @@
1
+ /*
2
+ Aerostat Beam Coder - Node.js native bindings for FFmpeg.
3
+ Copyright (C) 2019 Streampunk Media Ltd.
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ https://www.streampunk.media/ mailto:furnace@streampunk.media
19
+ 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K.
20
+ */
21
+
22
+ #include "frame.h"
23
+ #include "hwcontext.h"
24
+
25
+ napi_value getFrameLinesize(napi_env env, napi_callback_info info) {
26
+ napi_status status;
27
+ napi_value array, element;
28
+ frameData* f;
29
+
30
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
31
+ CHECK_STATUS;
32
+
33
+ status = napi_create_array(env, &array);
34
+ CHECK_STATUS;
35
+
36
+ for ( int x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
37
+ if (f->frame->linesize[x] == 0) break;
38
+ status = napi_create_int32(env, f->frame->linesize[x], &element);
39
+ CHECK_STATUS;
40
+ status = napi_set_element(env, array, x, element);
41
+ CHECK_STATUS;
42
+ }
43
+
44
+ return array;
45
+ }
46
+
47
+ napi_value setFrameLinesize(napi_env env, napi_callback_info info) {
48
+ napi_status status;
49
+ napi_value result, element;
50
+ napi_valuetype type;
51
+ frameData* f;
52
+ bool isArray;
53
+ uint32_t lineCount;
54
+
55
+ size_t argc = 1;
56
+ napi_value args[1];
57
+
58
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
59
+ CHECK_STATUS;
60
+ if (argc < 1) {
61
+ NAPI_THROW_ERROR("Set frame linesize must be provided with a value.");
62
+ }
63
+ status = napi_is_array(env, args[0], &isArray);
64
+ CHECK_STATUS;
65
+ if (!isArray) {
66
+ NAPI_THROW_ERROR("Set frame linesize must use an array of numbers.");
67
+ }
68
+
69
+ status = napi_get_array_length(env, args[0], &lineCount);
70
+ CHECK_STATUS;
71
+ for ( uint32_t x = 0 ; x < lineCount ; x++ ) {
72
+ status = napi_get_element(env, args[0], x, &element);
73
+ CHECK_STATUS;
74
+ status = napi_typeof(env, element, &type);
75
+ CHECK_STATUS;
76
+ if (type != napi_number) {
77
+ NAPI_THROW_ERROR("Set frame linesize must use an array of numbers.");
78
+ }
79
+ }
80
+
81
+ for ( uint32_t x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
82
+ if (x >= lineCount) {
83
+ f->frame->linesize[x] = 0;
84
+ continue;
85
+ }
86
+ status = napi_get_element(env, args[0], x, &element);
87
+ CHECK_STATUS;
88
+ status = napi_get_value_int32(env, element, &f->frame->linesize[x]);
89
+ CHECK_STATUS;
90
+ }
91
+
92
+ status = napi_get_undefined(env, &result);
93
+ CHECK_STATUS;
94
+ return result;
95
+ }
96
+
97
+ napi_value getFrameWidth(napi_env env, napi_callback_info info) {
98
+ napi_status status;
99
+ napi_value result;
100
+ frameData* f;
101
+
102
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
103
+ CHECK_STATUS;
104
+
105
+ status = napi_create_int32(env, f->frame->width, &result);
106
+ CHECK_STATUS;
107
+ return result;
108
+ }
109
+
110
+ napi_value setFrameWidth(napi_env env, napi_callback_info info) {
111
+ napi_status status;
112
+ napi_value result;
113
+ napi_valuetype type;
114
+ frameData* f;
115
+
116
+ size_t argc = 1;
117
+ napi_value args[1];
118
+
119
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
120
+ CHECK_STATUS;
121
+ if (argc < 1) {
122
+ NAPI_THROW_ERROR("Set frame width must be provided with a value.");
123
+ }
124
+ status = napi_typeof(env, args[0], &type);
125
+ CHECK_STATUS;
126
+ if (type != napi_number) {
127
+ NAPI_THROW_ERROR("Frame width property must be set with a number.");
128
+ }
129
+ status = napi_get_value_int32(env, args[0], &f->frame->width);
130
+ CHECK_STATUS;
131
+
132
+ status = napi_get_undefined(env, &result);
133
+ CHECK_STATUS;
134
+ return result;
135
+ }
136
+
137
+ napi_value getFrameHeight(napi_env env, napi_callback_info info) {
138
+ napi_status status;
139
+ napi_value result;
140
+ frameData* f;
141
+
142
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
143
+ CHECK_STATUS;
144
+
145
+ status = napi_create_int32(env, f->frame->height, &result);
146
+ CHECK_STATUS;
147
+ return result;
148
+ }
149
+
150
+ napi_value setFrameHeight(napi_env env, napi_callback_info info) {
151
+ napi_status status;
152
+ napi_value result;
153
+ napi_valuetype type;
154
+ frameData* f;
155
+
156
+ size_t argc = 1;
157
+ napi_value args[1];
158
+
159
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
160
+ CHECK_STATUS;
161
+ if (argc < 1) {
162
+ NAPI_THROW_ERROR("Set frame height must be provided with a value.");
163
+ }
164
+ status = napi_typeof(env, args[0], &type);
165
+ CHECK_STATUS;
166
+ if (type != napi_number) {
167
+ NAPI_THROW_ERROR("Frame height property must be set with a number.");
168
+ }
169
+ status = napi_get_value_int32(env, args[0], &f->frame->height);
170
+ CHECK_STATUS;
171
+
172
+ status = napi_get_undefined(env, &result);
173
+ CHECK_STATUS;
174
+ return result;
175
+ }
176
+
177
+ napi_value getFrameNbSamples(napi_env env, napi_callback_info info) {
178
+ napi_status status;
179
+ napi_value result;
180
+ frameData* f;
181
+
182
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
183
+ CHECK_STATUS;
184
+
185
+ status = napi_create_int32(env, f->frame->nb_samples, &result);
186
+ CHECK_STATUS;
187
+ return result;
188
+ }
189
+
190
+ napi_value setFrameNbSamples(napi_env env, napi_callback_info info) {
191
+ napi_status status;
192
+ napi_value result;
193
+ napi_valuetype type;
194
+ frameData* f;
195
+
196
+ size_t argc = 1;
197
+ napi_value args[1];
198
+
199
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
200
+ CHECK_STATUS;
201
+ if (argc < 1) {
202
+ NAPI_THROW_ERROR("Set frame nb_samples must be provided with a value.");
203
+ }
204
+ status = napi_typeof(env, args[0], &type);
205
+ CHECK_STATUS;
206
+ if (type != napi_number) {
207
+ NAPI_THROW_ERROR("Frame nb_samples property must be set with a number.");
208
+ }
209
+ status = napi_get_value_int32(env, args[0], &f->frame->nb_samples);
210
+ CHECK_STATUS;
211
+
212
+ status = napi_get_undefined(env, &result);
213
+ CHECK_STATUS;
214
+ return result;
215
+ }
216
+
217
+ napi_value getFrameFormat(napi_env env, napi_callback_info info) {
218
+ napi_status status;
219
+ napi_value result;
220
+ frameData* f;
221
+ const char* name = nullptr;
222
+
223
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
224
+ CHECK_STATUS;
225
+
226
+ // Assume audio data using FFmpeg's own technique
227
+ if (f->frame->nb_samples > 0 && (f->frame->channel_layout || f->frame->channels > 0)) {
228
+ name = av_get_sample_fmt_name((AVSampleFormat) f->frame->format);
229
+ }
230
+ if (name == nullptr) { // Assume that it is video data
231
+ name = av_get_pix_fmt_name((AVPixelFormat) f->frame->format);
232
+ }
233
+ if (name == nullptr) {
234
+ status = napi_get_null(env, &result);
235
+ } else {
236
+ status = napi_create_string_utf8(env, (char*) name, NAPI_AUTO_LENGTH, &result);
237
+ }
238
+ CHECK_STATUS;
239
+
240
+ return result;
241
+ }
242
+
243
+ napi_value setFrameFormat(napi_env env, napi_callback_info info) {
244
+ napi_status status;
245
+ napi_value result;
246
+ napi_valuetype type;
247
+ frameData* f;
248
+ char* name;
249
+ size_t len;
250
+ int format = (int) AV_PIX_FMT_NONE;
251
+
252
+ size_t argc = 1;
253
+ napi_value args[1];
254
+
255
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
256
+ CHECK_STATUS;
257
+ if (argc < 1) {
258
+ NAPI_THROW_ERROR("Set frame format must be provided with a value.");
259
+ }
260
+ status = napi_typeof(env, args[0], &type);
261
+ CHECK_STATUS;
262
+ if (type == napi_null) {
263
+ f->frame->format = -1;
264
+ goto done;
265
+ }
266
+ if (type != napi_string) {
267
+ NAPI_THROW_ERROR("Frame format property must be set with a string.");
268
+ }
269
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
270
+ CHECK_STATUS;
271
+ name = (char*) malloc(sizeof(char) * (len + 1));
272
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
273
+ CHECK_STATUS;
274
+
275
+ // TODO this may give surprising results
276
+ format = (int) av_get_pix_fmt( name);
277
+ if (format == AV_PIX_FMT_NONE) {
278
+ format = (int) av_get_sample_fmt((const char*) name);
279
+ if ((format != AV_SAMPLE_FMT_NONE) && (f->frame->nb_samples == 0)) {
280
+ f->frame->nb_samples = 1; // Cludge ... found a sample format ... force audio mode
281
+ f->frame->channels = 1;
282
+ }
283
+ }
284
+
285
+ f->frame->format = format;
286
+
287
+ done:
288
+ status = napi_get_undefined(env, &result);
289
+ CHECK_STATUS;
290
+ return result;
291
+ }
292
+
293
+ napi_value getFrameKeyFrame(napi_env env, napi_callback_info info) {
294
+ napi_status status;
295
+ napi_value result;
296
+ frameData* f;
297
+
298
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
299
+ CHECK_STATUS;
300
+
301
+ status = napi_get_boolean(env, (f->frame->key_frame == 1), &result);
302
+ CHECK_STATUS;
303
+ return result;
304
+ }
305
+
306
+ napi_value setFrameKeyFrame(napi_env env, napi_callback_info info) {
307
+ napi_status status;
308
+ napi_value result;
309
+ napi_valuetype type;
310
+ frameData* f;
311
+ bool keyFrame;
312
+
313
+ size_t argc = 1;
314
+ napi_value args[1];
315
+
316
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
317
+ CHECK_STATUS;
318
+ if (argc < 1) {
319
+ NAPI_THROW_ERROR("Set frame key_frame must be provided with a value.");
320
+ }
321
+ status = napi_typeof(env, args[0], &type);
322
+ CHECK_STATUS;
323
+ if (type != napi_boolean) {
324
+ NAPI_THROW_ERROR("Frame key_frame property must be set with a Boolean.");
325
+ }
326
+ status = napi_get_value_bool(env, args[0], &keyFrame);
327
+ CHECK_STATUS;
328
+ f->frame->key_frame = (keyFrame) ? 1 : 0;
329
+
330
+ status = napi_get_undefined(env, &result);
331
+ CHECK_STATUS;
332
+ return result;
333
+ }
334
+
335
+ napi_value getFramePictType(napi_env env, napi_callback_info info) {
336
+ napi_status status;
337
+ napi_value result;
338
+ frameData* f;
339
+ const char* name;
340
+
341
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
342
+ CHECK_STATUS;
343
+
344
+ switch (f->frame->pict_type) {
345
+ case AV_PICTURE_TYPE_I:
346
+ name = "I";
347
+ break;
348
+ case AV_PICTURE_TYPE_P:
349
+ name = "P";
350
+ break;
351
+ case AV_PICTURE_TYPE_B:
352
+ name = "B";
353
+ break;
354
+ case AV_PICTURE_TYPE_S:
355
+ name = "S";
356
+ break;
357
+ case AV_PICTURE_TYPE_SI:
358
+ name = "SI";
359
+ break;
360
+ case AV_PICTURE_TYPE_SP:
361
+ name = "SP";
362
+ break;
363
+ case AV_PICTURE_TYPE_BI:
364
+ name = "BI";
365
+ break;
366
+ default:
367
+ name = nullptr;
368
+ break;
369
+ }
370
+
371
+ if (name == nullptr) {
372
+ status = napi_get_null(env, &result);
373
+ } else {
374
+ status = napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &result);
375
+ }
376
+ CHECK_STATUS;
377
+ return result;
378
+ }
379
+
380
+ napi_value setFramePictType(napi_env env, napi_callback_info info) {
381
+ napi_status status;
382
+ napi_value result;
383
+ napi_valuetype type;
384
+ frameData* f;
385
+ char* name;
386
+ size_t len;
387
+
388
+ size_t argc = 1;
389
+ napi_value args[1];
390
+
391
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
392
+ CHECK_STATUS;
393
+ if (argc < 1) {
394
+ NAPI_THROW_ERROR("Set frame pict_type must be provided with a value.");
395
+ }
396
+ status = napi_typeof(env, args[0], &type);
397
+ CHECK_STATUS;
398
+ if ((type == napi_undefined) || (type == napi_null)) {
399
+ f->frame->pict_type = AV_PICTURE_TYPE_NONE;
400
+ goto done;
401
+ }
402
+ if (type != napi_string) {
403
+ NAPI_THROW_ERROR("Frame pict_type property must be set with a string.");
404
+ }
405
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
406
+ CHECK_STATUS;
407
+ name = (char*) malloc(sizeof(char) * (len + 1));
408
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
409
+ CHECK_STATUS;
410
+
411
+ switch (name[0]) {
412
+ case 'I':
413
+ f->frame->pict_type = AV_PICTURE_TYPE_I;
414
+ break;
415
+ case 'P':
416
+ f->frame->pict_type = AV_PICTURE_TYPE_P;
417
+ break;
418
+ case 'B':
419
+ f->frame->pict_type = (len == 1) ? AV_PICTURE_TYPE_B : AV_PICTURE_TYPE_BI;
420
+ break;
421
+ case 'S':
422
+ if (len == 1) {
423
+ f->frame->pict_type = AV_PICTURE_TYPE_S;
424
+ break;
425
+ }
426
+ if (len == 2) {
427
+ if (name[1] == 'I') {
428
+ f->frame->pict_type = AV_PICTURE_TYPE_SI;
429
+ break;
430
+ }
431
+ if (name[1] == 'P') {
432
+ f->frame->pict_type = AV_PICTURE_TYPE_SP;
433
+ break;
434
+ }
435
+ }
436
+ f->frame->pict_type = AV_PICTURE_TYPE_NONE;
437
+ break;
438
+ default:
439
+ f->frame->pict_type = AV_PICTURE_TYPE_NONE;
440
+ break;
441
+ }
442
+
443
+ done:
444
+ status = napi_get_undefined(env, &result);
445
+ CHECK_STATUS;
446
+ return result;
447
+ }
448
+
449
+ napi_value getFrameSampleAR(napi_env env, napi_callback_info info) {
450
+ napi_status status;
451
+ napi_value result, element;
452
+ frameData* f;
453
+
454
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
455
+ CHECK_STATUS;
456
+
457
+ status = napi_create_array(env, &result);
458
+ CHECK_STATUS;
459
+ status = napi_create_int32(env, f->frame->sample_aspect_ratio.num, &element);
460
+ CHECK_STATUS;
461
+ status = napi_set_element(env, result, 0, element);
462
+ CHECK_STATUS;
463
+ status = napi_create_int32(env, f->frame->sample_aspect_ratio.den, &element);
464
+ CHECK_STATUS;
465
+ status = napi_set_element(env, result, 1, element);
466
+ CHECK_STATUS;
467
+
468
+ return result;
469
+ }
470
+
471
+ napi_value setFrameSampleAR(napi_env env, napi_callback_info info) {
472
+ napi_status status;
473
+ napi_value result, element;
474
+ napi_valuetype type;
475
+ frameData* f;
476
+ bool isArray;
477
+
478
+ size_t argc = 1;
479
+ napi_value args[1];
480
+
481
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
482
+ CHECK_STATUS;
483
+ if (argc < 1) {
484
+ NAPI_THROW_ERROR("Set frame sample_aspect_ratio must be provided with a value.");
485
+ }
486
+ status = napi_typeof(env, args[0], &type);
487
+ CHECK_STATUS;
488
+ if ((type == napi_undefined) || (type == napi_null)) {
489
+ f->frame->sample_aspect_ratio = { 0, 1 };
490
+ goto done;
491
+ }
492
+ status = napi_is_array(env, args[0], &isArray);
493
+ CHECK_STATUS;
494
+ if (!isArray) {
495
+ NAPI_THROW_ERROR("Frame sample_aspect_ratio property must be set with an array of two numbers.");
496
+ }
497
+
498
+ f->frame->sample_aspect_ratio = { 0, 1 };
499
+ status = napi_get_element(env, args[0], 0, &element);
500
+ CHECK_STATUS;
501
+ status = napi_get_value_int32(env, element, &f->frame->sample_aspect_ratio.num);
502
+ CHECK_STATUS;
503
+ status = napi_get_element(env, args[0], 1, &element);
504
+ CHECK_STATUS;
505
+ status = napi_get_value_int32(env, element, &f->frame->sample_aspect_ratio.den);
506
+ CHECK_STATUS;
507
+
508
+ done:
509
+ status = napi_get_undefined(env, &result);
510
+ CHECK_STATUS;
511
+ return result;
512
+ }
513
+
514
+ napi_value getFramePTS(napi_env env, napi_callback_info info) {
515
+ napi_status status;
516
+ napi_value result;
517
+ frameData* f;
518
+
519
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
520
+ CHECK_STATUS;
521
+
522
+ if (f->frame->pts == AV_NOPTS_VALUE) {
523
+ status = napi_get_null(env, &result);
524
+ CHECK_STATUS;
525
+ } else {
526
+ status = napi_create_int64(env, f->frame->pts, &result);
527
+ CHECK_STATUS;
528
+ }
529
+
530
+ return result;
531
+ }
532
+
533
+ napi_value setFramePTS(napi_env env, napi_callback_info info) {
534
+ napi_status status;
535
+ napi_value result;
536
+ napi_valuetype type;
537
+ frameData* f;
538
+
539
+ size_t argc = 1;
540
+ napi_value args[1];
541
+
542
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
543
+ CHECK_STATUS;
544
+ if (argc < 1) {
545
+ NAPI_THROW_ERROR("Set frame PTS must be provided with a value.");
546
+ }
547
+ status = napi_typeof(env, args[0], &type);
548
+ CHECK_STATUS;
549
+ if ((type == napi_null) || (type == napi_undefined)) {
550
+ f->frame->pts = AV_NOPTS_VALUE;
551
+ goto done;
552
+ }
553
+ if (type != napi_number) {
554
+ NAPI_THROW_ERROR("Frame PTS property must be set with a number.");
555
+ }
556
+ status = napi_get_value_int64(env, args[0], &f->frame->pts);
557
+ CHECK_STATUS;
558
+
559
+ done:
560
+ status = napi_get_undefined(env, &result);
561
+ CHECK_STATUS;
562
+ return result;
563
+ }
564
+
565
+ napi_value getFramePktDTS(napi_env env, napi_callback_info info) {
566
+ napi_status status;
567
+ napi_value result;
568
+ frameData* f;
569
+
570
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
571
+ CHECK_STATUS;
572
+
573
+ if (f->frame->pkt_dts == AV_NOPTS_VALUE) {
574
+ status = napi_get_null(env, &result);
575
+ CHECK_STATUS;
576
+ } else {
577
+ status = napi_create_int64(env, f->frame->pkt_dts, &result);
578
+ CHECK_STATUS;
579
+ }
580
+
581
+ return result;
582
+ }
583
+
584
+ napi_value setFramePktDTS(napi_env env, napi_callback_info info) {
585
+ napi_status status;
586
+ napi_value result;
587
+ napi_valuetype type;
588
+ frameData* f;
589
+
590
+ size_t argc = 1;
591
+ napi_value args[1];
592
+
593
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
594
+ CHECK_STATUS;
595
+ if (argc < 1) {
596
+ NAPI_THROW_ERROR("Set frame pkt_dts must be provided with a value.");
597
+ }
598
+ status = napi_typeof(env, args[0], &type);
599
+ CHECK_STATUS;
600
+ if ((type == napi_null) || (type == napi_undefined)) {
601
+ f->frame->pkt_dts = AV_NOPTS_VALUE;
602
+ goto done;
603
+ }
604
+ if (type != napi_number) {
605
+ NAPI_THROW_ERROR("Frame pkt_dts property must be set with a number.");
606
+ }
607
+ status = napi_get_value_int64(env, args[0], &f->frame->pkt_dts);
608
+ CHECK_STATUS;
609
+
610
+ done:
611
+ status = napi_get_undefined(env, &result);
612
+ CHECK_STATUS;
613
+ return result;
614
+ }
615
+
616
+ napi_value getFrameCodedPicNum(napi_env env, napi_callback_info info) {
617
+ napi_status status;
618
+ napi_value result;
619
+ frameData* f;
620
+
621
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
622
+ CHECK_STATUS;
623
+
624
+ status = napi_create_int32(env, f->frame->coded_picture_number, &result);
625
+ CHECK_STATUS;
626
+ return result;
627
+ }
628
+
629
+ napi_value setFrameCodedPicNum(napi_env env, napi_callback_info info) {
630
+ napi_status status;
631
+ napi_value result;
632
+ napi_valuetype type;
633
+ frameData* f;
634
+
635
+ size_t argc = 1;
636
+ napi_value args[1];
637
+
638
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
639
+ CHECK_STATUS;
640
+ if (argc < 1) {
641
+ NAPI_THROW_ERROR("Set frame coded_picture_number must be provided with a value.");
642
+ }
643
+ status = napi_typeof(env, args[0], &type);
644
+ CHECK_STATUS;
645
+ if (type != napi_number) {
646
+ NAPI_THROW_ERROR("Frame coded_picture_number property must be set with a number.");
647
+ }
648
+ status = napi_get_value_int32(env, args[0], &f->frame->coded_picture_number);
649
+ CHECK_STATUS;
650
+
651
+ status = napi_get_undefined(env, &result);
652
+ CHECK_STATUS;
653
+ return result;
654
+ }
655
+
656
+ napi_value getFrameDispPicNum(napi_env env, napi_callback_info info) {
657
+ napi_status status;
658
+ napi_value result;
659
+ frameData* f;
660
+
661
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
662
+ CHECK_STATUS;
663
+
664
+ status = napi_create_int32(env, f->frame->display_picture_number, &result);
665
+ CHECK_STATUS;
666
+ return result;
667
+ }
668
+
669
+ napi_value setFrameDispPicNum(napi_env env, napi_callback_info info) {
670
+ napi_status status;
671
+ napi_value result;
672
+ napi_valuetype type;
673
+ frameData* f;
674
+
675
+ size_t argc = 1;
676
+ napi_value args[1];
677
+
678
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
679
+ CHECK_STATUS;
680
+ if (argc < 1) {
681
+ NAPI_THROW_ERROR("Set frame display_picture_number must be provided with a value.");
682
+ }
683
+ status = napi_typeof(env, args[0], &type);
684
+ CHECK_STATUS;
685
+ if (type != napi_number) {
686
+ NAPI_THROW_ERROR("Frame display_picture_number property must be set with a number.");
687
+ }
688
+ status = napi_get_value_int32(env, args[0], &f->frame->display_picture_number);
689
+ CHECK_STATUS;
690
+
691
+ status = napi_get_undefined(env, &result);
692
+ CHECK_STATUS;
693
+ return result;
694
+ }
695
+
696
+ napi_value getFrameQuality(napi_env env, napi_callback_info info) {
697
+ napi_status status;
698
+ napi_value result;
699
+ frameData* f;
700
+
701
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
702
+ CHECK_STATUS;
703
+
704
+ status = napi_create_int32(env, f->frame->quality, &result);
705
+ CHECK_STATUS;
706
+ return result;
707
+ }
708
+
709
+ napi_value setFrameQuality(napi_env env, napi_callback_info info) {
710
+ napi_status status;
711
+ napi_value result;
712
+ napi_valuetype type;
713
+ frameData* f;
714
+
715
+ size_t argc = 1;
716
+ napi_value args[1];
717
+
718
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
719
+ CHECK_STATUS;
720
+ if (argc < 1) {
721
+ NAPI_THROW_ERROR("Set frame quality must be provided with a value.");
722
+ }
723
+ status = napi_typeof(env, args[0], &type);
724
+ CHECK_STATUS;
725
+ if (type != napi_number) {
726
+ NAPI_THROW_ERROR("Frame quality property must be set with a number.");
727
+ }
728
+ status = napi_get_value_int32(env, args[0], &f->frame->quality);
729
+ CHECK_STATUS;
730
+
731
+ status = napi_get_undefined(env, &result);
732
+ CHECK_STATUS;
733
+ return result;
734
+ }
735
+
736
+ napi_value getFrameRepeatPict(napi_env env, napi_callback_info info) {
737
+ napi_status status;
738
+ napi_value result;
739
+ frameData* f;
740
+
741
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
742
+ CHECK_STATUS;
743
+
744
+ status = napi_create_int32(env, f->frame->repeat_pict, &result);
745
+ CHECK_STATUS;
746
+ return result;
747
+ }
748
+
749
+ napi_value setFrameRepeatPict(napi_env env, napi_callback_info info) {
750
+ napi_status status;
751
+ napi_value result;
752
+ napi_valuetype type;
753
+ frameData* f;
754
+
755
+ size_t argc = 1;
756
+ napi_value args[1];
757
+
758
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
759
+ CHECK_STATUS;
760
+ if (argc < 1) {
761
+ NAPI_THROW_ERROR("Set frame repeat_pict must be provided with a value.");
762
+ }
763
+ status = napi_typeof(env, args[0], &type);
764
+ CHECK_STATUS;
765
+ if (type != napi_number) {
766
+ NAPI_THROW_ERROR("Frame repeat_pict property must be set with a number.");
767
+ }
768
+ status = napi_get_value_int32(env, args[0], &f->frame->repeat_pict);
769
+ CHECK_STATUS;
770
+
771
+ status = napi_get_undefined(env, &result);
772
+ CHECK_STATUS;
773
+ return result;
774
+ }
775
+
776
+ napi_value getFrameInterlaced(napi_env env, napi_callback_info info) {
777
+ napi_status status;
778
+ napi_value result;
779
+ frameData* f;
780
+
781
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
782
+ CHECK_STATUS;
783
+
784
+ status = napi_get_boolean(env, f->frame->interlaced_frame == 1, &result);
785
+ CHECK_STATUS;
786
+ return result;
787
+ }
788
+
789
+ napi_value setFrameInterlaced(napi_env env, napi_callback_info info) {
790
+ napi_status status;
791
+ napi_value result;
792
+ napi_valuetype type;
793
+ frameData* f;
794
+ bool interlaced;
795
+
796
+ size_t argc = 1;
797
+ napi_value args[1];
798
+
799
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
800
+ CHECK_STATUS;
801
+ if (argc < 1) {
802
+ NAPI_THROW_ERROR("Set frame interlaced_frame must be provided with a value.");
803
+ }
804
+ status = napi_typeof(env, args[0], &type);
805
+ CHECK_STATUS;
806
+ if (type != napi_boolean) {
807
+ NAPI_THROW_ERROR("Frame interlaced_frame property must be set with a Boolean.");
808
+ }
809
+ status = napi_get_value_bool(env, args[0], &interlaced);
810
+ CHECK_STATUS;
811
+ f->frame->interlaced_frame = (interlaced) ? 1 : 0;
812
+
813
+ status = napi_get_undefined(env, &result);
814
+ CHECK_STATUS;
815
+ return result;
816
+ }
817
+
818
+ napi_value getFrameTopFieldFirst(napi_env env, napi_callback_info info) {
819
+ napi_status status;
820
+ napi_value result;
821
+ frameData* f;
822
+
823
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
824
+ CHECK_STATUS;
825
+
826
+ status = napi_get_boolean(env, f->frame->top_field_first == 1, &result);
827
+ CHECK_STATUS;
828
+ return result;
829
+ }
830
+
831
+ napi_value setFrameTopFieldFirst(napi_env env, napi_callback_info info) {
832
+ napi_status status;
833
+ napi_value result;
834
+ napi_valuetype type;
835
+ frameData* f;
836
+ bool topFieldFirst;
837
+
838
+ size_t argc = 1;
839
+ napi_value args[1];
840
+
841
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
842
+ CHECK_STATUS;
843
+ if (argc < 1) {
844
+ NAPI_THROW_ERROR("Set frame top_field_first must be provided with a value.");
845
+ }
846
+ status = napi_typeof(env, args[0], &type);
847
+ CHECK_STATUS;
848
+ if (type != napi_boolean) {
849
+ NAPI_THROW_ERROR("Frame top_field_first property must be set with a Boolean.");
850
+ }
851
+ status = napi_get_value_bool(env, args[0], &topFieldFirst);
852
+ CHECK_STATUS;
853
+ f->frame->top_field_first = (topFieldFirst) ? 1 : 0;
854
+
855
+ status = napi_get_undefined(env, &result);
856
+ CHECK_STATUS;
857
+ return result;
858
+ }
859
+
860
+ napi_value getFramePalHasChanged(napi_env env, napi_callback_info info) {
861
+ napi_status status;
862
+ napi_value result;
863
+ frameData* f;
864
+
865
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
866
+ CHECK_STATUS;
867
+
868
+ status = napi_get_boolean(env, f->frame->palette_has_changed == 1, &result);
869
+ CHECK_STATUS;
870
+ return result;
871
+ }
872
+
873
+ napi_value setFramePalHasChanged(napi_env env, napi_callback_info info) {
874
+ napi_status status;
875
+ napi_value result;
876
+ napi_valuetype type;
877
+ frameData* f;
878
+ bool palHasChanged;
879
+
880
+ size_t argc = 1;
881
+ napi_value args[1];
882
+
883
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
884
+ CHECK_STATUS;
885
+ if (argc < 1) {
886
+ NAPI_THROW_ERROR("Set frame palette_has_changed must be provided with a value.");
887
+ }
888
+ status = napi_typeof(env, args[0], &type);
889
+ CHECK_STATUS;
890
+ if (type != napi_boolean) {
891
+ NAPI_THROW_ERROR("Frame palette_has_changed property must be set with a Boolean.");
892
+ }
893
+ status = napi_get_value_bool(env, args[0], &palHasChanged);
894
+ CHECK_STATUS;
895
+ f->frame->palette_has_changed = (palHasChanged) ? 1 : 0;
896
+
897
+ status = napi_get_undefined(env, &result);
898
+ CHECK_STATUS;
899
+ return result;
900
+ }
901
+
902
+ napi_value getFrameReorderOpq(napi_env env, napi_callback_info info) {
903
+ napi_status status;
904
+ napi_value result;
905
+ frameData* f;
906
+
907
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
908
+ CHECK_STATUS;
909
+
910
+ if (f->frame->reordered_opaque == AV_NOPTS_VALUE) {
911
+ status = napi_get_null(env, &result);
912
+ CHECK_STATUS;
913
+ } else {
914
+ status = napi_create_int64(env, f->frame->reordered_opaque, &result);
915
+ CHECK_STATUS;
916
+ }
917
+ return result;
918
+ }
919
+
920
+ napi_value setFrameReorderOpq(napi_env env, napi_callback_info info) {
921
+ napi_status status;
922
+ napi_value result;
923
+ napi_valuetype type;
924
+ frameData* f;
925
+
926
+ size_t argc = 1;
927
+ napi_value args[1];
928
+
929
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
930
+ CHECK_STATUS;
931
+ if (argc < 1) {
932
+ NAPI_THROW_ERROR("Set frame reordered_opaque must be provided with a value.");
933
+ }
934
+ status = napi_typeof(env, args[0], &type);
935
+ CHECK_STATUS;
936
+ if ((type == napi_null) || (type == napi_undefined)) {
937
+ f->frame->reordered_opaque = AV_NOPTS_VALUE;
938
+ goto done;
939
+ }
940
+
941
+ if (type != napi_number) {
942
+ NAPI_THROW_ERROR("Frame reordered_opaque property must be set with a number.");
943
+ }
944
+ status = napi_get_value_int64(env, args[0], &f->frame->reordered_opaque);
945
+ CHECK_STATUS;
946
+
947
+ done:
948
+ status = napi_get_undefined(env, &result);
949
+ CHECK_STATUS;
950
+ return result;
951
+ }
952
+
953
+ napi_value getFrameSampleRate(napi_env env, napi_callback_info info) {
954
+ napi_status status;
955
+ napi_value result;
956
+ frameData* f;
957
+
958
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
959
+ CHECK_STATUS;
960
+
961
+ status = napi_create_int32(env, f->frame->sample_rate, &result);
962
+ CHECK_STATUS;
963
+ return result;
964
+ }
965
+
966
+ napi_value setFrameSampleRate(napi_env env, napi_callback_info info) {
967
+ napi_status status;
968
+ napi_value result;
969
+ napi_valuetype type;
970
+ frameData* f;
971
+
972
+ size_t argc = 1;
973
+ napi_value args[1];
974
+
975
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
976
+ CHECK_STATUS;
977
+ if (argc < 1) {
978
+ NAPI_THROW_ERROR("Set frame sample_rate must be provided with a value.");
979
+ }
980
+ status = napi_typeof(env, args[0], &type);
981
+ CHECK_STATUS;
982
+ if (type != napi_number) {
983
+ NAPI_THROW_ERROR("Frame sample_rate property must be set with a number.");
984
+ }
985
+ status = napi_get_value_int32(env, args[0], &f->frame->sample_rate);
986
+ CHECK_STATUS;
987
+
988
+ status = napi_get_undefined(env, &result);
989
+ CHECK_STATUS;
990
+ return result;
991
+ }
992
+
993
+ napi_value getFrameChanLayout(napi_env env, napi_callback_info info) {
994
+ napi_status status;
995
+ napi_value result;
996
+ frameData* f;
997
+
998
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
999
+ CHECK_STATUS;
1000
+
1001
+ char channelLayoutName[64];
1002
+ av_get_channel_layout_string(channelLayoutName, 64, 0,
1003
+ f->frame->channel_layout ? f->frame->channel_layout : av_get_default_channel_layout(f->frame->channels));
1004
+
1005
+ status = napi_create_string_utf8(env, channelLayoutName, NAPI_AUTO_LENGTH, &result);
1006
+ CHECK_STATUS;
1007
+ return result;
1008
+ }
1009
+
1010
+ napi_value setFrameChanLayout(napi_env env, napi_callback_info info) {
1011
+ napi_status status;
1012
+ napi_value result;
1013
+ napi_valuetype type;
1014
+ frameData* f;
1015
+ char* name;
1016
+ size_t len;
1017
+
1018
+ size_t argc = 1;
1019
+ napi_value args[1];
1020
+
1021
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1022
+ CHECK_STATUS;
1023
+ if (argc < 1) {
1024
+ NAPI_THROW_ERROR("Set frame channel_layout must be provided with a value.");
1025
+ }
1026
+ status = napi_typeof(env, args[0], &type);
1027
+ CHECK_STATUS;
1028
+ if ((type == napi_null) || (type == napi_undefined)) {
1029
+ f->frame->channel_layout = 0;
1030
+ goto done;
1031
+ }
1032
+ if (type != napi_string) {
1033
+ NAPI_THROW_ERROR("Frame channel_layout property must be set with a string.");
1034
+ }
1035
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1036
+ CHECK_STATUS;
1037
+ name = (char*) malloc(sizeof(char) * (len + 1));
1038
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1039
+ CHECK_STATUS;
1040
+
1041
+ f->frame->channel_layout = av_get_channel_layout(name);
1042
+ free(name);
1043
+
1044
+ done:
1045
+ status = napi_get_undefined(env, &result);
1046
+ CHECK_STATUS;
1047
+ return result;
1048
+ }
1049
+
1050
+ napi_value getFrameData(napi_env env, napi_callback_info info) {
1051
+ napi_status status;
1052
+ napi_value array, element;
1053
+ frameData* f;
1054
+ uint8_t* data;
1055
+ AVBufferRef* ref;
1056
+ size_t size;
1057
+ int curElem;
1058
+
1059
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1060
+ CHECK_STATUS;
1061
+
1062
+ status = napi_create_array(env, &array);
1063
+ CHECK_STATUS;
1064
+
1065
+ data = f->frame->data[0];
1066
+ ref = f->frame->buf[0] ? av_buffer_ref(f->frame->buf[0]) : nullptr;
1067
+ size = ref ? ref->size : 0;
1068
+ curElem = 0;
1069
+ // work through frame bufs checking whether allocation refcounts are shared
1070
+ for ( int x = 1 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
1071
+ // printf("Buffer %i is %p\n", x, f->frame->data[x]);
1072
+ if (f->frame->data[x] == nullptr) continue;
1073
+ size_t bufSize = size;
1074
+ if (f->frame->buf[x] == nullptr)
1075
+ bufSize = f->frame->data[x] - f->frame->data[x-1];
1076
+ status = napi_create_external_buffer(env, bufSize, data, frameBufferFinalizer, ref, &element);
1077
+ CHECK_STATUS;
1078
+ status = napi_set_element(env, array, curElem, element);
1079
+ CHECK_STATUS;
1080
+ data = f->frame->data[x];
1081
+ if (f->frame->buf[x]) {
1082
+ ref = av_buffer_ref(f->frame->buf[x]);
1083
+ size = ref->size;
1084
+ } else {
1085
+ ref = nullptr;
1086
+ size -= f->frame->data[x] - f->frame->data[x-1];
1087
+ }
1088
+ curElem++;
1089
+ }
1090
+ if (data) {
1091
+ status = napi_create_external_buffer(env, size, data, frameBufferFinalizer, ref, &element);
1092
+ CHECK_STATUS;
1093
+ status = napi_set_element(env, array, curElem, element);
1094
+ CHECK_STATUS;
1095
+ }
1096
+
1097
+ CHECK_STATUS;
1098
+ return array;
1099
+ }
1100
+
1101
+ napi_value setFrameData(napi_env env, napi_callback_info info) {
1102
+ napi_status status;
1103
+ napi_value result, element;
1104
+ napi_valuetype type;
1105
+ bool isArray, isBuffer;
1106
+ frameData* f;
1107
+ uint8_t* data;
1108
+ size_t length;
1109
+ avBufRef* avr;
1110
+ uint32_t bufCount;
1111
+ napi_ref dataRef;
1112
+
1113
+ size_t argc = 1;
1114
+ napi_value args[1];
1115
+
1116
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1117
+ CHECK_STATUS;
1118
+ if (argc < 1) {
1119
+ NAPI_THROW_ERROR("Set packet data must be provided with an array of buffer values.");
1120
+ }
1121
+ status = napi_typeof(env, args[0], &type);
1122
+ CHECK_STATUS;
1123
+ if ((type == napi_null) || (type == napi_undefined)) {
1124
+ for ( auto it = f->dataRefs.cbegin() ; it != f->dataRefs.cend() ; it++ ) {
1125
+ status = napi_delete_reference(env, *it);
1126
+ CHECK_STATUS;
1127
+ }
1128
+ f->dataRefs.clear();
1129
+ for ( uint32_t x = 0 ; x < AV_NUM_DATA_POINTERS ; x++) {
1130
+ if (f->frame->buf[x] != nullptr) {
1131
+ av_buffer_unref(&f->frame->buf[x]);
1132
+ }
1133
+ f->frame->data[x] = nullptr;
1134
+ }
1135
+ goto done;
1136
+ }
1137
+ status = napi_is_array(env, args[0], &isArray);
1138
+ CHECK_STATUS;
1139
+ if (!isArray) {
1140
+ NAPI_THROW_ERROR("Packet data property must be set with an array of buffer values.");
1141
+ }
1142
+ status = napi_get_array_length(env, args[0], &bufCount);
1143
+ CHECK_STATUS;
1144
+ for ( uint32_t x = 0 ; x < bufCount ; x++ ) {
1145
+ status = napi_get_element(env, args[0], x, &element);
1146
+ CHECK_STATUS;
1147
+ status = napi_is_buffer(env, element, &isBuffer);
1148
+ CHECK_STATUS;
1149
+ if (!isBuffer) {
1150
+ NAPI_THROW_ERROR("All elements of the packet data array must be buffers.");
1151
+ }
1152
+ }
1153
+
1154
+ for ( auto it = f->dataRefs.cbegin() ; it != f->dataRefs.cend() ; it++ ) {
1155
+ // printf("On new buffers provided, freeing data refs for pts = %i\n", f->frame->pts);
1156
+ status = napi_delete_reference(env, *it);
1157
+ CHECK_STATUS;
1158
+ }
1159
+ f->dataRefs.clear();
1160
+ for ( uint32_t x = 0 ; x < AV_NUM_DATA_POINTERS ; x++) {
1161
+ if (f->frame->buf[x] != nullptr) {
1162
+ av_buffer_unref(&f->frame->buf[x]);
1163
+ }
1164
+ }
1165
+ for ( uint32_t x = 0 ; x < AV_NUM_DATA_POINTERS ; x++) {
1166
+ if (x >= bufCount) {
1167
+ if (f->frame->buf[x] != nullptr) {
1168
+ av_buffer_unref(&f->frame->buf[x]); // sets pointer to null
1169
+ }
1170
+ f->frame->data[x] = nullptr;
1171
+ continue;
1172
+ }
1173
+ status = napi_get_element(env, args[0], x, &element);
1174
+ CHECK_STATUS;
1175
+ // printf("Creating data reference for pts = %i\n", f->frame->pts);
1176
+ status = napi_create_reference(env, element, 1, &dataRef);
1177
+ CHECK_STATUS;
1178
+ f->dataRefs.push_back(dataRef);
1179
+ avr = new avBufRef;
1180
+ avr->pts = f->frame->pts;
1181
+ // printf("Creating AV reference for pts = %i\n", f->frame->pts);
1182
+ status = napi_create_reference(env, element, 1, &avr->ref);
1183
+ CHECK_STATUS;
1184
+ avr->env = env;
1185
+ status = napi_get_buffer_info(env, element, (void**) &data, &length);
1186
+ CHECK_STATUS;
1187
+
1188
+ f->frame->buf[x] = av_buffer_create(data, length, frameBufferFree, avr, 0);
1189
+ CHECK_STATUS;
1190
+ f->frame->data[x] = f->frame->buf[x]->data;
1191
+ }
1192
+
1193
+ done:
1194
+ status = napi_get_undefined(env, &result);
1195
+ CHECK_STATUS;
1196
+ return result;
1197
+ }
1198
+
1199
+ napi_value getFrameSideData(napi_env env, napi_callback_info info) {
1200
+ napi_status status;
1201
+ napi_value result, element;
1202
+ void* resultData;
1203
+ frameData* f;
1204
+
1205
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1206
+ CHECK_STATUS;
1207
+
1208
+ if (f->frame->nb_side_data <= 0) {
1209
+ status = napi_get_null(env, &result);
1210
+ CHECK_STATUS;
1211
+ } else {
1212
+ status = napi_create_object(env, &result);
1213
+ CHECK_STATUS;
1214
+ status = beam_set_string_utf8(env, result, "type", "FrameSideData");
1215
+ for ( int x = 0 ; x < f->frame->nb_side_data ; x++ ) {
1216
+ status = napi_create_buffer_copy(env, f->frame->side_data[x]->size,
1217
+ f->frame->side_data[x]->data, &resultData, &element);
1218
+ CHECK_STATUS;
1219
+ status = napi_set_named_property(env, result,
1220
+ beam_lookup_name(beam_frame_side_data_type->forward,
1221
+ f->frame->side_data[x]->type), element);
1222
+ CHECK_STATUS;
1223
+ }
1224
+ }
1225
+
1226
+ return result;
1227
+ }
1228
+
1229
+ napi_value setFrameSideData(napi_env env, napi_callback_info info) {
1230
+ napi_status status;
1231
+ napi_value result, names, name, element, arrayData, global, jsBuffer, jsBufferFrom;
1232
+ napi_valuetype type;
1233
+ bool isArray, isBuffer;
1234
+ uint32_t sdCount = 0;
1235
+ AVFrameSideData* fsd;
1236
+ int fsdt;
1237
+ char* typeName;
1238
+ size_t strLen;
1239
+ void* rawdata;
1240
+ size_t rawdataSize;
1241
+ frameData* f;
1242
+
1243
+ size_t argc = 1;
1244
+ napi_value args[1];
1245
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1246
+ CHECK_STATUS;
1247
+ if (argc < 1) {
1248
+ NAPI_THROW_ERROR("Set frame flags must be provided with a value.");
1249
+ }
1250
+
1251
+ status = napi_get_global(env, &global);
1252
+ CHECK_STATUS;
1253
+ status = napi_get_named_property(env, global, "Buffer", &jsBuffer);
1254
+ CHECK_STATUS;
1255
+ status = napi_get_named_property(env, jsBuffer, "from", &jsBufferFrom);
1256
+ CHECK_STATUS;
1257
+
1258
+ status = napi_typeof(env, args[0], &type);
1259
+ CHECK_STATUS;
1260
+ status = napi_is_array(env, args[0], &isArray);
1261
+ CHECK_STATUS;
1262
+
1263
+ switch (type) {
1264
+ case napi_object:
1265
+ case napi_null:
1266
+ case napi_undefined:
1267
+ if ((f->frame->side_data != nullptr) && (f->frame->nb_side_data > 0)) {
1268
+ for ( int x = 0 ; x < f->frame->nb_side_data ; x++) {
1269
+ av_frame_remove_side_data(f->frame, f->frame->side_data[x]->type);
1270
+ }
1271
+ av_freep(&f->frame->data);
1272
+ f->frame->nb_side_data = 0;
1273
+ }
1274
+ if (type != napi_object) { goto done; };
1275
+ break;
1276
+ default:
1277
+ NAPI_THROW_ERROR("Frame side_data property requires an object with properties of Buffer type.");
1278
+ }
1279
+
1280
+ status = napi_get_property_names(env, args[0], &names);
1281
+ CHECK_STATUS;
1282
+ status = napi_get_array_length(env, names, &sdCount);
1283
+ CHECK_STATUS;
1284
+
1285
+ for ( uint32_t x = 0 ; x < sdCount ; x++ ) {
1286
+ status = napi_get_element(env, names, x, &name);
1287
+ CHECK_STATUS;
1288
+ status = napi_get_property(env, args[0], name, &element);
1289
+ CHECK_STATUS;
1290
+ status = napi_is_buffer(env, element, &isBuffer);
1291
+ CHECK_STATUS;
1292
+ if (!isBuffer) {
1293
+ status = napi_get_named_property(env, element, "data", &arrayData);
1294
+ CHECK_STATUS;
1295
+ // TODO more checks that this is a buffer from JSON?
1296
+ status = napi_is_array(env, arrayData, &isArray);
1297
+ CHECK_STATUS;
1298
+ if (isArray) {
1299
+ const napi_value fargs[] = { arrayData };
1300
+ status = napi_call_function(env, element, jsBufferFrom, 1, fargs, &element);
1301
+ CHECK_STATUS;
1302
+ } else {
1303
+ continue;
1304
+ }
1305
+ }
1306
+ status = napi_get_value_string_utf8(env, name, nullptr, 0, &strLen);
1307
+ CHECK_STATUS;
1308
+ typeName = (char*) malloc(sizeof(char) * (strLen + 1));
1309
+ status = napi_get_value_string_utf8(env, name, typeName, strLen + 1, &strLen);
1310
+ CHECK_STATUS;
1311
+
1312
+ fsdt = beam_lookup_enum(beam_frame_side_data_type->inverse, typeName);
1313
+ free(typeName);
1314
+ if (fsdt == BEAM_ENUM_UNKNOWN) {
1315
+ continue;
1316
+ } else {
1317
+ status = napi_get_buffer_info(env, element, &rawdata, &rawdataSize);
1318
+ CHECK_STATUS;
1319
+ fsd = av_frame_new_side_data(f->frame, (AVFrameSideDataType) fsdt, rawdataSize);
1320
+ if (fsd != nullptr) {
1321
+ memcpy(fsd->data, rawdata, rawdataSize);
1322
+ }
1323
+ }
1324
+ }
1325
+
1326
+ done:
1327
+ status = napi_get_undefined(env, &result);
1328
+ CHECK_STATUS;
1329
+ return result;
1330
+ }
1331
+
1332
+ napi_value getFrameFlags(napi_env env, napi_callback_info info) {
1333
+ napi_status status;
1334
+ napi_value result;
1335
+ frameData* f;
1336
+
1337
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1338
+ CHECK_STATUS;
1339
+
1340
+ status = napi_create_object(env, &result);
1341
+ CHECK_STATUS;
1342
+ status = beam_set_bool(env, result, "CORRUPT", (f->frame->flags & AV_FRAME_FLAG_CORRUPT) != 0);
1343
+ CHECK_STATUS;
1344
+ status = beam_set_bool(env, result, "DISCARD", (f->frame->flags & AV_FRAME_FLAG_DISCARD) != 0);
1345
+ CHECK_STATUS;
1346
+
1347
+ return result;
1348
+ }
1349
+
1350
+ napi_value setFrameFlags(napi_env env, napi_callback_info info) {
1351
+ napi_status status;
1352
+ napi_value result;
1353
+ napi_valuetype type;
1354
+ frameData* f;
1355
+ bool present, flag;
1356
+
1357
+ size_t argc = 1;
1358
+ napi_value args[1];
1359
+
1360
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1361
+ CHECK_STATUS;
1362
+ if (argc < 1) {
1363
+ NAPI_THROW_ERROR("Set frame flags must be provided with a value.");
1364
+ }
1365
+ status = napi_typeof(env, args[0], &type);
1366
+ CHECK_STATUS;
1367
+ if (type != napi_object) {
1368
+ NAPI_THROW_ERROR("Frame flags property must be set with an object of Boolean flags.");
1369
+ }
1370
+ status = beam_get_bool(env, args[0], "CORRUPT", &present, &flag);
1371
+ CHECK_STATUS;
1372
+ if (present) { f->frame->flags = (flag) ?
1373
+ f->frame->flags | AV_FRAME_FLAG_CORRUPT :
1374
+ f->frame->flags & ~AV_FRAME_FLAG_CORRUPT; }
1375
+ status = beam_get_bool(env, args[0], "DISCARD", &present, &flag);
1376
+ CHECK_STATUS;
1377
+ if (present) { f->frame->flags = (flag) ?
1378
+ f->frame->flags | AV_FRAME_FLAG_DISCARD :
1379
+ f->frame->flags & ~AV_FRAME_FLAG_DISCARD; }
1380
+
1381
+ status = napi_get_undefined(env, &result);
1382
+ CHECK_STATUS;
1383
+ return result;
1384
+ }
1385
+
1386
+ napi_value getFrameColorRange(napi_env env, napi_callback_info info) {
1387
+ napi_status status;
1388
+ napi_value result;
1389
+ frameData* f;
1390
+ const char* enumName;
1391
+
1392
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1393
+ CHECK_STATUS;
1394
+
1395
+ enumName = av_color_range_name(f->frame->color_range);
1396
+ status = napi_create_string_utf8(env,
1397
+ (enumName != nullptr) ? (char*) enumName : "unknown",
1398
+ NAPI_AUTO_LENGTH, &result);
1399
+ CHECK_STATUS;
1400
+ return result;
1401
+ }
1402
+
1403
+ napi_value setFrameColorRange(napi_env env, napi_callback_info info) {
1404
+ napi_status status;
1405
+ napi_value result;
1406
+ napi_valuetype type;
1407
+ frameData* f;
1408
+ char* name;
1409
+ size_t len;
1410
+ int ret;
1411
+
1412
+ size_t argc = 1;
1413
+ napi_value args[1];
1414
+
1415
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1416
+ CHECK_STATUS;
1417
+ if (argc < 1) {
1418
+ NAPI_THROW_ERROR("Set frame color_range must be provided with a value.");
1419
+ }
1420
+ status = napi_typeof(env, args[0], &type);
1421
+ CHECK_STATUS;
1422
+ if ((type == napi_null) || (type == napi_undefined)) {
1423
+ f->frame->color_range = AVCOL_RANGE_UNSPECIFIED;
1424
+ goto done;
1425
+ }
1426
+ if (type != napi_string) {
1427
+ NAPI_THROW_ERROR("Frame color_range property must be set with a string.");
1428
+ }
1429
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1430
+ CHECK_STATUS;
1431
+ name = (char*) malloc(sizeof(char) * (len + 1));
1432
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1433
+ CHECK_STATUS;
1434
+
1435
+ ret = av_color_range_from_name(name);
1436
+ free(name);
1437
+ if (ret < 0) {
1438
+ NAPI_THROW_ERROR("Color range was not recognised. Try one of 'tv' (MPEG), 'pc' (JPEG) or 'unknown'.");
1439
+ }
1440
+ f->frame->color_range = (AVColorRange) ret;
1441
+
1442
+ done:
1443
+ status = napi_get_undefined(env, &result);
1444
+ CHECK_STATUS;
1445
+ return result;
1446
+ }
1447
+
1448
+ napi_value getFrameColorPrimaries(napi_env env, napi_callback_info info) {
1449
+ napi_status status;
1450
+ napi_value result;
1451
+ frameData* f;
1452
+ const char* enumName;
1453
+
1454
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1455
+ CHECK_STATUS;
1456
+
1457
+ enumName = av_color_primaries_name(f->frame->color_primaries);
1458
+ status = napi_create_string_utf8(env,
1459
+ (enumName != nullptr) ? (char*) enumName : "unknown",
1460
+ NAPI_AUTO_LENGTH, &result);
1461
+ CHECK_STATUS;
1462
+ return result;
1463
+ }
1464
+
1465
+ napi_value setFrameColorPrimaries(napi_env env, napi_callback_info info) {
1466
+ napi_status status;
1467
+ napi_value result;
1468
+ napi_valuetype type;
1469
+ frameData* f;
1470
+ char* name;
1471
+ size_t len;
1472
+ int ret;
1473
+
1474
+ size_t argc = 1;
1475
+ napi_value args[1];
1476
+
1477
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1478
+ CHECK_STATUS;
1479
+ if (argc < 1) {
1480
+ NAPI_THROW_ERROR("Set frame color_primaries must be provided with a value.");
1481
+ }
1482
+ status = napi_typeof(env, args[0], &type);
1483
+ CHECK_STATUS;
1484
+ if ((type == napi_null) || (type == napi_undefined)) {
1485
+ f->frame->color_primaries = AVCOL_PRI_UNSPECIFIED;
1486
+ goto done;
1487
+ }
1488
+ if (type != napi_string) {
1489
+ NAPI_THROW_ERROR("Frame color_primaries property must be set with a string.");
1490
+ }
1491
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1492
+ CHECK_STATUS;
1493
+ name = (char*) malloc(sizeof(char) * (len + 1));
1494
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1495
+ CHECK_STATUS;
1496
+
1497
+ ret = av_color_primaries_from_name(name);
1498
+ free(name);
1499
+ if (ret < 0) {
1500
+ NAPI_THROW_ERROR("Color primaries not recognised. Did you mean e.g. 'bt709'?");
1501
+ }
1502
+ f->frame->color_primaries = (AVColorPrimaries) ret;
1503
+
1504
+ done:
1505
+ status = napi_get_undefined(env, &result);
1506
+ CHECK_STATUS;
1507
+ return result;
1508
+ }
1509
+
1510
+ napi_value getFrameColorTrc(napi_env env, napi_callback_info info) {
1511
+ napi_status status;
1512
+ napi_value result;
1513
+ frameData* f;
1514
+ const char* enumName;
1515
+
1516
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1517
+ CHECK_STATUS;
1518
+
1519
+ enumName = av_color_transfer_name(f->frame->color_trc);
1520
+ status = napi_create_string_utf8(env,
1521
+ (enumName != nullptr) ? (char*) enumName : "unknown",
1522
+ NAPI_AUTO_LENGTH, &result);
1523
+ CHECK_STATUS;
1524
+ return result;
1525
+ }
1526
+
1527
+ napi_value setFrameColorTrc(napi_env env, napi_callback_info info) {
1528
+ napi_status status;
1529
+ napi_value result;
1530
+ napi_valuetype type;
1531
+ frameData* f;
1532
+ char* name;
1533
+ size_t len;
1534
+ int ret;
1535
+
1536
+ size_t argc = 1;
1537
+ napi_value args[1];
1538
+
1539
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1540
+ CHECK_STATUS;
1541
+ if (argc < 1) {
1542
+ NAPI_THROW_ERROR("Set frame color_trc must be provided with a value.");
1543
+ }
1544
+ status = napi_typeof(env, args[0], &type);
1545
+ CHECK_STATUS;
1546
+ if ((type == napi_null) || (type == napi_undefined)) {
1547
+ f->frame->color_trc = AVCOL_TRC_UNSPECIFIED;
1548
+ goto done;
1549
+ }
1550
+ if (type != napi_string) {
1551
+ NAPI_THROW_ERROR("Frame color_trc property must be set with a string.");
1552
+ }
1553
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1554
+ CHECK_STATUS;
1555
+ name = (char*) malloc(sizeof(char) * (len + 1));
1556
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1557
+ CHECK_STATUS;
1558
+
1559
+ ret = av_color_transfer_from_name(name);
1560
+ free(name);
1561
+ if (ret < 0) {
1562
+ NAPI_THROW_ERROR("Color transfer characteristic not recognised. Did you mean e.g. 'bt709'?");
1563
+ }
1564
+ f->frame->color_trc = (AVColorTransferCharacteristic) ret;
1565
+
1566
+ done:
1567
+ status = napi_get_undefined(env, &result);
1568
+ CHECK_STATUS;
1569
+ return result;
1570
+ }
1571
+
1572
+ napi_value getFrameColorspace(napi_env env, napi_callback_info info) {
1573
+ napi_status status;
1574
+ napi_value result;
1575
+ frameData* f;
1576
+ const char* enumName;
1577
+
1578
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1579
+ CHECK_STATUS;
1580
+
1581
+ enumName = av_color_space_name(f->frame->colorspace);
1582
+ status = napi_create_string_utf8(env,
1583
+ (enumName != nullptr) ? (char*) enumName : "unknown",
1584
+ NAPI_AUTO_LENGTH, &result);
1585
+ CHECK_STATUS;
1586
+ return result;
1587
+ }
1588
+
1589
+ napi_value setFrameColorspace(napi_env env, napi_callback_info info) {
1590
+ napi_status status;
1591
+ napi_value result;
1592
+ napi_valuetype type;
1593
+ frameData* f;
1594
+ char* name;
1595
+ size_t len;
1596
+ int ret;
1597
+
1598
+ size_t argc = 1;
1599
+ napi_value args[1];
1600
+
1601
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1602
+ CHECK_STATUS;
1603
+ if (argc < 1) {
1604
+ NAPI_THROW_ERROR("Set frame colorspace must be provided with a value.");
1605
+ }
1606
+ status = napi_typeof(env, args[0], &type);
1607
+ CHECK_STATUS;
1608
+ if ((type == napi_null) || (type == napi_undefined)) {
1609
+ f->frame->colorspace = AVCOL_SPC_UNSPECIFIED;
1610
+ goto done;
1611
+ }
1612
+ if (type != napi_string) {
1613
+ NAPI_THROW_ERROR("Frame colorspace property must be set with a string.");
1614
+ }
1615
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1616
+ CHECK_STATUS;
1617
+ name = (char*) malloc(sizeof(char) * (len + 1));
1618
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1619
+ CHECK_STATUS;
1620
+
1621
+ ret = av_color_space_from_name(name);
1622
+ free(name);
1623
+ if (ret < 0) {
1624
+ NAPI_THROW_ERROR("Colorspace not recognised. Did you mean e.g. 'bt709'?");
1625
+ }
1626
+ f->frame->colorspace = (AVColorSpace) ret;
1627
+
1628
+ done:
1629
+ status = napi_get_undefined(env, &result);
1630
+ CHECK_STATUS;
1631
+ return result;
1632
+ }
1633
+
1634
+ napi_value getFrameChromaLoc(napi_env env, napi_callback_info info) {
1635
+ napi_status status;
1636
+ napi_value result;
1637
+ frameData* f;
1638
+ const char* enumName;
1639
+
1640
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1641
+ CHECK_STATUS;
1642
+
1643
+ enumName = av_chroma_location_name(f->frame->chroma_location);
1644
+ status = napi_create_string_utf8(env,
1645
+ (enumName != nullptr) ? (char*) enumName : "unspecified",
1646
+ NAPI_AUTO_LENGTH, &result);
1647
+ CHECK_STATUS;
1648
+ return result;
1649
+ }
1650
+
1651
+ napi_value setFrameChromaLoc(napi_env env, napi_callback_info info) {
1652
+ napi_status status;
1653
+ napi_value result;
1654
+ napi_valuetype type;
1655
+ frameData* f;
1656
+ char* name;
1657
+ size_t len;
1658
+ int ret;
1659
+
1660
+ size_t argc = 1;
1661
+ napi_value args[1];
1662
+
1663
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1664
+ CHECK_STATUS;
1665
+ if (argc < 1) {
1666
+ NAPI_THROW_ERROR("Set frame chroma_location must be provided with a value.");
1667
+ }
1668
+ status = napi_typeof(env, args[0], &type);
1669
+ CHECK_STATUS;
1670
+ if ((type == napi_null) || (type == napi_undefined)) {
1671
+ f->frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
1672
+ goto done;
1673
+ }
1674
+ if (type != napi_string) {
1675
+ NAPI_THROW_ERROR("Frame chroma_location property must be set with a string.");
1676
+ }
1677
+ status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);
1678
+ CHECK_STATUS;
1679
+ name = (char*) malloc(sizeof(char) * (len + 1));
1680
+ status = napi_get_value_string_utf8(env, args[0], name, len + 1, &len);
1681
+ CHECK_STATUS;
1682
+
1683
+ ret = av_chroma_location_from_name(name);
1684
+ free(name);
1685
+ if (ret < 0) {
1686
+ NAPI_THROW_ERROR("Chroma location not recognised. Did you mean e.g. 'left'?");
1687
+ }
1688
+ f->frame->chroma_location = (AVChromaLocation) ret;
1689
+
1690
+ done:
1691
+ status = napi_get_undefined(env, &result);
1692
+ CHECK_STATUS;
1693
+ return result;
1694
+ }
1695
+
1696
+ napi_value getFrameBestEffortTS(napi_env env, napi_callback_info info) {
1697
+ napi_status status;
1698
+ napi_value result;
1699
+ frameData* f;
1700
+
1701
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1702
+ CHECK_STATUS;
1703
+
1704
+ if (f->frame->best_effort_timestamp == AV_NOPTS_VALUE) {
1705
+ status = napi_get_null(env, &result);
1706
+ CHECK_STATUS;
1707
+ } else {
1708
+ status = napi_create_int64(env, f->frame->best_effort_timestamp, &result);
1709
+ CHECK_STATUS;
1710
+ }
1711
+
1712
+ return result;
1713
+ }
1714
+
1715
+ napi_value setFrameBestEffortTS(napi_env env, napi_callback_info info) {
1716
+ napi_status status;
1717
+ napi_value result;
1718
+ napi_valuetype type;
1719
+ frameData* f;
1720
+
1721
+ size_t argc = 1;
1722
+ napi_value args[1];
1723
+
1724
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1725
+ CHECK_STATUS;
1726
+ if (argc < 1) {
1727
+ NAPI_THROW_ERROR("Set frame best_effort_timestamp must be provided with a value.");
1728
+ }
1729
+ status = napi_typeof(env, args[0], &type);
1730
+ CHECK_STATUS;
1731
+ if ((type == napi_null) || (type == napi_undefined)) {
1732
+ f->frame->best_effort_timestamp = AV_NOPTS_VALUE;
1733
+ goto done;
1734
+ }
1735
+ if (type != napi_number) {
1736
+ NAPI_THROW_ERROR("Frame best_effort_timestamp property must be set with a number.");
1737
+ }
1738
+ status = napi_get_value_int64(env, args[0], &f->frame->best_effort_timestamp);
1739
+ CHECK_STATUS;
1740
+
1741
+ done:
1742
+ status = napi_get_undefined(env, &result);
1743
+ CHECK_STATUS;
1744
+ return result;
1745
+ }
1746
+
1747
+ napi_value getFramePktPos(napi_env env, napi_callback_info info) {
1748
+ napi_status status;
1749
+ napi_value result;
1750
+ frameData* f;
1751
+
1752
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1753
+ CHECK_STATUS;
1754
+
1755
+ status = napi_create_int64(env, f->frame->pkt_pos, &result);
1756
+ CHECK_STATUS;
1757
+ return result;
1758
+ }
1759
+
1760
+ napi_value setFramePktPos(napi_env env, napi_callback_info info) {
1761
+ napi_status status;
1762
+ napi_value result;
1763
+ napi_valuetype type;
1764
+ frameData* f;
1765
+
1766
+ size_t argc = 1;
1767
+ napi_value args[1];
1768
+
1769
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1770
+ CHECK_STATUS;
1771
+ if (argc < 1) {
1772
+ NAPI_THROW_ERROR("Set frame pkt_pos must be provided with a value.");
1773
+ }
1774
+ status = napi_typeof(env, args[0], &type);
1775
+ CHECK_STATUS;
1776
+ if (type != napi_number) {
1777
+ NAPI_THROW_ERROR("Frame pkt_pos property must be set with a number.");
1778
+ }
1779
+ status = napi_get_value_int64(env, args[0], &f->frame->pkt_pos);
1780
+ CHECK_STATUS;
1781
+
1782
+ status = napi_get_undefined(env, &result);
1783
+ CHECK_STATUS;
1784
+ return result;
1785
+ }
1786
+
1787
+ napi_value getFramePktDuration(napi_env env, napi_callback_info info) {
1788
+ napi_status status;
1789
+ napi_value result;
1790
+ frameData* f;
1791
+
1792
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1793
+ CHECK_STATUS;
1794
+
1795
+ status = napi_create_int64(env, f->frame->pkt_duration, &result);
1796
+ CHECK_STATUS;
1797
+ return result;
1798
+ }
1799
+
1800
+ napi_value setFramePktDuration(napi_env env, napi_callback_info info) {
1801
+ napi_status status;
1802
+ napi_value result;
1803
+ napi_valuetype type;
1804
+ frameData* f;
1805
+
1806
+ size_t argc = 1;
1807
+ napi_value args[1];
1808
+
1809
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1810
+ CHECK_STATUS;
1811
+ if (argc < 1) {
1812
+ NAPI_THROW_ERROR("Set frame pkt_duration must be provided with a value.");
1813
+ }
1814
+ status = napi_typeof(env, args[0], &type);
1815
+ CHECK_STATUS;
1816
+ if (type != napi_number) {
1817
+ NAPI_THROW_ERROR("Frame pkt_duration property must be set with a number.");
1818
+ }
1819
+ status = napi_get_value_int64(env, args[0], &f->frame->pkt_duration);
1820
+ CHECK_STATUS;
1821
+
1822
+ status = napi_get_undefined(env, &result);
1823
+ CHECK_STATUS;
1824
+ return result;
1825
+ }
1826
+
1827
+ napi_value getFrameMetadata(napi_env env, napi_callback_info info) {
1828
+ napi_status status;
1829
+ napi_value result;
1830
+ frameData* f;
1831
+ AVDictionaryEntry* tag = nullptr;
1832
+
1833
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1834
+ CHECK_STATUS;
1835
+
1836
+ if (f->frame->metadata != nullptr) {
1837
+ status = napi_create_object(env, &result);
1838
+ CHECK_STATUS;
1839
+ while((tag = av_dict_get(f->frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1840
+ status = beam_set_string_utf8(env, result, tag->key, tag->value);
1841
+ CHECK_STATUS;
1842
+ }
1843
+ } else {
1844
+ status = napi_get_null(env, &result);
1845
+ CHECK_STATUS;
1846
+ }
1847
+
1848
+ return result;
1849
+ }
1850
+
1851
+ napi_value setFrameMetadata(napi_env env, napi_callback_info info) {
1852
+ napi_status status;
1853
+ napi_value result;
1854
+ napi_valuetype type;
1855
+ frameData* f;
1856
+ AVDictionary* dict = nullptr;
1857
+
1858
+ size_t argc = 1;
1859
+ napi_value args[1];
1860
+
1861
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1862
+ CHECK_STATUS;
1863
+ if (argc < 1) {
1864
+ NAPI_THROW_ERROR("Set metadata must be provided with a value.");
1865
+ }
1866
+ status = napi_typeof(env, args[0], &type);
1867
+ CHECK_STATUS;
1868
+ if (type == napi_null || type == napi_undefined) {
1869
+ f->frame->metadata = nullptr;
1870
+ goto done;
1871
+ }
1872
+ if (type != napi_object) {
1873
+ NAPI_THROW_ERROR("Frame metadata property must be set with a object.");
1874
+ }
1875
+
1876
+ status = makeAVDictionary(env, args[0], &dict);
1877
+ CHECK_STATUS;
1878
+ f->frame->metadata = dict;
1879
+ done:
1880
+ status = napi_get_undefined(env, &result);
1881
+ CHECK_STATUS;
1882
+ return result;
1883
+ }
1884
+
1885
+ napi_value getFrameDecodeErrFlags(napi_env env, napi_callback_info info) {
1886
+ napi_status status;
1887
+ napi_value result;
1888
+ frameData* f;
1889
+
1890
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1891
+ CHECK_STATUS;
1892
+
1893
+ status = napi_create_object(env, &result);
1894
+ CHECK_STATUS;
1895
+
1896
+ status = beam_set_bool(env, result, "INVALID_BITSTREAM",
1897
+ (f->frame->decode_error_flags & FF_DECODE_ERROR_INVALID_BITSTREAM) != 0);
1898
+ CHECK_STATUS;
1899
+ status = beam_set_bool(env, result, "MISSING_REFERENCE",
1900
+ (f->frame->decode_error_flags & FF_DECODE_ERROR_MISSING_REFERENCE) != 0);
1901
+ CHECK_STATUS;
1902
+
1903
+ return result;
1904
+ }
1905
+
1906
+ napi_value setFrameDecodeErrFlags(napi_env env, napi_callback_info info) {
1907
+ napi_status status;
1908
+ napi_value result;
1909
+ napi_valuetype type;
1910
+ frameData* f;
1911
+ bool present, flag;
1912
+
1913
+ size_t argc = 1;
1914
+ napi_value args[1];
1915
+
1916
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1917
+ CHECK_STATUS;
1918
+ if (argc < 1) {
1919
+ NAPI_THROW_ERROR("Set decode_error_flags must be provided with a value.");
1920
+ }
1921
+ status = napi_typeof(env, args[0], &type);
1922
+ CHECK_STATUS;
1923
+ if (type != napi_object) {
1924
+ NAPI_THROW_ERROR("Frame decode_error_flags property must be set with a object of Boolean-valued properties.");
1925
+ }
1926
+
1927
+ status = beam_get_bool(env, args[0], "INVALID_BITSTREAM", &present, &flag);
1928
+ CHECK_STATUS;
1929
+ if (present) { f->frame->decode_error_flags = (flag) ?
1930
+ f->frame->decode_error_flags | FF_DECODE_ERROR_INVALID_BITSTREAM :
1931
+ f->frame->decode_error_flags & ~FF_DECODE_ERROR_INVALID_BITSTREAM; }
1932
+ status = beam_get_bool(env, args[0], "MISSING_REFERENCE", &present, &flag);
1933
+ CHECK_STATUS;
1934
+ if (present) { f->frame->decode_error_flags = (flag) ?
1935
+ f->frame->decode_error_flags | FF_DECODE_ERROR_INVALID_BITSTREAM :
1936
+ f->frame->decode_error_flags & ~FF_DECODE_ERROR_MISSING_REFERENCE; }
1937
+
1938
+ status = napi_get_undefined(env, &result);
1939
+ CHECK_STATUS;
1940
+ return result;
1941
+ }
1942
+
1943
+ napi_value getFrameChannels(napi_env env, napi_callback_info info) {
1944
+ napi_status status;
1945
+ napi_value result;
1946
+ frameData* f;
1947
+
1948
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1949
+ CHECK_STATUS;
1950
+
1951
+ status = napi_create_int32(env, f->frame->channels, &result);
1952
+ CHECK_STATUS;
1953
+ return result;
1954
+ }
1955
+
1956
+ napi_value setFrameChannels(napi_env env, napi_callback_info info) {
1957
+ napi_status status;
1958
+ napi_value result;
1959
+ napi_valuetype type;
1960
+ frameData* f;
1961
+
1962
+ size_t argc = 1;
1963
+ napi_value args[1];
1964
+
1965
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
1966
+ CHECK_STATUS;
1967
+ if (argc < 1) {
1968
+ NAPI_THROW_ERROR("Set frame channels must be provided with a value.");
1969
+ }
1970
+ status = napi_typeof(env, args[0], &type);
1971
+ CHECK_STATUS;
1972
+ if (type != napi_number) {
1973
+ NAPI_THROW_ERROR("Frame channels property must be set with a number.");
1974
+ }
1975
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->channels);
1976
+ CHECK_STATUS;
1977
+
1978
+ status = napi_get_undefined(env, &result);
1979
+ CHECK_STATUS;
1980
+ return result;
1981
+ }
1982
+
1983
+ napi_value getFramePktSize(napi_env env, napi_callback_info info) {
1984
+ napi_status status;
1985
+ napi_value result;
1986
+ frameData* f;
1987
+
1988
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
1989
+ CHECK_STATUS;
1990
+
1991
+ status = napi_create_int32(env, f->frame->pkt_size, &result);
1992
+ CHECK_STATUS;
1993
+ return result;
1994
+ }
1995
+
1996
+ napi_value setFramePktSize(napi_env env, napi_callback_info info) {
1997
+ napi_status status;
1998
+ napi_value result;
1999
+ napi_valuetype type;
2000
+ frameData* f;
2001
+
2002
+ size_t argc = 1;
2003
+ napi_value args[1];
2004
+
2005
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2006
+ CHECK_STATUS;
2007
+ if (argc < 1) {
2008
+ NAPI_THROW_ERROR("Set frame pkt_size must be provided with a value.");
2009
+ }
2010
+ status = napi_typeof(env, args[0], &type);
2011
+ CHECK_STATUS;
2012
+ if (type != napi_number) {
2013
+ NAPI_THROW_ERROR("Frame pkt_size property must be set with a number.");
2014
+ }
2015
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->pkt_size);
2016
+ CHECK_STATUS;
2017
+
2018
+ status = napi_get_undefined(env, &result);
2019
+ CHECK_STATUS;
2020
+ return result;
2021
+ }
2022
+
2023
+ napi_value getFrameHWFramesCtx(napi_env env, napi_callback_info info) {
2024
+ napi_status status;
2025
+ napi_value result;
2026
+ frameData* f;
2027
+
2028
+ size_t argc = 0;
2029
+ status = napi_get_cb_info(env, info, &argc, nullptr, nullptr, (void**) &f);
2030
+ CHECK_STATUS;
2031
+
2032
+ if (f->frame->hw_frames_ctx == nullptr) {
2033
+ status = napi_get_null(env, &result);
2034
+ CHECK_STATUS;
2035
+ } else {
2036
+ status = fromHWFramesContext(env, f->frame->hw_frames_ctx, &result);
2037
+ CHECK_STATUS;
2038
+ }
2039
+
2040
+ return result;
2041
+ }
2042
+
2043
+ napi_value setFrameHWFramesCtx(napi_env env, napi_callback_info info) {
2044
+ napi_status status;
2045
+ napi_value result, contextExt;
2046
+ napi_valuetype type;
2047
+ frameData* f;
2048
+ AVBufferRef* contextRef;
2049
+
2050
+ size_t argc = 1;
2051
+ napi_value args[1];
2052
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2053
+ CHECK_STATUS;
2054
+ if (argc < 1) {
2055
+ NAPI_THROW_ERROR("A value is required to set the hw_frames_context property.");
2056
+ }
2057
+ status = napi_typeof(env, args[0], &type);
2058
+ CHECK_STATUS;
2059
+ if (type != napi_object) {
2060
+ NAPI_THROW_ERROR("An object is required to set the hw_frames_context property.");
2061
+ }
2062
+ status = napi_get_named_property(env, args[0], "_framesContext", &contextExt);
2063
+ CHECK_STATUS;
2064
+ status = napi_get_value_external(env, contextExt, (void**) &contextRef);
2065
+ CHECK_STATUS;
2066
+ f->frame->hw_frames_ctx = av_buffer_ref(contextRef);
2067
+
2068
+ status = napi_get_undefined(env, &result);
2069
+ CHECK_STATUS;
2070
+ return result;
2071
+ }
2072
+
2073
+ napi_value getFrameCropTop(napi_env env, napi_callback_info info) {
2074
+ napi_status status;
2075
+ napi_value result;
2076
+ frameData* f;
2077
+
2078
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
2079
+ CHECK_STATUS;
2080
+
2081
+ status = napi_create_int32(env, f->frame->crop_top, &result);
2082
+ CHECK_STATUS;
2083
+ return result;
2084
+ }
2085
+
2086
+ napi_value setFrameCropTop(napi_env env, napi_callback_info info) {
2087
+ napi_status status;
2088
+ napi_value result;
2089
+ napi_valuetype type;
2090
+ frameData* f;
2091
+
2092
+ size_t argc = 1;
2093
+ napi_value args[1];
2094
+
2095
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2096
+ CHECK_STATUS;
2097
+ if (argc < 1) {
2098
+ NAPI_THROW_ERROR("Set frame crop_top must be provided with a value.");
2099
+ }
2100
+ status = napi_typeof(env, args[0], &type);
2101
+ CHECK_STATUS;
2102
+ if (type != napi_number) {
2103
+ NAPI_THROW_ERROR("Frame crop_top property must be set with a number.");
2104
+ }
2105
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->crop_top);
2106
+ CHECK_STATUS;
2107
+
2108
+ status = napi_get_undefined(env, &result);
2109
+ CHECK_STATUS;
2110
+ return result;
2111
+ }
2112
+
2113
+ napi_value getFrameCropBottom(napi_env env, napi_callback_info info) {
2114
+ napi_status status;
2115
+ napi_value result;
2116
+ frameData* f;
2117
+
2118
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
2119
+ CHECK_STATUS;
2120
+
2121
+ status = napi_create_int32(env, f->frame->crop_bottom, &result);
2122
+ CHECK_STATUS;
2123
+ return result;
2124
+ }
2125
+
2126
+ napi_value setFrameCropBottom(napi_env env, napi_callback_info info) {
2127
+ napi_status status;
2128
+ napi_value result;
2129
+ napi_valuetype type;
2130
+ frameData* f;
2131
+
2132
+ size_t argc = 1;
2133
+ napi_value args[1];
2134
+
2135
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2136
+ CHECK_STATUS;
2137
+ if (argc < 1) {
2138
+ NAPI_THROW_ERROR("Set frame crop_bottom must be provided with a value.");
2139
+ }
2140
+ status = napi_typeof(env, args[0], &type);
2141
+ CHECK_STATUS;
2142
+ if (type != napi_number) {
2143
+ NAPI_THROW_ERROR("Frame crop_bottom property must be set with a number.");
2144
+ }
2145
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->crop_bottom);
2146
+ CHECK_STATUS;
2147
+
2148
+ status = napi_get_undefined(env, &result);
2149
+ CHECK_STATUS;
2150
+ return result;
2151
+ }
2152
+
2153
+ napi_value getFrameCropLeft(napi_env env, napi_callback_info info) {
2154
+ napi_status status;
2155
+ napi_value result;
2156
+ frameData* f;
2157
+
2158
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
2159
+ CHECK_STATUS;
2160
+
2161
+ status = napi_create_int32(env, f->frame->crop_left, &result);
2162
+ CHECK_STATUS;
2163
+ return result;
2164
+ }
2165
+
2166
+ napi_value setFrameCropLeft(napi_env env, napi_callback_info info) {
2167
+ napi_status status;
2168
+ napi_value result;
2169
+ napi_valuetype type;
2170
+ frameData* f;
2171
+
2172
+ size_t argc = 1;
2173
+ napi_value args[1];
2174
+
2175
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2176
+ CHECK_STATUS;
2177
+ if (argc < 1) {
2178
+ NAPI_THROW_ERROR("Set frame crop_left must be provided with a value.");
2179
+ }
2180
+ status = napi_typeof(env, args[0], &type);
2181
+ CHECK_STATUS;
2182
+ if (type != napi_number) {
2183
+ NAPI_THROW_ERROR("Frame crop_left property must be set with a number.");
2184
+ }
2185
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->crop_left);
2186
+ CHECK_STATUS;
2187
+
2188
+ status = napi_get_undefined(env, &result);
2189
+ CHECK_STATUS;
2190
+ return result;
2191
+ }
2192
+
2193
+ napi_value getFrameCropRight(napi_env env, napi_callback_info info) {
2194
+ napi_status status;
2195
+ napi_value result;
2196
+ frameData* f;
2197
+
2198
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
2199
+ CHECK_STATUS;
2200
+
2201
+ status = napi_create_int32(env, f->frame->crop_right, &result);
2202
+ CHECK_STATUS;
2203
+ return result;
2204
+ }
2205
+
2206
+ napi_value setFrameCropRight(napi_env env, napi_callback_info info) {
2207
+ napi_status status;
2208
+ napi_value result;
2209
+ napi_valuetype type;
2210
+ frameData* f;
2211
+
2212
+ size_t argc = 1;
2213
+ napi_value args[1];
2214
+
2215
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, (void**) &f);
2216
+ CHECK_STATUS;
2217
+ if (argc < 1) {
2218
+ NAPI_THROW_ERROR("Set frame crop_right must be provided with a value.");
2219
+ }
2220
+ status = napi_typeof(env, args[0], &type);
2221
+ CHECK_STATUS;
2222
+ if (type != napi_number) {
2223
+ NAPI_THROW_ERROR("Frame crop_right property must be set with a number.");
2224
+ }
2225
+ status = napi_get_value_int32(env, args[0], (int32_t*) &f->frame->crop_right);
2226
+ CHECK_STATUS;
2227
+
2228
+ status = napi_get_undefined(env, &result);
2229
+ CHECK_STATUS;
2230
+ return result;
2231
+ }
2232
+
2233
+ napi_value makeFrame(napi_env env, napi_callback_info info) {
2234
+ napi_status status;
2235
+ napi_value result, global, jsObject, assign, jsJSON, jsParse;
2236
+ napi_valuetype type;
2237
+ bool isArray, deleted;
2238
+ frameData* f = new frameData;
2239
+ f->frame = av_frame_alloc();
2240
+ int align = 32; // av_cpu_max_align();
2241
+
2242
+ status = napi_get_global(env, &global);
2243
+ CHECK_STATUS;
2244
+
2245
+ size_t argc = 1;
2246
+ napi_value args[1];
2247
+
2248
+ status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
2249
+ CHECK_STATUS;
2250
+ if (argc > 1) {
2251
+ NAPI_THROW_ERROR("Frame may be created with zero or one options object argument.");
2252
+ }
2253
+ if (argc == 1) {
2254
+ status = napi_typeof(env, args[0], &type);
2255
+ CHECK_STATUS;
2256
+ if (type == napi_string) {
2257
+ status = napi_get_named_property(env, global, "JSON", &jsJSON);
2258
+ CHECK_STATUS;
2259
+ status = napi_get_named_property(env, jsJSON, "parse", &jsParse);
2260
+ CHECK_STATUS;
2261
+ const napi_value pargs[] = { args[0] };
2262
+ status = napi_call_function(env, args[0], jsParse, 1, pargs, &args[0]);
2263
+ CHECK_STATUS;
2264
+ status = napi_typeof(env, args[0], &type);
2265
+ CHECK_STATUS;
2266
+ if (type == napi_object) {
2267
+ status = beam_delete_named_property(env, args[0], "type", &deleted);
2268
+ CHECK_STATUS;
2269
+ status = beam_delete_named_property(env, args[0], "buf_sizes", &deleted);
2270
+ CHECK_STATUS;
2271
+ }
2272
+ }
2273
+ status = napi_is_array(env, args[0], &isArray);
2274
+ CHECK_STATUS;
2275
+ if (isArray || (type != napi_object)) {
2276
+ NAPI_THROW_ERROR("Cannot create a frame without an options object.");
2277
+ }
2278
+ }
2279
+
2280
+ status = fromAVFrame(env, f, &result);
2281
+ CHECK_STATUS;
2282
+
2283
+ if (argc == 1) {
2284
+ status = napi_get_named_property(env, global, "Object", &jsObject);
2285
+ CHECK_STATUS;
2286
+ status = napi_get_named_property(env, jsObject, "assign", &assign);
2287
+ CHECK_STATUS;
2288
+ const napi_value fargs[] = { result, args[0] };
2289
+ status = napi_call_function(env, result, assign, 2, fargs, &result);
2290
+ CHECK_STATUS;
2291
+ }
2292
+
2293
+ // MAINTAIN: needs to track FFmpeg
2294
+ if (f->frame->format >= 0) { // set up some useful line sizes.
2295
+ if (f->frame->width > 0 && f->frame->height > 0) { // video
2296
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((AVPixelFormat) f->frame->format);
2297
+ int ret, i;
2298
+ if (!desc)
2299
+ NAPI_THROW_ERROR("Could not determine frame descriptor details.");
2300
+
2301
+ if (!f->frame->linesize[0]) {
2302
+ for( i = 1 ; i <= align ; i += i) {
2303
+ ret = av_image_fill_linesizes(f->frame->linesize, (AVPixelFormat) f->frame->format,
2304
+ FFALIGN(f->frame->width, i));
2305
+ if (ret < 0)
2306
+ NAPI_THROW_ERROR("Failed to calculate line sizes.");
2307
+ if (!(f->frame->linesize[0] & (align-1)))
2308
+ break;
2309
+ }
2310
+ for ( i = 0 ; i < 4 && f->frame->linesize[i] ; i++) {
2311
+ f->frame->linesize[i] = FFALIGN(f->frame->linesize[i], align);
2312
+ }
2313
+ }
2314
+ }
2315
+ else if (f->frame->nb_samples > 0 && (f->frame->channel_layout || f->frame->channels > 0)) {
2316
+ int channels;
2317
+ // int planar = av_sample_fmt_is_planar((AVSampleFormat) f->frame->format);
2318
+ // int planes;
2319
+ int ret;
2320
+
2321
+ if (f->frame->channels < 2) { // Bump up from default of 1 if necessary
2322
+ f->frame->channels = av_get_channel_layout_nb_channels(f->frame->channel_layout);
2323
+ // printf("Calculated channel number %i\n", f->frame->channels);
2324
+ }
2325
+
2326
+ channels = f->frame->channels;
2327
+ // planes = planar ? channels : 1;
2328
+
2329
+ // TODO: is this needed? CHECK_CHANNELS_CONSISTENCY(f->frame);
2330
+ if (!f->frame->linesize[0]) {
2331
+ ret = av_samples_get_buffer_size(f->frame->linesize, channels,
2332
+ f->frame->nb_samples, (AVSampleFormat) f->frame->format,
2333
+ 0);
2334
+ if (ret < 0)
2335
+ NAPI_THROW_ERROR("Unable to determine frame line size.");
2336
+ }
2337
+ }
2338
+ } // Format provided
2339
+
2340
+ return result;
2341
+ }
2342
+
2343
+ napi_value alloc(napi_env env, napi_callback_info info) {
2344
+ napi_status status;
2345
+ napi_value result, extFrame;
2346
+ frameData* f;
2347
+
2348
+ size_t argc = 0;
2349
+ status = napi_get_cb_info(env, info, &argc, nullptr, &result, nullptr);
2350
+ CHECK_STATUS;
2351
+ status = napi_get_named_property(env, result, "_frame", &extFrame);
2352
+ CHECK_STATUS;
2353
+ status = napi_get_value_external(env, extFrame, (void**) &f);
2354
+ CHECK_STATUS;
2355
+
2356
+ if (f->frame->format >= 0) {
2357
+ if (f->frame->width > 0 && f->frame->height > 0) {
2358
+ for ( int x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
2359
+ if (f->frame->linesize[x] > 0) {
2360
+ int bufSize = f->frame->linesize[x] * f->frame->height;
2361
+ f->frame->buf[x] = av_buffer_alloc(
2362
+ (bufSize > AV_INPUT_BUFFER_MIN_SIZE) ? bufSize : AV_INPUT_BUFFER_MIN_SIZE);
2363
+ f->frame->data[x] = f->frame->buf[x]->data;
2364
+ } else {
2365
+ f->frame->data[x] = nullptr;
2366
+ f->frame->buf[x] = nullptr;
2367
+ }
2368
+ }
2369
+ }
2370
+ else if (f->frame->nb_samples > 0 && (f->frame->channel_layout || f->frame->channels > 0)) {
2371
+ int planar = av_sample_fmt_is_planar((AVSampleFormat) f->frame->format);
2372
+ if (planar) {
2373
+ for ( int x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
2374
+ if (x < f->frame->channels) {
2375
+ f->frame->buf[x] = av_buffer_alloc(f->frame->linesize[0]);
2376
+ f->frame->data[x] = f->frame->buf[x]->data;
2377
+ } else {
2378
+ f->frame->buf[x] = nullptr;
2379
+ f->frame->data[x] = nullptr;
2380
+ }
2381
+ }
2382
+ }
2383
+ else {
2384
+ f->frame->buf[0] = av_buffer_alloc(f->frame->linesize[0]);
2385
+ f->frame->data[0] = f->frame->buf[0]->data;
2386
+ for ( int x = 1 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
2387
+ f->frame->buf[x] = nullptr;
2388
+ f->frame->data[x] = nullptr;
2389
+ }
2390
+ }
2391
+ }
2392
+ else {
2393
+ NAPI_THROW_ERROR("Data size for frame could not be determined as not video or audio.");
2394
+ }
2395
+ } else {
2396
+ NAPI_THROW_ERROR("Format not set so data sizes for frame could not be computed.")
2397
+ }
2398
+
2399
+ return result;
2400
+ }
2401
+
2402
+ napi_value getFrameTypeName(napi_env env, napi_callback_info info) {
2403
+ napi_status status;
2404
+ napi_value result;
2405
+
2406
+ status = napi_create_string_utf8(env, "Frame", NAPI_AUTO_LENGTH, &result);
2407
+ CHECK_STATUS;
2408
+
2409
+ return result;
2410
+ }
2411
+
2412
+ napi_value getFrameBufSizes(napi_env env, napi_callback_info info) {
2413
+ napi_status status;
2414
+ napi_value array, element;
2415
+ frameData* f;
2416
+ uint32_t bufLengths;
2417
+
2418
+ status = napi_get_cb_info(env, info, 0, nullptr, nullptr, (void**) &f);
2419
+ CHECK_STATUS;
2420
+
2421
+ if (f->frame->buf[0] == nullptr) {
2422
+ status = napi_get_undefined(env, &array);
2423
+ CHECK_STATUS;
2424
+ } else {
2425
+ status = napi_create_array(env, &array);
2426
+ CHECK_STATUS;
2427
+ for ( int x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
2428
+ // printf("Buffer %i is %p\n", x, f->frame->buf[x]);
2429
+ if (f->frame->buf[x] == nullptr) continue;
2430
+ status = napi_create_int32(env, f->frame->buf[x]->size, &element);
2431
+ CHECK_STATUS;
2432
+ status = napi_set_element(env, array, x, element);
2433
+ CHECK_STATUS;
2434
+ }
2435
+ status = napi_get_array_length(env, array, &bufLengths);
2436
+ CHECK_STATUS;
2437
+ if (bufLengths == 0) {
2438
+ status = napi_get_undefined(env, &array);
2439
+ CHECK_STATUS;
2440
+ }
2441
+ }
2442
+
2443
+ CHECK_STATUS;
2444
+ return array;
2445
+ }
2446
+
2447
+ napi_value frameToJSON(napi_env env, napi_callback_info info) {
2448
+ napi_status status;
2449
+ napi_value result, base, sizeVal;
2450
+ frameData* f;
2451
+ int count = 0;
2452
+ bool hasBufSizes;
2453
+
2454
+ size_t argc = 0;
2455
+ status = napi_get_cb_info(env, info, &argc, nullptr, &base, (void**) &f);
2456
+ CHECK_STATUS;
2457
+
2458
+ status = napi_has_named_property(env, base, "buf_sizes", &hasBufSizes);
2459
+ CHECK_STATUS;
2460
+
2461
+ status = napi_create_object(env, &result);
2462
+ CHECK_STATUS;
2463
+
2464
+ napi_property_descriptor desc[45];
2465
+ DECLARE_GETTER3("type", true, getFrameTypeName, f);
2466
+ DECLARE_GETTER3("linesize", true, getFrameLinesize, f);
2467
+ DECLARE_GETTER3("width", f->frame->width > 0, getFrameWidth, f);
2468
+ DECLARE_GETTER3("height", f->frame->height > 0, getFrameHeight, f);
2469
+ DECLARE_GETTER3("nb_samples", f->frame->nb_samples > 0, getFrameNbSamples, f);
2470
+ DECLARE_GETTER3("format", f->frame->format > 0, getFrameFormat, f);
2471
+ DECLARE_GETTER3("key_frame", f->frame->key_frame != 1, getFrameKeyFrame, f);
2472
+ DECLARE_GETTER3("pict_type", f->frame->pict_type != AV_PICTURE_TYPE_NONE, getFramePictType, f);
2473
+ DECLARE_GETTER3("sample_aspect_ratio",
2474
+ (f->frame->sample_aspect_ratio.num != 0) || (f->frame->sample_aspect_ratio.den != 1),
2475
+ getFrameSampleAR, f);
2476
+ // 10
2477
+ DECLARE_GETTER3("pts", f->frame->pts != AV_NOPTS_VALUE, getFramePTS, f);
2478
+ DECLARE_GETTER3("pkt_dts", f->frame->pkt_dts != AV_NOPTS_VALUE, getFramePktDTS, f);
2479
+ DECLARE_GETTER3("coded_picture_number", f->frame->coded_picture_number > 0, getFrameCodedPicNum, f);
2480
+ DECLARE_GETTER3("display_picture_number", f->frame->display_picture_number > 0, getFrameDispPicNum, f);
2481
+ DECLARE_GETTER3("quality", f->frame->quality > 0, getFrameQuality, f);
2482
+ DECLARE_GETTER3("repeat_pict", f->frame->repeat_pict > 0, getFrameRepeatPict, f);
2483
+ DECLARE_GETTER3("interlaced_frame", f->frame->interlaced_frame != 0, getFrameInterlaced, f);
2484
+ DECLARE_GETTER3("top_field_first", f->frame->top_field_first != 0, getFrameTopFieldFirst, f);
2485
+ DECLARE_GETTER3("palette_has_changed", f->frame->palette_has_changed != 0, getFramePalHasChanged, f);
2486
+ DECLARE_GETTER3("reordered_opaque", f->frame->reordered_opaque != AV_NOPTS_VALUE, getFrameReorderOpq, f);
2487
+ // 20
2488
+ DECLARE_GETTER3("sample_rate", f->frame->sample_rate > 0, getFrameSampleRate, f);
2489
+ DECLARE_GETTER3("channel_layout", f->frame->channel_layout != 0, getFrameChanLayout, f);
2490
+ DECLARE_GETTER3("buf_sizes", f->frame->buf[0] != nullptr, getFrameBufSizes, f);
2491
+ DECLARE_GETTER3("side_data", f->frame->nb_side_data > 0, getFrameSideData, f);
2492
+ DECLARE_GETTER3("flags", f->frame->flags > 0, getFrameFlags, f);
2493
+ DECLARE_GETTER3("color_range", f->frame->color_range != AVCOL_RANGE_UNSPECIFIED, getFrameColorRange, f);
2494
+ DECLARE_GETTER3("color_primaries", f->frame->color_primaries != AVCOL_PRI_UNSPECIFIED, getFrameColorPrimaries, f);
2495
+ DECLARE_GETTER3("color_trc", f->frame->color_trc != AVCOL_TRC_UNSPECIFIED, getFrameColorTrc, f);
2496
+ DECLARE_GETTER3("colorspace", f->frame->colorspace != AVCOL_SPC_UNSPECIFIED, getFrameColorspace, f);
2497
+ DECLARE_GETTER3("chroma_location", f->frame->chroma_location != AVCHROMA_LOC_UNSPECIFIED, getFrameChromaLoc, f);
2498
+ // 30
2499
+ DECLARE_GETTER3("best_effort_timestamp", f->frame->best_effort_timestamp != AV_NOPTS_VALUE, getFrameBestEffortTS, f);
2500
+ DECLARE_GETTER3("pkt_pos", f->frame->pkt_pos >= 0, getFramePktPos, f);
2501
+ DECLARE_GETTER3("pkt_duration", f->frame->pkt_duration > 0, getFramePktDuration, f);
2502
+ DECLARE_GETTER3("metadata", f->frame->metadata != nullptr, getFrameMetadata, f);
2503
+ DECLARE_GETTER3("decode_error_flags", f->frame->decode_error_flags > 0, getFrameDecodeErrFlags, f);
2504
+ DECLARE_GETTER3("channels", f->frame->channels > 0, getFrameChannels, f);
2505
+ DECLARE_GETTER3("pkt_size", f->frame->pkt_size >= 0, getFramePktSize, f);
2506
+ DECLARE_GETTER3("crop_top", f->frame->crop_top > 0, getFrameCropTop, f);
2507
+ DECLARE_GETTER3("crop_bottom", f->frame->crop_bottom > 0, getFrameCropBottom, f);
2508
+ DECLARE_GETTER3("crop_left", f->frame->crop_left > 0, getFrameCropLeft, f);
2509
+ // 40
2510
+ DECLARE_GETTER3("crop_right", f->frame->crop_right > 0, getFrameCropRight, f);
2511
+
2512
+ if (hasBufSizes) {
2513
+ status = napi_get_named_property(env, base, "buf_sizes", &sizeVal);
2514
+ CHECK_STATUS;
2515
+ desc[count++] = { "buf_sizes", nullptr, nullptr, nullptr, nullptr, sizeVal,
2516
+ napi_enumerable, nullptr};
2517
+ }
2518
+
2519
+ status = napi_define_properties(env, result, count, desc);
2520
+ CHECK_STATUS;
2521
+
2522
+ return result;
2523
+ }
2524
+
2525
+ napi_status fromAVFrame(napi_env env, frameData* f, napi_value* result) {
2526
+ napi_status status;
2527
+ napi_value jsFrame, extFrame, undef;
2528
+ int64_t externalMemory;
2529
+
2530
+ status = napi_create_object(env, &jsFrame);
2531
+ PASS_STATUS;
2532
+ status = napi_get_undefined(env, &undef);
2533
+ PASS_STATUS;
2534
+ status = napi_create_external(env, f, frameDataFinalizer, nullptr, &extFrame);
2535
+ PASS_STATUS;
2536
+
2537
+ // TODO frame side data
2538
+ napi_property_descriptor desc[] = {
2539
+ { "type", nullptr, nullptr, getFrameTypeName, nop, nullptr, napi_enumerable, nullptr },
2540
+ { "linesize", nullptr, nullptr, getFrameLinesize, setFrameLinesize, nullptr,
2541
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2542
+ { "width", nullptr, nullptr, getFrameWidth, setFrameWidth, nullptr,
2543
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2544
+ { "height", nullptr, nullptr, getFrameHeight, setFrameHeight, nullptr,
2545
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2546
+ { "nb_samples", nullptr, nullptr, getFrameNbSamples, setFrameNbSamples, nullptr,
2547
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2548
+ { "format", nullptr, nullptr, getFrameFormat, setFrameFormat, nullptr,
2549
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2550
+ { "key_frame", nullptr, nullptr, getFrameKeyFrame, setFrameKeyFrame, nullptr,
2551
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2552
+ { "pict_type", nullptr, nullptr, getFramePictType, setFramePictType, nullptr,
2553
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2554
+ { "sample_aspect_ratio", nullptr, nullptr, getFrameSampleAR, setFrameSampleAR, nullptr,
2555
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2556
+ // 10
2557
+ { "pts", nullptr, nullptr, getFramePTS, setFramePTS, nullptr,
2558
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2559
+ { "pkt_dts", nullptr, nullptr, getFramePktDTS, setFramePktDTS, nullptr,
2560
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2561
+ { "coded_picture_number", nullptr, nullptr, getFrameCodedPicNum, setFrameCodedPicNum, nullptr,
2562
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2563
+ { "display_picture_number", nullptr, nullptr, getFrameDispPicNum, setFrameDispPicNum, nullptr,
2564
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2565
+ { "quality", nullptr, nullptr, getFrameQuality, setFrameQuality, nullptr,
2566
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2567
+ { "repeat_pict", nullptr, nullptr, getFrameRepeatPict, setFrameRepeatPict, nullptr,
2568
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2569
+ { "interlaced_frame", nullptr, nullptr, getFrameInterlaced, setFrameInterlaced, nullptr,
2570
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2571
+ { "top_field_first", nullptr, nullptr, getFrameTopFieldFirst, setFrameTopFieldFirst, nullptr,
2572
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2573
+ { "palette_has_changed", nullptr, nullptr, getFramePalHasChanged, setFramePalHasChanged, nullptr,
2574
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2575
+ { "reordered_opaque", nullptr, nullptr, getFrameReorderOpq, setFrameReorderOpq, nullptr,
2576
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2577
+ // 20
2578
+ { "sample_rate", nullptr, nullptr, getFrameSampleRate, setFrameSampleRate, nullptr,
2579
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2580
+ { "channel_layout", nullptr, nullptr, getFrameChanLayout, setFrameChanLayout, nullptr,
2581
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2582
+ { "data", nullptr, nullptr, getFrameData, setFrameData, nullptr,
2583
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2584
+ { "side_data", nullptr, nullptr, getFrameSideData, setFrameSideData, nullptr,
2585
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2586
+ { "flags", nullptr, nullptr, getFrameFlags, setFrameFlags, nullptr,
2587
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2588
+ { "color_range", nullptr, nullptr, getFrameColorRange, setFrameColorRange, nullptr,
2589
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2590
+ { "color_primaries", nullptr, nullptr, getFrameColorPrimaries, setFrameColorPrimaries, nullptr,
2591
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2592
+ { "color_trc", nullptr, nullptr, getFrameColorTrc, setFrameColorTrc, nullptr,
2593
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2594
+ { "colorspace", nullptr, nullptr, getFrameColorspace, setFrameColorspace, nullptr,
2595
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2596
+ { "chroma_location", nullptr, nullptr, getFrameChromaLoc, setFrameChromaLoc, nullptr,
2597
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2598
+ // 30
2599
+ { "best_effort_timestamp", nullptr, nullptr, getFrameBestEffortTS, setFrameBestEffortTS, nullptr,
2600
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2601
+ { "pkt_pos", nullptr, nullptr, getFramePktPos, setFramePktPos, nullptr,
2602
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2603
+ { "pkt_duration", nullptr, nullptr, getFramePktDuration, setFramePktDuration, nullptr,
2604
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2605
+ { "metadata", nullptr, nullptr, getFrameMetadata, setFrameMetadata, nullptr,
2606
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2607
+ { "decode_error_flags", nullptr, nullptr, getFrameDecodeErrFlags, setFrameDecodeErrFlags, nullptr,
2608
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2609
+ { "channels", nullptr, nullptr, getFrameChannels, setFrameChannels, nullptr,
2610
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2611
+ { "pkt_size", nullptr, nullptr, getFramePktSize, setFramePktSize, nullptr,
2612
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2613
+ { "hw_frames_ctx", nullptr, nullptr, getFrameHWFramesCtx, setFrameHWFramesCtx, nullptr,
2614
+ (napi_property_attributes) (napi_writable | napi_enumerable), f},
2615
+ { "crop_top", nullptr, nullptr, getFrameCropTop, setFrameCropTop, nullptr,
2616
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2617
+ { "crop_bottom", nullptr, nullptr, getFrameCropBottom, setFrameCropBottom, nullptr,
2618
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2619
+ // 40
2620
+ { "crop_left", nullptr, nullptr, getFrameCropLeft, setFrameCropLeft, nullptr,
2621
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2622
+ { "crop_right", nullptr, nullptr, getFrameCropRight, setFrameCropRight, nullptr,
2623
+ (napi_property_attributes) (napi_writable | napi_enumerable), f },
2624
+ { "alloc", nullptr, alloc, nullptr, nullptr, nullptr, napi_enumerable, nullptr },
2625
+ { "toJSON", nullptr, frameToJSON, nullptr, nullptr, nullptr, napi_default, f },
2626
+ { "_frame", nullptr, nullptr, nullptr, nullptr, extFrame, napi_default, nullptr }
2627
+ };
2628
+ status = napi_define_properties(env, jsFrame, 44, desc);
2629
+ PASS_STATUS;
2630
+
2631
+ for ( int x = 0 ; x < AV_NUM_DATA_POINTERS ; x++ ) {
2632
+ if (f->frame->buf[x] == nullptr) break;
2633
+ f->extSize += f->frame->buf[x]->size;
2634
+ }
2635
+ status = napi_adjust_external_memory(env, f->extSize, &externalMemory);
2636
+ PASS_STATUS;
2637
+
2638
+ *result = jsFrame;
2639
+ return napi_ok;
2640
+ }
2641
+
2642
+ void frameFinalizer(napi_env env, void* data, void* hint) {
2643
+ AVFrame* frame = (AVFrame*) data;
2644
+ av_frame_free(&frame);
2645
+ // printf("Freeing a frame.\n");
2646
+ }
2647
+
2648
+ void frameDataFinalizer(napi_env env, void* data, void* hint) {
2649
+ napi_status status;
2650
+ int64_t externalMemory;
2651
+ frameData* f = (frameData*) data;
2652
+ // printf("Freeing frame data for pts = %i\n", f->frame->pts);
2653
+ status = napi_adjust_external_memory(env, -f->extSize, &externalMemory);
2654
+ if (status != napi_ok) {
2655
+ printf("DEBUG: Failed to adjust external memory downwards on frame delete.\n");
2656
+ }
2657
+ for ( auto it = f->dataRefs.cbegin() ; it != f->dataRefs.cend() ; it++) {
2658
+ // printf("Freeing data reference for frame with pts = %i\n", f->frame->pts);
2659
+ status = napi_delete_reference(env, *it);
2660
+ if (status != napi_ok) {
2661
+ printf("DEBUG: Failed to delete data reference for frame data, status %i.\n", status);
2662
+ }
2663
+ }
2664
+ delete f;
2665
+ }
2666
+
2667
+ void frameBufferFinalizer(napi_env env, void* data, void* hint) {
2668
+ AVBufferRef* hintRef = (AVBufferRef*) hint;
2669
+ av_buffer_unref(&hintRef);
2670
+ // printf("Unreffing an AV buffer.\n");
2671
+ }
2672
+
2673
+ void frameBufferFree(void* opaque, uint8_t* data) {
2674
+ napi_status status;
2675
+ avBufRef* avr = (avBufRef*) opaque;
2676
+ // printf("AV freeing a frame buffer. pts = %i\n", avr->pts);
2677
+ status = napi_delete_reference(avr->env, (napi_ref) avr->ref);
2678
+ if (status != napi_ok)
2679
+ printf("DEBUG: Failed to delete buffer reference associated with an AVBufferRef.");
2680
+ delete avr;
2681
+ }