From fb59f87ce72035b940c3f5045884098b9324e1b2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 13 Jan 2017 10:53:35 +0100 Subject: [PATCH] nvenc: Explicitly push the cuda context on encoding Make sure that NVENC does not misbehave if other cuda usages happen in the application. --- libavcodec/nvenc.c | 7 +++++++ libavcodec/nvenc.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 4054e43eec..fe7b7f40f0 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -178,6 +178,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx) nvel->cu_device_compute_capability = cuDeviceComputeCapability; nvel->cu_ctx_create = cuCtxCreate_v2; nvel->cu_ctx_pop_current = cuCtxPopCurrent_v2; + nvel->cu_ctx_push_current = cuCtxPushCurrent_v2; nvel->cu_ctx_destroy = cuCtxDestroy_v2; #else LOAD_LIBRARY(nvel->cuda, CUDA_LIBNAME); @@ -190,6 +191,7 @@ static av_cold int nvenc_load_libraries(AVCodecContext *avctx) "cuDeviceComputeCapability"); LOAD_SYMBOL(nvel->cu_ctx_create, nvel->cuda, "cuCtxCreate_v2"); LOAD_SYMBOL(nvel->cu_ctx_pop_current, nvel->cuda, "cuCtxPopCurrent_v2"); + LOAD_SYMBOL(nvel->cu_ctx_push_current, nvel->cuda, "cuCtxPushCurrent_v2"); LOAD_SYMBOL(nvel->cu_ctx_destroy, nvel->cuda, "cuCtxDestroy_v2"); #endif @@ -1522,9 +1524,11 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { NVENCContext *ctx = avctx->priv_data; + NVENCLibraryContext *nvel = &ctx->nvel; NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs; NV_ENC_PIC_PARAMS params = { 0 }; NVENCFrame *nvenc_frame = NULL; + CUcontext dummy; int enc_ret, ret; params.version = NV_ENC_PIC_PARAMS_VER; @@ -1570,7 +1574,10 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; } + nvel->cu_ctx_push_current(ctx->cu_context); enc_ret = nv->nvEncEncodePicture(ctx->nvenc_ctx, ¶ms); + nvel->cu_ctx_pop_current(&dummy); + if (enc_ret != NV_ENC_SUCCESS && enc_ret != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, enc_ret, "Error encoding the frame"); diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index dfd03b5ebd..6df45480a9 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -66,6 +66,7 @@ typedef CUresult(CUDAAPI *PCUDEVICEGETNAME)(char *name, int len, CUdevice dev); typedef CUresult(CUDAAPI *PCUDEVICECOMPUTECAPABILITY)(int *major, int *minor, CUdevice dev); typedef CUresult(CUDAAPI *PCUCTXCREATE)(CUcontext *pctx, unsigned int flags, CUdevice dev); typedef CUresult(CUDAAPI *PCUCTXPOPCURRENT)(CUcontext *pctx); +typedef CUresult(CUDAAPI *PCUCTXPUSHCURRENT)(CUcontext ctx); typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx); typedef NVENCSTATUS (NVENCAPI *PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList); @@ -84,6 +85,7 @@ typedef struct NVENCLibraryContext PCUDEVICECOMPUTECAPABILITY cu_device_compute_capability; PCUCTXCREATE cu_ctx_create; PCUCTXPOPCURRENT cu_ctx_pop_current; + PCUCTXPUSHCURRENT cu_ctx_push_current; PCUCTXDESTROY cu_ctx_destroy; NV_ENCODE_API_FUNCTION_LIST nvenc_funcs;