bare-ffmpeg 1.0.0-13 → 1.0.0-15

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/README.md CHANGED
@@ -573,6 +573,16 @@ Parameters:
573
573
 
574
574
  **Returns**: void
575
575
 
576
+ ##### `Image.read(frame)`
577
+
578
+ Reads image data from a frame into the image buffer.
579
+
580
+ Parameters:
581
+
582
+ - `frame` (`Frame`): The frame to read from
583
+
584
+ **Returns**: `void`
585
+
576
586
  ##### `Image.lineSize([plane])`
577
587
 
578
588
  Gets the line size for a specific plane.
@@ -803,6 +813,98 @@ Destroys the `Scaler` and frees all associated resources. Automatically called w
803
813
 
804
814
  **Returns**: `void`
805
815
 
816
+ ### `AudioFIFO`
817
+
818
+ The `AudioFIFO` API provides a first in first out buffer for audio samples. This is useful for buffering audio data between different processing stages.
819
+
820
+ ```js
821
+ const fifo = new ffmpeg.AudioFIFO(sampleFormat, channels, nbSamples)
822
+ ```
823
+
824
+ Parameters:
825
+
826
+ - `sampleFormat` (`number` | `string`): The audio sample format
827
+ - `channels` (`number`): Number of audio channels
828
+ - `nbSamples` (`number`): Initial buffer size in samples
829
+
830
+ **Returns**: A new `AudioFIFO` instance
831
+
832
+ Example:
833
+
834
+ ```js
835
+ const fifo = new ffmpeg.AudioFIFO(ffmpeg.constants.sampleFormats.S16, 2, 1024)
836
+ ```
837
+
838
+ #### Properties
839
+
840
+ ##### `AudioFIFO.size`
841
+
842
+ Gets the number of samples currently in the FIFO.
843
+
844
+ **Returns**: `number`
845
+
846
+ ##### `AudioFIFO.space`
847
+
848
+ Gets the number of samples that can be written to the FIFO.
849
+
850
+ **Returns**: `number`
851
+
852
+ #### Methods
853
+
854
+ ##### `AudioFIFO.write(frame)`
855
+
856
+ Writes samples from a frame to the FIFO. The FIFO will automatically grow if needed.
857
+
858
+ Parameters:
859
+
860
+ - `frame` (`Frame`): The audio frame containing samples to write
861
+
862
+ **Returns**: `number` of samples written
863
+
864
+ ##### `AudioFIFO.read(frame, nbSamples)`
865
+
866
+ Reads samples from the FIFO into a frame.
867
+
868
+ Parameters:
869
+
870
+ - `frame` (`Frame`): The frame to read samples into
871
+ - `nbSamples` (`number`): Number of samples to read
872
+
873
+ **Returns**: `number` of samples actually read
874
+
875
+ ##### `AudioFIFO.peek(frame, nbSamples)`
876
+
877
+ Reads samples from the FIFO without removing them.
878
+
879
+ Parameters:
880
+
881
+ - `frame` (`Frame`): The frame to read samples into
882
+ - `nbSamples` (`number`): Number of samples to peek
883
+
884
+ **Returns**: `number` of samples peeked
885
+
886
+ ##### `AudioFIFO.drain(nbSamples)`
887
+
888
+ Removes samples from the FIFO without reading them.
889
+
890
+ Parameters:
891
+
892
+ - `nbSamples` (`number`): Number of samples to drain
893
+
894
+ **Returns**: `void`
895
+
896
+ ##### `AudioFIFO.reset()`
897
+
898
+ Resets the FIFO to empty state.
899
+
900
+ **Returns**: `void`
901
+
902
+ ##### `AudioFIFO.destroy()`
903
+
904
+ Destroys the `AudioFIFO` and frees all associated resources. Automatically called when the object is managed by a `using` declaration.
905
+
906
+ **Returns**: `void`
907
+
806
908
  ## License
807
909
 
808
910
  Apache-2.0
package/binding.cc CHANGED
@@ -16,6 +16,7 @@ extern "C" {
16
16
  #include <libavdevice/avdevice.h>
17
17
  #include <libavformat/avformat.h>
18
18
  #include <libavformat/avio.h>
19
+ #include <libavutil/audio_fifo.h>
19
20
  #include <libavutil/channel_layout.h>
20
21
  #include <libavutil/dict.h>
21
22
  #include <libavutil/error.h>
@@ -86,11 +87,16 @@ typedef struct {
86
87
  struct SwrContext *handle;
87
88
  } bare_ffmpeg_resampler_t;
88
89
 
90
+ typedef struct {
91
+ AVAudioFifo *handle;
92
+ } bare_ffmpeg_audio_fifo_t;
93
+
89
94
  static uv_once_t bare_ffmpeg__init_guard = UV_ONCE_INIT;
90
95
 
91
96
  static void
92
97
  bare_ffmpeg__on_init(void) {
93
98
  av_log_set_level(AV_LOG_ERROR);
99
+
94
100
  avdevice_register_all();
95
101
  }
96
102
 
@@ -117,8 +123,7 @@ bare_ffmpeg_io_context_init(
117
123
  else {
118
124
  io = reinterpret_cast<uint8_t *>(av_malloc(size));
119
125
 
120
- size_t off = static_cast<size_t>(offset);
121
- memcpy(io, &data[off], size);
126
+ memcpy(io, &data[static_cast<size_t>(offset)], size);
122
127
  }
123
128
 
124
129
  context->handle = avio_alloc_context(io, static_cast<int>(len), 0, NULL, NULL, NULL, NULL);
@@ -128,8 +133,13 @@ bare_ffmpeg_io_context_init(
128
133
  }
129
134
 
130
135
  static void
131
- bare_ffmpeg_io_context_destroy(js_env_t *env, js_receiver_t, js_arraybuffer_span_of_t<bare_ffmpeg_io_context_t, 1> context) {
136
+ bare_ffmpeg_io_context_destroy(
137
+ js_env_t *env,
138
+ js_receiver_t,
139
+ js_arraybuffer_span_of_t<bare_ffmpeg_io_context_t, 1> context
140
+ ) {
132
141
  av_free(context->handle->buffer);
142
+
133
143
  avio_context_free(&context->handle);
134
144
  }
135
145
 
@@ -147,6 +157,7 @@ bare_ffmpeg_output_format_init(js_env_t *env, js_receiver_t, std::string name) {
147
157
  }
148
158
 
149
159
  js_arraybuffer_t handle;
160
+
150
161
  bare_ffmpeg_output_format_t *context;
151
162
  err = js_create_arraybuffer(env, context, handle);
152
163
  assert(err == 0);
@@ -161,6 +172,7 @@ bare_ffmpeg_input_format_init(js_env_t *env, js_receiver_t, std::string name) {
161
172
  int err;
162
173
 
163
174
  const AVInputFormat *format = av_find_input_format(name.c_str());
175
+
164
176
  if (format == NULL) {
165
177
  err = js_throw_errorf(env, NULL, "No input format found for name '%s'", name.c_str());
166
178
  assert(err == 0);
@@ -169,6 +181,7 @@ bare_ffmpeg_input_format_init(js_env_t *env, js_receiver_t, std::string name) {
169
181
  }
170
182
 
171
183
  js_arraybuffer_t handle;
184
+
172
185
  bare_ffmpeg_input_format_t *context;
173
186
  err = js_create_arraybuffer(env, context, handle);
174
187
  assert(err == 0);
@@ -280,6 +293,7 @@ bare_ffmpeg_format_context_open_output(
280
293
  int err;
281
294
 
282
295
  js_arraybuffer_t handle;
296
+
283
297
  bare_ffmpeg_format_context_t *context;
284
298
  err = js_create_arraybuffer(env, context, handle);
285
299
  assert(err == 0);
@@ -344,11 +358,11 @@ bare_ffmpeg_format_context_get_best_stream_index(
344
358
  js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
345
359
  int32_t type
346
360
  ) {
347
- int best_stream = av_find_best_stream(context->handle, static_cast<AVMediaType>(type), -1, -1, NULL, 0);
361
+ auto i = av_find_best_stream(context->handle, static_cast<AVMediaType>(type), -1, -1, NULL, 0);
348
362
 
349
- if (best_stream < 0) best_stream = -1;
363
+ if (i < 0) i = -1;
350
364
 
351
- return best_stream;
365
+ return i;
352
366
  }
353
367
 
354
368
  static js_arraybuffer_t
@@ -361,19 +375,13 @@ bare_ffmpeg_format_context_create_stream(
361
375
  int err;
362
376
 
363
377
  js_arraybuffer_t handle;
378
+
364
379
  bare_ffmpeg_stream_t *stream;
365
380
  err = js_create_arraybuffer(env, stream, handle);
366
381
  assert(err == 0);
367
382
 
368
383
  stream->handle = avformat_new_stream(context->handle, codec->handle);
369
384
 
370
- if (stream->handle == NULL) {
371
- err = js_throw_error(env, NULL, av_err2str(err));
372
- assert(err == 0);
373
-
374
- throw js_pending_exception;
375
- }
376
-
377
385
  return handle;
378
386
  }
379
387
 
@@ -384,9 +392,11 @@ bare_ffmpeg_format_context_read_frame(
384
392
  js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
385
393
  js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
386
394
  ) {
395
+ int err;
396
+
387
397
  av_packet_unref(packet->handle);
388
398
 
389
- int err = av_read_frame(context->handle, packet->handle);
399
+ err = av_read_frame(context->handle, packet->handle);
390
400
  if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
391
401
  err = js_throw_error(env, NULL, av_err2str(err));
392
402
  assert(err == 0);
@@ -439,6 +449,7 @@ bare_ffmpeg_find_decoder_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
439
449
  }
440
450
 
441
451
  js_arraybuffer_t handle;
452
+
442
453
  bare_ffmpeg_codec_t *context;
443
454
  err = js_create_arraybuffer(env, context, handle);
444
455
  assert(err == 0);
@@ -462,6 +473,7 @@ bare_ffmpeg_find_encoder_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
462
473
  }
463
474
 
464
475
  js_arraybuffer_t handle;
476
+
465
477
  bare_ffmpeg_codec_t *context;
466
478
  err = js_create_arraybuffer(env, context, handle);
467
479
  assert(err == 0);
@@ -566,6 +578,7 @@ bare_ffmpeg_frame_set_channel_layout(
566
578
  js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
567
579
  ) {
568
580
  int err;
581
+
569
582
  err = av_channel_layout_copy(&frame->handle->ch_layout, &layout->handle);
570
583
  assert(err == 0);
571
584
  }
@@ -672,10 +685,12 @@ bare_ffmpeg_codec_context_get_time_base(
672
685
  js_receiver_t,
673
686
  js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
674
687
  ) {
688
+ int err;
689
+
675
690
  js_arraybuffer_t result;
676
- int32_t *data;
677
691
 
678
- int err = js_create_arraybuffer(env, data, result);
692
+ int32_t *data;
693
+ err = js_create_arraybuffer(env, 2, data, result);
679
694
  assert(err == 0);
680
695
 
681
696
  data[0] = context->handle->time_base.num;
@@ -724,6 +739,7 @@ bare_ffmpeg_codec_context_set_channel_layout(
724
739
  js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
725
740
  ) {
726
741
  int err;
742
+
727
743
  err = av_channel_layout_copy(&context->handle->ch_layout, &layout->handle);
728
744
  assert(err == 0);
729
745
  }
@@ -747,6 +763,25 @@ bare_ffmpeg_codec_context_set_sample_rate(
747
763
  context->handle->sample_rate = sample_rate;
748
764
  }
749
765
 
766
+ static int
767
+ bare_ffmpeg_codec_context_get_gop_size(
768
+ js_env_t *env,
769
+ js_receiver_t,
770
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
771
+ ) {
772
+ return context->handle->gop_size;
773
+ }
774
+
775
+ static void
776
+ bare_ffmpeg_codec_context_set_gop_size(
777
+ js_env_t *env,
778
+ js_receiver_t,
779
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
780
+ int32_t gop_size
781
+ ) {
782
+ context->handle->gop_size = gop_size;
783
+ }
784
+
750
785
  static bool
751
786
  bare_ffmpeg_codec_context_send_packet(
752
787
  js_env_t *env,
@@ -797,11 +832,7 @@ bare_ffmpeg_codec_context_send_frame(
797
832
  int err;
798
833
 
799
834
  err = avcodec_send_frame(context->handle, frame->handle);
800
- if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
801
- return false;
802
- }
803
-
804
- if (err < 0) {
835
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
805
836
  err = js_throw_error(env, NULL, av_err2str(err));
806
837
  assert(err == 0);
807
838
 
@@ -952,10 +983,12 @@ bare_ffmpeg_codec_parameters_get_channel_layout(
952
983
 
953
984
  static js_arraybuffer_t
954
985
  bare_ffmpeg_frame_init(js_env_t *env, js_receiver_t) {
986
+ int err;
987
+
955
988
  js_arraybuffer_t handle;
956
989
 
957
990
  bare_ffmpeg_frame_t *frame;
958
- int err = js_create_arraybuffer(env, frame, handle);
991
+ err = js_create_arraybuffer(env, frame, handle);
959
992
  assert(err == 0);
960
993
 
961
994
  frame->handle = av_frame_alloc();
@@ -1049,6 +1082,15 @@ bare_ffmpeg_frame_set_nb_samples(
1049
1082
  frame->handle->nb_samples = nb_samples;
1050
1083
  }
1051
1084
 
1085
+ static int32_t
1086
+ bare_ffmpeg_frame_get_pict_type(
1087
+ js_env_t *env,
1088
+ js_receiver_t,
1089
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1090
+ ) {
1091
+ return frame->handle->pict_type;
1092
+ }
1093
+
1052
1094
  static void
1053
1095
  bare_ffmpeg_frame_alloc(
1054
1096
  js_env_t *env,
@@ -1113,7 +1155,7 @@ bare_ffmpeg_image_fill(
1113
1155
  ) {
1114
1156
  int err;
1115
1157
 
1116
- err = av_image_fill_arrays(
1158
+ auto len = av_image_fill_arrays(
1117
1159
  frame->handle->data,
1118
1160
  frame->handle->linesize,
1119
1161
  &data[static_cast<size_t>(offset)],
@@ -1123,14 +1165,51 @@ bare_ffmpeg_image_fill(
1123
1165
  align
1124
1166
  );
1125
1167
 
1126
- if (err < 0) {
1127
- err = js_throw_error(env, NULL, av_err2str(err));
1168
+ if (len < 0) {
1169
+ err = js_throw_error(env, NULL, av_err2str(len));
1128
1170
  assert(err == 0);
1129
1171
 
1130
1172
  throw js_pending_exception;
1131
1173
  }
1132
1174
  }
1133
1175
 
1176
+ static void
1177
+ bare_ffmpeg_image_read(
1178
+ js_env_t *env,
1179
+ js_receiver_t,
1180
+ int32_t pixel_format,
1181
+ int32_t width,
1182
+ int32_t height,
1183
+ int32_t align,
1184
+ js_arraybuffer_span_t data,
1185
+ uint64_t offset,
1186
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1187
+ ) {
1188
+ uint8_t *dst_data[4];
1189
+ int dst_linesize[4];
1190
+
1191
+ int err = av_image_fill_arrays(
1192
+ dst_data,
1193
+ dst_linesize,
1194
+ &data[offset],
1195
+ static_cast<AVPixelFormat>(pixel_format),
1196
+ width,
1197
+ height,
1198
+ align
1199
+ );
1200
+ assert(err >= 0);
1201
+
1202
+ av_image_copy(
1203
+ dst_data,
1204
+ dst_linesize,
1205
+ frame->handle->data,
1206
+ frame->handle->linesize,
1207
+ static_cast<AVPixelFormat>(pixel_format),
1208
+ width,
1209
+ height
1210
+ );
1211
+ }
1212
+
1134
1213
  static int
1135
1214
  bare_ffmpeg_image_get_line_size(
1136
1215
  js_env_t *env,
@@ -1218,6 +1297,7 @@ bare_ffmpeg_packet_init(js_env_t *env, js_receiver_t) {
1218
1297
  int err;
1219
1298
 
1220
1299
  js_arraybuffer_t handle;
1300
+
1221
1301
  bare_ffmpeg_packet_t *packet;
1222
1302
  err = js_create_arraybuffer(env, packet, handle);
1223
1303
  assert(err == 0);
@@ -1238,7 +1318,6 @@ bare_ffmpeg_packet_init_from_buffer(
1238
1318
  int err;
1239
1319
 
1240
1320
  AVPacket *pkt = av_packet_alloc();
1241
- assert(pkt != NULL);
1242
1321
 
1243
1322
  err = av_new_packet(pkt, static_cast<int>(len));
1244
1323
  assert(err == 0);
@@ -1246,6 +1325,7 @@ bare_ffmpeg_packet_init_from_buffer(
1246
1325
  memcpy(pkt->data, &data[static_cast<size_t>(offset)], static_cast<size_t>(len));
1247
1326
 
1248
1327
  js_arraybuffer_t handle;
1328
+
1249
1329
  bare_ffmpeg_packet_t *packet;
1250
1330
  err = js_create_arraybuffer(env, packet, handle);
1251
1331
  assert(err == 0);
@@ -1280,9 +1360,11 @@ bare_ffmpeg_packet_get_data(
1280
1360
  js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
1281
1361
  ) {
1282
1362
  int err;
1283
- size_t size = static_cast<size_t>(packet->handle->size);
1363
+
1364
+ auto size = static_cast<size_t>(packet->handle->size);
1284
1365
 
1285
1366
  js_arraybuffer_t handle;
1367
+
1286
1368
  uint8_t *data;
1287
1369
  err = js_create_arraybuffer(env, size, data, handle);
1288
1370
  assert(err == 0);
@@ -1292,6 +1374,15 @@ bare_ffmpeg_packet_get_data(
1292
1374
  return handle;
1293
1375
  }
1294
1376
 
1377
+ static bool
1378
+ bare_ffmpeg_packet_is_keyframe(
1379
+ js_env_t *,
1380
+ js_receiver_t,
1381
+ js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
1382
+ ) {
1383
+ return packet->handle->flags & AV_PKT_FLAG_KEY;
1384
+ }
1385
+
1295
1386
  static js_arraybuffer_t
1296
1387
  bare_ffmpeg_scaler_init(
1297
1388
  js_env_t *env,
@@ -1303,18 +1394,21 @@ bare_ffmpeg_scaler_init(
1303
1394
  int32_t target_width,
1304
1395
  int32_t target_height
1305
1396
  ) {
1397
+ int err;
1398
+
1306
1399
  js_arraybuffer_t handle;
1400
+
1307
1401
  bare_ffmpeg_scaler_t *scaler;
1308
- int err = js_create_arraybuffer(env, scaler, handle);
1402
+ err = js_create_arraybuffer(env, scaler, handle);
1309
1403
  assert(err == 0);
1310
1404
 
1311
1405
  scaler->handle = sws_getContext(
1312
1406
  source_width,
1313
1407
  source_height,
1314
- (enum AVPixelFormat) source_format,
1408
+ static_cast<AVPixelFormat>(source_format),
1315
1409
  target_width,
1316
1410
  target_height,
1317
- (enum AVPixelFormat) target_format,
1411
+ static_cast<AVPixelFormat>(target_format),
1318
1412
  SWS_BICUBIC,
1319
1413
  NULL,
1320
1414
  NULL,
@@ -1345,7 +1439,7 @@ bare_ffmpeg_scaler_scale(
1345
1439
  ) {
1346
1440
  return sws_scale(
1347
1441
  scaler->handle,
1348
- (const uint8_t *const *) source->handle->data,
1442
+ reinterpret_cast<const uint8_t *const *>(source->handle->data),
1349
1443
  source->handle->linesize,
1350
1444
  y,
1351
1445
  height,
@@ -1359,9 +1453,12 @@ bare_ffmpeg_dictionary_init(
1359
1453
  js_env_t *env,
1360
1454
  js_receiver_t
1361
1455
  ) {
1456
+ int err;
1457
+
1362
1458
  js_arraybuffer_t handle;
1459
+
1363
1460
  bare_ffmpeg_dictionary_t *dict;
1364
- int err = js_create_arraybuffer(env, dict, handle);
1461
+ err = js_create_arraybuffer(env, dict, handle);
1365
1462
  assert(err == 0);
1366
1463
 
1367
1464
  dict->handle = NULL;
@@ -1386,7 +1483,9 @@ bare_ffmpeg_dictionary_set_entry(
1386
1483
  std::string key,
1387
1484
  std::string value
1388
1485
  ) {
1389
- int err = av_dict_set(&dict->handle, key.c_str(), value.c_str(), 0);
1486
+ int err;
1487
+
1488
+ err = av_dict_set(&dict->handle, key.c_str(), value.c_str(), 0);
1390
1489
  assert(err == 0);
1391
1490
  }
1392
1491
 
@@ -1449,7 +1548,6 @@ bare_ffmpeg_resampler_init(
1449
1548
  }
1450
1549
 
1451
1550
  err = swr_init(resampler->handle);
1452
-
1453
1551
  if (err < 0) {
1454
1552
  swr_free(&resampler->handle);
1455
1553
 
@@ -1472,7 +1570,7 @@ bare_ffmpeg_resampler_convert_frames(
1472
1570
  ) {
1473
1571
  int err;
1474
1572
 
1475
- int result = swr_convert(
1573
+ auto result = swr_convert(
1476
1574
  resampler->handle,
1477
1575
  (uint8_t **) out_frame->handle->data,
1478
1576
  out_frame->handle->nb_samples,
@@ -1483,6 +1581,7 @@ bare_ffmpeg_resampler_convert_frames(
1483
1581
  if (result < 0) {
1484
1582
  err = js_throw_error(env, NULL, av_err2str(result));
1485
1583
  assert(err == 0);
1584
+
1486
1585
  throw js_pending_exception;
1487
1586
  }
1488
1587
 
@@ -1510,7 +1609,7 @@ bare_ffmpeg_resampler_flush(
1510
1609
  ) {
1511
1610
  int err;
1512
1611
 
1513
- int result = swr_convert(
1612
+ auto result = swr_convert(
1514
1613
  resampler->handle,
1515
1614
  out_frame->handle->data,
1516
1615
  out_frame->handle->nb_samples,
@@ -1521,6 +1620,7 @@ bare_ffmpeg_resampler_flush(
1521
1620
  if (result < 0) {
1522
1621
  err = js_throw_error(env, NULL, av_err2str(result));
1523
1622
  assert(err == 0);
1623
+
1524
1624
  throw js_pending_exception;
1525
1625
  }
1526
1626
 
@@ -1587,6 +1687,149 @@ bare_ffmpeg_channel_layout_from_mask(
1587
1687
  return result;
1588
1688
  }
1589
1689
 
1690
+ static js_arraybuffer_t
1691
+ bare_ffmpeg_audio_fifo_init(
1692
+ js_env_t *env,
1693
+ js_receiver_t,
1694
+ int32_t sample_fmt,
1695
+ int32_t channels,
1696
+ int32_t nb_samples
1697
+ ) {
1698
+ int err;
1699
+
1700
+ js_arraybuffer_t handle;
1701
+
1702
+ bare_ffmpeg_audio_fifo_t *fifo;
1703
+ err = js_create_arraybuffer(env, fifo, handle);
1704
+ assert(err == 0);
1705
+
1706
+ fifo->handle = av_audio_fifo_alloc(
1707
+ static_cast<AVSampleFormat>(sample_fmt),
1708
+ channels,
1709
+ nb_samples
1710
+ );
1711
+
1712
+ return handle;
1713
+ }
1714
+
1715
+ static void
1716
+ bare_ffmpeg_audio_fifo_destroy(
1717
+ js_env_t *env,
1718
+ js_receiver_t,
1719
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1720
+ ) {
1721
+ av_audio_fifo_free(fifo->handle);
1722
+ }
1723
+
1724
+ static int
1725
+ bare_ffmpeg_audio_fifo_write(
1726
+ js_env_t *env,
1727
+ js_receiver_t,
1728
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1729
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1730
+ ) {
1731
+ int err;
1732
+
1733
+ int len = av_audio_fifo_write(fifo->handle, (void **) frame->handle->data, frame->handle->nb_samples);
1734
+
1735
+ if (len < 0) {
1736
+ err = js_throw_error(env, NULL, av_err2str(len));
1737
+ assert(err == 0);
1738
+ throw js_pending_exception;
1739
+ }
1740
+
1741
+ return len;
1742
+ }
1743
+
1744
+ static int
1745
+ bare_ffmpeg_audio_fifo_read(
1746
+ js_env_t *env,
1747
+ js_receiver_t,
1748
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1749
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1750
+ int32_t nb_samples
1751
+ ) {
1752
+ int err;
1753
+
1754
+ int len = av_audio_fifo_read(fifo->handle, (void **) frame->handle->data, nb_samples);
1755
+
1756
+ if (len < 0) {
1757
+ err = js_throw_error(env, NULL, av_err2str(len));
1758
+ assert(err == 0);
1759
+ throw js_pending_exception;
1760
+ }
1761
+
1762
+ return len;
1763
+ }
1764
+
1765
+ static int
1766
+ bare_ffmpeg_audio_fifo_peek(
1767
+ js_env_t *env,
1768
+ js_receiver_t,
1769
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1770
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1771
+ int32_t nb_samples
1772
+ ) {
1773
+ int err;
1774
+
1775
+ int len = av_audio_fifo_peek(fifo->handle, (void **) frame->handle->data, nb_samples);
1776
+
1777
+ if (len < 0) {
1778
+ err = js_throw_error(env, NULL, av_err2str(len));
1779
+ assert(err == 0);
1780
+ throw js_pending_exception;
1781
+ }
1782
+
1783
+ return len;
1784
+ }
1785
+
1786
+ static int
1787
+ bare_ffmpeg_audio_fifo_drain(
1788
+ js_env_t *env,
1789
+ js_receiver_t,
1790
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1791
+ int32_t nb_samples
1792
+ ) {
1793
+ int err;
1794
+
1795
+ int len = av_audio_fifo_drain(fifo->handle, nb_samples);
1796
+
1797
+ if (len < 0) {
1798
+ err = js_throw_error(env, NULL, av_err2str(len));
1799
+ assert(err == 0);
1800
+ throw js_pending_exception;
1801
+ }
1802
+
1803
+ return len;
1804
+ }
1805
+
1806
+ static void
1807
+ bare_ffmpeg_audio_fifo_reset(
1808
+ js_env_t *env,
1809
+ js_receiver_t,
1810
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1811
+ ) {
1812
+ av_audio_fifo_reset(fifo->handle);
1813
+ }
1814
+
1815
+ static int
1816
+ bare_ffmpeg_audio_fifo_size(
1817
+ js_env_t *env,
1818
+ js_receiver_t,
1819
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1820
+ ) {
1821
+ return av_audio_fifo_size(fifo->handle);
1822
+ }
1823
+
1824
+ static int
1825
+ bare_ffmpeg_audio_fifo_space(
1826
+ js_env_t *env,
1827
+ js_receiver_t,
1828
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1829
+ ) {
1830
+ return av_audio_fifo_space(fifo->handle);
1831
+ }
1832
+
1590
1833
  static js_value_t *
1591
1834
  bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1592
1835
  uv_once(&bare_ffmpeg__init_guard, bare_ffmpeg__on_init);
@@ -1637,6 +1880,9 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1637
1880
  V("setCodecContextChannelLayout", bare_ffmpeg_codec_context_set_channel_layout);
1638
1881
  V("getCodecContextSampleRate", bare_ffmpeg_codec_context_get_sample_rate);
1639
1882
  V("setCodecContextSampleRate", bare_ffmpeg_codec_context_set_sample_rate);
1883
+ V("getCodecContextGOPSize", bare_ffmpeg_codec_context_get_gop_size)
1884
+ V("setCodecContextGOPSize", bare_ffmpeg_codec_context_set_gop_size)
1885
+
1640
1886
  V("sendCodecContextPacket", bare_ffmpeg_codec_context_send_packet)
1641
1887
  V("receiveCodecContextPacket", bare_ffmpeg_codec_context_receive_packet)
1642
1888
  V("sendCodecContextFrame", bare_ffmpeg_codec_context_send_frame)
@@ -1667,10 +1913,12 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1667
1913
  V("setFrameChannelLayout", bare_ffmpeg_frame_set_channel_layout)
1668
1914
  V("getFrameNbSamples", bare_ffmpeg_frame_get_nb_samples)
1669
1915
  V("setFrameNbSamples", bare_ffmpeg_frame_set_nb_samples)
1916
+ V("getFramePictType", bare_ffmpeg_frame_get_pict_type)
1670
1917
  V("allocFrame", bare_ffmpeg_frame_alloc)
1671
1918
 
1672
1919
  V("initImage", bare_ffmpeg_image_init)
1673
1920
  V("fillImage", bare_ffmpeg_image_fill)
1921
+ V("readImage", bare_ffmpeg_image_read)
1674
1922
  V("getImageLineSize", bare_ffmpeg_image_get_line_size)
1675
1923
 
1676
1924
  V("initSamples", bare_ffmpeg_samples_init)
@@ -1681,6 +1929,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1681
1929
  V("unrefPacket", bare_ffmpeg_packet_unref)
1682
1930
  V("getPacketStreamIndex", bare_ffmpeg_packet_get_stream_index)
1683
1931
  V("getPacketData", bare_ffmpeg_packet_get_data)
1932
+ V("isPacketKeyframe", bare_ffmpeg_packet_is_keyframe)
1684
1933
 
1685
1934
  V("initScaler", bare_ffmpeg_scaler_init)
1686
1935
  V("destroyScaler", bare_ffmpeg_scaler_destroy)
@@ -1700,6 +1949,16 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1700
1949
  V("copyChannelLayout", bare_ffmpeg_channel_layout_copy)
1701
1950
  V("getChannelLayoutNbChannels", bare_ffmpeg_channel_layout_get_nb_channels)
1702
1951
  V("channelLayoutFromMask", bare_ffmpeg_channel_layout_from_mask)
1952
+
1953
+ V("initAudioFifo", bare_ffmpeg_audio_fifo_init)
1954
+ V("destroyAudioFifo", bare_ffmpeg_audio_fifo_destroy)
1955
+ V("writeAudioFifo", bare_ffmpeg_audio_fifo_write)
1956
+ V("readAudioFifo", bare_ffmpeg_audio_fifo_read)
1957
+ V("peekAudioFifo", bare_ffmpeg_audio_fifo_peek)
1958
+ V("drainAudioFifo", bare_ffmpeg_audio_fifo_drain)
1959
+ V("resetAudioFifo", bare_ffmpeg_audio_fifo_reset)
1960
+ V("getAudioFifoSize", bare_ffmpeg_audio_fifo_size)
1961
+ V("getAudioFifoSpace", bare_ffmpeg_audio_fifo_space)
1703
1962
  #undef V
1704
1963
 
1705
1964
  #define V(name) \
@@ -1721,6 +1980,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1721
1980
  V(AV_PIX_FMT_RGB24)
1722
1981
  V(AV_PIX_FMT_YUVJ420P)
1723
1982
  V(AV_PIX_FMT_YUV420P)
1983
+ V(AV_PIX_FMT_UYVY422)
1724
1984
 
1725
1985
  V(AVMEDIA_TYPE_UNKNOWN)
1726
1986
  V(AVMEDIA_TYPE_VIDEO)
@@ -1753,6 +2013,15 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1753
2013
  V(AV_CH_LAYOUT_5POINT0)
1754
2014
  V(AV_CH_LAYOUT_5POINT1)
1755
2015
  V(AV_CH_LAYOUT_7POINT1)
2016
+
2017
+ V(AV_PICTURE_TYPE_NONE)
2018
+ V(AV_PICTURE_TYPE_I)
2019
+ V(AV_PICTURE_TYPE_P)
2020
+ V(AV_PICTURE_TYPE_B)
2021
+ V(AV_PICTURE_TYPE_S)
2022
+ V(AV_PICTURE_TYPE_SI)
2023
+ V(AV_PICTURE_TYPE_SP)
2024
+ V(AV_PICTURE_TYPE_BI)
1756
2025
  #undef V
1757
2026
 
1758
2027
  return exports;
@@ -11,6 +11,10 @@ set(args
11
11
  -DBUILD_TESTING=OFF
12
12
  )
13
13
 
14
+ if(WIN32)
15
+ list(APPEND args -DOPUS_DISABLE_INTRINSICS=ON)
16
+ endif()
17
+
14
18
  declare_port(
15
19
  "github:xiph/opus@v1.5.2"
16
20
  opus
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ const AudioFIFO = require('./lib/audio-fifo')
1
2
  const ChannelLayout = require('./lib/channel-layout')
2
3
  const Codec = require('./lib/codec')
3
4
  const CodecContext = require('./lib/codec-context')
@@ -21,6 +22,7 @@ const Stream = require('./lib/stream')
21
22
  const Rational = require('./lib/rational')
22
23
  const Resampler = require('./lib/resampler')
23
24
 
25
+ exports.AudioFIFO = AudioFIFO
24
26
  exports.ChannelLayout = ChannelLayout
25
27
  exports.Codec = Codec
26
28
  exports.CodecContext = CodecContext
@@ -0,0 +1,47 @@
1
+ const binding = require('../binding')
2
+ const constants = require('./constants')
3
+
4
+ module.exports = class FFmpegAudioFIFO {
5
+ constructor(sampleFormat, channels, nbSamples) {
6
+ sampleFormat = constants.toSampleFormat(sampleFormat)
7
+
8
+ this._handle = binding.initAudioFifo(sampleFormat, channels, nbSamples)
9
+ }
10
+
11
+ destroy() {
12
+ binding.destroyAudioFifo(this._handle)
13
+ this._handle = null
14
+ }
15
+
16
+ write(frame) {
17
+ return binding.writeAudioFifo(this._handle, frame._handle)
18
+ }
19
+
20
+ read(frame, nbSamples) {
21
+ return binding.readAudioFifo(this._handle, frame._handle, nbSamples)
22
+ }
23
+
24
+ peek(frame, nbSamples) {
25
+ return binding.peekAudioFifo(this._handle, frame._handle, nbSamples)
26
+ }
27
+
28
+ drain(nbSamples) {
29
+ return binding.drainAudioFifo(this._handle, nbSamples)
30
+ }
31
+
32
+ reset() {
33
+ binding.resetAudioFifo(this._handle)
34
+ }
35
+
36
+ get size() {
37
+ return binding.getAudioFifoSize(this._handle)
38
+ }
39
+
40
+ get space() {
41
+ return binding.getAudioFifoSpace(this._handle)
42
+ }
43
+
44
+ [Symbol.dispose]() {
45
+ this.destroy()
46
+ }
47
+ }
@@ -78,6 +78,14 @@ module.exports = class FFmpegCodecContext {
78
78
  )
79
79
  }
80
80
 
81
+ get gopSize() {
82
+ return binding.getCodecContextGOPSize(this._handle)
83
+ }
84
+
85
+ set gopSize(value) {
86
+ binding.setCodecContextGOPSize(this._handle, value)
87
+ }
88
+
81
89
  open(options) {
82
90
  if (this._opened) return
83
91
  this._opened = true
package/lib/constants.js CHANGED
@@ -56,6 +56,16 @@ module.exports = exports = {
56
56
  '5.0': binding.AV_CH_LAYOUT_5POINT0,
57
57
  5.1: binding.AV_CH_LAYOUT_5POINT1,
58
58
  7.1: binding.AV_CH_LAYOUT_7POINT1
59
+ },
60
+ pictureType: {
61
+ NONE: binding.AV_PICTURE_TYPE_NONE,
62
+ I: binding.AV_PICTURE_TYPE_I,
63
+ P: binding.AV_PICTURE_TYPE_P,
64
+ B: binding.AV_PICTURE_TYPE_B,
65
+ S: binding.AV_PICTURE_TYPE_S,
66
+ SI: binding.AV_PICTURE_TYPE_SI,
67
+ SP: binding.AV_PICTURE_TYPE_SP,
68
+ BI: binding.AV_PICTURE_TYPE_BI
59
69
  }
60
70
  }
61
71
 
package/lib/frame.js CHANGED
@@ -62,6 +62,10 @@ module.exports = class FFmpegFrame {
62
62
  binding.setFrameNbSamples(this._handle, value)
63
63
  }
64
64
 
65
+ get pictType() {
66
+ return binding.getFramePictType(this._handle)
67
+ }
68
+
65
69
  alloc() {
66
70
  binding.allocFrame(this._handle, 32)
67
71
  }
package/lib/image.js CHANGED
@@ -47,6 +47,18 @@ module.exports = class FFmpegImage {
47
47
  )
48
48
  }
49
49
 
50
+ read(frame) {
51
+ binding.readImage(
52
+ this._pixelFormat,
53
+ this._width,
54
+ this._height,
55
+ this._align,
56
+ this._data.buffer,
57
+ this._data.byteOffset,
58
+ frame._handle
59
+ )
60
+ }
61
+
50
62
  lineSize(plane = 0) {
51
63
  return binding.getImageLineSize(this._pixelFormat, this._width, plane)
52
64
  }
@@ -3,6 +3,9 @@ const binding = require('../binding')
3
3
  let defaultName = null
4
4
 
5
5
  switch (Bare.platform) {
6
+ case 'android':
7
+ defaultName = 'android_camera'
8
+ break
6
9
  case 'darwin':
7
10
  case 'ios':
8
11
  defaultName = 'avfoundation'
package/lib/packet.js CHANGED
@@ -30,6 +30,10 @@ module.exports = class FFmpegPacket {
30
30
  return Buffer.from(binding.getPacketData(this._handle))
31
31
  }
32
32
 
33
+ get isKeyframe() {
34
+ return binding.isPacketKeyframe(this._handle)
35
+ }
36
+
33
37
  [Symbol.dispose]() {
34
38
  this.destroy()
35
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ffmpeg",
3
- "version": "1.0.0-13",
3
+ "version": "1.0.0-15",
4
4
  "description": "Low-level FFmpeg bindings for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",