react-native-skia-webgpu-video 0.0.0-stage → 0.1.0-beta.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/LICENSE +22 -0
- package/README.md +303 -2
- package/android/BUILD_VALIDATION.md +62 -0
- package/android/CMakeLists.txt +99 -0
- package/android/build-validation.json +262 -0
- package/android/build.gradle +185 -0
- package/android/cpp/EncoderTargets.cpp +226 -0
- package/android/cpp/EncoderTargets.h +70 -0
- package/android/cpp/JNIHelpers.cpp +15 -0
- package/android/cpp/JNIHelpers.h +20 -0
- package/android/cpp/NativeEventDispatcher.cpp +59 -0
- package/android/cpp/NativeEventDispatcher.h +31 -0
- package/android/cpp/NativeHardwareBuffer.cpp +397 -0
- package/android/cpp/NativeHardwareBuffer.h +34 -0
- package/android/cpp/NativeRgbaBuffer.cpp +45 -0
- package/android/cpp/NativeRgbaBuffer.h +9 -0
- package/android/cpp/ReturnedVideoFrames.h +37 -0
- package/android/cpp/RgbaFrameLease.h +53 -0
- package/android/cpp/VideoCapabilities.cpp +87 -0
- package/android/cpp/VideoCapabilities.h +44 -0
- package/android/cpp/VideoComposition.cpp +170 -0
- package/android/cpp/VideoComposition.h +36 -0
- package/android/cpp/VideoCompositionFramesExtractor.cpp +82 -0
- package/android/cpp/VideoCompositionFramesExtractor.h +48 -0
- package/android/cpp/VideoCompositionFramesExtractorHostObject.cpp +230 -0
- package/android/cpp/VideoCompositionFramesExtractorHostObject.h +42 -0
- package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.cpp +133 -0
- package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.h +46 -0
- package/android/cpp/VideoEncoderHostObject.cpp +318 -0
- package/android/cpp/VideoEncoderHostObject.h +76 -0
- package/android/cpp/VideoFrame.cpp +293 -0
- package/android/cpp/VideoFrame.h +27 -0
- package/android/cpp/VideoPlayer.cpp +96 -0
- package/android/cpp/VideoPlayer.h +52 -0
- package/android/cpp/VideoPlayerHostObject.cpp +225 -0
- package/android/cpp/VideoPlayerHostObject.h +43 -0
- package/android/cpp/cpp-adapter.cpp +316 -0
- package/android/gradle.properties +5 -0
- package/android/instrumentation-inventory.json +178 -0
- package/android/proguard-rules.pro +4 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/azzapp/rnskv/AudioCompositionExporter.java +537 -0
- package/android/src/main/java/com/azzapp/rnskv/AudioCompositionPlayer.java +321 -0
- package/android/src/main/java/com/azzapp/rnskv/BufferLifetime.java +55 -0
- package/android/src/main/java/com/azzapp/rnskv/DecodeRequests.java +100 -0
- package/android/src/main/java/com/azzapp/rnskv/DecoderWindow.java +55 -0
- package/android/src/main/java/com/azzapp/rnskv/EGLResourcesHolder.java +132 -0
- package/android/src/main/java/com/azzapp/rnskv/EGLUtils.java +225 -0
- package/android/src/main/java/com/azzapp/rnskv/FrameSize.java +50 -0
- package/android/src/main/java/com/azzapp/rnskv/GLFrameExtractor.java +510 -0
- package/android/src/main/java/com/azzapp/rnskv/JNIHelpers.java +12 -0
- package/android/src/main/java/com/azzapp/rnskv/NativeEventDispatcher.java +25 -0
- package/android/src/main/java/com/azzapp/rnskv/NativeHardwareBuffer.java +62 -0
- package/android/src/main/java/com/azzapp/rnskv/NativeRgbaBuffer.java +35 -0
- package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoModule.java +45 -0
- package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoPackage.java +43 -0
- package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoSpec.java +9 -0
- package/android/src/main/java/com/azzapp/rnskv/RgbaBufferAllocator.java +83 -0
- package/android/src/main/java/com/azzapp/rnskv/RgbaLayout.java +33 -0
- package/android/src/main/java/com/azzapp/rnskv/SurfaceOutputPolicy.java +13 -0
- package/android/src/main/java/com/azzapp/rnskv/TextureRenderer.java +150 -0
- package/android/src/main/java/com/azzapp/rnskv/TimeHelpers.java +11 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoCapabilities.java +354 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoComposition.java +147 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoCompositionDecoder.java +772 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractor.java +354 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractorSync.java +241 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoCompositionItemDecoder.java +492 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoEncoder.java +639 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoFrame.java +74 -0
- package/android/src/main/java/com/azzapp/rnskv/VideoPlayer.java +361 -0
- package/cpp/RNSVCheckedSizes.h +54 -0
- package/cpp/RNSVEventEmitter.cpp +199 -0
- package/cpp/RNSVEventEmitter.h +31 -0
- package/cpp/RNSVHostObject.cpp +79 -0
- package/cpp/RNSVHostObject.h +67 -0
- package/cpp/RNSVMemoryBudget.cpp +68 -0
- package/cpp/RNSVMemoryBudget.h +100 -0
- package/cpp/RNSVRuntimeLifecycleMonitor.cpp +88 -0
- package/cpp/RNSVRuntimeLifecycleMonitor.h +33 -0
- package/docs/ANDROID_DEVICE_306.md +95 -0
- package/docs/ANDROID_EXPORT_CACHE_306.md +48 -0
- package/docs/ANDROID_MEMORY_RETENTION_306.md +67 -0
- package/docs/BENCHMARKS.md +368 -0
- package/docs/IOS_DEVICE_TESTS.md +115 -0
- package/docs/IOS_SIMULATOR_TESTS.md +74 -0
- package/docs/MIGRATION.md +82 -0
- package/docs/NATIVE_MEMORY_INVESTIGATION_306.md +88 -0
- package/docs/PERFORMANCE_AB_IPHONE_303.md +196 -0
- package/docs/PERFORMANCE_AB_SIMULATOR.md +135 -0
- package/docs/PERFORMANCE_AB_SOAK_SIMULATOR.md +84 -0
- package/docs/PERFORMANCE_IPHONE_306_OPTIMIZATION.md +76 -0
- package/docs/PERFORMANCE_SIMULATOR.md +89 -0
- package/docs/PERFORMANCE_SIMULATOR_INITIAL.md +96 -0
- package/docs/PERFORMANCE_SOAK_IPHONE_303.md +41 -0
- package/docs/UPSTREAM_NOTES.md +188 -0
- package/docs/assets/banner.svg +26 -0
- package/examples/webgpu-overlay.ts +147 -0
- package/ios/AVAssetTrackUtils.h +24 -0
- package/ios/AudioCompositionUtils.h +27 -0
- package/ios/AudioCompositionUtils.mm +113 -0
- package/ios/DecoderWindow.h +52 -0
- package/ios/NativeResourceStats.h +32 -0
- package/ios/RNSVColorSpace.h +50 -0
- package/ios/RNSVJSIUtils.h +46 -0
- package/ios/RNSVScopedPixelBuffer.h +17 -0
- package/ios/RNSVVideoPlayer.h +46 -0
- package/ios/RNSVVideoPlayer.mm +410 -0
- package/ios/ReactNativeSkiaVideo.h +8 -0
- package/ios/ReactNativeSkiaVideo.mm +310 -0
- package/ios/SeekPolicy.h +27 -0
- package/ios/VideoComposition.h +148 -0
- package/ios/VideoCompositionFramesExtractorHostObject.h +105 -0
- package/ios/VideoCompositionFramesExtractorHostObject.mm +686 -0
- package/ios/VideoCompositionFramesExtractorSyncHostObject.h +37 -0
- package/ios/VideoCompositionFramesExtractorSyncHostObject.mm +168 -0
- package/ios/VideoCompositionItemDecoder.h +60 -0
- package/ios/VideoCompositionItemDecoder.mm +480 -0
- package/ios/VideoEncoderHostObject.h +83 -0
- package/ios/VideoEncoderHostObject.mm +706 -0
- package/ios/VideoFrame.h +66 -0
- package/ios/VideoFrame.mm +108 -0
- package/ios/VideoPlayerHostObject.h +52 -0
- package/ios/VideoPlayerHostObject.mm +332 -0
- package/lib/module/NativeReactNativeSkiaVideo.js +5 -0
- package/lib/module/NativeReactNativeSkiaVideo.js.map +1 -0
- package/lib/module/RNSkiaVideoModule.js +20 -0
- package/lib/module/RNSkiaVideoModule.js.map +1 -0
- package/lib/module/canvas.js +18 -0
- package/lib/module/canvas.js.map +1 -0
- package/lib/module/exportCache.js +22 -0
- package/lib/module/exportCache.js.map +1 -0
- package/lib/module/exportFrames.js +338 -0
- package/lib/module/exportFrames.js.map +1 -0
- package/lib/module/exportQueue.js +52 -0
- package/lib/module/exportQueue.js.map +1 -0
- package/lib/module/exportTarget.js +137 -0
- package/lib/module/exportTarget.js.map +1 -0
- package/lib/module/exportVideoComposition.js +492 -0
- package/lib/module/exportVideoComposition.js.map +1 -0
- package/lib/module/frameInterop.js +532 -0
- package/lib/module/frameInterop.js.map +1 -0
- package/lib/module/gpu.js +222 -0
- package/lib/module/gpu.js.map +1 -0
- package/lib/module/gpuDevice.js +54 -0
- package/lib/module/gpuDevice.js.map +1 -0
- package/lib/module/index.js +36 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/memory.js +38 -0
- package/lib/module/memory.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/previewLifecycle.js +52 -0
- package/lib/module/previewLifecycle.js.map +1 -0
- package/lib/module/runtimeYield.js +10 -0
- package/lib/module/runtimeYield.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/useEventListener.js +18 -0
- package/lib/module/utils/useEventListener.js.map +1 -0
- package/lib/module/videoCompositionPlayer.js +348 -0
- package/lib/module/videoCompositionPlayer.js.map +1 -0
- package/lib/module/videoFrameImage.js +185 -0
- package/lib/module/videoFrameImage.js.map +1 -0
- package/lib/module/videoPlayer.js +172 -0
- package/lib/module/videoPlayer.js.map +1 -0
- package/lib/module/yuvBlit.js +299 -0
- package/lib/module/yuvBlit.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts +7 -0
- package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts.map +1 -0
- package/lib/typescript/src/RNSkiaVideoModule.d.ts +4 -0
- package/lib/typescript/src/RNSkiaVideoModule.d.ts.map +1 -0
- package/lib/typescript/src/canvas.d.ts +4 -0
- package/lib/typescript/src/canvas.d.ts.map +1 -0
- package/lib/typescript/src/exportCache.d.ts +6 -0
- package/lib/typescript/src/exportCache.d.ts.map +1 -0
- package/lib/typescript/src/exportFrames.d.ts +57 -0
- package/lib/typescript/src/exportFrames.d.ts.map +1 -0
- package/lib/typescript/src/exportQueue.d.ts +5 -0
- package/lib/typescript/src/exportQueue.d.ts.map +1 -0
- package/lib/typescript/src/exportTarget.d.ts +28 -0
- package/lib/typescript/src/exportTarget.d.ts.map +1 -0
- package/lib/typescript/src/exportVideoComposition.d.ts +68 -0
- package/lib/typescript/src/exportVideoComposition.d.ts.map +1 -0
- package/lib/typescript/src/frameInterop.d.ts +17 -0
- package/lib/typescript/src/frameInterop.d.ts.map +1 -0
- package/lib/typescript/src/gpu.d.ts +39 -0
- package/lib/typescript/src/gpu.d.ts.map +1 -0
- package/lib/typescript/src/gpuDevice.d.ts +11 -0
- package/lib/typescript/src/gpuDevice.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +21 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/memory.d.ts +25 -0
- package/lib/typescript/src/memory.d.ts.map +1 -0
- package/lib/typescript/src/previewLifecycle.d.ts +22 -0
- package/lib/typescript/src/previewLifecycle.d.ts.map +1 -0
- package/lib/typescript/src/runtimeYield.d.ts +4 -0
- package/lib/typescript/src/runtimeYield.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +631 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/useEventListener.d.ts +5 -0
- package/lib/typescript/src/utils/useEventListener.d.ts.map +1 -0
- package/lib/typescript/src/videoCompositionPlayer.d.ts +85 -0
- package/lib/typescript/src/videoCompositionPlayer.d.ts.map +1 -0
- package/lib/typescript/src/videoFrameImage.d.ts +60 -0
- package/lib/typescript/src/videoFrameImage.d.ts.map +1 -0
- package/lib/typescript/src/videoPlayer.d.ts +99 -0
- package/lib/typescript/src/videoPlayer.d.ts.map +1 -0
- package/lib/typescript/src/yuvBlit.d.ts +50 -0
- package/lib/typescript/src/yuvBlit.d.ts.map +1 -0
- package/package.json +154 -4
- package/patches/react-native-skia+3.7.0.patch +502 -0
- package/react-native-skia-webgpu-video.podspec +35 -0
- package/scripts/apply-skia-canvas-patch.mjs +48 -0
- package/scripts/skia-canvas-patch.json +291 -0
- package/src/NativeReactNativeSkiaVideo.ts +8 -0
- package/src/RNSkiaVideoModule.ts +27 -0
- package/src/canvas.ts +22 -0
- package/src/exportCache.ts +27 -0
- package/src/exportFrames.ts +421 -0
- package/src/exportQueue.ts +65 -0
- package/src/exportTarget.ts +179 -0
- package/src/exportVideoComposition.ts +718 -0
- package/src/frameInterop.ts +684 -0
- package/src/gpu.ts +290 -0
- package/src/gpuDevice.ts +80 -0
- package/src/index.tsx +45 -0
- package/src/memory.ts +48 -0
- package/src/previewLifecycle.ts +60 -0
- package/src/runtimeYield.ts +6 -0
- package/src/types.ts +661 -0
- package/src/utils/useEventListener.ts +22 -0
- package/src/videoCompositionPlayer.ts +520 -0
- package/src/videoFrameImage.ts +205 -0
- package/src/videoPlayer.ts +318 -0
- package/src/yuvBlit.ts +331 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useSharedValue, useFrameCallback } from "react-native-reanimated";
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
|
+
import useEventListener from "./utils/useEventListener.js";
|
|
6
|
+
import RNSkiaVideoModule from "./RNSkiaVideoModule.js";
|
|
7
|
+
import { imageFromVideoFrame, releaseVideoFrameImage } from "./frameInterop.js";
|
|
8
|
+
import { runOnUI } from "react-native-reanimated";
|
|
9
|
+
import { scheduleOnRN } from "react-native-worklets";
|
|
10
|
+
import { disposePreviewResources } from "./previewLifecycle.js";
|
|
11
|
+
/**
|
|
12
|
+
* Hook that creates a video player and manages its state.
|
|
13
|
+
* @param options The options for the video player.
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const useVideoPlayback = ({
|
|
17
|
+
uri,
|
|
18
|
+
resolution,
|
|
19
|
+
textureMode,
|
|
20
|
+
autoPlay = false,
|
|
21
|
+
isLooping = false,
|
|
22
|
+
volume = 1,
|
|
23
|
+
playbackSpeed = 1,
|
|
24
|
+
onReadyToPlay,
|
|
25
|
+
onBufferingStart,
|
|
26
|
+
onBufferingEnd,
|
|
27
|
+
onBufferingUpdate,
|
|
28
|
+
onComplete,
|
|
29
|
+
onError,
|
|
30
|
+
onPlayingStatusChange,
|
|
31
|
+
onSeekComplete
|
|
32
|
+
}) => {
|
|
33
|
+
const sourceKey = JSON.stringify([uri, resolution?.width, resolution?.height, textureMode]);
|
|
34
|
+
const [failedSource, setFailedSource] = useState(null);
|
|
35
|
+
const isErrored = failedSource === sourceKey;
|
|
36
|
+
const [session, setSession] = useState(null);
|
|
37
|
+
const player = session?.player ?? null;
|
|
38
|
+
const generation = session?.generation ?? 0;
|
|
39
|
+
const nextGeneration = useRef(0);
|
|
40
|
+
const activeOnRN = useRef(0);
|
|
41
|
+
const currentFrame = useSharedValue(null);
|
|
42
|
+
const activeGeneration = useSharedValue(0);
|
|
43
|
+
const frameGeneration = useSharedValue(0);
|
|
44
|
+
const onCreationError = useRef(onError);
|
|
45
|
+
onCreationError.current = onError;
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!uri || isErrored) {
|
|
48
|
+
setSession(null);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
let created;
|
|
52
|
+
try {
|
|
53
|
+
created = RNSkiaVideoModule.createVideoPlayer(uri, resolution, textureMode ? {
|
|
54
|
+
textureMode
|
|
55
|
+
} : undefined);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
setFailedSource(sourceKey);
|
|
58
|
+
onCreationError.current?.(error, () => setFailedSource(null));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const createdGeneration = ++nextGeneration.current;
|
|
62
|
+
activeOnRN.current = createdGeneration;
|
|
63
|
+
activeGeneration.value = createdGeneration;
|
|
64
|
+
setSession({
|
|
65
|
+
player: created,
|
|
66
|
+
generation: createdGeneration,
|
|
67
|
+
sourceKey
|
|
68
|
+
});
|
|
69
|
+
return () => {
|
|
70
|
+
if (activeOnRN.current === createdGeneration) {
|
|
71
|
+
activeOnRN.current = 0;
|
|
72
|
+
activeGeneration.value = 0;
|
|
73
|
+
}
|
|
74
|
+
runOnUI(() => {
|
|
75
|
+
"worklet";
|
|
76
|
+
|
|
77
|
+
const frames = [];
|
|
78
|
+
if (frameGeneration.value === createdGeneration) {
|
|
79
|
+
const frame = currentFrame.value;
|
|
80
|
+
currentFrame.value = null;
|
|
81
|
+
frameGeneration.value = 0;
|
|
82
|
+
if (frame) frames.push(frame);
|
|
83
|
+
}
|
|
84
|
+
const failure = disposePreviewResources({
|
|
85
|
+
frames,
|
|
86
|
+
native: created
|
|
87
|
+
});
|
|
88
|
+
if (failure.failed) console.warn("Video preview cleanup failed; resources remain accounted until native runtime teardown", failure.error);
|
|
89
|
+
})();
|
|
90
|
+
};
|
|
91
|
+
// Resolution object identity does not recreate an unchanged decoder.
|
|
92
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
93
|
+
}, [isErrored, sourceKey, resolution?.width, resolution?.height, uri, textureMode, currentFrame, activeGeneration, frameGeneration]);
|
|
94
|
+
const retry = useCallback(() => {
|
|
95
|
+
setFailedSource(null);
|
|
96
|
+
}, []);
|
|
97
|
+
const errorHandler = useCallback(error => {
|
|
98
|
+
if (generation !== activeOnRN.current) return;
|
|
99
|
+
activeOnRN.current = 0;
|
|
100
|
+
activeGeneration.value = 0;
|
|
101
|
+
setFailedSource(session.sourceKey);
|
|
102
|
+
onCreationError.current?.(error, retry);
|
|
103
|
+
}, [retry, generation, activeGeneration, session]);
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (player) {
|
|
106
|
+
player.isLooping = isLooping;
|
|
107
|
+
}
|
|
108
|
+
}, [player, isLooping]);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (player) {
|
|
111
|
+
player.volume = volume;
|
|
112
|
+
}
|
|
113
|
+
}, [player, volume]);
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (player) {
|
|
116
|
+
player.playbackSpeed = playbackSpeed;
|
|
117
|
+
}
|
|
118
|
+
}, [player, playbackSpeed]);
|
|
119
|
+
const isCurrentSession = useCallback(() => generation !== 0 && generation === activeOnRN.current, [generation]);
|
|
120
|
+
useEventListener(player, "ready", onReadyToPlay, isCurrentSession);
|
|
121
|
+
useEventListener(player, "bufferingStart", onBufferingStart, isCurrentSession);
|
|
122
|
+
useEventListener(player, "bufferingEnd", onBufferingEnd, isCurrentSession);
|
|
123
|
+
useEventListener(player, "bufferingUpdate", onBufferingUpdate, isCurrentSession);
|
|
124
|
+
useEventListener(player, "complete", onComplete, isCurrentSession);
|
|
125
|
+
useEventListener(player, "error", errorHandler, isCurrentSession);
|
|
126
|
+
useEventListener(player, "playingStatusChange", onPlayingStatusChange, isCurrentSession);
|
|
127
|
+
useEventListener(player, "seekComplete", onSeekComplete, isCurrentSession);
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (autoPlay) {
|
|
130
|
+
player?.play();
|
|
131
|
+
}
|
|
132
|
+
}, [player, autoPlay]);
|
|
133
|
+
useFrameCallback(() => {
|
|
134
|
+
if (!player || activeGeneration.value !== generation) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
// Polled while paused too: decodeNextFrame returns null at almost no cost
|
|
138
|
+
// when nothing new was decoded, and the frame produced by a seek performed
|
|
139
|
+
// while paused only shows up if it gets picked up here.
|
|
140
|
+
try {
|
|
141
|
+
const nextFrame = player.decodeNextFrame();
|
|
142
|
+
if (nextFrame) {
|
|
143
|
+
const image = imageFromVideoFrame(nextFrame);
|
|
144
|
+
if (image) {
|
|
145
|
+
const previous = currentFrame.value;
|
|
146
|
+
if (previous && previous.producerId !== nextFrame.producerId) releaseVideoFrameImage(previous);
|
|
147
|
+
frameGeneration.value = generation;
|
|
148
|
+
currentFrame.value = {
|
|
149
|
+
width: nextFrame.width,
|
|
150
|
+
height: nextFrame.height,
|
|
151
|
+
rotation: nextFrame.rotation,
|
|
152
|
+
crop: nextFrame.crop,
|
|
153
|
+
id: nextFrame.id,
|
|
154
|
+
producerId: nextFrame.producerId,
|
|
155
|
+
texture: {
|
|
156
|
+
kind: "skia-image",
|
|
157
|
+
image
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
activeGeneration.value = 0;
|
|
164
|
+
scheduleOnRN(errorHandler, error);
|
|
165
|
+
}
|
|
166
|
+
}, true);
|
|
167
|
+
return {
|
|
168
|
+
currentFrame,
|
|
169
|
+
player
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=videoPlayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useSharedValue","useFrameCallback","useCallback","useEffect","useRef","useState","useEventListener","RNSkiaVideoModule","imageFromVideoFrame","releaseVideoFrameImage","runOnUI","scheduleOnRN","disposePreviewResources","useVideoPlayback","uri","resolution","textureMode","autoPlay","isLooping","volume","playbackSpeed","onReadyToPlay","onBufferingStart","onBufferingEnd","onBufferingUpdate","onComplete","onError","onPlayingStatusChange","onSeekComplete","sourceKey","JSON","stringify","width","height","failedSource","setFailedSource","isErrored","session","setSession","player","generation","nextGeneration","activeOnRN","currentFrame","activeGeneration","frameGeneration","onCreationError","current","created","createVideoPlayer","undefined","error","createdGeneration","value","frames","frame","push","failure","native","failed","console","warn","retry","errorHandler","isCurrentSession","play","nextFrame","decodeNextFrame","image","previous","producerId","rotation","crop","id","texture","kind"],"sourceRoot":"../../src","sources":["videoPlayer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/// <reference types="@webgpu/types" />
|
|
4
|
+
|
|
5
|
+
import { createNativeVideoGpuFrame, videoShaderStages, videoUniformBufferUsage } from "./gpuDevice.js";
|
|
6
|
+
|
|
7
|
+
/** One Android decoder buffer, imported once as an external texture. An
|
|
8
|
+
* ImageReader cycles through a few buffers: each one is imported the first
|
|
9
|
+
* time it shows up, then only its access is opened and closed per frame. */
|
|
10
|
+
|
|
11
|
+
// An ImageReader holds four buffers (GLFrameExtractor.READER_IMAGES); the
|
|
12
|
+
// slack covers a reader replaced while the clip keeps its producer id.
|
|
13
|
+
const maxImportsPerProducer = 6;
|
|
14
|
+
|
|
15
|
+
// The copyExternalImageToTexture blit of RN WebGPU (VideoFrameBlit.h), opaque
|
|
16
|
+
// and without its sRGB destination variant: uv = position01 * scale + offset,
|
|
17
|
+
// in the upright frame.
|
|
18
|
+
const shader = `
|
|
19
|
+
struct Uniforms { uvScale: vec2f, uvOffset: vec2f };
|
|
20
|
+
@group(0) @binding(0) var frame: texture_external;
|
|
21
|
+
@group(0) @binding(1) var frameSampler: sampler;
|
|
22
|
+
@group(0) @binding(2) var<uniform> u: Uniforms;
|
|
23
|
+
struct VsOut { @builtin(position) position: vec4f, @location(0) uv: vec2f };
|
|
24
|
+
@vertex fn vs(@builtin(vertex_index) index: u32) -> VsOut {
|
|
25
|
+
var corners = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
|
|
26
|
+
let corner = corners[index];
|
|
27
|
+
var out: VsOut;
|
|
28
|
+
out.position = vec4f(corner, 0.0, 1.0);
|
|
29
|
+
let position01 = vec2f(corner.x * 0.5 + 0.5, 0.5 - corner.y * 0.5);
|
|
30
|
+
out.uv = position01 * u.uvScale + u.uvOffset;
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
@fragment fn fs(in: VsOut) -> @location(0) vec4f {
|
|
34
|
+
let sampled = textureSampleBaseClampToEdge(frame, frameSampler, in.uv);
|
|
35
|
+
return vec4f(clamp(sampled.rgb, vec3f(0.0), vec3f(1.0)), 1.0);
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
// The samples' encoding is kept as is, as the EGL path and iOS decoding do:
|
|
40
|
+
// only the YCbCr matrix and range apply (the driver's suggestion for the
|
|
41
|
+
// buffer). Without this, Dawn also converts the video's transfer function and
|
|
42
|
+
// primaries to sRGB, and every export brightens the midtones again.
|
|
43
|
+
const sourceColorSpace = {
|
|
44
|
+
primaries: "srgb",
|
|
45
|
+
transfer: "srgb"
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** The corner of a decoder buffer's crop rectangle once the buffer is turned
|
|
49
|
+
* clockwise for display: the blit takes its source origin in that turned
|
|
50
|
+
* space. Throws unless the rectangle lies in the buffer and turns into the
|
|
51
|
+
* frame's display size. */
|
|
52
|
+
export const yuvFrameOrigin = (region, rotation, buffer, frame) => {
|
|
53
|
+
"worklet";
|
|
54
|
+
|
|
55
|
+
const turned = rotation === 90 || rotation === 270;
|
|
56
|
+
if (rotation !== 0 && !turned && rotation !== 180 || region.x < 0 || region.y < 0 || region.x + region.width > buffer.width || region.y + region.height > buffer.height || (turned ? region.height : region.width) !== frame.width || (turned ? region.width : region.height) !== frame.height) {
|
|
57
|
+
throw new Error("Native video buffer region or YUV layout mismatch");
|
|
58
|
+
}
|
|
59
|
+
const {
|
|
60
|
+
width,
|
|
61
|
+
height
|
|
62
|
+
} = buffer;
|
|
63
|
+
if (rotation === 90) return {
|
|
64
|
+
x: height - region.y - region.height,
|
|
65
|
+
y: region.x
|
|
66
|
+
};
|
|
67
|
+
if (rotation === 180) return {
|
|
68
|
+
x: width - region.x - region.width,
|
|
69
|
+
y: height - region.y - region.height
|
|
70
|
+
};
|
|
71
|
+
if (rotation === 270) return {
|
|
72
|
+
x: region.y,
|
|
73
|
+
y: width - region.x - region.width
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
x: region.x,
|
|
77
|
+
y: region.y
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const getYuvBlit = device => {
|
|
81
|
+
"worklet";
|
|
82
|
+
|
|
83
|
+
const runtime = globalThis;
|
|
84
|
+
if (!runtime.__rnskwgpuYuvBlit) {
|
|
85
|
+
const layout = device.createBindGroupLayout({
|
|
86
|
+
label: "video YUV blit",
|
|
87
|
+
entries: [{
|
|
88
|
+
binding: 0,
|
|
89
|
+
visibility: videoShaderStages.fragment,
|
|
90
|
+
externalTexture: {}
|
|
91
|
+
}, {
|
|
92
|
+
binding: 1,
|
|
93
|
+
visibility: videoShaderStages.fragment,
|
|
94
|
+
sampler: {
|
|
95
|
+
type: "filtering"
|
|
96
|
+
}
|
|
97
|
+
}, {
|
|
98
|
+
binding: 2,
|
|
99
|
+
visibility: videoShaderStages.vertex,
|
|
100
|
+
buffer: {
|
|
101
|
+
type: "uniform"
|
|
102
|
+
}
|
|
103
|
+
}]
|
|
104
|
+
});
|
|
105
|
+
runtime.__rnskwgpuYuvBlit = {
|
|
106
|
+
layout,
|
|
107
|
+
pipelineLayout: device.createPipelineLayout({
|
|
108
|
+
label: "video YUV blit",
|
|
109
|
+
bindGroupLayouts: [layout]
|
|
110
|
+
}),
|
|
111
|
+
sampler: device.createSampler({
|
|
112
|
+
label: "video YUV blit",
|
|
113
|
+
magFilter: "linear",
|
|
114
|
+
minFilter: "linear"
|
|
115
|
+
}),
|
|
116
|
+
module: device.createShaderModule({
|
|
117
|
+
label: "video YUV blit",
|
|
118
|
+
code: shader
|
|
119
|
+
}),
|
|
120
|
+
pipelines: new Map()
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return runtime.__rnskwgpuYuvBlit;
|
|
124
|
+
};
|
|
125
|
+
const getPipeline = (device, blit, format) => {
|
|
126
|
+
"worklet";
|
|
127
|
+
|
|
128
|
+
let pipeline = blit.pipelines.get(format);
|
|
129
|
+
if (!pipeline) {
|
|
130
|
+
pipeline = device.createRenderPipeline({
|
|
131
|
+
label: "video YUV blit",
|
|
132
|
+
layout: blit.pipelineLayout,
|
|
133
|
+
vertex: {
|
|
134
|
+
module: blit.module,
|
|
135
|
+
entryPoint: "vs"
|
|
136
|
+
},
|
|
137
|
+
fragment: {
|
|
138
|
+
module: blit.module,
|
|
139
|
+
entryPoint: "fs",
|
|
140
|
+
targets: [{
|
|
141
|
+
format
|
|
142
|
+
}]
|
|
143
|
+
},
|
|
144
|
+
primitive: {
|
|
145
|
+
topology: "triangle-list"
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
blit.pipelines.set(format, pipeline);
|
|
149
|
+
}
|
|
150
|
+
return pipeline;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/** Call only once the GPU work sampling the buffer has completed. */
|
|
154
|
+
export const releaseYuvImport = entry => {
|
|
155
|
+
"worklet";
|
|
156
|
+
|
|
157
|
+
entry.wrapper.destroy();
|
|
158
|
+
entry.uniforms.destroy();
|
|
159
|
+
entry.source.release();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/** Releases a producer's imports, or every producer's. Call only once the GPU
|
|
163
|
+
* work sampling them has completed (a checked flush). */
|
|
164
|
+
export const releaseYuvImports = (imports, producer) => {
|
|
165
|
+
"worklet";
|
|
166
|
+
|
|
167
|
+
for (const [key, entries] of imports) {
|
|
168
|
+
if (producer !== undefined && key !== producer) continue;
|
|
169
|
+
while (entries.length) {
|
|
170
|
+
releaseYuvImport(entries[0]);
|
|
171
|
+
entries.shift();
|
|
172
|
+
}
|
|
173
|
+
imports.delete(key);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const importYuvBuffer = (device, blit, handle, rotation) => {
|
|
177
|
+
"worklet";
|
|
178
|
+
|
|
179
|
+
// A reference of its own: the caller's frame keeps its usual lifetime.
|
|
180
|
+
const source = createNativeVideoGpuFrame(handle);
|
|
181
|
+
let wrapper = null;
|
|
182
|
+
let uniforms = null;
|
|
183
|
+
try {
|
|
184
|
+
wrapper = device.createNativeBufferExternalTexture(source, {
|
|
185
|
+
label: "video decoder buffer",
|
|
186
|
+
rotation: rotation,
|
|
187
|
+
mirrored: false,
|
|
188
|
+
sourceColorSpace
|
|
189
|
+
});
|
|
190
|
+
uniforms = device.createBuffer({
|
|
191
|
+
label: "video YUV blit uniforms",
|
|
192
|
+
size: 16,
|
|
193
|
+
usage: videoUniformBufferUsage
|
|
194
|
+
});
|
|
195
|
+
const bindGroup = device.createBindGroup({
|
|
196
|
+
label: "video YUV blit",
|
|
197
|
+
layout: blit.layout,
|
|
198
|
+
entries: [{
|
|
199
|
+
binding: 0,
|
|
200
|
+
resource: wrapper.externalTexture
|
|
201
|
+
}, {
|
|
202
|
+
binding: 1,
|
|
203
|
+
resource: blit.sampler
|
|
204
|
+
}, {
|
|
205
|
+
binding: 2,
|
|
206
|
+
resource: {
|
|
207
|
+
buffer: uniforms
|
|
208
|
+
}
|
|
209
|
+
}]
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
handle,
|
|
213
|
+
rotation,
|
|
214
|
+
source,
|
|
215
|
+
wrapper,
|
|
216
|
+
uniforms,
|
|
217
|
+
bindGroup,
|
|
218
|
+
mapping: []
|
|
219
|
+
};
|
|
220
|
+
} catch (error) {
|
|
221
|
+
// Nothing was submitted with this import yet.
|
|
222
|
+
uniforms?.destroy();
|
|
223
|
+
wrapper?.destroy();
|
|
224
|
+
source.release();
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Draws the upright `width`×`height` region at `origin` of a decoder buffer
|
|
231
|
+
* into `target`, converting YUV to RGB; the buffer is imported on its first
|
|
232
|
+
* frame. Submits the draw: the caller waits for it before releasing the
|
|
233
|
+
* frame's lease or `source`, as after copyExternalImageToTexture.
|
|
234
|
+
*/
|
|
235
|
+
export const blitYuvFrame = (device, imports, producer, source, rotation, origin, width, height, target) => {
|
|
236
|
+
"worklet";
|
|
237
|
+
|
|
238
|
+
const blit = getYuvBlit(device);
|
|
239
|
+
const pipeline = getPipeline(device, blit, target.format);
|
|
240
|
+
let entries = imports.get(producer);
|
|
241
|
+
if (!entries) {
|
|
242
|
+
entries = [];
|
|
243
|
+
imports.set(producer, entries);
|
|
244
|
+
}
|
|
245
|
+
let index = entries.findIndex(entry => entry.handle === source.handle && entry.rotation === rotation);
|
|
246
|
+
if (index < 0) {
|
|
247
|
+
// The least recently drawn buffer goes first. Its last frame completed:
|
|
248
|
+
// every import ends with a checked flush before the next one starts.
|
|
249
|
+
if (entries.length >= maxImportsPerProducer) {
|
|
250
|
+
releaseYuvImport(entries[0]);
|
|
251
|
+
entries.shift();
|
|
252
|
+
}
|
|
253
|
+
entries.push(importYuvBuffer(device, blit, source.handle, rotation));
|
|
254
|
+
index = entries.length - 1;
|
|
255
|
+
} else if (index !== entries.length - 1) {
|
|
256
|
+
entries.push(entries.splice(index, 1)[0]);
|
|
257
|
+
index = entries.length - 1;
|
|
258
|
+
}
|
|
259
|
+
const entry = entries[index];
|
|
260
|
+
// Dawn swaps the apparent size of a frame turned by 90 or 270 degrees.
|
|
261
|
+
const turned = rotation === 90 || rotation === 270;
|
|
262
|
+
const frameWidth = turned ? source.height : source.width;
|
|
263
|
+
const frameHeight = turned ? source.width : source.height;
|
|
264
|
+
const mapping = [width / frameWidth, height / frameHeight, origin.x / frameWidth, origin.y / frameHeight];
|
|
265
|
+
if (mapping.some((value, i) => value !== entry.mapping[i])) {
|
|
266
|
+
device.queue.writeBuffer(entry.uniforms, 0, new Float32Array(mapping));
|
|
267
|
+
entry.mapping = mapping;
|
|
268
|
+
}
|
|
269
|
+
entry.wrapper.beginAccess();
|
|
270
|
+
try {
|
|
271
|
+
const encoder = device.createCommandEncoder({
|
|
272
|
+
label: "video YUV blit"
|
|
273
|
+
});
|
|
274
|
+
const pass = encoder.beginRenderPass({
|
|
275
|
+
label: "video YUV blit",
|
|
276
|
+
colorAttachments: [{
|
|
277
|
+
view: target.createView(),
|
|
278
|
+
loadOp: "clear",
|
|
279
|
+
clearValue: {
|
|
280
|
+
r: 0,
|
|
281
|
+
g: 0,
|
|
282
|
+
b: 0,
|
|
283
|
+
a: 1
|
|
284
|
+
},
|
|
285
|
+
storeOp: "store"
|
|
286
|
+
}]
|
|
287
|
+
});
|
|
288
|
+
pass.setPipeline(pipeline);
|
|
289
|
+
pass.setBindGroup(0, entry.bindGroup);
|
|
290
|
+
pass.draw(3);
|
|
291
|
+
pass.end();
|
|
292
|
+
device.queue.submit([encoder.finish()]);
|
|
293
|
+
} finally {
|
|
294
|
+
// The caller's checked flush covers the draw; the release fence is not
|
|
295
|
+
// needed to hand the buffer back.
|
|
296
|
+
entry.wrapper.endAccess()?.fence.destroy();
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=yuvBlit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createNativeVideoGpuFrame","videoShaderStages","videoUniformBufferUsage","maxImportsPerProducer","shader","sourceColorSpace","primaries","transfer","yuvFrameOrigin","region","rotation","buffer","frame","turned","x","y","width","height","Error","getYuvBlit","device","runtime","globalThis","__rnskwgpuYuvBlit","layout","createBindGroupLayout","label","entries","binding","visibility","fragment","externalTexture","sampler","type","vertex","pipelineLayout","createPipelineLayout","bindGroupLayouts","createSampler","magFilter","minFilter","module","createShaderModule","code","pipelines","Map","getPipeline","blit","format","pipeline","get","createRenderPipeline","entryPoint","targets","primitive","topology","set","releaseYuvImport","entry","wrapper","destroy","uniforms","source","release","releaseYuvImports","imports","producer","key","undefined","length","shift","delete","importYuvBuffer","handle","createNativeBufferExternalTexture","mirrored","createBuffer","size","usage","bindGroup","createBindGroup","resource","mapping","error","blitYuvFrame","origin","target","index","findIndex","push","splice","frameWidth","frameHeight","some","value","i","queue","writeBuffer","Float32Array","beginAccess","encoder","createCommandEncoder","pass","beginRenderPass","colorAttachments","view","createView","loadOp","clearValue","r","g","b","a","storeOp","setPipeline","setBindGroup","draw","end","submit","finish","endAccess","fence"],"sourceRoot":"../../src","sources":["yuvBlit.ts"],"mappings":";;AAAA;;AAKA,SACEA,yBAAyB,EACzBC,iBAAiB,EACjBC,uBAAuB,QAClB,gBAAa;;AAEpB;AACA;AACA;;AAqBA;AACA;AACA,MAAMC,qBAAqB,GAAG,CAAC;;AAE/B;AACA;AACA;AACA,MAAMC,MAAM,GAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAMC,gBAAgB,GAAG;EAAEC,SAAS,EAAE,MAAM;EAAEC,QAAQ,EAAE;AAAO,CAAU;;AAEzE;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAGA,CAC5BC,MAA+D,EAC/DC,QAAgB,EAChBC,MAAyC,EACzCC,KAAwC,KACX;EAC7B,SAAS;;EACT,MAAMC,MAAM,GAAGH,QAAQ,KAAK,EAAE,IAAIA,QAAQ,KAAK,GAAG;EAClD,IACGA,QAAQ,KAAK,CAAC,IAAI,CAACG,MAAM,IAAIH,QAAQ,KAAK,GAAG,IAC9CD,MAAM,CAACK,CAAC,GAAG,CAAC,IACZL,MAAM,CAACM,CAAC,GAAG,CAAC,IACZN,MAAM,CAACK,CAAC,GAAGL,MAAM,CAACO,KAAK,GAAGL,MAAM,CAACK,KAAK,IACtCP,MAAM,CAACM,CAAC,GAAGN,MAAM,CAACQ,MAAM,GAAGN,MAAM,CAACM,MAAM,IACxC,CAACJ,MAAM,GAAGJ,MAAM,CAACQ,MAAM,GAAGR,MAAM,CAACO,KAAK,MAAMJ,KAAK,CAACI,KAAK,IACvD,CAACH,MAAM,GAAGJ,MAAM,CAACO,KAAK,GAAGP,MAAM,CAACQ,MAAM,MAAML,KAAK,CAACK,MAAM,EACxD;IACA,MAAM,IAAIC,KAAK,CAAC,mDAAmD,CAAC;EACtE;EACA,MAAM;IAAEF,KAAK;IAAEC;EAAO,CAAC,GAAGN,MAAM;EAChC,IAAID,QAAQ,KAAK,EAAE,EACjB,OAAO;IAAEI,CAAC,EAAEG,MAAM,GAAGR,MAAM,CAACM,CAAC,GAAGN,MAAM,CAACQ,MAAM;IAAEF,CAAC,EAAEN,MAAM,CAACK;EAAE,CAAC;EAC9D,IAAIJ,QAAQ,KAAK,GAAG,EAClB,OAAO;IACLI,CAAC,EAAEE,KAAK,GAAGP,MAAM,CAACK,CAAC,GAAGL,MAAM,CAACO,KAAK;IAClCD,CAAC,EAAEE,MAAM,GAAGR,MAAM,CAACM,CAAC,GAAGN,MAAM,CAACQ;EAChC,CAAC;EACH,IAAIP,QAAQ,KAAK,GAAG,EAClB,OAAO;IAAEI,CAAC,EAAEL,MAAM,CAACM,CAAC;IAAEA,CAAC,EAAEC,KAAK,GAAGP,MAAM,CAACK,CAAC,GAAGL,MAAM,CAACO;EAAM,CAAC;EAC5D,OAAO;IAAEF,CAAC,EAAEL,MAAM,CAACK,CAAC;IAAEC,CAAC,EAAEN,MAAM,CAACM;EAAE,CAAC;AACrC,CAAC;AAED,MAAMI,UAAU,GAAIC,MAAiB,IAAc;EACjD,SAAS;;EACT,MAAMC,OAAO,GAAGC,UAEf;EACD,IAAI,CAACD,OAAO,CAACE,iBAAiB,EAAE;IAC9B,MAAMC,MAAM,GAAGJ,MAAM,CAACK,qBAAqB,CAAC;MAC1CC,KAAK,EAAE,gBAAgB;MACvBC,OAAO,EAAE,CACP;QACEC,OAAO,EAAE,CAAC;QACVC,UAAU,EAAE5B,iBAAiB,CAAC6B,QAAQ;QACtCC,eAAe,EAAE,CAAC;MACpB,CAAC,EACD;QACEH,OAAO,EAAE,CAAC;QACVC,UAAU,EAAE5B,iBAAiB,CAAC6B,QAAQ;QACtCE,OAAO,EAAE;UAAEC,IAAI,EAAE;QAAY;MAC/B,CAAC,EACD;QACEL,OAAO,EAAE,CAAC;QACVC,UAAU,EAAE5B,iBAAiB,CAACiC,MAAM;QACpCvB,MAAM,EAAE;UAAEsB,IAAI,EAAE;QAAU;MAC5B,CAAC;IAEL,CAAC,CAAC;IACFZ,OAAO,CAACE,iBAAiB,GAAG;MAC1BC,MAAM;MACNW,cAAc,EAAEf,MAAM,CAACgB,oBAAoB,CAAC;QAC1CV,KAAK,EAAE,gBAAgB;QACvBW,gBAAgB,EAAE,CAACb,MAAM;MAC3B,CAAC,CAAC;MACFQ,OAAO,EAAEZ,MAAM,CAACkB,aAAa,CAAC;QAC5BZ,KAAK,EAAE,gBAAgB;QACvBa,SAAS,EAAE,QAAQ;QACnBC,SAAS,EAAE;MACb,CAAC,CAAC;MACFC,MAAM,EAAErB,MAAM,CAACsB,kBAAkB,CAAC;QAChChB,KAAK,EAAE,gBAAgB;QACvBiB,IAAI,EAAEvC;MACR,CAAC,CAAC;MACFwC,SAAS,EAAE,IAAIC,GAAG,CAAC;IACrB,CAAC;EACH;EACA,OAAOxB,OAAO,CAACE,iBAAiB;AAClC,CAAC;AAED,MAAMuB,WAAW,GAAGA,CAClB1B,MAAiB,EACjB2B,IAAa,EACbC,MAAwB,KACF;EACtB,SAAS;;EACT,IAAIC,QAAQ,GAAGF,IAAI,CAACH,SAAS,CAACM,GAAG,CAACF,MAAM,CAAC;EACzC,IAAI,CAACC,QAAQ,EAAE;IACbA,QAAQ,GAAG7B,MAAM,CAAC+B,oBAAoB,CAAC;MACrCzB,KAAK,EAAE,gBAAgB;MACvBF,MAAM,EAAEuB,IAAI,CAACZ,cAAc;MAC3BD,MAAM,EAAE;QAAEO,MAAM,EAAEM,IAAI,CAACN,MAAM;QAAEW,UAAU,EAAE;MAAK,CAAC;MACjDtB,QAAQ,EAAE;QACRW,MAAM,EAAEM,IAAI,CAACN,MAAM;QACnBW,UAAU,EAAE,IAAI;QAChBC,OAAO,EAAE,CAAC;UAAEL;QAAO,CAAC;MACtB,CAAC;MACDM,SAAS,EAAE;QAAEC,QAAQ,EAAE;MAAgB;IACzC,CAAC,CAAC;IACFR,IAAI,CAACH,SAAS,CAACY,GAAG,CAACR,MAAM,EAAEC,QAAQ,CAAC;EACtC;EACA,OAAOA,QAAQ;AACjB,CAAC;;AAED;AACA,OAAO,MAAMQ,gBAAgB,GAAIC,KAAgB,IAAW;EAC1D,SAAS;;EACTA,KAAK,CAACC,OAAO,CAACC,OAAO,CAAC,CAAC;EACvBF,KAAK,CAACG,QAAQ,CAACD,OAAO,CAAC,CAAC;EACxBF,KAAK,CAACI,MAAM,CAACC,OAAO,CAAC,CAAC;AACxB,CAAC;;AAED;AACA;AACA,OAAO,MAAMC,iBAAiB,GAAGA,CAC/BC,OAAiC,EACjCC,QAAiB,KACR;EACT,SAAS;;EACT,KAAK,MAAM,CAACC,GAAG,EAAExC,OAAO,CAAC,IAAIsC,OAAO,EAAE;IACpC,IAAIC,QAAQ,KAAKE,SAAS,IAAID,GAAG,KAAKD,QAAQ,EAAE;IAChD,OAAOvC,OAAO,CAAC0C,MAAM,EAAE;MACrBZ,gBAAgB,CAAC9B,OAAO,CAAC,CAAC,CAAE,CAAC;MAC7BA,OAAO,CAAC2C,KAAK,CAAC,CAAC;IACjB;IACAL,OAAO,CAACM,MAAM,CAACJ,GAAG,CAAC;EACrB;AACF,CAAC;AAED,MAAMK,eAAe,GAAGA,CACtBpD,MAAiB,EACjB2B,IAAa,EACb0B,MAAc,EACd/D,QAAgB,KACF;EACd,SAAS;;EACT;EACA,MAAMoD,MAAM,GAAG9D,yBAAyB,CAACyE,MAAM,CAAC;EAChD,IAAId,OAA8C,GAAG,IAAI;EACzD,IAAIE,QAA0B,GAAG,IAAI;EACrC,IAAI;IACFF,OAAO,GAAGvC,MAAM,CAACsD,iCAAiC,CAACZ,MAAM,EAAE;MACzDpC,KAAK,EAAE,sBAAsB;MAC7BhB,QAAQ,EAAEA,QAA8B;MACxCiE,QAAQ,EAAE,KAAK;MACftE;IACF,CAAC,CAAC;IACFwD,QAAQ,GAAGzC,MAAM,CAACwD,YAAY,CAAC;MAC7BlD,KAAK,EAAE,yBAAyB;MAChCmD,IAAI,EAAE,EAAE;MACRC,KAAK,EAAE5E;IACT,CAAC,CAAC;IACF,MAAM6E,SAAS,GAAG3D,MAAM,CAAC4D,eAAe,CAAC;MACvCtD,KAAK,EAAE,gBAAgB;MACvBF,MAAM,EAAEuB,IAAI,CAACvB,MAAM;MACnBG,OAAO,EAAE,CACP;QAAEC,OAAO,EAAE,CAAC;QAAEqD,QAAQ,EAAEtB,OAAO,CAAC5B;MAAgB,CAAC,EACjD;QAAEH,OAAO,EAAE,CAAC;QAAEqD,QAAQ,EAAElC,IAAI,CAACf;MAAQ,CAAC,EACtC;QAAEJ,OAAO,EAAE,CAAC;QAAEqD,QAAQ,EAAE;UAAEtE,MAAM,EAAEkD;QAAS;MAAE,CAAC;IAElD,CAAC,CAAC;IACF,OAAO;MACLY,MAAM;MACN/D,QAAQ;MACRoD,MAAM;MACNH,OAAO;MACPE,QAAQ;MACRkB,SAAS;MACTG,OAAO,EAAE;IACX,CAAC;EACH,CAAC,CAAC,OAAOC,KAAK,EAAE;IACd;IACAtB,QAAQ,EAAED,OAAO,CAAC,CAAC;IACnBD,OAAO,EAAEC,OAAO,CAAC,CAAC;IAClBE,MAAM,CAACC,OAAO,CAAC,CAAC;IAChB,MAAMoB,KAAK;EACb;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,YAAY,GAAGA,CAC1BhE,MAAiB,EACjB6C,OAAiC,EACjCC,QAAgB,EAChBJ,MAAwB,EACxBpD,QAAgB,EAChB2E,MAAgC,EAChCrE,KAAa,EACbC,MAAc,EACdqE,MAAkB,KACT;EACT,SAAS;;EACT,MAAMvC,IAAI,GAAG5B,UAAU,CAACC,MAAM,CAAC;EAC/B,MAAM6B,QAAQ,GAAGH,WAAW,CAAC1B,MAAM,EAAE2B,IAAI,EAAEuC,MAAM,CAACtC,MAAM,CAAC;EACzD,IAAIrB,OAAO,GAAGsC,OAAO,CAACf,GAAG,CAACgB,QAAQ,CAAC;EACnC,IAAI,CAACvC,OAAO,EAAE;IACZA,OAAO,GAAG,EAAE;IACZsC,OAAO,CAACT,GAAG,CAACU,QAAQ,EAAEvC,OAAO,CAAC;EAChC;EACA,IAAI4D,KAAK,GAAG5D,OAAO,CAAC6D,SAAS,CAC1B9B,KAAK,IAAKA,KAAK,CAACe,MAAM,KAAKX,MAAM,CAACW,MAAM,IAAIf,KAAK,CAAChD,QAAQ,KAAKA,QAClE,CAAC;EACD,IAAI6E,KAAK,GAAG,CAAC,EAAE;IACb;IACA;IACA,IAAI5D,OAAO,CAAC0C,MAAM,IAAIlE,qBAAqB,EAAE;MAC3CsD,gBAAgB,CAAC9B,OAAO,CAAC,CAAC,CAAE,CAAC;MAC7BA,OAAO,CAAC2C,KAAK,CAAC,CAAC;IACjB;IACA3C,OAAO,CAAC8D,IAAI,CAACjB,eAAe,CAACpD,MAAM,EAAE2B,IAAI,EAAEe,MAAM,CAACW,MAAM,EAAE/D,QAAQ,CAAC,CAAC;IACpE6E,KAAK,GAAG5D,OAAO,CAAC0C,MAAM,GAAG,CAAC;EAC5B,CAAC,MAAM,IAAIkB,KAAK,KAAK5D,OAAO,CAAC0C,MAAM,GAAG,CAAC,EAAE;IACvC1C,OAAO,CAAC8D,IAAI,CAAC9D,OAAO,CAAC+D,MAAM,CAACH,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;IAC1CA,KAAK,GAAG5D,OAAO,CAAC0C,MAAM,GAAG,CAAC;EAC5B;EACA,MAAMX,KAAK,GAAG/B,OAAO,CAAC4D,KAAK,CAAE;EAC7B;EACA,MAAM1E,MAAM,GAAGH,QAAQ,KAAK,EAAE,IAAIA,QAAQ,KAAK,GAAG;EAClD,MAAMiF,UAAU,GAAG9E,MAAM,GAAGiD,MAAM,CAAC7C,MAAM,GAAG6C,MAAM,CAAC9C,KAAK;EACxD,MAAM4E,WAAW,GAAG/E,MAAM,GAAGiD,MAAM,CAAC9C,KAAK,GAAG8C,MAAM,CAAC7C,MAAM;EACzD,MAAMiE,OAAO,GAAG,CACdlE,KAAK,GAAG2E,UAAU,EAClB1E,MAAM,GAAG2E,WAAW,EACpBP,MAAM,CAACvE,CAAC,GAAG6E,UAAU,EACrBN,MAAM,CAACtE,CAAC,GAAG6E,WAAW,CACvB;EACD,IAAIV,OAAO,CAACW,IAAI,CAAC,CAACC,KAAK,EAAEC,CAAC,KAAKD,KAAK,KAAKpC,KAAK,CAACwB,OAAO,CAACa,CAAC,CAAC,CAAC,EAAE;IAC1D3E,MAAM,CAAC4E,KAAK,CAACC,WAAW,CAACvC,KAAK,CAACG,QAAQ,EAAE,CAAC,EAAE,IAAIqC,YAAY,CAAChB,OAAO,CAAC,CAAC;IACtExB,KAAK,CAACwB,OAAO,GAAGA,OAAO;EACzB;EACAxB,KAAK,CAACC,OAAO,CAACwC,WAAW,CAAC,CAAC;EAC3B,IAAI;IACF,MAAMC,OAAO,GAAGhF,MAAM,CAACiF,oBAAoB,CAAC;MAAE3E,KAAK,EAAE;IAAiB,CAAC,CAAC;IACxE,MAAM4E,IAAI,GAAGF,OAAO,CAACG,eAAe,CAAC;MACnC7E,KAAK,EAAE,gBAAgB;MACvB8E,gBAAgB,EAAE,CAChB;QACEC,IAAI,EAAEnB,MAAM,CAACoB,UAAU,CAAC,CAAC;QACzBC,MAAM,EAAE,OAAO;QACfC,UAAU,EAAE;UAAEC,CAAC,EAAE,CAAC;UAAEC,CAAC,EAAE,CAAC;UAAEC,CAAC,EAAE,CAAC;UAAEC,CAAC,EAAE;QAAE,CAAC;QACtCC,OAAO,EAAE;MACX,CAAC;IAEL,CAAC,CAAC;IACFX,IAAI,CAACY,WAAW,CAACjE,QAAQ,CAAC;IAC1BqD,IAAI,CAACa,YAAY,CAAC,CAAC,EAAEzD,KAAK,CAACqB,SAAS,CAAC;IACrCuB,IAAI,CAACc,IAAI,CAAC,CAAC,CAAC;IACZd,IAAI,CAACe,GAAG,CAAC,CAAC;IACVjG,MAAM,CAAC4E,KAAK,CAACsB,MAAM,CAAC,CAAClB,OAAO,CAACmB,MAAM,CAAC,CAAC,CAAC,CAAC;EACzC,CAAC,SAAS;IACR;IACA;IACA7D,KAAK,CAACC,OAAO,CAAC6D,SAAS,CAAC,CAAC,EAAEC,KAAK,CAAC7D,OAAO,CAAC,CAAC;EAC5C;AACF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeReactNativeSkiaVideo.d.ts","sourceRoot":"","sources":["../../../src/NativeReactNativeSkiaVideo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,OAAO,IAAI,OAAO,CAAC;CACpB;;AAED,wBAAqE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RNSkiaVideoModule.d.ts","sourceRoot":"","sources":["../../../src/RNSkiaVideoModule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAmBjD,QAAA,MAAM,MAAM,EAAkC,iBAAiB,CAAC;AAMhE,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../../src/canvas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE7D,sFAAsF;AACtF,eAAO,MAAM,cAAc,GAAI,SAAS,SAAS,KAAG,QAkBnD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Private contract, used only on this library's dedicated export runtime. */
|
|
2
|
+
export declare const assertExportRecorderCacheSupport: () => void;
|
|
3
|
+
/** Close all export consumers first. Never call this from preview/UI cleanup:
|
|
4
|
+
* that recorder can also cache resources for unrelated application views. */
|
|
5
|
+
export declare const trimExportRecorderCache: () => void;
|
|
6
|
+
//# sourceMappingURL=exportCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportCache.d.ts","sourceRoot":"","sources":["../../../src/exportCache.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,YAa5C,CAAC;AAEF;6EAC6E;AAC7E,eAAO,MAAM,uBAAuB,YAMnC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { SkImage } from "react-native-skia";
|
|
2
|
+
import type { GPUSharedTextureMemory, NativeVideoFrame } from "react-native-webgpu";
|
|
3
|
+
import type { VideoFrame } from "./types.js";
|
|
4
|
+
import type { YuvImport } from "./yuvBlit.js";
|
|
5
|
+
/** A decoded frame sampled in place, without an owned snapshot: on iOS its
|
|
6
|
+
* IOSurface, on Android its producer's RGBA texture, which the decoder
|
|
7
|
+
* buffer was just converted into. The decoder lease stays open while the
|
|
8
|
+
* image is in use. */
|
|
9
|
+
export type ExportFrameImport = {
|
|
10
|
+
id: number;
|
|
11
|
+
frame: VideoFrame;
|
|
12
|
+
nativeFrame: NativeVideoFrame | null;
|
|
13
|
+
memory: GPUSharedTextureMemory | null;
|
|
14
|
+
texture: GPUTexture | null;
|
|
15
|
+
accessing: boolean;
|
|
16
|
+
image: SkImage | null;
|
|
17
|
+
/** Android: later leases of the same picture, already closed. */
|
|
18
|
+
aliases?: WeakSet<VideoFrame>;
|
|
19
|
+
};
|
|
20
|
+
/** Android: the texture a producer's decoded frames are converted into. */
|
|
21
|
+
type ProducerTexture = {
|
|
22
|
+
texture: GPUTexture;
|
|
23
|
+
reservation: number;
|
|
24
|
+
};
|
|
25
|
+
/** Per export session, keyed by producer. `enabled` turns off after a first
|
|
26
|
+
* failed import, before any frame was sampled in place. */
|
|
27
|
+
export type ExportFrameImports = {
|
|
28
|
+
entries: Map<number, ExportFrameImport>;
|
|
29
|
+
/** Producers sampled in place; frameInterop never caches their frames. */
|
|
30
|
+
producers: Set<number>;
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
imported: boolean;
|
|
33
|
+
/** Android: one RGBA texture per producer, rewritten by each frame. */
|
|
34
|
+
textures: Map<number, ProducerTexture>;
|
|
35
|
+
/** Android: decoder buffers imported once (see yuvBlit.ts). */
|
|
36
|
+
yuv: Map<number, YuvImport[]>;
|
|
37
|
+
};
|
|
38
|
+
export declare const createExportFrameImports: () => ExportFrameImports;
|
|
39
|
+
/** Decoder frames this path can sample in place; others use frameInterop. */
|
|
40
|
+
export declare const canImportInPlace: (frame: VideoFrame) => boolean;
|
|
41
|
+
/** Call only once every recording sampling the image has completed (a
|
|
42
|
+
* checked flush(true)). An access that cannot end throws: the export must
|
|
43
|
+
* then keep the lease and fail rather than recycle a buffer still in use. */
|
|
44
|
+
export declare const releaseExportFrame: (entry: ExportFrameImport) => void;
|
|
45
|
+
/** Wraps a decoded BGRA CVPixelBuffer's IOSurface as a Skia image, read-only.
|
|
46
|
+
* The decoder already finished writing it; no producer fence is needed. On
|
|
47
|
+
* Android, converts the decoded YUV frame instead (see importYuvExportFrame). */
|
|
48
|
+
export declare const importExportFrame: (frame: VideoFrame, imports?: ExportFrameImports) => ExportFrameImport;
|
|
49
|
+
/** Releases every in-place frame; the last GPU recording must have completed. */
|
|
50
|
+
export declare const releaseExportFrames: (imports: ExportFrameImports) => void;
|
|
51
|
+
/** The export counterpart of ownVideoFrames on iOS: decoded frames are drawn
|
|
52
|
+
* in place, and a producer's previous frame is released once its next one is
|
|
53
|
+
* imported, since every exported frame ends with a checked GPU wait. Other
|
|
54
|
+
* frames, or every frame after a first failed import, use `fallback`. */
|
|
55
|
+
export declare const ownExportFrames: (imports: ExportFrameImports, decoded: Record<string, VideoFrame>, fallback: (frames: Record<string, VideoFrame>) => Record<string, VideoFrame>) => Record<string, VideoFrame>;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=exportFrames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportFrames.d.ts","sourceRoot":"","sources":["../../../src/exportFrames.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,sBAAsB,EAEtB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAW7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAS,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAW,CAAC;AAE3C;;;sBAGsB;AACtB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAC/B,CAAC;AAEF,2EAA2E;AAC3E,KAAK,eAAe,GAAG;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;2DAC2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACxC,0EAA0E;IAC1E,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACvC,+DAA+D;IAC/D,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;CAC/B,CAAC;AAmBF,eAAO,MAAM,wBAAwB,QAAO,kBAU3C,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,KAAG,OAQpD,CAAC;AAGF;;6EAE6E;AAC7E,eAAO,MAAM,kBAAkB,GAAI,OAAO,iBAAiB,KAAG,IAiB7D,CAAC;AAqHF;;iFAEiF;AACjF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,EACjB,UAAU,kBAAkB,KAC3B,iBA0DF,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,mBAAmB,GAAI,SAAS,kBAAkB,KAAG,IAQjE,CAAC;AAEF;;;yEAGyE;AACzE,eAAO,MAAM,eAAe,GAC1B,SAAS,kBAAkB,EAC3B,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,KAC3E,MAAM,CAAC,MAAM,EAAE,UAAU,CAqG3B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const exportAbortError: (signal?: AbortSignal) => unknown;
|
|
2
|
+
/** One active export and at most three waiting jobs. A queued abort releases
|
|
3
|
+
* its captured composition immediately, without allocating native resources. */
|
|
4
|
+
export declare const enqueueExport: (run: () => Promise<void>, signal?: AbortSignal) => Promise<void>;
|
|
5
|
+
//# sourceMappingURL=exportQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportQueue.d.ts","sourceRoot":"","sources":["../../../src/exportQueue.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,KAAG,OAMvD,CAAC;AAiBF;gFACgF;AAChF,eAAO,MAAM,aAAa,GACxB,KAAK,MAAM,OAAO,CAAC,IAAI,CAAC,EACxB,SAAS,WAAW,KACnB,OAAO,CAAC,IAAI,CA0BX,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SkCanvas, SkSurface } from "react-native-skia";
|
|
2
|
+
import type { GPUSharedTextureMemory, NativeVideoFrame } from "react-native-webgpu";
|
|
3
|
+
import type { VideoEncoder } from "./types.js";
|
|
4
|
+
/** An encoder pool buffer that Skia draws into through WebGPU. */
|
|
5
|
+
export type EncoderTarget = {
|
|
6
|
+
pointer: bigint;
|
|
7
|
+
/** Android: sync-fds ending the GPU access, handed over to the encoder. */
|
|
8
|
+
fences: bigint[];
|
|
9
|
+
frame: NativeVideoFrame | null;
|
|
10
|
+
memory: GPUSharedTextureMemory | null;
|
|
11
|
+
texture: GPUTexture | null;
|
|
12
|
+
accessing: boolean;
|
|
13
|
+
surface: SkSurface | null;
|
|
14
|
+
canvas: SkCanvas | null;
|
|
15
|
+
};
|
|
16
|
+
export declare const supportsEncoderTargets: (encoder: VideoEncoder) => boolean;
|
|
17
|
+
/** Ends GPU access; the lent buffer stays with the caller, to encode or
|
|
18
|
+
* release. Call only after a checked flush(true) of its surface. With
|
|
19
|
+
* `encoding`, Android keeps the access's sync-fds in `target.fences` for the
|
|
20
|
+
* encoder, which owns and closes them: ending an AHB access submits a
|
|
21
|
+
* release that flush(true) has not waited for. */
|
|
22
|
+
export declare const closeEncoderTarget: (target: EncoderTarget, encoding?: boolean) => void;
|
|
23
|
+
/** Lends the next pool buffer and wraps it as a Skia surface. */
|
|
24
|
+
export declare const acquireEncoderTarget: (encoder: VideoEncoder, width: number, height: number) => EncoderTarget;
|
|
25
|
+
/** Clears one lent buffer on the GPU, then returns it unencoded. Returns the
|
|
26
|
+
* failure, or null when this device can export through encoder targets. */
|
|
27
|
+
export declare const probeEncoderTarget: (encoder: VideoEncoder, width: number, height: number) => unknown;
|
|
28
|
+
//# sourceMappingURL=exportTarget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportTarget.d.ts","sourceRoot":"","sources":["../../../src/exportTarget.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EACV,sBAAsB,EAEtB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAS,CAAC;AAE5C,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;CACzB,CAAC;AAYF,eAAO,MAAM,sBAAsB,GAAI,SAAS,YAAY,KAAG,OAM9D,CAAC;AAGF;;;;kDAIkD;AAClD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,aAAa,EACrB,kBAAgB,KACf,IAmCF,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,GAC/B,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,QAAQ,MAAM,KACb,aAwDF,CAAC;AAEF;2EAC2E;AAC3E,eAAO,MAAM,kBAAkB,GAC7B,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,QAAQ,MAAM,KACb,OAmBF,CAAC"}
|