[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,
+                                               &param, &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