Add gst_vaapi_display_get_pixel_aspect_ratio().
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 22 Mar 2010 09:32:01 +0000 (09:32 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 22 Mar 2010 09:32:01 +0000 (09:32 +0000)
docs/reference/libs/libs-sections.txt
gst-libs/gst/vaapi/gstvaapidisplay.c
gst-libs/gst/vaapi/gstvaapidisplay.h
gst-libs/gst/vaapi/gstvaapidisplay_x11.c
tests/test-display.c

index 0907fbd..f0832fa 100644 (file)
@@ -98,6 +98,7 @@ gst_vaapi_display_get_display
 gst_vaapi_display_get_width
 gst_vaapi_display_get_height
 gst_vaapi_display_get_size
+gst_vaapi_display_get_pixel_aspect_ratio
 gst_vaapi_display_has_profile
 gst_vaapi_display_get_image_caps
 gst_vaapi_display_has_image_format
index fde9043..e084baf 100644 (file)
@@ -45,6 +45,10 @@ struct _GstVaapiDisplayPrivate {
     VADisplay           display;
     guint               width;
     guint               height;
+    guint               width_mm;
+    guint               height_mm;
+    guint               par_n;
+    guint               par_d;
     gboolean            create_display;
     GArray             *profiles;
     GArray             *image_formats;
@@ -186,6 +190,51 @@ get_caps(GArray *formats)
 }
 
 static void
+gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display)
+{
+    GstVaapiDisplayPrivate * const priv = display->priv;
+    gdouble ratio, delta;
+    gint i, index;
+
+    static const gint par[][2] = {
+        {1, 1},         /* regular screen            */
+        {16, 15},       /* PAL TV                    */
+        {11, 10},       /* 525 line Rec.601 video    */
+        {54, 59},       /* 625 line Rec.601 video    */
+        {64, 45},       /* 1280x1024 on 16:9 display */
+        {5, 3},         /* 1280x1024 on  4:3 display */
+        {4, 3}          /*  800x600  on 16:9 display */
+    };
+
+    /* First, calculate the "real" ratio based on the X values;
+     * which is the "physical" w/h divided by the w/h in pixels of the
+     * display */
+    if (!priv->width || !priv->height || !priv->width_mm || !priv->height_mm)
+        ratio = 1.0;
+    else
+        ratio = (gdouble)(priv->width_mm * priv->height) /
+            (priv->height_mm * priv->width);
+    GST_DEBUG("calculated pixel aspect ratio: %f", ratio);
+
+    /* Now, find the one from par[][2] with the lowest delta to the real one */
+#define DELTA(idx) (ABS(ratio - ((gdouble)par[idx][0] / par[idx][1])))
+    delta = DELTA(0);
+    index = 0;
+
+    for (i = 1; i < G_N_ELEMENTS(par); i++) {
+        const gdouble this_delta = DELTA(i);
+        if (this_delta < delta) {
+            index = i;
+            delta = this_delta;
+        }
+    }
+#undef DELTA
+
+    priv->par_n = par[index][0];
+    priv->par_d = par[index][1];
+}
+
+static void
 gst_vaapi_display_destroy(GstVaapiDisplay *display)
 {
     GstVaapiDisplayPrivate * const priv = display->priv;
@@ -236,6 +285,9 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
             priv->display = klass->get_display(display);
         if (klass->get_size)
             klass->get_size(display, &priv->width, &priv->height);
+        if (klass->get_size_mm)
+            klass->get_size_mm(display, &priv->width_mm, &priv->height_mm);
+        gst_vaapi_display_calculate_pixel_aspect_ratio(display);
     }
     if (!priv->display)
         return FALSE;
@@ -446,6 +498,10 @@ gst_vaapi_display_init(GstVaapiDisplay *display)
     priv->display               = NULL;
     priv->width                 = 0;
     priv->height                = 0;
+    priv->width_mm              = 0;
+    priv->height_mm             = 0;
+    priv->par_n                 = 1;
+    priv->par_d                 = 1;
     priv->create_display        = TRUE;
     priv->profiles              = NULL;
     priv->image_formats         = NULL;
@@ -580,6 +636,30 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig
 }
 
 /**
+ * gst_vaapi_display_get_pixel_aspect_ratio:
+ * @display: a #GstVaapiDisplay
+ * @par_n: (out) (allow-none): return location for the numerator of pixel aspect ratio, or %NULL
+ * @par_d: (out) (allow-none): return location for the denominator of pixel aspect ratio, or %NULL
+ *
+ * Retrieves the pixel aspect ratio of a #GstVaapiDisplay.
+ */
+void
+gst_vaapi_display_get_pixel_aspect_ratio(
+    GstVaapiDisplay *display,
+    guint           *par_n,
+    guint           *par_d
+)
+{
+    g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
+
+    if (par_n)
+        *par_n = display->priv->par_n;
+
+    if (par_d)
+        *par_d = display->priv->par_d;
+}
+
+/**
  * gst_vaapi_display_has_profile:
  * @display: a #GstVaapiDisplay
  * @profile: a #VAProfile
index e1f9f86..8b41d3c 100644 (file)
@@ -101,7 +101,8 @@ struct _GstVaapiDisplay {
  * @lock_display: virtual function to lock a display
  * @unlock_display: virtual function to unlock a display
  * @get_display: virtual function to retrieve the #VADisplay
- * @get_size: virtual function to retrieve the display dimensions
+ * @get_size: virtual function to retrieve the display dimensions, in pixels
+ * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters
  *
  * Base class for VA displays.
  */
@@ -115,7 +116,10 @@ struct _GstVaapiDisplayClass {
     void       (*lock_display)  (GstVaapiDisplay *display);
     void       (*unlock_display)(GstVaapiDisplay *display);
     VADisplay  (*get_display)   (GstVaapiDisplay *display);
-    void       (*get_size)      (GstVaapiDisplay *display, guint *pw, guint *ph);
+    void       (*get_size)      (GstVaapiDisplay *display,
+                                 guint *pwidth, guint *pheight);
+    void       (*get_size_mm)   (GstVaapiDisplay *display,
+                                 guint *pwidth, guint *pheight);
 };
 
 GType
@@ -142,6 +146,13 @@ gst_vaapi_display_get_height(GstVaapiDisplay *display);
 void
 gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheight);
 
+void
+gst_vaapi_display_get_pixel_aspect_ratio(
+    GstVaapiDisplay *display,
+    guint           *par_n,
+    guint           *par_d
+);
+
 gboolean
 gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile);
 
index 133c808..5553f88 100644 (file)
@@ -186,7 +186,8 @@ gst_vaapi_display_x11_get_size(
     guint           *pheight
 )
 {
-    GstVaapiDisplayX11Private * const priv = GST_VAAPI_DISPLAY_X11(display)->priv;
+    GstVaapiDisplayX11Private * const priv =
+        GST_VAAPI_DISPLAY_X11(display)->priv;
 
     if (!priv->x11_display)
         return;
@@ -199,6 +200,26 @@ gst_vaapi_display_x11_get_size(
 }
 
 static void
+gst_vaapi_display_x11_get_size_mm(
+    GstVaapiDisplay *display,
+    guint           *pwidth,
+    guint           *pheight
+)
+{
+    GstVaapiDisplayX11Private * const priv =
+        GST_VAAPI_DISPLAY_X11(display)->priv;
+
+    if (!priv->x11_display)
+        return;
+
+    if (pwidth)
+        *pwidth = DisplayWidthMM(priv->x11_display, priv->x11_screen);
+
+    if (pheight)
+        *pheight = DisplayHeightMM(priv->x11_display, priv->x11_screen);
+}
+
+static void
 gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass)
 {
     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
@@ -215,6 +236,7 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass)
     dpy_class->close_display    = gst_vaapi_display_x11_close_display;
     dpy_class->get_display      = gst_vaapi_display_x11_get_va_display;
     dpy_class->get_size         = gst_vaapi_display_x11_get_size;
+    dpy_class->get_size_mm      = gst_vaapi_display_x11_get_size_mm;
 
     /**
      * GstVaapiDisplayX11:x11-display:
index 388abbf..f401de6 100644 (file)
@@ -94,7 +94,7 @@ main(int argc, char *argv[])
     Display *x11_display;
     VADisplay va_display;
     GstVaapiDisplay *display;
-    guint width, height;
+    guint width, height, par_n, par_d;
 
     gst_init(&argc, &argv);
 
@@ -109,6 +109,9 @@ main(int argc, char *argv[])
         gst_vaapi_display_get_size(display, &width, &height);
         g_print("Display size: %ux%u\n", width, height);
 
+        gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
+        g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
+
         dump_caps(display);
         g_object_unref(display);
     }