[vlc-devel] [PATCH 2/2] NVENC: query capabilities
Felix Paul Kühne
fkuehne at videolan.org
Thu Apr 7 16:43:33 CEST 2016
From: Jean-Paul Saman <jpsaman at videolan.org>
Signed-off-by: Felix Paul Kühne <fkuehne at videolan.org>
---
modules/hw/nvenc/nvenc.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/modules/hw/nvenc/nvenc.c b/modules/hw/nvenc/nvenc.c
index 50aa5bf..f4b6a07 100644
--- a/modules/hw/nvenc/nvenc.c
+++ b/modules/hw/nvenc/nvenc.c
@@ -130,6 +130,75 @@ static int input_string_to_uint32(const NvencValuePair *pair, const char *input,
return VLC_EBADVAR;
}
+static const char *nvenc_decode_cap_int(uint32_t val)
+{
+ switch(val) {
+ case 0: return "not supported";
+ case 1: return "supported";
+ case 2: return "both";
+ default: return "unknown";
+ }
+}
+
+static void nvenc_decode_cap_ratecontrol(encoder_t *enc, uint32_t mask)
+{
+ if (mask & NV_ENC_PARAMS_RC_CONSTQP) msg_Dbg(enc, "\t- Constant QP mode (CONSTQP)");
+ if (mask & NV_ENC_PARAMS_RC_VBR) msg_Dbg(enc, "\t- Variable bitrate mode (VBR)");
+ if (mask & NV_ENC_PARAMS_RC_CBR) msg_Dbg(enc, "\t- Constant bitrate mode (CBR)");
+ if (mask & NV_ENC_PARAMS_RC_VBR_MINQP) msg_Dbg(enc, "\t- Variable bitrate mode with MinQP (VBR_MINQP)");
+ if (mask & NV_ENC_PARAMS_RC_2_PASS_QUALITY) msg_Dbg(enc, "\t- Multi pass encoding optimized for image quality and works only with low latency mode");
+ if (mask & NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP) msg_Dbg(enc,"\t- Multi pass encoding optimized for maintaining frame size and works only with low latency mode");
+ if (mask & NV_ENC_PARAMS_RC_2_PASS_VBR) msg_Dbg(enc, "\t- Multi pass VBR");
+}
+
+typedef struct NvencCabapilities {
+ NV_ENC_CAPS caps;
+ const char *descr;
+ const char * (*func)(uint32_t val);
+} NvencCapabilities;
+
+static const NvencCapabilities nvenc_capabilities[] = {
+ { NV_ENC_CAPS_NUM_MAX_BFRAMES, "Maximum number of B-frames", NULL },
+ { NV_ENC_CAPS_SUPPORTED_RATECONTROL_MODES, "Rate control modes", NULL },
+ { NV_ENC_CAPS_SUPPORT_FIELD_ENCODING, "Field mode encoding (interlaced)", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_MONOCHROME, "Monochrome encoding", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_FMO, "FMO", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_QPELMV, "Quarter pel motion estimation", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_BDIRECT_MODE, "BDirect modes", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_CABAC, "CABAC entropy coding mode", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_ADAPTIVE_TRANSFORM, "Adaptive transforms", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_RESERVED, "Reserved", NULL },
+ { NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS, "Temporal layers", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_HIERARCHICAL_PFRAMES, "Hierarchical P frames", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_HIERARCHICAL_BFRAMES, "Hierarchical B frames", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_LEVEL_MAX, "Maximum encoding level", NULL },
+ { NV_ENC_CAPS_LEVEL_MIN, "Minimum encoding level", NULL },
+ { NV_ENC_CAPS_SEPARATE_COLOUR_PLANE, "Separate colour plane encoding", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_WIDTH_MAX, "Maximum output width", NULL },
+ { NV_ENC_CAPS_HEIGHT_MAX, "Maximum output height", NULL },
+ { NV_ENC_CAPS_SUPPORT_TEMPORAL_SVC, "Temporal Scalability", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_DYN_RES_CHANGE, "Dynamic encode resolution change", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE, "Dynamic encode bitrate change", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_DYN_FORCE_CONSTQP, "Forcing constant QP on the fly", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_DYN_RCMODE_CHANGE, "Dynamic rate control mode change", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_SUBFRAME_READBACK, "Subframe readback support (slice-based encoding)", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING, "Constrained encoding mode", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_INTRA_REFRESH, "Intra refresh mode support", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_CUSTOM_VBV_BUF_SIZE, "Custom VBV buffer size", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_DYNAMIC_SLICE_MODE, "Dynamic slice mode", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_REF_PIC_INVALIDATION, "Reference Picture Invalidation", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_PREPROC_SUPPORT, "Preprocessing mask", NULL },
+ { NV_ENC_CAPS_ASYNC_ENCODE_SUPPORT, "Async mode", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_MB_NUM_MAX, "Maximum MBs per frame", NULL },
+ { NV_ENC_CAPS_MB_PER_SEC_MAX, "Maximum aggregate throughput (MB/s)", NULL },
+ { NV_ENC_CAPS_SUPPORT_YUV444_ENCODE, "YUV444 mode encoding", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE, "Lossless encoding", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_SAO, "Sample Adaptive offset", nvenc_decode_cap_int },
+ { NV_ENC_CAPS_SUPPORT_MEONLY_MODE, "ME only mode", nvenc_decode_cap_int },
+
+ { NV_ENC_CAPS_EXPOSED_COUNT, NULL, NULL },
+};
+
static NvencData* data_queue_dequeue(NvencDataList* queue)
{
uint32_t mask;
@@ -360,6 +429,44 @@ error:
return false;
}
+static void nvenc_check_capabilities(encoder_t *enc, GUID codec)
+{
+ encoder_sys_t *sys = enc->p_sys;
+
+ NvencContext *ctx = &sys->ctx;
+ NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
+ NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
+ NVENCSTATUS nvstatus;
+
+ msg_Dbg(enc, "Capabilities: ");
+ int val = 0;
+ for (int capability = 0;
+ capability < NV_ENC_CAPS_EXPOSED_COUNT;
+ capability++) {
+ NV_ENC_CAPS_PARAM param = {0};
+ param.version = NV_ENC_CAPS_PARAM_VER;
+ param.capsToQuery = (NV_ENC_CAPS)capability;
+ nvstatus = p_nvenc->nvEncGetEncodeCaps(ctx->nvencoder, codec,
+ ¶m, &val);
+ if (nvstatus == NV_ENC_SUCCESS) {
+ if (nvenc_capabilities[capability].func) {
+ msg_Dbg(enc, " * %s: (%d) %s",
+ nvenc_capabilities[capability].descr, val,
+ nvenc_capabilities[capability].func(val));
+ } else if (capability == NV_ENC_CAPS_SUPPORTED_RATECONTROL_MODES) {
+ msg_Dbg(enc, " * %s: (0x%x) ", nvenc_capabilities[capability].descr, val);
+ nvenc_decode_cap_ratecontrol(enc, val);
+ } else if (capability != NV_ENC_CAPS_SUPPORT_RESERVED) {
+ msg_Dbg(enc, " * %s: (0x%x) %d",
+ nvenc_capabilities[capability].descr,
+ val, val);
+ }
+ } else
+ msg_Warn(enc, "\tCould not obtain capability '%s' from hardware",
+ nvenc_capabilities[capability].descr);
+ }
+}
+
static bool nvenc_dyload_nvenc(encoder_t *enc)
{
encoder_sys_t *sys = enc->p_sys;
@@ -569,6 +676,9 @@ int nvenc_encode_init(encoder_t *enc)
goto error;
}
+ /* Print capabilities */
+ nvenc_check_capabilities(enc, codec);
+
nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder, codec, encoder_preset, &preset_config);
if (nv_status != NV_ENC_SUCCESS) {
msg_Err(enc, "GetEncodePresetConfig failed: 0x%x", (int)nv_status);
--
2.8.1
More information about the vlc-devel
mailing list