From 8477bdb496b505f9c72a29b7506114593447c9fd Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Sun, 22 Feb 2009 17:16:47 +0000 Subject: [PATCH] gstreamer v4l support to emotion 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 SVN revision: 39147 --- .../emotion/src/modules/gstreamer/Makefile.am | 5 +- .../src/modules/gstreamer/emotion_gstreamer.c | 11 +++ .../gstreamer/emotion_gstreamer_pipeline.h | 1 + .../emotion_gstreamer_pipeline_v4l.c | 87 +++++++++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c diff --git a/legacy/emotion/src/modules/gstreamer/Makefile.am b/legacy/emotion/src/modules/gstreamer/Makefile.am index f3519afcaa..6aee2e3fb3 100644 --- a/legacy/emotion/src/modules/gstreamer/Makefile.am +++ b/legacy/emotion/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/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c index b76eb25bab..1516bd357f 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c +++ b/legacy/emotion/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 { diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h index 2e8a703294..3a8b849523 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h +++ b/legacy/emotion/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/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c new file mode 100644 index 0000000000..c978773561 --- /dev/null +++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline_v4l.c @@ -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; +}