diff --git a/src/misc/coders/Encoders/index.js b/src/misc/coders/Encoders/index.js
index e6bf7ee..17b8a30 100644
--- a/src/misc/coders/Encoders/index.js
+++ b/src/misc/coders/Encoders/index.js
@@ -18,6 +18,7 @@ import * as H264V4L2M2M from './video/h264_v4l2m2m';
import * as H264VAAPI from './video/h264_vaapi';
import * as HEVCVAAPI from './video/hevc_vaapi';
import * as HEVCVideoToolbox from './video/hevc_videotoolbox';
+import * as HEVCNVENC from './video/hevc_nvenc';
import * as VP9VPX from './video/vp9_libvpx';
import * as VP9VAAPI from './video/vp9_vaapi';
import * as VideoCopy from './video/copy';
@@ -25,6 +26,7 @@ import * as VideoNone from './video/none';
import * as VideoRaw from './video/rawvideo';
import * as AV1Rav1e from './video/av1_librav1e';
import * as AV1AOM from './video/av1_libaom';
+import * as AV1NVENC from './video/av1_nvenc';
class Registry {
constructor(type) {
@@ -136,10 +138,12 @@ videoRegistry.Register(H264VAAPI);
videoRegistry.Register(X265);
videoRegistry.Register(HEVCVAAPI);
videoRegistry.Register(HEVCVideoToolbox);
+videoRegistry.Register(HEVCNVENC);
videoRegistry.Register(VP9VPX);
videoRegistry.Register(VP9VAAPI);
videoRegistry.Register(AV1AOM);
videoRegistry.Register(AV1Rav1e);
+videoRegistry.Register(AV1NVENC);
videoRegistry.Register(VideoRaw);
export { audioRegistry as Audio, videoRegistry as Video };
diff --git a/src/misc/coders/Encoders/video/av1_nvenc.js b/src/misc/coders/Encoders/video/av1_nvenc.js
new file mode 100644
index 0000000..2fbc208
--- /dev/null
+++ b/src/misc/coders/Encoders/video/av1_nvenc.js
@@ -0,0 +1,222 @@
+import React from 'react';
+
+import Grid from '@mui/material/Grid';
+import MenuItem from '@mui/material/MenuItem';
+
+import { Trans } from '@lingui/macro';
+
+import Select from '../../../Select';
+import Video from '../../settings/Video';
+import Helper from '../../helper';
+
+function init(initialState) {
+ const state = {
+ bitrate: '4096',
+ fps: '25',
+ gop: '2',
+ preset: 'p4',
+ tune: 'll',
+ level: 'auto',
+ rc: 'auto',
+ ...initialState,
+ };
+
+ return state;
+}
+
+function createMapping(settings, stream, skills) {
+ stream = Helper.InitStream(stream);
+ skills = Helper.InitSkills(skills);
+
+ const local = [
+ '-codec:v',
+ 'av1_nvenc',
+ '-preset:v',
+ `${settings.preset}`,
+ '-tune:v',
+ `${settings.tune}`,
+ '-b:v',
+ `${settings.bitrate}k`,
+ '-maxrate',
+ `${settings.bitrate}k`,
+ '-bufsize',
+ `${settings.bitrate}k`,
+ '-r',
+ `${settings.fps}`,
+ '-pix_fmt',
+ 'yuv420p',
+ ];
+
+ if (settings.gop !== 'auto') {
+ local.push('-g', `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`);
+ }
+
+ if (settings.level !== 'auto') {
+ local.push('-level:v', `${settings.level}`);
+ }
+
+ if (settings.rc !== 'auto') {
+ local.push('-rc:v', `${settings.rc}`);
+ }
+
+ const mapping = {
+ global: [],
+ local: local,
+ filter: [],
+ };
+
+ return mapping;
+}
+
+function Preset({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Tune({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Level({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function RateControl({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Coder({ stream = {}, settings = {}, skills = {}, onChange = function (settings, mapping) {} }) {
+ settings = init(settings);
+ stream = Helper.InitStream(stream);
+ skills = Helper.InitSkills(skills);
+
+ const handleChange = (newSettings) => {
+ let automatic = false;
+ if (!newSettings) {
+ newSettings = settings;
+ automatic = true;
+ }
+
+ onChange(newSettings, createMapping(newSettings, stream, skills), automatic);
+ };
+
+ const update = (what) => (event) => {
+ const newSettings = {
+ ...settings,
+ [what]: event.target.value,
+ };
+
+ handleChange(newSettings);
+ };
+
+ React.useEffect(() => {
+ handleChange(null);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const coder = 'av1_nvenc';
+const name = 'AV1 (NVENC)';
+const codec = 'av1';
+const type = 'video';
+const hwaccel = true;
+
+function summarize(settings) {
+ return `${name}, ${settings.bitrate} kbit/s, ${settings.fps} FPS, Profile: ${settings.profile}`;
+}
+
+function defaults(stream, skills) {
+ const settings = init({});
+
+ return {
+ settings: settings,
+ mapping: createMapping(settings, stream, skills),
+ };
+}
+
+export { coder, name, codec, type, hwaccel, summarize, defaults, Coder as component };
diff --git a/src/misc/coders/Encoders/video/h264_nvenc.js b/src/misc/coders/Encoders/video/h264_nvenc.js
index f8bf818..db2c1e5 100644
--- a/src/misc/coders/Encoders/video/h264_nvenc.js
+++ b/src/misc/coders/Encoders/video/h264_nvenc.js
@@ -14,7 +14,8 @@ function init(initialState) {
bitrate: '4096',
fps: '25',
gop: '2',
- preset: 'medium',
+ preset: 'p4',
+ tune: 'll',
profile: 'auto',
level: 'auto',
rc: 'auto',
@@ -33,6 +34,8 @@ function createMapping(settings, stream, skills) {
'h264_nvenc',
'-preset:v',
`${settings.preset}`,
+ '-tune:v',
+ `${settings.tune}`,
'-b:v',
`${settings.bitrate}k`,
'-maxrate',
@@ -73,19 +76,24 @@ function createMapping(settings, stream, skills) {
function Preset({ value = '', onChange = function (event) {} }) {
return (
+ );
+}
+
+function Tune({ value = '', onChange = function (event) {} }) {
+ return (
+
);
}
@@ -139,9 +147,6 @@ function RateControl({ value = '', onChange = function (event) {} }) {
-
-
-
);
}
@@ -189,6 +194,9 @@ function Coder({ stream = {}, settings = {}, skills = {}, onChange = function (s
+
+
+
diff --git a/src/misc/coders/Encoders/video/hevc_nvenc.js b/src/misc/coders/Encoders/video/hevc_nvenc.js
new file mode 100644
index 0000000..e51f3ab
--- /dev/null
+++ b/src/misc/coders/Encoders/video/hevc_nvenc.js
@@ -0,0 +1,229 @@
+import React from 'react';
+
+import Grid from '@mui/material/Grid';
+import MenuItem from '@mui/material/MenuItem';
+
+import { Trans } from '@lingui/macro';
+
+import Select from '../../../Select';
+import Video from '../../settings/Video';
+import Helper from '../../helper';
+
+function init(initialState) {
+ const state = {
+ bitrate: '4096',
+ fps: '25',
+ gop: '2',
+ preset: 'p4',
+ tune: 'll',
+ profile: 'auto',
+ level: 'auto',
+ rc: 'auto',
+ ...initialState,
+ };
+
+ return state;
+}
+
+function createMapping(settings, stream, skills) {
+ stream = Helper.InitStream(stream);
+ skills = Helper.InitSkills(skills);
+
+ const local = [
+ '-codec:v',
+ 'hevc_nvenc',
+ '-preset:v',
+ `${settings.preset}`,
+ '-tune:v',
+ `${settings.tune}`,
+ '-b:v',
+ `${settings.bitrate}k`,
+ '-maxrate',
+ `${settings.bitrate}k`,
+ '-bufsize',
+ `${settings.bitrate}k`,
+ '-r',
+ `${settings.fps}`,
+ '-pix_fmt',
+ 'yuv420p',
+ ];
+
+ if (settings.gop !== 'auto') {
+ local.push('-g', `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`);
+ }
+
+ if (settings.profile !== 'auto') {
+ local.push('-profile:v', `${settings.profile}`);
+ }
+
+ if (settings.level !== 'auto') {
+ local.push('-level:v', `${settings.level}`);
+ }
+
+ if (settings.rc !== 'auto') {
+ local.push('-rc:v', `${settings.rc}`);
+ }
+
+ const mapping = {
+ global: [],
+ local: local,
+ filter: [],
+ };
+
+ return mapping;
+}
+
+function Preset({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Tune({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Profile({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Level({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function RateControl({ value = '', onChange = function (event) {} }) {
+ return (
+
+ );
+}
+
+function Coder({ stream = {}, settings = {}, skills = {}, onChange = function (settings, mapping) {} }) {
+ settings = init(settings);
+ stream = Helper.InitStream(stream);
+ skills = Helper.InitSkills(skills);
+
+ const handleChange = (newSettings) => {
+ let automatic = false;
+ if (!newSettings) {
+ newSettings = settings;
+ automatic = true;
+ }
+
+ onChange(newSettings, createMapping(newSettings, stream, skills), automatic);
+ };
+
+ const update = (what) => (event) => {
+ const newSettings = {
+ ...settings,
+ [what]: event.target.value,
+ };
+
+ handleChange(newSettings);
+ };
+
+ React.useEffect(() => {
+ handleChange(null);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const coder = 'hevc_nvenc';
+const name = 'HEVC (NVENC)';
+const codec = 'hevc';
+const type = 'video';
+const hwaccel = true;
+
+function summarize(settings) {
+ return `${name}, ${settings.bitrate} kbit/s, ${settings.fps} FPS, Profile: ${settings.profile}`;
+}
+
+function defaults(stream, skills) {
+ const settings = init({});
+
+ return {
+ settings: settings,
+ mapping: createMapping(settings, stream, skills),
+ };
+}
+
+export { coder, name, codec, type, hwaccel, summarize, defaults, Coder as component };