This is necessary to recreate the decoder with the correct parameters, as not all codecs invoke get_format() in this case.
Unified · Split
| @@ -76,6 +76,9 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 75 unmodified lines | ||
| 76 | 76 | uint32_t width = (avctx->coded_width + 1) & ~1; |
| 77 | 77 | uint32_t height = (avctx->coded_height + 3) & ~3; |
| 78 | 78 | |
| 79 | + vdctx->width = UINT32_MAX; | |
| 80 | + vdctx->height = UINT32_MAX; | |
| 81 | + | |
| 79 | 82 | if (hwctx->context.decoder != VDP_INVALID_HANDLE) { |
| 80 | 83 | vdctx->decoder = hwctx->context.decoder; |
| 81 | 84 | vdctx->render = hwctx->context.render; |
| @@ -102,6 +105,11 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 20 unmodified lines | ||
| 102 | 105 | |
| 103 | 106 | status = create(vdctx->device, profile, width, height, avctx->refs, |
| 104 | 107 | &vdctx->decoder); |
| 108 | + if (status == VDP_STATUS_OK) { | |
| 109 | + vdctx->width = avctx->coded_width; | |
| 110 | + vdctx->height = avctx->coded_height; | |
| 111 | + } | |
| 112 | + | |
| 105 | 113 | return vdpau_error(status); |
| 106 | 114 | } |
| 107 | 115 | |
| @@ -114,6 +122,8 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx) · 6 unmodified lines | ||
| 114 | 122 | |
| 115 | 123 | if (vdctx->device == VDP_INVALID_HANDLE) |
| 116 | 124 | return 0; /* Decoder created and destroyed by user */ |
| 125 | + if (vdctx->width == UINT32_MAX && vdctx->height == UINT32_MAX) | |
| 126 | + return 0; | |
| 117 | 127 | |
| 118 | 128 | status = vdctx->get_proc_address(vdctx->device, |
| 119 | 129 | VDP_FUNC_ID_DECODER_DESTROY, &func); |
| @@ -126,6 +136,20 @@ int ff_vdpau_common_uninit(AVCodecContext *avctx) · 6 unmodified lines | ||
| 126 | 136 | return vdpau_error(status); |
| 127 | 137 | } |
| 128 | 138 | |
| 139 | +static int ff_vdpau_common_reinit(AVCodecContext *avctx) | |
| 140 | +{ | |
| 141 | + VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data; | |
| 142 | + | |
| 143 | + if (vdctx->device == VDP_INVALID_HANDLE) | |
| 144 | + return 0; /* Decoder created by user */ | |
| 145 | + if (avctx->coded_width == vdctx->width && | |
| 146 | + avctx->coded_height == vdctx->height) | |
| 147 | + return 0; | |
| 148 | + | |
| 149 | + avctx->hwaccel->uninit(avctx); | |
| 150 | + return avctx->hwaccel->init(avctx); | |
| 151 | +} | |
| 152 | + | |
| 129 | 153 | int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx, |
| 130 | 154 | av_unused const uint8_t *buffer, |
| 131 | 155 | av_unused uint32_t size) |
| @@ -142,6 +166,11 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, · 10 unmodified lines | ||
| 142 | 166 | VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data; |
| 143 | 167 | VdpVideoSurface surf = ff_vdpau_get_surface_id(frame); |
| 144 | 168 | VdpStatus status; |
| 169 | + int val; | |
| 170 | + | |
| 171 | + val = ff_vdpau_common_reinit(avctx); | |
| 172 | + if (val < 0) | |
| 173 | + return val; | |
| 145 | 174 | |
| 146 | 175 | status = vdctx->render(vdctx->decoder, surf, (void *)&pic_ctx->info, |
| 147 | 176 | pic_ctx->bitstream_buffers_used, |
| @@ -74,6 +74,9 @@ typedef struct VDPAUContext { · 73 unmodified lines | ||
| 74 | 74 | * VDPAU decoder render callback |
| 75 | 75 | */ |
| 76 | 76 | VdpDecoderRender *render; |
| 77 | + | |
| 78 | + uint32_t width; | |
| 79 | + uint32_t height; | |
| 77 | 80 | } VDPAUContext; |
| 78 | 81 | |
| 79 | 82 | struct vdpau_picture_context { |