Module: Mesa
Branch: main
Commit: b5fa9f992da7618a9fb08605b953b2051cf63e2d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b5fa9f992da7618a9fb08605b953b2051cf63e2d

Author: David Rosca <[email protected]>
Date:   Sat Jul 15 14:46:53 2023 +0200

frontends/va: Skip processing buffers already converted with EFC

Since the EFC conversion reallocates the dst buffer with new format,
any subsequent VA postproc calls on the same surface will fall back
to vl_compositor conversion.

This is the case in ffmpeg where the postproc filter output
buffers are reused instead of allocated for each frame.

Reviewed-by: Ruijing Dong <[email protected]>
Reviewed-by: Leo Liu <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24170>

---

 src/gallium/frontends/va/postproc.c | 46 ++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/src/gallium/frontends/va/postproc.c 
b/src/gallium/frontends/va/postproc.c
index 5a4ad0fb994..ccb290f2d37 100644
--- a/src/gallium/frontends/va/postproc.c
+++ b/src/gallium/frontends/va/postproc.c
@@ -368,6 +368,27 @@ vlVaApplyDeint(vlVaDriver *drv, vlVaContext *context,
    return context->deint->video_buffer;
 }
 
+static bool can_convert_with_efc(vlVaSurface *src, vlVaSurface *dst)
+{
+   enum pipe_format src_format, dst_format;
+
+   if (src->buffer->interlaced)
+      return false;
+
+   src_format = src->buffer->buffer_format;
+
+   if (src_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
+       src_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
+       src_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
+       src_format != PIPE_FORMAT_R8G8B8X8_UNORM)
+      return false;
+
+   dst_format = dst->encoder_format != PIPE_FORMAT_NONE ?
+      dst->encoder_format : dst->buffer->buffer_format;
+
+   return dst_format == PIPE_FORMAT_NV12;
+}
+
 VAStatus
 vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext 
*context, vlVaBuffer *buf)
 {
@@ -400,28 +421,25 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver 
*drv, vlVaContext *contex
 
    pscreen = drv->vscreen->pscreen;
 
-   if (src_surface->buffer->buffer_format != 
dst_surface->buffer->buffer_format &&
-       !src_surface->buffer->interlaced &&
-       (dst_surface->buffer->buffer_format == PIPE_FORMAT_NV12 ||
-        dst_surface->buffer->buffer_format == PIPE_FORMAT_P010 ||
-        dst_surface->buffer->buffer_format == PIPE_FORMAT_P016) &&
+   if (can_convert_with_efc(src_surface, dst_surface) &&
        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 = dst_surface;
 
-      vlVaSurface *surf;
+      // EFC will convert the buffer to a format the encoder accepts
+      if (src_surface->buffer->buffer_format != surf->buffer->buffer_format) {
+         surf->encoder_format = surf->buffer->buffer_format;
 
-      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);
+         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;
+         if (vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0) != 
VA_STATUS_SUCCESS)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+      }
 
       pipe_resource_reference(&(((struct vl_video_buffer 
*)(surf->buffer))->resources[0]), ((struct vl_video_buffer 
*)(src_surface->buffer))->resources[0]);
       context->target = surf->buffer;

Reply via email to