[vlc-devel] [PATCH 2/6] nvdec: regroup picture-pool related code

Steve Lhomme robux4 at ycbcr.xyz
Thu Mar 26 11:19:43 CET 2020


Comments below,

On 2020-03-25 18:57, quentin.chateau at deepskycorp.com wrote:
> From: Quentin Chateau <quentin.chateau at deepskycorp.com>
> 
> ---
>   modules/hw/nvdec/nvdec.c | 148 ++++++++++++++++++++++++++-------------
>   1 file changed, 98 insertions(+), 50 deletions(-)
> 
> diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
> index 05a54c555d..d89d79b12f 100644
> --- a/modules/hw/nvdec/nvdec.c
> +++ b/modules/hw/nvdec/nvdec.c
> @@ -77,6 +77,14 @@ vlc_module_end ()
>   
>   #define OUTPUT_WIDTH_ALIGN   16
>   
> +typedef struct nvdec_pool_t {
> +    vlc_video_context           *vctx;
> +    decoder_device_nvdec_t      *nvdec_dev;
> +
> +    CUdeviceptr                 device_ptrs[MAX_POOL_SIZE];

You should avoid renaming when moving code so it's easier to match what 
was moved and if it matches.

> +    picture_pool_t              *picture_pool;
> +} nvdec_pool_t;
> +
>   typedef struct nvdec_ctx {
>       decoder_device_nvdec_t      *devsys;
>       CuvidFunctions              *cuvidFunctions;
> @@ -96,9 +104,8 @@ typedef struct nvdec_ctx {
>       bool                        b_nvparser_success;
>       size_t                      decoderHeight;
>   
> -    CUdeviceptr                 outputDevicePtr[MAX_POOL_SIZE];
>       unsigned int                outputPitch;
> -    picture_pool_t              *out_pool;
> +    nvdec_pool_t                *out_pool;
>   
>       vlc_video_context           *vctx_out;
>   } nvdec_ctx_t;
> @@ -106,6 +113,87 @@ typedef struct nvdec_ctx {
>   #define CALL_CUDA_DEC(func, ...) CudaCheckErr(VLC_OBJECT(p_dec),  p_sys->devsys->cudaFunctions, p_sys->devsys->cudaFunctions->func(__VA_ARGS__), #func)
>   #define CALL_CUDA_DEV(func, ...) CudaCheckErr(VLC_OBJECT(device), p_sys->cudaFunctions, p_sys->cudaFunctions->func(__VA_ARGS__), #func)
>   #define CALL_CUVID(func, ...)    CudaCheckErr(VLC_OBJECT(p_dec),  p_sys->devsys->cudaFunctions, p_sys->cuvidFunctions->func(__VA_ARGS__), #func)
> +#define CALL_CUDA_POOL(func, ...) pool->nvdec_dev->cudaFunctions->func(__VA_ARGS__)
> +
> +
> +static void nvdec_pool_Destroy(nvdec_pool_t *pool)
> +{
> +    CALL_CUDA_POOL(cuCtxPushCurrent, pool->nvdec_dev->cuCtx);
> +    for (size_t i=0; i < ARRAY_SIZE(pool->device_ptrs); i++)
> +        CALL_CUDA_POOL(cuMemFree, pool->device_ptrs[i]);
> +    CALL_CUDA_POOL(cuCtxPopCurrent, NULL);

This push/pop wasn't there in the original code. You may add a patch 
before that to tell about this addition.

> +
> +    picture_pool_Release(pool->picture_pool);
> +    vlc_video_context_Release(pool->vctx);
> +}
> +
> +static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
> +                                       const video_format_t *fmt,
> +                                       size_t buffer_pitch,
> +                                       size_t buffer_height)
> +{
> +    vlc_decoder_device *dec_dev = NULL;
> +    nvdec_pool_t *pool = calloc(1, sizeof(*pool));
> +    if (!pool)
> +        goto error;
> +
> +    dec_dev = vlc_video_context_HoldDevice(vctx);
> +    if (dec_dev == NULL)
> +        goto error;
> +
> +    pool->nvdec_dev = GetNVDECOpaqueDevice(dec_dev);
> +    if (pool->nvdec_dev == NULL)

Here you can assert. It should never happen.

> +        goto error;
> +
> +    int ret = CALL_CUDA_POOL(cuCtxPushCurrent, pool->nvdec_dev->cuCtx);
> +    if (ret != CUDA_SUCCESS)
> +        goto error;
> +
> +    picture_t *pics[ARRAY_SIZE(pool->device_ptrs)] = {0};
> +    for (size_t i=0; i < ARRAY_SIZE(pool->device_ptrs); i++)
> +    {
> +        ret = CALL_CUDA_POOL(cuMemAlloc,
> +                             &pool->device_ptrs[i],
> +                             buffer_pitch * buffer_height);
> +        if (ret != CUDA_SUCCESS || pool->device_ptrs[i] == 0)
> +            goto free_pool;
> +
> +        picture_resource_t res = {
> +            .p_sys = (void*)pool->device_ptrs[i],
> +        };
> +        pics[i] = picture_NewFromResource(fmt, &res);
> +        if (!pics[i])
> +            goto free_pool;
> +    }
> +
> +    pool->picture_pool = picture_pool_New(ARRAY_SIZE(pool->device_ptrs), pics);
> +    if (!pool->picture_pool)
> +        goto free_pool;
> +
> +    CALL_CUDA_POOL(cuCtxPopCurrent, NULL);
> +    vlc_decoder_device_Release(dec_dev);
> +
> +    pool->vctx = vctx;
> +    vlc_video_context_Hold(pool->vctx);
> +
> +    return pool;
> +
> +free_pool:
> +    for (size_t i=0; i < ARRAY_SIZE(pool->device_ptrs); i++)
> +    {
> +        if (pool->device_ptrs[i] != 0)
> +            CALL_CUDA_POOL(cuMemFree, pool->device_ptrs[i]);
> +        if (pics[i] != NULL)
> +            picture_Release(pics[i]);
> +    }
> +    CALL_CUDA_POOL(cuCtxPopCurrent, NULL);
> +error:
> +    if (dec_dev)
> +        vlc_decoder_device_Release(dec_dev);
> +    if (pool)
> +        free(pool);
> +    return NULL;
> +}
>   
>   static vlc_fourcc_t MapSurfaceChroma(cudaVideoChromaFormat chroma, unsigned bitDepth)
>   {
> @@ -180,15 +268,9 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
>   
>       if ( is_nvdec_opaque(p_dec->fmt_out.video.i_chroma) )
>       {
> -        for (size_t i=0; i < ARRAY_SIZE(p_sys->outputDevicePtr); i++)
> -        {
> -            CALL_CUDA_DEC(cuMemFree, p_sys->outputDevicePtr[i]);
> -            p_sys->outputDevicePtr[i] = 0;
> -        }
> -
>           if (p_sys->out_pool)
>           {
> -            picture_pool_Release(p_sys->out_pool);
> +            nvdec_pool_Destroy(p_sys->out_pool);
>               p_sys->out_pool = NULL;
>           }
>       }
> @@ -259,44 +341,12 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
>                   vlc_assert_unreachable();
>           }
>   
> -        picture_t *pics[ARRAY_SIZE(p_sys->outputDevicePtr)];
> -        for (size_t i=0; i < ARRAY_SIZE(p_sys->outputDevicePtr); i++)
> -        {
> -            ret = CALL_CUDA_DEC(cuMemAlloc, &p_sys->outputDevicePtr[i], ByteWidth * Height);
> -            if (ret != VLC_SUCCESS || p_sys->outputDevicePtr[i] == 0)
> -                goto clean_pics;
> -            picture_resource_t res = {
> -                .p_sys = (void*)p_sys->outputDevicePtr[i],
> -            };
> -            pics[i] = picture_NewFromResource( &p_dec->fmt_out.video, &res );
> -            if (unlikely(pics[i] == NULL))
> -            {
> -                msg_Dbg(p_dec, "failed to get a picture for the buffer");
> -                ret = VLC_ENOMEM;
> -                goto clean_pics;
> -            }
> -            continue;
> -clean_pics:
> -            if (p_sys->outputDevicePtr[i])
> -            {
> -                CALL_CUDA_DEC(cuMemFree, p_sys->outputDevicePtr[i]);
> -                p_sys->outputDevicePtr[i] = 0;
> -            }
> -            if (i > 0)
> -            {
> -                while (i--)
> -                {
> -                    picture_Release(pics[i]);
> -                    CALL_CUDA_DEC(cuMemFree, p_sys->outputDevicePtr[i]);
> -                    p_sys->outputDevicePtr[i] = 0;
> -                }
> -            }
> -            break;
> -        }
> -        if (ret != VLC_SUCCESS)
> +        p_sys->out_pool = nvdec_pool_Create(p_sys->vctx_out,
> +                                            &p_dec->fmt_out.video,
> +                                            ByteWidth,
> +                                            Height);
> +        if (p_sys->out_pool == NULL)
>               goto cuda_error;
> -
> -        p_sys->out_pool = picture_pool_New( ARRAY_SIZE(p_sys->outputDevicePtr), pics );
>       }
>   
>       p_sys->decoderHeight = p_format->coded_height;
> @@ -364,7 +414,7 @@ static int CUDAAPI HandlePictureDisplay(void *p_opaque, CUVIDPARSERDISPINFO *p_d
>   
>       if ( is_nvdec_opaque(p_dec->fmt_out.video.i_chroma) )
>       {
> -        p_pic = picture_pool_Wait(p_sys->out_pool);
> +        p_pic = picture_pool_Wait(p_sys->out_pool->picture_pool);

You may add a nvdec_pool_Wait() for consistency.

>           if (unlikely(p_pic == NULL))
>               return 0;
>   
> @@ -997,10 +1047,8 @@ static void CloseDecoder(vlc_object_t *p_this)
>       CALL_CUDA_DEC(cuCtxPushCurrent, p_sys->devsys->cuCtx);
>       CALL_CUDA_DEC(cuCtxPopCurrent, NULL);
>   
> -    for (size_t i=0; i < ARRAY_SIZE(p_sys->outputDevicePtr); i++)
> -        CALL_CUDA_DEC(cuMemFree, p_sys->outputDevicePtr[i]);
>       if (p_sys->out_pool)
> -        picture_pool_Release(p_sys->out_pool);
> +        nvdec_pool_Destroy(p_sys->out_pool);
>       if (p_sys->cudecoder)
>           CALL_CUVID(cuvidDestroyDecoder, p_sys->cudecoder);
>       if (p_sys->cuparser)
> -- 
> 2.17.1
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
> 


More information about the vlc-devel mailing list