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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel