[FFmpeg-cvslog] vdpau: force reinitialization when output resolution changes

Rémi Denis-Courmont git at videolan.org
Mon Oct 6 14:46:27 CEST 2014


ffmpeg | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Oct  4 16:55:06 2014 +0300| [502cde409ca5ee97ef70c2cdede88b9101746ff6] | committer: Anton Khirnov

vdpau: force reinitialization when output resolution changes

This is necessary to recreate the decoder with the correct parameters,
as not all codecs invoke get_format() in this case.

Signed-off-by: Anton Khirnov <anton at khirnov.net>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=502cde409ca5ee97ef70c2cdede88b9101746ff6
---

 libavcodec/vdpau.c          |   29 +++++++++++++++++++++++++++++
 libavcodec/vdpau_internal.h |    3 +++
 2 files changed, 32 insertions(+)

diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index ed8fd7f..c3a8a85 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -76,6 +76,9 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
     uint32_t width  = (avctx->coded_width + 1) & ~1;
     uint32_t height = (avctx->coded_height + 3) & ~3;
 
+    vdctx->width            = UINT32_MAX;
+    vdctx->height           = UINT32_MAX;
+
     if (hwctx->context.decoder != VDP_INVALID_HANDLE) {
         vdctx->decoder = hwctx->context.decoder;
         vdctx->render  = hwctx->context.render;
@@ -102,6 +105,11 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
 
     status = create(vdctx->device, profile, width, height, avctx->refs,
                     &vdctx->decoder);
+    if (status == VDP_STATUS_OK) {
+        vdctx->width  = avctx->coded_width;
+        vdctx->height = avctx->coded_height;
+    }
+
     return vdpau_error(status);
 }
 
@@ -114,6 +122,8 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx)
 
     if (vdctx->device == VDP_INVALID_HANDLE)
         return 0; /* Decoder created and destroyed by user */
+    if (vdctx->width == UINT32_MAX && vdctx->height == UINT32_MAX)
+        return 0;
 
     status = vdctx->get_proc_address(vdctx->device,
                                      VDP_FUNC_ID_DECODER_DESTROY, &func);
@@ -126,6 +136,20 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx)
     return vdpau_error(status);
 }
 
+static int ff_vdpau_common_reinit(AVCodecContext *avctx)
+{
+    VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
+
+    if (vdctx->device == VDP_INVALID_HANDLE)
+        return 0; /* Decoder created by user */
+    if (avctx->coded_width == vdctx->width &&
+        avctx->coded_height == vdctx->height)
+        return 0;
+
+    avctx->hwaccel->uninit(avctx);
+    return avctx->hwaccel->init(avctx);
+}
+
 int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx,
                                 av_unused const uint8_t *buffer,
                                 av_unused uint32_t size)
@@ -142,6 +166,11 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
     VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
     VdpVideoSurface surf = ff_vdpau_get_surface_id(frame);
     VdpStatus status;
+    int val;
+
+    val = ff_vdpau_common_reinit(avctx);
+    if (val < 0)
+        return val;
 
     status = vdctx->render(vdctx->decoder, surf, (void *)&pic_ctx->info,
                            pic_ctx->bitstream_buffers_used,
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 94fa9aa..3e74d46 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -74,6 +74,9 @@ typedef struct VDPAUContext {
      * VDPAU decoder render callback
      */
     VdpDecoderRender *render;
+
+    uint32_t width;
+    uint32_t height;
 } VDPAUContext;
 
 struct vdpau_picture_context {



More information about the ffmpeg-cvslog mailing list