diff options
author | Christian König <[email protected]> | 2015-12-13 11:44:13 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2016-01-18 10:59:32 +0100 |
commit | eaf7ec9cfc5165f461bddc365aaaf6cb25c2d9bd (patch) | |
tree | b7d02f9aa3ab35579186db776409826676ce6141 | |
parent | ad20be1f30ef5d11bcacef38a921cb778c504dd2 (diff) |
st/va: add motion adaptive deinterlacing v2
v2: minor cleanup
Signed-off-by: Christian König <[email protected]>
-rw-r--r-- | src/gallium/state_trackers/va/context.c | 5 | ||||
-rw-r--r-- | src/gallium/state_trackers/va/postproc.c | 60 | ||||
-rw-r--r-- | src/gallium/state_trackers/va/surface.c | 22 | ||||
-rw-r--r-- | src/gallium/state_trackers/va/va_private.h | 2 |
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 { |