mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-05-11 02:44:48 +00:00
[455/906] glimagesink: handle pixel-aspect-ratio
This commit is contained in:
parent
00030c2bdd
commit
2b46c87bd0
4 changed files with 87 additions and 11 deletions
|
@ -2167,8 +2167,9 @@ gst_gl_display_create_context (GstGLDisplay * display,
|
|||
|
||||
/* Called by the glimagesink element */
|
||||
gboolean
|
||||
gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, gint width,
|
||||
gint height, gboolean keep_aspect_ratio)
|
||||
gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture,
|
||||
gint gl_width, gint gl_height, gint window_width, gint window_height,
|
||||
gboolean keep_aspect_ratio)
|
||||
{
|
||||
gboolean isAlive = TRUE;
|
||||
|
||||
|
@ -2185,12 +2186,12 @@ gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, gint width,
|
|||
|
||||
if (texture) {
|
||||
display->redisplay_texture = texture;
|
||||
display->redisplay_texture_width = width;
|
||||
display->redisplay_texture_height = height;
|
||||
display->redisplay_texture_width = gl_width;
|
||||
display->redisplay_texture_height = gl_height;
|
||||
}
|
||||
display->keep_aspect_ratio = keep_aspect_ratio;
|
||||
if (display->gl_window)
|
||||
gst_gl_window_draw (display->gl_window, width, height);
|
||||
gst_gl_window_draw (display->gl_window, window_width, window_height);
|
||||
}
|
||||
gst_gl_display_unlock (display);
|
||||
|
||||
|
|
|
@ -241,7 +241,8 @@ GstGLDisplay *gst_gl_display_new (void);
|
|||
void gst_gl_display_create_context (GstGLDisplay * display,
|
||||
gulong external_gl_context);
|
||||
gboolean gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture,
|
||||
gint width, gint height, gboolean keep_aspect_ratio);
|
||||
gint gl_width, gint gl_height, gint window_width, gint window_height,
|
||||
gboolean keep_aspect_ratio);
|
||||
|
||||
void gst_gl_display_thread_add (GstGLDisplay * display,
|
||||
GstGLDisplayThreadFunc func, gpointer data);
|
||||
|
|
|
@ -151,7 +151,8 @@ enum
|
|||
PROP_CLIENT_RESHAPE_CALLBACK,
|
||||
PROP_CLIENT_DRAW_CALLBACK,
|
||||
PROP_CLIENT_DATA,
|
||||
PROP_FORCE_ASPECT_RATIO
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO
|
||||
};
|
||||
|
||||
GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink,
|
||||
|
@ -233,6 +234,11 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
|
|||
"When enabled, scaling will respect original aspect ratio", FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", "1/1",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gobject_class->finalize = gst_glimage_sink_finalize;
|
||||
|
||||
gstelement_class->change_state = gst_glimage_sink_change_state;
|
||||
|
@ -257,6 +263,7 @@ gst_glimage_sink_init (GstGLImageSink * glimage_sink,
|
|||
glimage_sink->clientDrawCallback = NULL;
|
||||
glimage_sink->client_data = NULL;
|
||||
glimage_sink->keep_aspect_ratio = FALSE;
|
||||
glimage_sink->par = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -296,6 +303,17 @@ gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
|||
glimage_sink->keep_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
}
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
{
|
||||
g_free (glimage_sink->par);
|
||||
glimage_sink->par = g_new0 (GValue, 1);
|
||||
g_value_init (glimage_sink->par, GST_TYPE_FRACTION);
|
||||
if (!g_value_transform (value, glimage_sink->par)) {
|
||||
g_warning ("Could not transform string to aspect ratio");
|
||||
gst_value_set_fraction (glimage_sink->par, 1, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -311,6 +329,11 @@ gst_glimage_sink_finalize (GObject * object)
|
|||
|
||||
glimage_sink = GST_GLIMAGE_SINK (object);
|
||||
|
||||
if (glimage_sink->par) {
|
||||
g_free (glimage_sink->par);
|
||||
glimage_sink->par = NULL;
|
||||
}
|
||||
|
||||
if (glimage_sink->caps)
|
||||
gst_caps_unref (glimage_sink->caps);
|
||||
|
||||
|
@ -336,6 +359,10 @@ gst_glimage_sink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, glimage_sink->keep_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
if (glimage_sink->par)
|
||||
g_value_transform (glimage_sink->par, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -352,7 +379,8 @@ gst_glimage_sink_query (GstElement * element, GstQuery * query)
|
|||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, glimage_sink->display, NULL);
|
||||
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER,
|
||||
glimage_sink->display, NULL);
|
||||
res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
|
||||
break;
|
||||
}
|
||||
|
@ -463,6 +491,8 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
gboolean ok;
|
||||
gint fps_n, fps_d;
|
||||
gint par_n, par_d;
|
||||
gint display_par_n, display_par_d;
|
||||
guint display_ratio_num, display_ratio_den;
|
||||
GstVideoFormat format;
|
||||
GstStructure *structure;
|
||||
gboolean is_gl;
|
||||
|
@ -481,13 +511,16 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
is_gl = FALSE;
|
||||
ok = gst_video_format_parse_caps (caps, &format, &width, &height);
|
||||
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
/* init colorspace conversion if needed */
|
||||
gst_gl_display_init_upload (glimage_sink->display, format,
|
||||
width, height, width, height);
|
||||
}
|
||||
|
||||
gst_gl_display_set_client_reshape_callback (glimage_sink->display,
|
||||
glimage_sink->clientReshapeCallback);
|
||||
glimage_sink->clientReshapeCallback);
|
||||
|
||||
gst_gl_display_set_client_draw_callback (glimage_sink->display,
|
||||
glimage_sink->clientDrawCallback);
|
||||
|
@ -501,6 +534,43 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
/* get display's PAR */
|
||||
if (glimage_sink->par) {
|
||||
display_par_n = gst_value_get_fraction_numerator (glimage_sink->par);
|
||||
display_par_d = gst_value_get_fraction_denominator (glimage_sink->par);
|
||||
} else {
|
||||
display_par_n = 1;
|
||||
display_par_d = 1;
|
||||
}
|
||||
|
||||
ok = gst_video_calculate_display_ratio (&display_ratio_num,
|
||||
&display_ratio_den, width, height, par_n, par_d, display_par_n,
|
||||
display_par_d);
|
||||
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
if (height % display_ratio_den == 0) {
|
||||
GST_DEBUG ("keeping video height");
|
||||
glimage_sink->window_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
glimage_sink->window_height = height;
|
||||
} else if (width % display_ratio_num == 0) {
|
||||
GST_DEBUG ("keeping video width");
|
||||
glimage_sink->window_width = width;
|
||||
glimage_sink->window_height = (guint)
|
||||
gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num);
|
||||
} else {
|
||||
GST_DEBUG ("approximating while keeping video height");
|
||||
glimage_sink->window_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
glimage_sink->window_height = height;
|
||||
}
|
||||
GST_DEBUG ("scaling to %dx%d",
|
||||
glimage_sink->window_width, glimage_sink->window_height);
|
||||
|
||||
GST_VIDEO_SINK_WIDTH (glimage_sink) = width;
|
||||
GST_VIDEO_SINK_HEIGHT (glimage_sink) = height;
|
||||
glimage_sink->is_gl = is_gl;
|
||||
|
@ -562,6 +632,7 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
if (gl_buffer->texture &&
|
||||
gst_gl_display_redisplay (glimage_sink->display,
|
||||
gl_buffer->texture, gl_buffer->width, gl_buffer->height,
|
||||
glimage_sink->window_width, glimage_sink->window_height,
|
||||
glimage_sink->keep_aspect_ratio))
|
||||
return GST_FLOW_OK;
|
||||
else
|
||||
|
@ -604,7 +675,7 @@ gst_glimage_sink_expose (GstXOverlay * overlay)
|
|||
glimage_sink->window_id);
|
||||
}
|
||||
|
||||
gst_gl_display_redisplay (glimage_sink->display, 0, 0, 0,
|
||||
gst_gl_display_redisplay (glimage_sink->display, 0, 0, 0, 0, 0,
|
||||
glimage_sink->keep_aspect_ratio);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
|
||||
* Copyright (C) 2005,2006,2007 David A. Schleef <ds@schleef.org>
|
||||
|
@ -59,6 +59,8 @@ struct _GstGLImageSink
|
|||
GstCaps *caps;
|
||||
gint width;
|
||||
gint height;
|
||||
gint window_width;
|
||||
gint window_height;
|
||||
gboolean is_gl;
|
||||
gint fps_n, fps_d;
|
||||
gint par_n, par_d;
|
||||
|
@ -71,6 +73,7 @@ struct _GstGLImageSink
|
|||
gpointer client_data;
|
||||
|
||||
gboolean keep_aspect_ratio;
|
||||
GValue *par;
|
||||
};
|
||||
|
||||
struct _GstGLImageSinkClass
|
||||
|
|
Loading…
Reference in a new issue