Skip to content

Commit

Permalink
NVENC SDK 12.2で追加されたオプションに対応。
Browse files Browse the repository at this point in the history
  • Loading branch information
rigaya committed Apr 8, 2024
1 parent 59de624 commit 634d6ec
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 6 deletions.
7 changes: 7 additions & 0 deletions NVEnc/NVEnc_readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ NVIDIA グラフィックドライバ 545.92
今後の更新で設定ファイルの互換性がなくなるかもしれません。

【メモ】
2024.04.08 (7.49)
- NVENC SDK 12.2に対応。
- 新しいオプションを追加。
- --lookahead-level [HEVC専用]
- --tf-level [HEVC専用]
- --tune

2024.03.28 (7.48)
- NVEnc 7.45から--vpp-resize nvvfx-superres使用時に意図しないリサイズが行われることがあるのを修正。

Expand Down
20 changes: 20 additions & 0 deletions NVEncC_Options.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
- [--vbr-quality \<float\>](#--vbr-quality-float)
- [--dynamic-rc \<int\>:\<int\>:\<int\>\<int\>,\<param1\>=\<value1\>\[,\<param2\>=\<value2\>\],...](#--dynamic-rc-intintintintparam1value1param2value2)
- [--lookahead \<int\>](#--lookahead-int)
- [--lookahead-level \<int\> \[HEVC\]](#--lookahead-level-int-hevc)
- [--tune \<string\>](#--tune-string)
- [--no-i-adapt](#--no-i-adapt)
- [--no-b-adapt](#--no-b-adapt)
- [--strict-gop](#--strict-gop)
Expand Down Expand Up @@ -96,6 +98,7 @@
- [--(no-)deblock \[H.264\]](#--no-deblock-h264)
- [--cu-max \<int\> \[HEVC\]](#--cu-max-int-hevc)
- [--cu-min \<int\> \[HEVC\]](#--cu-min-int-hevc)
- [--tf-level \<int\> \[HEVC\]](#--tf-level-int-hevc)
- [--part-size-min \<int\> \[AV1\]](#--part-size-min-int-av1)
- [--part-size-max \<int\> \[AV1\]](#--part-size-max-int-av1)
- [--tile-columns \<int\> \[AV1\]](#--tile-columns-int-av1)
Expand Down Expand Up @@ -647,6 +650,17 @@ Change the rate control mode and rate control params within the specified range
Enable lookahead, and specify its target range by the number of frames. (0 - 32)
This is useful to improve image quality, allowing adaptive insertion of I and B frames.

### --lookahead-level &lt;int&gt; [HEVC]
Set level of lookahead, higher level may improve quality at the expense of performance. (0 - 3, default = auto)

### --tune &lt;string&gt;
Set tuning info. Will be changed automatically if ```--lossless```, ```--lowlatecy``` is used.
- hq
- uhq
- lowlatency
- ultralowlatency
- lossless

### --no-i-adapt
Disable adaptive I frame insertion when lookahead is enabled.

Expand Down Expand Up @@ -736,6 +750,12 @@ Enable deblock filter. (Default: on)
Specify the maximum and minimum size of CU respectively. 8, 16, 32 can be specified.
**Since it is known that image quality may be degraded when this option is used, it is recommended not to use these options.**

### --tf-level &lt;int&gt; [HEVC]
Set HEVC temporal filtering, requires bframes >= 4. (Default: 0)
```
0, 4
```

### --part-size-min &lt;int&gt; [AV1]
Specifies the minimum size of luma coding block partition. (default: 0 = auto)
```
Expand Down
22 changes: 22 additions & 0 deletions NVEncC_Options.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
- [--vbr-quality \<float\>](#--vbr-quality-float)
- [--dynamic-rc \<int\>:\<int\>:\<int\>\<int\>,\<param1\>=\<value1\>\[,\<param2\>=\<value2\>\],...](#--dynamic-rc-intintintintparam1value1param2value2)
- [--lookahead \<int\>](#--lookahead-int)
- [--lookahead-level \<int\> \[HEVC\]](#--lookahead-level-int-hevc)
- [--tune \<string\>](#--tune-string)
- [--no-i-adapt](#--no-i-adapt)
- [--no-b-adapt](#--no-b-adapt)
- [--strict-gop](#--strict-gop)
Expand All @@ -92,6 +94,7 @@
- [--(no-)deblock \[H.264\]](#--no-deblock-h264)
- [--cu-max \<int\> \[HEVC\]](#--cu-max-int-hevc)
- [--cu-min \<int\> \[HEVC\]](#--cu-min-int-hevc)
- [--tf-level \<int\> \[HEVC\]](#--tf-level-int-hevc)
- [--part-size-min \<int\> \[AV1\]](#--part-size-min-int-av1)
- [--part-size-max \<int\> \[AV1\]](#--part-size-max-int-av1)
- [--tile-columns \<int\> \[AV1\]](#--tile-columns-int-av1)
Expand Down Expand Up @@ -650,6 +653,19 @@ VBRモード使用時の目標品質を設定する。(0.0-51.0, 0 = 自動)
lookaheadを有効にし、その対象範囲をフレーム数で指定する。(0-32)
画質の向上に役立つとともに、適応的なI,Bフレーム挿入が有効になる。

### --lookahead-level &lt;int&gt; [HEVC]
lookaheadのレベルの指定。(0 - 3, default = auto)

大きくするほど、品質が向上する代わりに速度が低下する。

### --tune &lt;string&gt;
チューニング用のパラメータを指定する。 ```--lossless```, ```--lowlatecy``` が使用された場合には自動的に変更(上書き)される。
- hq
- uhq
- lowlatency
- ultralowlatency
- lossless

### --no-i-adapt
lookahead有効時の適応的なIフレーム挿入を無効化する。

Expand Down Expand Up @@ -740,6 +756,12 @@ Bluray用出力を行う。(デフォルト: オフ)
HEVCの規格では64まで存在するが、現状NVENCでは32までしかサポートされていない。
**画質が低下する恐れがあることがわかっているので、--cu-min / --cu-max の使用は非推奨。**

### --tf-level &lt;int&gt; [HEVC]
HEVC temporal filterの指定。Bフレーム数が4以上である必要がある。(デフォルト: 0)
```
0, 4
```

### --part-size-min &lt;int&gt; [AV1]
輝度成分の最小符号化ブロックサイズを指定する。 (デフォルト: 0 = auto)
```
Expand Down
42 changes: 42 additions & 0 deletions NVEncCore/NVEncCmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ tstring encoder_help() {
_T(" --gop-len <int> set GOP Length / default: %d frames%s\n")
_T(" --lookahead <int> enable lookahead and set lookahead depth (1-32)\n")
_T(" default: %d frames\n")
_T(" --lookahead-level <int> set lookahead level (0 - 3) [HEVC only]\n")
_T(" default: auto\n")
_T(" --tune <string> set tuning info (default: auto)\n")
_T(" undef, hq, uhq, lowlatency, ultralowlatency, lossless\n")
_T(" --strict-gop avoid GOP len fluctuation\n")
_T(" --no-i-adapt disable adapt. I frame insertion\n")
_T(" --no-b-adapt disable adapt. B frame insertion\n")
Expand Down Expand Up @@ -256,6 +260,8 @@ tstring encoder_help() {
_T(" --(no-)deblock [H264] enable(disable) deblock filter\n"));

str += strsprintf(_T("\n")
_T(" --tf-level <int> [HEVC] set temporal filtering level (0 (default), 4)\n")
_T(" requires bframes >= 4\n")
_T(" --cu-max <int> [HEVC] set max CU size\n")
_T(" --cu-min <int> [HEVC] set min CU size\n")
_T(" 8, 16, 32 are avaliable\n")
Expand Down Expand Up @@ -1020,6 +1026,28 @@ int parse_one_option(const TCHAR *option_name, const TCHAR* strInput[], int& i,
}
return 0;
}
if (IS_OPTION("lookahead-level")) {
i++;
int value = 0;
if (get_list_value(list_lookahead_level, strInput[i], &value)) {
pParams->lookaheadLevel = (NV_ENC_LOOKAHEAD_LEVEL)value;
} else {
print_cmd_error_invalid_value(option_name, strInput[i], list_lookahead_level);
return 1;
}
return 0;
}
if (IS_OPTION("tune")) {
i++;
int value = 0;
if (get_list_value(list_tuning_info, strInput[i], &value)) {
pParams->tuningInfo = (NV_ENC_TUNING_INFO)value;
} else {
print_cmd_error_invalid_value(option_name, strInput[i], list_lookahead_level);
return 1;
}
return 0;
}
if (IS_OPTION("no-i-adapt")) {
pParams->disableIadapt = true;
return 0;
Expand Down Expand Up @@ -1094,6 +1122,17 @@ int parse_one_option(const TCHAR *option_name, const TCHAR* strInput[], int& i,
codecPrm[RGY_CODEC_H264].h264Config.hierarchicalBFrames = 1;
return 0;
}
if (IS_OPTION("tf-level")) {
i++;
int value = 0;
if (get_list_value(list_temporal_filter_level, strInput[i], &value)) {
pParams->temporalFilterLevel = (NV_ENC_TEMPORAL_FILTER_LEVEL)value;
} else {
print_cmd_error_invalid_value(option_name, strInput[i], list_temporal_filter_level);
return 1;
}
return 0;
}
if (IS_OPTION("temporal-layers")) {
i++;
int value = 0;
Expand Down Expand Up @@ -1903,6 +1942,8 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
if (pParams->enableLookahead || save_disabled_prm) {
OPT_NUM(_T("--lookahead"), lookahead);
}
OPT_LST(_T("--lookahead-level"), lookaheadLevel, list_lookahead_level);
OPT_LST(_T("--tune"), tuningInfo, list_tuning_info);
OPT_BOOL(_T("--no-i-adapt"), _T(""), disableIadapt);
OPT_BOOL(_T("--no-b-adapt"), _T(""), disableBadapt);
OPT_BOOL(_T("--strict-gop"), _T(""), strictGOP);
Expand Down Expand Up @@ -1931,6 +1972,7 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
if (pParams->yuv444) {
cmd << _T(" --output-csp ") << get_cx_desc(list_output_csp, (int)RGY_CSP_YUV444);
}
OPT_LST(_T("--tf-level"), temporalFilterLevel, list_temporal_filter_level);

if (pParams->codec_rgy == RGY_CODEC_AV1 || save_disabled_prm) {
OPT_LST_AV1(_T("--level"), _T(":av1"), level, list_av1_level);
Expand Down
27 changes: 24 additions & 3 deletions NVEncCore/NVEncCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,9 @@ NVENCSTATUS NVEncCore::SetInputParam(InEncodeVideoParam *inputParam) {
//HEVCのプロファイル情報は、m_stEncConfig.encodeCodecConfig.hevcConfig.tierの下位16bitに保存されている
if (inputParam->codec_rgy == RGY_CODEC_HEVC) {
m_stEncConfig.profileGUID = get_guid_from_value(m_stEncConfig.encodeCodecConfig.hevcConfig.tier & 0xffff, h265_profile_names);
if (inputParam->outputDepth > 8) {
m_stEncConfig.profileGUID = (inputParam->yuv444) ? NV_ENC_HEVC_PROFILE_FREXT_GUID : NV_ENC_HEVC_PROFILE_MAIN10_GUID;
}
m_stEncConfig.encodeCodecConfig.hevcConfig.tier >>= 16;
} else if (inputParam->codec_rgy == RGY_CODEC_AV1) {
m_stEncConfig.profileGUID = get_guid_from_value(m_stEncConfig.encodeCodecConfig.av1Config.tier & 0xffff, av1_profile_names);
Expand Down Expand Up @@ -1910,7 +1913,11 @@ NVENCSTATUS NVEncCore::SetInputParam(InEncodeVideoParam *inputParam) {
m_stCreateEncodeParams.enableWeightedPrediction = 1;
}
}
m_stCreateEncodeParams.tuningInfo = NV_ENC_TUNING_INFO_HIGH_QUALITY;
m_stCreateEncodeParams.tuningInfo = (inputParam->tuningInfo == NV_ENC_TUNING_INFO_UNDEFINED) ? NV_ENC_TUNING_INFO_HIGH_QUALITY : inputParam->tuningInfo;
if (!m_dev->encoder()->checkAPIver(12, 2) && m_stCreateEncodeParams.tuningInfo == NV_ENC_TUNING_INFO_ULTRA_HIGH_QUALITY) {
PrintMes(RGY_LOG_WARN, _T("tune uhq disabled as it requires NVENC API 12.2.\n"));
m_stCreateEncodeParams.tuningInfo = NV_ENC_TUNING_INFO_HIGH_QUALITY;
}

if (inputParam->ctrl.lowLatency
&& m_dev->encoder()->checkAPIver(10, 0)) {
Expand Down Expand Up @@ -2072,6 +2079,11 @@ NVENCSTATUS NVEncCore::SetInputParam(InEncodeVideoParam *inputParam) {
// シーク性を確保するため、常に有効にする
m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.av1Config.repeatSeqHdr = 1;
} else if (inputParam->codec_rgy == RGY_CODEC_HEVC) {
if (m_dev->encoder()->checkAPIver(12, 2)) {
m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.hevcConfig.tfLevel = (NV_ENC_TEMPORAL_FILTER_LEVEL)inputParam->temporalFilterLevel;
m_stEncConfig.rcParams.lookaheadLevel = (NV_ENC_LOOKAHEAD_LEVEL)inputParam->lookaheadLevel;
}

//整合性チェック (一般, H.265/HEVC)
if (m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.hevcConfig.outputPictureTimingSEI) {
m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.hevcConfig.outputBufferingPeriodSEI = 1;
Expand All @@ -2081,7 +2093,7 @@ NVENCSTATUS NVEncCore::SetInputParam(InEncodeVideoParam *inputParam) {
m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC = 3;
//m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.h264Config.separateColourPlaneFlag = 1;
m_stCreateEncodeParams.encodeConfig->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
} else if (!m_dev->encoder()->checkAPIver(12, 2) && m_stCreateEncodeParams.encodeConfig->encodeCodecConfig.hevcConfig.reserved3 /*pixelBitDepthMinus8*/ > 0) {
} else if (get_bitDepth(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy, m_dev->encoder()->getAPIver()) > 8) {
m_stCreateEncodeParams.encodeConfig->profileGUID = (inputParam->yuv444) ? NV_ENC_HEVC_PROFILE_FREXT_GUID : NV_ENC_HEVC_PROFILE_MAIN10_GUID;
}
if (require_repeat_headers()) {
Expand Down Expand Up @@ -3678,7 +3690,7 @@ NVENCSTATUS NVEncCore::NvEncEncodeFrame(EncodeBuffer *pEncodeBuffer, const int i
PrintMes(RGY_LOG_ERROR, _T("Invalid input frame ID %d sent to encoder.\n"), inputFrameId);
return NV_ENC_ERR_GENERIC;
}
m_encTimestamp->add(timestamp, inputFrameId, m_encodeFrameID++, duration, metadatalist);
m_encTimestamp->add(timestamp, inputFrameId, (encPicParams.frameIdx = m_encodeFrameID++), duration, metadatalist);

NVENCSTATUS nvStatus = m_dev->encoder()->NvEncEncodePicture(&encPicParams);
if (nvStatus != NV_ENC_SUCCESS && nvStatus != NV_ENC_ERR_NEED_MORE_INPUT) {
Expand Down Expand Up @@ -5088,9 +5100,13 @@ tstring NVEncCore::GetEncodingParamsInfo(int output_level) {
if (m_dev->encoder()->checkAPIver(12, 1)) {
add_str(RGY_LOG_INFO, _T("Split Enc Mode %s\n"), get_chr_from_value(list_split_enc_mode, m_stCreateEncodeParams.splitEncodeMode));
}
add_str(RGY_LOG_INFO, _T("Tuning Info "), get_chr_from_value(list_tuning_info, m_stCreateEncodeParams.tuningInfo));
tstring strLookahead = _T("Lookahead ");
if (m_stEncConfig.rcParams.enableLookahead) {
strLookahead += strsprintf(_T("on, %d frames"), m_stEncConfig.rcParams.lookaheadDepth);
if (rgy_codec == RGY_CODEC_HEVC && m_stEncConfig.rcParams.lookaheadLevel != NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT) {
strLookahead += tstring(_T(", Level ")) + get_chr_from_value(list_lookahead_level, m_stEncConfig.rcParams.lookaheadLevel);
}
if (!m_stEncConfig.rcParams.disableBadapt || !m_stEncConfig.rcParams.disableIadapt) {
strLookahead += _T(", Adaptive ");
if (!m_stEncConfig.rcParams.disableIadapt) strLookahead += _T("I");
Expand Down Expand Up @@ -5246,6 +5262,11 @@ tstring NVEncCore::GetEncodingParamsInfo(int output_level) {
add_str(RGY_LOG_INFO, _T("repeat-headers "));
}
}
if (rgy_codec == RGY_CODEC_HEVC) {
if (m_stEncConfig.encodeCodecConfig.hevcConfig.tfLevel != NV_ENC_TEMPORAL_FILTER_LEVEL_0 && m_stCreateEncodeParams.encodeConfig->frameIntervalP >= 5) {
add_str(RGY_LOG_INFO, _T("tf%s "), get_chr_from_value(list_temporal_filter_level, m_stEncConfig.encodeCodecConfig.hevcConfig.tfLevel));
}
}
if (rgy_codec == RGY_CODEC_AV1) {
if (m_stEncConfig.encodeCodecConfig.av1Config.outputAnnexBFormat) {
add_str(RGY_LOG_INFO, _T("annexb "));
Expand Down
3 changes: 2 additions & 1 deletion NVEncCore/NVEncParam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ InEncodeVideoParam::InEncodeVideoParam() :
lookahead(DEFAULT_LOOKAHEAD),
lookaheadLevel(NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT),
aqStrength(0),
temporalFilterLevel(0),
temporalFilterLevel(NV_ENC_TEMPORAL_FILTER_LEVEL_0),
tuningInfo(NV_ENC_TUNING_INFO_UNDEFINED),
encConfig(),
dynamicRC(),
codec_rgy(RGY_CODEC_H264),
Expand Down
15 changes: 13 additions & 2 deletions NVEncCore/NVEncParam.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,16 @@ const CX_DESC list_lookahead_level[] = {
{ NULL, 0 }
};

const CX_DESC list_tuning_info[] = {
{ _T("undef"), NV_ENC_TUNING_INFO_UNDEFINED },
{ _T("hq"), NV_ENC_TUNING_INFO_HIGH_QUALITY },
{ _T("lowlatency"), NV_ENC_TUNING_INFO_LOW_LATENCY },
{ _T("ultralowlatency"), NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY },
{ _T("lossless"), NV_ENC_TUNING_INFO_LOSSLESS },
{ _T("uhq"), NV_ENC_TUNING_INFO_ULTRA_HIGH_QUALITY },
{ NULL, 0 }
};

enum : uint32_t {
NV_ENC_AQ_DISABLED = 0x00,
NV_ENC_AQ_SPATIAL = 0x01,
Expand Down Expand Up @@ -708,9 +718,10 @@ struct InEncodeVideoParam {
bool nonrefP;
bool enableLookahead;
int lookahead;
int lookaheadLevel;
NV_ENC_LOOKAHEAD_LEVEL lookaheadLevel;
int aqStrength;
int temporalFilterLevel;
NV_ENC_TEMPORAL_FILTER_LEVEL temporalFilterLevel;
NV_ENC_TUNING_INFO tuningInfo;

NV_ENC_CONFIG encConfig; //エンコード設定

Expand Down

0 comments on commit 634d6ec

Please sign in to comment.