[FFmpeg-devel] [PATCH 1/3] nvenc: use runtime api version to support old drivers

2020-07-15 Thread wangbin
From: wang-bin 

There are reserved bit fields in nvEncoderAPI.h structs, so driver's abi
is stable. Requesting runtime version of these structs should work. I've
compared 7.0~9.x headers, and confirmed on some devices.
---
 libavcodec/nvenc.c | 72 ++
 libavcodec/nvenc.h |  3 ++
 2 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index c6740c1842..ac35cb9f48 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -193,14 +193,26 @@ static void nvenc_print_driver_requirement(AVCodecContext 
*avctx, int level)
 av_log(avctx, level, "The minimum required Nvidia driver for nvenc is %s 
or newer\n", minver);
 }
 
+static inline uint32_t struct_ver_rt(NvencContext* ctx, uint32_t struct_ver)
+{
+return ((uint32_t)ctx->apiver_rt | ((struct_ver)<<16) | (0x7 << 28));
+}
+
+static inline uint32_t api_ver(uint32_t major_ver, uint32_t minor_ver)
+{
+return major_ver | (minor_ver << 24);
+}
+
 static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
 {
 NvencContext *ctx= avctx->priv_data;
 NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
 NVENCSTATUS err;
 uint32_t nvenc_max_ver;
+uint32_t nvenc_max_major;
+uint32_t nvenc_max_minor;
+uint32_t func_ver = NV_ENCODE_API_FUNCTION_LIST_VER;
 int ret;
-
 ret = cuda_load_functions(&dl_fn->cuda_dl, avctx);
 if (ret < 0)
 return ret;
@@ -214,19 +226,17 @@ static av_cold int nvenc_load_libraries(AVCodecContext 
*avctx)
 err = dl_fn->nvenc_dl->NvEncodeAPIGetMaxSupportedVersion(&nvenc_max_ver);
 if (err != NV_ENC_SUCCESS)
 return nvenc_print_error(avctx, err, "Failed to query nvenc max 
version");
+nvenc_max_major = nvenc_max_ver >> 4;
+nvenc_max_minor = nvenc_max_ver & 0xf;
+av_log(avctx, AV_LOG_VERBOSE, "nvenc build version: %d.%d, runtime 
version: %d.%d\n", NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION, 
nvenc_max_major, nvenc_max_minor);
 
-av_log(avctx, AV_LOG_VERBOSE, "Loaded Nvenc version %d.%d\n", 
nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
-
-if ((NVENCAPI_MAJOR_VERSION << 4 | NVENCAPI_MINOR_VERSION) > 
nvenc_max_ver) {
-av_log(avctx, AV_LOG_ERROR, "Driver does not support the required 
nvenc API version. "
-   "Required: %d.%d Found: %d.%d\n",
-   NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION,
-   nvenc_max_ver >> 4, nvenc_max_ver & 0xf);
-nvenc_print_driver_requirement(avctx, AV_LOG_ERROR);
-return AVERROR(ENOSYS);
-}
+ctx->apiver_rt = api_ver(nvenc_max_major, nvenc_max_minor); /* 
NVENCAPI_VERSION */
+ctx->config_ver_rt = struct_ver_rt(ctx, 7) | (1<<31); /* NV_ENC_CONFIG_VER 
*/
+if (ctx->apiver_rt < api_ver(8, 1))
+ctx->config_ver_rt = struct_ver_rt(ctx, 6) | (1<<31);
+func_ver = struct_ver_rt(ctx, 2);
 
-dl_fn->nvenc_funcs.version = NV_ENCODE_API_FUNCTION_LIST_VER;
+dl_fn->nvenc_funcs.version = func_ver;
 
 err = dl_fn->nvenc_dl->NvEncodeAPICreateInstance(&dl_fn->nvenc_funcs);
 if (err != NV_ENC_SUCCESS)
@@ -267,8 +277,8 @@ static av_cold int nvenc_open_session(AVCodecContext *avctx)
 NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
 NVENCSTATUS ret;
 
-params.version= NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
-params.apiVersion = NVENCAPI_VERSION;
+params.version= struct_ver_rt(ctx, 1); // 
NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER
+params.apiVersion = ctx->apiver_rt;
 if (ctx->d3d11_device) {
 params.device = ctx->d3d11_device;
 params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
@@ -329,7 +339,7 @@ static int nvenc_check_cap(AVCodecContext *avctx, 
NV_ENC_CAPS cap)
 NV_ENC_CAPS_PARAM params= { 0 };
 int ret, val = 0;
 
-params.version = NV_ENC_CAPS_PARAM_VER;
+params.version = struct_ver_rt(ctx, 1); // NV_ENC_CAPS_PARAM_VER;
 params.capsToQuery = cap;
 
 ret = p_nvenc->nvEncGetEncodeCaps(ctx->nvencoder, 
ctx->init_encode_params.encodeGUID, ¶ms, &val);
@@ -688,7 +698,7 @@ static av_cold void set_constqp(AVCodecContext *avctx)
 NV_ENC_RC_PARAMS *rc = &ctx->encode_config.rcParams;
 
 rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
-
+/*rc->reservedBitField1 = 0;*/
 if (ctx->init_qp_p >= 0) {
 rc->constQP.qpInterP = ctx->init_qp_p;
 if (ctx->init_qp_i >= 0 && ctx->init_qp_b >= 0) {
@@ -1221,8 +1231,8 @@ static av_cold int nvenc_setup_encoder(AVCodecContext 
*avctx)
 int res = 0;
 int dw, dh;
 
-ctx->encode_config.version = NV_ENC_CONFIG_VER;
-ctx->init_encode_params.version = NV_ENC_INITIALIZE_PARAMS_VER;
+ctx->encode_config.version = ctx->config_ver_rt;//NV_ENC_CONFIG_VER;
+ctx->init_encode_params.version = struct_ver_rt(ctx, 5) | 
(1<<31);//NV_ENC_INITIALIZE_PARAMS_VER;
 
 ctx->init_encode_params.encodeHeight = avctx->height;
 ctx->init_encode_params.encodeWidth = 

[FFmpeg-devel] [PATCH 2/3] nvenc: check runtime 9.1 function ptrs before use

2020-07-15 Thread wangbin
From: wang-bin 

---
 libavcodec/nvenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index ac35cb9f48..cec59f02f3 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -140,7 +140,7 @@ static int nvenc_print_error(AVCodecContext *avctx, 
NVENCSTATUS err,
 NvencContext *ctx = avctx->priv_data;
 NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &ctx->nvenc_dload_funcs.nvenc_funcs;
 
-if (p_nvenc && ctx->nvencoder)
+if (p_nvenc && ctx->nvencoder && p_nvenc->nvEncGetLastErrorString)
 details = p_nvenc->nvEncGetLastErrorString(ctx->nvencoder);
 #endif
 
@@ -1353,7 +1353,7 @@ static av_cold int nvenc_setup_encoder(AVCodecContext 
*avctx)
 }
 
 #ifdef NVENC_HAVE_CUSTREAM_PTR
-if (ctx->cu_context) {
+if (ctx->cu_context && p_nvenc->nvEncSetIOCudaStreams) {
 nv_status = p_nvenc->nvEncSetIOCudaStreams(ctx->nvencoder, 
&ctx->cu_stream, &ctx->cu_stream);
 if (nv_status != NV_ENC_SUCCESS) {
 nvenc_pop_context(avctx);
-- 
2.24.1 (Apple Git-126)

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 3/3] nvenc: check sdk 10.0 ptrs at runtime

2020-07-15 Thread wangbin
From: wang-bin 

---
 libavcodec/nvenc.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index cec59f02f3..c421c292c8 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1248,11 +1248,12 @@ static av_cold int nvenc_setup_encoder(AVCodecContext 
*avctx)
 #ifdef NVENC_HAVE_NEW_PRESETS
 ctx->init_encode_params.tuningInfo = ctx->tuning_info;
 
-nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
-ctx->init_encode_params.encodeGUID,
-ctx->init_encode_params.presetGUID,
-ctx->init_encode_params.tuningInfo,
-&preset_config);
+if (p_nvenc->nvEncGetEncodePresetConfigEx)
+nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder,
+ctx->init_encode_params.encodeGUID,
+ctx->init_encode_params.presetGUID,
+ctx->init_encode_params.tuningInfo,
+&preset_config);
 #endif
 } else {
 #ifdef NVENC_HAVE_NEW_PRESETS
-- 
2.24.1 (Apple Git-126)

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".