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)) { + vlVaSurface *surf = dst_surface; + // EFC will convert the buffer to a format the encoder accepts - dst_surface->encoder_format = dst_surface->buffer->buffer_format; + if (src_surface->buffer->buffer_format != surf->buffer->buffer_format) { + surf->encoder_format = surf->buffer->buffer_format; - vlVaSurface *surf; + surf->templat.interlaced = src_surface->templat.interlaced; + surf->templat.buffer_format = src_surface->templat.buffer_format; + surf->buffer->destroy(surf->buffer); - 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; + 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;