react-native-webgpu 0.10.5 → 0.11.1
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/android/cpp/AndroidPlatformContext.h +100 -9
- package/android/cpp/AndroidVideoPlayer.h +307 -0
- package/android/cpp/cpp-adapter.cpp +66 -6
- package/android/src/main/java/com/webgpu/ViewSnapshot.java +162 -0
- package/android/src/main/java/com/webgpu/WebGPUModule.java +78 -0
- package/android/src/main/java/com/webgpu/WebGPUVideoPlayer.java +420 -0
- package/apple/ApplePlatformContext.h +14 -1
- package/apple/ApplePlatformContext.mm +176 -1
- package/apple/AppleVideoPlayer.mm +157 -47
- package/apple/WebGPUModule.mm +20 -1
- package/cpp/rnwgpu/PlatformContext.h +76 -1
- package/cpp/rnwgpu/RNWebGPUManager.cpp +7 -0
- package/cpp/rnwgpu/api/GPUDevice.cpp +2 -1
- package/cpp/rnwgpu/api/GPUDevice.h +6 -0
- package/cpp/rnwgpu/api/GPUQueue.cpp +261 -4
- package/cpp/rnwgpu/api/GPUQueue.h +29 -2
- package/cpp/rnwgpu/api/VideoFrameBlit.h +355 -0
- package/cpp/rnwgpu/api/VideoPlayer.h +50 -3
- package/cpp/rnwgpu/api/descriptors/GPUDrawElementImageDestination.h +60 -0
- package/cpp/rnwgpu/api/descriptors/GPUDrawElementImageSource.h +106 -0
- package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +30 -3
- package/lib/commonjs/importDevice.js +2 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/main/index.js +45 -0
- package/lib/commonjs/main/index.js.map +1 -1
- package/lib/commonjs/main/index.web.js +11 -0
- package/lib/commonjs/main/index.web.js.map +1 -1
- package/lib/commonjs/video.js +58 -0
- package/lib/commonjs/video.js.map +1 -0
- package/lib/module/importDevice.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/main/index.js +34 -0
- package/lib/module/main/index.js.map +1 -1
- package/lib/module/main/index.web.js +1 -0
- package/lib/module/main/index.web.js.map +1 -1
- package/lib/module/video.js +49 -0
- package/lib/module/video.js.map +1 -0
- package/lib/typescript/lib/commonjs/video.d.ts +30 -0
- package/lib/typescript/lib/commonjs/video.d.ts.map +1 -0
- package/lib/typescript/lib/module/main/index.d.ts +1 -0
- package/lib/typescript/lib/module/main/index.web.d.ts +1 -0
- package/lib/typescript/lib/module/video.d.ts +4 -0
- package/lib/typescript/lib/module/video.d.ts.map +1 -0
- package/lib/typescript/src/importDevice.d.ts +2 -2
- package/lib/typescript/src/index.d.ts +8 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/main/index.d.ts +1 -0
- package/lib/typescript/src/main/index.d.ts.map +1 -1
- package/lib/typescript/src/main/index.web.d.ts +1 -0
- package/lib/typescript/src/main/index.web.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +32 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/video.d.ts +41 -0
- package/lib/typescript/src/video.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/importDevice.ts +2 -2
- package/src/index.tsx +57 -3
- package/src/main/index.tsx +50 -0
- package/src/main/index.web.tsx +1 -0
- package/src/types.ts +89 -7
- package/src/video.ts +69 -0
package/src/importDevice.ts
CHANGED
|
@@ -26,10 +26,10 @@ export const importDevice = (pointer: bigint): GPUDevice => {
|
|
|
26
26
|
* ownership of one reference: the returned texture releases it when destroyed.
|
|
27
27
|
*
|
|
28
28
|
* Pair with producers that hand out a +1 reference, such as
|
|
29
|
-
* `Skia.Image.
|
|
29
|
+
* `Skia.Image.MakeGPUTextureFromImage()`:
|
|
30
30
|
*
|
|
31
31
|
* ```ts
|
|
32
|
-
* const texture = adoptTexture(Skia.Image.
|
|
32
|
+
* const texture = adoptTexture(Skia.Image.MakeGPUTextureFromImage(image));
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export const adoptTexture = (pointer: bigint): GPUTexture => {
|
package/src/index.tsx
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import type {
|
|
3
|
+
GPUDrawElementImageDestination,
|
|
4
|
+
GPUDrawElementImageSource,
|
|
3
5
|
GPUSharedFence,
|
|
4
6
|
GPUSharedFenceDescriptor,
|
|
5
7
|
GPUDawnTogglesDescriptor,
|
|
8
|
+
GPUNativeExternalTextureDescriptor,
|
|
6
9
|
GPUSharedTextureMemory,
|
|
7
10
|
GPUSharedTextureMemoryDescriptor,
|
|
11
|
+
GPUCopyExternalNativeFrameSourceInfo,
|
|
8
12
|
NativeCanvas,
|
|
9
13
|
RNCanvasContext,
|
|
10
14
|
VideoPlayer,
|
|
@@ -28,7 +32,12 @@ export type {
|
|
|
28
32
|
GPUSharedTextureMemoryEndAccessState,
|
|
29
33
|
NativeVideoPixelFormat,
|
|
30
34
|
CreateVideoPlayerOptions,
|
|
35
|
+
GPUCopyExternalNativeFrameSourceInfo,
|
|
31
36
|
GPUDawnTogglesDescriptor,
|
|
37
|
+
GPUNativeExternalTextureDescriptor,
|
|
38
|
+
GPUDrawElementImageDestination,
|
|
39
|
+
GPUDrawElementImageSource,
|
|
40
|
+
GPUDrawElementImageSourceView,
|
|
32
41
|
} from "./types";
|
|
33
42
|
|
|
34
43
|
declare global {
|
|
@@ -64,10 +73,11 @@ declare global {
|
|
|
64
73
|
importDevice: (pointer: bigint) => GPUDevice;
|
|
65
74
|
// Wrap an externally created WGPUTexture pointer into a GPUTexture,
|
|
66
75
|
// taking ownership of one reference (pair with producers that return a
|
|
67
|
-
// +1 pointer, e.g. Skia.Image.
|
|
76
|
+
// +1 pointer, e.g. Skia.Image.MakeGPUTextureFromImage()).
|
|
68
77
|
adoptTexture: (pointer: bigint) => GPUTexture;
|
|
78
|
+
// Prefer the createVideoPlayer() export, which takes an options object.
|
|
69
79
|
createVideoPlayer: (
|
|
70
|
-
|
|
80
|
+
source: string,
|
|
71
81
|
pixelFormat?: NativeVideoPixelFormat,
|
|
72
82
|
) => VideoPlayer;
|
|
73
83
|
writeTestVideoFile: () => string;
|
|
@@ -75,18 +85,62 @@ declare global {
|
|
|
75
85
|
|
|
76
86
|
interface GPUTexture {
|
|
77
87
|
// Non-spec RN extension: raw WGPUTexture handle as a BigInt for
|
|
78
|
-
// pointer-based interop (
|
|
88
|
+
// pointer-based interop (Skia.Image.MakeImageFromGPUTexture reads it).
|
|
79
89
|
// Borrowed: keep this GPUTexture alive while the pointer is in use.
|
|
80
90
|
readonly nativePointer: bigint;
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
interface GPUDevice {
|
|
94
|
+
// Non-spec RN extension: the source of an external texture is a
|
|
95
|
+
// NativeVideoFrame (from a VideoPlayer, createVideoFrameFromNativeBuffer
|
|
96
|
+
// or createTestVideoFrame) instead of the web's HTMLVideoElement /
|
|
97
|
+
// VideoFrame. Overloads the spec signature, which stays available for
|
|
98
|
+
// the web implementation.
|
|
99
|
+
importExternalTexture(
|
|
100
|
+
descriptor: GPUNativeExternalTextureDescriptor,
|
|
101
|
+
): GPUExternalTexture;
|
|
84
102
|
importSharedTextureMemory(
|
|
85
103
|
descriptor: GPUSharedTextureMemoryDescriptor,
|
|
86
104
|
): GPUSharedTextureMemory;
|
|
87
105
|
importSharedFence(descriptor: GPUSharedFenceDescriptor): GPUSharedFence;
|
|
88
106
|
}
|
|
89
107
|
|
|
108
|
+
// Non-spec RN extension modeled on the html-in-canvas proposal's
|
|
109
|
+
// GPUQueue.drawElementImageToTexture: rasterizes a native React Native view
|
|
110
|
+
// (the "element") and writes the pixels into `destination.texture`, which
|
|
111
|
+
// must be rgba8unorm or bgra8unorm (or their -srgb variants) with
|
|
112
|
+
// GPUTextureUsage.COPY_DST. Unlike the web API it returns a Promise: the
|
|
113
|
+
// view is rasterized on the platform UI thread, and the texture write is
|
|
114
|
+
// issued right before the promise resolves, so submit work that samples the
|
|
115
|
+
// texture after awaiting it. Snapshot the view with `collapsable={false}`
|
|
116
|
+
// so React Native does not optimize the host view away.
|
|
117
|
+
//
|
|
118
|
+
// What is captured is what the platform renders for the view hierarchy
|
|
119
|
+
// (iOS: UIView.drawViewHierarchyInRect; Android API 29+: HardwareRenderer
|
|
120
|
+
// over the views' display lists, older: View.draw into a software canvas).
|
|
121
|
+
// On Android, SurfaceView content (a WebGPU Canvas with the default
|
|
122
|
+
// "SurfaceView" surfaceType, video players) is not part of the hierarchy and
|
|
123
|
+
// comes out blank; use `android={{ surfaceType: "TextureView" }}` for a
|
|
124
|
+
// canvas that must be captured.
|
|
125
|
+
interface GPUQueue {
|
|
126
|
+
drawElementImageToTexture(
|
|
127
|
+
source: GPUDrawElementImageSource,
|
|
128
|
+
destination: GPUDrawElementImageDestination,
|
|
129
|
+
): Promise<void>;
|
|
130
|
+
// Non-spec extension: a NativeVideoFrame (from createVideoPlayer,
|
|
131
|
+
// createVideoFrameFromNativeBuffer or createTestVideoFrame) as the copy
|
|
132
|
+
// source. The frame is rendered into the destination on the GPU through
|
|
133
|
+
// an external texture, which converts YUV to RGB and applies `rotation`
|
|
134
|
+
// and `mirrored`; the destination needs GPUTextureUsage.RENDER_ATTACHMENT
|
|
135
|
+
// and an rgba8unorm, bgra8unorm (or -srgb), rgba16float or rgb10a2unorm
|
|
136
|
+
// format. The frame can be released as soon as the call returns.
|
|
137
|
+
copyExternalImageToTexture(
|
|
138
|
+
source: GPUCopyExternalNativeFrameSourceInfo,
|
|
139
|
+
destination: GPUCopyExternalImageDestInfo,
|
|
140
|
+
copySize: GPUExtent3DStrict,
|
|
141
|
+
): undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
90
144
|
// Non-standard, Dawn-only. Lets callers set Dawn device-stage toggles at
|
|
91
145
|
// device creation: adapter.requestDevice({ dawnToggles: { ... } }).
|
|
92
146
|
interface GPUDeviceDescriptor {
|
package/src/main/index.tsx
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
|
+
import { findNodeHandle } from "react-native";
|
|
2
|
+
|
|
1
3
|
import { registerWebGPUForReanimated } from "../external";
|
|
2
4
|
import { provideGPUForInstall } from "../install";
|
|
3
5
|
import WebGPUModule from "../NativeWebGPUModule";
|
|
6
|
+
import type { GPUDrawElementImageSourceView } from "../types";
|
|
7
|
+
|
|
8
|
+
// Resolve the `source` of drawElementImageToTexture to a React tag on the
|
|
9
|
+
// main JS runtime, where findNodeHandle is available: it handles class
|
|
10
|
+
// components and legacy host instances that the native fallback (a number or
|
|
11
|
+
// an instance carrying `__nativeTag`) does not.
|
|
12
|
+
const resolveElementSource = (source: GPUDrawElementImageSourceView) => {
|
|
13
|
+
if (typeof source === "number") {
|
|
14
|
+
return source;
|
|
15
|
+
}
|
|
16
|
+
const instance =
|
|
17
|
+
source !== null && typeof source === "object" && "current" in source
|
|
18
|
+
? source.current
|
|
19
|
+
: source;
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
const tag = instance == null ? null : findNodeHandle(instance as any);
|
|
22
|
+
if (tag === null || tag === undefined) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
"[WebGPU] drawElementImageToTexture: `source` does not resolve to a " +
|
|
25
|
+
"mounted native view (pass a host component ref rendered with " +
|
|
26
|
+
"collapsable={false})",
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return tag;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const installDrawElementImageToTexture = () => {
|
|
33
|
+
if (typeof GPUQueue === "undefined") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const native = GPUQueue.prototype.drawElementImageToTexture;
|
|
37
|
+
if (typeof native !== "function") {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
GPUQueue.prototype.drawElementImageToTexture = function (
|
|
41
|
+
this: GPUQueue,
|
|
42
|
+
source,
|
|
43
|
+
destination,
|
|
44
|
+
) {
|
|
45
|
+
return native.call(
|
|
46
|
+
this,
|
|
47
|
+
{ ...source, source: resolveElementSource(source.source) },
|
|
48
|
+
destination,
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
};
|
|
4
52
|
|
|
5
53
|
export * from "../Canvas";
|
|
6
54
|
export * from "../Offscreen";
|
|
@@ -8,6 +56,7 @@ export * from "../WebGPUViewNativeComponent";
|
|
|
8
56
|
export * from "../hooks";
|
|
9
57
|
export * from "../GPUDeviceProvider";
|
|
10
58
|
export * from "../importDevice";
|
|
59
|
+
export * from "../video";
|
|
11
60
|
export * from "../formats";
|
|
12
61
|
|
|
13
62
|
export { default as WebGPUModule } from "../NativeWebGPUModule";
|
|
@@ -37,6 +86,7 @@ if (typeof RNWebGPU !== "undefined") {
|
|
|
37
86
|
}
|
|
38
87
|
global.createImageBitmap =
|
|
39
88
|
global.createImageBitmap ?? RNWebGPU.createImageBitmap.bind(RNWebGPU);
|
|
89
|
+
installDrawElementImageToTexture();
|
|
40
90
|
// Let installWebGPU() put navigator.gpu on other runtimes (see install.ts).
|
|
41
91
|
provideGPUForInstall(RNWebGPU.gpu);
|
|
42
92
|
} else {
|
package/src/main/index.web.tsx
CHANGED
package/src/types.ts
CHANGED
|
@@ -63,24 +63,106 @@ export interface NativeVideoFrame {
|
|
|
63
63
|
release(): void;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
66
|
+
// GPUExternalTextureDescriptor with a NativeVideoFrame as the source: what
|
|
67
|
+
// GPUDevice.importExternalTexture() takes on React Native, where there is no
|
|
68
|
+
// HTMLVideoElement or WebCodecs VideoFrame. The other members (label,
|
|
69
|
+
// colorSpace, and the rotation / mirrored extensions) are the same.
|
|
70
|
+
export interface GPUNativeExternalTextureDescriptor extends Omit<
|
|
71
|
+
GPUExternalTextureDescriptor,
|
|
72
|
+
"source"
|
|
73
|
+
> {
|
|
74
|
+
source: NativeVideoFrame;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// A decoded video, modeled on HTMLMediaElement: play(), pause(), paused,
|
|
78
|
+
// currentTime (in seconds, assign it to seek), duration, volume and loop work
|
|
79
|
+
// as on the web. Frames are pulled instead of displayed: poll
|
|
80
|
+
// copyLatestFrame() on every render tick to obtain the most recently decoded
|
|
81
|
+
// frame as an IOSurface/AHardwareBuffer-backed NativeVideoFrame (null between
|
|
82
|
+
// frames, so callers can skip the import work).
|
|
69
83
|
export interface VideoPlayer {
|
|
70
84
|
copyLatestFrame(): NativeVideoFrame | null;
|
|
71
85
|
play(): void;
|
|
72
86
|
pause(): void;
|
|
87
|
+
// Stops playback and releases the decoder. Frames already copied stay
|
|
88
|
+
// valid until they are released.
|
|
73
89
|
release(): void;
|
|
90
|
+
readonly paused: boolean;
|
|
91
|
+
// The playback position in seconds. Assign it to seek, also while paused:
|
|
92
|
+
// the next copyLatestFrame() then returns the frame at the new position.
|
|
93
|
+
currentTime: number;
|
|
94
|
+
// The length in seconds, 0 until the metadata has loaded.
|
|
95
|
+
readonly duration: number;
|
|
96
|
+
// 0 to 1.
|
|
97
|
+
volume: number;
|
|
98
|
+
// Restart from the beginning at the end of the stream. Unlike on the web,
|
|
99
|
+
// it defaults to true.
|
|
100
|
+
loop: boolean;
|
|
101
|
+
// The coded size of the frames in pixels, 0 until the metadata has loaded.
|
|
102
|
+
readonly videoWidth: number;
|
|
103
|
+
readonly videoHeight: number;
|
|
104
|
+
// The clockwise rotation to apply when displaying the frames: a video
|
|
105
|
+
// recorded in portrait stores landscape frames with a rotation. Pass it as
|
|
106
|
+
// the `rotation` of importExternalTexture().
|
|
107
|
+
readonly rotation: 0 | 90 | 180 | 270;
|
|
108
|
+
// The nominal frame rate of the video track, 0 if unknown.
|
|
109
|
+
readonly frameRate: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// The source info of GPUQueue.copyExternalImageToTexture() for a native
|
|
113
|
+
// frame (a React Native extension of GPUCopyExternalImageSourceInfo). The
|
|
114
|
+
// frame is rendered into the destination through an external texture, which
|
|
115
|
+
// converts YUV to RGB and applies `rotation` and `mirrored` (the extension of
|
|
116
|
+
// importExternalTexture), so the destination needs
|
|
117
|
+
// GPUTextureUsage.RENDER_ATTACHMENT. `origin` and the copy size are in the
|
|
118
|
+
// upright frame, after rotation.
|
|
119
|
+
export interface GPUCopyExternalNativeFrameSourceInfo {
|
|
120
|
+
source: NativeVideoFrame;
|
|
121
|
+
origin?: GPUOrigin2D;
|
|
122
|
+
flipY?: boolean;
|
|
123
|
+
rotation?: 0 | 90 | 180 | 270;
|
|
124
|
+
mirrored?: boolean;
|
|
74
125
|
}
|
|
75
126
|
|
|
76
127
|
export interface CreateVideoPlayerOptions {
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
// GPUDevice.importExternalTexture.
|
|
128
|
+
// The layout of the frames on Apple platforms:
|
|
129
|
+
// 'bgra8' (default): single-plane BGRA surfaces, for importSharedTextureMemory
|
|
130
|
+
// and a regular sampled GPUTexture.
|
|
131
|
+
// 'nv12': biplanar Y + CbCr surfaces, for GPUDevice.importExternalTexture.
|
|
132
|
+
// On Android the decoder always writes its native YUV layout (reported as
|
|
133
|
+
// 'nv12'), which only importExternalTexture samples; the option is ignored.
|
|
81
134
|
pixelFormat?: NativeVideoPixelFormat;
|
|
82
135
|
}
|
|
83
136
|
|
|
137
|
+
// A React Native view to draw with GPUQueue.drawElementImageToTexture: a host
|
|
138
|
+
// component ref (`useRef` object), the host instance itself (`ref.current`),
|
|
139
|
+
// or the numeric tag returned by findNodeHandle. On worklet runtimes (no
|
|
140
|
+
// findNodeHandle) pass the instance or the tag.
|
|
141
|
+
export type GPUDrawElementImageSourceView =
|
|
142
|
+
number | { current: unknown } | React.Component | object;
|
|
143
|
+
|
|
144
|
+
// The source argument of drawElementImageToTexture, modeled on the
|
|
145
|
+
// html-in-canvas proposal's GPUDrawElementImageSource. The optional rectangle
|
|
146
|
+
// selects the part of the view to draw, in the view's own coordinate space
|
|
147
|
+
// and in density-independent points (React Native layout units); it defaults
|
|
148
|
+
// to the whole view.
|
|
149
|
+
export interface GPUDrawElementImageSource {
|
|
150
|
+
source: GPUDrawElementImageSourceView;
|
|
151
|
+
sourceX?: number;
|
|
152
|
+
sourceY?: number;
|
|
153
|
+
sourceWidth?: number;
|
|
154
|
+
sourceHeight?: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// The destination argument of drawElementImageToTexture:
|
|
158
|
+
// GPUCopyExternalImageDestInfo plus the pixel size of the region the view is
|
|
159
|
+
// drawn into. `size` defaults to the source rectangle's natural pixel size
|
|
160
|
+
// (points times the device pixel ratio); pass it explicitly to scale the view
|
|
161
|
+
// to the destination region.
|
|
162
|
+
export interface GPUDrawElementImageDestination extends GPUCopyExternalImageDestInfo {
|
|
163
|
+
size?: GPUExtent3DStrict;
|
|
164
|
+
}
|
|
165
|
+
|
|
84
166
|
export interface GPUSharedTextureMemoryDescriptor {
|
|
85
167
|
// Raw native handle (IOSurfaceRef on Apple, AHardwareBuffer* on Android),
|
|
86
168
|
// encoded as a BigInt. The caller is responsible for keeping the underlying
|
package/src/video.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CreateVideoPlayerOptions,
|
|
3
|
+
NativeVideoFrame,
|
|
4
|
+
VideoPlayer,
|
|
5
|
+
} from "./types";
|
|
6
|
+
|
|
7
|
+
const native = (name: string) => {
|
|
8
|
+
if (typeof RNWebGPU === "undefined") {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`react-native-webgpu is not installed natively; ${name} is unavailable`,
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return RNWebGPU;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Decodes a video into native frames the GPU samples without any copy.
|
|
18
|
+
*
|
|
19
|
+
* `source` is a URL (`http`, `https`, `file`) or a file path. Playback is
|
|
20
|
+
* controlled like an HTMLMediaElement (`play()`, `pause()`, `currentTime`,
|
|
21
|
+
* `loop`, `volume`); frames are pulled with `copyLatestFrame()` on every
|
|
22
|
+
* render tick and sampled through `importExternalTexture()` or
|
|
23
|
+
* `importSharedTextureMemory()`:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const player = createVideoPlayer(url);
|
|
27
|
+
* player.play();
|
|
28
|
+
* const render = () => {
|
|
29
|
+
* const frame = player.copyLatestFrame();
|
|
30
|
+
* if (frame) {
|
|
31
|
+
* // import, draw, then release once the frame is no longer sampled
|
|
32
|
+
* }
|
|
33
|
+
* requestAnimationFrame(render);
|
|
34
|
+
* };
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* On Apple platforms the frames are BGRA by default, or NV12 with
|
|
38
|
+
* `{ pixelFormat: "nv12" }`. On Android they are always in the decoder's
|
|
39
|
+
* native YUV layout, for `importExternalTexture()`.
|
|
40
|
+
*/
|
|
41
|
+
export const createVideoPlayer = (
|
|
42
|
+
source: string,
|
|
43
|
+
options?: CreateVideoPlayerOptions,
|
|
44
|
+
): VideoPlayer =>
|
|
45
|
+
native("createVideoPlayer").createVideoPlayer(source, options?.pixelFormat);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Wraps a native buffer produced by another library (a `CVPixelBufferRef` on
|
|
49
|
+
* Apple platforms, an `AHardwareBuffer*` on Android, for instance
|
|
50
|
+
* VisionCamera's `frame.getNativeBuffer().pointer`) into a `NativeVideoFrame`
|
|
51
|
+
* that keeps it alive until released.
|
|
52
|
+
*/
|
|
53
|
+
export const createVideoFrameFromNativeBuffer = (
|
|
54
|
+
pointer: bigint,
|
|
55
|
+
): NativeVideoFrame =>
|
|
56
|
+
native("createVideoFrameFromNativeBuffer").createVideoFrameFromNativeBuffer(
|
|
57
|
+
pointer,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Allocates a native frame of the given size filled with a test pattern (a
|
|
62
|
+
* red/green gradient with diagonal stripes in the blue channel), for examples
|
|
63
|
+
* and tests that need a frame without a camera or a video.
|
|
64
|
+
*/
|
|
65
|
+
export const createTestVideoFrame = (
|
|
66
|
+
width: number,
|
|
67
|
+
height: number,
|
|
68
|
+
): NativeVideoFrame =>
|
|
69
|
+
native("createTestVideoFrame").createTestVideoFrame(width, height);
|