diff options
-rw-r--r-- | kvmd/apps/__init__.py | 36 | ||||
-rw-r--r-- | kvmd/apps/kvmd/__init__.py | 7 | ||||
-rw-r--r-- | kvmd/apps/kvmd/streamer.py | 35 | ||||
-rw-r--r-- | kvmd/validators/kvm.py | 4 | ||||
-rw-r--r-- | testenv/tests/validators/test_kvm.py | 15 |
5 files changed, 78 insertions, 19 deletions
diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py index b835088e..1255c1eb 100644 --- a/kvmd/apps/__init__.py +++ b/kvmd/apps/__init__.py @@ -91,6 +91,7 @@ from ..validators.kvm import valid_stream_quality from ..validators.kvm import valid_stream_fps from ..validators.kvm import valid_stream_resolution from ..validators.kvm import valid_stream_h264_bitrate +from ..validators.kvm import valid_stream_h264_gop from ..validators.ugpio import valid_ugpio_driver from ..validators.ugpio import valid_ugpio_channel @@ -189,6 +190,19 @@ def _patch_raw(raw_config: Dict) -> None: raw_config["otg"]["devices"] = {} raw_config["otg"]["devices"][new] = raw_config["otg"].pop(old) + if isinstance(raw_config.get("kvmd"), dict) and isinstance(raw_config["kvmd"].get("streamer"), dict): + streamer_config = raw_config["kvmd"]["streamer"] + + desired_fps = streamer_config.get("desired_fps") + if desired_fps is not None and not isinstance(desired_fps, dict): + streamer_config["desired_fps"] = {"default": desired_fps} + + max_fps = streamer_config.get("max_fps") + if max_fps is not None: + if not isinstance(streamer_config.get("desired_fps"), dict): + streamer_config["desired_fps"] = {} + streamer_config["desired_fps"] = {"max": max_fps} + def _patch_dynamic( # pylint: disable=too-many-locals raw_config: Dict, @@ -355,14 +369,26 @@ def _get_config_scheme() -> Dict: "state_poll": Option(1.0, type=valid_float_f01), "quality": Option(80, type=(lambda arg: (valid_stream_quality(arg) if arg else 0))), # 0 for disabled feature - "desired_fps": Option(30, type=valid_stream_fps), - "max_fps": Option(60, type=valid_stream_fps), "resolution": Option("", type=(lambda arg: (valid_stream_resolution(arg) if arg else ""))), "available_resolutions": Option([], type=functools.partial(valid_string_list, subval=valid_stream_resolution)), - "h264_bitrate": Option(0, type=(lambda arg: (valid_stream_h264_bitrate(arg) if arg else 0))), - "h264_min_bitrate": Option(100, type=valid_stream_h264_bitrate), - "h264_max_bitrate": Option(16000, type=valid_stream_h264_bitrate), + "desired_fps": { + "default": Option(30, type=valid_stream_fps, unpack_as="desired_fps"), + "min": Option(0, type=valid_stream_fps, unpack_as="desired_fps_min"), + "max": Option(60, type=valid_stream_fps, unpack_as="desired_fps_max"), + }, + + "h264_bitrate": { + "default": Option(0, type=(lambda arg: (valid_stream_h264_bitrate(arg) if arg else 0)), unpack_as="h264_bitrate"), + "min": Option(100, type=valid_stream_h264_bitrate, unpack_as="h264_bitrate_min"), + "max": Option(16000, type=valid_stream_h264_bitrate, unpack_as="h264_bitrate_max"), + }, + + "h264_gop": { + "default": Option(30, type=valid_stream_h264_gop, unpack_as="h264_gop"), + "min": Option(0, type=valid_stream_h264_gop, unpack_as="h264_gop_min"), + "max": Option(60, type=valid_stream_h264_gop, unpack_as="h264_gop_max"), + }, "host": Option("localhost", type=valid_ip_or_host), "port": Option(0, type=valid_port), diff --git a/kvmd/apps/kvmd/__init__.py b/kvmd/apps/kvmd/__init__.py index 82e0baa5..7e570278 100644 --- a/kvmd/apps/kvmd/__init__.py +++ b/kvmd/apps/kvmd/__init__.py @@ -67,7 +67,12 @@ def main(argv: Optional[List[str]]=None) -> None: config = config.kvmd hid = get_hid_class(config.hid.type)(**hid_kwargs) - streamer = Streamer(**config.streamer._unpack(ignore=["forever"])) + streamer = Streamer( + **config.streamer._unpack(ignore=["forever", "desired_fps", "h264_bitrate", "h264_gop"]), + **config.streamer.desired_fps._unpack(), + **config.streamer.h264_bitrate._unpack(), + **config.streamer.h264_gop._unpack(), + ) KvmdServer( auth_manager=AuthManager( diff --git a/kvmd/apps/kvmd/streamer.py b/kvmd/apps/kvmd/streamer.py index 4c4499ab..6f26a422 100644 --- a/kvmd/apps/kvmd/streamer.py +++ b/kvmd/apps/kvmd/streamer.py @@ -62,28 +62,34 @@ class _StreamerParams: __AVAILABLE_RESOLUTIONS = "available_resolutions" __H264_BITRATE = "h264_bitrate" + __H264_GOP = "h264_gop" - def __init__( + def __init__( # pylint: disable=too-many-arguments self, - desired_fps: int, - max_fps: int, - quality: int, resolution: str, available_resolutions: List[str], + desired_fps: int, + desired_fps_min: int, + desired_fps_max: int, + h264_bitrate: int, h264_min_bitrate: int, h264_max_bitrate: int, + + h264_gop: int, + h264_min_gop: int, + h264_max_gop: int, ) -> None: self.__has_quality = bool(quality) self.__has_resolution = bool(resolution) self.__has_h264 = bool(h264_bitrate) - self.__params: Dict = {self.__DESIRED_FPS: min(desired_fps, max_fps)} - self.__limits: Dict = {self.__DESIRED_FPS: {"min": 0, "max": max_fps}} + self.__params: Dict = {self.__DESIRED_FPS: min(desired_fps, desired_fps_min)} + self.__limits: Dict = {self.__DESIRED_FPS: {"min": desired_fps_min, "max": desired_fps_max}} if self.__has_quality: self.__params[self.__QUALITY] = quality @@ -95,6 +101,8 @@ class _StreamerParams: if self.__has_h264: self.__params[self.__H264_BITRATE] = min(max(h264_bitrate, h264_min_bitrate), h264_max_bitrate) self.__limits[self.__H264_BITRATE] = {"min": h264_min_bitrate, "max": h264_max_bitrate} + self.__params[self.__H264_GOP] = min(max(h264_gop, h264_min_gop), h264_max_gop) + self.__limits[self.__H264_GOP] = {"min": h264_min_gop, "max": h264_max_gop} def get_features(self) -> Dict: return { @@ -115,10 +123,6 @@ class _StreamerParams: def set_params(self, params: Dict) -> None: new_params = dict(self.__params) - if self.__DESIRED_FPS in params: - if self.__check_limits_min_max(self.__DESIRED_FPS, params[self.__DESIRED_FPS]): - new_params[self.__DESIRED_FPS] = params[self.__DESIRED_FPS] - if self.__QUALITY in params and self.__has_quality: new_params[self.__QUALITY] = min(max(params[self.__QUALITY], 1), 100) @@ -126,9 +130,14 @@ class _StreamerParams: if params[self.__RESOLUTION] in self.__limits[self.__AVAILABLE_RESOLUTIONS]: new_params[self.__RESOLUTION] = params[self.__RESOLUTION] - if self.__H264_BITRATE in params and self.__has_h264: - if self.__check_limits_min_max(self.__H264_BITRATE, params[self.__H264_BITRATE]): - new_params[self.__H264_BITRATE] = params[self.__H264_BITRATE] + for (key, enabled) in [ + (self.__DESIRED_FPS, True), + (self.__H264_BITRATE, self.__has_h264), + (self.__H264_GOP, self.__has_h264), + ]: + if key in params and enabled: + if self.__check_limits_min_max(key, params[key]): + new_params[key] = params[key] self.__params = new_params diff --git a/kvmd/validators/kvm.py b/kvmd/validators/kvm.py index e8f14f6a..a2701060 100644 --- a/kvmd/validators/kvm.py +++ b/kvmd/validators/kvm.py @@ -78,3 +78,7 @@ def valid_stream_resolution(arg: Any) -> str: def valid_stream_h264_bitrate(arg: Any) -> int: return int(valid_number(arg, min=100, max=16000, name="stream H264 bitrate")) + + +def valid_stream_h264_gop(arg: Any) -> int: + return int(valid_number(arg, min=0, max=60, name="stream H264 GOP")) diff --git a/testenv/tests/validators/test_kvm.py b/testenv/tests/validators/test_kvm.py index b0058fde..c6ba4436 100644 --- a/testenv/tests/validators/test_kvm.py +++ b/testenv/tests/validators/test_kvm.py @@ -33,6 +33,7 @@ from kvmd.validators.kvm import valid_stream_quality from kvmd.validators.kvm import valid_stream_fps from kvmd.validators.kvm import valid_stream_resolution from kvmd.validators.kvm import valid_stream_h264_bitrate +from kvmd.validators.kvm import valid_stream_h264_gop # ===== @@ -141,3 +142,17 @@ def test_ok__valid_stream_h264_bitrate(arg: Any) -> None: def test_fail__valid_stream_h264_bitrate(arg: Any) -> None: with pytest.raises(ValidatorError): print(valid_stream_h264_bitrate(arg)) + + +# ===== [email protected]("arg", ["1 ", 0, 60]) +def test_ok__valid_stream_h264_gop(arg: Any) -> None: + value = valid_stream_h264_gop(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + [email protected]("arg", ["test", "", None, 61, 1.1]) +def test_fail__valid_stream_h264_gop(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_stream_h264_gop(arg)) |