Skip to content

Commit

Permalink
defaultより遅いpresetの場合、可能ならbref-modeを使用するように。 (#449, #458)
Browse files Browse the repository at this point in the history
そうでないと、映像が破綻するケースがある。
  • Loading branch information
rigaya committed Jan 29, 2023
1 parent 9be4633 commit 8a1c7cf
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 13 deletions.
11 changes: 4 additions & 7 deletions NVEncCore/NVEncCmd.cpp
Expand Up @@ -231,7 +231,8 @@ tstring encoder_help() {
_T(" --aq-strength <int> set aq strength (weak 1 - 15 strong)\n")
_T(" default: 0 = auto\n")
_T(" --bref-mode <string> set B frame reference mode\n")
_T(" - disabled (default)\n")
_T(" - auto (default)\n")
_T(" - disabled\n")
_T(" - each\n")
_T(" - middle\n")
_T(" --direct <string> [H264] set B Direct mode\n")
Expand Down Expand Up @@ -812,9 +813,7 @@ int parse_one_option(const TCHAR *option_name, const TCHAR* strInput[], int& i,
i++;
int value = 0;
if (get_list_value(list_bref_mode, strInput[i], &value)) {
codecPrm[RGY_CODEC_H264].h264Config.useBFramesAsRef = (NV_ENC_BFRAME_REF_MODE)value;
codecPrm[RGY_CODEC_HEVC].hevcConfig.useBFramesAsRef = (NV_ENC_BFRAME_REF_MODE)value;
codecPrm[RGY_CODEC_AV1 ].av1Config.useBFramesAsRef = (NV_ENC_BFRAME_REF_MODE)value;
pParams->brefMode = value;
} else {
print_cmd_error_invalid_value(option_name, strInput[i], list_bref_mode);
return 1;
Expand Down Expand Up @@ -1674,6 +1673,7 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
OPT_NUM(_T("--gop-len"), encConfig.gopLength);
}
OPT_NUM(_T("-b"), encConfig.frameIntervalP-1);
OPT_NUM(_T("--bref-mode"), brefMode);
OPT_BOOL(_T("--weightp"), _T(""), nWeightP);
OPT_BOOL(_T("--nonrefp"), _T(""), encConfig.rcParams.enableNonRefP);
OPT_BOOL(_T("--aq"), _T("--no-aq"), encConfig.rcParams.enableAQ);
Expand All @@ -1692,7 +1692,6 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
OPT_LST_AV1(_T("--level"), _T(":av1"), level, list_av1_level);
OPT_GUID_AV1(_T("--profile"), _T(":av1"), tier & 0xffff, av1_profile_names);
OPT_LST_AV1(_T("--tier"), _T(":av1"), tier >> 16, av1_tier_names);
OPT_LST_AV1(_T("--bref-mode"), _T(""), useBFramesAsRef, list_bref_mode);
if (codecPrm[RGY_CODEC_AV1].av1Config.pixelBitDepthMinus8 != codecPrmDefault[RGY_CODEC_AV1].av1Config.pixelBitDepthMinus8) {
cmd << _T(" --output-depth ") << codecPrm[RGY_CODEC_AV1].av1Config.pixelBitDepthMinus8 + 8;
}
Expand All @@ -1714,7 +1713,6 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
OPT_NUM_HEVC(_T("--ref"), _T(""), maxNumRefFramesInDPB);
OPT_NUM_HEVC(_T("--multiref-l0"), _T(""), numRefL0);
OPT_NUM_HEVC(_T("--multiref-l1"), _T(""), numRefL1);
OPT_LST_HEVC(_T("--bref-mode"), _T(""), useBFramesAsRef, list_bref_mode);
if (codecPrm[RGY_CODEC_HEVC].hevcConfig.pixelBitDepthMinus8 != codecPrmDefault[RGY_CODEC_HEVC].hevcConfig.pixelBitDepthMinus8) {
cmd << _T(" --output-depth ") << codecPrm[RGY_CODEC_HEVC].hevcConfig.pixelBitDepthMinus8 + 8;
}
Expand All @@ -1731,7 +1729,6 @@ tstring gen_cmd(const InEncodeVideoParam *pParams, const NV_ENC_CODEC_CONFIG cod
OPT_NUM_H264(_T("--ref"), _T(""), maxNumRefFrames);
OPT_NUM_H264(_T("--multiref-l0"), _T(""), numRefL0);
OPT_NUM_H264(_T("--multiref-l1"), _T(""), numRefL1);
OPT_LST_H264(_T("--bref-mode"), _T(""), useBFramesAsRef, list_bref_mode);
OPT_LST_H264(_T("--direct"), _T(""), bdirectMode, list_bdirect);
OPT_LST_H264(_T("--adapt-transform"), _T(""), adaptiveTransformMode, list_adapt_transform);
OPT_NUM_H264(_T("--slices"), _T(":h264"), sliceModeData);
Expand Down
26 changes: 21 additions & 5 deletions NVEncCore/NVEncCore.cpp
Expand Up @@ -1304,7 +1304,7 @@ NVENCSTATUS NVEncCore::InitDecoder(const InEncodeVideoParam *inputParam) {
}
#pragma warning(pop)

NVENCSTATUS NVEncCore::SetInputParam(const InEncodeVideoParam *inputParam) {
NVENCSTATUS NVEncCore::SetInputParam(InEncodeVideoParam *inputParam) {
memcpy(&m_stEncConfig, &inputParam->encConfig, sizeof(m_stEncConfig));

m_dev->encoder()->setStructVer(m_stCreateEncodeParams);
Expand Down Expand Up @@ -1574,11 +1574,11 @@ NVENCSTATUS NVEncCore::SetInputParam(const InEncodeVideoParam *inputParam) {
}
}
}
if (get_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy) != NV_ENC_BFRAME_REF_MODE_DISABLED) {
if (inputParam->brefMode > NV_ENC_BFRAME_REF_MODE_DISABLED) {
const int cap = codecFeature->getCapLimit(NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE);
if ((cap & get_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy)) != get_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy)) {
error_feature_unsupported(RGY_LOG_WARN, strsprintf(_T("B Ref Mode %s"), get_chr_from_value(list_bref_mode, get_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy))).c_str());
set_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy, NV_ENC_BFRAME_REF_MODE_DISABLED);
if ((cap & inputParam->brefMode) != inputParam->brefMode) {
error_feature_unsupported(RGY_LOG_WARN, strsprintf(_T("B Ref Mode %s"), get_chr_from_value(list_bref_mode, inputParam->brefMode)).c_str());
inputParam->brefMode = NV_ENC_BFRAME_REF_MODE_DISABLED;
}
}
if (inputParam->codec_rgy == RGY_CODEC_H264) {
Expand Down Expand Up @@ -1789,11 +1789,27 @@ NVENCSTATUS NVEncCore::SetInputParam(const InEncodeVideoParam *inputParam) {
m_stCreateEncodeParams.enableEncodeAsync = ENABLE_ASYNC != 0;
m_stCreateEncodeParams.enablePTD = true;
m_stCreateEncodeParams.encodeGUID = m_stCodecGUID;

//bref-modeの自動設定
if (m_dev->encoder()->checkAPIver(10, 0)) {
m_stCreateEncodeParams.presetGUID = get_guid_from_value(inputParam->preset, list_nvenc_preset_names_ver10);
} else {
m_stCreateEncodeParams.presetGUID = get_guid_from_value(inputParam->preset, list_nvenc_preset_names_ver9_2);
}
if (inputParam->brefMode == NV_ENC_BFRAME_REF_MODE_AUTO) {
inputParam->brefMode = NV_ENC_BFRAME_REF_MODE_DISABLED;
if (preset_slower_than_default(inputParam->preset)) {
//defaultより遅いpresetの場合、可能ならbref-modeを使用しないと映像が破綻するケースがある (#449, #458)
const auto caps = codecFeature->getCapLimit(NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE);
for (auto mode : { NV_ENC_BFRAME_REF_MODE_EACH, NV_ENC_BFRAME_REF_MODE_MIDDLE }) {
if ((caps & mode) == mode) {
inputParam->brefMode = mode;
}
}
}
}
set_useBFramesAsRef(m_stEncConfig.encodeCodecConfig, inputParam->codec_rgy, (NV_ENC_BFRAME_REF_MODE)inputParam->brefMode);

//ロスレス出力
if (inputParam->lossless) {
if (m_dev->encoder()->checkAPIver(10, 0)) {
Expand Down
2 changes: 1 addition & 1 deletion NVEncCore/NVEncCore.h
Expand Up @@ -124,7 +124,7 @@ class NVEncCore : public NVEncCtrl {
virtual NVENCSTATUS InitDevice(std::vector<std::unique_ptr<NVGPUInfo>> &gpuList, const InEncodeVideoParam *inputParam);

//inputParamからエンコーダに渡すパラメータを設定
NVENCSTATUS SetInputParam(const InEncodeVideoParam *inputParam);
NVENCSTATUS SetInputParam(InEncodeVideoParam *inputParam);

//デコーダインスタンスを作成
NVENCSTATUS InitDecoder(const InEncodeVideoParam *inputParam);
Expand Down
1 change: 1 addition & 0 deletions NVEncCore/NVEncParam.cpp
Expand Up @@ -289,6 +289,7 @@ InEncodeVideoParam::InEncodeVideoParam() :
losslessIgnoreInputCsp(0),
nWeightP(0),
chromaQPOffset(0),
brefMode(NV_ENC_BFRAME_REF_MODE_AUTO),
common(),
inprm(),
ctrl(),
Expand Down
11 changes: 11 additions & 0 deletions NVEncCore/NVEncParam.h
Expand Up @@ -182,6 +182,13 @@ const guid_desc list_nvenc_preset_names_ver10[] = {
{ NV_ENC_PRESET_P6_GUID, _T("P6"), NVENC_PRESET_P6 },
{ NV_ENC_PRESET_P7_GUID, _T("P7"), NVENC_PRESET_HQ },
};
static const int list_nvenc_preset_slower_than_default[] = {
NVENC_PRESET_P5, NVENC_PRESET_P6, NVENC_PRESET_HQ, NVENC_PRESET_LL_HQ
};
static inline bool preset_slower_than_default(const int preset) {
const auto end = list_nvenc_preset_slower_than_default + _countof(list_nvenc_preset_slower_than_default);
return std::find(list_nvenc_preset_slower_than_default, end, preset) != end;
}

const guid_desc list_nvenc_codecs[] = {
{ NV_ENC_CODEC_H264_GUID, _T("H.264/AVC"), RGY_CODEC_H264 },
Expand Down Expand Up @@ -325,7 +332,10 @@ const CX_DESC list_bdirect[] = {
{ NULL, 0 }
};

static const int NV_ENC_BFRAME_REF_MODE_AUTO = -1;

const CX_DESC list_bref_mode[] = {
{ _T("auto"), NV_ENC_BFRAME_REF_MODE_AUTO },
{ _T("disabled"), NV_ENC_BFRAME_REF_MODE_DISABLED },
{ _T("each"), NV_ENC_BFRAME_REF_MODE_EACH },
{ _T("middle"), NV_ENC_BFRAME_REF_MODE_MIDDLE },
Expand Down Expand Up @@ -680,6 +690,7 @@ struct InEncodeVideoParam {
int losslessIgnoreInputCsp;
int nWeightP;
int chromaQPOffset;
int brefMode;

RGYParamCommon common;
RGYParamInput inprm;
Expand Down

0 comments on commit 8a1c7cf

Please sign in to comment.