From 1af7f2c877bf74248c1fd6cbcbfbc785cf49b18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Le=20Calvar?= Date: Sat, 3 Apr 2021 21:22:18 +0200 Subject: [PATCH 1/2] fix size() when using vaapi encoder --- lib/options/videosize.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/options/videosize.js b/lib/options/videosize.js index b175dcd4..90cbd99b 100644 --- a/lib/options/videosize.js +++ b/lib/options/videosize.js @@ -13,10 +13,11 @@ * @param {Number} height output height * @param {Number} aspect video aspect ratio (without padding) * @param {Number} color padding color + * @param {String} scale_filter scale filter name to use * @return scale/pad filters * @private */ -function getScalePadFilters(width, height, aspect, color) { +function getScalePadFilters(width, height, aspect, color, scale_filter) { /* let a be the input aspect ratio, A be the requested aspect ratio @@ -30,7 +31,7 @@ function getScalePadFilters(width, height, aspect, color) { When using computed width/height, we truncate them to multiples of 2 */ { - filter: 'scale', + filter: scale_filter, options: { w: 'if(gt(a,' + aspect + '),' + width + ',trunc(' + height + '*a/2)*2)', h: 'if(lt(a,' + aspect + '),' + height + ',trunc(' + width + '/a/2)*2)' @@ -68,6 +69,7 @@ function getScalePadFilters(width, height, aspect, color) { function createSizeFilters(output, key, value) { // Store parameters var data = output.sizeData = output.sizeData || {}; + var scale_filter = "scale"; data[key] = value; if (!('size' in data)) { @@ -75,6 +77,10 @@ function createSizeFilters(output, key, value) { return []; } + if (output.video.get('-vcodec').length > 1 && output.video.get('-vcodec')[1].endsWith('_vaapi')) { + scale_filter = "scale_vaapi"; + } + // Try to match the different size string formats var fixedSize = data.size.match(/([0-9]+)x([0-9]+)/); var fixedWidth = data.size.match(/([0-9]+)x\?/); @@ -85,7 +91,7 @@ function createSizeFilters(output, key, value) { if (percentRatio) { var ratio = Number(percentRatio[1]) / 100; return [{ - filter: 'scale', + filter: scale_filter, options: { w: 'trunc(iw*' + ratio + '/2)*2', h: 'trunc(ih*' + ratio + '/2)*2' @@ -99,10 +105,10 @@ function createSizeFilters(output, key, value) { aspect = width / height; if (data.pad) { - return getScalePadFilters(width, height, aspect, data.pad); + return getScalePadFilters(width, height, aspect, data.pad, scale_filter); } else { // No autopad requested, rescale to target size - return [{ filter: 'scale', options: { w: width, h: height }}]; + return [{ filter: scale_filter, options: { w: width, h: height }}]; } } else if (fixedWidth || fixedHeight) { if ('aspect' in data) { @@ -115,17 +121,17 @@ function createSizeFilters(output, key, value) { height = Math.round(height / 2) * 2; if (data.pad) { - return getScalePadFilters(width, height, data.aspect, data.pad); + return getScalePadFilters(width, height, data.aspect, data.pad, scale_filter); } else { // No autopad requested, rescale to target size - return [{ filter: 'scale', options: { w: width, h: height }}]; + return [{ filter: scale_filter, options: { w: width, h: height }}]; } } else { // Keep input aspect ratio if (fixedWidth) { return [{ - filter: 'scale', + filter: scale_filter, options: { w: Math.round(Number(fixedWidth[1]) / 2) * 2, h: 'trunc(ow/a/2)*2' @@ -133,7 +139,7 @@ function createSizeFilters(output, key, value) { }]; } else { return [{ - filter: 'scale', + filter: scale_filter, options: { w: 'trunc(oh*a/2)*2', h: Math.round(Number(fixedHeight[1]) / 2) * 2 From e48f622402f2aecb95746914d24761f07d741d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Le=20Calvar?= Date: Sun, 4 Apr 2021 01:11:16 +0200 Subject: [PATCH 2/2] add support for other hardware encoder that do not use scale filter --- lib/options/videosize.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/options/videosize.js b/lib/options/videosize.js index 90cbd99b..3addd195 100644 --- a/lib/options/videosize.js +++ b/lib/options/videosize.js @@ -6,6 +6,23 @@ */ +function getScaleFilter(output) { + if (output.video.get('-vcodec').length > 1) { + let codec = output.video.get('-vcodec')[1]; + + if (codec.endsWith('_vaapi')) { + return 'scale_vaapi'; + } + else if (codec.endsWith('_nvenc')) { + return 'scale_npp'; + } + else if (codec.endsWith('_qsv')) { + return 'scale_qsv'; + } + } + return 'scale'; +} + /** * Return filters to pad video to width*height, * @@ -69,7 +86,7 @@ function getScalePadFilters(width, height, aspect, color, scale_filter) { function createSizeFilters(output, key, value) { // Store parameters var data = output.sizeData = output.sizeData || {}; - var scale_filter = "scale"; + var scale_filter = getScaleFilter(output); data[key] = value; if (!('size' in data)) { @@ -77,10 +94,6 @@ function createSizeFilters(output, key, value) { return []; } - if (output.video.get('-vcodec').length > 1 && output.video.get('-vcodec')[1].endsWith('_vaapi')) { - scale_filter = "scale_vaapi"; - } - // Try to match the different size string formats var fixedSize = data.size.match(/([0-9]+)x([0-9]+)/); var fixedWidth = data.size.match(/([0-9]+)x\?/); @@ -177,7 +190,7 @@ module.exports = function(proto) { proto.keepDAR = function() { return this.videoFilters([ { - filter: 'scale', + filter: getScaleFilter(output), options: { w: 'if(gt(sar,1),iw*sar,iw)', h: 'if(lt(sar,1),ih/sar,ih)'