CUvideodecoder cudecoder;
CUvideoparser cuparser;
+ char *cu_gpu;
+
AVBufferRef *hwdevice;
AVBufferRef *hwframe;
int64_t prev_pts;
int internal_error;
- int ever_flushed;
int decoder_flushing;
cudaVideoCodec codec_type;
return 0;
}
- if (hwframe_ctx->pool && !ctx->ever_flushed) {
- av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized\n");
+ if (hwframe_ctx->pool && (
+ hwframe_ctx->width < avctx->width ||
+ hwframe_ctx->height < avctx->height ||
+ hwframe_ctx->format != AV_PIX_FMT_CUDA ||
+ hwframe_ctx->sw_format != AV_PIX_FMT_NV12)) {
+ av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized with incompatible parameters\n");
ctx->internal_error = AVERROR(EINVAL);
return 0;
}
if (!hwframe_ctx->pool) {
hwframe_ctx->format = AV_PIX_FMT_CUDA;
hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
- hwframe_ctx->width = FFALIGN(avctx->coded_width, 32);
- hwframe_ctx->height = FFALIGN(avctx->coded_height, 32);
+ hwframe_ctx->width = avctx->width;
+ hwframe_ctx->height = avctx->height;
if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
.dstPitch = frame->linesize[i],
.srcY = offset,
.WidthInBytes = FFMIN(pitch, frame->linesize[i]),
- .Height = avctx->coded_height >> (i ? 1 : 0),
+ .Height = avctx->height >> (i ? 1 : 0),
};
ret = CHECK_CU(cuMemcpy2D(&cpy));
/* CUVIDs opaque reordering breaks the internal pkt logic.
* So set pkt_pts and clear all the other pkt_ fields.
*/
+#if FF_API_PKT_PTS
+FF_DISABLE_DEPRECATION_WARNINGS
frame->pkt_pts = frame->pts;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
av_frame_set_pkt_pos(frame, -1);
av_frame_set_pkt_duration(frame, 0);
av_frame_set_pkt_size(frame, -1);
return 0;
}
-static void cuvid_ctx_free(AVHWDeviceContext *ctx)
-{
- AVCUDADeviceContext *hwctx = ctx->hwctx;
- cuCtxDestroy(hwctx->cuda_ctx);
-}
-
static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cuparseinfo)
{
CUVIDDECODECREATEINFO cuinfo;
AVHWDeviceContext *device_ctx;
AVHWFramesContext *hwframe_ctx;
CUVIDSOURCEDATAPACKET seq_pkt;
- CUdevice device;
CUcontext cuda_ctx = NULL;
CUcontext dummy;
const AVBitStreamFilter *bsf;
ret = AVERROR(ENOMEM);
goto error;
}
-
- device_ctx = hwframe_ctx->device_ctx;
- device_hwctx = device_ctx->hwctx;
- cuda_ctx = device_hwctx->cuda_ctx;
} else {
- ctx->hwdevice = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
- if (!ctx->hwdevice) {
- av_log(avctx, AV_LOG_ERROR, "Error allocating hwdevice\n");
- ret = AVERROR(ENOMEM);
- goto error;
- }
-
- ret = CHECK_CU(cuInit(0));
- if (ret < 0)
- goto error;
-
- ret = CHECK_CU(cuDeviceGet(&device, 0));
- if (ret < 0)
- goto error;
-
- ret = CHECK_CU(cuCtxCreate(&cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, device));
- if (ret < 0)
- goto error;
-
- device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
- device_ctx->free = cuvid_ctx_free;
-
- device_hwctx = device_ctx->hwctx;
- device_hwctx->cuda_ctx = cuda_ctx;
-
- ret = CHECK_CU(cuCtxPopCurrent(&dummy));
+ ret = av_hwdevice_ctx_create(&ctx->hwdevice, AV_HWDEVICE_TYPE_CUDA, ctx->cu_gpu, NULL, 0);
if (ret < 0)
goto error;
- ret = av_hwdevice_ctx_init(ctx->hwdevice);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "av_hwdevice_ctx_init failed\n");
- goto error;
- }
-
ctx->hwframe = av_hwframe_ctx_alloc(ctx->hwdevice);
if (!ctx->hwframe) {
av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
ret = AVERROR(ENOMEM);
goto error;
}
+
+ hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
}
+ device_ctx = hwframe_ctx->device_ctx;
+ device_hwctx = device_ctx->hwctx;
+ cuda_ctx = device_hwctx->cuda_ctx;
+
memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo));
memset(&ctx->cuparse_ext, 0, sizeof(ctx->cuparse_ext));
memset(&seq_pkt, 0, sizeof(seq_pkt));
if (ret < 0)
goto error;
- ctx->ever_flushed = 0;
-
ctx->prev_pts = INT64_MIN;
if (!avctx->pkt_timebase.num || !avctx->pkt_timebase.den)
CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
int ret;
- ctx->ever_flushed = 1;
-
ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));
if (ret < 0)
goto error;
{ "weave", "Weave deinterlacing (do nothing)", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0, VD, "deint" },
{ "bob", "Bob deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0, VD, "deint" },
{ "adaptive", "Adaptive deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0, VD, "deint" },
+ { "gpu", "GPU to be used for decoding", OFFSET(cu_gpu), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
{ NULL }
};