From 9494a2fcad60357d1c54b0af76717db4e11e4fb6 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:48:41 +0000 Subject: [PATCH 01/14] Added new tests & also fixed up a few issues - Added check to ensure video bitrate is actually a number - Updated QSV decoders since VC1 & VP8 aren't supported on latest hardware (according to wikipedia...) & AV1 added - Added new video codec check which enables protection for 10 bit encoding, basically trying to encode from something like mpeg4 into 10bit could cause issues --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 68 +-- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 423 +++++++++++++++++- 2 files changed, 460 insertions(+), 31 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index c21d1ee..2720d0a 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -28,11 +28,8 @@ const details = () => ({ true. If it is then these will be reconverted again if they exceed the bitrate specified in "hevc_max_bitrate". This plugin will also attempt to use mkvpropedit to generate accurate bitrate metadata in MKV files. It's not required to enable mkvpropedit but highly recommended to ensure accurate bitrates are used when - encoding your media. - \n\n==NOTE== Intel ARC cards are reportedly working successfully with this plugin, however please bare in mind that - I've not officially tested with them yet and your results might vary. Don't just assume it will work and if it does - ensure you properly test your files & workflow!`, - Version: '1.2', + encoding your media.`, + Version: '1.21', Tags: 'pre-processing,ffmpeg,video only,qsv,h265,hevc,mkvpropedit,configurable', Inputs: [ { @@ -330,10 +327,9 @@ let bitrateSettings = ''; let inflatedCutoff = 0; let main10 = false; let high10 = false; +let oldFormat = false; let videoBR = 0; -// Finds the first video stream and get video bitrate - // eslint-disable-next-line @typescript-eslint/no-unused-vars const plugin = (file, librarySettings, inputs, otherArguments) => { const lib = require('../methods/lib')(); @@ -390,8 +386,10 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Strings for easy to read dates in info log let statsThresString = new Date(statsThres); statsThresString = statsThresString.toUTCString(); + statsThresString = `${statsThresString.slice(0, 22)}:00 GMT`; let datStatsString = new Date(datStats); datStatsString = datStatsString.toUTCString(); + datStatsString = `${datStatsString.slice(0, 22)}:00 GMT`; response.infoLog += `Checking file stats - If stats are older than ${intStatsDays} days we'll grab new stats.\n Stats threshold: ${statsThresString}\n Current stats date: ${datStatsString}\n`; @@ -437,7 +435,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; // If MediaInfo fails somehow fallback to ffprobe - Try two types of tags that might exist - if (videoBR <= 0) { + if (videoBR <= 0 || Number.isNaN(videoBR)) { if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; } else { @@ -450,20 +448,21 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } } } + // Check if duration info is filled, if so convert time format to minutes. + if (Number.isNaN(file.meta.Duration) === false) { + // If duration is a number then convert seconds to minutes + duration = file.meta.Duration / 60; + } else if (typeof file.meta.Duration !== 'undefined') { + // Get seconds by using a Date & then convert to minutes + duration = file.meta.Duration; + 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. + duration = file.ffProbeData.streams[videoIdx].tags.DURATION; + duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; + } } } - // Check if duration info is filled, if so convert time format to minutes. - // If not filled then get duration of video stream and do the same. - if (typeof file.meta.Duration !== 'undefined') { - duration = file.meta.Duration; - // Get seconds by using a Date & then convert to minutes - duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; - } else { - duration = file.ffProbeData.streams[videoIdx].tags.DURATION; - duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; - } - if (Number.isNaN(videoBR) || videoBR <= 0) { // Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" currentBitrate = Math.round(file.file_size / (duration * 0.0075)); @@ -710,8 +709,28 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } } + // Some video codecs won't play nice with 10 bit via QSV, whitelist safe ones here + switch (file.video_codec_name) { + case 'mpeg2': + break; + case 'h264': + break; + case 'mjpeg': + break; + case 'hevc': + break; + case 'vp9': + break; + case 'av1': + break; + default: + oldFormat = true; + } + // Are we encoding to 10 bit? If so enable correct profile & pixel format. - if (high10 === true) { // This is used if we have High10 files. SW decode and use standard -pix_fmt p010le + if (high10 === true || (oldFormat === true && main10 === true)) { + // This is used if we have High10 or Main10 is enabled & odd format files. + // SW decode and use standard -pix_fmt p010le extraArguments += '-profile:v main10 -pix_fmt p010le '; response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; } else if (main10 === true) { // Pixel formate method when using HW decode @@ -764,21 +783,18 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { case 'h264': response.preset += '-c:v h264_qsv'; break; - case 'vc1': - response.preset += '-c:v vc1_qsv'; - break; case 'mjpeg': response.preset += '-c:v mjpeg_qsv'; break; - case 'vp8': - response.preset += '-c:v vp8_qsv'; - break; case 'hevc': response.preset += '-c:v hevc_qsv'; break; case 'vp9': // Should be supported by 8th Gen + response.preset += '-c:v vp9_qsv'; break; + case 'av1': // Should be supported by 11th gen + + response.preset += '-c:v av1_qsv'; + break; default: response.preset += ''; } diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 14c7734..637f179 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -2,7 +2,14 @@ const _ = require('lodash'); const run = require('../helpers/run'); +// Date stuff for mkvpropedit +const intStatsDays = 7; // Use 1 week threshold for new stats +let statsThresString = new Date(new Date().setDate(new Date().getDate() - intStatsDays)).toUTCString(); +statsThresString = `${statsThresString.slice(0, 22)}:00 GMT`; +let datStatsString = new Date().toUTCString(); +datStatsString = `${datStatsString.slice(0, 22)}:00 GMT`; const tests = [ + // Test 0 { input: { file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), @@ -65,6 +72,7 @@ const tests = [ }, }, }, + // Test 1 { input: { file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), @@ -134,15 +142,245 @@ const tests = [ }, }, }, + // Test 2 { input: { - file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.ffProbeData.streams[0].profile = 'High 10'; + file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); + return file; + })(), + librarySettings: {}, + inputs: { + container: 'mkv', + encoder_speedpreset: 'fast', + }, + otherArguments: {}, + }, + output: { + linux: { + processFile: true, + preset: '-fflags +genpts -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 -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \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 = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \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 = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \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 = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \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', + }, + }, + }, + // Test 3 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.mediaInfo.track[1].BitRate = 12059590; + file.ffProbeData.streams[0].profile = 'Main 10'; + file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); + 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 \n' + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 12060kbps. \n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' + + 'Minimum = 4523k \n' + + 'Maximum = 7538k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 12060kbps. \n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' + + 'Minimum = 4523k \n' + + 'Maximum = 7538k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 12060kbps. \n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' + + 'Minimum = 4523k \n' + + 'Maximum = 7538k \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', + }, + }, + }, + // Test 4 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.mediaInfo.track[1].BitRate = 5000000; + file.ffProbeData.streams[0].profile = 'Main 10'; + file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); + return file; + })(), + librarySettings: {}, + inputs: { + container: 'mkv', + encoder_speedpreset: 'fast', + reconvert_hevc: 'true', + hevc_max_bitrate: '6000', + bitrate_cutoff: '4000', + }, + otherArguments: {}, + }, + output: { + processFile: false, + preset: '', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 5000kbps. \n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + + '☑ The file is NOT above this new cutoff. Exiting plugin. \n', + container: '.mkv', + }, + }, + // Test 5 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); + file.container = 'mp4'; + return file; + })(), librarySettings: {}, inputs: { container: 'mp4', encoder_speedpreset: 'fast', - enable_10bit: 'true', - bitrate_cutoff: '2000', + bitrate_cutoff: '3500', }, otherArguments: {}, }, @@ -153,12 +391,187 @@ const tests = [ FFmpegMode: true, reQueueAfter: true, infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' - + '☑ Current bitrate is below set cutoff of 2000kbps. \n' + + '==WARNING== Failed to get an accurate video bitrate, falling back to old method to get OVERALL file bitrate of 3059kbps. Bitrate calculations for video encode will likely be inaccurate... \n' + + '☑ Current bitrate is below set cutoff of 3500kbps. \n' + 'Cancelling plugin. \n', container: '.mp4', }, }, + // Test 6 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); + file.ffProbeData.streams[3].codec_name = 'hdmv_pgs_subtitle'; + file.ffProbeData.streams[4].codec_name = 'eia_608'; + file.ffProbeData.streams[5].codec_name = 'subrip'; + file.ffProbeData.streams[6].codec_name = 'timed_id3'; + return file; + })(), + librarySettings: {}, + inputs: { + container: 'mp4', + encoder_speedpreset: 'fast', + force_conform: 'true', + }, + otherArguments: {}, + }, + output: { + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mp4. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mp4', + }, + }, + }, + // Test 7 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); + file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); + file.ffProbeData.streams[3].codec_name = 'mov_text'; + file.ffProbeData.streams[4].codec_name = 'eia_608'; + file.ffProbeData.streams[5].codec_name = 'timed_id3'; + return file; + })(), + librarySettings: {}, + inputs: { + container: 'mkv', + encoder_speedpreset: 'fast', + force_conform: 'true', + }, + otherArguments: {}, + }, + output: { + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" + + '\n' + + ` Stats threshold: ${statsThresString}\n` + + '\n' + + ` Current stats date: ${datStatsString}\n` + + '☑ File stats are upto date! - Continuing...\n' + + '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + }, + }, ]; void run(tests); From c7c47a16b0978bcc8793a7d1d678ac69baf88f53 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:27:15 +0000 Subject: [PATCH 02/14] Updated with better hw control - Removed mkvpropedit remux behaviour - No longer seems to be needed (It's upto the user to have the mkvpropedit option enabled on Tdarr side) - Corrected parts of the ffmpeg cmd to define the output format based on container - Updated win32 hwaccel cmd to use a more correct type - Enabled hwupload & hwupload frames --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 131 ++++++------------ 1 file changed, 44 insertions(+), 87 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 2720d0a..234696e 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -334,7 +334,6 @@ let videoBR = 0; const plugin = (file, librarySettings, inputs, otherArguments) => { const lib = require('../methods/lib')(); const os = require('os'); - const proc = require('child_process'); // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign inputs = lib.loadDefaultValues(inputs, details); const response = { @@ -353,79 +352,6 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { return response; } - // MKVPROPEDIT - Refresh video stats - const intStatsDays = 7; // Use 1 week threshold for new stats - let statsUptoDate = false; - const currentFileName = file._id; - let statsError = false; - let metadataEncode = ''; - - // Only process MKV files - if (file.container === 'mkv') { - let datStats = Date.parse(new Date(70, 1).toISOString()); // Placeholder date - metadataEncode = `-map_metadata:g -1 -metadata JBDONEDATE=${datStats}`; - if (file.mediaInfo.track[0].extra !== undefined && file.mediaInfo.track[0].extra.JBDONEDATE !== undefined) { - datStats = Date.parse(file.mediaInfo.track[0].extra.JBDONEDATE); - } else { - try { - if ( - file.mediaInfo.track[0].extra !== undefined - && file.ffProbeData.streams[0].tags['_STATISTICS_WRITING_DATE_UTC-eng'] !== undefined - ) { - // Set stats date to match info inside file - datStats = Date.parse(`${file.ffProbeData.streams[0].tags['_STATISTICS_WRITING_DATE_UTC-eng']} GMT`); - } - } catch (err) { - // Catch error - Ignore & carry on - If check can bomb out if the tag doesn't exist... - } - } - - // Threshold for stats date - const statsThres = Date.parse(new Date(new Date().setDate(new Date().getDate() - intStatsDays)).toISOString()); - - // Strings for easy to read dates in info log - let statsThresString = new Date(statsThres); - statsThresString = statsThresString.toUTCString(); - statsThresString = `${statsThresString.slice(0, 22)}:00 GMT`; - let datStatsString = new Date(datStats); - datStatsString = datStatsString.toUTCString(); - datStatsString = `${datStatsString.slice(0, 22)}:00 GMT`; - response.infoLog += `Checking file stats - If stats are older than ${intStatsDays} days we'll grab new stats.\n - Stats threshold: ${statsThresString}\n - Current stats date: ${datStatsString}\n`; - - // Are the stats out of date? - if (datStats >= statsThres) { - statsUptoDate = true; - response.infoLog += '☑ File stats are upto date! - Continuing...\n'; - } else { - response.infoLog += '☒ File stats are out of date! - Will attempt to use mkvpropedit to refresh stats\n'; - try { - if (otherArguments.mkvpropeditPath !== '') { // Try to use mkvpropedit path if it is set - proc.execSync(`"${otherArguments.mkvpropeditPath}" --add-track-statistics-tags "${currentFileName}"`); - } else { // Otherwise just use standard mkvpropedit cmd - proc.execSync(`mkvpropedit --add-track-statistics-tags "${currentFileName}"`); - } - } catch (err) { - response.infoLog += '☒ Error updating file stats - Possible mkvpropedit failure or file issue - ' - + ' Ensure mkvpropedit is set correctly in the node settings & check the filename for unusual characters.\n' - + ' Continuing but file stats will likely be inaccurate...\n'; - statsError = true; - } - if (statsError !== true) { - // File now updated with new stats - response.infoLog += 'Remuxing file to write in updated file stats! \n'; - response.preset += `-fflags +genpts -map 0 -c copy -max_muxing_queue_size 9999 -map_metadata:g -1 - -metadata JBDONEDATE=${new Date().toISOString()}`; - response.processFile = true; - return response; - } - } - } else { - response.infoLog += 'Input file is not MKV so cannot use mkvpropedit to get new file stats. ' - + 'Continuing but file stats will likely be inaccurate...\n'; - } - for (let i = 0; i < file.ffProbeData.streams.length; i += 1) { const strstreamType = file.ffProbeData.streams[i].codec_type.toLowerCase(); videoIdx = -1; @@ -649,12 +575,6 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // which can be inaccurate. We may inflate the current bitrate check so we don't keep looping this logic. } else if (inputs.reconvert_hevc === true && (file.ffProbeData.streams[i].codec_name === 'hevc' || file.ffProbeData.streams[i].codec_name === 'vp9' || file.ffProbeData.streams[i].codec_name === 'av1')) { - if (statsUptoDate !== true) { - currentBitrate = overallBitRate; // User overall bitrate if we don't have upto date stats - response.infoLog += `☒ Unable to get accurate stats for HEVC so falling back to Overall file Bitrate. - Remux to MKV to allow generation of accurate video bitrate statistics. - File overall bitrate is ${overallBitRate}kbps.\n`; - } if (inputs.hevc_max_bitrate > 0) { if (currentBitrate > inputs.hevc_max_bitrate) { // If bitrate is higher then hevc_max_bitrate then need to re-encode @@ -709,6 +629,17 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } } + // Specify the output format + switch (inputs.container) { + case 'mkv': + extraArguments += '-f matroska '; + break; + case 'mp4': + extraArguments += '-f mp4 '; + break; + default: + } + // Some video codecs won't play nice with 10 bit via QSV, whitelist safe ones here switch (file.video_codec_name) { case 'mpeg2': @@ -766,7 +697,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { break; case 'win32': // Windows - Full device, should fix child_device_type warnings response.preset += `-hwaccel qsv -hwaccel_output_format qsv - -init_hw_device qsv:hw_any,child_device_type=d3d11va `; + -init_hw_device qsv=qsv:MFX_IMPL_hw `; break; default: response.preset += '-hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any '; @@ -796,7 +727,6 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.preset += '-c:v av1_qsv'; break; default: - response.preset += ''; } } } @@ -807,18 +737,45 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Account for different OS setup for QSV HEVC encode. switch (os.platform()) { case 'darwin': - response.preset += 'hevc_videotoolbox'; + response.preset += 'hevc_videotoolbox '; // Mac OS & uses hevc_videotoolbox not QSV - Only shows up on Mac installs break; case 'linux': - response.preset += 'hevc_qsv'; + response.preset += 'hevc_qsv '; break; case 'win32': - response.preset += 'hevc_qsv -load_plugin hevc_hw'; + response.preset += 'hevc_qsv -load_plugin hevc_hw '; // Windows needs the additional -load_plugin. Tested working on a Win 10 - i5-10505 break; default: - response.preset += 'hevc_qsv'; // Default to QSV + response.preset += 'hevc_qsv '; // Default to QSV + } + + // If HW decode is happening add hwupload to encode + if (os.platform() !== 'darwin') { + if (high10 === false) { // Don't enable for High10 + switch (file.video_codec_name) { + case 'mpeg2': + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + case 'h264': + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + case 'mjpeg': + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + case 'hevc': + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + case 'vp9': // Should be supported by 8th Gen + + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + case 'av1': // Should be supported by 11th gen + + extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + break; + default: + } + } } // Add the rest of the ffmpeg command @@ -834,7 +791,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Normal behavior response.preset += ` ${bitrateSettings} ` + `-preset ${inputs.encoder_speedpreset} ${inputs.extra_qsv_options} ` - + `-c:a copy -c:s copy -max_muxing_queue_size 9999 ${extraArguments} ${metadataEncode}`; + + `-c:a copy -c:s copy -max_muxing_queue_size 9999 ${extraArguments}`; } response.processFile = true; From eb92f001be5fd2876bf9d1f97f9530c8784097a6 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Wed, 10 Jan 2024 19:51:29 +0000 Subject: [PATCH 03/14] Updated new description & tests Description updated since mkvpropedit is gone Tests updated for recent changes --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 13 +- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 246 +++++------------- 2 files changed, 71 insertions(+), 188 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 234696e..15efbdd 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -26,9 +26,8 @@ const details = () => ({ Settings are dependant on file bitrate working by the logic that H265 can support the same amount of data at half the bitrate of H264. This plugin will skip files already in HEVC, AV1 & VP9 unless "reconvert_hevc" is marked as true. If it is then these will be reconverted again if they exceed the bitrate specified in "hevc_max_bitrate". - This plugin will also attempt to use mkvpropedit to generate accurate bitrate metadata in MKV files. - It's not required to enable mkvpropedit but highly recommended to ensure accurate bitrates are used when - encoding your media.`, + This plugin relies on understanding the accurate video bitrate of your files. It's highly recommended to remux + into MKV & enable "Run mkvpropedit on files before running plugins" under Tdarr>Options.`, Version: '1.21', Tags: 'pre-processing,ffmpeg,video only,qsv,h265,hevc,mkvpropedit,configurable', Inputs: [ @@ -737,18 +736,18 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Account for different OS setup for QSV HEVC encode. switch (os.platform()) { case 'darwin': - response.preset += 'hevc_videotoolbox '; + response.preset += 'hevc_videotoolbox'; // Mac OS & uses hevc_videotoolbox not QSV - Only shows up on Mac installs break; case 'linux': - response.preset += 'hevc_qsv '; + response.preset += 'hevc_qsv'; break; case 'win32': - response.preset += 'hevc_qsv -load_plugin hevc_hw '; + response.preset += 'hevc_qsv -load_plugin hevc_hw'; // Windows needs the additional -load_plugin. Tested working on a Win 10 - i5-10505 break; default: - response.preset += 'hevc_qsv '; // Default to QSV + response.preset += 'hevc_qsv'; // Default to QSV } // If HW decode is happening add hwupload to encode diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 637f179..b84bf1a 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -21,12 +21,11 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 ', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + 'Container for output selected as mkv. \n' + 'Encode variable bitrate settings: \n' + 'Target = 603k \n' @@ -38,12 +37,11 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + 'Container for output selected as mkv. \n' + 'Encode variable bitrate settings: \n' + 'Target = 603k \n' @@ -54,12 +52,11 @@ const tests = [ }, darwin: { processFile: true, - preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 ', + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + 'Container for output selected as mkv. \n' + 'Encode variable bitrate settings: \n' + 'Target = 603k \n' @@ -88,12 +85,11 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -profile:v main10 -vf scale_qsv=format=p010le ', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + 'Container for output selected as mp4. \n' + 'Encode variable bitrate settings: \n' @@ -106,12 +102,11 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le ', + + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + 'Container for output selected as mp4. \n' + 'Encode variable bitrate settings: \n' @@ -123,7 +118,7 @@ const tests = [ }, darwin: { processFile: true, - preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le ', + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -148,7 +143,6 @@ const tests = [ file: (() => { const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); file.ffProbeData.streams[0].profile = 'High 10'; - file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); return file; })(), librarySettings: {}, @@ -161,17 +155,11 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -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 -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n' + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + 'Container for output selected as mkv. \n' @@ -184,17 +172,11 @@ const tests = [ }, win32: { processFile: true, - preset: '-fflags +genpts -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n' + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + 'Container for output selected as mkv. \n' @@ -207,17 +189,11 @@ const tests = [ }, darwin: { processFile: true, - preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -profile:v main10 -pix_fmt p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -f matroska -profile:v main10 -pix_fmt p010le ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n' + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' + 'Container for output selected as mkv. \n' @@ -237,9 +213,8 @@ const tests = [ input: { file: (() => { const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); - file.mediaInfo.track[1].BitRate = 12059590; + file.mediaInfo.track[1].BitRate = 12000000; file.ffProbeData.streams[0].profile = 'Main 10'; - file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); return file; })(), librarySettings: {}, @@ -256,73 +231,55 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 12060kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' - + 'Minimum = 4523k \n' - + 'Maximum = 7538k \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 \n' - + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 12060kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' - + 'Minimum = 4523k \n' - + 'Maximum = 7538k \n' + + 'Target = 6000k \n' + + 'Minimum = 4500k \n' + + 'Maximum = 7500k \n' + 'File Transcoding... \n', container: '.mkv', }, darwin: { processFile: true, - preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 6030k -minrate 4523k -maxrate 7538k -bufsize 12060k -preset fast -c:a copy -c:s copy -max_muxing_queue_size 9999 -profile:v main10 -vf scale_qsv=format=p010le -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -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 -profile:v main10 -f matroska -profile:v main10 -vf scale_qsv=format=p010le', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 12060kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + '☒ The file is still above this new cutoff! Reconverting. \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 = 6030k \n' - + 'Minimum = 4523k \n' - + 'Maximum = 7538k \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', @@ -356,53 +313,17 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 5000kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 5000kbps. \n' + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' + '☑ The file is NOT above this new cutoff. Exiting plugin. \n', container: '.mkv', }, }, // Test 5 - { - input: { - file: (() => { - const file = _.cloneDeep(require('../sampleData/media/sampleH265_1.json')); - file.container = 'mp4'; - return file; - })(), - librarySettings: {}, - inputs: { - container: 'mp4', - encoder_speedpreset: 'fast', - bitrate_cutoff: '3500', - }, - otherArguments: {}, - }, - output: { - processFile: false, - preset: '', - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '==WARNING== Failed to get an accurate video bitrate, falling back to old method to get OVERALL file bitrate of 3059kbps. Bitrate calculations for video encode will likely be inaccurate... \n' - + '☑ Current bitrate is below set cutoff of 3500kbps. \n' - + 'Cancelling plugin. \n', - container: '.mp4', - }, - }, - // Test 6 { input: { file: (() => { const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); - file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); file.ffProbeData.streams[3].codec_name = 'hdmv_pgs_subtitle'; file.ffProbeData.streams[4].codec_name = 'eia_608'; file.ffProbeData.streams[5].codec_name = 'subrip'; @@ -421,17 +342,11 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Container for output selected as mp4. \n' + 'Encode variable bitrate settings: \n' + 'Target = 3227k \n' @@ -443,17 +358,11 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Container for output selected as mp4. \n' + 'Encode variable bitrate settings: \n' + 'Target = 3227k \n' @@ -464,17 +373,11 @@ const tests = [ }, darwin: { processFile: true, - preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + 'Container for output selected as mp4. \n' + 'Encode variable bitrate settings: \n' + 'Target = 3227k \n' @@ -485,12 +388,11 @@ const tests = [ }, }, }, - // Test 7 + // Test 6 { input: { file: (() => { const file = _.cloneDeep(require('../sampleData/media/sampleH264_2.json')); - file.mediaInfo.track[0].extra.JBDONEDATE = new Date().toISOString(); file.ffProbeData.streams[3].codec_name = 'mov_text'; file.ffProbeData.streams[4].codec_name = 'eia_608'; file.ffProbeData.streams[5].codec_name = 'timed_id3'; @@ -508,66 +410,48 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=d3d11va -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, darwin: { processFile: true, - preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -map_metadata:g -1 -metadata JBDONEDATE=2674800000', + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: "Checking file stats - If stats are older than 7 days we'll grab new stats.\n" - + '\n' - + ` Stats threshold: ${statsThresString}\n` - + '\n' - + ` Current stats date: ${datStatsString}\n` - + '☑ File stats are upto date! - Continuing...\n' - + '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, }, From 0c925ded518d0749bd0d720d70ecb74598bd58ce Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Wed, 10 Jan 2024 19:53:01 +0000 Subject: [PATCH 04/14] Updated tests again Removed left over bits from testing mkvpropedit --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index b84bf1a..1eb92f1 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -2,12 +2,6 @@ const _ = require('lodash'); const run = require('../helpers/run'); -// Date stuff for mkvpropedit -const intStatsDays = 7; // Use 1 week threshold for new stats -let statsThresString = new Date(new Date().setDate(new Date().getDate() - intStatsDays)).toUTCString(); -statsThresString = `${statsThresString.slice(0, 22)}:00 GMT`; -let datStatsString = new Date().toUTCString(); -datStatsString = `${datStatsString.slice(0, 22)}:00 GMT`; const tests = [ // Test 0 { @@ -415,12 +409,12 @@ const tests = [ FFmpegMode: true, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, win32: { @@ -431,12 +425,12 @@ const tests = [ FFmpegMode: true, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, darwin: { @@ -446,12 +440,12 @@ const tests = [ FFmpegMode: true, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + + 'Container for output selected as mkv. \n' + + 'Encode variable bitrate settings: \n' + + 'Target = 3227k \n' + + 'Minimum = 2420k \n' + + 'Maximum = 4034k \n' + + 'File Transcoding... \n', container: '.mkv', }, }, From a5dc4934eee0cb92a8bdc2e5fd7f5c36dad79bcf Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:28:41 +0000 Subject: [PATCH 05/14] Corrected -vf cmd so it's added on the end better --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 85 ++++++++++++++++--- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 81 ++++++++++++++++-- 2 files changed, 146 insertions(+), 20 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 15efbdd..bf0fbc0 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -166,6 +166,7 @@ const details = () => ({ \\nDefault is empty but the first example below has a suggested value. If unsure just leave empty. \\nEnsure to only use cmds valid to encoding QSV as the script handles other ffmpeg cmds relating to bitrate etc. Anything else entered here might be supported but could cause undesired results. + \\nIf you are using a "-vf" cmd, please put it at the end to avoid issues! \\nExample:\\n -look_ahead 1 -look_ahead_depth 100 -extbrc 1 -rdo 1 -mbbrc 1 -b_strategy 1 -adaptive_i 1 -adaptive_b 1 \\n Above enables look ahead, extended bitrate control, b-frames, etc.\\n @@ -664,7 +665,13 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { extraArguments += '-profile:v main10 -pix_fmt p010le '; response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; } else if (main10 === true) { // Pixel formate method when using HW decode - extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le '; + if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { + extraArguments += '-profile:v main10'; + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ':format=p010le'; // Only add on the pixel format to existing scale_qsv cmd + } else { + extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le'; + } response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; } @@ -696,7 +703,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { break; case 'win32': // Windows - Full device, should fix child_device_type warnings response.preset += `-hwaccel qsv -hwaccel_output_format qsv - -init_hw_device qsv=qsv:MFX_IMPL_hw `; + -init_hw_device qsv:hw,child_device_type=d3d11va `; break; default: response.preset += '-hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any '; @@ -743,34 +750,86 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.preset += 'hevc_qsv'; break; case 'win32': - response.preset += 'hevc_qsv -load_plugin hevc_hw'; - // Windows needs the additional -load_plugin. Tested working on a Win 10 - i5-10505 + response.preset += 'hevc_qsv'; + // Tested working on a Win 10 - i5-10505 break; default: response.preset += 'hevc_qsv'; // Default to QSV } - // If HW decode is happening add hwupload to encode - if (os.platform() !== 'darwin') { - if (high10 === false) { // Don't enable for High10 + // Check if -vf cmd has already been used on user input + if (high10 !== true) { + if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { + switch (file.video_codec_name) { + case 'mpeg2': + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'h264': + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'mjpeg': + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'hevc': + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'vp9': // Should be supported by 8th Gen + + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'av1': // Should be supported by 11th gen + + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',hwupload=extra_hw_frames=64,format=qsv '; + break; + default: + } + } else if (extraArguments.search('-vf') === -1) { + // Check if -vf cmd has been used on the other var instead, if not add it & rest of cmd + switch (file.video_codec_name) { + case 'mpeg2': + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'h264': + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'mjpeg': + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'hevc': + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'vp9': // Should be supported by 8th Gen + + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + case 'av1': // Should be supported by 11th gen + + extraArguments += '-vf hwupload=extra_hw_frames=64,format=qsv '; + break; + default: + } + } else { + // Otherwise add the cmd onto the end switch (file.video_codec_name) { case 'mpeg2': - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; case 'h264': - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; case 'mjpeg': - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; case 'hevc': - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; case 'vp9': // Should be supported by 8th Gen + - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; case 'av1': // Should be supported by 11th gen + - extraArguments += '-vf "hwupload=extra_hw_frames=64,format=qsv" '; + extraArguments += ',hwupload=extra_hw_frames=64,format=qsv '; break; default: } diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 1eb92f1..f4c96ce 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -31,7 +31,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -96,7 +96,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -166,7 +166,7 @@ const tests = [ }, win32: { processFile: true, - preset: '-fflags +genpts -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 ', + preset: '-fflags +genpts -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, FFmpegMode: true, reQueueAfter: true, @@ -243,7 +243,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -352,7 +352,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -420,7 +420,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv=qsv:MFX_IMPL_hw -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -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 ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -450,6 +450,73 @@ const tests = [ }, }, }, + // Test 7 + { + input: { + file: _.cloneDeep(require('../sampleData/media/sampleH264_1.json')), + librarySettings: {}, + inputs: { + container: 'mkv', + encoder_speedpreset: 'fast', + extra_qsv_options: '-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', + enable_10bit: 'true', + }, + otherArguments: {}, + }, + output: { + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska -profile:v main10', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -hwaccel videotoolbox -map 0 -c:v hevc_videotoolbox -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \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); From cb1dfe2d19a3f31c7e1d1c4da19bf28b454c5467 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:19:24 +0000 Subject: [PATCH 06/14] Updated tests --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index f4c96ce..6350ce1 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -15,7 +15,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -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, FFmpegMode: true, reQueueAfter: true, @@ -31,7 +31,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -79,7 +79,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -96,7 +96,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -225,7 +225,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -vf "hwupload=extra_hw_frames=64,format=qsv" ', + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -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, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' @@ -243,7 +243,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv -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 ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -336,7 +336,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -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, FFmpegMode: true, reQueueAfter: true, @@ -352,7 +352,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -404,7 +404,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -map 0 -c:v hevc_qsv -load_plugin hevc_hw -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 -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, FFmpegMode: true, reQueueAfter: true, @@ -420,7 +420,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, @@ -467,7 +467,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -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 -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, FFmpegMode: true, reQueueAfter: true, @@ -484,7 +484,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 -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 -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, FFmpegMode: true, reQueueAfter: true, From afe538fcbdf3694b24510f6662abcf3c500aa5ad Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:59:17 +0000 Subject: [PATCH 07/14] Restored some cases for HW decode but commented out --- Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index bf0fbc0..d2e594a 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -720,9 +720,15 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { case 'h264': response.preset += '-c:v h264_qsv'; break; + case 'vc1': // VC1 no longer supported on latest intel HW + // response.preset += '-c:v vc1_qsv'; + break; case 'mjpeg': response.preset += '-c:v mjpeg_qsv'; break; + case 'vp8': // VP8 no longer supported on latest intel HW + // response.preset += '-c:v vp8_qsv'; + break; case 'hevc': response.preset += '-c:v hevc_qsv'; break; From 7f87af3c1b47e880a01d06c95002ea3e439f3761 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:10:55 +0000 Subject: [PATCH 08/14] Quick update to tooltip --- Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index d2e594a..e01a033 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -157,7 +157,6 @@ const details = () => ({ https://ffmpeg.org/ffmpeg-codecs.html#toc-HEVC-Options-1 \\n ==WARNING== \\n - Just because a cmd is mentioned doesn't mean your installed version of ffmpeg supports it... Be certain to verify the cmds work before adding to your workflow. \\n Check Tdarr Help Tab. Enter ffmpeg cmd - "-h encoder=hevc_qsv". This will give a list of supported commands. \\n MAC SPECIFIC - This option is ignored on Mac because videotoolbox is used rather than qsv. From 23bef4c77829e16d8f3a0d40d67af09818160aa1 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Wed, 17 Jan 2024 20:30:08 +0000 Subject: [PATCH 09/14] Protection against errors if unable to use MediaInfo or ffprobe Just changed the videoBR logic to be inside a try block to avoid errors on rare instances where Media info & ffprobe fail --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index e01a033..3d2d2c6 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -357,21 +357,19 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Check if stream is a video. if (videoIdx === -1 && strstreamType === 'video') { videoIdx = i; - videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; - - // If MediaInfo fails somehow fallback to ffprobe - Try two types of tags that might exist - if (videoBR <= 0 || Number.isNaN(videoBR)) { - if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; - } else { - try { - if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; - } - } catch (err) { - // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... + // Try checking file stats using Mediainfo first, then ffprobe. + try { + videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; + if (videoBR <= 0 || Number.isNaN(videoBR)) { + if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; + } else if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; } } + } catch (err) { + // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... + 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) { From f4c02bc997e423f269cea61cebc59cbb94bb4109 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:58:49 +0000 Subject: [PATCH 10/14] Found new edge cases so changed how HW decode is triggered Ended up finding more cases where errors would pop up and looks to all to do with HW decode. - Now ensured that unless the incoming format is in the white list then sw decode is done instead - Correctly removed -hwaccel cmd when sw decode happens preventing accidental hwdecode - Specify the format to decode when using sw - renamed oldformat var to match its use case (now swDecode) - Info log updated with when SW decode happens and will report which incoming format caused it --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 108 +++++++++++------- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 84 +++++++++++++- 2 files changed, 143 insertions(+), 49 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 3d2d2c6..450595e 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -326,7 +326,7 @@ let bitrateSettings = ''; let inflatedCutoff = 0; let main10 = false; let high10 = false; -let oldFormat = false; +let swDecode = false; let videoBR = 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -609,14 +609,13 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } } - // On testing I've found files in the High10 profile don't play nice with hw decoding so mark these + // Files in the High10 profile are not supported for HW Decode if (file.ffProbeData.streams[i].profile === 'High 10') { high10 = true; - response.infoLog += 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n'; - } - // If files are 10 bit or the enable_10bit setting is used mark to enable Main10. - if (file.ffProbeData.streams[i].profile === 'Main 10' || file.ffProbeData.streams[i].bits_per_raw_sample === '10' - || inputs.enable_10bit === true) { + main10 = true; + // If files are 10 bit or the enable_10bit setting is used mark to enable Main10. + } else if (file.ffProbeData.streams[i].profile === 'Main 10' + || file.ffProbeData.streams[i].bits_per_raw_sample === '10' || inputs.enable_10bit === true) { main10 = true; } @@ -637,26 +636,32 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { default: } - // Some video codecs won't play nice with 10 bit via QSV, whitelist safe ones here + // Some video codecs don't support HW decode so mark these + // VC1 & VP8 are no longer supported on new HW, add cases here if your HW does support switch (file.video_codec_name) { case 'mpeg2': break; case 'h264': + if (high10 === true) { + response.infoLog += `Input file is ${file.video_codec_name} High10. Hardware Decode not supported. \n`; + swDecode = true; + } break; case 'mjpeg': break; case 'hevc': break; - case 'vp9': + case 'vp9':// Should be supported by 8th Gen + break; - case 'av1': + case 'av1':// Should be supported by 11th gen + break; default: - oldFormat = true; + swDecode = true; + response.infoLog += `Input file is ${file.video_codec_name}. Hardware Decode not supported. \n`; } // Are we encoding to 10 bit? If so enable correct profile & pixel format. - if (high10 === true || (oldFormat === true && main10 === true)) { + if (swDecode === true && main10 === true) { // This is used if we have High10 or Main10 is enabled & odd format files. // SW decode and use standard -pix_fmt p010le extraArguments += '-profile:v main10 -pix_fmt p010le '; @@ -686,10 +691,10 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // -fflags +genpts should regenerate timestamps if they end up missing... response.preset = '-fflags +genpts '; - // HW ACCEL FLAGS - I think these are good practice but are they necessary? + // HW ACCEL FLAGS // Account for different OS - if (high10 === false) { - // Seems incoming High10 files don't play nice decoding so use software decode + if (swDecode !== true) { + // Only enable hw decode for accepted formats switch (os.platform()) { case 'darwin': // Mac OS - Enable videotoolbox instead of QSV response.preset += '-hwaccel videotoolbox'; @@ -705,38 +710,51 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { default: response.preset += '-hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any '; } + } else { + switch (os.platform()) { + case 'linux': // Linux - Full device, should fix child_device_type warnings + response.preset += `-hwaccel_output_format qsv + -init_hw_device qsv:hw_any,child_device_type=vaapi `; + break; + case 'win32': // Windows - Full device, should fix child_device_type warnings + response.preset += `-hwaccel_output_format qsv + -init_hw_device qsv:hw,child_device_type=d3d11va `; + break; + default: + // Default to enabling hwaccel for output only + response.preset += '-hwaccel_output_format qsv -init_hw_device qsv:hw_any '; + } } // DECODE FLAGS + // VC1 & VP8 are no longer supported on new HW, add cases here if your HW does support if (os.platform() !== 'darwin') { - if (high10 === false) { // Don't enable for High10 - switch (file.video_codec_name) { - case 'mpeg2': - response.preset += '-c:v mpeg2_qsv'; - break; - case 'h264': + switch (file.video_codec_name) { + case 'mpeg2': + response.preset += '-c:v mpeg2_qsv'; + break; + case 'h264': + if (high10 !== true) { // Don't enable for High10 response.preset += '-c:v h264_qsv'; - break; - case 'vc1': // VC1 no longer supported on latest intel HW - // response.preset += '-c:v vc1_qsv'; - break; - case 'mjpeg': - response.preset += '-c:v mjpeg_qsv'; - break; - case 'vp8': // VP8 no longer supported on latest intel HW - // response.preset += '-c:v vp8_qsv'; - break; - case 'hevc': - response.preset += '-c:v hevc_qsv'; - break; - case 'vp9': // Should be supported by 8th Gen + - response.preset += '-c:v vp9_qsv'; - break; - case 'av1': // Should be supported by 11th gen + - response.preset += '-c:v av1_qsv'; - break; - default: - } + } else { + response.preset += `-c:v ${file.video_codec_name}`; + } + break; + case 'mjpeg': + response.preset += '-c:v mjpeg_qsv'; + break; + case 'hevc': + response.preset += '-c:v hevc_qsv'; + break; + case 'vp9': // Should be supported by 8th Gen + + response.preset += '-c:v vp9_qsv'; + break; + case 'av1': // Should be supported by 11th gen + + response.preset += '-c:v av1_qsv'; + break; + default: + // Use incoming format for software decode + response.preset += `-c:v ${file.video_codec_name}`; } } @@ -760,8 +778,10 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.preset += 'hevc_qsv'; // Default to QSV } - // Check if -vf cmd has already been used on user input - if (high10 !== true) { + // Only add on for HW decoded formats + // VC1 & VP8 are no longer supported on new HW, add cases here if your HW does support + if (swDecode !== true) { + // Check if -vf cmd has already been used on user input if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { switch (file.video_codec_name) { case 'mpeg2': diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 6350ce1..afcc6ac 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -149,12 +149,13 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw,child_device_type=vaapi -c:v h264 -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, FFmpegMode: true, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n' + + 'Input file is h264 High10. Hardware Decode not supported. \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' @@ -166,12 +167,13 @@ const tests = [ }, win32: { processFile: true, - preset: '-fflags +genpts -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264 -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, FFmpegMode: true, reQueueAfter: true, infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \n' + + 'Input file is h264 High10. Hardware Decode not supported. \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' @@ -183,7 +185,7 @@ const tests = [ }, darwin: { processFile: true, - preset: '-fflags +genpts -map 0 -c:v hevc_videotoolbox -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -f matroska -profile:v main10 -pix_fmt p010le ', + preset: '-fflags +genpts -c:v h264 -map 0 -c:v hevc_videotoolbox -b:v 3227k -minrate 2420k -maxrate 4034k -bufsize 6454k -preset fast -c:a copy -c:s copy -f matroska -profile:v main10 -pix_fmt p010le ', handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, @@ -518,5 +520,77 @@ const tests = [ }, }, }, + // Test 8 + { + input: { + file: (() => { + const file = _.cloneDeep(require('../sampleData/media/sampleH264_1.json')); + file.ffProbeData.streams[0].bits_per_raw_sample = '10'; + file.video_codec_name = 'vc1'; + return file; + })(), + librarySettings: {}, + inputs: { + container: 'mkv', + encoder_speedpreset: 'fast', + }, + otherArguments: {}, + }, + output: { + linux: { + processFile: true, + preset: '-fflags +genpts -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v vc1 -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, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + + 'Input file is vc1. Hardware Decode not supported. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + win32: { + processFile: true, + preset: '-fflags +genpts -hwaccel_output_format qsv \n' + + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v vc1 -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, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' + + 'Input file is vc1. Hardware Decode not supported. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \n' + + 'File Transcoding... \n', + container: '.mkv', + }, + darwin: { + processFile: true, + preset: '-fflags +genpts -c:v vc1 -map 0 -c:v hevc_videotoolbox -b:v 603k -minrate 452k -maxrate 754k -bufsize 1206k -preset slow -c:a copy -c:s copy -max_muxing_queue_size 9999 -f matroska ', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' + + 'Minimum = 452k \n' + + 'Maximum = 754k \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); From a17ac70d25e40a46e1a0941d25e5731af57deb88 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:53:55 +0000 Subject: [PATCH 11/14] Noticed one last -vf filter check used a colon incorrectly Changed to a comma which matches all other formatting with the -vf cmd & updated tests --- Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 2 +- tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 450595e..fc6cb2a 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -670,7 +670,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { extraArguments += '-profile:v main10'; // eslint-disable-next-line no-param-reassign - inputs.extra_qsv_options += ':format=p010le'; // Only add on the pixel format to existing scale_qsv cmd + inputs.extra_qsv_options += ',format=p010le'; // Only add on the pixel format to existing scale_qsv cmd } else { extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le'; } diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index afcc6ac..64c6120 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -469,7 +469,7 @@ const tests = [ linux: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 -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, FFmpegMode: true, reQueueAfter: true, @@ -486,7 +486,7 @@ const tests = [ win32: { processFile: true, preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 -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, FFmpegMode: true, reQueueAfter: true, From 8aadba149618c57c791c940d8ef902b1b1f75405 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Fri, 26 Jan 2024 21:02:18 +0000 Subject: [PATCH 12/14] Final things, remove tag mkvpropedit & bump the Version number ;) --- Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index fc6cb2a..30ae184 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -28,8 +28,8 @@ const details = () => ({ true. If it is then these will be reconverted again if they exceed the bitrate specified in "hevc_max_bitrate". This plugin relies on understanding the accurate video bitrate of your files. It's highly recommended to remux into MKV & enable "Run mkvpropedit on files before running plugins" under Tdarr>Options.`, - Version: '1.21', - Tags: 'pre-processing,ffmpeg,video only,qsv,h265,hevc,mkvpropedit,configurable', + Version: '1.3', + Tags: 'pre-processing,ffmpeg,video only,qsv,h265,hevc,configurable', Inputs: [ { name: 'container', From 890c2642e1384044c0dd7c632b8413083f6b0352 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:32:59 +0000 Subject: [PATCH 13/14] Updates to video loop & darwin support - Corrected some Mac/Darwin support, incorrect 10 bit options (In future will remove videotoolbox support and split into separate plugin) - Improved video check loops, some logic did seem to not correctly stop when needed & the remove stream option had the wrong syntax so probably wouldn't have worked --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 245 ++++++++++-------- 1 file changed, 130 insertions(+), 115 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 30ae184..add6127 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -353,35 +353,41 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { for (let i = 0; i < file.ffProbeData.streams.length; i += 1) { const strstreamType = file.ffProbeData.streams[i].codec_type.toLowerCase(); - videoIdx = -1; // Check if stream is a video. - if (videoIdx === -1 && strstreamType === 'video') { - videoIdx = i; - // Try checking file stats using Mediainfo first, then ffprobe. - try { - videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; - if (videoBR <= 0 || Number.isNaN(videoBR)) { - if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; - } else if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; + if (strstreamType === 'video') { + if (file.ffProbeData.streams[i].codec_name !== 'mjpeg' + && file.ffProbeData.streams[i].codec_name !== 'png') { + // Try checking file stats using Mediainfo first, then ffprobe. + try { + videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; + if (videoBR <= 0 || Number.isNaN(videoBR)) { + if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; + } else if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; + } } + } catch (err) { + // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... + 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 is a number then convert seconds to minutes + duration = file.meta.Duration / 60; + } else if (typeof file.meta.Duration !== 'undefined') { + // Get seconds by using a Date & then convert to minutes + duration = file.meta.Duration; + 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. + duration = file.ffProbeData.streams[i].tags.DURATION; + duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; + } + if (videoBR <= 0 || Number.isNaN(videoBR)) { + // videoBR not yet valid so Loop + } else { + break;// Exit loop if videoBR is valid } - } catch (err) { - // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... - 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 is a number then convert seconds to minutes - duration = file.meta.Duration / 60; - } else if (typeof file.meta.Duration !== 'undefined') { - // Get seconds by using a Date & then convert to minutes - duration = file.meta.Duration; - 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. - duration = file.ffProbeData.streams[videoIdx].tags.DURATION; - duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; } } } @@ -532,91 +538,91 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Check if codec of stream is mjpeg/png, if so then remove this "video" stream. // mjpeg/png are usually embedded pictures that can cause havoc with plugins. if (file.ffProbeData.streams[i].codec_name === 'mjpeg' || file.ffProbeData.streams[i].codec_name === 'png') { - extraArguments += `-map -v:${videoIdx} `; - } - - // Check for HDR in files. If so exit plugin. We assume HDR files have bt2020 color spaces. HDR can be complicated - // 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' - && file.ffProbeData.streams[i].color_transfer === 'smpte2084' - && file.ffProbeData.streams[i].color_primaries === 'bt2020') { - response.infoLog += '☒ This looks to be a HDR file. HDR files are unfortunately ' - + 'not supported by this plugin. Exiting plugin. \n\n'; - return response; - } - - // Now check if we're reprocessing HEVC files, if not then ensure we don't convert HEVC again - if (inputs.reconvert_hevc === false && (file.ffProbeData.streams[i].codec_name === 'hevc' - || file.ffProbeData.streams[i].codec_name === 'vp9' || file.ffProbeData.streams[i].codec_name === 'av1')) { - // Check if codec of stream is HEVC, VP9 or AV1 AND check if file.container matches inputs.container. - // If so nothing for plugin to do. - 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 already HEVC, VP9 or AV1 & in ${inputs.container}. \n`; + extraArguments += `-map -0:v:${videoIdx} `; + } 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 + // 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' + && file.ffProbeData.streams[i].color_transfer === 'smpte2084' + && file.ffProbeData.streams[i].color_primaries === 'bt2020') { + response.infoLog += '☒ This looks to be a HDR file. HDR files are unfortunately ' + + 'not supported by this plugin. Exiting plugin. \n\n'; 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 = ` -map 0 -c copy ${extraArguments}`; - response.processFile = true; - return response; - } + // Now check if we're reprocessing HEVC files, if not then ensure we don't convert HEVC again + if (inputs.reconvert_hevc === false && (file.ffProbeData.streams[i].codec_name === 'hevc' + || file.ffProbeData.streams[i].codec_name === 'vp9' || file.ffProbeData.streams[i].codec_name === 'av1')) { + // Check if codec of stream is HEVC, VP9 or AV1 AND check if file.container matches inputs.container. + // If so nothing for plugin to do. + 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 already HEVC, VP9 or AV1 & in ${inputs.container}. \n`; + return response; + } - // 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 - // which can be inaccurate. We may inflate the current bitrate check so we don't keep looping this logic. - } else if (inputs.reconvert_hevc === true && (file.ffProbeData.streams[i].codec_name === 'hevc' - || file.ffProbeData.streams[i].codec_name === 'vp9' || file.ffProbeData.streams[i].codec_name === 'av1')) { - if (inputs.hevc_max_bitrate > 0) { - if (currentBitrate > inputs.hevc_max_bitrate) { - // 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, ` - + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; + // 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 = ` -map 0 -c copy ${extraArguments}`; + response.processFile = true; + return response; + } + + // 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 + // which can be inaccurate. We may inflate the current bitrate check so we don't keep looping this logic. + } else if (inputs.reconvert_hevc === true && (file.ffProbeData.streams[i].codec_name === 'hevc' + || file.ffProbeData.streams[i].codec_name === 'vp9' || file.ffProbeData.streams[i].codec_name === 'av1')) { + if (inputs.hevc_max_bitrate > 0) { + if (currentBitrate > inputs.hevc_max_bitrate) { + // 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, ` + + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; + response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; + } else { + // 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, ` + + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; + response.infoLog += '☑ The file is NOT above this new cutoff. Exiting plugin. \n'; + return response; + } + + // If we're not using the hevc max bitrate then we need a safety net to try and ensure we don't keep + // looping this plugin. For maximum safety we simply multiply the cutoff by 2. + } else if (currentBitrate > (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 += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; + response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; + response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; + response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; } else { - // 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, ` - + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; - response.infoLog += '☑ The file is NOT above this new cutoff. Exiting plugin. \n'; + // File is below cutoff so we can exit + inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2); + response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, `; + response.infoLog += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; + response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; + response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; + response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; + response.infoLog += '☑The file is NOT above this new cutoff. Exiting plugin. \n'; return response; } - - // If we're not using the hevc max bitrate then we need a safety net to try and ensure we don't keep - // looping this plugin. For maximum safety we simply multiply the cutoff by 2. - } else if (currentBitrate > (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 += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; - response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; - response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; - response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; - response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; - } else { - // File is below cutoff so we can exit - inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2); - response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, `; - response.infoLog += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; - response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; - response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; - response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; - response.infoLog += '☑The file is NOT above this new cutoff. Exiting plugin. \n'; - return response; } - } - // Files in the High10 profile are not supported for HW Decode - if (file.ffProbeData.streams[i].profile === 'High 10') { - high10 = true; - main10 = true; - // If files are 10 bit or the enable_10bit setting is used mark to enable Main10. - } else if (file.ffProbeData.streams[i].profile === 'Main 10' - || file.ffProbeData.streams[i].bits_per_raw_sample === '10' || inputs.enable_10bit === true) { - main10 = true; + // Files in the High10 profile are not supported for HW Decode + if (file.ffProbeData.streams[i].profile === 'High 10') { + high10 = true; + main10 = true; + // If files are 10 bit or the enable_10bit setting is used mark to enable Main10. + } else if (file.ffProbeData.streams[i].profile === 'Main 10' + || file.ffProbeData.streams[i].bits_per_raw_sample === '10' || inputs.enable_10bit === true) { + main10 = true; + } } // Increment video index. Needed to keep track of video id in case there is more than one video track. @@ -661,20 +667,26 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } // Are we encoding to 10 bit? If so enable correct profile & pixel format. - if (swDecode === true && main10 === true) { - // This is used if we have High10 or Main10 is enabled & odd format files. - // SW decode and use standard -pix_fmt p010le - extraArguments += '-profile:v main10 -pix_fmt p010le '; - response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; - } else if (main10 === true) { // Pixel formate method when using HW decode - if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { - extraArguments += '-profile:v main10'; - // eslint-disable-next-line no-param-reassign - inputs.extra_qsv_options += ',format=p010le'; // Only add on the pixel format to existing scale_qsv cmd - } else { - extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le'; + if (os.platform() !== 'darwin') { + if (swDecode === true && main10 === true) { + // This is used if we have High10 or Main10 is enabled & odd format files. + // SW decode and use standard -pix_fmt p010le + extraArguments += '-profile:v main10 -pix_fmt p010le '; + response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; + } else if (main10 === true) { // Pixel formate method when using HW decode + if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { + extraArguments += '-profile:v main10'; + // eslint-disable-next-line no-param-reassign + inputs.extra_qsv_options += ',format=p010le'; // Only add on the pixel format to existing scale_qsv cmd + } else { + extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le'; + } + response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; } - response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; + } else { + // Mac - Video toolbox profile & pixel format + extraArguments += '-profile:v 2 -pix_fmt yuv420p10le '; + response.infoLog += '10 bit encode enabled. Setting VideoToolBox Profile v2 & 10 bit pixel format \n'; } // Set bitrateSettings variable using bitrate information calculated earlier. @@ -712,6 +724,9 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } } else { switch (os.platform()) { + case 'darwin': // Mac OS - Enable videotoolbox instead of QSV + response.preset += '-hwaccel videotoolbox'; + break; case 'linux': // Linux - Full device, should fix child_device_type warnings response.preset += `-hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi `; @@ -780,7 +795,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Only add on for HW decoded formats // VC1 & VP8 are no longer supported on new HW, add cases here if your HW does support - if (swDecode !== true) { + if (swDecode !== true && os.platform() !== 'darwin') { // Check if -vf cmd has already been used on user input if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { switch (file.video_codec_name) { From 03d8a75033e7b809c34a8254c7d8233c16ca8647 Mon Sep 17 00:00:00 2001 From: Boosh1 <45874141+Boosh1@users.noreply.github.com> Date: Sat, 2 Mar 2024 19:33:42 +0000 Subject: [PATCH 14/14] 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 --- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 219 ++++---- ...Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js | 519 ++++++++++-------- 2 files changed, 405 insertions(+), 333 deletions(-) diff --git a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index add6127..cef350f 100644 --- a/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -97,7 +97,7 @@ const details = () => ({ ==DESCRIPTION== \\nSpecify if we want to enable 10bit encoding. \\nIf this is enabled files will be processed and converted into 10bit - HEVC using main10 profile and with p010le pixel format. \n + HEVC using main10 profile and with p010le pixel format.\n If you just want to retain files that are already 10 bit then this can be left as false, as 10bit to 10bit in ffmpeg should be automatic. \\n @@ -185,7 +185,7 @@ const details = () => ({ }, tooltip: `\\n ==DESCRIPTION== - \\nSpecify bitrate cutoff, files with a video bitrate lower then this will not be processed. \n + \\nSpecify bitrate cutoff, files with a video bitrate lower then this will not be processed.\n \\n ==INFO== \\nRate is in kbps. @@ -347,7 +347,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (file.fileMedium !== 'video') { response.processFile = false; - response.infoLog += `☒ File seems to be ${file.fileMedium} & not video. Exiting \n`; + response.infoLog += `☒ File seems to be ${file.fileMedium} & not video. Exiting\n`; return response; } @@ -357,36 +357,47 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (strstreamType === 'video') { if (file.ffProbeData.streams[i].codec_name !== 'mjpeg' && file.ffProbeData.streams[i].codec_name !== 'png') { - // Try checking file stats using Mediainfo first, then ffprobe. - try { - videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; - if (videoBR <= 0 || Number.isNaN(videoBR)) { - if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; - } else if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { - videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; + if (videoBR <= 0) { // Process if videoBR is not yet valid + try { // Try checking file stats using Mediainfo first, then ffprobe. + videoBR = Number(file.mediaInfo.track[i + 1].BitRate) / 1000; + if (videoBR <= 0 || Number.isNaN(videoBR)) { + if (Number(file.ffProbeData.streams[i].tags.BPS) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS / 1000; + } else if (Number(file.ffProbeData.streams[i].tags.BPS['-eng']) > 0) { + videoBR = file.ffProbeData.streams[i].tags.BPS['-eng'] / 1000; + } } + } catch (err) { + // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... + videoBR = 0; // Set videoBR to 0 for safety } - } catch (err) { - // Catch error - Ignore & carry on - If check can bomb out if tags don't exist... - 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 is a number then convert seconds to minutes - duration = file.meta.Duration / 60; - } else if (typeof file.meta.Duration !== 'undefined') { - // Get seconds by using a Date & then convert to minutes - duration = file.meta.Duration; - 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. - duration = file.ffProbeData.streams[i].tags.DURATION; - duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; + if (duration <= 0) { // Process if duration is not yet valid + try { // Attempt to get duration info + if (Number.isNaN(file.meta.Duration)) { + duration = file.meta.Duration; + duration = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; + } 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 = (new Date(`1970-01-01T${duration}Z`).getTime() / 1000) / 60; + } + } + } 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)) { - // videoBR not yet valid so Loop + if ((videoBR <= 0 || Number.isNaN(videoBR)) || (duration <= 0 || Number.isNaN(duration))) { + // videoBR or duration not yet valid so Loop } else { - break;// Exit loop if videoBR is valid + break;// Exit loop if both valid } } } @@ -395,12 +406,12 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (Number.isNaN(videoBR) || videoBR <= 0) { // Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" currentBitrate = Math.round(file.file_size / (duration * 0.0075)); - 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. `; - response.infoLog += 'Bitrate calculations for video encode will likely be inaccurate... \n'; + response.infoLog += '==WARNING== Failed to get an accurate video bitrate, ' + + `falling back to old method to get OVERALL file bitrate of ${currentBitrate}kbps. ` + + 'Bitrate calculations for video encode will likely be inaccurate...\n'; } else { 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`; } // Get overall bitrate for use with HEVC reprocessing @@ -414,8 +425,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // If targetBitrate or currentBitrate comes out as 0 then something // has gone wrong and bitrates could not be calculated. // Cancel plugin completely. - if (targetBitrate <= 0 || currentBitrate <= 0) { - response.infoLog += '☒ Target bitrate could not be calculated. Skipping this plugin. \n'; + if (targetBitrate <= 0 || currentBitrate <= 0 || overallBitRate <= 0) { + response.infoLog += '☒ Target bitrates could not be calculated. Skipping this plugin.\n'; return response; } @@ -423,19 +434,18 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // has gone wrong as that is not what we want. // Cancel plugin completely. if (targetBitrate >= currentBitrate) { - response.infoLog += `☒ Target bitrate has been calculated as ${targetBitrate}kbps. This is equal or greater `; - response.infoLog += "than the current bitrate... Something has gone wrong and this shouldn't happen! " - + 'Skipping this plugin. \n'; + response.infoLog += `☒ Target bitrate has been calculated as ${targetBitrate}kbps. This is equal or greater than ` + + "the current bitrate... Something has gone wrong and this shouldn't happen! Skipping this plugin.\n"; return response; } // Ensure that bitrate_cutoff is set if reconvert_hevc is true since we need some protection against a loop // Cancel the plugin 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 += 'or HEVC 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' - + '☒ Skipping this plugin. \n'; + response.infoLog += `Reconvert HEVC is ${inputs.reconvert_hevc}, however there is no bitrate cutoff or HEVC ` + + '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' + + '☒ Skipping this plugin.\n'; return response; } @@ -445,13 +455,13 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Checks if currentBitrate is below inputs.bitrate_cutoff. // If so then cancel plugin without touching original files. if (currentBitrate <= inputs.bitrate_cutoff) { - response.infoLog += `☑ Current bitrate is below set cutoff of ${inputs.bitrate_cutoff}kbps. \n` - + 'Cancelling plugin. \n'; + response.infoLog += `☑ Current bitrate is below set cutoff of ${inputs.bitrate_cutoff}kbps.\n` + + 'Cancelling plugin.\n'; return response; } // If above cutoff then carry on if (currentBitrate > inputs.bitrate_cutoff && inputs.reconvert_hevc === false) { - response.infoLog += '☒ Current bitrate appears to be above the cutoff. Need to process \n'; + response.infoLog += '☒ Current bitrate appears to be above the cutoff. Need to process\n'; } } @@ -459,8 +469,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // Checks if targetBitrate is above inputs.max_average_bitrate. // If so then clamp target bitrate if (targetBitrate > inputs.max_average_bitrate) { - response.infoLog += 'Our target bitrate is above the max_average_bitrate '; - response.infoLog += `so clamping at max of ${inputs.max_average_bitrate}kbps. \n`; + response.infoLog += 'Our target bitrate is above the max_average_bitrate so clamping at max of ' + + `${inputs.max_average_bitrate}kbps.\n`; targetBitrate = Math.round(inputs.max_average_bitrate); minimumBitrate = Math.round(targetBitrate * 0.75); maximumBitrate = Math.round(targetBitrate * 1.25); @@ -472,14 +482,14 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (inputs.min_average_bitrate > 0) { // 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) { - 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`; + 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`; return response; } // Checks if inputs.bitrate_cutoff is below inputs.min_average_bitrate. // If so then set currentBitrate to the minimum allowed.) if (targetBitrate < inputs.min_average_bitrate) { - response.infoLog += `Target average bitrate clamped at min of ${inputs.min_average_bitrate}kbps. \n`; + response.infoLog += `Target average bitrate clamped at min of ${inputs.min_average_bitrate}kbps.\n`; targetBitrate = Math.round(inputs.min_average_bitrate); minimumBitrate = Math.round(targetBitrate * 0.75); maximumBitrate = Math.round(targetBitrate * 1.25); @@ -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') { extraArguments += `-map -0:v:${videoIdx} `; } 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 - // 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' - && file.ffProbeData.streams[i].color_transfer === 'smpte2084' + // Check for HDR in files. Attempt to use same color + 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 === 'arib-std-b67') && file.ffProbeData.streams[i].color_primaries === 'bt2020') { - response.infoLog += '☒ This looks to be a HDR file. HDR files are unfortunately ' - + 'not supported by this plugin. Exiting plugin. \n\n'; + response.infoLog += '==WARNING== This looks to be a HDR file. HDR is supported but ' + + '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 = ` -map 0 -c copy ${extraArguments}`; + response.processFile = true; return response; } @@ -557,18 +581,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // If so nothing for plugin to do. 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 already HEVC, VP9 or AV1 & in ${inputs.container}. \n`; - 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 = ` -map 0 -c copy ${extraArguments}`; - response.processFile = true; + response.infoLog += `☑ File is already HEVC, VP9 or AV1 & in ${inputs.container}.\n`; return response; } @@ -580,14 +593,14 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { if (inputs.hevc_max_bitrate > 0) { if (currentBitrate > inputs.hevc_max_bitrate) { // 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, ` - + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; - response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; + response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. ` + + `Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps.\n` + + '☒ The file is still above this new cutoff! Reconverting.\n'; } else { // 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, ` - + `VP9 or AV1. Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps. \n`; - response.infoLog += '☑ The file is NOT above this new cutoff. Exiting plugin. \n'; + response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. ` + + `Using HEVC specific cutoff of ${inputs.hevc_max_bitrate}kbps.\n` + + '☑ The file is NOT above this new cutoff. Exiting plugin.\n'; 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. } else if (currentBitrate > (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 += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; - response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; - response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; - response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; - response.infoLog += '☒ The file is still above this new cutoff! Reconverting. \n'; + response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. ` + + `Will use Overall file Bitrate for HEVC files as safety, bitrate is ${overallBitRate}kbps.\n` + + 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety!\n' + + `Cutoff now temporarily ${inflatedCutoff}kbps.\n` + + '☒ The file is still above this new cutoff! Reconverting.\n'; } else { // File is below cutoff so we can exit inflatedCutoff = Math.round(inputs.bitrate_cutoff * 2); - response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, `; - response.infoLog += 'VP9 or AV1. Will use Overall file Bitrate for HEVC files as safety, '; - response.infoLog += `bitrate is ${overallBitRate}kbps. \n`; - response.infoLog += 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety! \n'; - response.infoLog += `Cutoff now temporarily ${inflatedCutoff}kbps. \n`; - response.infoLog += '☑The file is NOT above this new cutoff. Exiting plugin. \n'; + response.infoLog += `Reconvert_hevc is ${inputs.reconvert_hevc} & the file is already HEVC, VP9 or AV1. ` + + `Will use Overall file Bitrate for HEVC files as safety, bitrate is ${overallBitRate}kbps.\n` + + 'HEVC specific cutoff not set so bitrate_cutoff is multiplied by 2 for safety!\n' + + `Cutoff now temporarily ${inflatedCutoff}kbps.\n` + + '☑The file is NOT above this new cutoff. Exiting plugin.\n'; return response; } } @@ -649,8 +660,8 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { break; case 'h264': if (high10 === true) { - response.infoLog += `Input file is ${file.video_codec_name} High10. Hardware Decode not supported. \n`; swDecode = true; + response.infoLog += 'Input file is h264 High10. Hardware Decode not supported.\n'; } break; case 'mjpeg': @@ -663,7 +674,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { break; default: swDecode = true; - response.infoLog += `Input file is ${file.video_codec_name}. Hardware Decode not supported. \n`; + response.infoLog += `Input file is ${file.video_codec_name}. Hardware Decode not supported.\n`; } // Are we encoding to 10 bit? If so enable correct profile & pixel format. @@ -672,7 +683,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { // This is used if we have High10 or Main10 is enabled & odd format files. // SW decode and use standard -pix_fmt p010le extraArguments += '-profile:v main10 -pix_fmt p010le '; - response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; + response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n'; } else if (main10 === true) { // Pixel formate method when using HW decode if (inputs.extra_qsv_options.search('-vf scale_qsv') >= 0) { extraArguments += '-profile:v main10'; @@ -681,23 +692,23 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } else { extraArguments += '-profile:v main10 -vf scale_qsv=format=p010le'; } - response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n'; + response.infoLog += '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n'; } } else { // Mac - Video toolbox profile & pixel format extraArguments += '-profile:v 2 -pix_fmt yuv420p10le '; - response.infoLog += '10 bit encode enabled. Setting VideoToolBox Profile v2 & 10 bit pixel format \n'; + response.infoLog += '10 bit encode enabled. Setting VideoToolBox Profile v2 & 10 bit pixel format\n'; } // Set bitrateSettings variable using bitrate information calculated earlier. bitrateSettings = `-b:v ${targetBitrate}k -minrate ${minimumBitrate}k ` + `-maxrate ${maximumBitrate}k -bufsize ${currentBitrate}k`; // Print to infoLog information around file & bitrate settings. - response.infoLog += `Container for output selected as ${inputs.container}. \n`; - response.infoLog += 'Encode variable bitrate settings: \n'; - response.infoLog += `Target = ${targetBitrate}k \n`; - response.infoLog += `Minimum = ${minimumBitrate}k \n`; - response.infoLog += `Maximum = ${maximumBitrate}k \n`; + response.infoLog += `Container for output selected as ${inputs.container}.\n` + + 'Encode variable bitrate settings:\n' + + `Target = ${targetBitrate}k\n` + + `Minimum = ${minimumBitrate}k\n` + + `Maximum = ${maximumBitrate}k\n`; // START PRESET // -fflags +genpts should regenerate timestamps if they end up missing... @@ -712,12 +723,12 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { response.preset += '-hwaccel videotoolbox'; break; case 'linux': // Linux - Full device, should fix child_device_type warnings - response.preset += `-hwaccel qsv -hwaccel_output_format qsv - -init_hw_device qsv:hw_any,child_device_type=vaapi `; + response.preset += '-hwaccel qsv -hwaccel_output_format qsv ' + + '-init_hw_device qsv:hw_any,child_device_type=vaapi '; break; case 'win32': // Windows - Full device, should fix child_device_type warnings - response.preset += `-hwaccel qsv -hwaccel_output_format qsv - -init_hw_device qsv:hw,child_device_type=d3d11va `; + response.preset += '-hwaccel qsv -hwaccel_output_format qsv ' + + '-init_hw_device qsv:hw,child_device_type=d3d11va '; break; default: 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'; break; case 'linux': // Linux - Full device, should fix child_device_type warnings - response.preset += `-hwaccel_output_format qsv - -init_hw_device qsv:hw_any,child_device_type=vaapi `; + response.preset += '-hwaccel_output_format qsv ' + + '-init_hw_device qsv:hw_any,child_device_type=vaapi '; break; case 'win32': // Windows - Full device, should fix child_device_type warnings - response.preset += `-hwaccel_output_format qsv - -init_hw_device qsv:hw,child_device_type=d3d11va `; + response.preset += '-hwaccel_output_format qsv ' + + '-init_hw_device qsv:hw,child_device_type=d3d11va '; break; default: // Default to enabling hwaccel for output only @@ -891,7 +902,7 @@ const plugin = (file, librarySettings, inputs, otherArguments) => { } response.processFile = true; - response.infoLog += 'File Transcoding... \n'; + response.infoLog += 'File Transcoding...\n'; return response; }; diff --git a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js index 64c6120..7b0e8e9 100644 --- a/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js +++ b/tests/Community/Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC.js @@ -14,34 +14,32 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, darwin: { @@ -50,15 +48,15 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\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', + + 'File Transcoding...\n', container: '.mkv', }, }, @@ -78,36 +76,34 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mp4', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mp4', }, darwin: { @@ -117,16 +113,16 @@ const tests = [ FFmpegMode: true, reQueueAfter: true, infoLog: 'Input file is not MKV so cannot use mkvpropedit to get new file stats. Continuing but file stats will likely be inaccurate...\n' - + '☑ It looks like the current video bitrate is 1206kbps. \n' - + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' + + '☑ It looks like the current video bitrate is 1206kbps.\n' + + '10 bit encode enabled. Setting Main10 Profile & 10 bit pixel format\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\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', + + 'File Transcoding...\n', container: '.mp4', }, }, @@ -149,38 +145,36 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=vaapi -c:v h264 -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=vaapi -c:v h264 -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Input file is h264 High10. Hardware Decode not supported. \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 = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Input file is h264 High10. Hardware Decode not supported.\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 = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mkv', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264 -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264 -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Input file is h264 High10. Hardware Decode not supported. \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 = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Input file is h264 High10. Hardware Decode not supported.\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 = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mkv', }, darwin: { @@ -189,17 +183,17 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems. \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 = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Input file is 10bit using High10. Disabling hardware decoding to avoid problems.\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 = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\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', + + 'File Transcoding...\n', container: '.mkv', }, }, @@ -226,39 +220,37 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v hevc_qsv -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, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' - + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' - + '☒ The file is still above this new cutoff! Reconverting. \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', + infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps.\n' + + '☒ The file is still above this new cutoff! Reconverting.\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 \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v hevc_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' - + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' - + '☒ The file is still above this new cutoff! Reconverting. \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', + infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps.\n' + + '☒ The file is still above this new cutoff! Reconverting.\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: { @@ -267,18 +259,18 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 12000kbps. \n' - + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' - + '☒ The file is still above this new cutoff! Reconverting. \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' + infoLog: '☑ It looks like the current video bitrate is 12000kbps.\n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps.\n' + + '☒ The file is still above this new cutoff! Reconverting.\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', + + 'File Transcoding...\n', container: '.mkv', }, }, @@ -309,9 +301,9 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 5000kbps. \n' - + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps. \n' - + '☑ The file is NOT above this new cutoff. Exiting plugin. \n', + infoLog: '☑ It looks like the current video bitrate is 5000kbps.\n' + + 'Reconvert_hevc is true & the file is already HEVC, VP9 or AV1. Using HEVC specific cutoff of 6000kbps.\n' + + '☑ The file is NOT above this new cutoff. Exiting plugin.\n', container: '.mkv', }, }, @@ -337,34 +329,32 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mp4', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mp4', }, darwin: { @@ -373,13 +363,13 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mp4. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mp4.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mp4', }, }, @@ -405,34 +395,32 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mkv', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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 ', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mkv', }, darwin: { @@ -441,13 +429,13 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 6454kbps. \n' - + 'Container for output selected as mkv. \n' - + 'Encode variable bitrate settings: \n' - + 'Target = 3227k \n' - + 'Minimum = 2420k \n' - + 'Maximum = 4034k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 6454kbps.\n' + + 'Container for output selected as mkv.\n' + + 'Encode variable bitrate settings:\n' + + 'Target = 3227k\n' + + 'Minimum = 2420k\n' + + 'Maximum = 4034k\n' + + 'File Transcoding...\n', container: '.mkv', }, }, @@ -468,36 +456,34 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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', + preset: '-fflags +genpts -hwaccel qsv -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v h264_qsv -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, darwin: { @@ -506,16 +492,16 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\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', + + 'File Transcoding...\n', container: '.mkv', }, }, @@ -539,37 +525,35 @@ const tests = [ output: { linux: { processFile: true, - preset: '-fflags +genpts -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v vc1 -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw_any,child_device_type=vaapi -c:v vc1 -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, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + 'Input file is vc1. Hardware Decode not supported. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + 'Input file is vc1. Hardware Decode not supported.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, win32: { processFile: true, - preset: '-fflags +genpts -hwaccel_output_format qsv \n' - + ' -init_hw_device qsv:hw,child_device_type=d3d11va -c:v vc1 -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 ', + preset: '-fflags +genpts -hwaccel_output_format qsv -init_hw_device qsv:hw,child_device_type=d3d11va -c:v vc1 -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, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \n' - + 'Input file is vc1. Hardware Decode not supported. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' - + 'File Transcoding... \n', + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\n' + + 'Input file is vc1. Hardware Decode not supported.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\n' + + 'File Transcoding...\n', container: '.mkv', }, darwin: { @@ -578,16 +562,93 @@ const tests = [ handBrakeMode: false, FFmpegMode: true, reQueueAfter: true, - infoLog: '☑ It looks like the current video bitrate is 1206kbps. \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 = 603k \n' - + 'Minimum = 452k \n' - + 'Maximum = 754k \n' + infoLog: '☑ It looks like the current video bitrate is 1206kbps.\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 = 603k\n' + + 'Minimum = 452k\n' + + 'Maximum = 754k\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', + + 'File Transcoding...\n', + container: '.mkv', + }, + }, + }, + // 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 -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 -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 -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', }, },