feat(perception): connect full graph to external streaming source and scene receiver
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
"""One bounded scene document plus its actual uint8 segmentation plane.
|
||||
|
||||
No image re-encoding, base64, hidden array cache or new domain ontology. This
|
||||
codec only frames the existing scene and plane; domain layer digests/freshness
|
||||
must still be checked by the receiving profile adapter before presentation.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import struct
|
||||
from hashlib import sha256
|
||||
from typing import Any
|
||||
|
||||
from . import streaming_wire as wire
|
||||
from .realtime_contract import StreamStart
|
||||
from .realtime_scene import SceneFreshness
|
||||
from .streaming_network import MAX_RESULT
|
||||
|
||||
PREFIX = struct.Struct("!4sIHH")
|
||||
MAX_SCENE_JSON = 512 * 1024
|
||||
MAX_MASK_BYTES = 512 * 1024
|
||||
|
||||
|
||||
def encode_scene_payload(scene: bytes, mask: bytes, shape: tuple[int, int]) -> bytes:
|
||||
height, width = shape
|
||||
if (
|
||||
type(scene) is not bytes
|
||||
or type(mask) is not bytes
|
||||
or type(height) is not int
|
||||
or type(width) is not int
|
||||
or not 0 < height <= 2048
|
||||
or not 0 < width <= 2048
|
||||
or not 0 < len(scene) <= MAX_SCENE_JSON
|
||||
or not 0 < height * width == len(mask) <= MAX_MASK_BYTES
|
||||
or PREFIX.size + len(scene) + len(mask) > MAX_RESULT
|
||||
):
|
||||
raise wire.StreamWireError("scene/segmentation exceeds bounded output contract")
|
||||
return PREFIX.pack(b"MCS1", len(scene), height, width) + scene + mask
|
||||
|
||||
|
||||
def decode_scene_payload(
|
||||
raw: bytes, epoch: StreamStart, sequence: int
|
||||
) -> tuple[dict[str, Any], memoryview, tuple[int, int]]:
|
||||
if not PREFIX.size < len(raw) <= MAX_RESULT:
|
||||
raise wire.StreamWireError("invalid scene payload length")
|
||||
magic, length, height, width = PREFIX.unpack_from(raw)
|
||||
if (
|
||||
magic != b"MCS1"
|
||||
or not 0 < length <= MAX_SCENE_JSON
|
||||
or not 0 < height <= 2048
|
||||
or not 0 < width <= 2048
|
||||
or not 0 < height * width <= MAX_MASK_BYTES
|
||||
or PREFIX.size + length + height * width != len(raw)
|
||||
):
|
||||
raise wire.StreamWireError("invalid scene/segmentation framing")
|
||||
scene = wire.parse_header(bytearray(raw[PREFIX.size : PREFIX.size + length]))
|
||||
mask = memoryview(raw)[PREFIX.size + length :]
|
||||
freshness = SceneFreshness.from_dict(scene.get("freshness"))
|
||||
if (
|
||||
StreamStart.from_dict(scene.get("runtime_binding")) != epoch
|
||||
or type(scene.get("sequence")) is not int
|
||||
or scene["sequence"] != sequence
|
||||
or freshness.source_sequence != sequence
|
||||
or freshness.epoch_id != epoch.epoch_id
|
||||
or freshness.clock_domain_id != epoch.clock_domain_id
|
||||
or scene.get("segmentation_sha256") != sha256(mask).hexdigest()
|
||||
or freshness.layers[0].payload_sha256 != scene["segmentation_sha256"]
|
||||
or scene.get("commands_enabled") is not False
|
||||
or scene.get("actuation_allowed") is not False
|
||||
):
|
||||
raise wire.StreamWireError("scene identity, mask digest or authority mismatch")
|
||||
return scene, mask, (height, width)
|
||||
@@ -105,8 +105,11 @@ def _unique_pairs(pairs: list[tuple[str, Any]]) -> dict[str, Any]:
|
||||
|
||||
|
||||
def parse_header(raw: bytearray) -> dict[str, Any]:
|
||||
def reject_constant(value: str) -> Any:
|
||||
raise StreamWireError("non-finite JSON metadata")
|
||||
|
||||
try:
|
||||
value = json.loads(raw, object_pairs_hook=_unique_pairs)
|
||||
value = json.loads(raw, object_pairs_hook=_unique_pairs, parse_constant=reject_constant)
|
||||
except (ValueError, UnicodeError, RecursionError) as exc:
|
||||
raise StreamWireError("invalid bounded metadata") from exc
|
||||
if not isinstance(value, dict):
|
||||
|
||||
Reference in New Issue
Block a user