This is necessary to recreate the decoder with the correct parameters,
as not all codecs invoke get_format() in this case.
---
libavcodec/vdpau.c | 28 ++++++++++++++++++++++++++--
libavcodec/vdpau_internal.h | 3 +++
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index b92f194..f8c1738 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -88,6 +88,8 @@ int ff_vdpau_common_init(AVCodecContext *avctx,
VdpDecoderProfile profile,
vdctx->device = hwctx->device;
vdctx->get_proc_address = hwctx->get_proc_address;
+ vdctx->width = -1;
+ vdctx->height = -1;
if (hwctx->device == VDP_INVALID_HANDLE) {
vdctx->decoder = hwctx->decoder;
@@ -103,6 +105,11 @@ int ff_vdpau_common_init(AVCodecContext *avctx,
VdpDecoderProfile profile,
status = create(vdctx->device, profile, width, height, surfaces,
&vdctx->decoder);
+ if (status == VDP_STATUS_OK)
+ {
+ vdctx->width = avctx->coded_width;
+ vdctx->height = avctx->coded_height;
+ }
return ff_vdpau_error(status);
}
@@ -113,8 +120,8 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx)
VdpDecoderDestroy *destroy;
VdpStatus status;
- if (vdctx->device == VDP_INVALID_HANDLE)
- return 0; /* Decoder created and destroyed by user */
+ if (vdctx->width == (uint32_t)-1 && vdctx->height == (uint32_t)-1)
+ return 0;
destroy = ff_vdpau_get_proc_address(avctx, VDP_FUNC_ID_DECODER_DESTROY);
if (destroy == NULL)
@@ -124,6 +131,18 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx)
return ff_vdpau_error(status);
}
+static int ff_vdpau_common_reinit(AVCodecContext *avctx)
+{
+ struct vdpau_context *vdctx = avctx->internal->hwaccel_priv_data;
+
+ 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)
@@ -140,6 +159,11 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx,
AVFrame *frame,
struct vdpau_context *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 cefc0a1..e4c2681 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -68,6 +68,9 @@ struct vdpau_context {
* VDPAU decoder render callback
*/
VdpDecoderRender *render;
+
+ uint32_t width;
+ uint32_t height;
};
struct vdpau_picture_context {
--
1.8.1.5
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel