| @@ -138,34 +138,75 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 137 unmodified lines |
| 138 | 138 | vdctx->width = UINT32_MAX; |
| 139 | 139 | vdctx->height = UINT32_MAX; |
| 140 | 140 | |
| 141 | | − if (!hwctx) { |
| 142 | | − vdctx->device = VDP_INVALID_HANDLE; |
| 143 | | − av_log(avctx, AV_LOG_WARNING, "hwaccel_context has not been setup by the user application, cannot initialize\n"); |
| 144 | | − return 0; |
| 145 | | − } |
| 141 | + if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) |
| 142 | + return AVERROR(ENOSYS); |
| 146 | 143 | |
| 147 | | − if (hwctx->context.decoder != VDP_INVALID_HANDLE) { |
| 148 | | − vdctx->decoder = hwctx->context.decoder; |
| 149 | | − vdctx->render = hwctx->context.render; |
| 150 | | − vdctx->device = VDP_INVALID_HANDLE; |
| 151 | | − return 0; /* Decoder created by user */ |
| 152 | | − } |
| 153 | | − hwctx->reset = 0; |
| 144 | + if (hwctx) { |
| 145 | + hwctx->reset = 0; |
| 154 | 146 | |
| 155 | | − vdctx->device = hwctx->device; |
| 156 | | − vdctx->get_proc_address = hwctx->get_proc_address; |
| 147 | + if (hwctx->context.decoder != VDP_INVALID_HANDLE) { |
| 148 | + vdctx->decoder = hwctx->context.decoder; |
| 149 | + vdctx->render = hwctx->context.render; |
| 150 | + vdctx->device = VDP_INVALID_HANDLE; |
| 151 | + return 0; /* Decoder created by user */ |
| 152 | + } |
| 157 | 153 | |
| 158 | | − if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) |
| 159 | | − level = 0; |
| 160 | | − else if (level < 0) |
| 161 | | − return AVERROR(ENOTSUP); |
| 154 | + vdctx->device = hwctx->device; |
| 155 | + vdctx->get_proc_address = hwctx->get_proc_address; |
| 156 | + |
| 157 | + if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) |
| 158 | + level = 0; |
| 159 | + |
| 160 | + if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && |
| 161 | + type != VDP_CHROMA_TYPE_420) |
| 162 | + return AVERROR(ENOSYS); |
| 163 | + } else { |
| 164 | + AVHWFramesContext *frames_ctx = NULL; |
| 165 | + AVVDPAUDeviceContext *dev_ctx; |
| 166 | + |
| 167 | + // We assume the hw_frames_ctx always survives until ff_vdpau_common_uninit |
| 168 | + // is called. This holds true as the user is not allowed to touch |
| 169 | + // hw_device_ctx, or hw_frames_ctx after get_format (and ff_get_format |
| 170 | + // itself also uninits before unreffing hw_frames_ctx). |
| 171 | + if (avctx->hw_frames_ctx) { |
| 172 | + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; |
| 173 | + } else if (avctx->hw_device_ctx) { |
| 174 | + int ret; |
| 175 | + |
| 176 | + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); |
| 177 | + if (!avctx->hw_frames_ctx) |
| 178 | + return AVERROR(ENOMEM); |
| 179 | + |
| 180 | + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; |
| 181 | + frames_ctx->format = AV_PIX_FMT_VDPAU; |
| 182 | + frames_ctx->sw_format = avctx->sw_pix_fmt; |
| 183 | + frames_ctx->width = avctx->coded_width; |
| 184 | + frames_ctx->height = avctx->coded_height; |
| 185 | + |
| 186 | + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); |
| 187 | + if (ret < 0) { |
| 188 | + av_buffer_unref(&avctx->hw_frames_ctx); |
| 189 | + return ret; |
| 190 | + } |
| 191 | + } |
| 162 | 192 | |
| 163 | | − if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) |
| 164 | | − return AVERROR(ENOSYS); |
| 193 | + if (!frames_ctx) { |
| 194 | + av_log(avctx, AV_LOG_ERROR, "A hardware frames context is " |
| 195 | + "required for VDPAU decoding.\n"); |
| 196 | + return AVERROR(EINVAL); |
| 197 | + } |
| 165 | 198 | |
| 166 | | − if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) && |
| 167 | | − type != VDP_CHROMA_TYPE_420) |
| 168 | | − return AVERROR(ENOSYS); |
| 199 | + dev_ctx = frames_ctx->device_ctx->hwctx; |
| 200 | + |
| 201 | + vdctx->device = dev_ctx->device; |
| 202 | + vdctx->get_proc_address = dev_ctx->get_proc_address; |
| 203 | + |
| 204 | + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_IGNORE_LEVEL) |
| 205 | + level = 0; |
| 206 | + } |
| 207 | + |
| 208 | + if (level < 0) |
| 209 | + return AVERROR(ENOTSUP); |
| 169 | 210 | |
| 170 | 211 | status = vdctx->get_proc_address(vdctx->device, |
| 171 | 212 | VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, |
| @@ -263,7 +304,7 @@ static int ff_vdpau_common_reinit(AVCodecContext *avctx) · 91 unmodified lines |
| 263 | 304 | if (vdctx->device == VDP_INVALID_HANDLE) |
| 264 | 305 | return 0; /* Decoder created by user */ |
| 265 | 306 | if (avctx->coded_width == vdctx->width && |
| 266 | | − avctx->coded_height == vdctx->height && !hwctx->reset) |
| 307 | + avctx->coded_height == vdctx->height && (!hwctx || !hwctx->reset)) |
| 267 | 308 | return 0; |
| 268 | 309 | |
| 269 | 310 | avctx->hwaccel->uninit(avctx); |
| @@ -295,15 +336,17 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, · 25 unmodified lines |
| 295 | 336 | |
| 296 | 337 | #if FF_API_BUFS_VDPAU |
| 297 | 338 | FF_DISABLE_DEPRECATION_WARNINGS |
| 339 | + if (hwctx) { |
| 298 | 340 | av_assert0(sizeof(hwctx->info) <= sizeof(pic_ctx->info)); |
| 299 | 341 | memcpy(&hwctx->info, &pic_ctx->info, sizeof(hwctx->info)); |
| 300 | 342 | hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; |
| 301 | 343 | hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; |
| 302 | 344 | hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; |
| 345 | + } |
| 303 | 346 | FF_ENABLE_DEPRECATION_WARNINGS |
| 304 | 347 | #endif |
| 305 | 348 | |
| 306 | | − if (!hwctx->render && hwctx->render2) { |
| 349 | + if (hwctx && !hwctx->render && hwctx->render2) { |
| 307 | 350 | status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info, |
| 308 | 351 | pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); |
| 309 | 352 | } else |
| @@ -315,9 +358,11 @@ FF_ENABLE_DEPRECATION_WARNINGS · 5 unmodified lines |
| 315 | 358 | |
| 316 | 359 | #if FF_API_BUFS_VDPAU |
| 317 | 360 | FF_DISABLE_DEPRECATION_WARNINGS |
| 361 | + if (hwctx) { |
| 318 | 362 | hwctx->bitstream_buffers = NULL; |
| 319 | 363 | hwctx->bitstream_buffers_used = 0; |
| 320 | 364 | hwctx->bitstream_buffers_allocated = 0; |
| 365 | + } |
| 321 | 366 | FF_ENABLE_DEPRECATION_WARNINGS |
| 322 | 367 | #endif |
| 323 | 368 | |