[455/906] glimagesink: handle pixel-aspect-ratio

This commit is contained in:
Julien Isorce 2010-05-04 11:37:38 +02:00 committed by Matthew Waters
parent 00030c2bdd
commit 2b46c87bd0
4 changed files with 87 additions and 11 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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