This patch adds gstreamer v4l support to emotion. If you got a webcam it can
be tested by doing:

emotion_test -gstreamer v4l://

This will use the first video device /dev/video0.

If you do not have a webcam, you can also try it using the Virtual Video driver
(modprobe vivi). If you got more that one video device you can also use

emotion_test -gstreamer v4l://0 v4l://1

to play from both /dev/video0 and /dev/video1.

Regards
Lars Munch

---
 src/modules/gstreamer/Makefile.am                  |    5 +-
 src/modules/gstreamer/emotion_gstreamer.c          |   13 +++-
 src/modules/gstreamer/emotion_gstreamer_pipeline.c |    6 +-
 src/modules/gstreamer/emotion_gstreamer_pipeline.h |    1 +
 .../gstreamer/emotion_gstreamer_pipeline_v4l.c     |   85 ++++++++++++++++++++
 5 files changed, 103 insertions(+), 7 deletions(-)
 create mode 100644 src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c

diff --git a/src/modules/gstreamer/Makefile.am 
b/src/modules/gstreamer/Makefile.am
index f3519af..6aee2e3 100644
--- a/src/modules/gstreamer/Makefile.am
+++ b/src/modules/gstreamer/Makefile.am
@@ -24,10 +24,11 @@ emotion_gstreamer_pipeline.h \
 emotion_gstreamer_pipeline_cdda.c \
 emotion_gstreamer_pipeline_dvd.c \
 emotion_gstreamer_pipeline_file.c \
-emotion_gstreamer_pipeline_uri.c
+emotion_gstreamer_pipeline_uri.c \
+emotion_gstreamer_pipeline_v4l.c
 gstreamer_la_LIBADD  = @EVAS_LIBS@ @ECORE_LIBS@ @GST_LIBS@ 
$(top_builddir)/src/lib/libemotion.la
 gstreamer_la_LDFLAGS = -module -avoid-version
 gstreamer_la_LIBTOOLFLAGS = --tag=disable-static
 gstreamer_la_DEPENDENCIES = $(top_builddir)/config.h
 
-endif
\ No newline at end of file
+endif
diff --git a/src/modules/gstreamer/emotion_gstreamer.c 
b/src/modules/gstreamer/emotion_gstreamer.c
index d528dea..1516bd3 100644
--- a/src/modules/gstreamer/emotion_gstreamer.c
+++ b/src/modules/gstreamer/emotion_gstreamer.c
@@ -390,6 +390,17 @@ em_file_open(const char   *file,
             return 0;
          }
      }
+   /* v4l */
+   else if (strstr(file, "v4l://"))
+     {
+       fprintf(stderr, "[Emotion] [gst] build V4L pipeline\n");
+       if (!(emotion_pipeline_v4l_build(ev, file)))
+         {
+            fprintf(stderr, "[Emotion] [gst] error while building V4L 
pipeline\n");
+            gst_object_unref(ev->pipeline);
+            return 0;
+         }
+     }
    /* Normal media file */
    else
      {
@@ -605,8 +616,6 @@ em_len_get(void *video)
    return val / 1000000000.0;
 
  fallback:
-   fputs("Gstreamer reported no length, try existing sinks...\n", stderr);
-
    ecore_list_first_goto(ev->audio_sinks);
    while ((asink = ecore_list_next(ev->audio_sinks)) != NULL)
      if (asink->length_time >= 0)
diff --git a/src/modules/gstreamer/emotion_gstreamer_pipeline.c 
b/src/modules/gstreamer/emotion_gstreamer_pipeline.c
index cf1e28b..5fcd742 100644
--- a/src/modules/gstreamer/emotion_gstreamer_pipeline.c
+++ b/src/modules/gstreamer/emotion_gstreamer_pipeline.c
@@ -93,7 +93,7 @@ file_new_decoded_pad_cb(GstElement *decodebin,
        GstElement         *queue;
        GstPad             *videopad;
 
-       vsink = (Emotion_Video_Sink *)malloc(sizeof(Emotion_Video_Sink));
+       vsink = (Emotion_Video_Sink *)calloc(1, sizeof(Emotion_Video_Sink));
        if (!vsink) return;
        if (!ecore_list_append(ev->video_sinks, vsink))
          {
@@ -121,7 +121,7 @@ file_new_decoded_pad_cb(GstElement *decodebin,
        Emotion_Audio_Sink *asink;
        GstPad             *audiopad;
 
-       asink = (Emotion_Audio_Sink *)malloc(sizeof(Emotion_Audio_Sink));
+       asink = (Emotion_Audio_Sink *)calloc(1, sizeof(Emotion_Audio_Sink));
        if (!asink) return;
        if (!ecore_list_append(ev->audio_sinks, asink))
          {
@@ -146,7 +146,7 @@ emotion_video_sink_new(Emotion_Gstreamer_Video *ev)
 
    if (!ev) return NULL;
 
-   vsink = (Emotion_Video_Sink *)malloc(sizeof(Emotion_Video_Sink));
+   vsink = (Emotion_Video_Sink *)calloc(1, sizeof(Emotion_Video_Sink));
    if (!vsink) return NULL;
 
    if (!ecore_list_append(ev->video_sinks, vsink))
diff --git a/src/modules/gstreamer/emotion_gstreamer_pipeline.h 
b/src/modules/gstreamer/emotion_gstreamer_pipeline.h
index 2e8a703..3a8b849 100644
--- a/src/modules/gstreamer/emotion_gstreamer_pipeline.h
+++ b/src/modules/gstreamer/emotion_gstreamer_pipeline.h
@@ -14,6 +14,7 @@ int emotion_pipeline_cdda_build           (void *video, const 
char * device, uns
 int emotion_pipeline_file_build           (void *video, const char *file);
 int emotion_pipeline_uri_build            (void *video, const char *uri);
 int emotion_pipeline_dvd_build            (void *video, const char *device);
+int emotion_pipeline_v4l_build            (void *video, const char *device);
 int emotion_pipeline_cdda_track_count_get (void *video);
 
 GstElement         *emotion_audio_sink_create         (Emotion_Gstreamer_Video 
*ev, int index);
diff --git a/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c 
b/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c
new file mode 100644
index 0000000..bb6f45b
--- /dev/null
+++ b/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c
@@ -0,0 +1,85 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "emotion_gstreamer.h"
+#include "emotion_gstreamer_pipeline.h"
+
+int
+emotion_pipeline_v4l_build(void *video, const char *device)
+{
+   GstElement *v4l2src, *cspace, *queue, *sink;
+   Emotion_Video_Sink *vsink;
+   GstCaps *caps;
+   Emotion_Gstreamer_Video *ev;
+   char dev[128];
+   int devno = 0;
+
+   ev = (Emotion_Gstreamer_Video *)video;
+   if (!ev) return 0;
+
+   v4l2src = gst_element_factory_make("v4l2src", "v4l2src");
+   cspace = gst_element_factory_make("ffmpegcolorspace", "cspace");
+   queue = gst_element_factory_make("queue", "queue");
+   sink = gst_element_factory_make("fakesink", "sink");
+
+   if ((!v4l2src) || (!cspace) || (!queue) || (!sink))
+     goto failure;
+
+   sscanf(device, "v4l://%d", &devno);
+   snprintf(dev, sizeof(dev), "/dev/video%d", devno);
+   g_object_set (v4l2src, "device", dev, NULL);
+
+   gst_bin_add_many(GST_BIN(ev->pipeline), v4l2src, cspace, queue, sink, NULL);
+
+   caps = gst_caps_new_simple("video/x-raw-yuv",
+                              "width", G_TYPE_INT, 320,
+                              "height", G_TYPE_INT, 240,
+                              NULL);
+   if (!gst_element_link_filtered(v4l2src, cspace, caps))
+     {
+        gst_caps_unref(caps);
+        goto failure;
+     }
+   gst_caps_unref(caps);
+
+   caps = gst_caps_new_simple("video/x-raw-rgb",
+                              "bpp", G_TYPE_INT, 32,
+                              "width", G_TYPE_INT, 320,
+                              "height", G_TYPE_INT, 240,
+                              NULL);
+   if (!gst_element_link_filtered(cspace, queue, caps))
+     {
+       gst_caps_unref(caps);
+       goto failure;
+     }
+   gst_caps_unref(caps);
+
+   gst_element_link(queue, sink);
+
+   vsink = emotion_video_sink_new(ev);
+   if(!vsink) goto failure;
+   vsink->sink = sink;
+   vsink->width=320;
+   vsink->height=240;
+   vsink->fourcc = GST_MAKE_FOURCC ('A', 'R', 'G', 'B');
+
+   g_object_set(G_OBJECT(vsink->sink), "sync", FALSE, NULL);
+   g_object_set(G_OBJECT(vsink->sink), "signal-handoffs", TRUE, NULL);
+   g_signal_connect(G_OBJECT(vsink->sink),
+                   "handoff",
+                   G_CALLBACK(cb_handoff), ev);
+
+   return 1;
+
+failure:
+   if(v4l2src)
+     gst_object_unref(v4l2src);
+   if(cspace)
+     gst_object_unref(cspace);
+   if(queue)
+     gst_object_unref(queue);
+   if(sink)
+     gst_object_unref(sink);
+
+   return 0;
+}
-- 
1.5.6.5


------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to