---
 libavcodec/vdpau.c | 47 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 68d0813f65..a84ff81d7d 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -152,22 +152,45 @@ int ff_vdpau_common_init(AVCodecContext *avctx, 
VdpDecoderProfile profile,
         if (avctx->hw_frames_ctx) {
             frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
         } else if (avctx->hw_device_ctx) {
+            AVHWFramesContext *frames_cached = NULL;
             int ret;
 
-            avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
-            if (!avctx->hw_frames_ctx)
-                return AVERROR(ENOMEM);
+            if (avctx->internal->hw_frames_ctx)
+                frames_cached = 
(AVHWFramesContext*)avctx->internal->hw_frames_ctx->data;
 
-            frames_ctx            = 
(AVHWFramesContext*)avctx->hw_frames_ctx->data;
-            frames_ctx->format    = AV_PIX_FMT_VDPAU;
-            frames_ctx->sw_format = avctx->sw_pix_fmt;
-            frames_ctx->width     = avctx->coded_width;
-            frames_ctx->height    = avctx->coded_height;
+            if ((avctx->hwaccel_flags & AV_HWACCEL_FLAG_CACHE_FRAMES) &&
+                frames_cached &&
+                frames_cached->device_ctx->type == AV_HWDEVICE_TYPE_VDPAU &&
+                frames_cached->sw_format == avctx->sw_pix_fmt &&
+                frames_cached->width == avctx->coded_width &&
+                frames_cached->height == avctx->coded_height) {
 
-            ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
-            if (ret < 0) {
-                av_buffer_unref(&avctx->hw_frames_ctx);
-                return ret;
+                avctx->hw_frames_ctx = 
av_buffer_ref(avctx->internal->hw_frames_ctx);
+                if (!avctx->hw_frames_ctx)
+                    return AVERROR(ENOMEM);
+
+                frames_ctx            = 
(AVHWFramesContext*)avctx->hw_frames_ctx->data;
+
+            } else {
+                av_buffer_unref(&avctx->internal->hw_frames_ctx);
+
+                avctx->hw_frames_ctx = 
av_hwframe_ctx_alloc(avctx->hw_device_ctx);
+                if (!avctx->hw_frames_ctx)
+                    return AVERROR(ENOMEM);
+
+                frames_ctx            = 
(AVHWFramesContext*)avctx->hw_frames_ctx->data;
+                frames_ctx->format    = AV_PIX_FMT_VDPAU;
+                frames_ctx->sw_format = avctx->sw_pix_fmt;
+                frames_ctx->width     = avctx->coded_width;
+                frames_ctx->height    = avctx->coded_height;
+
+                ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
+                if (ret < 0) {
+                    av_buffer_unref(&avctx->hw_frames_ctx);
+                    return ret;
+                }
+
+                avctx->internal->hw_frames_ctx = 
av_buffer_ref(avctx->hw_frames_ctx);
             }
         }
 
-- 
2.11.0

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to