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