+static void cuvid_flush(AVCodecContext *avctx)
+{
+ CuvidContext *ctx = avctx->priv_data;
+ AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
+ AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
+ CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
+ CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
+ int ret;
+
+ ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));
+ if (ret < 0)
+ goto error;
+
+ av_fifo_freep(&ctx->frame_queue);
+
+ ctx->frame_queue = av_fifo_alloc(MAX_FRAME_COUNT * sizeof(CuvidParsedFrame));
+ if (!ctx->frame_queue) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to recreate frame queue on flush\n");
+ return;
+ }
+
+ if (ctx->cudecoder) {
+ cuvidDestroyDecoder(ctx->cudecoder);
+ ctx->cudecoder = NULL;
+ }
+
+ if (ctx->cuparser) {
+ cuvidDestroyVideoParser(ctx->cuparser);
+ ctx->cuparser = NULL;
+ }
+
+ ret = CHECK_CU(cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
+ if (ret < 0)
+ goto error;
+
+ seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data;
+ seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length;
+
+ if (seq_pkt.payload && seq_pkt.payload_size) {
+ ret = CHECK_CU(cuvidParseVideoData(ctx->cuparser, &seq_pkt));
+ if (ret < 0)
+ goto error;
+ }
+
+ ret = CHECK_CU(cuCtxPopCurrent(&dummy));
+ if (ret < 0)
+ goto error;
+
+ ctx->prev_pts = INT64_MIN;
+ ctx->decoder_flushing = 0;
+
+ return;
+ error:
+ av_log(avctx, AV_LOG_ERROR, "CUDA reinit on flush failed\n");
+}
+
+#define OFFSET(x) offsetof(CuvidContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "deint", "Set deinterlacing mode", OFFSET(deint_mode), AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive, VD, "deint" },
+ { "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 }
+};
+