docs/plugins/: Updates.
authorJulien Moutte <julien@moutte.net>
Sun, 18 Dec 2005 10:58:44 +0000 (10:58 +0000)
committerJulien Moutte <julien@moutte.net>
Sun, 18 Dec 2005 10:58:44 +0000 (10:58 +0000)
Original commit message from CVS:
2005-12-18  Julien MOUTTE  <julien@moutte.net>

* docs/plugins/gst-plugins-bad-plugins-decl.txt:
* docs/plugins/gst-plugins-bad-plugins-undocumented.txt:
Updates.
* ext/directfb/dfbvideosink.c:
(gst_dfbvideosink_surface_create),
(gst_dfbvideosink_event_thread),
(gst_dfbvideosink_enum_devices),
(gst_dfbvideosink_setup), (gst_dfbvideosink_cleanup),
(gst_dfbvideosink_can_blit_from_format),
(gst_dfbvideosink_getcaps), (gst_dfbvideosink_setcaps),
(gst_dfbvideosink_show_frame), (gst_dfbvideosink_buffer_alloc),
(gst_dfbsurface_finalize),
(gst_dfbvideosink_navigation_send_event),
(gst_dfbvideosink_update_colorbalance),
(gst_dfbvideosink_set_property),
(gst_dfbvideosink_get_property),
(gst_dfbvideosink_finalize), (gst_dfbvideosink_init),
(gst_dfbvideosink_class_init):
* ext/directfb/dfbvideosink.h: Implement pixel-aspect-ratio.
This should work both for hardware accelerated scaling and
reverse caps negotiation with a scaling element.

ChangeLog
docs/plugins/gst-plugins-bad-plugins-decl.txt
docs/plugins/gst-plugins-bad-plugins-undocumented.txt
ext/directfb/dfbvideosink.c
ext/directfb/dfbvideosink.h

index 0e37d2c..8813e4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2005-12-18  Julien MOUTTE  <julien@moutte.net>
+
+       * docs/plugins/gst-plugins-bad-plugins-decl.txt:
+       * docs/plugins/gst-plugins-bad-plugins-undocumented.txt: Updates.
+       * ext/directfb/dfbvideosink.c: (gst_dfbvideosink_surface_create),
+       (gst_dfbvideosink_event_thread), (gst_dfbvideosink_enum_devices),
+       (gst_dfbvideosink_setup), (gst_dfbvideosink_cleanup),
+       (gst_dfbvideosink_can_blit_from_format),
+       (gst_dfbvideosink_getcaps), (gst_dfbvideosink_setcaps),
+       (gst_dfbvideosink_show_frame), (gst_dfbvideosink_buffer_alloc),
+       (gst_dfbsurface_finalize),
+       (gst_dfbvideosink_navigation_send_event),
+       (gst_dfbvideosink_update_colorbalance),
+       (gst_dfbvideosink_set_property), (gst_dfbvideosink_get_property),
+       (gst_dfbvideosink_finalize), (gst_dfbvideosink_init),
+       (gst_dfbvideosink_class_init):
+       * ext/directfb/dfbvideosink.h: Implement pixel-aspect-ratio.
+       This should work both for hardware accelerated scaling and
+       reverse caps negotiation with a scaling element.
+
 2005-12-17  Julien MOUTTE  <julien@moutte.net>
 
        * docs/plugins/gst-plugins-bad-plugins-decl.txt:
index 0d26d3d..dcd20c0 100644 (file)
@@ -112,6 +112,9 @@ struct _GstDfbVideoSink {
   gint hue;
   gint saturation;
   gboolean cb_changed;
+  
+  /* object-set pixel aspect ratio */
+  GValue *par;
 };
 </STRUCT>
 <STRUCT>
index 3c6b8cf..69f30a7 100644 (file)
@@ -1,5 +1,5 @@
 100% symbol docs coverage.
-4 symbols documented.
+9 symbols documented.
 0 symbols incomplete.
 0 not documented.
 
index 1beb442..b425de6 100644 (file)
@@ -131,6 +131,7 @@ enum
   ARG_BRIGHTNESS,
   ARG_HUE,
   ARG_SATURATION,
+  ARG_PIXEL_ASPECT_RATIO,
   ARG_VSYNC
 };
 
@@ -1173,6 +1174,15 @@ gst_dfbvideosink_getcaps (GstBaseSink * bsink)
         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
         "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+
+    if (!dfbvideosink->hw_scaling && dfbvideosink->par) {
+      int nom, den;
+
+      nom = gst_value_get_fraction_numerator (dfbvideosink->par);
+      den = gst_value_get_fraction_denominator (dfbvideosink->par);
+      gst_structure_set (structure, "pixel-aspect-ratio",
+          GST_TYPE_FRACTION, nom, den, NULL);
+    }
   }
 
   GST_DEBUG_OBJECT (dfbvideosink, "returning our caps %" GST_PTR_FORMAT, caps);
@@ -1207,11 +1217,90 @@ gst_dfbvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 
   pixel_format = gst_dfbvideosink_get_format_from_caps (caps);
 
-  GST_DEBUG_OBJECT (dfbvideosink, "setcaps called, %dx%d %s video at %d/%d fps",
+  GST_DEBUG_OBJECT (dfbvideosink, "setcaps called with %" GST_PTR_FORMAT, caps);
+  GST_DEBUG_OBJECT (dfbvideosink, "our format is: %dx%d %s video at %d/%d fps",
       video_width, video_height,
       gst_dfbvideosink_get_format_name (pixel_format), dfbvideosink->fps_n,
       dfbvideosink->fps_d);
 
+  if (dfbvideosink->hw_scaling && dfbvideosink->par) {
+    gint video_par_n, video_par_d;      /* video's PAR */
+    gint display_par_n, display_par_d;  /* display's PAR */
+    gint num, den;
+    GValue display_ratio = { 0, };      /* display w/h ratio */
+    const GValue *caps_par;
+
+    /* get aspect ratio from caps if it's present, and
+     * convert video width and height to a display width and height
+     * using wd / hd = wv / hv * PARv / PARd
+     * the ratio wd / hd will be stored in display_ratio */
+    g_value_init (&display_ratio, GST_TYPE_FRACTION);
+
+    /* get video's PAR */
+    caps_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+    if (caps_par) {
+      video_par_n = gst_value_get_fraction_numerator (caps_par);
+      video_par_d = gst_value_get_fraction_denominator (caps_par);
+    } else {
+      video_par_n = 1;
+      video_par_d = 1;
+    }
+    /* get display's PAR */
+    if (dfbvideosink->par) {
+      display_par_n = gst_value_get_fraction_numerator (dfbvideosink->par);
+      display_par_d = gst_value_get_fraction_denominator (dfbvideosink->par);
+    } else {
+      display_par_n = 1;
+      display_par_d = 1;
+    }
+
+    gst_value_set_fraction (&display_ratio,
+        video_width * video_par_n * display_par_d,
+        video_height * video_par_d * display_par_n);
+
+    num = gst_value_get_fraction_numerator (&display_ratio);
+    den = gst_value_get_fraction_denominator (&display_ratio);
+    GST_DEBUG_OBJECT (dfbvideosink,
+        "video width/height: %dx%d, calculated display ratio: %d/%d",
+        video_width, video_height, num, den);
+
+    /* now find a width x height that respects this display ratio.
+     * prefer those that have one of w/h the same as the incoming video
+     * using wd / hd = num / den */
+
+    /* start with same height, because of interlaced video */
+    /* check hd / den is an integer scale factor, and scale wd with the PAR */
+    if (video_height % den == 0) {
+      GST_DEBUG_OBJECT (dfbvideosink, "keeping video height");
+      GST_VIDEO_SINK_WIDTH (dfbvideosink) = video_height * num / den;
+      GST_VIDEO_SINK_HEIGHT (dfbvideosink) = video_height;
+    } else if (video_width % num == 0) {
+      GST_DEBUG_OBJECT (dfbvideosink, "keeping video width");
+      GST_VIDEO_SINK_WIDTH (dfbvideosink) = video_width;
+      GST_VIDEO_SINK_HEIGHT (dfbvideosink) = video_width * den / num;
+    } else {
+      GST_DEBUG_OBJECT (dfbvideosink, "approximating while keeping height");
+      GST_VIDEO_SINK_WIDTH (dfbvideosink) = video_height * num / den;
+      GST_VIDEO_SINK_HEIGHT (dfbvideosink) = video_height;
+    }
+    GST_DEBUG_OBJECT (dfbvideosink, "scaling to %dx%d",
+        GST_VIDEO_SINK_WIDTH (dfbvideosink),
+        GST_VIDEO_SINK_HEIGHT (dfbvideosink));
+  } else {
+    if (dfbvideosink->par) {
+      const GValue *par;
+
+      par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+      if (par) {
+        if (gst_value_compare (par, dfbvideosink->par) != GST_VALUE_EQUAL) {
+          goto wrong_aspect;
+        }
+      }
+    }
+    GST_VIDEO_SINK_WIDTH (dfbvideosink) = video_width;
+    GST_VIDEO_SINK_HEIGHT (dfbvideosink) = video_height;
+  }
+
   /* Try to adapt the video mode to the video geometry */
   if (dfbvideosink->dfb) {
     DFBResult ret;
@@ -1221,8 +1310,9 @@ gst_dfbvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
         "geometry");
 
     /* Set video mode and layer configuration appropriately */
-    if (gst_dfbvideosink_get_best_vmode (dfbvideosink, video_width,
-            video_height, &vmode)) {
+    if (gst_dfbvideosink_get_best_vmode (dfbvideosink,
+            GST_VIDEO_SINK_WIDTH (dfbvideosink),
+            GST_VIDEO_SINK_HEIGHT (dfbvideosink), &vmode)) {
       DFBDisplayLayerConfig lc;
       gint width, height, bpp;
 
@@ -1240,22 +1330,21 @@ gst_dfbvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
             "at %d bpp", width, height, bpp);
       }
 
-      lc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
-      lc.width = width;
-      lc.height = height;
+      lc.flags = DLCONF_PIXELFORMAT;
       lc.pixelformat = pixel_format;
 
       ret = dfbvideosink->layer->SetConfiguration (dfbvideosink->layer, &lc);
       if (ret != DFB_OK) {
-        GST_WARNING_OBJECT (dfbvideosink, "failed setting layer "
-            "configuration to  %dx%d", width, height);
+        GST_WARNING_OBJECT (dfbvideosink, "failed setting layer pixelformat "
+            "to %s", gst_dfbvideosink_get_format_name (pixel_format));
       } else {
-        dfbvideosink->out_width = width;
-        dfbvideosink->out_height = height;
-        dfbvideosink->pixel_format = pixel_format;
+        dfbvideosink->layer->GetConfiguration (dfbvideosink->layer, &lc);
+        dfbvideosink->out_width = lc.width;
+        dfbvideosink->out_height = lc.height;
+        dfbvideosink->pixel_format = lc.pixelformat;
         GST_DEBUG_OBJECT (dfbvideosink, "layer %d now configured to %dx%d %s",
-            dfbvideosink->layer_id, width, height,
-            gst_dfbvideosink_get_format_name (pixel_format));
+            dfbvideosink->layer_id, lc.width, lc.height,
+            gst_dfbvideosink_get_format_name (lc.pixelformat));
       }
     }
   }
@@ -1273,6 +1362,13 @@ gst_dfbvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 
 beach:
   return result;
+
+/* ERRORS */
+wrong_aspect:
+  {
+    GST_INFO_OBJECT (dfbvideosink, "pixel aspect ratio does not match");
+    return FALSE;
+  }
 }
 
 static GstStateChangeReturn
@@ -1373,22 +1469,13 @@ gst_dfbvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
     goto beach;
   }
 
-  if (GST_IS_DFBSURFACE (buf)) {
-    GstDfbSurface *surface = GST_DFBSURFACE (buf);
-
-    src.w = surface->width;
-    src.h = surface->height;
-  } else {
-    src.w = dfbvideosink->video_width;
-    src.h = dfbvideosink->video_height;
-  }
-
   /* If we are rendering from a buffer we did not allocate or to an external
    * surface, we will memcpy data */
   if (!GST_IS_DFBSURFACE (buf) || dfbvideosink->ext_surface) {
     IDirectFBSurface *dest = NULL, *surface = NULL;
     gpointer data;
     gint dest_pitch, src_pitch, line;
+    GstStructure *structure;
 
     /* As we are not blitting no acceleration is possible. If the surface is
      * too small we do clipping, if it's too big we center. Theoretically as 
@@ -1405,6 +1492,14 @@ gst_dfbvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
           "(vsync %d)", dfbvideosink->vsync);
     }
 
+    structure = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0);
+    if (structure) {
+      gst_structure_get_int (structure, "width", &src.w);
+      gst_structure_get_int (structure, "height", &src.h);
+    } else {
+      src.w = dfbvideosink->video_width;
+      src.h = dfbvideosink->video_height;
+    }
     res = surface->GetSize (surface, &dst.w, &dst.h);
 
     /* Center / Clip */
@@ -1459,6 +1554,9 @@ gst_dfbvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
     GST_DEBUG_OBJECT (dfbvideosink, "blitting to a primary surface (vsync %d)",
         dfbvideosink->vsync);
 
+    src.w = GST_VIDEO_SINK_WIDTH (dfbvideosink);
+    src.h = GST_VIDEO_SINK_HEIGHT (dfbvideosink);
+
     dfbvideosink->primary->GetSize (dfbvideosink->primary, &dst.w, &dst.h);
 
     /* Unlocking surface before blit */
@@ -1587,6 +1685,16 @@ gst_dfbvideosink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
       gst_structure_set (structure, "width", G_TYPE_INT, result.w, NULL);
       gst_structure_set (structure, "height", G_TYPE_INT, result.h, NULL);
 
+      /* PAR property overrides the X calculated one */
+      if (dfbvideosink->par) {
+        gint nom, den;
+
+        nom = gst_value_get_fraction_numerator (dfbvideosink->par);
+        den = gst_value_get_fraction_denominator (dfbvideosink->par);
+        gst_structure_set (structure, "pixel-aspect-ratio",
+            GST_TYPE_FRACTION, nom, den, NULL);
+      }
+
       if (gst_pad_accept_caps (peer, desired_caps)) {
         gint bpp;
 
@@ -1767,8 +1875,8 @@ gst_dfbvideosink_navigation_send_event (GstNavigation * navigation,
   double x, y;
   GstPad *pad = NULL;
 
-  src.w = dfbvideosink->video_width;
-  src.h = dfbvideosink->video_height;
+  src.w = GST_VIDEO_SINK_WIDTH (dfbvideosink);
+  src.h = GST_VIDEO_SINK_HEIGHT (dfbvideosink);
   dst.w = dfbvideosink->out_width;
   dst.h = dfbvideosink->out_height;
   gst_video_sink_center_rect (src, dst, &result, dfbvideosink->hw_scaling);
@@ -1966,6 +2074,19 @@ gst_dfbvideosink_set_property (GObject * object, guint prop_id,
       dfbvideosink->cb_changed = TRUE;
       gst_dfbvideosink_update_colorbalance (dfbvideosink);
       break;
+    case ARG_PIXEL_ASPECT_RATIO:
+      g_free (dfbvideosink->par);
+      dfbvideosink->par = g_new0 (GValue, 1);
+      g_value_init (dfbvideosink->par, GST_TYPE_FRACTION);
+      if (!g_value_transform (value, dfbvideosink->par)) {
+        GST_WARNING_OBJECT (dfbvideosink, "Could not transform string to "
+            "aspect ratio");
+        gst_value_set_fraction (dfbvideosink->par, 1, 1);
+      }
+      GST_DEBUG_OBJECT (dfbvideosink, "set PAR to %d/%d",
+          gst_value_get_fraction_numerator (dfbvideosink->par),
+          gst_value_get_fraction_denominator (dfbvideosink->par));
+      break;
     case ARG_VSYNC:
       dfbvideosink->vsync = g_value_get_boolean (value);
       break;
@@ -1997,6 +2118,10 @@ gst_dfbvideosink_get_property (GObject * object, guint prop_id,
     case ARG_SATURATION:
       g_value_set_int (value, dfbvideosink->saturation);
       break;
+    case ARG_PIXEL_ASPECT_RATIO:
+      if (dfbvideosink->par)
+        g_value_transform (dfbvideosink->par, value);
+      break;
     case ARG_VSYNC:
       g_value_set_boolean (value, dfbvideosink->vsync);
       break;
@@ -2018,6 +2143,10 @@ gst_dfbvideosink_finalize (GObject * object)
 
   dfbvideosink = GST_DFBVIDEOSINK (object);
 
+  if (dfbvideosink->par) {
+    g_free (dfbvideosink->par);
+    dfbvideosink->par = NULL;
+  }
   if (dfbvideosink->pool_lock) {
     g_mutex_free (dfbvideosink->pool_lock);
     dfbvideosink->pool_lock = NULL;
@@ -2060,6 +2189,8 @@ gst_dfbvideosink_init (GstDfbVideoSink * dfbvideosink)
   dfbvideosink->contrast = -1;
   dfbvideosink->hue = -1;
   dfbvideosink->saturation = -1;
+
+  dfbvideosink->par = NULL;
 }
 
 static void
@@ -2107,6 +2238,9 @@ gst_dfbvideosink_class_init (GstDfbVideoSinkClass * klass)
       g_param_spec_int ("saturation", "Saturation",
           "The saturation of the video", 0x0000, 0xFFFF, 0x8000,
           G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, ARG_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_object_class_install_property (gobject_class, ARG_VSYNC,
       g_param_spec_boolean ("vsync", "Vertical synchronisation",
           "Wait for next vertical sync to draw frames", TRUE,
index f62d659..9bdfbf4 100644 (file)
@@ -113,6 +113,9 @@ struct _GstDfbVideoSink {
   gint hue;
   gint saturation;
   gboolean cb_changed;
+  
+  /* object-set pixel aspect ratio */
+  GValue *par;
 };
 
 struct _GstDfbVideoSinkClass {