Add Infinity_Vis_1 performance core
This commit is contained in:
1
Infinity_Vis_1/infinity_vis_1/output/__init__.py
Normal file
1
Infinity_Vis_1/infinity_vis_1/output/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Output backends for Infinity_Vis_1."""
|
||||
56
Infinity_Vis_1/infinity_vis_1/output/ddp.py
Normal file
56
Infinity_Vis_1/infinity_vis_1/output/ddp.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import socket
|
||||
import struct
|
||||
|
||||
|
||||
DDP_DEFAULT_PORT = 4048
|
||||
DDP_MAX_DATA_LENGTH = 1440
|
||||
DDP_VERSION_1 = 0x40
|
||||
DDP_PUSH_FLAG = 0x01
|
||||
DDP_RGB888 = 0x0B
|
||||
DDP_DESTINATION_ID = 1
|
||||
|
||||
|
||||
class DDPClient:
|
||||
def __init__(self, port: int = DDP_DEFAULT_PORT) -> None:
|
||||
self.port = int(port)
|
||||
self._sequence = 1
|
||||
|
||||
def count_packets(self, host_payloads: dict[str, bytes]) -> int:
|
||||
packet_count = 0
|
||||
for payload in host_payloads.values():
|
||||
chunks, remainder = divmod(len(payload), DDP_MAX_DATA_LENGTH)
|
||||
packet_count += chunks + (1 if remainder else 0)
|
||||
return packet_count
|
||||
|
||||
def build_packets(self, host_payloads: dict[str, bytes]) -> list[tuple[str, bytes]]:
|
||||
packets: list[tuple[str, bytes]] = []
|
||||
sequence = self._next_sequence()
|
||||
for host, payload in host_payloads.items():
|
||||
for offset in range(0, len(payload), DDP_MAX_DATA_LENGTH):
|
||||
chunk = payload[offset : offset + DDP_MAX_DATA_LENGTH]
|
||||
last = offset + DDP_MAX_DATA_LENGTH >= len(payload)
|
||||
header = struct.pack(
|
||||
"!BBBBLH",
|
||||
DDP_VERSION_1 | (DDP_PUSH_FLAG if last else 0),
|
||||
sequence,
|
||||
DDP_RGB888,
|
||||
DDP_DESTINATION_ID,
|
||||
offset,
|
||||
len(chunk),
|
||||
)
|
||||
packets.append((host, header + chunk))
|
||||
return packets
|
||||
|
||||
def send(self, host_payloads: dict[str, bytes]) -> int:
|
||||
packets = self.build_packets(host_payloads)
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||
for host, packet in packets:
|
||||
sock.sendto(packet, (host, self.port))
|
||||
return len(packets)
|
||||
|
||||
def _next_sequence(self) -> int:
|
||||
sequence = self._sequence
|
||||
self._sequence = 1 if self._sequence >= 15 else self._sequence + 1
|
||||
return sequence
|
||||
Reference in New Issue
Block a user