webcodecs-node 0.2.2 → 0.5.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.
Files changed (246) hide show
  1. package/README.md +4 -0
  2. package/dist/__tests__/AudioData.test.js +2 -1
  3. package/dist/__tests__/AudioData.test.js.map +1 -1
  4. package/dist/__tests__/AudioDecoder.test.js +8 -8
  5. package/dist/__tests__/AudioDecoder.test.js.map +1 -1
  6. package/dist/__tests__/AudioEncoder.test.js +3 -3
  7. package/dist/__tests__/AudioEncoder.test.js.map +1 -1
  8. package/dist/__tests__/EncodedChunks.test.js +3 -2
  9. package/dist/__tests__/EncodedChunks.test.js.map +1 -1
  10. package/dist/__tests__/HardwareAcceleration.test.js +2 -1
  11. package/dist/__tests__/HardwareAcceleration.test.js.map +1 -1
  12. package/dist/__tests__/ImageDecoder.test.js +16 -45
  13. package/dist/__tests__/ImageDecoder.test.js.map +1 -1
  14. package/dist/__tests__/ImageDecoder.wpt.test.d.ts +8 -0
  15. package/dist/__tests__/ImageDecoder.wpt.test.d.ts.map +1 -0
  16. package/dist/__tests__/ImageDecoder.wpt.test.js +135 -0
  17. package/dist/__tests__/ImageDecoder.wpt.test.js.map +1 -0
  18. package/dist/__tests__/NodeAvDecoder.test.d.ts +2 -0
  19. package/dist/__tests__/NodeAvDecoder.test.d.ts.map +1 -0
  20. package/dist/__tests__/NodeAvDecoder.test.js +206 -0
  21. package/dist/__tests__/NodeAvDecoder.test.js.map +1 -0
  22. package/dist/__tests__/NodeAvEncoder.test.d.ts +2 -0
  23. package/dist/__tests__/NodeAvEncoder.test.d.ts.map +1 -0
  24. package/dist/__tests__/NodeAvEncoder.test.js +176 -0
  25. package/dist/__tests__/NodeAvEncoder.test.js.map +1 -0
  26. package/dist/__tests__/VideoDecoder.test.js +5 -5
  27. package/dist/__tests__/VideoDecoder.test.js.map +1 -1
  28. package/dist/__tests__/VideoEncoder.test.js +3 -3
  29. package/dist/__tests__/VideoEncoder.test.js.map +1 -1
  30. package/dist/__tests__/VideoFrame.test.js +4 -1
  31. package/dist/__tests__/VideoFrame.test.js.map +1 -1
  32. package/dist/backends/index.d.ts +3 -0
  33. package/dist/backends/index.d.ts.map +1 -0
  34. package/dist/backends/index.js +2 -0
  35. package/dist/backends/index.js.map +1 -0
  36. package/dist/backends/types.d.ts +168 -0
  37. package/dist/backends/types.d.ts.map +1 -0
  38. package/dist/backends/types.js +25 -0
  39. package/dist/backends/types.js.map +1 -0
  40. package/dist/codec-utils/audio-codecs.d.ts +60 -0
  41. package/dist/codec-utils/audio-codecs.d.ts.map +1 -0
  42. package/dist/codec-utils/audio-codecs.js +117 -0
  43. package/dist/codec-utils/audio-codecs.js.map +1 -0
  44. package/dist/codec-utils/formats.d.ts +42 -0
  45. package/dist/codec-utils/formats.d.ts.map +1 -0
  46. package/dist/codec-utils/formats.js +147 -0
  47. package/dist/codec-utils/formats.js.map +1 -0
  48. package/dist/codec-utils/index.d.ts +9 -0
  49. package/dist/codec-utils/index.d.ts.map +1 -0
  50. package/dist/codec-utils/index.js +12 -0
  51. package/dist/codec-utils/index.js.map +1 -0
  52. package/dist/codec-utils/types.d.ts +87 -0
  53. package/dist/codec-utils/types.d.ts.map +1 -0
  54. package/dist/codec-utils/types.js +10 -0
  55. package/dist/codec-utils/types.js.map +1 -0
  56. package/dist/containers/Demuxer.d.ts +114 -0
  57. package/dist/containers/Demuxer.d.ts.map +1 -0
  58. package/dist/containers/Demuxer.js +256 -0
  59. package/dist/containers/Demuxer.js.map +1 -0
  60. package/dist/containers/Muxer.d.ts +142 -0
  61. package/dist/containers/Muxer.d.ts.map +1 -0
  62. package/dist/containers/Muxer.js +295 -0
  63. package/dist/containers/Muxer.js.map +1 -0
  64. package/dist/containers/extract.d.ts +25 -0
  65. package/dist/containers/extract.d.ts.map +1 -0
  66. package/dist/containers/extract.js +64 -0
  67. package/dist/containers/extract.js.map +1 -0
  68. package/dist/containers/index.d.ts +40 -0
  69. package/dist/containers/index.d.ts.map +1 -0
  70. package/dist/containers/index.js +41 -0
  71. package/dist/containers/index.js.map +1 -0
  72. package/dist/containers/transcode.d.ts +138 -0
  73. package/dist/containers/transcode.d.ts.map +1 -0
  74. package/dist/containers/transcode.js +536 -0
  75. package/dist/containers/transcode.js.map +1 -0
  76. package/dist/core/AudioData.d.ts +5 -1
  77. package/dist/core/AudioData.d.ts.map +1 -1
  78. package/dist/core/AudioData.js +69 -13
  79. package/dist/core/AudioData.js.map +1 -1
  80. package/dist/core/EncodedAudioChunk.d.ts +1 -1
  81. package/dist/core/EncodedAudioChunk.d.ts.map +1 -1
  82. package/dist/core/EncodedAudioChunk.js +1 -1
  83. package/dist/core/EncodedAudioChunk.js.map +1 -1
  84. package/dist/core/EncodedVideoChunk.d.ts.map +1 -1
  85. package/dist/core/EncodedVideoChunk.js +3 -19
  86. package/dist/core/EncodedVideoChunk.js.map +1 -1
  87. package/dist/core/VideoFrame.d.ts +31 -11
  88. package/dist/core/VideoFrame.d.ts.map +1 -1
  89. package/dist/core/VideoFrame.js +244 -81
  90. package/dist/core/VideoFrame.js.map +1 -1
  91. package/dist/decoders/AudioDecoder.d.ts +14 -12
  92. package/dist/decoders/AudioDecoder.d.ts.map +1 -1
  93. package/dist/decoders/AudioDecoder.js +113 -173
  94. package/dist/decoders/AudioDecoder.js.map +1 -1
  95. package/dist/decoders/ImageDecoder.d.ts +1 -3
  96. package/dist/decoders/ImageDecoder.d.ts.map +1 -1
  97. package/dist/decoders/ImageDecoder.js +39 -192
  98. package/dist/decoders/ImageDecoder.js.map +1 -1
  99. package/dist/decoders/VideoDecoder.d.ts +14 -13
  100. package/dist/decoders/VideoDecoder.d.ts.map +1 -1
  101. package/dist/decoders/VideoDecoder.js +115 -166
  102. package/dist/decoders/VideoDecoder.js.map +1 -1
  103. package/dist/demos/demo-1080p-transcode.d.ts +8 -0
  104. package/dist/demos/demo-1080p-transcode.d.ts.map +1 -0
  105. package/dist/demos/demo-1080p-transcode.js +188 -0
  106. package/dist/demos/demo-1080p-transcode.js.map +1 -0
  107. package/dist/demos/demo-containers.d.ts +7 -0
  108. package/dist/demos/demo-containers.d.ts.map +1 -0
  109. package/dist/demos/demo-containers.js +140 -0
  110. package/dist/demos/demo-containers.js.map +1 -0
  111. package/dist/demos/demo-conversion.js +2 -2
  112. package/dist/demos/demo-conversion.js.map +1 -1
  113. package/dist/demos/demo-four-corners.d.ts +6 -0
  114. package/dist/demos/demo-four-corners.d.ts.map +1 -0
  115. package/dist/demos/demo-four-corners.js +218 -0
  116. package/dist/demos/demo-four-corners.js.map +1 -0
  117. package/dist/demos/demo-hwaccel-conversion.js +1 -1
  118. package/dist/demos/demo-hwaccel-conversion.js.map +1 -1
  119. package/dist/demos/demo-hwaccel.js +1 -1
  120. package/dist/demos/demo-hwaccel.js.map +1 -1
  121. package/dist/demos/demo-samples.js +232 -68
  122. package/dist/demos/demo-samples.js.map +1 -1
  123. package/dist/demos/demo-streaming.js +6 -6
  124. package/dist/demos/demo-streaming.js.map +1 -1
  125. package/dist/encoders/AudioEncoder.d.ts +14 -13
  126. package/dist/encoders/AudioEncoder.d.ts.map +1 -1
  127. package/dist/encoders/AudioEncoder.js +138 -228
  128. package/dist/encoders/AudioEncoder.js.map +1 -1
  129. package/dist/encoders/VideoEncoder.d.ts +13 -14
  130. package/dist/encoders/VideoEncoder.d.ts.map +1 -1
  131. package/dist/encoders/VideoEncoder.js +92 -161
  132. package/dist/encoders/VideoEncoder.js.map +1 -1
  133. package/dist/ffmpeg/index.d.ts +3 -2
  134. package/dist/ffmpeg/index.d.ts.map +1 -1
  135. package/dist/ffmpeg/index.js +3 -3
  136. package/dist/ffmpeg/index.js.map +1 -1
  137. package/dist/formats/conversions/batch-converter.d.ts +61 -0
  138. package/dist/formats/conversions/batch-converter.d.ts.map +1 -0
  139. package/dist/formats/conversions/batch-converter.js +274 -0
  140. package/dist/formats/conversions/batch-converter.js.map +1 -0
  141. package/dist/formats/conversions/frame-converter.d.ts +17 -0
  142. package/dist/formats/conversions/frame-converter.d.ts.map +1 -1
  143. package/dist/formats/conversions/frame-converter.js +144 -10
  144. package/dist/formats/conversions/frame-converter.js.map +1 -1
  145. package/dist/formats/conversions/index.d.ts +2 -0
  146. package/dist/formats/conversions/index.d.ts.map +1 -1
  147. package/dist/formats/conversions/index.js +4 -0
  148. package/dist/formats/conversions/index.js.map +1 -1
  149. package/dist/hardware/decoder-args.d.ts +2 -7
  150. package/dist/hardware/decoder-args.d.ts.map +1 -1
  151. package/dist/hardware/decoder-args.js +2 -32
  152. package/dist/hardware/decoder-args.js.map +1 -1
  153. package/dist/hardware/detection.d.ts +1 -1
  154. package/dist/hardware/detection.d.ts.map +1 -1
  155. package/dist/hardware/detection.js +54 -27
  156. package/dist/hardware/detection.js.map +1 -1
  157. package/dist/hardware/encoder-args.d.ts +2 -11
  158. package/dist/hardware/encoder-args.d.ts.map +1 -1
  159. package/dist/hardware/encoder-args.js +2 -71
  160. package/dist/hardware/encoder-args.js.map +1 -1
  161. package/dist/hardware/index.d.ts +2 -2
  162. package/dist/hardware/index.d.ts.map +1 -1
  163. package/dist/hardware/index.js +2 -2
  164. package/dist/hardware/index.js.map +1 -1
  165. package/dist/index.d.ts +5 -7
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +5 -6
  168. package/dist/index.js.map +1 -1
  169. package/dist/mediabunny/FFmpegAudioDecoder.d.ts +4 -17
  170. package/dist/mediabunny/FFmpegAudioDecoder.d.ts.map +1 -1
  171. package/dist/mediabunny/FFmpegAudioDecoder.js +57 -185
  172. package/dist/mediabunny/FFmpegAudioDecoder.js.map +1 -1
  173. package/dist/mediabunny/FFmpegAudioEncoder.d.ts +6 -39
  174. package/dist/mediabunny/FFmpegAudioEncoder.d.ts.map +1 -1
  175. package/dist/mediabunny/FFmpegAudioEncoder.js +66 -329
  176. package/dist/mediabunny/FFmpegAudioEncoder.js.map +1 -1
  177. package/dist/mediabunny/FFmpegVideoDecoder.d.ts +5 -38
  178. package/dist/mediabunny/FFmpegVideoDecoder.d.ts.map +1 -1
  179. package/dist/mediabunny/FFmpegVideoDecoder.js +39 -283
  180. package/dist/mediabunny/FFmpegVideoDecoder.js.map +1 -1
  181. package/dist/mediabunny/FFmpegVideoEncoder.d.ts +9 -37
  182. package/dist/mediabunny/FFmpegVideoEncoder.d.ts.map +1 -1
  183. package/dist/mediabunny/FFmpegVideoEncoder.js +49 -336
  184. package/dist/mediabunny/FFmpegVideoEncoder.js.map +1 -1
  185. package/dist/node-av/HardwarePipeline.d.ts +36 -0
  186. package/dist/node-av/HardwarePipeline.d.ts.map +1 -0
  187. package/dist/node-av/HardwarePipeline.js +243 -0
  188. package/dist/node-av/HardwarePipeline.js.map +1 -0
  189. package/dist/node-av/NodeAvAudioDecoder.d.ts +46 -0
  190. package/dist/node-av/NodeAvAudioDecoder.d.ts.map +1 -0
  191. package/dist/node-av/NodeAvAudioDecoder.js +350 -0
  192. package/dist/node-av/NodeAvAudioDecoder.js.map +1 -0
  193. package/dist/node-av/NodeAvAudioEncoder.d.ts +50 -0
  194. package/dist/node-av/NodeAvAudioEncoder.d.ts.map +1 -0
  195. package/dist/node-av/NodeAvAudioEncoder.js +506 -0
  196. package/dist/node-av/NodeAvAudioEncoder.js.map +1 -0
  197. package/dist/node-av/NodeAvImageDecoder.d.ts +114 -0
  198. package/dist/node-av/NodeAvImageDecoder.d.ts.map +1 -0
  199. package/dist/node-av/NodeAvImageDecoder.js +406 -0
  200. package/dist/node-av/NodeAvImageDecoder.js.map +1 -0
  201. package/dist/node-av/NodeAvVideoDecoder.d.ts +43 -0
  202. package/dist/node-av/NodeAvVideoDecoder.d.ts.map +1 -0
  203. package/dist/node-av/NodeAvVideoDecoder.js +365 -0
  204. package/dist/node-av/NodeAvVideoDecoder.js.map +1 -0
  205. package/dist/node-av/NodeAvVideoEncoder.d.ts +56 -0
  206. package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -0
  207. package/dist/node-av/NodeAvVideoEncoder.js +509 -0
  208. package/dist/node-av/NodeAvVideoEncoder.js.map +1 -0
  209. package/dist/polyfill.d.ts.map +1 -1
  210. package/dist/polyfill.js +11 -9
  211. package/dist/polyfill.js.map +1 -1
  212. package/dist/utils/aac.d.ts.map +1 -1
  213. package/dist/utils/aac.js +6 -0
  214. package/dist/utils/aac.js.map +1 -1
  215. package/dist/utils/buffer-pool.d.ts +109 -0
  216. package/dist/utils/buffer-pool.d.ts.map +1 -0
  217. package/dist/utils/buffer-pool.js +278 -0
  218. package/dist/utils/buffer-pool.js.map +1 -0
  219. package/dist/utils/codec-cache.d.ts +65 -0
  220. package/dist/utils/codec-cache.d.ts.map +1 -0
  221. package/dist/utils/codec-cache.js +116 -0
  222. package/dist/utils/codec-cache.js.map +1 -0
  223. package/dist/utils/errors.d.ts +62 -0
  224. package/dist/utils/errors.d.ts.map +1 -0
  225. package/dist/utils/errors.js +84 -0
  226. package/dist/utils/errors.js.map +1 -0
  227. package/dist/utils/event-target.d.ts +42 -0
  228. package/dist/utils/event-target.d.ts.map +1 -0
  229. package/dist/utils/event-target.js +96 -0
  230. package/dist/utils/event-target.js.map +1 -0
  231. package/dist/utils/hardware-pool.d.ts +88 -0
  232. package/dist/utils/hardware-pool.d.ts.map +1 -0
  233. package/dist/utils/hardware-pool.js +266 -0
  234. package/dist/utils/hardware-pool.js.map +1 -0
  235. package/dist/utils/index.d.ts +6 -0
  236. package/dist/utils/index.d.ts.map +1 -1
  237. package/dist/utils/index.js +12 -0
  238. package/dist/utils/index.js.map +1 -1
  239. package/dist/utils/timeout.d.ts +44 -0
  240. package/dist/utils/timeout.d.ts.map +1 -0
  241. package/dist/utils/timeout.js +73 -0
  242. package/dist/utils/timeout.js.map +1 -0
  243. package/dist/utils/type-guards.d.ts +11 -1
  244. package/dist/utils/type-guards.d.ts.map +1 -1
  245. package/dist/utils/type-guards.js.map +1 -1
  246. package/package.json +20 -34
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Buffer Pool - Reuses typed array buffers to reduce allocation overhead
3
+ *
4
+ * Frequently allocating large buffers (e.g., 1080p frame = ~8MB) can cause
5
+ * GC pressure. This pool maintains reusable buffers organized by size buckets.
6
+ *
7
+ * Usage:
8
+ * - For temporary buffers in format conversions, encoding, decoding
9
+ * - NOT for long-lived VideoFrame/AudioData data (those follow WebCodecs lifecycle)
10
+ */
11
+ /**
12
+ * Pool configuration
13
+ */
14
+ export interface BufferPoolConfig {
15
+ /** Size buckets for buffer allocation (defaults cover common video resolutions) */
16
+ sizeBuckets?: number[];
17
+ /** Maximum number of buffers to keep per bucket */
18
+ maxBuffersPerBucket?: number;
19
+ /** Time in ms after which unused buffers are released (default: 30000ms) */
20
+ idleTimeoutMs?: number;
21
+ /** Whether to track statistics (default: false in production) */
22
+ trackStats?: boolean;
23
+ }
24
+ /**
25
+ * Statistics for monitoring pool efficiency
26
+ */
27
+ export interface BufferPoolStats {
28
+ hits: number;
29
+ misses: number;
30
+ allocations: number;
31
+ returns: number;
32
+ discards: number;
33
+ totalPooled: number;
34
+ totalPooledBytes: number;
35
+ }
36
+ /**
37
+ * Buffer pool for efficient buffer reuse
38
+ */
39
+ declare class BufferPool {
40
+ private buckets;
41
+ private config;
42
+ private cleanupTimer;
43
+ private disposed;
44
+ private stats;
45
+ constructor(config?: BufferPoolConfig);
46
+ /**
47
+ * Acquire a buffer of at least the specified size
48
+ * Returns a buffer from the pool if available, or allocates a new one
49
+ *
50
+ * @param size - Minimum required buffer size in bytes
51
+ * @returns Uint8Array of at least the requested size
52
+ */
53
+ acquire(size: number): Uint8Array;
54
+ /**
55
+ * Return a buffer to the pool for reuse
56
+ *
57
+ * @param buffer - The buffer to return (must be the original buffer, not a subarray)
58
+ */
59
+ release(buffer: Uint8Array | null): void;
60
+ /**
61
+ * Get pool statistics
62
+ */
63
+ getStats(): BufferPoolStats;
64
+ /**
65
+ * Clear all pooled buffers
66
+ */
67
+ clear(): void;
68
+ /**
69
+ * Dispose the pool and release all buffers
70
+ */
71
+ dispose(): void;
72
+ /**
73
+ * Find the smallest bucket that can fit the requested size
74
+ */
75
+ private findBucketSize;
76
+ /**
77
+ * Find exact bucket size match
78
+ */
79
+ private findExactBucketSize;
80
+ private startCleanupTimer;
81
+ private cleanupIdleBuffers;
82
+ }
83
+ /**
84
+ * Get the global buffer pool
85
+ * Creates one on first access with default configuration
86
+ */
87
+ export declare function getBufferPool(): BufferPool;
88
+ /**
89
+ * Initialize the global pool with custom configuration
90
+ * Should be called before first use if custom config is needed
91
+ */
92
+ export declare function initBufferPool(config: BufferPoolConfig): BufferPool;
93
+ /**
94
+ * Dispose the global pool
95
+ * Call this when shutting down the application
96
+ */
97
+ export declare function disposeBufferPool(): void;
98
+ /**
99
+ * Acquire a buffer from the global pool
100
+ * @param size - Minimum required buffer size in bytes
101
+ */
102
+ export declare function acquireBuffer(size: number): Uint8Array;
103
+ /**
104
+ * Release a buffer back to the global pool
105
+ * @param buffer - The buffer to return
106
+ */
107
+ export declare function releaseBuffer(buffer: Uint8Array | null): void;
108
+ export { BufferPool };
109
+ //# sourceMappingURL=buffer-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffer-pool.d.ts","sourceRoot":"","sources":["../../src/utils/buffer-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkCD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAQX;gBAEU,MAAM,GAAE,gBAAqB;IAWzC;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAuCjC;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IA2CxC;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,OAAO,IAAI,IAAI;IAiBf;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,kBAAkB;CA2B3B;AAQD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAK1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAMnE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Buffer Pool - Reuses typed array buffers to reduce allocation overhead
3
+ *
4
+ * Frequently allocating large buffers (e.g., 1080p frame = ~8MB) can cause
5
+ * GC pressure. This pool maintains reusable buffers organized by size buckets.
6
+ *
7
+ * Usage:
8
+ * - For temporary buffers in format conversions, encoding, decoding
9
+ * - NOT for long-lived VideoFrame/AudioData data (those follow WebCodecs lifecycle)
10
+ */
11
+ import { createLogger } from './logger.js';
12
+ const logger = createLogger('BufferPool');
13
+ /**
14
+ * Default size buckets optimized for video frames:
15
+ * - Small: 720p I420 (~1.4MB), 720p RGBA (~3.7MB)
16
+ * - Medium: 1080p I420 (~3.1MB), 1080p RGBA (~8.3MB)
17
+ * - Large: 4K I420 (~12.4MB), 4K RGBA (~33MB)
18
+ */
19
+ const DEFAULT_SIZE_BUCKETS = [
20
+ 512 * 1024, // 512KB - small audio/thumbnails
21
+ 1024 * 1024, // 1MB
22
+ 2 * 1024 * 1024, // 2MB - 720p I420
23
+ 4 * 1024 * 1024, // 4MB - 720p RGBA / 1080p I420
24
+ 8 * 1024 * 1024, // 8MB - 1080p RGBA
25
+ 16 * 1024 * 1024, // 16MB - 4K I420
26
+ 32 * 1024 * 1024, // 32MB - 4K RGBA
27
+ 64 * 1024 * 1024, // 64MB - 8K I420
28
+ ];
29
+ const DEFAULT_CONFIG = {
30
+ sizeBuckets: DEFAULT_SIZE_BUCKETS,
31
+ maxBuffersPerBucket: 4,
32
+ idleTimeoutMs: 30_000,
33
+ trackStats: false,
34
+ };
35
+ /**
36
+ * Buffer pool for efficient buffer reuse
37
+ */
38
+ class BufferPool {
39
+ buckets = new Map();
40
+ config;
41
+ cleanupTimer = null;
42
+ disposed = false;
43
+ stats = {
44
+ hits: 0,
45
+ misses: 0,
46
+ allocations: 0,
47
+ returns: 0,
48
+ discards: 0,
49
+ totalPooled: 0,
50
+ totalPooledBytes: 0,
51
+ };
52
+ constructor(config = {}) {
53
+ this.config = { ...DEFAULT_CONFIG, ...config };
54
+ // Initialize buckets
55
+ for (const size of this.config.sizeBuckets) {
56
+ this.buckets.set(size, []);
57
+ }
58
+ this.startCleanupTimer();
59
+ }
60
+ /**
61
+ * Acquire a buffer of at least the specified size
62
+ * Returns a buffer from the pool if available, or allocates a new one
63
+ *
64
+ * @param size - Minimum required buffer size in bytes
65
+ * @returns Uint8Array of at least the requested size
66
+ */
67
+ acquire(size) {
68
+ if (this.disposed) {
69
+ return new Uint8Array(size);
70
+ }
71
+ const bucketSize = this.findBucketSize(size);
72
+ if (bucketSize === null) {
73
+ // Size too large for buckets, allocate directly
74
+ if (this.config.trackStats) {
75
+ this.stats.allocations++;
76
+ this.stats.misses++;
77
+ }
78
+ return new Uint8Array(size);
79
+ }
80
+ const bucket = this.buckets.get(bucketSize);
81
+ if (bucket.length > 0) {
82
+ const entry = bucket.pop();
83
+ if (this.config.trackStats) {
84
+ this.stats.hits++;
85
+ this.stats.totalPooled--;
86
+ this.stats.totalPooledBytes -= bucketSize;
87
+ }
88
+ // Return a view of the buffer with exact requested size
89
+ return entry.buffer.subarray(0, size);
90
+ }
91
+ // No pooled buffer available, allocate new one at bucket size
92
+ if (this.config.trackStats) {
93
+ this.stats.allocations++;
94
+ this.stats.misses++;
95
+ }
96
+ const buffer = new Uint8Array(bucketSize);
97
+ return buffer.subarray(0, size);
98
+ }
99
+ /**
100
+ * Return a buffer to the pool for reuse
101
+ *
102
+ * @param buffer - The buffer to return (must be the original buffer, not a subarray)
103
+ */
104
+ release(buffer) {
105
+ if (!buffer || this.disposed) {
106
+ return;
107
+ }
108
+ // Get the underlying buffer's full length
109
+ const fullBuffer = buffer.byteLength === buffer.buffer.byteLength
110
+ ? buffer
111
+ : new Uint8Array(buffer.buffer, buffer.byteOffset);
112
+ const bucketSize = this.findExactBucketSize(fullBuffer.byteLength);
113
+ if (bucketSize === null) {
114
+ // Not a poolable size, let GC handle it
115
+ if (this.config.trackStats) {
116
+ this.stats.discards++;
117
+ }
118
+ return;
119
+ }
120
+ const bucket = this.buckets.get(bucketSize);
121
+ if (bucket.length >= this.config.maxBuffersPerBucket) {
122
+ // Bucket full, let GC handle this buffer
123
+ if (this.config.trackStats) {
124
+ this.stats.discards++;
125
+ }
126
+ return;
127
+ }
128
+ // Add to pool
129
+ bucket.push({
130
+ buffer: fullBuffer,
131
+ lastUsed: Date.now(),
132
+ });
133
+ if (this.config.trackStats) {
134
+ this.stats.returns++;
135
+ this.stats.totalPooled++;
136
+ this.stats.totalPooledBytes += bucketSize;
137
+ }
138
+ }
139
+ /**
140
+ * Get pool statistics
141
+ */
142
+ getStats() {
143
+ return { ...this.stats };
144
+ }
145
+ /**
146
+ * Clear all pooled buffers
147
+ */
148
+ clear() {
149
+ for (const bucket of this.buckets.values()) {
150
+ bucket.length = 0;
151
+ }
152
+ this.stats.totalPooled = 0;
153
+ this.stats.totalPooledBytes = 0;
154
+ logger.debug('Buffer pool cleared');
155
+ }
156
+ /**
157
+ * Dispose the pool and release all buffers
158
+ */
159
+ dispose() {
160
+ if (this.disposed)
161
+ return;
162
+ this.disposed = true;
163
+ if (this.cleanupTimer) {
164
+ clearInterval(this.cleanupTimer);
165
+ this.cleanupTimer = null;
166
+ }
167
+ this.clear();
168
+ logger.info('Buffer pool disposed');
169
+ }
170
+ // ─────────────────────────────────────────────────────────────────────────────
171
+ // Private methods
172
+ // ─────────────────────────────────────────────────────────────────────────────
173
+ /**
174
+ * Find the smallest bucket that can fit the requested size
175
+ */
176
+ findBucketSize(size) {
177
+ for (const bucketSize of this.config.sizeBuckets) {
178
+ if (bucketSize >= size) {
179
+ return bucketSize;
180
+ }
181
+ }
182
+ return null;
183
+ }
184
+ /**
185
+ * Find exact bucket size match
186
+ */
187
+ findExactBucketSize(size) {
188
+ if (this.buckets.has(size)) {
189
+ return size;
190
+ }
191
+ return null;
192
+ }
193
+ startCleanupTimer() {
194
+ // Run cleanup every 10 seconds
195
+ this.cleanupTimer = setInterval(() => {
196
+ this.cleanupIdleBuffers();
197
+ }, 10_000);
198
+ // Don't prevent process from exiting
199
+ if (this.cleanupTimer.unref) {
200
+ this.cleanupTimer.unref();
201
+ }
202
+ }
203
+ cleanupIdleBuffers() {
204
+ const now = Date.now();
205
+ let removed = 0;
206
+ let bytesRemoved = 0;
207
+ for (const [size, bucket] of this.buckets) {
208
+ // Keep at least one buffer per bucket for quick reuse
209
+ const keepCount = 1;
210
+ for (let i = bucket.length - 1; i >= keepCount; i--) {
211
+ const entry = bucket[i];
212
+ if ((now - entry.lastUsed) > this.config.idleTimeoutMs) {
213
+ bucket.splice(i, 1);
214
+ removed++;
215
+ bytesRemoved += size;
216
+ }
217
+ }
218
+ }
219
+ if (removed > 0) {
220
+ if (this.config.trackStats) {
221
+ this.stats.totalPooled -= removed;
222
+ this.stats.totalPooledBytes -= bytesRemoved;
223
+ }
224
+ logger.debug(`Cleaned up ${removed} idle buffers (${(bytesRemoved / 1024 / 1024).toFixed(1)}MB)`);
225
+ }
226
+ }
227
+ }
228
+ // ─────────────────────────────────────────────────────────────────────────────
229
+ // Global pool singleton
230
+ // ─────────────────────────────────────────────────────────────────────────────
231
+ let globalPool = null;
232
+ /**
233
+ * Get the global buffer pool
234
+ * Creates one on first access with default configuration
235
+ */
236
+ export function getBufferPool() {
237
+ if (!globalPool) {
238
+ globalPool = new BufferPool();
239
+ }
240
+ return globalPool;
241
+ }
242
+ /**
243
+ * Initialize the global pool with custom configuration
244
+ * Should be called before first use if custom config is needed
245
+ */
246
+ export function initBufferPool(config) {
247
+ if (globalPool) {
248
+ globalPool.dispose();
249
+ }
250
+ globalPool = new BufferPool(config);
251
+ return globalPool;
252
+ }
253
+ /**
254
+ * Dispose the global pool
255
+ * Call this when shutting down the application
256
+ */
257
+ export function disposeBufferPool() {
258
+ if (globalPool) {
259
+ globalPool.dispose();
260
+ globalPool = null;
261
+ }
262
+ }
263
+ /**
264
+ * Acquire a buffer from the global pool
265
+ * @param size - Minimum required buffer size in bytes
266
+ */
267
+ export function acquireBuffer(size) {
268
+ return getBufferPool().acquire(size);
269
+ }
270
+ /**
271
+ * Release a buffer back to the global pool
272
+ * @param buffer - The buffer to return
273
+ */
274
+ export function releaseBuffer(buffer) {
275
+ getBufferPool().release(buffer);
276
+ }
277
+ export { BufferPool };
278
+ //# sourceMappingURL=buffer-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffer-pool.js","sourceRoot":"","sources":["../../src/utils/buffer-pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Cached codec string parsing utilities
3
+ *
4
+ * Codec strings are parsed frequently throughout the codebase.
5
+ * Caching avoids repeated string operations for the same codec.
6
+ */
7
+ /**
8
+ * Parsed codec information
9
+ */
10
+ export interface ParsedCodec {
11
+ /** Base codec identifier (e.g., 'avc1', 'hev1', 'vp09') */
12
+ base: string;
13
+ /** Normalized codec name (e.g., 'h264', 'hevc', 'vp9') */
14
+ name: VideoCodecName | AudioCodecName | null;
15
+ /** Original codec string */
16
+ original: string;
17
+ /** Whether this is a video codec */
18
+ isVideo: boolean;
19
+ /** Whether this is an audio codec */
20
+ isAudio: boolean;
21
+ }
22
+ export type VideoCodecName = 'h264' | 'hevc' | 'vp8' | 'vp9' | 'av1';
23
+ export type AudioCodecName = 'aac' | 'opus' | 'mp3' | 'vorbis' | 'flac';
24
+ /**
25
+ * Get the base codec identifier from a codec string (cached)
26
+ *
27
+ * @example
28
+ * getCodecBase('avc1.42001E') // 'avc1'
29
+ * getCodecBase('vp09.00.10.08') // 'vp09'
30
+ * getCodecBase('opus') // 'opus'
31
+ */
32
+ export declare function getCodecBase(codec: string): string;
33
+ /**
34
+ * Parse a codec string and return structured information (cached)
35
+ *
36
+ * @example
37
+ * parseCodec('avc1.42001E')
38
+ * // { base: 'avc1', name: 'h264', original: 'avc1.42001E', isVideo: true, isAudio: false }
39
+ */
40
+ export declare function parseCodec(codec: string): ParsedCodec;
41
+ /**
42
+ * Get normalized video codec name from codec string (cached)
43
+ *
44
+ * @returns Normalized name or null if not a recognized video codec
45
+ */
46
+ export declare function getVideoCodecName(codec: string): VideoCodecName | null;
47
+ /**
48
+ * Get normalized audio codec name from codec string (cached)
49
+ *
50
+ * @returns Normalized name or null if not a recognized audio codec
51
+ */
52
+ export declare function getAudioCodecName(codec: string): AudioCodecName | null;
53
+ /**
54
+ * Check if a codec string represents a video codec
55
+ */
56
+ export declare function isVideoCodec(codec: string): boolean;
57
+ /**
58
+ * Check if a codec string represents an audio codec
59
+ */
60
+ export declare function isAudioCodec(codec: string): boolean;
61
+ /**
62
+ * Clear the codec caches (for testing)
63
+ */
64
+ export declare function clearCodecCache(): void;
65
+ //# sourceMappingURL=codec-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec-cache.d.ts","sourceRoot":"","sources":["../../src/utils/codec-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,IAAI,CAAC;IAC7C,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACrE,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAgCxE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAiBrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGtE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAGtC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Cached codec string parsing utilities
3
+ *
4
+ * Codec strings are parsed frequently throughout the codebase.
5
+ * Caching avoids repeated string operations for the same codec.
6
+ */
7
+ // Cache for codec base extraction (e.g., 'avc1.42001E' -> 'avc1')
8
+ const codecBaseCache = new Map();
9
+ // Cache for full codec parsing results
10
+ const codecParseCache = new Map();
11
+ /**
12
+ * Video codec base to name mapping
13
+ */
14
+ const VIDEO_CODEC_MAP = {
15
+ 'avc1': 'h264',
16
+ 'avc3': 'h264',
17
+ 'h264': 'h264',
18
+ 'hvc1': 'hevc',
19
+ 'hev1': 'hevc',
20
+ 'hevc': 'hevc',
21
+ 'h265': 'hevc',
22
+ 'vp8': 'vp8',
23
+ 'vp9': 'vp9',
24
+ 'vp09': 'vp9',
25
+ 'av01': 'av1',
26
+ 'av1': 'av1',
27
+ };
28
+ /**
29
+ * Audio codec base to name mapping
30
+ */
31
+ const AUDIO_CODEC_MAP = {
32
+ 'mp4a': 'aac',
33
+ 'aac': 'aac',
34
+ 'opus': 'opus',
35
+ 'mp3': 'mp3',
36
+ 'vorbis': 'vorbis',
37
+ 'flac': 'flac',
38
+ };
39
+ /**
40
+ * Get the base codec identifier from a codec string (cached)
41
+ *
42
+ * @example
43
+ * getCodecBase('avc1.42001E') // 'avc1'
44
+ * getCodecBase('vp09.00.10.08') // 'vp09'
45
+ * getCodecBase('opus') // 'opus'
46
+ */
47
+ export function getCodecBase(codec) {
48
+ let base = codecBaseCache.get(codec);
49
+ if (base === undefined) {
50
+ base = codec.split('.')[0].toLowerCase();
51
+ codecBaseCache.set(codec, base);
52
+ }
53
+ return base;
54
+ }
55
+ /**
56
+ * Parse a codec string and return structured information (cached)
57
+ *
58
+ * @example
59
+ * parseCodec('avc1.42001E')
60
+ * // { base: 'avc1', name: 'h264', original: 'avc1.42001E', isVideo: true, isAudio: false }
61
+ */
62
+ export function parseCodec(codec) {
63
+ let parsed = codecParseCache.get(codec);
64
+ if (parsed === undefined) {
65
+ const base = getCodecBase(codec);
66
+ const videoName = VIDEO_CODEC_MAP[base] ?? null;
67
+ const audioName = AUDIO_CODEC_MAP[base] ?? null;
68
+ parsed = {
69
+ base,
70
+ name: videoName ?? audioName,
71
+ original: codec,
72
+ isVideo: videoName !== null,
73
+ isAudio: audioName !== null,
74
+ };
75
+ codecParseCache.set(codec, parsed);
76
+ }
77
+ return parsed;
78
+ }
79
+ /**
80
+ * Get normalized video codec name from codec string (cached)
81
+ *
82
+ * @returns Normalized name or null if not a recognized video codec
83
+ */
84
+ export function getVideoCodecName(codec) {
85
+ const parsed = parseCodec(codec);
86
+ return parsed.isVideo ? parsed.name : null;
87
+ }
88
+ /**
89
+ * Get normalized audio codec name from codec string (cached)
90
+ *
91
+ * @returns Normalized name or null if not a recognized audio codec
92
+ */
93
+ export function getAudioCodecName(codec) {
94
+ const parsed = parseCodec(codec);
95
+ return parsed.isAudio ? parsed.name : null;
96
+ }
97
+ /**
98
+ * Check if a codec string represents a video codec
99
+ */
100
+ export function isVideoCodec(codec) {
101
+ return parseCodec(codec).isVideo;
102
+ }
103
+ /**
104
+ * Check if a codec string represents an audio codec
105
+ */
106
+ export function isAudioCodec(codec) {
107
+ return parseCodec(codec).isAudio;
108
+ }
109
+ /**
110
+ * Clear the codec caches (for testing)
111
+ */
112
+ export function clearCodecCache() {
113
+ codecBaseCache.clear();
114
+ codecParseCache.clear();
115
+ }
116
+ //# sourceMappingURL=codec-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec-cache.js","sourceRoot":"","sources":["../../src/utils/codec-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Standardized error utilities for WebCodecs compliance
3
+ *
4
+ * The WebCodecs spec uses specific DOMException error names:
5
+ * - InvalidStateError: operation on wrong state
6
+ * - NotSupportedError: unsupported codec/config
7
+ * - DataError: malformed/corrupt data
8
+ * - EncodingError: codec processing failure
9
+ * - AbortError: operation was aborted
10
+ * - TypeError: invalid parameters (thrown, not via callback)
11
+ * - QuotaExceededError: queue full
12
+ * - TimeoutError: operation timed out
13
+ */
14
+ import { DOMException } from '../types/index.js';
15
+ /**
16
+ * Standard WebCodecs error types
17
+ */
18
+ export type WebCodecsErrorName = 'InvalidStateError' | 'NotSupportedError' | 'DataError' | 'EncodingError' | 'AbortError' | 'QuotaExceededError' | 'TimeoutError';
19
+ /**
20
+ * Create a WebCodecs-compliant error
21
+ */
22
+ export declare function createWebCodecsError(message: string, name: WebCodecsErrorName): DOMException;
23
+ /**
24
+ * Create an InvalidStateError (e.g., encoder not configured)
25
+ */
26
+ export declare function invalidStateError(message: string): DOMException;
27
+ /**
28
+ * Create a NotSupportedError (e.g., unsupported codec)
29
+ */
30
+ export declare function notSupportedError(message: string): DOMException;
31
+ /**
32
+ * Create a DataError (e.g., corrupt input data)
33
+ */
34
+ export declare function dataError(message: string): DOMException;
35
+ /**
36
+ * Create an EncodingError (e.g., codec processing failed)
37
+ */
38
+ export declare function encodingError(message: string): DOMException;
39
+ /**
40
+ * Create an AbortError (e.g., operation was reset/closed)
41
+ */
42
+ export declare function abortError(message: string): DOMException;
43
+ /**
44
+ * Create a QuotaExceededError (e.g., queue full)
45
+ */
46
+ export declare function quotaExceededError(message: string): DOMException;
47
+ /**
48
+ * Create a TimeoutError (e.g., operation timed out)
49
+ */
50
+ export declare function timeoutError(message: string): DOMException;
51
+ /**
52
+ * Wrap an error as a DOMException if it isn't already
53
+ *
54
+ * @param error - The error to wrap
55
+ * @param defaultName - The error name to use if error is not a DOMException
56
+ */
57
+ export declare function wrapAsWebCodecsError(error: unknown, defaultName?: WebCodecsErrorName): DOMException;
58
+ /**
59
+ * Check if an error is a specific WebCodecs error type
60
+ */
61
+ export declare function isWebCodecsError(error: unknown, name: WebCodecsErrorName): boolean;
62
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,mBAAmB,GACnB,mBAAmB,GACnB,WAAW,GACX,eAAe,GACf,YAAY,GACZ,oBAAoB,GACpB,cAAc,CAAC;AAEnB;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,kBAAkB,GACvB,YAAY,CAEd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAE/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAE/D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAEvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAE3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAExD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAEhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,WAAW,GAAE,kBAAoC,GAChD,YAAY,CAQd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAElF"}