5 Commits

Author SHA1 Message Date
96ececa3f1 add h264 profile picker 2024-04-15 19:57:26 -04:00
f81fa92956 fix issue with hevc profile selection 2024-04-14 16:36:23 -04:00
e7ff13c14b bump version 2024-04-14 16:32:30 -04:00
805d3eb702 remove hevc profile enablement - no longer needed 2024-04-14 16:32:11 -04:00
7314c18ca4 add ability to do that young -cq shit nigga 2024-04-14 16:12:26 -04:00
2 changed files with 58 additions and 28 deletions

84
dist/main.js vendored
View File

@ -5,9 +5,11 @@ 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_HEVC_PROFILE = "main";
const DEFAULT_LIVE_QUALITY = "hq"; const DEFAULT_LIVE_QUALITY = "hq";
const DEFAULT_HEVC_ENABLED = false; const DEFAULT_CQ_H264 = 26;
const DEFAULT_CQ_HEVC = 28;
const DEFAULT_H264_PROFILE = "main";
const DEFAULT_BITRATES = new Map([ const DEFAULT_BITRATES = new Map([
[0, 64 * 1000], [0, 64 * 1000],
[144, 320 * 1000], [144, 320 * 1000],
@ -22,8 +24,10 @@ 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, hevcProfile: DEFAULT_HEVC_PROFILE,
cqH264: DEFAULT_CQ_H264,
cqHEVC: DEFAULT_CQ_HEVC,
h264Profile: DEFAULT_H264_PROFILE,
baseBitrate: new Map(DEFAULT_BITRATES) baseBitrate: new Map(DEFAULT_BITRATES)
}; };
let latestStreamNum = 9999; let latestStreamNum = 9999;
@ -56,11 +60,19 @@ async function register({ settingsManager, peertubeHelpers, transcodingManager:
private: false private: false
}); });
registerSetting({ registerSetting({
name: 'hevc-enabled', name: 'cq-h264',
label: 'Enable H265 NVENC', label: 'CQ Value for H264_nvenc',
type: 'input-checkbox', type: 'input',
descriptionHTML: 'Enables H265 NVENC (experimental)', descriptionHTML: 'Sets the -cq value for h264_nvenc encoder. Valid values are between 0 and 51 (lossess and AIDS, respectively)',
default: DEFAULT_HEVC_ENABLED, default: DEFAULT_CQ_H264,
private: false
});
registerSetting({
name: 'cq-hevc',
label: 'CQ Value for hevc_nvenc',
type: 'input',
descriptionHTML: 'Sets the -cq value for hevc_nvenc encoder. Valid values are between 0 and 51 (lossess and AIDS, respectively)',
default: DEFAULT_CQ_HEVC,
private: false private: false
}); });
registerSetting({ registerSetting({
@ -85,14 +97,27 @@ async function register({ settingsManager, peertubeHelpers, transcodingManager:
label: 'HEVC Profile', label: 'HEVC Profile',
type: 'select', type: 'select',
options: [ options: [
{ label: 'main', value: 'main' }, { label: 'main (default)', value: 'main' },
{ label: 'main10 (default)', value: 'main10' }, { label: 'main10', value: 'main10' },
{ label: 'rext', value: 'rext' } { label: 'rext', value: 'rext' }
], ],
descriptionHTML: 'Set the HEVC profile', descriptionHTML: 'Set the HEVC profile',
default: DEFAULT_HEVC_PROFILE.toString(), default: DEFAULT_HEVC_PROFILE.toString(),
private: false private: false
}); });
registerSetting({
name: 'h264-profile',
label: 'H264 Profile',
type: 'select',
options: [
{ label: 'main (default)', value: 'main' },
{ label: 'high', value: 'high' },
{ label: 'high444p', value: 'high444p' }
],
descriptionHTML: 'Set the H264 profile',
default: DEFAULT_H264_PROFILE.toString(),
private: false
});
registerSetting({ registerSetting({
name: 'live-quality', name: 'live-quality',
label: 'Live Quality', label: 'Live Quality',
@ -138,10 +163,13 @@ async function unregister() {
exports.unregister = unregister; exports.unregister = unregister;
async function loadSettings(settingsManager) { async function loadSettings(settingsManager) {
pluginSettings.hardwareDecode = await settingsManager.getSetting('hardware-decode') || DEFAULT_HARDWARE_DECODE; pluginSettings.hardwareDecode = await settingsManager.getSetting('hardware-decode') || DEFAULT_HARDWARE_DECODE;
pluginSettings.vodQuality = parseInt(await settingsManager.getSetting('vod-quality')) || DEFAULT_VOD_QUALITY; pluginSettings.vodQuality = await settingsManager.getSetting('vod-quality') || DEFAULT_VOD_QUALITY;
pluginSettings.liveQuality = parseInt(await settingsManager.getSetting('live-quality')) || DEFAULT_LIVE_QUALITY; pluginSettings.liveQuality = await settingsManager.getSetting('live-quality') || DEFAULT_LIVE_QUALITY;
pluginSettings.hevcProfile = parseInt(await settingsManager.getSetting('hevc-profile')) || DEFAULT_HEVC_PROFILE; pluginSettings.hevcProfile = await settingsManager.getSetting('hevc-profile') || DEFAULT_HEVC_PROFILE;
pluginSettings.hevcEnabled = await settingsManager.getSetting('hevc-enabled') || DEFAULT_HEVC_ENABLED; pluginSettings.cqH264 = parseInt(await settingsManager.getSetting('cq-h264')) || DEFAULT_CQ_H264;
pluginSettings.cqHEVC = parseInt(await settingsManager.getSetting('cq-hevc')) || DEFAULT_CQ_HEVC;
pluginSettings.h264Profile = await settingsManager.getSetting('h264-profile') || DEFAULT_H264_PROFILE;
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);
@ -151,8 +179,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 enabled: ${pluginSettings.hevcEnabled}`);
logger.info(`HEVC profile: ${pluginSettings.hevcProfile}`); logger.info(`HEVC profile: ${pluginSettings.hevcProfile}`);
logger.info(`H264 profile: ${pluginSettings.h264Profile}`);
} }
function printResolution(resolution) { function printResolution(resolution) {
switch (resolution) { switch (resolution) {
@ -193,7 +221,7 @@ async function vodBuilder(params) {
if (targetBitrate > inputBitrate) { if (targetBitrate > inputBitrate) {
targetBitrate = inputBitrate; targetBitrate = inputBitrate;
} }
logger.info(`Building encoder options, received ${JSON.stringify(params)}, HEVC: ${pluginSettings.hevcEnabled}`); logger.info(`Building encoder options, received ${JSON.stringify(params)}`);
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
@ -206,13 +234,13 @@ async function vodBuilder(params) {
`-preset ${pluginSettings.vodQuality}`, `-preset ${pluginSettings.vodQuality}`,
`-b:v${streamSuffix} ${targetBitrate}`, `-b:v${streamSuffix} ${targetBitrate}`,
`-bufsize ${targetBitrate * 2}`, `-bufsize ${targetBitrate * 2}`,
`-profile:v${streamSuffix} high`, `-profile:v${streamSuffix} ${pluginSettings.h264Profile}`,
`-cq 25`, `-cq ${pluginSettings.cqH264}`,
`-bf 4` `-bf 4`
] ]
}; };
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}, HEVC: false`);
return options; return options;
} }
@ -226,7 +254,7 @@ async function hevcVODBuilder(params) {
if (targetBitrate > inputBitrate) { if (targetBitrate > inputBitrate) {
targetBitrate = inputBitrate; targetBitrate = inputBitrate;
} }
logger.info(`Building encoder options, received ${JSON.stringify(params)}, HEVC: ${pluginSettings.hevcEnabled}`); logger.info(`Building encoder options, received ${JSON.stringify(params)}`);
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
@ -240,10 +268,11 @@ async function hevcVODBuilder(params) {
`-b:v${streamSuffix} ${targetBitrate}`, `-b:v${streamSuffix} ${targetBitrate}`,
`-bufsize ${targetBitrate * 2}`, `-bufsize ${targetBitrate * 2}`,
`-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`, `-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`,
`-cq ${pluginSettings.cqHEVC}`
] ]
}; };
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}, HEVC: true`);
return options; return options;
} }
@ -259,7 +288,7 @@ async function hevcLiveBuilder(params) {
if (targetBitrate > inputBitrate) { if (targetBitrate > inputBitrate) {
targetBitrate = inputBitrate; targetBitrate = inputBitrate;
} }
logger.info(`Building encoder options, received ${JSON.stringify(params)}, HEVC: ${pluginSettings.hevcEnabled}`); logger.info(`Building encoder options, received ${JSON.stringify(params)}`);
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
@ -275,11 +304,12 @@ async function hevcLiveBuilder(params) {
`-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`, `-profile:v${streamSuffix} ${pluginSettings.hevcProfile}`,
`-g:v${streamSuffix} ${fps * 2}`, `-g:v${streamSuffix} ${fps * 2}`,
`-b:v${streamSuffix} ${targetBitrate}`, `-b:v${streamSuffix} ${targetBitrate}`,
`-cq ${pluginSettings.cqHEVC}`,
`-bufsize ${targetBitrate * 2}` `-bufsize ${targetBitrate * 2}`
] ]
}; };
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}, HEVC: true`);
return options; return options;
} }
@ -294,7 +324,7 @@ async function liveBuilder(params) {
if (targetBitrate > inputBitrate) { if (targetBitrate > inputBitrate) {
targetBitrate = inputBitrate; targetBitrate = inputBitrate;
} }
logger.info(`Building encoder options, received ${JSON.stringify(params)}, HEVC: ${pluginSettings.hevcEnabled}`); logger.info(`Building encoder options, received ${JSON.stringify(params)}`);
if (shouldInitVaapi && streamNum != undefined) { if (shouldInitVaapi && streamNum != undefined) {
latestStreamNum = streamNum; latestStreamNum = streamNum;
} }
@ -307,8 +337,8 @@ async function liveBuilder(params) {
outputOptions: [ outputOptions: [
`-tune ${pluginSettings.liveQuality}`, `-tune ${pluginSettings.liveQuality}`,
`-r:v${streamSuffix} ${fps}`, `-r:v${streamSuffix} ${fps}`,
`-profile:v${streamSuffix} high`, `-profile:v${streamSuffix} ${pluginSettings.h264Profile}`,
`-cq 25`, `-cq ${pluginSettings.cqH264}`,
`-g:v${streamSuffix} ${fps * 2}`, `-g:v${streamSuffix} ${fps * 2}`,
`-b:v${streamSuffix} ${targetBitrate}`, `-b:v${streamSuffix} ${targetBitrate}`,
`-bufsize ${targetBitrate * 2}`, `-bufsize ${targetBitrate * 2}`,
@ -316,7 +346,7 @@ async function liveBuilder(params) {
] ]
}; };
logger.info(`EncoderOptions: ${JSON.stringify(options)}`); logger.info(`EncoderOptions: ${JSON.stringify(options)}, HEVC: false`);
return options; return options;
} }
function getTargetBitrate(resolution, fps) { function getTargetBitrate(resolution, fps) {

View File

@ -1,6 +1,6 @@
{ {
"name": "peertube-plugin-nctv-nvenc-transcode", "name": "peertube-plugin-nctv-nvenc-transcode",
"version": "1.1.1", "version": "1.2.0",
"license": "MIT", "license": "MIT",
"description": "Plugin that adds transcode profiles which use NVIDIA NVENC for hardware acceleration", "description": "Plugin that adds transcode profiles which use NVIDIA NVENC for hardware acceleration",
"engine": { "engine": {