diff mbox series

[FFmpeg-devel] avcodec/cuviddec: fix CUDA_ERROR_INVALID_CONTEXT error found by cuda-memcheck tool

Message ID 20201118082407.1817-1-nowerzt@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel] avcodec/cuviddec: fix CUDA_ERROR_INVALID_CONTEXT error found by cuda-memcheck tool
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

leozhang Nov. 18, 2020, 8:24 a.m. UTC
Test command like below:
cuda-memcheck ./ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input_file -c:v h264_nvenc -f null -

Signed-off-by: leozhang <nowerzt@gmail.com>
---
 libavcodec/cuviddec.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Timo Rothenpieler Nov. 19, 2020, 4:29 p.m. UTC | #1
On 18.11.2020 09:24, leozhang wrote:
> Test command like below:
> cuda-memcheck ./ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input_file -c:v h264_nvenc -f null -
> 
> Signed-off-by: leozhang <nowerzt@gmail.com>
> ---
>   libavcodec/cuviddec.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
> index 5e698d4cd0..816a9c1b3c 100644
> --- a/libavcodec/cuviddec.c
> +++ b/libavcodec/cuviddec.c
> @@ -673,15 +673,27 @@ static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
>   static av_cold int cuvid_decode_end(AVCodecContext *avctx)
>   {
>       CuvidContext *ctx = avctx->priv_data;
> +    AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)ctx->hwdevice->data;
> +    AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
> +    CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
> +    int ret;
>   
>       av_fifo_freep(&ctx->frame_queue);
>   
> +    ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
> +    if (ret < 0)
> +        goto error;
> +
>       if (ctx->cuparser)
>           ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
>   
>       if (ctx->cudecoder)
>           ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
>   
> +    ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
> +    if (ret < 0)
> +        goto error;

This will cause it to leak all other resources in case Push/Pop fails 
for some reason, which is very much not ideal.

I'd probably just leave all CUDA calls unchecked here. Or check them, 
but ignore the result and just go on anyway.
Nothing sensible to be done when stuff fails on uninit anyway.

>       ctx->cudl = NULL;
>   
>       av_buffer_unref(&ctx->hwframe);
> @@ -693,6 +705,9 @@ static av_cold int cuvid_decode_end(AVCodecContext *avctx)
>       cuvid_free_functions(&ctx->cvdl);
>   
>       return 0;
> +
> +error:
> +    return ret;
>   }
>   
>   static int cuvid_test_capabilities(AVCodecContext *avctx,
>
leozhang Nov. 20, 2020, 2:27 a.m. UTC | #2
Timo Rothenpieler <timo@rothenpieler.org> 于2020年11月20日周五 上午12:29写道:
>
> On 18.11.2020 09:24, leozhang wrote:
> > Test command like below:
> > cuda-memcheck ./ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input_file -c:v h264_nvenc -f null -
> >
> > Signed-off-by: leozhang <nowerzt@gmail.com>
> > ---
> >   libavcodec/cuviddec.c | 15 +++++++++++++++
> >   1 file changed, 15 insertions(+)
> >
> > diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
> > index 5e698d4cd0..816a9c1b3c 100644
> > --- a/libavcodec/cuviddec.c
> > +++ b/libavcodec/cuviddec.c
> > @@ -673,15 +673,27 @@ static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
> >   static av_cold int cuvid_decode_end(AVCodecContext *avctx)
> >   {
> >       CuvidContext *ctx = avctx->priv_data;
> > +    AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)ctx->hwdevice->data;
> > +    AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
> > +    CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
> > +    int ret;
> >
> >       av_fifo_freep(&ctx->frame_queue);
> >
> > +    ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
> > +    if (ret < 0)
> > +        goto error;
> > +
> >       if (ctx->cuparser)
> >           ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
> >
> >       if (ctx->cudecoder)
> >           ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
> >
> > +    ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
> > +    if (ret < 0)
> > +        goto error;
>
> This will cause it to leak all other resources in case Push/Pop fails
> for some reason, which is very much not ideal.
Good catch! I will fix it.
>
> I'd probably just leave all CUDA calls unchecked here. Or check them,
> but ignore the result and just go on anyway.
> Nothing sensible to be done when stuff fails on uninit anyway.
>
> >       ctx->cudl = NULL;
> >
> >       av_buffer_unref(&ctx->hwframe);
> > @@ -693,6 +705,9 @@ static av_cold int cuvid_decode_end(AVCodecContext *avctx)
> >       cuvid_free_functions(&ctx->cvdl);
> >
> >       return 0;
> > +
> > +error:
> > +    return ret;
> >   }
> >
> >   static int cuvid_test_capabilities(AVCodecContext *avctx,
> >
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 5e698d4cd0..816a9c1b3c 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -673,15 +673,27 @@  static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 static av_cold int cuvid_decode_end(AVCodecContext *avctx)
 {
     CuvidContext *ctx = avctx->priv_data;
+    AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)ctx->hwdevice->data;
+    AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
+    CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
+    int ret;
 
     av_fifo_freep(&ctx->frame_queue);
 
+    ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
+    if (ret < 0)
+        goto error;
+
     if (ctx->cuparser)
         ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
 
     if (ctx->cudecoder)
         ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
 
+    ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
+    if (ret < 0)
+        goto error;
+
     ctx->cudl = NULL;
 
     av_buffer_unref(&ctx->hwframe);
@@ -693,6 +705,9 @@  static av_cold int cuvid_decode_end(AVCodecContext *avctx)
     cuvid_free_functions(&ctx->cvdl);
 
     return 0;
+
+error:
+    return ret;
 }
 
 static int cuvid_test_capabilities(AVCodecContext *avctx,