diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
index 7e03e30..7cc1331 100644
--- a/libavcodec/cuvid.c
+++ b/libavcodec/cuvid.c
@@ -46,9 +46,13 @@ typedef struct CuvidContext
     AVFifoBuffer *frame_queue;
 
     int internal_error;
+    int ever_flushed;
 
     cudaVideoCodec codec_type;
     cudaVideoChromaFormat chroma_format;
+
+    CUVIDPARSERPARAMS cuparseinfo;
+    CUVIDEOFORMATEX cuparse_ext;
 } CuvidContext;
 
 static int check_cu(AVCodecContext *avctx, CUresult err, const char *func)
@@ -127,7 +131,7 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
         return 0;
     }
 
-    if (hwframe_ctx->pool) {
+    if (hwframe_ctx->pool && !ctx->ever_flushed) {
         av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized\n");
         ctx->internal_error = AVERROR(EINVAL);
         return 0;
@@ -164,14 +168,16 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
     if (ctx->internal_error < 0)
         return 0;
 
-    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);
+    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);
 
-    if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
-        return 0;
+        if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
+            return 0;
+        }
     }
 
     return 1;
@@ -461,8 +467,6 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
     AVCUDADeviceContext *device_hwctx;
     AVHWDeviceContext *device_ctx;
     AVHWFramesContext *hwframe_ctx;
-    CUVIDPARSERPARAMS cuparseinfo;
-    CUVIDEOFORMATEX cuparse_ext;
     CUVIDSOURCEDATAPACKET seq_pkt;
     CUdevice device;
     CUcontext cuda_ctx = NULL;
@@ -550,61 +554,61 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
         }
     }
 
-    memset(&cuparseinfo, 0, sizeof(cuparseinfo));
-    memset(&cuparse_ext, 0, sizeof(cuparse_ext));
+    memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo));
+    memset(&ctx->cuparse_ext, 0, sizeof(ctx->cuparse_ext));
     memset(&seq_pkt, 0, sizeof(seq_pkt));
 
-    cuparseinfo.pExtVideoInfo = &cuparse_ext;
+    ctx->cuparseinfo.pExtVideoInfo = &ctx->cuparse_ext;
 
     switch (avctx->codec->id) {
 #if CONFIG_H263_CUVID_DECODER
     case AV_CODEC_ID_H263:
-        cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
         break;
 #endif
 #if CONFIG_H264_CUVID_DECODER
     case AV_CODEC_ID_H264:
-        cuparseinfo.CodecType = cudaVideoCodec_H264;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
         break;
 #endif
 #if CONFIG_HEVC_CUVID_DECODER
     case AV_CODEC_ID_HEVC:
-        cuparseinfo.CodecType = cudaVideoCodec_HEVC;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
         break;
 #endif
 #if CONFIG_MJPEG_CUVID_DECODER
     case AV_CODEC_ID_MJPEG:
-        cuparseinfo.CodecType = cudaVideoCodec_JPEG;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
         break;
 #endif
 #if CONFIG_MPEG1_CUVID_DECODER
     case AV_CODEC_ID_MPEG1VIDEO:
-        cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
         break;
 #endif
 #if CONFIG_MPEG2_CUVID_DECODER
     case AV_CODEC_ID_MPEG2VIDEO:
-        cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
         break;
 #endif
 #if CONFIG_MPEG4_CUVID_DECODER
     case AV_CODEC_ID_MPEG4:
-        cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
         break;
 #endif
 #if CONFIG_VP8_CUVID_DECODER
     case AV_CODEC_ID_VP8:
-        cuparseinfo.CodecType = cudaVideoCodec_VP8;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
         break;
 #endif
 #if CONFIG_VP9_CUVID_DECODER
     case AV_CODEC_ID_VP9:
-        cuparseinfo.CodecType = cudaVideoCodec_VP9;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
         break;
 #endif
 #if CONFIG_VC1_CUVID_DECODER
     case AV_CODEC_ID_VC1:
-        cuparseinfo.CodecType = cudaVideoCodec_VC1;
+        ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
         break;
 #endif
     default:
@@ -630,38 +634,38 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
             goto error;
         }
 
-        cuparse_ext.format.seqhdr_data_length = ctx->bsf->par_out->extradata_size;
-        memcpy(cuparse_ext.raw_seqhdr_data,
+        ctx->cuparse_ext.format.seqhdr_data_length = ctx->bsf->par_out->extradata_size;
+        memcpy(ctx->cuparse_ext.raw_seqhdr_data,
                ctx->bsf->par_out->extradata,
-               FFMIN(sizeof(cuparse_ext.raw_seqhdr_data), ctx->bsf->par_out->extradata_size));
+               FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), ctx->bsf->par_out->extradata_size));
     } else if (avctx->extradata_size > 0) {
-        cuparse_ext.format.seqhdr_data_length = avctx->extradata_size;
-        memcpy(cuparse_ext.raw_seqhdr_data,
+        ctx->cuparse_ext.format.seqhdr_data_length = avctx->extradata_size;
+        memcpy(ctx->cuparse_ext.raw_seqhdr_data,
                avctx->extradata,
-               FFMIN(sizeof(cuparse_ext.raw_seqhdr_data), avctx->extradata_size));
+               FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), avctx->extradata_size));
     }
 
-    cuparseinfo.ulMaxNumDecodeSurfaces = MAX_FRAME_COUNT;
-    cuparseinfo.ulMaxDisplayDelay = 4;
-    cuparseinfo.pUserData = avctx;
-    cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
-    cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
-    cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
+    ctx->cuparseinfo.ulMaxNumDecodeSurfaces = MAX_FRAME_COUNT;
+    ctx->cuparseinfo.ulMaxDisplayDelay = 4;
+    ctx->cuparseinfo.pUserData = avctx;
+    ctx->cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
+    ctx->cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
+    ctx->cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
 
     ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));
     if (ret < 0)
         goto error;
 
-    ret = cuvid_test_dummy_decoder(avctx, &cuparseinfo);
+    ret = cuvid_test_dummy_decoder(avctx, &ctx->cuparseinfo);
     if (ret < 0)
         goto error;
 
-    ret = CHECK_CU(cuvidCreateVideoParser(&ctx->cuparser, &cuparseinfo));
+    ret = CHECK_CU(cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
     if (ret < 0)
         goto error;
 
-    seq_pkt.payload = cuparse_ext.raw_seqhdr_data;
-    seq_pkt.payload_size = cuparse_ext.format.seqhdr_data_length;
+    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));
@@ -673,6 +677,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
     if (ret < 0)
         goto error;
 
+    ctx->ever_flushed = 0;
+
     return 0;
 
 error:
@@ -680,6 +686,51 @@ error:
     return ret;
 }
 
+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;
+    int ret;
+
+    ctx->ever_flushed = 1;
+
+    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(CUVIDPARSERDISPINFO));
+    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;
+
+    ret = CHECK_CU(cuCtxPopCurrent(&dummy));
+    if (ret < 0)
+        goto error;
+
+    return;
+ error:
+    av_log(avctx, AV_LOG_ERROR, "CUDA reinit on flush failed\n");
+}
+
 #define DEFINE_CUVID_CODEC(x, X) \
     AVHWAccel ff_##x##_cuvid_hwaccel = { \
         .name           = #x "_cuvid", \
@@ -696,6 +747,7 @@ error:
         .init           = cuvid_decode_init, \
         .close          = cuvid_decode_end, \
         .decode         = cuvid_decode_frame, \
+        .flush          = cuvid_flush, \
         .capabilities   = AV_CODEC_CAP_DELAY, \
         .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
                                                         AV_PIX_FMT_NV12, \
