summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/directfb/Makefile.am4
-rw-r--r--ext/directfb/dfb-example.c78
-rw-r--r--ext/directfb/dfbvideosink.c68
3 files changed, 148 insertions, 2 deletions
diff --git a/ext/directfb/Makefile.am b/ext/directfb/Makefile.am
index eb90c28b..7a6a65c6 100644
--- a/ext/directfb/Makefile.am
+++ b/ext/directfb/Makefile.am
@@ -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
index 00000000..3f455c92
--- /dev/null
+++ b/ext/directfb/dfb-example.c
@@ -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;
+}
diff --git a/ext/directfb/dfbvideosink.c b/ext/directfb/dfbvideosink.c
index 47b2cd2f..84dd0407 100644
--- a/ext/directfb/dfbvideosink.c
+++ b/ext/directfb/dfbvideosink.c
@@ -17,6 +17,66 @@
* 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);