Re: [Mesa-dev] [PATCH 8/8] st/va: add BOB/WEAVE deinterlacing
This patch is: Reviewed-by: Julien IsorceTested-by: Julien Isorce (tested with gstvaapipostproc from gstreamer-vaapi) On 11 December 2015 at 12:33, Christian König wrote: > From: Christian König > > Tested with MPV. > > Signed-off-by: Christian König > --- > src/gallium/state_trackers/va/postproc.c | 72 > > src/gallium/state_trackers/va/surface.c | 16 ++- > 2 files changed, 78 insertions(+), 10 deletions(-) > > diff --git a/src/gallium/state_trackers/va/postproc.c > b/src/gallium/state_trackers/va/postproc.c > index c6cfd3a..bcac66a 100644 > --- a/src/gallium/state_trackers/va/postproc.c > +++ b/src/gallium/state_trackers/va/postproc.c > @@ -51,7 +51,8 @@ vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext > *context, > const VARectangle *src_region, > const VARectangle *dst_region, > struct pipe_video_buffer *src, > - struct pipe_video_buffer *dst) > + struct pipe_video_buffer *dst, > + enum vl_compositor_deinterlace deinterlace) > { > struct pipe_surface **surfaces; > struct u_rect src_rect; > @@ -100,7 +101,8 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, > vlVaContext *context, > const VARectangle *src_region, > const VARectangle *dst_region, > struct pipe_video_buffer *src, > - struct pipe_video_buffer *dst) > + struct pipe_video_buffer *dst, > + enum vl_compositor_deinterlace > deinterlace) > { > struct pipe_surface **src_surfaces; > struct pipe_surface **dst_surfaces; > @@ -118,18 +120,33 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, > vlVaContext *context, >return VA_STATUS_ERROR_INVALID_SURFACE; > > for (i = 0; i < VL_MAX_SURFACES; ++i) { > + struct pipe_surface *from = src_surfaces[i]; >struct pipe_blit_info blit; > > - if (!src_surfaces[i] || !dst_surfaces[i]) > + if (src->interlaced) { > + /* Not 100% accurate, but close enough */ > + switch (deinterlace) { > + case VL_COMPOSITOR_BOB_TOP: > +from = src_surfaces[i & ~1]; > +break; > + case VL_COMPOSITOR_BOB_BOTTOM: > +from = src_surfaces[(i & ~1) + 1]; > +break; > + default: > +break; > + } > + } > + > + if (!from || !dst_surfaces[i]) > continue; > >memset(, 0, sizeof(blit)); > - blit.src.resource = src_surfaces[i]->texture; > - blit.src.format = src_surfaces[i]->format; > + blit.src.resource = from->texture; > + blit.src.format = from->format; >blit.src.level = 0; >blit.src.box.x = src_region->x; >blit.src.box.y = src_region->y; > - blit.src.box.z = src_surfaces[i]->u.tex.first_layer; > + blit.src.box.z = from->u.tex.first_layer; >blit.src.box.width = src_region->width; >blit.src.box.height = src_region->height; >blit.src.box.depth = 1; > @@ -158,10 +175,12 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, > vlVaContext *context, > VAStatus > vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext > *context, vlVaBuffer *buf) > { > + enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_WEAVE; > VARectangle def_src_region, def_dst_region; > const VARectangle *src_region, *dst_region; > VAProcPipelineParameterBuffer *param; > vlVaSurface *src_surface; > + unsigned i; > > if (!drv || !context) >return VA_STATUS_ERROR_INVALID_CONTEXT; > @@ -178,13 +197,50 @@ > vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext > *contex > if (!src_surface || !src_surface->buffer) >return VA_STATUS_ERROR_INVALID_SURFACE; > > + for (i = 0; i < param->num_filters; i++) { > + vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); > + VAProcFilterParameterBufferBase *filter; > + > + if (!buf || buf->type != VAProcFilterParameterBufferType) > + return VA_STATUS_ERROR_INVALID_BUFFER; > + > + filter = buf->data; > + switch (filter->type) { > + case VAProcFilterDeinterlacing: { > + VAProcFilterParameterBufferDeinterlacing *deint = buf->data; > + switch (deint->algorithm) { > + case VAProcDeinterlacingBob: > +if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD) > + deinterlace = VL_COMPOSITOR_BOB_BOTTOM; > +else > + deinterlace = VL_COMPOSITOR_BOB_TOP; > +break; > + > + case VAProcDeinterlacingWeave: > +deinterlace = VL_COMPOSITOR_WEAVE; > +
[Mesa-dev] [PATCH 8/8] st/va: add BOB/WEAVE deinterlacing
From: Christian KönigTested with MPV. Signed-off-by: Christian König --- src/gallium/state_trackers/va/postproc.c | 72 src/gallium/state_trackers/va/surface.c | 16 ++- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c index c6cfd3a..bcac66a 100644 --- a/src/gallium/state_trackers/va/postproc.c +++ b/src/gallium/state_trackers/va/postproc.c @@ -51,7 +51,8 @@ vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context, const VARectangle *src_region, const VARectangle *dst_region, struct pipe_video_buffer *src, - struct pipe_video_buffer *dst) + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) { struct pipe_surface **surfaces; struct u_rect src_rect; @@ -100,7 +101,8 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, const VARectangle *src_region, const VARectangle *dst_region, struct pipe_video_buffer *src, - struct pipe_video_buffer *dst) + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) { struct pipe_surface **src_surfaces; struct pipe_surface **dst_surfaces; @@ -118,18 +120,33 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, return VA_STATUS_ERROR_INVALID_SURFACE; for (i = 0; i < VL_MAX_SURFACES; ++i) { + struct pipe_surface *from = src_surfaces[i]; struct pipe_blit_info blit; - if (!src_surfaces[i] || !dst_surfaces[i]) + if (src->interlaced) { + /* Not 100% accurate, but close enough */ + switch (deinterlace) { + case VL_COMPOSITOR_BOB_TOP: +from = src_surfaces[i & ~1]; +break; + case VL_COMPOSITOR_BOB_BOTTOM: +from = src_surfaces[(i & ~1) + 1]; +break; + default: +break; + } + } + + if (!from || !dst_surfaces[i]) continue; memset(, 0, sizeof(blit)); - blit.src.resource = src_surfaces[i]->texture; - blit.src.format = src_surfaces[i]->format; + blit.src.resource = from->texture; + blit.src.format = from->format; blit.src.level = 0; blit.src.box.x = src_region->x; blit.src.box.y = src_region->y; - blit.src.box.z = src_surfaces[i]->u.tex.first_layer; + blit.src.box.z = from->u.tex.first_layer; blit.src.box.width = src_region->width; blit.src.box.height = src_region->height; blit.src.box.depth = 1; @@ -158,10 +175,12 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, VAStatus vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { + enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_WEAVE; VARectangle def_src_region, def_dst_region; const VARectangle *src_region, *dst_region; VAProcPipelineParameterBuffer *param; vlVaSurface *src_surface; + unsigned i; if (!drv || !context) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -178,13 +197,50 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex if (!src_surface || !src_surface->buffer) return VA_STATUS_ERROR_INVALID_SURFACE; + for (i = 0; i < param->num_filters; i++) { + vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); + VAProcFilterParameterBufferBase *filter; + + if (!buf || buf->type != VAProcFilterParameterBufferType) + return VA_STATUS_ERROR_INVALID_BUFFER; + + filter = buf->data; + switch (filter->type) { + case VAProcFilterDeinterlacing: { + VAProcFilterParameterBufferDeinterlacing *deint = buf->data; + switch (deint->algorithm) { + case VAProcDeinterlacingBob: +if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD) + deinterlace = VL_COMPOSITOR_BOB_BOTTOM; +else + deinterlace = VL_COMPOSITOR_BOB_TOP; +break; + + case VAProcDeinterlacingWeave: +deinterlace = VL_COMPOSITOR_WEAVE; +break; + + default: +return VA_STATUS_ERROR_UNIMPLEMENTED; + } + + break; + } + + default: + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + } + src_region = vlVaRegionDefault(param->surface_region, src_surface->buffer, _src_region); dst_region = vlVaRegionDefault(param->output_region, context->target, _dst_region); if (context->target->buffer_format != PIPE_FORMAT_NV12) return