bare-ffmpeg 1.0.0-3 → 1.0.0-31

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 (51) hide show
  1. package/CMakeLists.txt +10 -3
  2. package/README.md +1811 -0
  3. package/binding.cc +4638 -0
  4. package/cmake/ports/ffmpeg/port.cmake +514 -0
  5. package/cmake/ports/opus/patches/01-windows-clang.patch +52 -0
  6. package/cmake/ports/opus/port.cmake +42 -0
  7. package/cmake/ports/svt-av1/port.cmake +42 -0
  8. package/cmake/ports/x264/patches/01-windows-clang.patch +33 -0
  9. package/cmake/ports/x264/port.cmake +157 -0
  10. package/index.js +22 -4
  11. package/lib/audio-fifo.js +47 -0
  12. package/lib/channel-layout.js +35 -0
  13. package/lib/codec-context.js +210 -16
  14. package/lib/codec-parameters.js +242 -8
  15. package/lib/codec.js +19 -1
  16. package/lib/constants.js +245 -9
  17. package/lib/dictionary.js +28 -15
  18. package/lib/errors.js +38 -0
  19. package/lib/filter-context.js +7 -0
  20. package/lib/filter-graph.js +47 -0
  21. package/lib/filter-inout.js +55 -0
  22. package/lib/filter.js +7 -0
  23. package/lib/format-context.js +72 -31
  24. package/lib/frame.js +88 -22
  25. package/lib/image.js +22 -0
  26. package/lib/input-format.js +36 -4
  27. package/lib/io-context.js +36 -6
  28. package/lib/log.js +16 -0
  29. package/lib/output-format.js +33 -2
  30. package/lib/packet.js +153 -12
  31. package/lib/rational.js +49 -1
  32. package/lib/resampler.js +63 -0
  33. package/lib/samples.js +96 -0
  34. package/lib/scaler.js +8 -7
  35. package/lib/stream.js +58 -14
  36. package/package.json +9 -4
  37. package/prebuilds/android-arm/bare-ffmpeg.bare +0 -0
  38. package/prebuilds/android-arm64/bare-ffmpeg.bare +0 -0
  39. package/prebuilds/android-ia32/bare-ffmpeg.bare +0 -0
  40. package/prebuilds/android-x64/bare-ffmpeg.bare +0 -0
  41. package/prebuilds/darwin-arm64/bare-ffmpeg.bare +0 -0
  42. package/prebuilds/darwin-x64/bare-ffmpeg.bare +0 -0
  43. package/prebuilds/ios-arm64/bare-ffmpeg.bare +0 -0
  44. package/prebuilds/ios-arm64-simulator/bare-ffmpeg.bare +0 -0
  45. package/prebuilds/ios-x64-simulator/bare-ffmpeg.bare +0 -0
  46. package/prebuilds/linux-arm64/bare-ffmpeg.bare +0 -0
  47. package/prebuilds/linux-x64/bare-ffmpeg.bare +0 -0
  48. package/prebuilds/win32-arm64/bare-ffmpeg.bare +0 -0
  49. package/prebuilds/win32-x64/bare-ffmpeg.bare +0 -0
  50. package/binding.c +0 -2203
  51. package/lib/reference-counted.js +0 -39
package/binding.cc ADDED
@@ -0,0 +1,4638 @@
1
+ #include <cstdio>
2
+ #include <optional>
3
+ #include <tuple>
4
+ #include <unordered_set>
5
+ #include <vector>
6
+
7
+ #include <assert.h>
8
+ #include <bare.h>
9
+ #include <js.h>
10
+ #include <jstl.h>
11
+ #include <stddef.h>
12
+ #include <stdint.h>
13
+ #include <string.h>
14
+
15
+ extern "C" {
16
+ #include <libavcodec/avcodec.h>
17
+ #include <libavcodec/codec.h>
18
+ #include <libavcodec/codec_id.h>
19
+ #include <libavcodec/codec_par.h>
20
+ #include <libavcodec/packet.h>
21
+ #include <libavdevice/avdevice.h>
22
+ #include <libavfilter/avfilter.h>
23
+ #include <libavfilter/buffersink.h>
24
+ #include <libavfilter/buffersrc.h>
25
+ #include <libavformat/avformat.h>
26
+ #include <libavformat/avio.h>
27
+ #include <libavutil/audio_fifo.h>
28
+ #include <libavutil/channel_layout.h>
29
+ #include <libavutil/dict.h>
30
+ #include <libavutil/error.h>
31
+ #include <libavutil/frame.h>
32
+ #include <libavutil/imgutils.h>
33
+ #include <libavutil/log.h>
34
+ #include <libavutil/mathematics.h>
35
+ #include <libavutil/mem.h>
36
+ #include <libavutil/opt.h>
37
+ #include <libavutil/pixfmt.h>
38
+ #include <libavutil/rational.h>
39
+ #include <libavutil/samplefmt.h>
40
+ #include <libswresample/swresample.h>
41
+ #include <libswscale/swscale.h>
42
+ }
43
+
44
+ using bare_ffmpeg_io_context_write_cb_t = js_function_t<void, js_arraybuffer_t>;
45
+ using bare_ffmpeg_io_context_read_cb_t = js_function_t<int32_t, js_arraybuffer_t, int32_t>;
46
+ using bare_ffmpeg_io_context_seek_cb_t = js_function_t<int64_t, int64_t, int>;
47
+ using bare_ffmpeg_codec_context_get_format_cb_t = js_function_t<int, std::vector<int>>;
48
+
49
+ typedef struct {
50
+ AVIOContext *handle;
51
+
52
+ js_env_t *env;
53
+
54
+ js_persistent_t<bare_ffmpeg_io_context_write_cb_t> on_write;
55
+ js_persistent_t<bare_ffmpeg_io_context_read_cb_t> on_read;
56
+ js_persistent_t<bare_ffmpeg_io_context_seek_cb_t> on_seek;
57
+ } bare_ffmpeg_io_context_t;
58
+
59
+ typedef struct {
60
+ const AVOutputFormat *handle;
61
+ } bare_ffmpeg_output_format_t;
62
+
63
+ typedef struct {
64
+ const AVInputFormat *handle;
65
+ } bare_ffmpeg_input_format_t;
66
+
67
+ typedef struct {
68
+ AVFormatContext *handle;
69
+ } bare_ffmpeg_format_context_t;
70
+
71
+ typedef struct {
72
+ AVStream *handle;
73
+ } bare_ffmpeg_stream_t;
74
+
75
+ typedef struct {
76
+ const AVCodec *handle;
77
+ } bare_ffmpeg_codec_t;
78
+
79
+ typedef struct {
80
+ AVCodecParameters *handle;
81
+ } bare_ffmpeg_codec_parameters_t;
82
+
83
+ typedef struct {
84
+ AVCodecContext *handle;
85
+ js_env_t *env;
86
+ js_persistent_t<bare_ffmpeg_codec_context_get_format_cb_t> get_format_cb;
87
+ } bare_ffmpeg_codec_context_t;
88
+
89
+ typedef struct {
90
+ AVChannelLayout handle;
91
+ } bare_ffmpeg_channel_layout_t;
92
+
93
+ typedef struct {
94
+ AVFrame *handle;
95
+ } bare_ffmpeg_frame_t;
96
+
97
+ typedef struct {
98
+ AVPacket *handle;
99
+ } bare_ffmpeg_packet_t;
100
+
101
+ typedef struct {
102
+ struct SwsContext *handle;
103
+ } bare_ffmpeg_scaler_t;
104
+
105
+ typedef struct {
106
+ struct AVDictionary *handle;
107
+ } bare_ffmpeg_dictionary_t;
108
+
109
+ typedef struct {
110
+ struct SwrContext *handle;
111
+ } bare_ffmpeg_resampler_t;
112
+
113
+ typedef struct {
114
+ AVAudioFifo *handle;
115
+ } bare_ffmpeg_audio_fifo_t;
116
+
117
+ typedef struct {
118
+ AVPacketSideData *handle;
119
+ } bare_ffmpeg_side_data_t;
120
+
121
+ typedef struct {
122
+ const AVFilter *handle;
123
+ } bare_ffmpeg_filter_t;
124
+
125
+ typedef struct {
126
+ AVFilterContext *handle;
127
+ } bare_ffmpeg_filter_context_t;
128
+
129
+ typedef struct {
130
+ AVFilterGraph *handle;
131
+ } bare_ffmpeg_filter_graph_t;
132
+
133
+ typedef struct {
134
+ AVFilterInOut *handle;
135
+ } bare_ffmpeg_filter_inout_t;
136
+
137
+ static uv_once_t bare_ffmpeg__init_guard = UV_ONCE_INIT;
138
+
139
+ static void
140
+ bare_ffmpeg__on_init(void) {
141
+ av_log_set_level(AV_LOG_ERROR);
142
+
143
+ avdevice_register_all();
144
+ }
145
+
146
+ static int32_t
147
+ bare_ffmpeg_log_get_level(js_env_t *) {
148
+ return av_log_get_level();
149
+ }
150
+
151
+ static void
152
+ bare_ffmpeg_log_set_level(js_env_t *, int32_t level) {
153
+ av_log_set_level(level);
154
+ }
155
+
156
+ static int
157
+ bare_ffmpeg__on_io_context_write(void *opaque, const uint8_t *buf, int len) {
158
+ int err;
159
+
160
+ auto context = static_cast<bare_ffmpeg_io_context_t *>(opaque);
161
+
162
+ auto env = context->env;
163
+
164
+ bare_ffmpeg_io_context_write_cb_t callback;
165
+ err = js_get_reference_value(env, context->on_write, callback);
166
+ assert(err == 0);
167
+
168
+ js_arraybuffer_t data;
169
+ err = js_create_arraybuffer(env, buf, static_cast<size_t>(len), data);
170
+ assert(err == 0);
171
+
172
+ err = js_call_function(env, callback, data);
173
+
174
+ if (err < 0) return AVERROR(EIO);
175
+
176
+ return 0;
177
+ }
178
+
179
+ static int
180
+ bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
181
+ int err;
182
+
183
+ auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
184
+
185
+ auto env = context->env;
186
+
187
+ bare_ffmpeg_io_context_read_cb_t callback;
188
+ err = js_get_reference_value(env, context->on_read, callback);
189
+ assert(err == 0);
190
+
191
+ js_arraybuffer_t arraybuffer;
192
+ err = js_create_external_arraybuffer(env, buf, static_cast<size_t>(len), arraybuffer);
193
+ assert(err == 0);
194
+
195
+ int32_t result;
196
+ int call_status = js_call_function<js_type_options_t{}, int32_t, js_arraybuffer_t, int32_t>(
197
+ env, callback, arraybuffer, len, result
198
+ );
199
+
200
+ err = js_detach_arraybuffer(env, arraybuffer);
201
+ assert(err == 0);
202
+
203
+ if (call_status < 0) return AVERROR(EIO);
204
+
205
+ if (result == 0) return AVERROR_EOF;
206
+
207
+ return result;
208
+ }
209
+
210
+ static int64_t
211
+ bare_ffmpeg__on_io_context_seek(void *opaque, int64_t offset, int whence) {
212
+ auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
213
+ auto env = context->env;
214
+
215
+ int64_t result;
216
+ bare_ffmpeg_io_context_seek_cb_t callback;
217
+ int err = js_get_reference_value(env, context->on_seek, callback);
218
+ assert(err == 0);
219
+
220
+ err = js_call_function<
221
+ js_type_options_t{},
222
+ int64_t,
223
+ int64_t,
224
+ int>(
225
+ env, callback, offset, whence, result
226
+ );
227
+ if (err < 0) return AVERROR(EIO); // read-error
228
+
229
+ if (result == -1) {
230
+ return AVERROR(ENOSYS); // seek-op not supported by IO
231
+ }
232
+
233
+ return result;
234
+ }
235
+
236
+ static js_arraybuffer_t
237
+ bare_ffmpeg_io_context_init(
238
+ js_env_t *env,
239
+ js_receiver_t,
240
+ std::optional<js_arraybuffer_span_t> data,
241
+ uint64_t offset,
242
+ uint64_t len,
243
+ std::optional<bare_ffmpeg_io_context_write_cb_t> on_write,
244
+ std::optional<bare_ffmpeg_io_context_read_cb_t> on_read,
245
+ std::optional<bare_ffmpeg_io_context_seek_cb_t> on_seek
246
+ ) {
247
+ int err;
248
+
249
+ js_arraybuffer_t handle;
250
+
251
+ bare_ffmpeg_io_context_t *context;
252
+ err = js_create_arraybuffer(env, context, handle);
253
+ assert(err == 0);
254
+
255
+ context->env = env;
256
+
257
+ int writable = 0;
258
+
259
+ if (on_write) {
260
+ writable = 1;
261
+
262
+ err = js_create_reference(env, *on_write, context->on_write);
263
+ assert(err == 0);
264
+ }
265
+
266
+ if (on_read) {
267
+ err = js_create_reference(env, *on_read, context->on_read);
268
+ assert(err == 0);
269
+ }
270
+
271
+ if (on_seek) {
272
+ err = js_create_reference(env, *on_seek, context->on_seek);
273
+ assert(err == 0);
274
+ }
275
+
276
+ auto size = static_cast<size_t>(len);
277
+
278
+ auto io = reinterpret_cast<uint8_t *>(av_malloc(size));
279
+
280
+ if (data) {
281
+ memcpy(io, &data.value()[static_cast<size_t>(offset)], size);
282
+ }
283
+
284
+ context->handle = avio_alloc_context(
285
+ io,
286
+ static_cast<int>(len),
287
+ writable,
288
+ context,
289
+ on_read ? bare_ffmpeg__on_io_context_read : nullptr,
290
+ on_write ? bare_ffmpeg__on_io_context_write : nullptr,
291
+ on_seek ? bare_ffmpeg__on_io_context_seek : nullptr
292
+ );
293
+
294
+ if (!on_seek) {
295
+ context->handle->seekable = 0;
296
+ }
297
+
298
+ return handle;
299
+ }
300
+
301
+ static void
302
+ bare_ffmpeg_io_context_destroy(
303
+ js_env_t *env,
304
+ js_receiver_t,
305
+ js_arraybuffer_span_of_t<bare_ffmpeg_io_context_t, 1> context
306
+ ) {
307
+ av_free(context->handle->buffer);
308
+
309
+ avio_context_free(&context->handle);
310
+
311
+ context->on_write.reset();
312
+ context->on_read.reset();
313
+ context->on_seek.reset();
314
+ }
315
+
316
+ static js_arraybuffer_t
317
+ bare_ffmpeg_output_format_init(js_env_t *env, js_receiver_t, std::string name) {
318
+ int err;
319
+
320
+ const AVOutputFormat *format = av_guess_format(name.c_str(), NULL, NULL);
321
+
322
+ if (format == NULL) {
323
+ err = js_throw_errorf(env, NULL, "No output format found for name '%s'", name.c_str());
324
+ assert(err == 0);
325
+
326
+ throw js_pending_exception;
327
+ }
328
+
329
+ js_arraybuffer_t handle;
330
+
331
+ bare_ffmpeg_output_format_t *context;
332
+ err = js_create_arraybuffer(env, context, handle);
333
+ assert(err == 0);
334
+
335
+ context->handle = format;
336
+
337
+ return handle;
338
+ }
339
+
340
+ static int32_t
341
+ bare_ffmpeg_output_format_get_flags(
342
+ js_env_t *,
343
+ js_receiver_t,
344
+ js_arraybuffer_span_of_t<bare_ffmpeg_output_format_t, 1> format
345
+ ) {
346
+ return format->handle->flags;
347
+ }
348
+
349
+ static js_arraybuffer_t
350
+ bare_ffmpeg_input_format_init(js_env_t *env, js_receiver_t, std::string name) {
351
+ int err;
352
+
353
+ const AVInputFormat *format = av_find_input_format(name.c_str());
354
+
355
+ if (format == NULL) {
356
+ err = js_throw_errorf(env, NULL, "No input format found for name '%s'", name.c_str());
357
+ assert(err == 0);
358
+
359
+ throw js_pending_exception;
360
+ }
361
+
362
+ js_arraybuffer_t handle;
363
+
364
+ bare_ffmpeg_input_format_t *context;
365
+ err = js_create_arraybuffer(env, context, handle);
366
+ assert(err == 0);
367
+
368
+ context->handle = format;
369
+
370
+ return handle;
371
+ }
372
+
373
+ static int32_t
374
+ bare_ffmpeg_input_format_get_flags(
375
+ js_env_t *,
376
+ js_receiver_t,
377
+ js_arraybuffer_span_of_t<bare_ffmpeg_input_format_t, 1> format
378
+ ) {
379
+ return format->handle->flags;
380
+ }
381
+
382
+ static std::string
383
+ bare_ffmpeg_input_format_get_extensions(
384
+ js_env_t *env,
385
+ js_receiver_t,
386
+ js_arraybuffer_span_of_t<bare_ffmpeg_input_format_t, 1> context
387
+ ) {
388
+ return context->handle->extensions;
389
+ }
390
+
391
+ static std::string
392
+ bare_ffmpeg_input_format_get_mime_type(
393
+ js_env_t *env,
394
+ js_receiver_t,
395
+ js_arraybuffer_span_of_t<bare_ffmpeg_input_format_t, 1> context
396
+ ) {
397
+ return context->handle->mime_type;
398
+ }
399
+
400
+ static std::string
401
+ bare_ffmpeg_input_format_get_name(
402
+ js_env_t *env,
403
+ js_receiver_t,
404
+ js_arraybuffer_span_of_t<bare_ffmpeg_input_format_t, 1> context
405
+ ) {
406
+ return context->handle->name;
407
+ }
408
+
409
+ static js_arraybuffer_t
410
+ bare_ffmpeg_format_context_open_input_with_io(
411
+ js_env_t *env,
412
+ js_receiver_t,
413
+ js_arraybuffer_span_of_t<bare_ffmpeg_io_context_t, 1> io
414
+ ) {
415
+ int err;
416
+
417
+ js_arraybuffer_t handle;
418
+
419
+ bare_ffmpeg_format_context_t *context;
420
+ err = js_create_arraybuffer(env, context, handle);
421
+ assert(err == 0);
422
+
423
+ context->handle = avformat_alloc_context();
424
+ context->handle->pb = io->handle;
425
+ context->handle->opaque = (void *) context;
426
+
427
+ err = avformat_open_input(&context->handle, NULL, NULL, NULL);
428
+ if (err < 0) {
429
+ avformat_free_context(context->handle);
430
+
431
+ bool is_exception_pending;
432
+ err = js_is_exception_pending(env, &is_exception_pending);
433
+ assert(err == 0);
434
+
435
+ if (is_exception_pending) throw js_pending_exception;
436
+
437
+ err = js_throw_error(env, NULL, av_err2str(err));
438
+ assert(err == 0);
439
+
440
+ throw js_pending_exception;
441
+ }
442
+
443
+ err = avformat_find_stream_info(context->handle, NULL);
444
+ if (err < 0) {
445
+ avformat_close_input(&context->handle);
446
+
447
+ err = js_throw_error(env, NULL, av_err2str(err));
448
+ assert(err == 0);
449
+
450
+ throw js_pending_exception;
451
+ }
452
+
453
+ return handle;
454
+ }
455
+
456
+ static js_arraybuffer_t
457
+ bare_ffmpeg_format_context_open_input_with_format(
458
+ js_env_t *env,
459
+ js_receiver_t,
460
+ js_arraybuffer_span_of_t<bare_ffmpeg_input_format_t, 1> format,
461
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> options,
462
+ std::string url
463
+ ) {
464
+ int err;
465
+
466
+ js_arraybuffer_t handle;
467
+
468
+ bare_ffmpeg_format_context_t *context;
469
+ err = js_create_arraybuffer(env, context, handle);
470
+ assert(err == 0);
471
+
472
+ context->handle = avformat_alloc_context();
473
+ context->handle->opaque = (void *) context;
474
+
475
+ err = avformat_open_input(&context->handle, url.c_str(), format->handle, &options->handle);
476
+ if (err < 0) {
477
+ avformat_free_context(context->handle);
478
+
479
+ err = js_throw_error(env, NULL, av_err2str(err));
480
+ assert(err == 0);
481
+
482
+ throw js_pending_exception;
483
+ }
484
+
485
+ err = avformat_find_stream_info(context->handle, NULL);
486
+ if (err < 0) {
487
+ avformat_close_input(&context->handle);
488
+
489
+ err = js_throw_error(env, NULL, av_err2str(err));
490
+ assert(err == 0);
491
+
492
+ throw js_pending_exception;
493
+ }
494
+
495
+ return handle;
496
+ }
497
+
498
+ static void
499
+ bare_ffmpeg_format_context_close_input(
500
+ js_env_t *env,
501
+ js_receiver_t,
502
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
503
+ ) {
504
+ avformat_close_input(&context->handle);
505
+ }
506
+
507
+ static js_arraybuffer_t
508
+ bare_ffmpeg_format_context_open_output(
509
+ js_env_t *env,
510
+ js_receiver_t,
511
+ js_arraybuffer_span_of_t<bare_ffmpeg_output_format_t, 1> format,
512
+ js_arraybuffer_span_of_t<bare_ffmpeg_io_context_t, 1> io
513
+ ) {
514
+ int err;
515
+
516
+ js_arraybuffer_t handle;
517
+
518
+ bare_ffmpeg_format_context_t *context;
519
+ err = js_create_arraybuffer(env, context, handle);
520
+ assert(err == 0);
521
+
522
+ err = avformat_alloc_output_context2(&context->handle, format->handle, NULL, NULL);
523
+ if (err < 0) {
524
+ err = js_throw_error(env, NULL, av_err2str(err));
525
+ assert(err == 0);
526
+
527
+ throw js_pending_exception;
528
+ }
529
+
530
+ context->handle->pb = io->handle;
531
+ context->handle->opaque = (void *) context;
532
+
533
+ return handle;
534
+ }
535
+
536
+ static std::string
537
+ bare_ffmpeg_output_format_get_extensions(
538
+ js_env_t *env,
539
+ js_receiver_t,
540
+ js_arraybuffer_span_of_t<bare_ffmpeg_output_format_t, 1> context
541
+ ) {
542
+ return context->handle->extensions;
543
+ }
544
+
545
+ static std::string
546
+ bare_ffmpeg_output_format_get_mime_type(
547
+ js_env_t *env,
548
+ js_receiver_t,
549
+ js_arraybuffer_span_of_t<bare_ffmpeg_output_format_t, 1> context
550
+ ) {
551
+ return context->handle->mime_type;
552
+ }
553
+
554
+ static std::string
555
+ bare_ffmpeg_output_format_get_name(
556
+ js_env_t *env,
557
+ js_receiver_t,
558
+ js_arraybuffer_span_of_t<bare_ffmpeg_output_format_t, 1> context
559
+ ) {
560
+ return context->handle->name;
561
+ }
562
+
563
+ static void
564
+ bare_ffmpeg_format_context_close_output(
565
+ js_env_t *env,
566
+ js_receiver_t,
567
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
568
+ ) {
569
+ avformat_free_context(context->handle);
570
+ }
571
+
572
+ static js_array_t
573
+ bare_ffmpeg_format_context_get_streams(
574
+ js_env_t *env,
575
+ js_receiver_t,
576
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
577
+ ) {
578
+ int err;
579
+
580
+ auto len = context->handle->nb_streams;
581
+
582
+ js_array_t result;
583
+ err = js_create_array(env, len, result);
584
+ assert(err == 0);
585
+
586
+ for (uint32_t i = 0; i < len; i++) {
587
+ js_arraybuffer_t handle;
588
+
589
+ bare_ffmpeg_stream_t *stream;
590
+ err = js_create_arraybuffer(env, stream, handle);
591
+ assert(err == 0);
592
+
593
+ stream->handle = context->handle->streams[i];
594
+
595
+ err = js_set_element(env, result, i, handle);
596
+ assert(err == 0);
597
+ }
598
+
599
+ return result;
600
+ }
601
+
602
+ static int
603
+ bare_ffmpeg_format_context_get_best_stream_index(
604
+ js_env_t *env,
605
+ js_receiver_t,
606
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
607
+ int32_t type
608
+ ) {
609
+ auto i = av_find_best_stream(context->handle, static_cast<AVMediaType>(type), -1, -1, NULL, 0);
610
+
611
+ if (i < 0) i = -1;
612
+
613
+ return i;
614
+ }
615
+
616
+ static js_arraybuffer_t
617
+ bare_ffmpeg_format_context_create_stream(
618
+ js_env_t *env,
619
+ js_receiver_t,
620
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
621
+ ) {
622
+ int err;
623
+
624
+ js_arraybuffer_t handle;
625
+
626
+ bare_ffmpeg_stream_t *stream;
627
+ err = js_create_arraybuffer(env, stream, handle);
628
+ assert(err == 0);
629
+
630
+ stream->handle = avformat_new_stream(context->handle, NULL);
631
+
632
+ return handle;
633
+ }
634
+
635
+ static bool
636
+ bare_ffmpeg_format_context_read_frame(
637
+ js_env_t *env,
638
+ js_receiver_t,
639
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
640
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
641
+ ) {
642
+ int err;
643
+
644
+ av_packet_unref(packet->handle);
645
+
646
+ err = av_read_frame(context->handle, packet->handle);
647
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
648
+ err = js_throw_error(env, NULL, av_err2str(err));
649
+ assert(err == 0);
650
+
651
+ throw js_pending_exception;
652
+ }
653
+
654
+ return err == 0;
655
+ }
656
+
657
+ static bool
658
+ bare_ffmpeg_format_context_write_header(
659
+ js_env_t *env,
660
+ js_receiver_t,
661
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
662
+ std::optional<js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1>> options
663
+ ) {
664
+ int err;
665
+
666
+ if (options) {
667
+ err = avformat_write_header(context->handle, &options.value()->handle);
668
+ } else {
669
+ err = avformat_write_header(context->handle, NULL);
670
+ }
671
+
672
+ if (err < 0) {
673
+ err = js_throw_error(env, NULL, av_err2str(err));
674
+ assert(err == 0);
675
+
676
+ throw js_pending_exception;
677
+ }
678
+
679
+ return err;
680
+ }
681
+
682
+ static void
683
+ bare_ffmpeg_format_context_write_frame(
684
+ js_env_t *env,
685
+ js_receiver_t,
686
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
687
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
688
+ ) {
689
+ int err;
690
+
691
+ err = av_interleaved_write_frame(context->handle, packet->handle);
692
+ if (err < 0) {
693
+ err = js_throw_error(env, NULL, av_err2str(err));
694
+ assert(err == 0);
695
+
696
+ throw js_pending_exception;
697
+ }
698
+ }
699
+
700
+ static void
701
+ bare_ffmpeg_format_context_write_trailer(
702
+ js_env_t *env,
703
+ js_receiver_t,
704
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
705
+ ) {
706
+ int err;
707
+
708
+ err = av_write_trailer(context->handle);
709
+ if (err < 0) {
710
+ err = js_throw_error(env, NULL, av_err2str(err));
711
+ assert(err == 0);
712
+
713
+ throw js_pending_exception;
714
+ }
715
+ }
716
+
717
+ static void
718
+ bare_ffmpeg_format_context_dump(
719
+ js_env_t *env,
720
+ js_receiver_t,
721
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
722
+ bool is_output,
723
+ int32_t index,
724
+ std::string url
725
+ ) {
726
+ av_dump_format(context->handle, index, url.c_str(), is_output);
727
+
728
+ for (int i = 0; i < context->handle->nb_streams; i++) {
729
+ auto stream = context->handle->streams[i];
730
+
731
+ av_log(NULL, AV_LOG_INFO, " - stream=%i timebase=(%i / %i)\n", i, stream->time_base.num, stream->time_base.den);
732
+ }
733
+ }
734
+
735
+ static std::optional<js_arraybuffer_t>
736
+ get_bare_ffmpeg_format_context_output_format(
737
+ js_env_t *env,
738
+ js_receiver_t,
739
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
740
+ ) {
741
+ int err;
742
+
743
+ if (!context->handle->oformat) return std::nullopt;
744
+
745
+ js_arraybuffer_t handle;
746
+
747
+ bare_ffmpeg_output_format_t *format;
748
+ err = js_create_arraybuffer(env, format, handle);
749
+ assert(err == 0);
750
+
751
+ format->handle = context->handle->oformat;
752
+
753
+ return handle;
754
+ }
755
+
756
+ static std::optional<js_arraybuffer_t>
757
+ get_bare_ffmpeg_format_context_input_format(
758
+ js_env_t *env,
759
+ js_receiver_t,
760
+ js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
761
+ ) {
762
+ int err;
763
+
764
+ if (!context->handle->iformat) return std::nullopt;
765
+
766
+ js_arraybuffer_t handle;
767
+
768
+ bare_ffmpeg_input_format_t *format;
769
+ err = js_create_arraybuffer(env, format, handle);
770
+ assert(err == 0);
771
+
772
+ format->handle = context->handle->iformat;
773
+
774
+ return handle;
775
+ }
776
+
777
+ static int32_t
778
+ bare_ffmpeg_stream_get_index(
779
+ js_env_t *env,
780
+ js_receiver_t,
781
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
782
+ ) {
783
+ return stream->handle->index;
784
+ }
785
+
786
+ static int32_t
787
+ bare_ffmpeg_stream_get_id(
788
+ js_env_t *env,
789
+ js_receiver_t,
790
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
791
+ ) {
792
+ return stream->handle->id;
793
+ }
794
+
795
+ static void
796
+ bare_ffmpeg_stream_set_id(
797
+ js_env_t *env,
798
+ js_receiver_t,
799
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream,
800
+ int32_t id
801
+ ) {
802
+ stream->handle->id = id;
803
+ }
804
+
805
+ static js_arraybuffer_t
806
+ bare_ffmpeg_stream_get_time_base(
807
+ js_env_t *env,
808
+ js_receiver_t,
809
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
810
+ ) {
811
+ int err;
812
+
813
+ js_arraybuffer_t result;
814
+
815
+ int32_t *data;
816
+ err = js_create_arraybuffer(env, 2, data, result);
817
+ assert(err == 0);
818
+
819
+ data[0] = stream->handle->time_base.num;
820
+ data[1] = stream->handle->time_base.den;
821
+
822
+ return result;
823
+ }
824
+
825
+ static void
826
+ bare_ffmpeg_stream_set_time_base(
827
+ js_env_t *env,
828
+ js_receiver_t,
829
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream,
830
+ int num,
831
+ int den
832
+ ) {
833
+ stream->handle->time_base.num = num;
834
+ stream->handle->time_base.den = den;
835
+ }
836
+
837
+ static js_arraybuffer_t
838
+ bare_ffmpeg_stream_get_avg_framerate(
839
+ js_env_t *env,
840
+ js_receiver_t,
841
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
842
+ ) {
843
+ int err;
844
+
845
+ js_arraybuffer_t result;
846
+
847
+ int32_t *data;
848
+ err = js_create_arraybuffer(env, 2, data, result);
849
+ assert(err == 0);
850
+
851
+ data[0] = stream->handle->avg_frame_rate.num;
852
+ data[1] = stream->handle->avg_frame_rate.den;
853
+
854
+ return result;
855
+ }
856
+
857
+ static void
858
+ bare_ffmpeg_stream_set_avg_framerate(
859
+ js_env_t *env,
860
+ js_receiver_t,
861
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream,
862
+ int num,
863
+ int den
864
+ ) {
865
+ stream->handle->avg_frame_rate.num = num;
866
+ stream->handle->avg_frame_rate.den = den;
867
+ }
868
+
869
+ static js_arraybuffer_t
870
+ bare_ffmpeg_stream_get_codec_parameters(
871
+ js_env_t *env,
872
+ js_receiver_t,
873
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
874
+ ) {
875
+ int err;
876
+
877
+ js_arraybuffer_t handle;
878
+
879
+ bare_ffmpeg_codec_parameters_t *parameters;
880
+ err = js_create_arraybuffer(env, parameters, handle);
881
+ assert(err == 0);
882
+
883
+ parameters->handle = stream->handle->codecpar;
884
+
885
+ return handle;
886
+ }
887
+
888
+ static int64_t
889
+ bare_ffmpeg_stream_get_duration(
890
+ js_env_t *env,
891
+ js_receiver_t,
892
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream
893
+ ) {
894
+ if (stream->handle->duration == AV_NOPTS_VALUE) {
895
+ return 0;
896
+ }
897
+
898
+ return stream->handle->duration;
899
+ }
900
+
901
+ static void
902
+ bare_ffmpeg_stream_set_duration(
903
+ js_env_t *env,
904
+ js_receiver_t,
905
+ js_arraybuffer_span_of_t<bare_ffmpeg_stream_t, 1> stream,
906
+ int64_t duration
907
+ ) {
908
+ stream->handle->duration = duration;
909
+ }
910
+
911
+ static js_arraybuffer_t
912
+ bare_ffmpeg_find_decoder_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
913
+ int err;
914
+
915
+ const AVCodec *decoder = avcodec_find_decoder((enum AVCodecID) id);
916
+
917
+ if (decoder == NULL) {
918
+ err = js_throw_errorf(env, NULL, "No decoder found for codec '%d'", id);
919
+ assert(err == 0);
920
+
921
+ throw js_pending_exception;
922
+ }
923
+
924
+ js_arraybuffer_t handle;
925
+
926
+ bare_ffmpeg_codec_t *context;
927
+ err = js_create_arraybuffer(env, context, handle);
928
+ assert(err == 0);
929
+
930
+ context->handle = decoder;
931
+
932
+ return handle;
933
+ }
934
+
935
+ static js_arraybuffer_t
936
+ bare_ffmpeg_find_encoder_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
937
+ int err;
938
+
939
+ const AVCodec *encoder = avcodec_find_encoder((enum AVCodecID) id);
940
+
941
+ if (encoder == NULL) {
942
+ err = js_throw_errorf(env, NULL, "No encoder found for codec '%d'", id);
943
+ assert(err == 0);
944
+
945
+ throw js_pending_exception;
946
+ }
947
+
948
+ js_arraybuffer_t handle;
949
+
950
+ bare_ffmpeg_codec_t *context;
951
+ err = js_create_arraybuffer(env, context, handle);
952
+ assert(err == 0);
953
+
954
+ context->handle = encoder;
955
+
956
+ return handle;
957
+ }
958
+
959
+ static std::string
960
+ bare_ffmpeg_get_codec_name_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
961
+ auto name = avcodec_get_name((enum AVCodecID) id);
962
+
963
+ return std::string(name);
964
+ }
965
+
966
+ static std::string
967
+ bare_ffmpeg_get_sample_format_name_by_id(js_env_t *env, js_receiver_t, int id) {
968
+ return av_get_sample_fmt_name(static_cast<enum AVSampleFormat>(id));
969
+ }
970
+
971
+ static std::string
972
+ bare_ffmpeg_get_pixel_format_name_by_id(js_env_t *env, js_receiver_t, int id) {
973
+ return av_get_pix_fmt_name(static_cast<enum AVPixelFormat>(id));
974
+ }
975
+
976
+ static std::vector<int32_t>
977
+ bare_ffmpeg_codec_get_supported_config(
978
+ js_env_t *env,
979
+ js_receiver_t,
980
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
981
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_t, 1> codec,
982
+ int32_t cfg
983
+ ) {
984
+ int err;
985
+
986
+ int count = 0;
987
+ const void *list = nullptr;
988
+
989
+ err = avcodec_get_supported_config(context->handle, codec->handle, static_cast<AVCodecConfig>(cfg), 0, &list, &count);
990
+ if (err < 0) {
991
+ err = js_throw_error(env, NULL, av_err2str(err));
992
+ assert(err == 0);
993
+
994
+ throw js_pending_exception;
995
+ }
996
+
997
+ std::vector<int32_t> values;
998
+
999
+ if (count > 0 && list) {
1000
+ const int32_t *int_list = static_cast<const int32_t *>(list);
1001
+ for (int i = 0; i < count; i++) {
1002
+ values.push_back(int_list[i]);
1003
+ }
1004
+ return values;
1005
+ }
1006
+
1007
+ switch (static_cast<AVCodecConfig>(cfg)) {
1008
+ case AV_CODEC_CONFIG_PIX_FORMAT:
1009
+ for (int i = 0; i < AV_PIX_FMT_NB; i++) {
1010
+ if (av_pix_fmt_desc_get(static_cast<AVPixelFormat>(i)) != nullptr) {
1011
+ values.push_back(i);
1012
+ }
1013
+ }
1014
+ break;
1015
+ case AV_CODEC_CONFIG_SAMPLE_FORMAT:
1016
+ for (int i = 0; i < AV_SAMPLE_FMT_NB; i++) {
1017
+ values.push_back(i);
1018
+ }
1019
+ break;
1020
+ case AV_CODEC_CONFIG_COLOR_RANGE:
1021
+ values.push_back(AVCOL_RANGE_UNSPECIFIED);
1022
+ values.push_back(AVCOL_RANGE_MPEG);
1023
+ values.push_back(AVCOL_RANGE_JPEG);
1024
+ break;
1025
+ case AV_CODEC_CONFIG_COLOR_SPACE:
1026
+ for (int i = 0; i < AVCOL_SPC_NB; i++) {
1027
+ values.push_back(i);
1028
+ }
1029
+ break;
1030
+ case AV_CODEC_CONFIG_SAMPLE_RATE:
1031
+ values.push_back(0);
1032
+ break;
1033
+ default:
1034
+ break;
1035
+ }
1036
+
1037
+ return values;
1038
+ }
1039
+
1040
+ static std::optional<js_arraybuffer_t>
1041
+ bare_ffmpeg_codec_get_supported_frame_rates(
1042
+ js_env_t *env,
1043
+ js_receiver_t,
1044
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1045
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_t, 1> codec
1046
+ ) {
1047
+ int err;
1048
+
1049
+ const AVCodecContext *ctx = context->handle;
1050
+ const AVCodec *c = codec->handle;
1051
+
1052
+ int count = 0;
1053
+ const void *list = nullptr;
1054
+
1055
+ err = avcodec_get_supported_config(ctx, c, AV_CODEC_CONFIG_FRAME_RATE, 0, &list, &count);
1056
+ if (err < 0) {
1057
+ err = js_throw_error(env, NULL, av_err2str(err));
1058
+ assert(err == 0);
1059
+
1060
+ throw js_pending_exception;
1061
+ }
1062
+
1063
+ if (!list || count == 0) {
1064
+ return std::nullopt;
1065
+ }
1066
+
1067
+ js_arraybuffer_t result;
1068
+ int32_t *data;
1069
+ err = js_create_arraybuffer(env, static_cast<size_t>(count * 2), data, result);
1070
+ assert(err == 0);
1071
+
1072
+ const AVRational *rational_list = static_cast<const AVRational *>(list);
1073
+ for (int i = 0; i < count; i++) {
1074
+ data[i * 2] = rational_list[i].num;
1075
+ data[i * 2 + 1] = rational_list[i].den;
1076
+ }
1077
+
1078
+ return result;
1079
+ }
1080
+
1081
+ static std::optional<std::vector<js_arraybuffer_t>>
1082
+ bare_ffmpeg_codec_get_supported_channel_layouts(
1083
+ js_env_t *env,
1084
+ js_receiver_t,
1085
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1086
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_t, 1> codec
1087
+ ) {
1088
+ int err;
1089
+ std::vector<js_arraybuffer_t> result;
1090
+
1091
+ const AVCodecContext *ctx = context->handle;
1092
+ const AVCodec *c = codec->handle;
1093
+
1094
+ int count = 0;
1095
+ const void *list = nullptr;
1096
+
1097
+ err = avcodec_get_supported_config(ctx, c, AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0, &list, &count);
1098
+ if (err < 0) {
1099
+ err = js_throw_error(env, NULL, av_err2str(err));
1100
+ assert(err == 0);
1101
+
1102
+ throw js_pending_exception;
1103
+ }
1104
+
1105
+ if (!list || count == 0) {
1106
+ return std::nullopt;
1107
+ }
1108
+
1109
+ const AVChannelLayout *layout_list = static_cast<const AVChannelLayout *>(list);
1110
+ for (int i = 0; i < count; i++) {
1111
+ js_arraybuffer_t handle;
1112
+ bare_ffmpeg_channel_layout_t *layout;
1113
+ err = js_create_arraybuffer(env, layout, handle);
1114
+ assert(err == 0);
1115
+
1116
+ err = av_channel_layout_copy(&layout->handle, &layout_list[i]);
1117
+ assert(err >= 0);
1118
+
1119
+ result.push_back(handle);
1120
+ }
1121
+
1122
+ return result;
1123
+ }
1124
+
1125
+ static js_arraybuffer_t
1126
+ bare_ffmpeg_codec_context_init(
1127
+ js_env_t *env,
1128
+ js_receiver_t,
1129
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_t, 1> codec
1130
+ ) {
1131
+ int err;
1132
+
1133
+ js_arraybuffer_t handle;
1134
+
1135
+ bare_ffmpeg_codec_context_t *context;
1136
+ err = js_create_arraybuffer(env, context, handle);
1137
+ assert(err == 0);
1138
+
1139
+ context->handle = avcodec_alloc_context3(codec->handle);
1140
+ context->handle->opaque = (void *) context;
1141
+
1142
+ return handle;
1143
+ }
1144
+
1145
+ static void
1146
+ bare_ffmpeg_codec_context_destroy(
1147
+ js_env_t *env,
1148
+ js_receiver_t,
1149
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1150
+ ) {
1151
+ avcodec_free_context(&context->handle);
1152
+ context->get_format_cb.reset();
1153
+ }
1154
+
1155
+ static bool
1156
+ bare_ffmpeg_codec_context_open(
1157
+ js_env_t *env,
1158
+ js_receiver_t,
1159
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1160
+ ) {
1161
+ int err;
1162
+
1163
+ err = avcodec_open2(context->handle, context->handle->codec, NULL);
1164
+ if (err < 0) {
1165
+ err = js_throw_error(env, NULL, av_err2str(err));
1166
+ assert(err == 0);
1167
+
1168
+ throw js_pending_exception;
1169
+ }
1170
+
1171
+ return err == 0;
1172
+ }
1173
+
1174
+ static int32_t
1175
+ bare_ffmpeg_codec_context_get_flags(
1176
+ js_env_t *env,
1177
+ js_receiver_t,
1178
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1179
+ ) {
1180
+ return context->handle->flags;
1181
+ }
1182
+
1183
+ static void
1184
+ bare_ffmpeg_codec_context_set_flags(
1185
+ js_env_t *env,
1186
+ js_receiver_t,
1187
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1188
+ int32_t value
1189
+ ) {
1190
+ context->handle->flags = value;
1191
+ }
1192
+
1193
+ static js_arraybuffer_t
1194
+ bare_ffmpeg_codec_context_get_extra_data(
1195
+ js_env_t *env,
1196
+ js_receiver_t,
1197
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1198
+ ) {
1199
+ js_arraybuffer_t buffer;
1200
+ int err = js_create_arraybuffer(
1201
+ env,
1202
+ context->handle->extradata,
1203
+ static_cast<size_t>(context->handle->extradata_size),
1204
+ buffer
1205
+ );
1206
+ assert(err == 0);
1207
+
1208
+ return buffer;
1209
+ }
1210
+
1211
+ void
1212
+ bare_ffmpeg_codec_context_set_extra_data(
1213
+ js_env_t *env,
1214
+ js_receiver_t,
1215
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1216
+ js_arraybuffer_t buffer,
1217
+ uint32_t offset,
1218
+ uint32_t len
1219
+ ) {
1220
+ std::span<uint8_t> view;
1221
+ int err = js_get_arraybuffer_info(env, buffer, view);
1222
+ assert(err == 0);
1223
+
1224
+ if (context->handle->extradata_size) {
1225
+ av_free(context->handle->extradata);
1226
+ }
1227
+
1228
+ context->handle->extradata = reinterpret_cast<uint8_t *>(av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE));
1229
+
1230
+ memset(&context->handle->extradata[len], 0, AV_INPUT_BUFFER_PADDING_SIZE);
1231
+ memcpy(context->handle->extradata, &view[offset], len);
1232
+
1233
+ context->handle->extradata_size = static_cast<int>(len);
1234
+ }
1235
+
1236
+ static int
1237
+ bare_ffmpeg_frame_get_format(
1238
+ js_env_t *env,
1239
+ js_receiver_t,
1240
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1241
+ ) {
1242
+ return frame->handle->format;
1243
+ }
1244
+
1245
+ static void
1246
+ bare_ffmpeg_frame_set_format(
1247
+ js_env_t *env,
1248
+ js_receiver_t,
1249
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1250
+ int format
1251
+ ) {
1252
+ frame->handle->format = format;
1253
+ }
1254
+
1255
+ static js_arraybuffer_t
1256
+ bare_ffmpeg_frame_get_channel_layout(
1257
+ js_env_t *env,
1258
+ js_receiver_t,
1259
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1260
+ ) {
1261
+ int err;
1262
+
1263
+ js_arraybuffer_t result;
1264
+
1265
+ bare_ffmpeg_channel_layout_t *layout;
1266
+ err = js_create_arraybuffer(env, layout, result);
1267
+ assert(err == 0);
1268
+
1269
+ err = av_channel_layout_copy(&layout->handle, &frame->handle->ch_layout);
1270
+ assert(err == 0);
1271
+
1272
+ return result;
1273
+ }
1274
+
1275
+ static void
1276
+ bare_ffmpeg_frame_set_channel_layout(
1277
+ js_env_t *env,
1278
+ js_receiver_t,
1279
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1280
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
1281
+ ) {
1282
+ int err;
1283
+
1284
+ err = av_channel_layout_copy(&frame->handle->ch_layout, &layout->handle);
1285
+ assert(err == 0);
1286
+ }
1287
+
1288
+ static void
1289
+ bare_ffmpeg_frame_copy_properties(
1290
+ js_env_t *env,
1291
+ js_receiver_t,
1292
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> dst,
1293
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> src
1294
+ ) {
1295
+ int err = av_frame_copy_props(dst->handle, src->handle);
1296
+
1297
+ if (err < 0) {
1298
+ err = js_throw_error(env, NULL, av_err2str(err));
1299
+ assert(err == 0);
1300
+
1301
+ throw js_pending_exception;
1302
+ }
1303
+ }
1304
+
1305
+ static bool
1306
+ bare_ffmpeg_codec_context_open_with_options(
1307
+ js_env_t *env,
1308
+ js_receiver_t,
1309
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1310
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> options
1311
+ ) {
1312
+ int err;
1313
+
1314
+ err = avcodec_open2(context->handle, context->handle->codec, &options->handle);
1315
+ if (err < 0) {
1316
+ err = js_throw_error(env, NULL, av_err2str(err));
1317
+ assert(err == 0);
1318
+
1319
+ throw js_pending_exception;
1320
+ }
1321
+
1322
+ return err == 0;
1323
+ }
1324
+
1325
+ static int64_t
1326
+ bare_ffmpeg_codec_context_get_pixel_format(
1327
+ js_env_t *env,
1328
+ js_receiver_t,
1329
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1330
+ ) {
1331
+ return context->handle->pix_fmt;
1332
+ }
1333
+
1334
+ static void
1335
+ bare_ffmpeg_codec_context_set_pixel_format(
1336
+ js_env_t *env,
1337
+ js_receiver_t,
1338
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1339
+ int32_t value
1340
+ ) {
1341
+ context->handle->pix_fmt = static_cast<AVPixelFormat>(value);
1342
+ }
1343
+
1344
+ static int64_t
1345
+ bare_ffmpeg_codec_context_get_width(
1346
+ js_env_t *env,
1347
+ js_receiver_t,
1348
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1349
+ ) {
1350
+ return context->handle->width;
1351
+ }
1352
+
1353
+ static void
1354
+ bare_ffmpeg_codec_context_set_width(
1355
+ js_env_t *env,
1356
+ js_receiver_t,
1357
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1358
+ int value
1359
+ ) {
1360
+ context->handle->width = value;
1361
+ }
1362
+
1363
+ static int64_t
1364
+ bare_ffmpeg_codec_context_get_height(
1365
+ js_env_t *env,
1366
+ js_receiver_t,
1367
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1368
+ ) {
1369
+ return context->handle->height;
1370
+ }
1371
+
1372
+ static void
1373
+ bare_ffmpeg_codec_context_set_height(
1374
+ js_env_t *env,
1375
+ js_receiver_t,
1376
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1377
+ int value
1378
+ ) {
1379
+ context->handle->height = value;
1380
+ }
1381
+
1382
+ static int64_t
1383
+ bare_ffmpeg_codec_context_get_sample_format(
1384
+ js_env_t *env,
1385
+ js_receiver_t,
1386
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1387
+ ) {
1388
+ return context->handle->sample_fmt;
1389
+ }
1390
+
1391
+ static void
1392
+ bare_ffmpeg_codec_context_set_sample_format(
1393
+ js_env_t *env,
1394
+ js_receiver_t,
1395
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1396
+ int32_t value
1397
+ ) {
1398
+ context->handle->sample_fmt = static_cast<AVSampleFormat>(value);
1399
+ }
1400
+
1401
+ static js_arraybuffer_t
1402
+ bare_ffmpeg_codec_context_get_time_base(
1403
+ js_env_t *env,
1404
+ js_receiver_t,
1405
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1406
+ ) {
1407
+ int err;
1408
+
1409
+ js_arraybuffer_t result;
1410
+
1411
+ int32_t *data;
1412
+ err = js_create_arraybuffer(env, 2, data, result);
1413
+ assert(err == 0);
1414
+
1415
+ data[0] = context->handle->time_base.num;
1416
+ data[1] = context->handle->time_base.den;
1417
+
1418
+ return result;
1419
+ }
1420
+
1421
+ static void
1422
+ bare_ffmpeg_codec_context_set_time_base(
1423
+ js_env_t *env,
1424
+ js_receiver_t,
1425
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1426
+ int num,
1427
+ int den
1428
+ ) {
1429
+ context->handle->time_base.num = num;
1430
+ context->handle->time_base.den = den;
1431
+ }
1432
+
1433
+ static js_arraybuffer_t
1434
+ bare_ffmpeg_codec_context_get_channel_layout(
1435
+ js_env_t *env,
1436
+ js_receiver_t,
1437
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1438
+ ) {
1439
+ int err;
1440
+
1441
+ js_arraybuffer_t result;
1442
+
1443
+ bare_ffmpeg_channel_layout_t *layout;
1444
+ err = js_create_arraybuffer(env, layout, result);
1445
+ assert(err == 0);
1446
+
1447
+ err = av_channel_layout_copy(&layout->handle, &context->handle->ch_layout);
1448
+ assert(err == 0);
1449
+
1450
+ return result;
1451
+ }
1452
+
1453
+ static void
1454
+ bare_ffmpeg_codec_context_set_channel_layout(
1455
+ js_env_t *env,
1456
+ js_receiver_t,
1457
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1458
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
1459
+ ) {
1460
+ int err;
1461
+
1462
+ err = av_channel_layout_copy(&context->handle->ch_layout, &layout->handle);
1463
+ assert(err == 0);
1464
+ }
1465
+
1466
+ static int
1467
+ bare_ffmpeg_codec_context_get_sample_rate(
1468
+ js_env_t *env,
1469
+ js_receiver_t,
1470
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1471
+ ) {
1472
+ return context->handle->sample_rate;
1473
+ }
1474
+
1475
+ static void
1476
+ bare_ffmpeg_codec_context_set_sample_rate(
1477
+ js_env_t *env,
1478
+ js_receiver_t,
1479
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1480
+ int32_t sample_rate
1481
+ ) {
1482
+ context->handle->sample_rate = sample_rate;
1483
+ }
1484
+
1485
+ static int
1486
+ bare_ffmpeg_codec_context_get_gop_size(
1487
+ js_env_t *env,
1488
+ js_receiver_t,
1489
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1490
+ ) {
1491
+ return context->handle->gop_size;
1492
+ }
1493
+
1494
+ static void
1495
+ bare_ffmpeg_codec_context_set_gop_size(
1496
+ js_env_t *env,
1497
+ js_receiver_t,
1498
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1499
+ int32_t gop_size
1500
+ ) {
1501
+ context->handle->gop_size = gop_size;
1502
+ }
1503
+
1504
+ static int
1505
+ bare_ffmpeg_codec_context_get_frame_size(
1506
+ js_env_t *env,
1507
+ js_receiver_t,
1508
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1509
+ ) {
1510
+ return context->handle->frame_size;
1511
+ }
1512
+
1513
+ static int64_t
1514
+ bare_ffmpeg_codec_context_get_frame_num(
1515
+ js_env_t *env,
1516
+ js_receiver_t,
1517
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1518
+ ) {
1519
+ return context->handle->frame_num;
1520
+ }
1521
+
1522
+ static js_arraybuffer_t
1523
+ bare_ffmpeg_codec_context_get_framerate(
1524
+ js_env_t *env,
1525
+ js_receiver_t,
1526
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1527
+ ) {
1528
+ int err;
1529
+
1530
+ js_arraybuffer_t result;
1531
+
1532
+ int32_t *data;
1533
+ err = js_create_arraybuffer(env, 2, data, result);
1534
+ assert(err == 0);
1535
+
1536
+ data[0] = context->handle->framerate.num;
1537
+ data[1] = context->handle->framerate.den;
1538
+
1539
+ return result;
1540
+ }
1541
+
1542
+ static void
1543
+ bare_ffmpeg_codec_context_set_framerate(
1544
+ js_env_t *env,
1545
+ js_receiver_t,
1546
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1547
+ int num,
1548
+ int den
1549
+ ) {
1550
+ context->handle->framerate.num = num;
1551
+ context->handle->framerate.den = den;
1552
+ }
1553
+
1554
+ static bool
1555
+ bare_ffmpeg_codec_context_send_packet(
1556
+ js_env_t *env,
1557
+ js_receiver_t,
1558
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1559
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
1560
+ ) {
1561
+ int err;
1562
+
1563
+ err = avcodec_send_packet(context->handle, packet->handle);
1564
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
1565
+ err = js_throw_error(env, NULL, av_err2str(err));
1566
+ assert(err == 0);
1567
+
1568
+ throw js_pending_exception;
1569
+ }
1570
+
1571
+ return err == 0;
1572
+ }
1573
+
1574
+ static int64_t
1575
+ bare_ffmpeg_codec_context_get_request_sample_format(
1576
+ js_env_t *env,
1577
+ js_receiver_t,
1578
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1579
+ ) {
1580
+ return context->handle->request_sample_fmt;
1581
+ }
1582
+
1583
+ static void
1584
+ bare_ffmpeg_codec_context_set_request_sample_format(
1585
+ js_env_t *env,
1586
+ js_receiver_t,
1587
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1588
+ int64_t sample_format
1589
+ ) {
1590
+ context->handle->request_sample_fmt = static_cast<AVSampleFormat>(sample_format);
1591
+ }
1592
+
1593
+ static enum AVPixelFormat
1594
+ bare_ffmpeg__on_codec_context_get_format(struct AVCodecContext *input_context, const enum AVPixelFormat *fmt) {
1595
+ int err;
1596
+
1597
+ auto context = static_cast<bare_ffmpeg_codec_context_t *>(input_context->opaque);
1598
+
1599
+ assert(context->env);
1600
+ assert(context->get_format_cb);
1601
+
1602
+ bare_ffmpeg_codec_context_get_format_cb_t callback;
1603
+ err = js_get_reference_value(context->env, context->get_format_cb, callback);
1604
+ assert(err == 0);
1605
+
1606
+ std::vector<int> formats{};
1607
+ for (const enum AVPixelFormat *p = fmt; *p != AV_PIX_FMT_NONE; ++p) {
1608
+ formats.push_back(static_cast<int>(*p));
1609
+ }
1610
+
1611
+ int result;
1612
+ err = js_call_function<js_type_options_t{}, int, std::vector<int>>(
1613
+ context->env,
1614
+ callback,
1615
+ formats,
1616
+ result
1617
+ );
1618
+ assert(err == 0);
1619
+
1620
+ return static_cast<enum AVPixelFormat>(result);
1621
+ }
1622
+
1623
+ static void
1624
+ bare_ffmpeg_codec_context_set_get_format(
1625
+ js_env_t *env,
1626
+ js_receiver_t,
1627
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1628
+ bare_ffmpeg_codec_context_get_format_cb_t callback
1629
+ ) {
1630
+ int err = js_create_reference(env, callback, context->get_format_cb);
1631
+ assert(err == 0);
1632
+
1633
+ context->handle->get_format = bare_ffmpeg__on_codec_context_get_format;
1634
+ context->env = env;
1635
+ }
1636
+
1637
+ static bool
1638
+ bare_ffmpeg_codec_context_receive_packet(
1639
+ js_env_t *env,
1640
+ js_receiver_t,
1641
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1642
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
1643
+ ) {
1644
+ int err;
1645
+
1646
+ err = avcodec_receive_packet(context->handle, packet->handle);
1647
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
1648
+ err = js_throw_error(env, NULL, av_err2str(err));
1649
+ assert(err == 0);
1650
+
1651
+ throw js_pending_exception;
1652
+ }
1653
+
1654
+ return err == 0;
1655
+ }
1656
+
1657
+ static bool
1658
+ bare_ffmpeg_codec_context_send_frame(
1659
+ js_env_t *env,
1660
+ js_receiver_t,
1661
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1662
+ std::optional<js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1>> frame
1663
+ ) {
1664
+ int err;
1665
+
1666
+ if (frame) {
1667
+ err = avcodec_send_frame(context->handle, frame.value()->handle);
1668
+ } else {
1669
+ err = avcodec_send_frame(context->handle, NULL); // End of stream
1670
+ }
1671
+
1672
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
1673
+ err = js_throw_error(env, NULL, av_err2str(err));
1674
+ assert(err == 0);
1675
+
1676
+ throw js_pending_exception;
1677
+ }
1678
+
1679
+ return err == 0;
1680
+ }
1681
+
1682
+ static bool
1683
+ bare_ffmpeg_codec_context_receive_frame(
1684
+ js_env_t *env,
1685
+ js_receiver_t,
1686
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1687
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1688
+ ) {
1689
+ int err;
1690
+
1691
+ err = avcodec_receive_frame(context->handle, frame->handle);
1692
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
1693
+ err = js_throw_error(env, NULL, av_err2str(err));
1694
+ assert(err == 0);
1695
+
1696
+ throw js_pending_exception;
1697
+ }
1698
+
1699
+ return err == 0;
1700
+ }
1701
+
1702
+ static void
1703
+ bare_ffmpeg_codec_parameters_from_context(
1704
+ js_env_t *env,
1705
+ js_receiver_t,
1706
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1707
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
1708
+ ) {
1709
+ int err;
1710
+
1711
+ err = avcodec_parameters_from_context(parameters->handle, context->handle);
1712
+ if (err < 0) {
1713
+ err = js_throw_error(env, NULL, av_err2str(err));
1714
+ assert(err == 0);
1715
+
1716
+ throw js_pending_exception;
1717
+ }
1718
+ }
1719
+
1720
+ static void
1721
+ bare_ffmpeg_codec_parameters_to_context(
1722
+ js_env_t *env,
1723
+ js_receiver_t,
1724
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
1725
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1726
+ ) {
1727
+ int err;
1728
+
1729
+ err = avcodec_parameters_to_context(context->handle, parameters->handle);
1730
+ if (err < 0) {
1731
+ err = js_throw_error(env, NULL, av_err2str(err));
1732
+ assert(err == 0);
1733
+
1734
+ throw js_pending_exception;
1735
+ }
1736
+ }
1737
+
1738
+ static js_arraybuffer_t
1739
+ bare_ffmpeg_codec_parameters_alloc(
1740
+ js_env_t *env,
1741
+ js_receiver_t
1742
+ ) {
1743
+ int err;
1744
+
1745
+ js_arraybuffer_t handle;
1746
+
1747
+ bare_ffmpeg_codec_parameters_t *parameters;
1748
+ err = js_create_arraybuffer(env, parameters, handle);
1749
+ assert(err == 0);
1750
+
1751
+ parameters->handle = avcodec_parameters_alloc();
1752
+
1753
+ return handle;
1754
+ }
1755
+
1756
+ static void
1757
+ bare_ffmpeg_codec_parameters_destroy(
1758
+ js_env_t *env,
1759
+ js_receiver_t,
1760
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1761
+ ) {
1762
+ avcodec_parameters_free(&parameters->handle);
1763
+ }
1764
+
1765
+ static int64_t
1766
+ bare_ffmpeg_codec_parameters_get_bit_rate(
1767
+ js_env_t *env,
1768
+ js_receiver_t,
1769
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1770
+ ) {
1771
+ return parameters->handle->bit_rate;
1772
+ }
1773
+
1774
+ static void
1775
+ bare_ffmpeg_codec_parameters_set_bit_rate(
1776
+ js_env_t *env,
1777
+ js_receiver_t,
1778
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1779
+ int64_t bit_rate
1780
+ ) {
1781
+ parameters->handle->bit_rate = bit_rate;
1782
+ }
1783
+
1784
+ static int
1785
+ bare_ffmpeg_codec_parameters_get_bits_per_coded_sample(
1786
+ js_env_t *env,
1787
+ js_receiver_t,
1788
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1789
+ ) {
1790
+ return parameters->handle->bits_per_coded_sample;
1791
+ }
1792
+
1793
+ static void
1794
+ bare_ffmpeg_codec_parameters_set_bits_per_coded_sample(
1795
+ js_env_t *env,
1796
+ js_receiver_t,
1797
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1798
+ int bits
1799
+ ) {
1800
+ parameters->handle->bits_per_coded_sample = bits;
1801
+ }
1802
+
1803
+ static int
1804
+ bare_ffmpeg_codec_parameters_get_bits_per_raw_sample(
1805
+ js_env_t *env,
1806
+ js_receiver_t,
1807
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1808
+ ) {
1809
+ return parameters->handle->bits_per_raw_sample;
1810
+ }
1811
+
1812
+ static void
1813
+ bare_ffmpeg_codec_parameters_set_bits_per_raw_sample(
1814
+ js_env_t *env,
1815
+ js_receiver_t,
1816
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1817
+ int bits
1818
+ ) {
1819
+ parameters->handle->bits_per_raw_sample = bits;
1820
+ }
1821
+
1822
+ static int
1823
+ bare_ffmpeg_codec_parameters_get_sample_rate(
1824
+ js_env_t *env,
1825
+ js_receiver_t,
1826
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1827
+ ) {
1828
+ return parameters->handle->sample_rate;
1829
+ }
1830
+
1831
+ static void
1832
+ bare_ffmpeg_codec_parameters_set_sample_rate(
1833
+ js_env_t *env,
1834
+ js_receiver_t,
1835
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1836
+ int rate
1837
+ ) {
1838
+ parameters->handle->sample_rate = rate;
1839
+ }
1840
+
1841
+ static int
1842
+ bare_ffmpeg_codec_parameters_get_nb_channels(
1843
+ js_env_t *env,
1844
+ js_receiver_t,
1845
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1846
+ ) {
1847
+ return parameters->handle->ch_layout.nb_channels;
1848
+ }
1849
+
1850
+ static void
1851
+ bare_ffmpeg_codec_parameters_set_nb_channels(
1852
+ js_env_t *env,
1853
+ js_receiver_t,
1854
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1855
+ int nb_channels
1856
+ ) {
1857
+ parameters->handle->ch_layout.nb_channels = nb_channels;
1858
+ }
1859
+
1860
+ static int64_t
1861
+ bare_ffmpeg_codec_parameters_get_type(
1862
+ js_env_t *env,
1863
+ js_receiver_t,
1864
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1865
+ ) {
1866
+ return parameters->handle->codec_type;
1867
+ }
1868
+
1869
+ static void
1870
+ bare_ffmpeg_codec_parameters_set_type(
1871
+ js_env_t *env,
1872
+ js_receiver_t,
1873
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1874
+ int type
1875
+ ) {
1876
+ parameters->handle->codec_type = static_cast<AVMediaType>(type);
1877
+ }
1878
+
1879
+ static uint32_t
1880
+ bare_ffmpeg_codec_parameters_get_tag(
1881
+ js_env_t *env,
1882
+ js_receiver_t,
1883
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1884
+ ) {
1885
+ return parameters->handle->codec_tag;
1886
+ }
1887
+
1888
+ static void
1889
+ bare_ffmpeg_codec_parameters_set_tag(
1890
+ js_env_t *env,
1891
+ js_receiver_t,
1892
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1893
+ uint32_t codec_tag
1894
+ ) {
1895
+ parameters->handle->codec_tag = codec_tag;
1896
+ }
1897
+
1898
+ static int32_t
1899
+ bare_ffmpeg_codec_parameters_get_id(
1900
+ js_env_t *env,
1901
+ js_receiver_t,
1902
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1903
+ ) {
1904
+ return parameters->handle->codec_id;
1905
+ }
1906
+
1907
+ static void
1908
+ bare_ffmpeg_codec_parameters_set_id(
1909
+ js_env_t *env,
1910
+ js_receiver_t,
1911
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1912
+ uint32_t codec_id
1913
+ ) {
1914
+ parameters->handle->codec_id = static_cast<AVCodecID>(codec_id);
1915
+ }
1916
+
1917
+ static int
1918
+ bare_ffmpeg_codec_parameters_get_level(
1919
+ js_env_t *env,
1920
+ js_receiver_t,
1921
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1922
+ ) {
1923
+ return parameters->handle->level;
1924
+ }
1925
+
1926
+ static void
1927
+ bare_ffmpeg_codec_parameters_set_level(
1928
+ js_env_t *env,
1929
+ js_receiver_t,
1930
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1931
+ int level
1932
+ ) {
1933
+ parameters->handle->level = level;
1934
+ }
1935
+
1936
+ static int
1937
+ bare_ffmpeg_codec_parameters_get_profile(
1938
+ js_env_t *env,
1939
+ js_receiver_t,
1940
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1941
+ ) {
1942
+ return parameters->handle->profile;
1943
+ }
1944
+
1945
+ static void
1946
+ bare_ffmpeg_codec_parameters_set_profile(
1947
+ js_env_t *env,
1948
+ js_receiver_t,
1949
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1950
+ int profile
1951
+ ) {
1952
+ parameters->handle->profile = profile;
1953
+ }
1954
+
1955
+ static int
1956
+ bare_ffmpeg_codec_parameters_get_format(
1957
+ js_env_t *env,
1958
+ js_receiver_t,
1959
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1960
+ ) {
1961
+ return parameters->handle->format;
1962
+ }
1963
+
1964
+ static void
1965
+ bare_ffmpeg_codec_parameters_set_format(
1966
+ js_env_t *env,
1967
+ js_receiver_t,
1968
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1969
+ int format
1970
+ ) {
1971
+ parameters->handle->format = format;
1972
+ }
1973
+
1974
+ static js_arraybuffer_t
1975
+ bare_ffmpeg_codec_parameters_get_channel_layout(
1976
+ js_env_t *env,
1977
+ js_receiver_t,
1978
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1979
+ ) {
1980
+ int err;
1981
+
1982
+ js_arraybuffer_t result;
1983
+
1984
+ bare_ffmpeg_channel_layout_t *layout;
1985
+ err = js_create_arraybuffer(env, layout, result);
1986
+ assert(err == 0);
1987
+
1988
+ err = av_channel_layout_copy(&layout->handle, &parameters->handle->ch_layout);
1989
+ assert(err == 0);
1990
+
1991
+ return result;
1992
+ }
1993
+
1994
+ static void
1995
+ bare_ffmpeg_codec_parameters_set_channel_layout(
1996
+ js_env_t *env,
1997
+ js_receiver_t,
1998
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1999
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
2000
+ ) {
2001
+ int err;
2002
+
2003
+ err = av_channel_layout_copy(&parameters->handle->ch_layout, &layout->handle);
2004
+ assert(err == 0);
2005
+ }
2006
+
2007
+ static int
2008
+ bare_ffmpeg_codec_parameters_get_width(
2009
+ js_env_t *env,
2010
+ js_receiver_t,
2011
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2012
+ ) {
2013
+ return parameters->handle->width;
2014
+ }
2015
+
2016
+ static void
2017
+ bare_ffmpeg_codec_parameters_set_width(
2018
+ js_env_t *env,
2019
+ js_receiver_t,
2020
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2021
+ int width
2022
+ ) {
2023
+ parameters->handle->width = width;
2024
+ }
2025
+
2026
+ static int32_t
2027
+ bare_ffmpeg_codec_parameters_get_height(
2028
+ js_env_t *env,
2029
+ js_receiver_t,
2030
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2031
+ ) {
2032
+ return parameters->handle->height;
2033
+ }
2034
+
2035
+ static void
2036
+ bare_ffmpeg_codec_parameters_set_height(
2037
+ js_env_t *env,
2038
+ js_receiver_t,
2039
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2040
+ int height
2041
+ ) {
2042
+ parameters->handle->height = height;
2043
+ }
2044
+
2045
+ static js_arraybuffer_t
2046
+ bare_ffmpeg_codec_parameters_get_framerate(
2047
+ js_env_t *env,
2048
+ js_receiver_t,
2049
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2050
+ ) {
2051
+ int err;
2052
+
2053
+ js_arraybuffer_t result;
2054
+
2055
+ int32_t *data;
2056
+ err = js_create_arraybuffer(env, 2, data, result);
2057
+ assert(err == 0);
2058
+
2059
+ data[0] = parameters->handle->framerate.num;
2060
+ data[1] = parameters->handle->framerate.den;
2061
+
2062
+ return result;
2063
+ }
2064
+
2065
+ static void
2066
+ bare_ffmpeg_codec_parameters_set_framerate(
2067
+ js_env_t *env,
2068
+ js_receiver_t,
2069
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2070
+ int numerator,
2071
+ int denominator
2072
+ ) {
2073
+ parameters->handle->framerate.num = numerator;
2074
+ parameters->handle->framerate.den = denominator;
2075
+ }
2076
+
2077
+ static js_arraybuffer_t
2078
+ bare_ffmpeg_codec_parameters_get_extra_data(
2079
+ js_env_t *env,
2080
+ js_receiver_t,
2081
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2082
+ ) {
2083
+ int err;
2084
+
2085
+ js_arraybuffer_t buffer;
2086
+
2087
+ assert(parameters->handle->extradata_size >= 0);
2088
+
2089
+ err = js_create_arraybuffer(
2090
+ env,
2091
+ parameters->handle->extradata,
2092
+ static_cast<size_t>(parameters->handle->extradata_size),
2093
+ buffer
2094
+ );
2095
+ assert(err == 0);
2096
+
2097
+ return buffer;
2098
+ }
2099
+
2100
+ void
2101
+ bare_ffmpeg_codec_parameters_set_extra_data(
2102
+ js_env_t *env,
2103
+ js_receiver_t,
2104
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2105
+ js_arraybuffer_t buffer,
2106
+ uint32_t offset,
2107
+ uint32_t len
2108
+ ) {
2109
+ int err;
2110
+
2111
+ std::span<uint8_t> view;
2112
+ err = js_get_arraybuffer_info(env, buffer, view);
2113
+ assert(err == 0);
2114
+
2115
+ if (parameters->handle->extradata_size) {
2116
+ assert(parameters->handle->extradata_size > 0);
2117
+ assert(parameters->handle->extradata);
2118
+
2119
+ av_free(parameters->handle->extradata);
2120
+ }
2121
+
2122
+ size_t min_size = len + AV_INPUT_BUFFER_PADDING_SIZE;
2123
+
2124
+ parameters->handle->extradata = reinterpret_cast<uint8_t *>(av_malloc(min_size));
2125
+
2126
+ memset(&parameters->handle->extradata[len], 0, AV_INPUT_BUFFER_PADDING_SIZE);
2127
+
2128
+ memcpy(parameters->handle->extradata, &view[offset], len);
2129
+
2130
+ parameters->handle->extradata_size = static_cast<int>(len);
2131
+ }
2132
+
2133
+ static int
2134
+ bare_ffmpeg_codec_parameters_get_block_align(
2135
+ js_env_t *env,
2136
+ js_receiver_t,
2137
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2138
+ ) {
2139
+ return parameters->handle->block_align;
2140
+ }
2141
+
2142
+ static void
2143
+ bare_ffmpeg_codec_parameters_set_block_align(
2144
+ js_env_t *env,
2145
+ js_receiver_t,
2146
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2147
+ int block_align
2148
+ ) {
2149
+ parameters->handle->block_align = block_align;
2150
+ }
2151
+
2152
+ static int
2153
+ bare_ffmpeg_codec_parameters_get_initial_padding(
2154
+ js_env_t *env,
2155
+ js_receiver_t,
2156
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2157
+ ) {
2158
+ return parameters->handle->initial_padding;
2159
+ }
2160
+
2161
+ static void
2162
+ bare_ffmpeg_codec_parameters_set_initial_padding(
2163
+ js_env_t *env,
2164
+ js_receiver_t,
2165
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2166
+ int initial_padding
2167
+ ) {
2168
+ parameters->handle->initial_padding = initial_padding;
2169
+ }
2170
+
2171
+ static int
2172
+ bare_ffmpeg_codec_parameters_get_trailing_padding(
2173
+ js_env_t *env,
2174
+ js_receiver_t,
2175
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2176
+ ) {
2177
+ return parameters->handle->trailing_padding;
2178
+ }
2179
+
2180
+ static void
2181
+ bare_ffmpeg_codec_parameters_set_trailing_padding(
2182
+ js_env_t *env,
2183
+ js_receiver_t,
2184
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2185
+ int trailing_padding
2186
+ ) {
2187
+ parameters->handle->trailing_padding = trailing_padding;
2188
+ }
2189
+
2190
+ static int
2191
+ bare_ffmpeg_codec_parameters_get_seek_preroll(
2192
+ js_env_t *env,
2193
+ js_receiver_t,
2194
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2195
+ ) {
2196
+ return parameters->handle->seek_preroll;
2197
+ }
2198
+
2199
+ static void
2200
+ bare_ffmpeg_codec_parameters_set_seek_preroll(
2201
+ js_env_t *env,
2202
+ js_receiver_t,
2203
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2204
+ int seek_preroll
2205
+ ) {
2206
+ parameters->handle->seek_preroll = seek_preroll;
2207
+ }
2208
+
2209
+ static js_arraybuffer_t
2210
+ bare_ffmpeg_codec_parameters_get_sample_aspect_ratio(
2211
+ js_env_t *env,
2212
+ js_receiver_t,
2213
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2214
+ ) {
2215
+ int err;
2216
+ js_arraybuffer_t result;
2217
+
2218
+ int32_t *data;
2219
+ err = js_create_arraybuffer(env, 2, data, result);
2220
+ assert(err == 0);
2221
+
2222
+ data[0] = parameters->handle->sample_aspect_ratio.num;
2223
+ data[1] = parameters->handle->sample_aspect_ratio.den;
2224
+
2225
+ return result;
2226
+ }
2227
+
2228
+ static void
2229
+ bare_ffmpeg_codec_parameters_set_sample_aspect_ratio(
2230
+ js_env_t *env,
2231
+ js_receiver_t,
2232
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2233
+ int num,
2234
+ int den
2235
+ ) {
2236
+ parameters->handle->sample_aspect_ratio.num = num;
2237
+ parameters->handle->sample_aspect_ratio.den = den;
2238
+ }
2239
+
2240
+ static int
2241
+ bare_ffmpeg_codec_parameters_get_video_delay(
2242
+ js_env_t *env,
2243
+ js_receiver_t,
2244
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2245
+ ) {
2246
+ return parameters->handle->video_delay;
2247
+ }
2248
+
2249
+ static void
2250
+ bare_ffmpeg_codec_parameters_set_video_delay(
2251
+ js_env_t *env,
2252
+ js_receiver_t,
2253
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2254
+ int delay
2255
+ ) {
2256
+ parameters->handle->video_delay = delay;
2257
+ }
2258
+
2259
+ static int
2260
+ bare_ffmpeg_codec_parameters_get_frame_size(
2261
+ js_env_t *env,
2262
+ js_receiver_t,
2263
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
2264
+ ) {
2265
+ return parameters->handle->frame_size;
2266
+ }
2267
+
2268
+ static void
2269
+ bare_ffmpeg_codec_parameters_set_frame_size(
2270
+ js_env_t *env,
2271
+ js_receiver_t,
2272
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
2273
+ int frame_size
2274
+ ) {
2275
+ parameters->handle->frame_size = frame_size;
2276
+ }
2277
+
2278
+ static js_arraybuffer_t
2279
+ bare_ffmpeg_frame_init(js_env_t *env, js_receiver_t) {
2280
+ int err;
2281
+
2282
+ js_arraybuffer_t handle;
2283
+
2284
+ bare_ffmpeg_frame_t *frame;
2285
+ err = js_create_arraybuffer(env, frame, handle);
2286
+ assert(err == 0);
2287
+
2288
+ frame->handle = av_frame_alloc();
2289
+ frame->handle->opaque = (void *) frame;
2290
+
2291
+ return handle;
2292
+ }
2293
+
2294
+ static void
2295
+ bare_ffmpeg_frame_unref(
2296
+ js_env_t *env,
2297
+ js_receiver_t,
2298
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2299
+ ) {
2300
+ av_frame_unref(frame->handle);
2301
+ }
2302
+
2303
+ static void
2304
+ bare_ffmpeg_frame_destroy(
2305
+ js_env_t *env,
2306
+ js_receiver_t,
2307
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2308
+ ) {
2309
+ av_frame_free(&frame->handle);
2310
+ }
2311
+
2312
+ static int32_t
2313
+ bare_ffmpeg_frame_get_width(
2314
+ js_env_t *env,
2315
+ js_receiver_t,
2316
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2317
+ ) {
2318
+ return frame->handle->width;
2319
+ }
2320
+
2321
+ static void
2322
+ bare_ffmpeg_frame_set_width(
2323
+ js_env_t *env,
2324
+ js_receiver_t,
2325
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2326
+ int32_t width
2327
+ ) {
2328
+ frame->handle->width = width;
2329
+ }
2330
+
2331
+ static int32_t
2332
+ bare_ffmpeg_frame_get_height(
2333
+ js_env_t *env,
2334
+ js_receiver_t,
2335
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2336
+ ) {
2337
+ return frame->handle->height;
2338
+ }
2339
+
2340
+ static void
2341
+ bare_ffmpeg_frame_set_height(
2342
+ js_env_t *env,
2343
+ js_receiver_t,
2344
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2345
+ int32_t height
2346
+ ) {
2347
+ frame->handle->height = height;
2348
+ }
2349
+
2350
+ static int32_t
2351
+ bare_ffmpeg_frame_get_nb_samples(
2352
+ js_env_t *env,
2353
+ js_receiver_t,
2354
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2355
+ ) {
2356
+ return frame->handle->nb_samples;
2357
+ }
2358
+
2359
+ static void
2360
+ bare_ffmpeg_frame_set_nb_samples(
2361
+ js_env_t *env,
2362
+ js_receiver_t,
2363
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2364
+ int32_t nb_samples
2365
+ ) {
2366
+ frame->handle->nb_samples = nb_samples;
2367
+ }
2368
+
2369
+ static int32_t
2370
+ bare_ffmpeg_frame_get_pict_type(
2371
+ js_env_t *env,
2372
+ js_receiver_t,
2373
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2374
+ ) {
2375
+ return frame->handle->pict_type;
2376
+ }
2377
+
2378
+ static int64_t
2379
+ bare_ffmpeg_frame_get_pts(
2380
+ js_env_t *env,
2381
+ js_receiver_t,
2382
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2383
+ ) {
2384
+ int64_t ts = frame->handle->pts;
2385
+
2386
+ if (ts == AV_NOPTS_VALUE) return -1;
2387
+
2388
+ return ts;
2389
+ }
2390
+
2391
+ static void
2392
+ bare_ffmpeg_frame_set_pts(
2393
+ js_env_t *,
2394
+ js_receiver_t,
2395
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2396
+ int64_t value
2397
+ ) {
2398
+ frame->handle->pts = value;
2399
+ }
2400
+
2401
+ static int64_t
2402
+ bare_ffmpeg_frame_get_pkt_dts(
2403
+ js_env_t *env,
2404
+ js_receiver_t,
2405
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2406
+ ) {
2407
+ int64_t ts = frame->handle->pkt_dts;
2408
+
2409
+ if (ts == AV_NOPTS_VALUE) return -1;
2410
+
2411
+ return ts;
2412
+ }
2413
+
2414
+ static void
2415
+ bare_ffmpeg_frame_set_pkt_dts(
2416
+ js_env_t *,
2417
+ js_receiver_t,
2418
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2419
+ int64_t value
2420
+ ) {
2421
+ frame->handle->pkt_dts = value;
2422
+ }
2423
+
2424
+ static js_arraybuffer_t
2425
+ bare_ffmpeg_frame_get_time_base(
2426
+ js_env_t *env,
2427
+ js_receiver_t,
2428
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2429
+ ) {
2430
+ int err;
2431
+
2432
+ js_arraybuffer_t result;
2433
+
2434
+ int32_t *data;
2435
+ err = js_create_arraybuffer(env, 2, data, result);
2436
+ assert(err == 0);
2437
+
2438
+ data[0] = frame->handle->time_base.num;
2439
+ data[1] = frame->handle->time_base.den;
2440
+
2441
+ return result;
2442
+ }
2443
+
2444
+ static void
2445
+ bare_ffmpeg_frame_set_time_base(
2446
+ js_env_t *env,
2447
+ js_receiver_t,
2448
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2449
+ int num,
2450
+ int den
2451
+ ) {
2452
+ frame->handle->time_base.num = num;
2453
+ frame->handle->time_base.den = den;
2454
+ }
2455
+
2456
+ static int32_t
2457
+ bare_ffmpeg_frame_get_sample_rate(
2458
+ js_env_t *env,
2459
+ js_receiver_t,
2460
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2461
+ ) {
2462
+ return frame->handle->sample_rate;
2463
+ }
2464
+
2465
+ static void
2466
+ bare_ffmpeg_frame_set_sample_rate(
2467
+ js_env_t *env,
2468
+ js_receiver_t,
2469
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2470
+ int32_t rate
2471
+ ) {
2472
+ frame->handle->sample_rate = rate;
2473
+ }
2474
+
2475
+ static void
2476
+ bare_ffmpeg_frame_alloc(
2477
+ js_env_t *env,
2478
+ js_receiver_t,
2479
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2480
+ int align
2481
+ ) {
2482
+ int err;
2483
+
2484
+ err = av_frame_get_buffer(frame->handle, align);
2485
+ if (err < 0) {
2486
+ err = js_throw_error(env, NULL, av_err2str(err));
2487
+ assert(err == 0);
2488
+
2489
+ throw js_pending_exception;
2490
+ }
2491
+ }
2492
+
2493
+ static js_arraybuffer_t
2494
+ bare_ffmpeg_image_init(
2495
+ js_env_t *env,
2496
+ js_receiver_t,
2497
+ int32_t pixel_format,
2498
+ int32_t width,
2499
+ int32_t height,
2500
+ int32_t align
2501
+ ) {
2502
+ int err;
2503
+
2504
+ auto len = av_image_get_buffer_size(
2505
+ static_cast<AVPixelFormat>(pixel_format),
2506
+ width,
2507
+ height,
2508
+ align
2509
+ );
2510
+
2511
+ if (len < 0) {
2512
+ err = js_throw_error(env, NULL, av_err2str(len));
2513
+ assert(err == 0);
2514
+
2515
+ throw js_pending_exception;
2516
+ }
2517
+
2518
+ js_arraybuffer_t handle;
2519
+ err = js_create_arraybuffer(env, static_cast<size_t>(len), handle);
2520
+ assert(err == 0);
2521
+
2522
+ return handle;
2523
+ }
2524
+
2525
+ static void
2526
+ bare_ffmpeg_image_fill(
2527
+ js_env_t *env,
2528
+ js_receiver_t,
2529
+ int32_t pixel_format,
2530
+ int32_t width,
2531
+ int32_t height,
2532
+ int32_t align,
2533
+ js_arraybuffer_span_t data,
2534
+ uint64_t offset,
2535
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2536
+ ) {
2537
+ int err;
2538
+
2539
+ auto len = av_image_fill_arrays(
2540
+ frame->handle->data,
2541
+ frame->handle->linesize,
2542
+ &data[static_cast<size_t>(offset)],
2543
+ static_cast<AVPixelFormat>(pixel_format),
2544
+ width,
2545
+ height,
2546
+ align
2547
+ );
2548
+
2549
+ if (len < 0) {
2550
+ err = js_throw_error(env, NULL, av_err2str(len));
2551
+ assert(err == 0);
2552
+
2553
+ throw js_pending_exception;
2554
+ }
2555
+ }
2556
+
2557
+ static void
2558
+ bare_ffmpeg_image_read(
2559
+ js_env_t *env,
2560
+ js_receiver_t,
2561
+ int32_t pixel_format,
2562
+ int32_t width,
2563
+ int32_t height,
2564
+ int32_t align,
2565
+ js_arraybuffer_span_t data,
2566
+ uint64_t offset,
2567
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
2568
+ ) {
2569
+ int err;
2570
+
2571
+ uint8_t *dst_data[4];
2572
+ int dst_linesize[4];
2573
+
2574
+ auto len = av_image_fill_arrays(
2575
+ dst_data,
2576
+ dst_linesize,
2577
+ &data[offset],
2578
+ static_cast<AVPixelFormat>(pixel_format),
2579
+ width,
2580
+ height,
2581
+ align
2582
+ );
2583
+
2584
+ if (len < 0) {
2585
+ err = js_throw_error(env, NULL, av_err2str(len));
2586
+ assert(err == 0);
2587
+
2588
+ throw js_pending_exception;
2589
+ }
2590
+
2591
+ av_image_copy(
2592
+ dst_data,
2593
+ dst_linesize,
2594
+ frame->handle->data,
2595
+ frame->handle->linesize,
2596
+ static_cast<AVPixelFormat>(pixel_format),
2597
+ width,
2598
+ height
2599
+ );
2600
+ }
2601
+
2602
+ static int
2603
+ bare_ffmpeg_image_get_line_size(
2604
+ js_env_t *env,
2605
+ js_receiver_t,
2606
+ int32_t pixel_format,
2607
+ int32_t width,
2608
+ int32_t plane
2609
+ ) {
2610
+ return av_image_get_linesize(
2611
+ static_cast<AVPixelFormat>(pixel_format),
2612
+ width,
2613
+ plane
2614
+ );
2615
+ }
2616
+
2617
+ static int
2618
+ bare_ffmpeg_samples_buffer_size(
2619
+ js_env_t *env,
2620
+ js_receiver_t,
2621
+ int32_t sample_format,
2622
+ int32_t nb_channels,
2623
+ int32_t nb_samples,
2624
+ bool no_alignment
2625
+ ) {
2626
+ auto len = av_samples_get_buffer_size(
2627
+ NULL,
2628
+ nb_channels,
2629
+ nb_samples,
2630
+ static_cast<AVSampleFormat>(sample_format),
2631
+ no_alignment
2632
+ );
2633
+
2634
+ if (len < 0) {
2635
+ int err = js_throw_error(env, NULL, av_err2str(len));
2636
+ assert(err == 0);
2637
+
2638
+ throw js_pending_exception;
2639
+ }
2640
+
2641
+ return len;
2642
+ }
2643
+
2644
+ static int
2645
+ bare_ffmpeg_samples_fill(
2646
+ js_env_t *env,
2647
+ js_receiver_t,
2648
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2649
+ js_arraybuffer_span_t target,
2650
+ uint64_t offset,
2651
+ bool no_alignment
2652
+ ) {
2653
+ auto res = av_samples_fill_arrays(
2654
+ frame->handle->data,
2655
+ frame->handle->linesize,
2656
+ &target[offset],
2657
+ frame->handle->ch_layout.nb_channels,
2658
+ frame->handle->nb_samples,
2659
+ static_cast<AVSampleFormat>(frame->handle->format),
2660
+ no_alignment
2661
+ );
2662
+
2663
+ if (res < 0) {
2664
+ int err = js_throw_error(env, NULL, av_err2str(res));
2665
+ assert(err == 0);
2666
+
2667
+ throw js_pending_exception;
2668
+ }
2669
+
2670
+ return res;
2671
+ }
2672
+
2673
+ static void
2674
+ bare_ffmpeg_samples_copy(
2675
+ js_env_t *env,
2676
+ js_receiver_t,
2677
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> dst,
2678
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> src,
2679
+ int32_t dst_offset,
2680
+ int32_t src_offset,
2681
+ int32_t nb_samples
2682
+ ) {
2683
+ int err = av_samples_copy(
2684
+ dst->handle->data,
2685
+ src->handle->data,
2686
+ dst_offset,
2687
+ src_offset,
2688
+ nb_samples,
2689
+ src->handle->ch_layout.nb_channels,
2690
+ static_cast<AVSampleFormat>(src->handle->format)
2691
+ );
2692
+ if (err < 0) {
2693
+ err = js_throw_error(env, NULL, av_err2str(err));
2694
+ assert(err == 0);
2695
+
2696
+ throw js_pending_exception;
2697
+ }
2698
+ }
2699
+
2700
+ static int
2701
+ bare_ffmpeg_samples_read(
2702
+ js_env_t *env,
2703
+ js_receiver_t,
2704
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
2705
+ js_arraybuffer_span_t target,
2706
+ uint64_t offset,
2707
+ bool no_alignment
2708
+ ) {
2709
+ int err;
2710
+ uint8_t *dst_data[8];
2711
+ int dst_linesize[4];
2712
+
2713
+ auto len = av_samples_fill_arrays(
2714
+ dst_data,
2715
+ dst_linesize,
2716
+ &target[offset],
2717
+ frame->handle->ch_layout.nb_channels,
2718
+ frame->handle->nb_samples,
2719
+ static_cast<AVSampleFormat>(frame->handle->format),
2720
+ no_alignment
2721
+ );
2722
+ if (len < 0) {
2723
+ err = js_throw_error(env, NULL, av_err2str(len));
2724
+ assert(err == 0);
2725
+
2726
+ throw js_pending_exception;
2727
+ }
2728
+
2729
+ err = av_samples_copy(
2730
+ dst_data,
2731
+ frame->handle->data,
2732
+ 0,
2733
+ 0,
2734
+ frame->handle->nb_samples,
2735
+ frame->handle->ch_layout.nb_channels,
2736
+ static_cast<AVSampleFormat>(frame->handle->format)
2737
+ );
2738
+ if (err < 0) {
2739
+ err = js_throw_error(env, NULL, av_err2str(err));
2740
+ assert(err == 0);
2741
+
2742
+ throw js_pending_exception;
2743
+ }
2744
+
2745
+ return len;
2746
+ }
2747
+
2748
+ static js_arraybuffer_t
2749
+ bare_ffmpeg_packet_init(js_env_t *env, js_receiver_t) {
2750
+ int err;
2751
+
2752
+ js_arraybuffer_t handle;
2753
+
2754
+ bare_ffmpeg_packet_t *packet;
2755
+ err = js_create_arraybuffer(env, packet, handle);
2756
+ assert(err == 0);
2757
+
2758
+ packet->handle = av_packet_alloc();
2759
+
2760
+ return handle;
2761
+ }
2762
+
2763
+ static js_arraybuffer_t
2764
+ bare_ffmpeg_packet_init_from_buffer(
2765
+ js_env_t *env,
2766
+ js_receiver_t,
2767
+ js_arraybuffer_span_t data,
2768
+ uint64_t offset,
2769
+ uint64_t len
2770
+ ) {
2771
+ int err;
2772
+
2773
+ AVPacket *pkt = av_packet_alloc();
2774
+
2775
+ err = av_new_packet(pkt, static_cast<int>(len));
2776
+ assert(err == 0);
2777
+
2778
+ memcpy(pkt->data, &data[static_cast<size_t>(offset)], static_cast<size_t>(len));
2779
+
2780
+ js_arraybuffer_t handle;
2781
+
2782
+ bare_ffmpeg_packet_t *packet;
2783
+ err = js_create_arraybuffer(env, packet, handle);
2784
+ assert(err == 0);
2785
+
2786
+ packet->handle = pkt;
2787
+
2788
+ return handle;
2789
+ }
2790
+
2791
+ static void
2792
+ bare_ffmpeg_packet_unref(
2793
+ js_env_t *env,
2794
+ js_receiver_t,
2795
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2796
+ ) {
2797
+ av_packet_unref(packet->handle);
2798
+ }
2799
+
2800
+ static void
2801
+ bare_ffmpeg_packet_destroy(
2802
+ js_env_t *env,
2803
+ js_receiver_t,
2804
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2805
+ ) {
2806
+ av_packet_free(&packet->handle);
2807
+ }
2808
+
2809
+ static int32_t
2810
+ bare_ffmpeg_packet_get_stream_index(
2811
+ js_env_t *env,
2812
+ js_receiver_t,
2813
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2814
+ ) {
2815
+ return packet->handle->stream_index;
2816
+ }
2817
+
2818
+ static void
2819
+ bare_ffmpeg_packet_set_stream_index(
2820
+ js_env_t *env,
2821
+ js_receiver_t,
2822
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2823
+ int32_t value
2824
+ ) {
2825
+ packet->handle->stream_index = value;
2826
+ }
2827
+
2828
+ static js_arraybuffer_t
2829
+ bare_ffmpeg_packet_get_data(
2830
+ js_env_t *env,
2831
+ js_receiver_t,
2832
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2833
+ ) {
2834
+ int err;
2835
+
2836
+ auto size = static_cast<size_t>(packet->handle->size);
2837
+
2838
+ js_arraybuffer_t handle;
2839
+
2840
+ uint8_t *data;
2841
+ err = js_create_arraybuffer(env, size, data, handle);
2842
+ assert(err == 0);
2843
+
2844
+ memcpy(data, packet->handle->data, size);
2845
+
2846
+ return handle;
2847
+ }
2848
+
2849
+ static void
2850
+ bare_ffmpeg_packet_set_data(
2851
+ js_env_t *env,
2852
+ js_receiver_t,
2853
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2854
+ js_arraybuffer_span_t data,
2855
+ uint32_t offset,
2856
+ uint32_t len
2857
+ ) {
2858
+ int err;
2859
+
2860
+ assert(offset + len <= data.size());
2861
+
2862
+ av_packet_unref(packet->handle);
2863
+
2864
+ err = av_new_packet(packet->handle, static_cast<int>(len));
2865
+ assert(err == 0);
2866
+
2867
+ memcpy(packet->handle->data, &data[offset], len);
2868
+ }
2869
+
2870
+ static std::vector<js_arraybuffer_t>
2871
+ bare_ffmpeg_packet_get_side_data(
2872
+ js_env_t *env,
2873
+ js_receiver_t,
2874
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2875
+ ) {
2876
+ std::vector<js_arraybuffer_t> res{};
2877
+
2878
+ int count = packet->handle->side_data_elems;
2879
+ if (count == 0) return res;
2880
+
2881
+ for (int i = 0; i < count; i++) {
2882
+ js_arraybuffer_t handle;
2883
+ bare_ffmpeg_side_data_t *sd;
2884
+ int err = js_create_arraybuffer(env, sd, handle);
2885
+ assert(err == 0);
2886
+
2887
+ sd->handle = &packet->handle->side_data[i];
2888
+
2889
+ res.push_back(handle);
2890
+ }
2891
+
2892
+ return res;
2893
+ }
2894
+
2895
+ static void
2896
+ bare_ffmpeg_packet_set_side_data(
2897
+ js_env_t *env,
2898
+ js_receiver_t,
2899
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2900
+ std::vector<js_object_t> side_data_array
2901
+ ) {
2902
+ for (js_object_t side_data : side_data_array) {
2903
+ int err;
2904
+
2905
+ int32_t type;
2906
+ err = js_get_property(env, side_data, "type", type);
2907
+ assert(err == 0);
2908
+
2909
+ js_arraybuffer_span_t buf;
2910
+ err = js_get_property(env, side_data, "buffer", buf);
2911
+ assert(err == 0);
2912
+
2913
+ int32_t offset;
2914
+ err = js_get_property(env, side_data, "offset", offset);
2915
+ assert(err == 0);
2916
+
2917
+ int32_t len;
2918
+ err = js_get_property(env, side_data, "length", len);
2919
+ assert(err == 0);
2920
+
2921
+ uint8_t *data = av_packet_new_side_data(packet->handle, static_cast<AVPacketSideDataType>(type), static_cast<size_t>(len));
2922
+ memcpy(data, &buf[static_cast<size_t>(offset)], static_cast<size_t>(len));
2923
+ }
2924
+ }
2925
+
2926
+ static bool
2927
+ bare_ffmpeg_packet_is_keyframe(
2928
+ js_env_t *,
2929
+ js_receiver_t,
2930
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2931
+ ) {
2932
+ return packet->handle->flags & AV_PKT_FLAG_KEY;
2933
+ }
2934
+
2935
+ static void
2936
+ bare_ffmpeg_packet_set_is_keyframe(
2937
+ js_env_t *,
2938
+ js_receiver_t,
2939
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2940
+ bool has_key_frame
2941
+ ) {
2942
+ if (has_key_frame) {
2943
+ packet->handle->flags |= AV_PKT_FLAG_KEY;
2944
+ } else {
2945
+ packet->handle->flags &= ~AV_PKT_FLAG_KEY;
2946
+ }
2947
+ }
2948
+
2949
+ static int64_t
2950
+ bare_ffmpeg_packet_get_dts(
2951
+ js_env_t *env,
2952
+ js_receiver_t,
2953
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2954
+ ) {
2955
+ int64_t ts = packet->handle->dts;
2956
+
2957
+ if (ts == AV_NOPTS_VALUE) return -1;
2958
+
2959
+ return ts;
2960
+ }
2961
+
2962
+ static void
2963
+ bare_ffmpeg_packet_set_dts(
2964
+ js_env_t *env,
2965
+ js_receiver_t,
2966
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2967
+ int64_t value
2968
+ ) {
2969
+ packet->handle->dts = value;
2970
+ }
2971
+
2972
+ static int64_t
2973
+ bare_ffmpeg_packet_get_pts(
2974
+ js_env_t *env,
2975
+ js_receiver_t,
2976
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
2977
+ ) {
2978
+ int64_t ts = packet->handle->pts;
2979
+
2980
+ if (ts == AV_NOPTS_VALUE) return -1;
2981
+
2982
+ return ts;
2983
+ }
2984
+
2985
+ static void
2986
+ bare_ffmpeg_packet_set_pts(
2987
+ js_env_t *env,
2988
+ js_receiver_t,
2989
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
2990
+ int64_t value
2991
+ ) {
2992
+ packet->handle->pts = value;
2993
+ }
2994
+
2995
+ static js_arraybuffer_t
2996
+ bare_ffmpeg_packet_get_time_base(
2997
+ js_env_t *env,
2998
+ js_receiver_t,
2999
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
3000
+ ) {
3001
+ int err;
3002
+
3003
+ js_arraybuffer_t result;
3004
+
3005
+ int32_t *data;
3006
+ err = js_create_arraybuffer(env, 2, data, result);
3007
+ assert(err == 0);
3008
+
3009
+ data[0] = packet->handle->time_base.num;
3010
+ data[1] = packet->handle->time_base.den;
3011
+
3012
+ return result;
3013
+ }
3014
+
3015
+ static void
3016
+ bare_ffmpeg_packet_set_time_base(
3017
+ js_env_t *env,
3018
+ js_receiver_t,
3019
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
3020
+ int num,
3021
+ int den
3022
+ ) {
3023
+ packet->handle->time_base.num = num;
3024
+ packet->handle->time_base.den = den;
3025
+ }
3026
+
3027
+ static void
3028
+ bare_ffmpeg_packet_rescale_ts(
3029
+ js_env_t *env,
3030
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
3031
+ int32_t src_num,
3032
+ int32_t src_den,
3033
+ int32_t dst_num,
3034
+ int32_t dst_den
3035
+ ) {
3036
+ av_packet_rescale_ts(
3037
+ packet->handle,
3038
+ {src_num, src_den},
3039
+ {dst_num, dst_den}
3040
+ );
3041
+ }
3042
+
3043
+ static int64_t
3044
+ bare_ffmpeg_packet_get_duration(
3045
+ js_env_t *env,
3046
+ js_receiver_t,
3047
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
3048
+ ) {
3049
+ return packet->handle->duration;
3050
+ }
3051
+
3052
+ static void
3053
+ bare_ffmpeg_packet_set_duration(
3054
+ js_env_t *env,
3055
+ js_receiver_t,
3056
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
3057
+ int64_t value
3058
+ ) {
3059
+ packet->handle->duration = value;
3060
+ }
3061
+
3062
+ static int32_t
3063
+ bare_ffmpeg_packet_get_flags(
3064
+ js_env_t *env,
3065
+ js_receiver_t,
3066
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
3067
+ ) {
3068
+ return packet->handle->flags;
3069
+ }
3070
+
3071
+ static void
3072
+ bare_ffmpeg_packet_set_flags(
3073
+ js_env_t *env,
3074
+ js_receiver_t,
3075
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
3076
+ int32_t value
3077
+ ) {
3078
+ packet->handle->flags = value;
3079
+ }
3080
+
3081
+ static void
3082
+ bare_ffmpeg_packet_copy_props(
3083
+ js_env_t *env,
3084
+ js_receiver_t,
3085
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> dst,
3086
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> src
3087
+ ) {
3088
+ int err;
3089
+
3090
+ err = av_packet_copy_props(dst->handle, src->handle);
3091
+ if (err < 0) {
3092
+ err = js_throw_error(env, NULL, av_err2str(err));
3093
+ assert(err == 0);
3094
+
3095
+ throw js_pending_exception;
3096
+ }
3097
+ }
3098
+
3099
+ static int
3100
+ bare_ffmpeg_side_data_get_type(
3101
+ js_env_t *env,
3102
+ js_receiver_t,
3103
+ js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
3104
+ ) {
3105
+ return side_data->handle->type;
3106
+ }
3107
+
3108
+ static std::string
3109
+ bare_ffmpeg_side_data_get_name(
3110
+ js_env_t *env,
3111
+ js_receiver_t,
3112
+ js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
3113
+ ) {
3114
+ return av_packet_side_data_name(side_data->handle->type);
3115
+ }
3116
+
3117
+ static js_arraybuffer_t
3118
+ bare_ffmpeg_side_data_get_data(
3119
+ js_env_t *env,
3120
+ js_receiver_t,
3121
+ js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
3122
+ ) {
3123
+ js_arraybuffer_t handle;
3124
+ uint8_t *buf;
3125
+ int err = js_create_arraybuffer(env, side_data->handle->size, buf, handle);
3126
+ assert(err == 0);
3127
+
3128
+ memcpy(buf, side_data->handle->data, side_data->handle->size);
3129
+
3130
+ return handle;
3131
+ }
3132
+
3133
+ static js_arraybuffer_t
3134
+ bare_ffmpeg_scaler_init(
3135
+ js_env_t *env,
3136
+ js_receiver_t,
3137
+ int64_t source_format,
3138
+ int32_t source_width,
3139
+ int32_t source_height,
3140
+ int64_t target_format,
3141
+ int32_t target_width,
3142
+ int32_t target_height
3143
+ ) {
3144
+ int err;
3145
+
3146
+ js_arraybuffer_t handle;
3147
+
3148
+ bare_ffmpeg_scaler_t *scaler;
3149
+ err = js_create_arraybuffer(env, scaler, handle);
3150
+ assert(err == 0);
3151
+
3152
+ scaler->handle = sws_getContext(
3153
+ source_width,
3154
+ source_height,
3155
+ static_cast<AVPixelFormat>(source_format),
3156
+ target_width,
3157
+ target_height,
3158
+ static_cast<AVPixelFormat>(target_format),
3159
+ SWS_BICUBIC,
3160
+ NULL,
3161
+ NULL,
3162
+ NULL
3163
+ );
3164
+
3165
+ return handle;
3166
+ }
3167
+
3168
+ static void
3169
+ bare_ffmpeg_scaler_destroy(
3170
+ js_env_t *env,
3171
+ js_receiver_t,
3172
+ js_arraybuffer_span_of_t<bare_ffmpeg_scaler_t, 1> scaler
3173
+ ) {
3174
+ sws_freeContext(scaler->handle);
3175
+ }
3176
+
3177
+ static int
3178
+ bare_ffmpeg_scaler_scale(
3179
+ js_env_t *env,
3180
+ js_receiver_t,
3181
+ js_arraybuffer_span_of_t<bare_ffmpeg_scaler_t, 1> scaler,
3182
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> source,
3183
+ int y,
3184
+ int height,
3185
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> target
3186
+ ) {
3187
+ return sws_scale(
3188
+ scaler->handle,
3189
+ reinterpret_cast<const uint8_t *const *>(source->handle->data),
3190
+ source->handle->linesize,
3191
+ y,
3192
+ height,
3193
+ target->handle->data,
3194
+ target->handle->linesize
3195
+ );
3196
+ }
3197
+
3198
+ static js_arraybuffer_t
3199
+ bare_ffmpeg_dictionary_init(
3200
+ js_env_t *env,
3201
+ js_receiver_t
3202
+ ) {
3203
+ int err;
3204
+
3205
+ js_arraybuffer_t handle;
3206
+
3207
+ bare_ffmpeg_dictionary_t *dict;
3208
+ err = js_create_arraybuffer(env, dict, handle);
3209
+ assert(err == 0);
3210
+
3211
+ dict->handle = NULL;
3212
+
3213
+ return handle;
3214
+ }
3215
+
3216
+ static void
3217
+ bare_ffmpeg_dictionary_destroy(
3218
+ js_env_t *env,
3219
+ js_receiver_t,
3220
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict
3221
+ ) {
3222
+ av_dict_free(&dict->handle);
3223
+ }
3224
+
3225
+ static void
3226
+ bare_ffmpeg_dictionary_set_entry(
3227
+ js_env_t *env,
3228
+ js_receiver_t,
3229
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict,
3230
+ std::string key,
3231
+ std::string value
3232
+ ) {
3233
+ int err;
3234
+
3235
+ err = av_dict_set(&dict->handle, key.c_str(), value.c_str(), 0);
3236
+ assert(err == 0);
3237
+ }
3238
+
3239
+ static std::vector<std::tuple<const char *, const char *>>
3240
+ bare_ffmpeg_dictionary_get_entries(
3241
+ js_env_t *env,
3242
+ js_receiver_t,
3243
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict
3244
+ ) {
3245
+ std::vector<std::tuple<const char *, const char *>> entries{};
3246
+
3247
+ const AVDictionaryEntry *entry = nullptr;
3248
+
3249
+ while ((entry = av_dict_iterate(dict->handle, entry))) {
3250
+ entries.emplace_back(entry->key, entry->value);
3251
+ }
3252
+
3253
+ return entries;
3254
+ }
3255
+
3256
+ static std::optional<std::string>
3257
+ bare_ffmpeg_dictionary_get_entry(
3258
+ js_env_t *env,
3259
+ js_receiver_t,
3260
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict,
3261
+ std::string key
3262
+ ) {
3263
+ AVDictionaryEntry *entry = av_dict_get(dict->handle, key.c_str(), NULL, 0);
3264
+
3265
+ if (entry == NULL) {
3266
+ return std::nullopt;
3267
+ }
3268
+
3269
+ return std::string{entry->value};
3270
+ }
3271
+
3272
+ static js_arraybuffer_t
3273
+ bare_ffmpeg_resampler_init(
3274
+ js_env_t *env,
3275
+ js_receiver_t,
3276
+ int32_t in_rate,
3277
+ int32_t in_fmt,
3278
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> in_layout,
3279
+ int32_t out_rate,
3280
+ int32_t out_fmt,
3281
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> out_layout
3282
+ ) {
3283
+ int err;
3284
+
3285
+ js_arraybuffer_t handle;
3286
+
3287
+ bare_ffmpeg_resampler_t *resampler;
3288
+ err = js_create_arraybuffer(env, resampler, handle);
3289
+ assert(err == 0);
3290
+
3291
+ resampler->handle = swr_alloc();
3292
+
3293
+ err = swr_alloc_set_opts2(
3294
+ &resampler->handle,
3295
+ &out_layout->handle,
3296
+ static_cast<AVSampleFormat>(out_fmt),
3297
+ out_rate,
3298
+ &in_layout->handle,
3299
+ static_cast<AVSampleFormat>(in_fmt),
3300
+ in_rate,
3301
+ 0,
3302
+ NULL
3303
+ );
3304
+
3305
+ if (err < 0) {
3306
+ swr_free(&resampler->handle);
3307
+
3308
+ err = js_throw_error(env, NULL, av_err2str(err));
3309
+ assert(err == 0);
3310
+
3311
+ throw js_pending_exception;
3312
+ }
3313
+
3314
+ err = swr_init(resampler->handle);
3315
+ if (err < 0) {
3316
+ swr_free(&resampler->handle);
3317
+
3318
+ err = js_throw_error(env, NULL, av_err2str(err));
3319
+ assert(err == 0);
3320
+
3321
+ throw js_pending_exception;
3322
+ }
3323
+
3324
+ return handle;
3325
+ }
3326
+
3327
+ static int64_t
3328
+ bare_ffmpeg_resampler_convert_frames(
3329
+ js_env_t *env,
3330
+ js_receiver_t,
3331
+ js_arraybuffer_span_of_t<bare_ffmpeg_resampler_t, 1> resampler,
3332
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> in_frame,
3333
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> out_frame
3334
+ ) {
3335
+ int err;
3336
+
3337
+ auto result = swr_convert(
3338
+ resampler->handle,
3339
+ (uint8_t **) out_frame->handle->data,
3340
+ out_frame->handle->nb_samples,
3341
+ (const uint8_t **) in_frame->handle->data,
3342
+ in_frame->handle->nb_samples
3343
+ );
3344
+
3345
+ if (result < 0) {
3346
+ err = js_throw_error(env, NULL, av_err2str(result));
3347
+ assert(err == 0);
3348
+
3349
+ throw js_pending_exception;
3350
+ }
3351
+
3352
+ return result;
3353
+ }
3354
+
3355
+ static int64_t
3356
+ bare_ffmpeg_resampler_get_delay(
3357
+ js_env_t *env,
3358
+ js_receiver_t,
3359
+ js_arraybuffer_span_of_t<bare_ffmpeg_resampler_t, 1> resampler,
3360
+ int64_t base
3361
+ ) {
3362
+ return swr_get_delay(resampler->handle, base);
3363
+ }
3364
+
3365
+ static int64_t
3366
+ bare_ffmpeg_resampler_flush(
3367
+ js_env_t *env,
3368
+ js_receiver_t,
3369
+ js_arraybuffer_span_of_t<bare_ffmpeg_resampler_t, 1> resampler,
3370
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> out_frame
3371
+ ) {
3372
+ int err;
3373
+
3374
+ auto result = swr_convert(
3375
+ resampler->handle,
3376
+ out_frame->handle->data,
3377
+ out_frame->handle->nb_samples,
3378
+ NULL,
3379
+ 0
3380
+ );
3381
+
3382
+ if (result < 0) {
3383
+ err = js_throw_error(env, NULL, av_err2str(result));
3384
+ assert(err == 0);
3385
+
3386
+ throw js_pending_exception;
3387
+ }
3388
+
3389
+ out_frame->handle->nb_samples = result;
3390
+
3391
+ return result;
3392
+ }
3393
+
3394
+ static void
3395
+ bare_ffmpeg_resampler_destroy(
3396
+ js_env_t *env,
3397
+ js_receiver_t,
3398
+ js_arraybuffer_span_of_t<bare_ffmpeg_resampler_t, 1> resampler
3399
+ ) {
3400
+ swr_free(&resampler->handle);
3401
+ }
3402
+
3403
+ static js_arraybuffer_t
3404
+ bare_ffmpeg_channel_layout_copy(
3405
+ js_env_t *env,
3406
+ js_receiver_t,
3407
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
3408
+ ) {
3409
+ int err;
3410
+
3411
+ js_arraybuffer_t result;
3412
+
3413
+ bare_ffmpeg_channel_layout_t *copy;
3414
+ err = js_create_arraybuffer(env, copy, result);
3415
+ assert(err == 0);
3416
+
3417
+ err = av_channel_layout_copy(&copy->handle, &layout->handle);
3418
+ assert(err == 0);
3419
+
3420
+ return result;
3421
+ }
3422
+
3423
+ static int
3424
+ bare_ffmpeg_channel_layout_get_nb_channels(
3425
+ js_env_t *env,
3426
+ js_receiver_t,
3427
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
3428
+ ) {
3429
+ return layout->handle.nb_channels;
3430
+ }
3431
+
3432
+ static uint64_t
3433
+ bare_ffmpeg_channel_layout_get_mask(
3434
+ js_env_t *env,
3435
+ js_receiver_t,
3436
+ js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
3437
+ ) {
3438
+ return layout->handle.u.mask;
3439
+ }
3440
+
3441
+ static js_arraybuffer_t
3442
+ bare_ffmpeg_channel_layout_from_mask(
3443
+ js_env_t *env,
3444
+ js_receiver_t,
3445
+ uint64_t mask
3446
+ ) {
3447
+ int err;
3448
+
3449
+ js_arraybuffer_t result;
3450
+
3451
+ bare_ffmpeg_channel_layout_t *layout;
3452
+ err = js_create_arraybuffer(env, layout, result);
3453
+ assert(err == 0);
3454
+
3455
+ err = av_channel_layout_from_mask(&layout->handle, mask);
3456
+ assert(err == 0);
3457
+
3458
+ return result;
3459
+ }
3460
+
3461
+ static js_arraybuffer_t
3462
+ bare_ffmpeg_audio_fifo_init(
3463
+ js_env_t *env,
3464
+ js_receiver_t,
3465
+ int32_t sample_fmt,
3466
+ int32_t channels,
3467
+ int32_t nb_samples
3468
+ ) {
3469
+ int err;
3470
+
3471
+ js_arraybuffer_t handle;
3472
+
3473
+ bare_ffmpeg_audio_fifo_t *fifo;
3474
+ err = js_create_arraybuffer(env, fifo, handle);
3475
+ assert(err == 0);
3476
+
3477
+ fifo->handle = av_audio_fifo_alloc(
3478
+ static_cast<AVSampleFormat>(sample_fmt),
3479
+ channels,
3480
+ nb_samples
3481
+ );
3482
+
3483
+ return handle;
3484
+ }
3485
+
3486
+ static void
3487
+ bare_ffmpeg_audio_fifo_destroy(
3488
+ js_env_t *env,
3489
+ js_receiver_t,
3490
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
3491
+ ) {
3492
+ av_audio_fifo_free(fifo->handle);
3493
+ }
3494
+
3495
+ static int
3496
+ bare_ffmpeg_audio_fifo_write(
3497
+ js_env_t *env,
3498
+ js_receiver_t,
3499
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
3500
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
3501
+ ) {
3502
+ int err;
3503
+
3504
+ auto len = av_audio_fifo_write(fifo->handle, (void **) frame->handle->data, frame->handle->nb_samples);
3505
+
3506
+ if (len < 0) {
3507
+ err = js_throw_error(env, NULL, av_err2str(len));
3508
+ assert(err == 0);
3509
+
3510
+ throw js_pending_exception;
3511
+ }
3512
+
3513
+ return len;
3514
+ }
3515
+
3516
+ static int
3517
+ bare_ffmpeg_audio_fifo_read(
3518
+ js_env_t *env,
3519
+ js_receiver_t,
3520
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
3521
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
3522
+ int32_t nb_samples
3523
+ ) {
3524
+ int err;
3525
+
3526
+ auto len = av_audio_fifo_read(fifo->handle, (void **) frame->handle->data, nb_samples);
3527
+
3528
+ if (len < 0) {
3529
+ err = js_throw_error(env, NULL, av_err2str(len));
3530
+ assert(err == 0);
3531
+
3532
+ throw js_pending_exception;
3533
+ }
3534
+
3535
+ return len;
3536
+ }
3537
+
3538
+ static int
3539
+ bare_ffmpeg_audio_fifo_peek(
3540
+ js_env_t *env,
3541
+ js_receiver_t,
3542
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
3543
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
3544
+ int32_t nb_samples
3545
+ ) {
3546
+ int err;
3547
+
3548
+ auto len = av_audio_fifo_peek(fifo->handle, (void **) frame->handle->data, nb_samples);
3549
+
3550
+ if (len < 0) {
3551
+ err = js_throw_error(env, NULL, av_err2str(len));
3552
+ assert(err == 0);
3553
+
3554
+ throw js_pending_exception;
3555
+ }
3556
+
3557
+ return len;
3558
+ }
3559
+
3560
+ static int
3561
+ bare_ffmpeg_audio_fifo_drain(
3562
+ js_env_t *env,
3563
+ js_receiver_t,
3564
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
3565
+ int32_t nb_samples
3566
+ ) {
3567
+ int err;
3568
+
3569
+ auto len = av_audio_fifo_drain(fifo->handle, nb_samples);
3570
+
3571
+ if (len < 0) {
3572
+ err = js_throw_error(env, NULL, av_err2str(len));
3573
+ assert(err == 0);
3574
+
3575
+ throw js_pending_exception;
3576
+ }
3577
+
3578
+ return len;
3579
+ }
3580
+
3581
+ static void
3582
+ bare_ffmpeg_audio_fifo_reset(
3583
+ js_env_t *env,
3584
+ js_receiver_t,
3585
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
3586
+ ) {
3587
+ av_audio_fifo_reset(fifo->handle);
3588
+ }
3589
+
3590
+ static int
3591
+ bare_ffmpeg_audio_fifo_size(
3592
+ js_env_t *env,
3593
+ js_receiver_t,
3594
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
3595
+ ) {
3596
+ return av_audio_fifo_size(fifo->handle);
3597
+ }
3598
+
3599
+ static int
3600
+ bare_ffmpeg_audio_fifo_space(
3601
+ js_env_t *env,
3602
+ js_receiver_t,
3603
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
3604
+ ) {
3605
+ return av_audio_fifo_space(fifo->handle);
3606
+ }
3607
+
3608
+ static js_arraybuffer_t
3609
+ bare_ffmpeg_rational_d2q(
3610
+ js_env_t *env,
3611
+ js_receiver_t,
3612
+ double num
3613
+ ) {
3614
+ int err;
3615
+
3616
+ auto rational = av_d2q(num, 1 << 26);
3617
+
3618
+ js_arraybuffer_t result;
3619
+
3620
+ int32_t *data;
3621
+ err = js_create_arraybuffer(env, 2, data, result);
3622
+ assert(err == 0);
3623
+
3624
+ data[0] = rational.num;
3625
+ data[1] = rational.den;
3626
+
3627
+ return result;
3628
+ }
3629
+
3630
+ static js_arraybuffer_t
3631
+ bare_ffmpeg_filter_get_by_name(
3632
+ js_env_t *env,
3633
+ js_receiver_t,
3634
+ std::string name
3635
+ ) {
3636
+ int err;
3637
+
3638
+ js_arraybuffer_t handle;
3639
+ bare_ffmpeg_filter_t *filter;
3640
+ err = js_create_arraybuffer(env, filter, handle);
3641
+ assert(err == 0);
3642
+
3643
+ filter->handle = avfilter_get_by_name(name.c_str());
3644
+ if (filter->handle == nullptr) {
3645
+ err = js_throw_errorf(env, nullptr, "No Filter found for '%s' name", name.c_str());
3646
+ assert(err == 0);
3647
+
3648
+ throw js_pending_exception;
3649
+ }
3650
+
3651
+ return handle;
3652
+ }
3653
+
3654
+ static js_arraybuffer_t
3655
+ bare_ffmpeg_filter_context_init(
3656
+ js_env_t *env,
3657
+ js_receiver_t
3658
+ ) {
3659
+ js_arraybuffer_t handle;
3660
+ bare_ffmpeg_filter_context_t *filter_ctx;
3661
+ int err = js_create_arraybuffer(env, filter_ctx, handle);
3662
+ assert(err == 0);
3663
+
3664
+ return handle;
3665
+ }
3666
+
3667
+ static js_arraybuffer_t
3668
+ bare_ffmpeg_filter_graph_init(
3669
+ js_env_t *env,
3670
+ js_receiver_t
3671
+ ) {
3672
+ js_arraybuffer_t handle;
3673
+ bare_ffmpeg_filter_graph_t *filter_graph;
3674
+ int err = js_create_arraybuffer(env, filter_graph, handle);
3675
+ assert(err == 0);
3676
+
3677
+ filter_graph->handle = avfilter_graph_alloc();
3678
+ assert(filter_graph->handle != nullptr);
3679
+
3680
+ return handle;
3681
+ }
3682
+
3683
+ static void
3684
+ bare_ffmpeg_filter_graph_destroy(
3685
+ js_env_t *env,
3686
+ js_receiver_t,
3687
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_graph_t, 1> filter_graph
3688
+ ) {
3689
+ avfilter_graph_free(&filter_graph->handle);
3690
+ }
3691
+
3692
+ static void
3693
+ bare_ffmpeg_filter_graph_create_filter(
3694
+ js_env_t *env,
3695
+ js_receiver_t,
3696
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_graph_t, 1> graph,
3697
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_context_t, 1> filter_context,
3698
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_t, 1> filter,
3699
+ std::string name,
3700
+ std::optional<std::string> args
3701
+ ) {
3702
+ int err = avfilter_graph_create_filter(
3703
+ &filter_context->handle,
3704
+ filter->handle,
3705
+ name.c_str(),
3706
+ args.has_value() ? args.value().c_str() : nullptr,
3707
+ nullptr,
3708
+ graph->handle
3709
+ );
3710
+
3711
+ if (err < 0) {
3712
+ err = js_throw_error(env, nullptr, av_err2str(err));
3713
+ assert(err == 0);
3714
+
3715
+ throw js_pending_exception;
3716
+ }
3717
+ }
3718
+
3719
+ static void
3720
+ bare_ffmpeg_filter_graph_parse(
3721
+ js_env_t *env,
3722
+ js_receiver_t,
3723
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_graph_t, 1> graph,
3724
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> inputs,
3725
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> outputs,
3726
+ std::string filter_description
3727
+ ) {
3728
+ int err = avfilter_graph_parse(graph->handle, filter_description.c_str(), inputs->handle, outputs->handle, nullptr);
3729
+ if (err < 0) {
3730
+ err = js_throw_error(env, nullptr, av_err2str(err));
3731
+ assert(err == 0);
3732
+
3733
+ throw js_pending_exception;
3734
+ }
3735
+ }
3736
+
3737
+ static void
3738
+ bare_ffmpeg_filter_graph_configure(
3739
+ js_env_t *env,
3740
+ js_receiver_t,
3741
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_graph_t, 1> graph
3742
+ ) {
3743
+ int err = avfilter_graph_config(graph->handle, nullptr);
3744
+ if (err < 0) {
3745
+ err = js_throw_error(env, nullptr, av_err2str(err));
3746
+ assert(err == 0);
3747
+
3748
+ throw js_pending_exception;
3749
+ }
3750
+ }
3751
+
3752
+ static int
3753
+ bare_ffmpeg_filter_graph_push_frame(
3754
+ js_env_t *env,
3755
+ js_receiver_t,
3756
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_context_t, 1> ctx,
3757
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
3758
+ ) {
3759
+ return av_buffersrc_add_frame(ctx->handle, frame->handle);
3760
+ }
3761
+
3762
+ static int
3763
+ bare_ffmpeg_filter_graph_pull_frame(
3764
+ js_env_t *env,
3765
+ js_receiver_t,
3766
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_context_t, 1> ctx,
3767
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
3768
+ ) {
3769
+ return av_buffersink_get_frame(ctx->handle, frame->handle);
3770
+ }
3771
+
3772
+ static js_arraybuffer_t
3773
+ bare_ffmpeg_filter_inout_init(
3774
+ js_env_t *env,
3775
+ js_receiver_t
3776
+ ) {
3777
+ js_arraybuffer_t handle;
3778
+ bare_ffmpeg_filter_inout_t *filter_inout;
3779
+ int err = js_create_arraybuffer(env, filter_inout, handle);
3780
+ assert(err == 0);
3781
+
3782
+ filter_inout->handle = avfilter_inout_alloc();
3783
+ assert(filter_inout->handle);
3784
+
3785
+ return handle;
3786
+ }
3787
+
3788
+ static void
3789
+ bare_ffmpeg_filter_inout_destroy(
3790
+ js_env_t *env,
3791
+ js_receiver_t,
3792
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout
3793
+ ) {
3794
+ avfilter_inout_free(&filter_inout->handle);
3795
+ }
3796
+
3797
+ static std::optional<std::string>
3798
+ bare_ffmpeg_filter_inout_get_name(
3799
+ js_env_t *env,
3800
+ js_receiver_t,
3801
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout
3802
+ ) {
3803
+ if (!filter_inout->handle->name) return std::nullopt;
3804
+ return filter_inout->handle->name;
3805
+ }
3806
+
3807
+ static void
3808
+ bare_ffmpeg_filter_inout_set_name(
3809
+ js_env_t *env,
3810
+ js_receiver_t,
3811
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout,
3812
+ std::string name
3813
+ ) {
3814
+ if (filter_inout->handle->name) {
3815
+ av_free(filter_inout->handle->name);
3816
+ }
3817
+ filter_inout->handle->name = av_strdup(name.c_str());
3818
+ }
3819
+
3820
+ static void
3821
+ bare_ffmpeg_filter_inout_set_filter_context(
3822
+ js_env_t *env,
3823
+ js_receiver_t,
3824
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout,
3825
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_context_t, 1> filter_ctx
3826
+ ) {
3827
+ filter_inout->handle->filter_ctx = filter_ctx->handle;
3828
+ }
3829
+
3830
+ static int
3831
+ bare_ffmpeg_filter_inout_get_pad_idx(
3832
+ js_env_t *env,
3833
+ js_receiver_t,
3834
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout
3835
+ ) {
3836
+ return filter_inout->handle->pad_idx;
3837
+ }
3838
+
3839
+ static void
3840
+ bare_ffmpeg_filter_inout_set_pad_idx(
3841
+ js_env_t *env,
3842
+ js_receiver_t,
3843
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout,
3844
+ int pad_idx
3845
+ ) {
3846
+ filter_inout->handle->pad_idx = pad_idx;
3847
+ }
3848
+
3849
+ static void
3850
+ bare_ffmpeg_filter_inout_set_next(
3851
+ js_env_t *env,
3852
+ js_receiver_t,
3853
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> filter_inout,
3854
+ js_arraybuffer_span_of_t<bare_ffmpeg_filter_inout_t, 1> next
3855
+ ) {
3856
+ filter_inout->handle->next = next->handle;
3857
+ }
3858
+
3859
+ static int64_t
3860
+ bare_ffmpeg_rational_rescale_q(
3861
+ int64_t ts,
3862
+ int32_t bq_num,
3863
+ int32_t bq_den,
3864
+ int32_t cq_num,
3865
+ int32_t cq_den,
3866
+ int64_t av_round
3867
+ ) {
3868
+ return av_rescale_q_rnd(
3869
+ ts,
3870
+ {bq_num, bq_den},
3871
+ {cq_num, cq_den},
3872
+ static_cast<AVRounding>(av_round)
3873
+ );
3874
+ }
3875
+
3876
+ static void
3877
+ bare_ffmpeg_set_option(
3878
+ js_env_t *env,
3879
+ js_receiver_t,
3880
+ js_arraybuffer_span_t handle,
3881
+ std::string key,
3882
+ std::string value,
3883
+ int flags
3884
+ ) {
3885
+ int err;
3886
+
3887
+ AVClass **owner = reinterpret_cast<AVClass **>(handle.data());
3888
+ if (!owner || !*owner) {
3889
+ int err = js_throw_error(env, NULL, "object does not have AVClass");
3890
+ assert(err == 0);
3891
+ throw js_pending_exception;
3892
+ }
3893
+
3894
+ err = av_opt_set(
3895
+ *owner,
3896
+ key.c_str(),
3897
+ value.c_str(),
3898
+ flags
3899
+ );
3900
+ if (err < 0) {
3901
+ err = js_throw_error(env, NULL, av_err2str(err));
3902
+ assert(err == 0);
3903
+ throw js_pending_exception;
3904
+ }
3905
+ }
3906
+
3907
+ static std::optional<std::string>
3908
+ bare_ffmpeg_get_option(
3909
+ js_env_t *env,
3910
+ js_receiver_t,
3911
+ js_arraybuffer_span_t handle,
3912
+ std::string key,
3913
+ int flags
3914
+ ) {
3915
+ int err;
3916
+ char *buf = NULL;
3917
+ AVClass **owner = reinterpret_cast<AVClass **>(handle.data());
3918
+ if (!owner || !*owner) {
3919
+ err = js_throw_error(env, NULL, "object does not have AVClass");
3920
+ assert(err == 0);
3921
+ throw js_pending_exception;
3922
+ }
3923
+
3924
+ err = av_opt_get(
3925
+ *owner,
3926
+ key.c_str(),
3927
+ flags,
3928
+ reinterpret_cast<uint8_t **>(&buf)
3929
+ );
3930
+ if (err < 0) {
3931
+ err = js_throw_error(env, NULL, av_err2str(err));
3932
+ assert(err == 0);
3933
+ throw js_pending_exception;
3934
+ }
3935
+
3936
+ if (!buf) {
3937
+ return std::nullopt;
3938
+ }
3939
+
3940
+ std::string result(buf);
3941
+ av_freep(&buf);
3942
+ return result;
3943
+ }
3944
+
3945
+ static std::vector<std::string>
3946
+ bare_ffmpeg_list_option_names(
3947
+ js_env_t *env,
3948
+ js_receiver_t,
3949
+ js_arraybuffer_span_t avclass_owner_handle,
3950
+ int flags
3951
+ ) {
3952
+ AVClass **owner = reinterpret_cast<AVClass **>(avclass_owner_handle.data());
3953
+ if (!owner || !*owner) {
3954
+ int err = js_throw_error(env, NULL, "object does not have AVClass");
3955
+ assert(err == 0);
3956
+
3957
+ throw js_pending_exception;
3958
+ }
3959
+
3960
+ std::unordered_set<std::string> unique_names;
3961
+
3962
+ auto collect = [&](void *target) {
3963
+ const AVOption *opt = nullptr;
3964
+ while ((opt = av_opt_next(target, opt))) {
3965
+ if (opt->name) {
3966
+ unique_names.insert(opt->name);
3967
+ }
3968
+ }
3969
+ };
3970
+
3971
+ collect(*owner);
3972
+
3973
+ if (flags & AV_OPT_SEARCH_CHILDREN) {
3974
+ void *child = nullptr;
3975
+ while ((child = av_opt_child_next(*owner, child))) {
3976
+ collect(child);
3977
+ }
3978
+ }
3979
+
3980
+ return {unique_names.begin(), unique_names.end()};
3981
+ }
3982
+
3983
+ static void
3984
+ bare_ffmpeg_set_option_dictionary(
3985
+ js_env_t *env,
3986
+ js_receiver_t,
3987
+ js_arraybuffer_span_t avclass_owner_handle,
3988
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict,
3989
+ int flags
3990
+ ) {
3991
+ int err;
3992
+ AVClass **owner = reinterpret_cast<AVClass **>(avclass_owner_handle.data());
3993
+ if (!owner || !*owner) {
3994
+ err = js_throw_error(env, NULL, "object does not have AVClass");
3995
+ assert(err == 0);
3996
+ throw js_pending_exception;
3997
+ }
3998
+
3999
+ err = av_opt_set_dict2(*owner, &dict->handle, flags);
4000
+ if (err < 0) {
4001
+ err = js_throw_error(env, NULL, av_err2str(err));
4002
+ assert(err == 0);
4003
+ throw js_pending_exception;
4004
+ }
4005
+ }
4006
+
4007
+ static void
4008
+ bare_ffmpeg_set_option_defaults(
4009
+ js_env_t *env,
4010
+ js_receiver_t,
4011
+ js_arraybuffer_span_t avclass_owner_handle
4012
+ ) {
4013
+ AVClass **owner = reinterpret_cast<AVClass **>(avclass_owner_handle.data());
4014
+ if (!owner || !*owner) {
4015
+ int err = js_throw_error(env, NULL, "object does not have AVClass");
4016
+ assert(err == 0);
4017
+ throw js_pending_exception;
4018
+ }
4019
+
4020
+ av_opt_set_defaults(*owner);
4021
+ }
4022
+
4023
+ static void
4024
+ bare_ffmpeg_copy_options(
4025
+ js_env_t *env,
4026
+ js_receiver_t,
4027
+ js_arraybuffer_span_t target_avclass_owner_handle,
4028
+ js_arraybuffer_span_t source_avclass_owner_handle
4029
+ ) {
4030
+ int err;
4031
+ AVClass **target_owner = reinterpret_cast<AVClass **>(target_avclass_owner_handle.data());
4032
+ if (!target_owner || !*target_owner) {
4033
+ err = js_throw_error(env, NULL, "object does not have AVClass");
4034
+ assert(err == 0);
4035
+ throw js_pending_exception;
4036
+ }
4037
+
4038
+ AVClass **source_owner = reinterpret_cast<AVClass **>(source_avclass_owner_handle.data());
4039
+ if (!source_owner || !*source_owner) {
4040
+ err = js_throw_error(env, NULL, "object does not have AVClass");
4041
+ assert(err == 0);
4042
+ throw js_pending_exception;
4043
+ }
4044
+
4045
+ err = av_opt_copy(*target_owner, *source_owner);
4046
+ if (err < 0) {
4047
+ err = js_throw_error(env, NULL, av_err2str(err));
4048
+ assert(err == 0);
4049
+ throw js_pending_exception;
4050
+ }
4051
+ }
4052
+
4053
+ static js_value_t *
4054
+ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
4055
+ uv_once(&bare_ffmpeg__init_guard, bare_ffmpeg__on_init);
4056
+
4057
+ int err;
4058
+
4059
+ #define V(name, fn) \
4060
+ err = js_set_property<fn>(env, exports, name); \
4061
+ assert(err == 0);
4062
+
4063
+ V("getLogLevel", bare_ffmpeg_log_get_level);
4064
+ V("setLogLevel", bare_ffmpeg_log_set_level);
4065
+
4066
+ V("initIOContext", bare_ffmpeg_io_context_init)
4067
+ V("destroyIOContext", bare_ffmpeg_io_context_destroy)
4068
+
4069
+ V("initInputFormat", bare_ffmpeg_input_format_init)
4070
+ V("getInputFormatFlags", bare_ffmpeg_input_format_get_flags)
4071
+ V("getInputFormatExtensions", bare_ffmpeg_input_format_get_extensions)
4072
+ V("getInputFormatMimeType", bare_ffmpeg_input_format_get_mime_type)
4073
+ V("getInputFormatName", bare_ffmpeg_input_format_get_name)
4074
+
4075
+ V("initOutputFormat", bare_ffmpeg_output_format_init)
4076
+ V("getOutputFormatFlags", bare_ffmpeg_output_format_get_flags)
4077
+ V("getOutputFormatExtensions", bare_ffmpeg_output_format_get_extensions)
4078
+ V("getOutputFormatMimeType", bare_ffmpeg_output_format_get_mime_type)
4079
+ V("getOutputFormatName", bare_ffmpeg_output_format_get_name)
4080
+
4081
+ V("openInputFormatContextWithIO", bare_ffmpeg_format_context_open_input_with_io)
4082
+ V("openInputFormatContextWithFormat", bare_ffmpeg_format_context_open_input_with_format)
4083
+ V("closeInputFormatContext", bare_ffmpeg_format_context_close_input)
4084
+
4085
+ V("openOutputFormatContext", bare_ffmpeg_format_context_open_output)
4086
+ V("closeOutputFormatContext", bare_ffmpeg_format_context_close_output)
4087
+
4088
+ V("getFormatContextStreams", bare_ffmpeg_format_context_get_streams)
4089
+ V("getFormatContextBestStreamIndex", bare_ffmpeg_format_context_get_best_stream_index)
4090
+ V("createFormatContextStream", bare_ffmpeg_format_context_create_stream)
4091
+ V("readFormatContextFrame", bare_ffmpeg_format_context_read_frame)
4092
+ V("writeFormatContextHeader", bare_ffmpeg_format_context_write_header)
4093
+ V("writeFormatContextFrame", bare_ffmpeg_format_context_write_frame)
4094
+ V("writeFormatContextTrailer", bare_ffmpeg_format_context_write_trailer)
4095
+ V("dumpFormatContext", bare_ffmpeg_format_context_dump)
4096
+ V("getFormatContextOutputFormat", get_bare_ffmpeg_format_context_output_format)
4097
+ V("getFormatContextInputFormat", get_bare_ffmpeg_format_context_input_format)
4098
+
4099
+ V("getStreamIndex", bare_ffmpeg_stream_get_index)
4100
+ V("getStreamId", bare_ffmpeg_stream_get_id)
4101
+ V("setStreamId", bare_ffmpeg_stream_set_id)
4102
+ V("getStreamTimeBase", bare_ffmpeg_stream_get_time_base)
4103
+ V("setStreamTimeBase", bare_ffmpeg_stream_set_time_base)
4104
+ V("getStreamAverageFramerate", bare_ffmpeg_stream_get_avg_framerate)
4105
+ V("setStreamAverageFramerate", bare_ffmpeg_stream_set_avg_framerate)
4106
+ V("getStreamCodecParameters", bare_ffmpeg_stream_get_codec_parameters)
4107
+ V("getStreamDuration", bare_ffmpeg_stream_get_duration)
4108
+ V("setStreamDuration", bare_ffmpeg_stream_set_duration)
4109
+
4110
+ V("findDecoderByID", bare_ffmpeg_find_decoder_by_id)
4111
+ V("findEncoderByID", bare_ffmpeg_find_encoder_by_id)
4112
+ V("getCodecNameByID", bare_ffmpeg_get_codec_name_by_id)
4113
+ V("getSampleFormatNameByID", bare_ffmpeg_get_sample_format_name_by_id)
4114
+ V("getPixelFormatNameByID", bare_ffmpeg_get_pixel_format_name_by_id)
4115
+ V("getSupportedConfig", bare_ffmpeg_codec_get_supported_config)
4116
+ V("getSupportedFrameRates", bare_ffmpeg_codec_get_supported_frame_rates)
4117
+ V("getSupportedChannelLayouts", bare_ffmpeg_codec_get_supported_channel_layouts)
4118
+
4119
+ V("initCodecContext", bare_ffmpeg_codec_context_init)
4120
+ V("destroyCodecContext", bare_ffmpeg_codec_context_destroy)
4121
+ V("openCodecContext", bare_ffmpeg_codec_context_open)
4122
+ V("openCodecContextWithOptions", bare_ffmpeg_codec_context_open_with_options)
4123
+ V("getCodecContextFlags", bare_ffmpeg_codec_context_get_flags)
4124
+ V("setCodecContextFlags", bare_ffmpeg_codec_context_set_flags)
4125
+ V("getCodecContextPixelFormat", bare_ffmpeg_codec_context_get_pixel_format)
4126
+ V("setCodecContextPixelFormat", bare_ffmpeg_codec_context_set_pixel_format)
4127
+ V("getCodecContextWidth", bare_ffmpeg_codec_context_get_width)
4128
+ V("setCodecContextWidth", bare_ffmpeg_codec_context_set_width)
4129
+ V("getCodecContextHeight", bare_ffmpeg_codec_context_get_height)
4130
+ V("setCodecContextHeight", bare_ffmpeg_codec_context_set_height)
4131
+ V("getCodecContextSampleFormat", bare_ffmpeg_codec_context_get_sample_format)
4132
+ V("setCodecContextSampleFormat", bare_ffmpeg_codec_context_set_sample_format)
4133
+ V("getCodecContextTimeBase", bare_ffmpeg_codec_context_get_time_base)
4134
+ V("setCodecContextTimeBase", bare_ffmpeg_codec_context_set_time_base)
4135
+ V("getCodecContextChannelLayout", bare_ffmpeg_codec_context_get_channel_layout);
4136
+ V("setCodecContextChannelLayout", bare_ffmpeg_codec_context_set_channel_layout);
4137
+ V("getCodecContextSampleRate", bare_ffmpeg_codec_context_get_sample_rate);
4138
+ V("setCodecContextSampleRate", bare_ffmpeg_codec_context_set_sample_rate);
4139
+ V("getCodecContextGOPSize", bare_ffmpeg_codec_context_get_gop_size)
4140
+ V("setCodecContextGOPSize", bare_ffmpeg_codec_context_set_gop_size)
4141
+ V("getCodecContextFramerate", bare_ffmpeg_codec_context_get_framerate)
4142
+ V("setCodecContextFramerate", bare_ffmpeg_codec_context_set_framerate)
4143
+ V("getCodecContextExtraData", bare_ffmpeg_codec_context_get_extra_data)
4144
+ V("setCodecContextExtraData", bare_ffmpeg_codec_context_set_extra_data)
4145
+ V("getCodecContextFrameSize", bare_ffmpeg_codec_context_get_frame_size)
4146
+ V("getCodecContextFrameNum", bare_ffmpeg_codec_context_get_frame_num)
4147
+ V("getCodecContextRequestSampleFormat", bare_ffmpeg_codec_context_get_request_sample_format)
4148
+ V("setCodecContextRequestSampleFormat", bare_ffmpeg_codec_context_set_request_sample_format)
4149
+ V("setCodecContextGetFormat", bare_ffmpeg_codec_context_set_get_format)
4150
+
4151
+ V("sendCodecContextPacket", bare_ffmpeg_codec_context_send_packet)
4152
+ V("receiveCodecContextPacket", bare_ffmpeg_codec_context_receive_packet)
4153
+ V("sendCodecContextFrame", bare_ffmpeg_codec_context_send_frame)
4154
+ V("receiveCodecContextFrame", bare_ffmpeg_codec_context_receive_frame)
4155
+
4156
+ V("codecParametersFromContext", bare_ffmpeg_codec_parameters_from_context)
4157
+ V("codecParametersToContext", bare_ffmpeg_codec_parameters_to_context)
4158
+ V("allocCodecParameters", bare_ffmpeg_codec_parameters_alloc)
4159
+ V("destroyCodecParameters", bare_ffmpeg_codec_parameters_destroy)
4160
+ V("getCodecParametersBitRate", bare_ffmpeg_codec_parameters_get_bit_rate)
4161
+ V("setCodecParametersBitRate", bare_ffmpeg_codec_parameters_set_bit_rate)
4162
+ V("getCodecParametersBitsPerCodedSample", bare_ffmpeg_codec_parameters_get_bits_per_coded_sample)
4163
+ V("setCodecParametersBitsPerCodedSample", bare_ffmpeg_codec_parameters_set_bits_per_coded_sample)
4164
+ V("getCodecParametersBitsPerRawSample", bare_ffmpeg_codec_parameters_get_bits_per_raw_sample)
4165
+ V("setCodecParametersBitsPerRawSample", bare_ffmpeg_codec_parameters_set_bits_per_raw_sample)
4166
+ V("getCodecParametersSampleRate", bare_ffmpeg_codec_parameters_get_sample_rate)
4167
+ V("setCodecParametersSampleRate", bare_ffmpeg_codec_parameters_set_sample_rate)
4168
+ V("getCodecParametersFramerate", bare_ffmpeg_codec_parameters_get_framerate)
4169
+ V("setCodecParametersFramerate", bare_ffmpeg_codec_parameters_set_framerate)
4170
+ V("getCodecParametersNbChannels", bare_ffmpeg_codec_parameters_get_nb_channels)
4171
+ V("setCodecParametersNbChannels", bare_ffmpeg_codec_parameters_set_nb_channels)
4172
+ V("getCodecParametersType", bare_ffmpeg_codec_parameters_get_type)
4173
+ V("setCodecParametersType", bare_ffmpeg_codec_parameters_set_type)
4174
+ V("getCodecParametersTag", bare_ffmpeg_codec_parameters_get_tag)
4175
+ V("setCodecParametersTag", bare_ffmpeg_codec_parameters_set_tag)
4176
+ V("getCodecParametersId", bare_ffmpeg_codec_parameters_get_id)
4177
+ V("setCodecParametersId", bare_ffmpeg_codec_parameters_set_id)
4178
+ V("getCodecParametersLevel", bare_ffmpeg_codec_parameters_get_level)
4179
+ V("setCodecParametersLevel", bare_ffmpeg_codec_parameters_set_level)
4180
+ V("getCodecParametersProfile", bare_ffmpeg_codec_parameters_get_profile)
4181
+ V("setCodecParametersProfile", bare_ffmpeg_codec_parameters_set_profile)
4182
+ V("getCodecParametersFormat", bare_ffmpeg_codec_parameters_get_format)
4183
+ V("setCodecParametersFormat", bare_ffmpeg_codec_parameters_set_format)
4184
+ V("getCodecParametersChannelLayout", bare_ffmpeg_codec_parameters_get_channel_layout)
4185
+ V("setCodecParametersChannelLayout", bare_ffmpeg_codec_parameters_set_channel_layout)
4186
+ V("getCodecParametersWidth", bare_ffmpeg_codec_parameters_get_width)
4187
+ V("setCodecParametersWidth", bare_ffmpeg_codec_parameters_set_width)
4188
+ V("getCodecParametersHeight", bare_ffmpeg_codec_parameters_get_height)
4189
+ V("setCodecParametersHeight", bare_ffmpeg_codec_parameters_set_height)
4190
+ V("getCodecParametersExtraData", bare_ffmpeg_codec_parameters_get_extra_data)
4191
+ V("setCodecParametersExtraData", bare_ffmpeg_codec_parameters_set_extra_data)
4192
+ V("getCodecParametersBlockAlign", bare_ffmpeg_codec_parameters_get_block_align)
4193
+ V("setCodecParametersBlockAlign", bare_ffmpeg_codec_parameters_set_block_align)
4194
+ V("getCodecParametersInitialPadding", bare_ffmpeg_codec_parameters_get_initial_padding)
4195
+ V("setCodecParametersInitialPadding", bare_ffmpeg_codec_parameters_set_initial_padding)
4196
+ V("getCodecParametersTrailingPadding", bare_ffmpeg_codec_parameters_get_trailing_padding)
4197
+ V("setCodecParametersTrailingPadding", bare_ffmpeg_codec_parameters_set_trailing_padding)
4198
+ V("getCodecParametersSeekPreroll", bare_ffmpeg_codec_parameters_get_seek_preroll)
4199
+ V("setCodecParametersSeekPreroll", bare_ffmpeg_codec_parameters_set_seek_preroll)
4200
+ V("getCodecParametersSampleAspectRatio", bare_ffmpeg_codec_parameters_get_sample_aspect_ratio)
4201
+ V("setCodecParametersSampleAspectRatio", bare_ffmpeg_codec_parameters_set_sample_aspect_ratio)
4202
+ V("getCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_get_video_delay)
4203
+ V("setCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_set_video_delay)
4204
+ V("getCodecParametersFrameSize", bare_ffmpeg_codec_parameters_get_frame_size)
4205
+ V("setCodecParametersFrameSize", bare_ffmpeg_codec_parameters_set_frame_size)
4206
+
4207
+ V("initFrame", bare_ffmpeg_frame_init)
4208
+ V("destroyFrame", bare_ffmpeg_frame_destroy)
4209
+ V("unrefFrame", bare_ffmpeg_frame_unref)
4210
+ V("getFrameWidth", bare_ffmpeg_frame_get_width)
4211
+ V("setFrameWidth", bare_ffmpeg_frame_set_width)
4212
+ V("getFrameHeight", bare_ffmpeg_frame_get_height)
4213
+ V("setFrameHeight", bare_ffmpeg_frame_set_height)
4214
+ V("getFrameFormat", bare_ffmpeg_frame_get_format)
4215
+ V("setFrameFormat", bare_ffmpeg_frame_set_format)
4216
+ V("getFrameChannelLayout", bare_ffmpeg_frame_get_channel_layout)
4217
+ V("setFrameChannelLayout", bare_ffmpeg_frame_set_channel_layout)
4218
+ V("getFrameNbSamples", bare_ffmpeg_frame_get_nb_samples)
4219
+ V("setFrameNbSamples", bare_ffmpeg_frame_set_nb_samples)
4220
+ V("getFramePictType", bare_ffmpeg_frame_get_pict_type)
4221
+ V("getFramePTS", bare_ffmpeg_frame_get_pts)
4222
+ V("setFramePTS", bare_ffmpeg_frame_set_pts)
4223
+ V("getFramePacketDTS", bare_ffmpeg_frame_get_pkt_dts)
4224
+ V("setFramePacketDTS", bare_ffmpeg_frame_set_pkt_dts)
4225
+ V("getFrameTimeBase", bare_ffmpeg_frame_get_time_base)
4226
+ V("setFrameTimeBase", bare_ffmpeg_frame_set_time_base)
4227
+ V("getFrameSampleRate", bare_ffmpeg_frame_get_sample_rate)
4228
+ V("setFrameSampleRate", bare_ffmpeg_frame_set_sample_rate)
4229
+ V("copyFrameProperties", bare_ffmpeg_frame_copy_properties)
4230
+ V("allocFrame", bare_ffmpeg_frame_alloc)
4231
+
4232
+ V("initImage", bare_ffmpeg_image_init)
4233
+ V("fillImage", bare_ffmpeg_image_fill)
4234
+ V("readImage", bare_ffmpeg_image_read)
4235
+ V("getImageLineSize", bare_ffmpeg_image_get_line_size)
4236
+
4237
+ V("samplesBufferSize", bare_ffmpeg_samples_buffer_size)
4238
+ V("fillSamples", bare_ffmpeg_samples_fill)
4239
+ V("copySamples", bare_ffmpeg_samples_copy)
4240
+ V("readSamples", bare_ffmpeg_samples_read)
4241
+
4242
+ V("initPacket", bare_ffmpeg_packet_init)
4243
+ V("initPacketFromBuffer", bare_ffmpeg_packet_init_from_buffer)
4244
+ V("destroyPacket", bare_ffmpeg_packet_destroy)
4245
+ V("unrefPacket", bare_ffmpeg_packet_unref)
4246
+ V("getPacketStreamIndex", bare_ffmpeg_packet_get_stream_index)
4247
+ V("setPacketStreamIndex", bare_ffmpeg_packet_set_stream_index)
4248
+ V("getPacketData", bare_ffmpeg_packet_get_data)
4249
+ V("setPacketData", bare_ffmpeg_packet_set_data)
4250
+ V("getPacketSideData", bare_ffmpeg_packet_get_side_data)
4251
+ V("setPacketSideData", bare_ffmpeg_packet_set_side_data)
4252
+ V("isPacketKeyframe", bare_ffmpeg_packet_is_keyframe)
4253
+ V("setPacketIsKeyFrame", bare_ffmpeg_packet_set_is_keyframe)
4254
+ V("getPacketDTS", bare_ffmpeg_packet_get_dts)
4255
+ V("setPacketDTS", bare_ffmpeg_packet_set_dts)
4256
+ V("getPacketPTS", bare_ffmpeg_packet_get_pts)
4257
+ V("setPacketPTS", bare_ffmpeg_packet_set_pts)
4258
+ V("getPacketTimeBase", bare_ffmpeg_packet_get_time_base)
4259
+ V("setPacketTimeBase", bare_ffmpeg_packet_set_time_base)
4260
+ V("rescalePacketTimestamps", bare_ffmpeg_packet_rescale_ts)
4261
+ V("getPacketDuration", bare_ffmpeg_packet_get_duration)
4262
+ V("setPacketDuration", bare_ffmpeg_packet_set_duration)
4263
+ V("getPacketFlags", bare_ffmpeg_packet_get_flags)
4264
+ V("setPacketFlags", bare_ffmpeg_packet_set_flags)
4265
+ V("copyPacketProps", bare_ffmpeg_packet_copy_props)
4266
+
4267
+ V("getSideDataType", bare_ffmpeg_side_data_get_type)
4268
+ V("getSideDataName", bare_ffmpeg_side_data_get_name)
4269
+ V("getSideDataBuffer", bare_ffmpeg_side_data_get_data)
4270
+
4271
+ V("initScaler", bare_ffmpeg_scaler_init)
4272
+ V("destroyScaler", bare_ffmpeg_scaler_destroy)
4273
+ V("scaleScaler", bare_ffmpeg_scaler_scale)
4274
+
4275
+ V("initDictionary", bare_ffmpeg_dictionary_init)
4276
+ V("destroyDictionary", bare_ffmpeg_dictionary_destroy)
4277
+ V("getDictionaryEntry", bare_ffmpeg_dictionary_get_entry)
4278
+ V("setDictionaryEntry", bare_ffmpeg_dictionary_set_entry)
4279
+ V("getDictionaryEntries", bare_ffmpeg_dictionary_get_entries)
4280
+
4281
+ V("initResampler", bare_ffmpeg_resampler_init)
4282
+ V("destroyResampler", bare_ffmpeg_resampler_destroy)
4283
+ V("convertResampler", bare_ffmpeg_resampler_convert_frames)
4284
+ V("getResamplerDelay", bare_ffmpeg_resampler_get_delay)
4285
+ V("flushResampler", bare_ffmpeg_resampler_flush)
4286
+
4287
+ V("copyChannelLayout", bare_ffmpeg_channel_layout_copy)
4288
+ V("getChannelLayoutNbChannels", bare_ffmpeg_channel_layout_get_nb_channels)
4289
+ V("getChannelLayoutMask", bare_ffmpeg_channel_layout_get_mask)
4290
+ V("channelLayoutFromMask", bare_ffmpeg_channel_layout_from_mask)
4291
+
4292
+ V("initAudioFifo", bare_ffmpeg_audio_fifo_init)
4293
+ V("destroyAudioFifo", bare_ffmpeg_audio_fifo_destroy)
4294
+ V("writeAudioFifo", bare_ffmpeg_audio_fifo_write)
4295
+ V("readAudioFifo", bare_ffmpeg_audio_fifo_read)
4296
+ V("peekAudioFifo", bare_ffmpeg_audio_fifo_peek)
4297
+ V("drainAudioFifo", bare_ffmpeg_audio_fifo_drain)
4298
+ V("resetAudioFifo", bare_ffmpeg_audio_fifo_reset)
4299
+ V("getAudioFifoSize", bare_ffmpeg_audio_fifo_size)
4300
+ V("getAudioFifoSpace", bare_ffmpeg_audio_fifo_space)
4301
+
4302
+ V("rationalD2Q", bare_ffmpeg_rational_d2q)
4303
+ V("rationalRescaleQ", bare_ffmpeg_rational_rescale_q)
4304
+
4305
+ V("getFilterByName", bare_ffmpeg_filter_get_by_name)
4306
+
4307
+ V("initFilterContext", bare_ffmpeg_filter_context_init)
4308
+
4309
+ V("initFilterGraph", bare_ffmpeg_filter_graph_init)
4310
+ V("destroyFilterGraph", bare_ffmpeg_filter_graph_destroy)
4311
+ V("createFilterGraphFilter", bare_ffmpeg_filter_graph_create_filter)
4312
+ V("parseFilterGraph", bare_ffmpeg_filter_graph_parse)
4313
+ V("configureFilterGraph", bare_ffmpeg_filter_graph_configure)
4314
+ V("pushFilterGraphFrame", bare_ffmpeg_filter_graph_push_frame)
4315
+ V("pullFilterGraphFrame", bare_ffmpeg_filter_graph_pull_frame)
4316
+
4317
+ V("initFilterInout", bare_ffmpeg_filter_inout_init)
4318
+ V("destroyFilterInOut", bare_ffmpeg_filter_inout_destroy)
4319
+ V("getFilterInOutName", bare_ffmpeg_filter_inout_get_name)
4320
+ V("setFilterInOutName", bare_ffmpeg_filter_inout_set_name)
4321
+ V("setFilterInOutFilterContext", bare_ffmpeg_filter_inout_set_filter_context)
4322
+ V("getFilterInOutPadIdx", bare_ffmpeg_filter_inout_get_pad_idx)
4323
+ V("setFilterInOutPadIdx", bare_ffmpeg_filter_inout_set_pad_idx)
4324
+ V("setFilterInOutNext", bare_ffmpeg_filter_inout_set_next)
4325
+
4326
+ V("setOption", bare_ffmpeg_set_option)
4327
+ V("getOption", bare_ffmpeg_get_option)
4328
+ V("listOptionNames", bare_ffmpeg_list_option_names)
4329
+ V("setOptionDictionary", bare_ffmpeg_set_option_dictionary)
4330
+ V("setOptionDefaults", bare_ffmpeg_set_option_defaults)
4331
+ V("copyOptions", bare_ffmpeg_copy_options)
4332
+ #undef V
4333
+
4334
+ #define V(name) \
4335
+ { \
4336
+ js_value_t *val; \
4337
+ err = js_create_int64(env, name, &val); \
4338
+ assert(err == 0); \
4339
+ err = js_set_named_property(env, exports, #name, val); \
4340
+ assert(err == 0); \
4341
+ }
4342
+
4343
+ V(AV_LOG_QUIET)
4344
+ V(AV_LOG_PANIC)
4345
+ V(AV_LOG_FATAL)
4346
+ V(AV_LOG_ERROR)
4347
+ V(AV_LOG_WARNING)
4348
+ V(AV_LOG_INFO)
4349
+ V(AV_LOG_VERBOSE)
4350
+ V(AV_LOG_DEBUG)
4351
+ V(AV_LOG_TRACE)
4352
+
4353
+ V(AV_CODEC_ID_MJPEG)
4354
+ V(AV_CODEC_ID_H264)
4355
+ V(AV_CODEC_ID_AAC)
4356
+ V(AV_CODEC_ID_OPUS)
4357
+ V(AV_CODEC_ID_AV1)
4358
+ V(AV_CODEC_ID_FLAC)
4359
+ V(AV_CODEC_ID_MP3)
4360
+
4361
+ V(AV_CODEC_FLAG_COPY_OPAQUE)
4362
+ V(AV_CODEC_FLAG_FRAME_DURATION)
4363
+ V(AV_CODEC_FLAG_PASS1)
4364
+ V(AV_CODEC_FLAG_PASS2)
4365
+ V(AV_CODEC_FLAG_LOOP_FILTER)
4366
+ V(AV_CODEC_FLAG_GRAY)
4367
+ V(AV_CODEC_FLAG_PSNR)
4368
+ V(AV_CODEC_FLAG_INTERLACED_DCT)
4369
+ V(AV_CODEC_FLAG_LOW_DELAY)
4370
+ V(AV_CODEC_FLAG_GLOBAL_HEADER)
4371
+ V(AV_CODEC_FLAG_BITEXACT)
4372
+ V(AV_CODEC_FLAG_AC_PRED)
4373
+ V(AV_CODEC_FLAG_INTERLACED_ME)
4374
+ V(AV_CODEC_FLAG_CLOSED_GOP)
4375
+
4376
+ V(AV_PIX_FMT_NONE)
4377
+ V(AV_PIX_FMT_RGBA)
4378
+ V(AV_PIX_FMT_RGB24)
4379
+ V(AV_PIX_FMT_YUVJ420P)
4380
+ V(AV_PIX_FMT_YUV420P)
4381
+ V(AV_PIX_FMT_UYVY422)
4382
+ V(AV_PIX_FMT_NV12)
4383
+ V(AV_PIX_FMT_NV21)
4384
+ V(AV_PIX_FMT_NV24)
4385
+
4386
+ V(AVMEDIA_TYPE_UNKNOWN)
4387
+ V(AVMEDIA_TYPE_VIDEO)
4388
+ V(AVMEDIA_TYPE_AUDIO)
4389
+ V(AVMEDIA_TYPE_DATA)
4390
+ V(AVMEDIA_TYPE_SUBTITLE)
4391
+ V(AVMEDIA_TYPE_ATTACHMENT)
4392
+ V(AVMEDIA_TYPE_NB)
4393
+
4394
+ V(AV_SAMPLE_FMT_NONE)
4395
+ V(AV_SAMPLE_FMT_U8)
4396
+ V(AV_SAMPLE_FMT_S16)
4397
+ V(AV_SAMPLE_FMT_S32)
4398
+ V(AV_SAMPLE_FMT_FLT)
4399
+ V(AV_SAMPLE_FMT_DBL)
4400
+ V(AV_SAMPLE_FMT_U8P)
4401
+ V(AV_SAMPLE_FMT_S16P)
4402
+ V(AV_SAMPLE_FMT_S32P)
4403
+ V(AV_SAMPLE_FMT_FLTP)
4404
+ V(AV_SAMPLE_FMT_DBLP)
4405
+ V(AV_SAMPLE_FMT_S64)
4406
+ V(AV_SAMPLE_FMT_S64P)
4407
+ V(AV_SAMPLE_FMT_NB)
4408
+
4409
+ V(AV_CH_LAYOUT_MONO)
4410
+ V(AV_CH_LAYOUT_STEREO)
4411
+ V(AV_CH_LAYOUT_QUAD)
4412
+ V(AV_CH_LAYOUT_SURROUND)
4413
+ V(AV_CH_LAYOUT_2POINT1)
4414
+ V(AV_CH_LAYOUT_5POINT0)
4415
+ V(AV_CH_LAYOUT_5POINT1)
4416
+ V(AV_CH_LAYOUT_7POINT1)
4417
+
4418
+ V(AV_PICTURE_TYPE_NONE)
4419
+ V(AV_PICTURE_TYPE_I)
4420
+ V(AV_PICTURE_TYPE_P)
4421
+ V(AV_PICTURE_TYPE_B)
4422
+ V(AV_PICTURE_TYPE_S)
4423
+ V(AV_PICTURE_TYPE_SI)
4424
+ V(AV_PICTURE_TYPE_SP)
4425
+ V(AV_PICTURE_TYPE_BI)
4426
+
4427
+ // InputFormat flags
4428
+ V(AVFMT_SHOW_IDS)
4429
+ V(AVFMT_GENERIC_INDEX)
4430
+ V(AVFMT_TS_DISCONT)
4431
+ V(AVFMT_NOBINSEARCH)
4432
+ V(AVFMT_NOGENSEARCH)
4433
+ V(AVFMT_NO_BYTE_SEEK)
4434
+ V(AVFMT_SEEK_TO_PTS)
4435
+
4436
+ // OutputFormat flags
4437
+ V(AVFMT_GLOBALHEADER)
4438
+ V(AVFMT_VARIABLE_FPS)
4439
+ V(AVFMT_NODIMENSIONS)
4440
+ V(AVFMT_NOSTREAMS)
4441
+ V(AVFMT_TS_NONSTRICT)
4442
+ V(AVFMT_TS_NEGATIVE)
4443
+
4444
+ // Common format flags
4445
+ V(AVFMT_NOFILE)
4446
+ V(AVFMT_NEEDNUMBER)
4447
+ V(AVFMT_NOTIMESTAMPS)
4448
+
4449
+ // Profile
4450
+ V(AV_PROFILE_UNKNOWN)
4451
+ V(AV_PROFILE_RESERVED)
4452
+ V(AV_PROFILE_AAC_MAIN)
4453
+ V(AV_PROFILE_AAC_LOW)
4454
+ V(AV_PROFILE_AAC_SSR)
4455
+ V(AV_PROFILE_AAC_LTP)
4456
+ V(AV_PROFILE_AAC_HE)
4457
+ V(AV_PROFILE_AAC_HE_V2)
4458
+ V(AV_PROFILE_AAC_LD)
4459
+ V(AV_PROFILE_AAC_ELD)
4460
+ V(AV_PROFILE_AAC_USAC)
4461
+ V(AV_PROFILE_MPEG2_AAC_LOW)
4462
+ V(AV_PROFILE_MPEG2_AAC_HE)
4463
+ V(AV_PROFILE_DNXHD)
4464
+ V(AV_PROFILE_DNXHR_LB)
4465
+ V(AV_PROFILE_DNXHR_SQ)
4466
+ V(AV_PROFILE_DNXHR_HQ)
4467
+ V(AV_PROFILE_DNXHR_HQX)
4468
+ V(AV_PROFILE_DNXHR_444)
4469
+ V(AV_PROFILE_DTS)
4470
+ V(AV_PROFILE_DTS_ES)
4471
+ V(AV_PROFILE_DTS_96_24)
4472
+ V(AV_PROFILE_DTS_HD_HRA)
4473
+ V(AV_PROFILE_DTS_HD_MA)
4474
+ V(AV_PROFILE_DTS_EXPRESS)
4475
+ V(AV_PROFILE_DTS_HD_MA_X)
4476
+ V(AV_PROFILE_DTS_HD_MA_X_IMAX)
4477
+ V(AV_PROFILE_EAC3_DDP_ATMOS)
4478
+ V(AV_PROFILE_TRUEHD_ATMOS)
4479
+ V(AV_PROFILE_MPEG2_422)
4480
+ V(AV_PROFILE_MPEG2_HIGH)
4481
+ V(AV_PROFILE_MPEG2_SS)
4482
+ V(AV_PROFILE_MPEG2_SNR_SCALABLE)
4483
+ V(AV_PROFILE_MPEG2_MAIN)
4484
+ V(AV_PROFILE_MPEG2_SIMPLE)
4485
+ V(AV_PROFILE_H264_CONSTRAINED)
4486
+ V(AV_PROFILE_H264_INTRA)
4487
+ V(AV_PROFILE_H264_BASELINE)
4488
+ V(AV_PROFILE_H264_CONSTRAINED_BASELINE)
4489
+ V(AV_PROFILE_H264_MAIN)
4490
+ V(AV_PROFILE_H264_EXTENDED)
4491
+ V(AV_PROFILE_H264_HIGH)
4492
+ V(AV_PROFILE_H264_HIGH_10)
4493
+ V(AV_PROFILE_H264_HIGH_10_INTRA)
4494
+ V(AV_PROFILE_H264_MULTIVIEW_HIGH)
4495
+ V(AV_PROFILE_H264_HIGH_422)
4496
+ V(AV_PROFILE_H264_HIGH_422_INTRA)
4497
+ V(AV_PROFILE_H264_STEREO_HIGH)
4498
+ V(AV_PROFILE_H264_HIGH_444)
4499
+ V(AV_PROFILE_H264_HIGH_444_PREDICTIVE)
4500
+ V(AV_PROFILE_H264_HIGH_444_INTRA)
4501
+ V(AV_PROFILE_H264_CAVLC_444)
4502
+ V(AV_PROFILE_VC1_SIMPLE)
4503
+ V(AV_PROFILE_VC1_MAIN)
4504
+ V(AV_PROFILE_VC1_COMPLEX)
4505
+ V(AV_PROFILE_VC1_ADVANCED)
4506
+ V(AV_PROFILE_MPEG4_SIMPLE)
4507
+ V(AV_PROFILE_MPEG4_SIMPLE_SCALABLE)
4508
+ V(AV_PROFILE_MPEG4_CORE)
4509
+ V(AV_PROFILE_MPEG4_MAIN)
4510
+ V(AV_PROFILE_MPEG4_N_BIT)
4511
+ V(AV_PROFILE_MPEG4_SCALABLE_TEXTURE)
4512
+ V(AV_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION)
4513
+ V(AV_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE)
4514
+ V(AV_PROFILE_MPEG4_HYBRID)
4515
+ V(AV_PROFILE_MPEG4_ADVANCED_REAL_TIME)
4516
+ V(AV_PROFILE_MPEG4_CORE_SCALABLE)
4517
+ V(AV_PROFILE_MPEG4_ADVANCED_CODING)
4518
+ V(AV_PROFILE_MPEG4_ADVANCED_CORE)
4519
+ V(AV_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE)
4520
+ V(AV_PROFILE_MPEG4_SIMPLE_STUDIO)
4521
+ V(AV_PROFILE_MPEG4_ADVANCED_SIMPLE)
4522
+ V(AV_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0)
4523
+ V(AV_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1)
4524
+ V(AV_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION)
4525
+ V(AV_PROFILE_JPEG2000_DCINEMA_2K)
4526
+ V(AV_PROFILE_JPEG2000_DCINEMA_4K)
4527
+ V(AV_PROFILE_VP9_0)
4528
+ V(AV_PROFILE_VP9_1)
4529
+ V(AV_PROFILE_VP9_2)
4530
+ V(AV_PROFILE_VP9_3)
4531
+ V(AV_PROFILE_HEVC_MAIN)
4532
+ V(AV_PROFILE_HEVC_MAIN_10)
4533
+ V(AV_PROFILE_HEVC_MAIN_STILL_PICTURE)
4534
+ V(AV_PROFILE_HEVC_REXT)
4535
+ V(AV_PROFILE_HEVC_MULTIVIEW_MAIN)
4536
+ V(AV_PROFILE_HEVC_SCC)
4537
+ V(AV_PROFILE_VVC_MAIN_10)
4538
+ V(AV_PROFILE_VVC_MAIN_10_444)
4539
+ V(AV_PROFILE_AV1_MAIN)
4540
+ V(AV_PROFILE_AV1_HIGH)
4541
+ V(AV_PROFILE_AV1_PROFESSIONAL)
4542
+ V(AV_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT)
4543
+ V(AV_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT)
4544
+ V(AV_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT)
4545
+ V(AV_PROFILE_MJPEG_HUFFMAN_LOSSLESS)
4546
+ V(AV_PROFILE_MJPEG_JPEG_LS)
4547
+ V(AV_PROFILE_SBC_MSBC)
4548
+ V(AV_PROFILE_PRORES_PROXY)
4549
+ V(AV_PROFILE_PRORES_LT)
4550
+ V(AV_PROFILE_PRORES_STANDARD)
4551
+ V(AV_PROFILE_PRORES_HQ)
4552
+ V(AV_PROFILE_PRORES_4444)
4553
+ V(AV_PROFILE_PRORES_XQ)
4554
+ V(AV_PROFILE_ARIB_PROFILE_A)
4555
+ V(AV_PROFILE_ARIB_PROFILE_C)
4556
+ V(AV_PROFILE_KLVA_SYNC)
4557
+ V(AV_PROFILE_KLVA_ASYNC)
4558
+ V(AV_PROFILE_EVC_BASELINE)
4559
+ V(AV_PROFILE_EVC_MAIN)
4560
+
4561
+ // Levels
4562
+ V(AV_LEVEL_UNKNOWN)
4563
+
4564
+ // SEEK
4565
+ V(AVSEEK_SIZE)
4566
+ V(AVSEEK_FORCE)
4567
+ V(SEEK_CUR)
4568
+ V(SEEK_SET)
4569
+ V(SEEK_END)
4570
+
4571
+ V(AV_PKT_DATA_PALETTE)
4572
+ V(AV_PKT_DATA_NEW_EXTRADATA)
4573
+ V(AV_PKT_DATA_PARAM_CHANGE)
4574
+ V(AV_PKT_DATA_H263_MB_INFO)
4575
+ V(AV_PKT_DATA_REPLAYGAIN)
4576
+ V(AV_PKT_DATA_DISPLAYMATRIX)
4577
+ V(AV_PKT_DATA_STEREO3D)
4578
+ V(AV_PKT_DATA_AUDIO_SERVICE_TYPE)
4579
+ V(AV_PKT_DATA_QUALITY_STATS)
4580
+ V(AV_PKT_DATA_FALLBACK_TRACK)
4581
+ V(AV_PKT_DATA_CPB_PROPERTIES)
4582
+ V(AV_PKT_DATA_SKIP_SAMPLES)
4583
+ V(AV_PKT_DATA_JP_DUALMONO)
4584
+ V(AV_PKT_DATA_STRINGS_METADATA)
4585
+ V(AV_PKT_DATA_SUBTITLE_POSITION)
4586
+ V(AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL)
4587
+ V(AV_PKT_DATA_WEBVTT_IDENTIFIER)
4588
+ V(AV_PKT_DATA_WEBVTT_SETTINGS)
4589
+ V(AV_PKT_DATA_METADATA_UPDATE)
4590
+ V(AV_PKT_DATA_MPEGTS_STREAM_ID)
4591
+ V(AV_PKT_DATA_MASTERING_DISPLAY_METADATA)
4592
+ V(AV_PKT_DATA_SPHERICAL)
4593
+ V(AV_PKT_DATA_CONTENT_LIGHT_LEVEL)
4594
+ V(AV_PKT_DATA_A53_CC)
4595
+ V(AV_PKT_DATA_ENCRYPTION_INIT_INFO)
4596
+ V(AV_PKT_DATA_ENCRYPTION_INFO)
4597
+ V(AV_PKT_DATA_AFD)
4598
+ V(AV_PKT_DATA_PRFT)
4599
+ V(AV_PKT_DATA_ICC_PROFILE)
4600
+ V(AV_PKT_DATA_DOVI_CONF)
4601
+ V(AV_PKT_DATA_S12M_TIMECODE)
4602
+ V(AV_PKT_DATA_DYNAMIC_HDR10_PLUS)
4603
+ V(AV_PKT_DATA_IAMF_MIX_GAIN_PARAM)
4604
+ V(AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM)
4605
+ V(AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM)
4606
+ V(AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT)
4607
+ V(AV_PKT_DATA_FRAME_CROPPING)
4608
+ V(AV_PKT_DATA_LCEVC)
4609
+ V(AV_PKT_DATA_3D_REFERENCE_DISPLAYS)
4610
+ V(AV_PKT_DATA_RTCP_SR)
4611
+ V(AV_PKT_DATA_NB)
4612
+
4613
+ V(AV_CODEC_CONFIG_PIX_FORMAT)
4614
+ V(AV_CODEC_CONFIG_FRAME_RATE)
4615
+ V(AV_CODEC_CONFIG_SAMPLE_RATE)
4616
+ V(AV_CODEC_CONFIG_SAMPLE_FORMAT)
4617
+ V(AV_CODEC_CONFIG_CHANNEL_LAYOUT)
4618
+ V(AV_CODEC_CONFIG_COLOR_RANGE)
4619
+ V(AV_CODEC_CONFIG_COLOR_SPACE)
4620
+
4621
+ V(AV_ROUND_ZERO)
4622
+ V(AV_ROUND_INF)
4623
+ V(AV_ROUND_DOWN)
4624
+ V(AV_ROUND_UP)
4625
+ V(AV_ROUND_NEAR_INF) // default
4626
+ V(AV_ROUND_PASS_MINMAX)
4627
+
4628
+ V(AV_OPT_SEARCH_CHILDREN)
4629
+ V(AV_OPT_SEARCH_FAKE_OBJ)
4630
+ V(AV_OPT_ALLOW_NULL)
4631
+ V(AV_OPT_ARRAY_REPLACE)
4632
+ V(AV_OPT_MULTI_COMPONENT_RANGE)
4633
+ #undef V
4634
+
4635
+ return exports;
4636
+ }
4637
+
4638
+ BARE_MODULE(bare_ffmpeg, bare_ffmpeg_exports)