From 4ecea006df0d06619666a80eab072ac68bac7963 Mon Sep 17 00:00:00 2001 From: rigaya Date: Thu, 14 May 2020 07:49:43 +0900 Subject: [PATCH] =?UTF-8?q?HEVC=E6=99=82=E3=81=AE=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=E3=81=AE=E6=8C=99=E5=8B=95=E3=82=92=E6=94=B9?= =?UTF-8?q?=E5=96=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VCECore/vce_cmd.cpp | 78 ++++++++++++++------------ VCECore/vce_core.cpp | 7 +-- VCECore/vce_param.h | 100 +++++++++++++++++++++------------- VCEEnc/frm/frmConfig.cpp | 12 ++-- VCEEnc/frm/frmConfig_helper.h | 8 +++ 5 files changed, 121 insertions(+), 84 deletions(-) diff --git a/VCECore/vce_cmd.cpp b/VCECore/vce_cmd.cpp index d46fbd3b..fe2fc01f 100644 --- a/VCECore/vce_cmd.cpp +++ b/VCECore/vce_cmd.cpp @@ -314,8 +314,8 @@ int parse_one_option(const TCHAR *option_name, const TCHAR* strInput[], int& i, if (IS_OPTION("quality")) { i++; int value = AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED; - if (PARSE_ERROR_FLAG == (value = get_value_from_chr(list_vce_quality_preset, strInput[i]))) { - print_cmd_error_invalid_value(option_name, strInput[i], list_vce_quality_preset); + if (PARSE_ERROR_FLAG == (value = get_value_from_chr(list_vce_quality_preset_h264, strInput[i]))) { + print_cmd_error_invalid_value(option_name, strInput[i], list_vce_quality_preset_h264); return 1; } pParams->qualityPreset = value; @@ -1132,19 +1132,37 @@ int parse_cmd(VCEParam *pParams, int nArgNum, const TCHAR **strInput, bool ignor return 1; } } - if (pParams->codec == RGY_CODEC_HEVC) { - int nH264RateControl = pParams->rateControl; - switch (nH264RateControl) { - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR: - pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR; - break; - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR: - pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; - break; - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP: - default: - pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP; - break; + if (pParams->codec != RGY_CODEC_H264) { + if (pParams->codec == RGY_CODEC_HEVC) { + int h264RateControl = pParams->rateControl; + switch (h264RateControl) { + case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR: + pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR; + break; + case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR: + pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; + break; + case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP: + default: + pParams->rateControl = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP; + break; + } + int h264qualityPreset = pParams->qualityPreset; + switch (h264qualityPreset) { + case AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED: + pParams->qualityPreset = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED; + break; + case AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY: + pParams->qualityPreset = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY; + break; + case AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED: + default: + pParams->qualityPreset = AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED; + break; + } + } else { + fprintf(stderr, "Unsupported codec!\n"); + abort(); } } @@ -1237,35 +1255,23 @@ tstring gen_cmd(const VCEParam *pParams, bool save_disabled_prm) { cmd << _T(" -c ") << get_chr_from_value(list_codec, pParams->codec); cmd << gen_cmd(&pParams->input, &encPrmDefault.input, save_disabled_prm); - if (save_disabled_prm) { - switch (pParams->rateControl) { - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR: - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR: - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR: { - OPT_QP(_T("--cqp"), nQPI, nQPP, nQPB, true, true); - } break; - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP: - default: { + if (pParams->rateControl == get_codec_cqp(pParams->codec)) { cmd << _T(" --vbr ") << pParams->nBitrate; - } break; + } else { + OPT_QP(_T("--cqp"), nQPI, nQPP, nQPB, true, true); } } - OPT_LST(_T("--quality"), qualityPreset, list_vce_quality_preset); - switch (pParams->rateControl) { - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR: { + cmd << _T(" --quality ") << get_chr_from_value(get_quality_preset(pParams->codec), (pParams->qualityPreset)); + if (pParams->rateControl == get_codec_cbr(pParams->codec)) { cmd << _T(" --cbr ") << pParams->nBitrate; - } break; - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR: - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR: { + } else if (pParams->rateControl == get_codec_vbr(pParams->codec) + || pParams->rateControl == get_codec_vbr_lat(pParams->codec)) { cmd << _T(" --vbr ") << pParams->nBitrate; - } break; - case AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP: - default: { + } else if (pParams->rateControl == get_codec_cqp(pParams->codec)) { OPT_QP(_T("--cqp"), nQPI, nQPP, nQPB, true, true); - } break; } - if (pParams->rateControl != AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP || save_disabled_prm) { + if (pParams->rateControl != get_codec_cqp(pParams->codec) || save_disabled_prm) { OPT_NUM(_T("--vbv-bufsize"), nVBVBufferSize); OPT_NUM(_T("--max-bitrate"), nMaxBitrate); } diff --git a/VCECore/vce_core.cpp b/VCECore/vce_core.cpp index 7b6c7e14..3ad629ab 100644 --- a/VCECore/vce_core.cpp +++ b/VCECore/vce_core.cpp @@ -1414,7 +1414,7 @@ RGY_ERR VCECore::initEncoder(VCEParam *prm) { m_params.SetParam(AMF_PARAM_USAGE(prm->codec), (amf_int64)((prm->codec == RGY_CODEC_HEVC) ? AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING : AMF_VIDEO_ENCODER_USAGE_TRANSCONDING)); m_params.SetParam(AMF_PARAM_PROFILE(prm->codec), (amf_int64)prm->codecParam[prm->codec].nProfile); m_params.SetParam(AMF_PARAM_PROFILE_LEVEL(prm->codec), (amf_int64)prm->codecParam[prm->codec].nLevel); - m_params.SetParam(AMF_PARAM_QUALITY_PRESET(prm->codec), (amf_int64)get_quality_preset(prm->codec)[prm->qualityPreset]); + m_params.SetParam(AMF_PARAM_QUALITY_PRESET(prm->codec), (amf_int64)get_quality_preset(prm->codec)[prm->qualityPreset].value); m_params.SetParam(AMF_PARAM_QP_I(prm->codec), (amf_int64)prm->nQPI); m_params.SetParam(AMF_PARAM_QP_P(prm->codec), (amf_int64)prm->nQPP); m_params.SetParam(AMF_PARAM_TARGET_BITRATE(prm->codec), (amf_int64)prm->nBitrate * 1000); @@ -1434,7 +1434,7 @@ RGY_ERR VCECore::initEncoder(VCEParam *prm) { m_params.SetParam(AMF_PARAM_GOP_SIZE(prm->codec), (amf_int64)nGOPLen); m_params.SetParam(AMF_PARAM_PREENCODE_ENABLE(prm->codec), prm->pe); - if (prm->pa.enable && prm->rateControl != get_cx_value(get_rc_method(prm->codec), _T("VBR"))) { + if (prm->pa.enable && prm->rateControl != get_codec_vbr(prm->codec)) { PrintMes(RGY_LOG_WARN, _T("Pre analysis is currently supported only with VBR mode.\n")); PrintMes(RGY_LOG_WARN, _T("Currenlty %s mode is selected, so pre analysis will be disabled.\n"), get_cx_desc(get_rc_method(prm->codec), prm->rateControl)); prm->pa.enable = false; @@ -2477,8 +2477,7 @@ tstring VCECore::GetEncoderParam() { } } } - const int quality_preset = GetPropertyInt(AMF_PARAM_QUALITY_PRESET(m_encCodec)); - mes += strsprintf(_T("Quality: %s\n"), list_vce_quality_preset[get_quality_index(m_encCodec, quality_preset)].desc); + mes += strsprintf(_T("Quality: %s\n"), getPropertyDesc(AMF_PARAM_QUALITY_PRESET(m_encCodec), get_quality_preset(m_encCodec)).c_str()); if (GetPropertyInt(AMF_PARAM_RATE_CONTROL_METHOD(m_encCodec)) == get_rc_method(m_encCodec)[0].value) { mes += strsprintf(_T("CQP: I:%d, P:%d"), GetPropertyInt(AMF_PARAM_QP_I(m_encCodec)), diff --git a/VCECore/vce_param.h b/VCECore/vce_param.h index 7353f5e5..89b71930 100644 --- a/VCECore/vce_param.h +++ b/VCECore/vce_param.h @@ -173,13 +173,6 @@ const CX_DESC list_vce_hevc_rc_method[] = { { NULL, NULL } }; -const CX_DESC list_vce_quality_preset[] = { - { _T("balanced"), 0 }, - { _T("fast"), 1 }, - { _T("slow"), 2 }, - { NULL, NULL } -}; - const CX_DESC list_vce_preanalysis_h264[] = { { _T("off"), AMF_VIDEO_ENCODER_PREENCODE_DISABLED }, { _T("on"), AMF_VIDEO_ENCODER_PREENCODE_ENABLED }, @@ -239,21 +232,24 @@ const CX_DESC list_vpp_resize[] = { { NULL, NULL } }; -static const int H264_QUALITY_PRESET[3] = { - AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED, - AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED, - AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY +const CX_DESC list_vce_quality_preset_h264[] = { + { _T("balanced"), AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED }, + { _T("fast"), AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED }, + { _T("slow"), AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY }, + { NULL, NULL } }; -static const int HEVC_QUALITY_PRESET[3] = { - AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED, - AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED, - AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY +const CX_DESC list_vce_quality_preset_hevc[] = { + { _T("balanced"), AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED }, + { _T("fast"), AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED }, + { _T("slow"), AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY }, + { NULL, NULL } }; -static const int *get_quality_preset(RGY_CODEC codec) { + +static const CX_DESC *get_quality_preset(RGY_CODEC codec) { switch (codec) { - case RGY_CODEC_HEVC: return HEVC_QUALITY_PRESET; - case RGY_CODEC_H264: return H264_QUALITY_PRESET; + case RGY_CODEC_HEVC: return list_vce_quality_preset_hevc; + case RGY_CODEC_H264: return list_vce_quality_preset_h264; default: return nullptr; } } @@ -264,26 +260,6 @@ static const CX_DESC *get_rc_method(RGY_CODEC codec) { default: return list_empty; } } -static int get_quality_index(RGY_CODEC codec, int quality_preset) { - const int *preset = nullptr; - switch (codec) { - case RGY_CODEC_HEVC: - preset = HEVC_QUALITY_PRESET; - break; - case RGY_CODEC_H264: - default: - preset = H264_QUALITY_PRESET; - break; - } - if (preset) { - for (int i = 0; i < 3; i++) { - if (preset[i] == quality_preset) { - return i; - } - } - } - return 0; -} static inline const CX_DESC *get_level_list(RGY_CODEC codec) { switch (codec) { @@ -308,6 +284,54 @@ static inline const CX_DESC *get_tier_list(RGY_CODEC codec) { } } +static inline int get_codec_cqp(RGY_CODEC codec) { + int codec_cqp = 0; + switch (codec) { + case RGY_CODEC_HEVC: codec_cqp = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP; break; + case RGY_CODEC_H264: codec_cqp = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP; break; + default: + fprintf(stderr, "Unsupported codec!\n"); + abort(); + } + return codec_cqp; +} + +static inline int get_codec_vbr(RGY_CODEC codec) { + int codec_vbr = 0; + switch (codec) { + case RGY_CODEC_HEVC: codec_vbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; break; + case RGY_CODEC_H264: codec_vbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; break; + default: + fprintf(stderr, "Unsupported codec!\n"); + abort(); + } + return codec_vbr; +} + +static inline int get_codec_vbr_lat(RGY_CODEC codec) { + int codec_vbr = 0; + switch (codec) { + case RGY_CODEC_HEVC: codec_vbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR; break; + case RGY_CODEC_H264: codec_vbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR; break; + default: + fprintf(stderr, "Unsupported codec!\n"); + abort(); + } + return codec_vbr; +} + +static inline int get_codec_cbr(RGY_CODEC codec) { + int codec_cbr = 0; + switch (codec) { + case RGY_CODEC_HEVC: codec_cbr = AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR; break; + case RGY_CODEC_H264: codec_cbr = AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR; break; + default: + fprintf(stderr, "Unsupported codec!\n"); + abort(); + } + return codec_cbr; +} + struct VCECodecParam { int nProfile; int nTier; diff --git a/VCEEnc/frm/frmConfig.cpp b/VCEEnc/frm/frmConfig.cpp index f36157b2..5710aa63 100644 --- a/VCEEnc/frm/frmConfig.cpp +++ b/VCEEnc/frm/frmConfig.cpp @@ -725,8 +725,8 @@ System::Void frmConfig::InitData(CONF_GUIEX *set_config, const SYSTEM_DATA *syst System::Void frmConfig::InitComboBox() { //コンボボックスに値を設定する setComboBox(fcgCXCodec, list_codec); - setComboBox(fcgCXEncMode, list_vce_h264_rc_method); - setComboBox(fcgCXQualityPreset, list_vce_quality_preset); + setComboBox(fcgCXEncMode, list_vce_rc_method_auo); + setComboBox(fcgCXQualityPreset, list_vce_quality_preset_h264); setComboBox(fcgCXCodecLevel, list_avc_level); setComboBox(fcgCXCodecProfile, list_avc_profile); setComboBox(fcgCXHEVCLevel, list_hevc_level); @@ -953,8 +953,8 @@ System::Void frmConfig::ConfToFrm(CONF_GUIEX *cnf) { parse_cmd(&vce, cnf->vce.cmd); SetCXIndex(fcgCXCodec, get_cx_index(list_codec, vce.codec)); - SetCXIndex(fcgCXEncMode, get_cx_index(list_vce_h264_rc_method, vce.rateControl)); - SetCXIndex(fcgCXQualityPreset, get_cx_index(list_vce_quality_preset, vce.qualityPreset)); + SetCXIndex(fcgCXEncMode, get_cx_index(get_rc_method(vce.codec), vce.rateControl)); + SetCXIndex(fcgCXQualityPreset, get_cx_index(get_quality_preset(vce.codec), vce.qualityPreset)); SetNUValue(fcgNUBitrate, vce.nBitrate); SetNUValue(fcgNUMaxkbps, vce.nMaxBitrate); SetNUValue(fcgNUVBVBufSize, vce.nVBVBufferSize); @@ -1088,8 +1088,8 @@ System::String^ frmConfig::FrmToConf(CONF_GUIEX *cnf) { VCEParam vce; vce.codec = (RGY_CODEC)list_codec[fcgCXCodec->SelectedIndex].value; conf->vce.codec = vce.codec; - vce.rateControl = list_vce_h264_rc_method[fcgCXEncMode->SelectedIndex].value; - vce.qualityPreset = list_vce_quality_preset[fcgCXQualityPreset->SelectedIndex].value; + vce.rateControl = get_rc_method(vce.codec)[fcgCXEncMode->SelectedIndex].value; + vce.qualityPreset = get_quality_preset(vce.codec)[fcgCXQualityPreset->SelectedIndex].value; vce.codecParam[RGY_CODEC_H264].nProfile = list_avc_profile[fcgCXCodecProfile->SelectedIndex].value; vce.codecParam[RGY_CODEC_H264].nLevel = list_avc_level[fcgCXCodecLevel->SelectedIndex].value; vce.codecParam[RGY_CODEC_HEVC].nProfile = list_hevc_profile[fcgCXHEVCProfile->SelectedIndex].value; diff --git a/VCEEnc/frm/frmConfig_helper.h b/VCEEnc/frm/frmConfig_helper.h index 4d7932a5..0e5b9586 100644 --- a/VCEEnc/frm/frmConfig_helper.h +++ b/VCEEnc/frm/frmConfig_helper.h @@ -151,6 +151,14 @@ static const wchar_t *const list_vpp_afs_analyze[] = { NULL }; + +static const wchar_t *const list_vce_rc_method_auo[] = { + L"CQP - 固定量子化量", + L"CBR - 固定ビットレート", + L"VBR - 可変ビットレート", + NULL +}; + static int get_cx_index(const wchar_t *const *list, const wchar_t *wchr) { for (int i = 0; list[i]; i++) if (0 == wcscmp(list[i], wchr))