bare-ffmpeg 1.0.0-21 → 1.0.0-23
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 +1 -1
- package/README.md +49 -10
- package/binding.cc +190 -82
- package/cmake/ports/ffmpeg/port.cmake +1 -0
- package/lib/codec.js +0 -1
- package/lib/constants.js +0 -6
- package/lib/dictionary.js +10 -0
- package/lib/frame.js +0 -9
- package/lib/io-context.js +8 -9
- package/lib/packet.js +1 -1
- package/package.json +1 -1
- package/prebuilds/android-arm/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-ia32/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/darwin-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/darwin-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-arm64-simulator/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-x64-simulator/bare-ffmpeg.bare +0 -0
- package/prebuilds/linux-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/linux-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/win32-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/win32-x64/bare-ffmpeg.bare +0 -0
package/CMakeLists.txt
CHANGED
package/README.md
CHANGED
|
@@ -108,6 +108,21 @@ for (const [key, value] of dict) {
|
|
|
108
108
|
}
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
#### Static methods
|
|
112
|
+
|
|
113
|
+
##### `Dictionary.from(object)`
|
|
114
|
+
|
|
115
|
+
A helper to create a `Dictionary` instance from an object.
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
const dict = ffmpeg.Dictionary.from({
|
|
119
|
+
foo: 'bar',
|
|
120
|
+
baz: 'qux'
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Returns**: A new `Dictionary` instance
|
|
125
|
+
|
|
111
126
|
### `FormatContext`
|
|
112
127
|
|
|
113
128
|
The `FormatContext` API provides the base functionality for reading and writing media files.
|
|
@@ -600,15 +615,9 @@ Gets or sets the frame height.
|
|
|
600
615
|
|
|
601
616
|
**Returns**: `number`
|
|
602
617
|
|
|
603
|
-
##### `Frame.pixelFormat`
|
|
604
|
-
|
|
605
|
-
Gets or sets the pixel format.
|
|
606
|
-
|
|
607
|
-
**Returns**: `number` (pixel format constant)
|
|
608
|
-
|
|
609
618
|
##### `Frame.format`
|
|
610
619
|
|
|
611
|
-
Gets or sets the
|
|
620
|
+
Gets or sets the format of the frame, `-1` if unknown or unset.
|
|
612
621
|
|
|
613
622
|
**Returns**: `number` (sample format constant)
|
|
614
623
|
|
|
@@ -852,17 +861,47 @@ Parameters:
|
|
|
852
861
|
|
|
853
862
|
#### Properties
|
|
854
863
|
|
|
864
|
+
##### `Stream.id`
|
|
865
|
+
|
|
866
|
+
Gets or sets the stream ID.
|
|
867
|
+
|
|
868
|
+
**Returns**: `number`
|
|
869
|
+
|
|
870
|
+
##### `Stream.index`
|
|
871
|
+
|
|
872
|
+
Gets the stream index.
|
|
873
|
+
|
|
874
|
+
**Returns**: `number`
|
|
875
|
+
|
|
876
|
+
##### `Stream.codec`
|
|
877
|
+
|
|
878
|
+
Gets the codec for this stream.
|
|
879
|
+
|
|
880
|
+
**Returns**: `Codec` instance
|
|
881
|
+
|
|
855
882
|
##### `Stream.codecParameters`
|
|
856
883
|
|
|
857
884
|
Gets the codec parameters for this stream.
|
|
858
885
|
|
|
859
886
|
**Returns**: `CodecParameters` instance
|
|
860
887
|
|
|
861
|
-
##### `Stream.
|
|
888
|
+
##### `Stream.timeBase`
|
|
862
889
|
|
|
863
|
-
Gets the
|
|
890
|
+
Gets or sets the time base for the stream.
|
|
864
891
|
|
|
865
|
-
**Returns**: `
|
|
892
|
+
**Returns**: `Rational` instance
|
|
893
|
+
|
|
894
|
+
##### `Stream.avgFramerate`
|
|
895
|
+
|
|
896
|
+
Gets or sets the average framerate for video streams.
|
|
897
|
+
|
|
898
|
+
**Returns**: `Rational` instance
|
|
899
|
+
|
|
900
|
+
Example:
|
|
901
|
+
|
|
902
|
+
```js
|
|
903
|
+
const fps = stream.avgFramerate.toNumber()
|
|
904
|
+
```
|
|
866
905
|
|
|
867
906
|
#### Methods
|
|
868
907
|
|
package/binding.cc
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
#include <assert.h>
|
|
2
|
-
#include <cstdint>
|
|
3
|
-
#include <stddef.h>
|
|
4
|
-
#include <stdint.h>
|
|
5
|
-
#include <string.h>
|
|
6
1
|
#include <tuple>
|
|
7
2
|
#include <vector>
|
|
8
3
|
|
|
4
|
+
#include <assert.h>
|
|
9
5
|
#include <bare.h>
|
|
10
6
|
#include <js.h>
|
|
11
7
|
#include <jstl.h>
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
#include <string.h>
|
|
12
11
|
|
|
13
12
|
extern "C" {
|
|
14
13
|
#include <libavcodec/avcodec.h>
|
|
@@ -34,13 +33,18 @@ extern "C" {
|
|
|
34
33
|
#include <libswscale/swscale.h>
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
using
|
|
36
|
+
using bare_ffmpeg_io_context_write_cb_t = js_function_t<void, js_typedarray_t<uint8_t>>;
|
|
37
|
+
using bare_ffmpeg_io_context_read_cb_t = js_function_t<int32_t, js_typedarray_t<uint8_t>, int32_t>;
|
|
38
|
+
using bare_ffmpeg_io_context_seek_cb_t = js_function_t<int64_t, int64_t, std::string>;
|
|
38
39
|
|
|
39
40
|
typedef struct {
|
|
40
41
|
AVIOContext *handle;
|
|
41
42
|
|
|
42
43
|
js_env_t *env;
|
|
43
|
-
|
|
44
|
+
|
|
45
|
+
js_persistent_t<bare_ffmpeg_io_context_write_cb_t> on_write;
|
|
46
|
+
js_persistent_t<bare_ffmpeg_io_context_read_cb_t> on_read;
|
|
47
|
+
js_persistent_t<bare_ffmpeg_io_context_seek_cb_t> on_seek;
|
|
44
48
|
} bare_ffmpeg_io_context_t;
|
|
45
49
|
|
|
46
50
|
typedef struct {
|
|
@@ -102,9 +106,9 @@ typedef struct {
|
|
|
102
106
|
static uv_once_t bare_ffmpeg__init_guard = UV_ONCE_INIT;
|
|
103
107
|
|
|
104
108
|
static inline bool
|
|
105
|
-
|
|
106
|
-
return r.den < 1 || //
|
|
107
|
-
av_q2d(r) == 0; //
|
|
109
|
+
bare_ffmpeg__bad_timebase(const AVRational r) {
|
|
110
|
+
return r.den < 1 || // Invalid denominator
|
|
111
|
+
av_q2d(r) == 0; // Initial state (0 / 1)
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
static void
|
|
@@ -125,24 +129,107 @@ bare_ffmpeg_log_set_level(js_env_t *, int32_t level) {
|
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
static int
|
|
128
|
-
|
|
132
|
+
bare_ffmpeg__on_io_context_write(void *opaque, const uint8_t *buf, int len) {
|
|
133
|
+
int err;
|
|
134
|
+
|
|
135
|
+
auto context = static_cast<bare_ffmpeg_io_context_t *>(opaque);
|
|
136
|
+
|
|
137
|
+
auto env = context->env;
|
|
138
|
+
|
|
139
|
+
bare_ffmpeg_io_context_write_cb_t callback;
|
|
140
|
+
err = js_get_reference_value(env, context->on_write, callback);
|
|
141
|
+
assert(err == 0);
|
|
142
|
+
|
|
143
|
+
js_arraybuffer_t data;
|
|
144
|
+
err = js_create_arraybuffer(env, buf, static_cast<size_t>(len), data);
|
|
145
|
+
assert(err == 0);
|
|
146
|
+
|
|
147
|
+
js_typedarray_t<uint8_t> view;
|
|
148
|
+
err = js_create_typedarray(env, static_cast<size_t>(len), data, view);
|
|
149
|
+
assert(err == 0);
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
err = js_call_function(env, callback, view);
|
|
153
|
+
assert(err == 0);
|
|
154
|
+
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static int
|
|
159
|
+
bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
|
|
160
|
+
int err;
|
|
161
|
+
|
|
129
162
|
auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
|
|
163
|
+
|
|
130
164
|
auto env = context->env;
|
|
131
165
|
|
|
132
|
-
|
|
166
|
+
bare_ffmpeg_io_context_read_cb_t callback;
|
|
167
|
+
err = js_get_reference_value(env, context->on_read, callback);
|
|
168
|
+
assert(err == 0);
|
|
133
169
|
|
|
134
|
-
|
|
170
|
+
js_arraybuffer_t arraybuffer;
|
|
171
|
+
err = js_create_external_arraybuffer(env, buf, static_cast<size_t>(len), arraybuffer);
|
|
135
172
|
assert(err == 0);
|
|
136
173
|
|
|
137
|
-
|
|
138
|
-
err =
|
|
174
|
+
js_typedarray_t<uint8_t> view;
|
|
175
|
+
err = js_create_typedarray(env, static_cast<size_t>(len), arraybuffer, view);
|
|
176
|
+
assert(err == 0);
|
|
177
|
+
|
|
178
|
+
int32_t result;
|
|
179
|
+
int call_status = js_call_function<js_type_options_t{}, int32_t, js_typedarray_t<uint8_t>, int32_t>(env, callback, view, len, result);
|
|
139
180
|
|
|
181
|
+
err = js_detach_arraybuffer(env, arraybuffer);
|
|
140
182
|
assert(err == 0);
|
|
141
183
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
184
|
+
if (call_status < 0) return AVERROR(EIO);
|
|
185
|
+
|
|
186
|
+
if (result == 0) return AVERROR_EOF;
|
|
187
|
+
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static int64_t
|
|
192
|
+
bare_ffmpeg__on_io_context_seek(void *opaque, int64_t offset, int whence) {
|
|
193
|
+
int err;
|
|
194
|
+
|
|
195
|
+
auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
|
|
196
|
+
|
|
197
|
+
auto env = context->env;
|
|
198
|
+
|
|
199
|
+
int64_t result;
|
|
200
|
+
std::string whence_str;
|
|
201
|
+
switch (whence) {
|
|
202
|
+
case AVSEEK_SIZE:
|
|
203
|
+
whence_str = "avseek_size";
|
|
204
|
+
break;
|
|
205
|
+
case AVSEEK_FORCE:
|
|
206
|
+
whence_str = "avseek_force";
|
|
207
|
+
break;
|
|
208
|
+
case SEEK_SET:
|
|
209
|
+
whence_str = "seek_set";
|
|
210
|
+
break;
|
|
211
|
+
case SEEK_CUR:
|
|
212
|
+
whence_str = "seek_cur";
|
|
213
|
+
break;
|
|
214
|
+
case SEEK_END:
|
|
215
|
+
whence_str = "seek_end";
|
|
216
|
+
break;
|
|
217
|
+
default:
|
|
218
|
+
whence_str = "unknown:" + std::to_string(whence);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
bare_ffmpeg_io_context_seek_cb_t callback;
|
|
222
|
+
err = js_get_reference_value(env, context->on_seek, callback);
|
|
223
|
+
assert(err == 0);
|
|
224
|
+
|
|
225
|
+
err = js_call_function<js_type_options_t{}, int64_t, int64_t, std::string>(env, callback, offset, whence_str, result);
|
|
226
|
+
if (err < 0) return AVERROR(EIO); // read-error
|
|
227
|
+
|
|
228
|
+
if (result == -1) {
|
|
229
|
+
return AVERROR(ENOSYS); // seek-op not supported by IO
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return result;
|
|
146
233
|
}
|
|
147
234
|
|
|
148
235
|
static js_arraybuffer_t
|
|
@@ -152,7 +239,9 @@ bare_ffmpeg_io_context_init(
|
|
|
152
239
|
std::optional<js_arraybuffer_span_t> data,
|
|
153
240
|
uint64_t offset,
|
|
154
241
|
uint64_t len,
|
|
155
|
-
std::optional<
|
|
242
|
+
std::optional<bare_ffmpeg_io_context_write_cb_t> on_write,
|
|
243
|
+
std::optional<bare_ffmpeg_io_context_read_cb_t> on_read,
|
|
244
|
+
std::optional<bare_ffmpeg_io_context_seek_cb_t> on_seek
|
|
156
245
|
) {
|
|
157
246
|
int err;
|
|
158
247
|
|
|
@@ -164,37 +253,46 @@ bare_ffmpeg_io_context_init(
|
|
|
164
253
|
|
|
165
254
|
context->env = env;
|
|
166
255
|
|
|
167
|
-
int
|
|
256
|
+
int writable = 0;
|
|
257
|
+
|
|
168
258
|
if (on_write) {
|
|
169
|
-
|
|
259
|
+
writable = 1;
|
|
260
|
+
|
|
170
261
|
err = js_create_reference(env, *on_write, context->on_write);
|
|
171
262
|
assert(err == 0);
|
|
172
263
|
}
|
|
173
264
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
265
|
+
if (on_read) {
|
|
266
|
+
err = js_create_reference(env, *on_read, context->on_read);
|
|
267
|
+
assert(err == 0);
|
|
268
|
+
}
|
|
177
269
|
|
|
178
|
-
if (
|
|
179
|
-
|
|
270
|
+
if (on_seek) {
|
|
271
|
+
err = js_create_reference(env, *on_seek, context->on_seek);
|
|
272
|
+
assert(err == 0);
|
|
180
273
|
}
|
|
181
274
|
|
|
275
|
+
auto size = static_cast<size_t>(len);
|
|
276
|
+
|
|
277
|
+
auto io = reinterpret_cast<uint8_t *>(av_malloc(size));
|
|
278
|
+
|
|
182
279
|
if (data) {
|
|
183
280
|
memcpy(io, &data.value()[static_cast<size_t>(offset)], size);
|
|
184
281
|
}
|
|
185
282
|
|
|
186
|
-
// TODO: for stream read support provide read/seek callbacks
|
|
187
|
-
|
|
188
283
|
context->handle = avio_alloc_context(
|
|
189
284
|
io,
|
|
190
285
|
static_cast<int>(len),
|
|
191
|
-
|
|
286
|
+
writable,
|
|
192
287
|
context,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
288
|
+
on_read ? bare_ffmpeg__on_io_context_read : nullptr,
|
|
289
|
+
on_write ? bare_ffmpeg__on_io_context_write : nullptr,
|
|
290
|
+
on_seek ? bare_ffmpeg__on_io_context_seek : nullptr
|
|
196
291
|
);
|
|
197
|
-
|
|
292
|
+
|
|
293
|
+
if (!on_seek) {
|
|
294
|
+
context->handle->seekable = 0;
|
|
295
|
+
}
|
|
198
296
|
|
|
199
297
|
return handle;
|
|
200
298
|
}
|
|
@@ -208,7 +306,10 @@ bare_ffmpeg_io_context_destroy(
|
|
|
208
306
|
av_free(context->handle->buffer);
|
|
209
307
|
|
|
210
308
|
avio_context_free(&context->handle);
|
|
309
|
+
|
|
211
310
|
context->on_write.reset();
|
|
311
|
+
context->on_read.reset();
|
|
312
|
+
context->on_seek.reset();
|
|
212
313
|
}
|
|
213
314
|
|
|
214
315
|
static js_arraybuffer_t
|
|
@@ -415,7 +516,7 @@ bare_ffmpeg_format_context_get_streams(
|
|
|
415
516
|
) {
|
|
416
517
|
int err;
|
|
417
518
|
|
|
418
|
-
|
|
519
|
+
auto len = context->handle->nb_streams;
|
|
419
520
|
|
|
420
521
|
js_array_t result;
|
|
421
522
|
err = js_create_array(env, len, result);
|
|
@@ -497,15 +598,14 @@ bare_ffmpeg_format_context_write_header(
|
|
|
497
598
|
js_env_t *env,
|
|
498
599
|
js_receiver_t,
|
|
499
600
|
js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
|
|
500
|
-
std::optional<js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1>>
|
|
601
|
+
std::optional<js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1>> options
|
|
501
602
|
) {
|
|
502
603
|
int err;
|
|
503
604
|
|
|
504
|
-
if (
|
|
505
|
-
err = avformat_write_header(context->handle,
|
|
605
|
+
if (options) {
|
|
606
|
+
err = avformat_write_header(context->handle, &options.value()->handle);
|
|
506
607
|
} else {
|
|
507
|
-
|
|
508
|
-
err = avformat_write_header(context->handle, &dict->handle);
|
|
608
|
+
err = avformat_write_header(context->handle, NULL);
|
|
509
609
|
}
|
|
510
610
|
|
|
511
611
|
if (err < 0) {
|
|
@@ -517,6 +617,7 @@ bare_ffmpeg_format_context_write_header(
|
|
|
517
617
|
|
|
518
618
|
return err;
|
|
519
619
|
}
|
|
620
|
+
|
|
520
621
|
static void
|
|
521
622
|
bare_ffmpeg_format_context_write_frame(
|
|
522
623
|
js_env_t *env,
|
|
@@ -524,8 +625,9 @@ bare_ffmpeg_format_context_write_frame(
|
|
|
524
625
|
js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context,
|
|
525
626
|
js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
|
|
526
627
|
) {
|
|
527
|
-
int err
|
|
628
|
+
int err;
|
|
528
629
|
|
|
630
|
+
err = av_interleaved_write_frame(context->handle, packet->handle);
|
|
529
631
|
if (err < 0) {
|
|
530
632
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
531
633
|
assert(err == 0);
|
|
@@ -540,7 +642,9 @@ bare_ffmpeg_format_context_write_trailer(
|
|
|
540
642
|
js_receiver_t,
|
|
541
643
|
js_arraybuffer_span_of_t<bare_ffmpeg_format_context_t, 1> context
|
|
542
644
|
) {
|
|
543
|
-
int err
|
|
645
|
+
int err;
|
|
646
|
+
|
|
647
|
+
err = av_write_trailer(context->handle);
|
|
544
648
|
if (err < 0) {
|
|
545
649
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
546
650
|
assert(err == 0);
|
|
@@ -562,6 +666,7 @@ bare_ffmpeg_format_context_dump(
|
|
|
562
666
|
|
|
563
667
|
for (int i = 0; i < context->handle->nb_streams; i++) {
|
|
564
668
|
auto stream = context->handle->streams[i];
|
|
669
|
+
|
|
565
670
|
av_log(NULL, AV_LOG_INFO, " - stream=%i timebase=(%i / %i)\n", i, stream->time_base.num, stream->time_base.den);
|
|
566
671
|
}
|
|
567
672
|
}
|
|
@@ -770,7 +875,6 @@ bare_ffmpeg_codec_context_open(
|
|
|
770
875
|
int err;
|
|
771
876
|
|
|
772
877
|
err = avcodec_open2(context->handle, context->handle->codec, NULL);
|
|
773
|
-
|
|
774
878
|
if (err < 0) {
|
|
775
879
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
776
880
|
assert(err == 0);
|
|
@@ -800,7 +904,7 @@ bare_ffmpeg_codec_context_set_flags(
|
|
|
800
904
|
context->handle->flags = value;
|
|
801
905
|
}
|
|
802
906
|
|
|
803
|
-
static
|
|
907
|
+
static int
|
|
804
908
|
bare_ffmpeg_frame_get_format(
|
|
805
909
|
js_env_t *env,
|
|
806
910
|
js_receiver_t,
|
|
@@ -1133,7 +1237,7 @@ bare_ffmpeg_codec_context_send_frame(
|
|
|
1133
1237
|
int err;
|
|
1134
1238
|
|
|
1135
1239
|
if (frame) {
|
|
1136
|
-
err = avcodec_send_frame(context->handle, (
|
|
1240
|
+
err = avcodec_send_frame(context->handle, frame.value()->handle);
|
|
1137
1241
|
} else {
|
|
1138
1242
|
err = avcodec_send_frame(context->handle, NULL); // End of stream
|
|
1139
1243
|
}
|
|
@@ -1178,7 +1282,6 @@ bare_ffmpeg_codec_parameters_from_context(
|
|
|
1178
1282
|
int err;
|
|
1179
1283
|
|
|
1180
1284
|
err = avcodec_parameters_from_context(parameters->handle, context->handle);
|
|
1181
|
-
|
|
1182
1285
|
if (err < 0) {
|
|
1183
1286
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
1184
1287
|
assert(err == 0);
|
|
@@ -1213,6 +1316,7 @@ bare_ffmpeg_codec_parameters_alloc(
|
|
|
1213
1316
|
int err;
|
|
1214
1317
|
|
|
1215
1318
|
js_arraybuffer_t handle;
|
|
1319
|
+
|
|
1216
1320
|
bare_ffmpeg_codec_parameters_t *parameters;
|
|
1217
1321
|
err = js_create_arraybuffer(env, parameters, handle);
|
|
1218
1322
|
assert(err == 0);
|
|
@@ -1578,7 +1682,6 @@ bare_ffmpeg_codec_parameters_set_extra_data(
|
|
|
1578
1682
|
int err;
|
|
1579
1683
|
|
|
1580
1684
|
std::span<uint8_t> view;
|
|
1581
|
-
|
|
1582
1685
|
err = js_get_arraybuffer_info(env, buffer, view);
|
|
1583
1686
|
assert(err == 0);
|
|
1584
1687
|
|
|
@@ -1592,6 +1695,7 @@ bare_ffmpeg_codec_parameters_set_extra_data(
|
|
|
1592
1695
|
size_t min_size = len + AV_INPUT_BUFFER_PADDING_SIZE;
|
|
1593
1696
|
|
|
1594
1697
|
parameters->handle->extradata = reinterpret_cast<uint8_t *>(av_malloc(min_size));
|
|
1698
|
+
|
|
1595
1699
|
memset(¶meters->handle->extradata[len], 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
1596
1700
|
|
|
1597
1701
|
memcpy(parameters->handle->extradata, &view[offset], len);
|
|
@@ -1797,25 +1901,6 @@ bare_ffmpeg_frame_set_height(
|
|
|
1797
1901
|
frame->handle->height = height;
|
|
1798
1902
|
}
|
|
1799
1903
|
|
|
1800
|
-
static int64_t
|
|
1801
|
-
bare_ffmpeg_frame_get_pixel_format(
|
|
1802
|
-
js_env_t *env,
|
|
1803
|
-
js_receiver_t,
|
|
1804
|
-
js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
|
|
1805
|
-
) {
|
|
1806
|
-
return frame->handle->format;
|
|
1807
|
-
}
|
|
1808
|
-
|
|
1809
|
-
static void
|
|
1810
|
-
bare_ffmpeg_frame_set_pixel_format(
|
|
1811
|
-
js_env_t *env,
|
|
1812
|
-
js_receiver_t,
|
|
1813
|
-
js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame,
|
|
1814
|
-
int32_t format
|
|
1815
|
-
) {
|
|
1816
|
-
frame->handle->format = static_cast<AVPixelFormat>(format);
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
1904
|
static int32_t
|
|
1820
1905
|
bare_ffmpeg_frame_get_nb_samples(
|
|
1821
1906
|
js_env_t *env,
|
|
@@ -1909,6 +1994,7 @@ bare_ffmpeg_frame_get_time_base(
|
|
|
1909
1994
|
|
|
1910
1995
|
return result;
|
|
1911
1996
|
}
|
|
1997
|
+
|
|
1912
1998
|
static void
|
|
1913
1999
|
bare_ffmpeg_frame_set_time_base(
|
|
1914
2000
|
js_env_t *env,
|
|
@@ -2015,10 +2101,12 @@ bare_ffmpeg_image_read(
|
|
|
2015
2101
|
uint64_t offset,
|
|
2016
2102
|
js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> frame
|
|
2017
2103
|
) {
|
|
2104
|
+
int err;
|
|
2105
|
+
|
|
2018
2106
|
uint8_t *dst_data[4];
|
|
2019
2107
|
int dst_linesize[4];
|
|
2020
2108
|
|
|
2021
|
-
|
|
2109
|
+
auto len = av_image_fill_arrays(
|
|
2022
2110
|
dst_data,
|
|
2023
2111
|
dst_linesize,
|
|
2024
2112
|
&data[offset],
|
|
@@ -2027,7 +2115,13 @@ bare_ffmpeg_image_read(
|
|
|
2027
2115
|
height,
|
|
2028
2116
|
align
|
|
2029
2117
|
);
|
|
2030
|
-
|
|
2118
|
+
|
|
2119
|
+
if (len < 0) {
|
|
2120
|
+
err = js_throw_error(env, NULL, av_err2str(len));
|
|
2121
|
+
assert(err == 0);
|
|
2122
|
+
|
|
2123
|
+
throw js_pending_exception;
|
|
2124
|
+
}
|
|
2031
2125
|
|
|
2032
2126
|
av_image_copy(
|
|
2033
2127
|
dst_data,
|
|
@@ -2174,6 +2268,15 @@ bare_ffmpeg_packet_unref(
|
|
|
2174
2268
|
av_packet_unref(packet->handle);
|
|
2175
2269
|
}
|
|
2176
2270
|
|
|
2271
|
+
static void
|
|
2272
|
+
bare_ffmpeg_packet_destroy(
|
|
2273
|
+
js_env_t *env,
|
|
2274
|
+
js_receiver_t,
|
|
2275
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
|
|
2276
|
+
) {
|
|
2277
|
+
av_packet_free(&packet->handle);
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2177
2280
|
static int32_t
|
|
2178
2281
|
bare_ffmpeg_packet_get_stream_index(
|
|
2179
2282
|
js_env_t *env,
|
|
@@ -2224,6 +2327,7 @@ bare_ffmpeg_packet_set_data(
|
|
|
2224
2327
|
uint32_t len
|
|
2225
2328
|
) {
|
|
2226
2329
|
int err;
|
|
2330
|
+
|
|
2227
2331
|
assert(offset + len <= data.size());
|
|
2228
2332
|
|
|
2229
2333
|
av_packet_unref(packet->handle);
|
|
@@ -2329,11 +2433,11 @@ bare_ffmpeg_packet_rescale_ts(
|
|
|
2329
2433
|
int32_t den
|
|
2330
2434
|
) {
|
|
2331
2435
|
AVRational src = packet->handle->time_base;
|
|
2332
|
-
AVRational dst = {
|
|
2436
|
+
AVRational dst = {num, den};
|
|
2333
2437
|
|
|
2334
2438
|
if (
|
|
2335
|
-
|
|
2336
|
-
|
|
2439
|
+
bare_ffmpeg__bad_timebase(src) ||
|
|
2440
|
+
bare_ffmpeg__bad_timebase(dst) ||
|
|
2337
2441
|
packet->handle->dts == AV_NOPTS_VALUE ||
|
|
2338
2442
|
packet->handle->pts == AV_NOPTS_VALUE
|
|
2339
2443
|
) {
|
|
@@ -2439,7 +2543,9 @@ bare_ffmpeg_scaler_scale(
|
|
|
2439
2543
|
int height,
|
|
2440
2544
|
js_arraybuffer_span_of_t<bare_ffmpeg_frame_t, 1> target
|
|
2441
2545
|
) {
|
|
2442
|
-
int err
|
|
2546
|
+
int err;
|
|
2547
|
+
|
|
2548
|
+
err = av_frame_copy_props(target->handle, source->handle);
|
|
2443
2549
|
assert(err == 0);
|
|
2444
2550
|
|
|
2445
2551
|
return sws_scale(
|
|
@@ -2503,6 +2609,7 @@ bare_ffmpeg_dictionary_get_entries(
|
|
|
2503
2609
|
std::vector<std::tuple<const char *, const char *>> entries{};
|
|
2504
2610
|
|
|
2505
2611
|
const AVDictionaryEntry *entry = nullptr;
|
|
2612
|
+
|
|
2506
2613
|
while ((entry = av_dict_iterate(dict->handle, entry))) {
|
|
2507
2614
|
entries.emplace_back(entry->key, entry->value);
|
|
2508
2615
|
}
|
|
@@ -2760,11 +2867,12 @@ bare_ffmpeg_audio_fifo_write(
|
|
|
2760
2867
|
) {
|
|
2761
2868
|
int err;
|
|
2762
2869
|
|
|
2763
|
-
|
|
2870
|
+
auto len = av_audio_fifo_write(fifo->handle, (void **) frame->handle->data, frame->handle->nb_samples);
|
|
2764
2871
|
|
|
2765
2872
|
if (len < 0) {
|
|
2766
2873
|
err = js_throw_error(env, NULL, av_err2str(len));
|
|
2767
2874
|
assert(err == 0);
|
|
2875
|
+
|
|
2768
2876
|
throw js_pending_exception;
|
|
2769
2877
|
}
|
|
2770
2878
|
|
|
@@ -2781,11 +2889,12 @@ bare_ffmpeg_audio_fifo_read(
|
|
|
2781
2889
|
) {
|
|
2782
2890
|
int err;
|
|
2783
2891
|
|
|
2784
|
-
|
|
2892
|
+
auto len = av_audio_fifo_read(fifo->handle, (void **) frame->handle->data, nb_samples);
|
|
2785
2893
|
|
|
2786
2894
|
if (len < 0) {
|
|
2787
2895
|
err = js_throw_error(env, NULL, av_err2str(len));
|
|
2788
2896
|
assert(err == 0);
|
|
2897
|
+
|
|
2789
2898
|
throw js_pending_exception;
|
|
2790
2899
|
}
|
|
2791
2900
|
|
|
@@ -2802,11 +2911,12 @@ bare_ffmpeg_audio_fifo_peek(
|
|
|
2802
2911
|
) {
|
|
2803
2912
|
int err;
|
|
2804
2913
|
|
|
2805
|
-
|
|
2914
|
+
auto len = av_audio_fifo_peek(fifo->handle, (void **) frame->handle->data, nb_samples);
|
|
2806
2915
|
|
|
2807
2916
|
if (len < 0) {
|
|
2808
2917
|
err = js_throw_error(env, NULL, av_err2str(len));
|
|
2809
2918
|
assert(err == 0);
|
|
2919
|
+
|
|
2810
2920
|
throw js_pending_exception;
|
|
2811
2921
|
}
|
|
2812
2922
|
|
|
@@ -2822,11 +2932,12 @@ bare_ffmpeg_audio_fifo_drain(
|
|
|
2822
2932
|
) {
|
|
2823
2933
|
int err;
|
|
2824
2934
|
|
|
2825
|
-
|
|
2935
|
+
auto len = av_audio_fifo_drain(fifo->handle, nb_samples);
|
|
2826
2936
|
|
|
2827
2937
|
if (len < 0) {
|
|
2828
2938
|
err = js_throw_error(env, NULL, av_err2str(len));
|
|
2829
2939
|
assert(err == 0);
|
|
2940
|
+
|
|
2830
2941
|
throw js_pending_exception;
|
|
2831
2942
|
}
|
|
2832
2943
|
|
|
@@ -2866,12 +2977,10 @@ bare_ffmpeg_rational_d2q(
|
|
|
2866
2977
|
js_receiver_t,
|
|
2867
2978
|
double num
|
|
2868
2979
|
) {
|
|
2869
|
-
constexpr int safe_max = 1 << 26;
|
|
2870
|
-
|
|
2871
|
-
auto rational = av_d2q(num, safe_max);
|
|
2872
|
-
|
|
2873
2980
|
int err;
|
|
2874
2981
|
|
|
2982
|
+
auto rational = av_d2q(num, 1 << 26);
|
|
2983
|
+
|
|
2875
2984
|
js_arraybuffer_t result;
|
|
2876
2985
|
|
|
2877
2986
|
int32_t *data;
|
|
@@ -3018,8 +3127,6 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3018
3127
|
V("setFrameWidth", bare_ffmpeg_frame_set_width)
|
|
3019
3128
|
V("getFrameHeight", bare_ffmpeg_frame_get_height)
|
|
3020
3129
|
V("setFrameHeight", bare_ffmpeg_frame_set_height)
|
|
3021
|
-
V("getFramePixelFormat", bare_ffmpeg_frame_get_pixel_format)
|
|
3022
|
-
V("setFramePixelFormat", bare_ffmpeg_frame_set_pixel_format)
|
|
3023
3130
|
V("getFrameFormat", bare_ffmpeg_frame_get_format)
|
|
3024
3131
|
V("setFrameFormat", bare_ffmpeg_frame_set_format)
|
|
3025
3132
|
V("getFrameChannelLayout", bare_ffmpeg_frame_get_channel_layout)
|
|
@@ -3045,6 +3152,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3045
3152
|
|
|
3046
3153
|
V("initPacket", bare_ffmpeg_packet_init)
|
|
3047
3154
|
V("initPacketFromBuffer", bare_ffmpeg_packet_init_from_buffer)
|
|
3155
|
+
V("destroyPacket", bare_ffmpeg_packet_destroy)
|
|
3048
3156
|
V("unrefPacket", bare_ffmpeg_packet_unref)
|
|
3049
3157
|
V("getPacketStreamIndex", bare_ffmpeg_packet_get_stream_index)
|
|
3050
3158
|
V("setPacketStreamIndex", bare_ffmpeg_packet_set_stream_index)
|
package/lib/codec.js
CHANGED
|
@@ -51,7 +51,6 @@ module.exports = class FFmpegCodec {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
static MJPEG = this.for(constants.codecs.MJPEG)
|
|
54
|
-
static H264 = this.for(constants.codecs.H264)
|
|
55
54
|
static AAC = this.for(constants.codecs.AAC)
|
|
56
55
|
static OPUS = this.for(constants.codecs.OPUS)
|
|
57
56
|
static AV1 = this.for(constants.codecs.AV1)
|
package/lib/constants.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const binding = require('../binding')
|
|
2
2
|
const errors = require('./errors')
|
|
3
3
|
|
|
4
|
-
// Helpers
|
|
5
4
|
function makeTag(a, b, c, d) {
|
|
6
5
|
return (
|
|
7
6
|
a.charCodeAt(0) |
|
|
@@ -14,7 +13,6 @@ function makeTag(a, b, c, d) {
|
|
|
14
13
|
module.exports = exports = {
|
|
15
14
|
codecs: {
|
|
16
15
|
MJPEG: binding.AV_CODEC_ID_MJPEG,
|
|
17
|
-
H264: binding.AV_CODEC_ID_H264,
|
|
18
16
|
AAC: binding.AV_CODEC_ID_AAC,
|
|
19
17
|
OPUS: binding.AV_CODEC_ID_OPUS,
|
|
20
18
|
AV1: binding.AV_CODEC_ID_AV1,
|
|
@@ -22,11 +20,7 @@ module.exports = exports = {
|
|
|
22
20
|
MP3: binding.AV_CODEC_ID_MP3
|
|
23
21
|
},
|
|
24
22
|
tags: {
|
|
25
|
-
// Source Ref:
|
|
26
|
-
// https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/riff.c#L36
|
|
27
|
-
// https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/riff.c#L530
|
|
28
23
|
MJPEG: makeTag('M', 'J', 'P', 'G'),
|
|
29
|
-
H264: makeTag('H', '2', '6', '4'),
|
|
30
24
|
AV1: makeTag('A', 'V', '0', '1'),
|
|
31
25
|
AAC: 0x00ff,
|
|
32
26
|
FLAC: 0xf1ac,
|
package/lib/dictionary.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
const binding = require('../binding')
|
|
2
2
|
|
|
3
3
|
module.exports = class FFmpegDictionary {
|
|
4
|
+
static from(obj) {
|
|
5
|
+
const dictionary = new FFmpegDictionary()
|
|
6
|
+
|
|
7
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
8
|
+
dictionary.set(key, value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return dictionary
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
constructor() {
|
|
5
15
|
this._handle = binding.initDictionary()
|
|
6
16
|
}
|
package/lib/frame.js
CHANGED
|
@@ -32,14 +32,6 @@ module.exports = class FFmpegFrame {
|
|
|
32
32
|
binding.setFrameHeight(this._handle, value)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
get pixelFormat() {
|
|
36
|
-
return binding.getFramePixelFormat(this._handle)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
set pixelFormat(value) {
|
|
40
|
-
binding.setFramePixelFormat(this._handle, value)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
35
|
get format() {
|
|
44
36
|
return binding.getFrameFormat(this._handle)
|
|
45
37
|
}
|
|
@@ -109,7 +101,6 @@ module.exports = class FFmpegFrame {
|
|
|
109
101
|
__proto__: { constructor: FFmpegFrame },
|
|
110
102
|
width: this.width,
|
|
111
103
|
height: this.height,
|
|
112
|
-
pixelFormat: this.pixelFormat,
|
|
113
104
|
format: this.format,
|
|
114
105
|
channelLayout: this.channelLayout,
|
|
115
106
|
nbSamples: this.nbSamples,
|
package/lib/io-context.js
CHANGED
|
@@ -16,15 +16,14 @@ module.exports = class FFmpegIOContext {
|
|
|
16
16
|
buffer = Buffer.alloc(0)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this._handle = binding.initIOContext(buffer, offset, len, onwrite)
|
|
19
|
+
this._handle = binding.initIOContext(
|
|
20
|
+
buffer,
|
|
21
|
+
offset,
|
|
22
|
+
len,
|
|
23
|
+
opts.onwrite,
|
|
24
|
+
opts.onread,
|
|
25
|
+
opts.onseek
|
|
26
|
+
)
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
destroy() {
|
package/lib/packet.js
CHANGED
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|