| 548 | } |
| 549 | |
| 550 | static int create_hw_frame(VkRenderer *renderer, AVFrame *frame) |
| 551 | { |
| 552 | RendererContext *ctx = (RendererContext *) renderer; |
| 553 | AVHWFramesContext *src_hw_frame = (AVHWFramesContext *) |
| 554 | frame->hw_frames_ctx->data; |
| 555 | AVHWFramesContext *hw_frame; |
| 556 | AVVulkanFramesContext *vk_frame_ctx; |
| 557 | int ret; |
| 558 | |
| 559 | if (ctx->hw_frame_ref) { |
| 560 | hw_frame = (AVHWFramesContext *) ctx->hw_frame_ref->data; |
| 561 | |
| 562 | if (hw_frame->width == frame->width && |
| 563 | hw_frame->height == frame->height && |
| 564 | hw_frame->sw_format == src_hw_frame->sw_format) |
| 565 | return 0; |
| 566 | |
| 567 | av_buffer_unref(&ctx->hw_frame_ref); |
| 568 | } |
| 569 | |
| 570 | if (!ctx->constraints) { |
| 571 | ctx->constraints = av_hwdevice_get_hwframe_constraints( |
| 572 | ctx->hw_device_ref, NULL); |
| 573 | if (!ctx->constraints) |
| 574 | return AVERROR(ENOMEM); |
| 575 | } |
| 576 | |
| 577 | // Check constraints and skip create hwframe. Don't take it as error since |
| 578 | // we can fallback to memory copy from GPU to CPU. |
| 579 | if ((ctx->constraints->max_width && |
| 580 | ctx->constraints->max_width < frame->width) || |
| 581 | (ctx->constraints->max_height && |
| 582 | ctx->constraints->max_height < frame->height) || |
| 583 | (ctx->constraints->min_width && |
| 584 | ctx->constraints->min_width > frame->width) || |
| 585 | (ctx->constraints->min_height && |
| 586 | ctx->constraints->min_height > frame->height)) |
| 587 | return 0; |
| 588 | |
| 589 | if (ctx->constraints->valid_sw_formats) { |
| 590 | enum AVPixelFormat *sw_formats = ctx->constraints->valid_sw_formats; |
| 591 | while (*sw_formats != AV_PIX_FMT_NONE) { |
| 592 | if (*sw_formats == src_hw_frame->sw_format) |
| 593 | break; |
| 594 | sw_formats++; |
| 595 | } |
| 596 | if (*sw_formats == AV_PIX_FMT_NONE) |
| 597 | return 0; |
| 598 | } |
| 599 | |
| 600 | ctx->hw_frame_ref = av_hwframe_ctx_alloc(ctx->hw_device_ref); |
| 601 | if (!ctx->hw_frame_ref) |
| 602 | return AVERROR(ENOMEM); |
| 603 | |
| 604 | hw_frame = (AVHWFramesContext *) ctx->hw_frame_ref->data; |
| 605 | hw_frame->format = AV_PIX_FMT_VULKAN; |
| 606 | hw_frame->sw_format = src_hw_frame->sw_format; |
| 607 | hw_frame->width = frame->width; |
no test coverage detected