tatolab-testpattern 0.68.27__py3-none-any.whl

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.
@@ -0,0 +1,341 @@
1
+ # Copyright (c) 2025 Jonathan Fontanez
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ """`TestPatternSource`: SMPTE bars, a bouncing potato and the sample stream's captions, on the GPU.
5
+
6
+ A frame's picture is a function of its index alone: the potato leaves the
7
+ top-left corner at frame zero and moves four pixels a frame along each axis,
8
+ bouncing off every edge, and the caption panel sits in the bottom-right corner.
9
+ One compute dispatch per frame writes the picture into a texture from the
10
+ node's output pool.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import ctypes
16
+ import dataclasses
17
+ import struct
18
+ from importlib import resources
19
+ from typing import Annotated, Any
20
+
21
+ from tatolab.stream import (
22
+ ComputeKernel,
23
+ GpuContextFullAccess,
24
+ GpuSurfaceHandle,
25
+ NodeOutputTextureRing,
26
+ RuntimeContextFullAccess,
27
+ RuntimeContextLimitedAccess,
28
+ VideoFrame,
29
+ log,
30
+ monotonic_now_ns,
31
+ msgpack,
32
+ node,
33
+ )
34
+ from tatolab.stream.catalog import BinaryEntry
35
+
36
+ __all__ = ["TestPatternSource", "TestPatternSourceConfig"]
37
+
38
+ _THIS_PACKAGE = "tatolab.testpattern"
39
+
40
+ VIDEO_OUTPUT_PORT_NAME = "video"
41
+
42
+ TEST_PATTERN_FRAMES_PER_SECOND = 30
43
+
44
+ LARGEST_TEST_PATTERN_FRAME_SIDE_PIXELS = 16_384
45
+ """The largest frame side the source renders: 16K, far past any frame a stream asks for."""
46
+
47
+ POTATO_SPRITE_PIXELS_PER_FRAME = 4
48
+ """How far the potato travels along each axis per frame."""
49
+
50
+ CAPTION_PANEL_MARGIN_PIXELS = 24
51
+ """The gap between the caption panel and the frame's right and bottom edges."""
52
+
53
+ DROPPED_FRAMES_BETWEEN_REPORTS = 1800
54
+ """A run of frames the output pool refused is logged at its first and then at every this many."""
55
+
56
+ _TEST_PATTERN_FRAME_TEXTURE_FORMAT = "rgba8_unorm"
57
+ _TEST_PATTERN_FRAME_TEXTURE_USAGE = ["storage_binding", "texture_binding"]
58
+ _OVERLAY_TEXTURE_USAGE = ["texture_binding"]
59
+
60
+ # The shader's `local_size_x` and `local_size_y`.
61
+ _WORKGROUP_TILE_SIZE_IN_PIXELS = 16
62
+
63
+ _POTATO_SPRITE_BINDING_NAME = "potato_sprite_texture"
64
+ _CAPTION_PANEL_BINDING_NAME = "caption_panel_texture"
65
+ _TEST_PATTERN_FRAME_BINDING_NAME = "test_pattern_frame"
66
+
67
+ # The shader's `TestPatternFramePushConstants` block, field for field.
68
+ _PUSH_CONSTANT_BLOCK_STRUCT = struct.Struct("<IIiiIIiiII")
69
+
70
+ _SIGNED_PIXEL_OFFSET_RANGE = (-(2**31), 2**31 - 1)
71
+
72
+
73
+ @dataclasses.dataclass(frozen=True)
74
+ class BakedRgbaOverlay:
75
+ """A picture shipped in this package as tightly packed RGBA rows."""
76
+
77
+ resource_name: str
78
+ width: int
79
+ height: int
80
+
81
+ def rgba_rows(self) -> bytes:
82
+ """The overlay's `width × height` RGBA pixels, row by row."""
83
+ rgba = resources.files(_THIS_PACKAGE).joinpath(self.resource_name).read_bytes()
84
+ expected_byte_count = self.width * self.height * 4
85
+ if len(rgba) != expected_byte_count:
86
+ raise RuntimeError(
87
+ f"TestPatternSource: {self.resource_name} holds {len(rgba)} bytes, not the "
88
+ f"{expected_byte_count} of {self.width}x{self.height} RGBA pixels"
89
+ )
90
+ return rgba
91
+
92
+
93
+ POTATO_SPRITE = BakedRgbaOverlay("potato_sprite_160x160.rgba", 160, 160)
94
+ """The potato, drawn over the bars wherever its frame index puts it."""
95
+
96
+ SAMPLE_STREAM_CAPTION_PANEL = BakedRgbaOverlay("sample_stream_captions_548x62.rgba", 548, 62)
97
+ """"Tatolab stream setup successfully" over "sample stream", right-aligned, in Press Start 2P
98
+ white on an opaque dark panel."""
99
+
100
+
101
+ @dataclasses.dataclass(frozen=True)
102
+ class OverlayTopLeftInTheFrame:
103
+ """Where an overlay's top-left pixel lands; negative where the frame is smaller than it."""
104
+
105
+ left: int
106
+ top: int
107
+
108
+
109
+ def _saturated_to_a_signed_pixel_offset(pixel_offset: int) -> int:
110
+ smallest, largest = _SIGNED_PIXEL_OFFSET_RANGE
111
+ return max(smallest, min(largest, pixel_offset))
112
+
113
+
114
+ def _bounced_position_along(distance: int, travel: int) -> int:
115
+ if travel == 0:
116
+ return 0
117
+ distance_into_the_round_trip = distance % (2 * travel)
118
+ if distance_into_the_round_trip <= travel:
119
+ return distance_into_the_round_trip
120
+ return 2 * travel - distance_into_the_round_trip
121
+
122
+
123
+ def potato_sprite_top_left_at_frame(
124
+ frame_index: int, frame_width: int, frame_height: int
125
+ ) -> OverlayTopLeftInTheFrame:
126
+ """Where the potato sits in frame `frame_index`, bouncing off every edge it reaches."""
127
+ distance = (frame_index * POTATO_SPRITE_PIXELS_PER_FRAME) % 2**64
128
+ return OverlayTopLeftInTheFrame(
129
+ left=_bounced_position_along(distance, max(frame_width - POTATO_SPRITE.width, 0)),
130
+ top=_bounced_position_along(distance, max(frame_height - POTATO_SPRITE.height, 0)),
131
+ )
132
+
133
+
134
+ def caption_panel_top_left(frame_width: int, frame_height: int) -> OverlayTopLeftInTheFrame:
135
+ """Where the caption panel sits: the bottom-right corner, inset by its margin."""
136
+
137
+ def inset_from_the_far_edge(frame_side: int, panel_side: int) -> int:
138
+ return _saturated_to_a_signed_pixel_offset(
139
+ frame_side - panel_side - CAPTION_PANEL_MARGIN_PIXELS
140
+ )
141
+
142
+ return OverlayTopLeftInTheFrame(
143
+ left=inset_from_the_far_edge(frame_width, SAMPLE_STREAM_CAPTION_PANEL.width),
144
+ top=inset_from_the_far_edge(frame_height, SAMPLE_STREAM_CAPTION_PANEL.height),
145
+ )
146
+
147
+
148
+ def pack_push_constants_for_frame(frame_index: int, frame_width: int, frame_height: int) -> bytes:
149
+ """The kernel's push-constant block for frame `frame_index`."""
150
+ potato_sprite = potato_sprite_top_left_at_frame(frame_index, frame_width, frame_height)
151
+ caption_panel = caption_panel_top_left(frame_width, frame_height)
152
+ return _PUSH_CONSTANT_BLOCK_STRUCT.pack(
153
+ frame_width,
154
+ frame_height,
155
+ potato_sprite.left,
156
+ potato_sprite.top,
157
+ POTATO_SPRITE.width,
158
+ POTATO_SPRITE.height,
159
+ caption_panel.left,
160
+ caption_panel.top,
161
+ SAMPLE_STREAM_CAPTION_PANEL.width,
162
+ SAMPLE_STREAM_CAPTION_PANEL.height,
163
+ )
164
+
165
+
166
+ def compute_kernel_glsl_rendering_a_test_pattern_frame() -> str:
167
+ """The compute kernel that renders one frame."""
168
+ return resources.files(_THIS_PACKAGE).joinpath("test_pattern_frame.comp").read_text()
169
+
170
+
171
+ def _is_plain_int(value: Any) -> bool:
172
+ return isinstance(value, int) and not isinstance(value, bool)
173
+
174
+
175
+ @dataclasses.dataclass
176
+ class TestPatternSourceConfig:
177
+ """What a `TestPatternSource` is configured with: the frame size; the animation, rate and format are fixed."""
178
+
179
+ __test__ = False
180
+
181
+ width: Annotated[int, "Frame width in pixels."] = 1280
182
+ height: Annotated[int, "Frame height in pixels."] = 720
183
+
184
+ def __post_init__(self) -> None:
185
+ for dimension_name, dimension in (("width", self.width), ("height", self.height)):
186
+ if not _is_plain_int(dimension) or not (
187
+ 1 <= dimension <= LARGEST_TEST_PATTERN_FRAME_SIDE_PIXELS
188
+ ):
189
+ raise ValueError(
190
+ f"TestPatternSourceConfig: {dimension_name} is a frame side of 1 to "
191
+ f"{LARGEST_TEST_PATTERN_FRAME_SIDE_PIXELS} pixels, got {dimension!r}"
192
+ )
193
+
194
+
195
+ def _workgroups_covering(pixels: int) -> int:
196
+ return (pixels + _WORKGROUP_TILE_SIZE_IN_PIXELS - 1) // _WORKGROUP_TILE_SIZE_IN_PIXELS
197
+
198
+
199
+ def _upload_overlay_into_a_texture(
200
+ gpu_full_access: GpuContextFullAccess, overlay: BakedRgbaOverlay
201
+ ) -> GpuSurfaceHandle:
202
+ rgba_rows = overlay.rgba_rows()
203
+ overlay_texture = gpu_full_access.acquire_texture(
204
+ overlay.width, overlay.height, _TEST_PATTERN_FRAME_TEXTURE_FORMAT, _OVERLAY_TEXTURE_USAGE
205
+ )
206
+ row_byte_count = overlay.width * 4
207
+ overlay_texture.lock(read_only=False)
208
+ try:
209
+ base_address = overlay_texture.base_address
210
+ if base_address is None:
211
+ raise RuntimeError(
212
+ f"TestPatternSource: the {overlay.resource_name} texture opened no host mapping"
213
+ )
214
+ bytes_per_row = overlay_texture.bytes_per_row
215
+ for row_index in range(overlay.height):
216
+ ctypes.memmove(
217
+ base_address + row_index * bytes_per_row,
218
+ rgba_rows[row_index * row_byte_count : (row_index + 1) * row_byte_count],
219
+ row_byte_count,
220
+ )
221
+ finally:
222
+ overlay_texture.unlock()
223
+ return overlay_texture
224
+
225
+
226
+ @node(
227
+ execution="continuous",
228
+ interval_ms=33,
229
+ description=(
230
+ "Synthetic SMPTE-style color bars with a bouncing potato and the sample stream's "
231
+ "captions, rendered on the GPU — demos a pipeline with no camera attached"
232
+ ),
233
+ )
234
+ class TestPatternSource:
235
+ """The sample stream's animation at about 30 frames a second, as RGBA `VideoFrame`s."""
236
+
237
+ __test__ = False
238
+
239
+ def __init__(self, config: TestPatternSourceConfig) -> None:
240
+ self._config = config
241
+ self._frame_ring = NodeOutputTextureRing(
242
+ _TEST_PATTERN_FRAME_TEXTURE_FORMAT, _TEST_PATTERN_FRAME_TEXTURE_USAGE
243
+ )
244
+ self._compute_kernel: "ComputeKernel | None" = None
245
+ self._potato_sprite_texture: "GpuSurfaceHandle | None" = None
246
+ self._caption_panel_texture: "GpuSurfaceHandle | None" = None
247
+ # Advances only on a published frame, so frame N's picture never depends on a dropped one.
248
+ self._next_frame_index = 0
249
+ self._consecutive_dropped_frames = 0
250
+
251
+ @node.output(
252
+ description="Test-pattern video frames",
253
+ catalog=BinaryEntry(mode="snapshot", mime="application/msgpack"),
254
+ )
255
+ def video(self) -> VideoFrame: ...
256
+
257
+ def setup(self, ctx: RuntimeContextFullAccess) -> None:
258
+ gpu_full_access = ctx.gpu_full_access
259
+ self._compute_kernel = gpu_full_access.create_compute_kernel(
260
+ source=compute_kernel_glsl_rendering_a_test_pattern_frame(),
261
+ push_constant_size=_PUSH_CONSTANT_BLOCK_STRUCT.size,
262
+ bindings={
263
+ _POTATO_SPRITE_BINDING_NAME: "sampled_texture",
264
+ _CAPTION_PANEL_BINDING_NAME: "sampled_texture",
265
+ _TEST_PATTERN_FRAME_BINDING_NAME: "storage_image",
266
+ },
267
+ )
268
+ self._potato_sprite_texture = _upload_overlay_into_a_texture(
269
+ gpu_full_access, POTATO_SPRITE
270
+ )
271
+ self._caption_panel_texture = _upload_overlay_into_a_texture(
272
+ gpu_full_access, SAMPLE_STREAM_CAPTION_PANEL
273
+ )
274
+ log.info(
275
+ f"TestPatternSource: rendering {self._config.width}x{self._config.height} on the GPU"
276
+ )
277
+
278
+ def process(self, ctx: RuntimeContextLimitedAccess) -> None:
279
+ if (
280
+ self._compute_kernel is None
281
+ or self._potato_sprite_texture is None
282
+ or self._caption_panel_texture is None
283
+ ):
284
+ return
285
+ frame_width, frame_height = self._config.width, self._config.height
286
+ try:
287
+ frame_texture = self._frame_ring.next_texture_for_this_frame(
288
+ ctx.gpu_limited_access, frame_width, frame_height
289
+ )
290
+ except RuntimeError as refusal:
291
+ self._note_a_frame_the_output_pool_refused(refusal)
292
+ return
293
+ self._consecutive_dropped_frames = 0
294
+ self._compute_kernel.dispatch(
295
+ bindings={
296
+ _POTATO_SPRITE_BINDING_NAME: self._potato_sprite_texture,
297
+ _CAPTION_PANEL_BINDING_NAME: self._caption_panel_texture,
298
+ _TEST_PATTERN_FRAME_BINDING_NAME: frame_texture,
299
+ },
300
+ group_count=(
301
+ _workgroups_covering(frame_width),
302
+ _workgroups_covering(frame_height),
303
+ 1,
304
+ ),
305
+ push_constants=pack_push_constants_for_frame(
306
+ self._next_frame_index, frame_width, frame_height
307
+ ),
308
+ )
309
+ self._next_frame_index += 1
310
+ timestamp_ns = monotonic_now_ns()
311
+ ctx.outputs.write(
312
+ VIDEO_OUTPUT_PORT_NAME,
313
+ msgpack.pack(
314
+ {
315
+ "surface_id": frame_texture.surface_id,
316
+ "width": frame_width,
317
+ "height": frame_height,
318
+ "timestamp_ns": timestamp_ns,
319
+ "fps": TEST_PATTERN_FRAMES_PER_SECOND,
320
+ "color_info": {"primaries": "bt709", "transfer": "srgb", "range": "full"},
321
+ }
322
+ ),
323
+ timestamp_ns=timestamp_ns,
324
+ )
325
+
326
+ def teardown(self, ctx: RuntimeContextFullAccess) -> None:
327
+ del ctx
328
+ for overlay_texture in (self._potato_sprite_texture, self._caption_panel_texture):
329
+ if overlay_texture is not None:
330
+ overlay_texture.close()
331
+ self._potato_sprite_texture = None
332
+ self._caption_panel_texture = None
333
+ self._compute_kernel = None
334
+
335
+ def _note_a_frame_the_output_pool_refused(self, refusal: RuntimeError) -> None:
336
+ self._consecutive_dropped_frames += 1
337
+ if (self._consecutive_dropped_frames - 1) % DROPPED_FRAMES_BETWEEN_REPORTS == 0:
338
+ log.warn(
339
+ f"TestPatternSource: dropped frame {self._next_frame_index}, "
340
+ f"{self._consecutive_dropped_frames} in a row: {refusal}"
341
+ )
File without changes
@@ -0,0 +1 @@
1
+ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
@@ -0,0 +1,96 @@
1
+ // Copyright (c) 2025 Jonathan Fontanez
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+
4
+ // One test-pattern frame: SMPTE bars, the potato sprite over them, the caption
5
+ // panel over both. Every channel is blended as a whole byte, so every device
6
+ // writes the same bytes for the same push constants.
7
+
8
+ #version 450
9
+
10
+ layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
11
+
12
+ layout(set = 0, binding = 0) uniform sampler2D potato_sprite_texture;
13
+ layout(set = 0, binding = 1) uniform sampler2D caption_panel_texture;
14
+ layout(set = 0, binding = 2, rgba8) uniform writeonly image2D test_pattern_frame;
15
+
16
+ layout(push_constant) uniform TestPatternFramePushConstants {
17
+ uint frame_width;
18
+ uint frame_height;
19
+ int potato_sprite_left;
20
+ int potato_sprite_top;
21
+ uint potato_sprite_width;
22
+ uint potato_sprite_height;
23
+ int caption_panel_left;
24
+ int caption_panel_top;
25
+ uint caption_panel_width;
26
+ uint caption_panel_height;
27
+ } placement;
28
+
29
+ const uint SMPTE_BAR_COUNT = 8u;
30
+ const uvec4 SMPTE_BAR_COLORS_RGBA[SMPTE_BAR_COUNT] = uvec4[](
31
+ uvec4(255u, 255u, 255u, 255u), // white
32
+ uvec4(255u, 255u, 0u, 255u), // yellow
33
+ uvec4(0u, 255u, 255u, 255u), // cyan
34
+ uvec4(0u, 255u, 0u, 255u), // green
35
+ uvec4(255u, 0u, 255u, 255u), // magenta
36
+ uvec4(255u, 0u, 0u, 255u), // red
37
+ uvec4(0u, 0u, 255u, 255u), // blue
38
+ uvec4(0u, 0u, 0u, 255u) // black
39
+ );
40
+
41
+ // An `rgba8_unorm` texel holds `byte / 255` exactly enough that rounding
42
+ // recovers the byte.
43
+ uvec4 texel_bytes(sampler2D overlay_texture, ivec2 within_overlay) {
44
+ return uvec4(round(texelFetch(overlay_texture, within_overlay, 0) * 255.0));
45
+ }
46
+
47
+ // `above` composited over an opaque `below`, rounded to the nearest byte.
48
+ uvec4 composite_over_opaque(uvec4 above, uvec4 below) {
49
+ if (above.a == 0u) {
50
+ return below;
51
+ }
52
+ if (above.a == 255u) {
53
+ return above;
54
+ }
55
+ uvec3 blended = (above.rgb * above.a + below.rgb * (255u - above.a) + 127u) / 255u;
56
+ return uvec4(blended, 255u);
57
+ }
58
+
59
+ // The overlay byte quadruple covering frame pixel `at`, or a transparent one
60
+ // where the overlay placed at `top_left` does not cover it.
61
+ uvec4 overlay_bytes_at(
62
+ sampler2D overlay_texture, ivec2 at, ivec2 top_left, uvec2 overlay_extent) {
63
+ ivec2 within_overlay = at - top_left;
64
+ if (any(lessThan(within_overlay, ivec2(0)))
65
+ || any(greaterThanEqual(uvec2(within_overlay), overlay_extent))) {
66
+ return uvec4(0u);
67
+ }
68
+ return texel_bytes(overlay_texture, within_overlay);
69
+ }
70
+
71
+ void main() {
72
+ uvec2 at = gl_GlobalInvocationID.xy;
73
+ if (at.x >= placement.frame_width || at.y >= placement.frame_height) {
74
+ return;
75
+ }
76
+
77
+ uint bar = min((at.x * SMPTE_BAR_COUNT) / placement.frame_width, SMPTE_BAR_COUNT - 1u);
78
+ uvec4 pixel = SMPTE_BAR_COLORS_RGBA[bar];
79
+
80
+ pixel = composite_over_opaque(
81
+ overlay_bytes_at(
82
+ potato_sprite_texture,
83
+ ivec2(at),
84
+ ivec2(placement.potato_sprite_left, placement.potato_sprite_top),
85
+ uvec2(placement.potato_sprite_width, placement.potato_sprite_height)),
86
+ pixel);
87
+ pixel = composite_over_opaque(
88
+ overlay_bytes_at(
89
+ caption_panel_texture,
90
+ ivec2(at),
91
+ ivec2(placement.caption_panel_left, placement.caption_panel_top),
92
+ uvec2(placement.caption_panel_width, placement.caption_panel_height)),
93
+ pixel);
94
+
95
+ imageStore(test_pattern_frame, ivec2(at), vec4(pixel) / 255.0);
96
+ }
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.5
2
+ Name: tatolab-testpattern
3
+ Version: 0.68.27
4
+ Summary: A test-pattern video source for Tatolab streams: SMPTE bars and a bouncing potato, rendered on the GPU.
5
+ Project-URL: Homepage, https://tatolab.com
6
+ Project-URL: Install, https://tatolab.com/docs/install
7
+ Project-URL: Source, https://github.com/tatolab/streamlib
8
+ Author-email: Jonathan Fontanez <fontanezj1@gmail.com>
9
+ License-Expression: BUSL-1.1
10
+ License-File: LICENSE
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Multimedia :: Video
13
+ Classifier: Typing :: Typed
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: tatolab-stream>=0.68.7
16
+ Description-Content-Type: text/markdown
17
+
18
+ # tatolab-testpattern
19
+
20
+ The sample stream's test pattern, built the way a third party builds a node: an
21
+ ordinary Python package that depends on `tatolab-stream` and on no engine crate.
22
+ Its GPU work is one compute kernel built through `create_compute_kernel`, the
23
+ surface every node is handed.
24
+
25
+ - `TestPatternSource` publishes SMPTE-style colour bars with a bouncing potato
26
+ and the sample stream's caption panel on `video`, about 30 frames a second, as
27
+ RGBA `VideoFrame`s tagged BT.709 primaries, the sRGB transfer and full range.
28
+ - Config: `width` and `height` of each frame, 1280x720 by default, each side 1
29
+ to 16384 pixels.
30
+ - A frame's picture is a function of its index alone: the potato leaves the
31
+ top-left corner at frame zero, travels four pixels a frame along each axis
32
+ and bounces off every edge; the caption panel sits 24 pixels in from the
33
+ bottom-right corner. The index advances only when a frame is published, so
34
+ a frame the output pool refused never shifts the next one's picture.
35
+
36
+ ```python
37
+ from tatolab.testpattern import TestPatternSource
38
+
39
+ source = stream_builder.add(TestPatternSource, config={"width": 1920, "height": 1080})
40
+ ```
41
+
42
+ ## Check it
43
+
44
+ ```bash
45
+ uv venv --python 3.12 .venv && VIRTUAL_ENV=.venv uv pip install ../../sdk/tatolab-stream -e . pytest
46
+ .venv/bin/pytest tests && uvx pyright@1.1.411
47
+ ```
48
+
49
+ The pixel tests run on a runtime, in the integration suite's
50
+ `test_test_pattern_module.py`.
@@ -0,0 +1,10 @@
1
+ tatolab/testpattern/__init__.py,sha256=LHjqSvMfEURnQEgwKgFo0lWwrRpH83QDa6refAuHlTo,12924
2
+ tatolab/testpattern/potato_sprite_160x160.rgba,sha256=Tq3EhnggkawIoH-nTc5CToapU--Jx1J0nNti0rF_wJg,102400
3
+ tatolab/testpattern/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ tatolab/testpattern/sample_stream_captions_548x62.rgba,sha256=HKV9AZk1XRO8H1B7y7duX9WN1qL6KHEA_t4ck0T83Wc,135904
5
+ tatolab/testpattern/test_pattern_frame.comp,sha256=PdRLZc4_qBzKQe30yxG5PcJasDkJVPoqOnsDGkB0mm4,3467
6
+ tatolab_testpattern-0.68.27.dist-info/METADATA,sha256=r-U8aSpJ6SugcwmtBZb9ld-XRqIeas1EHQjIpYv36DU,2100
7
+ tatolab_testpattern-0.68.27.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
8
+ tatolab_testpattern-0.68.27.dist-info/entry_points.txt,sha256=57nknH8_5SMEU65zK9-adWvrXB8sllKJ56vQXhVs0C0,74
9
+ tatolab_testpattern-0.68.27.dist-info/licenses/LICENSE,sha256=6JmFbJaesl1Pzr79-PQAOnYBnZ0R-PuAd7kPWA_kBG8,6634
10
+ tatolab_testpattern-0.68.27.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [tatolab.nodes]
2
+ TestPatternSource = tatolab.testpattern:TestPatternSource
@@ -0,0 +1,134 @@
1
+ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
2
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
3
+
4
+ Parameters
5
+
6
+ Licensor: Jonathan Fontanez
7
+ Licensed Work: StreamLib
8
+ The Licensed Work is (c) 2025 Jonathan Fontanez.
9
+ Additional Use Grant: You may make production use of the Licensed Work, provided
10
+ that you do not engage in any Restricted Use.
11
+
12
+ RESTRICTED USES (require commercial license):
13
+
14
+ (a) Selling, licensing, sublicensing, or distributing the
15
+ Runtime (or any derivative work based on the Runtime)
16
+ as a standalone product, SDK, framework, engine, or
17
+ library;
18
+
19
+ (b) Offering the Runtime as a managed service, hosted
20
+ platform, cloud offering, or "as-a-service" product
21
+ where third parties interact with the Runtime's
22
+ functionality;
23
+
24
+ (c) White-labeling, rebranding, or OEM licensing of the
25
+ Runtime for redistribution to third parties;
26
+
27
+ (d) Creating a product that competes with StreamLib by
28
+ providing substantially similar media processing
29
+ runtime capabilities derived from the Licensed Work;
30
+
31
+ (e) Embedding the Runtime in a product where the Runtime
32
+ itself (or access to it) is sold, licensed, or
33
+ sublicensed separately to end users.
34
+
35
+ "Runtime" means the StreamLib runtime engine, including
36
+ the graph data structures, graph compiler, scheduler,
37
+ processor execution system, link/port infrastructure,
38
+ GPU context management, and associated infrastructure
39
+ code found in this repository.
40
+
41
+ The Runtime does NOT include Processors you create using
42
+ StreamLib's Processor API (see Permitted Uses below).
43
+
44
+ PERMITTED USES (no commercial license required):
45
+
46
+ (a) Personal, educational, and research use;
47
+
48
+ (b) Internal business use for evaluation and development;
49
+
50
+ (c) Use in open source projects licensed under OSI-approved
51
+ licenses;
52
+
53
+ (d) Use in commercial products where StreamLib is not the
54
+ primary value proposition (e.g., a video conferencing
55
+ app, a security camera system, a robotics application);
56
+
57
+ (e) Building, distributing, and selling custom Processors.
58
+ "Processors" are components that implement StreamLib's
59
+ processor traits (ReactiveProcessor, ContinuousProcessor,
60
+ ManualProcessor) to add functionality to the pipeline.
61
+
62
+ YOU OWN YOUR PROCESSORS. StreamLib claims no rights to
63
+ Processor code you create. You may:
64
+ - License your Processors under any terms (including
65
+ proprietary/commercial)
66
+ - Sell your Processors for any price
67
+ - Keep your Processor source code private
68
+ - Build Processors for clients as a contractor/consultant
69
+
70
+ This grant exists to encourage a thriving ecosystem of
71
+ community and commercial Processors, similar to how game
72
+ engines enable developers to build and sell games.
73
+
74
+ For any Restricted Use, you must obtain a commercial license.
75
+ Two options are available:
76
+
77
+ - Commercial License: For production use that falls under
78
+ Restricted Uses.
79
+ - Partner License: For consulting companies, integrators,
80
+ and strategic partners with additional benefits including
81
+ early access, roadmap input, and co-marketing rights.
82
+
83
+ Change Date: January 1, 2029
84
+
85
+ Change License: Apache License, Version 2.0
86
+
87
+ For information about alternative licensing arrangements for the Licensed Work,
88
+ please contact: fontanezj1@gmail.com
89
+
90
+ Notice
91
+
92
+ Business Source License 1.1
93
+
94
+ Terms
95
+
96
+ The Licensor hereby grants you the right to copy, modify, create derivative
97
+ works, redistribute, and make non-production use of the Licensed Work. The
98
+ Licensor may make an Additional Use Grant, above, permitting limited production
99
+ use.
100
+
101
+ Effective on the Change Date, or the fourth anniversary of the first publicly
102
+ available distribution of a specific version of the Licensed Work under this
103
+ License, whichever comes first, the Licensor hereby grants you rights under
104
+ the terms of the Change License, and the rights granted in the paragraph
105
+ above terminate.
106
+
107
+ If your use of the Licensed Work does not comply with the requirements
108
+ currently in effect as described in this License, you must purchase a
109
+ commercial license from the Licensor, its affiliated entities, or authorized
110
+ resellers, or you must refrain from using the Licensed Work.
111
+
112
+ All copies of the original and modified Licensed Work, and derivative works
113
+ of the Licensed Work, are subject to this License. This License applies
114
+ separately for each version of the Licensed Work and the Change Date may vary
115
+ for each version of the Licensed Work released by Licensor.
116
+
117
+ You must conspicuously display this License on each original or modified copy
118
+ of the Licensed Work. If you receive the Licensed Work in original or
119
+ modified form from a third party, the terms and conditions set forth in this
120
+ License apply to your use of that work.
121
+
122
+ Any use of the Licensed Work in violation of this License will automatically
123
+ terminate your rights under this License for the current and all other
124
+ versions of the Licensed Work.
125
+
126
+ This License does not grant you any right in any trademark or logo of
127
+ Licensor or its affiliates (provided that you may use a trademark or logo of
128
+ Licensor as expressly required by this License).
129
+
130
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
131
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
132
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
133
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
134
+ TITLE.