add vlc backend
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 27 Sep 2008 21:07:53 +0000 (21:07 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 27 Sep 2008 21:07:53 +0000 (21:07 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/emotion@36280 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.in
src/modules/Makefile.am
src/modules/vlc/.cvsignore [new file with mode: 0644]
src/modules/vlc/Makefile.am [new file with mode: 0644]
src/modules/vlc/TODO [new file with mode: 0644]
src/modules/vlc/emotion_vlc.c [new file with mode: 0644]
src/modules/vlc/emotion_vlc.h [new file with mode: 0644]

index 93e88fd..6da5366 100644 (file)
@@ -38,6 +38,16 @@ CPPFLAGS="$CPPFLAGS $ECORE_CFLAGS"
 AC_CHECK_HEADERS(Ecore_X.h Ecore_Fb.h)
 CPPFLAGS=$save_CPPFLAGS
 
+AC_ARG_ENABLE(vlc,
+       AC_HELP_STRING([--disable-vlc],[disable vlc support @<:@default=auto@:>@]),
+       [enable_vlc=$enableval],[enable_vlc=auto])
+if test "$enable_vlc" != "no" ; then
+       PKG_CHECK_MODULES(VLC, [libvlc >= 0.9], [HAVE_VLC="yes"], [HAVE_VLC="no"])
+fi
+if test "$enable_vlc$HAVE_VLC" = "yesno" ; then
+       AC_MSG_RESULT(vlc not found)
+fi
+
 AC_ARG_ENABLE(xine,
        AC_HELP_STRING([--disable-xine],[disable xine support @<:@default=auto@:>@]),
        [enable_xine=$enableval],[enable_xine=auto])
@@ -115,6 +125,7 @@ if test "$HAVE_XINE$HAVE_GSTREAMER" = "nono" ; then
        AC_MSG_ERROR([Xine or Gstreamer must be installed to build emotion])
 fi
 
+AM_CONDITIONAL([BUILD_VLC_MODULE], [test "$HAVE_VLC" = yes])
 AM_CONDITIONAL([BUILD_XINE_MODULE], [test "$HAVE_XINE" = yes])
 AM_CONDITIONAL([BUILD_GSTREAMER_MODULE], [test "$HAVE_GSTREAMER" = yes])
 
@@ -127,6 +138,7 @@ src/lib/Makefile
 src/modules/Makefile
 src/modules/xine/Makefile
 src/modules/gstreamer/Makefile
+src/modules/vlc/Makefile
 src/bin/Makefile
 data/Makefile
 debian/changelog
@@ -147,6 +159,7 @@ echo "Configuration Options Summary:"
 echo
 echo "  Modules:"
 echo "    Xine...............: $HAVE_XINE"
+echo "    Vlc................: $HAVE_VLC"
 echo "    Gstreamer..........: $HAVE_GSTREAMER"
 echo "    Gstreamer plugins..: $GSTPLUG_MSG"
 echo "    Gstreamer FFmpeg...: $HAVE_GSTFFMPEG"
index 1af8c8c..aac1813 100644 (file)
@@ -1,4 +1,4 @@
 
 MAINTAINERCLEANFILES = Makefile.in
 
-SUBDIRS = xine gstreamer
+SUBDIRS = xine gstreamer vlc
diff --git a/src/modules/vlc/.cvsignore b/src/modules/vlc/.cvsignore
new file mode 100644 (file)
index 0000000..9730646
--- /dev/null
@@ -0,0 +1,6 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
diff --git a/src/modules/vlc/Makefile.am b/src/modules/vlc/Makefile.am
new file mode 100644 (file)
index 0000000..842e34f
--- /dev/null
@@ -0,0 +1,29 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/modules \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EVAS_CFLAGS@ \
+@ECORE_CFLAGS@ \
+@VLC_CFLAGS@
+
+if BUILD_VLC_MODULE
+
+pkgdir = $(libdir)/emotion
+
+pkg_LTLIBRARIES = vlc.la
+
+vlc_la_SOURCES      = \
+emotion_vlc.c \
+emotion_vlc.h
+vlc_la_LIBADD       = @EVAS_LIBS@ @ECORE_LIBS@ @VLC_LIBS@ $(top_builddir)/src/lib/libemotion.la -lpthread
+vlc_la_LDFLAGS      = -module -avoid-version
+vlc_la_LIBTOOLFLAGS = --tag=disable-static
+vlc_la_DEPENDENCIES = $(top_builddir)/config.h
+
+endif
diff --git a/src/modules/vlc/TODO b/src/modules/vlc/TODO
new file mode 100644 (file)
index 0000000..496805e
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# TODO for emotion/vlc plugin
+#
+
+# Known bug
+When changing video size at begining, there is sometimes SEGV in evas.
+The plugin first load the movie with default geometry, wait for it inputThread from VLC to be launched
+and read the movie geometry. Then it stops vlc and start it again with known geometry and realloc frames.
+Plugin warn emotion that size changed using API func "_emotion_frame_resize" thru fd_write/fd_read socket.
+
+It seems that it tries to convert original picture from YUV to BGRA but it's already in RGBA format. 
+p im->cache_entry = {_list_data = {next = 0x818f860, prev = 0x0, last = 0x818f860}, cache = 0x80627f0, cache_key = 0x0, file = 0x0, key = 0x0, 
+       timestamp = 0, laststat = 1221825297, references = 1, scale = 1 '\001', load_opts = {scale_down_by = 0, dpi = 0, w = 0, h = 0}, 
+       space = 1, w = 384, h = 288, allocated = {w = 384, h = 288}, info = {module = 0x0, loader = 0x0}, flags = {loaded = 0 '\0', 
+       dirty = 1 '\001', activ = 0 '\0', need_data = 1 '\001', lru_nodata = 0 '\0', cached = 1 '\001', alpha = 0 '\0', alpha_sparse = 0 '\0'}}
+We can see cache is 1 (=EVAS_COLORSPACE_YCBCR422P601_PL) instead of 0 (=EVAS_COLORSPACE_ARGB8888).
+
+GDB TRACE =
+evas_common_convert_yuv_420p_601_rgba (src=0xb40a6008, dst=0xb3e72008 "", w=720, h=400) at evas_convert_yuv.c:198
+198                 movd_m2r(*up, mm3);
+(gdb) bt
+0  evas_common_convert_yuv_420p_601_rgba (src=0xb40a6008, dst=0xb3e72008 "", w=720, h=400) at evas_convert_yuv.c:198
+1  0xb7f3e087 in evas_common_image_colorspace_normalize (im=0x8090a88) at evas_image_main.c:388
+2  0xb7e6486d in eng_image_draw (data=0x8063388, context=0x8061120, surface=0x8090808, image=0x8090a88, src_x=0, src_y=0, src_w=720, src_h=400, dst_x=0, dst_y=0, dst_w=800, dst_h=600, smooth=1) at evas_engine.c:566
+3  0xb7ee027b in evas_object_image_render (obj=0x8061788, output=0x8063388, context=0x8061120, surface=0x8090808, x=0, y=0) at evas_object_image.c:1974
+4  0xb7f09db1 in evas_render_updates_internal (e=0x8063c80, make_updates=1 '\001', do_draw=1 '\001') at evas_render.c:526
+5  0xb7e7f3d6 in _ecore_evas_x_render (ee=0x8063a98) at ecore_evas_x.c:330
+6  0xb7e82207 in _ecore_evas_x_idle_enter (data=0x0) at ecore_evas_x.c:1320
+7  0xb7ea738b in _ecore_idle_enterer_call () at ecore_idle_enterer.c:101
+8  0xb7eaaae5 in _ecore_main_loop_iterate_internal (once_only=0) at ecore_main.c:691
+9  0xb7eaaccf in ecore_main_loop_begin () at ecore_main.c:87
+10 0x08048bb2 in main ()
+
+# Missing functions (empty bodies) int emotion_vlc.c
+/* STUB */
+static void em_event_feed(void *ef, int event)
+--
+/* STUB */
+static void em_event_mouse_button_feed(void *ef, int button, int x, int y)
+--
+/* STUB */
+static void em_event_mouse_move_feed(void *ef, int x, int y)
+--
+/* STUB */
+static void em_video_channel_set(void *ef, int channel)
+--
+/* STUB */
+static int em_video_channel_get(void *ef)
+--
+/* STUB */
+static const char * em_video_channel_name_get(void *ef, int channel)
+--
+/* STUB */
+static int em_audio_channel_count(void *ef)
+--
+/* STUB */
+static const char * em_audio_channel_name_get(void *ef, int channel)
+--
+/* STUB */
+static int em_spu_channel_count(void *ef)
+--
+/* STUB */
+static const char * em_spu_channel_name_get(void *ef, int channel)
+--
+/* STUB */
+static void em_spu_channel_mute_set(void *ef, int mute)
+--
+/* STUB */
+static int em_spu_channel_mute_get(void *ef)
+--
+/* STUB */
+static const char * em_chapter_name_get(void *ef, int chapter)
diff --git a/src/modules/vlc/emotion_vlc.c b/src/modules/vlc/emotion_vlc.c
new file mode 100644 (file)
index 0000000..84ae5f8
--- /dev/null
@@ -0,0 +1,1201 @@
+/* 
+ * SICMA AERO SEAT
+ * code@ife-sit.info
+ */
+
+#ifndef EMOTION_VLC_C
+#define EMOTION_VLC_C
+
+#include "Emotion.h"
+#include "emotion_private.h"
+#include "emotion_vlc.h"
+
+void * _em_slave_thread(void * t)
+{
+       int event;
+       pthread_detach(pthread_self());
+       Emotion_Vlc_Video *ev=  (Emotion_Vlc_Video*)t;
+       while(read(ev->fd_slave_read, &event,  sizeof(int)) > 0)        {
+               switch(event)   {
+                       case VLC_RESIZE:
+                               _em_resize(ev, -1, -1);
+                       break;
+                       case VLC_CHANGE_VOL:
+                               _emotion_audio_level_change(ev->obj);
+                       break;
+                       default:
+                       break;
+               }
+       }
+       fprintf(stderr,"BYE BYE");
+       return NULL;
+}
+
+static unsigned char em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
+{
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *ef;
+       int fds[2], x, y;
+       int event = VLC_NEW_FRAME;
+       pthread_t t_id;
+       x = WIDTH;
+       y = HEIGHT;
+
+
+       if (!emotion_video) return 0;
+
+       ev = (Emotion_Vlc_Video*)malloc(sizeof(Emotion_Vlc_Video));
+       ASSERT_EV(ev) return 0;
+       memset(ev, 0, sizeof(Emotion_Vlc_Video));
+
+       ef = (Emotion_Vlc_Video_Frame*)malloc(sizeof(Emotion_Vlc_Video_Frame));
+       if (!ef) return 0;
+       memset(ef, 0, sizeof(Emotion_Vlc_Video_Frame));
+
+       /* init internal frames */
+       if(ef->frame_A) {
+               free(ef->frame_A);
+       }
+       if(ef->frame_B) {
+               free(ef->frame_B);
+       }
+       ef->frame_A = (char*)malloc(x*y*sizeof(char)*4);
+       ef->frame_B = (char*)malloc(x*y*sizeof(char)*4);
+       memset(ef->frame_A, 0x00, x*y*sizeof(char)*4);
+       memset(ef->frame_B, 0x00, x*y*sizeof(char)*4);
+       ef->frame = ef->frame_A;
+
+       /* update size in object */
+       ev->w = x;
+       ev->h = y;
+       ev->ratio = (double)x/(double)y;
+
+       ev->cur_frame = ef;
+
+       if(pipe(fds) == 0)
+       {
+               ev->fd_read = fds[0];
+               ev->fd_write = fds[1];
+               fcntl(ev->fd_read, F_SETFL, O_NONBLOCK);
+               ev->fd_handler = ecore_main_fd_handler_add(ev->fd_read, ECORE_FD_READ, _em_fd_active, ev, NULL, NULL);
+               ecore_main_fd_handler_active_set(ev->fd_handler, ECORE_FD_READ);
+       }
+
+       if (pipe(fds) == 0)
+       {
+               ev->fd_slave_read = fds[0];
+               ev->fd_slave_write = fds[1];
+               fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK);
+       }
+       ev->obj = obj;
+
+       ev->delete_me = 0;
+       ev->opening = 1;
+       ev->play_ok = 0;
+       ev->video_mute = 1;
+
+       if (opt)
+       {
+               ev->opt_no_audio = opt->no_audio;
+               ev->opt_no_video = opt->no_video;
+       }
+
+
+       /* init libvlc */
+       int vlc_argc = 0;
+       char const *vlc_argv[] =
+       {
+               "-q",
+               //"-vvvvv",
+               "--ignore-config",
+               "--vout", "vmem",
+               "--vmem-width", ev->width,
+               "--vmem-height", ev->height,
+               "--vmem-pitch", ev->pitch,
+               "--vmem-chroma", "RV32",
+               "--vmem-lock", ev->clock,
+               "--vmem-unlock", ev->cunlock,
+               "--vmem-data", ev->cdata,
+       };
+       vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
+       sprintf(ev->clock, "%lld", (long long int)(intptr_t)_em_lock);
+       sprintf(ev->cunlock, "%lld", (long long int)(intptr_t)_em_unlock);
+       sprintf(ev->cdata, "%lld", (long long int)(intptr_t)ev);
+       sprintf(ev->width, "%d", WIDTH);
+       sprintf(ev->height, "%d", HEIGHT);
+       sprintf(ev->pitch, "%d", 4*WIDTH);
+
+       ev->vlc_ex = (libvlc_exception_t*)malloc(sizeof(libvlc_exception_t));
+       libvlc_exception_init(ev->vlc_ex);
+       ev->vlc_player = libvlc_new(vlc_argc, vlc_argv, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+
+       if(ev->vlc_player)      {
+               ev->play_ok = 1;
+       }
+
+       pthread_mutex_init(&ef->frame_copy_lock, NULL);
+       pthread_create(&t_id, NULL, _em_slave_thread, ev);
+
+       ev->opening = 0;
+       write(ev->fd_write, &event, sizeof(void *));
+
+       *emotion_video = ev;
+       return 1;
+}
+
+static int em_shutdown(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *evvf;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       evvf = ev->cur_frame;
+
+       ASSERT_EV_VLC(ev) return 0;
+       libvlc_release(ev->vlc_player);
+       CATCH(ev->vlc_ex)
+       ev->vlc_player = NULL;
+       free(ev->vlc_ex);
+
+       ev->closing = 0;
+
+       ecore_main_fd_handler_del(ev->fd_handler);
+
+       if(evvf)        {
+               if(evvf->frame_A)       {
+                       free(evvf->frame_A);
+               }
+               if(evvf->frame_B)       {
+                       free(evvf->frame_B);
+               }
+               pthread_mutex_destroy(&(evvf->frame_copy_lock));
+               free(evvf);
+       }
+       close(ev->fd_write);
+       close(ev->fd_read);
+       close(ev->fd_slave_write);
+       close(ev->fd_slave_read);
+
+       return 1;
+}
+
+static unsigned char em_file_open(const char *file, Evas_Object *obj, void *ef)
+{
+       Emotion_Vlc_Video *ev;
+       int i;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_VLC(ev) return 0;
+
+       ev->vlc_m = libvlc_media_new(ev->vlc_player, file, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       ASSERT_EV_M(ev) return 0;
+       ev->vlc_mp = libvlc_media_player_new_from_media(ev->vlc_m, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       libvlc_media_release(ev->vlc_m); 
+       CATCH(ev->vlc_ex)
+       ev->vlc_m = NULL;
+       ASSERT_EV_MP(ev) return 0;
+
+       ev->vlc_evtmngr = libvlc_media_player_event_manager (ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+
+       for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
+               libvlc_event_attach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+       }
+
+       if(ev->filename)        {
+               free(ev->filename);
+               ev->filename = NULL;
+       }
+       ev->filename = strdup(file);
+
+       /* set properties to video object */
+       ev->just_loaded = 1;
+
+       return 1;
+}
+
+static void em_file_close(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+       int i;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+
+       for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
+               libvlc_event_detach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+       }
+       libvlc_media_player_stop(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       libvlc_media_player_release(ev->vlc_mp);
+       CATCH(ev->vlc_ex)
+       ev->vlc_mp = NULL;
+       if(ev->filename)        {
+               free(ev->filename);
+               ev->filename = NULL;
+       }
+}
+
+static void em_play(void *ef, double pos)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+
+       ev->play = 1;
+       ev->play_ok = 0;
+
+       if(pos != ev->pos)      {
+               libvlc_media_player_set_time(ev->vlc_mp, (libvlc_time_t)(pos*1000), ev->vlc_ex);
+       }
+       
+       libvlc_media_player_play(ev->vlc_mp, ev->vlc_ex);
+
+       ev->just_loaded = 0;
+}
+
+static void em_stop(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+
+       ev->play = 0;
+       ev->play_ok = 0;
+       libvlc_media_player_pause(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static void em_size_get(void *ef, int *w, int *h)
+{
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *fr;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       fr = ev->cur_frame;
+
+       pthread_mutex_lock(&fr->frame_copy_lock);
+       if(w) *w = ev->w;
+       if(h) *h = ev->h;
+       pthread_mutex_unlock(&fr->frame_copy_lock);
+}
+
+static void em_pos_set(void *ef, double pos)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+       libvlc_media_player_set_time(ev->vlc_mp, (libvlc_time_t)(pos*1000), ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static void em_vis_set(void *ef, Emotion_Vis vis)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       if (ev->vis == vis) return;
+       ev->vis = vis;
+}
+
+static double em_len_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+       ASSERT_EV(ev) return 0;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       return ev->len;
+}
+
+static int em_fps_num_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ASSERT_EV(ev) return 0;
+       ev = (Emotion_Vlc_Video *)ef;
+       return (int)(ev->fps * 1000.0);
+}
+
+static int em_fps_den_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       return 1000;
+}
+
+static double em_fps_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ASSERT_EV(ev) return 0;
+       ev = (Emotion_Vlc_Video *)ef;
+       return ev->fps;
+}
+
+static double em_pos_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ASSERT_EV(ev) return 0;
+       ev = (Emotion_Vlc_Video *)ef;
+       return ev->pos;
+}
+
+static Emotion_Vis em_vis_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       return ev->vis;
+}
+
+static double em_ratio_get(void *ef)
+{
+       double ratio;
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *fr;
+
+       ASSERT_EV(ev) return 0;
+       ev = (Emotion_Vlc_Video *)ef;
+       fr = ev->cur_frame;
+       pthread_mutex_lock(&fr->frame_copy_lock);
+       ratio = ev->ratio;
+       pthread_mutex_unlock(&fr->frame_copy_lock);
+       return ratio;
+}
+
+static int em_video_handled(void *ef)
+{
+       int ret = 0;
+       Emotion_Vlc_Video *ev;
+
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       ev = (Emotion_Vlc_Video *)ef;
+       if (ev->opening || (!ev->play_ok)) return 0;
+
+       ret = libvlc_media_player_has_vout(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return ret;
+}
+
+static int em_audio_handled(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       return 1;
+}
+
+static int em_seekable(void *ef)
+{
+       int ret = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       ret = vlc_media_player_is_seekable(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return ret;
+}
+
+static void em_frame_done(void *ef)
+{
+       return;
+}
+
+static Emotion_Format em_format_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       return EMOTION_FORMAT_BGRA;
+}
+
+static void em_video_data_size_get(void *ef, int *w, int *h)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       if (w) *w = ev->w;
+       if (h) *h = ev->h;
+}
+
+static int em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows)
+{
+       Emotion_Vlc_Video *ev;
+       return 0;
+}
+
+static int em_bgra_data_get(void *ef, unsigned char **bgra_data)
+{
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *fr;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       fr = ev->cur_frame;
+       if (!fr) return 0;
+       if (fr->frame)
+       {
+               /* wait for frame to be ready */
+               pthread_mutex_lock(&fr->frame_copy_lock);
+               /* send cur frame to emotion */
+               *bgra_data = fr->frame;
+
+               /* switch frames */
+               if(fr->frame == fr->frame_A)    {
+                       fr->frame = fr->frame_B;
+               } else {
+                       fr->frame = fr->frame_A;
+               }
+
+               /* unlock both frames */
+               pthread_mutex_unlock(&fr->frame_copy_lock);
+               return 1;
+       }
+       return 0;
+}
+
+static void _em_resize(Emotion_Vlc_Video *ev, int x,  int y)
+{
+       int i;
+       int event;
+       int vlc_argc = 0;
+       char const *vlc_argv[] =
+       {
+               "-q",
+               //"-vvvvv",
+               "--ignore-config",
+               "--vout", "vmem",
+               "--vmem-width", ev->width,
+               "--vmem-height", ev->height,
+               "--vmem-pitch", ev->pitch,
+               "--vmem-chroma", "RV32",
+               "--vmem-lock", ev->clock,
+               "--vmem-unlock", ev->cunlock,
+               "--vmem-data", ev->cdata,
+       };
+       Emotion_Vlc_Video_Frame *fr;
+
+       ASSERT_EV(ev)   return;
+       ASSERT_EV_VLC(ev) return;
+       fr = ev->cur_frame;
+
+       /* We look for new size if not specified */
+       if(x == -1)     {
+               x = libvlc_video_get_width(ev->vlc_mp, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+       }
+       if(y == -1)     {
+               y = libvlc_video_get_height(ev->vlc_mp, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+       }
+
+       if((x == 0)||(y == 0))  {
+               return;
+       }
+
+       /* stop vlc if necessary */
+       if(ev->filename)        {       
+               libvlc_media_player_stop(ev->vlc_mp, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+               libvlc_media_player_release(ev->vlc_mp);
+               CATCH(ev->vlc_ex)
+       }
+
+       /* update size in object */
+       ev->w = x;
+       ev->h = y;
+       ev->ratio = (double)x/(double)y;
+
+       /* we need to restart vlc */
+       libvlc_release(ev->vlc_player);
+       CATCH(ev->vlc_ex)
+       vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
+       sprintf(ev->clock, "%lld", (long long int)(intptr_t)_em_lock);
+       sprintf(ev->cunlock, "%lld", (long long int)(intptr_t)_em_unlock);
+       sprintf(ev->cdata, "%lld", (long long int)(intptr_t)ev);
+       sprintf(ev->width, "%d", ev->w);
+       sprintf(ev->height, "%d", ev->h);
+       sprintf(ev->pitch, "%d", 4*ev->w);
+       ev->vlc_player = libvlc_new(vlc_argc, vlc_argv, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+
+       pthread_mutex_lock(&fr->frame_copy_lock);
+
+       if(ev->filename)        {       
+               /* relaunch media and mediaplayer */
+               ev->vlc_m = libvlc_media_new(ev->vlc_player, ev->filename, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+                       ASSERT_EV_M(ev) return;
+               ev->vlc_mp = libvlc_media_player_new_from_media(ev->vlc_m, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+                       libvlc_media_release(ev->vlc_m); 
+               CATCH(ev->vlc_ex)
+                       ev->vlc_m = NULL;
+               ASSERT_EV_MP(ev) return;
+
+               ev->vlc_evtmngr = libvlc_media_player_event_manager (ev->vlc_mp, ev->vlc_ex);
+               CATCH(ev->vlc_ex)
+
+               for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
+                       libvlc_event_attach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev, ev->vlc_ex);
+                       CATCH(ev->vlc_ex)
+               }
+       }
+
+       /* resize frames */
+       if(fr->frame_A) {
+               free(fr->frame_A);
+       }
+       if(fr->frame_B) {
+               free(fr->frame_B);
+       }
+       fr->frame_A = malloc(ev->w*ev->h*sizeof(char)*4);
+       fr->frame_B = malloc(ev->w*ev->h*sizeof(char)*4);
+       memset(fr->frame_A, 0xFF, x*y*sizeof(char)*4);
+       memset(fr->frame_B, 0xFF, x*y*sizeof(char)*4);
+       fr->frame = fr->frame_A;
+
+       /* notify a new frame is available */
+       event = VLC_RESIZE;
+       write(ev->fd_write, &event, sizeof(void *));
+
+       pthread_mutex_unlock(&fr->frame_copy_lock);
+
+       /* unlock both frames */
+       if(ev->filename)        {       
+               libvlc_media_player_play(ev->vlc_mp, ev->vlc_ex);
+       }
+
+       /* activate display */
+       ev->video_mute = 0;
+}
+
+static int _em_fd_active(void *data, Ecore_Fd_Handler *fdh)
+{
+       /* this only used for ecore notification */
+       /* every other internal event should be done in _em_slave_thread */
+       int event;
+       int fd, len;
+       Emotion_Vlc_Video_Frame *fr;
+       Emotion_Vlc_Video *ev;
+
+       ev = data;
+       fd = ecore_main_fd_handler_fd_get(fdh);
+       while((len = read(fd, &event, sizeof(int))) > 0) {
+               if(len == sizeof(int)) {
+                       switch(event)   {
+                               case VLC_NEW_FRAME:
+                                       ASSERT_EV(ev)   return 1;
+                                       _emotion_frame_new(ev->obj);
+                               break;
+                               case VLC_RESIZE:
+                                       ASSERT_EV(ev)   return 1;
+                                       _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio);
+                               break;
+                               default:
+                               break;
+                       }
+               }
+       }
+       return 1;
+}
+
+
+/* STUB */
+static void em_event_feed(void *ef, int event)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       if ((ev->opening) || (!ev->play_ok)) return;
+
+       switch (event)
+       {
+               case EMOTION_EVENT_MENU1:
+                       break;
+               case EMOTION_EVENT_MENU2:
+                       break;
+               case EMOTION_EVENT_MENU3:
+                       break;
+               case EMOTION_EVENT_MENU4:
+                       break;
+               case EMOTION_EVENT_MENU5:
+                       break;
+               case EMOTION_EVENT_MENU6:
+                       break;
+               case EMOTION_EVENT_MENU7:
+                       break;
+               case EMOTION_EVENT_UP:
+                       break;
+               case EMOTION_EVENT_DOWN:
+                       break;
+               case EMOTION_EVENT_LEFT:
+                       break;
+               case EMOTION_EVENT_RIGHT:
+                       break;
+               case EMOTION_EVENT_SELECT:
+                       break;
+               case EMOTION_EVENT_NEXT:
+                       break;
+               case EMOTION_EVENT_PREV:
+                       break;
+               case EMOTION_EVENT_ANGLE_NEXT:
+                       break;
+               case EMOTION_EVENT_ANGLE_PREV:
+                       break;
+               case EMOTION_EVENT_FORCE:
+                       break;
+               case EMOTION_EVENT_0:
+                       break;
+               case EMOTION_EVENT_1:
+                       break;
+               case EMOTION_EVENT_2:
+                       break;
+               case EMOTION_EVENT_3:
+                       break;
+               case EMOTION_EVENT_4:
+                       break;
+               case EMOTION_EVENT_5:
+                       break;
+               case EMOTION_EVENT_6:
+                       break;
+               case EMOTION_EVENT_7:
+                       break;
+               case EMOTION_EVENT_8:
+                       break;
+               case EMOTION_EVENT_9:
+                       break;
+               case EMOTION_EVENT_10:
+                       break;
+               default:
+                       return;
+                       break;
+       }
+}
+
+/* STUB */
+static void em_event_mouse_button_feed(void *ef, int button, int x, int y)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       if ((ev->opening) || (!ev->play_ok)) return;
+}
+
+/* STUB */
+static void em_event_mouse_move_feed(void *ef, int x, int y)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       if ((ev->opening) || (!ev->play_ok)) return;
+}
+
+static int em_video_channel_count(void *ef)
+{
+       int ret  = 0;
+       Emotion_Vlc_Video *ev;
+       ev = (Emotion_Vlc_Video *)ef; 
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       ret = libvlc_media_player_has_vout(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return ret;
+}
+
+/* STUB */
+static void em_video_channel_set(void *ef, int channel)
+{
+       return;
+}
+
+/* STUB */
+static int em_video_channel_get(void *ef)
+{
+       return 1;
+}
+
+/* STUB */
+static const char * em_video_channel_name_get(void *ef, int channel)
+{
+       Emotion_Vlc_Video *ev;
+       return NULL;
+}
+
+static void em_video_channel_mute_set(void *ef, int mute)
+{
+       Emotion_Vlc_Video *ev;
+       ev = (Emotion_Vlc_Video*)ef;
+       ASSERT_EV(ev)   return;
+       ev->video_mute = mute;
+}
+
+static int em_video_channel_mute_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+       ev = (Emotion_Vlc_Video*)ef;
+       ASSERT_EV(ev)   return;
+       return ev->video_mute;
+}
+
+/* STUB */
+static int em_audio_channel_count(void *ef)
+{
+       return -1;
+}
+
+static void em_audio_channel_set(void *ef, int channel)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_VLC(ev) return;
+       if (channel < -1) channel = -1;
+       ev->audio_channel = channel;
+       libvlc_audio_set_channel(ev->vlc_player, channel, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static int em_audio_channel_get(void *ef)
+{
+       int ret = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_VLC(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       ret = libvlc_audio_get_channel(ev->vlc_player, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return ret;
+}
+
+/* STUB */
+static const char * em_audio_channel_name_get(void *ef, int channel)
+{
+       return NULL;
+}
+
+static void em_audio_channel_mute_set(void *ef, int mute)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_VLC(ev) return;
+       ev->audio_mute = mute;
+       libvlc_audio_set_mute(ev->vlc_player, (int)(ev->audio_mute), ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static int em_audio_channel_mute_get(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       return ev->audio_mute;
+}
+
+static void em_audio_channel_volume_set(void *ef, double vol)
+{
+       int event = VLC_CHANGE_VOL;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_VLC(ev) return;
+
+       if (vol < 0.0) vol = 0.0;
+       if (vol > 1.0) vol = 1.0;
+       libvlc_audio_set_volume(ev->vlc_player, (int)(vol * 200), ev->vlc_ex);
+       write(ev->fd_slave_write, &event, sizeof(void *));
+       CATCH(ev->vlc_ex)
+}
+
+static double em_audio_channel_volume_get(void *ef)
+{
+       int vol;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_VLC(ev) return;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       vol = libvlc_audio_get_volume(ev->vlc_player, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return (double)(vol/200.0);
+}
+
+/* STUB */
+static int em_spu_channel_count(void *ef)
+{
+       return 0;
+}
+
+static void em_spu_channel_set(void *ef, int channel)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+       if (channel < 0) channel = 0;
+       ev->spu_channel = channel;
+       libvlc_video_set_spu(ev->vlc_mp, ev->spu_channel, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static int em_spu_channel_get(void *ef)
+{
+       int num = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       num = libvlc_video_get_spu(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return num;
+}
+
+/* STUB */
+static const char * em_spu_channel_name_get(void *ef, int channel)
+{
+       return NULL;
+}
+
+/* STUB */
+static void em_spu_channel_mute_set(void *ef, int mute)
+{
+       return;
+}
+
+/* STUB */
+static int em_spu_channel_mute_get(void *ef)
+{
+       return 0;
+}
+
+static int em_chapter_count(void *ef)
+{
+       int num = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       if (ev->opening || (!ev->play_ok)) return 0;
+       num = libvlc_media_player_get_chapter_count(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return num;
+}
+
+static void em_chapter_set(void *ef, int chapter)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return ;
+       libvlc_media_player_set_chapter(ev->vlc_mp, chapter, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static int em_chapter_get(void *ef)
+{
+       int num = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       num = libvlc_media_player_get_chapter(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return num;
+}
+
+/* STUB */
+static const char * em_chapter_name_get(void *ef, int chapter)
+{
+       return NULL;
+}
+
+static void em_speed_set(void *ef, double speed)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return;
+       ASSERT_EV_MP(ev) return;
+       libvlc_media_player_set_rate(ev->vlc_mp, speed, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+}
+
+static double em_speed_get(void *ef)
+{
+       float speed = 0;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev) return 0;
+       ASSERT_EV_MP(ev) return 0;
+       speed = libvlc_media_player_get_rate(ev->vlc_mp, ev->vlc_ex);
+       CATCH(ev->vlc_ex)
+       return (double)speed;
+}
+
+static int em_eject(void *ef)
+{
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       system("eject");
+       return 1;
+}
+
+static const char * em_meta_get(void *ef, int meta)
+{
+       char * meta_data = NULL;
+       Emotion_Vlc_Video *ev;
+
+       ev = (Emotion_Vlc_Video *)ef;
+       ASSERT_EV(ev)   return NULL;
+       ASSERT_EV_M(ev) return NULL;
+       if ((ev->opening) || (!ev->play_ok)) return NULL;
+       switch (meta)
+       {
+               case META_TRACK_TITLE:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Title, ev->vlc_ex);
+                       break;
+               case META_TRACK_ARTIST:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Artist, ev->vlc_ex);
+                       break;
+               case META_TRACK_GENRE:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Genre, ev->vlc_ex);
+                       break;
+               case META_TRACK_COMMENT:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Description, ev->vlc_ex);
+                       break;
+               case META_TRACK_ALBUM:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Album, ev->vlc_ex);
+                       break;
+               case META_TRACK_YEAR:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Date, ev->vlc_ex);
+                       break;
+               case META_TRACK_DISCID:
+                       meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_TrackID, ev->vlc_ex);
+                       break;
+               default:
+                       break;
+       }
+       return meta_data;
+}
+
+static void _em_event(const libvlc_event_t *event, void *data)
+{
+       Emotion_Vlc_Event *new_ev;
+       Emotion_Vlc_Video *ev;
+
+       ev = data;
+       ASSERT_EV(ev)   return;
+       switch (event->type) {
+               case libvlc_MediaPlayerTimeChanged: {
+                               libvlc_time_t pos = event->u.media_player_time_changed.new_time;
+                               double time = (pos / 1000000.f);
+                               _emotion_video_pos_update(ev->obj, time, 0);
+                               ev->pos = time;
+                               if(ev->len == 0)        {
+                                       pos = libvlc_media_player_get_length(ev->vlc_mp, ev->vlc_ex);
+                                       ev->len = (double)(pos / 1000.0);
+                               }
+                       }
+               case libvlc_MediaPlayerPlaying: {
+                               int x, y;
+                               float fps = 0;
+                               float pos = 0;
+                               float total_pos = 0;
+                               libvlc_time_t time = 0;
+                               libvlc_time_t total_time = 0;
+
+                               /* get video properties */
+                               total_time = libvlc_media_player_get_length(ev->vlc_mp, ev->vlc_ex);
+                               CATCH(ev->vlc_ex)
+                               fps = libvlc_media_player_get_fps(ev->vlc_mp, ev->vlc_ex);
+                               CATCH(ev->vlc_ex)
+                               x = libvlc_video_get_width(ev->vlc_mp, ev->vlc_ex);
+                               CATCH(ev->vlc_ex)
+                               y = libvlc_video_get_height(ev->vlc_mp, ev->vlc_ex);
+                               CATCH(ev->vlc_ex)
+                               /* set them to object */
+                               if(ev->fps == 0)        {
+                                       ev->fps = fps;
+                               }
+                               if(ev->len == 0)        {
+                                       ev->len = (double)(total_time / 1000.0);
+                               }
+                               if((x != 0) && (y != 0))        {
+                                       if((ev->w != x)||(ev->h != y))  {
+                                               int event;
+                                               event = VLC_RESIZE;
+                                               write(ev->fd_slave_write, &event, sizeof(void *));
+                                       }
+                               }
+                       } break;
+               case libvlc_MediaPlayerEndReached: {
+                               ev->play = 0;
+                               _emotion_decode_stop(ev->obj);
+                               _emotion_playback_finished(ev->obj);
+                       } break;
+               default:
+                       break;
+       }
+}
+
+static void *_em_lock(void *par)
+{
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *evvf; 
+
+       /* get current frame */
+       ev = (Emotion_Vlc_Video*)par;
+       evvf = ev->cur_frame;
+
+       /* lock current frame */
+       pthread_mutex_lock(&(evvf->frame_copy_lock));
+       
+       /* send current frame address to vlc */
+       return evvf->frame;
+}
+
+static void  _em_unlock(void *par)
+{
+       float p = 0;
+       int ret;
+       int event;
+       Emotion_Vlc_Video *ev;
+       Emotion_Vlc_Video_Frame *evvf; 
+
+       /* get current frame */
+       ev = (Emotion_Vlc_Video*)par;
+       evvf = ev->cur_frame;
+
+       /* notify a new frame is available */
+       event = VLC_NEW_FRAME;
+       
+       if(ev->video_mute == 0) {
+               ret = write(ev->fd_write, &event, sizeof(void *));
+       }
+       pthread_mutex_unlock(&(evvf->frame_copy_lock));
+
+       return;
+}
+
+static Emotion_Video_Module em_module =
+{
+       em_init, /* init */
+       em_shutdown, /* shutdown */
+       em_file_open, /* file_open */
+       em_file_close, /* file_close */
+       em_play, /* play */
+       em_stop, /* stop */
+       em_size_get, /* size_get */
+       em_pos_set, /* pos_set */
+       em_vis_set, /* vis_set */
+       em_len_get, /* len_get */
+       em_fps_num_get, /* fps_num_get */
+       em_fps_den_get, /* fps_den_get */
+       em_fps_get, /* fps_get */
+       em_pos_get, /* pos_get */
+       em_vis_get, /* vis_get */
+       em_ratio_get, /* ratio_get */
+       em_video_handled, /* video_handled */
+       em_audio_handled, /* audio_handled */
+       em_seekable, /* seekable */
+       em_frame_done, /* frame_done */
+       em_format_get, /* format_get */
+       em_video_data_size_get, /* video_data_size_get */
+       NULL, /* yuv_rows_get */
+       em_bgra_data_get, /* bgra_data_get */
+       em_event_feed, /* event_feed */
+       em_event_mouse_button_feed, /* event_mouse_button_feed */
+       em_event_mouse_move_feed, /* event_mouse_move_feed */
+       em_video_channel_count, /* video_channel_count */
+       em_video_channel_set, /* video_channel_set */
+       em_video_channel_get, /* video_channel_get */
+       em_video_channel_name_get, /* video_channel_name_get */
+       em_video_channel_mute_set, /* video_channel_mute_set */
+       em_video_channel_mute_get, /* video_channel_mute_get */
+       em_audio_channel_count, /* audio_channel_count */
+       em_audio_channel_set, /* audio_channel_set */
+       em_audio_channel_get, /* audio_channel_get */
+       em_audio_channel_name_get, /* audio_channel_name_get */
+       em_audio_channel_mute_set, /* audio_channel_mute_set */
+       em_audio_channel_mute_get, /* audio_channel_mute_get */
+       em_audio_channel_volume_set, /* audio_channel_volume_set */
+       em_audio_channel_volume_get, /* audio_channel_volume_get */
+       em_spu_channel_count, /* spu_channel_count */
+       em_spu_channel_set, /* spu_channel_set */
+       em_spu_channel_get, /* spu_channel_get */
+       em_spu_channel_name_get, /* spu_channel_name_get */
+       em_spu_channel_mute_set, /* spu_channel_mute_set */
+       em_spu_channel_mute_get, /* spu_channel_mute_get */
+       em_chapter_count, /* chapter_count */
+       em_chapter_set, /* chapter_set */
+       em_chapter_get, /* chapter_get */
+       em_chapter_name_get, /* chapter_name_get */
+       em_speed_set, /* speed_set */
+       em_speed_get, /* speed_get */
+       em_eject, /* eject */
+       em_meta_get, /* meta_get */
+
+       NULL /* handle */
+};
+
+unsigned char module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
+{
+       if (!module)    {
+               return 0;
+       }
+
+       if (!em_module.init(obj, video, opt))   {
+               return 0;
+       }
+
+       *module = &em_module;
+       
+       return 1;
+}
+
+void module_close(Emotion_Video_Module *module, void *video)
+{
+       em_module.shutdown(video);
+}
+
+#endif /* EMOTION_VLC_C */
+
diff --git a/src/modules/vlc/emotion_vlc.h b/src/modules/vlc/emotion_vlc.h
new file mode 100644 (file)
index 0000000..84faccc
--- /dev/null
@@ -0,0 +1,182 @@
+/* 
+ * SICMA AERO SEAT
+ * code@ife-sit.info
+ */
+
+#ifndef EMOTION_VLC_H
+#define EMOTION_VLC_H
+
+#include <vlc/vlc.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+
+/* default values */
+#define WIDTH          10
+#define HEIGHT         10
+
+/* internal values */
+#define EVENT_BEG_ID   6
+#define NB_EVENTS      14
+
+/* checking macros */
+#define ASSERT_EV(ev)          if(!ev)
+#define ASSERT_EV_M(ev)                if(!ev->vlc_m)
+#define ASSERT_EV_MP(ev)       if(!ev->vlc_mp)
+#define ASSERT_EV_VLC(ev)      if(!ev->vlc_player)
+
+#ifdef DEBUG
+#define CATCH(ex)      if(libvlc_exception_raised(ex)){ \
+                               fprintf(stderr,"VLC EX [%s]::%s:%d %s\n", __FILE__,__func__,__LINE__, \
+                               libvlc_exception_get_message(ex)); \
+                       }libvlc_exception_clear(ex);
+#else
+#define CATCH(ex)      libvlc_exception_clear(ex);
+#endif
+
+/* internal events */
+#define VLC_NEW_FRAME  1
+#define VLC_RESIZE     2
+#define VLC_CHANGE_VOL 3
+
+typedef struct _Emotion_Vlc_Video       Emotion_Vlc_Video;
+typedef struct _Emotion_Vlc_Video_Frame Emotion_Vlc_Video_Frame;
+typedef struct _Emotion_Vlc_Event       Emotion_Vlc_Event;
+
+/* module api EMOTION --> VLC */
+static unsigned char  em_init                    (Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt);
+static int            em_shutdown                (void *ef);
+static unsigned char  em_file_open               (const char *file, Evas_Object *obj, void *ef);
+static void           em_file_close              (void *ef);
+static void           em_play                    (void *ef, double pos);
+static void           em_stop                    (void *ef);
+static void           em_size_get                (void *ef, int *w, int *h);
+static void           em_pos_set                 (void *ef, double pos);
+static void           em_vis_set                 (void *ef, Emotion_Vis vis);
+static double         em_len_get                 (void *ef);
+static int            em_fps_num_get             (void *ef);
+static int            em_fps_den_get             (void *ef);
+static double         em_fps_get                 (void *ef);
+static double         em_pos_get                 (void *ef);
+static Emotion_Vis    em_vis_get                 (void *ef);
+static double         em_ratio_get               (void *ef);
+static int            em_seekable                (void *ef);
+static void           em_frame_done              (void *ef);
+static Emotion_Format em_format_get              (void *ef);
+static void           em_video_data_size_get     (void *ef, int *w, int *h);
+static int            em_bgra_data_get           (void *ef, unsigned char **bgra_data);
+static void           em_event_feed              (void *ef, int event);
+static void           em_event_mouse_button_feed (void *ef, int button, int x, int y);
+static void           em_event_mouse_move_feed   (void *ef, int x, int y);
+static int            em_video_channel_count     (void *ef);
+static void           em_video_channel_set       (void *ef, int channel);
+static int            em_video_channel_get       (void *ef);
+static const char    *em_video_channel_name_get  (void *ef, int channel);
+static void           em_video_channel_mute_set  (void *ef, int mute);
+static int            em_video_channel_mute_get  (void *ef);
+static int            em_audio_channel_count     (void *ef);
+static void           em_audio_channel_set       (void *ef, int channel);
+static int            em_audio_channel_get       (void *ef);
+static const char    *em_audio_channel_name_get  (void *ef, int channel);
+static void           em_audio_channel_mute_set  (void *ef, int mute);
+static int            em_audio_channel_mute_get  (void *ef);
+static void           em_audio_channel_volume_set(void *ef, double vol);
+static double         em_audio_channel_volume_get(void *ef);
+static int            em_spu_channel_count       (void *ef);
+static void           em_spu_channel_set         (void *ef, int channel);
+static int            em_spu_channel_get         (void *ef);
+static const char    *em_spu_channel_name_get    (void *ef, int channel);
+static void           em_spu_channel_mute_set    (void *ef, int mute);
+static int            em_spu_channel_mute_get    (void *ef);
+static int            em_chapter_count           (void *ef);
+static void           em_chapter_set             (void *ef, int chapter);
+static int            em_chapter_get             (void *ef);
+static const char    *em_chapter_name_get        (void *ef, int chapter);
+static void           em_speed_set               (void *ef, double speed);
+static double         em_speed_get               (void *ef);
+static int            em_eject                   (void *ef);
+static const char    *em_meta_get                (void *ef, int meta);
+
+/* entry points for module */
+unsigned char         module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt);
+void                  module_close(Emotion_Video_Module *module, void *video);
+
+typedef struct _vlc_event_t {
+       libvlc_event_type_t type;
+       int data_length;
+       void * data;
+} vlc_event_t;
+
+/* emotion/vlc main structure */
+struct _Emotion_Vlc_Video
+{
+   /* vlc objects */
+   libvlc_instance_t *      vlc_player;
+   libvlc_media_player_t *   vlc_mp;
+   libvlc_media_t *         vlc_m;
+   libvlc_exception_t *      vlc_ex;
+   libvlc_event_manager_t *  vlc_evtmngr;
+   
+   /* vlc datas */
+   char clock[64], cunlock[64], cdata[64];
+   char width[32], height[32], pitch[32];
+  
+   int                      fd_read, fd_write;
+   int                              fd_slave_read, fd_slave_write;
+   Ecore_Fd_Handler         *fd_handler;
+
+   char                     *filename;
+   volatile double          len;
+   volatile double           pos;
+   double                    fps;
+   double                    ratio;
+   int                       w, h;
+   Evas_Object               *obj;
+   Emotion_Vlc_Video_Frame   *cur_frame;
+   volatile int              spu_channel;
+   volatile int              audio_channel;
+   volatile int              video_channel;
+   volatile int              fq;
+   Emotion_Vis               vis;
+   unsigned char             play : 1;
+   unsigned char             just_loaded : 1;
+   unsigned char             video_mute : 1;
+   unsigned char             audio_mute : 1;
+   unsigned char             spu_mute : 1;
+   unsigned char             opt_no_video : 1;
+   unsigned char             opt_no_audio : 1;
+   volatile unsigned char    delete_me : 1;
+   volatile unsigned char    opening : 1;
+   volatile unsigned char    closing : 1;
+   volatile unsigned char    have_vo : 1;
+   volatile unsigned char    play_ok : 1;
+};
+
+/* structure for frames 2 buffers to keep integrity */
+struct _Emotion_Vlc_Video_Frame
+{
+   unsigned char  *frame;
+   unsigned char  *frame_A;
+   unsigned char  *frame_B;
+   pthread_mutex_t frame_copy_lock;
+};
+
+
+/* internal util calls */
+static void *_em_lock          (void *par);
+static void  _em_unlock        (void *par);
+static void  _em_event         (const libvlc_event_t *event, void* data);
+static void  _em_resize        (Emotion_Vlc_Video *ev, int x,  int y);
+static int   _em_fd_active     (void *data, Ecore_Fd_Handler *fdh);
+static int   _em_reload_vlc    (Emotion_Vlc_Video *ev);
+void*       _em_slave_thread  (void * t);
+/* internal event struct */
+
+struct _Emotion_Vlc_Event
+{
+   int   type;
+   int   mtype;
+};
+
+#endif
+