mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 04:40:09 +01:00
frontends/va: add encoder format conversion (EFC) support
Signed-off-by: Thong Thai <thong.thai@amd.com> Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15196>
This commit is contained in:
parent
73153746d5
commit
9602526568
3 changed files with 42 additions and 5 deletions
|
|
@ -785,6 +785,10 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
|
||||||
context->desc.h264enc.frame_num_cnt++;
|
context->desc.h264enc.frame_num_cnt++;
|
||||||
} else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
|
} else if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_HEVC)
|
||||||
getEncParamPresetH265(context);
|
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->begin_frame(context->decoder, context->target, &context->desc.base);
|
||||||
context->decoder->encode_bitstream(context->decoder, context->target,
|
context->decoder->encode_bitstream(context->decoder, context->target,
|
||||||
coded_buf->derived_surface.resource, &feedback);
|
coded_buf->derived_surface.resource, &feedback);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "vl/vl_defines.h"
|
#include "vl/vl_defines.h"
|
||||||
#include "vl/vl_video_buffer.h"
|
#include "vl/vl_video_buffer.h"
|
||||||
#include "vl/vl_deint_filter.h"
|
#include "vl/vl_deint_filter.h"
|
||||||
|
#include "vl/vl_winsys.h"
|
||||||
|
|
||||||
#include "va_private.h"
|
#include "va_private.h"
|
||||||
|
|
||||||
|
|
@ -124,9 +125,12 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
|
||||||
bool scale = false;
|
bool scale = false;
|
||||||
bool grab = false;
|
bool grab = false;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
struct pipe_screen *pscreen = drv->vscreen->pscreen;
|
||||||
|
|
||||||
if ((src->buffer_format == PIPE_FORMAT_B8G8R8A8_UNORM ||
|
if ((src->buffer_format == PIPE_FORMAT_B8G8R8X8_UNORM ||
|
||||||
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)
|
!src->interlaced)
|
||||||
grab = true;
|
grab = true;
|
||||||
|
|
||||||
|
|
@ -165,7 +169,9 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
|
||||||
dst_rect.x1 = dst_region->x + dst_region->width;
|
dst_rect.x1 = dst_region->x + dst_region->width;
|
||||||
dst_rect.y1 = dst_region->y + dst_region->height;
|
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,
|
vl_compositor_convert_rgb_to_yuv(&drv->cstate, &drv->compositor, 0,
|
||||||
((struct vl_video_buffer *)src)->resources[0],
|
((struct vl_video_buffer *)src)->resources[0],
|
||||||
dst, &src_rect, &dst_rect);
|
dst, &src_rect, &dst_rect);
|
||||||
|
|
@ -220,7 +226,7 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
|
||||||
blit.mask = PIPE_MASK_RGBA;
|
blit.mask = PIPE_MASK_RGBA;
|
||||||
blit.filter = PIPE_TEX_MIPFILTER_LINEAR;
|
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))
|
PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA))
|
||||||
util_compute_blit(drv->pipe, &blit, &context->blit_cs, !drv->compositor.deinterlace);
|
util_compute_blit(drv->pipe, &blit, &context->blit_cs, !drv->compositor.deinterlace);
|
||||||
else
|
else
|
||||||
|
|
@ -288,6 +294,7 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
|
||||||
struct pipe_video_buffer *src, *dst;
|
struct pipe_video_buffer *src, *dst;
|
||||||
vlVaSurface *src_surface, *dst_surface;
|
vlVaSurface *src_surface, *dst_surface;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
struct pipe_screen *pscreen;
|
||||||
|
|
||||||
if (!drv || !context)
|
if (!drv || !context)
|
||||||
return VA_STATUS_ERROR_INVALID_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);
|
src_surface = handle_table_get(drv->htab, param->surface);
|
||||||
dst_surface = handle_table_get(drv->htab, context->target_id);
|
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)
|
if (!src_surface || !src_surface->buffer)
|
||||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
|
|
@ -369,7 +397,11 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
|
||||||
|
|
||||||
if (context->target->buffer_format != PIPE_FORMAT_NV12 &&
|
if (context->target->buffer_format != PIPE_FORMAT_NV12 &&
|
||||||
context->target->buffer_format != PIPE_FORMAT_P010 &&
|
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,
|
return vlVaPostProcCompositor(drv, context, src_region, dst_region,
|
||||||
src, context->target, deinterlace);
|
src, context->target, deinterlace);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,7 @@ typedef struct {
|
||||||
unsigned int frame_num_cnt;
|
unsigned int frame_num_cnt;
|
||||||
bool force_flushed;
|
bool force_flushed;
|
||||||
struct pipe_video_buffer *obsolete_buf;
|
struct pipe_video_buffer *obsolete_buf;
|
||||||
|
enum pipe_format encoder_format;
|
||||||
} vlVaSurface;
|
} vlVaSurface;
|
||||||
|
|
||||||
// Public functions:
|
// Public functions:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue