Added HDR support, Cleaned up info log & initial test fix

- Added HDR support. Tested as working but can have issues. Warning applied
- Made duration check a bit better with try statement
- Cleaned up how the info log was used so it's more consistent & fixed up trailing spaces & line breaks
- Initial test fix up but more will be needed
make-only-subtitle-default
Boosh1 2 years ago
parent 890c2642e1
commit 03d8a75033

@ -357,8 +357,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
if (strstreamType === 'video') { if (strstreamType === 'video') {
if (file.ffProbeData.streams[i].codec_name !== 'mjpeg' if (file.ffProbeData.streams[i].codec_name !== 'mjpeg'
&& file.ffProbeData.streams[i].codec_name !== 'png') { && file.ffProbeData.streams[i].codec_name !== 'png') {
// Try checking file stats using Mediainfo first, then ffprobe. if (videoBR <= 0) { // Process if videoBR is not yet valid
try { try { // Try checking file stats using Mediainfo first, then ffprobe.
videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000;
if (videoBR <= 0 || Number.isNaN(videoBR)) { if (videoBR <= 0 || Number.isNaN(videoBR)) {
if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) {
@ -371,22 +371,33 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
// Catch error - Ignore & carry on - If check can bomb out if tags don't exist... // Catch error - Ignore & carry on - If check can bomb out if tags don't exist...
videoBR = 0; // Set videoBR to 0 for safety videoBR = 0; // Set videoBR to 0 for safety
} }
// Check if duration info is filled, if so convert time format to minutes. }
if (Number.isNaN(file.meta.Duration) === false) { if (duration <= 0) { // Process if duration is not yet valid
// If duration is a number then convert seconds to minutes try { // Attempt to get duration info
duration = file.meta.Duration / 60; if (Number.isNaN(file.meta.Duration)) {
} else if (typeof file.meta.Duration !== 'undefined') {
// Get seconds by using a Date & then convert to minutes
duration = file.meta.Duration; duration = file.meta.Duration;
duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60;
} else { // If not filled then get duration of video stream and do the same. } else if (file.meta.Duration > 0) {
duration = file.meta.Duration / 60;
}
if (duration <= 0 || Number.isNaN(duration)) {
if (typeof file.mediaInfo.track[i + 1].Duration !== 'undefined') {
duration = file.mediaInfo.track[i + 1].Duration;
duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60;
} else if (typeof file.ffProbeData.streams[i].tags.DURATION !== 'undefined') {
duration = file.ffProbeData.streams[i].tags.DURATION; duration = file.ffProbeData.streams[i].tags.DURATION;
duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60;
} }
if (videoBR <= 0 || Number.isNaN(videoBR)) { }
// videoBR not yet valid so Loop } catch (err) {
// Catch error - Ignore & carry on - If check can bomb out if tags don't exist...
duration = 0; // Set duration to 0 for safety
}
}
if ((videoBR <= 0 || Number.isNaN(videoBR)) || (duration <= 0 || Number.isNaN(duration))) {
// videoBR or duration not yet valid so Loop
} else { } else {
break;// Exit loop if videoBR is valid break;// Exit loop if both valid
} }
} }
} }
@ -395,9 +406,9 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
if (Number.isNaN(videoBR) || videoBR <= 0) { if (Number.isNaN(videoBR) || videoBR <= 0) {
// Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" // Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)"
currentBitrate = Math.round(file.file_size / (duration * 0.0075)); currentBitrate = Math.round(file.file_size / (duration * 0.0075));
response.infoLog += '==WARNING== Failed to get an accurate video bitrate, '; response.infoLog += '==WARNING== Failed to get an accurate video bitrate, '
response.infoLog += `falling back to old method to get OVERALL file bitrate of ${currentBitrate}kbps. `; + `falling back to old method to get OVERALL file bitrate of ${currentBitrate}kbps. `
response.infoLog += 'Bitrate calculations for video encode will likely be inaccurate... \n'; + 'Bitrate calculations for video encode will likely be inaccurate...\n';
} else { } else {
currentBitrate = Math.round(videoBR); currentBitrate = Math.round(videoBR);
response.infoLog += `☑ It looks like the current video bitrate is ${currentBitrate}kbps.\n`; response.infoLog += `☑ It looks like the current video bitrate is ${currentBitrate}kbps.\n`;
@ -414,8 +425,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
// If targetBitrate or currentBitrate comes out as 0 then something // If targetBitrate or currentBitrate comes out as 0 then something
// has gone wrong and bitrates could not be calculated. // has gone wrong and bitrates could not be calculated.
// Cancel plugin completely. // Cancel plugin completely.
if (targetBitrate <= 0 || currentBitrate <= 0) { if (targetBitrate <= 0 || currentBitrate <= 0 || overallBitRate <= 0) {
response.infoLog += '☒ Target bitrate could not be calculated. Skipping this plugin. \n'; response.infoLog += '☒ Target bitrates could not be calculated. Skipping this plugin.\n';
return response; return response;
} }
@ -423,17 +434,16 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
// has gone wrong as that is not what we want. // has gone wrong as that is not what we want.
// Cancel plugin completely. // Cancel plugin completely.
if (targetBitrate >= currentBitrate) { if (targetBitrate >= currentBitrate) {
response.infoLog += `☒ Target bitrate has been calculated as ${targetBitrate}kbps. This is equal or greater `; response.infoLog += `☒ Target bitrate has been calculated as ${targetBitrate}kbps. This is equal or greater than `
response.infoLog += "than the current bitrate... Something has gone wrong and this shouldn't happen! " + "the current bitrate... Something has gone wrong and this shouldn't happen! Skipping this plugin.\n";
+ 'Skipping this plugin. \n';
return response; return response;
} }
// Ensure that bitrate_cutoff is set if reconvert_hevc is true since we need some protection against a loop // Ensure that bitrate_cutoff is set if reconvert_hevc is true since we need some protection against a loop
// Cancel the plugin // Cancel the plugin
if (inputs.reconvert_hevc === true && inputs.bitrate_cutoff <= 0 && inputs.hevc_max_bitrate <= 0) { if (inputs.reconvert_hevc === true && inputs.bitrate_cutoff <= 0 && inputs.hevc_max_bitrate <= 0) {
response.infoLog += `Reconvert HEVC is ${inputs.reconvert_hevc}, however there is no bitrate cutoff `; response.infoLog += `Reconvert HEVC is ${inputs.reconvert_hevc}, however there is no bitrate cutoff or HEVC `
response.infoLog += 'or HEVC specific cutoff set so we have no way to know when to stop processing this file. \n' + 'specific cutoff set so we have no way to know when to stop processing this file.\n'
+ 'Either set reconvert_HEVC to false or set a bitrate cutoff and set a hevc_max_bitrate cutoff.\n' + 'Either set reconvert_HEVC to false or set a bitrate cutoff and set a hevc_max_bitrate cutoff.\n'
+ '☒ Skipping this plugin.\n'; + '☒ Skipping this plugin.\n';
return response; return response;
@ -459,8 +469,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
// Checks if targetBitrate is above inputs.max_average_bitrate. // Checks if targetBitrate is above inputs.max_average_bitrate.
// If so then clamp target bitrate // If so then clamp target bitrate
if (targetBitrate > inputs.max_average_bitrate) { if (targetBitrate > inputs.max_average_bitrate) {
response.infoLog += 'Our target bitrate is above the max_average_bitrate '; response.infoLog += 'Our target bitrate is above the max_average_bitrate so clamping at max of '
response.infoLog += `so clamping at max of ${inputs.max_average_bitrate}kbps. \n`; + `${inputs.max_average_bitrate}kbps.\n`;
targetBitrate = Math.round(inputs.max_average_bitrate); targetBitrate = Math.round(inputs.max_average_bitrate);
minimumBitrate = Math.round(targetBitrate * 0.75); minimumBitrate = Math.round(targetBitrate * 0.75);
maximumBitrate = Math.round(targetBitrate * 1.25); maximumBitrate = Math.round(targetBitrate * 1.25);
@ -472,8 +482,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
if (inputs.min_average_bitrate > 0) { if (inputs.min_average_bitrate > 0) {
// Exit the plugin is the cutoff is less than the min average bitrate. Most likely user error // Exit the plugin is the cutoff is less than the min average bitrate. Most likely user error
if (inputs.bitrate_cutoff < inputs.min_average_bitrate) { if (inputs.bitrate_cutoff < inputs.min_average_bitrate) {
response.infoLog += `☒ Bitrate cutoff ${inputs.bitrate_cutoff}k is less than the set minimum response.infoLog += `☒ Bitrate cutoff ${inputs.bitrate_cutoff}k is less than the set minimum `
average bitrate set of ${inputs.min_average_bitrate}kbps. We don't want this. Cancelling plugin. \n`; + `average bitrate set of ${inputs.min_average_bitrate}kbps. We don't want this. Cancelling plugin.\n`;
return response; return response;
} }
// Checks if inputs.bitrate_cutoff is below inputs.min_average_bitrate. // Checks if inputs.bitrate_cutoff is below inputs.min_average_bitrate.
@ -540,13 +550,27 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
if (file.ffProbeData.streams[i].codec_name === 'mjpeg' || file.ffProbeData.streams[i].codec_name === 'png') { if (file.ffProbeData.streams[i].codec_name === 'mjpeg' || file.ffProbeData.streams[i].codec_name === 'png') {
extraArguments += `-map -0:v:${videoIdx} `; extraArguments += `-map -0:v:${videoIdx} `;
} else { // Ensure to only do further checks if video stream is valid for use } else { // Ensure to only do further checks if video stream is valid for use
// Check for HDR in files. If so exit plugin. HDR can be complicated // Check for HDR in files. Attempt to use same color
// and some aspects are still unsupported in ffmpeg I believe. Likely we don't want to re-encode anything HDR. if ((file.ffProbeData.streams[i].color_space === 'bt2020nc'
if (file.ffProbeData.streams[i].color_space === 'bt2020nc' || file.ffProbeData.streams[i].color_space === 'bt2020n')
&& file.ffProbeData.streams[i].color_transfer === 'smpte2084' && (file.ffProbeData.streams[i].color_transfer === 'smpte2084'
|| file.ffProbeData.streams[i].color_transfer === 'arib-std-b67')
&& file.ffProbeData.streams[i].color_primaries === 'bt2020') { && file.ffProbeData.streams[i].color_primaries === 'bt2020') {
response.infoLog += '☒ This looks to be a HDR file. HDR files are unfortunately ' response.infoLog += '==WARNING== This looks to be a HDR file. HDR is supported but '
+ 'not supported by this plugin. Exiting plugin. \n\n'; + 'correct encoding is not guaranteed.\n';
extraArguments += `-color_primaries ${file.ffProbeData.streams[i].color_primaries} `
+ `-color_trc ${file.ffProbeData.streams[i].color_transfer} `
+ `-colorspace ${file.ffProbeData.streams[i].color_space} `;
}
// Check if codec of stream is HEVC, Vp9 or AV1
// AND check if file.container does NOT match inputs.container. If so remux file.
if ((file.ffProbeData.streams[i].codec_name === 'hevc'
|| file.ffProbeData.streams[i].codec_name === 'vp9'
|| file.ffProbeData.streams[i].codec_name === 'av1') && file.container !== inputs.container) {
response.infoLog += `☒ File is HEVC, VP9 or AV1 but is not in ${inputs.container} container. Remuxing.\n`;
response.preset = `<io> -map 0 -c copy ${extraArguments}`;
response.processFile = true;
return response; return response;
} }
@ -561,17 +585,6 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
return response; return response;
} }
// Check if codec of stream is HEVC, Vp9 or AV1
// AND check if file.container does NOT match inputs.container.
// If so remux file.
if ((file.ffProbeData.streams[i].codec_name === 'hevc' || file.ffProbeData.streams[i].codec_name === 'vp9'
|| file.ffProbeData.streams[i].codec_name === 'av1') && file.container !== inputs.container) {
response.infoLog += `☒ File is HEVC, VP9 or AV1 but is not in ${inputs.container} container. Remuxing. \n`;
response.preset = `<io> -map 0 -c copy ${extraArguments}`;
response.processFile = true;
return response;
}
// New logic for reprocessing HEVC. Mainly done for my own use. // New logic for reprocessing HEVC. Mainly done for my own use.
// We attempt to get accurate stats earlier - If we can't we fall back onto overall bitrate // We attempt to get accurate stats earlier - If we can't we fall back onto overall bitrate
// which can be inaccurate. We may inflate the current bitrate check so we don't keep looping this logic. // which can be inaccurate. We may inflate the current bitrate check so we don't keep looping this logic.
@ -580,14 +593,14 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
if (inputs.hevc_max_bitrate > 0) { if (inputs.hevc_max_bitrate > 0) {
if (currentBitrate > inputs.hevc_max_bitrate) { if (currentBitrate > inputs.hevc_max_bitrate) {
// If bitrate is higher then hevc_max_bitrate then need to re-encode // If bitrate is higher then hevc_max_bitrate then need to re-encode
response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, ` response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. `
+ `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; + `Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps.\n`
response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; + '☒ The file is still above this new cutoff! Reconverting.\n';
} else { } else {
// Otherwise we're now below the hevc cutoff and we can exit // Otherwise we're now below the hevc cutoff and we can exit
response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, ` response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. `
+ `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; + `Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps.\n`
response.infoLog += '☑ The file is NOT above this new cutoff. Exiting plugin. \n'; + '☑ The file is NOT above this new cutoff. Exiting plugin.\n';
return response; return response;
} }
@ -595,21 +608,19 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
// looping this plugin. For maximum safety we simply multiply the cutoff by 2. // looping this plugin. For maximum safety we simply multiply the cutoff by 2.
} else if (currentBitrate > (inputs.bitrate_cutoff * 2)) { } else if (currentBitrate > (inputs.bitrate_cutoff * 2)) {
inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2); inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2);
response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, `; response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. `
response.infoLog += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; + `Will use Overall file Bitrate for HEVC files as safety, bitrate is ${overallBitRate}kbps.\n`
response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; + 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety!\n'
response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; + `Cutoff now temporarily ${inflatedCutoff}kbps.\n`
response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; + '☒ The file is still above this new cutoff! Reconverting.\n';
response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n';
} else { } else {
// File is below cutoff so we can exit // File is below cutoff so we can exit
inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2); inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2);
response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, `; response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. `
response.infoLog += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; + `Will use Overall file Bitrate for HEVC files as safety, bitrate is ${overallBitRate}kbps.\n`
response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; + 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety!\n'
response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; + `Cutoff now temporarily ${inflatedCutoff}kbps.\n`
response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; + '☑The file is NOT above this new cutoff. Exiting plugin.\n';
response.infoLog += '☑The file is NOT above this new cutoff. Exiting plugin. \n';
return response; return response;
} }
} }
@ -649,8 +660,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
break; break;
case 'h264': case 'h264':
if (high10 === true) { if (high10 === true) {
response.infoLog += `Input file is ${file.video_codec_name} High10. Hardware Decode not supported. \n`;
swDecode = true; swDecode = true;
response.infoLog += 'Input file is h264 High10. Hardware Decode not supported.\n';
} }
break; break;
case 'mjpeg': case 'mjpeg':
@ -693,11 +704,11 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k ` bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k `
+ `-maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`; + `-maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`;
// Print to infoLog information around file & bitrate settings. // Print to infoLog information around file & bitrate settings.
response.infoLog += `Container for output selected as ${inputs.container}. \n`; response.infoLog += `Container for output selected as ${inputs.container}.\n`
response.infoLog += 'Encode variable bitrate settings: \n'; + 'Encode variable bitrate settings:\n'
response.infoLog += `Target = ${targetBitrate}k \n`; + `Target = ${targetBitrate}k\n`
response.infoLog += `Minimum = ${minimumBitrate}k \n`; + `Minimum = ${minimumBitrate}k\n`
response.infoLog += `Maximum = ${maximumBitrate}k \n`; + `Maximum = ${maximumBitrate}k\n`;
// START PRESET // START PRESET
// -fflags +genpts should regenerate timestamps if they end up missing... // -fflags +genpts should regenerate timestamps if they end up missing...
@ -712,12 +723,12 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
response.preset += '-hwaccel videotoolbox'; response.preset += '-hwaccel videotoolbox';
break; break;
case 'linux': // Linux - Full device, should fix child_device_type warnings case 'linux': // Linux - Full device, should fix child_device_type warnings
response.preset += `-hwaccel qsv -hwaccel_output_format qsv response.preset += '-hwaccel qsv -hwaccel_output_format qsv '
-init_hw_device qsv:hw_any,child_device_type=vaapi `; + '-init_hw_device qsv:hw_any,child_device_type=vaapi ';
break; break;
case 'win32': // Windows - Full device, should fix child_device_type warnings case 'win32': // Windows - Full device, should fix child_device_type warnings
response.preset += `-hwaccel qsv -hwaccel_output_format qsv response.preset += '-hwaccel qsv -hwaccel_output_format qsv '
-init_hw_device qsv:hw,child_device_type=d3d11va `; + '-init_hw_device qsv:hw,child_device_type=d3d11va ';
break; break;
default: default:
response.preset += '-hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any '; response.preset += '-hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any ';
@ -728,12 +739,12 @@ const plugin = (file, librarySettings, inputs, otherArguments) => {
response.preset += '-hwaccel videotoolbox'; response.preset += '-hwaccel videotoolbox';
break; break;
case 'linux': // Linux - Full device, should fix child_device_type warnings case 'linux': // Linux - Full device, should fix child_device_type warnings
response.preset += `-hwaccel_output_format qsv response.preset += '-hwaccel_output_format qsv '
-init_hw_device qsv:hw_any,child_device_type=vaapi `; + '-init_hw_device qsv:hw_any,child_device_type=vaapi ';
break; break;
case 'win32': // Windows - Full device, should fix child_device_type warnings case 'win32': // Windows - Full device, should fix child_device_type warnings
response.preset += `-hwaccel_output_format qsv response.preset += '-hwaccel_output_format qsv '
-init_hw_device qsv:hw,child_device_type=d3d11va `; + '-init_hw_device qsv:hw,child_device_type=d3d11va ';
break; break;
default: default:
// Default to enabling hwaccel for output only // Default to enabling hwaccel for output only

@ -14,8 +14,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -30,8 +29,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -78,8 +76,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f mp4 -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f mp4 -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -95,8 +92,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f mp4 -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f mp4 -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -149,8 +145,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=vaapi -c:v h264<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
+ ' -init_hw_device qsv:hw,child_device_type=vaapi -c:v h264<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -167,8 +162,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -226,8 +220,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n' infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n'
@ -244,8 +237,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -337,8 +329,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:3 -map -0:4 -map -0:5 -map -0:6 -f mp4 -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:3 -map -0:4 -map -0:5 -map -0:6 -f mp4 -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -353,8 +344,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:3 -map -0:4 -map -0:5 -map -0:6 -f mp4 -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:3 -map -0:4 -map -0:5 -map -0:6 -f mp4 -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -405,8 +395,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:d -map -0:3 -map -0:4 -map -0:5 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:d -map -0:3 -map -0:4 -map -0:5 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -421,8 +410,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:d -map -0:3 -map -0:4 -map -0:5 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -map -0:d -map -0:3 -map -0:4 -map -0:5 -f matroska -vf hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -468,8 +456,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -look_ahead 1 -look_ahead_depth 100 -extbrc 1 -rdo 1 -mbbrc 1 -b_strategy 1 -adaptive_i 1 -adaptive_b 1 -vf scale_qsv=1280:-1,format=p010le,hwupload=extra_hw_frames=64,format=qsv -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -look_ahead 1 -look_ahead_depth 100 -extbrc 1 -rdo 1 -mbbrc 1 -b_strategy 1 -adaptive_i 1 -adaptive_b 1 -vf scale_qsv=1280:-1,format=p010le,hwupload=extra_hw_frames=64,format=qsv -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -485,8 +472,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -look_ahead 1 -look_ahead_depth 100 -extbrc 1 -rdo 1 -mbbrc 1 -b_strategy 1 -adaptive_i 1 -adaptive_b 1 -vf scale_qsv=1280:-1,format=p010le,hwupload=extra_hw_frames=64,format=qsv -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -look_ahead 1 -look_ahead_depth 100 -extbrc 1 -rdo 1 -mbbrc 1 -b_strategy 1 -adaptive_i 1 -adaptive_b 1 -vf scale_qsv=1280:-1,format=p010le,hwupload=extra_hw_frames=64,format=qsv -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -539,8 +525,7 @@ const tests = [
output: { output: {
linux: { linux: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v vc1<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
+ ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v vc1<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n'
@ -556,8 +541,7 @@ const tests = [
}, },
win32: { win32: {
processFile: true, processFile: true,
preset: '-fflags +genpts -hwaccel_output_format qsv \n' preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v vc1<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
+ ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v vc1<io> -map 0 -c:v hevc_qsv -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10 -pix_fmt p010le ',
handBrakeMode: false, handBrakeMode: false,
FFmpegMode: true, FFmpegMode: true,
reQueueAfter: true, reQueueAfter: true,
@ -592,5 +576,82 @@ const tests = [
}, },
}, },
}, },
// Test 9
{
input: {
file: (() => {
const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json'));
file.ffProbeData.streams[0].color_space = 'bt2020nc';
file.ffProbeData.streams[0].color_transfer = 'smpte2084';
file.ffProbeData.streams[0].color_primaries = 'bt2020';
file.mediaInfo.track[1].BitRate = 12000000;
file.ffProbeData.streams[0].profile = 'Main 10';
return file;
})(),
librarySettings: {},
inputs: {
container: 'mkv',
encoder_speedpreset: 'fast',
reconvert_hevc: 'true',
hevc_max_bitrate: '6000',
bitrate_cutoff: '4000',
},
otherArguments: {},
},
output: {
linux: {
processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
FFmpegMode: true,
reQueueAfter: true,
infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n'
+ '==WARNING== This looks to be a HDR file. HDR is supported but correct encoding is not guaranteed.\n'
+ '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n'
+ 'Container for output selected as mkv.\n'
+ 'Encode variable bitrate settings:\n'
+ 'Target = 6000k\n'
+ 'Minimum = 4500k\n'
+ 'Maximum = 7500k\n'
+ 'File Transcoding...\n',
container: '.mkv',
},
win32: {
processFile: true,
preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv<io> -map 0 -c:v hevc_qsv -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc -f matroska -profile:v main10 -vf scale_qsv=format=p010le,hwupload=extra_hw_frames=64,format=qsv ',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n'
+ '==WARNING== This looks to be a HDR file. HDR is supported but correct encoding is not guaranteed.\n'
+ '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n'
+ 'Container for output selected as mkv.\n'
+ 'Encode variable bitrate settings:\n'
+ 'Target = 6000k\n'
+ 'Minimum = 4500k\n'
+ 'Maximum = 7500k\n'
+ 'File Transcoding...\n',
container: '.mkv',
},
darwin: {
processFile: true,
preset: '-fflags +genpts <io> -map 0 -c:v hevc_videotoolbox -b:v 6000k -minrate 4500k -maxrate 7500k -bufsize 12000k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc -f matroska -profile:v main10 -vf scale_qsv=format=p010le',
handBrakeMode: false,
FFmpegMode: true,
reQueueAfter: true,
infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n'
+ '==WARNING== This looks to be a HDR file. HDR is supported but correct encoding is not guaranteed.\n'
+ '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n'
+ 'Container for output selected as mkv.\n'
+ 'Encode variable bitrate settings:\n'
+ 'Target = 6000k\n'
+ 'Minimum = 4500k\n'
+ 'Maximum = 7500k\n'
+ '==ALERT== OS detected as MAC - This will use VIDEOTOOLBOX to encode which is NOT QSV\n'
+ 'cmds set in extra_qsv_options will be IGNORED!\n'
+ 'File Transcoding...\n',
container: '.mkv',
},
},
},
]; ];
void run(tests); void run(tests);

Loading…
Cancel
Save