added hardware encoding
This commit is contained in:
parent
56d2144bcc
commit
966970c256
2 changed files with 131 additions and 10 deletions
|
|
@ -32,14 +32,24 @@ in
|
||||||
frontcam = {
|
frontcam = {
|
||||||
device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0";
|
device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0";
|
||||||
rtspUrl = "rtsp://192.168.1.143:8554/frontcam";
|
rtspUrl = "rtsp://192.168.1.143:8554/frontcam";
|
||||||
framerate = 15;
|
framerate = 12;
|
||||||
videoSize = "1280x720";
|
videoSize = "1280x720";
|
||||||
|
useVaapi = true;
|
||||||
|
vaapiQp = 26;
|
||||||
|
bitrateKbps = 900;
|
||||||
|
maxrateKbps = 1100;
|
||||||
|
bufsizeKbps = 1800;
|
||||||
};
|
};
|
||||||
webcam = {
|
webcam = {
|
||||||
device = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0";
|
device = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0";
|
||||||
rtspUrl = "rtsp://192.168.1.143:8554/webcam";
|
rtspUrl = "rtsp://192.168.1.143:8554/webcam";
|
||||||
framerate = 15;
|
framerate = 12;
|
||||||
videoSize = "1280x720";
|
videoSize = "1280x720";
|
||||||
|
useVaapi = true;
|
||||||
|
vaapiQp = 26;
|
||||||
|
bitrateKbps = 900;
|
||||||
|
maxrateKbps = 1100;
|
||||||
|
bufsizeKbps = 1800;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ let
|
||||||
rtspUrl = cfg.rtspUrl;
|
rtspUrl = cfg.rtspUrl;
|
||||||
framerate = cfg.framerate;
|
framerate = cfg.framerate;
|
||||||
videoSize = cfg.videoSize;
|
videoSize = cfg.videoSize;
|
||||||
|
preset = cfg.preset;
|
||||||
|
bitrateKbps = cfg.bitrateKbps;
|
||||||
|
maxrateKbps = cfg.maxrateKbps;
|
||||||
|
bufsizeKbps = cfg.bufsizeKbps;
|
||||||
|
useVaapi = cfg.useVaapi;
|
||||||
|
vaapiDevice = cfg.vaapiDevice;
|
||||||
|
vaapiQp = cfg.vaapiQp;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -47,6 +54,51 @@ in
|
||||||
default = "1280x720";
|
default = "1280x720";
|
||||||
description = "Input video size for the webcam stream.";
|
description = "Input video size for the webcam stream.";
|
||||||
};
|
};
|
||||||
|
preset = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"ultrafast"
|
||||||
|
"superfast"
|
||||||
|
"veryfast"
|
||||||
|
"faster"
|
||||||
|
"fast"
|
||||||
|
"medium"
|
||||||
|
"slow"
|
||||||
|
"slower"
|
||||||
|
"veryslow"
|
||||||
|
];
|
||||||
|
default = "veryfast";
|
||||||
|
description = "x264 preset used for software encoding.";
|
||||||
|
};
|
||||||
|
bitrateKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Target bitrate in kbps. Set to null for CRF-like unconstrained output.";
|
||||||
|
};
|
||||||
|
maxrateKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Maximum bitrate in kbps. Defaults to bitrateKbps when unset.";
|
||||||
|
};
|
||||||
|
bufsizeKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Rate-control buffer in kbps. Defaults to 2x bitrateKbps when unset.";
|
||||||
|
};
|
||||||
|
useVaapi = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Use VAAPI hardware encoding (h264_vaapi) instead of libx264.";
|
||||||
|
};
|
||||||
|
vaapiDevice = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/dev/dri/renderD128";
|
||||||
|
description = "VAAPI render device path used when useVaapi = true.";
|
||||||
|
};
|
||||||
|
vaapiQp = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 24;
|
||||||
|
description = "VAAPI quality parameter (lower means better quality, higher CPU/bitrate).";
|
||||||
|
};
|
||||||
streams = mkOption {
|
streams = mkOption {
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (
|
||||||
types.submodule {
|
types.submodule {
|
||||||
|
|
@ -69,6 +121,51 @@ in
|
||||||
default = "1280x720";
|
default = "1280x720";
|
||||||
description = "Input video size for this stream.";
|
description = "Input video size for this stream.";
|
||||||
};
|
};
|
||||||
|
preset = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"ultrafast"
|
||||||
|
"superfast"
|
||||||
|
"veryfast"
|
||||||
|
"faster"
|
||||||
|
"fast"
|
||||||
|
"medium"
|
||||||
|
"slow"
|
||||||
|
"slower"
|
||||||
|
"veryslow"
|
||||||
|
];
|
||||||
|
default = "veryfast";
|
||||||
|
description = "x264 preset used for software encoding.";
|
||||||
|
};
|
||||||
|
bitrateKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Target bitrate in kbps. Set to null for unconstrained output.";
|
||||||
|
};
|
||||||
|
maxrateKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Maximum bitrate in kbps. Defaults to bitrateKbps when unset.";
|
||||||
|
};
|
||||||
|
bufsizeKbps = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = "Rate-control buffer in kbps. Defaults to 2x bitrateKbps when unset.";
|
||||||
|
};
|
||||||
|
useVaapi = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Use VAAPI hardware encoding (h264_vaapi) instead of libx264.";
|
||||||
|
};
|
||||||
|
vaapiDevice = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/dev/dri/renderD128";
|
||||||
|
description = "VAAPI render device path used when useVaapi = true.";
|
||||||
|
};
|
||||||
|
vaapiQp = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 24;
|
||||||
|
description = "VAAPI quality parameter for h264_vaapi.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -81,6 +178,27 @@ in
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services = mapAttrs' (
|
systemd.services = mapAttrs' (
|
||||||
streamName: streamCfg:
|
streamName: streamCfg:
|
||||||
|
let
|
||||||
|
maxrateKbps =
|
||||||
|
if streamCfg.maxrateKbps != null then streamCfg.maxrateKbps else streamCfg.bitrateKbps;
|
||||||
|
bufsizeKbps =
|
||||||
|
if streamCfg.bufsizeKbps != null then
|
||||||
|
streamCfg.bufsizeKbps
|
||||||
|
else if streamCfg.bitrateKbps != null then
|
||||||
|
streamCfg.bitrateKbps * 2
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
rateControlArgs =
|
||||||
|
if streamCfg.bitrateKbps != null then
|
||||||
|
"-b:v ${toString streamCfg.bitrateKbps}k -maxrate ${toString maxrateKbps}k -bufsize ${toString bufsizeKbps}k"
|
||||||
|
else
|
||||||
|
"";
|
||||||
|
videoCodecArgs =
|
||||||
|
if streamCfg.useVaapi then
|
||||||
|
"-vaapi_device ${streamCfg.vaapiDevice} -vf format=nv12,hwupload -c:v h264_vaapi -qp ${toString streamCfg.vaapiQp}"
|
||||||
|
else
|
||||||
|
"-vcodec libx264 -tune zerolatency -preset ${streamCfg.preset}";
|
||||||
|
in
|
||||||
nameValuePair "webcam-rtsp-publisher-${sanitizeName streamName}" {
|
nameValuePair "webcam-rtsp-publisher-${sanitizeName streamName}" {
|
||||||
description = "Publish webcam stream '${streamName}' to MediaMTX over RTSP";
|
description = "Publish webcam stream '${streamName}' to MediaMTX over RTSP";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
@ -91,14 +209,7 @@ in
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = "2";
|
RestartSec = "2";
|
||||||
ExecStart = ''
|
ExecStart = "${pkgs.ffmpeg}/bin/ffmpeg -hide_banner -loglevel warning -f v4l2 -framerate ${toString streamCfg.framerate} -video_size ${streamCfg.videoSize} -i ${streamCfg.device} ${videoCodecArgs} ${rateControlArgs} -f rtsp ${streamCfg.rtspUrl}";
|
||||||
${pkgs.ffmpeg}/bin/ffmpeg \
|
|
||||||
-hide_banner -loglevel warning \
|
|
||||||
-f v4l2 -framerate ${toString streamCfg.framerate} -video_size ${streamCfg.videoSize} \
|
|
||||||
-i ${streamCfg.device} \
|
|
||||||
-vcodec libx264 -tune zerolatency -preset veryfast \
|
|
||||||
-f rtsp ${streamCfg.rtspUrl}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) effectiveStreams;
|
) effectiveStreams;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue