mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
vaapipostproc: add mirror support
Adds vpp mirroring support to vaapipostproc. Use property video-direction. Valid values are identity, horiz or vert. Default is identity (no mirror). Closes #89 v2: Use GstVideoOrientationMethod enum v3: Don't warn for VA_MIRROR_NONE. Use GST_TYPE_VIDEO_ORIENTATION_METHOD type. v4: Query VAAPI caps when setting mirror value instead of during per-frame processing. v5: Return TRUE in warning cases when setting mirror value.
This commit is contained in:
parent
38d25c65c3
commit
3ccf3f3334
6 changed files with 169 additions and 1 deletions
|
@ -61,6 +61,7 @@ struct _GstVaapiFilter
|
|||
GPtrArray *operations;
|
||||
GstVideoFormat format;
|
||||
GstVaapiScaleMethod scale_method;
|
||||
GstVideoOrientationMethod video_direction;
|
||||
GArray *formats;
|
||||
GArray *forward_references;
|
||||
GArray *backward_references;
|
||||
|
@ -115,6 +116,17 @@ gst_vaapi_scale_method_get_type (void)
|
|||
return g_type;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gst_vaapi_get_video_direction_nick (GstVideoOrientationMethod method)
|
||||
{
|
||||
gpointer const klass = g_type_class_peek (GST_TYPE_VIDEO_ORIENTATION_METHOD);
|
||||
GEnumValue *const e = g_enum_get_value (klass, method);
|
||||
|
||||
if (e)
|
||||
return e->value_nick;
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
GType
|
||||
gst_vaapi_deinterlace_method_get_type (void)
|
||||
{
|
||||
|
@ -277,6 +289,7 @@ vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type,
|
|||
|
||||
#define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN
|
||||
#define DEFAULT_SCALING GST_VAAPI_SCALE_METHOD_DEFAULT
|
||||
#define DEFAULT_VIDEO_DIRECTION GST_VIDEO_ORIENTATION_IDENTITY
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -297,6 +310,7 @@ enum
|
|||
PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING,
|
||||
PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
|
||||
PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE,
|
||||
|
||||
N_PROPERTIES
|
||||
|
@ -420,6 +434,18 @@ init_properties (void)
|
|||
GST_VAAPI_TYPE_SCALE_METHOD,
|
||||
DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GstVaapiFilter:video-direction:
|
||||
*
|
||||
* The video-direction to use, expressed as an enum value. See
|
||||
* #GstVideoOrientationMethod.
|
||||
*/
|
||||
g_properties[PROP_VIDEO_DIRECTION] = g_param_spec_enum ("video-direction",
|
||||
"Video Direction",
|
||||
"Video direction: rotation and flipping",
|
||||
GST_TYPE_VIDEO_ORIENTATION_METHOD,
|
||||
DEFAULT_VIDEO_DIRECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GstVaapiFilter:skin-tone-enhancement:
|
||||
*
|
||||
|
@ -465,6 +491,7 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec)
|
|||
case GST_VAAPI_FILTER_OP_FORMAT:
|
||||
case GST_VAAPI_FILTER_OP_CROP:
|
||||
case GST_VAAPI_FILTER_OP_SCALING:
|
||||
case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
|
||||
op_data->va_type = VAProcFilterNone;
|
||||
break;
|
||||
case GST_VAAPI_FILTER_OP_DENOISE:
|
||||
|
@ -1330,6 +1357,9 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op,
|
|||
return op_set_skintone (filter, op_data,
|
||||
(value ? g_value_get_boolean (value) :
|
||||
G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value));
|
||||
case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
|
||||
return gst_vaapi_filter_set_video_direction (filter, value ?
|
||||
g_value_get_enum (value) : DEFAULT_VIDEO_DIRECTION);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1362,6 +1392,7 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter,
|
|||
guint i, num_filters = 0;
|
||||
VAStatus va_status;
|
||||
VARectangle src_rect, dst_rect;
|
||||
guint va_mirror = from_GstVideoOrientationMethod (filter->video_direction);
|
||||
|
||||
if (!ensure_operations (filter))
|
||||
return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
|
@ -1444,6 +1475,10 @@ gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter,
|
|||
pipeline_param->filters = filters;
|
||||
pipeline_param->num_filters = num_filters;
|
||||
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
pipeline_param->mirror_state = va_mirror;
|
||||
#endif
|
||||
|
||||
// Reference frames for advanced deinterlacing
|
||||
if (filter->forward_references->len > 0) {
|
||||
pipeline_param->forward_references = (VASurfaceID *)
|
||||
|
@ -1838,6 +1873,58 @@ gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance)
|
|||
find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_filter_set_video_direction:
|
||||
* @filter: a #GstVaapiFilter
|
||||
* @method: the video direction (see #GstVideoOrientationMethod)
|
||||
*
|
||||
* Applies mirror/rotation to the video processing pipeline.
|
||||
*
|
||||
* Return value: %TRUE if the operation is supported, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter,
|
||||
GstVideoOrientationMethod method)
|
||||
{
|
||||
g_return_val_if_fail (filter != NULL, FALSE);
|
||||
|
||||
switch (method) {
|
||||
case GST_VIDEO_ORIENTATION_IDENTITY:
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_HORIZ:
|
||||
case GST_VIDEO_ORIENTATION_VERT:
|
||||
{
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
VAProcPipelineCaps pipeline_caps;
|
||||
guint va_mirror = from_GstVideoOrientationMethod (method);
|
||||
|
||||
VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
|
||||
filter->va_context, NULL, 0, &pipeline_caps);
|
||||
if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()"))
|
||||
return FALSE;
|
||||
|
||||
if (!(pipeline_caps.mirror_flags & va_mirror)) {
|
||||
GST_WARNING ("%s video-direction unsupported",
|
||||
gst_vaapi_get_video_direction_nick (method));
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
GST_WARNING ("%s video-direction unsupported",
|
||||
gst_vaapi_get_video_direction_nick (method));
|
||||
return TRUE;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GST_WARNING ("%s video-direction unsupported or unimplemented",
|
||||
gst_vaapi_get_video_direction_nick (method));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
filter->video_direction = method;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gfloat
|
||||
op_get_float_default_value (GstVaapiFilter * filter,
|
||||
GstVaapiFilterOpData * op_data)
|
||||
|
@ -1915,3 +2002,11 @@ gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GstVideoOrientationMethod
|
||||
gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter)
|
||||
{
|
||||
g_return_val_if_fail (filter != NULL, FALSE);
|
||||
|
||||
return DEFAULT_VIDEO_DIRECTION;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ typedef struct _GstVaapiFilterOpInfo GstVaapiFilterOpInfo;
|
|||
* @GST_VAAPI_FILTER_OP_BRIGHTNESS: Change brightness (float).
|
||||
* @GST_VAAPI_FILTER_OP_CONTRAST: Change contrast (float).
|
||||
* @GST_VAAPI_FILTER_OP_SCALING: Change scaling method (#GstVaapiScaleMethod).
|
||||
* @GST_VAAPI_FILTER_OP_VIDEO_DIRECTION: Change video direction
|
||||
* (#GstVideoOrientationMethod).
|
||||
* @GST_VAAPI_FILTER_OP_SKINTONE: Skin tone enhancement (bool).
|
||||
*
|
||||
* The set of operations that could be applied to the filter.
|
||||
|
@ -63,6 +65,7 @@ typedef enum {
|
|||
GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
GST_VAAPI_FILTER_OP_SCALING,
|
||||
GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
|
||||
GST_VAAPI_FILTER_OP_SKINTONE,
|
||||
} GstVaapiFilterOp;
|
||||
|
||||
|
@ -246,6 +249,10 @@ gboolean
|
|||
gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
|
||||
GstVaapiScaleMethod method);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter,
|
||||
GstVideoOrientationMethod method);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_set_skintone (GstVaapiFilter * filter,
|
||||
gboolean enhance);
|
||||
|
@ -271,6 +278,9 @@ gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter);
|
|||
GstVaapiScaleMethod
|
||||
gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter);
|
||||
|
||||
GstVideoOrientationMethod
|
||||
gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter);
|
||||
|
||||
|
|
|
@ -828,3 +828,27 @@ to_GstVaapiScaleMethod (guint flags)
|
|||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/* VPP: translate GstVideoOrientationMethod into VA mirror flags */
|
||||
guint
|
||||
from_GstVideoOrientationMethod (guint value)
|
||||
{
|
||||
guint va_flags = 0;
|
||||
|
||||
switch (value) {
|
||||
#if VA_CHECK_VERSION(1,1,0)
|
||||
case GST_VIDEO_ORIENTATION_IDENTITY:
|
||||
va_flags = VA_MIRROR_NONE;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_HORIZ:
|
||||
va_flags = VA_MIRROR_HORIZONTAL;
|
||||
break;
|
||||
case GST_VIDEO_ORIENTATION_VERT:
|
||||
va_flags = VA_MIRROR_VERTICAL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return va_flags;
|
||||
}
|
||||
|
|
|
@ -147,4 +147,8 @@ G_GNUC_INTERNAL
|
|||
guint
|
||||
to_GstVaapiScaleMethod (guint flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint
|
||||
from_GstVideoOrientationMethod (guint value);
|
||||
|
||||
#endif /* GST_VAAPI_UTILS_H */
|
||||
|
|
|
@ -121,6 +121,7 @@ enum
|
|||
PROP_BRIGHTNESS,
|
||||
PROP_CONTRAST,
|
||||
PROP_SCALE_METHOD,
|
||||
PROP_VIDEO_DIRECTION,
|
||||
PROP_SKIN_TONE_ENHANCEMENT,
|
||||
};
|
||||
|
||||
|
@ -593,6 +594,16 @@ update_filter (GstVaapiPostproc * postproc)
|
|||
postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_SCALE);
|
||||
}
|
||||
|
||||
if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION) {
|
||||
if (!gst_vaapi_filter_set_video_direction (postproc->filter,
|
||||
postproc->video_direction))
|
||||
return FALSE;
|
||||
|
||||
if (gst_vaapi_filter_get_video_direction_default (postproc->filter) ==
|
||||
postproc->video_direction)
|
||||
postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION);
|
||||
}
|
||||
|
||||
if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) {
|
||||
if (!gst_vaapi_filter_set_skintone (postproc->filter,
|
||||
postproc->skintone_enhance))
|
||||
|
@ -1613,6 +1624,10 @@ gst_vaapipostproc_set_property (GObject * object,
|
|||
postproc->scale_method = g_value_get_enum (value);
|
||||
postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE;
|
||||
break;
|
||||
case PROP_VIDEO_DIRECTION:
|
||||
postproc->video_direction = g_value_get_enum (value);
|
||||
postproc->flags |= GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION;
|
||||
break;
|
||||
case PROP_SKIN_TONE_ENHANCEMENT:
|
||||
postproc->skintone_enhance = g_value_get_boolean (value);
|
||||
postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE;
|
||||
|
@ -1674,6 +1689,9 @@ gst_vaapipostproc_get_property (GObject * object,
|
|||
case PROP_SCALE_METHOD:
|
||||
g_value_set_enum (value, postproc->scale_method);
|
||||
break;
|
||||
case PROP_VIDEO_DIRECTION:
|
||||
g_value_set_enum (value, postproc->video_direction);
|
||||
break;
|
||||
case PROP_SKIN_TONE_ENHANCEMENT:
|
||||
g_value_set_boolean (value, postproc->skintone_enhance);
|
||||
break;
|
||||
|
@ -1894,6 +1912,17 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass)
|
|||
g_object_class_install_property (object_class,
|
||||
PROP_SCALE_METHOD, filter_op->pspec);
|
||||
|
||||
/**
|
||||
* GstVaapiPostproc:video-direction:
|
||||
*
|
||||
* The video-direction to use, expressed as an enum value. See
|
||||
* #GstVideoDirectionMethod.
|
||||
*/
|
||||
filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION);
|
||||
if (filter_op)
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VIDEO_DIRECTION, filter_op->pspec);
|
||||
|
||||
/**
|
||||
* GstVaapiPostproc:skin-tone-enhancement:
|
||||
*
|
||||
|
|
|
@ -86,6 +86,7 @@ typedef enum
|
|||
* @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing.
|
||||
* @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling.
|
||||
* @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode.
|
||||
* @GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION: Video rotation and flip/mirroring.
|
||||
* @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement.
|
||||
*
|
||||
* The set of operations that are to be performed for each frame.
|
||||
|
@ -101,6 +102,8 @@ typedef enum
|
|||
GST_VAAPI_POSTPROC_FLAG_CONTRAST = 1 << GST_VAAPI_FILTER_OP_CONTRAST,
|
||||
GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING,
|
||||
GST_VAAPI_POSTPROC_FLAG_SCALE = 1 << GST_VAAPI_FILTER_OP_SCALING,
|
||||
GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION =
|
||||
1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
|
||||
GST_VAAPI_POSTPROC_FLAG_SKINTONE = 1 << GST_VAAPI_FILTER_OP_SKINTONE,
|
||||
|
||||
/* Additional custom flags */
|
||||
|
@ -160,8 +163,11 @@ struct _GstVaapiPostproc
|
|||
gfloat denoise_level;
|
||||
gfloat sharpen_level;
|
||||
|
||||
/* Color balance filter values */
|
||||
GstVaapiScaleMethod scale_method;
|
||||
|
||||
GstVideoOrientationMethod video_direction;
|
||||
|
||||
/* Color balance filter values */
|
||||
gfloat hue;
|
||||
gfloat saturation;
|
||||
gfloat brightness;
|
||||
|
|
Loading…
Reference in a new issue