| @@ -138,34 +138,75 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 137 unmodified lines |
| 138 | vdctx->width = UINT32_MAX; | 138 | vdctx->width = UINT32_MAX; |
| 139 | vdctx->height = UINT32_MAX; | 139 | vdctx->height = UINT32_MAX; |
| 140 | | 140 | |
| 141 | if (!hwctx) { | 141 | if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height)) |
| 142 | vdctx->device = VDP_INVALID_HANDLE; | 142 | return AVERROR(ENOSYS); |
| 143 | av_log(avctx, AV_LOG_WARNING, "hwaccel_context has not been setup by the user application, cannot initialize\n"); | | |
| 144 | return 0; | | |
| 145 | } | | |
| 146 | | 143 | |
| 147 | if (hwctx->context.decoder != VDP_INVALID_HANDLE) { | 144 | if (hwctx) { |
| 148 | vdctx->decoder = hwctx->context.decoder; | 145 | hwctx->reset = 0; |
| 149 | vdctx->render = hwctx->context.render; | | |
| 150 | vdctx->device = VDP_INVALID_HANDLE; | | |
| 151 | return 0; /* Decoder created by user */ | | |
| 152 | } | | |
| 153 | hwctx->reset = 0; | | |
| 154 | | 146 | |
| 155 | vdctx->device = hwctx->device; | 147 | if (hwctx->context.decoder != VDP_INVALID_HANDLE) { |
| 156 | vdctx->get_proc_address = hwctx->get_proc_address; | 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) | 154 | vdctx->device = hwctx->device; |
| 159 | level = 0; | 155 | vdctx->get_proc_address = hwctx->get_proc_address; |
| 160 | else if (level < 0) | 156 | |
| 161 | return AVERROR(ENOTSUP); | 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)) | 193 | if (!frames_ctx) { |
| 164 | return AVERROR(ENOSYS); | 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) && | 199 | dev_ctx = frames_ctx->device_ctx->hwctx; |
| 167 | type != VDP_CHROMA_TYPE_420) | 200 | |
| 168 | return AVERROR(ENOSYS); | 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 | status = vdctx->get_proc_address(vdctx->device, | 211 | status = vdctx->get_proc_address(vdctx->device, |
| 171 | VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, | 212 | VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, |
| @@ -263,7 +304,7 @@ static int ff_vdpau_common_reinit(AVCodecContext *avctx) · 91 unmodified lines |
| 263 | if (vdctx->device == VDP_INVALID_HANDLE) | 304 | if (vdctx->device == VDP_INVALID_HANDLE) |
| 264 | return 0; /* Decoder created by user */ | 305 | return 0; /* Decoder created by user */ |
| 265 | if (avctx->coded_width == vdctx->width && | 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 | return 0; | 308 | return 0; |
| 268 | | 309 | |
| 269 | avctx->hwaccel->uninit(avctx); | 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 | #if FF_API_BUFS_VDPAU | 337 | #if FF_API_BUFS_VDPAU |
| 297 | FF_DISABLE_DEPRECATION_WARNINGS | 338 | FF_DISABLE_DEPRECATION_WARNINGS |
| | 339 | if (hwctx) { |
| 298 | av_assert0(sizeof(hwctx->info) <= sizeof(pic_ctx->info)); | 340 | av_assert0(sizeof(hwctx->info) <= sizeof(pic_ctx->info)); |
| 299 | memcpy(&hwctx->info, &pic_ctx->info, sizeof(hwctx->info)); | 341 | memcpy(&hwctx->info, &pic_ctx->info, sizeof(hwctx->info)); |
| 300 | hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; | 342 | hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; |
| 301 | hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; | 343 | hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; |
| 302 | hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; | 344 | hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; |
| | 345 | } |
| 303 | FF_ENABLE_DEPRECATION_WARNINGS | 346 | FF_ENABLE_DEPRECATION_WARNINGS |
| 304 | #endif | 347 | #endif |
| 305 | | 348 | |
| 306 | if (!hwctx->render && hwctx->render2) { | 349 | if (hwctx && !hwctx->render && hwctx->render2) { |
| 307 | status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info, | 350 | status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info, |
| 308 | pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); | 351 | pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); |
| 309 | } else | 352 | } else |
| @@ -315,9 +358,11 @@ FF_ENABLE_DEPRECATION_WARNINGS · 5 unmodified lines |
| 315 | | 358 | |
| 316 | #if FF_API_BUFS_VDPAU | 359 | #if FF_API_BUFS_VDPAU |
| 317 | FF_DISABLE_DEPRECATION_WARNINGS | 360 | FF_DISABLE_DEPRECATION_WARNINGS |
| | 361 | if (hwctx) { |
| 318 | hwctx->bitstream_buffers = NULL; | 362 | hwctx->bitstream_buffers = NULL; |
| 319 | hwctx->bitstream_buffers_used = 0; | 363 | hwctx->bitstream_buffers_used = 0; |
| 320 | hwctx->bitstream_buffers_allocated = 0; | 364 | hwctx->bitstream_buffers_allocated = 0; |
| | 365 | } |
| 321 | FF_ENABLE_DEPRECATION_WARNINGS | 366 | FF_ENABLE_DEPRECATION_WARNINGS |
| 322 | #endif | 367 | #endif |
| 323 | | 368 | |