mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
filter: add initial support for deinterlacing.
Add basic deinterlacing support, i.e. bob-deinterlacing whereby only the selected field from the input surface is kept for the target surface. Setting gst_vaapi_filter_set_deinterlacing() method argument to GST_VAAPI_DEINTERLACE_METHOD_NONE means to disable deinterlacing. Also move GstVaapiDeinterlaceMethod definition from vaapipostproc plug-in to libgstvaapi core library. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
1d222d3b4a
commit
944a7bd077
7 changed files with 269 additions and 45 deletions
|
@ -393,6 +393,7 @@ gst_vaapi_filter_set_hue
|
|||
gst_vaapi_filter_set_saturation
|
||||
gst_vaapi_filter_set_brightness
|
||||
gst_vaapi_filter_set_saturation
|
||||
gst_vaapi_filter_set_deinterlacing
|
||||
<SUBSECTION Standard>
|
||||
GST_VAAPI_FILTER
|
||||
</SECTION>
|
||||
|
|
162
gst-libs/gst/vaapi/gstvaapifilter.c
Normal file → Executable file
162
gst-libs/gst/vaapi/gstvaapifilter.c
Normal file → Executable file
|
@ -67,6 +67,60 @@ struct _GstVaapiFilter {
|
|||
guint use_crop_rect : 1;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VPP Types --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_method_get_type(void)
|
||||
{
|
||||
static gsize g_type = 0;
|
||||
|
||||
static const GEnumValue enum_values[] = {
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_NONE,
|
||||
"Disable deinterlacing", "none" },
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_BOB,
|
||||
"Bob deinterlacing", "bob" },
|
||||
#if USE_VA_VPP
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
|
||||
"Weave deinterlacing", "weave" },
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
|
||||
"Motion adaptive deinterlacing", "motion-adaptive" },
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
|
||||
"Motion compensated deinterlacing", "motion-compensated" },
|
||||
#endif
|
||||
{ 0, NULL, NULL },
|
||||
};
|
||||
|
||||
if (g_once_init_enter(&g_type)) {
|
||||
const GType type =
|
||||
g_enum_register_static("GstVaapiDeinterlaceMethod", enum_values);
|
||||
g_once_init_leave(&g_type, type);
|
||||
}
|
||||
return g_type;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_flags_get_type(void)
|
||||
{
|
||||
static gsize g_type = 0;
|
||||
|
||||
static const GEnumValue enum_values[] = {
|
||||
{ GST_VAAPI_DEINTERLACE_FLAG_TFF,
|
||||
"Top-field first", "top-field-first" },
|
||||
{ GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD,
|
||||
"One field", "one-field" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
if (g_once_init_enter(&g_type)) {
|
||||
const GType type =
|
||||
g_enum_register_static("GstVaapiDeinterlaceFlags", enum_values);
|
||||
g_once_init_leave(&g_type, type);
|
||||
}
|
||||
return g_type;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- VPP Helpers --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -188,6 +242,7 @@ enum {
|
|||
PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION,
|
||||
PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS,
|
||||
PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
@ -299,6 +354,20 @@ init_properties(void)
|
|||
"The color contrast value",
|
||||
0.0, 2.0, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* GstVaapiFilter:deinterlace-method:
|
||||
*
|
||||
* The deinterlacing algorithm to apply, expressed a an enum
|
||||
* value. See #GstVaapiDeinterlaceMethod.
|
||||
*/
|
||||
g_properties[PROP_DEINTERLACING] =
|
||||
g_param_spec_enum("deinterlace",
|
||||
"Deinterlacing Method",
|
||||
"Deinterlacing method to apply",
|
||||
GST_VAAPI_TYPE_DEINTERLACE_METHOD,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_NONE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -354,6 +423,11 @@ op_data_new(GstVaapiFilterOp op, GParamSpec *pspec)
|
|||
op_data->va_cap_size = sizeof(VAProcFilterCapColorBalance);
|
||||
op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferColorBalance);
|
||||
break;
|
||||
case GST_VAAPI_FILTER_OP_DEINTERLACING:
|
||||
op_data->va_type = VAProcFilterDeinterlacing;
|
||||
op_data->va_cap_size = sizeof(VAProcFilterCapDeinterlacing);
|
||||
op_data->va_buffer_size = sizeof(VAProcFilterParameterBufferDeinterlacing);
|
||||
break;
|
||||
default:
|
||||
g_assert(0 && "unsupported operation");
|
||||
goto error;
|
||||
|
@ -409,9 +483,14 @@ op_data_ensure_caps(GstVaapiFilterOpData *op_data, gpointer filter_caps,
|
|||
if (i == num_filter_caps)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
op_data->va_caps = g_memdup(filter_cap,
|
||||
op_data->va_cap_size * num_filter_caps);
|
||||
return op_data->va_caps != NULL;
|
||||
if (!op_data->va_caps)
|
||||
return FALSE;
|
||||
|
||||
op_data->va_num_caps = num_filter_caps;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Scale the filter value wrt. library spec and VA driver spec */
|
||||
|
@ -681,6 +760,59 @@ op_set_color_balance(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data,
|
|||
return success;
|
||||
}
|
||||
|
||||
/* Update deinterlace filter */
|
||||
#if USE_VA_VPP
|
||||
static gboolean
|
||||
op_set_deinterlace_unlocked(GstVaapiFilter *filter,
|
||||
GstVaapiFilterOpData *op_data, GstVaapiDeinterlaceMethod method,
|
||||
guint flags)
|
||||
{
|
||||
VAProcFilterParameterBufferDeinterlacing *buf;
|
||||
const VAProcFilterCapDeinterlacing *filter_caps;
|
||||
VAProcDeinterlacingType algorithm;
|
||||
guint i;
|
||||
|
||||
if (!op_data || !op_ensure_buffer(filter, op_data))
|
||||
return FALSE;
|
||||
|
||||
op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE);
|
||||
if (!op_data->is_enabled)
|
||||
return TRUE;
|
||||
|
||||
algorithm = from_GstVaapiDeinterlaceMethod(method);
|
||||
for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) {
|
||||
if (filter_caps[i].type == algorithm)
|
||||
break;
|
||||
}
|
||||
if (i == op_data->va_num_caps)
|
||||
return FALSE;
|
||||
|
||||
buf = vaapi_map_buffer(filter->va_display, op_data->va_buffer);
|
||||
if (!buf)
|
||||
return FALSE;
|
||||
|
||||
buf->type = op_data->va_type;
|
||||
buf->algorithm = algorithm;
|
||||
buf->flags = from_GstVaapiDeinterlaceFlags(flags);
|
||||
vaapi_unmap_buffer(filter->va_display, op_data->va_buffer, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline gboolean
|
||||
op_set_deinterlace(GstVaapiFilter *filter, GstVaapiFilterOpData *op_data,
|
||||
GstVaapiDeinterlaceMethod method, guint flags)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
#if USE_VA_VPP
|
||||
GST_VAAPI_DISPLAY_LOCK(filter->display);
|
||||
success = op_set_deinterlace_unlocked(filter, op_data, method, flags);
|
||||
GST_VAAPI_DISPLAY_UNLOCK(filter->display);
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Surface Formats --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -1004,6 +1136,11 @@ gst_vaapi_filter_set_operation(GstVaapiFilter *filter, GstVaapiFilterOp op,
|
|||
return op_set_color_balance(filter, op_data,
|
||||
(value ? g_value_get_float(value) :
|
||||
G_PARAM_SPEC_FLOAT(op_data->pspec)->default_value));
|
||||
case GST_VAAPI_FILTER_OP_DEINTERLACING:
|
||||
return op_set_deinterlace(filter, op_data,
|
||||
(value ? g_value_get_enum(value) :
|
||||
G_PARAM_SPEC_ENUM(op_data->pspec)->default_value), 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1322,3 +1459,26 @@ gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value)
|
|||
return op_set_color_balance(filter,
|
||||
find_operation(filter, GST_VAAPI_FILTER_OP_CONTRAST), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_filter_set_deinterlacing:
|
||||
* @filter: a #GstVaapiFilter
|
||||
* @method: the deinterlacing algorithm (see #GstVaapiDeinterlaceMethod)
|
||||
* @flags: the additional flags
|
||||
*
|
||||
* Applies deinterlacing to the video processing pipeline. If @method
|
||||
* is not @GST_VAAPI_DEINTERLACE_METHOD_NONE, then @flags could
|
||||
* represent the initial picture structure of the source frame.
|
||||
*
|
||||
* Return value: %TRUE if the operation is supported, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter,
|
||||
GstVaapiDeinterlaceMethod method, guint flags)
|
||||
{
|
||||
g_return_val_if_fail(filter != NULL, FALSE);
|
||||
|
||||
return op_set_deinterlace(filter,
|
||||
find_operation(filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method,
|
||||
flags);
|
||||
}
|
||||
|
|
52
gst-libs/gst/vaapi/gstvaapifilter.h
Normal file → Executable file
52
gst-libs/gst/vaapi/gstvaapifilter.h
Normal file → Executable file
|
@ -51,6 +51,7 @@ typedef enum {
|
|||
GST_VAAPI_FILTER_OP_SATURATION,
|
||||
GST_VAAPI_FILTER_OP_BRIGHTNESS,
|
||||
GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
} GstVaapiFilterOp;
|
||||
|
||||
/**
|
||||
|
@ -85,6 +86,53 @@ typedef enum {
|
|||
GST_VAAPI_FILTER_STATUS_ERROR_UNSUPPORTED_FORMAT,
|
||||
} GstVaapiFilterStatus;
|
||||
|
||||
/**
|
||||
* GstVaapiDeinterlaceMethod:
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_NONE: No deinterlacing.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_BOB: Basic bob deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_WEAVE: Weave deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: Motion adaptive
|
||||
* deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: Motion compensated
|
||||
* deinterlacing algorithm.
|
||||
*
|
||||
* Deinterlacing algorithms.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DEINTERLACE_METHOD_NONE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_BOB,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
|
||||
} GstVaapiDeinterlaceMethod;
|
||||
|
||||
/**
|
||||
* GstVaapiDeinterlaceFlags:
|
||||
* @GST_VAAPI_DEINTERLACE_FLAG_TFF: Top-field first. If this flag is
|
||||
* not set, then bottom-field first order is assumed.
|
||||
* @GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD: The input frame represents a
|
||||
* single field. If this flag is not set, then the whole frame holds
|
||||
* two fields.
|
||||
*
|
||||
* The set of gst_vaapi_filter_set_deinterlacing() flags.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DEINTERLACE_FLAG_TFF = 1 << 31,
|
||||
GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD = 1 << 30,
|
||||
} GstVaapiDeinterlaceFlags;
|
||||
|
||||
#define GST_VAAPI_TYPE_DEINTERLACE_METHOD \
|
||||
gst_vaapi_deinterlace_method_get_type()
|
||||
|
||||
#define GST_VAAPI_TYPE_DEINTERLACE_FLAGS \
|
||||
gst_vaapi_deinterlace_flags_get_type()
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_method_get_type(void) G_GNUC_CONST;
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_flags_get_type(void) G_GNUC_CONST;
|
||||
|
||||
GstVaapiFilter *
|
||||
gst_vaapi_filter_new(GstVaapiDisplay *display);
|
||||
|
||||
|
@ -137,4 +185,8 @@ gst_vaapi_filter_set_brightness(GstVaapiFilter *filter, gfloat value);
|
|||
gboolean
|
||||
gst_vaapi_filter_set_contrast(GstVaapiFilter *filter, gfloat value);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_deinterlacing(GstVaapiFilter *filter,
|
||||
GstVaapiDeinterlaceMethod method, guint flags);
|
||||
|
||||
#endif /* GST_VAAPI_FILTER_H */
|
||||
|
|
|
@ -25,9 +25,14 @@
|
|||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapisurface.h"
|
||||
#include "gstvaapisubpicture.h"
|
||||
#include "gstvaapifilter.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if USE_VA_VPP
|
||||
# include <va/va_vpp.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
|
@ -433,3 +438,44 @@ to_GstVaapiRotation(guint value)
|
|||
GST_ERROR("unsupported VA-API rotation value %d", value);
|
||||
return GST_VAAPI_ROTATION_0;
|
||||
}
|
||||
|
||||
/* VPP: translate GstVaapiDeinterlaceMethod to VA deinterlacing algorithm */
|
||||
guint
|
||||
from_GstVaapiDeinterlaceMethod(guint value)
|
||||
{
|
||||
switch (value) {
|
||||
case GST_VAAPI_DEINTERLACE_METHOD_NONE:
|
||||
return 0;
|
||||
#if USE_VA_VPP
|
||||
case GST_VAAPI_DEINTERLACE_METHOD_BOB:
|
||||
return VAProcDeinterlacingBob;
|
||||
case GST_VAAPI_DEINTERLACE_METHOD_WEAVE:
|
||||
return VAProcDeinterlacingWeave;
|
||||
case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE:
|
||||
return VAProcDeinterlacingMotionAdaptive;
|
||||
case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED:
|
||||
return VAProcDeinterlacingMotionCompensated;
|
||||
#endif
|
||||
}
|
||||
GST_ERROR("unsupported GstVaapiDeinterlaceMethod value %d", value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VPP: translate GstVaapiDeinterlaceFlags into VA deinterlacing flags */
|
||||
guint
|
||||
from_GstVaapiDeinterlaceFlags(guint flags)
|
||||
{
|
||||
guint va_flags = 0;
|
||||
|
||||
#if USE_VA_VPP
|
||||
if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF))
|
||||
va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
|
||||
|
||||
if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) {
|
||||
va_flags |= VA_DEINTERLACING_ONE_FIELD;
|
||||
if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF))
|
||||
va_flags |= VA_DEINTERLACING_BOTTOM_FIELD;
|
||||
}
|
||||
#endif
|
||||
return va_flags;
|
||||
}
|
||||
|
|
|
@ -109,4 +109,12 @@ G_GNUC_INTERNAL
|
|||
guint
|
||||
to_GstVaapiRotation(guint value);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
from_GstVaapiDeinterlaceMethod(guint value);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
from_GstVaapiDeinterlaceFlags(guint flags);
|
||||
|
||||
#endif /* GST_VAAPI_UTILS_H */
|
||||
|
|
30
gst/vaapi/gstvaapipostproc.c
Normal file → Executable file
30
gst/vaapi/gstvaapipostproc.c
Normal file → Executable file
|
@ -149,36 +149,6 @@ gst_vaapi_deinterlace_mode_get_type(void)
|
|||
return deinterlace_mode_type;
|
||||
}
|
||||
|
||||
#define GST_VAAPI_TYPE_DEINTERLACE_METHOD \
|
||||
gst_vaapi_deinterlace_method_get_type()
|
||||
|
||||
static GType
|
||||
gst_vaapi_deinterlace_method_get_type(void)
|
||||
{
|
||||
static GType deinterlace_method_type = 0;
|
||||
|
||||
static const GEnumValue method_types[] = {
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_BOB,
|
||||
"Bob deinterlacing", "bob" },
|
||||
#if 0
|
||||
/* VA/VPP */
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
|
||||
"Weave deinterlacing", "weave" },
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
|
||||
"Motion adaptive deinterlacing", "motion-adaptive" },
|
||||
{ GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
|
||||
"Motion compensated deinterlacing", "motion-compensated" },
|
||||
#endif
|
||||
{ 0, NULL, NULL },
|
||||
};
|
||||
|
||||
if (!deinterlace_method_type) {
|
||||
deinterlace_method_type =
|
||||
g_enum_register_static("GstVaapiDeinterlaceMethod", method_types);
|
||||
}
|
||||
return deinterlace_method_type;
|
||||
}
|
||||
|
||||
static inline GstVaapiPostproc *
|
||||
get_vaapipostproc_from_pad(GstPad *pad)
|
||||
{
|
||||
|
|
15
gst/vaapi/gstvaapipostproc.h
Normal file → Executable file
15
gst/vaapi/gstvaapipostproc.h
Normal file → Executable file
|
@ -26,6 +26,7 @@
|
|||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
#include <gst/vaapi/gstvaapisurface.h>
|
||||
#include <gst/vaapi/gstvaapisurfacepool.h>
|
||||
#include <gst/vaapi/gstvaapifilter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -68,20 +69,6 @@ typedef enum {
|
|||
GST_VAAPI_DEINTERLACE_MODE_DISABLED,
|
||||
} GstVaapiDeinterlaceMode;
|
||||
|
||||
/**
|
||||
* GstVaapiDeinterlaceMethod:
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_BOB: Basic bob deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_WEAVE: Weave deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE: Motion adaptive deinterlacing algorithm.
|
||||
* @GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED: Motion compensated deinterlacing algorithm.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VAAPI_DEINTERLACE_METHOD_BOB = 1,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
|
||||
GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
|
||||
} GstVaapiDeinterlaceMethod;
|
||||
|
||||
struct _GstVaapiPostproc {
|
||||
/*< private >*/
|
||||
GstElement parent_instance;
|
||||
|
|
Loading…
Reference in a new issue