add basic settings for hevc_nvenc

This commit is contained in:
matty 2024-04-14 14:39:10 -04:00
parent d82f43cea5
commit 17eafa8872
1 changed files with 115 additions and 37 deletions

152
dist/main.js vendored
View File

@ -5,7 +5,9 @@ let logger;
let transcodingManager; let transcodingManager;
const DEFAULT_HARDWARE_DECODE = false; const DEFAULT_HARDWARE_DECODE = false;
const DEFAULT_VOD_QUALITY = "p7"; const DEFAULT_VOD_QUALITY = "p7";
const DEFAULT_HEVC_PROFILE = "main10";
const DEFAULT_LIVE_QUALITY = "hq"; const DEFAULT_LIVE_QUALITY = "hq";
const DEFAULT_HEVC_ENABLED = false;
const DEFAULT_BITRATES = new Map([ const DEFAULT_BITRATES = new Map([
[0, 64 * 1000], [0, 64 * 1000],
[144, 320 * 1000], [144, 320 * 1000],
@ -20,6 +22,8 @@ let pluginSettings = {
hardwareDecode: DEFAULT_HARDWARE_DECODE, hardwareDecode: DEFAULT_HARDWARE_DECODE,
vodQuality: DEFAULT_VOD_QUALITY, vodQuality: DEFAULT_VOD_QUALITY,
liveQuality: DEFAULT_LIVE_QUALITY, liveQuality: DEFAULT_LIVE_QUALITY,
hevcEnabled: DEFAULT_HEVC_ENABLED,
hevcProfile: DEFAULT_HEVC_PROFILE,
baseBitrate: new Map(DEFAULT_BITRATES) baseBitrate: new Map(DEFAULT_BITRATES)
}; };
let latestStreamNum = 9999; let latestStreamNum = 9999;
@ -42,6 +46,14 @@ async function register({ settingsManager, peertubeHelpers, transcodingManager:
default: DEFAULT_HARDWARE_DECODE, default: DEFAULT_HARDWARE_DECODE,
private: false private: false
}); });
registerSetting({
name: 'hevc-encode',
label: 'Enable H265 NVENC',
type: 'input-checkbox',
descriptionHTML: 'Enables H265 NVENC (experimental)',
default: DEFAULT_HEVC_ENABLED,
private: false
});
registerSetting({ registerSetting({
name: 'vod-quality', name: 'vod-quality',
label: 'VOD Quality', label: 'VOD Quality',
@ -59,6 +71,19 @@ async function register({ settingsManager, peertubeHelpers, transcodingManager:
default: DEFAULT_VOD_QUALITY.toString(), default: DEFAULT_VOD_QUALITY.toString(),
private: false private: false
}); });
registerSetting({
name: 'hevc-profile',
label: 'HEVC Profile',
type: 'select',
options: [
{ label: 'main', value: 'main' },
{ label: 'main10 (default)', value: 'main10' },
{ label: 'rext', value: 'rext' }
],
descriptionHTML: 'Set the HEVC profile',
default: DEFAULT_VOD_QUALITY.toString(),
private: false
});
registerSetting({ registerSetting({
name: 'live-quality', name: 'live-quality',
label: 'Live Quality', label: 'Live Quality',
@ -106,6 +131,8 @@ async function loadSettings(settingsManager) {
pluginSettings.hardwareDecode = await settingsManager.getSetting('hardware-decode') == "true"; pluginSettings.hardwareDecode = await settingsManager.getSetting('hardware-decode') == "true";
pluginSettings.vodQuality = parseInt(await settingsManager.getSetting('vod-quality')) || DEFAULT_VOD_QUALITY; pluginSettings.vodQuality = parseInt(await settingsManager.getSetting('vod-quality')) || DEFAULT_VOD_QUALITY;
pluginSettings.liveQuality = parseInt(await settingsManager.getSetting('live-quality')) || DEFAULT_LIVE_QUALITY; pluginSettings.liveQuality = parseInt(await settingsManager.getSetting('live-quality')) || DEFAULT_LIVE_QUALITY;
pluginSettings.hevcProfile = parseInt(await settingsManager.getSetting('hevc-profile')) || DEFAULT_HEVC_PROFILE;
pluginSettings.hevcEnabled = parseInt(await settingsManager.getSetting('hevc-encode')) || DEFAULT_HEVC_ENABLED;
for (const [resolution, bitrate] of DEFAULT_BITRATES) { for (const [resolution, bitrate] of DEFAULT_BITRATES) {
const key = `base-bitrate-${resolution}`; const key = `base-bitrate-${resolution}`;
const storedValue = await settingsManager.getSetting(key); const storedValue = await settingsManager.getSetting(key);
@ -115,6 +142,8 @@ async function loadSettings(settingsManager) {
logger.info(`Hardware decode: ${pluginSettings.hardwareDecode}`); logger.info(`Hardware decode: ${pluginSettings.hardwareDecode}`);
logger.info(`VOD Quality: ${pluginSettings.vodQuality}`); logger.info(`VOD Quality: ${pluginSettings.vodQuality}`);
logger.info(`Live Quality: ${pluginSettings.liveQuality}`); logger.info(`Live Quality: ${pluginSettings.liveQuality}`);
logger.info(`HEVC encode: ${pluginSettings.hevcEnabled}`);
logger.info(`HEVC profile: ${pluginSettings.hevcProfile}`);
} }
function printResolution(resolution) { function printResolution(resolution) {
switch (resolution) { switch (resolution) {
@ -150,29 +179,53 @@ async function vodBuilder(params) {
// let targetBitrate = inputBitrate; // let targetBitrate = inputBitrate;
let shouldInitVaapi = (streamNum == undefined || streamNum <= latestStreamNum); let shouldInitVaapi = (streamNum == undefined || streamNum <= latestStreamNum);
if (targetBitrate > inputBitrate) { if (targetBitrate > inputBitrate) {
targetBitrate = inputBitrate; targetBitrate = inputBitrate;
} }
logger.info(`Building encoder options, received ${JSON.stringify(params)}`); logger.info(`Building encoder options, received ${JSON.stringify(params)}`);
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
let options = { let options = {};
scaleFilter: { if (pluginSettings.hevcEnabled) {
name: 'scale'
}, options = {
inputOptions: shouldInitVaapi ? buildInitOptions() : [], scaleFilter: {
outputOptions: [ name: 'scale'
`-preset ${pluginSettings.vodQuality}`, },
`-b:v${streamSuffix} ${targetBitrate}`, inputOptions: shouldInitVaapi ? buildInitOptions() : [],
//`-b:v${streamSuffix} 0`, outputOptions: [
`-bufsize ${targetBitrate * 2}`, `-preset ${pluginSettings.hevcQuality}`,
`-profile:v${streamSuffix} high`, `-b:v${streamSuffix} ${targetBitrate}`,
`-cq 25`, //`-b:v${streamSuffix} 0`,
//`-rc vbr`, `-bufsize ${targetBitrate * 2}`,
//`-c:v${streamSuffix} h264_nvenc`, `-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`,
`-bf 4` //`-cq 25`,
] //`-rc vbr`,
}; `-c:v${streamSuffix} hevc_nvenc`,
//`-bf 4`
]
};
} else {
options = {
scaleFilter: {
name: 'scale'
},
inputOptions: shouldInitVaapi ? buildInitOptions() : [],
outputOptions: [
`-preset ${pluginSettings.vodQuality}`,
`-b:v${streamSuffix} ${targetBitrate}`,
//`-b:v${streamSuffix} 0`,
`-bufsize ${targetBitrate * 2}`,
`-profile:v${streamSuffix} high`,
`-cq 25`,
//`-rc vbr`,
//`-c:v${streamSuffix} h264_nvenc`,
`-bf 4`
]
};
}
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}`);
return options; return options;
} }
@ -189,25 +242,50 @@ async function liveBuilder(params) {
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
const options = {
scaleFilter: { let options = {};
name: 'scale'
}, if (pluginSettings.hevcEnabled) {
inputOptions: shouldInitVaapi ? buildInitOptions() : [], options = {
outputOptions: [ scaleFilter: {
`-tune ${pluginSettings.liveQuality}`, name: 'scale'
`-r:v${streamSuffix} ${fps}`, },
`-profile:v${streamSuffix} high`, inputOptions: shouldInitVaapi ? buildInitOptions() : [],
//`-c:v${streamSuffix} h264_nvenc`, outputOptions: [
`-cq 25`, `-tune ${pluginSettings.liveQuality}`,
`-g:v${streamSuffix} ${fps * 2}`, `-r:v${streamSuffix} ${fps}`,
`-b:v${streamSuffix} ${targetBitrate}`, `-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`,
//`-b:v${streamSuffix} 0`, `-c:v${streamSuffix} hevc_nvenc`,
`-bufsize ${targetBitrate * 2}`, //`-cq 25`,
//`-rc vbr`, `-g:v${streamSuffix} ${fps * 2}`,
`-bf 4` `-b:v${streamSuffix} ${targetBitrate}`,
] //`-b:v${streamSuffix} 0`,
}; `-bufsize ${targetBitrate * 2}`,
//`-rc vbr`,
// `-bf 4`
]
};
} else {
options = {
scaleFilter: {
name: 'scale'
},
inputOptions: shouldInitVaapi ? buildInitOptions() : [],
outputOptions: [
`-tune ${pluginSettings.liveQuality}`,
`-r:v${streamSuffix} ${fps}`,
`-profile:v${streamSuffix} high`,
`-cq 25`,
`-g:v${streamSuffix} ${fps * 2}`,
`-b:v${streamSuffix} ${targetBitrate}`,
`-bufsize ${targetBitrate * 2}`,
//`-rc vbr`,
`-bf 4`
]
};
}
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}`);
return options; return options;
} }