[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