st/va: add motion adaptive deinterlacing v2

v2: minor cleanup

Signed-off-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
Christian König 2015-12-13 11:44:13 +01:00
parent ad20be1f30
commit eaf7ec9cfc
4 changed files with 82 additions and 7 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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;

View file

@ -236,6 +236,8 @@ typedef struct {
VAPictureParameterBufferMPEG4 pps;
uint8_t start_code[32];
} mpeg4;
struct vl_deint_filter *deint;
} vlVaContext;
typedef struct {