nvenc, amdvce: rework all user presets/options (#623)

This commit is contained in:
Conn O'Griofa
2022-12-28 02:27:47 +00:00
committed by GitHub
parent 05f5370efe
commit 215c86455f
5 changed files with 224 additions and 159 deletions

View File

@@ -824,27 +824,52 @@ nv_preset
========== ===========
Value Description
========== ===========
default let ffmpeg decide
hp high performance
hq high quality
slow high quality, 2 passes
medium high quality, 1 pass
fast high performance, 1 pass
bd
ll low latency
llhq low latency, high quality
llhp low latency, high performance
lossless lossless
losslesshp lossless, high performance
p1 fastest (lowest quality)
p2 faster (lower quality)
p3 fast (low quality)
p4 medium (default)
p5 slow (good quality)
p6 slower (better quality)
p7 slowest (best quality)
========== ===========
**Default**
``llhq``
``p4``
**Example**
.. code-block:: text
nv_preset = llhq
nv_preset = p4
nv_tune
^^^^^^^
**Description**
The encoder tuning profile.
.. Note:: This option only applies when using nvenc `encoder`_.
**Choices**
.. table::
:widths: auto
========== ===========
Value Description
========== ===========
hq high quality
ll low latency
ull ultra low latency
lossless lossless
========== ===========
**Default**
``ull``
**Example**
.. code-block:: text
nv_tune = ull
nv_rc
^^^^^
@@ -854,8 +879,6 @@ nv_rc
.. Note:: This option only applies when using nvenc `encoder`_.
.. Note:: Moonlight does not currently support variable bitrate, although it can still be selected here.
**Choices**
.. table::
@@ -864,22 +887,18 @@ nv_rc
========== ===========
Value Description
========== ===========
auto let ffmpeg decide
constqp constant QP mode
cbr constant bitrate
cbr_hq constant bitrate, high quality
cbr_ld_hq constant bitrate, low delay, high quality
vbr variable bitrate
vbr_hq variable bitrate, high quality
cbr constant bitrate
========== ===========
**Default**
``auto``
``cbr``
**Example**
.. code-block:: text
nv_rc = auto
nv_rc = cbr
nv_coder
^^^^^^^^
@@ -887,7 +906,7 @@ nv_coder
**Description**
The entropy encoding to use.
.. Note:: This option only applies when using nvenc `encoder`_.
.. Note:: This option only applies when using H264 with nvenc `encoder`_.
**Choices**
@@ -898,8 +917,8 @@ nv_coder
Value Description
========== ===========
auto let ffmpeg decide
cabac
cavlc
cabac context adaptive binary arithmetic coding - higher quality
cavlc context adaptive variable-length coding - faster decode
========== ===========
**Default**
@@ -926,9 +945,9 @@ amd_quality
========== ===========
Value Description
========== ===========
default let ffmpeg decide
speed fast
balanced balance performance and speed
speed prefer speed
balanced balanced
quality prefer quality
========== ===========
**Default**
@@ -947,8 +966,6 @@ amd_rc
.. Note:: This option only applies when using amdvce `encoder`_.
.. Note:: Moonlight does not currently support variable bitrate, although it can still be selected here.
**Choices**
.. table::
@@ -957,20 +974,19 @@ amd_rc
=========== ===========
Value Description
=========== ===========
auto let ffmpeg decide
cqp constant QP mode
cqp constant qp mode
cbr constant bitrate
vbr_latency variable bitrate, latency constrained
vbr_peak variable bitrate, peak constrained
=========== ===========
**Default**
``auto``
``vbr_latency``
**Example**
.. code-block:: text
amd_rc = auto
amd_rc = vbr_latency
amd_coder
^^^^^^^^^
@@ -978,7 +994,7 @@ amd_coder
**Description**
The entropy encoding to use.
.. Note:: This option only applies when using nvenc `encoder`_.
.. Note:: This option only applies when using H264 with amdvce `encoder`_.
**Choices**
@@ -989,8 +1005,8 @@ amd_coder
Value Description
========== ===========
auto let ffmpeg decide
cabac
cavlc
cabac context adaptive variable-length coding - higher quality
cavlc context adaptive binary arithmetic coding - faster decode
========== ===========
**Default**

View File

@@ -25,50 +25,71 @@ using namespace std::literals;
namespace config {
namespace nv {
#ifdef __APPLE__
// values accurate as of 27/12/2022, but aren't strictly necessary for MacOS build
#define NV_ENC_TUNING_INFO_HIGH_QUALITY 1
#define NV_ENC_TUNING_INFO_LOW_LATENCY 2
#define NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY 3
#define NV_ENC_TUNING_INFO_LOSSLESS 4
#define NV_ENC_PARAMS_RC_CONSTQP 0x0
#define NV_ENC_PARAMS_RC_VBR 0x1
#define NV_ENC_PARAMS_RC_CBR 0x2
#define NV_ENC_H264_ENTROPY_CODING_MODE_CABAC 1
#define NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC 2
#else
#include <ffnvcodec/nvEncodeAPI.h>
#endif
enum preset_e : int {
_default = 0,
slow,
medium,
fast,
hp,
hq,
bd,
ll_default,
llhq,
llhp,
lossless_default, // lossless presets must be the last ones
lossless_hp,
p1 = 12, // PRESET_P1, // must be kept in sync with <libavcodec/nvenc.h>
p2, // PRESET_P2,
p3, // PRESET_P3,
p4, // PRESET_P4,
p5, // PRESET_P5,
p6, // PRESET_P6,
p7 // PRESET_P7
};
enum tune_e : int {
hq = NV_ENC_TUNING_INFO_HIGH_QUALITY,
ll = NV_ENC_TUNING_INFO_LOW_LATENCY,
ull = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY,
lossless = NV_ENC_TUNING_INFO_LOSSLESS
};
enum rc_e : int {
constqp = 0x0, /**< Constant QP mode */
vbr = 0x1, /**< Variable bitrate mode */
cbr = 0x2, /**< Constant bitrate mode */
cbr_ld_hq = 0x8, /**< low-delay CBR, high quality */
cbr_hq = 0x10, /**< CBR, high quality (slower) */
vbr_hq = 0x20 /**< VBR, high quality (slower) */
constqp = NV_ENC_PARAMS_RC_CONSTQP, /**< Constant QP mode */
vbr = NV_ENC_PARAMS_RC_VBR, /**< Variable bitrate mode */
cbr = NV_ENC_PARAMS_RC_CBR /**< Constant bitrate mode */
};
enum coder_e : int {
_auto = 0,
cabac,
cavlc
cabac = NV_ENC_H264_ENTROPY_CODING_MODE_CABAC,
cavlc = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC,
};
std::optional<preset_e> preset_from_view(const std::string_view &preset) {
#define _CONVERT_(x) \
if(preset == #x##sv) return x
_CONVERT_(slow);
_CONVERT_(medium);
_CONVERT_(fast);
_CONVERT_(hp);
_CONVERT_(bd);
_CONVERT_(ll_default);
_CONVERT_(llhq);
_CONVERT_(llhp);
_CONVERT_(lossless_default);
_CONVERT_(lossless_hp);
if(preset == "default"sv) return _default;
_CONVERT_(p1);
_CONVERT_(p2);
_CONVERT_(p3);
_CONVERT_(p4);
_CONVERT_(p5);
_CONVERT_(p6);
_CONVERT_(p7);
#undef _CONVERT_
return std::nullopt;
}
std::optional<tune_e> tune_from_view(const std::string_view &tune) {
#define _CONVERT_(x) \
if(tune == #x##sv) return x
_CONVERT_(hq);
_CONVERT_(ll);
_CONVERT_(ull);
_CONVERT_(lossless);
#undef _CONVERT_
return std::nullopt;
}
@@ -79,9 +100,6 @@ std::optional<rc_e> rc_from_view(const std::string_view &rc) {
_CONVERT_(constqp);
_CONVERT_(vbr);
_CONVERT_(cbr);
_CONVERT_(cbr_hq);
_CONVERT_(vbr_hq);
_CONVERT_(cbr_ld_hq);
#undef _CONVERT_
return std::nullopt;
}
@@ -96,56 +114,75 @@ int coder_from_view(const std::string_view &coder) {
} // namespace nv
namespace amd {
enum quality_e : int {
_default = 0,
speed,
balanced,
#ifdef __APPLE__
// values accurate as of 27/12/2022, but aren't strictly necessary for MacOS build
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED 10
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY 0
#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED 5
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED 1
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY 2
#define AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED 0
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP 0
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR 3
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2
#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 1
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP 0
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR 1
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 2
#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 3
#define AMF_VIDEO_ENCODER_UNDEFINED 0
#define AMF_VIDEO_ENCODER_CABAC 1
#define AMF_VIDEO_ENCODER_CALV 2
#else
#include <AMF/components/VideoEncoderHEVC.h>
#include <AMF/components/VideoEncoderVCE.h>
#endif
enum class quality_hevc_e : int {
speed = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED,
quality = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY,
balanced = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED
};
enum class quality_h264_e : int {
speed = AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED,
quality = AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY,
balanced = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED
};
enum class rc_hevc_e : int {
cqp, /**< Constant QP mode */
vbr_latency, /**< Latency Constrained Variable Bitrate */
vbr_peak, /**< Peak Constrained Variable Bitrate */
cbr, /**< Constant bitrate mode */
cqp = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP,
vbr_latency = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
vbr_peak = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR
};
enum class rc_h264_e : int {
cqp, /**< Constant QP mode */
cbr, /**< Constant bitrate mode */
vbr_peak, /**< Peak Constrained Variable Bitrate */
vbr_latency, /**< Latency Constrained Variable Bitrate */
cqp = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP,
vbr_latency = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
vbr_peak = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR
};
enum coder_e : int {
_auto = 0,
cabac,
cavlc
_auto = AMF_VIDEO_ENCODER_UNDEFINED,
cabac = AMF_VIDEO_ENCODER_CABAC,
cavlc = AMF_VIDEO_ENCODER_CALV
};
std::optional<quality_e> quality_from_view(const std::string_view &quality) {
std::optional<int> quality_from_view(const std::string_view &quality_type, int codec) {
#define _CONVERT_(x) \
if(quality == #x##sv) return x
if(quality_type == #x##sv) return codec == 0 ? (int)quality_hevc_e::x : (int)quality_h264_e::x
_CONVERT_(quality);
_CONVERT_(speed);
_CONVERT_(balanced);
if(quality == "default"sv) return _default;
#undef _CONVERT_
return std::nullopt;
}
std::optional<int> rc_h264_from_view(const std::string_view &rc) {
std::optional<int> rc_from_view(const std::string_view &rc, int codec) {
#define _CONVERT_(x) \
if(rc == #x##sv) return (int)rc_h264_e::x
_CONVERT_(cqp);
_CONVERT_(vbr_latency);
_CONVERT_(vbr_peak);
_CONVERT_(cbr);
#undef _CONVERT_
return std::nullopt;
}
std::optional<int> rc_hevc_from_view(const std::string_view &rc) {
#define _CONVERT_(x) \
if(rc == #x##sv) return (int)rc_hevc_e::x
if(rc == #x##sv) return codec == 0 ? (int)rc_hevc_e::x : (int)rc_h264_e::x
_CONVERT_(cqp);
_CONVERT_(vbr_latency);
_CONVERT_(vbr_peak);
@@ -211,16 +248,19 @@ video_t video {
}, // software
{
nv::llhq,
std::nullopt,
-1 }, // nv
nv::p4, // preset
nv::ull, // tune
nv::cbr, // rc
nv::_auto // coder
}, // nv
{
amd::balanced,
std::nullopt,
std::nullopt,
-1 }, // amd
(int)amd::quality_h264_e::balanced, // quality (h264)
(int)amd::quality_hevc_e::balanced, // quality (hevc)
(int)amd::rc_h264_e::vbr_latency, // rate control (h264)
(int)amd::rc_hevc_e::vbr_latency, // rate control (hevc)
(int)amd::coder_e::_auto, // coder
}, // amd
{
0,
0,
@@ -716,17 +756,23 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
string_f(vars, "sw_preset", video.sw.preset);
string_f(vars, "sw_tune", video.sw.tune);
int_f(vars, "nv_preset", video.nv.preset, nv::preset_from_view);
int_f(vars, "nv_tune", video.nv.tune, nv::tune_from_view);
int_f(vars, "nv_rc", video.nv.rc, nv::rc_from_view);
int_f(vars, "nv_coder", video.nv.coder, nv::coder_from_view);
int_f(vars, "amd_quality", video.amd.quality, amd::quality_from_view);
std::string quality;
string_f(vars, "amd_quality", quality);
if(!quality.empty()) {
video.amd.quality_h264 = amd::quality_from_view(quality, 1);
video.amd.quality_hevc = amd::quality_from_view(quality, 0);
}
std::string rc;
string_f(vars, "amd_rc", rc);
int_f(vars, "amd_coder", video.amd.coder, amd::coder_from_view);
if(!rc.empty()) {
video.amd.rc_h264 = amd::rc_h264_from_view(rc);
video.amd.rc_hevc = amd::rc_hevc_from_view(rc);
video.amd.rc_h264 = amd::rc_from_view(rc, 1);
video.amd.rc_hevc = amd::rc_from_view(rc, 0);
}
int_f(vars, "vt_coder", video.vt.coder, vt::coder_from_view);

View File

@@ -23,12 +23,14 @@ struct video_t {
struct {
std::optional<int> preset;
std::optional<int> tune;
std::optional<int> rc;
int coder;
} nv;
struct {
std::optional<int> quality;
std::optional<int> quality_h264;
std::optional<int> quality_hevc;
std::optional<int> rc_h264;
std::optional<int> rc_hevc;
int coder;

View File

@@ -422,6 +422,7 @@ static encoder_t nvenc {
{ "forced-idr"s, 1 },
{ "zerolatency"s, 1 },
{ "preset"s, &config::video.nv.preset },
{ "tune"s, &config::video.nv.tune },
{ "rc"s, &config::video.nv.rc },
},
std::nullopt,
@@ -433,6 +434,7 @@ static encoder_t nvenc {
{ "forced-idr"s, 1 },
{ "zerolatency"s, 1 },
{ "preset"s, &config::video.nv.preset },
{ "tune"s, &config::video.nv.tune },
{ "rc"s, &config::video.nv.rc },
{ "coder"s, &config::video.nv.coder },
},
@@ -462,7 +464,7 @@ static encoder_t amdvce {
{ "header_insertion_mode"s, "idr"s },
{ "qmax"s, 51 },
{ "qmin"s, 0 },
{ "quality"s, &config::video.amd.quality },
{ "quality"s, &config::video.amd.quality_hevc },
{ "rc"s, &config::video.amd.rc_hevc },
{ "usage"s, "ultralowlatency"s },
{ "vbaq"s, true },
@@ -476,7 +478,7 @@ static encoder_t amdvce {
{ "log_to_dbg"s, "1"s },
{ "qmax"s, 51 },
{ "qmin"s, 0 },
{ "quality"s, &config::video.amd.quality },
{ "quality"s, &config::video.amd.quality_h264 },
{ "rc"s, &config::video.amd.rc_h264 },
{ "usage"s, "ultralowlatency"s },
{ "vbaq"s, true },

View File

@@ -644,40 +644,40 @@
<div v-if="currentTab === 'nv'" class="config-page">
<!--NVENC SETTINGS-->
<div class="mb-3">
<label for="nv_preset" class="form-label">NVEnc Preset</label>
<label for="nv_preset" class="form-label">NVENC Preset</label>
<select id="nv_preset" class="form-select" v-model="config.nv_preset">
<option value="default">Default</option>
<option value="hp">High Performance</option>
<option value="hq">High Quality</option>
<option value="slow">Slow - hq 2 passes</option>
<option value="medium">medium -- hq 1 pass</option>
<option value="fast">fast -- hp 1 pass</option>
<option value="bd">bd</option>
<option value="p1">p1 -- fastest (lowest quality)</option>
<option value="p2">p2 -- faster (lower quality)</option>
<option value="p3">p3 -- fast (low quality)</option>
<option value="p4">p4 -- medium (default)</option>
<option value="p5">p5 -- slow (good quality)</option>
<option value="p6">p6 -- slower (better quality)</option>
<option value="p7">p7 -- slowest (best quality)</option>
</select>
</div>
<div class="mb-3">
<label for="nv_tune" class="form-label">NVENC Tune</label>
<select id="nv_tune" class="form-select" v-model="config.nv_tune">
<option value="hq">hq -- high quality</option>
<option value="ll">ll -- low latency</option>
<option value="llhq">llhq</option>
<option value="llhp">llhp</option>
<option value="lossless">lossless</option>
<option value="losslesshp">losslesshp</option>
<option value="ull">ull -- ultra low latency (default)</option>
<option value="lossless">lossless -- lossless</option>
</select>
</div>
<div class="mb-3">
<label for="nv_rc" class="form-label">NVEnc Rate Control</label>
<label for="nv_rc" class="form-label">NVENC Rate Control</label>
<select id="nv_rc" class="form-select" v-model="config.nv_rc">
<option value="auto">auto -- let ffmpeg decide rate control</option>
<option value="constqp">constqp -- constant QP mode</option>
<option value="constqp">constqp -- constant qp mode</option>
<option value="vbr">vbr -- variable bitrate</option>
<option value="cbr">cbr -- constant bitrate</option>
<option value="cbr_hq">cbr_hq -- cbr high quality</option>
<option value="cbr_ld_hq">cbr_ld_hq -- cbr low delay high quality</option>
<option value="vbr_hq">vbr_hq -- vbr high quality</option>
<option value="cbr">cbr -- constant bitrate (default)</option>
</select>
</div>
<div class="mb-3">
<label for="nv_coder" class="form-label">NVEnc Coder</label>
<label for="nv_coder" class="form-label">NVENC Coder (H264)</label>
<select id="nv_coder" class="form-select" v-model="config.nv_coder">
<option value="auto">auto</option>
<option value="cabac">cabac</option>
<option value="cavlc">cavlc</option>
<option value="auto">auto -- let ffmpeg decide (default)</option>
<option value="cabac">cabac -- context adaptive binary arithmetic coding - higher quality</option>
<option value="cavlc">cavlc -- context adaptive variable-length coding - faster decode</option>
</select>
</div>
</div>
@@ -685,33 +685,31 @@
<div v-if="currentTab === 'amd'" class="config-page">
<!--Presets-->
<div class="mb-3">
<label for="amd_quality" class="form-label">AMD AMF Quality</label>
<label for="amd_quality" class="form-label">AMF Quality</label>
<select
id="amd_quality"
class="form-select"
v-model="config.amd_quality"
>
<option value="default">Default</option>
<option value="speed">Speed</option>
<option value="balanced">Balanced</option>
v-model="config.amd_quality">
<option value="speed">speed -- prefer speed</option>
<option value="balanced">balanced -- balanced (default)</option>
<option value="quality">quality -- prefer quality</option>
</select>
</div>
<div class="mb-3">
<label for="amd_rc" class="form-label">AMD AMF Rate Control</label>
<label for="amd_rc" class="form-label">AMF Rate Control</label>
<select id="amd_rc" class="form-select" v-model="config.amd_rc">
<option value="auto">auto -- let ffmpeg decide rate control</option>
<option value="cqp">cqp -- constant QP mode</option>
<option value="vbr_latency">vbr_latency -- Latency Constrained Variable Bitrate</option>
<option value="vbr_peak">vbr_peak -- Peak Contrained Variable Bitrate</option>
<option value="cqp">cqp -- constant qp mode</option>
<option value="vbr_latency">vbr_latency -- latency constrained variable bitrate (default)</option>
<option value="vbr_peak">vbr_peak -- peak contrained variable bitrate</option>
<option value="cbr">cbr -- constant bitrate</option>
</select>
</div>
<div class="mb-3">
<label for="amd_coder" class="form-label">AMD AMF Coder</label>
<label for="amd_coder" class="form-label">AMF Coder (H264)</label>
<select id="amd_coder" class="form-select" v-model="config.amd_coder">
<option value="auto">auto</option>
<option value="cabac">cabac</option>
<option value="cavlc">cavlc</option>
<option value="auto">auto -- let ffmpeg decide (default)</option>
<option value="cabac">cabac -- context adaptive variable-length coding - higher quality</option>
<option value="cavlc">cavlc -- context adaptive binary arithmetic coding - faster decode</option>
</select>
</div>
</div>
@@ -851,12 +849,13 @@
this.config.origin_web_manager_allowed || "lan";
this.config.hevc_mode = this.config.hevc_mode || 0;
this.config.encoder = this.config.encoder || "";
this.config.nv_preset = this.config.nv_preset || "default";
this.config.nv_rc = this.config.nv_rc || "auto";
this.config.nv_preset = this.config.nv_preset || "p4";
this.config.nv_tune = this.config.nv_tune || "ull";
this.config.nv_coder = this.config.nv_coder || "auto";
this.config.nv_rc = this.config.nv_rc || "cbr";
this.config.amd_coder = this.config.amd_coder || "auto"
this.config.amd_quality = this.config.amd_quality || "default";
this.config.amd_rc = this.config.amd_rc || "auto";
this.config.amd_quality = this.config.amd_quality || "balanced";
this.config.amd_rc = this.config.amd_rc || "vbr_latency";
this.config.vt_coder = this.config.vt_coder || "auto";
this.config.vt_software = this.config.vt_software || "auto";
this.config.vt_realtime = this.config.vt_realtime || "enabled";