react-native-skia-webgpu-video 0.0.0-stage → 0.1.0-beta.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.
Files changed (237) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +303 -2
  3. package/android/BUILD_VALIDATION.md +62 -0
  4. package/android/CMakeLists.txt +99 -0
  5. package/android/build-validation.json +262 -0
  6. package/android/build.gradle +185 -0
  7. package/android/cpp/EncoderTargets.cpp +226 -0
  8. package/android/cpp/EncoderTargets.h +70 -0
  9. package/android/cpp/JNIHelpers.cpp +15 -0
  10. package/android/cpp/JNIHelpers.h +20 -0
  11. package/android/cpp/NativeEventDispatcher.cpp +59 -0
  12. package/android/cpp/NativeEventDispatcher.h +31 -0
  13. package/android/cpp/NativeHardwareBuffer.cpp +397 -0
  14. package/android/cpp/NativeHardwareBuffer.h +34 -0
  15. package/android/cpp/NativeRgbaBuffer.cpp +45 -0
  16. package/android/cpp/NativeRgbaBuffer.h +9 -0
  17. package/android/cpp/ReturnedVideoFrames.h +37 -0
  18. package/android/cpp/RgbaFrameLease.h +53 -0
  19. package/android/cpp/VideoCapabilities.cpp +87 -0
  20. package/android/cpp/VideoCapabilities.h +44 -0
  21. package/android/cpp/VideoComposition.cpp +170 -0
  22. package/android/cpp/VideoComposition.h +36 -0
  23. package/android/cpp/VideoCompositionFramesExtractor.cpp +82 -0
  24. package/android/cpp/VideoCompositionFramesExtractor.h +48 -0
  25. package/android/cpp/VideoCompositionFramesExtractorHostObject.cpp +230 -0
  26. package/android/cpp/VideoCompositionFramesExtractorHostObject.h +42 -0
  27. package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.cpp +133 -0
  28. package/android/cpp/VideoCompositionFramesExtractorSyncHostObject.h +46 -0
  29. package/android/cpp/VideoEncoderHostObject.cpp +318 -0
  30. package/android/cpp/VideoEncoderHostObject.h +76 -0
  31. package/android/cpp/VideoFrame.cpp +293 -0
  32. package/android/cpp/VideoFrame.h +27 -0
  33. package/android/cpp/VideoPlayer.cpp +96 -0
  34. package/android/cpp/VideoPlayer.h +52 -0
  35. package/android/cpp/VideoPlayerHostObject.cpp +225 -0
  36. package/android/cpp/VideoPlayerHostObject.h +43 -0
  37. package/android/cpp/cpp-adapter.cpp +316 -0
  38. package/android/gradle.properties +5 -0
  39. package/android/instrumentation-inventory.json +178 -0
  40. package/android/proguard-rules.pro +4 -0
  41. package/android/src/main/AndroidManifest.xml +2 -0
  42. package/android/src/main/java/com/azzapp/rnskv/AudioCompositionExporter.java +537 -0
  43. package/android/src/main/java/com/azzapp/rnskv/AudioCompositionPlayer.java +321 -0
  44. package/android/src/main/java/com/azzapp/rnskv/BufferLifetime.java +55 -0
  45. package/android/src/main/java/com/azzapp/rnskv/DecodeRequests.java +100 -0
  46. package/android/src/main/java/com/azzapp/rnskv/DecoderWindow.java +55 -0
  47. package/android/src/main/java/com/azzapp/rnskv/DisplayVsyncPeriod.java +72 -0
  48. package/android/src/main/java/com/azzapp/rnskv/EGLResourcesHolder.java +132 -0
  49. package/android/src/main/java/com/azzapp/rnskv/EGLUtils.java +225 -0
  50. package/android/src/main/java/com/azzapp/rnskv/FrameSize.java +50 -0
  51. package/android/src/main/java/com/azzapp/rnskv/GLFrameExtractor.java +510 -0
  52. package/android/src/main/java/com/azzapp/rnskv/JNIHelpers.java +12 -0
  53. package/android/src/main/java/com/azzapp/rnskv/NativeEventDispatcher.java +25 -0
  54. package/android/src/main/java/com/azzapp/rnskv/NativeHardwareBuffer.java +62 -0
  55. package/android/src/main/java/com/azzapp/rnskv/NativeRgbaBuffer.java +43 -0
  56. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoModule.java +45 -0
  57. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoPackage.java +43 -0
  58. package/android/src/main/java/com/azzapp/rnskv/ReactNativeSkiaVideoSpec.java +9 -0
  59. package/android/src/main/java/com/azzapp/rnskv/RgbaBufferAllocator.java +114 -0
  60. package/android/src/main/java/com/azzapp/rnskv/RgbaLayout.java +33 -0
  61. package/android/src/main/java/com/azzapp/rnskv/SurfaceOutputPolicy.java +13 -0
  62. package/android/src/main/java/com/azzapp/rnskv/TextureRenderer.java +150 -0
  63. package/android/src/main/java/com/azzapp/rnskv/TimeHelpers.java +11 -0
  64. package/android/src/main/java/com/azzapp/rnskv/VideoCapabilities.java +354 -0
  65. package/android/src/main/java/com/azzapp/rnskv/VideoComposition.java +147 -0
  66. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionDecoder.java +779 -0
  67. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractor.java +463 -0
  68. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionFramesExtractorSync.java +241 -0
  69. package/android/src/main/java/com/azzapp/rnskv/VideoCompositionItemDecoder.java +492 -0
  70. package/android/src/main/java/com/azzapp/rnskv/VideoEncoder.java +639 -0
  71. package/android/src/main/java/com/azzapp/rnskv/VideoFrame.java +74 -0
  72. package/android/src/main/java/com/azzapp/rnskv/VideoPlayer.java +361 -0
  73. package/cpp/RNSVCheckedSizes.h +54 -0
  74. package/cpp/RNSVEventEmitter.cpp +199 -0
  75. package/cpp/RNSVEventEmitter.h +31 -0
  76. package/cpp/RNSVHostObject.cpp +79 -0
  77. package/cpp/RNSVHostObject.h +67 -0
  78. package/cpp/RNSVMemoryBudget.cpp +68 -0
  79. package/cpp/RNSVMemoryBudget.h +100 -0
  80. package/cpp/RNSVRuntimeLifecycleMonitor.cpp +88 -0
  81. package/cpp/RNSVRuntimeLifecycleMonitor.h +33 -0
  82. package/docs/ANDROID_DEVICE_306.md +95 -0
  83. package/docs/ANDROID_EXPORT_CACHE_306.md +48 -0
  84. package/docs/ANDROID_MEMORY_RETENTION_306.md +67 -0
  85. package/docs/BENCHMARKS.md +368 -0
  86. package/docs/IOS_DEVICE_TESTS.md +115 -0
  87. package/docs/IOS_SIMULATOR_TESTS.md +74 -0
  88. package/docs/MIGRATION.md +82 -0
  89. package/docs/NATIVE_MEMORY_INVESTIGATION_306.md +88 -0
  90. package/docs/PERFORMANCE_AB_IPHONE_303.md +196 -0
  91. package/docs/PERFORMANCE_AB_SIMULATOR.md +135 -0
  92. package/docs/PERFORMANCE_AB_SOAK_SIMULATOR.md +84 -0
  93. package/docs/PERFORMANCE_IPHONE_306_OPTIMIZATION.md +76 -0
  94. package/docs/PERFORMANCE_SIMULATOR.md +89 -0
  95. package/docs/PERFORMANCE_SIMULATOR_INITIAL.md +96 -0
  96. package/docs/PERFORMANCE_SOAK_IPHONE_303.md +41 -0
  97. package/docs/UPSTREAM_NOTES.md +188 -0
  98. package/docs/assets/banner.svg +26 -0
  99. package/examples/webgpu-overlay.ts +147 -0
  100. package/ios/AVAssetTrackUtils.h +24 -0
  101. package/ios/AudioCompositionUtils.h +27 -0
  102. package/ios/AudioCompositionUtils.mm +113 -0
  103. package/ios/DecoderWindow.h +52 -0
  104. package/ios/NativeResourceStats.h +32 -0
  105. package/ios/RNSVColorSpace.h +50 -0
  106. package/ios/RNSVJSIUtils.h +46 -0
  107. package/ios/RNSVScopedPixelBuffer.h +17 -0
  108. package/ios/RNSVVideoPlayer.h +46 -0
  109. package/ios/RNSVVideoPlayer.mm +410 -0
  110. package/ios/ReactNativeSkiaVideo.h +8 -0
  111. package/ios/ReactNativeSkiaVideo.mm +310 -0
  112. package/ios/SeekPolicy.h +27 -0
  113. package/ios/VideoComposition.h +148 -0
  114. package/ios/VideoCompositionFramesExtractorHostObject.h +105 -0
  115. package/ios/VideoCompositionFramesExtractorHostObject.mm +686 -0
  116. package/ios/VideoCompositionFramesExtractorSyncHostObject.h +37 -0
  117. package/ios/VideoCompositionFramesExtractorSyncHostObject.mm +168 -0
  118. package/ios/VideoCompositionItemDecoder.h +60 -0
  119. package/ios/VideoCompositionItemDecoder.mm +480 -0
  120. package/ios/VideoEncoderHostObject.h +83 -0
  121. package/ios/VideoEncoderHostObject.mm +706 -0
  122. package/ios/VideoFrame.h +66 -0
  123. package/ios/VideoFrame.mm +108 -0
  124. package/ios/VideoPlayerHostObject.h +52 -0
  125. package/ios/VideoPlayerHostObject.mm +332 -0
  126. package/lib/module/NativeReactNativeSkiaVideo.js +5 -0
  127. package/lib/module/NativeReactNativeSkiaVideo.js.map +1 -0
  128. package/lib/module/RNSkiaVideoModule.js +20 -0
  129. package/lib/module/RNSkiaVideoModule.js.map +1 -0
  130. package/lib/module/canvas.js +18 -0
  131. package/lib/module/canvas.js.map +1 -0
  132. package/lib/module/exportCache.js +22 -0
  133. package/lib/module/exportCache.js.map +1 -0
  134. package/lib/module/exportFrames.js +338 -0
  135. package/lib/module/exportFrames.js.map +1 -0
  136. package/lib/module/exportQueue.js +52 -0
  137. package/lib/module/exportQueue.js.map +1 -0
  138. package/lib/module/exportTarget.js +137 -0
  139. package/lib/module/exportTarget.js.map +1 -0
  140. package/lib/module/exportVideoComposition.js +492 -0
  141. package/lib/module/exportVideoComposition.js.map +1 -0
  142. package/lib/module/frameInterop.js +532 -0
  143. package/lib/module/frameInterop.js.map +1 -0
  144. package/lib/module/gpu.js +222 -0
  145. package/lib/module/gpu.js.map +1 -0
  146. package/lib/module/gpuDevice.js +54 -0
  147. package/lib/module/gpuDevice.js.map +1 -0
  148. package/lib/module/index.js +36 -0
  149. package/lib/module/index.js.map +1 -0
  150. package/lib/module/memory.js +38 -0
  151. package/lib/module/memory.js.map +1 -0
  152. package/lib/module/package.json +1 -0
  153. package/lib/module/previewLifecycle.js +52 -0
  154. package/lib/module/previewLifecycle.js.map +1 -0
  155. package/lib/module/runtimeYield.js +10 -0
  156. package/lib/module/runtimeYield.js.map +1 -0
  157. package/lib/module/types.js +4 -0
  158. package/lib/module/types.js.map +1 -0
  159. package/lib/module/utils/useEventListener.js +18 -0
  160. package/lib/module/utils/useEventListener.js.map +1 -0
  161. package/lib/module/videoCompositionPlayer.js +368 -0
  162. package/lib/module/videoCompositionPlayer.js.map +1 -0
  163. package/lib/module/videoFrameImage.js +185 -0
  164. package/lib/module/videoFrameImage.js.map +1 -0
  165. package/lib/module/videoPlayer.js +172 -0
  166. package/lib/module/videoPlayer.js.map +1 -0
  167. package/lib/module/yuvBlit.js +299 -0
  168. package/lib/module/yuvBlit.js.map +1 -0
  169. package/lib/typescript/package.json +1 -0
  170. package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts +7 -0
  171. package/lib/typescript/src/NativeReactNativeSkiaVideo.d.ts.map +1 -0
  172. package/lib/typescript/src/RNSkiaVideoModule.d.ts +4 -0
  173. package/lib/typescript/src/RNSkiaVideoModule.d.ts.map +1 -0
  174. package/lib/typescript/src/canvas.d.ts +4 -0
  175. package/lib/typescript/src/canvas.d.ts.map +1 -0
  176. package/lib/typescript/src/exportCache.d.ts +6 -0
  177. package/lib/typescript/src/exportCache.d.ts.map +1 -0
  178. package/lib/typescript/src/exportFrames.d.ts +57 -0
  179. package/lib/typescript/src/exportFrames.d.ts.map +1 -0
  180. package/lib/typescript/src/exportQueue.d.ts +5 -0
  181. package/lib/typescript/src/exportQueue.d.ts.map +1 -0
  182. package/lib/typescript/src/exportTarget.d.ts +28 -0
  183. package/lib/typescript/src/exportTarget.d.ts.map +1 -0
  184. package/lib/typescript/src/exportVideoComposition.d.ts +68 -0
  185. package/lib/typescript/src/exportVideoComposition.d.ts.map +1 -0
  186. package/lib/typescript/src/frameInterop.d.ts +17 -0
  187. package/lib/typescript/src/frameInterop.d.ts.map +1 -0
  188. package/lib/typescript/src/gpu.d.ts +39 -0
  189. package/lib/typescript/src/gpu.d.ts.map +1 -0
  190. package/lib/typescript/src/gpuDevice.d.ts +11 -0
  191. package/lib/typescript/src/gpuDevice.d.ts.map +1 -0
  192. package/lib/typescript/src/index.d.ts +21 -0
  193. package/lib/typescript/src/index.d.ts.map +1 -0
  194. package/lib/typescript/src/memory.d.ts +25 -0
  195. package/lib/typescript/src/memory.d.ts.map +1 -0
  196. package/lib/typescript/src/previewLifecycle.d.ts +22 -0
  197. package/lib/typescript/src/previewLifecycle.d.ts.map +1 -0
  198. package/lib/typescript/src/runtimeYield.d.ts +4 -0
  199. package/lib/typescript/src/runtimeYield.d.ts.map +1 -0
  200. package/lib/typescript/src/types.d.ts +631 -0
  201. package/lib/typescript/src/types.d.ts.map +1 -0
  202. package/lib/typescript/src/utils/useEventListener.d.ts +5 -0
  203. package/lib/typescript/src/utils/useEventListener.d.ts.map +1 -0
  204. package/lib/typescript/src/videoCompositionPlayer.d.ts +105 -0
  205. package/lib/typescript/src/videoCompositionPlayer.d.ts.map +1 -0
  206. package/lib/typescript/src/videoFrameImage.d.ts +60 -0
  207. package/lib/typescript/src/videoFrameImage.d.ts.map +1 -0
  208. package/lib/typescript/src/videoPlayer.d.ts +99 -0
  209. package/lib/typescript/src/videoPlayer.d.ts.map +1 -0
  210. package/lib/typescript/src/yuvBlit.d.ts +50 -0
  211. package/lib/typescript/src/yuvBlit.d.ts.map +1 -0
  212. package/package.json +155 -4
  213. package/patches/react-native-skia+3.7.0.patch +502 -0
  214. package/react-native-skia-webgpu-video.podspec +35 -0
  215. package/scripts/apply-skia-canvas-patch.mjs +48 -0
  216. package/scripts/skia-canvas-patch.json +291 -0
  217. package/src/NativeReactNativeSkiaVideo.ts +8 -0
  218. package/src/RNSkiaVideoModule.ts +27 -0
  219. package/src/canvas.ts +22 -0
  220. package/src/exportCache.ts +27 -0
  221. package/src/exportFrames.ts +421 -0
  222. package/src/exportQueue.ts +65 -0
  223. package/src/exportTarget.ts +179 -0
  224. package/src/exportVideoComposition.ts +718 -0
  225. package/src/frameInterop.ts +684 -0
  226. package/src/gpu.ts +290 -0
  227. package/src/gpuDevice.ts +80 -0
  228. package/src/index.tsx +45 -0
  229. package/src/memory.ts +48 -0
  230. package/src/previewLifecycle.ts +60 -0
  231. package/src/runtimeYield.ts +6 -0
  232. package/src/types.ts +661 -0
  233. package/src/utils/useEventListener.ts +22 -0
  234. package/src/videoCompositionPlayer.ts +568 -0
  235. package/src/videoFrameImage.ts +205 -0
  236. package/src/videoPlayer.ts +318 -0
  237. package/src/yuvBlit.ts +331 -0
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+
3
+ /// <reference types="@webgpu/types" />
4
+ import { Platform } from "react-native";
5
+ import { BlendMode, Skia } from "react-native-skia";
6
+ import { createNativeVideoGpuFrame, getVideoGpuDevice, nativeVideoTextureUsage } from "./gpuDevice.js";
7
+ import { frameByteSize, releaseVideoMemory, reserveVideoMemory } from "./memory.js";
8
+ import { blitYuvFrame, releaseYuvImports, yuvFrameOrigin } from "./yuvBlit.js";
9
+
10
+ /** A decoded frame sampled in place, without an owned snapshot: on iOS its
11
+ * IOSurface, on Android its producer's RGBA texture, which the decoder
12
+ * buffer was just converted into. The decoder lease stays open while the
13
+ * image is in use. */
14
+
15
+ /** Android: the texture a producer's decoded frames are converted into. */
16
+
17
+ /** Per export session, keyed by producer. `enabled` turns off after a first
18
+ * failed import, before any frame was sampled in place. */
19
+
20
+ // Captured on the RN runtime. Android samples its ImageReader YUV frames
21
+ // (those with a `region`) once converted; other Android frames are copied.
22
+ const convertsYuv = Platform.OS === "android";
23
+ export const createExportFrameImports = () => {
24
+ "worklet";
25
+
26
+ return {
27
+ entries: new Map(),
28
+ producers: new Set(),
29
+ enabled: true,
30
+ imported: false,
31
+ textures: new Map(),
32
+ yuv: new Map()
33
+ };
34
+ };
35
+
36
+ /** Decoder frames this path can sample in place; others use frameInterop. */
37
+ export const canImportInPlace = frame => {
38
+ "worklet";
39
+
40
+ const texture = frame.texture;
41
+ return texture?.kind === "native-buffer" && frame.id !== undefined && (!convertsYuv || texture.region !== undefined);
42
+ };
43
+
44
+ // Declared before its callers: worklets capture their closure on creation.
45
+ /** Call only once every recording sampling the image has completed (a
46
+ * checked flush(true)). An access that cannot end throws: the export must
47
+ * then keep the lease and fail rather than recycle a buffer still in use. */
48
+ export const releaseExportFrame = entry => {
49
+ "worklet";
50
+
51
+ entry.image?.dispose();
52
+ entry.image = null;
53
+ if (entry.accessing && entry.memory && entry.texture) {
54
+ const ended = entry.memory.endAccess(entry.texture);
55
+ entry.accessing = false;
56
+ for (const state of ended?.fences ?? []) state.fence.destroy();
57
+ }
58
+ entry.accessing = false;
59
+ entry.texture?.destroy();
60
+ entry.texture = null;
61
+ entry.memory?.destroy();
62
+ entry.memory = null;
63
+ entry.nativeFrame?.release();
64
+ entry.nativeFrame = null;
65
+ entry.frame.dispose?.();
66
+ };
67
+
68
+ /** Android: releases a producer's texture and decoder buffer imports. Call
69
+ * only once its last frame's GPU work has completed. */
70
+ const releaseProducerTexture = (imports, producer) => {
71
+ "worklet";
72
+
73
+ releaseYuvImports(imports.yuv, producer);
74
+ const target = imports.textures.get(producer);
75
+ if (target) {
76
+ target.texture.destroy();
77
+ releaseVideoMemory(target.reservation);
78
+ imports.textures.delete(producer);
79
+ }
80
+ };
81
+
82
+ /** Android: converts a decoded ImageReader frame into its producer's RGBA
83
+ * texture, wrapped as a Skia image. The conversion is submitted ahead of the
84
+ * frame's drawing, on the same queue; the export's checked flush waits for
85
+ * both before the lease or the texture is reused. */
86
+ const importYuvExportFrame = (imports, frame) => {
87
+ "worklet";
88
+
89
+ const entry = {
90
+ id: frame.id,
91
+ frame,
92
+ nativeFrame: null,
93
+ memory: null,
94
+ texture: null,
95
+ accessing: false,
96
+ image: null
97
+ };
98
+ const producer = frame.producerId ?? frame.id;
99
+ const source = frame.texture;
100
+ let submitted = false;
101
+ let target;
102
+ try {
103
+ entry.nativeFrame = createNativeVideoGpuFrame(source.nativeBuffer);
104
+ const rotation = source.rotation ?? 0;
105
+ const origin = yuvFrameOrigin(source.region, rotation, entry.nativeFrame, frame);
106
+ const device = getVideoGpuDevice();
107
+ target = imports.textures.get(producer);
108
+ if (target && (target.texture.width !== frame.width || target.texture.height !== frame.height)) {
109
+ // A resized clip: its previous frame completed with the last export
110
+ // frame, so the texture can go.
111
+ releaseProducerTexture(imports, producer);
112
+ target = undefined;
113
+ }
114
+ if (!target) {
115
+ const reservation = reserveVideoMemory(frameByteSize(frame.width, frame.height), "export frame texture");
116
+ try {
117
+ target = {
118
+ texture: device.createTexture({
119
+ size: {
120
+ width: frame.width,
121
+ height: frame.height
122
+ },
123
+ format: "rgba8unorm",
124
+ usage: nativeVideoTextureUsage,
125
+ label: "video export source frame"
126
+ }),
127
+ reservation
128
+ };
129
+ } catch (error) {
130
+ releaseVideoMemory(reservation);
131
+ throw error;
132
+ }
133
+ imports.textures.set(producer, target);
134
+ }
135
+ // Can throw after submitting: drain below before giving the lease back.
136
+ submitted = true;
137
+ blitYuvFrame(device, imports.yuv, producer, entry.nativeFrame, rotation, origin, frame.width, frame.height, target.texture);
138
+ entry.image = Skia.Image.MakeImageFromGPUTexture(target.texture);
139
+ if (!entry.image) throw new Error("Cannot wrap the decoded frame");
140
+ return entry;
141
+ } catch (error) {
142
+ // The lease stays with the caller, which still owns the decoded frame;
143
+ // a submitted conversion must have completed before it is given back.
144
+ try {
145
+ entry.image?.dispose();
146
+ if (submitted && target) {
147
+ const drain = Skia.Surface.MakeFromGPUTexture(target.texture);
148
+ drain?.getCanvas().drawColor(Skia.Color("#00000000"), BlendMode.Clear);
149
+ drain?.flush(true);
150
+ drain?.dispose();
151
+ }
152
+ entry.nativeFrame?.release();
153
+ } catch {
154
+ /* the native wrappers close with their JS objects */
155
+ }
156
+ throw error;
157
+ }
158
+ };
159
+
160
+ /** Wraps a decoded BGRA CVPixelBuffer's IOSurface as a Skia image, read-only.
161
+ * The decoder already finished writing it; no producer fence is needed. On
162
+ * Android, converts the decoded YUV frame instead (see importYuvExportFrame). */
163
+ export const importExportFrame = (frame, imports) => {
164
+ "worklet";
165
+
166
+ if (convertsYuv) {
167
+ if (!imports) throw new Error("Android in-place frames need their imports");
168
+ return importYuvExportFrame(imports, frame);
169
+ }
170
+ const entry = {
171
+ id: frame.id,
172
+ frame,
173
+ nativeFrame: null,
174
+ memory: null,
175
+ texture: null,
176
+ accessing: false,
177
+ image: null
178
+ };
179
+ try {
180
+ const texture = frame.texture;
181
+ entry.nativeFrame = createNativeVideoGpuFrame(texture.nativeBuffer);
182
+ if (entry.nativeFrame.width !== frame.width || entry.nativeFrame.height !== frame.height || entry.nativeFrame.pixelFormat !== "bgra8") {
183
+ throw new Error("Native video buffer dimensions or BGRA layout mismatch");
184
+ }
185
+ const device = getVideoGpuDevice();
186
+ if (typeof device.importSharedTextureMemory !== "function") {
187
+ throw new Error("WebGPU shared texture memory is unavailable");
188
+ }
189
+ entry.memory = device.importSharedTextureMemory({
190
+ handle: entry.nativeFrame.handle,
191
+ label: "video export source frame"
192
+ });
193
+ entry.texture = entry.memory.createTexture();
194
+ entry.memory.beginAccess(entry.texture, true);
195
+ entry.accessing = true;
196
+ entry.image = Skia.Image.MakeImageFromGPUTexture(entry.texture);
197
+ if (!entry.image) throw new Error("Cannot wrap the decoded frame");
198
+ return entry;
199
+ } catch (error) {
200
+ // Nothing was submitted: closing this access cannot race the GPU. The
201
+ // lease stays with the caller, which still owns the decoded frame.
202
+ try {
203
+ entry.image?.dispose();
204
+ entry.image = null;
205
+ if (entry.accessing && entry.memory && entry.texture) {
206
+ const ended = entry.memory.endAccess(entry.texture);
207
+ for (const state of ended?.fences ?? []) state.fence.destroy();
208
+ }
209
+ entry.accessing = false;
210
+ entry.texture?.destroy();
211
+ entry.memory?.destroy();
212
+ entry.nativeFrame?.release();
213
+ } catch {
214
+ /* the native wrappers close with their JS objects */
215
+ }
216
+ throw error;
217
+ }
218
+ };
219
+
220
+ /** Releases every in-place frame; the last GPU recording must have completed. */
221
+ export const releaseExportFrames = imports => {
222
+ "worklet";
223
+
224
+ for (const [producer, entry] of imports.entries) {
225
+ releaseExportFrame(entry);
226
+ imports.entries.delete(producer);
227
+ }
228
+ for (const producer of [...imports.textures.keys(), ...imports.yuv.keys()]) releaseProducerTexture(imports, producer);
229
+ };
230
+
231
+ /** The export counterpart of ownVideoFrames on iOS: decoded frames are drawn
232
+ * in place, and a producer's previous frame is released once its next one is
233
+ * imported, since every exported frame ends with a checked GPU wait. Other
234
+ * frames, or every frame after a first failed import, use `fallback`. */
235
+ export const ownExportFrames = (imports, decoded, fallback) => {
236
+ "worklet";
237
+
238
+ const owned = {};
239
+ const held = new Set();
240
+ const current = new Map();
241
+ try {
242
+ for (const [key, frame] of Object.entries(decoded)) {
243
+ if (!imports.enabled || !canImportInPlace(frame)) continue;
244
+ const producer = frame.producerId ?? frame.id;
245
+ const seen = current.get(producer);
246
+ if (seen !== undefined && seen !== frame.id) {
247
+ throw new Error("Composition yielded different frames for one producer; stable native frame identities are required");
248
+ }
249
+ let entry = imports.entries.get(producer);
250
+ // The extractor hands back the same native frame while a clip holds
251
+ // its picture: that lease is still ours, keep sampling it.
252
+ if (entry?.id !== frame.id) {
253
+ let next;
254
+ try {
255
+ next = importExportFrame(frame, imports);
256
+ } catch (error) {
257
+ if (imports.imported) throw error;
258
+ imports.enabled = false;
259
+ console.warn("[react-native-skia-webgpu-video] In-place frame import unavailable, copying decoded frames:", String(error));
260
+ continue;
261
+ }
262
+ imports.imported = true;
263
+ if (entry) {
264
+ try {
265
+ releaseExportFrame(entry);
266
+ } catch (error) {
267
+ // Keep the unreleased entry tracked; the new one was never used.
268
+ try {
269
+ releaseExportFrame(next);
270
+ } catch {
271
+ /* nothing was submitted with it */
272
+ }
273
+ throw error;
274
+ }
275
+ }
276
+ imports.entries.set(producer, next);
277
+ imports.producers.add(producer);
278
+ entry = next;
279
+ } else if (convertsYuv && entry && entry.frame !== frame) {
280
+ // Android leases a picture afresh on every decode, also one a clip
281
+ // still holds: the entry keeps its first lease, this one closes.
282
+ entry.aliases ??= new WeakSet();
283
+ if (!entry.aliases.has(frame)) {
284
+ entry.aliases.add(frame);
285
+ frame.dispose?.();
286
+ }
287
+ }
288
+ held.add(frame);
289
+ current.set(producer, frame.id);
290
+ owned[key] = {
291
+ width: frame.width,
292
+ height: frame.height,
293
+ rotation: frame.rotation,
294
+ crop: frame.crop,
295
+ id: frame.id,
296
+ producerId: producer,
297
+ texture: {
298
+ kind: "skia-image",
299
+ image: entry.image
300
+ }
301
+ };
302
+ }
303
+ // Clips that left the composition. A failed release stays tracked.
304
+ for (const [producer, entry] of imports.entries) {
305
+ if (current.has(producer)) continue;
306
+ releaseExportFrame(entry);
307
+ imports.entries.delete(producer);
308
+ releaseProducerTexture(imports, producer);
309
+ }
310
+ } catch (error) {
311
+ // Close the leases this call does not hold; none reached the fallback.
312
+ for (const frame of Object.values(decoded)) {
313
+ if (held.has(frame)) continue;
314
+ const producer = frame.producerId ?? frame.id;
315
+ const entry = producer === undefined ? undefined : imports.entries.get(producer);
316
+ if (entry && entry.id === frame.id) continue;
317
+ try {
318
+ frame.dispose?.();
319
+ } catch {
320
+ /* the native frame closes with its JS object */
321
+ }
322
+ }
323
+ throw error;
324
+ }
325
+ // The fallback owns, closes or retains every frame it is handed.
326
+ const rest = {};
327
+ let copying = false;
328
+ for (const [key, frame] of Object.entries(decoded)) {
329
+ if (held.has(frame)) continue;
330
+ rest[key] = frame;
331
+ copying = true;
332
+ }
333
+ return copying ? {
334
+ ...owned,
335
+ ...fallback(rest)
336
+ } : owned;
337
+ };
338
+ //# sourceMappingURL=exportFrames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","BlendMode","Skia","createNativeVideoGpuFrame","getVideoGpuDevice","nativeVideoTextureUsage","frameByteSize","releaseVideoMemory","reserveVideoMemory","blitYuvFrame","releaseYuvImports","yuvFrameOrigin","convertsYuv","OS","createExportFrameImports","entries","Map","producers","Set","enabled","imported","textures","yuv","canImportInPlace","frame","texture","kind","id","undefined","region","releaseExportFrame","entry","image","dispose","accessing","memory","ended","endAccess","state","fences","fence","destroy","nativeFrame","release","releaseProducerTexture","imports","producer","target","get","reservation","delete","importYuvExportFrame","producerId","source","submitted","nativeBuffer","rotation","origin","device","width","height","createTexture","size","format","usage","label","error","set","Image","MakeImageFromGPUTexture","Error","drain","Surface","MakeFromGPUTexture","getCanvas","drawColor","Color","Clear","flush","importExportFrame","pixelFormat","importSharedTextureMemory","handle","beginAccess","releaseExportFrames","keys","ownExportFrames","decoded","fallback","owned","held","current","key","Object","seen","next","console","warn","String","add","aliases","WeakSet","has","crop","values","rest","copying"],"sourceRoot":"../../src","sources":["exportFrames.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ const waiting = [];
4
+ let running = false;
5
+ export const exportAbortError = signal => {
6
+ const reason = signal?.reason;
7
+ if (reason !== undefined) return reason;
8
+ const error = new Error("Aborted");
9
+ error.name = "AbortError";
10
+ return error;
11
+ };
12
+ const pump = () => {
13
+ if (running) return;
14
+ const job = waiting.shift();
15
+ if (!job) return;
16
+ job.signal?.removeEventListener("abort", job.onAbort);
17
+ running = true;
18
+ Promise.resolve().then(job.run).then(job.resolve, job.reject).finally(() => {
19
+ running = false;
20
+ pump();
21
+ });
22
+ };
23
+
24
+ /** One active export and at most three waiting jobs. A queued abort releases
25
+ * its captured composition immediately, without allocating native resources. */
26
+ export const enqueueExport = (run, signal) => new Promise((resolve, reject) => {
27
+ if (signal?.aborted) {
28
+ reject(exportAbortError(signal));
29
+ return;
30
+ }
31
+ if (waiting.length >= 3) {
32
+ reject(new Error("Video export queue is full"));
33
+ return;
34
+ }
35
+ const job = {
36
+ run,
37
+ resolve,
38
+ reject,
39
+ signal,
40
+ onAbort: () => {
41
+ const index = waiting.indexOf(job);
42
+ if (index < 0) return;
43
+ waiting.splice(index, 1);
44
+ signal?.removeEventListener("abort", job.onAbort);
45
+ reject(exportAbortError(signal));
46
+ }
47
+ };
48
+ signal?.addEventListener("abort", job.onAbort);
49
+ waiting.push(job);
50
+ pump();
51
+ });
52
+ //# sourceMappingURL=exportQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["waiting","running","exportAbortError","signal","reason","undefined","error","Error","name","pump","job","shift","removeEventListener","onAbort","Promise","resolve","then","run","reject","finally","enqueueExport","aborted","length","index","indexOf","splice","addEventListener","push"],"sourceRoot":"../../src","sources":["exportQueue.ts"],"mappings":";;AAOA,MAAMA,OAAc,GAAG,EAAE;AACzB,IAAIC,OAAO,GAAG,KAAK;AAEnB,OAAO,MAAMC,gBAAgB,GAAIC,MAAoB,IAAc;EACjE,MAAMC,MAAM,GAAID,MAAM,EAAuCC,MAAM;EACnE,IAAIA,MAAM,KAAKC,SAAS,EAAE,OAAOD,MAAM;EACvC,MAAME,KAAK,GAAG,IAAIC,KAAK,CAAC,SAAS,CAAC;EAClCD,KAAK,CAACE,IAAI,GAAG,YAAY;EACzB,OAAOF,KAAK;AACd,CAAC;AAED,MAAMG,IAAI,GAAGA,CAAA,KAAM;EACjB,IAAIR,OAAO,EAAE;EACb,MAAMS,GAAG,GAAGV,OAAO,CAACW,KAAK,CAAC,CAAC;EAC3B,IAAI,CAACD,GAAG,EAAE;EACVA,GAAG,CAACP,MAAM,EAAES,mBAAmB,CAAC,OAAO,EAAEF,GAAG,CAACG,OAAO,CAAC;EACrDZ,OAAO,GAAG,IAAI;EACda,OAAO,CAACC,OAAO,CAAC,CAAC,CACdC,IAAI,CAACN,GAAG,CAACO,GAAG,CAAC,CACbD,IAAI,CAACN,GAAG,CAACK,OAAO,EAAEL,GAAG,CAACQ,MAAM,CAAC,CAC7BC,OAAO,CAAC,MAAM;IACblB,OAAO,GAAG,KAAK;IACfQ,IAAI,CAAC,CAAC;EACR,CAAC,CAAC;AACN,CAAC;;AAED;AACA;AACA,OAAO,MAAMW,aAAa,GAAGA,CAC3BH,GAAwB,EACxBd,MAAoB,KAEpB,IAAIW,OAAO,CAAC,CAACC,OAAO,EAAEG,MAAM,KAAK;EAC/B,IAAIf,MAAM,EAAEkB,OAAO,EAAE;IACnBH,MAAM,CAAChB,gBAAgB,CAACC,MAAM,CAAC,CAAC;IAChC;EACF;EACA,IAAIH,OAAO,CAACsB,MAAM,IAAI,CAAC,EAAE;IACvBJ,MAAM,CAAC,IAAIX,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC/C;EACF;EACA,MAAMG,GAAQ,GAAG;IACfO,GAAG;IACHF,OAAO;IACPG,MAAM;IACNf,MAAM;IACNU,OAAO,EAAEA,CAAA,KAAM;MACb,MAAMU,KAAK,GAAGvB,OAAO,CAACwB,OAAO,CAACd,GAAG,CAAC;MAClC,IAAIa,KAAK,GAAG,CAAC,EAAE;MACfvB,OAAO,CAACyB,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC;MACxBpB,MAAM,EAAES,mBAAmB,CAAC,OAAO,EAAEF,GAAG,CAACG,OAAO,CAAC;MACjDK,MAAM,CAAChB,gBAAgB,CAACC,MAAM,CAAC,CAAC;IAClC;EACF,CAAC;EACDA,MAAM,EAAEuB,gBAAgB,CAAC,OAAO,EAAEhB,GAAG,CAACG,OAAO,CAAC;EAC9Cb,OAAO,CAAC2B,IAAI,CAACjB,GAAG,CAAC;EACjBD,IAAI,CAAC,CAAC;AACR,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+
3
+ /// <reference types="@webgpu/types" />
4
+ import { Platform } from "react-native";
5
+ import { BlendMode, Skia } from "react-native-skia";
6
+ import { getVideoCanvas } from "./canvas.js";
7
+ import { createNativeVideoGpuFrame, getVideoGpuDevice } from "./gpuDevice.js";
8
+
9
+ /** An encoder pool buffer that Skia draws into through WebGPU. */
10
+
11
+ // Captured on the RN runtime. iOS lends CVPixelBuffers, imported through
12
+ // their IOSurface; Android lends the AHardwareBuffer itself.
13
+ const lendsPixelBuffers = Platform.OS === "ios";
14
+ export const supportsEncoderTargets = encoder => {
15
+ "worklet";
16
+
17
+ return typeof encoder.acquireFrameBuffer === "function" && typeof encoder.releaseFrameBuffer === "function";
18
+ };
19
+
20
+ // Declared before its callers: worklets capture their closure on creation.
21
+ /** Ends GPU access; the lent buffer stays with the caller, to encode or
22
+ * release. Call only after a checked flush(true) of its surface. With
23
+ * `encoding`, Android keeps the access's sync-fds in `target.fences` for the
24
+ * encoder, which owns and closes them: ending an AHB access submits a
25
+ * release that flush(true) has not waited for. */
26
+ export const closeEncoderTarget = (target, encoding = false) => {
27
+ "worklet";
28
+
29
+ target.canvas?.dispose();
30
+ target.canvas = null;
31
+ target.surface?.dispose();
32
+ target.surface = null;
33
+ if (target.accessing && target.memory && target.texture) {
34
+ const ended = target.memory.endAccess(target.texture);
35
+ target.accessing = false;
36
+ for (const state of ended?.fences ?? []) {
37
+ try {
38
+ if (encoding && !lendsPixelBuffers) {
39
+ const exported = state.fence.export();
40
+ // Unreachable when negotiated: AHB interop requires the device's
41
+ // only shared-fence feature to be sync-fd (see gpuDevice.ts).
42
+ if (exported.type !== "sync-fd") throw new Error("GPU export needs sync-fd fences");
43
+ target.fences.push(exported.handle);
44
+ }
45
+ } finally {
46
+ // iOS: already waited for. The wrapper is released either way.
47
+ state.fence.destroy();
48
+ }
49
+ }
50
+ }
51
+ target.accessing = false;
52
+ target.texture?.destroy();
53
+ target.texture = null;
54
+ // Close the IOSurface import now rather than at the export runtime's next
55
+ // GC, so the encoder's bounded pool gets the buffer back promptly.
56
+ target.memory?.destroy();
57
+ target.memory = null;
58
+ // Drop the IOSurface promptly so the pool can recycle it.
59
+ target.frame?.release();
60
+ target.frame = null;
61
+ };
62
+
63
+ /** Lends the next pool buffer and wraps it as a Skia surface. */
64
+ export const acquireEncoderTarget = (encoder, width, height) => {
65
+ "worklet";
66
+
67
+ const target = {
68
+ pointer: encoder.acquireFrameBuffer(),
69
+ fences: [],
70
+ frame: null,
71
+ memory: null,
72
+ texture: null,
73
+ accessing: false,
74
+ surface: null,
75
+ canvas: null
76
+ };
77
+ try {
78
+ if (lendsPixelBuffers) {
79
+ target.frame = createNativeVideoGpuFrame(target.pointer);
80
+ if (target.frame.width !== width || target.frame.height !== height || target.frame.pixelFormat !== "bgra8") {
81
+ throw new Error("Encoder buffer dimensions or BGRA layout mismatch");
82
+ }
83
+ }
84
+ const device = getVideoGpuDevice();
85
+ if (typeof device.importSharedTextureMemory !== "function") {
86
+ throw new Error("WebGPU shared texture memory is unavailable");
87
+ }
88
+ target.memory = device.importSharedTextureMemory({
89
+ handle: target.frame ? target.frame.handle : target.pointer,
90
+ label: "video export frame"
91
+ });
92
+ target.texture = target.memory.createTexture();
93
+ if (!lendsPixelBuffers && (target.texture.width !== width || target.texture.height !== height || target.texture.format !== "rgba8unorm")) {
94
+ throw new Error("Encoder buffer dimensions or RGBA layout mismatch");
95
+ }
96
+ // Uninitialized: every frame starts with a full clear.
97
+ target.memory.beginAccess(target.texture, false);
98
+ target.accessing = true;
99
+ target.surface = Skia.Surface.MakeFromGPUTexture(target.texture);
100
+ if (!target.surface) throw new Error("Cannot wrap the encoder buffer");
101
+ target.canvas = getVideoCanvas(target.surface);
102
+ return target;
103
+ } catch (error) {
104
+ try {
105
+ closeEncoderTarget(target);
106
+ encoder.releaseFrameBuffer();
107
+ } catch {
108
+ /* the encoder releases its lent buffer on dispose */
109
+ }
110
+ throw error;
111
+ }
112
+ };
113
+
114
+ /** Clears one lent buffer on the GPU, then returns it unencoded. Returns the
115
+ * failure, or null when this device can export through encoder targets. */
116
+ export const probeEncoderTarget = (encoder, width, height) => {
117
+ "worklet";
118
+
119
+ let target;
120
+ try {
121
+ target = acquireEncoderTarget(encoder, width, height);
122
+ } catch (error) {
123
+ return error ?? new Error("GPU export target unavailable");
124
+ }
125
+ let failure = null;
126
+ try {
127
+ target.canvas.drawColor(Skia.Color("#00000000"), BlendMode.Clear);
128
+ target.surface.flush(true);
129
+ } catch (error) {
130
+ failure = error ?? new Error("GPU export probe failed");
131
+ }
132
+ // Not caught: an access that cannot end must fail the export, not fall back.
133
+ closeEncoderTarget(target);
134
+ encoder.releaseFrameBuffer();
135
+ return failure;
136
+ };
137
+ //# sourceMappingURL=exportTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","BlendMode","Skia","getVideoCanvas","createNativeVideoGpuFrame","getVideoGpuDevice","lendsPixelBuffers","OS","supportsEncoderTargets","encoder","acquireFrameBuffer","releaseFrameBuffer","closeEncoderTarget","target","encoding","canvas","dispose","surface","accessing","memory","texture","ended","endAccess","state","fences","exported","fence","export","type","Error","push","handle","destroy","frame","release","acquireEncoderTarget","width","height","pointer","pixelFormat","device","importSharedTextureMemory","label","createTexture","format","beginAccess","Surface","MakeFromGPUTexture","error","probeEncoderTarget","failure","drawColor","Color","Clear","flush"],"sourceRoot":"../../src","sources":["exportTarget.ts"],"mappings":"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","ignoreList":[]}