From 9602526568964e9395b255868a504dd34b77296a Mon Sep 17 00:00:00 2001 From: Thong Thai Date: Mon, 28 Feb 2022 15:23:17 -0500 Subject: [PATCH] frontends/va: add encoder format conversion (EFC) support Signed-off-by: Thong Thai Reviewed-by: Leo Liu Part-of: --- src/gallium/frontends/va/picture.c | 4 ++++ src/gallium/frontends/va/postproc.c | 42 ++++++++++++++++++++++++++++++----- src/gallium/frontends/va/va_private.h | 1 + 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index ba8f9de..6c13217 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -785,6 +785,10 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->desc.h264enc.frame_num_cnt++; } else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC) getEncParamPresetH265(context); + + context->desc.base.input_format = surf->buffer->buffer_format; + context->desc.base.output_format = surf->encoder_format; + context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); diff --git a/src/gallium/frontends/va/postproc.c b/src/gallium/frontends/va/postproc.c index 88d7d81..1201eb0 100644 --- a/src/gallium/frontends/va/postproc.c +++ b/src/gallium/frontends/va/postproc.c @@ -32,6 +32,7 @@ #include "vl/vl_defines.h" #include "vl/vl_video_buffer.h" #include "vl/vl_deint_filter.h" +#include "vl/vl_winsys.h" #include "va_private.h" @@ -124,9 +125,12 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, bool scale = false; bool grab = false; unsigned i; + struct pipe_screen *pscreen = drv->vscreen->pscreen; - if ((src->buffer_format == PIPE_FORMAT_B8G8R8A8_UNORM || - src->buffer_format == PIPE_FORMAT_B8G8R8X8_UNORM) && + if ((src->buffer_format == PIPE_FORMAT_B8G8R8X8_UNORM || + src->buffer_format == PIPE_FORMAT_B8G8R8A8_UNORM || + src->buffer_format == PIPE_FORMAT_R8G8B8X8_UNORM || + src->buffer_format == PIPE_FORMAT_R8G8B8A8_UNORM) && !src->interlaced) grab = true; @@ -165,7 +169,9 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, dst_rect.x1 = dst_region->x + dst_region->width; dst_rect.y1 = dst_region->y + dst_region->height; - if (grab) { + if (grab && !pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_EFC_SUPPORTED)) { vl_compositor_convert_rgb_to_yuv(&drv->cstate, &drv->compositor, 0, ((struct vl_video_buffer *)src)->resources[0], dst, &src_rect, &dst_rect); @@ -220,7 +226,7 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, blit.mask = PIPE_MASK_RGBA; blit.filter = PIPE_TEX_MIPFILTER_LINEAR; - if (drv->pipe->screen->get_param(drv->pipe->screen, + if (!grab && drv->pipe->screen->get_param(drv->pipe->screen, PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA)) util_compute_blit(drv->pipe, &blit, &context->blit_cs, !drv->compositor.deinterlace); else @@ -288,6 +294,7 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex struct pipe_video_buffer *src, *dst; vlVaSurface *src_surface, *dst_surface; unsigned i; + struct pipe_screen *pscreen; if (!drv || !context) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -303,6 +310,27 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex src_surface = handle_table_get(drv->htab, param->surface); dst_surface = handle_table_get(drv->htab, context->target_id); + pscreen = drv->vscreen->pscreen; + + if (src_surface->buffer->buffer_format != dst_surface->buffer->buffer_format && + pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_EFC_SUPPORTED)) { + + // EFC will convert the buffer to a format the encoder accepts + dst_surface->encoder_format = dst_surface->buffer->buffer_format; + + vlVaSurface *surf; + + surf = handle_table_get(drv->htab, context->target_id); + surf->templat.interlaced = src_surface->templat.interlaced; + surf->templat.buffer_format = src_surface->templat.buffer_format; + surf->buffer->destroy(surf->buffer); + + if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != VA_STATUS_SUCCESS) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + context->target = surf->buffer; + } + if (!src_surface || !src_surface->buffer) return VA_STATUS_ERROR_INVALID_SURFACE; @@ -369,7 +397,11 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex if (context->target->buffer_format != PIPE_FORMAT_NV12 && context->target->buffer_format != PIPE_FORMAT_P010 && - context->target->buffer_format != PIPE_FORMAT_P016) + context->target->buffer_format != PIPE_FORMAT_P016 && + context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM) return vlVaPostProcCompositor(drv, context, src_region, dst_region, src, context->target, deinterlace); else diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index d511686..149cfa2 100755 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -337,6 +337,7 @@ typedef struct { unsigned int frame_num_cnt; bool force_flushed; struct pipe_video_buffer *obsolete_buf; + enum pipe_format encoder_format; } vlVaSurface; // Public functions: -- 2.7.4