diff options
Diffstat (limited to 'kvmd/apps/vnc/rfb')
-rw-r--r-- | kvmd/apps/vnc/rfb/__init__.py | 18 | ||||
-rw-r--r-- | kvmd/apps/vnc/rfb/encodings.py | 8 |
2 files changed, 22 insertions, 4 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py index f0a42223..d4702d74 100644 --- a/kvmd/apps/vnc/rfb/__init__.py +++ b/kvmd/apps/vnc/rfb/__init__.py @@ -22,6 +22,7 @@ import asyncio import ssl +import dataclasses from typing import Tuple from typing import List @@ -164,6 +165,13 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute else: await self._write_struct("", bytes([0b10011111, length & 0x7F | 0x80, length >> 7 & 0x7F | 0x80, length >> 14 & 0xFF]), data) + async def _send_fb_h264(self, data: bytes) -> None: + assert self._encodings.has_h264 + assert len(data) <= 0xFFFFFFFF, len(data) + await self._write_fb_update(self._width, self._height, RfbEncodings.H264, drain=False) + await self._write_struct("LL", len(data), 0, drain=False) + await self._write_struct("", data) + async def _send_resize(self, width: int, height: int) -> None: assert self._encodings.has_resize await self._write_fb_update(width, height, RfbEncodings.RESIZE) @@ -380,14 +388,18 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute raise RfbError(f"Requested unsupported bits_per_pixel={bits_per_pixel} for Tight JPEG; required 16 or 32") async def __handle_set_encodings(self) -> None: + logger = get_logger(0) + encodings_count = (await self._read_struct("x H"))[0] if encodings_count > 1024: raise RfbError(f"Too many encodings: {encodings_count}") + self._encodings = RfbClientEncodings(frozenset(await self._read_struct("l" * encodings_count))) - get_logger(0).info("[main] %s: Features: resize=%d, rename=%d, leds=%d, extkeys=%d", - self._remote, self._encodings.has_resize, self._encodings.has_rename, - self._encodings.has_leds_state, self._encodings.has_ext_keys) + logger.info("[main] %s: Client features (SetEncodings): ...", self._remote) + for (key, value) in dataclasses.asdict(self._encodings).items(): + logger.info("[main] %s: ... %s=%s", self._remote, key, value) self.__check_tight_jpeg() + if self._encodings.has_ext_keys: # Preferred method await self._write_fb_update(0, 0, RfbEncodings.EXT_KEYS, drain=True) await self._on_set_encodings() diff --git a/kvmd/apps/vnc/rfb/encodings.py b/kvmd/apps/vnc/rfb/encodings.py index ad83f726..6ecfaa76 100644 --- a/kvmd/apps/vnc/rfb/encodings.py +++ b/kvmd/apps/vnc/rfb/encodings.py @@ -39,9 +39,11 @@ class RfbEncodings: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], )) + H264 = 0xCAFE0101 # Pi-KVM H264 Encoding + @dataclasses.dataclass(frozen=True) -class RfbClientEncodings: +class RfbClientEncodings: # pylint: disable=too-many-instance-attributes encodings: FrozenSet[int] has_resize: bool = dataclasses.field(default=False) @@ -52,6 +54,8 @@ class RfbClientEncodings: has_tight: bool = dataclasses.field(default=False) tight_jpeg_quality: int = dataclasses.field(default=0) + has_h264: bool = dataclasses.field(default=False) + def __post_init__(self) -> None: self.__set("has_resize", (RfbEncodings.RESIZE in self.encodings)) self.__set("has_rename", (RfbEncodings.RENAME in self.encodings)) @@ -61,6 +65,8 @@ class RfbClientEncodings: self.__set("has_tight", (RfbEncodings.TIGHT in self.encodings)) self.__set("tight_jpeg_quality", self.__get_tight_jpeg_quality()) + self.__set("has_h264", (RfbEncodings.H264 in self.encodings)) + def __set(self, key: str, value: Any) -> None: object.__setattr__(self, key, value) |