bare-ffmpeg 1.0.0-12 → 1.0.0-14

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
@@ -361,12 +361,6 @@ Parameters:
361
361
 
362
362
  **Returns**: `void`
363
363
 
364
- ##### `CodecParameters.destroy()`
365
-
366
- Destroys the `CodecParameters` and frees all associated resources. Automatically called when the object is managed by a `using` declaration.
367
-
368
- **Returns**: `void`
369
-
370
364
  ### `InputFormat`
371
365
 
372
366
  The `InputFormat` API provides functionality to specify input format for media sources.
@@ -676,12 +670,6 @@ Creates and opens an encoder for this stream.
676
670
 
677
671
  **Returns**: `CodecContext` instance
678
672
 
679
- ##### `Stream.destroy()`
680
-
681
- Destroys the `Stream` and frees all associated resources. Automatically called when the object is managed by a `using` declaration.
682
-
683
- **Returns**: `void`
684
-
685
673
  ### `Resampler`
686
674
 
687
675
  The `Resampler` API provides functionality to convert audio between different sample rates, channel layouts, and sample formats.
@@ -815,6 +803,98 @@ Destroys the `Scaler` and frees all associated resources. Automatically called w
815
803
 
816
804
  **Returns**: `void`
817
805
 
806
+ ### `AudioFIFO`
807
+
808
+ The `AudioFIFO` API provides a first in first out buffer for audio samples. This is useful for buffering audio data between different processing stages.
809
+
810
+ ```js
811
+ const fifo = new ffmpeg.AudioFIFO(sampleFormat, channels, nbSamples)
812
+ ```
813
+
814
+ Parameters:
815
+
816
+ - `sampleFormat` (`number` | `string`): The audio sample format
817
+ - `channels` (`number`): Number of audio channels
818
+ - `nbSamples` (`number`): Initial buffer size in samples
819
+
820
+ **Returns**: A new `AudioFIFO` instance
821
+
822
+ Example:
823
+
824
+ ```js
825
+ const fifo = new ffmpeg.AudioFIFO(ffmpeg.constants.sampleFormats.S16, 2, 1024)
826
+ ```
827
+
828
+ #### Properties
829
+
830
+ ##### `AudioFIFO.size`
831
+
832
+ Gets the number of samples currently in the FIFO.
833
+
834
+ **Returns**: `number`
835
+
836
+ ##### `AudioFIFO.space`
837
+
838
+ Gets the number of samples that can be written to the FIFO.
839
+
840
+ **Returns**: `number`
841
+
842
+ #### Methods
843
+
844
+ ##### `AudioFIFO.write(frame)`
845
+
846
+ Writes samples from a frame to the FIFO. The FIFO will automatically grow if needed.
847
+
848
+ Parameters:
849
+
850
+ - `frame` (`Frame`): The audio frame containing samples to write
851
+
852
+ **Returns**: `number` of samples written
853
+
854
+ ##### `AudioFIFO.read(frame, nbSamples)`
855
+
856
+ Reads samples from the FIFO into a frame.
857
+
858
+ Parameters:
859
+
860
+ - `frame` (`Frame`): The frame to read samples into
861
+ - `nbSamples` (`number`): Number of samples to read
862
+
863
+ **Returns**: `number` of samples actually read
864
+
865
+ ##### `AudioFIFO.peek(frame, nbSamples)`
866
+
867
+ Reads samples from the FIFO without removing them.
868
+
869
+ Parameters:
870
+
871
+ - `frame` (`Frame`): The frame to read samples into
872
+ - `nbSamples` (`number`): Number of samples to peek
873
+
874
+ **Returns**: `number` of samples peeked
875
+
876
+ ##### `AudioFIFO.drain(nbSamples)`
877
+
878
+ Removes samples from the FIFO without reading them.
879
+
880
+ Parameters:
881
+
882
+ - `nbSamples` (`number`): Number of samples to drain
883
+
884
+ **Returns**: `void`
885
+
886
+ ##### `AudioFIFO.reset()`
887
+
888
+ Resets the FIFO to empty state.
889
+
890
+ **Returns**: `void`
891
+
892
+ ##### `AudioFIFO.destroy()`
893
+
894
+ Destroys the `AudioFIFO` and frees all associated resources. Automatically called when the object is managed by a `using` declaration.
895
+
896
+ **Returns**: `void`
897
+
818
898
  ## License
819
899
 
820
900
  Apache-2.0
package/binding.cc CHANGED
@@ -26,6 +26,7 @@ extern "C" {
26
26
  #include <libavutil/pixfmt.h>
27
27
  #include <libavutil/rational.h>
28
28
  #include <libavutil/samplefmt.h>
29
+ #include <libavutil/audio_fifo.h>
29
30
  #include <libswresample/swresample.h>
30
31
  #include <libswscale/swscale.h>
31
32
  }
@@ -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
  }
@@ -797,11 +813,7 @@ bare_ffmpeg_codec_context_send_frame(
797
813
  int err;
798
814
 
799
815
  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) {
816
+ if (err < 0 && err != AVERROR(EAGAIN) && err != AVERROR_EOF) {
805
817
  err = js_throw_error(env, NULL, av_err2str(err));
806
818
  assert(err == 0);
807
819
 
@@ -952,10 +964,12 @@ bare_ffmpeg_codec_parameters_get_channel_layout(
952
964
 
953
965
  static js_arraybuffer_t
954
966
  bare_ffmpeg_frame_init(js_env_t *env, js_receiver_t) {
967
+ int err;
968
+
955
969
  js_arraybuffer_t handle;
956
970
 
957
971
  bare_ffmpeg_frame_t *frame;
958
- int err = js_create_arraybuffer(env, frame, handle);
972
+ err = js_create_arraybuffer(env, frame, handle);
959
973
  assert(err == 0);
960
974
 
961
975
  frame->handle = av_frame_alloc();
@@ -1113,7 +1127,7 @@ bare_ffmpeg_image_fill(
1113
1127
  ) {
1114
1128
  int err;
1115
1129
 
1116
- err = av_image_fill_arrays(
1130
+ auto len = av_image_fill_arrays(
1117
1131
  frame->handle->data,
1118
1132
  frame->handle->linesize,
1119
1133
  &data[static_cast<size_t>(offset)],
@@ -1123,8 +1137,8 @@ bare_ffmpeg_image_fill(
1123
1137
  align
1124
1138
  );
1125
1139
 
1126
- if (err < 0) {
1127
- err = js_throw_error(env, NULL, av_err2str(err));
1140
+ if (len < 0) {
1141
+ err = js_throw_error(env, NULL, av_err2str(len));
1128
1142
  assert(err == 0);
1129
1143
 
1130
1144
  throw js_pending_exception;
@@ -1218,6 +1232,7 @@ bare_ffmpeg_packet_init(js_env_t *env, js_receiver_t) {
1218
1232
  int err;
1219
1233
 
1220
1234
  js_arraybuffer_t handle;
1235
+
1221
1236
  bare_ffmpeg_packet_t *packet;
1222
1237
  err = js_create_arraybuffer(env, packet, handle);
1223
1238
  assert(err == 0);
@@ -1238,7 +1253,6 @@ bare_ffmpeg_packet_init_from_buffer(
1238
1253
  int err;
1239
1254
 
1240
1255
  AVPacket *pkt = av_packet_alloc();
1241
- assert(pkt != NULL);
1242
1256
 
1243
1257
  err = av_new_packet(pkt, static_cast<int>(len));
1244
1258
  assert(err == 0);
@@ -1246,6 +1260,7 @@ bare_ffmpeg_packet_init_from_buffer(
1246
1260
  memcpy(pkt->data, &data[static_cast<size_t>(offset)], static_cast<size_t>(len));
1247
1261
 
1248
1262
  js_arraybuffer_t handle;
1263
+
1249
1264
  bare_ffmpeg_packet_t *packet;
1250
1265
  err = js_create_arraybuffer(env, packet, handle);
1251
1266
  assert(err == 0);
@@ -1280,9 +1295,11 @@ bare_ffmpeg_packet_get_data(
1280
1295
  js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
1281
1296
  ) {
1282
1297
  int err;
1283
- size_t size = static_cast<size_t>(packet->handle->size);
1298
+
1299
+ auto size = static_cast<size_t>(packet->handle->size);
1284
1300
 
1285
1301
  js_arraybuffer_t handle;
1302
+
1286
1303
  uint8_t *data;
1287
1304
  err = js_create_arraybuffer(env, size, data, handle);
1288
1305
  assert(err == 0);
@@ -1303,18 +1320,21 @@ bare_ffmpeg_scaler_init(
1303
1320
  int32_t target_width,
1304
1321
  int32_t target_height
1305
1322
  ) {
1323
+ int err;
1324
+
1306
1325
  js_arraybuffer_t handle;
1326
+
1307
1327
  bare_ffmpeg_scaler_t *scaler;
1308
- int err = js_create_arraybuffer(env, scaler, handle);
1328
+ err = js_create_arraybuffer(env, scaler, handle);
1309
1329
  assert(err == 0);
1310
1330
 
1311
1331
  scaler->handle = sws_getContext(
1312
1332
  source_width,
1313
1333
  source_height,
1314
- (enum AVPixelFormat) source_format,
1334
+ static_cast<AVPixelFormat>(source_format),
1315
1335
  target_width,
1316
1336
  target_height,
1317
- (enum AVPixelFormat) target_format,
1337
+ static_cast<AVPixelFormat>(target_format),
1318
1338
  SWS_BICUBIC,
1319
1339
  NULL,
1320
1340
  NULL,
@@ -1345,7 +1365,7 @@ bare_ffmpeg_scaler_scale(
1345
1365
  ) {
1346
1366
  return sws_scale(
1347
1367
  scaler->handle,
1348
- (const uint8_t *const *) source->handle->data,
1368
+ reinterpret_cast<const uint8_t *const *>(source->handle->data),
1349
1369
  source->handle->linesize,
1350
1370
  y,
1351
1371
  height,
@@ -1359,9 +1379,12 @@ bare_ffmpeg_dictionary_init(
1359
1379
  js_env_t *env,
1360
1380
  js_receiver_t
1361
1381
  ) {
1382
+ int err;
1383
+
1362
1384
  js_arraybuffer_t handle;
1385
+
1363
1386
  bare_ffmpeg_dictionary_t *dict;
1364
- int err = js_create_arraybuffer(env, dict, handle);
1387
+ err = js_create_arraybuffer(env, dict, handle);
1365
1388
  assert(err == 0);
1366
1389
 
1367
1390
  dict->handle = NULL;
@@ -1386,7 +1409,9 @@ bare_ffmpeg_dictionary_set_entry(
1386
1409
  std::string key,
1387
1410
  std::string value
1388
1411
  ) {
1389
- int err = av_dict_set(&dict->handle, key.c_str(), value.c_str(), 0);
1412
+ int err;
1413
+
1414
+ err = av_dict_set(&dict->handle, key.c_str(), value.c_str(), 0);
1390
1415
  assert(err == 0);
1391
1416
  }
1392
1417
 
@@ -1449,7 +1474,6 @@ bare_ffmpeg_resampler_init(
1449
1474
  }
1450
1475
 
1451
1476
  err = swr_init(resampler->handle);
1452
-
1453
1477
  if (err < 0) {
1454
1478
  swr_free(&resampler->handle);
1455
1479
 
@@ -1472,7 +1496,7 @@ bare_ffmpeg_resampler_convert_frames(
1472
1496
  ) {
1473
1497
  int err;
1474
1498
 
1475
- int result = swr_convert(
1499
+ auto result = swr_convert(
1476
1500
  resampler->handle,
1477
1501
  (uint8_t **) out_frame->handle->data,
1478
1502
  out_frame->handle->nb_samples,
@@ -1483,6 +1507,7 @@ bare_ffmpeg_resampler_convert_frames(
1483
1507
  if (result < 0) {
1484
1508
  err = js_throw_error(env, NULL, av_err2str(result));
1485
1509
  assert(err == 0);
1510
+
1486
1511
  throw js_pending_exception;
1487
1512
  }
1488
1513
 
@@ -1510,7 +1535,7 @@ bare_ffmpeg_resampler_flush(
1510
1535
  ) {
1511
1536
  int err;
1512
1537
 
1513
- int result = swr_convert(
1538
+ auto result = swr_convert(
1514
1539
  resampler->handle,
1515
1540
  out_frame->handle->data,
1516
1541
  out_frame->handle->nb_samples,
@@ -1521,6 +1546,7 @@ bare_ffmpeg_resampler_flush(
1521
1546
  if (result < 0) {
1522
1547
  err = js_throw_error(env, NULL, av_err2str(result));
1523
1548
  assert(err == 0);
1549
+
1524
1550
  throw js_pending_exception;
1525
1551
  }
1526
1552
 
@@ -1538,15 +1564,6 @@ bare_ffmpeg_resampler_destroy(
1538
1564
  swr_free(&resampler->handle);
1539
1565
  }
1540
1566
 
1541
- static void
1542
- bare_ffmpeg_channel_layout_destroy(
1543
- js_env_t *env,
1544
- js_receiver_t,
1545
- js_arraybuffer_span_of_t<bare_ffmpeg_channel_layout_t, 1> layout
1546
- ) {
1547
- av_channel_layout_uninit(&layout->handle);
1548
- }
1549
-
1550
1567
  static js_arraybuffer_t
1551
1568
  bare_ffmpeg_channel_layout_copy(
1552
1569
  js_env_t *env,
@@ -1596,6 +1613,149 @@ bare_ffmpeg_channel_layout_from_mask(
1596
1613
  return result;
1597
1614
  }
1598
1615
 
1616
+ static js_arraybuffer_t
1617
+ bare_ffmpeg_audio_fifo_init(
1618
+ js_env_t *env,
1619
+ js_receiver_t,
1620
+ int32_t sample_fmt,
1621
+ int32_t channels,
1622
+ int32_t nb_samples
1623
+ ) {
1624
+ int err;
1625
+
1626
+ js_arraybuffer_t handle;
1627
+
1628
+ bare_ffmpeg_audio_fifo_t *fifo;
1629
+ err = js_create_arraybuffer(env, fifo, handle);
1630
+ assert(err == 0);
1631
+
1632
+ fifo->handle = av_audio_fifo_alloc(
1633
+ static_cast<AVSampleFormat>(sample_fmt),
1634
+ channels,
1635
+ nb_samples
1636
+ );
1637
+
1638
+ return handle;
1639
+ }
1640
+
1641
+ static void
1642
+ bare_ffmpeg_audio_fifo_destroy(
1643
+ js_env_t *env,
1644
+ js_receiver_t,
1645
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1646
+ ) {
1647
+ av_audio_fifo_free(fifo->handle);
1648
+ }
1649
+
1650
+ static int
1651
+ bare_ffmpeg_audio_fifo_write(
1652
+ js_env_t *env,
1653
+ js_receiver_t,
1654
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1655
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
1656
+ ) {
1657
+ int err;
1658
+
1659
+ int len = av_audio_fifo_write(fifo->handle, (void **) frame->handle->data, frame->handle->nb_samples);
1660
+
1661
+ if (len < 0) {
1662
+ err = js_throw_error(env, NULL, av_err2str(len));
1663
+ assert(err == 0);
1664
+ throw js_pending_exception;
1665
+ }
1666
+
1667
+ return len;
1668
+ }
1669
+
1670
+ static int
1671
+ bare_ffmpeg_audio_fifo_read(
1672
+ js_env_t *env,
1673
+ js_receiver_t,
1674
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1675
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1676
+ int32_t nb_samples
1677
+ ) {
1678
+ int err;
1679
+
1680
+ int len = av_audio_fifo_read(fifo->handle, (void **) frame->handle->data, nb_samples);
1681
+
1682
+ if (len < 0) {
1683
+ err = js_throw_error(env, NULL, av_err2str(len));
1684
+ assert(err == 0);
1685
+ throw js_pending_exception;
1686
+ }
1687
+
1688
+ return len;
1689
+ }
1690
+
1691
+ static int
1692
+ bare_ffmpeg_audio_fifo_peek(
1693
+ js_env_t *env,
1694
+ js_receiver_t,
1695
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1696
+ js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
1697
+ int32_t nb_samples
1698
+ ) {
1699
+ int err;
1700
+
1701
+ int len = av_audio_fifo_peek(fifo->handle, (void **) frame->handle->data, nb_samples);
1702
+
1703
+ if (len < 0) {
1704
+ err = js_throw_error(env, NULL, av_err2str(len));
1705
+ assert(err == 0);
1706
+ throw js_pending_exception;
1707
+ }
1708
+
1709
+ return len;
1710
+ }
1711
+
1712
+ static int
1713
+ bare_ffmpeg_audio_fifo_drain(
1714
+ js_env_t *env,
1715
+ js_receiver_t,
1716
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo,
1717
+ int32_t nb_samples
1718
+ ) {
1719
+ int err;
1720
+
1721
+ int len = av_audio_fifo_drain(fifo->handle, nb_samples);
1722
+
1723
+ if (len < 0) {
1724
+ err = js_throw_error(env, NULL, av_err2str(len));
1725
+ assert(err == 0);
1726
+ throw js_pending_exception;
1727
+ }
1728
+
1729
+ return len;
1730
+ }
1731
+
1732
+ static void
1733
+ bare_ffmpeg_audio_fifo_reset(
1734
+ js_env_t *env,
1735
+ js_receiver_t,
1736
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1737
+ ) {
1738
+ av_audio_fifo_reset(fifo->handle);
1739
+ }
1740
+
1741
+ static int
1742
+ bare_ffmpeg_audio_fifo_size(
1743
+ js_env_t *env,
1744
+ js_receiver_t,
1745
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1746
+ ) {
1747
+ return av_audio_fifo_size(fifo->handle);
1748
+ }
1749
+
1750
+ static int
1751
+ bare_ffmpeg_audio_fifo_space(
1752
+ js_env_t *env,
1753
+ js_receiver_t,
1754
+ js_arraybuffer_span_of_t<bare_ffmpeg_audio_fifo_t, 1> fifo
1755
+ ) {
1756
+ return av_audio_fifo_space(fifo->handle);
1757
+ }
1758
+
1599
1759
  static js_value_t *
1600
1760
  bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1601
1761
  uv_once(&bare_ffmpeg__init_guard, bare_ffmpeg__on_init);
@@ -1706,10 +1866,19 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
1706
1866
  V("getResamplerDelay", bare_ffmpeg_resampler_get_delay)
1707
1867
  V("flushResampler", bare_ffmpeg_resampler_flush)
1708
1868
 
1709
- V("destroyChannelLayout", bare_ffmpeg_channel_layout_destroy)
1710
1869
  V("copyChannelLayout", bare_ffmpeg_channel_layout_copy)
1711
1870
  V("getChannelLayoutNbChannels", bare_ffmpeg_channel_layout_get_nb_channels)
1712
1871
  V("channelLayoutFromMask", bare_ffmpeg_channel_layout_from_mask)
1872
+
1873
+ V("initAudioFifo", bare_ffmpeg_audio_fifo_init)
1874
+ V("destroyAudioFifo", bare_ffmpeg_audio_fifo_destroy)
1875
+ V("writeAudioFifo", bare_ffmpeg_audio_fifo_write)
1876
+ V("readAudioFifo", bare_ffmpeg_audio_fifo_read)
1877
+ V("peekAudioFifo", bare_ffmpeg_audio_fifo_peek)
1878
+ V("drainAudioFifo", bare_ffmpeg_audio_fifo_drain)
1879
+ V("resetAudioFifo", bare_ffmpeg_audio_fifo_reset)
1880
+ V("getAudioFifoSize", bare_ffmpeg_audio_fifo_size)
1881
+ V("getAudioFifoSpace", bare_ffmpeg_audio_fifo_space)
1713
1882
  #undef V
1714
1883
 
1715
1884
  #define V(name) \
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
+ }
@@ -10,15 +10,6 @@ module.exports = class FFmpegChannelLayout {
10
10
  return binding.getChannelLayoutNbChannels(this._handle)
11
11
  }
12
12
 
13
- destroy() {
14
- binding.destroyChannelLayout(this._handle)
15
- this._handle = null
16
- }
17
-
18
- [Symbol.dispose]() {
19
- this.destroy()
20
- }
21
-
22
13
  static from(value) {
23
14
  if (typeof value === 'string') value = constants.toChannelLayout(value)
24
15
 
@@ -72,9 +72,10 @@ module.exports = class FFmpegCodecContext {
72
72
  }
73
73
 
74
74
  set channelLayout(value) {
75
- using copy = ChannelLayout.from(value)
76
-
77
- binding.setCodecContextChannelLayout(this._handle, copy._handle)
75
+ binding.setCodecContextChannelLayout(
76
+ this._handle,
77
+ ChannelLayout.from(value)._handle
78
+ )
78
79
  }
79
80
 
80
81
  open(options) {
@@ -6,10 +6,6 @@ module.exports = class FFmpegCodecParameters {
6
6
  this._handle = handle
7
7
  }
8
8
 
9
- destroy() {
10
- this._handle = null
11
- }
12
-
13
9
  get bitRate() {
14
10
  return binding.getCodecParametersBitRate(this._handle)
15
11
  }
@@ -51,8 +47,4 @@ module.exports = class FFmpegCodecParameters {
51
47
  toContext(context) {
52
48
  binding.codecParametersToContext(context._handle, this._handle)
53
49
  }
54
-
55
- [Symbol.dispose]() {
56
- this.destroy()
57
- }
58
50
  }
@@ -16,9 +16,6 @@ class FFmpegFormatContext {
16
16
  this._io.destroy()
17
17
  this._io = null
18
18
  }
19
-
20
- for (const stream of this._streams) stream.destroy()
21
- this._streams = []
22
19
  }
23
20
 
24
21
  get io() {
package/lib/frame.js CHANGED
@@ -48,9 +48,10 @@ module.exports = class FFmpegFrame {
48
48
  }
49
49
 
50
50
  set channelLayout(value) {
51
- using copy = ChannelLayout.from(value)
52
-
53
- binding.setFrameChannelLayout(this._handle, copy._handle)
51
+ binding.setFrameChannelLayout(
52
+ this._handle,
53
+ ChannelLayout.from(value)._handle
54
+ )
54
55
  }
55
56
 
56
57
  get nbSamples() {
package/lib/stream.js CHANGED
@@ -14,11 +14,6 @@ module.exports = class FFmpegStream {
14
14
  )
15
15
  }
16
16
 
17
- destroy() {
18
- this._codecParameters.destroy()
19
- this._codecParameters = null
20
- }
21
-
22
17
  get codec() {
23
18
  return this._codec
24
19
  }
@@ -38,8 +33,4 @@ module.exports = class FFmpegStream {
38
33
  this._codecParameters.toContext(context)
39
34
  return context.open()
40
35
  }
41
-
42
- [Symbol.dispose]() {
43
- this.destroy()
44
- }
45
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ffmpeg",
3
- "version": "1.0.0-12",
3
+ "version": "1.0.0-14",
4
4
  "description": "Low-level FFmpeg bindings for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",