Re: [Mesa-dev] [PATCH 8/8] st/va: add BOB/WEAVE deinterlacing

2015-12-14 Thread Julien Isorce
This patch is:
Reviewed-by: Julien Isorce 
Tested-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

2015-12-11 Thread Christian König
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;
+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