bare-ffmpeg 1.0.0-0

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.
package/binding.c ADDED
@@ -0,0 +1,962 @@
1
+ #include <assert.h>
2
+ #include <bare.h>
3
+ #include <js.h>
4
+ #include <libavcodec/avcodec.h>
5
+ #include <libavcodec/codec.h>
6
+ #include <libavcodec/codec_id.h>
7
+ #include <libavcodec/codec_par.h>
8
+ #include <libavcodec/packet.h>
9
+ #include <libavformat/avformat.h>
10
+ #include <libavformat/avio.h>
11
+ #include <libavutil/error.h>
12
+ #include <libavutil/frame.h>
13
+ #include <libavutil/imgutils.h>
14
+ #include <libavutil/log.h>
15
+ #include <libavutil/mem.h>
16
+ #include <libavutil/pixfmt.h>
17
+ #include <libswscale/swscale.h>
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+ #include <string.h>
21
+
22
+ typedef struct {
23
+ AVIOContext *handle;
24
+ } bare_ffmpeg_io_context_t;
25
+
26
+ typedef struct {
27
+ AVFormatContext *handle;
28
+ } bare_ffmpeg_format_context_t;
29
+
30
+ typedef struct {
31
+ AVStream *handle;
32
+ } bare_ffmpeg_stream_t;
33
+
34
+ typedef struct {
35
+ const AVCodec *handle;
36
+ } bare_ffmpeg_codec_t;
37
+
38
+ typedef struct {
39
+ AVCodecParameters *handle;
40
+ } bare_ffmpeg_codec_parameters_t;
41
+
42
+ typedef struct {
43
+ AVCodecContext *handle;
44
+ } bare_ffmpeg_codec_context_t;
45
+
46
+ typedef struct {
47
+ AVFrame *handle;
48
+ } bare_ffmpeg_frame_t;
49
+
50
+ typedef struct {
51
+ AVPacket handle;
52
+ } bare_ffmpeg_packet_t;
53
+
54
+ typedef struct {
55
+ struct SwsContext *handle;
56
+ } bare_ffmpeg_scaler_t;
57
+
58
+ static uv_once_t bare_ffmpeg__init_guard = UV_ONCE_INIT;
59
+
60
+ static void
61
+ bare_ffmpeg__on_init(void) {
62
+ av_log_set_level(AV_LOG_ERROR);
63
+ }
64
+
65
+ static js_value_t *
66
+ bare_ffmpeg_io_context_init(js_env_t *env, js_callback_info_t *info) {
67
+ int err;
68
+
69
+ size_t argc = 1;
70
+ js_value_t *argv[1];
71
+
72
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
73
+ assert(err == 0);
74
+
75
+ assert(argc == 1);
76
+
77
+ void *data;
78
+ size_t len;
79
+ err = js_get_typedarray_info(env, argv[0], NULL, &data, &len, NULL, NULL);
80
+ assert(err == 0);
81
+
82
+ js_value_t *handle;
83
+
84
+ bare_ffmpeg_io_context_t *context;
85
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_io_context_t), (void **) &context, &handle);
86
+ assert(err == 0);
87
+
88
+ uint8_t *io;
89
+
90
+ if (len == 0) io = NULL;
91
+ else {
92
+ io = av_malloc(len);
93
+
94
+ memcpy(io, data, len);
95
+ }
96
+
97
+ context->handle = avio_alloc_context(io, len, 0, NULL, NULL, NULL, NULL);
98
+
99
+ context->handle->opaque = (void *) context;
100
+
101
+ return handle;
102
+ }
103
+
104
+ static js_value_t *
105
+ bare_ffmpeg_io_context_destroy(js_env_t *env, js_callback_info_t *info) {
106
+ int err;
107
+
108
+ size_t argc = 1;
109
+ js_value_t *argv[1];
110
+
111
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
112
+ assert(err == 0);
113
+
114
+ assert(argc == 1);
115
+
116
+ bare_ffmpeg_io_context_t *context;
117
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
118
+ assert(err == 0);
119
+
120
+ av_free(context->handle->buffer);
121
+
122
+ avio_context_free(&context->handle);
123
+
124
+ return NULL;
125
+ }
126
+
127
+ static js_value_t *
128
+ bare_ffmpeg_format_context_init(js_env_t *env, js_callback_info_t *info) {
129
+ int err;
130
+
131
+ size_t argc = 1;
132
+ js_value_t *argv[1];
133
+
134
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
135
+ assert(err == 0);
136
+
137
+ assert(argc == 1);
138
+
139
+ bare_ffmpeg_io_context_t *io;
140
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &io, NULL);
141
+ assert(err == 0);
142
+
143
+ js_value_t *handle;
144
+
145
+ bare_ffmpeg_format_context_t *context;
146
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_format_context_t), (void **) &context, &handle);
147
+ assert(err == 0);
148
+
149
+ context->handle = avformat_alloc_context();
150
+
151
+ context->handle->pb = io->handle;
152
+ context->handle->opaque = (void *) context;
153
+
154
+ err = avformat_open_input(&context->handle, NULL, NULL, NULL);
155
+
156
+ if (err < 0) {
157
+ avformat_free_context(context->handle);
158
+
159
+ err = js_throw_error(env, NULL, av_err2str(err));
160
+ assert(err == 0);
161
+
162
+ return NULL;
163
+ }
164
+
165
+ err = avformat_find_stream_info(context->handle, NULL);
166
+
167
+ if (err < 0) {
168
+ avformat_close_input(&context->handle);
169
+
170
+ err = js_throw_error(env, NULL, av_err2str(err));
171
+ assert(err == 0);
172
+
173
+ return NULL;
174
+ }
175
+
176
+ return handle;
177
+ }
178
+
179
+ static js_value_t *
180
+ bare_ffmpeg_format_context_destroy(js_env_t *env, js_callback_info_t *info) {
181
+ int err;
182
+
183
+ size_t argc = 1;
184
+ js_value_t *argv[1];
185
+
186
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
187
+ assert(err == 0);
188
+
189
+ assert(argc == 1);
190
+
191
+ bare_ffmpeg_format_context_t *context;
192
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
193
+ assert(err == 0);
194
+
195
+ avformat_close_input(&context->handle);
196
+
197
+ return NULL;
198
+ }
199
+
200
+ static js_value_t *
201
+ bare_ffmpeg_format_context_get_streams(js_env_t *env, js_callback_info_t *info) {
202
+ int err;
203
+
204
+ size_t argc = 1;
205
+ js_value_t *argv[1];
206
+
207
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
208
+ assert(err == 0);
209
+
210
+ assert(argc == 1);
211
+
212
+ bare_ffmpeg_format_context_t *context;
213
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
214
+ assert(err == 0);
215
+
216
+ uint32_t len = context->handle->nb_streams;
217
+
218
+ js_value_t *result;
219
+ err = js_create_array_with_length(env, len, &result);
220
+ assert(err == 0);
221
+
222
+ for (uint32_t i = 0; i < len; i++) {
223
+ js_value_t *handle;
224
+
225
+ bare_ffmpeg_stream_t *stream;
226
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_stream_t), (void **) &stream, &handle);
227
+ assert(err == 0);
228
+
229
+ stream->handle = context->handle->streams[i];
230
+
231
+ err = js_set_element(env, result, i, handle);
232
+ assert(err == 0);
233
+ }
234
+
235
+ return result;
236
+ }
237
+
238
+ static js_value_t *
239
+ bare_ffmpeg_format_context_read_frame(js_env_t *env, js_callback_info_t *info) {
240
+ int err;
241
+
242
+ size_t argc = 2;
243
+ js_value_t *argv[2];
244
+
245
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
246
+ assert(err == 0);
247
+
248
+ assert(argc == 2);
249
+
250
+ bare_ffmpeg_format_context_t *context;
251
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
252
+ assert(err == 0);
253
+
254
+ bare_ffmpeg_packet_t *packet;
255
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &packet, NULL);
256
+ assert(err == 0);
257
+
258
+ av_packet_unref(&packet->handle);
259
+
260
+ err = av_read_frame(context->handle, &packet->handle);
261
+
262
+ if (err < 0) {
263
+ err = js_throw_error(env, NULL, av_err2str(err));
264
+ assert(err == 0);
265
+ }
266
+
267
+ return NULL;
268
+ }
269
+
270
+ static js_value_t *
271
+ bare_ffmpeg_stream_get_codec(js_env_t *env, js_callback_info_t *info) {
272
+ int err;
273
+
274
+ size_t argc = 1;
275
+ js_value_t *argv[1];
276
+
277
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
278
+ assert(err == 0);
279
+
280
+ assert(argc == 1);
281
+
282
+ bare_ffmpeg_stream_t *stream;
283
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &stream, NULL);
284
+ assert(err == 0);
285
+
286
+ js_value_t *id;
287
+ err = js_create_uint32(env, stream->handle->codecpar->codec_id, &id);
288
+ assert(err == 0);
289
+
290
+ return id;
291
+ }
292
+
293
+ static js_value_t *
294
+ bare_ffmpeg_stream_get_codec_parameters(js_env_t *env, js_callback_info_t *info) {
295
+ int err;
296
+
297
+ size_t argc = 1;
298
+ js_value_t *argv[1];
299
+
300
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
301
+ assert(err == 0);
302
+
303
+ assert(argc == 1);
304
+
305
+ bare_ffmpeg_stream_t *stream;
306
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &stream, NULL);
307
+ assert(err == 0);
308
+
309
+ js_value_t *handle;
310
+
311
+ bare_ffmpeg_codec_parameters_t *parameters;
312
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_codec_parameters_t), (void **) &parameters, &handle);
313
+ assert(err == 0);
314
+
315
+ parameters->handle = stream->handle->codecpar;
316
+
317
+ return handle;
318
+ }
319
+
320
+ static js_value_t *
321
+ bare_ffmpeg_find_decoder_by_id(js_env_t *env, js_callback_info_t *info) {
322
+ int err;
323
+
324
+ size_t argc = 1;
325
+ js_value_t *argv[1];
326
+
327
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
328
+ assert(err == 0);
329
+
330
+ assert(argc == 1);
331
+
332
+ uint32_t id;
333
+ err = js_get_value_uint32(env, argv[0], &id);
334
+ assert(err == 0);
335
+
336
+ const AVCodec *decoder = avcodec_find_decoder((enum AVCodecID) id);
337
+
338
+ if (decoder == NULL) {
339
+ err = js_throw_errorf(env, NULL, "No decoder found for codec '%d'", id);
340
+ assert(err == 0);
341
+
342
+ return NULL;
343
+ }
344
+
345
+ js_value_t *handle;
346
+
347
+ bare_ffmpeg_codec_t *context;
348
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_codec_t), (void **) &context, &handle);
349
+ assert(err == 0);
350
+
351
+ context->handle = decoder;
352
+
353
+ return handle;
354
+ }
355
+
356
+ static js_value_t *
357
+ bare_ffmpeg_find_encoder_by_id(js_env_t *env, js_callback_info_t *info) {
358
+ int err;
359
+
360
+ size_t argc = 1;
361
+ js_value_t *argv[1];
362
+
363
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
364
+ assert(err == 0);
365
+
366
+ assert(argc == 1);
367
+
368
+ uint32_t id;
369
+ err = js_get_value_uint32(env, argv[0], &id);
370
+ assert(err == 0);
371
+
372
+ const AVCodec *encoder = avcodec_find_encoder((enum AVCodecID) id);
373
+
374
+ if (encoder == NULL) {
375
+ err = js_throw_errorf(env, NULL, "No encoder found for codec '%d'", id);
376
+ assert(err == 0);
377
+
378
+ return NULL;
379
+ }
380
+
381
+ js_value_t *handle;
382
+
383
+ bare_ffmpeg_codec_t *context;
384
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_codec_t), (void **) &context, &handle);
385
+ assert(err == 0);
386
+
387
+ context->handle = encoder;
388
+
389
+ return handle;
390
+ }
391
+
392
+ static js_value_t *
393
+ bare_ffmpeg_codec_context_init(js_env_t *env, js_callback_info_t *info) {
394
+ int err;
395
+
396
+ size_t argc = 2;
397
+ js_value_t *argv[2];
398
+
399
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
400
+ assert(err == 0);
401
+
402
+ assert(argc == 2);
403
+
404
+ bare_ffmpeg_codec_t *codec;
405
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &codec, NULL);
406
+ assert(err == 0);
407
+
408
+ bare_ffmpeg_codec_parameters_t *parameters;
409
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &parameters, NULL);
410
+ assert(err == 0);
411
+
412
+ js_value_t *handle;
413
+
414
+ bare_ffmpeg_codec_context_t *context;
415
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_codec_context_t), (void **) &context, &handle);
416
+ assert(err == 0);
417
+
418
+ context->handle = avcodec_alloc_context3(codec->handle);
419
+
420
+ context->handle->opaque = (void *) context;
421
+
422
+ err = avcodec_parameters_to_context(context->handle, parameters->handle);
423
+
424
+ if (err < 0) {
425
+ avcodec_free_context(&context->handle);
426
+
427
+ err = js_throw_error(env, NULL, av_err2str(err));
428
+ assert(err == 0);
429
+
430
+ return NULL;
431
+ }
432
+
433
+ err = avcodec_open2(context->handle, codec->handle, NULL);
434
+
435
+ if (err < 0) {
436
+ avcodec_free_context(&context->handle);
437
+
438
+ err = js_throw_error(env, NULL, av_err2str(err));
439
+ assert(err == 0);
440
+
441
+ return NULL;
442
+ }
443
+
444
+ return handle;
445
+ }
446
+
447
+ static js_value_t *
448
+ bare_ffmpeg_codec_context_destroy(js_env_t *env, js_callback_info_t *info) {
449
+ int err;
450
+
451
+ size_t argc = 1;
452
+ js_value_t *argv[1];
453
+
454
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
455
+ assert(err == 0);
456
+
457
+ assert(argc == 1);
458
+
459
+ bare_ffmpeg_codec_context_t *context;
460
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
461
+ assert(err == 0);
462
+
463
+ avcodec_free_context(&context->handle);
464
+
465
+ return NULL;
466
+ }
467
+
468
+ static js_value_t *
469
+ bare_ffmpeg_codec_context_get_pixel_format(js_env_t *env, js_callback_info_t *info) {
470
+ int err;
471
+
472
+ size_t argc = 1;
473
+ js_value_t *argv[1];
474
+
475
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
476
+ assert(err == 0);
477
+
478
+ assert(argc == 1);
479
+
480
+ bare_ffmpeg_codec_context_t *context;
481
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
482
+ assert(err == 0);
483
+
484
+ js_value_t *result;
485
+ err = js_create_int64(env, context->handle->pix_fmt, &result);
486
+ assert(err == 0);
487
+
488
+ return result;
489
+ }
490
+
491
+ static js_value_t *
492
+ bare_ffmpeg_codec_context_get_width(js_env_t *env, js_callback_info_t *info) {
493
+ int err;
494
+
495
+ size_t argc = 1;
496
+ js_value_t *argv[1];
497
+
498
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
499
+ assert(err == 0);
500
+
501
+ assert(argc == 1);
502
+
503
+ bare_ffmpeg_codec_context_t *context;
504
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
505
+ assert(err == 0);
506
+
507
+ js_value_t *result;
508
+ err = js_create_int64(env, context->handle->width, &result);
509
+ assert(err == 0);
510
+
511
+ return result;
512
+ }
513
+
514
+ static js_value_t *
515
+ bare_ffmpeg_codec_context_get_height(js_env_t *env, js_callback_info_t *info) {
516
+ int err;
517
+
518
+ size_t argc = 1;
519
+ js_value_t *argv[1];
520
+
521
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
522
+ assert(err == 0);
523
+
524
+ assert(argc == 1);
525
+
526
+ bare_ffmpeg_codec_context_t *context;
527
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
528
+ assert(err == 0);
529
+
530
+ js_value_t *result;
531
+ err = js_create_int64(env, context->handle->height, &result);
532
+ assert(err == 0);
533
+
534
+ return result;
535
+ }
536
+
537
+ static js_value_t *
538
+ bare_ffmpeg_codec_context_send_packet(js_env_t *env, js_callback_info_t *info) {
539
+ int err;
540
+
541
+ size_t argc = 2;
542
+ js_value_t *argv[2];
543
+
544
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
545
+ assert(err == 0);
546
+
547
+ assert(argc == 2);
548
+
549
+ bare_ffmpeg_codec_context_t *context;
550
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
551
+ assert(err == 0);
552
+
553
+ bare_ffmpeg_packet_t *packet;
554
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &packet, NULL);
555
+ assert(err == 0);
556
+
557
+ err = avcodec_send_packet(context->handle, &packet->handle);
558
+
559
+ if (err < 0) {
560
+ err = js_throw_error(env, NULL, av_err2str(err));
561
+ assert(err == 0);
562
+ }
563
+
564
+ return NULL;
565
+ }
566
+
567
+ static js_value_t *
568
+ bare_ffmpeg_codec_context_receive_frame(js_env_t *env, js_callback_info_t *info) {
569
+ int err;
570
+
571
+ size_t argc = 2;
572
+ js_value_t *argv[2];
573
+
574
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
575
+ assert(err == 0);
576
+
577
+ assert(argc == 2);
578
+
579
+ bare_ffmpeg_codec_context_t *context;
580
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
581
+ assert(err == 0);
582
+
583
+ bare_ffmpeg_frame_t *frame;
584
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &frame, NULL);
585
+ assert(err == 0);
586
+
587
+ err = avcodec_receive_frame(context->handle, frame->handle);
588
+
589
+ if (err < 0) {
590
+ err = js_throw_error(env, NULL, av_err2str(err));
591
+ assert(err == 0);
592
+ }
593
+
594
+ return NULL;
595
+ }
596
+
597
+ static js_value_t *
598
+ bare_ffmpeg_frame_init(js_env_t *env, js_callback_info_t *info) {
599
+ int err;
600
+
601
+ js_value_t *handle;
602
+
603
+ bare_ffmpeg_frame_t *frame;
604
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_frame_t), (void **) &frame, &handle);
605
+ assert(err == 0);
606
+
607
+ frame->handle = av_frame_alloc();
608
+
609
+ frame->handle->opaque = (void *) frame;
610
+
611
+ return handle;
612
+ }
613
+
614
+ static js_value_t *
615
+ bare_ffmpeg_frame_destroy(js_env_t *env, js_callback_info_t *info) {
616
+ int err;
617
+
618
+ size_t argc = 1;
619
+ js_value_t *argv[1];
620
+
621
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
622
+ assert(err == 0);
623
+
624
+ assert(argc == 1);
625
+
626
+ bare_ffmpeg_frame_t *frame;
627
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &frame, NULL);
628
+ assert(err == 0);
629
+
630
+ av_frame_free(&frame->handle);
631
+
632
+ return NULL;
633
+ }
634
+
635
+ static js_value_t *
636
+ bare_ffmpeg_image_init(js_env_t *env, js_callback_info_t *info) {
637
+ int err;
638
+
639
+ size_t argc = 4;
640
+ js_value_t *argv[4];
641
+
642
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
643
+ assert(err == 0);
644
+
645
+ assert(argc == 4);
646
+
647
+ int64_t format;
648
+ err = js_get_value_int64(env, argv[0], &format);
649
+ assert(err == 0);
650
+
651
+ int32_t width;
652
+ err = js_get_value_int32(env, argv[1], &width);
653
+ assert(err == 0);
654
+
655
+ int32_t height;
656
+ err = js_get_value_int32(env, argv[2], &height);
657
+ assert(err == 0);
658
+
659
+ int32_t align;
660
+ err = js_get_value_int32(env, argv[3], &align);
661
+ assert(err == 0);
662
+
663
+ size_t len = av_image_get_buffer_size((enum AVPixelFormat) format, width, height, align);
664
+
665
+ js_value_t *handle;
666
+
667
+ uint8_t *data;
668
+ err = js_create_arraybuffer(env, len, (void **) &data, &handle);
669
+ assert(err == 0);
670
+
671
+ return handle;
672
+ }
673
+
674
+ static js_value_t *
675
+ bare_ffmpeg_image_fill(js_env_t *env, js_callback_info_t *info) {
676
+ int err;
677
+
678
+ size_t argc = 5;
679
+ js_value_t *argv[5];
680
+
681
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
682
+ assert(err == 0);
683
+
684
+ assert(argc == 5);
685
+
686
+ int64_t pixel_format;
687
+ err = js_get_value_int64(env, argv[0], &pixel_format);
688
+ assert(err == 0);
689
+
690
+ int32_t width;
691
+ err = js_get_value_int32(env, argv[1], &width);
692
+ assert(err == 0);
693
+
694
+ int32_t height;
695
+ err = js_get_value_int32(env, argv[2], &height);
696
+ assert(err == 0);
697
+
698
+ uint8_t *data;
699
+ err = js_get_arraybuffer_info(env, argv[3], (void **) &data, NULL);
700
+ assert(err == 0);
701
+
702
+ bare_ffmpeg_frame_t *frame;
703
+ err = js_get_arraybuffer_info(env, argv[4], (void **) &frame, NULL);
704
+ assert(err == 0);
705
+
706
+ err = av_image_fill_arrays(frame->handle->data, frame->handle->linesize, data, (enum AVPixelFormat) pixel_format, width, height, 1);
707
+ assert(err >= 0);
708
+
709
+ return NULL;
710
+ }
711
+
712
+ static js_value_t *
713
+ bare_ffmpeg_packet_init(js_env_t *env, js_callback_info_t *info) {
714
+ int err;
715
+
716
+ js_value_t *handle;
717
+
718
+ bare_ffmpeg_packet_t *packet;
719
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_packet_t), (void **) &packet, &handle);
720
+ assert(err == 0);
721
+
722
+ return handle;
723
+ }
724
+
725
+ static js_value_t *
726
+ bare_ffmpeg_packet_destroy(js_env_t *env, js_callback_info_t *info) {
727
+ int err;
728
+
729
+ size_t argc = 1;
730
+ js_value_t *argv[1];
731
+
732
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
733
+ assert(err == 0);
734
+
735
+ assert(argc == 1);
736
+
737
+ bare_ffmpeg_packet_t *packet;
738
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
739
+ assert(err == 0);
740
+
741
+ av_packet_unref(&packet->handle);
742
+
743
+ return NULL;
744
+ }
745
+
746
+ static js_value_t *
747
+ bare_ffmpeg_packet_unref(js_env_t *env, js_callback_info_t *info) {
748
+ int err;
749
+
750
+ size_t argc = 1;
751
+ js_value_t *argv[1];
752
+
753
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
754
+ assert(err == 0);
755
+
756
+ assert(argc == 1);
757
+
758
+ bare_ffmpeg_packet_t *packet;
759
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
760
+ assert(err == 0);
761
+
762
+ av_packet_unref(&packet->handle);
763
+
764
+ return NULL;
765
+ }
766
+
767
+ static js_value_t *
768
+ bare_ffmpeg_scaler_init(js_env_t *env, js_callback_info_t *info) {
769
+ int err;
770
+
771
+ size_t argc = 6;
772
+ js_value_t *argv[6];
773
+
774
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
775
+ assert(err == 0);
776
+
777
+ assert(argc == 6);
778
+
779
+ int64_t source_format;
780
+ err = js_get_value_int64(env, argv[0], &source_format);
781
+ assert(err == 0);
782
+
783
+ int32_t source_width;
784
+ err = js_get_value_int32(env, argv[1], &source_width);
785
+ assert(err == 0);
786
+
787
+ int32_t source_height;
788
+ err = js_get_value_int32(env, argv[2], &source_height);
789
+ assert(err == 0);
790
+
791
+ int64_t target_format;
792
+ err = js_get_value_int64(env, argv[3], &target_format);
793
+ assert(err == 0);
794
+
795
+ int32_t target_width;
796
+ err = js_get_value_int32(env, argv[4], &target_width);
797
+ assert(err == 0);
798
+
799
+ int32_t target_height;
800
+ err = js_get_value_int32(env, argv[5], &target_height);
801
+ assert(err == 0);
802
+
803
+ js_value_t *handle;
804
+
805
+ bare_ffmpeg_scaler_t *scaler;
806
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_scaler_t), (void **) &scaler, &handle);
807
+ assert(err == 0);
808
+
809
+ scaler->handle = sws_getContext(
810
+ source_width,
811
+ source_height,
812
+ (enum AVPixelFormat) source_format,
813
+ target_width,
814
+ target_height,
815
+ (enum AVPixelFormat) target_format,
816
+ SWS_BICUBIC,
817
+ NULL,
818
+ NULL,
819
+ NULL
820
+ );
821
+
822
+ return handle;
823
+ }
824
+
825
+ static js_value_t *
826
+ bare_ffmpeg_scaler_destroy(js_env_t *env, js_callback_info_t *info) {
827
+ int err;
828
+
829
+ size_t argc = 1;
830
+ js_value_t *argv[1];
831
+
832
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
833
+ assert(err == 0);
834
+
835
+ assert(argc == 1);
836
+
837
+ bare_ffmpeg_scaler_t *scaler;
838
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &scaler, NULL);
839
+ assert(err == 0);
840
+
841
+ sws_freeContext(scaler->handle);
842
+
843
+ return NULL;
844
+ }
845
+
846
+ static js_value_t *
847
+ bare_ffmpeg_scaler_scale(js_env_t *env, js_callback_info_t *info) {
848
+ int err;
849
+
850
+ size_t argc = 5;
851
+ js_value_t *argv[5];
852
+
853
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
854
+ assert(err == 0);
855
+
856
+ assert(argc == 5);
857
+
858
+ bare_ffmpeg_scaler_t *scaler;
859
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &scaler, NULL);
860
+ assert(err == 0);
861
+
862
+ bare_ffmpeg_frame_t *source;
863
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &source, NULL);
864
+ assert(err == 0);
865
+
866
+ int64_t y;
867
+ err = js_get_value_int64(env, argv[2], &y);
868
+ assert(err == 0);
869
+
870
+ int64_t height;
871
+ err = js_get_value_int64(env, argv[3], &height);
872
+ assert(err == 0);
873
+
874
+ bare_ffmpeg_frame_t *target;
875
+ err = js_get_arraybuffer_info(env, argv[4], (void **) &target, NULL);
876
+ assert(err == 0);
877
+
878
+ height = sws_scale(
879
+ scaler->handle,
880
+ (const uint8_t *const *) source->handle->data,
881
+ source->handle->linesize,
882
+ y,
883
+ height,
884
+ target->handle->data,
885
+ target->handle->linesize
886
+ );
887
+
888
+ js_value_t *result;
889
+ err = js_create_int64(env, height, &result);
890
+ assert(err == 0);
891
+
892
+ return result;
893
+ }
894
+
895
+ static js_value_t *
896
+ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
897
+ uv_once(&bare_ffmpeg__init_guard, bare_ffmpeg__on_init);
898
+
899
+ int err;
900
+
901
+ #define V(name, fn) \
902
+ { \
903
+ js_value_t *val; \
904
+ err = js_create_function(env, name, -1, fn, NULL, &val); \
905
+ assert(err == 0); \
906
+ err = js_set_named_property(env, exports, name, val); \
907
+ assert(err == 0); \
908
+ }
909
+
910
+ V("initIOContext", bare_ffmpeg_io_context_init)
911
+ V("destroyIOContext", bare_ffmpeg_io_context_destroy)
912
+
913
+ V("initFormatContext", bare_ffmpeg_format_context_init)
914
+ V("destroyFormatContext", bare_ffmpeg_format_context_destroy)
915
+ V("getFormatContextStreams", bare_ffmpeg_format_context_get_streams)
916
+ V("readFormatContextFrame", bare_ffmpeg_format_context_read_frame)
917
+
918
+ V("getStreamCodec", bare_ffmpeg_stream_get_codec)
919
+ V("getStreamCodecParameters", bare_ffmpeg_stream_get_codec_parameters)
920
+
921
+ V("findDecoderByID", bare_ffmpeg_find_decoder_by_id)
922
+ V("findEncoderByID", bare_ffmpeg_find_encoder_by_id)
923
+
924
+ V("initCodecContext", bare_ffmpeg_codec_context_init)
925
+ V("destroyCodecContext", bare_ffmpeg_codec_context_destroy)
926
+ V("getCodecContextPixelFormat", bare_ffmpeg_codec_context_get_pixel_format)
927
+ V("getCodecContextWidth", bare_ffmpeg_codec_context_get_width)
928
+ V("getCodecContextHeight", bare_ffmpeg_codec_context_get_height)
929
+ V("sendCodecContextPacket", bare_ffmpeg_codec_context_send_packet)
930
+ V("receiveCodecContextFrame", bare_ffmpeg_codec_context_receive_frame)
931
+
932
+ V("initFrame", bare_ffmpeg_frame_init)
933
+ V("destroyFrame", bare_ffmpeg_frame_destroy)
934
+
935
+ V("initImage", bare_ffmpeg_image_init)
936
+ V("fillImage", bare_ffmpeg_image_fill)
937
+
938
+ V("initPacket", bare_ffmpeg_packet_init)
939
+ V("destroyPacket", bare_ffmpeg_packet_destroy)
940
+ V("unrefPacket", bare_ffmpeg_packet_unref)
941
+
942
+ V("initScaler", bare_ffmpeg_scaler_init)
943
+ V("destroyScaler", bare_ffmpeg_scaler_destroy)
944
+ V("scaleScaler", bare_ffmpeg_scaler_scale)
945
+ #undef V
946
+
947
+ #define V(name) \
948
+ { \
949
+ js_value_t *val; \
950
+ err = js_create_int64(env, name, &val); \
951
+ assert(err == 0); \
952
+ err = js_set_named_property(env, exports, #name, val); \
953
+ assert(err == 0); \
954
+ }
955
+
956
+ V(AV_PIX_FMT_RGBA)
957
+ #undef V
958
+
959
+ return exports;
960
+ }
961
+
962
+ BARE_MODULE(bare_ffmpeg, bare_ffmpeg_exports)