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,368 @@
1
+ "use strict";
2
+
3
+ import { getVideoCanvas } from "./canvas.js";
4
+ import { BlendMode, Skia } from "react-native-skia";
5
+ import { useSharedValue, useFrameCallback, runOnUI } from "react-native-reanimated";
6
+ import { useCallback, useEffect, useRef, useState } from "react";
7
+ import RNSkiaVideoModule from "./RNSkiaVideoModule.js";
8
+ import useEventListener from "./utils/useEventListener.js";
9
+ import { PixelRatio } from "react-native";
10
+ import { scheduleOnRN } from "react-native-worklets";
11
+ import { ownVideoFrames, releaseVideoFrameImage } from "./frameInterop.js";
12
+ import { frameByteSize, reserveVideoMemory } from "./memory.js";
13
+ import { disposePreviewResources } from "./previewLifecycle.js";
14
+ /**
15
+ * A hook that creates a video composition player.
16
+ */
17
+ export const useVideoComposition = ({
18
+ composition,
19
+ drawFrame,
20
+ beforeDrawFrame,
21
+ afterDrawFrame,
22
+ width,
23
+ height,
24
+ autoPlay = false,
25
+ isLooping = false,
26
+ drawWhenPaused = false,
27
+ redrawOnTime,
28
+ splitImportAndDraw = false,
29
+ onReadyToPlay,
30
+ onComplete,
31
+ onError
32
+ }) => {
33
+ const [failedComposition, setFailedComposition] = useState(null);
34
+ const isErrored = composition !== null && failedComposition === composition;
35
+ const [session, setSession] = useState(null);
36
+ const framesExtractor = session?.extractor ?? null;
37
+ const generation = session?.generation ?? 0;
38
+ const nextGeneration = useRef(0);
39
+ const activeOnRN = useRef(0);
40
+ // HostObject JS wrappers are recreated across runtimes; compare numbers.
41
+ const activeGeneration = useSharedValue(0);
42
+ const frameGeneration = useSharedValue(0);
43
+ const sourcesGeneration = useSharedValue(0);
44
+ const currentFrame = useSharedValue(null);
45
+ const pendingSnapshot = useSharedValue(null);
46
+ // Reanimated interprets a function assigned to `.value` as an animation
47
+ // factory. Keep the teardown callback inside an ordinary value instead.
48
+ const pendingAfterDraw = useSharedValue(null);
49
+ const previousSources = useSharedValue({});
50
+ const onCreationError = useRef(onError);
51
+ onCreationError.current = onError;
52
+ useEffect(() => {
53
+ if (!composition || isErrored) {
54
+ setSession(null);
55
+ return;
56
+ }
57
+ let created;
58
+ try {
59
+ created = RNSkiaVideoModule.createVideoCompositionFramesExtractor(composition);
60
+ } catch (error) {
61
+ setFailedComposition(composition);
62
+ onCreationError.current?.(error, () => setFailedComposition(null));
63
+ return;
64
+ }
65
+ const createdGeneration = ++nextGeneration.current;
66
+ activeOnRN.current = createdGeneration;
67
+ activeGeneration.value = createdGeneration;
68
+ setSession({
69
+ extractor: created,
70
+ generation: createdGeneration,
71
+ composition
72
+ });
73
+ return () => {
74
+ if (activeOnRN.current === createdGeneration) {
75
+ activeOnRN.current = 0;
76
+ activeGeneration.value = 0;
77
+ }
78
+ runOnUI(() => {
79
+ "worklet";
80
+
81
+ if (frameGeneration.value === createdGeneration || sourcesGeneration.value === createdGeneration) releasePreview(created);else {
82
+ const failure = disposePreviewResources({
83
+ native: created
84
+ });
85
+ if (failure.failed) console.warn("Video preview cleanup failed; resources remain accounted until native runtime teardown", failure.error);
86
+ }
87
+ })();
88
+ };
89
+ }, [composition, isErrored, activeGeneration, currentFrame, previousSources, frameGeneration, sourcesGeneration, pendingSnapshot, pendingAfterDraw]);
90
+ const retry = useCallback(() => {
91
+ setFailedComposition(null);
92
+ }, []);
93
+ const errorHandler = useCallback(error => {
94
+ if (generation !== activeOnRN.current) return;
95
+ activeOnRN.current = 0;
96
+ activeGeneration.value = 0;
97
+ setFailedComposition(session.composition);
98
+ onCreationError.current?.(error, retry);
99
+ }, [retry, generation, activeGeneration, session]);
100
+ useEffect(() => {
101
+ if (framesExtractor) {
102
+ framesExtractor.isLooping = isLooping;
103
+ }
104
+ }, [framesExtractor, isLooping]);
105
+ const isCurrentSession = useCallback(() => generation !== 0 && generation === activeOnRN.current, [generation]);
106
+ useEventListener(framesExtractor, "ready", onReadyToPlay, isCurrentSession);
107
+ useEventListener(framesExtractor, "complete", onComplete, isCurrentSession);
108
+ useEventListener(framesExtractor, "error", errorHandler, isCurrentSession);
109
+ useEffect(() => {
110
+ if (!framesExtractor) return;
111
+ runOnUI(() => {
112
+ "worklet";
113
+
114
+ if (activeGeneration.value !== generation) return;
115
+ try {
116
+ framesExtractor.prepare();
117
+ } catch (error) {
118
+ activeGeneration.value = 0;
119
+ scheduleOnRN(errorHandler, error);
120
+ }
121
+ })();
122
+ }, [framesExtractor, activeGeneration, generation, errorHandler]);
123
+ useEffect(() => {
124
+ if (autoPlay) {
125
+ framesExtractor?.play();
126
+ }
127
+ }, [framesExtractor, autoPlay]);
128
+ const surfaceSharedValue = useSharedValue(null);
129
+ const canvasSharedValue = useSharedValue(null);
130
+ const surfaceReservation = useSharedValue(0);
131
+ const surfaceWidth = useSharedValue(0);
132
+ const surfaceHeight = useSharedValue(0);
133
+ const releasePreview = native => {
134
+ "worklet";
135
+
136
+ const resources = {
137
+ surface: surfaceSharedValue.value,
138
+ canvas: canvasSharedValue.value,
139
+ images: [currentFrame.value, pendingSnapshot.value],
140
+ frames: Object.values(previousSources.value),
141
+ reservation: surfaceReservation.value,
142
+ afterDraw: pendingAfterDraw.value?.run,
143
+ native
144
+ };
145
+ // Remove consumers before attempting a drain. A thrown drain must never
146
+ // leave teardown callbacks able to recycle these same resources later.
147
+ currentFrame.value = null;
148
+ pendingSnapshot.value = null;
149
+ pendingAfterDraw.value = null;
150
+ frameGeneration.value = 0;
151
+ previousSources.value = {};
152
+ sourcesGeneration.value = 0;
153
+ surfaceSharedValue.value = null;
154
+ canvasSharedValue.value = null;
155
+ surfaceReservation.value = 0;
156
+ surfaceWidth.value = 0;
157
+ surfaceHeight.value = 0;
158
+ const failure = disposePreviewResources(resources);
159
+ if (failure.failed) console.warn("Video preview cleanup failed; resources remain accounted until native runtime teardown", failure.error);
160
+ };
161
+ // Frames version and composition time of the last drawn image, to skip
162
+ // redrawing an unchanged picture while paused.
163
+ const lastDrawnFramesVersion = useSharedValue(-1);
164
+ const lastDrawnTime = useSharedValue(-1);
165
+ const lastDrawnInputs = useSharedValue(null);
166
+ // Frames version whose new frames the previous vsyncs already imported.
167
+ const lastImportedVersion = useSharedValue(-1);
168
+ // Whether the previous vsync imported and left its draw to this one.
169
+ const drawDeferred = useSharedValue(false);
170
+ // A new drawFrame can draw something else from the same time and frames.
171
+ useEffect(() => {
172
+ lastDrawnTime.value = -1;
173
+ }, [drawFrame, lastDrawnTime]);
174
+ const pixelRatio = PixelRatio.get();
175
+
176
+ // Release the offscreen surface with the hook that made it. Without this a
177
+ // caller that mounts and unmounts the player repeatedly — a player inside a
178
+ // modal, say — leaks a full size texture per cycle. runOnUI because this
179
+ // effect is declared before the frame callback below, and so its cleanup runs
180
+ // before the callback is unregistered.
181
+ useEffect(() => () => {
182
+ runOnUI(() => {
183
+ "worklet";
184
+
185
+ releasePreview();
186
+ })();
187
+ }, [surfaceSharedValue, canvasSharedValue, surfaceReservation, surfaceWidth, surfaceHeight, currentFrame, pendingSnapshot, pendingAfterDraw, frameGeneration, previousSources, sourcesGeneration]);
188
+ useFrameCallback(() => {
189
+ "worklet";
190
+
191
+ if (!framesExtractor || activeGeneration.value !== generation) {
192
+ return;
193
+ }
194
+ try {
195
+ const pixelWidth = Math.floor(width * pixelRatio);
196
+ const pixelHeight = Math.floor(height * pixelRatio);
197
+
198
+ // Layout can report zero or NaN before the player is measured. Avoid
199
+ // native surface allocation until the dimensions are valid.
200
+ if (!(pixelWidth > 0) || !(pixelHeight > 0) || !isFinite(pixelWidth) || !isFinite(pixelHeight)) {
201
+ return;
202
+ }
203
+
204
+ // Pull the frames decoded since the last vsync first: it is cheap when
205
+ // nothing new arrived, and it is what lets a paused player pick up the
206
+ // frame of a seek.
207
+ const frames = ownVideoFrames(framesExtractor.decodeCompositionFrames());
208
+ for (const [key, previous] of Object.entries(previousSources.value)) {
209
+ if (!frames[key] || frames[key].producerId !== previous.producerId) releaseVideoFrameImage(previous);
210
+ }
211
+ previousSources.value = frames;
212
+ sourcesGeneration.value = generation;
213
+ const currentTime = framesExtractor.currentTime;
214
+ const framesVersion = framesExtractor.framesVersion;
215
+ if (splitImportAndDraw && framesVersion !== lastImportedVersion.value) {
216
+ // ownVideoFrames above has just imported the new frames: leave the
217
+ // draw to the next vsync, which finds them in the import cache. Never
218
+ // twice running: a frame that lands on the vsync owed a draw would
219
+ // push it again, and the frame before it would never be shown.
220
+ lastImportedVersion.value = framesVersion;
221
+ if (!drawDeferred.value && currentFrame.value !== null && frameGeneration.value === generation) {
222
+ drawDeferred.value = true;
223
+ return;
224
+ }
225
+ }
226
+ drawDeferred.value = false;
227
+ const inputs = Array.isArray(drawWhenPaused) ? drawWhenPaused : null;
228
+ let inputsSame = true;
229
+ if (inputs) {
230
+ const last = lastDrawnInputs.value;
231
+ if (!last || last.length !== inputs.length) inputsSame = false;else {
232
+ for (let i = 0; i < inputs.length; i++) {
233
+ if (inputs[i].value !== last[i]) {
234
+ inputsSame = false;
235
+ break;
236
+ }
237
+ }
238
+ }
239
+ }
240
+ // A negative last time means a redraw was requested (a new drawFrame).
241
+ const timeSame = currentTime === lastDrawnTime.value || redrawOnTime !== undefined && lastDrawnTime.value >= 0 && !redrawOnTime(lastDrawnTime.value, currentTime);
242
+ if (drawWhenPaused !== true && inputsSame && (!framesExtractor.isPlaying || redrawOnTime !== undefined) && currentFrame.value !== null && frameGeneration.value === generation && framesVersion === lastDrawnFramesVersion.value && timeSame && surfaceWidth.value === pixelWidth && surfaceHeight.value === pixelHeight) {
243
+ // Nothing new to show: the image on screen is still exact, and
244
+ // redrawing it at every vsync would only burn GPU time and battery.
245
+ return;
246
+ }
247
+ let surface = surfaceSharedValue.value;
248
+ if (!surface || surfaceWidth.value !== pixelWidth || surfaceHeight.value !== pixelHeight) {
249
+ // width and height can change while the player stays mounted — laying the
250
+ // stage out for a different aspect ratio calls the hook with new
251
+ // dimensions and the same surface. Drawing the new size into the old
252
+ // texture and then declaring the result to be the new size stretches the
253
+ // picture by the ratio between them, so the surface is re-keyed on its
254
+ // dimensions the way exportVideoComposition already re-keys its own.
255
+ const retired = {
256
+ images: [currentFrame.value, pendingSnapshot.value],
257
+ surface,
258
+ canvas: canvasSharedValue.value,
259
+ reservation: surfaceReservation.value,
260
+ afterDraw: pendingAfterDraw.value?.run
261
+ };
262
+ currentFrame.value = null;
263
+ pendingSnapshot.value = null;
264
+ pendingAfterDraw.value = null;
265
+ canvasSharedValue.value = null;
266
+ surfaceSharedValue.value = null;
267
+ surfaceReservation.value = 0;
268
+ const retiredFailure = disposePreviewResources(retired);
269
+ if (retiredFailure.failed) throw retiredFailure.error;
270
+ // Surface + immutable snapshot/COW backing while replacing the preview.
271
+ const reservation = reserveVideoMemory(frameByteSize(pixelWidth, pixelHeight) * 2, "composition preview");
272
+ surfaceReservation.value = reservation;
273
+ try {
274
+ surface = Skia.Surface.MakeOffscreen(pixelWidth, pixelHeight);
275
+ surfaceSharedValue.value = surface;
276
+ if (!surface) throw new Error("Cannot allocate preview surface");
277
+ canvasSharedValue.value = getVideoCanvas(surface);
278
+ surfaceWidth.value = pixelWidth;
279
+ surfaceHeight.value = pixelHeight;
280
+ } catch (error) {
281
+ // The ordinary session cleanup owns partial allocation state too.
282
+ // Preserve the setup error and keep its reservation reachable.
283
+ throw error;
284
+ }
285
+ }
286
+ if (!surface) {
287
+ console.warn("Failed to create surface");
288
+ return;
289
+ }
290
+ const canvas = canvasSharedValue.value;
291
+ // Cleared as the export clears it: a drawFrame that leaves part of the
292
+ // canvas alone showed the previous frames there, and not in the export.
293
+ canvas.drawColor(Skia.Color("#00000000"), BlendMode.Clear);
294
+ const context = beforeDrawFrame?.();
295
+ const drawn = {
296
+ submitted: false,
297
+ failed: false,
298
+ error: undefined
299
+ };
300
+ const releaseContext = () => {
301
+ "worklet";
302
+
303
+ afterDrawFrame?.(context);
304
+ };
305
+ pendingAfterDraw.value = {
306
+ run: releaseContext
307
+ };
308
+ try {
309
+ drawFrame({
310
+ canvas,
311
+ context,
312
+ videoComposition: composition,
313
+ currentTime,
314
+ frames,
315
+ width: pixelWidth,
316
+ height: pixelHeight
317
+ });
318
+ const previous = currentFrame.value;
319
+ const next = surface.makeImageSnapshot(undefined, previous ?? undefined);
320
+ if (next !== previous) pendingSnapshot.value = next;
321
+ surface.flush(true);
322
+ drawn.submitted = true;
323
+ frameGeneration.value = generation;
324
+ if (next === previous) currentFrame.modify(undefined, true);else {
325
+ currentFrame.value = next;
326
+ previous?.dispose();
327
+ }
328
+ pendingSnapshot.value = null;
329
+ } catch (error) {
330
+ drawn.failed = true;
331
+ drawn.error = error;
332
+ } finally {
333
+ // A drawer can throw after recording commands that sample resources
334
+ // from context. Submit and wait before the caller releases them.
335
+ if (!drawn.submitted) {
336
+ try {
337
+ surface.flush(true);
338
+ drawn.submitted = true;
339
+ } catch (error) {
340
+ if (!drawn.failed) drawn.error = error;
341
+ drawn.failed = true;
342
+ }
343
+ }
344
+ if (drawn.submitted) {
345
+ pendingAfterDraw.value = null;
346
+ try {
347
+ releaseContext();
348
+ } catch (error) {
349
+ if (!drawn.failed) drawn.error = error;
350
+ drawn.failed = true;
351
+ }
352
+ }
353
+ }
354
+ if (drawn.failed) throw drawn.error;
355
+ lastDrawnFramesVersion.value = framesVersion;
356
+ lastDrawnTime.value = currentTime;
357
+ if (inputs) lastDrawnInputs.value = inputs.map(input => input.value);
358
+ } catch (error) {
359
+ activeGeneration.value = 0;
360
+ scheduleOnRN(errorHandler, error);
361
+ }
362
+ }, true);
363
+ return {
364
+ currentFrame,
365
+ player: framesExtractor
366
+ };
367
+ };
368
+ //# sourceMappingURL=videoCompositionPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getVideoCanvas","BlendMode","Skia","useSharedValue","useFrameCallback","runOnUI","useCallback","useEffect","useRef","useState","RNSkiaVideoModule","useEventListener","PixelRatio","scheduleOnRN","ownVideoFrames","releaseVideoFrameImage","frameByteSize","reserveVideoMemory","disposePreviewResources","useVideoComposition","composition","drawFrame","beforeDrawFrame","afterDrawFrame","width","height","autoPlay","isLooping","drawWhenPaused","redrawOnTime","splitImportAndDraw","onReadyToPlay","onComplete","onError","failedComposition","setFailedComposition","isErrored","session","setSession","framesExtractor","extractor","generation","nextGeneration","activeOnRN","activeGeneration","frameGeneration","sourcesGeneration","currentFrame","pendingSnapshot","pendingAfterDraw","previousSources","onCreationError","current","created","createVideoCompositionFramesExtractor","error","createdGeneration","value","releasePreview","failure","native","failed","console","warn","retry","errorHandler","isCurrentSession","prepare","play","surfaceSharedValue","canvasSharedValue","surfaceReservation","surfaceWidth","surfaceHeight","resources","surface","canvas","images","frames","Object","values","reservation","afterDraw","run","lastDrawnFramesVersion","lastDrawnTime","lastDrawnInputs","lastImportedVersion","drawDeferred","pixelRatio","get","pixelWidth","Math","floor","pixelHeight","isFinite","decodeCompositionFrames","key","previous","entries","producerId","currentTime","framesVersion","inputs","Array","isArray","inputsSame","last","length","i","timeSame","undefined","isPlaying","retired","retiredFailure","Surface","MakeOffscreen","Error","drawColor","Color","Clear","context","drawn","submitted","releaseContext","videoComposition","next","makeImageSnapshot","flush","modify","dispose","map","input","player"],"sourceRoot":"../../src","sources":["videoCompositionPlayer.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+
3
+ import { Skia } from "react-native-skia";
4
+ import { imageFromVideoFrame } from "./frameInterop.js";
5
+
6
+ /**
7
+ * A frame as a Skia image, with what it takes to show its picture: the part of
8
+ * the image that is the picture, and the rotation that shows it upright.
9
+ */
10
+
11
+ /**
12
+ * How the picture fills the destination of {@link drawVideoFrame}.
13
+ *
14
+ * - `fill`: all of it, stretched to the destination.
15
+ * - `cover`: the middle of it with the destination's aspect, all of the
16
+ * destination.
17
+ * - `contain`: all of it with its own aspect, in the middle of the destination.
18
+ */
19
+
20
+ /**
21
+ * Wraps a frame's texture in a Skia image, and says which part of it to draw
22
+ * and how to turn it. Works with every frame, whatever the platform and the
23
+ * texture mode: iOS frames and Android `direct` frames come as decoded, with
24
+ * a rotation, and Android `direct` frames are larger than their picture.
25
+ *
26
+ * @param frame the frame, drawn in the tick it was handed out in
27
+ * @param output an image returned for a previous frame, recycled rather than
28
+ * allocating a new wrapper. Accepted for compatibility; owned snapshots are used in v3
29
+ * @returns the image and its picture, or null when the frame has no texture
30
+ */
31
+ export const makeVideoFrameImage = (frame, _output) => {
32
+ "worklet";
33
+
34
+ const image = imageFromVideoFrame(frame);
35
+ if (!image) {
36
+ return null;
37
+ }
38
+ const crop = frame.crop ?? {
39
+ x: 0,
40
+ y: 0,
41
+ width: frame.width,
42
+ height: frame.height
43
+ };
44
+ const rotation = (Math.round(frame.rotation / 90) * 90 % 360 + 360) % 360;
45
+ const quarter = rotation === 90 || rotation === 270;
46
+ return {
47
+ image,
48
+ rect: {
49
+ x: crop.x,
50
+ y: crop.y,
51
+ width: crop.width,
52
+ height: crop.height
53
+ },
54
+ rotation,
55
+ width: quarter ? crop.height : crop.width,
56
+ height: quarter ? crop.width : crop.height
57
+ };
58
+ };
59
+
60
+ /**
61
+ * The part of the texture that shows a rectangle of the upright picture.
62
+ */
63
+ const textureRectOf = (rect, rotation, upright) => {
64
+ "worklet";
65
+
66
+ const u0 = upright.x;
67
+ const u1 = upright.x + upright.width;
68
+ const v0 = upright.y;
69
+ const v1 = upright.y + upright.height;
70
+ switch (rotation) {
71
+ case 90:
72
+ // Turned clockwise: the texture's left edge is the picture's top.
73
+ return {
74
+ x: rect.x + v0,
75
+ y: rect.y + rect.height - u1,
76
+ width: v1 - v0,
77
+ height: u1 - u0
78
+ };
79
+ case 180:
80
+ return {
81
+ x: rect.x + rect.width - u1,
82
+ y: rect.y + rect.height - v1,
83
+ width: u1 - u0,
84
+ height: v1 - v0
85
+ };
86
+ case 270:
87
+ return {
88
+ x: rect.x + rect.width - v1,
89
+ y: rect.y + u0,
90
+ width: v1 - v0,
91
+ height: u1 - u0
92
+ };
93
+ default:
94
+ return {
95
+ x: rect.x + u0,
96
+ y: rect.y + v0,
97
+ width: u1 - u0,
98
+ height: v1 - v0
99
+ };
100
+ }
101
+ };
102
+
103
+ /**
104
+ * Draws a frame's picture, upright, into a rectangle of the canvas.
105
+ *
106
+ * @param canvas the canvas to draw on
107
+ * @param frame the frame, drawn in the tick it was handed out in
108
+ * @param dst where to draw the picture
109
+ * @param options.paint the paint to draw with, for an opacity say
110
+ * @param options.fit how the picture fills `dst`, `fill` by default
111
+ * @param options.output an image returned by a previous call, recycled
112
+ * @returns the image drawn, to pass back as `output` next time, or null when
113
+ * the frame has no texture
114
+ */
115
+ export const drawVideoFrame = (canvas, frame, dst, options) => {
116
+ "worklet";
117
+
118
+ const frameImage = makeVideoFrameImage(frame, options?.output);
119
+ if (!frameImage) {
120
+ return null;
121
+ }
122
+ const {
123
+ image,
124
+ rect,
125
+ rotation,
126
+ width,
127
+ height
128
+ } = frameImage;
129
+ const fit = options?.fit ?? "fill";
130
+ // What of the upright picture is drawn, and where.
131
+ let picture = {
132
+ x: 0,
133
+ y: 0,
134
+ width,
135
+ height
136
+ };
137
+ let target = dst;
138
+ if (fit === "cover") {
139
+ const scale = Math.max(dst.width / width, dst.height / height);
140
+ const visibleWidth = dst.width / scale;
141
+ const visibleHeight = dst.height / scale;
142
+ picture = {
143
+ x: (width - visibleWidth) / 2,
144
+ y: (height - visibleHeight) / 2,
145
+ width: visibleWidth,
146
+ height: visibleHeight
147
+ };
148
+ } else if (fit === "contain") {
149
+ const scale = Math.min(dst.width / width, dst.height / height);
150
+ target = {
151
+ x: dst.x + (dst.width - width * scale) / 2,
152
+ y: dst.y + (dst.height - height * scale) / 2,
153
+ width: width * scale,
154
+ height: height * scale
155
+ };
156
+ }
157
+ const src = textureRectOf(rect, rotation, picture);
158
+ const paint = options?.paint ?? Skia.Paint();
159
+ try {
160
+ if (rotation === 0) {
161
+ canvas.drawImageRect(image, src, target, paint);
162
+ return image;
163
+ }
164
+ const quarter = rotation === 90 || rotation === 270;
165
+ const turnedWidth = quarter ? target.height : target.width;
166
+ const turnedHeight = quarter ? target.width : target.height;
167
+ canvas.save();
168
+ try {
169
+ canvas.translate(target.x + target.width / 2, target.y + target.height / 2);
170
+ canvas.rotate(rotation, 0, 0);
171
+ canvas.drawImageRect(image, src, {
172
+ x: -turnedWidth / 2,
173
+ y: -turnedHeight / 2,
174
+ width: turnedWidth,
175
+ height: turnedHeight
176
+ }, paint);
177
+ } finally {
178
+ canvas.restore();
179
+ }
180
+ return image;
181
+ } finally {
182
+ if (!options?.paint) paint.dispose();
183
+ }
184
+ };
185
+ //# sourceMappingURL=videoFrameImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Skia","imageFromVideoFrame","makeVideoFrameImage","frame","_output","image","crop","x","y","width","height","rotation","Math","round","quarter","rect","textureRectOf","upright","u0","u1","v0","v1","drawVideoFrame","canvas","dst","options","frameImage","output","fit","picture","target","scale","max","visibleWidth","visibleHeight","min","src","paint","Paint","drawImageRect","turnedWidth","turnedHeight","save","translate","rotate","restore","dispose"],"sourceRoot":"../../src","sources":["videoFrameImage.ts"],"mappings":";;AACA,SAASA,IAAI,QAAQ,mBAAmB;AAExC,SAASC,mBAAmB,QAAQ,mBAAgB;;AAEpD;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,mBAAmB,GAAGA,CACjCC,KAAiB,EACjBC,OAAwB,KACG;EAC3B,SAAS;;EACT,MAAMC,KAAK,GAAGJ,mBAAmB,CAACE,KAAK,CAAC;EACxC,IAAI,CAACE,KAAK,EAAE;IACV,OAAO,IAAI;EACb;EACA,MAAMC,IAAI,GAAGH,KAAK,CAACG,IAAI,IAAI;IACzBC,CAAC,EAAE,CAAC;IACJC,CAAC,EAAE,CAAC;IACJC,KAAK,EAAEN,KAAK,CAACM,KAAK;IAClBC,MAAM,EAAEP,KAAK,CAACO;EAChB,CAAC;EACD,MAAMC,QAAQ,GAAG,CAAGC,IAAI,CAACC,KAAK,CAACV,KAAK,CAACQ,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE,GAAI,GAAG,GAAI,GAAG,IAAI,GAAG;EAC7E,MAAMG,OAAO,GAAGH,QAAQ,KAAK,EAAE,IAAIA,QAAQ,KAAK,GAAG;EACnD,OAAO;IACLN,KAAK;IACLU,IAAI,EAAE;MAAER,CAAC,EAAED,IAAI,CAACC,CAAC;MAAEC,CAAC,EAAEF,IAAI,CAACE,CAAC;MAAEC,KAAK,EAAEH,IAAI,CAACG,KAAK;MAAEC,MAAM,EAAEJ,IAAI,CAACI;IAAO,CAAC;IACtEC,QAAQ;IACRF,KAAK,EAAEK,OAAO,GAAGR,IAAI,CAACI,MAAM,GAAGJ,IAAI,CAACG,KAAK;IACzCC,MAAM,EAAEI,OAAO,GAAGR,IAAI,CAACG,KAAK,GAAGH,IAAI,CAACI;EACtC,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA,MAAMM,aAAa,GAAGA,CACpBD,IAAY,EACZJ,QAAgB,EAChBM,OAAe,KACJ;EACX,SAAS;;EACT,MAAMC,EAAE,GAAGD,OAAO,CAACV,CAAC;EACpB,MAAMY,EAAE,GAAGF,OAAO,CAACV,CAAC,GAAGU,OAAO,CAACR,KAAK;EACpC,MAAMW,EAAE,GAAGH,OAAO,CAACT,CAAC;EACpB,MAAMa,EAAE,GAAGJ,OAAO,CAACT,CAAC,GAAGS,OAAO,CAACP,MAAM;EACrC,QAAQC,QAAQ;IACd,KAAK,EAAE;MACL;MACA,OAAO;QACLJ,CAAC,EAAEQ,IAAI,CAACR,CAAC,GAAGa,EAAE;QACdZ,CAAC,EAAEO,IAAI,CAACP,CAAC,GAAGO,IAAI,CAACL,MAAM,GAAGS,EAAE;QAC5BV,KAAK,EAAEY,EAAE,GAAGD,EAAE;QACdV,MAAM,EAAES,EAAE,GAAGD;MACf,CAAC;IACH,KAAK,GAAG;MACN,OAAO;QACLX,CAAC,EAAEQ,IAAI,CAACR,CAAC,GAAGQ,IAAI,CAACN,KAAK,GAAGU,EAAE;QAC3BX,CAAC,EAAEO,IAAI,CAACP,CAAC,GAAGO,IAAI,CAACL,MAAM,GAAGW,EAAE;QAC5BZ,KAAK,EAAEU,EAAE,GAAGD,EAAE;QACdR,MAAM,EAAEW,EAAE,GAAGD;MACf,CAAC;IACH,KAAK,GAAG;MACN,OAAO;QACLb,CAAC,EAAEQ,IAAI,CAACR,CAAC,GAAGQ,IAAI,CAACN,KAAK,GAAGY,EAAE;QAC3Bb,CAAC,EAAEO,IAAI,CAACP,CAAC,GAAGU,EAAE;QACdT,KAAK,EAAEY,EAAE,GAAGD,EAAE;QACdV,MAAM,EAAES,EAAE,GAAGD;MACf,CAAC;IACH;MACE,OAAO;QACLX,CAAC,EAAEQ,IAAI,CAACR,CAAC,GAAGW,EAAE;QACdV,CAAC,EAAEO,IAAI,CAACP,CAAC,GAAGY,EAAE;QACdX,KAAK,EAAEU,EAAE,GAAGD,EAAE;QACdR,MAAM,EAAEW,EAAE,GAAGD;MACf,CAAC;EACL;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,cAAc,GAAGA,CAC5BC,MAAgB,EAChBpB,KAAiB,EACjBqB,GAAW,EACXC,OAIC,KACkB;EACnB,SAAS;;EACT,MAAMC,UAAU,GAAGxB,mBAAmB,CAACC,KAAK,EAAEsB,OAAO,EAAEE,MAAM,CAAC;EAC9D,IAAI,CAACD,UAAU,EAAE;IACf,OAAO,IAAI;EACb;EACA,MAAM;IAAErB,KAAK;IAAEU,IAAI;IAAEJ,QAAQ;IAAEF,KAAK;IAAEC;EAAO,CAAC,GAAGgB,UAAU;EAC3D,MAAME,GAAG,GAAGH,OAAO,EAAEG,GAAG,IAAI,MAAM;EAClC;EACA,IAAIC,OAAe,GAAG;IAAEtB,CAAC,EAAE,CAAC;IAAEC,CAAC,EAAE,CAAC;IAAEC,KAAK;IAAEC;EAAO,CAAC;EACnD,IAAIoB,MAAc,GAAGN,GAAG;EACxB,IAAII,GAAG,KAAK,OAAO,EAAE;IACnB,MAAMG,KAAK,GAAGnB,IAAI,CAACoB,GAAG,CAACR,GAAG,CAACf,KAAK,GAAGA,KAAK,EAAEe,GAAG,CAACd,MAAM,GAAGA,MAAM,CAAC;IAC9D,MAAMuB,YAAY,GAAGT,GAAG,CAACf,KAAK,GAAGsB,KAAK;IACtC,MAAMG,aAAa,GAAGV,GAAG,CAACd,MAAM,GAAGqB,KAAK;IACxCF,OAAO,GAAG;MACRtB,CAAC,EAAE,CAACE,KAAK,GAAGwB,YAAY,IAAI,CAAC;MAC7BzB,CAAC,EAAE,CAACE,MAAM,GAAGwB,aAAa,IAAI,CAAC;MAC/BzB,KAAK,EAAEwB,YAAY;MACnBvB,MAAM,EAAEwB;IACV,CAAC;EACH,CAAC,MAAM,IAAIN,GAAG,KAAK,SAAS,EAAE;IAC5B,MAAMG,KAAK,GAAGnB,IAAI,CAACuB,GAAG,CAACX,GAAG,CAACf,KAAK,GAAGA,KAAK,EAAEe,GAAG,CAACd,MAAM,GAAGA,MAAM,CAAC;IAC9DoB,MAAM,GAAG;MACPvB,CAAC,EAAEiB,GAAG,CAACjB,CAAC,GAAG,CAACiB,GAAG,CAACf,KAAK,GAAGA,KAAK,GAAGsB,KAAK,IAAI,CAAC;MAC1CvB,CAAC,EAAEgB,GAAG,CAAChB,CAAC,GAAG,CAACgB,GAAG,CAACd,MAAM,GAAGA,MAAM,GAAGqB,KAAK,IAAI,CAAC;MAC5CtB,KAAK,EAAEA,KAAK,GAAGsB,KAAK;MACpBrB,MAAM,EAAEA,MAAM,GAAGqB;IACnB,CAAC;EACH;EACA,MAAMK,GAAG,GAAGpB,aAAa,CAACD,IAAI,EAAEJ,QAAQ,EAAEkB,OAAO,CAAC;EAClD,MAAMQ,KAAK,GAAGZ,OAAO,EAAEY,KAAK,IAAIrC,IAAI,CAACsC,KAAK,CAAC,CAAC;EAC5C,IAAI;IACF,IAAI3B,QAAQ,KAAK,CAAC,EAAE;MAClBY,MAAM,CAACgB,aAAa,CAAClC,KAAK,EAAE+B,GAAG,EAAEN,MAAM,EAAEO,KAAK,CAAC;MAC/C,OAAOhC,KAAK;IACd;IACA,MAAMS,OAAO,GAAGH,QAAQ,KAAK,EAAE,IAAIA,QAAQ,KAAK,GAAG;IACnD,MAAM6B,WAAW,GAAG1B,OAAO,GAAGgB,MAAM,CAACpB,MAAM,GAAGoB,MAAM,CAACrB,KAAK;IAC1D,MAAMgC,YAAY,GAAG3B,OAAO,GAAGgB,MAAM,CAACrB,KAAK,GAAGqB,MAAM,CAACpB,MAAM;IAC3Da,MAAM,CAACmB,IAAI,CAAC,CAAC;IACb,IAAI;MACFnB,MAAM,CAACoB,SAAS,CACdb,MAAM,CAACvB,CAAC,GAAGuB,MAAM,CAACrB,KAAK,GAAG,CAAC,EAC3BqB,MAAM,CAACtB,CAAC,GAAGsB,MAAM,CAACpB,MAAM,GAAG,CAC7B,CAAC;MACDa,MAAM,CAACqB,MAAM,CAACjC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;MAC7BY,MAAM,CAACgB,aAAa,CAClBlC,KAAK,EACL+B,GAAG,EACH;QACE7B,CAAC,EAAE,CAACiC,WAAW,GAAG,CAAC;QACnBhC,CAAC,EAAE,CAACiC,YAAY,GAAG,CAAC;QACpBhC,KAAK,EAAE+B,WAAW;QAClB9B,MAAM,EAAE+B;MACV,CAAC,EACDJ,KACF,CAAC;IACH,CAAC,SAAS;MACRd,MAAM,CAACsB,OAAO,CAAC,CAAC;IAClB;IACA,OAAOxC,KAAK;EACd,CAAC,SAAS;IACR,IAAI,CAACoB,OAAO,EAAEY,KAAK,EAAEA,KAAK,CAACS,OAAO,CAAC,CAAC;EACtC;AACF,CAAC","ignoreList":[]}