[FFmpeg-devel] [PATCH] nvenc: Don't segfault on close if no cuda is available
Philip Langdale
philipl at overt.org
Sat Sep 2 05:58:16 EEST 2017
On Wed, 30 Aug 2017 20:09:34 +0100
Mark Thompson <sw at jkqxz.net> wrote:
> ---
> """
> Cannot load libcuda.so.1
>
> Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
> 0x000055555657cd59 in ff_nvenc_encode_close (avctx=0x5555578ed920) at
> src/libavcodec/nvenc.c:1337 1337 cu_res =
> dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context); """
>
> This only fixes the segfaults - some of the other stuff might want to
> be gated as well?
>
>
> libavcodec/nvenc.c | 26 +++++++++++++++-----------
> 1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index 8c4fd31fec..5586a8901f 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -1334,10 +1334,12 @@ av_cold int
> ff_nvenc_encode_close(AVCodecContext *avctx) CUcontext dummy;
> int i;
>
> - cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);
> - if (cu_res != CUDA_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");
> - return AVERROR_EXTERNAL;
> + if (dl_fn->cuda_dl) {
> + cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);
> + if (cu_res != CUDA_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");
> + return AVERROR_EXTERNAL;
> + }
> }
>
> /* the encoder has to be flushed before it can be closed */
> @@ -1381,14 +1383,16 @@ av_cold int
> ff_nvenc_encode_close(AVCodecContext *avctx)
> p_nvenc->nvEncDestroyEncoder(ctx->nvencoder); ctx->nvencoder = NULL;
>
> - cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);
> - if (cu_res != CUDA_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");
> - return AVERROR_EXTERNAL;
> - }
> + if (dl_fn->cuda_dl) {
> + cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);
> + if (cu_res != CUDA_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");
> + return AVERROR_EXTERNAL;
> + }
>
> - if (ctx->cu_context_internal)
> - dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal);
> + if (ctx->cu_context_internal)
> + dl_fn->cuda_dl->cuCtxDestroy(ctx->cu_context_internal);
> + }
> ctx->cu_context = ctx->cu_context_internal = NULL;
>
> nvenc_free_functions(&dl_fn->nvenc_dl);
It looks correct. I agree you probably want to short cut the cleanup if
you know it failed during function loading, but looking it over, the
remaining cleanup steps are safe.
--phil
More information about the ffmpeg-devel
mailing list