[vlc-devel] [PATCH 6/6] nvdec: add reference-count to the picture pool
Steve Lhomme
robux4 at ycbcr.xyz
Thu Mar 26 11:19:36 CET 2020
It seems odd that the picture created by the pool is responsible to
release the pool when it's released. That's why I went with va_surface
which holds the buffers, not the pictures. The pictures are only managed
by the pool.
Looking at the picture_Destroy() code it seems that it's not safe.
PictureDestroyContext destroys the context which will decrement the pool
refcount in your code. When it's the last picture, after the decoder is
closed, it will release the pool. Then priv->gc.destroy is called which
should call the picture_pool_ReleasePicture() which will also free the pool.
va_surface removes the pool from the equation. Only the buffers and
pictures exist. When the decoder is released the pool is release too.
Only the buffers and in-flight pictures still exist. The last picture
released releases the buffers.
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 | 52 +++++++++++++++++++++++++++++++---------
> 1 file changed, 41 insertions(+), 11 deletions(-)
>
> diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
> index d687f8ba3d..88c8709d81 100644
> --- a/modules/hw/nvdec/nvdec.c
> +++ b/modules/hw/nvdec/nvdec.c
> @@ -29,6 +29,7 @@
> #include <vlc_codec.h>
> #include <vlc_messages.h>
> #include <vlc_picture_pool.h>
> +#include <vlc_atomic.h>
>
> #define FFNV_LOG_FUNC(logctx, msg, ...) msg_Err((vlc_object_t*)logctx, msg, __VA_ARGS__)
> #define FFNV_DEBUG_LOG_FUNC(logctx, msg, ...) msg_Dbg((vlc_object_t*)logctx, msg, __VA_ARGS__)
> @@ -83,8 +84,15 @@ typedef struct nvdec_pool_t {
>
> CUdeviceptr device_ptrs[MAX_POOL_SIZE];
> picture_pool_t *picture_pool;
> +
> + vlc_atomic_rc_t rc;
> } nvdec_pool_t;
>
> +typedef struct pic_pool_context_nvdec_t {
> + pic_context_nvdec_t ctx;
> + nvdec_pool_t *pool;
> +} pic_pool_context_nvdec_t;
> +
> typedef struct nvdec_ctx {
> decoder_device_nvdec_t *devsys;
> CuvidFunctions *cuvidFunctions;
> @@ -115,6 +123,9 @@ typedef struct nvdec_ctx {
> #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__)
>
> +#define NVDEC_PICPOOLCTX_FROM_PICCTX(pic_ctx) \
> + container_of(NVDEC_PICCTX_FROM_PICCTX(pic_ctx), pic_pool_context_nvdec_t, ctx)
> +
>
> static void nvdec_pool_Destroy(nvdec_pool_t *pool)
> {
> @@ -127,6 +138,19 @@ static void nvdec_pool_Destroy(nvdec_pool_t *pool)
> vlc_video_context_Release(pool->vctx);
> }
>
> +static void nvdec_pool_AddRef(nvdec_pool_t *pool)
> +{
> + vlc_atomic_rc_inc(&pool->rc);
> +}
> +
> +static void nvdec_pool_Release(nvdec_pool_t *pool)
> +{
> + if (!vlc_atomic_rc_dec(&pool->rc))
> + return;
> +
> + nvdec_pool_Destroy(pool);
> +}
> +
> static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
> const video_format_t *fmt,
> size_t buffer_pitch,
> @@ -176,6 +200,7 @@ static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
> pool->vctx = vctx;
> vlc_video_context_Hold(pool->vctx);
>
> + vlc_atomic_rc_init(&pool->rc);
> return pool;
>
> free_pool:
> @@ -197,20 +222,22 @@ error:
>
> static void nvdec_picture_CtxDestroy(struct picture_context_t *picctx)
> {
> - pic_context_nvdec_t *srcpic = NVDEC_PICCTX_FROM_PICCTX(picctx);
> + pic_pool_context_nvdec_t *srcpic = NVDEC_PICPOOLCTX_FROM_PICCTX(picctx);
> + nvdec_pool_Release(srcpic->pool);
> free(srcpic);
> }
>
> static struct picture_context_t *nvdec_picture_CtxClone(struct picture_context_t *srcctx)
> {
> - pic_context_nvdec_t *clonectx = malloc(sizeof(*clonectx));
> + pic_pool_context_nvdec_t *clonectx = malloc(sizeof(*clonectx));
> if (unlikely(clonectx == NULL))
> return NULL;
> - pic_context_nvdec_t *srcpic = NVDEC_PICCTX_FROM_PICCTX(srcctx);
> + pic_pool_context_nvdec_t *srcpic = NVDEC_PICPOOLCTX_FROM_PICCTX(srcctx);
>
> *clonectx = *srcpic;
> - vlc_video_context_Hold(clonectx->ctx.vctx);
> - return &clonectx->ctx;
> + vlc_video_context_Hold(clonectx->ctx.ctx.vctx);
> + nvdec_pool_AddRef(clonectx->pool);
> + return &clonectx->ctx.ctx;
> }
>
> static picture_t* nvdec_pool_Wait(nvdec_pool_t *pool)
> @@ -219,18 +246,21 @@ static picture_t* nvdec_pool_Wait(nvdec_pool_t *pool)
> if (!pic)
> return NULL;
>
> - pic_context_nvdec_t *picctx = malloc(sizeof(*picctx));
> + pic_pool_context_nvdec_t *picctx = malloc(sizeof(*picctx));
> if (!picctx)
> goto error;
>
> - picctx->ctx = (picture_context_t) {
> + picctx->ctx.ctx = (picture_context_t) {
> nvdec_picture_CtxDestroy,
> nvdec_picture_CtxClone,
> pool->vctx,
> };
> - vlc_video_context_Hold(picctx->ctx.vctx);
> + vlc_video_context_Hold(picctx->ctx.ctx.vctx);
> +
> + picctx->pool = pool;
> + nvdec_pool_AddRef(picctx->pool);
>
> - pic->context = &picctx->ctx;
> + pic->context = &picctx->ctx.ctx;
> return pic;
>
> error:
> @@ -313,7 +343,7 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
> {
> if (p_sys->out_pool)
> {
> - nvdec_pool_Destroy(p_sys->out_pool);
> + nvdec_pool_Release(p_sys->out_pool);
> p_sys->out_pool = NULL;
> }
> }
> @@ -1059,7 +1089,7 @@ static void CloseDecoder(vlc_object_t *p_this)
> CALL_CUDA_DEC(cuCtxPopCurrent, NULL);
>
> if (p_sys->out_pool)
> - nvdec_pool_Destroy(p_sys->out_pool);
> + nvdec_pool_Release(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