gstreamer v4l support to emotion
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 22 Feb 2009 17:16:47 +0000 (17:16 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 22 Feb 2009 17:16:47 +0000 (17:16 +0000)
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

By: Lars Munch <lars@segv.dk>

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/emotion@39147 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/gstreamer/Makefile.am
src/modules/gstreamer/emotion_gstreamer.c
src/modules/gstreamer/emotion_gstreamer_pipeline.h
src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c [new file with mode: 0644]

index f3519af..6aee2e3 100644 (file)
@@ -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
index b76eb25..1516bd3 100644 (file)
@@ -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
      {
index 2e8a703..3a8b849 100644 (file)
@@ -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 (file)
index 0000000..c978773
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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;
+
+   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;
+
+   if (sscanf(device, "v4l://%d", &devno) != 1)
+     devno = 0;
+
+   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;
+}