summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Isorce <julien.isorce@gmail.com>2010-05-04 11:37:38 +0200
committerJulien Isorce <julien.isorce@gmail.com>2010-05-04 11:37:38 +0200
commitabb711ae06a24cfd8f7cc2ebfae6c2854aebf5b4 (patch)
tree6b2c4cfd9f7648a8d9570a5be30bf62bdb8d9324
parent56d180896aeaffe04876c93796478f1a0d7716db (diff)
glimagesink: handle pixel-aspect-ratio
-rw-r--r--gst-libs/gst/gl/gstgldisplay.c11
-rw-r--r--gst-libs/gst/gl/gstgldisplay.h3
-rw-r--r--gst/gl/gstglimagesink.c79
-rw-r--r--gst/gl/gstglimagesink.h5
-rw-r--r--tests/pipelines4
5 files changed, 91 insertions, 11 deletions
diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c
index f96bc14..b95ce64 100644
--- a/gst-libs/gst/gl/gstgldisplay.c
+++ b/gst-libs/gst/gl/gstgldisplay.c
@@ -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);
diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h
index 670d339..00789b8 100644
--- a/gst-libs/gst/gl/gstgldisplay.h
+++ b/gst-libs/gst/gl/gstgldisplay.h
@@ -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);
diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c
index 02ff7f9..25d16d9 100644
--- a/gst/gl/gstglimagesink.c
+++ b/gst/gl/gstglimagesink.c
@@ -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);
}
}
diff --git a/gst/gl/gstglimagesink.h b/gst/gl/gstglimagesink.h
index 453fbfe..c61b5c5 100644
--- a/gst/gl/gstglimagesink.h
+++ b/gst/gl/gstglimagesink.h
@@ -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
diff --git a/tests/pipelines b/tests/pipelines
index 6eb1523..5f9d45c 100644
--- a/tests/pipelines
+++ b/tests/pipelines
@@ -65,3 +65,7 @@ gst-launch-0.10 videotestsrc ! "video/x-raw-yuv, format=(fourcc)YUY2" ! glupload
gst-launch-0.10 -v videotestsrc ! glupload ! gloverlay location=image.png proportion-png=40 proportion-video=40 xpos-png=75 ypos-png=50 xpos-video=30 ypos-video=50 rotate-png=2 rotate-video=2 angle-png=-15 angle-video=15 ! glimagesink
+gst-launch-0.10 videotestsrc ! "video/x-raw-yuv, pixel-aspect-ratio=(fraction)5/2" ! glimagesink
+
+gst-launch-0.10 videotestsrc ! "video/x-raw-yuv,format=(fourcc)I420,width=720,height=576,pixel-aspect-ratio=(fraction)64/45" ! glupload ! glimagesink
+