mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
gtk: implement pixel and display aspect ratio handling
This commit is contained in:
parent
8648d59974
commit
48db03200d
6 changed files with 239 additions and 12 deletions
|
@ -33,6 +33,8 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_gl_sink);
|
|||
#define GST_CAT_DEFAULT gst_debug_gtk_gl_sink
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 0
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
static void gst_gtk_gl_sink_finalize (GObject * object);
|
||||
static void gst_gtk_gl_sink_set_property (GObject * object, guint prop_id,
|
||||
|
@ -67,6 +69,7 @@ enum
|
|||
PROP_0,
|
||||
PROP_WIDGET,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -112,6 +115,11 @@ gst_gtk_gl_sink_class_init (GstGtkGLSinkClass * klass)
|
|||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_gtk_gl_sink_template));
|
||||
|
||||
|
@ -131,6 +139,8 @@ static void
|
|||
gst_gtk_gl_sink_init (GstGtkGLSink * gtk_sink)
|
||||
{
|
||||
gtk_sink->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
gtk_sink->par_n = DEFAULT_PAR_N;
|
||||
gtk_sink->par_d = DEFAULT_PAR_D;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -157,9 +167,12 @@ gst_gtk_gl_sink_get_widget (GstGtkGLSink * gtk_sink)
|
|||
}
|
||||
|
||||
gtk_sink->widget = (GtkGstGLWidget *) gtk_gst_gl_widget_new ();
|
||||
gtk_sink->bind_aspect_ratio =
|
||||
gtk_sink->bind_force_aspect_ratio =
|
||||
g_object_bind_property (gtk_sink, "force-aspect-ratio", gtk_sink->widget,
|
||||
"force-aspect-ratio", G_BINDING_BIDIRECTIONAL);
|
||||
gtk_sink->bind_pixel_aspect_ratio =
|
||||
g_object_bind_property (gtk_sink, "pixel-aspect-ratio", gtk_sink->widget,
|
||||
"pixel-aspect-ratio", G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
/* Take the floating ref, otherwise the destruction of the container will
|
||||
* make this widget disapear possibly before we are done. */
|
||||
|
@ -183,6 +196,9 @@ gst_gtk_gl_sink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, gtk_sink->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, gtk_sink->par_n, gtk_sink->par_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -199,6 +215,10 @@ gst_gtk_gl_sink_set_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
gtk_sink->force_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gtk_sink->par_n = gst_value_get_fraction_numerator (value);
|
||||
gtk_sink->par_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -67,7 +67,11 @@ struct _GstGtkGLSink
|
|||
|
||||
/* properties */
|
||||
gboolean force_aspect_ratio;
|
||||
GBinding *bind_aspect_ratio;
|
||||
GBinding *bind_force_aspect_ratio;
|
||||
|
||||
gint par_n;
|
||||
gint par_d;
|
||||
GBinding *bind_pixel_aspect_ratio;
|
||||
|
||||
GstGtkGLSinkPrivate *priv;
|
||||
};
|
||||
|
|
|
@ -59,12 +59,15 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
);
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 0
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_WIDGET,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -110,6 +113,11 @@ gst_gtk_sink_class_init (GstGtkSinkClass * klass)
|
|||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_gtk_sink_template));
|
||||
|
||||
|
@ -127,6 +135,9 @@ gst_gtk_sink_class_init (GstGtkSinkClass * klass)
|
|||
static void
|
||||
gst_gtk_sink_init (GstGtkSink * gtk_sink)
|
||||
{
|
||||
gtk_sink->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
gtk_sink->par_n = DEFAULT_PAR_N;
|
||||
gtk_sink->par_d = DEFAULT_PAR_D;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -156,6 +167,9 @@ gst_gtk_sink_get_widget (GstGtkSink * gtk_sink)
|
|||
gtk_sink->bind_aspect_ratio =
|
||||
g_object_bind_property (gtk_sink, "force-aspect-ratio", gtk_sink->widget,
|
||||
"force-aspect-ratio", G_BINDING_BIDIRECTIONAL);
|
||||
gtk_sink->bind_pixel_aspect_ratio =
|
||||
g_object_bind_property (gtk_sink, "pixel-aspect-ratio", gtk_sink->widget,
|
||||
"pixel-aspect-ratio", G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
/* Take the floating ref, other wise the destruction of the container will
|
||||
* make this widget disapear possibly before we are done. */
|
||||
|
@ -177,6 +191,9 @@ gst_gtk_sink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, gtk_sink->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, gtk_sink->par_n, gtk_sink->par_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -193,6 +210,10 @@ gst_gtk_sink_set_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
gtk_sink->force_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gtk_sink->par_n = gst_value_get_fraction_numerator (value);
|
||||
gtk_sink->par_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -60,6 +60,10 @@ struct _GstGtkSink
|
|||
gboolean force_aspect_ratio;
|
||||
GBinding *bind_aspect_ratio;
|
||||
|
||||
gint par_n;
|
||||
gint par_d;
|
||||
GBinding *bind_pixel_aspect_ratio;
|
||||
|
||||
GstGtkSinkPrivate *priv;
|
||||
};
|
||||
|
||||
|
|
|
@ -51,18 +51,20 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkGstGLWidget, gtk_gst_gl_widget, GTK_TYPE_GL_AREA,
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "gtkgstglwidget", 0,
|
||||
"Gtk Gst GL Widget");
|
||||
);
|
||||
"Gtk Gst GL Widget"););
|
||||
|
||||
#define GTK_GST_GL_WIDGET_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
|
||||
GTK_TYPE_GST_GL_WIDGET, GtkGstGLWidgetPrivate))
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 0
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
struct _GtkGstGLWidgetPrivate
|
||||
|
@ -71,6 +73,10 @@ struct _GtkGstGLWidgetPrivate
|
|||
|
||||
/* properties */
|
||||
gboolean force_aspect_ratio;
|
||||
gint par_n, par_d;
|
||||
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
|
||||
gboolean negotiated;
|
||||
GstBuffer *buffer;
|
||||
|
@ -210,8 +216,8 @@ _redraw_texture (GtkGstGLWidget * gst_widget, guint tex)
|
|||
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = GST_VIDEO_INFO_WIDTH (&gst_widget->priv->v_info);
|
||||
src.h = GST_VIDEO_INFO_HEIGHT (&gst_widget->priv->v_info);
|
||||
src.w = gst_widget->priv->display_width;
|
||||
src.h = gst_widget->priv->display_height;
|
||||
|
||||
dst.x = gtk_viewport[0];
|
||||
dst.y = gtk_viewport[1];
|
||||
|
@ -442,6 +448,10 @@ gtk_gst_gl_widget_set_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
gtk_widget->priv->force_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gtk_widget->priv->par_n = gst_value_get_fraction_numerator (value);
|
||||
gtk_widget->priv->par_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -458,6 +468,10 @@ gtk_gst_gl_widget_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, gtk_widget->priv->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, gtk_widget->priv->par_n,
|
||||
gtk_widget->priv->par_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -484,6 +498,11 @@ gtk_gst_gl_widget_class_init (GtkGstGLWidgetClass * klass)
|
|||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_klass, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gl_widget_klass->render = gtk_gst_gl_widget_render;
|
||||
|
||||
widget_klass->get_preferred_width = gtk_gst_gl_widget_get_preferred_width;
|
||||
|
@ -498,6 +517,8 @@ gtk_gst_gl_widget_init (GtkGstGLWidget * widget)
|
|||
widget->priv = GTK_GST_GL_WIDGET_GET_PRIVATE (widget);
|
||||
|
||||
widget->priv->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
widget->priv->par_n = DEFAULT_PAR_N;
|
||||
widget->priv->par_d = DEFAULT_PAR_D;
|
||||
|
||||
g_mutex_init (&widget->priv->lock);
|
||||
|
||||
|
@ -523,7 +544,7 @@ gtk_gst_gl_widget_init (GtkGstGLWidget * widget)
|
|||
if (!widget->priv->display)
|
||||
widget->priv->display = gst_gl_display_new ();
|
||||
|
||||
gtk_gl_area_set_has_alpha ((GtkGLArea *) widget, TRUE);
|
||||
gtk_gl_area_set_has_alpha ((GtkGLArea *) widget, FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
@ -665,6 +686,66 @@ gtk_gst_gl_widget_init_winsys (GtkGstGLWidget * widget)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_calculate_par (GtkGstGLWidget * widget, GstVideoInfo * info)
|
||||
{
|
||||
gboolean ok;
|
||||
gint width, height;
|
||||
gint par_n, par_d;
|
||||
gint display_par_n, display_par_d;
|
||||
guint display_ratio_num, display_ratio_den;
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (info);
|
||||
|
||||
par_n = GST_VIDEO_INFO_PAR_N (info);
|
||||
par_d = GST_VIDEO_INFO_PAR_D (info);
|
||||
|
||||
if (!par_n)
|
||||
par_n = 1;
|
||||
|
||||
/* get display's PAR */
|
||||
if (widget->priv->par_n != 0 && widget->priv->par_d != 0) {
|
||||
display_par_n = widget->priv->par_n;
|
||||
display_par_d = widget->priv->par_d;
|
||||
} 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;
|
||||
|
||||
GST_LOG ("PAR: %u/%u DAR:%u/%u", par_n, par_d, display_par_n, display_par_d);
|
||||
|
||||
if (height % display_ratio_den == 0) {
|
||||
GST_DEBUG ("keeping video height");
|
||||
widget->priv->display_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
widget->priv->display_height = height;
|
||||
} else if (width % display_ratio_num == 0) {
|
||||
GST_DEBUG ("keeping video width");
|
||||
widget->priv->display_width = width;
|
||||
widget->priv->display_height = (guint)
|
||||
gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num);
|
||||
} else {
|
||||
GST_DEBUG ("approximating while keeping video height");
|
||||
widget->priv->display_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
widget->priv->display_height = height;
|
||||
}
|
||||
GST_DEBUG ("scaling to %dx%d", widget->priv->display_width,
|
||||
widget->priv->display_height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gst_gl_widget_set_caps (GtkGstGLWidget * widget, GstCaps * caps)
|
||||
{
|
||||
|
@ -691,6 +772,11 @@ gtk_gst_gl_widget_set_caps (GtkGstGLWidget * widget, GstCaps * caps)
|
|||
gst_caps_set_features (widget->priv->gl_caps, 0,
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
|
||||
|
||||
if (!_calculate_par (widget, &v_info)) {
|
||||
g_mutex_unlock (&widget->priv->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
widget->priv->v_info = v_info;
|
||||
widget->priv->negotiated = TRUE;
|
||||
|
||||
|
|
|
@ -41,11 +41,14 @@ G_DEFINE_TYPE (GtkGstWidget, gtk_gst_widget, GTK_TYPE_DRAWING_AREA);
|
|||
GTK_TYPE_GST_WIDGET, GtkGstWidgetPrivate))
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 0
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
struct _GtkGstWidgetPrivate
|
||||
|
@ -54,6 +57,10 @@ struct _GtkGstWidgetPrivate
|
|||
|
||||
/* properties */
|
||||
gboolean force_aspect_ratio;
|
||||
gint par_n, par_d;
|
||||
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
|
||||
gboolean negotiated;
|
||||
GstBuffer *buffer;
|
||||
|
@ -110,10 +117,9 @@ gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr)
|
|||
if (gst_widget->priv->negotiated && gst_widget->priv->buffer
|
||||
&& gst_video_frame_map (&frame, &gst_widget->priv->v_info,
|
||||
gst_widget->priv->buffer, GST_MAP_READ)) {
|
||||
gdouble scale_x =
|
||||
(gdouble) widget_width / GST_VIDEO_INFO_WIDTH (&frame.info);
|
||||
gdouble scale_x = (gdouble) widget_width / gst_widget->priv->display_width;
|
||||
gdouble scale_y =
|
||||
(gdouble) widget_height / GST_VIDEO_INFO_HEIGHT (&frame.info);
|
||||
(gdouble) widget_height / gst_widget->priv->display_height;
|
||||
GstVideoRectangle result;
|
||||
|
||||
gst_widget->priv->v_info = frame.info;
|
||||
|
@ -127,8 +133,8 @@ gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr)
|
|||
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = GST_VIDEO_INFO_WIDTH (&frame.info);
|
||||
src.h = GST_VIDEO_INFO_HEIGHT (&frame.info);
|
||||
src.w = gst_widget->priv->display_width;
|
||||
src.h = gst_widget->priv->display_height;
|
||||
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
|
@ -145,6 +151,12 @@ gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr)
|
|||
result.h = widget_height;
|
||||
}
|
||||
|
||||
scale_x *=
|
||||
(gdouble) gst_widget->priv->display_width / (gdouble) frame.info.width;
|
||||
scale_y *=
|
||||
(gdouble) gst_widget->priv->display_height /
|
||||
(gdouble) frame.info.height;
|
||||
|
||||
cairo_translate (cr, result.x, result.y);
|
||||
cairo_scale (cr, scale_x, scale_y);
|
||||
cairo_rectangle (cr, 0, 0, result.w, result.h);
|
||||
|
@ -189,6 +201,10 @@ gtk_gst_widget_set_property (GObject * object, guint prop_id,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
gtk_widget->priv->force_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gtk_widget->priv->par_n = gst_value_get_fraction_numerator (value);
|
||||
gtk_widget->priv->par_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -205,6 +221,10 @@ gtk_gst_widget_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, gtk_widget->priv->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, gtk_widget->priv->par_n,
|
||||
gtk_widget->priv->par_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -230,6 +250,11 @@ gtk_gst_widget_class_init (GtkGstWidgetClass * klass)
|
|||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_klass, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
widget_klass->draw = gtk_gst_widget_draw;
|
||||
widget_klass->get_preferred_width = gtk_gst_widget_get_preferred_width;
|
||||
widget_klass->get_preferred_height = gtk_gst_widget_get_preferred_height;
|
||||
|
@ -241,6 +266,8 @@ gtk_gst_widget_init (GtkGstWidget * widget)
|
|||
widget->priv = GTK_GST_WIDGET_GET_PRIVATE (widget);
|
||||
|
||||
widget->priv->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
widget->priv->par_n = DEFAULT_PAR_N;
|
||||
widget->priv->par_d = DEFAULT_PAR_D;
|
||||
|
||||
g_mutex_init (&widget->priv->lock);
|
||||
}
|
||||
|
@ -284,6 +311,66 @@ _queue_resize (GtkGstWidget * widget)
|
|||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_calculate_par (GtkGstWidget * widget, GstVideoInfo * info)
|
||||
{
|
||||
gboolean ok;
|
||||
gint width, height;
|
||||
gint par_n, par_d;
|
||||
gint display_par_n, display_par_d;
|
||||
guint display_ratio_num, display_ratio_den;
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (info);
|
||||
|
||||
par_n = GST_VIDEO_INFO_PAR_N (info);
|
||||
par_d = GST_VIDEO_INFO_PAR_D (info);
|
||||
|
||||
if (!par_n)
|
||||
par_n = 1;
|
||||
|
||||
/* get display's PAR */
|
||||
if (widget->priv->par_n != 0 && widget->priv->par_d != 0) {
|
||||
display_par_n = widget->priv->par_n;
|
||||
display_par_d = widget->priv->par_d;
|
||||
} 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;
|
||||
|
||||
GST_LOG ("PAR: %u/%u DAR:%u/%u", par_n, par_d, display_par_n, display_par_d);
|
||||
|
||||
if (height % display_ratio_den == 0) {
|
||||
GST_DEBUG ("keeping video height");
|
||||
widget->priv->display_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
widget->priv->display_height = height;
|
||||
} else if (width % display_ratio_num == 0) {
|
||||
GST_DEBUG ("keeping video width");
|
||||
widget->priv->display_width = width;
|
||||
widget->priv->display_height = (guint)
|
||||
gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num);
|
||||
} else {
|
||||
GST_DEBUG ("approximating while keeping video height");
|
||||
widget->priv->display_width = (guint)
|
||||
gst_util_uint64_scale_int (height, display_ratio_num,
|
||||
display_ratio_den);
|
||||
widget->priv->display_height = height;
|
||||
}
|
||||
GST_DEBUG ("scaling to %dx%d", widget->priv->display_width,
|
||||
widget->priv->display_height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gst_widget_set_caps (GtkGstWidget * widget, GstCaps * caps)
|
||||
{
|
||||
|
@ -306,6 +393,11 @@ gtk_gst_widget_set_caps (GtkGstWidget * widget, GstCaps * caps)
|
|||
|
||||
g_mutex_lock (&widget->priv->lock);
|
||||
|
||||
if (!_calculate_par (widget, &v_info)) {
|
||||
g_mutex_unlock (&widget->priv->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_caps_replace (&widget->priv->caps, caps);
|
||||
widget->priv->v_info = v_info;
|
||||
widget->priv->negotiated = TRUE;
|
||||
|
|
Loading…
Reference in a new issue