ext/directfb/Makefile.am: Add the example application.
authorJulien Moutte <julien@moutte.net>
Sat, 5 Nov 2005 23:36:20 +0000 (23:36 +0000)
committerJulien Moutte <julien@moutte.net>
Sat, 5 Nov 2005 23:36:20 +0000 (23:36 +0000)
Original commit message from CVS:
2005-11-06  Julien MOUTTE  <julien@moutte.net>

* ext/directfb/Makefile.am: Add the example application.
* ext/directfb/dfb-example.c: (get_me_out), (main):
Here is an example application that runs videotestsrc for 20
seconds. It's included in the documentation.
* ext/directfb/dfbvideosink.c: (gst_dfbvideosink_enum_layers),
(gst_dfbvideosink_setup),
(gst_dfbvideosink_can_blit_from_format),
(gst_dfbvideosink_getcaps), (gst_dfbvideosink_buffer_alloc):
More fixes, calculate new size of the buffer when renegotiating.
This completely breaks ffmpegcolorspace but i need to discuss
that with Wim on monday. Add documentation.

ChangeLog
ext/directfb/Makefile.am
ext/directfb/dfb-example.c [new file with mode: 0644]
ext/directfb/dfbvideosink.c

index 1f57192..ba043a7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-11-06  Julien MOUTTE  <julien@moutte.net>
+
+       * ext/directfb/Makefile.am: Add the example application.
+       * ext/directfb/dfb-example.c: (get_me_out), (main):
+       Here is an example application that runs videotestsrc for 20
+       seconds. It's included in the documentation.
+       * ext/directfb/dfbvideosink.c: (gst_dfbvideosink_enum_layers),
+       (gst_dfbvideosink_setup), (gst_dfbvideosink_can_blit_from_format),
+       (gst_dfbvideosink_getcaps), (gst_dfbvideosink_buffer_alloc):
+       More fixes, calculate new size of the buffer when renegotiating.
+       This completely breaks ffmpegcolorspace but i need to discuss 
+       that with Wim on monday. Add documentation.
+
 2005-11-05  Julien MOUTTE  <julien@moutte.net>
 
        * ext/directfb/dfbvideosink.c: (gst_dfbvideosink_enum_layers),
index eb90c28..7a6a65c 100644 (file)
@@ -12,3 +12,7 @@ libgstdfbvideosink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
 libgstdfbvideosink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 noinst_HEADERS = dfbvideosink.h
+
+noinst_PROGRAMS = dfb-example
+dfb_example_CFLAGS = $(GST_CFLAGS) $(DIRECTFB_CFLAGS)
+dfb_example_LDADD = $(GST_LIBS) $(DIRECTFB_LIBS)
diff --git a/ext/directfb/dfb-example.c b/ext/directfb/dfb-example.c
new file mode 100644 (file)
index 0000000..3f455c9
--- /dev/null
@@ -0,0 +1,78 @@
+
+#include <directfb.h>
+#include <gst/gst.h>
+
+static IDirectFB *dfb = NULL;
+static IDirectFBSurface *primary = NULL;
+static GMainLoop *loop;
+
+#define DFBCHECK(x...)                                         \
+  {                                                            \
+    DFBResult err = x;                                         \
+                                                               \
+    if (err != DFB_OK)                                         \
+      {                                                        \
+        fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
+        DirectFBErrorFatal( #x, err );                         \
+      }                                                        \
+  }
+
+static gboolean
+get_me_out (gpointer data)
+{
+  g_main_loop_quit (loop);
+  return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+  DFBSurfaceDescription dsc;
+  GstElement *pipeline, *src, *sink;
+
+  /* Init both GStreamer and DirectFB */
+  DFBCHECK (DirectFBInit (&argc, &argv));
+  gst_init (&argc, &argv);
+
+  /* Creates DirectFB main context and set it to fullscreen layout */
+  DFBCHECK (DirectFBCreate (&dfb));
+  DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
+
+  /* We want a double buffered primary surface */
+  dsc.flags = DSDESC_CAPS;
+  dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
+
+  DFBCHECK (dfb->CreateSurface (dfb, &dsc, &primary));
+
+  /* Creating our pipeline : videotestsrc ! dfbvideosink */
+  pipeline = gst_pipeline_new (NULL);
+  g_assert (pipeline);
+  src = gst_element_factory_make ("videotestsrc", NULL);
+  g_assert (src);
+  sink = gst_element_factory_make ("dfbvideosink", NULL);
+  g_assert (sink);
+  /* That's the interesting part, giving the primary surface to dfbvideosink */
+  g_object_set (sink, "surface", primary, NULL);
+
+  /* Adding elements to the pipeline */
+  gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
+  g_assert (gst_element_link (src, sink));
+
+  /* Let's play ! */
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  /* we need to run a GLib main loop to get out of here */
+  loop = g_main_loop_new (NULL, FALSE);
+  /* Get us out after 20 seconds */
+  g_timeout_add (20000, get_me_out, NULL);
+  g_main_loop_run (loop);
+
+  /* Release elements and stop playback */
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+
+  /* Release DirectFB context and surface */
+  primary->Release (primary);
+  dfb->Release (dfb);
+
+  return 0;
+}
index 47b2cd2..84dd040 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+/**
+ * SECTION:element-dfbvideosink
+ *
+ * <refsect2>
+ * <para>
+ * DfbVideoSink renders video frames using the
+ * <ulink url="http://www.directfb.org/">DirectFB</ulink> library.
+ * Rendering can happen in two different modes :
+ * <itemizedlist>
+ * <listitem>
+ *   <para>
+ *   Standalone: this mode will take complete control of the monitor forcing
+ *   <ulink url="http://www.directfb.org/">DirectFB</ulink> to fullscreen layout.
+ *   This is convenient to test using the  gst-launch command line tool or
+ *   other simple applications. It is possible to interrupt playback while
+ *   being in this mode by pressing the Escape key.
+ *   </para>
+ *   <para>
+ *   This mode handles navigation events for every input device supported by
+ *   the <ulink url="http://www.directfb.org/">DirectFB</ulink> library, it will
+ *   look for available video modes in the fb.modes file and try to switch
+ *   the framebuffer video mode to the most suitable one. Depending on 
+ *   hardware acceleration capabilities the element will handle scaling or not.
+ *   If no acceleration is available it will do clipping or centering of the
+ *   video frames respecting the original aspect ratio.
+ *   </para>
+ * </listitem>
+ * <listitem>
+ *   <para>
+ *   Embedded: this mode will render video frames in a 
+ *   <link linkend="GstDfbVideoSink--surface">surface</link> provided by the
+ *   application developer. This is a more advanced usage of the element and
+ *   it is required to integrate video playback in existing 
+ *   <ulink url="http://www.directfb.org/">DirectFB</ulink> applications.
+ *   </para>
+ *   <para>
+ *   When using this mode the element just renders to the
+ *   <link linkend="GstDfbVideoSink--surface">surface</link> provided by the 
+ *   application, that means it won't handle navigation events and won't resize
+ *   the <link linkend="GstDfbVideoSink--surface">surface</link> to fit video
+ *   frames geometry. Application has to implement the necessary code to grab
+ *   informations about the negotiated geometry and resize there
+ *   <link linkend="GstDfbVideoSink--surface">surface</link> accordingly.
+ *   </para>
+ * </listitem>
+ * </itemizedlist>
+ * For both modes the element implements a buffer pool allocation system to 
+ * optimize memory allocation time and handle reverse negotiation. Indeed if 
+ * you insert an element like videoscale in the pipeline the video sink will
+ * negotiate with it to try get a scaled video for either the fullscreen layout
+ * or the application provided external
+ * <link linkend="GstDfbVideoSink--surface">surface</link>.
+ * </para>
+ * <title>Example application</title>
+ * <para>
+ * <include xmlns="http://www.w3.org/2003/XInclude" href="element-dfb-example.xml" />
+ * </para>
+ * </refsect2>
+ */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -1392,11 +1452,15 @@ gst_dfbvideosink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
       gst_structure_set (structure, "height", G_TYPE_INT, result.h, NULL);
 
       if (gst_pad_accept_caps (peer, desired_caps)) {
-        GST_DEBUG ("peed pad accepts our desired caps %" GST_PTR_FORMAT,
-            desired_caps);
+        gint bpp;
+
+        bpp = size / height / width;
         rev_nego = TRUE;
         width = result.w;
         height = result.h;
+        size = bpp * width * height;
+        GST_DEBUG ("peed pad accepts our desired caps %" GST_PTR_FORMAT
+            " buffer size is now %d bytes", desired_caps, size);
       } else {
         GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT,
             desired_caps);