mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
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@khirnov.net>
This commit is contained in:
parent
89ac99ba5f
commit
502cde409c
@ -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,
|
||||
|
@ -74,6 +74,9 @@ typedef struct VDPAUContext {
|
||||
* VDPAU decoder render callback
|
||||
*/
|
||||
VdpDecoderRender *render;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} VDPAUContext;
|
||||
|
||||
struct vdpau_picture_context {
|
||||
|
Loading…
Reference in New Issue
Block a user