@livekit/rtc-node 0.0.7 → 0.2.0
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/build.rs +4 -0
- package/dist/audio_frame.d.ts +1 -1
- package/dist/audio_frame.d.ts.map +1 -1
- package/dist/audio_frame.js +10 -11
- package/dist/audio_frame.js.map +1 -1
- package/dist/audio_source.d.ts +3 -3
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +14 -15
- package/dist/audio_source.js.map +1 -1
- package/dist/audio_stream.d.ts +8 -5
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +18 -22
- package/dist/audio_stream.js.map +1 -1
- package/dist/e2ee.d.ts +1 -1
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +42 -45
- package/dist/e2ee.js.map +1 -1
- package/dist/ffi_client.d.ts +2 -2
- package/dist/ffi_client.d.ts.map +1 -1
- package/dist/ffi_client.js +17 -24
- package/dist/ffi_client.js.map +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -70
- package/dist/index.js.map +1 -1
- package/{src/native.js → dist/napi/native.cjs} +12 -0
- package/dist/napi/native.js +15 -0
- package/dist/participant.d.ts +24 -9
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +45 -45
- package/dist/participant.js.map +1 -1
- package/dist/proto/audio_frame_pb.d.ts +0 -46
- package/dist/proto/audio_frame_pb.d.ts.map +1 -1
- package/dist/proto/audio_frame_pb.js +138 -236
- package/dist/proto/audio_frame_pb.js.map +1 -1
- package/dist/proto/e2ee_pb.js +134 -162
- package/dist/proto/e2ee_pb.js.map +1 -1
- package/dist/proto/ffi_pb.d.ts +31 -44
- package/dist/proto/ffi_pb.d.ts.map +1 -1
- package/dist/proto/ffi_pb.js +140 -126
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/proto/handle_pb.js +7 -11
- package/dist/proto/handle_pb.js.map +1 -1
- package/dist/proto/participant_pb.js +13 -18
- package/dist/proto/participant_pb.js.map +1 -1
- package/dist/proto/room_pb.d.ts +5 -1
- package/dist/proto/room_pb.d.ts.map +1 -1
- package/dist/proto/room_pb.js +393 -454
- package/dist/proto/room_pb.js.map +1 -1
- package/dist/proto/stats_pb.js +265 -303
- package/dist/proto/stats_pb.js.map +1 -1
- package/dist/proto/track_pb.js +87 -102
- package/dist/proto/track_pb.js.map +1 -1
- package/dist/proto/video_frame_pb.d.ts +124 -390
- package/dist/proto/video_frame_pb.d.ts.map +1 -1
- package/dist/proto/video_frame_pb.js +252 -620
- package/dist/proto/video_frame_pb.js.map +1 -1
- package/dist/room.d.ts +10 -9
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +74 -76
- package/dist/room.js.map +1 -1
- package/dist/track.d.ts +4 -4
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +15 -20
- package/dist/track.js.map +1 -1
- package/dist/track_publication.d.ts +4 -4
- package/dist/track_publication.d.ts.map +1 -1
- package/dist/track_publication.js +12 -15
- package/dist/track_publication.js.map +1 -1
- package/dist/video_frame.d.ts +8 -103
- package/dist/video_frame.d.ts.map +1 -1
- package/dist/video_frame.js +161 -341
- package/dist/video_frame.js.map +1 -1
- package/dist/video_source.d.ts +4 -4
- package/dist/video_source.d.ts.map +1 -1
- package/dist/video_source.js +16 -22
- package/dist/video_source.js.map +1 -1
- package/dist/video_stream.d.ts +10 -5
- package/dist/video_stream.d.ts.map +1 -1
- package/dist/video_stream.js +20 -24
- package/dist/video_stream.js.map +1 -1
- package/package.json +14 -14
- package/src/audio_frame.ts +6 -2
- package/src/audio_source.ts +8 -4
- package/src/audio_stream.ts +15 -7
- package/src/e2ee.ts +6 -2
- package/src/ffi_client.ts +6 -2
- package/src/index.ts +19 -28
- package/src/lib.rs +4 -0
- package/src/napi/native.cjs +281 -0
- package/src/napi/native.js +15 -0
- package/src/nodejs.rs +4 -0
- package/src/participant.ts +45 -22
- package/src/proto/audio_frame_pb.ts +1 -91
- package/src/proto/e2ee_pb.ts +1 -1
- package/src/proto/ffi_pb.ts +55 -53
- package/src/proto/handle_pb.ts +1 -1
- package/src/proto/participant_pb.ts +1 -1
- package/src/proto/room_pb.ts +7 -1
- package/src/proto/stats_pb.ts +1 -1
- package/src/proto/track_pb.ts +1 -1
- package/src/proto/video_frame_pb.ts +186 -641
- package/src/room.ts +56 -48
- package/src/track.ts +8 -4
- package/src/track_publication.ts +10 -6
- package/src/video_frame.ts +186 -579
- package/src/video_source.ts +12 -12
- package/src/video_stream.ts +21 -10
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -297
- package/dist/native.js.map +0 -1
- /package/dist/{native.d.ts → napi/native.d.ts} +0 -0
- /package/src/{native.d.ts → napi/native.d.ts} +0 -0
package/src/video_frame.ts
CHANGED
|
@@ -1,620 +1,227 @@
|
|
|
1
|
-
|
|
1
|
+
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import { FfiClient, FfiHandle, FfiRequest } from './ffi_client.js';
|
|
2
6
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
VideoFrameBufferInfo,
|
|
10
|
-
VideoFrameBufferType,
|
|
11
|
-
VideoRotation,
|
|
12
|
-
} from './proto/video_frame_pb';
|
|
7
|
+
OwnedVideoBuffer,
|
|
8
|
+
VideoBufferInfo,
|
|
9
|
+
VideoBufferInfo_ComponentInfo,
|
|
10
|
+
VideoBufferType,
|
|
11
|
+
VideoConvertResponse,
|
|
12
|
+
} from './proto/video_frame_pb.js';
|
|
13
13
|
|
|
14
14
|
export class VideoFrame {
|
|
15
|
-
timestampUs: number;
|
|
16
|
-
rotation: VideoRotation;
|
|
17
|
-
buffer: VideoFrameBuffer;
|
|
18
|
-
|
|
19
|
-
constructor(timestampUs: number, rotation: VideoRotation, buffer: VideoFrameBuffer) {
|
|
20
|
-
this.timestampUs = timestampUs;
|
|
21
|
-
this.rotation = rotation;
|
|
22
|
-
this.buffer = buffer;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export abstract class VideoFrameBuffer {
|
|
27
15
|
data: Uint8Array;
|
|
28
16
|
width: number;
|
|
29
17
|
height: number;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
constructor(data: Uint8Array, width: number, height: number, bufferType: VideoFrameBufferType) {
|
|
33
|
-
this.data = data;
|
|
34
|
-
this.width = width;
|
|
35
|
-
this.height = height;
|
|
36
|
-
this.bufferType = bufferType;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** @internal */
|
|
40
|
-
abstract protoInfo(): VideoFrameBufferInfo;
|
|
41
|
-
|
|
42
|
-
/** @internal */
|
|
43
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): VideoFrameBuffer {
|
|
44
|
-
let info = owned.info;
|
|
45
|
-
switch (info.bufferType) {
|
|
46
|
-
case VideoFrameBufferType.NATIVE:
|
|
47
|
-
return NativeBuffer.fromOwnedInfo(owned);
|
|
48
|
-
case VideoFrameBufferType.I420:
|
|
49
|
-
return I420Buffer.fromOwnedInfo(owned);
|
|
50
|
-
case VideoFrameBufferType.I420A:
|
|
51
|
-
return I420ABuffer.fromOwnedInfo(owned);
|
|
52
|
-
case VideoFrameBufferType.I422:
|
|
53
|
-
return I422Buffer.fromOwnedInfo(owned);
|
|
54
|
-
case VideoFrameBufferType.I444:
|
|
55
|
-
return I444Buffer.fromOwnedInfo(owned);
|
|
56
|
-
case VideoFrameBufferType.I010:
|
|
57
|
-
return I010Buffer.fromOwnedInfo(owned);
|
|
58
|
-
case VideoFrameBufferType.NV12:
|
|
59
|
-
return NV12Buffer.fromOwnedInfo(owned);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export class NativeBuffer extends VideoFrameBuffer {
|
|
65
|
-
private info: VideoFrameBufferInfo;
|
|
66
|
-
|
|
67
|
-
constructor(ownedInfo: OwnedVideoFrameBuffer) {
|
|
68
|
-
super(new Uint8Array(), ownedInfo.info.width, ownedInfo.info.height, ownedInfo.info.bufferType);
|
|
69
|
-
this.info = ownedInfo.info;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** @internal */
|
|
73
|
-
protoInfo(): VideoFrameBufferInfo {
|
|
74
|
-
return this.info;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export abstract class PlanarYuvBuffer extends VideoFrameBuffer {
|
|
79
|
-
strideY: number;
|
|
80
|
-
strideU: number;
|
|
81
|
-
strideV: number;
|
|
82
|
-
chromaWidth: number;
|
|
83
|
-
chromaHeight: number;
|
|
18
|
+
type: VideoBufferType;
|
|
19
|
+
dataPtr: bigint;
|
|
84
20
|
|
|
85
21
|
constructor(
|
|
86
22
|
data: Uint8Array,
|
|
87
23
|
width: number,
|
|
88
24
|
height: number,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
strideU: number,
|
|
92
|
-
strideV: number,
|
|
93
|
-
chromaWidth: number,
|
|
94
|
-
chromaHeight: number,
|
|
25
|
+
type: VideoBufferType,
|
|
26
|
+
dataPtr: bigint,
|
|
95
27
|
) {
|
|
96
|
-
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
101
|
-
this.chromaHeight = chromaHeight;
|
|
28
|
+
this.data = data;
|
|
29
|
+
this.width = width;
|
|
30
|
+
this.height = height;
|
|
31
|
+
this.type = type;
|
|
32
|
+
this.dataPtr = dataPtr;
|
|
102
33
|
}
|
|
103
34
|
|
|
104
35
|
/** @internal */
|
|
105
|
-
protoInfo():
|
|
106
|
-
|
|
36
|
+
protoInfo(): VideoBufferInfo {
|
|
37
|
+
const info = new VideoBufferInfo({
|
|
107
38
|
width: this.width,
|
|
108
39
|
height: this.height,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
case: 'yuv',
|
|
112
|
-
value: new PlanarYuvBufferInfo({
|
|
113
|
-
strideY: this.strideY,
|
|
114
|
-
strideU: this.strideU,
|
|
115
|
-
strideV: this.strideV,
|
|
116
|
-
chromaWidth: this.chromaWidth,
|
|
117
|
-
chromaHeight: this.chromaHeight,
|
|
118
|
-
}),
|
|
119
|
-
},
|
|
40
|
+
type: this.type,
|
|
41
|
+
dataPtr: this.dataPtr,
|
|
120
42
|
});
|
|
121
|
-
return info;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export abstract class PlanarYuv8Buffer extends PlanarYuvBuffer {
|
|
126
|
-
constructor(
|
|
127
|
-
data: Uint8Array,
|
|
128
|
-
width: number,
|
|
129
|
-
height: number,
|
|
130
|
-
bufferType: VideoFrameBufferType,
|
|
131
|
-
strideY: number,
|
|
132
|
-
strideU: number,
|
|
133
|
-
strideV: number,
|
|
134
|
-
chromaWidth: number,
|
|
135
|
-
chromaHeight: number,
|
|
136
|
-
) {
|
|
137
|
-
super(data, width, height, bufferType, strideY, strideU, strideV, chromaWidth, chromaHeight);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** @internal */
|
|
141
|
-
protoInfo(): VideoFrameBufferInfo {
|
|
142
|
-
let info = super.protoInfo();
|
|
143
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
144
|
-
yuv.dataYPtr = FfiClient.instance.retrievePtr(this.dataY());
|
|
145
|
-
yuv.dataUPtr = FfiClient.instance.retrievePtr(this.dataU());
|
|
146
|
-
yuv.dataVPtr = FfiClient.instance.retrievePtr(this.dataV());
|
|
147
|
-
return info;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
dataY(): Uint8Array {
|
|
151
|
-
return this.data.subarray(0, this.strideY * this.height);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
dataU(): Uint8Array {
|
|
155
|
-
return this.data.subarray(
|
|
156
|
-
this.strideY * this.height,
|
|
157
|
-
this.strideY * this.height + this.strideU * this.chromaHeight,
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
dataV(): Uint8Array {
|
|
162
|
-
return this.data.subarray(
|
|
163
|
-
this.strideY * this.height + this.strideU * this.chromaHeight,
|
|
164
|
-
this.strideY * this.height +
|
|
165
|
-
this.strideU * this.chromaHeight +
|
|
166
|
-
this.strideV * this.chromaHeight,
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export abstract class PlanarYuv16Buffer extends PlanarYuvBuffer {
|
|
172
|
-
constructor(
|
|
173
|
-
data: Uint16Array,
|
|
174
|
-
width: number,
|
|
175
|
-
height: number,
|
|
176
|
-
bufferType: VideoFrameBufferType,
|
|
177
|
-
strideY: number,
|
|
178
|
-
strideU: number,
|
|
179
|
-
strideV: number,
|
|
180
|
-
chromaWidth: number,
|
|
181
|
-
chromaHeight: number,
|
|
182
|
-
) {
|
|
183
|
-
super(
|
|
184
|
-
new Uint8Array(data),
|
|
185
|
-
width,
|
|
186
|
-
height,
|
|
187
|
-
bufferType,
|
|
188
|
-
strideY,
|
|
189
|
-
strideU,
|
|
190
|
-
strideV,
|
|
191
|
-
chromaWidth,
|
|
192
|
-
chromaHeight,
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** @internal */
|
|
197
|
-
protoInfo(): VideoFrameBufferInfo {
|
|
198
|
-
let info = super.protoInfo();
|
|
199
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
200
|
-
yuv.dataYPtr = FfiClient.instance.retrievePtr(new Uint8Array(this.dataY()));
|
|
201
|
-
yuv.dataUPtr = FfiClient.instance.retrievePtr(new Uint8Array(this.dataU()));
|
|
202
|
-
yuv.dataVPtr = FfiClient.instance.retrievePtr(new Uint8Array(this.dataV()));
|
|
203
|
-
return info;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
dataY(): Uint16Array {
|
|
207
|
-
return new Uint16Array(this.data.subarray(0, this.strideY * this.height));
|
|
208
|
-
}
|
|
209
43
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
dataV(): Uint16Array {
|
|
220
|
-
return new Uint16Array(
|
|
221
|
-
this.data.subarray(
|
|
222
|
-
this.strideY * this.height + this.strideU * this.chromaHeight,
|
|
223
|
-
this.strideY * this.height +
|
|
224
|
-
this.strideU * this.chromaHeight +
|
|
225
|
-
this.strideV * this.chromaHeight,
|
|
226
|
-
),
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export abstract class BiplanarYuv8Buffer extends VideoFrameBuffer {
|
|
232
|
-
strideY: number;
|
|
233
|
-
strideUV: number;
|
|
234
|
-
chromaWidth: number;
|
|
235
|
-
chromaHeight: number;
|
|
236
|
-
|
|
237
|
-
constructor(
|
|
238
|
-
data: Uint8Array,
|
|
239
|
-
width: number,
|
|
240
|
-
height: number,
|
|
241
|
-
bufferType: VideoFrameBufferType,
|
|
242
|
-
strideY: number,
|
|
243
|
-
strideUV: number,
|
|
244
|
-
chromaWidth: number,
|
|
245
|
-
chromaHeight: number,
|
|
246
|
-
) {
|
|
247
|
-
super(data, width, height, bufferType);
|
|
248
|
-
this.strideY = strideY;
|
|
249
|
-
this.strideUV = strideUV;
|
|
250
|
-
this.chromaWidth = chromaWidth;
|
|
251
|
-
this.chromaHeight = chromaHeight;
|
|
252
|
-
}
|
|
44
|
+
switch (this.type) {
|
|
45
|
+
case VideoBufferType.ARGB:
|
|
46
|
+
case VideoBufferType.RGBA:
|
|
47
|
+
case VideoBufferType.ABGR:
|
|
48
|
+
case VideoBufferType.BGRA:
|
|
49
|
+
info.stride = this.width * 4;
|
|
50
|
+
case VideoBufferType.RGB24:
|
|
51
|
+
info.stride = this.width * 3;
|
|
52
|
+
}
|
|
253
53
|
|
|
254
|
-
|
|
255
|
-
protoInfo(): VideoFrameBufferInfo {
|
|
256
|
-
let info = new VideoFrameBufferInfo({
|
|
257
|
-
width: this.width,
|
|
258
|
-
height: this.height,
|
|
259
|
-
bufferType: this.bufferType,
|
|
260
|
-
buffer: {
|
|
261
|
-
case: 'biYuv',
|
|
262
|
-
value: new BiplanarYuvBufferInfo({
|
|
263
|
-
strideY: this.strideY,
|
|
264
|
-
strideUv: this.strideUV,
|
|
265
|
-
chromaWidth: this.chromaWidth,
|
|
266
|
-
chromaHeight: this.chromaHeight,
|
|
267
|
-
}),
|
|
268
|
-
},
|
|
269
|
-
});
|
|
54
|
+
info.components.push(...getPlaneInfos(this.dataPtr, this.type, this.width, this.height));
|
|
270
55
|
|
|
271
56
|
return info;
|
|
272
57
|
}
|
|
273
58
|
|
|
274
|
-
dataY(): Uint8Array {
|
|
275
|
-
return this.data.subarray(0, this.strideY * this.height);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
dataUV(): Uint8Array {
|
|
279
|
-
return this.data.subarray(
|
|
280
|
-
this.strideY * this.height,
|
|
281
|
-
this.strideY * this.height + this.strideUV * this.chromaHeight,
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export class I420Buffer extends PlanarYuv8Buffer {
|
|
287
|
-
constructor(
|
|
288
|
-
data: Uint8Array,
|
|
289
|
-
width: number,
|
|
290
|
-
height: number,
|
|
291
|
-
strideY: number,
|
|
292
|
-
strideU: number,
|
|
293
|
-
strideV: number,
|
|
294
|
-
) {
|
|
295
|
-
let chromaWidth = ~~((width + 1) / 2);
|
|
296
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
297
|
-
super(
|
|
298
|
-
data,
|
|
299
|
-
width,
|
|
300
|
-
height,
|
|
301
|
-
VideoFrameBufferType.I420,
|
|
302
|
-
strideY,
|
|
303
|
-
strideU,
|
|
304
|
-
strideV,
|
|
305
|
-
chromaWidth,
|
|
306
|
-
chromaHeight,
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/** @internal */
|
|
311
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): I420Buffer {
|
|
312
|
-
let info = owned.info;
|
|
313
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
314
|
-
let strideY = yuv.strideY;
|
|
315
|
-
let strideU = yuv.strideU;
|
|
316
|
-
let strideV = yuv.strideV;
|
|
317
|
-
let nbytes = I420Buffer.calcDataSize(info.height, strideY, strideU, strideV);
|
|
318
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
319
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
320
|
-
return new I420Buffer(data, info.width, info.height, strideY, strideU, strideV);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
static calcDataSize(height: number, strideY: number, strideU: number, strideV: number): number {
|
|
324
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
325
|
-
return strideY * height + strideU * chromaHeight + strideV * chromaHeight;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
static create(width: number, height: number): I420Buffer {
|
|
329
|
-
let strideY = width;
|
|
330
|
-
let strideU = ~~((width + 1) / 2);
|
|
331
|
-
let strideV = ~~((width + 1) / 2);
|
|
332
|
-
let dataSize = I420Buffer.calcDataSize(height, strideY, strideU, strideV);
|
|
333
|
-
let data = new Uint8Array(dataSize);
|
|
334
|
-
return new I420Buffer(data, width, height, strideY, strideU, strideV);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
export class I420ABuffer extends PlanarYuv8Buffer {
|
|
339
|
-
strideA: number;
|
|
340
|
-
|
|
341
|
-
constructor(
|
|
342
|
-
data: Uint8Array,
|
|
343
|
-
width: number,
|
|
344
|
-
height: number,
|
|
345
|
-
strideY: number,
|
|
346
|
-
strideU: number,
|
|
347
|
-
strideV: number,
|
|
348
|
-
strideA: number,
|
|
349
|
-
) {
|
|
350
|
-
let chromaWidth = ~~((width + 1) / 2);
|
|
351
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
352
|
-
super(
|
|
353
|
-
data,
|
|
354
|
-
width,
|
|
355
|
-
height,
|
|
356
|
-
VideoFrameBufferType.I420A,
|
|
357
|
-
strideY,
|
|
358
|
-
strideU,
|
|
359
|
-
strideV,
|
|
360
|
-
chromaWidth,
|
|
361
|
-
chromaHeight,
|
|
362
|
-
);
|
|
363
|
-
this.strideA = strideA;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/** @internal */
|
|
367
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): I420ABuffer {
|
|
368
|
-
let info = owned.info;
|
|
369
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
370
|
-
let strideY = yuv.strideY;
|
|
371
|
-
let strideU = yuv.strideU;
|
|
372
|
-
let strideV = yuv.strideV;
|
|
373
|
-
let strideA = yuv.strideA;
|
|
374
|
-
let nbytes = I420ABuffer.calcDataSize(info.height, strideY, strideU, strideV, strideA);
|
|
375
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
376
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
377
|
-
return new I420ABuffer(data, info.width, info.height, strideY, strideU, strideV, strideA);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
static calcDataSize(
|
|
381
|
-
height: number,
|
|
382
|
-
strideY: number,
|
|
383
|
-
strideU: number,
|
|
384
|
-
strideV: number,
|
|
385
|
-
strideA: number,
|
|
386
|
-
): number {
|
|
387
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
388
|
-
return strideY * height + strideU * chromaHeight + strideV * chromaHeight + strideA * height;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
dataA(): Uint8Array {
|
|
392
|
-
return this.data.subarray(
|
|
393
|
-
this.strideY * this.height +
|
|
394
|
-
this.strideU * this.chromaHeight +
|
|
395
|
-
this.strideV * this.chromaHeight,
|
|
396
|
-
this.strideY * this.height +
|
|
397
|
-
this.strideU * this.chromaHeight +
|
|
398
|
-
this.strideV * this.chromaHeight +
|
|
399
|
-
this.strideA * this.height,
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export class I422Buffer extends PlanarYuv8Buffer {
|
|
405
|
-
constructor(
|
|
406
|
-
data: Uint8Array,
|
|
407
|
-
width: number,
|
|
408
|
-
height: number,
|
|
409
|
-
strideY: number,
|
|
410
|
-
strideU: number,
|
|
411
|
-
strideV: number,
|
|
412
|
-
) {
|
|
413
|
-
let chromaWidth = ~~((width + 1) / 2);
|
|
414
|
-
let chromaHeight = height;
|
|
415
|
-
super(
|
|
416
|
-
data,
|
|
417
|
-
width,
|
|
418
|
-
height,
|
|
419
|
-
VideoFrameBufferType.I422,
|
|
420
|
-
strideY,
|
|
421
|
-
strideU,
|
|
422
|
-
strideV,
|
|
423
|
-
chromaWidth,
|
|
424
|
-
chromaHeight,
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/** @internal */
|
|
429
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): I422Buffer {
|
|
430
|
-
let info = owned.info;
|
|
431
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
432
|
-
let strideY = yuv.strideY;
|
|
433
|
-
let strideU = yuv.strideU;
|
|
434
|
-
let strideV = yuv.strideV;
|
|
435
|
-
let nbytes = I422Buffer.calcDataSize(info.height, strideY, strideU, strideV);
|
|
436
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
437
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
438
|
-
return new I422Buffer(data, info.width, info.height, strideY, strideU, strideV);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
static calcDataSize(height: number, strideY: number, strideU: number, strideV: number): number {
|
|
442
|
-
return strideY * height + strideU * height + strideV * height;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
export class I444Buffer extends PlanarYuv8Buffer {
|
|
447
|
-
constructor(
|
|
448
|
-
data: Uint8Array,
|
|
449
|
-
width: number,
|
|
450
|
-
height: number,
|
|
451
|
-
strideY: number,
|
|
452
|
-
strideU: number,
|
|
453
|
-
strideV: number,
|
|
454
|
-
) {
|
|
455
|
-
let chromaWidth = width;
|
|
456
|
-
let chromaHeight = height;
|
|
457
|
-
super(
|
|
458
|
-
data,
|
|
459
|
-
width,
|
|
460
|
-
height,
|
|
461
|
-
VideoFrameBufferType.I444,
|
|
462
|
-
strideY,
|
|
463
|
-
strideU,
|
|
464
|
-
strideV,
|
|
465
|
-
chromaWidth,
|
|
466
|
-
chromaHeight,
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/** @internal */
|
|
471
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): I444Buffer {
|
|
472
|
-
let info = owned.info;
|
|
473
|
-
let yuv = info.buffer.value as PlanarYuvBufferInfo;
|
|
474
|
-
let strideY = yuv.strideY;
|
|
475
|
-
let strideU = yuv.strideU;
|
|
476
|
-
let strideV = yuv.strideV;
|
|
477
|
-
let nbytes = I444Buffer.calcDataSize(info.height, strideY, strideU, strideV);
|
|
478
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
479
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
480
|
-
return new I444Buffer(data, info.width, info.height, strideY, strideU, strideV);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
static calcDataSize(height: number, strideY: number, strideU: number, strideV: number): number {
|
|
484
|
-
return strideY * height + strideU * height + strideV * height;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
export class I010Buffer extends PlanarYuv16Buffer {
|
|
489
|
-
constructor(
|
|
490
|
-
data: Uint16Array,
|
|
491
|
-
width: number,
|
|
492
|
-
height: number,
|
|
493
|
-
strideY: number,
|
|
494
|
-
strideU: number,
|
|
495
|
-
strideV: number,
|
|
496
|
-
) {
|
|
497
|
-
let chromaWidth = ~~((width + 1) / 2);
|
|
498
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
499
|
-
super(
|
|
500
|
-
data,
|
|
501
|
-
width,
|
|
502
|
-
height,
|
|
503
|
-
VideoFrameBufferType.I010,
|
|
504
|
-
strideY,
|
|
505
|
-
strideU,
|
|
506
|
-
strideV,
|
|
507
|
-
chromaWidth,
|
|
508
|
-
chromaHeight,
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
59
|
/** @internal */
|
|
513
|
-
static fromOwnedInfo(owned:
|
|
60
|
+
static fromOwnedInfo(owned: OwnedVideoBuffer): VideoFrame {
|
|
514
61
|
let info = owned.info;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
521
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
522
|
-
return new I010Buffer(
|
|
523
|
-
new Uint16Array(data),
|
|
62
|
+
return new VideoFrame(
|
|
63
|
+
FfiClient.instance.copyBuffer(
|
|
64
|
+
info.dataPtr,
|
|
65
|
+
getPlaneLength(info.type, info.width, info.height),
|
|
66
|
+
),
|
|
524
67
|
info.width,
|
|
525
68
|
info.height,
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
strideV,
|
|
69
|
+
info.type,
|
|
70
|
+
info.dataPtr,
|
|
529
71
|
);
|
|
530
72
|
}
|
|
531
73
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
export class NV12Buffer extends BiplanarYuv8Buffer {
|
|
539
|
-
constructor(data: Uint8Array, width: number, height: number, strideY: number, strideUV: number) {
|
|
540
|
-
let chromaWidth = ~~((width + 1) / 2);
|
|
541
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
542
|
-
super(
|
|
543
|
-
data,
|
|
544
|
-
width,
|
|
545
|
-
height,
|
|
546
|
-
VideoFrameBufferType.NV12,
|
|
547
|
-
strideY,
|
|
548
|
-
strideUV,
|
|
549
|
-
chromaWidth,
|
|
550
|
-
chromaHeight,
|
|
551
|
-
);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/** @internal */
|
|
555
|
-
static fromOwnedInfo(owned: OwnedVideoFrameBuffer): NV12Buffer {
|
|
556
|
-
let info = owned.info;
|
|
557
|
-
let yuv = info.buffer.value as BiplanarYuvBufferInfo;
|
|
558
|
-
let strideY = yuv.strideY;
|
|
559
|
-
let strideUV = yuv.strideUv;
|
|
560
|
-
let nbytes = NV12Buffer.calcDataSize(info.height, strideY, strideUV);
|
|
561
|
-
let data = FfiClient.instance.copyBuffer(yuv.dataYPtr, nbytes);
|
|
562
|
-
new FfiHandle(owned.handle.id).dispose();
|
|
563
|
-
return new NV12Buffer(data, info.width, info.height, strideY, strideUV);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
static calcDataSize(height: number, strideY: number, strideUV: number): number {
|
|
567
|
-
let chromaHeight = ~~((height + 1) / 2);
|
|
568
|
-
return strideY * height + strideUV * chromaHeight;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
export class ArgbFrame {
|
|
573
|
-
data: Uint8Array;
|
|
574
|
-
format: VideoFormatType;
|
|
575
|
-
width: number;
|
|
576
|
-
height: number;
|
|
577
|
-
stride: number;
|
|
578
|
-
|
|
579
|
-
constructor(
|
|
580
|
-
data: Uint8Array,
|
|
581
|
-
format: VideoFormatType,
|
|
582
|
-
width: number,
|
|
583
|
-
height: number,
|
|
584
|
-
stride: number = width * 4,
|
|
585
|
-
) {
|
|
586
|
-
this.data = data;
|
|
587
|
-
this.format = format;
|
|
588
|
-
this.width = width;
|
|
589
|
-
this.height = height;
|
|
590
|
-
this.stride = stride;
|
|
591
|
-
}
|
|
74
|
+
getPlane(planeNth: number): Uint8Array | void {
|
|
75
|
+
const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height)
|
|
76
|
+
if (planeNth >= planeInfos.length) return;
|
|
592
77
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return new ArgbFrame(data, format, width, height);
|
|
78
|
+
const planeInfo = planeInfos[planeNth];
|
|
79
|
+
return FfiClient.instance.copyBuffer(planeInfo.dataPtr, planeInfo.size);
|
|
596
80
|
}
|
|
597
81
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
case: '
|
|
82
|
+
convert(dstType: VideoBufferType, flipY = false): VideoFrame {
|
|
83
|
+
const req = new FfiRequest({
|
|
84
|
+
message: {
|
|
85
|
+
case: 'videoConvert',
|
|
602
86
|
value: {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
stride: this.stride,
|
|
607
|
-
ptr: FfiClient.instance.retrievePtr(this.data),
|
|
87
|
+
flipY,
|
|
88
|
+
dstType,
|
|
89
|
+
buffer: this.protoInfo(),
|
|
608
90
|
},
|
|
609
91
|
},
|
|
610
92
|
});
|
|
93
|
+
const resp = FfiClient.instance.request<VideoConvertResponse>(req)
|
|
94
|
+
if (resp.error) {
|
|
95
|
+
throw resp.error
|
|
96
|
+
}
|
|
611
97
|
|
|
612
|
-
|
|
613
|
-
message: {
|
|
614
|
-
case: 'toI420',
|
|
615
|
-
value: req,
|
|
616
|
-
},
|
|
617
|
-
});
|
|
618
|
-
return I420Buffer.fromOwnedInfo(resp.buffer);
|
|
98
|
+
return VideoFrame.fromOwnedInfo(resp.buffer)
|
|
619
99
|
}
|
|
620
100
|
}
|
|
101
|
+
|
|
102
|
+
const getPlaneLength = (type: VideoBufferType, width: number, height: number): number => {
|
|
103
|
+
const chromaWidth = Math.trunc((width + 1) / 2);
|
|
104
|
+
const chromaHeight = Math.trunc((height + 1) / 2);
|
|
105
|
+
switch (type) {
|
|
106
|
+
case VideoBufferType.ARGB:
|
|
107
|
+
case VideoBufferType.RGBA:
|
|
108
|
+
case VideoBufferType.ABGR:
|
|
109
|
+
case VideoBufferType.BGRA:
|
|
110
|
+
return width * height * 4;
|
|
111
|
+
case VideoBufferType.RGB24:
|
|
112
|
+
case VideoBufferType.I444:
|
|
113
|
+
return width * height * 3;
|
|
114
|
+
case VideoBufferType.I420:
|
|
115
|
+
return width * height + chromaWidth * chromaHeight * 2;
|
|
116
|
+
case VideoBufferType.I420A:
|
|
117
|
+
return width * height * 2 + chromaWidth * chromaWidth * 2;
|
|
118
|
+
case VideoBufferType.I422:
|
|
119
|
+
return width * height + chromaWidth * height * 2;
|
|
120
|
+
case VideoBufferType.I010:
|
|
121
|
+
return width * height * 2 + chromaWidth * chromaHeight * 4;
|
|
122
|
+
case VideoBufferType.NV12:
|
|
123
|
+
return width * height + chromaWidth * chromaWidth * 2;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const getPlaneInfos = (
|
|
128
|
+
dataPtr: bigint,
|
|
129
|
+
type: VideoBufferType,
|
|
130
|
+
width: number,
|
|
131
|
+
height: number,
|
|
132
|
+
): VideoBufferInfo_ComponentInfo[] => {
|
|
133
|
+
const chromaWidth = Math.trunc((width + 1) / 2);
|
|
134
|
+
const chromaHeight = Math.trunc((height + 1) / 2);
|
|
135
|
+
switch (type) {
|
|
136
|
+
case VideoBufferType.I420: {
|
|
137
|
+
const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
|
|
138
|
+
const u = new VideoBufferInfo_ComponentInfo({
|
|
139
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
140
|
+
stride: chromaWidth,
|
|
141
|
+
size: chromaWidth * chromaHeight,
|
|
142
|
+
});
|
|
143
|
+
const v = new VideoBufferInfo_ComponentInfo({
|
|
144
|
+
dataPtr: u.dataPtr + BigInt(u.size),
|
|
145
|
+
stride: chromaWidth,
|
|
146
|
+
size: chromaWidth * chromaHeight,
|
|
147
|
+
});
|
|
148
|
+
return [y, u, v];
|
|
149
|
+
}
|
|
150
|
+
case VideoBufferType.I420A: {
|
|
151
|
+
const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
|
|
152
|
+
const u = new VideoBufferInfo_ComponentInfo({
|
|
153
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
154
|
+
stride: chromaWidth,
|
|
155
|
+
size: chromaWidth * chromaHeight,
|
|
156
|
+
});
|
|
157
|
+
const v = new VideoBufferInfo_ComponentInfo({
|
|
158
|
+
dataPtr: u.dataPtr + BigInt(u.size),
|
|
159
|
+
stride: chromaWidth,
|
|
160
|
+
size: chromaWidth * chromaHeight,
|
|
161
|
+
});
|
|
162
|
+
const a = new VideoBufferInfo_ComponentInfo({
|
|
163
|
+
dataPtr: v.dataPtr + BigInt(v.size),
|
|
164
|
+
stride: width,
|
|
165
|
+
size: width * height,
|
|
166
|
+
});
|
|
167
|
+
return [y, u, v, a];
|
|
168
|
+
}
|
|
169
|
+
case VideoBufferType.I422: {
|
|
170
|
+
const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
|
|
171
|
+
const u = new VideoBufferInfo_ComponentInfo({
|
|
172
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
173
|
+
stride: chromaWidth,
|
|
174
|
+
size: chromaWidth * height,
|
|
175
|
+
});
|
|
176
|
+
const v = new VideoBufferInfo_ComponentInfo({
|
|
177
|
+
dataPtr: u.dataPtr + BigInt(u.size),
|
|
178
|
+
stride: chromaWidth,
|
|
179
|
+
size: chromaWidth * height,
|
|
180
|
+
});
|
|
181
|
+
return [y, u, v];
|
|
182
|
+
}
|
|
183
|
+
case VideoBufferType.I444: {
|
|
184
|
+
const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
|
|
185
|
+
const u = new VideoBufferInfo_ComponentInfo({
|
|
186
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
187
|
+
stride: width,
|
|
188
|
+
size: width * height,
|
|
189
|
+
});
|
|
190
|
+
const v = new VideoBufferInfo_ComponentInfo({
|
|
191
|
+
dataPtr: u.dataPtr + BigInt(u.size),
|
|
192
|
+
stride: width,
|
|
193
|
+
size: width * height,
|
|
194
|
+
});
|
|
195
|
+
return [y, u, v];
|
|
196
|
+
}
|
|
197
|
+
case VideoBufferType.I010: {
|
|
198
|
+
const y = new VideoBufferInfo_ComponentInfo({
|
|
199
|
+
dataPtr,
|
|
200
|
+
stride: width * 2,
|
|
201
|
+
size: width * height * 2,
|
|
202
|
+
});
|
|
203
|
+
const u = new VideoBufferInfo_ComponentInfo({
|
|
204
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
205
|
+
stride: chromaWidth * 2,
|
|
206
|
+
size: chromaWidth * chromaHeight * 2,
|
|
207
|
+
});
|
|
208
|
+
const v = new VideoBufferInfo_ComponentInfo({
|
|
209
|
+
dataPtr: u.dataPtr + BigInt(u.size),
|
|
210
|
+
stride: chromaWidth * 2,
|
|
211
|
+
size: chromaWidth * chromaHeight * 2,
|
|
212
|
+
});
|
|
213
|
+
return [y, u, v];
|
|
214
|
+
}
|
|
215
|
+
case VideoBufferType.NV12: {
|
|
216
|
+
const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
|
|
217
|
+
const uv = new VideoBufferInfo_ComponentInfo({
|
|
218
|
+
dataPtr: y.dataPtr + BigInt(y.size),
|
|
219
|
+
stride: chromaWidth * 2,
|
|
220
|
+
size: chromaWidth * chromaHeight * 2,
|
|
221
|
+
});
|
|
222
|
+
return [y, uv];
|
|
223
|
+
}
|
|
224
|
+
default:
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
227
|
+
};
|