mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-03 05:34:16 -04:00
Enable Rockchip MJPEG encoder for Trickplay (#12610)
This commit is contained in:
parent
0d85af019c
commit
36d934f4c0
@ -129,7 +129,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
{
|
{
|
||||||
{ HardwareAccelerationType.vaapi, _defaultMjpegEncoder + "_vaapi" },
|
{ HardwareAccelerationType.vaapi, _defaultMjpegEncoder + "_vaapi" },
|
||||||
{ HardwareAccelerationType.qsv, _defaultMjpegEncoder + "_qsv" },
|
{ HardwareAccelerationType.qsv, _defaultMjpegEncoder + "_qsv" },
|
||||||
{ HardwareAccelerationType.videotoolbox, _defaultMjpegEncoder + "_videotoolbox" }
|
{ HardwareAccelerationType.videotoolbox, _defaultMjpegEncoder + "_videotoolbox" },
|
||||||
|
{ HardwareAccelerationType.rkmpp, _defaultMjpegEncoder + "_rkmpp" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly string[] LosslessAudioCodecs =
|
public static readonly string[] LosslessAudioCodecs =
|
||||||
@ -5435,6 +5436,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var isSwDecoder = !isRkmppDecoder;
|
var isSwDecoder = !isRkmppDecoder;
|
||||||
var isSwEncoder = !isRkmppEncoder;
|
var isSwEncoder = !isRkmppEncoder;
|
||||||
var isDrmInDrmOut = isRkmppDecoder && isRkmppEncoder;
|
var isDrmInDrmOut = isRkmppDecoder && isRkmppEncoder;
|
||||||
|
var isEncoderSupportAfbc = isRkmppEncoder
|
||||||
|
&& (vidEncoder.Contains("h264", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| vidEncoder.Contains("hevc", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
|
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
|
||||||
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
|
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
|
||||||
@ -5493,7 +5497,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
{
|
{
|
||||||
// INPUT rkmpp/drm surface(gem/dma-heap)
|
// INPUT rkmpp/drm surface(gem/dma-heap)
|
||||||
|
|
||||||
var isFullAfbcPipeline = isDrmInDrmOut && !doOclTonemap;
|
var isFullAfbcPipeline = isEncoderSupportAfbc && isDrmInDrmOut && !doOclTonemap;
|
||||||
var swapOutputWandH = doRkVppTranspose && swapWAndH;
|
var swapOutputWandH = doRkVppTranspose && swapWAndH;
|
||||||
var outFormat = doOclTonemap ? "p010" : "nv12";
|
var outFormat = doOclTonemap ? "p010" : "nv12";
|
||||||
var hwScalePrefix = doRkVppTranspose ? "vpp" : "scale";
|
var hwScalePrefix = doRkVppTranspose ? "vpp" : "scale";
|
||||||
@ -5531,12 +5535,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
if (doOclTonemap)
|
if (doOclTonemap)
|
||||||
{
|
{
|
||||||
var tonemapFilter = GetHwTonemapFilter(options, "opencl", "nv12");
|
var tonemapFilter = GetHwTonemapFilter(options, "opencl", "nv12");
|
||||||
// enable tradeoffs for performance
|
|
||||||
if (!string.IsNullOrEmpty(tonemapFilter))
|
|
||||||
{
|
|
||||||
tonemapFilter += ":tradeoff=1";
|
|
||||||
}
|
|
||||||
|
|
||||||
mainFilters.Add(tonemapFilter);
|
mainFilters.Add(tonemapFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5607,7 +5605,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
subFilters.Add("hwupload=derive_device=rkmpp");
|
subFilters.Add("hwupload=derive_device=rkmpp");
|
||||||
|
|
||||||
// try enabling AFBC to save DDR bandwidth
|
// try enabling AFBC to save DDR bandwidth
|
||||||
overlayFilters.Add("overlay_rkrga=eof_action=pass:repeatlast=0:format=nv12:afbc=1");
|
var hwOverlayFilter = "overlay_rkrga=eof_action=pass:repeatlast=0:format=nv12";
|
||||||
|
if (isEncoderSupportAfbc)
|
||||||
|
{
|
||||||
|
hwOverlayFilter += ":afbc=1";
|
||||||
|
}
|
||||||
|
|
||||||
|
overlayFilters.Add(hwOverlayFilter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (memoryOutput)
|
else if (memoryOutput)
|
||||||
|
@ -93,7 +93,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
"hevc_videotoolbox",
|
"hevc_videotoolbox",
|
||||||
"mjpeg_videotoolbox",
|
"mjpeg_videotoolbox",
|
||||||
"h264_rkmpp",
|
"h264_rkmpp",
|
||||||
"hevc_rkmpp"
|
"hevc_rkmpp",
|
||||||
|
"mjpeg_rkmpp"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly string[] _requiredFilters = new[]
|
private static readonly string[] _requiredFilters = new[]
|
||||||
|
@ -896,21 +896,30 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
throw new InvalidOperationException("Empty or invalid input argument.");
|
throw new InvalidOperationException("Empty or invalid input argument.");
|
||||||
}
|
}
|
||||||
|
|
||||||
float? encoderQuality = qualityScale;
|
// ffmpeg qscale is a value from 1-31, with 1 being best quality and 31 being worst
|
||||||
if (vidEncoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase))
|
// jpeg quality is a value from 0-100, with 0 being worst quality and 100 being best
|
||||||
|
var encoderQuality = Math.Clamp(qualityScale ?? 4, 1, 31);
|
||||||
|
var encoderQualityOption = "-qscale:v ";
|
||||||
|
|
||||||
|
if (vidEncoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| vidEncoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// vaapi's mjpeg encoder uses jpeg quality divided by QP2LAMBDA (118) as input, instead of ffmpeg defined qscale
|
// vaapi and qsv's mjpeg encoder use jpeg quality as input, instead of ffmpeg defined qscale
|
||||||
// ffmpeg qscale is a value from 1-31, with 1 being best quality and 31 being worst
|
encoderQuality = 100 - ((encoderQuality - 1) * (100 / 30));
|
||||||
// jpeg quality is a value from 0-100, with 0 being worst quality and 100 being best
|
encoderQualityOption = "-global_quality:v ";
|
||||||
encoderQuality = (100 - ((qualityScale - 1) * (100 / 30))) / 118;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vidEncoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase))
|
if (vidEncoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// videotoolbox's mjpeg encoder uses jpeg quality scaled to QP2LAMBDA (118) instead of ffmpeg defined qscale
|
// videotoolbox's mjpeg encoder uses jpeg quality scaled to QP2LAMBDA (118) instead of ffmpeg defined qscale
|
||||||
// ffmpeg qscale is a value from 1-31, with 1 being best quality and 31 being worst
|
encoderQuality = 118 - ((encoderQuality - 1) * (118 / 30));
|
||||||
// jpeg quality is a value from 0-100, with 0 being worst quality and 100 being best
|
}
|
||||||
encoderQuality = 118 - ((qualityScale - 1) * (118 / 30));
|
|
||||||
|
if (vidEncoder.Contains("rkmpp", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// rkmpp's mjpeg encoder uses jpeg quality as input (max is 99, not 100), instead of ffmpeg defined qscale
|
||||||
|
encoderQuality = 99 - ((encoderQuality - 1) * (99 / 30));
|
||||||
|
encoderQualityOption = "-qp_init:v ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output arguments
|
// Output arguments
|
||||||
@ -926,7 +935,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
filterParam,
|
filterParam,
|
||||||
outputThreads.GetValueOrDefault(_threads),
|
outputThreads.GetValueOrDefault(_threads),
|
||||||
vidEncoder,
|
vidEncoder,
|
||||||
qualityScale.HasValue ? "-qscale:v " + encoderQuality.Value.ToString(CultureInfo.InvariantCulture) + " " : string.Empty,
|
encoderQualityOption + encoderQuality + " ",
|
||||||
vidEncoder.Contains("videotoolbox", StringComparison.InvariantCultureIgnoreCase) ? "-allow_sw 1 " : string.Empty, // allow_sw fallback for some intel macs
|
vidEncoder.Contains("videotoolbox", StringComparison.InvariantCultureIgnoreCase) ? "-allow_sw 1 " : string.Empty, // allow_sw fallback for some intel macs
|
||||||
"image2",
|
"image2",
|
||||||
outputPath);
|
outputPath);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user