@scrypted/libav 1.0.172 → 1.0.173
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/package.json +1 -1
- package/.vscode/launch.json +0 -23
- package/.vscode/settings.json +0 -32
- package/darwin.md +0 -24
- package/src/bsf.cpp +0 -213
- package/src/bsf.h +0 -35
- package/src/build-ffmpeg-darwin.sh +0 -13
- package/src/build-ffmpeg-linux.sh +0 -52
- package/src/build-ffmpeg-msys.sh +0 -41
- package/src/build-ffmpeg-windows.bat +0 -8
- package/src/codeccontext.cpp +0 -602
- package/src/codeccontext.h +0 -50
- package/src/error.cpp +0 -33
- package/src/error.h +0 -19
- package/src/ffmpeg-graphparser.cpp +0 -302
- package/src/filter.cpp +0 -487
- package/src/filter.h +0 -37
- package/src/flags.ts +0 -63
- package/src/formatcontext.cpp +0 -899
- package/src/formatcontext.h +0 -47
- package/src/frame.cpp +0 -667
- package/src/frame.h +0 -55
- package/src/index.ts +0 -356
- package/src/packet.cpp +0 -182
- package/src/packet.h +0 -42
- package/src/pkgconfig/glslang.pc +0 -10
- package/src/profiles.ts +0 -108
- package/src/tsconfig.json +0 -26
- package/tsconfig.json +0 -26
package/src/formatcontext.h
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#include <napi.h>
|
|
2
|
-
extern "C"
|
|
3
|
-
{
|
|
4
|
-
#include <libavcodec/avcodec.h>
|
|
5
|
-
#include <libavformat/avformat.h>
|
|
6
|
-
#include <libavutil/hwcontext.h>
|
|
7
|
-
#include <libavutil/frame.h>
|
|
8
|
-
#include <libavfilter/buffersink.h>
|
|
9
|
-
#include <libavfilter/buffersrc.h>
|
|
10
|
-
#include <libavfilter/avfilter.h>
|
|
11
|
-
#include <libavutil/opt.h>
|
|
12
|
-
#include <libavutil/avutil.h>
|
|
13
|
-
// rtpenc.h header uses a weird restrict keyword
|
|
14
|
-
#ifndef restrict
|
|
15
|
-
#define restrict
|
|
16
|
-
#include <libavformat/rtpenc.h>
|
|
17
|
-
#undef restrict
|
|
18
|
-
#else
|
|
19
|
-
#include <libavformat/rtpenc.h>
|
|
20
|
-
#endif
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
class AVFormatContextObject : public Napi::ObjectWrap<AVFormatContextObject>
|
|
24
|
-
{
|
|
25
|
-
public:
|
|
26
|
-
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
27
|
-
AVFormatContextObject(const Napi::CallbackInfo &info);
|
|
28
|
-
~AVFormatContextObject(); // Explicitly declare the destructor
|
|
29
|
-
static Napi::FunctionReference constructor;
|
|
30
|
-
AVFormatContext *fmt_ctx_;
|
|
31
|
-
Napi::ThreadSafeFunction callbackRef;
|
|
32
|
-
|
|
33
|
-
private:
|
|
34
|
-
Napi::Value Open(const Napi::CallbackInfo &info);
|
|
35
|
-
Napi::Value Close(const Napi::CallbackInfo &info);
|
|
36
|
-
Napi::Value CreateDecoder(const Napi::CallbackInfo &info);
|
|
37
|
-
Napi::Value GetMetadata(const Napi::CallbackInfo &info);
|
|
38
|
-
Napi::Value ReadFrame(const Napi::CallbackInfo &info);
|
|
39
|
-
Napi::Value ReceiveFrame(const Napi::CallbackInfo &info);
|
|
40
|
-
Napi::Value Create(const Napi::CallbackInfo &info);
|
|
41
|
-
Napi::Value NewStream(const Napi::CallbackInfo &info);
|
|
42
|
-
Napi::Value WriteFrame(const Napi::CallbackInfo &info);
|
|
43
|
-
Napi::Value GetStreams(const Napi::CallbackInfo &info);
|
|
44
|
-
Napi::Value CreateSDP(const Napi::CallbackInfo &info);
|
|
45
|
-
|
|
46
|
-
bool is_input;
|
|
47
|
-
};
|
package/src/frame.cpp
DELETED
|
@@ -1,667 +0,0 @@
|
|
|
1
|
-
#include <napi.h>
|
|
2
|
-
extern "C"
|
|
3
|
-
{
|
|
4
|
-
#include <libavutil/frame.h>
|
|
5
|
-
#include <libavutil/pixdesc.h>
|
|
6
|
-
#include <libavcodec/avcodec.h>
|
|
7
|
-
#include <libavformat/avformat.h>
|
|
8
|
-
#include <libavformat/avformat.h>
|
|
9
|
-
#include <libavutil/hwcontext.h>
|
|
10
|
-
#include <libavutil/frame.h>
|
|
11
|
-
#include <libavfilter/buffersink.h>
|
|
12
|
-
#include <libavfilter/buffersrc.h>
|
|
13
|
-
#include <libavfilter/avfilter.h>
|
|
14
|
-
#include <libavutil/opt.h>
|
|
15
|
-
#include <libavutil/imgutils.h>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
#include "error.h"
|
|
19
|
-
#include "codeccontext.h"
|
|
20
|
-
#include "frame.h"
|
|
21
|
-
#include "filter.h"
|
|
22
|
-
|
|
23
|
-
Napi::FunctionReference AVFrameObject::constructor;
|
|
24
|
-
|
|
25
|
-
Napi::Object AVFrameObject::Init(Napi::Env env, Napi::Object exports)
|
|
26
|
-
{
|
|
27
|
-
Napi::HandleScope scope(env);
|
|
28
|
-
|
|
29
|
-
Napi::Function func = DefineClass(env, "AVFrameObject", {
|
|
30
|
-
|
|
31
|
-
AVFrameObject::InstanceAccessor("width", &AVFrameObject::GetWidth, nullptr),
|
|
32
|
-
|
|
33
|
-
AVFrameObject::InstanceAccessor("height", &AVFrameObject::GetHeight, nullptr),
|
|
34
|
-
|
|
35
|
-
AVFrameObject::InstanceAccessor("pixelFormat", &AVFrameObject::GetPixelFormat, nullptr),
|
|
36
|
-
|
|
37
|
-
AVFrameObject::InstanceAccessor("timeBaseNum", &AVFrameObject::GetTimeBaseNum, &AVFrameObject::SetTimeBaseNum),
|
|
38
|
-
|
|
39
|
-
AVFrameObject::InstanceAccessor("timeBaseDen", &AVFrameObject::GetTimeBaseDen, &AVFrameObject::SetTimeBaseDen),
|
|
40
|
-
|
|
41
|
-
AVFrameObject::InstanceAccessor("pts", &AVFrameObject::GetPTS, &AVFrameObject::SetPTS),
|
|
42
|
-
|
|
43
|
-
AVFrameObject::InstanceAccessor("dts", &AVFrameObject::GetDTS, &AVFrameObject::SetDTS),
|
|
44
|
-
|
|
45
|
-
AVFrameObject::InstanceAccessor("hardwareDeviceType", &AVFrameObject::GetHardware, NULL),
|
|
46
|
-
|
|
47
|
-
AVFrameObject::InstanceAccessor("softwareFormat", &AVFrameObject::GetSoftware, NULL),
|
|
48
|
-
|
|
49
|
-
AVFrameObject::InstanceAccessor("flags", &AVFrameObject::GetFlags, &AVFrameObject::SetFlags),
|
|
50
|
-
|
|
51
|
-
AVFrameObject::InstanceAccessor("pictType", &AVFrameObject::GetPictType, &AVFrameObject::SetPictType),
|
|
52
|
-
|
|
53
|
-
InstanceMethod(Napi::Symbol::WellKnown(env, "dispose"), &AVFrameObject::Destroy),
|
|
54
|
-
|
|
55
|
-
InstanceMethod("destroy", &AVFrameObject::Destroy),
|
|
56
|
-
|
|
57
|
-
InstanceMethod("toBuffer", &AVFrameObject::ToBuffer),
|
|
58
|
-
|
|
59
|
-
InstanceMethod("fromBuffer", &AVFrameObject::FromBuffer),
|
|
60
|
-
|
|
61
|
-
InstanceMethod("createEncoder", &AVFrameObject::CreateEncoder),
|
|
62
|
-
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
constructor = Napi::Persistent(func);
|
|
66
|
-
constructor.SuppressDestruct();
|
|
67
|
-
|
|
68
|
-
exports.Set("AVFrame", func);
|
|
69
|
-
return exports;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Factory method to create an instance from C++
|
|
73
|
-
Napi::Object AVFrameObject::NewInstance(Napi::Env env, AVFrame *frame)
|
|
74
|
-
{
|
|
75
|
-
Napi::Object obj = constructor.New({});
|
|
76
|
-
AVFrameObject *wrapper = Napi::ObjectWrap<AVFrameObject>::Unwrap(obj);
|
|
77
|
-
wrapper->frame_ = frame;
|
|
78
|
-
return obj;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
AVFrameObject::AVFrameObject(const Napi::CallbackInfo &info)
|
|
82
|
-
: Napi::ObjectWrap<AVFrameObject>(info), frame_(nullptr)
|
|
83
|
-
{
|
|
84
|
-
if (info.Length())
|
|
85
|
-
{
|
|
86
|
-
if (info.Length() < 3)
|
|
87
|
-
{
|
|
88
|
-
Napi::TypeError::New(info.Env(), "Expected 3 arguments: width, height, pixelFormat").ThrowAsJavaScriptException();
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!info[0].IsNumber())
|
|
93
|
-
{
|
|
94
|
-
Napi::TypeError::New(info.Env(), "Number expected for width").ThrowAsJavaScriptException();
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
int width = info[0].As<Napi::Number>().Int32Value();
|
|
98
|
-
|
|
99
|
-
if (!info[1].IsNumber())
|
|
100
|
-
{
|
|
101
|
-
Napi::TypeError::New(info.Env(), "Number expected for height").ThrowAsJavaScriptException();
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
int height = info[1].As<Napi::Number>().Int32Value();
|
|
106
|
-
|
|
107
|
-
if (!info[2].IsString())
|
|
108
|
-
{
|
|
109
|
-
Napi::TypeError::New(info.Env(), "String expected for pixel format").ThrowAsJavaScriptException();
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
bool fillBlack = true;
|
|
114
|
-
if (info.Length() > 3 && info[3].IsBoolean())
|
|
115
|
-
{
|
|
116
|
-
fillBlack = info[3].As<Napi::Boolean>().Value();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
std::string pixelFormat = info[2].As<Napi::String>().Utf8Value();
|
|
120
|
-
AVPixelFormat format = av_get_pix_fmt(pixelFormat.c_str());
|
|
121
|
-
if (format == AV_PIX_FMT_NONE)
|
|
122
|
-
{
|
|
123
|
-
Napi::Error::New(info.Env(), "Invalid pixel format").ThrowAsJavaScriptException();
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// construct frame
|
|
128
|
-
frame_ = av_frame_alloc();
|
|
129
|
-
if (!frame_)
|
|
130
|
-
{
|
|
131
|
-
Napi::Error::New(info.Env(), "Could not allocate frame").ThrowAsJavaScriptException();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
frame_->width = width;
|
|
136
|
-
frame_->height = height;
|
|
137
|
-
frame_->format = format;
|
|
138
|
-
|
|
139
|
-
int ret = av_frame_get_buffer(frame_, 0);
|
|
140
|
-
if (ret < 0)
|
|
141
|
-
{
|
|
142
|
-
av_frame_free(&frame_);
|
|
143
|
-
Napi::Error::New(info.Env(), AVErrorString(ret)).ThrowAsJavaScriptException();
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (fillBlack)
|
|
147
|
-
{
|
|
148
|
-
ptrdiff_t linesizes[AV_NUM_DATA_POINTERS];
|
|
149
|
-
for (int i = 0; i < AV_NUM_DATA_POINTERS; i++)
|
|
150
|
-
{
|
|
151
|
-
linesizes[i] = (ptrdiff_t)frame_->linesize[i];
|
|
152
|
-
}
|
|
153
|
-
av_image_fill_black(frame_->data, linesizes, format, frame_->color_range, frame_->width, frame_->height);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
AVFrameObject::~AVFrameObject()
|
|
159
|
-
{
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
Napi::Value AVFrameObject::CreateEncoder(const Napi::CallbackInfo &info)
|
|
163
|
-
{
|
|
164
|
-
Napi::Env env = info.Env();
|
|
165
|
-
|
|
166
|
-
if (info.Length() < 1 || !info[0].IsObject())
|
|
167
|
-
{
|
|
168
|
-
Napi::TypeError::New(env, "Object expected for argument 0: options").ThrowAsJavaScriptException();
|
|
169
|
-
return env.Undefined();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (!frame_)
|
|
173
|
-
{
|
|
174
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
175
|
-
return env.Undefined();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
Napi::Object options = info[0].As<Napi::Object>();
|
|
179
|
-
Napi::Value codecNameValue = options.Get("encoder");
|
|
180
|
-
|
|
181
|
-
if (!codecNameValue.IsString())
|
|
182
|
-
{
|
|
183
|
-
Napi::TypeError::New(env, "String expected for encoder").ThrowAsJavaScriptException();
|
|
184
|
-
return env.Undefined();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const AVCodec *codec = avcodec_find_encoder_by_name(codecNameValue.As<Napi::String>().Utf8Value().c_str());
|
|
188
|
-
|
|
189
|
-
if (!codec)
|
|
190
|
-
{
|
|
191
|
-
Napi::Error::New(env, "Failed to find encoder").ThrowAsJavaScriptException();
|
|
192
|
-
return env.Undefined();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
Napi::Value bitrate = options.Get("bitrate");
|
|
196
|
-
if (!bitrate.IsNumber())
|
|
197
|
-
{
|
|
198
|
-
Napi::TypeError::New(env, "Number expected for bitrate").ThrowAsJavaScriptException();
|
|
199
|
-
return env.Undefined();
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
Napi::Value timebaseValue = options.Get("timeBase");
|
|
203
|
-
if (!timebaseValue.IsObject())
|
|
204
|
-
{
|
|
205
|
-
Napi::TypeError::New(env, "Object expected for timeBase").ThrowAsJavaScriptException();
|
|
206
|
-
return env.Undefined();
|
|
207
|
-
}
|
|
208
|
-
Napi::Object timebaseObject = timebaseValue.As<Napi::Object>();
|
|
209
|
-
// validate the timebase object
|
|
210
|
-
if (!timebaseObject.Has("timeBaseNum") || !timebaseObject.Get("timeBaseNum").IsNumber() ||
|
|
211
|
-
!timebaseObject.Has("timeBaseDen") || !timebaseObject.Get("timeBaseDen").IsNumber())
|
|
212
|
-
{
|
|
213
|
-
Napi::TypeError::New(env, "invalid object for timeBase").ThrowAsJavaScriptException();
|
|
214
|
-
return env.Undefined();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
int timeBaseNum = timebaseObject.Get("timeBaseNum").As<Napi::Number>().Int32Value();
|
|
218
|
-
int timeBaseDen = timebaseObject.Get("timeBaseDen").As<Napi::Number>().Int32Value();
|
|
219
|
-
|
|
220
|
-
AVCodecContext *c = avcodec_alloc_context3(codec);
|
|
221
|
-
if (!c)
|
|
222
|
-
{
|
|
223
|
-
Napi::Error::New(env, "Failed to allocate codec context").ThrowAsJavaScriptException();
|
|
224
|
-
return env.Undefined();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
c->bit_rate = bitrate.As<Napi::Number>().Int32Value();
|
|
228
|
-
Napi::Value maxRateValue = options.Get("maxRate");
|
|
229
|
-
if (maxRateValue.IsNumber())
|
|
230
|
-
{
|
|
231
|
-
c->rc_max_rate = maxRateValue.As<Napi::Number>().Int32Value();
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
c->rc_max_rate = c->bit_rate;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
Napi::Value minRateValue = options.Get("minRate");
|
|
238
|
-
if (minRateValue.IsNumber())
|
|
239
|
-
{
|
|
240
|
-
c->rc_min_rate = minRateValue.As<Napi::Number>().Int32Value();
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
c->rc_min_rate = c->bit_rate;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
Napi::Value bufSizeValue = options.Get("bufSize");
|
|
247
|
-
if (bufSizeValue.IsNumber())
|
|
248
|
-
{
|
|
249
|
-
c->rc_buffer_size = bufSizeValue.As<Napi::Number>().Int32Value();
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
c->rc_buffer_size = c->bit_rate * 2;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
c->width = frame_->width;
|
|
256
|
-
c->height = frame_->height;
|
|
257
|
-
c->pix_fmt = (enum AVPixelFormat)frame_->format;
|
|
258
|
-
c->time_base.num = timeBaseNum;
|
|
259
|
-
c->time_base.den = timeBaseDen;
|
|
260
|
-
|
|
261
|
-
Napi::Value flagsValue = options.Get("flags");
|
|
262
|
-
if (flagsValue.IsNumber())
|
|
263
|
-
{
|
|
264
|
-
c->flags = flagsValue.As<Napi::Number>().Int32Value();
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
Napi::Value framerateValue = options.Get("framerate");
|
|
268
|
-
if (framerateValue.IsObject())
|
|
269
|
-
{
|
|
270
|
-
Napi::Object framerateObject = framerateValue.As<Napi::Object>();
|
|
271
|
-
if (framerateObject.Has("timeBaseNum") && framerateObject.Get("timeBaseNum").IsNumber() &&
|
|
272
|
-
framerateObject.Has("timeBaseDen") && framerateObject.Get("timeBaseDen").IsNumber())
|
|
273
|
-
{
|
|
274
|
-
c->framerate.num = framerateObject.Get("timeBaseNum").As<Napi::Number>().Int32Value();
|
|
275
|
-
c->framerate.den = framerateObject.Get("timeBaseDen").As<Napi::Number>().Int32Value();
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
c->max_b_frames = 0;
|
|
280
|
-
|
|
281
|
-
Napi::Value profileValue = options.Get("profile");
|
|
282
|
-
// if number, set it
|
|
283
|
-
if (profileValue.IsNumber())
|
|
284
|
-
{
|
|
285
|
-
c->profile = profileValue.As<Napi::Number>().Int32Value();
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
Napi::Value gopSizeValue = options.Get("gopSize");
|
|
289
|
-
if (gopSizeValue.IsNumber()) {
|
|
290
|
-
c->gop_size = gopSizeValue.As<Napi::Number>().Int32Value();
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
Napi::Value keyintMinValue = options.Get("keyIntMin");
|
|
294
|
-
if (keyintMinValue.IsNumber()) {
|
|
295
|
-
c->keyint_min = keyintMinValue.As<Napi::Number>().Int32Value();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
Napi::Value opts = options.Get("opts");
|
|
300
|
-
if (opts.IsObject())
|
|
301
|
-
{
|
|
302
|
-
Napi::Object optsObj = opts.As<Napi::Object>();
|
|
303
|
-
Napi::Array keys = optsObj.GetPropertyNames();
|
|
304
|
-
for (size_t i = 0; i < keys.Length(); i++)
|
|
305
|
-
{
|
|
306
|
-
Napi::String key = keys.Get(i).As<Napi::String>();
|
|
307
|
-
Napi::Value value = optsObj.Get(key);
|
|
308
|
-
if (value.IsString())
|
|
309
|
-
{
|
|
310
|
-
av_opt_set(c->priv_data, key.Utf8Value().c_str(), value.As<Napi::String>().Utf8Value().c_str(), 0);
|
|
311
|
-
}
|
|
312
|
-
else if (value.IsNumber())
|
|
313
|
-
{
|
|
314
|
-
av_opt_set_int(c->priv_data, key.Utf8Value().c_str(), value.As<Napi::Number>().Int32Value(), 0);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (frame_->hw_frames_ctx)
|
|
320
|
-
{
|
|
321
|
-
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)(frame_->hw_frames_ctx->data);
|
|
322
|
-
AVBufferRef *hw_device_ctx = frames_ctx->device_ref;
|
|
323
|
-
c->hw_frames_ctx = av_buffer_ref(frame_->hw_frames_ctx);
|
|
324
|
-
if (hw_device_ctx)
|
|
325
|
-
{
|
|
326
|
-
c->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
int ret;
|
|
331
|
-
if ((ret = avcodec_open2(c, codec, NULL)) < 0)
|
|
332
|
-
{
|
|
333
|
-
avcodec_free_context(&c);
|
|
334
|
-
Napi::Error::New(env, AVErrorString(ret)).ThrowAsJavaScriptException();
|
|
335
|
-
return env.Undefined();
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
Napi::Value codecContextObject = AVCodecContextObject::NewInstance(env);
|
|
339
|
-
AVCodecContextObject *codecContextWrapper = Napi::ObjectWrap<AVCodecContextObject>::Unwrap(codecContextObject.As<Napi::Object>());
|
|
340
|
-
codecContextWrapper->codecContext = c;
|
|
341
|
-
return codecContextObject;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
Napi::Value AVFrameObject::FromBuffer(const Napi::CallbackInfo &info)
|
|
345
|
-
{
|
|
346
|
-
Napi::Env env = info.Env();
|
|
347
|
-
if (!frame_)
|
|
348
|
-
{
|
|
349
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
350
|
-
return env.Undefined();
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (frame_->hw_frames_ctx)
|
|
354
|
-
{
|
|
355
|
-
return env.Undefined();
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (!frame_->data[0])
|
|
359
|
-
{
|
|
360
|
-
Napi::Error::New(env, "Frame data is null").ThrowAsJavaScriptException();
|
|
361
|
-
return env.Undefined();
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (info.Length() < 1 || !info[0].IsBuffer())
|
|
365
|
-
{
|
|
366
|
-
Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
|
|
367
|
-
return env.Undefined();
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
Napi::Buffer<uint8_t> buffer = info[0].As<Napi::Buffer<uint8_t>>();
|
|
371
|
-
if ((int)buffer.Length() != av_image_get_buffer_size((enum AVPixelFormat)frame_->format, frame_->width, frame_->height, 1))
|
|
372
|
-
{
|
|
373
|
-
Napi::Error::New(env, "Buffer size does not match frame size").ThrowAsJavaScriptException();
|
|
374
|
-
return env.Undefined();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
int ret = av_image_fill_arrays(frame_->data, frame_->linesize, buffer.Data(), (enum AVPixelFormat)frame_->format, frame_->width, frame_->height, 1);
|
|
378
|
-
if (ret < 0)
|
|
379
|
-
{
|
|
380
|
-
Napi::Error::New(env, AVErrorString(ret)).ThrowAsJavaScriptException();
|
|
381
|
-
return env.Undefined();
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return env.Undefined();
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
Napi::Value AVFrameObject::ToBuffer(const Napi::CallbackInfo &info)
|
|
388
|
-
{
|
|
389
|
-
Napi::Env env = info.Env();
|
|
390
|
-
if (!frame_)
|
|
391
|
-
{
|
|
392
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
393
|
-
return env.Undefined();
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
if (frame_->hw_frames_ctx)
|
|
397
|
-
{
|
|
398
|
-
return env.Undefined();
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (!frame_->data[0])
|
|
402
|
-
{
|
|
403
|
-
Napi::Error::New(env, "Frame data is null").ThrowAsJavaScriptException();
|
|
404
|
-
return env.Undefined();
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// Calculate the required buffer size
|
|
408
|
-
int width = frame_->width;
|
|
409
|
-
int height = frame_->height;
|
|
410
|
-
int buffer_size = av_image_get_buffer_size((enum AVPixelFormat)frame_->format, width, height, 1);
|
|
411
|
-
|
|
412
|
-
Napi::Buffer<uint8_t> buffer = Napi::Buffer<uint8_t>::New(env, buffer_size);
|
|
413
|
-
|
|
414
|
-
uint8_t *byte_array = buffer.Data();
|
|
415
|
-
if (!byte_array)
|
|
416
|
-
{
|
|
417
|
-
Napi::Error::New(env, "Failed to allocate memory for byte array").ThrowAsJavaScriptException();
|
|
418
|
-
return env.Undefined();
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
int ret = av_image_copy_to_buffer(byte_array, buffer_size, (const uint8_t *const *)frame_->data, frame_->linesize, (enum AVPixelFormat)frame_->format, width, height, 1);
|
|
422
|
-
if (ret < 0)
|
|
423
|
-
{
|
|
424
|
-
Napi::Error::New(env, AVErrorString(ret)).ThrowAsJavaScriptException();
|
|
425
|
-
return env.Undefined();
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
return buffer;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
Napi::Value AVFrameObject::Destroy(const Napi::CallbackInfo &info)
|
|
432
|
-
{
|
|
433
|
-
if (frame_)
|
|
434
|
-
{
|
|
435
|
-
av_frame_free(&frame_);
|
|
436
|
-
frame_ = nullptr;
|
|
437
|
-
}
|
|
438
|
-
return info.Env().Undefined();
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
Napi::Value AVFrameObject::GetWidth(const Napi::CallbackInfo &info)
|
|
442
|
-
{
|
|
443
|
-
Napi::Env env = info.Env();
|
|
444
|
-
if (!frame_)
|
|
445
|
-
{
|
|
446
|
-
return env.Undefined();
|
|
447
|
-
}
|
|
448
|
-
return Napi::Number::New(env, frame_->width);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
Napi::Value AVFrameObject::GetHeight(const Napi::CallbackInfo &info)
|
|
452
|
-
{
|
|
453
|
-
Napi::Env env = info.Env();
|
|
454
|
-
if (!frame_)
|
|
455
|
-
{
|
|
456
|
-
return env.Undefined();
|
|
457
|
-
}
|
|
458
|
-
return Napi::Number::New(env, frame_->height);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
Napi::Value AVFrameObject::GetPixelFormat(const Napi::CallbackInfo &info)
|
|
462
|
-
{
|
|
463
|
-
Napi::Env env = info.Env();
|
|
464
|
-
if (!frame_)
|
|
465
|
-
{
|
|
466
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
467
|
-
return env.Undefined();
|
|
468
|
-
}
|
|
469
|
-
enum AVPixelFormat pix_fmt = (enum AVPixelFormat)frame_->format;
|
|
470
|
-
const char *format = av_get_pix_fmt_name(pix_fmt);
|
|
471
|
-
return Napi::String::New(env, format);
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
Napi::Value AVFrameObject::GetTimeBaseNum(const Napi::CallbackInfo &info)
|
|
475
|
-
{
|
|
476
|
-
Napi::Env env = info.Env();
|
|
477
|
-
if (!frame_)
|
|
478
|
-
{
|
|
479
|
-
return env.Undefined();
|
|
480
|
-
}
|
|
481
|
-
return Napi::Number::New(env, frame_->time_base.num);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
void AVFrameObject::SetTimeBaseNum(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
485
|
-
{
|
|
486
|
-
Napi::Env env = info.Env();
|
|
487
|
-
if (!frame_)
|
|
488
|
-
{
|
|
489
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
if (!value.IsNumber())
|
|
493
|
-
{
|
|
494
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
frame_->time_base.num = value.As<Napi::Number>().Int32Value();
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
void AVFrameObject::SetTimeBaseDen(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
501
|
-
{
|
|
502
|
-
Napi::Env env = info.Env();
|
|
503
|
-
if (!frame_)
|
|
504
|
-
{
|
|
505
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
if (!value.IsNumber())
|
|
509
|
-
{
|
|
510
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
513
|
-
frame_->time_base.den = value.As<Napi::Number>().Int32Value();
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
Napi::Value AVFrameObject::GetTimeBaseDen(const Napi::CallbackInfo &info)
|
|
517
|
-
{
|
|
518
|
-
Napi::Env env = info.Env();
|
|
519
|
-
if (!frame_)
|
|
520
|
-
{
|
|
521
|
-
return env.Undefined();
|
|
522
|
-
}
|
|
523
|
-
return Napi::Number::New(env, frame_->time_base.den);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
Napi::Value AVFrameObject::GetPTS(const Napi::CallbackInfo &info)
|
|
527
|
-
{
|
|
528
|
-
Napi::Env env = info.Env();
|
|
529
|
-
if (!frame_)
|
|
530
|
-
{
|
|
531
|
-
return env.Undefined();
|
|
532
|
-
}
|
|
533
|
-
return Napi::Number::New(env, frame_->pts);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
void AVFrameObject::SetPTS(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
537
|
-
{
|
|
538
|
-
Napi::Env env = info.Env();
|
|
539
|
-
if (!frame_)
|
|
540
|
-
{
|
|
541
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
542
|
-
return;
|
|
543
|
-
}
|
|
544
|
-
if (!value.IsNumber())
|
|
545
|
-
{
|
|
546
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
frame_->pts = value.As<Napi::Number>().Int64Value();
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
Napi::Value AVFrameObject::GetDTS(const Napi::CallbackInfo &info)
|
|
553
|
-
{
|
|
554
|
-
Napi::Env env = info.Env();
|
|
555
|
-
if (!frame_)
|
|
556
|
-
{
|
|
557
|
-
return env.Undefined();
|
|
558
|
-
}
|
|
559
|
-
return Napi::Number::New(env, frame_->pkt_dts);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
void AVFrameObject::SetDTS(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
563
|
-
{
|
|
564
|
-
Napi::Env env = info.Env();
|
|
565
|
-
if (!frame_)
|
|
566
|
-
{
|
|
567
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
568
|
-
return;
|
|
569
|
-
}
|
|
570
|
-
if (!value.IsNumber())
|
|
571
|
-
{
|
|
572
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
frame_->pkt_dts = value.As<Napi::Number>().Int64Value();
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
Napi::Value AVFrameObject::GetHardware(const Napi::CallbackInfo &info)
|
|
579
|
-
{
|
|
580
|
-
Napi::Env env = info.Env();
|
|
581
|
-
if (!frame_)
|
|
582
|
-
{
|
|
583
|
-
return env.Undefined();
|
|
584
|
-
}
|
|
585
|
-
if (frame_->hw_frames_ctx)
|
|
586
|
-
{
|
|
587
|
-
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)(frame_->hw_frames_ctx->data);
|
|
588
|
-
AVBufferRef *hw_device_ctx = frames_ctx->device_ref;
|
|
589
|
-
if (hw_device_ctx)
|
|
590
|
-
{
|
|
591
|
-
AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)(hw_device_ctx->data);
|
|
592
|
-
// type to string
|
|
593
|
-
std::string type = av_hwdevice_get_type_name(device_ctx->type);
|
|
594
|
-
return Napi::String::New(env, type.c_str());
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
return env.Null();
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
Napi::Value AVFrameObject::GetSoftware(const Napi::CallbackInfo &info)
|
|
601
|
-
{
|
|
602
|
-
Napi::Env env = info.Env();
|
|
603
|
-
if (!frame_)
|
|
604
|
-
{
|
|
605
|
-
return env.Undefined();
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
if (frame_->hw_frames_ctx)
|
|
609
|
-
{
|
|
610
|
-
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)(frame_->hw_frames_ctx->data);
|
|
611
|
-
std::string format = av_get_pix_fmt_name(frames_ctx->sw_format);
|
|
612
|
-
return Napi::String::New(env, format.c_str());
|
|
613
|
-
}
|
|
614
|
-
return env.Null();
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
Napi::Value AVFrameObject::GetFlags(const Napi::CallbackInfo &info)
|
|
618
|
-
{
|
|
619
|
-
Napi::Env env = info.Env();
|
|
620
|
-
if (!frame_)
|
|
621
|
-
{
|
|
622
|
-
return env.Undefined();
|
|
623
|
-
}
|
|
624
|
-
return Napi::Number::New(env, frame_->flags);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
void AVFrameObject::SetFlags(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
628
|
-
{
|
|
629
|
-
Napi::Env env = info.Env();
|
|
630
|
-
if (!frame_)
|
|
631
|
-
{
|
|
632
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
if (!value.IsNumber())
|
|
636
|
-
{
|
|
637
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
frame_->flags = value.As<Napi::Number>().Int32Value();
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
Napi::Value AVFrameObject::GetPictType(const Napi::CallbackInfo &info)
|
|
644
|
-
{
|
|
645
|
-
Napi::Env env = info.Env();
|
|
646
|
-
if (!frame_)
|
|
647
|
-
{
|
|
648
|
-
return env.Undefined();
|
|
649
|
-
}
|
|
650
|
-
return Napi::Number::New(env, frame_->pict_type);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
void AVFrameObject::SetPictType(const Napi::CallbackInfo &info, const Napi::Value &value)
|
|
654
|
-
{
|
|
655
|
-
Napi::Env env = info.Env();
|
|
656
|
-
if (!frame_)
|
|
657
|
-
{
|
|
658
|
-
Napi::Error::New(env, "Frame object is null").ThrowAsJavaScriptException();
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
if (!value.IsNumber())
|
|
662
|
-
{
|
|
663
|
-
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
frame_->pict_type = (enum AVPictureType)value.As<Napi::Number>().Int32Value();
|
|
667
|
-
}
|