summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/libs/libs-sections.txt1
-rwxr-xr-x[-rw-r--r--]gst-libs/gst/vaapi/gstvaapifilter.c162
-rwxr-xr-x[-rw-r--r--]gst-libs/gst/vaapi/gstvaapifilter.h52
-rw-r--r--gst-libs/gst/vaapi/gstvaapiutils.c46
-rw-r--r--gst-libs/gst/vaapi/gstvaapiutils.h8
-rwxr-xr-x[-rw-r--r--]gst/vaapi/gstvaapipostproc.c30
-rwxr-xr-x[-rw-r--r--]gst/vaapi/gstvaapipostproc.h15
7 files changed, 269 insertions, 45 deletions
diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt
index 0aa16205..b70eaaaa 100644
--- a/docs/reference/libs/libs-sections.txt
+++ b/docs/reference/libs/libs-sections.txt
@@ -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>
diff --git a/gst-libs/gst/vaapi/gstvaapifilter.c b/gst-libs/gst/vaapi/gstvaapifilter.c
index 4ac3c221..78ab1078 100644..100755
--- a/gst-libs/gst/vaapi/gstvaapifilter.c
+++ b/gst-libs/gst/vaapi/gstvaapifilter.c
@@ -68,6 +68,60 @@ struct _GstVaapiFilter {
};
/* ------------------------------------------------------------------------- */
+/* --- 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);
+}
diff --git a/gst-libs/gst/vaapi/gstvaapifilter.h b/gst-libs/gst/vaapi/gstvaapifilter.h
index 8da28d47..bd770771 100644..100755
--- a/gst-libs/gst/vaapi/gstvaapifilter.h
+++ b/gst-libs/gst/vaapi/gstvaapifilter.h
@@ -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 */
diff --git a/gst-libs/gst/vaapi/gstvaapiutils.c b/gst-libs/gst/vaapi/gstvaapiutils.c
index aec68ff6..a0b0d0a7 100644
--- a/gst-libs/gst/vaapi/gstvaapiutils.c
+++ b/gst-libs/gst/vaapi/gstvaapiutils.c
@@ -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;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiutils.h b/gst-libs/gst/vaapi/gstvaapiutils.h
index a0a84b4f..0ab132bf 100644
--- a/gst-libs/gst/vaapi/gstvaapiutils.h
+++ b/gst-libs/gst/vaapi/gstvaapiutils.h
@@ -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 */
diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c
index 944e11f8..2504fb6b 100644..100755
--- a/gst/vaapi/gstvaapipostproc.c
+++ b/gst/vaapi/gstvaapipostproc.c
@@ -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)
{
diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h
index e983a312..b33e724e 100644..100755
--- a/gst/vaapi/gstvaapipostproc.h
+++ b/gst/vaapi/gstvaapipostproc.h
@@ -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;