bare-ffmpeg 1.0.0-1 → 1.0.0-3

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/CMakeLists.txt CHANGED
@@ -5,7 +5,7 @@ find_package(cmake-ports REQUIRED PATHS node_modules/cmake-ports)
5
5
 
6
6
  project(bare_ffmpeg C)
7
7
 
8
- find_port(ffmpeg FEATURES dav1d)
8
+ find_port(ffmpeg FEATURES dav1d x264)
9
9
 
10
10
  add_bare_module(bare_ffmpeg)
11
11
 
package/binding.c CHANGED
@@ -59,7 +59,7 @@ typedef struct {
59
59
  } bare_ffmpeg_frame_t;
60
60
 
61
61
  typedef struct {
62
- AVPacket handle;
62
+ AVPacket *handle;
63
63
  } bare_ffmpeg_packet_t;
64
64
 
65
65
  typedef struct {
@@ -229,7 +229,7 @@ bare_ffmpeg_input_format_init(js_env_t *env, js_callback_info_t *info) {
229
229
  }
230
230
 
231
231
  static js_value_t *
232
- bare_ffmpeg_format_context_open_input(js_env_t *env, js_callback_info_t *info) {
232
+ bare_ffmpeg_format_context_open_input_with_io(js_env_t *env, js_callback_info_t *info) {
233
233
  int err;
234
234
 
235
235
  size_t argc = 1;
@@ -280,6 +280,70 @@ bare_ffmpeg_format_context_open_input(js_env_t *env, js_callback_info_t *info) {
280
280
  return handle;
281
281
  }
282
282
 
283
+ static js_value_t *
284
+ bare_ffmpeg_format_context_open_input_with_format(js_env_t *env, js_callback_info_t *info) {
285
+ int err;
286
+
287
+ size_t argc = 3;
288
+ js_value_t *argv[3];
289
+
290
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
291
+ assert(err == 0);
292
+ assert(argc == 3);
293
+
294
+ bare_ffmpeg_input_format_t *format;
295
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &format, NULL);
296
+ assert(err == 0);
297
+
298
+ js_value_t *handle;
299
+
300
+ bare_ffmpeg_format_context_t *context;
301
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_format_context_t), (void **) &context, &handle);
302
+ assert(err == 0);
303
+
304
+ context->handle = avformat_alloc_context();
305
+ context->handle->opaque = (void *) context;
306
+
307
+ bare_ffmpeg_dictionary_t *options;
308
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &options, NULL);
309
+ assert(err == 0);
310
+
311
+ size_t len;
312
+ err = js_get_value_string_utf8(env, argv[2], NULL, 0, &len);
313
+ assert(err == 0);
314
+
315
+ len += +1 /* NULL */;
316
+
317
+ utf8_t *url = malloc(len);
318
+ err = js_get_value_string_utf8(env, argv[2], url, len, NULL);
319
+ assert(err == 0);
320
+
321
+ err = avformat_open_input(&context->handle, (char *) url, format->handle, &options->handle);
322
+ free(url);
323
+
324
+ if (err < 0) {
325
+ avformat_free_context(context->handle);
326
+
327
+ err = js_throw_error(env, NULL, av_err2str(err));
328
+ assert(err == 0);
329
+
330
+ return NULL;
331
+ }
332
+
333
+ err = avformat_find_stream_info(context->handle, NULL);
334
+
335
+ if (err < 0) {
336
+ avformat_close_input(&context->handle);
337
+
338
+ err = js_throw_error(env, NULL, av_err2str(err));
339
+ assert(err == 0);
340
+
341
+ return NULL;
342
+ }
343
+
344
+ return handle;
345
+ }
346
+
283
347
  static js_value_t *
284
348
  bare_ffmpeg_format_context_close_input(js_env_t *env, js_callback_info_t *info) {
285
349
  int err;
@@ -401,6 +465,38 @@ bare_ffmpeg_format_context_get_streams(js_env_t *env, js_callback_info_t *info)
401
465
  return result;
402
466
  }
403
467
 
468
+ static js_value_t *
469
+ bare_ffmpeg_format_context_get_best_stream_index(js_env_t *env, js_callback_info_t *info) {
470
+ int err;
471
+
472
+ size_t argc = 2;
473
+ js_value_t *argv[2];
474
+
475
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
476
+ assert(err == 0);
477
+
478
+ assert(argc == 2);
479
+
480
+ bare_ffmpeg_format_context_t *context;
481
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
482
+ assert(err == 0);
483
+
484
+ int type;
485
+ err = js_get_value_int32(env, argv[1], &type);
486
+ assert(err == 0);
487
+
488
+ int stream_index = av_find_best_stream(context->handle, type, -1, -1, NULL, 0);
489
+ if (stream_index < 0) {
490
+ stream_index = -1;
491
+ }
492
+
493
+ js_value_t *result;
494
+ err = js_create_int32(env, stream_index, &result);
495
+ assert(err == 0);
496
+
497
+ return result;
498
+ }
499
+
404
500
  static js_value_t *
405
501
  bare_ffmpeg_format_context_create_stream(js_env_t *env, js_callback_info_t *info) {
406
502
  int err;
@@ -459,9 +555,9 @@ bare_ffmpeg_format_context_read_frame(js_env_t *env, js_callback_info_t *info) {
459
555
  err = js_get_arraybuffer_info(env, argv[1], (void **) &packet, NULL);
460
556
  assert(err == 0);
461
557
 
462
- av_packet_unref(&packet->handle);
558
+ av_packet_unref(packet->handle);
463
559
 
464
- err = av_read_frame(context->handle, &packet->handle);
560
+ err = av_read_frame(context->handle, packet->handle);
465
561
 
466
562
  if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
467
563
  err = js_throw_error(env, NULL, av_err2str(err));
@@ -656,7 +752,6 @@ bare_ffmpeg_codec_context_open(js_env_t *env, js_callback_info_t *info) {
656
752
 
657
753
  err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
658
754
  assert(err == 0);
659
-
660
755
  assert(argc == 1);
661
756
 
662
757
  bare_ffmpeg_codec_context_t *context;
@@ -673,6 +768,34 @@ bare_ffmpeg_codec_context_open(js_env_t *env, js_callback_info_t *info) {
673
768
  return NULL;
674
769
  }
675
770
 
771
+ static js_value_t *
772
+ bare_ffmpeg_codec_context_open_with_options(js_env_t *env, js_callback_info_t *info) {
773
+ int err;
774
+
775
+ size_t argc = 2;
776
+ js_value_t *argv[2];
777
+
778
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
779
+ assert(err == 0);
780
+ assert(argc == 2);
781
+
782
+ bare_ffmpeg_codec_context_t *context;
783
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
784
+ assert(err == 0);
785
+
786
+ bare_ffmpeg_dictionary_t *options;
787
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &options, NULL);
788
+ assert(err == 0);
789
+
790
+ err = avcodec_open2(context->handle, context->handle->codec, &options->handle);
791
+ if (err < 0) {
792
+ err = js_throw_error(env, NULL, av_err2str(err));
793
+ assert(err == 0);
794
+ }
795
+
796
+ return NULL;
797
+ }
798
+
676
799
  static js_value_t *
677
800
  bare_ffmpeg_codec_context_get_pixel_format(js_env_t *env, js_callback_info_t *info) {
678
801
  int err;
@@ -891,7 +1014,7 @@ bare_ffmpeg_codec_context_send_packet(js_env_t *env, js_callback_info_t *info) {
891
1014
  err = js_get_arraybuffer_info(env, argv[1], (void **) &packet, NULL);
892
1015
  assert(err == 0);
893
1016
 
894
- err = avcodec_send_packet(context->handle, &packet->handle);
1017
+ err = avcodec_send_packet(context->handle, packet->handle);
895
1018
 
896
1019
  if (err < 0) {
897
1020
  err = js_throw_error(env, NULL, av_err2str(err));
@@ -901,6 +1024,83 @@ bare_ffmpeg_codec_context_send_packet(js_env_t *env, js_callback_info_t *info) {
901
1024
  return NULL;
902
1025
  }
903
1026
 
1027
+ static js_value_t *
1028
+ bare_ffmpeg_codec_context_receive_packet(js_env_t *env, js_callback_info_t *info) {
1029
+ int err;
1030
+
1031
+ size_t argc = 2;
1032
+ js_value_t *argv[2];
1033
+
1034
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1035
+ assert(err == 0);
1036
+ assert(argc == 2);
1037
+
1038
+ bare_ffmpeg_codec_context_t *context;
1039
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
1040
+ assert(err == 0);
1041
+
1042
+ bare_ffmpeg_packet_t *packet;
1043
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &packet, NULL);
1044
+ assert(err == 0);
1045
+
1046
+ err = avcodec_receive_packet(context->handle, packet->handle);
1047
+
1048
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
1049
+ err = js_throw_error(env, NULL, av_err2str(err));
1050
+ assert(err == 0);
1051
+
1052
+ return NULL;
1053
+ }
1054
+
1055
+ js_value_t *result;
1056
+ err = js_get_boolean(env, err == 0, &result);
1057
+ assert(err == 0);
1058
+
1059
+ return result;
1060
+ }
1061
+
1062
+ static js_value_t *
1063
+ bare_ffmpeg_codec_context_send_frame(js_env_t *env, js_callback_info_t *info) {
1064
+ int err;
1065
+
1066
+ size_t argc = 2;
1067
+ js_value_t *argv[2];
1068
+
1069
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1070
+ assert(err == 0);
1071
+ assert(argc == 2);
1072
+
1073
+ bare_ffmpeg_codec_context_t *context;
1074
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &context, NULL);
1075
+ assert(err == 0);
1076
+
1077
+ bare_ffmpeg_frame_t *frame;
1078
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &frame, NULL);
1079
+ assert(err == 0);
1080
+
1081
+ err = avcodec_send_frame(context->handle, frame->handle);
1082
+
1083
+ if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
1084
+ js_value_t *result;
1085
+ err = js_get_boolean(env, false, &result);
1086
+ assert(err == 0);
1087
+ return result;
1088
+ }
1089
+
1090
+ if (err < 0) {
1091
+ err = js_throw_error(env, NULL, av_err2str(err));
1092
+ assert(err == 0);
1093
+
1094
+ return NULL;
1095
+ }
1096
+
1097
+ js_value_t *result;
1098
+ err = js_get_boolean(env, err == 0, &result);
1099
+ assert(err == 0);
1100
+
1101
+ return result;
1102
+ }
1103
+
904
1104
  static js_value_t *
905
1105
  bare_ffmpeg_codec_context_receive_frame(js_env_t *env, js_callback_info_t *info) {
906
1106
  int err;
@@ -1304,6 +1504,35 @@ bare_ffmpeg_frame_set_pixel_format(js_env_t *env, js_callback_info_t *info) {
1304
1504
  return NULL;
1305
1505
  }
1306
1506
 
1507
+ static js_value_t *
1508
+ bare_ffmpeg_frame_get_linesize(js_env_t *env, js_callback_info_t *info) {
1509
+ int err;
1510
+
1511
+ size_t argc = 2;
1512
+ js_value_t *argv[2];
1513
+
1514
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1515
+ assert(err == 0);
1516
+ assert(argc == 2);
1517
+
1518
+ bare_ffmpeg_frame_t *frame;
1519
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &frame, NULL);
1520
+ assert(err == 0);
1521
+
1522
+ uint32_t channel;
1523
+ err = js_get_value_uint32(env, argv[1], &channel);
1524
+ assert(err == 0);
1525
+ assert(channel < AV_NUM_DATA_POINTERS);
1526
+
1527
+ int32_t linesize = frame->handle->linesize[channel];
1528
+
1529
+ js_value_t *result;
1530
+ err = js_create_int32(env, linesize, &result);
1531
+ assert(err == 0);
1532
+
1533
+ return result;
1534
+ }
1535
+
1307
1536
  static js_value_t *
1308
1537
  bare_ffmpeg_frame_alloc(js_env_t *env, js_callback_info_t *info) {
1309
1538
  int err;
@@ -1335,6 +1564,49 @@ bare_ffmpeg_frame_alloc(js_env_t *env, js_callback_info_t *info) {
1335
1564
  return NULL;
1336
1565
  }
1337
1566
 
1567
+ static js_value_t *
1568
+ bare_ffmpeg_frame_get_data(js_env_t *env, js_callback_info_t *info) {
1569
+ int err;
1570
+
1571
+ size_t argc = 1;
1572
+ js_value_t *argv[1];
1573
+
1574
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1575
+ assert(err == 0);
1576
+ assert(argc == 1);
1577
+
1578
+ bare_ffmpeg_frame_t *frame;
1579
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &frame, NULL);
1580
+ assert(err == 0);
1581
+
1582
+ int size = av_image_get_buffer_size(
1583
+ frame->handle->format,
1584
+ frame->handle->width,
1585
+ frame->handle->height,
1586
+ 1
1587
+ );
1588
+ assert(size > 0);
1589
+
1590
+ js_value_t *result;
1591
+ uint8_t *buffer;
1592
+ err = js_create_arraybuffer(env, size, (void **) &buffer, &result);
1593
+ assert(err == 0);
1594
+
1595
+ err = av_image_copy_to_buffer(
1596
+ buffer,
1597
+ size,
1598
+ (const uint8_t *const *) frame->handle->data,
1599
+ frame->handle->linesize,
1600
+ frame->handle->format,
1601
+ frame->handle->width,
1602
+ frame->handle->height,
1603
+ 1
1604
+ );
1605
+ assert(err >= 0);
1606
+
1607
+ return result;
1608
+ }
1609
+
1338
1610
  static js_value_t *
1339
1611
  bare_ffmpeg_image_init(js_env_t *env, js_callback_info_t *info) {
1340
1612
  int err;
@@ -1422,6 +1694,49 @@ bare_ffmpeg_packet_init(js_env_t *env, js_callback_info_t *info) {
1422
1694
  err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_packet_t), (void **) &packet, &handle);
1423
1695
  assert(err == 0);
1424
1696
 
1697
+ packet->handle = av_packet_alloc();
1698
+
1699
+ return handle;
1700
+ }
1701
+
1702
+ static js_value_t *
1703
+ bare_ffmpeg_packet_init_from_buffer(js_env_t *env, js_callback_info_t *info) {
1704
+ int err;
1705
+
1706
+ size_t argc = 3;
1707
+ js_value_t *argv[3];
1708
+
1709
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1710
+ assert(err == 0);
1711
+ assert(argc == 3);
1712
+
1713
+ uint8_t *data;
1714
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &data, NULL);
1715
+ assert(err == 0);
1716
+
1717
+ uint32_t offset;
1718
+ err = js_get_value_uint32(env, argv[1], &offset);
1719
+ assert(err == 0);
1720
+
1721
+ uint32_t len;
1722
+ err = js_get_value_uint32(env, argv[2], &len);
1723
+ assert(err == 0);
1724
+
1725
+ AVPacket *pkt = av_packet_alloc();
1726
+ assert(pkt != NULL);
1727
+
1728
+ err = av_new_packet(pkt, len);
1729
+ assert(err == 0);
1730
+
1731
+ memcpy(pkt->data, &data[offset], len);
1732
+
1733
+ js_value_t *handle;
1734
+ bare_ffmpeg_packet_t *packet;
1735
+ err = js_create_arraybuffer(env, sizeof(bare_ffmpeg_packet_t), (void **) &packet, &handle);
1736
+ assert(err == 0);
1737
+
1738
+ packet->handle = pkt;
1739
+
1425
1740
  return handle;
1426
1741
  }
1427
1742
 
@@ -1441,7 +1756,7 @@ bare_ffmpeg_packet_destroy(js_env_t *env, js_callback_info_t *info) {
1441
1756
  err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
1442
1757
  assert(err == 0);
1443
1758
 
1444
- av_packet_unref(&packet->handle);
1759
+ av_packet_unref(packet->handle);
1445
1760
 
1446
1761
  return NULL;
1447
1762
  }
@@ -1462,11 +1777,60 @@ bare_ffmpeg_packet_unref(js_env_t *env, js_callback_info_t *info) {
1462
1777
  err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
1463
1778
  assert(err == 0);
1464
1779
 
1465
- av_packet_unref(&packet->handle);
1780
+ av_packet_unref(packet->handle);
1466
1781
 
1467
1782
  return NULL;
1468
1783
  }
1469
1784
 
1785
+ static js_value_t *
1786
+ bare_ffmpeg_packet_get_stream_index(js_env_t *env, js_callback_info_t *info) {
1787
+ int err;
1788
+
1789
+ size_t argc = 1;
1790
+ js_value_t *argv[1];
1791
+
1792
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1793
+ assert(err == 0);
1794
+
1795
+ assert(argc == 1);
1796
+
1797
+ bare_ffmpeg_packet_t *packet;
1798
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
1799
+ assert(err == 0);
1800
+
1801
+ js_value_t *result;
1802
+ err = js_create_int32(env, packet->handle->stream_index, &result);
1803
+ assert(err == 0);
1804
+
1805
+ return result;
1806
+ }
1807
+
1808
+ static js_value_t *
1809
+ bare_ffmpeg_packet_get_data(js_env_t *env, js_callback_info_t *info) {
1810
+ int err;
1811
+
1812
+ size_t argc = 1;
1813
+ js_value_t *argv[1];
1814
+
1815
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1816
+ assert(err == 0);
1817
+
1818
+ assert(argc == 1);
1819
+
1820
+ bare_ffmpeg_packet_t *packet;
1821
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &packet, NULL);
1822
+ assert(err == 0);
1823
+
1824
+ js_value_t *result;
1825
+ uint8_t *data;
1826
+ err = js_create_arraybuffer(env, packet->handle->size, (void **) &data, &result);
1827
+ assert(err == 0);
1828
+
1829
+ memcpy(data, packet->handle->data, packet->handle->size);
1830
+
1831
+ return result;
1832
+ }
1833
+
1470
1834
  static js_value_t *
1471
1835
  bare_ffmpeg_scaler_init(js_env_t *env, js_callback_info_t *info) {
1472
1836
  int err;
@@ -1734,11 +2098,13 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1734
2098
  V("initOutputFormat", bare_ffmpeg_output_format_init)
1735
2099
  V("initInputFormat", bare_ffmpeg_input_format_init)
1736
2100
 
1737
- V("openInputFormatContext", bare_ffmpeg_format_context_open_input)
2101
+ V("openInputFormatContextWithIO", bare_ffmpeg_format_context_open_input_with_io)
2102
+ V("openInputFormatContextWithFormat", bare_ffmpeg_format_context_open_input_with_format)
1738
2103
  V("closeInputFormatContext", bare_ffmpeg_format_context_close_input)
1739
2104
  V("openOutputFormatContext", bare_ffmpeg_format_context_open_output)
1740
2105
  V("closeOutputFormatContext", bare_ffmpeg_format_context_close_output)
1741
2106
  V("getFormatContextStreams", bare_ffmpeg_format_context_get_streams)
2107
+ V("getFormatContextBestStreamIndex", bare_ffmpeg_format_context_get_best_stream_index)
1742
2108
  V("createFormatContextStream", bare_ffmpeg_format_context_create_stream)
1743
2109
  V("readFormatContextFrame", bare_ffmpeg_format_context_read_frame)
1744
2110
 
@@ -1751,6 +2117,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1751
2117
  V("initCodecContext", bare_ffmpeg_codec_context_init)
1752
2118
  V("destroyCodecContext", bare_ffmpeg_codec_context_destroy)
1753
2119
  V("openCodecContext", bare_ffmpeg_codec_context_open)
2120
+ V("openCodecContextWithOptions", bare_ffmpeg_codec_context_open_with_options)
1754
2121
  V("getCodecContextPixelFormat", bare_ffmpeg_codec_context_get_pixel_format)
1755
2122
  V("setCodecContextPixelFormat", bare_ffmpeg_codec_context_set_pixel_format)
1756
2123
  V("getCodecContextWidth", bare_ffmpeg_codec_context_get_width)
@@ -1760,6 +2127,8 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1760
2127
  V("getCodecContextTimeBase", bare_ffmpeg_codec_context_get_time_base)
1761
2128
  V("setCodecContextTimeBase", bare_ffmpeg_codec_context_set_time_base)
1762
2129
  V("sendCodecContextPacket", bare_ffmpeg_codec_context_send_packet)
2130
+ V("receiveCodecContextPacket", bare_ffmpeg_codec_context_receive_packet)
2131
+ V("sendCodecContextFrame", bare_ffmpeg_codec_context_send_frame)
1763
2132
  V("receiveCodecContextFrame", bare_ffmpeg_codec_context_receive_frame)
1764
2133
 
1765
2134
  V("codecParametersFromContext", bare_ffmpeg_codec_parameters_from_context)
@@ -1778,14 +2147,19 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1778
2147
  V("setFrameHeight", bare_ffmpeg_frame_set_height)
1779
2148
  V("getFramePixelFormat", bare_ffmpeg_frame_get_pixel_format)
1780
2149
  V("setFramePixelFormat", bare_ffmpeg_frame_set_pixel_format)
2150
+ V("getFrameLineSize", bare_ffmpeg_frame_get_linesize)
1781
2151
  V("allocFrame", bare_ffmpeg_frame_alloc)
2152
+ V("getFrameData", bare_ffmpeg_frame_get_data)
1782
2153
 
1783
2154
  V("initImage", bare_ffmpeg_image_init)
1784
2155
  V("fillImage", bare_ffmpeg_image_fill)
1785
2156
 
1786
2157
  V("initPacket", bare_ffmpeg_packet_init)
2158
+ V("initPacketFromBuffer", bare_ffmpeg_packet_init_from_buffer)
1787
2159
  V("destroyPacket", bare_ffmpeg_packet_destroy)
1788
2160
  V("unrefPacket", bare_ffmpeg_packet_unref)
2161
+ V("getPacketStreamIndex", bare_ffmpeg_packet_get_stream_index)
2162
+ V("getPacketData", bare_ffmpeg_packet_get_data)
1789
2163
 
1790
2164
  V("initScaler", bare_ffmpeg_scaler_init)
1791
2165
  V("destroyScaler", bare_ffmpeg_scaler_destroy)
@@ -1807,10 +2181,20 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1807
2181
  }
1808
2182
 
1809
2183
  V(AV_CODEC_ID_MJPEG)
2184
+ V(AV_CODEC_ID_H264)
1810
2185
 
1811
2186
  V(AV_PIX_FMT_RGBA)
2187
+ V(AV_PIX_FMT_RGB24)
1812
2188
  V(AV_PIX_FMT_YUVJ420P)
1813
2189
  V(AV_PIX_FMT_YUV420P)
2190
+
2191
+ V(AVMEDIA_TYPE_UNKNOWN)
2192
+ V(AVMEDIA_TYPE_VIDEO)
2193
+ V(AVMEDIA_TYPE_AUDIO)
2194
+ V(AVMEDIA_TYPE_DATA)
2195
+ V(AVMEDIA_TYPE_SUBTITLE)
2196
+ V(AVMEDIA_TYPE_ATTACHMENT)
2197
+ V(AVMEDIA_TYPE_NB)
1814
2198
  #undef V
1815
2199
 
1816
2200
  return exports;
@@ -52,10 +52,14 @@ module.exports = class FFmpegCodecContext extends ReferenceCounted {
52
52
  binding.setCodecContextTimeBase(this._handle, view.buffer)
53
53
  }
54
54
 
55
- open() {
55
+ open(options) {
56
56
  if (this._opened) return
57
57
  this._opened = true
58
- binding.openCodecContext(this._handle)
58
+ if (options) {
59
+ binding.openCodecContextWithOptions(this._handle, options._handle)
60
+ } else {
61
+ binding.openCodecContext(this._handle)
62
+ }
59
63
  return this
60
64
  }
61
65
 
@@ -64,6 +68,16 @@ module.exports = class FFmpegCodecContext extends ReferenceCounted {
64
68
  return this
65
69
  }
66
70
 
71
+ receivePacket(packet) {
72
+ const res = binding.receiveCodecContextPacket(this._handle, packet._handle)
73
+ if (res) packet._ref()
74
+ return res
75
+ }
76
+
77
+ sendFrame(frame) {
78
+ return binding.sendCodecContextFrame(this._handle, frame._handle)
79
+ }
80
+
67
81
  receiveFrame(frame) {
68
82
  return binding.receiveCodecContextFrame(this._handle, frame._handle)
69
83
  }
package/lib/codec.js CHANGED
@@ -35,4 +35,5 @@ module.exports = class FFmpegCodec {
35
35
  }
36
36
 
37
37
  static MJPEG = this.for(constants.codecs.MJPEG)
38
+ static H264 = this.for(constants.codecs.H264)
38
39
  }
package/lib/constants.js CHANGED
@@ -2,12 +2,24 @@ const binding = require('../binding')
2
2
 
3
3
  module.exports = exports = {
4
4
  codecs: {
5
- MJPEG: binding.AV_CODEC_ID_MJPEG
5
+ MJPEG: binding.AV_CODEC_ID_MJPEG,
6
+ H264: binding.AV_CODEC_ID_H264
6
7
  },
7
8
  pixelFormats: {
8
9
  RGBA: binding.AV_PIX_FMT_RGBA,
10
+ RGB24: binding.AV_PIX_FMT_RGB24,
9
11
  YUVJ420P: binding.AV_PIX_FMT_YUVJ420P,
12
+ UYVY422: binding.AV_PIX_FMT_UYVY422,
10
13
  YUV420P: binding.AV_PIX_FMT_YUV420P
14
+ },
15
+ mediaType: {
16
+ UNKNOWN: binding.AVMEDIA_TYPE_UNKNOWN,
17
+ VIDEO: binding.AVMEDIA_TYPE_VIDEO,
18
+ AUDIO: binding.AVMEDIA_TYPE_AUDIO,
19
+ DATA: binding.AVMEDIA_TYPE_DATA,
20
+ SUBTITLE: binding.AVMEDIA_TYPE_SUBTITLE,
21
+ ATTACHEMENT: binding.AVMEDIA_TYPE_ATTACHMENT,
22
+ NB: binding.AVMEDIA_TYPE_NB
11
23
  }
12
24
  }
13
25
 
@@ -2,18 +2,22 @@ const binding = require('../binding')
2
2
  const Stream = require('./stream.js')
3
3
  const ReferenceCounted = require('./reference-counted')
4
4
  const OutputFormat = require('./output-format')
5
+ const IOContext = require('./io-context')
6
+ const InputFormat = require('./input-format')
5
7
 
6
8
  class FFmpegFormatContext extends ReferenceCounted {
7
9
  constructor(io) {
8
10
  super()
9
11
 
10
- this._io = io._ref()
12
+ this._io = io ? io._ref() : null
11
13
  this._streams = []
12
14
  }
13
15
 
14
16
  _destroy() {
15
- this._io._unref()
16
- this._io = null
17
+ if (this._io) {
18
+ this._io._unref()
19
+ this._io = null
20
+ }
17
21
 
18
22
  for (const stream of this._streams) stream.destroy()
19
23
  this._streams = []
@@ -36,15 +40,61 @@ class FFmpegFormatContext extends ReferenceCounted {
36
40
  if (result) packet._ref()
37
41
  return result
38
42
  }
43
+
44
+ getBestStream(type) {
45
+ if (typeof type !== 'number') {
46
+ throw new TypeError(
47
+ `Type parameter should be of type number but got: ${typeof type}`
48
+ )
49
+ }
50
+
51
+ if (this._streams.length == 0) {
52
+ return null
53
+ }
54
+
55
+ const bestIndex = binding.getFormatContextBestStreamIndex(
56
+ this._handle,
57
+ type
58
+ )
59
+
60
+ if (bestIndex < 0 || bestIndex >= this._streams.length) {
61
+ return null
62
+ }
63
+
64
+ return this._streams[bestIndex]
65
+ }
66
+ }
67
+
68
+ let defaultURL = null
69
+
70
+ switch (Bare.platform) {
71
+ case 'darwin':
72
+ defaultURL = '0'
73
+ break
74
+ case 'linux':
75
+ // TODO: test on real machine
76
+ defaultURL = '/dev/video0'
77
+ break
78
+ case 'win32':
79
+ defaultURL = 'video=Integrated Camera'
80
+ break
39
81
  }
40
82
 
41
83
  exports.InputFormatContext = class FFmpegInputFormatContext extends (
42
84
  FFmpegFormatContext
43
85
  ) {
44
- constructor(io) {
45
- super(io)
46
-
47
- this._handle = binding.openInputFormatContext(io._handle)
86
+ constructor(io, options, url = defaultURL) {
87
+ if (io instanceof IOContext) {
88
+ super(io)
89
+ this._handle = binding.openInputFormatContextWithIO(io._handle)
90
+ } else if (io instanceof InputFormat) {
91
+ super()
92
+ this._handle = binding.openInputFormatContextWithFormat(
93
+ io._handle,
94
+ options._handle,
95
+ url
96
+ )
97
+ }
48
98
 
49
99
  for (const handle of binding.getFormatContextStreams(this._handle)) {
50
100
  this._streams.push(new Stream(handle))
package/lib/frame.js CHANGED
@@ -45,7 +45,15 @@ module.exports = class FFmpegFrame extends ReferenceCounted {
45
45
  return binding.getFramePixelFormat(this._handle)
46
46
  }
47
47
 
48
+ lineSize(channel) {
49
+ return binding.getFrameLineSize(this._handle, channel)
50
+ }
51
+
48
52
  alloc() {
49
53
  binding.allocFrame(this._handle, 32)
50
54
  }
55
+
56
+ get data() {
57
+ return Buffer.from(binding.getFrameData(this._handle))
58
+ }
51
59
  }
package/lib/packet.js CHANGED
@@ -2,10 +2,24 @@ const binding = require('../binding')
2
2
  const ReferenceCounted = require('./reference-counted')
3
3
 
4
4
  module.exports = class FFmpegPacket extends ReferenceCounted {
5
- constructor() {
5
+ constructor(buffer) {
6
6
  super()
7
7
 
8
- this._handle = binding.initPacket()
8
+ if (buffer) {
9
+ if (!Buffer.isBuffer(buffer)) {
10
+ throw TypeError(
11
+ `Buffer parameter should be of type Buffer but got: ${typeof buffer}`
12
+ )
13
+ }
14
+
15
+ this._handle = binding.initPacketFromBuffer(
16
+ buffer.buffer,
17
+ buffer.byteOffset,
18
+ buffer.byteLength
19
+ )
20
+ } else {
21
+ this._handle = binding.initPacket()
22
+ }
9
23
  }
10
24
 
11
25
  _destroy() {
@@ -17,4 +31,12 @@ module.exports = class FFmpegPacket extends ReferenceCounted {
17
31
  this._unref()
18
32
  binding.unrefPacket(this._handle)
19
33
  }
34
+
35
+ get streamIndex() {
36
+ return binding.getPacketStreamIndex(this._handle)
37
+ }
38
+
39
+ get data() {
40
+ return Buffer.from(binding.getPacketData(this._handle))
41
+ }
20
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ffmpeg",
3
- "version": "1.0.0-1",
3
+ "version": "1.0.0-3",
4
4
  "description": "Low-level FFmpeg bindings for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -31,7 +31,7 @@
31
31
  "devDependencies": {
32
32
  "brittle": "^3.4.0",
33
33
  "cmake-bare": "^1.1.2",
34
- "cmake-ports": "^1.1.7",
34
+ "cmake-ports": "^1.5.0",
35
35
  "prettier": "^3.3.3",
36
36
  "prettier-config-standard": "^7.0.0"
37
37
  }