summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/va
diff options
context:
space:
mode:
authorChristian König <[email protected]>2015-12-13 11:44:13 +0100
committerChristian König <[email protected]>2016-01-18 10:59:32 +0100
commiteaf7ec9cfc5165f461bddc365aaaf6cb25c2d9bd (patch)
treeb7d02f9aa3ab35579186db776409826676ce6141 /src/gallium/state_trackers/va
parentad20be1f30ef5d11bcacef38a921cb778c504dd2 (diff)
st/va: add motion adaptive deinterlacing v2
v2: minor cleanup Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/va')
-rw-r--r--src/gallium/state_trackers/va/context.c5
-rw-r--r--src/gallium/state_trackers/va/postproc.c60
-rw-r--r--src/gallium/state_trackers/va/surface.c22
-rw-r--r--src/gallium/state_trackers/va/va_private.h2
4 files changed, 82 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
index 37a011799e2..b25c381d968 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -31,6 +31,7 @@
#include "util/u_memory.h"
#include "util/u_handle_table.h"
#include "util/u_video.h"
+#include "vl/vl_deint_filter.h"
#include "vl/vl_winsys.h"
#include "va_private.h"
@@ -296,6 +297,10 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
}
context->decoder->destroy(context->decoder);
}
+ if (context->deint) {
+ vl_deint_filter_cleanup(context->deint);
+ FREE(context->deint);
+ }
FREE(context);
handle_table_remove(drv->htab, context_id);
pipe_mutex_unlock(drv->mutex);
diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c
index 0cec0c88124..f541f7c8aeb 100644
--- a/src/gallium/state_trackers/va/postproc.c
+++ b/src/gallium/state_trackers/va/postproc.c
@@ -29,6 +29,7 @@
#include "vl/vl_defines.h"
#include "vl/vl_video_buffer.h"
+#include "vl/vl_deint_filter.h"
#include "va_private.h"
@@ -174,6 +175,51 @@ static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context,
return VA_STATUS_SUCCESS;
}
+static struct pipe_video_buffer *
+vlVaApplyDeint(vlVaDriver *drv, vlVaContext *context,
+ VAProcPipelineParameterBuffer *param,
+ struct pipe_video_buffer *current,
+ unsigned field)
+{
+ vlVaSurface *prevprev, *prev, *next;
+
+ if (param->num_forward_references < 1 ||
+ param->num_backward_references < 2)
+ return current;
+
+ prevprev = handle_table_get(drv->htab, param->backward_references[1]);
+ prev = handle_table_get(drv->htab, param->backward_references[0]);
+ next = handle_table_get(drv->htab, param->forward_references[0]);
+
+ if (!prevprev || !prev || !next)
+ return current;
+
+ if (context->deint && (context->deint->video_width != current->width ||
+ context->deint->video_height != current->height)) {
+ vl_deint_filter_cleanup(context->deint);
+ FREE(context->deint);
+ context->deint = NULL;
+ }
+
+ if (!context->deint) {
+ context->deint = MALLOC(sizeof(struct vl_deint_filter));
+ if (!vl_deint_filter_init(context->deint, drv->pipe, current->width,
+ current->height, false, false)) {
+ FREE(context->deint);
+ context->deint = NULL;
+ return current;
+ }
+ }
+
+ if (!vl_deint_filter_check_buffers(context->deint, prevprev->buffer,
+ prev->buffer, current, next->buffer))
+ return current;
+
+ vl_deint_filter_render(context->deint, prevprev->buffer, prev->buffer,
+ current, next->buffer, field);
+ return context->deint->video_buffer;
+}
+
VAStatus
vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
@@ -181,6 +227,7 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
VARectangle def_src_region, def_dst_region;
const VARectangle *src_region, *dst_region;
VAProcPipelineParameterBuffer *param;
+ struct pipe_video_buffer *src;
vlVaSurface *src_surface;
unsigned i;
@@ -199,6 +246,8 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
if (!src_surface || !src_surface->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
+ src = src_surface->buffer;
+
for (i = 0; i < param->num_filters; i++) {
vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]);
VAProcFilterParameterBufferBase *filter;
@@ -222,6 +271,11 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
deinterlace = VL_COMPOSITOR_WEAVE;
break;
+ case VAProcDeinterlacingMotionAdaptive:
+ src = vlVaApplyDeint(drv, context, param, src,
+ deint->flags & VA_DEINTERLACING_BOTTOM_FIELD);
+ break;
+
default:
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
@@ -239,10 +293,8 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
if (context->target->buffer_format != PIPE_FORMAT_NV12)
return vlVaPostProcCompositor(drv, context, src_region, dst_region,
- src_surface->buffer, context->target,
- deinterlace);
+ src, context->target, deinterlace);
else
return vlVaPostProcBlit(drv, context, src_region, dst_region,
- src_surface->buffer, context->target,
- deinterlace);
+ src, context->target, deinterlace);
}
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
index f23a88901f5..84a94949c47 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -691,13 +691,14 @@ vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context,
case VAProcFilterDeinterlacing: {
VAProcFilterCapDeinterlacing *deint = filter_caps;
- if (*num_filter_caps < 2) {
- *num_filter_caps = 2;
+ if (*num_filter_caps < 3) {
+ *num_filter_caps = 3;
return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
}
deint[i++].type = VAProcDeinterlacingBob;
deint[i++].type = VAProcDeinterlacingWeave;
+ deint[i++].type = VAProcDeinterlacingMotionAdaptive;
break;
}
@@ -750,9 +751,24 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
for (i = 0; i < num_filters; i++) {
vlVaBuffer *buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, filters[i]);
+ VAProcFilterParameterBufferBase *filter;
- if (!buf || buf->type >= VABufferTypeMax)
+ if (!buf || buf->type != VAProcFilterParameterBufferType)
return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ filter = buf->data;
+ switch (filter->type) {
+ case VAProcFilterDeinterlacing: {
+ VAProcFilterParameterBufferDeinterlacing *deint = buf->data;
+ if (deint->algorithm == VAProcDeinterlacingMotionAdaptive) {
+ pipeline_cap->num_forward_references = 1;
+ pipeline_cap->num_backward_references = 2;
+ }
+ break;
+ }
+ default:
+ return VA_STATUS_ERROR_UNIMPLEMENTED;
+ }
}
return VA_STATUS_SUCCESS;
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index 7afd81a196d..614fa98fef7 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -236,6 +236,8 @@ typedef struct {
VAPictureParameterBufferMPEG4 pps;
uint8_t start_code[32];
} mpeg4;
+
+ struct vl_deint_filter *deint;
} vlVaContext;
typedef struct {