mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 04:15:35 +00:00
glvideoflip: incorporate the aspect ratio into the scale_x calculations
1. Otherwise rotating the video will clip and show black bars due to gltransformation's implementation. 2. The other option of make gltransformation aspect-agnostic produces incorrect output with perspective transformations.
This commit is contained in:
parent
6f80d5c59a
commit
3cf98f7e5e
2 changed files with 66 additions and 40 deletions
|
@ -101,8 +101,7 @@ gst_video_flip_method_get_type (void)
|
||||||
#define gst_gl_video_flip_parent_class parent_class
|
#define gst_gl_video_flip_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstGLVideoFlip, gst_gl_video_flip,
|
G_DEFINE_TYPE_WITH_CODE (GstGLVideoFlip, gst_gl_video_flip,
|
||||||
GST_TYPE_BIN, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
|
GST_TYPE_BIN, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
|
||||||
"glvideoflip", 0, "glvideoflip element");
|
"glvideoflip", 0, "glvideoflip element"););
|
||||||
);
|
|
||||||
|
|
||||||
static void gst_gl_video_flip_set_property (GObject * object, guint prop_id,
|
static void gst_gl_video_flip_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
@ -148,6 +147,8 @@ gst_gl_video_flip_init (GstGLVideoFlip * flip)
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
|
||||||
|
flip->aspect = 1.0;
|
||||||
|
|
||||||
flip->input_capsfilter = gst_element_factory_make ("capsfilter", NULL);
|
flip->input_capsfilter = gst_element_factory_make ("capsfilter", NULL);
|
||||||
res &= gst_bin_add (GST_BIN (flip), flip->input_capsfilter);
|
res &= gst_bin_add (GST_BIN (flip), flip->input_capsfilter);
|
||||||
|
|
||||||
|
@ -200,6 +201,55 @@ gst_gl_video_flip_init (GstGLVideoFlip * flip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* with object lock */
|
||||||
|
static void
|
||||||
|
_set_active_method (GstGLVideoFlip * vf, GstGLVideoFlipMethod method)
|
||||||
|
{
|
||||||
|
gfloat rot_z = 0., scale_x = 1.0, scale_y = 1.0;
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_IDENTITY:
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_90R:
|
||||||
|
scale_x *= vf->aspect;
|
||||||
|
scale_y *= 1. / vf->aspect;
|
||||||
|
rot_z = 90.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_180:
|
||||||
|
rot_z = 180.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_90L:
|
||||||
|
scale_x *= vf->aspect;
|
||||||
|
scale_y *= 1. / vf->aspect;
|
||||||
|
rot_z = 270.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_FLIP_HORIZ:
|
||||||
|
scale_x *= -1.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_FLIP_UR_LL:
|
||||||
|
scale_x *= -vf->aspect;
|
||||||
|
scale_y *= 1. / vf->aspect;
|
||||||
|
rot_z = 90.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_FLIP_VERT:
|
||||||
|
scale_x *= -1.;
|
||||||
|
rot_z = 180.;
|
||||||
|
break;
|
||||||
|
case GST_GL_VIDEO_FLIP_METHOD_FLIP_UL_LR:
|
||||||
|
scale_x *= -vf->aspect;
|
||||||
|
scale_y *= 1. / vf->aspect;
|
||||||
|
rot_z = 270.;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vf->active_method = method;
|
||||||
|
GST_OBJECT_UNLOCK (vf);
|
||||||
|
g_object_set (vf->transformation, "rotation-z", rot_z, "scale-x", scale_x,
|
||||||
|
"scale-y", scale_y, NULL);
|
||||||
|
GST_OBJECT_LOCK (vf);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_video_flip_set_method (GstGLVideoFlip * vf, GstGLVideoFlipMethod method,
|
gst_gl_video_flip_set_method (GstGLVideoFlip * vf, GstGLVideoFlipMethod method,
|
||||||
gboolean from_tag)
|
gboolean from_tag)
|
||||||
|
@ -217,46 +267,10 @@ gst_gl_video_flip_set_method (GstGLVideoFlip * vf, GstGLVideoFlipMethod method,
|
||||||
else
|
else
|
||||||
method = vf->method;
|
method = vf->method;
|
||||||
|
|
||||||
if (method != vf->active_method) {
|
_set_active_method (vf, method);
|
||||||
vf->active_method = method;
|
|
||||||
GST_OBJECT_UNLOCK (vf);
|
|
||||||
|
|
||||||
g_object_set (vf->transformation, "rotation-x", 0., "rotation-y", 0.,
|
|
||||||
"rotation-z", 0., "scale-x", 1., "scale-y", 1., NULL);
|
|
||||||
switch (method) {
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_IDENTITY:
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_90R:
|
|
||||||
g_object_set (vf->transformation, "rotation-z", 90., NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_180:
|
|
||||||
g_object_set (vf->transformation, "rotation-z", 180., NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_90L:
|
|
||||||
g_object_set (vf->transformation, "rotation-z", 270., NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_FLIP_HORIZ:
|
|
||||||
g_object_set (vf->transformation, "scale-x", -1., NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_FLIP_UR_LL:
|
|
||||||
g_object_set (vf->transformation, "scale-x", -1., "rotation-z", 90.,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_FLIP_VERT:
|
|
||||||
g_object_set (vf->transformation, "scale-x", -1., "rotation-z", 180.,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case GST_GL_VIDEO_FLIP_METHOD_FLIP_UL_LR:
|
|
||||||
g_object_set (vf->transformation, "scale-x", -1., "rotation-z", 270.,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GST_OBJECT_UNLOCK (vf);
|
GST_OBJECT_UNLOCK (vf);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_video_flip_set_property (GObject * object, guint prop_id,
|
gst_gl_video_flip_set_property (GObject * object, guint prop_id,
|
||||||
|
@ -394,8 +408,18 @@ _input_sink_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
case GST_EVENT_CAPS:{
|
case GST_EVENT_CAPS:{
|
||||||
GstCaps *caps, *output, *templ;
|
GstCaps *caps, *output, *templ;
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
GstVideoInfo v_info;
|
||||||
|
|
||||||
gst_event_parse_caps (event, &caps);
|
gst_event_parse_caps (event, &caps);
|
||||||
|
GST_OBJECT_LOCK (vf);
|
||||||
|
if (gst_video_info_from_caps (&v_info, caps))
|
||||||
|
vf->aspect =
|
||||||
|
(gfloat) GST_VIDEO_INFO_WIDTH (&v_info) /
|
||||||
|
(gfloat) GST_VIDEO_INFO_HEIGHT (&v_info);
|
||||||
|
else
|
||||||
|
vf->aspect = 1.0;
|
||||||
|
_set_active_method (vf, vf->active_method);
|
||||||
|
GST_OBJECT_UNLOCK (vf);
|
||||||
|
|
||||||
output = _transform_caps (vf, GST_PAD_SINK, caps);
|
output = _transform_caps (vf, GST_PAD_SINK, caps);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct _GstGLVideoFlip
|
||||||
GstGLVideoFlipMethod method;
|
GstGLVideoFlipMethod method;
|
||||||
GstGLVideoFlipMethod tag_method;
|
GstGLVideoFlipMethod tag_method;
|
||||||
GstGLVideoFlipMethod active_method;
|
GstGLVideoFlipMethod active_method;
|
||||||
|
|
||||||
|
gfloat aspect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLVideoFlipClass
|
struct _GstGLVideoFlipClass
|
||||||
|
|
Loading…
Reference in a new issue