[vlc-commits] nvdec: allocate all surfaces before creating the pool
Steve Lhomme
git at videolan.org
Fri Sep 4 13:49:12 CEST 2020
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Thu Sep 3 16:52:33 2020 +0200| [03b87931aa04297a3150f7b8f050c7b5088ebde7] | committer: Steve Lhomme
nvdec: allocate all surfaces before creating the pool
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=03b87931aa04297a3150f7b8f050c7b5088ebde7
---
modules/hw/nvdec/nvdec.c | 96 +++++++++++++++++++++++++++---------------------
1 file changed, 55 insertions(+), 41 deletions(-)
diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
index 85705853ee..e255c8a4fb 100644
--- a/modules/hw/nvdec/nvdec.c
+++ b/modules/hw/nvdec/nvdec.c
@@ -78,9 +78,11 @@ vlc_module_end ()
#define OUTPUT_WIDTH_ALIGN 16
+typedef struct nvdec_ctx nvdec_ctx_t;
+
typedef struct nvdec_pool_t {
vlc_video_context *vctx;
- decoder_device_nvdec_t *nvdec_dev;
+ nvdec_ctx_t *p_sys;
CUdeviceptr outputDevicePtr[MAX_POOL_SIZE];
picture_pool_t *picture_pool;
@@ -93,7 +95,7 @@ typedef struct pic_pool_context_nvdec_t {
nvdec_pool_t *pool;
} pic_pool_context_nvdec_t;
-typedef struct nvdec_ctx {
+struct nvdec_ctx {
decoder_device_nvdec_t *devsys;
CuvidFunctions *cuvidFunctions;
CUVIDDECODECAPS selectedDecoder;
@@ -116,16 +118,23 @@ typedef struct nvdec_ctx {
nvdec_pool_t *out_pool;
vlc_video_context *vctx_out;
-} nvdec_ctx_t;
+};
#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__)
#define NVDEC_PICPOOLCTX_FROM_PICCTX(pic_ctx) \
container_of(NVDEC_PICCONTEXT_FROM_PICCTX(pic_ctx), pic_pool_context_nvdec_t, ctx)
+static void PoolRelease(nvdec_ctx_t *p_sys, CUdeviceptr buffers[], size_t pics_count)
+{
+ for (size_t i=0; i < pics_count; i++)
+ p_sys->devsys->cudaFunctions->cuMemFree( buffers[i] );
+ cuvid_free_functions(&p_sys->cuvidFunctions);
+ free(p_sys);
+}
+
static void nvdec_pool_AddRef(nvdec_pool_t *pool)
{
vlc_atomic_rc_inc(&pool->rc);
@@ -136,8 +145,7 @@ static void nvdec_pool_Release(nvdec_pool_t *pool)
if (!vlc_atomic_rc_dec(&pool->rc))
return;
- for (size_t i=0; i < ARRAY_SIZE(pool->outputDevicePtr); i++)
- CALL_CUDA_POOL(cuMemFree, pool->outputDevicePtr[i]);
+ PoolRelease(pool->p_sys, pool->outputDevicePtr, ARRAY_SIZE(pool->outputDevicePtr));
picture_pool_Release(pool->picture_pool);
vlc_video_context_Release(pool->vctx);
@@ -145,37 +153,19 @@ static void nvdec_pool_Release(nvdec_pool_t *pool)
static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
const video_format_t *fmt,
- size_t buffer_pitch,
- size_t buffer_height)
+ CUdeviceptr outputDevicePtr[MAX_POOL_SIZE])
{
- 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);
- assert(pool->nvdec_dev != NULL);
-
- int ret = CALL_CUDA_POOL(cuCtxPushCurrent, pool->nvdec_dev->cuCtx);
- if (ret != CUDA_SUCCESS)
+ if (unlikely(!pool))
goto error;
picture_t *pics[ARRAY_SIZE(pool->outputDevicePtr)] = {0};
for (size_t i=0; i < ARRAY_SIZE(pool->outputDevicePtr); i++)
{
- ret = CALL_CUDA_POOL(cuMemAlloc,
- &pool->outputDevicePtr[i],
- buffer_pitch * buffer_height);
- if (ret != CUDA_SUCCESS || pool->outputDevicePtr[i] == 0)
- goto free_pool;
-
pics[i] = picture_NewFromResource(fmt, &(picture_resource_t) { 0 });
if (!pics[i])
goto free_pool;
+ pool->outputDevicePtr[i] = outputDevicePtr[i];
pics[i]->p_sys = (void*)(uintptr_t)pool->outputDevicePtr[i];
}
@@ -183,9 +173,6 @@ static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
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);
@@ -195,15 +182,10 @@ static nvdec_pool_t* nvdec_pool_Create(vlc_video_context *vctx,
free_pool:
for (size_t i=0; i < ARRAY_SIZE(pool->outputDevicePtr); i++)
{
- if (pool->outputDevicePtr[i] != 0)
- CALL_CUDA_POOL(cuMemFree, pool->outputDevicePtr[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;
@@ -421,10 +403,39 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
vlc_assert_unreachable();
}
- p_sys->out_pool = nvdec_pool_Create(p_sys->vctx_out,
- &p_dec->fmt_out.video,
- ByteWidth,
- Height);
+ int ret = CALL_CUDA_DEC(cuCtxPushCurrent, p_sys->devsys->cuCtx);
+ if (ret != CUDA_SUCCESS)
+ goto cuda_error;
+
+ CUdeviceptr outputDevicePtr[MAX_POOL_SIZE];
+ for (size_t i=0; i < ARRAY_SIZE(outputDevicePtr); i++)
+ {
+ ret = CALL_CUDA_DEC(cuMemAlloc,
+ &outputDevicePtr[i],
+ ByteWidth * Height);
+ if (ret != CUDA_SUCCESS || outputDevicePtr[i] == 0)
+ {
+ while (i)
+ CALL_CUDA_DEC(cuMemFree, outputDevicePtr[--i]);
+ outputDevicePtr[0] = 0;
+ break;
+ }
+ }
+
+ p_sys->out_pool = NULL;
+ if (outputDevicePtr[0])
+ {
+ void *bufferPtr[ARRAY_SIZE(outputDevicePtr)];
+ for (size_t i=0; i<ARRAY_SIZE(outputDevicePtr); i++)
+ bufferPtr[i] = (void*)(uintptr_t)outputDevicePtr[i];
+ p_sys->out_pool = nvdec_pool_Create(p_sys->vctx_out, &p_dec->fmt_out.video,
+ outputDevicePtr);
+ if (p_sys->out_pool == NULL)
+ PoolRelease(p_sys, outputDevicePtr, ARRAY_SIZE(outputDevicePtr));
+ else
+ p_sys->out_pool->p_sys = p_sys;
+ }
+ CALL_CUDA_DEC(cuCtxPopCurrent, NULL);
if (p_sys->out_pool == NULL)
goto cuda_error;
}
@@ -1089,8 +1100,11 @@ static void CloseDecoder(vlc_object_t *p_this)
hxxx_helper_clean(&p_sys->hh);
if (p_sys->out_pool)
nvdec_pool_Release(p_sys->out_pool);
- cuvid_free_functions(&p_sys->cuvidFunctions);
- free(p_sys);
+ else
+ {
+ cuvid_free_functions(&p_sys->cuvidFunctions);
+ free(p_sys);
+ }
}
/** Decoder Device **/
More information about the vlc-commits
mailing list