@scrypted/libav 1.0.172 → 1.0.174

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.
@@ -1,602 +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
-
13
- #ifdef __linux__
14
- #include <libavutil/hwcontext_vaapi.h>
15
- extern const char *vaQueryVendorString(void *dpy);
16
- #endif
17
- }
18
-
19
- #include <thread>
20
- #include <v8.h>
21
-
22
- #include "packet.h"
23
- #include "error.h"
24
- #include "codeccontext.h"
25
- #include "frame.h"
26
-
27
- Napi::FunctionReference AVCodecContextObject::constructor;
28
-
29
- AVCodecContextObject::AVCodecContextObject(const Napi::CallbackInfo &info)
30
- : Napi::ObjectWrap<AVCodecContextObject>(info),
31
- codecContext(nullptr),
32
- hw_device_value(AV_HWDEVICE_TYPE_NONE)
33
- {
34
- // i don't think this constructor is called from js??
35
- }
36
-
37
- AVCodecContextObject::~AVCodecContextObject()
38
- {
39
- }
40
-
41
- Napi::Value AVCodecContextObject::Destroy(const Napi::CallbackInfo &info)
42
- {
43
- if (codecContext)
44
- {
45
- avcodec_free_context(&codecContext);
46
- codecContext = nullptr;
47
- }
48
-
49
- return info.Env().Undefined();
50
- }
51
-
52
- Napi::Object AVCodecContextObject::Init(Napi::Env env, Napi::Object exports)
53
- {
54
- Napi::HandleScope scope(env);
55
-
56
- Napi::Function func = DefineClass(env, "AVCodecContextObject", {
57
-
58
- AVCodecContextObject::InstanceAccessor("hardwareDevice", &AVCodecContextObject::GetHardwareDevice, nullptr),
59
-
60
- AVCodecContextObject::InstanceAccessor("pixelFormat", &AVCodecContextObject::GetPixelFormat, nullptr),
61
-
62
- AVCodecContextObject::InstanceAccessor("hardwarePixelFormat", &AVCodecContextObject::GetHardwarePixelFormat, nullptr),
63
-
64
- AVCodecContextObject::InstanceAccessor("timeBaseNum", &AVCodecContextObject::GetTimeBaseNum, nullptr),
65
-
66
- AVCodecContextObject::InstanceAccessor("timeBaseDen", &AVCodecContextObject::GetTimeBaseDen, nullptr),
67
-
68
- AVCodecContextObject::InstanceAccessor("vendorInfo", &AVCodecContextObject::GetVendorInfo, nullptr),
69
-
70
- AVCodecContextObject::InstanceAccessor("keyIntMin", &AVCodecContextObject::GetKeyIntMin, &AVCodecContextObject::SetKeyIntMin),
71
-
72
- AVCodecContextObject::InstanceAccessor("gopSize", &AVCodecContextObject::GetGopSize, &AVCodecContextObject::SetGopSize),
73
-
74
- InstanceMethod(Napi::Symbol::WellKnown(env, "dispose"), &AVCodecContextObject::Destroy),
75
-
76
- InstanceMethod("destroy", &AVCodecContextObject::Destroy),
77
-
78
- InstanceMethod("sendPacket", &AVCodecContextObject::SendPacket),
79
-
80
- InstanceMethod("receiveFrame", &AVCodecContextObject::ReceiveFrame),
81
-
82
- InstanceMethod("sendFrame", &AVCodecContextObject::SendFrame),
83
-
84
- InstanceMethod("receivePacket", &AVCodecContextObject::ReceivePacket),
85
- });
86
-
87
- constructor = Napi::Persistent(func);
88
- constructor.SuppressDestruct();
89
- return exports;
90
- }
91
-
92
- // Factory method to create an instance from C++
93
- Napi::Object AVCodecContextObject::NewInstance(Napi::Env env)
94
-
95
- {
96
- Napi::Object obj = constructor.New({});
97
- AVCodecContextObject *wrapper = Napi::ObjectWrap<AVCodecContextObject>::Unwrap(obj);
98
- wrapper->codecContext = nullptr;
99
- return obj;
100
- }
101
-
102
- class ReceiveFrameWorker : public Napi::AsyncWorker
103
- {
104
- public:
105
- ReceiveFrameWorker(napi_env env, napi_deferred deferred, AVCodecContext *codecContext)
106
- : Napi::AsyncWorker(env), deferred(deferred), codecContext(codecContext)
107
- {
108
- }
109
-
110
- void Execute() override
111
- {
112
- result = nullptr;
113
-
114
- AVFrame *frame = av_frame_alloc();
115
- if (!frame)
116
- {
117
- SetError("Failed to allocate frame");
118
- return;
119
- }
120
-
121
- // EAGAIN will be returned if packets need to be sent to decoder.
122
- int ret = avcodec_receive_frame(codecContext, frame);
123
- if (!ret)
124
- {
125
- result = frame;
126
- return;
127
- }
128
-
129
- av_frame_free(&frame);
130
- if (ret != AVERROR(EAGAIN))
131
- {
132
- SetError(AVErrorString(ret));
133
- }
134
- }
135
-
136
- // This method runs in the main thread after Execute completes successfully
137
- void OnOK() override
138
- {
139
- Napi::Env env = Env();
140
- if (!result)
141
- {
142
- napi_resolve_deferred(Env(), deferred, env.Undefined());
143
- }
144
- else
145
- {
146
- napi_resolve_deferred(Env(), deferred, AVFrameObject::NewInstance(env, result));
147
- }
148
- }
149
-
150
- // This method runs in the main thread if Execute fails
151
- void OnError(const Napi::Error &e) override
152
- {
153
- napi_value error = e.Value();
154
-
155
- // Reject the promise
156
- napi_reject_deferred(Env(), deferred, error);
157
- }
158
-
159
- private:
160
- AVFrame *result;
161
- napi_deferred deferred;
162
- AVCodecContext *codecContext;
163
- };
164
-
165
- class ReceivePacketWorker : public Napi::AsyncWorker
166
- {
167
- public:
168
- ReceivePacketWorker(napi_env env, napi_deferred deferred, AVCodecContext *codecContext)
169
- : Napi::AsyncWorker(env), deferred(deferred), codecContext(codecContext)
170
- {
171
- }
172
-
173
- void Execute() override
174
- {
175
- result = nullptr;
176
-
177
- AVPacket *packet = av_packet_alloc();
178
- if (!packet)
179
- {
180
- SetError("Failed to allocate packet");
181
- return;
182
- }
183
-
184
- // EAGAIN will be returned if frames needs to be sent to encoder
185
- int ret = avcodec_receive_packet(codecContext, packet);
186
- if (!ret)
187
- {
188
- result = packet;
189
- return;
190
- }
191
-
192
- av_packet_free(&packet);
193
- if (ret != AVERROR(EAGAIN))
194
- {
195
- SetError(AVErrorString(ret));
196
- }
197
- }
198
-
199
- // This method runs in the main thread after Execute completes successfully
200
- void OnOK() override
201
- {
202
- Napi::Env env = Env();
203
- if (!result)
204
- {
205
- napi_resolve_deferred(Env(), deferred, env.Undefined());
206
- }
207
- else
208
- {
209
- napi_resolve_deferred(Env(), deferred, AVPacketObject::NewInstance(env, result));
210
- }
211
- }
212
-
213
- // This method runs in the main thread if Execute fails
214
- void OnError(const Napi::Error &e) override
215
- {
216
- napi_value error = e.Value();
217
-
218
- // Reject the promise
219
- napi_reject_deferred(Env(), deferred, error);
220
- }
221
-
222
- private:
223
- AVPacket *result;
224
- napi_deferred deferred;
225
- AVCodecContext *codecContext;
226
- };
227
-
228
- Napi::Value AVCodecContextObject::ReceiveFrame(const Napi::CallbackInfo &info)
229
- {
230
- Napi::Env env = info.Env();
231
- // Create a new promise and get its deferred handle
232
- napi_deferred deferred;
233
- napi_value promise;
234
- napi_create_promise(env, &deferred, &promise);
235
-
236
- // Create and queue the AsyncWorker, passing the deferred handle
237
- ReceiveFrameWorker *worker = new ReceiveFrameWorker(env, deferred, codecContext);
238
- worker->Queue();
239
-
240
- // Return the promise to JavaScript
241
- return Napi::Value(env, promise);
242
- }
243
-
244
- Napi::Value AVCodecContextObject::ReceivePacket(const Napi::CallbackInfo &info)
245
- {
246
- Napi::Env env = info.Env();
247
- // Create a new promise and get its deferred handle
248
- napi_deferred deferred;
249
- napi_value promise;
250
- napi_create_promise(env, &deferred, &promise);
251
-
252
- // Create and queue the AsyncWorker, passing the deferred handle
253
- ReceivePacketWorker *worker = new ReceivePacketWorker(env, deferred, codecContext);
254
- worker->Queue();
255
-
256
- // Return the promise to JavaScript
257
- return Napi::Value(env, promise);
258
- }
259
-
260
- class SendFrameWorker : public Napi::AsyncWorker
261
- {
262
- public:
263
- SendFrameWorker(napi_env env, napi_deferred deferred, AVCodecContext *codecContext, AVFrame *frame)
264
- : Napi::AsyncWorker(env), deferred(deferred), codecContext(codecContext), frame(frame)
265
- {
266
- }
267
-
268
- void Execute() override
269
- {
270
- result = false;
271
-
272
- if (!frame)
273
- {
274
- SetError("SendFrame received null frame");
275
- return;
276
- }
277
- if (!codecContext)
278
- {
279
- SetError("Codec Context is null");
280
- return;
281
- }
282
-
283
- int ret = avcodec_send_frame(codecContext, frame);
284
-
285
- if (!ret)
286
- {
287
- result = true;
288
- return;
289
- }
290
-
291
- if (ret != AVERROR(EAGAIN))
292
- {
293
- // what would cause this?
294
- SetError(AVErrorString(ret));
295
- }
296
- }
297
-
298
- // This method runs in the main thread after Execute completes successfully
299
- void OnOK() override
300
- {
301
- Napi::Env env = Env();
302
- napi_resolve_deferred(env, deferred, Napi::Boolean::New(env, result));
303
- }
304
-
305
- // This method runs in the main thread if Execute fails
306
- void OnError(const Napi::Error &e) override
307
- {
308
- napi_value error = e.Value();
309
-
310
- // Reject the promise
311
- napi_reject_deferred(Env(), deferred, error);
312
- }
313
-
314
- private:
315
- bool result;
316
- napi_deferred deferred;
317
- AVCodecContext *codecContext;
318
- AVFrame *frame;
319
- };
320
-
321
- class SendPacketWorker : public Napi::AsyncWorker
322
- {
323
- public:
324
- SendPacketWorker(napi_env env, napi_deferred deferred, AVCodecContext *codecContext, AVPacket *packet)
325
- : Napi::AsyncWorker(env), deferred(deferred), codecContext(codecContext), packet(packet)
326
- {
327
- }
328
-
329
- void Execute() override
330
- {
331
- result = false;
332
-
333
- if (!packet)
334
- {
335
- SetError("SendPacket received null packet");
336
- return;
337
- }
338
-
339
- int ret = avcodec_send_packet(codecContext, packet);
340
-
341
- if (!ret)
342
- {
343
- result = true;
344
- return;
345
- }
346
-
347
- if (ret != AVERROR(EAGAIN))
348
- {
349
- // errors are typically caused by missing codec info
350
- // or invalid packets, and may resolve on a later packet.
351
- // suppress all errors until a keyframe is sent.
352
- SetError(AVErrorString(ret));
353
- }
354
- }
355
-
356
- // This method runs in the main thread after Execute completes successfully
357
- void OnOK() override
358
- {
359
- Napi::Env env = Env();
360
- napi_resolve_deferred(env, deferred, Napi::Boolean::New(env, result));
361
- }
362
-
363
- // This method runs in the main thread if Execute fails
364
- void OnError(const Napi::Error &e) override
365
- {
366
- napi_value error = e.Value();
367
-
368
- // Reject the promise
369
- napi_reject_deferred(Env(), deferred, error);
370
- }
371
-
372
- private:
373
- bool result;
374
- napi_deferred deferred;
375
- AVCodecContext *codecContext;
376
- AVPacket *packet;
377
- };
378
-
379
- Napi::Value AVCodecContextObject::SendPacket(const Napi::CallbackInfo &info)
380
- {
381
- if (!info.Length())
382
- {
383
- Napi::TypeError::New(info.Env(), "Packet object expected").ThrowAsJavaScriptException();
384
- return info.Env().Undefined();
385
- }
386
-
387
- AVPacketObject *packet = Napi::ObjectWrap<AVPacketObject>::Unwrap(info[0].As<Napi::Object>());
388
-
389
- Napi::Env env = info.Env();
390
- // Create a new promise and get its deferred handle
391
- napi_deferred deferred;
392
- napi_value promise;
393
- napi_create_promise(env, &deferred, &promise);
394
-
395
- // Create and queue the AsyncWorker, passing the deferred handle
396
- SendPacketWorker *worker = new SendPacketWorker(env, deferred, codecContext, packet->packet);
397
- worker->Queue();
398
-
399
- // Return the promise to JavaScript
400
- return Napi::Value(env, promise);
401
- }
402
-
403
- Napi::Value AVCodecContextObject::SendFrame(const Napi::CallbackInfo &info)
404
- {
405
- if (!info.Length() || !info[0].IsObject())
406
- {
407
- Napi::TypeError::New(info.Env(), "Frame object expected").ThrowAsJavaScriptException();
408
- return info.Env().Undefined();
409
- }
410
-
411
- AVFrameObject *frame = Napi::ObjectWrap<AVFrameObject>::Unwrap(info[0].As<Napi::Object>());
412
-
413
- Napi::Env env = info.Env();
414
- // Create a new promise and get its deferred handle
415
- napi_deferred deferred;
416
- napi_value promise;
417
- napi_create_promise(env, &deferred, &promise);
418
-
419
- // Create and queue the AsyncWorker, passing the deferred handle
420
- SendFrameWorker *worker = new SendFrameWorker(env, deferred, codecContext, frame->frame_);
421
- worker->Queue();
422
-
423
- // Return the promise to JavaScript
424
- return Napi::Value(env, promise);
425
- }
426
-
427
- Napi::Value AVCodecContextObject::GetHardwareDevice(const Napi::CallbackInfo &info)
428
- {
429
- Napi::Env env = info.Env();
430
- const char *hardwareDeviceName = av_hwdevice_get_type_name(hw_device_value);
431
- if (hw_device_value == AV_HWDEVICE_TYPE_NONE || !hardwareDeviceName)
432
- {
433
- return info.Env().Undefined();
434
- }
435
- return Napi::String::New(env, hardwareDeviceName);
436
- }
437
-
438
- Napi::Value AVCodecContextObject::GetPixelFormat(const Napi::CallbackInfo &info)
439
- {
440
- Napi::Env env = info.Env();
441
-
442
- if (!codecContext)
443
- {
444
- return env.Undefined();
445
- }
446
-
447
- const char *name = av_get_pix_fmt_name(codecContext->pix_fmt);
448
- if (!name)
449
- {
450
- return env.Undefined();
451
- }
452
- return Napi::String::New(env, name);
453
- }
454
-
455
- Napi::Value AVCodecContextObject::GetHardwarePixelFormat(const Napi::CallbackInfo &info)
456
- {
457
- Napi::Env env = info.Env();
458
-
459
- if (!codecContext)
460
- {
461
- return env.Undefined();
462
- }
463
-
464
- const char *name = av_get_pix_fmt_name(hw_pix_fmt);
465
- if (!name)
466
- {
467
- return env.Undefined();
468
- }
469
- return Napi::String::New(env, name);
470
- }
471
-
472
- Napi::Value AVCodecContextObject::GetTimeBaseNum(const Napi::CallbackInfo &info)
473
- {
474
- Napi::Env env = info.Env();
475
-
476
- if (!codecContext)
477
- {
478
- return env.Undefined();
479
- }
480
-
481
- return Napi::Number::New(env, codecContext->time_base.num);
482
- }
483
-
484
- Napi::Value AVCodecContextObject::GetTimeBaseDen(const Napi::CallbackInfo &info)
485
- {
486
- Napi::Env env = info.Env();
487
-
488
- if (!codecContext)
489
- {
490
- return env.Undefined();
491
- }
492
-
493
- return Napi::Number::New(env, codecContext->time_base.den);
494
- }
495
-
496
- Napi::Value AVCodecContextObject::GetVendorInfo(const Napi::CallbackInfo &info)
497
- {
498
- Napi::Env env = info.Env();
499
-
500
- // compiler check for linux x64 to query vaapi
501
- #ifndef __x86_64__
502
- return env.Undefined();
503
- #endif
504
- #ifndef __linux__
505
- return env.Undefined();
506
- #else
507
-
508
- if (!codecContext)
509
- {
510
- return env.Undefined();
511
- }
512
-
513
- const char *name = av_get_pix_fmt_name(hw_pix_fmt);
514
- if (strcmp(name, "vaapi"))
515
- {
516
- return env.Undefined();
517
- }
518
-
519
- if (!codecContext->hw_device_ctx || !codecContext->hw_device_ctx->data)
520
- {
521
- return env.Undefined();
522
- }
523
- AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)codecContext->hw_device_ctx->data;
524
-
525
- AVVAAPIDeviceContext *vaapi_device_ctx = (AVVAAPIDeviceContext *)hw_device_ctx->hwctx;
526
- if (!vaapi_device_ctx)
527
- {
528
- return env.Undefined();
529
- }
530
-
531
- void *display = vaapi_device_ctx->display;
532
- const char *driver = vaQueryVendorString(display);
533
- if (!driver)
534
- {
535
- return env.Undefined();
536
- }
537
-
538
- Napi::Object obj = Napi::Object::New(env);
539
- obj.Set("driver", Napi::String::New(env, driver));
540
- return obj;
541
- #endif
542
- }
543
-
544
- Napi::Value AVCodecContextObject::GetKeyIntMin(const Napi::CallbackInfo &info)
545
- {
546
- Napi::Env env = info.Env();
547
-
548
- if (!codecContext)
549
- {
550
- return env.Undefined();
551
- }
552
-
553
- return Napi::Number::New(env, codecContext->keyint_min);
554
- }
555
-
556
- void AVCodecContextObject::SetKeyIntMin(const Napi::CallbackInfo &info, const Napi::Value &value)
557
- {
558
- Napi::Env env = info.Env();
559
-
560
- if (!codecContext)
561
- {
562
- return;
563
- }
564
-
565
- if (!value.IsNumber())
566
- {
567
- Napi::TypeError::New(env, "keyIntMin must be a number").ThrowAsJavaScriptException();
568
- return;
569
- }
570
-
571
- codecContext->keyint_min = value.As<Napi::Number>().Int32Value();
572
- }
573
-
574
- Napi::Value AVCodecContextObject::GetGopSize(const Napi::CallbackInfo &info)
575
- {
576
- Napi::Env env = info.Env();
577
-
578
- if (!codecContext)
579
- {
580
- return env.Undefined();
581
- }
582
-
583
- return Napi::Number::New(env, codecContext->gop_size);
584
- }
585
-
586
- void AVCodecContextObject::SetGopSize(const Napi::CallbackInfo &info, const Napi::Value &value)
587
- {
588
- Napi::Env env = info.Env();
589
-
590
- if (!codecContext)
591
- {
592
- return;
593
- }
594
-
595
- if (!value.IsNumber())
596
- {
597
- Napi::TypeError::New(env, "gopSize must be a number").ThrowAsJavaScriptException();
598
- return;
599
- }
600
-
601
- codecContext->gop_size = value.As<Napi::Number>().Int32Value();
602
- }
@@ -1,50 +0,0 @@
1
- #pragma once
2
-
3
- #include <napi.h>
4
- extern "C"
5
- {
6
- #include <libavcodec/avcodec.h>
7
- #include <libavformat/avformat.h>
8
- #include <libavutil/hwcontext.h>
9
- #include <libavutil/frame.h>
10
- #include <libavfilter/buffersink.h>
11
- #include <libavfilter/buffersrc.h>
12
- #include <libavfilter/avfilter.h>
13
- #include <libavutil/opt.h>
14
- }
15
-
16
- #include <thread>
17
- #include <v8.h>
18
-
19
- class AVCodecContextObject : public Napi::ObjectWrap<AVCodecContextObject>
20
- {
21
- public:
22
- static Napi::Object Init(Napi::Env env, Napi::Object exports);
23
- static Napi::Object NewInstance(Napi::Env env);
24
- static Napi::FunctionReference constructor;
25
-
26
- AVCodecContextObject(const Napi::CallbackInfo &info);
27
- ~AVCodecContextObject(); // Explicitly declare the destructor
28
-
29
- enum AVPixelFormat hw_pix_fmt;
30
- int videoStreamIndex;
31
- AVCodecContext *codecContext;
32
- enum AVHWDeviceType hw_device_value;
33
-
34
- private:
35
- Napi::Value GetKeyIntMin(const Napi::CallbackInfo &info);
36
- void SetKeyIntMin(const Napi::CallbackInfo &info, const Napi::Value &value);
37
- Napi::Value GetGopSize(const Napi::CallbackInfo &info);
38
- void SetGopSize(const Napi::CallbackInfo &info, const Napi::Value &value);
39
- Napi::Value GetTimeBaseNum(const Napi::CallbackInfo &info);
40
- Napi::Value GetTimeBaseDen(const Napi::CallbackInfo &info);
41
- Napi::Value GetHardwareDevice(const Napi::CallbackInfo &info);
42
- Napi::Value GetPixelFormat(const Napi::CallbackInfo &info);
43
- Napi::Value GetHardwarePixelFormat(const Napi::CallbackInfo &info);
44
- Napi::Value GetVendorInfo(const Napi::CallbackInfo &info);
45
- Napi::Value ReceiveFrame(const Napi::CallbackInfo &info);
46
- Napi::Value ReceivePacket(const Napi::CallbackInfo &info);
47
- Napi::Value SendPacket(const Napi::CallbackInfo &info);
48
- Napi::Value SendFrame(const Napi::CallbackInfo &info);
49
- Napi::Value Destroy(const Napi::CallbackInfo &info);
50
- };
package/src/error.cpp DELETED
@@ -1,33 +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
- }
13
-
14
- #include <thread>
15
- #include <v8.h>
16
-
17
- #include "error.h"
18
-
19
- std::string AVErrorString(int errnum)
20
- {
21
- char errbuf[256];
22
- std::string error;
23
-
24
- if (av_strerror(errnum, errbuf, sizeof(errbuf)) < 0)
25
- {
26
- error = "Unknown error code: " + std::to_string(errnum);
27
- }
28
- else
29
- {
30
- error = errbuf;
31
- }
32
- return error;
33
- }
package/src/error.h DELETED
@@ -1,19 +0,0 @@
1
- #pragma once
2
-
3
- #include <napi.h>
4
- extern "C"
5
- {
6
- #include <libavcodec/avcodec.h>
7
- #include <libavformat/avformat.h>
8
- #include <libavutil/hwcontext.h>
9
- #include <libavutil/frame.h>
10
- #include <libavfilter/buffersink.h>
11
- #include <libavfilter/buffersrc.h>
12
- #include <libavfilter/avfilter.h>
13
- #include <libavutil/opt.h>
14
- }
15
-
16
- #include <thread>
17
- #include <v8.h>
18
-
19
- std::string AVErrorString(int errnum);