From 075bab83c4288b5de20f6acfc6b0459656ea85e0 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 3 Mar 2020 20:38:58 +0000 Subject: [PATCH] remove vlc, gst-0.10, xine deps, modules as they are broken they dont work. easier to remove than fix, so... remove :) only gst 1.x supported now. --- .ci/ci-configure.sh | 11 +- .ci/ubuntu-bionic-install-deps.sh | 2 +- meson.build | 3 - meson_options.txt | 16 +- src/generic/emotion/meson.build | 8 - src/generic/emotion/vlc/emotion_generic_vlc.c | 789 ------- src/generic/emotion/vlc/meson.build | 8 - src/generic/evas/meson.build | 10 +- .../emotion/generic/Emotion_Generic_Plugin.h | 148 -- src/modules/emotion/generic/README | 79 - src/modules/emotion/generic/emotion_generic.c | 1908 ----------------- src/modules/emotion/generic/emotion_generic.h | 123 -- src/modules/emotion/generic/meson.build | 24 - src/modules/emotion/libvlc/emotion_libvlc.c | 1555 -------------- src/modules/emotion/libvlc/meson.build | 14 - src/modules/emotion/meson.build | 12 +- src/modules/emotion/xine/emotion_xine.c | 1707 --------------- src/modules/emotion/xine/emotion_xine.h | 118 - .../emotion/xine/emotion_xine_vo_out.c | 766 ------- src/modules/emotion/xine/meson.build | 16 - 20 files changed, 14 insertions(+), 7303 deletions(-) delete mode 100644 src/generic/emotion/meson.build delete mode 100644 src/generic/emotion/vlc/emotion_generic_vlc.c delete mode 100644 src/generic/emotion/vlc/meson.build delete mode 100644 src/modules/emotion/generic/Emotion_Generic_Plugin.h delete mode 100644 src/modules/emotion/generic/README delete mode 100644 src/modules/emotion/generic/emotion_generic.c delete mode 100644 src/modules/emotion/generic/emotion_generic.h delete mode 100644 src/modules/emotion/generic/meson.build delete mode 100644 src/modules/emotion/libvlc/emotion_libvlc.c delete mode 100644 src/modules/emotion/libvlc/meson.build delete mode 100644 src/modules/emotion/xine/emotion_xine.c delete mode 100644 src/modules/emotion/xine/emotion_xine.h delete mode 100644 src/modules/emotion/xine/emotion_xine_vo_out.c delete mode 100644 src/modules/emotion/xine/meson.build diff --git a/.ci/ci-configure.sh b/.ci/ci-configure.sh index 773e536aa1..cd7f9eb889 100755 --- a/.ci/ci-configure.sh +++ b/.ci/ci-configure.sh @@ -13,12 +13,11 @@ if [ "$DISTRO" != "" ] ; then # TODO: # - No libelogind package in fedora 30 repo - # - RPM fusion repo for xine and libvlc # - Ibus ENABLED_LINUX_COPTS=" -Dfb=true -Dsdl=true -Dbuffer=true -Dbuild-id=travis-build \ -Ddebug-threads=true -Dglib=true -Dg-mainloop=true -Dxpresent=true -Dxinput22=true \ - -Devas-loaders-disabler=json -Decore-imf-loaders-disabler= -Demotion-loaders-disabler=libvlc,xine \ - -Demotion-generic-loaders-disabler=vlc -Dharfbuzz=true -Dpixman=true -Dhyphen=true \ + -Devas-loaders-disabler=json -Decore-imf-loaders-disabler= \ + -Dharfbuzz=true -Dpixman=true -Dhyphen=true \ -Dvnc-server=true -Dbindings=luajit,cxx,mono -Delogind=false -Dinstall-eo-files=true -Dphysics=true" # Enabled png, jpeg evas loader for in tree edje file builds @@ -27,8 +26,8 @@ if [ "$DISTRO" != "" ] ; then -Dcrypto=gnutls -Dglib=false -Dgstreamer=false -Dsystemd=false -Dpulseaudio=false \ -Dnetwork-backend=connman -Dxinput2=false -Dtslib=false \ -Devas-loaders-disabler=gst,pdf,ps,raw,svg,xcf,bmp,dds,eet,generic,gif,ico,jp2k,json,pmaps,psd,tga,tgv,tiff,wbmp,webp,xpm \ - -Decore-imf-loaders-disabler=xim,ibus,scim -Demotion-loaders-disabler=gstreamer1,libvlc,xine \ - -Demotion-generic-loaders-disabler=vlc -Dfribidi=false -Dfontconfig=false \ + -Decore-imf-loaders-disabler=xim,ibus,scim \ + -Dfribidi=false -Dfontconfig=false \ -Dedje-sound-and-video=false -Dembedded-lz4=false -Dlibmount=false -Dv4l2=false \ -Delua=true -Dnls=false -Dbindings= -Dlua-interpreter=luajit -Dnative-arch-optimization=false" #evas_filter_parser.c:(.text+0xc59): undefined reference to `lua_getglobal' with interpreter lua @@ -98,7 +97,7 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:/usr/local/Cellar/libffi/$LIBFFI_VER/lib/pkgconfig" export CC="ccache gcc" travis_fold meson meson - mkdir build && meson build -Dopengl=full -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Demotion-loaders-disabler=gstreamer1,libvlc,xine + mkdir build && meson build -Dopengl=full -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Dgstreamer=false travis_endfold meson else travis_fold meson meson diff --git a/.ci/ubuntu-bionic-install-deps.sh b/.ci/ubuntu-bionic-install-deps.sh index 998e74b084..9eefa7d7fc 100755 --- a/.ci/ubuntu-bionic-install-deps.sh +++ b/.ci/ubuntu-bionic-install-deps.sh @@ -1,4 +1,4 @@ #!/bin/sh sudo apt-get update -y -sudo apt-get install -y build-essential autoconf automake autopoint doxygen check luajit libharfbuzz-dev libpng-dev libudev-dev libwebp-dev libssl-dev libluajit-5.1-dev libfribidi-dev libcogl-gles2-dev libgif-dev libtiff5-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libdbus-1-dev libmount-dev libblkid-dev libpulse-dev libxrandr-dev libxtst-dev libxcursor-dev libxcomposite-dev libxinerama-dev libxkbfile-dev libbullet-dev libvlc-dev libsndfile1-dev libraw-dev libspectre-dev libpoppler-cpp-dev libpam0g-dev liblz4-dev faenza-icon-theme gettext git imagemagick libasound2-dev libbluetooth-dev libfontconfig1-dev libfreetype6-dev libibus-1.0-dev libiconv-hook-dev libjpeg-dev libjpeg-turbo8-dev libpoppler-dev libpoppler-private-dev libproxy-dev librsvg2-dev libscim-dev libsystemd-dev libtool libudisks2-dev libunibreak-dev libxcb-keysyms1-dev libxine2-dev libxss-dev linux-tools-common libcurl4-openssl-dev systemd ccache git binutils-gold python3-pip ninja-build dbus-x11 libavahi-client-dev python3-setuptools libopenjp2-7-dev +sudo apt-get install -y build-essential autoconf automake autopoint doxygen check luajit libharfbuzz-dev libpng-dev libudev-dev libwebp-dev libssl-dev libluajit-5.1-dev libfribidi-dev libcogl-gles2-dev libgif-dev libtiff5-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libdbus-1-dev libmount-dev libblkid-dev libpulse-dev libxrandr-dev libxtst-dev libxcursor-dev libxcomposite-dev libxinerama-dev libxkbfile-dev libbullet-dev libsndfile1-dev libraw-dev libspectre-dev libpoppler-cpp-dev libpam0g-dev liblz4-dev faenza-icon-theme gettext git imagemagick libasound2-dev libbluetooth-dev libfontconfig1-dev libfreetype6-dev libibus-1.0-dev libiconv-hook-dev libjpeg-dev libjpeg-turbo8-dev libpoppler-dev libpoppler-private-dev libproxy-dev librsvg2-dev libscim-dev libsystemd-dev libtool libudisks2-dev libunibreak-dev libxcb-keysyms1-dev libxss-dev linux-tools-common libcurl4-openssl-dev systemd ccache git binutils-gold python3-pip ninja-build dbus-x11 libavahi-client-dev python3-setuptools libopenjp2-7-dev sudo pip3 install meson diff --git a/meson.build b/meson.build index fb77c43570..256256d8a8 100644 --- a/meson.build +++ b/meson.build @@ -456,9 +456,6 @@ endforeach subdir(join_paths('src', 'bin', 'efl')) subdir(join_paths('src', 'generic', 'evas')) -if sys_windows == false - subdir(join_paths('src', 'generic', 'emotion')) -endif subdir('cmakeconfig') subdir(join_paths('src', 'bindings')) subdir(join_paths('src', 'edje_external')) diff --git a/meson_options.txt b/meson_options.txt index 2c6d138981..0907aff980 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -122,7 +122,7 @@ option('g-mainloop', option('gstreamer', type : 'boolean', value : true, - description : 'GStreamer 1.0+ support in efl' + description : 'GStreamer support in efl' ) option('systemd', @@ -200,20 +200,6 @@ option('ecore-imf-loaders-disabler', value : ['ibus'] ) -option('emotion-loaders-disabler', - type : 'array', - description : 'List of video back-ends to disable in efl', - choices : ['gstreamer1', 'libvlc', 'xine'], - value : ['libvlc', 'xine'] -) - -option('emotion-generic-loaders-disabler', - type : 'array', - description : 'List of out-of-process generic binary video loaders to disable in efl', - choices : ['vlc'], - value : ['vlc'] -) - option('harfbuzz', type : 'boolean', value : true, diff --git a/src/generic/emotion/meson.build b/src/generic/emotion/meson.build deleted file mode 100644 index 58cd5294aa..0000000000 --- a/src/generic/emotion/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -generic_loaders = ['vlc'] - -foreach loader : generic_loaders - if get_option('emotion-generic-loaders-disabler').contains(loader) == false - subdir(loader) - endif -endforeach - diff --git a/src/generic/emotion/vlc/emotion_generic_vlc.c b/src/generic/emotion/vlc/emotion_generic_vlc.c deleted file mode 100644 index dcfcbe9e8c..0000000000 --- a/src/generic/emotion/vlc/emotion_generic_vlc.c +++ /dev/null @@ -1,789 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -static int _em_vlc_log_dom = -1; -#define ERR(...) EINA_LOG_DOM_ERR(_em_vlc_log_dom, __VA_ARGS__) -#define DBG(...) EINA_LOG_DOM_DBG(_em_vlc_log_dom, __VA_ARGS__) -#define INF(...) EINA_LOG_DOM_INFO(_em_vlc_log_dom, __VA_ARGS__) -#define WRN(...) EINA_LOG_DOM_WARN(_em_vlc_log_dom, __VA_ARGS__) -#define CRIT(...) EINA_LOG_DOM_CRIT(_em_vlc_log_dom, __VA_ARGS__) - - -typedef struct _App App; -struct _App { - Emotion_Generic_Video_Shared *vs; - Emotion_Generic_Video_Frame vf; - - libvlc_instance_t *libvlc; - libvlc_media_t *m; - libvlc_media_player_t *mp; - libvlc_event_manager_t *event_mgr; - - Ecore_Pipe *fd_read; // read commands from emotion here - Ecore_Pipe *fd_write; // write commands for emotion here - Eina_Lock cmd_mutex;// lock used to send just one command at a time - int last_order; // current command received from emotion - - char *filename; - char *subtitle_path; - char *shmname; - unsigned w, h; - int volume; - Eina_Bool audio_muted; - - Eina_Bool opening; - Eina_Bool closing; - Eina_Bool playing; - Eina_Bool inited; -}; - -static void _player_setup(App *app); - - -/* Utilities to send commands back to emotion */ -#define SEND_CMD_PARAM(app, i) \ - if ((app)->fd_write) \ - if (!ecore_pipe_write((app)->fd_write, &(i), sizeof((i)))) \ - ecore_main_loop_quit(); - -static void -_send_cmd(App *app, int cmd) -{ - if (!app->fd_write) - return; - - eina_lock_take(&app->cmd_mutex); /* LOCK HERE */ - - if (!ecore_pipe_write(app->fd_write, &cmd, sizeof(cmd))) - ecore_main_loop_quit(); -} - -static void -_send_cmd_str(App *app, const char *str) -{ - int len; - - len = str ? strlen(str) + 1 : 0; - if (app->fd_write) - if (!ecore_pipe_write(app->fd_write, &len, sizeof(len))) - ecore_main_loop_quit(); - if (app->fd_write) - if (!ecore_pipe_write(app->fd_write, str, len)) - ecore_main_loop_quit(); -} - -static void -_send_cmd_finish(App *app) -{ - eina_lock_release(&app->cmd_mutex); /* UNLOCK HERE */ -} - -/* Commands sent to the emotion pipe */ -static void -_send_file_closed(App *app) -{ - _send_cmd(app, EM_RESULT_FILE_CLOSE); - _send_cmd_finish(app); -} - -static void -_send_time_changed(App *app) -{ - float new_time; - - if (app->vs->frame_drop > 1) - return; - - new_time = libvlc_media_player_get_time(app->mp); - new_time /= 1000; - _send_cmd(app, EM_RESULT_POSITION_CHANGED); - SEND_CMD_PARAM(app, new_time); - _send_cmd_finish(app); -} - -static void -_send_resize(App *app, int width, int height) -{ - _send_cmd(app, EM_RESULT_FRAME_SIZE); - SEND_CMD_PARAM(app, width); - SEND_CMD_PARAM(app, height); - _send_cmd_finish(app); -} - -static void -_send_track_info(App *app, int cmd, int current, int count, libvlc_track_description_t *desc) -{ - _send_cmd(app, cmd); - SEND_CMD_PARAM(app, current); - SEND_CMD_PARAM(app, count); - while (desc) - { - int tid = desc->i_id; - const char *name = desc->psz_name; - SEND_CMD_PARAM(app, tid); - _send_cmd_str(app, name); - desc = desc->p_next; - } - _send_cmd_finish(app); -} - -static void -_send_all_track_info(App *app) -{ - int track_count, current; - libvlc_track_description_t *desc; - - current = libvlc_audio_get_track(app->mp); - track_count = libvlc_audio_get_track_count(app->mp); - desc = libvlc_audio_get_track_description(app->mp); - - _send_track_info(app, EM_RESULT_AUDIO_TRACK_INFO, - current, track_count, desc); - - current = libvlc_video_get_track(app->mp); - track_count = libvlc_video_get_track_count(app->mp); - desc = libvlc_video_get_track_description(app->mp); - - _send_track_info(app, EM_RESULT_VIDEO_TRACK_INFO, - current, track_count, desc); - - current = libvlc_video_get_spu(app->mp); - track_count = libvlc_video_get_spu_count(app->mp); - desc = libvlc_video_get_spu_description(app->mp); - - _send_track_info(app, EM_RESULT_SPU_TRACK_INFO, - current, track_count, desc); -} - -static void -_send_all_meta_info(App *app) -{ - const char *meta; - - _send_cmd(app, EM_RESULT_META_INFO); - - /* - * Will send in this order: title, artist, album, year, - * genre, comments, disc id and track count. - */ - meta = libvlc_media_get_meta(app->m, libvlc_meta_Title); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Artist); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Album); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Date); - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_Genre); - _send_cmd_str(app, meta); - meta = NULL; // sending empty comments - _send_cmd_str(app, meta); - meta = NULL; // sending empty disc id - _send_cmd_str(app, meta); - meta = libvlc_media_get_meta(app->m, libvlc_meta_TrackNumber); - _send_cmd_str(app, meta); - - _send_cmd_finish(app); -} - -static void -_send_length_changed(App *app) -{ - float length = libvlc_media_player_get_length(app->mp); - - length /= 1000; - _send_cmd(app, EM_RESULT_LENGTH_CHANGED); - SEND_CMD_PARAM(app, length); - _send_cmd_finish(app); -} - -static void -_send_seekable_changed(App *app, const struct libvlc_event_t *ev) -{ - int seekable = ev->u.media_player_seekable_changed.new_seekable; - - _send_cmd(app, EM_RESULT_SEEKABLE_CHANGED); - SEND_CMD_PARAM(app, seekable); - _send_cmd_finish(app); -} - -static void -_send_playback_started(App *app) -{ - _send_cmd(app, EM_RESULT_PLAYBACK_STARTED); - _send_cmd_finish(app); -} - -static void -_send_playback_stopped(App *app) -{ - _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED); - _send_cmd_finish(app); -} - -static void -_send_init(App *app) -{ - _send_cmd(app, EM_RESULT_INIT); - _send_cmd_finish(app); -} - -static void -_send_file_set(App *app) -{ - _send_cmd(app, EM_RESULT_FILE_SET); - _send_cmd_finish(app); -} - -static void -_send_file_set_done(App *app, int success) -{ - _send_cmd(app, EM_RESULT_FILE_SET_DONE); - SEND_CMD_PARAM(app, success); - _send_cmd_finish(app); -} - - -/* VLC events and callbacks */ -static void -_event_cb(const struct libvlc_event_t *ev, void *data) -{ - App *app = data; - - ecore_thread_main_loop_begin(); - switch (ev->type) - { - case libvlc_MediaPlayerTimeChanged: - // DBG("libvlc_MediaPlayerTimeChanged"); - _send_time_changed(app); - break; - case libvlc_MediaPlayerLengthChanged: - DBG("libvlc_MediaPlayerLengthChanged"); - _send_length_changed(app); - break; - case libvlc_MediaPlayerSeekableChanged: - DBG("libvlc_MediaPlayerSeekableChanged"); - _send_seekable_changed(app, ev); - break; - case libvlc_MediaPlayerPlaying: - DBG("libvlc_MediaPlayerPlaying"); - libvlc_audio_set_volume(app->mp, app->volume); - libvlc_audio_set_mute(app->mp, app->audio_muted); - _send_playback_started(app); - break; - case libvlc_MediaPlayerStopped: - DBG("libvlc_MediaPlayerStopped"); - _send_playback_stopped(app); - if (app->closing) - { - free(app->filename); - app->filename = NULL; - free(app->subtitle_path); - app->subtitle_path = NULL; - libvlc_media_release(app->m); - app->m = NULL; - libvlc_media_player_release(app->mp); - app->mp = NULL; - emotion_generic_shm_free(app->vs); - app->playing = EINA_FALSE; - app->closing = EINA_FALSE; - _send_file_closed(app); - } - break; - case libvlc_MediaPlayerEndReached: - DBG("libvlc_MediaPlayerEndReached"); - app->playing = EINA_FALSE; - /* vlc had released the media_playere here, we create a new one */ - app->mp = libvlc_media_player_new_from_media(app->m); - _player_setup(app); - _send_playback_stopped(app); - break; - } - ecore_thread_main_loop_end(); -} - -static void -_tmp_playing_event_cb(const struct libvlc_event_t *ev, void *data) -{ - App *app = data; - - if (ev->type != libvlc_MediaPlayerPlaying) - return; - - /* pause and stop listening the temporary event */ - libvlc_event_detach(app->event_mgr,libvlc_MediaPlayerPlaying, - _tmp_playing_event_cb, app); - libvlc_media_player_set_pause(app->mp, 1); - - /* sending size info */ - libvlc_video_get_size(app->mp, 0, &app->w, &app->h); - _send_resize(app, app->w, app->h); - - /* sending total lenght */ - _send_length_changed(app); - - /* sending audio track info */ - _send_all_track_info(app); - - /* sending meta info */ - _send_all_meta_info(app); - - /* ok, we are done! Now let emotion create the shmem for us */ - _send_file_set(app); -} - -static void * -_lock(void *data, void **pixels) -{ - App *app = data; - - if (app->playing) - *pixels = app->vf.frames[app->vs->frame.player]; - else - *pixels = NULL; - - return NULL; // picture identifier, not needed here -} - -static void -_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED) -{ -} - -static void -_display(void *data, void *id EINA_UNUSED) -{ - App *app = data; - - if (!app->playing) - return; - - eina_semaphore_lock(&app->vs->lock); - app->vs->frame.last = app->vs->frame.player; - app->vs->frame.player = app->vs->frame.next; - app->vs->frame.next = app->vs->frame.last; - if (!app->vs->frame_drop++) - { - _send_cmd(app, EM_RESULT_FRAME_NEW); - _send_cmd_finish(app); - } - eina_semaphore_release(&app->vs->lock, 1); -} - -static void -_player_setup(App *app) -{ - - libvlc_video_set_format(app->mp, "RV32", app->w, app->h, app->w * 4); - libvlc_video_set_callbacks(app->mp, _lock, _unlock, _display, app); - - app->event_mgr = libvlc_media_player_event_manager(app->mp); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPlaying, - _event_cb, app); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerTimeChanged, - _event_cb, app); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerLengthChanged, - _event_cb, app); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerSeekableChanged, - _event_cb, app); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerEndReached, - _event_cb, app); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerStopped, - _event_cb, app); -} - -/* Commands received from the emotion pipe */ -static void -_file_set(App *app) -{ - DBG("Path: %s", app->filename); - app->m = libvlc_media_new_path(app->libvlc, app->filename); - if (!app->m) - { - ERR("could not open path: \"%s\"", app->filename); - return; - } - - app->mp = libvlc_media_player_new_from_media(app->m); - if (!app->mp) - { - ERR("could not create new player from media."); - return; - } - - app->opening = EINA_TRUE; - - /* Here we start playing and connect a temporary callback to know when - * the file is parsed and ready to be played for real. - */ - app->event_mgr = libvlc_media_player_event_manager(app->mp); - libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPlaying, - _tmp_playing_event_cb, app); - - libvlc_media_player_play(app->mp); -} - -static void -_file_set_done(App *app) -{ - int r; - - DBG("Path: %s", app->filename); - app->opening = EINA_FALSE; - - r = emotion_generic_shm_get(app->shmname, &app->vs, &app->vf); - if (!r) - { - free(app->filename); - libvlc_media_release(app->m); - libvlc_media_player_release(app->mp); - app->filename = NULL; - app->m = NULL; - app->mp = NULL; - } - else - { - _player_setup(app); - } - - _send_file_set_done(app, r); -} - -static void -_file_close(App *app) -{ - DBG("closing file"); - - if (!app->mp) - return; - - app->closing = EINA_TRUE; - libvlc_media_player_stop(app->mp); -} - -static void -_stop(App *app) -{ - DBG("Stop"); - if (app->mp) - libvlc_media_player_set_pause(app->mp, 1); -} - -static void -_play(App *app, float pos) -{ - DBG("Play at %.3f", pos); - - if (!app->mp) - return; - - if (app->playing) - { - libvlc_media_player_set_pause(app->mp, 0); - } - else - { - libvlc_time_t new_time = pos * 1000; - libvlc_media_player_set_time(app->mp, new_time); - libvlc_media_player_play(app->mp); - - if (app->subtitle_path) - libvlc_video_set_subtitle_file(app->mp, app->subtitle_path); - - app->playing = EINA_TRUE; - } -} - -static void -_position_set(App *app, float position) -{ - libvlc_time_t new_time; - - DBG("Position set %.3f", position); - if (!app->mp) - return; - - new_time = position * 1000; - libvlc_media_player_set_time(app->mp, new_time); - - if (libvlc_media_player_get_state(app->mp) == libvlc_Paused) - _send_time_changed(app); -} - -static void -_speed_set(App *app, float rate) -{ - DBG("Speed set %.3f", rate); - if (!app->mp) - return; - - libvlc_media_player_set_rate(app->mp, rate); -} - -static void -_mute_set(App *app, int mute) -{ - DBG("Mute %d", mute); - if (!app->mp) - return; - - app->audio_muted = mute; - libvlc_audio_set_mute(app->mp, mute); -} - -static void -_volume_set(App *app, float volume) -{ - DBG("Volume set %.2f", volume); - if (!app->mp) - return; - - app->volume = volume * 100; - libvlc_audio_set_volume(app->mp, app->volume); -} - -static void -_spu_track_set(App *app, int track) -{ - DBG("SPU track %d", track); - libvlc_video_set_spu(app->mp, track); -} - -static void -_audio_track_set(App *app, int track) -{ - DBG("Audio track %d", track); - libvlc_audio_set_track(app->mp, track); -} - -static void -_video_track_set(App *app, int track) -{ - DBG("Video Track %d", track); - libvlc_video_set_track(app->mp, track); -} - -static void -_remote_command(void *data, void *buffer, unsigned int nbyte) -{ - App *app = data; - - if (nbyte == 0) - { - ecore_main_loop_quit(); - return ; - } - - if (app->last_order == EM_CMD_LAST) - { - if (nbyte != sizeof (int)) - { - ERR("didn't receive a valid command from emotion (%i) !", nbyte); - ecore_main_loop_quit(); - return ; - } - - app->last_order = *((int*) buffer); - - if (!app->inited && - app->last_order != EM_CMD_INIT) - { - ERR("wrong init command!"); - ecore_main_loop_quit(); - return ; - } - - switch (app->last_order) - { - case EM_CMD_FILE_SET: - if (app->opening) - { - libvlc_media_release(app->m); - libvlc_media_player_release(app->mp); - free(app->filename); - app->opening = EINA_FALSE; - } - break; - case EM_CMD_FILE_SET_DONE: - _file_set_done(app); - app->last_order = EM_CMD_LAST; - break; - case EM_CMD_FILE_CLOSE: - _file_close(app); - app->last_order = EM_CMD_LAST; - break; - case EM_CMD_STOP: - _stop(app); - app->last_order = EM_CMD_LAST; - break; - } - } - else - { - switch (app->last_order) - { - case EM_CMD_INIT: - app->shmname = strdup(buffer); - app->inited = EINA_TRUE; - _send_init(app); - break; - case EM_CMD_FILE_SET: - app->filename = strdup(buffer); - _file_set(app); - break; - case EM_CMD_SUBTITLE_SET: - app->subtitle_path = strdup(buffer); - break; - case EM_CMD_PLAY: - _play(app, *(float*) buffer); - break; - case EM_CMD_POSITION_SET: - _position_set(app, *(float*) buffer); - break; - case EM_CMD_SPEED_SET: - _speed_set(app, *(float*) buffer); - break; - case EM_CMD_AUDIO_MUTE_SET: - _mute_set(app, *(int*) buffer); - break; - case EM_CMD_VOLUME_SET: - _volume_set(app, *(float*) buffer); - break; - case EM_CMD_SPU_TRACK_SET: - _spu_track_set(app, *(int*) buffer); - break; - case EM_CMD_AUDIO_TRACK_SET: - _audio_track_set(app, *(int*) buffer); - break; - case EM_CMD_VIDEO_TRACK_SET: - _video_track_set(app, *(int*) buffer); - break; - } - app->last_order = EM_CMD_LAST; - } -} - -static void -_dummy(void *data EINA_UNUSED, void *buffer EINA_UNUSED, unsigned int nbyte EINA_UNUSED) -{ - /* This function is useless for the pipe we use to send message back - to emotion, but still needed */ -} - -/* Main */ -static Eina_Bool -exit_func(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED) -{ - DBG("Quit signal received !"); - ecore_main_loop_quit(); - return EINA_TRUE; -} - -int -main(int argc, const char *argv[]) -{ - App app; - Ecore_Event_Handler *hld; - int vlc_argc; - - const char *vlc_argv[] = - { - "--quiet", - "--intf", "dummy", /* no interface */ - "--vout", "dummy", /* we don't want video (output) */ - "--no-video-title-show", /* nor the filename displayed */ - "--no-sub-autodetect-file", /* we don't want automatic subtitles */ - "--no-stats", /* no stats */ - "--no-inhibit", /* we don't want interfaces */ - "--no-disable-screensaver", /* we don't want interfaces */ -// XXX: causes newer vlcs to segv! -// "--codec", "avcodec", -// XXX: disable this just in case -// "--demux", "avformat" - }; - vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); - - memset(&app, 0, sizeof(app)); - if (!eina_init()) - { - EINA_LOG_CRIT("Can't initialize generic vlc player, eina failed."); - return -1; - } - - _em_vlc_log_dom = eina_log_domain_register("emotion_generic_vlc", - EINA_COLOR_CYAN); - if (_em_vlc_log_dom < 0) - { - EINA_LOG_CRIT("Unable to register emotion_generic_vlc log domain."); - goto error; - } - - if (!eina_log_domain_level_check(_em_vlc_log_dom, EINA_LOG_LEVEL_WARN)) - eina_log_domain_level_set("emotion_generic_vlc", EINA_LOG_LEVEL_WARN); - - if (argc < 3) - { - ERR("missing parameters."); - ERR("syntax:\n\t%s ", argv[0]); - goto error; - } - - ecore_init(); - - eina_lock_new(&app.cmd_mutex); - - app.fd_read = ecore_pipe_full_add(_remote_command, &app, - atoi(argv[1]), -1, EINA_FALSE, EINA_FALSE); - app.fd_write = ecore_pipe_full_add(_dummy, NULL, - -1, atoi(argv[2]), EINA_FALSE, EINA_FALSE); - - hld = ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP, exit_func, NULL); - - app.libvlc = libvlc_new(vlc_argc, vlc_argv); - app.mp = NULL; - app.filename = NULL; - app.subtitle_path = NULL; - app.w = 0; - app.h = 0; - app.opening = EINA_FALSE; - app.playing = EINA_FALSE; - app.inited = EINA_FALSE; - app.last_order = EM_CMD_LAST; - - ecore_main_loop_begin(); - - libvlc_release(app.libvlc); - ecore_pipe_del(app.fd_read); - ecore_pipe_del(app.fd_write); - ecore_event_handler_del(hld); - eina_lock_free(&app.cmd_mutex); - - ecore_shutdown(); - eina_shutdown(); - return 0; - - error: - eina_shutdown(); - return -1; -} -#undef SEND_CMD_PARAM diff --git a/src/generic/emotion/vlc/meson.build b/src/generic/emotion/vlc/meson.build deleted file mode 100644 index b21f4a16df..0000000000 --- a/src/generic/emotion/vlc/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -vlc = dependency('libvlc') - -executable('vlc', - 'emotion_generic_vlc.c', - dependencies: [emotion_generic, eina, ecore, rt, vlc], - install: true, - install_dir: join_paths(dir_lib, 'emotion', 'generic_players', version_name) -) diff --git a/src/generic/evas/meson.build b/src/generic/evas/meson.build index 2e5b58ae4c..e651b8b16a 100644 --- a/src/generic/evas/meson.build +++ b/src/generic/evas/meson.build @@ -1,8 +1,8 @@ -generic_loaders = ['gst', 'pdf', -'ps', -'raw', -'rsvg', -'xcf'] +generic_loaders = [ 'pdf', 'ps', 'raw', 'rsvg', 'xcf' ] + +if get_option('gstreamer') == true + generic_loaders += [ 'gst' ] +endif generic_src = [] generic_deps = [] diff --git a/src/modules/emotion/generic/Emotion_Generic_Plugin.h b/src/modules/emotion/generic/Emotion_Generic_Plugin.h deleted file mode 100644 index 96b69f6421..0000000000 --- a/src/modules/emotion/generic/Emotion_Generic_Plugin.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef EMOTION_GENERIC_PLUGIN_H -#define EMOTION_GENERIC_PLUGIN_H - -#include -#include -#include -#include -#include - -#include - -#define DEFAULTWIDTH 320 -#define DEFAULTHEIGHT 240 -#define DEFAULTPITCH 4 - -typedef enum _Emotion_Generic_Cmd Emotion_Generic_Cmd; -typedef enum _Emotion_Generic_Result Emotion_Generic_Result; -typedef struct _Emotion_Generic_Video_Frame Emotion_Generic_Video_Frame; -typedef struct _Emotion_Generic_Video_Shared Emotion_Generic_Video_Shared; - -enum _Emotion_Generic_Cmd -{ - EM_CMD_INIT = 0, // 0 param: shared memory identifier (string) - EM_CMD_PLAY, // 1 param: position (float) - EM_CMD_STOP, // 2 param: none - EM_CMD_FILE_SET, // 3 param: filename (string) - EM_CMD_FILE_SET_DONE, // 4 param: none - EM_CMD_FILE_CLOSE, // 5 param: none - EM_CMD_POSITION_SET, // 6 param: position (float) - EM_CMD_SPEED_SET, // 7 param: speed (float) - EM_CMD_AUDIO_MUTE_SET, // 8 param: muted (int) - EM_CMD_VIDEO_MUTE_SET, // 9 param: muted (int) - EM_CMD_SPU_MUTE_SET, // 10 param: muted (int) - EM_CMD_VOLUME_SET, // 11 param: volume (float) - EM_CMD_AUDIO_TRACK_SET, // 12 param: track id (int) - EM_CMD_VIDEO_TRACK_SET, // 13 param: track id (int) - EM_CMD_SPU_TRACK_SET, // 14 param: track id (int) - EM_CMD_SUBTITLE_SET, // 15 param: subtitle filename (string) - EM_CMD_LAST -}; - -enum _Emotion_Generic_Result -{ - EM_RESULT_INIT = 0, // param: none - EM_RESULT_FILE_SET, // param: none - EM_RESULT_FILE_SET_DONE, // param: success (int) - EM_RESULT_PLAYBACK_STARTED, // param: none - EM_RESULT_PLAYBACK_STOPPED, // param: none - EM_RESULT_FILE_CLOSE, // param: none - EM_RESULT_FRAME_NEW, // param: none - EM_RESULT_FRAME_SIZE, // param: int, int (width, height) - EM_RESULT_LENGTH_CHANGED, // param: float - EM_RESULT_POSITION_CHANGED, // param: float - EM_RESULT_SEEKABLE_CHANGED, // param: int - EM_RESULT_AUDIO_TRACK_INFO, // param: current track, track count, track_id, track_name, track_id2, track_name2, ... - EM_RESULT_VIDEO_TRACK_INFO, // param: current track, track count, track_id, track_name, track_id2, track_name2, ... - EM_RESULT_SPU_TRACK_INFO, // param: current spu, spu count, spu_id, spu_name, spu_id2, spu_name2, ... - // (int, int, int, string, int, string, ...) - EM_RESULT_META_INFO, // param: title, artist, album, year, genre, comments, disc id, count (all int) - EM_RESULT_LAST -}; - -/* structure for frames 2 buffers to keep integrity */ -struct _Emotion_Generic_Video_Frame -{ - unsigned char *frames[3]; -}; - -/* structure for frames 2 buffers to keep integrity */ -struct _Emotion_Generic_Video_Shared -{ - int size; - int width; - int height; - int pitch; - /** - * - "emotion" is the frame from where the Emotion process is reading pixels. - * The player shouldn't touch this frame. - * - "player" is the frame where the slave process is writing pixels. - * The emotion process shouldn't touch this frame. - * - "last" is the last frame that was rendered by the player. Emotion will - * use this frame the next time it will fetch pixels to Evas. - * - "next" is the unused frame. The player currently using the "player" - * should, after finishing this frame, set "last" to "player", and "player" - * to "next", and finally "next" to "last" so this operation can be done - * many times in case that Emotion does not request pixels fast enough. - */ - struct { - int emotion; - int player; - int last; - int next; - } frame; - Eina_Semaphore lock; - int frame_drop; -}; - -static inline int -emotion_generic_shm_get(const char *shmname, Emotion_Generic_Video_Shared **vs, Emotion_Generic_Video_Frame *vf) -{ - int shmfd = -1; - int size; - Emotion_Generic_Video_Shared *t_vs; - - shmfd = shm_open(shmname, O_RDWR, 0700); - if (shmfd == -1) - { - fprintf(stderr, "player: could not open shm: %s: %s\n", - shmname, strerror(errno)); - return 0; - } - - t_vs = mmap(NULL, sizeof(*t_vs), PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); - if (t_vs == MAP_FAILED) - { - fprintf(stderr, "player: could not map shared memory: %s\n", - strerror(errno)); - close(shmfd); - return 0; - } - size = t_vs->size; - munmap(t_vs, sizeof(*t_vs)); - t_vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); - if (t_vs == MAP_FAILED) - { - fprintf(stderr, "player: could not map shared memory: %s\n", - strerror(errno)); - close(shmfd); - return 0; - } - close(shmfd); - - vf->frames[0] = (unsigned char *)t_vs + sizeof(*t_vs); - vf->frames[1] = (unsigned char *)t_vs + sizeof(*t_vs) + t_vs->height * t_vs->width * t_vs->pitch; - vf->frames[2] = (unsigned char *)t_vs + sizeof(*t_vs) + 2 * t_vs->height * t_vs->width * t_vs->pitch; - - *vs = t_vs; - - return 1; -} - -static inline void -emotion_generic_shm_free(Emotion_Generic_Video_Shared *vs) -{ - munmap(vs, vs->size); -} - -#endif // EMOTION_GENERIC_PLUGIN_H diff --git a/src/modules/emotion/generic/README b/src/modules/emotion/generic/README deleted file mode 100644 index c2a028de5d..0000000000 --- a/src/modules/emotion/generic/README +++ /dev/null @@ -1,79 +0,0 @@ -Generic - emotion backend -========================= - -This generic player backend executes a separate player in another -process. It receives the bytes to be drawn on the emotion object through -a shared memory, and communicates with the player through a pipe, using -the player standard input/output. - -The player must communicate with emotion using the defined commands -specified in the Emotion_Generic_Plugin.h. It doesn't need to link -against emotion, just include this file for easier implementation. - - -How does it work? -================= - -When the module is initialized for an emotion object, it starts another process -that runs the specified player. The player command line is specified using: - - emotion_object_module_option_set(object, "player", ); - -A player using libvlc is being provided now, and the generic module internally -checks if the command given was "vlc", in which case it will use this provided -vlc player. - -When a file is set to this object, it will send the file name to the player, and -expect an answer that will tell that the player already decoded a bit of the -file, and the video size is already set on the module, so it can allocate a -shared memory with correct size. - -The module then allocates the memory, sends a message to the player and expect -an answer. After this last answer, the "open_done" signal is sent and the module -knows that it is ready for playing. Commands sent before the module being ready -are now applied (and play is resumed if necessary). - -During this setup stage, info about the file set will be stored in the module, -so commands like meta data get, length get and so will be available to sync -calls like emotion_object_play_length_get(); - -If the player dies for any reason, a "decode_stop" signal is sent (should change -to something more like an error signal), and if play is called again, it will be -restarted. The playback should start from the same point it was before the -player crashed, if the player supports seek on the current media format). - -TODO -==== - - - Provide better description for commands; - - Explain in details the communication emotion <-> player; - - Make more common functions for players; - - (maybe) add support for named pipes, so we don't rely on standard in/out - for communication; - - Add a detection on the player to know that the emotion process died (so it - can just exit); - - shmname should contain the child pid too; - - better names for commands, maybe add namespace everywhere; - - -questions -========= - - - Using semaphores to lock the critical region between process, and pthread - mutexes for the threads inside the player. Should move to only one type - (semphores or mutexes)? - - There are 2 inline functions insde Emotion_Generic_Plugin.h to make it easier - for the player to get the shared memory correctly. Any problem with this? - Would be good to add more functions/macros to make common tasks like - parsing commands there too? - - Should move players to another project (outside of emotion)? - - -problems -======== - - file_set has some critical time when file is not set yet when we can't call - some functions (I think only another file_set now); - - communication player -> emotion depends on '\n' to delimitate commands, will - remove this soon (fix this urgently!); - - need to implement missing APIs; - diff --git a/src/modules/emotion/generic/emotion_generic.c b/src/modules/emotion/generic/emotion_generic.c deleted file mode 100644 index 601e9e2d92..0000000000 --- a/src/modules/emotion/generic/emotion_generic.c +++ /dev/null @@ -1,1908 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "emotion_modules.h" -#include "emotion_generic.h" - -static Eina_Prefix *pfx = NULL; -static Eina_List *_generic_players = NULL; -static int _emotion_init_count = 0; - -static int _emotion_generic_log_domain = -1; -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_emotion_generic_log_domain, __VA_ARGS__) - -#ifdef INF -#undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_emotion_generic_log_domain, __VA_ARGS__) - -#ifdef WRN -#undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_emotion_generic_log_domain, __VA_ARGS__) - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_emotion_generic_log_domain, __VA_ARGS__) - -#ifdef CRI -#undef CRI -#endif -#define CRI(...) EINA_LOG_DOM_CRIT(_emotion_generic_log_domain, __VA_ARGS__) - - -static Eina_Bool _fork_and_exec(Emotion_Generic_Video *ev); -static void em_partial_shutdown(Emotion_Generic_Video *ev); - - -static void -_player_send_cmd(Emotion_Generic_Video *ev, int cmd) -{ - if (cmd >= EM_CMD_LAST) - { - ERR("invalid command to player."); - return; - } - if (!ev->fd_write) - { - ERR("you should wait for emotion to be ready to take action."); - return; - } - ecore_pipe_write(ev->fd_write, &cmd, sizeof(cmd)); -} - -static void -_player_send_int(Emotion_Generic_Video *ev, int number) -{ - if (!ev->fd_write) - { - ERR("you should wait for emotion to be ready to take action."); - return; - } - ecore_pipe_write(ev->fd_write, &number, sizeof(number)); -} - -static void -_player_send_float(Emotion_Generic_Video *ev, float number) -{ - if (!ev->fd_write) - { - ERR("you should wait for emotion to be ready to take action."); - return; - } - ecore_pipe_write(ev->fd_write, &number, sizeof(number)); -} - -static void -_player_send_str(Emotion_Generic_Video *ev, const char *str, Eina_Bool stringshared) -{ - int len; - - if (stringshared) - len = str ? eina_stringshare_strlen(str) + 1 : 0; - else - len = str ? strlen(str) + 1 : 0; - - if (str) - ecore_pipe_write(ev->fd_write, str, len); -} - -static Eina_Bool -_create_shm_data(Emotion_Generic_Video *ev, const char *shmname) -{ - int shmfd; - int npages; - size_t size; - Emotion_Generic_Video_Shared *vs; - - shmfd = shm_open(shmname, O_CREAT | O_RDWR | O_TRUNC, 0700); - if (shmfd == -1) - { - ERR("player: could not create shm %s: %s", shmname, strerror(errno)); - return 0; - } - size = 3 * (ev->w * ev->h * DEFAULTPITCH) + sizeof(*vs); - - npages = (int)(size / getpagesize()) + 1; - size = npages * getpagesize(); - - if (ftruncate(shmfd, size)) - { - ERR("error when allocating shared memory (size = %zd): " - "%s", size, strerror(errno)); - close(shmfd); - shm_unlink(shmname); - return EINA_FALSE; - } - vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); - if (vs == MAP_FAILED) - { - ERR("error when mapping shared memory: %s", strerror(errno)); - close(shmfd); - shm_unlink(shmname); - return EINA_FALSE; - } - close(shmfd); - - vs->size = size; - vs->width = ev->w; - vs->height = ev->h; - vs->pitch = DEFAULTPITCH; - vs->frame.emotion = 0; - vs->frame.player = 1; - vs->frame.last = 2; - vs->frame.next = 2; - vs->frame_drop = 0; - if (!eina_semaphore_new(&vs->lock, 1)) - { - ERR("can not create semaphore"); - munmap(vs, size); - shm_unlink(shmname); - return EINA_FALSE; - } - ev->frame.frames[0] = (unsigned char *)vs + sizeof(*vs); - ev->frame.frames[1] = (unsigned char *)vs + sizeof(*vs) + vs->height * vs->width * vs->pitch; - ev->frame.frames[2] = (unsigned char *)vs + sizeof(*vs) + 2 * vs->height * vs->width * vs->pitch; - - if (ev->shared) - munmap(ev->shared, ev->shared->size); - ev->shared = vs; - - return EINA_TRUE; -} - -static void -_player_new_frame(Emotion_Generic_Video *ev) -{ - if (!ev->file_ready) - return; - _emotion_frame_new(ev->obj); -} - -static void -_file_open(Emotion_Generic_Video *ev) -{ - INF("Opening file: %s", ev->filename); - ev->drop = 0; - - if (!ev->ready || !ev->filename) - return; - _player_send_cmd(ev, EM_CMD_FILE_SET); - _player_send_str(ev, ev->filename, EINA_TRUE); -} - -static void -_player_file_set_done(Emotion_Generic_Video *ev) -{ - if (ev->file_changed) - { - _file_open(ev); - ev->file_changed = EINA_FALSE; - return; - } - - if (!_create_shm_data(ev, ev->shmname)) - { - ERR("could not create shared memory."); - return; - } - _player_send_cmd(ev, EM_CMD_FILE_SET_DONE); -} - -static void -_player_ready(Emotion_Generic_Video *ev) -{ - INF("received: player ready."); - - ev->initializing = EINA_FALSE; - ev->ready = EINA_TRUE; - - if (!ev->filename) - return; - - _file_open(ev); -} - -static Eina_Bool -_player_cmd_param_read(Emotion_Generic_Video *ev, void *param, size_t size) -{ - ssize_t done, todo, i; - - /* When a parameter must be read, we cannot make sure it will be entirely - * available. Thus we store the bytes that could be read in a temp buffer, - * and when more data is read we try to complete the buffer and finally use - * the read value. - */ - if (!ev->cmd.tmp) - { - ev->cmd.tmp = malloc(size); - ev->cmd.i = 0; - ev->cmd.total = size; - } - - todo = ev->cmd.total - ev->cmd.i; - i = ev->cmd.i; - - done = (ev->offset + todo > ev->length) ? ev->length - ev->offset : todo; - memcpy(&ev->cmd.tmp[i], &ev->buffer[ev->offset], done); - ev->offset += done; - - if (done == todo) - { - memcpy(param, ev->cmd.tmp, size); - free(ev->cmd.tmp); - ev->cmd.tmp = NULL; - return EINA_TRUE; - } - - if (done > 0) - ev->cmd.i += done; - - return EINA_FALSE; -} - -static void -_player_frame_resize(Emotion_Generic_Video *ev) -{ - int w, h; - - w = ev->cmd.param.size.width; - h = ev->cmd.param.size.height; - - INF("received frame resize: %dx%d", w, h); - ev->w = w; - ev->h = h; - ev->ratio = (float)w / h; - - _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio); -} - -static void -_player_length_changed(Emotion_Generic_Video *ev) -{ - float length = ev->cmd.param.f_num; - - INF("received length changed: %0.3f", length); - - ev->len = length; - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); -} - -static void -_player_position_changed(Emotion_Generic_Video *ev) -{ - float position = ev->cmd.param.f_num; - - // INF("received position changed: %0.3f", position); - - ev->pos = position; - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); -/* hmmm. no _emotion_progress_set() is for "buffering" progress. - if (ev->len == 0) - return; - - float progress = ev->pos / ev->len; - char buf[16]; - snprintf(buf, sizeof(buf), "%0.1f%%", progress * 100); - - _emotion_progress_set(ev->obj, buf, progress); - */ -} - -static void -_player_seekable_changed(Emotion_Generic_Video *ev) -{ - int seekable = ev->cmd.param.i_num; - - INF("received seekable changed: %d", seekable); - - seekable = !!seekable; - - ev->seekable = seekable; -} - -static void -_audio_channels_free(Emotion_Generic_Video *ev) -{ - int i; - for (i = 0; i < ev->audio_channels_count; i++) - eina_stringshare_del(ev->audio_channels[i].name); - free(ev->audio_channels); - ev->audio_channels = NULL; - ev->audio_channels_count = 0; -} - -static void -_video_channels_free(Emotion_Generic_Video *ev) -{ - int i; - for (i = 0; i < ev->video_channels_count; i++) - eina_stringshare_del(ev->video_channels[i].name); - free(ev->video_channels); - ev->video_channels = NULL; - ev->video_channels_count = 0; -} - -static void -_spu_channels_free(Emotion_Generic_Video *ev) -{ - int i; - for (i = 0; i < ev->spu_channels_count; i++) - eina_stringshare_del(ev->spu_channels[i].name); - free(ev->spu_channels); - ev->spu_channels = NULL; - ev->spu_channels_count = 0; -} - -static void -_player_tracks_info(Emotion_Generic_Video *ev, Emotion_Generic_Channel **channels, int *count, int *current) -{ - Emotion_Generic_Channel *pchannels; - int i; - - *count = ev->cmd.param.track.total; - *current = ev->cmd.param.track.current; - pchannels = ev->cmd.param.track.channels; - - INF("number of tracks: %d (current = %d):", *count, *current); - for (i = 0; i < *count; i++) - { - INF("\tchannel %d: %s", pchannels[i].id, pchannels[i].name); - } - - *channels = pchannels; -} - -static void -_player_audio_tracks_info(Emotion_Generic_Video *ev) -{ - INF("Receiving audio channels:"); - if (ev->audio_channels_count) - _audio_channels_free(ev); - - _player_tracks_info(ev, &ev->audio_channels, &ev->audio_channels_count, - &ev->audio_channel_current); -} - -static void -_player_video_tracks_info(Emotion_Generic_Video *ev) -{ - INF("Receiving video channels:"); - if (ev->video_channels_count) - _video_channels_free(ev); - - _player_tracks_info(ev, &ev->video_channels, &ev->video_channels_count, - &ev->video_channel_current); -} - -static void -_player_spu_tracks_info(Emotion_Generic_Video *ev) -{ - INF("Receiving spu channels:"); - if (ev->spu_channels_count) - _spu_channels_free(ev); - - _player_tracks_info(ev, &ev->spu_channels, &ev->spu_channels_count, - &ev->spu_channel_current); -} - -static void -_player_meta_info_free(Emotion_Generic_Video *ev) -{ - eina_stringshare_replace(&ev->meta.title, NULL); - eina_stringshare_replace(&ev->meta.artist, NULL); - eina_stringshare_replace(&ev->meta.album, NULL); - eina_stringshare_replace(&ev->meta.year, NULL); - eina_stringshare_replace(&ev->meta.genre, NULL); - eina_stringshare_replace(&ev->meta.comment, NULL); - eina_stringshare_replace(&ev->meta.disc_id, NULL); - eina_stringshare_replace(&ev->meta.count, NULL); -} - -static void -_player_meta_info_read(Emotion_Generic_Video *ev) -{ - INF("Receiving meta info:"); - _player_meta_info_free(ev); - ev->meta.title = ev->cmd.param.meta.title; - ev->meta.artist = ev->cmd.param.meta.artist; - ev->meta.album = ev->cmd.param.meta.album; - ev->meta.year = ev->cmd.param.meta.year; - ev->meta.genre = ev->cmd.param.meta.genre; - ev->meta.comment = ev->cmd.param.meta.comment; - ev->meta.disc_id = ev->cmd.param.meta.disc_id; - ev->meta.count = ev->cmd.param.meta.count; - INF("title: '%s'", ev->meta.title); - INF("artist: '%s'", ev->meta.artist); - INF("album: '%s'", ev->meta.album); - INF("year: '%s'", ev->meta.year); - INF("genre: '%s'", ev->meta.genre); - INF("comment: '%s'", ev->meta.comment); - INF("disc_id: '%s'", ev->meta.disc_id); - INF("count: '%s'", ev->meta.count); -} - -static void -_player_file_closed(Emotion_Generic_Video *ev) -{ - INF("Closed previous file."); - eina_semaphore_free(&ev->shared->lock); - ev->closing = EINA_FALSE; - - if (ev->opening) - _file_open(ev); -} - -static void -_player_open_done(Emotion_Generic_Video *ev) -{ - int success; - - success = ev->cmd.param.i_num; - shm_unlink(ev->shmname); - - if (ev->file_changed) - { - _file_open(ev); - ev->file_changed = EINA_FALSE; - return; - } - - ev->opening = EINA_FALSE; - if (!success) - { - ERR("Could not open file."); - return; - } - - ev->file_ready = EINA_TRUE; - - _emotion_open_done(ev->obj); - - _player_send_cmd(ev, EM_CMD_VOLUME_SET); - _player_send_float(ev, ev->volume); - - _player_send_cmd(ev, EM_CMD_SPEED_SET); - _player_send_float(ev, ev->speed); - - int mute = ev->audio_mute; - _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET); - _player_send_int(ev, mute); - - mute = ev->video_mute; - _player_send_cmd(ev, EM_CMD_VIDEO_MUTE_SET); - _player_send_int(ev, mute); - - mute = ev->spu_mute; - _player_send_cmd(ev, EM_CMD_SPU_MUTE_SET); - _player_send_int(ev, mute); - - if (ev->play) - { - _player_send_cmd(ev, EM_CMD_PLAY); - _player_send_float(ev, ev->pos); - } - - INF("Open done"); -} - -static void -_player_cmd_process(Emotion_Generic_Video *ev) -{ - switch (ev->cmd.type) { - case EM_RESULT_INIT: - _player_ready(ev); - break; - case EM_RESULT_FRAME_NEW: - _player_new_frame(ev); - break; - case EM_RESULT_FILE_SET: - _player_file_set_done(ev); - break; - case EM_RESULT_FILE_SET_DONE: - _player_open_done(ev); - break; - case EM_RESULT_FILE_CLOSE: - _player_file_closed(ev); - break; - case EM_RESULT_PLAYBACK_STARTED: - _emotion_playback_started(ev->obj); - break; - case EM_RESULT_PLAYBACK_STOPPED: - ev->play = 0; - _emotion_playback_finished(ev->obj); - _emotion_decode_stop(ev->obj); - break; - case EM_RESULT_FRAME_SIZE: - _player_frame_resize(ev); - break; - case EM_RESULT_LENGTH_CHANGED: - _player_length_changed(ev); - break; - case EM_RESULT_POSITION_CHANGED: - _player_position_changed(ev); - break; - case EM_RESULT_SEEKABLE_CHANGED: - _player_seekable_changed(ev); - break; - case EM_RESULT_AUDIO_TRACK_INFO: - _player_audio_tracks_info(ev); - break; - case EM_RESULT_VIDEO_TRACK_INFO: - _player_video_tracks_info(ev); - break; - case EM_RESULT_SPU_TRACK_INFO: - _player_spu_tracks_info(ev); - break; - case EM_RESULT_META_INFO: - _player_meta_info_read(ev); - break; - default: - WRN("received wrong command: %d", ev->cmd.type); - } - - ev->cmd.type = -1; -} - -static void -_player_cmd_single_int_process(Emotion_Generic_Video *ev) -{ - if (!_player_cmd_param_read(ev, &ev->cmd.param.i_num, sizeof(ev->cmd.param.i_num))) - return; - - _player_cmd_process(ev); -} - -static void -_player_cmd_single_float_process(Emotion_Generic_Video *ev) -{ - if (!_player_cmd_param_read(ev, &ev->cmd.param.f_num, sizeof(ev->cmd.param.f_num))) - return; - - _player_cmd_process(ev); -} - -static void -_player_cmd_double_int_process(Emotion_Generic_Video *ev) -{ - int param; - - if (ev->cmd.num_params == 0) - { - ev->cmd.num_params = 2; - ev->cmd.cur_param = 0; - ev->cmd.param.size.width = 0; - ev->cmd.param.size.height = 0; - } - - if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) - return; - - if (ev->cmd.cur_param == 0) - ev->cmd.param.size.width = param; - else - ev->cmd.param.size.height = param; - - ev->cmd.cur_param++; - if (ev->cmd.cur_param == ev->cmd.num_params) - _player_cmd_process(ev); -} - -static void -_player_cmd_track_info(Emotion_Generic_Video *ev) -{ - int param; - int i; - - if (ev->cmd.num_params == 0) - { - ev->cmd.cur_param = 0; - ev->cmd.num_params = 2; - ev->cmd.param.track.channels = NULL; - ev->cmd.s_len = -1; - } - - while (ev->cmd.cur_param < 2) - { - if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) - return; - - if (ev->cmd.cur_param == 0) - ev->cmd.param.track.current = param; - else - { - ev->cmd.param.track.total = param; - ev->cmd.num_params += param * 2; - ev->cmd.param.track.channels = - calloc(param, sizeof(*ev->cmd.param.track.channels)); - } - ev->cmd.cur_param++; - } - - if (ev->cmd.cur_param == ev->cmd.num_params) - { - _player_cmd_process(ev); - return; - } - - i = (ev->cmd.cur_param - 2) / 2; - if ((ev->cmd.cur_param % 2) == 0) // reading track id - { - if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) - return; - ev->cmd.param.track.channels[i].id = param; - ev->cmd.cur_param++; - } - else // reading track name - { - char buf[PATH_MAX]; - - if (ev->cmd.s_len == -1) - { - if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) - return; - ev->cmd.s_len = param; - } - - if (!_player_cmd_param_read(ev, buf, ev->cmd.s_len)) - return; - ev->cmd.param.track.channels[i].name = - eina_stringshare_add_length(buf, ev->cmd.s_len); - ev->cmd.cur_param++; - ev->cmd.s_len = -1; - } - - if (ev->cmd.cur_param == ev->cmd.num_params) - _player_cmd_process(ev); -} - -static void -_player_cmd_meta_info(Emotion_Generic_Video *ev) -{ - int param; - const char *info; - char buf[PATH_MAX]; - - if (ev->cmd.num_params == 0) - { - ev->cmd.cur_param = 0; - ev->cmd.num_params = 8; - ev->cmd.param.meta.title = NULL; - ev->cmd.param.meta.artist = NULL; - ev->cmd.param.meta.album = NULL; - ev->cmd.param.meta.year = NULL; - ev->cmd.param.meta.genre = NULL; - ev->cmd.param.meta.comment = NULL; - ev->cmd.param.meta.disc_id = NULL; - ev->cmd.param.meta.count = NULL; - ev->cmd.s_len = -1; - } - - if (ev->cmd.s_len == -1) - { - if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) - return; - ev->cmd.s_len = param; - } - - if (!_player_cmd_param_read(ev, buf, ev->cmd.s_len)) - return; - - info = eina_stringshare_add_length(buf, ev->cmd.s_len); - ev->cmd.s_len = -1; - - if (ev->cmd.cur_param == 0) - ev->cmd.param.meta.title = info; - else if (ev->cmd.cur_param == 1) - ev->cmd.param.meta.artist = info; - else if (ev->cmd.cur_param == 2) - ev->cmd.param.meta.album = info; - else if (ev->cmd.cur_param == 3) - ev->cmd.param.meta.year = info; - else if (ev->cmd.cur_param == 4) - ev->cmd.param.meta.genre = info; - else if (ev->cmd.cur_param == 5) - ev->cmd.param.meta.comment = info; - else if (ev->cmd.cur_param == 6) - ev->cmd.param.meta.disc_id = info; - else if (ev->cmd.cur_param == 7) - ev->cmd.param.meta.count = info; - - ev->cmd.cur_param++; - - if (ev->cmd.cur_param == 8) - _player_cmd_process(ev); -} - -static void -_player_cmd_read(Emotion_Generic_Video *ev) -{ - if (ev->cmd.type < 0) - { - if (!_player_cmd_param_read(ev, &ev->cmd.type, sizeof(ev->cmd.type))) - return; - ev->cmd.num_params = 0; - } - - switch (ev->cmd.type) { - case EM_RESULT_INIT: - case EM_RESULT_FILE_SET: - case EM_RESULT_PLAYBACK_STARTED: - case EM_RESULT_PLAYBACK_STOPPED: - case EM_RESULT_FILE_CLOSE: - case EM_RESULT_FRAME_NEW: - _player_cmd_process(ev); - break; - case EM_RESULT_FILE_SET_DONE: - case EM_RESULT_SEEKABLE_CHANGED: - _player_cmd_single_int_process(ev); - break; - case EM_RESULT_LENGTH_CHANGED: - case EM_RESULT_POSITION_CHANGED: - _player_cmd_single_float_process(ev); - break; - case EM_RESULT_FRAME_SIZE: - _player_cmd_double_int_process(ev); - break; - case EM_RESULT_AUDIO_TRACK_INFO: - case EM_RESULT_VIDEO_TRACK_INFO: - case EM_RESULT_SPU_TRACK_INFO: - _player_cmd_track_info(ev); - break; - case EM_RESULT_META_INFO: - _player_cmd_meta_info(ev); - break; - - default: - WRN("received wrong command: %d", ev->cmd.type); - ev->cmd.type = -1; - } -} - -static void -_player_cmd_handler_cb(void *data, void *buffer, unsigned int nbyte) -{ - Emotion_Generic_Video *ev = data; - - ev->buffer = buffer; - ev->length = nbyte; - ev->offset = 0; - - _player_cmd_read(ev); - - ev->buffer = NULL; - ev->length = 0; -} - -static Eina_Bool -_player_data_cb(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Exe_Event_Data *ev = event; - Emotion_Generic_Video *evideo = data; - int i; - - if (ev->exe != evideo->player.exe) - { - INF("slave != ev->exe"); - return ECORE_CALLBACK_PASS_ON; - } - - for (i = 0; ev->lines[i].line; i++) - INF("received input from player: \"%s\"", ev->lines[i].line); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_player_add_cb(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Exe_Event_Add *event_add = event; - Ecore_Exe *player = event_add->exe; - Emotion_Generic_Video *ev = data; - - if (ev->player.exe != player) - { - INF("ev->player != player."); - return ECORE_CALLBACK_PASS_ON; - } - - _player_send_cmd(ev, EM_CMD_INIT); - _player_send_str(ev, ev->shmname, EINA_TRUE); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_player_del_cb(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Exe_Event_Del *event_del = event; - Ecore_Exe *player = event_del->exe; - Emotion_Generic_Video *ev = data; - - if (ev->player.exe != player) - { - INF("ev->player != player."); - return ECORE_CALLBACK_PASS_ON; - } - - ERR("player died."); - - ev->player.exe = NULL; - ev->ready = EINA_FALSE; - ev->file_ready = EINA_FALSE; - ecore_pipe_del(ev->fd_read); - ecore_pipe_del(ev->fd_write); - ev->fd_read = NULL; - ev->fd_write = NULL; - _emotion_decode_stop(ev->obj); - - return ECORE_CALLBACK_DONE; -} - -static void -_player_dummy(void *data EINA_UNUSED, - void *buffer EINA_UNUSED, - unsigned int nbyte EINA_UNUSED) -{ -} - -static Eina_Bool -_player_exec(Emotion_Generic_Video *ev) -{ - Ecore_Pipe *in; - Ecore_Pipe *out; - char buf[PATH_MAX]; - - out = ecore_pipe_full_add(_player_dummy, NULL, -1, -1, EINA_TRUE, EINA_FALSE); - if (!out) - { - ERR("could not create pipe for communication emotion -> player: %s", strerror(errno)); - return EINA_FALSE; - } - - in = ecore_pipe_full_add(_player_cmd_handler_cb, ev, -1, -1, EINA_FALSE, EINA_TRUE); - if (!in) - { - ERR("could not create pipe for communication player -> emotion: %s", strerror(errno)); - ecore_pipe_del(in); - ecore_pipe_del(out); - return EINA_FALSE; - } - - snprintf(buf, sizeof(buf), "%s %d %d", ev->engine->path, - ecore_pipe_read_fd(out), - ecore_pipe_write_fd(in)); - - ev->player.exe = ecore_exe_pipe_run( - buf, ECORE_EXE_NOT_LEADER | ECORE_EXE_TERM_WITH_PARENT, ev); - - INF("created pipe emotion -> player: %d -> %d", - ecore_pipe_write_fd(out), ecore_pipe_read_fd(out)); - INF("created pipe player -> emotion: %d -> %d", - ecore_pipe_write_fd(in), ecore_pipe_read_fd(in)); - - ecore_pipe_write_close(in); - ecore_pipe_read_close(out); - - if (!ev->player.exe) - { - ecore_pipe_del(in); - ecore_pipe_del(out); - return EINA_FALSE; - } - - ev->fd_read = in; - ev->fd_write = out; - - return EINA_TRUE; -} - -static Eina_Bool -_fork_and_exec(Emotion_Generic_Video *ev) -{ - char shmname[256]; - - snprintf(shmname, sizeof(shmname), "/em-generic-shm_%d_%p_%f", - getpid(), ev->obj, ecore_time_get()); - - ev->shmname = eina_stringshare_add(shmname); - - ev->player_add = ecore_event_handler_add(ECORE_EXE_EVENT_ADD, - _player_add_cb, ev); - ev->player_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, - _player_del_cb, ev); - ev->player_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA, - _player_data_cb, ev); - - if (!_player_exec(ev)) - { - eina_stringshare_del(ev->shmname); - ecore_event_handler_del(ev->player_add); - ecore_event_handler_del(ev->player_del); - ecore_event_handler_del(ev->player_data); - ERR("could not start player."); - return EINA_FALSE; - } - - ev->initializing = EINA_TRUE; - - return EINA_TRUE; -} - -typedef struct _Delay_Munmap Delay_Munmap; -struct _Delay_Munmap -{ - void *map; - size_t size; -}; - -static void -_delayed_munmap(void *data, Evas *e, void *event_info EINA_UNUSED) -{ - Delay_Munmap *dm = data; - - evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_POST, _delayed_munmap, data); - fprintf(stderr, "munmapping !\n"); - munmap(dm->map, dm->size); - free(dm); -} - -static void -_delayed_next_frame(void *data, Evas *e, void *event_info EINA_UNUSED) -{ - evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, _delayed_munmap, data); - evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_PRE, _delayed_next_frame, data); -} - -static void -em_partial_shutdown(Emotion_Generic_Video *ev) -{ - if (ev->player.exe) - { - ecore_exe_terminate(ev->player.exe); - ecore_exe_free(ev->player.exe); - ev->player.exe = NULL; - } - - ev->file_ready = EINA_FALSE; - - if (ev->shared) - { - Evas_Object *o; - Delay_Munmap *dm; - - dm = malloc(sizeof (Delay_Munmap)); - if (dm) - { - dm->map = ev->shared; - dm->size = ev->shared->size; - evas_event_callback_add(evas_object_evas_get(ev->obj), - EVAS_CALLBACK_RENDER_PRE, - _delayed_next_frame, dm); - } - - o = emotion_object_image_get(ev->obj); - evas_object_image_data_set(o, NULL); - evas_object_image_size_set(o, 1, 1); - } - ev->shared = NULL; - - _emotion_image_reset(ev->obj); - - if (ev->fd_read) - ecore_pipe_del(ev->fd_read); - ev->fd_read = NULL; - if (ev->fd_write) - ecore_pipe_del(ev->fd_write); - ev->fd_write = NULL; - - if (ev->player_add) ecore_event_handler_del(ev->player_add); - ev->player_add = NULL; - if (ev->player_data) ecore_event_handler_del(ev->player_data); - ev->player_data = NULL; - if (ev->player_del) ecore_event_handler_del(ev->player_del); - ev->player_del = NULL; -} - - -/* Emotion interface */ -static void * -em_add(const Emotion_Engine *api, Evas_Object *obj, const Emotion_Module_Options *opt EINA_UNUSED) -{ - Emotion_Generic_Video *ev; - - ev = calloc(1, sizeof(*ev)); - EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL); - - ev->fd_read = NULL; - ev->fd_write = NULL; - ev->speed = 1.0; - ev->volume = 0.8; - ev->audio_mute = EINA_FALSE; - ev->cmd.type = -1; - - ev->obj = obj; - ev->engine = (Emotion_Engine_Generic *)api; - - if (!_fork_and_exec(ev)) - { - free(ev); - return NULL; - } - - return ev; -} - -static void -em_del(void *data) -{ - Emotion_Generic_Video *ev = data; - - eina_stringshare_del(ev->shmname); - - em_partial_shutdown(ev); -} - -static unsigned char -em_file_open(void *data, const char *file) -{ - Emotion_Generic_Video *ev = data; - INF("file set: %s", file); - if (!ev) return 0; - - eina_stringshare_replace(&ev->filename, file); - - ev->pos = 0; - ev->w = 0; - ev->h = 0; - ev->ratio = 1; - ev->len = 0; - - if (ev->ready && ev->opening) - { - INF("file changed while opening."); - ev->file_changed = EINA_TRUE; - return 1; - } - - ev->opening = EINA_TRUE; - - if (!ev->closing) - _file_open(ev); - - return 1; -} - -static void -em_file_close(void *data) -{ - Emotion_Generic_Video *ev = data; - - if (!ev || !ev->filename) return; - - INF("file close: %s", ev->filename); - - eina_stringshare_replace(&ev->filename, NULL); - eina_stringshare_replace(&ev->subtitle_path, NULL); - - ev->file_ready = EINA_FALSE; - _audio_channels_free(ev); - _video_channels_free(ev); - _spu_channels_free(ev); - _player_meta_info_free(ev); - - if (ev->opening) - return; - - _player_send_cmd(ev, EM_CMD_FILE_CLOSE); - ev->closing = EINA_TRUE; -} - -static Emotion_Format -em_format_get(void *ef EINA_UNUSED) -{ - return EMOTION_FORMAT_BGRA; -} - -static void -em_video_data_size_get(void *data, int *w, int *h) -{ - Emotion_Generic_Video *ev = data; - - if (!ev) return; - if (w) *w = ev->w; - if (h) *h = ev->h; -} - -static void -em_play(void *data, double pos) -{ - Emotion_Generic_Video *ev = data; - - if (!ev) - return; - - ev->play = EINA_TRUE; - INF("play: %0.3f", pos); - - if (ev->initializing || ev->opening) - return; - - if (ev->ready) - { - if (ev->subtitle_path) - { - _player_send_cmd(ev, EM_CMD_SUBTITLE_SET); - _player_send_str(ev, ev->subtitle_path, EINA_TRUE); - } - - _player_send_cmd(ev, EM_CMD_PLAY); - _player_send_float(ev, ev->pos); - - return; - } - - if (!_player_exec(ev)) - ERR("could not start player."); -} - -static void -em_stop(void *data) -{ - Emotion_Generic_Video *ev = data; - - if (!ev) - return; - - ev->play = EINA_FALSE; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_STOP); - _emotion_decode_stop(ev->obj); -} - -static void -em_size_get(void *data, int *w, int *h) -{ - Emotion_Generic_Video *ev = data; - if (w) *w = ev->w; - if (h) *h = ev->h; -} - -static void -em_pos_set(void *data, double pos) -{ - Emotion_Generic_Video *ev = data; - float position = pos; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_POSITION_SET); - _player_send_float(ev, position); - _emotion_seek_done(ev->obj); -} - -static double -em_len_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->len; -} - -static double -em_buffer_size_get(void *data EINA_UNUSED) -{ - return 1.0; -} - -static int -em_fps_num_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return (int)(ev->fps * 1000.0); -} - -static int -em_fps_den_get(void *ef EINA_UNUSED) -{ - return 1000; -} - -static double -em_fps_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->fps; -} - -static double -em_pos_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->pos; -} - -static void -em_vis_set(void *ef EINA_UNUSED, Emotion_Vis vis EINA_UNUSED) -{ -} - -static Emotion_Vis -em_vis_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->vis; -} - -static Eina_Bool -em_vis_supported(void *ef EINA_UNUSED, Emotion_Vis vis EINA_UNUSED) -{ - return EINA_FALSE; -} - -static double -em_ratio_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->ratio; -} - -static int -em_video_handled(void *ef EINA_UNUSED) -{ - DBG("video handled!"); - return 1; -} - -static int -em_audio_handled(void *ef EINA_UNUSED) -{ - DBG("audio handled!"); - return 1; -} - -static int -em_seekable(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->seekable; -} - -static void -em_frame_done(void *ef EINA_UNUSED) -{ -} - -static int -em_yuv_rows_get(void *data EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, unsigned char **yrows EINA_UNUSED, unsigned char **urows EINA_UNUSED, unsigned char **vrows EINA_UNUSED) -{ - return 0; -} - -static int -em_bgra_data_get(void *data, unsigned char **bgra_data) -{ - Emotion_Generic_Video *ev = data; - - if (!ev || !ev->file_ready) - return 0; - - // lock frame here - if (!eina_semaphore_lock(&ev->shared->lock)) - return 0; - - // send current frame to emotion - if (ev->shared->frame.emotion != ev->shared->frame.last) - { - ev->shared->frame.next = ev->shared->frame.emotion; - ev->shared->frame.emotion = ev->shared->frame.last; - } - *bgra_data = ev->frame.frames[ev->shared->frame.emotion]; - - if (ev->shared->frame_drop > 1) - WRN("dropped frames: %d", ev->shared->frame_drop - 1); - ev->shared->frame_drop = 0; - - // unlock frame here - eina_semaphore_release(&ev->shared->lock, 1); - ev->drop = 0; - - return 1; -} - -static void -em_event_feed(void *ef EINA_UNUSED, int event EINA_UNUSED) -{ -} - -static void -em_event_mouse_button_feed(void *ef EINA_UNUSED, int button EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) -{ -} - -static void -em_event_mouse_move_feed(void *ef EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) -{ -} - -static int -em_video_channel_count(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->video_channels_count; -} - -static void -em_video_channel_set(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->video_channels_count) - { - WRN("video channel out of range."); - return; - } - - _player_send_cmd(ev, EM_CMD_VIDEO_TRACK_SET); - _player_send_int(ev, ev->video_channels[channel].id); - ev->video_channel_current = channel; -} - -static int -em_video_channel_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->video_channel_current; -} - -static void -em_video_subtitle_file_set(void *data, const char *filepath) -{ - Emotion_Generic_Video *ev = data; - eina_stringshare_replace(&ev->subtitle_path, filepath); -} - -static const char * -em_video_subtitle_file_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->subtitle_path; -} - -static const char * -em_video_channel_name_get(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->video_channels_count) - { - WRN("video channel out of range."); - return NULL; - } - - return ev->video_channels[channel].name; -} - -static void -em_video_channel_mute_set(void *data, int mute) -{ - Emotion_Generic_Video *ev = data; - - ev->video_mute = !!mute; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_VIDEO_MUTE_SET); - _player_send_int(ev, mute); -} - -static int -em_video_channel_mute_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->video_mute; -} - -static int -em_audio_channel_count(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->audio_channels_count; -} - -static void -em_audio_channel_set(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->audio_channels_count) - { - WRN("audio channel out of range."); - return; - } - - _player_send_cmd(ev, EM_CMD_AUDIO_TRACK_SET); - _player_send_int(ev, ev->audio_channels[channel].id); - ev->audio_channel_current = channel; -} - -static int -em_audio_channel_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->audio_channel_current; -} - -static const char * -em_audio_channel_name_get(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->audio_channels_count) - { - WRN("audio channel out of range."); - return NULL; - } - - return ev->audio_channels[channel].name; -} - -static void -em_audio_channel_mute_set(void *data, int mute) -{ - Emotion_Generic_Video *ev = data; - - ev->audio_mute = !!mute; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET); - _player_send_int(ev, mute); -} - -static int -em_audio_channel_mute_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->audio_mute; -} - -static void -em_audio_channel_volume_set(void *data, double vol) -{ - Emotion_Generic_Video *ev = data; - - if (vol > 1.0) vol = 1.0; - if (vol < 0.0) vol = 0.0; - - ev->volume = vol; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_VOLUME_SET); - _player_send_float(ev, ev->volume); -} - -static double -em_audio_channel_volume_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->volume; -} - -static int -em_spu_channel_count(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->spu_channels_count; -} - -static void -em_spu_channel_set(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->spu_channels_count) - { - WRN("spu channel out of range."); - return; - } - - _player_send_cmd(ev, EM_CMD_SPU_TRACK_SET); - _player_send_int(ev, ev->spu_channels[channel].id); - ev->spu_channel_current = channel; -} - -static int -em_spu_channel_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->spu_channel_current; -} - -static const char * -em_spu_channel_name_get(void *data, int channel) -{ - Emotion_Generic_Video *ev = data; - - if (channel < 0 || channel >= ev->spu_channels_count) - { - WRN("spu channel out of range."); - return NULL; - } - - return ev->spu_channels[channel].name; -} - -static void -em_spu_channel_mute_set(void *data, int mute) -{ - Emotion_Generic_Video *ev = data; - - ev->spu_mute = !!mute; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_SPU_MUTE_SET); - _player_send_int(ev, mute); -} - -static int -em_spu_channel_mute_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return ev->spu_mute; -} - -static int -em_chapter_count(void *ef EINA_UNUSED) -{ - int num = 0; - return num; -} - -static void -em_chapter_set(void *ef EINA_UNUSED, int chapter EINA_UNUSED) -{ -} - -static int -em_chapter_get(void *ef EINA_UNUSED) -{ - int num = 0; - return num; -} - -static const char * -em_chapter_name_get(void *ef EINA_UNUSED, int chapter EINA_UNUSED) -{ - return NULL; -} - -static void -em_speed_set(void *data, double speed) -{ - Emotion_Generic_Video *ev = data; - float rate = speed; - ev->speed = rate; - - if (!ev->file_ready) - return; - - _player_send_cmd(ev, EM_CMD_SPEED_SET); - _player_send_float(ev, rate); -} - -static double -em_speed_get(void *data) -{ - Emotion_Generic_Video *ev = data; - return (double)ev->speed; -} - -static int -em_eject(void *ef EINA_UNUSED) -{ - return 1; -} - -static const char * -em_meta_get(void *data, int meta) -{ - Emotion_Generic_Video *ev = data; - - switch (meta) - { - case EMOTION_META_INFO_TRACK_TITLE: - return ev->meta.title; - case EMOTION_META_INFO_TRACK_ARTIST: - return ev->meta.artist; - case EMOTION_META_INFO_TRACK_ALBUM: - return ev->meta.album; - case EMOTION_META_INFO_TRACK_YEAR: - return ev->meta.year; - case EMOTION_META_INFO_TRACK_GENRE: - return ev->meta.genre; - case EMOTION_META_INFO_TRACK_COMMENT: - return ev->meta.comment; - case EMOTION_META_INFO_TRACK_DISC_ID: - return ev->meta.disc_id; - case EMOTION_META_INFO_TRACK_COUNT: - return ev->meta.count; - } - - return NULL; -} - - -/* Players/modules */ -static const Emotion_Engine em_template_engine = -{ - EMOTION_ENGINE_API_VERSION, - EMOTION_ENGINE_PRIORITY_DEFAULT, - "generic", - em_add, /* add */ - em_del, /* del */ - 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_len_get, /* len_get */ - em_buffer_size_get, /* buffer_size_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_set, /* vis_set */ - em_vis_get, /* vis_get */ - em_vis_supported, /* vis_supported */ - 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 */ - em_yuv_rows_get, /* 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_subtitle_file_set, /* video_subtitle_file_set */ - em_video_subtitle_file_get, /* video_subtitle_file_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, /* priority_set */ - NULL, /* priority_get */ - NULL /* em_meta_artwork_get */ -}; - -static void -_player_entry_add(const Eina_File_Direct_Info *info) -{ - Emotion_Engine_Generic *eg; - const char *name; - char *endptr; - int priority; - - name = info->path + info->name_start; - - priority = strtol(name, &endptr, 10); - if (endptr == name) - priority = EMOTION_ENGINE_PRIORITY_DEFAULT; - else - { - if ((*endptr == '-') || (*endptr == '_')) - endptr++; - name = endptr; - } - - if (*name == '\0') - { - ERR("Invalid generic player: %s", info->path); - return; - } - - eg = malloc(sizeof(Emotion_Engine_Generic)); - EINA_SAFETY_ON_NULL_RETURN(eg); - - /* inherit template */ - memcpy(&(eg->engine), &em_template_engine, sizeof(em_template_engine)); - - eg->path = strdup(info->path); - EINA_SAFETY_ON_NULL_GOTO(eg->path, error_path); - - eg->engine.name = strdup(name); - EINA_SAFETY_ON_NULL_GOTO(eg->engine.name, error_name); - - eg->engine.priority = priority; - - DBG("Add player name=%s, priority=%d, path=%s", - eg->engine.name, eg->engine.priority, eg->path); - _generic_players = eina_list_append(_generic_players, eg); - - return; - - error_name: - free(eg->path); - error_path: - free(eg); -} - -static void -_player_entry_free(Emotion_Engine_Generic *eg) -{ - free(eg->path); - free((void *)eg->engine.name); - free(eg); -} - -static void -_players_all_from(const char *path) -{ - const Eina_File_Direct_Info *info; - int count = 0; - Eina_Iterator *itr = eina_file_direct_ls(path); - if (!itr) goto end; - EINA_ITERATOR_FOREACH(itr, info) - { - if (access(info->path, R_OK | X_OK) == 0) - { - _player_entry_add(info); - count++; - } - } - eina_iterator_free(itr); - - end: - if (count == 0) - DBG("No generic players at %s", path); -} - -static void -_players_load(void) -{ - char buf[PATH_MAX]; - - eina_str_join(buf, sizeof(buf), '/', - eina_prefix_lib_get(pfx), - "emotion/generic_players/" MODULE_ARCH); - _players_all_from(buf); - - if (!_generic_players) - { - WRN("no generic players available"); - } - else - { - const Eina_List *n; - const Emotion_Engine_Generic *eg; - INF("Found %d generic players", eina_list_count(_generic_players)); - EINA_LIST_FOREACH(_generic_players, n, eg) - _emotion_module_register(&(eg->engine)); - } -} - -Eina_Bool -generic_module_init(void) -{ - if (_emotion_init_count > 0) - { - _emotion_init_count++; - return EINA_TRUE; - } - - _emotion_generic_log_domain = eina_log_domain_register("emotion_generic", - EINA_COLOR_LIGHTCYAN); - if (_emotion_generic_log_domain < 0) - { - EINA_LOG_CRIT("Could not register log domain 'emotion_generic'"); - return EINA_FALSE; - } - - pfx = eina_prefix_new(NULL, emotion_init, - "EMOTION", "emotion", "checkme", - PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, - PACKAGE_DATA_DIR, PACKAGE_DATA_DIR); - if (!pfx) - { - CRI("Could not get prefix for emotion"); - eina_log_domain_unregister(_emotion_generic_log_domain); - _emotion_generic_log_domain = -1; - return EINA_FALSE; - } - - _players_load(); - - _emotion_init_count = 1; - return EINA_TRUE; -} - -void -generic_module_shutdown(void) -{ - Emotion_Engine_Generic *eg; - - if (_emotion_init_count > 1) - { - _emotion_init_count--; - return; - } - else if (_emotion_init_count == 0) - { - EINA_LOG_ERR("too many generic_module_shutdown()"); - return; - } - _emotion_init_count = 0; - - EINA_LIST_FREE(_generic_players, eg) - { - _emotion_module_unregister(&(eg->engine)); - _player_entry_free(eg); - } - - eina_log_domain_unregister(_emotion_generic_log_domain); - _emotion_generic_log_domain = -1; - - eina_prefix_free(pfx); - pfx = NULL; -} - -#ifndef EMOTION_STATIC_BUILD_GENERIC - -EINA_MODULE_INIT(generic_module_init); -EINA_MODULE_SHUTDOWN(generic_module_shutdown); - -#endif diff --git a/src/modules/emotion/generic/emotion_generic.h b/src/modules/emotion/generic/emotion_generic.h deleted file mode 100644 index 2830d33d4a..0000000000 --- a/src/modules/emotion/generic/emotion_generic.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef EMOTION_GENERIC_H -#define EMOTION_GENERIC_H - -#include - -#include "Emotion_Generic_Plugin.h" - -/* default values */ - -typedef struct _Emotion_Generic_Video Emotion_Generic_Video; -typedef struct _Emotion_Generic_Player Emotion_Generic_Player; -typedef struct _Emotion_Generic_Cmd_Buffer Emotion_Generic_Cmd_Buffer; -typedef struct _Emotion_Generic_Channel Emotion_Generic_Channel; -typedef struct _Emotion_Generic_Meta Emotion_Generic_Meta; - -struct _Emotion_Generic_Player -{ - Ecore_Exe *exe; -}; - -struct _Emotion_Generic_Channel -{ - int id; - const char *name; -}; - -struct _Emotion_Generic_Meta -{ - const char *title; - const char *artist; - const char *album; - const char *year; - const char *genre; - const char *comment; - const char *disc_id; - const char *count; -}; - -struct _Emotion_Generic_Cmd_Buffer -{ - char *tmp; - int type; - ssize_t i, total; - int s_len; - int num_params, cur_param; - int padding; - union { - struct { - int width; - int height; - } size; - int i_num; - float f_num; - struct { - int total; - int current; - Emotion_Generic_Channel *channels; - } track; - Emotion_Generic_Meta meta; - } param; -}; - -typedef struct _Emotion_Engine_Generic -{ - Emotion_Engine engine; - char *path; -} Emotion_Engine_Generic; - -/* emotion/generic main structure */ -struct _Emotion_Generic_Video -{ - const Emotion_Engine_Generic *engine; - const char *shmname; - - Emotion_Generic_Player player; - Emotion_Generic_Cmd_Buffer cmd; - Ecore_Event_Handler *player_add, *player_del, *player_data; - int drop; - Ecore_Pipe *fd_read; - Ecore_Pipe *fd_write; - const unsigned char *buffer; - ssize_t length; - ssize_t offset; - - const char *filename; - volatile double len; - volatile double pos; - double fps; - double ratio; - int w, h; - Evas_Object *obj; - Emotion_Generic_Video_Shared *shared; - Emotion_Generic_Video_Frame frame; - volatile int fq; - float volume; - float speed; - Emotion_Vis vis; - Eina_Bool initializing : 1; - Eina_Bool ready : 1; - Eina_Bool play : 1; - Eina_Bool video_mute : 1; - Eina_Bool audio_mute : 1; - Eina_Bool spu_mute : 1; - Eina_Bool seekable : 1; - volatile Eina_Bool opening : 1; - volatile Eina_Bool closing : 1; - Eina_Bool file_changed : 1; - Eina_Bool file_ready : 1; - int audio_channels_count; - int audio_channel_current; - Emotion_Generic_Channel *audio_channels; - int video_channels_count; - int video_channel_current; - Emotion_Generic_Channel *video_channels; - int spu_channels_count; - int spu_channel_current; - Emotion_Generic_Channel *spu_channels; - Emotion_Generic_Meta meta; - const char *subtitle_path; -}; - -#endif - diff --git a/src/modules/emotion/generic/meson.build b/src/modules/emotion/generic/meson.build deleted file mode 100644 index 4f62c7a43e..0000000000 --- a/src/modules/emotion/generic/meson.build +++ /dev/null @@ -1,24 +0,0 @@ -generic_src = files([ - 'emotion_generic.c', - 'emotion_generic.h', -]) - -emotion_generic = declare_dependency( - include_directories: include_directories('.'), - dependencies: emotion, -) - -if sys_windows == false - shared_module(emotion_loader, - generic_src, - include_directories : config_dir, - dependencies: [eina, evas, emotion, generic_deps, rt], - install: true, - install_dir : mod_install_dir, - c_args : package_c_args, - ) - - install_headers('Emotion_Generic_Plugin.h', - install_dir : dir_package_include, - ) -endif diff --git a/src/modules/emotion/libvlc/emotion_libvlc.c b/src/modules/emotion/libvlc/emotion_libvlc.c deleted file mode 100644 index 1e8f9d69b4..0000000000 --- a/src/modules/emotion/libvlc/emotion_libvlc.c +++ /dev/null @@ -1,1555 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include -#include - -#include -#include -#include - -#include "emotion_modules.h" - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_emotion_libvlc_log_domain, __VA_ARGS__) - -#ifdef INF -#undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_emotion_libvlc_log_domain, __VA_ARGS__) - -#ifdef WRN -#undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_emotion_libvlc_log_domain, __VA_ARGS__) - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_emotion_libvlc_log_domain, __VA_ARGS__) - -#ifdef CRI -#undef CRI -#endif -#define CRI(...) EINA_LOG_DOM_CRIT(_emotion_libvlc_log_domain, __VA_ARGS__) - -static int _emotion_libvlc_log_domain = -1; -static Eina_Bool debug_fps = EINA_FALSE; -static libvlc_instance_t *libvlc = NULL; - -typedef struct _Emotion_LibVLC Emotion_LibVLC; - -static void em_file_close(void *); - -struct _Emotion_LibVLC -{ - /* Evas object */ - Evas_Object *obj; - Evas_Object *evas_obj; - Emotion_Module_Options opt; - - /* libvlc */ - libvlc_media_t *m; - libvlc_media_player_t *mp; - unsigned int nb_tracks; - libvlc_media_track_t **tracks; - int nb_chapters; - libvlc_chapter_description_t **chapters; - char *subtitle_file; - char *metas[META_TRACK_COUNT]; - - /* options */ - int video_mute; - int video_mute_force; - int audio_mute; - int spu_mute; - int audio_vol; - Emotion_Vis vis; - - /* There can be remaining mainloop callbacks that owns the Emotion_LibVLC - * object when em_del is called. Use a ref_count to delete the ev object - * when em_del is called and when all callbacks are processed. */ - unsigned int ref_count; - - /* locks */ - Eina_Lock lock; - Eina_Condition wait; - Eina_List *event_list; - - /* stats */ - double pos; - double len; - double buffer_cache; - Eina_Bool seeking; - Eina_Bool started; - Eina_Bool invalidate_tracks; -}; - -struct close_data -{ - libvlc_media_player_t *mp; - Evas_Object *evas_obj; -}; - -static const libvlc_event_type_t mp_events[] = { - //libvlc_MediaPlayerMediaChanged, - //libvlc_MediaPlayerNothingSpecial, - //libvlc_MediaPlayerOpening, - libvlc_MediaPlayerBuffering, - libvlc_MediaPlayerPlaying, - //libvlc_MediaPlayerPaused, - libvlc_MediaPlayerStopped, - libvlc_MediaPlayerForward, - //libvlc_MediaPlayerBackward, - libvlc_MediaPlayerEndReached, - libvlc_MediaPlayerEncounteredError, - libvlc_MediaPlayerTimeChanged, - //libvlc_MediaPlayerPositionChanged, - //libvlc_MediaPlayerSeekableChanged, - //libvlc_MediaPlayerPausableChanged, - //libvlc_MediaPlayerTitleChanged, - //libvlc_MediaPlayerSnapshotTaken, - libvlc_MediaPlayerLengthChanged, - //libvlc_MediaPlayerVout, - //libvlc_MediaPlayerScrambledChanged, - libvlc_MediaPlayerESAdded, - libvlc_MediaPlayerESDeleted, - //libvlc_MediaPlayerESSelected, - //libvlc_MediaPlayerCorked, - //libvlc_MediaPlayerUncorked, - //libvlc_MediaPlayerMuted, - //libvlc_MediaPlayerUnmuted, - //libvlc_MediaPlayerAudioVolume, - //libvlc_MediaPlayerAudioDevice, - -1, -}; - -static void -em_del_safe(Emotion_LibVLC *ev) -{ - eina_lock_free(&ev->lock); - eina_condition_free(&ev->wait); - free(ev->subtitle_file); - free(ev); -} - -/* Take the ev->lock from a mainloop callback. - * Returns false if the ev object is destroyed. */ -static Eina_Bool -emotion_mainloop_lock(Emotion_LibVLC *ev) -{ - eina_lock_take(&ev->lock); - _emotion_pending_ecore_end(); - if (--ev->ref_count == 0) - { - eina_lock_release(&ev->lock); - WRN("callbacks ended, deleting Emotion_LibVLC"); - em_del_safe(ev); - return EINA_FALSE; - } - return EINA_TRUE; -} - -/* Send a callback to the mainloop */ -static void -emotion_mainloop_call_locked(Emotion_LibVLC *ev, Ecore_Cb callback) -{ - ++ev->ref_count; - _emotion_pending_ecore_begin(); - ecore_main_loop_thread_safe_call_async(callback, ev); -} - -/* Process one libvlc event from the mainloop. */ -static void -emotion_mainloop_event(Emotion_LibVLC *ev, const libvlc_event_t *event) -{ - switch (event->type) - { - case libvlc_MediaPlayerBuffering: - ev->buffer_cache = event->u.media_player_buffering.new_cache / 100.0; - break; - - case libvlc_MediaPlayerPlaying: - if (!ev->started) - { - _emotion_open_done(ev->obj); - _emotion_playback_started(ev->obj); - ev->started = EINA_TRUE; - } - break; - - case libvlc_MediaPlayerStopped: - case libvlc_MediaPlayerEndReached: - case libvlc_MediaPlayerEncounteredError: - _emotion_decode_stop(ev->obj); - _emotion_playback_finished(ev->obj); - break; - - case libvlc_MediaPlayerTimeChanged: - { - if (ev->seeking) - { - _emotion_seek_done(ev->obj); - ev->seeking = EINA_FALSE; - } - - ev->pos = event->u.media_player_time_changed.new_time / 1000.0; - if (ev->pos > 0 && ev->len > 0) - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - break; - } - - case libvlc_MediaPlayerLengthChanged: - ev->len = event->u.media_player_length_changed.new_length / 1000.0; - if (ev->pos > 0 && ev->len > 0) - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - break; - - case libvlc_MediaPlayerESAdded: - case libvlc_MediaPlayerESDeleted: - ev->invalidate_tracks = EINA_TRUE; - _emotion_channels_change(ev->obj); - break; - } -} - -/* Mainloop callback, sent by libvlc_on_mp_event. It processes a list of libvlc - * event. */ -static void -emotion_mainloop_event_list(void *data) -{ - Emotion_LibVLC *ev = data; - Eina_List *event_list; - libvlc_event_t *event; - - if (!emotion_mainloop_lock(ev)) return; - event_list = ev->event_list; - ev->event_list = NULL; - eina_lock_release(&ev->lock); - - if (!event_list) return; - - EINA_LIST_FREE(event_list, event) - { - if (ev->mp) - emotion_mainloop_event(ev, event); - free(event); - } -} - -/* Libvlc callback, see libvlc_event_manager_t. */ -static void -libvlc_on_mp_event(const libvlc_event_t *event, void *opaque) -{ - Emotion_LibVLC *ev = opaque; - - if (eina_main_loop_is()) - { - /* Process the event directly */ - emotion_mainloop_event(ev, event); - } - else - { - /* Add the event to a list of events that will be processed by the - * mainloop */ - - void *data = malloc(sizeof(libvlc_event_t)); - if (!data) return; - memcpy(data, event, sizeof(libvlc_event_t)); - - eina_lock_take(&ev->lock); - if (!ev->event_list) - emotion_mainloop_call_locked(ev, emotion_mainloop_event_list); - ev->event_list = eina_list_append(ev->event_list, data); - eina_lock_release(&ev->lock); - } -} - -static void -evas_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, - void *event EINA_UNUSED) -{ - Emotion_LibVLC *ev = data; - int w, h; - - evas_object_image_size_get(ev->evas_obj, &w, &h); - _emotion_frame_resize(ev->obj, w, h, w / (double) h); - efl_event_callback_call(ev->obj, EFL_CANVAS_VIDEO_EVENT_FRAME_DECODE, NULL); -} - -/* Fetch all libvlc tracks. */ -static int -libvlc_fetch_tracks(Emotion_LibVLC *ev) -{ - if (ev->invalidate_tracks) - { - if (ev->nb_tracks) - libvlc_media_tracks_release(ev->tracks, ev->nb_tracks); - ev->nb_tracks = libvlc_media_tracks_get(ev->m, &ev->tracks); - ev->invalidate_tracks = EINA_FALSE; - } - return ev->nb_tracks; -} - -/* Get a libvlc tracks from a track_id. */ -static libvlc_media_track_t * -libvlc_get_track(Emotion_LibVLC *ev, libvlc_track_type_t type, int id) -{ - unsigned int i; - - if (!ev->m || id < 0 || type == libvlc_track_unknown) return NULL; - - if (!libvlc_fetch_tracks(ev)) return NULL; - - for (i = 0; i < ev->nb_tracks; ++i) - { - libvlc_media_track_t *track = ev->tracks[i]; - - if (track->i_id == id && track->i_type == type) - return track; - } - - return NULL; -} - -/* Get the current libvlc video track. */ -static libvlc_media_track_t * -libvlc_get_current_video_track(Emotion_LibVLC *ev) -{ - int id = libvlc_video_get_track(ev->mp); - return id >= 0 ? libvlc_get_track(ev, libvlc_track_video, id) : NULL; -} - -/* Get a libvlc video track at a pos. - * XXX: Libvlc use a track_id to get and select a track. The first track_id doesn't - * necessarily starts with 0. Emotion use a position (that starts with 0) to - * get and select a track. */ -static libvlc_media_track_t * -libvlc_get_track_at_pos(Emotion_LibVLC *ev, - int pos, libvlc_track_type_t type) -{ - unsigned int i; - - if (!ev->m || pos < 0 || type == libvlc_track_unknown) return NULL; - - if (!libvlc_fetch_tracks(ev)) return NULL; - - for (i = 0; i < ev->nb_tracks; ++i) - { - libvlc_media_track_t *track = ev->tracks[i]; - - if (type == track->i_type && pos-- == 0) - return track; - } - - return NULL; -} - -/* Get the position of the libvlc track. - * See libvlc_get_track_at_pos. */ -static int -libvlc_get_track_pos(Emotion_LibVLC *ev, int id, libvlc_track_type_t type) -{ - unsigned int i; - int pos = 0; - - if (!ev->m || id < 0 || type == libvlc_track_unknown) return -1; - - if (!libvlc_fetch_tracks(ev)) return -1; - - for (i = 0; i < ev->nb_tracks; ++i) - { - libvlc_media_track_t *track = ev->tracks[i]; - - if (type == track->i_type) - { - if (id == track->i_id) - return pos; - else - pos++; - } - } - - return -1; -} - -static void * -em_add(const Emotion_Engine *api EINA_UNUSED, - Evas_Object *obj, - const Emotion_Module_Options *opt) -{ - Emotion_LibVLC *ev; - ev = calloc(1, sizeof(Emotion_LibVLC)); - EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL); - - ev->obj = obj; - ev->opt = *opt; - eina_lock_new(&ev->lock); - eina_condition_new(&ev->wait, &ev->lock); - ev->ref_count = 1; - ev->audio_vol = -1; - - return ev; -} - -static void -em_del(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev) return; - - em_file_close(video); - - eina_lock_take(&ev->lock); - if (--ev->ref_count > 0) - { - eina_lock_release(&ev->lock); - WRN("em_del delayed, some callbacks are still running"); - } - else - { - eina_lock_release(&ev->lock); - em_del_safe(ev); - } -} - -static Eina_Bool -em_file_open(void *video, - const char *file) -{ - int ret, i; - Emotion_LibVLC *ev = video; - libvlc_event_manager_t *event_m; - - if (!file) return EINA_FALSE; - - ev->evas_obj = emotion_object_image_get(ev->obj); - if (!ev->evas_obj) - { - WRN("emotion_object_image_get failed: no video"); - ev->opt.no_video = EINA_TRUE; - } - - evas_object_image_pixels_get_callback_set(ev->evas_obj, NULL, NULL); - - ev->invalidate_tracks = true; - - /* Create libvlc_media */ - ev->m = libvlc_media_new_path(libvlc, file); - if (strstr(file, "://") == NULL) - ev->m = libvlc_media_new_path(libvlc, file); - else - ev->m = libvlc_media_new_location(libvlc, file); - - EINA_SAFETY_ON_NULL_GOTO(ev->m, error); - - if (ev->opt.no_audio || ev->audio_mute) - libvlc_media_add_option(ev->m, ":no-audio"); - - if (ev->opt.no_video || ev->video_mute) - libvlc_media_add_option(ev->m, ":no-video"); - - if (ev->spu_mute) - libvlc_media_add_option(ev->m, ":no-spu"); - - /* Create libvlc_media_player */ - ev->mp = libvlc_media_player_new_from_media(ev->m); - EINA_SAFETY_ON_NULL_GOTO(ev->mp, error); - - event_m = libvlc_media_player_event_manager(ev->mp); - for (i = 0; mp_events[i] != -1; ++i) - libvlc_event_attach(event_m, mp_events[i], libvlc_on_mp_event, ev); - - libvlc_media_player_set_video_title_display(ev->mp, - libvlc_position_disable, 0); - - evas_object_ref(ev->evas_obj); - if (libvlc_media_player_set_evas_object(ev->mp, ev->evas_obj) == -1) - { - CRI("libvlc_media_player_set_evas_object failed"); - libvlc_media_add_option(ev->m, ":no-video"); - ev->video_mute = ev->video_mute_force = 1; - } - - evas_object_event_callback_add(ev->evas_obj, EVAS_CALLBACK_IMAGE_RESIZE, - evas_resize_cb, ev); - - if (ev->audio_vol != -1) - libvlc_audio_set_volume(ev->mp, ev->audio_vol); - - ret = libvlc_media_player_play(ev->mp); - EINA_SAFETY_ON_FALSE_GOTO(ret == 0, error); - - return EINA_TRUE; -error: - em_file_close(video); - return EINA_FALSE; -} - -static void -emotion_close_cb(void *data, Ecore_Thread *thread EINA_UNUSED) -{ - struct close_data *close_data = data; - - libvlc_media_player_release(close_data->mp); -} - -static void -emotion_close_mainloop_cb(void *data, - Ecore_Thread *thread EINA_UNUSED) -{ - struct close_data *close_data = data; - - evas_object_unref(close_data->evas_obj); - free(close_data); - _emotion_pending_ecore_end(); -} - -static void -em_file_close(void *video) -{ - Emotion_LibVLC *ev = video; - unsigned int i; - - if (ev->mp) - { - struct close_data *close_data; - libvlc_event_manager_t *event_m; - - evas_object_event_callback_del(ev->evas_obj, EVAS_CALLBACK_IMAGE_RESIZE, - evas_resize_cb); - - event_m = libvlc_media_player_event_manager(ev->mp); - for (i = 0; mp_events[i] != -1; ++i) - libvlc_event_detach(event_m, mp_events[i], libvlc_on_mp_event, ev); - - libvlc_media_player_set_evas_object(ev->mp, NULL); - - close_data = malloc(sizeof(struct close_data)); - if (close_data) - { - close_data->evas_obj = ev->evas_obj; - close_data->mp = ev->mp; - _emotion_pending_ecore_begin(); - ecore_thread_run(emotion_close_cb, - emotion_close_mainloop_cb, - NULL, close_data); - } - - ev->evas_obj = NULL; - ev->mp = NULL; - - if (ev->seeking) - { - ev->seeking = EINA_FALSE; - _emotion_seek_done(ev->obj); - } - } - if (ev->m) - { - libvlc_media_release(ev->m); - ev->m = NULL; - } - if (ev->nb_tracks > 0) - { - libvlc_media_tracks_release(ev->tracks, ev->nb_tracks); - ev->nb_tracks = 0; - ev->tracks = NULL; - } - if (ev->nb_chapters > 0) - { - libvlc_chapter_descriptions_release(ev->chapters, ev->nb_chapters); - ev->nb_chapters = 0; - ev->chapters = NULL; - } - for (i = 0; i < META_TRACK_COUNT; ++i) - { - free(ev->metas[i]); - ev->metas[i] = NULL; - } - if (ev->subtitle_file) - { - free(ev->subtitle_file); - ev->subtitle_file = NULL; - } - ev->vis = EMOTION_VIS_NONE; - ev->started = ev->seeking = ev->invalidate_tracks = EINA_FALSE; - ev->pos = ev->len = ev->buffer_cache = 0.0; -} - -static void -em_play(void *video, - double pos EINA_UNUSED) -{ - Emotion_LibVLC *ev = video; - - libvlc_media_player_set_pause(ev->mp, false); -} - -static void -em_stop(void *video) -{ - Emotion_LibVLC *ev = video; - - libvlc_media_player_set_pause(ev->mp, true); -} - -static void -em_size_get(void *video, - int *width, - int *height) -{ - Emotion_LibVLC *ev = video; - libvlc_media_track_t *track; - - if (!width || !height) return; - *width = 0; - *height = 0; - - if (!ev->started) return; - - track = libvlc_get_current_video_track(ev); - if (track) - { - *width = track->video->i_width; - *height = track->video->i_height; - } -} - -static double -em_pos_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0.0; - - return ev->pos; -} - -static void -em_pos_set(void *video, - double pos) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) - { - _emotion_seek_done(ev->obj); - return; - } - - libvlc_media_player_set_time(ev->mp, pos * 1000); - - ev->seeking = EINA_TRUE; -} - -static double -em_len_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0.0; - - return ev->len; -} - -static double -em_buffer_size_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0.0; - - return ev->buffer_cache; -} - -static void -em_fps_num_den_get(Emotion_LibVLC *ev, int *num, int *den) -{ - libvlc_media_track_t *track; - - if (!ev->started) return; - - track = libvlc_get_current_video_track(ev); - if (track) - { - if (num) - *num = track->video->i_frame_rate_num; - if (den) - *den = track->video->i_frame_rate_den; - } -} - -static int -em_fps_num_get(void *video) -{ - int num = 0; - - em_fps_num_den_get(video, &num, NULL); - return num; -} - -static int -em_fps_den_get(void *video) -{ - int den = 0; - - em_fps_num_den_get(video, NULL, &den); - return den; -} - -static double -em_fps_get(void *video) -{ - int num = 0, den = 0; - - em_fps_num_den_get(video, &num, &den); - if (den > 0) return num / (double)den; - return 0.0; -} - -static void -em_vis_set(void *video, - Emotion_Vis vis) -{ - Emotion_LibVLC *ev = video; - - ev->vis = vis; -} - -static Emotion_Vis -em_vis_get(void *video) -{ - Emotion_LibVLC *ev = video; - - return ev->vis; -} - -static Eina_Bool -em_vis_supported(void *ev EINA_UNUSED, Emotion_Vis vis) -{ - /* FIXME */ - if (vis == EMOTION_VIS_NONE) - return EINA_TRUE; - else - return EINA_FALSE; -} - -static double -em_ratio_get(void *video) -{ - Emotion_LibVLC *ev = video; - libvlc_media_track_t *track; - - if (!ev->started) return 0.0; - - track = libvlc_get_current_video_track(ev); - if (track) - { - double ratio = track->video->i_sar_num - / (double)track->video->i_sar_den; - return ratio; - } - else - return 0.0; -} - -static int -em_video_handled(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0.0; - - return libvlc_video_get_track_count(ev->mp) > 0; -} - -static int -em_audio_handled(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0.0; - - return libvlc_audio_get_track_count(ev->mp) > 0; -} - -static int -em_seekable(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0; - - return libvlc_media_player_is_seekable(ev->mp); -} - -static void -em_frame_done(void *video EINA_UNUSED) -{ -} - -static Emotion_Format -em_format_get(void *video EINA_UNUSED) -{ - return EMOTION_FORMAT_NONE; -} - -static void -em_video_data_size_get(void *video EINA_UNUSED, int *w EINA_UNUSED, int *h EINA_UNUSED) -{ -} - -static int -em_yuv_rows_get(void *video EINA_UNUSED, - int w EINA_UNUSED, - int h EINA_UNUSED, - unsigned char **yrows EINA_UNUSED, - unsigned char **urows EINA_UNUSED, - unsigned char **vrows EINA_UNUSED) -{ - return 0; -} - -static int -em_bgra_data_get(void *video EINA_UNUSED, unsigned char **bgra_data EINA_UNUSED) -{ - return 0; -} - -static void -em_event_feed(void *video, int event) -{ - Emotion_LibVLC *ev = video; - unsigned int navigate; - - if (!ev->started) return; - - switch (event) - { - case EMOTION_EVENT_UP: - navigate = libvlc_navigate_up; - break; - - case EMOTION_EVENT_DOWN: - navigate = libvlc_navigate_down; - break; - - case EMOTION_EVENT_LEFT: - navigate = libvlc_navigate_left; - break; - - case EMOTION_EVENT_RIGHT: - navigate = libvlc_navigate_right; - break; - - case EMOTION_EVENT_SELECT: - navigate = libvlc_navigate_activate; - break; - - /* FIXME */ - default: - case EMOTION_EVENT_MENU1: - case EMOTION_EVENT_MENU2: - case EMOTION_EVENT_MENU3: - case EMOTION_EVENT_MENU4: - case EMOTION_EVENT_MENU5: - case EMOTION_EVENT_MENU6: - case EMOTION_EVENT_MENU7: - case EMOTION_EVENT_NEXT: - case EMOTION_EVENT_PREV: - case EMOTION_EVENT_ANGLE_NEXT: - case EMOTION_EVENT_ANGLE_PREV: - case EMOTION_EVENT_FORCE: - case EMOTION_EVENT_0: - case EMOTION_EVENT_1: - case EMOTION_EVENT_2: - case EMOTION_EVENT_3: - case EMOTION_EVENT_4: - case EMOTION_EVENT_5: - case EMOTION_EVENT_6: - case EMOTION_EVENT_7: - case EMOTION_EVENT_8: - case EMOTION_EVENT_9: - case EMOTION_EVENT_10: - return; - } - libvlc_media_player_navigate(ev->mp, navigate); -} - -static void -em_event_mouse_button_feed(void *video EINA_UNUSED, int button EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) -{ - /* Handled directly by VLC evas vout module */ -} - -static void -em_event_mouse_move_feed(void *video EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) -{ - /* Handled directly by VLC evas vout module */ -} - -static int -em_video_channel_count(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return -1; - - return libvlc_video_get_track_count(ev->mp); -} - -static void -em_video_channel_set(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - if (channel < 0) - libvlc_video_set_track(ev->mp, -1); - else - { - libvlc_media_track_t *track; - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_video); - if (track) - libvlc_video_set_track(ev->mp, track->i_id); - } -} - -static int -em_video_channel_get(void *video) -{ - Emotion_LibVLC *ev = video; - int id; - - if (!ev->started) return -1; - - id = libvlc_video_get_track(ev->mp); - - return id >= 0 ? libvlc_get_track_pos(ev, id, libvlc_track_video) : -1; -} - -static void -em_video_subtitle_file_set(void *video, - const char *filepath) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - free(ev->subtitle_file); - ev->subtitle_file = filepath ? strdup(filepath) : NULL; - libvlc_video_set_subtitle_file(ev->mp, ev->subtitle_file); -} - -static const char * -em_video_subtitle_file_get(void *video) -{ - Emotion_LibVLC *ev = video; - - return ev->subtitle_file; -} - -static const char * -em_video_channel_name_get(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - libvlc_media_track_t *track; - - if (!ev->started) return NULL; - - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_video); - if (track) - return track->psz_description; - else - return NULL; -} - -static void -em_video_channel_mute_set(void *video, - int mute) -{ - Emotion_LibVLC *ev = video; - - if (ev->video_mute_force) - return; - ev->video_mute = mute; - - if (ev->started) - em_video_channel_set(video, mute ? -1 : 0); -} - -static int -em_video_channel_mute_get(void *video) -{ - Emotion_LibVLC *ev = video; - - return ev->video_mute; -} - -static int -em_channel_count(int vlc_count) -{ - /* vlc count the -1 track that deactivate the channel for audio and spu */ - return vlc_count > 0 ? vlc_count - 1 : vlc_count; -} - -static int -em_audio_channel_count(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return -1; - - return em_channel_count(libvlc_audio_get_track_count(ev->mp)); -} - -static void -em_audio_channel_set(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - if (channel < 0) - libvlc_audio_set_track(ev->mp, -1); - else - { - libvlc_media_track_t *track; - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_audio); - if (track) - libvlc_audio_set_track(ev->mp, track->i_id); - } -} - -static int -em_audio_channel_get(void *video) -{ - Emotion_LibVLC *ev = video; - int id; - - if (!ev->started) return -1; - - id = libvlc_audio_get_track(ev->mp); - - return id >= 0 ? libvlc_get_track_pos(ev, id, libvlc_track_audio) : -1; -} - -static const char * -em_audio_channel_name_get(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - libvlc_media_track_t *track; - - if (!ev->started) return NULL; - - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_audio); - if (track) - return track->psz_description; - else - return NULL; -} - -static void -em_audio_channel_mute_set(void *video, - int mute) -{ - Emotion_LibVLC *ev = video; - - ev->audio_mute = mute; - - if (ev->started) - em_audio_channel_set(video, mute ? -1 : 0); -} - -static int -em_audio_channel_mute_get(void *video) -{ - Emotion_LibVLC *ev = video; - - return ev->audio_mute; -} - -static void -em_audio_channel_volume_set(void *video, - double vol) -{ - Emotion_LibVLC *ev = video; - - if (vol < 0.0) - vol = 0.0; - else if (vol > 1.0) - vol = 1.0; - ev->audio_vol = vol * 100; - - if (!ev->started) return; - - libvlc_audio_set_volume(ev->mp, ev->audio_vol); -} - -static double -em_audio_channel_volume_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) - return ev->audio_vol / 100.0; - - return libvlc_audio_get_volume(ev->mp) / 100.0; -} - -static int -em_spu_channel_count(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return -1; - - return em_channel_count(libvlc_video_get_spu_count(ev->mp)); -} - -static void -em_spu_channel_set(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - if (channel < 0) - libvlc_video_set_spu(ev->mp, -1); - else - { - libvlc_media_track_t *track; - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_text); - if (track) - libvlc_video_set_spu(ev->mp, track->i_id); - } -} - -static int -em_spu_channel_get(void *video) -{ - Emotion_LibVLC *ev = video; - int id; - - if (!ev->started) return -1; - - id = libvlc_video_get_spu(ev->mp); - - return id >= 0 ? libvlc_get_track_pos(ev, id, libvlc_track_text) : -1; -} - -static const char * -em_spu_channel_name_get(void *video, - int channel) -{ - Emotion_LibVLC *ev = video; - libvlc_media_track_t *track; - - if (!ev->started) return NULL; - - track = libvlc_get_track_at_pos(ev, channel, libvlc_track_text); - if (track) - return track->psz_description; - else - return NULL; -} - -static void -em_spu_channel_mute_set(void *video, int mute) -{ - Emotion_LibVLC *ev = video; - - ev->spu_mute = mute; - - if (ev->started) - em_spu_channel_set(video, mute ? -1 : 0); -} - -static int -em_spu_channel_mute_get(void *video) -{ - Emotion_LibVLC *ev = video; - - return ev->spu_mute; -} - -static int -em_chapter_count(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0; - - return libvlc_media_player_get_chapter_count(ev->mp); -} - -static void -em_chapter_set(void *video, int chapter) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - libvlc_media_player_set_chapter(ev->mp, chapter); -} - -static int -em_chapter_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 0; - - return libvlc_media_player_get_chapter(ev->mp); -} - -static const char * -em_chapter_name_get(void *video, int chapter) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return NULL; - - if (ev->nb_chapters == 0) - { - ev->nb_chapters = - libvlc_media_player_get_full_chapter_descriptions(ev->mp, - -1, - &ev->chapters); - if (ev->nb_chapters == 0) - ev->nb_chapters = -1; - } - return chapter < ev->nb_chapters ? ev->chapters[chapter]->psz_name : NULL; -} - -static void -em_speed_set(void *video, double speed) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return; - - libvlc_media_player_set_rate(ev->mp, speed); -} - -static double -em_speed_get(void *video) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return 1.0; - - return libvlc_media_player_get_rate(ev->mp); -} - -static int -em_eject(void *video EINA_UNUSED) -{ - return 1; -} - -static const char * -em_meta_get(void *video, int meta) -{ - Emotion_LibVLC *ev = video; - - if (!ev->started) return NULL; - - if (meta <= 0 || meta >= META_TRACK_COUNT) - return NULL; - - if (ev->metas[meta]) - return ev->metas[meta]; - else - { - libvlc_meta_t vlc_meta; - switch (meta) - { - case META_TRACK_TITLE: - vlc_meta = libvlc_meta_Title; - break; - - case META_TRACK_ARTIST: - vlc_meta = libvlc_meta_Artist; - break; - - case META_TRACK_ALBUM: - vlc_meta = libvlc_meta_Album; - break; - - case META_TRACK_YEAR: - vlc_meta = libvlc_meta_Date; - break; - - case META_TRACK_GENRE: - vlc_meta = libvlc_meta_Genre; - break; - - case META_TRACK_COMMENT: - vlc_meta = libvlc_meta_Description; - break; - - case META_TRACK_DISCID: - vlc_meta = libvlc_meta_TrackID; - break; - - default: - return NULL; - break; - } - ev->metas[meta] = libvlc_media_get_meta(ev->m, vlc_meta); - - return ev->metas[meta]; - } -} - -static const Emotion_Engine em_engine = -{ - EMOTION_ENGINE_API_VERSION, - EMOTION_ENGINE_PRIORITY_DEFAULT, - "libvlc", - em_add, /* add */ - em_del, /* del */ - 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_len_get, /* len_get */ - em_buffer_size_get, /* buffer_size_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_set, /* vis_set */ - em_vis_get, /* vis_get */ - em_vis_supported, /* vis_supported */ - 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 */ - em_yuv_rows_get, /* 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_subtitle_file_set, /* video_subtitle_file_set */ - em_video_subtitle_file_get, /* video_subtitle_file_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, /* priority_set */ - NULL, /* priority_get */ - NULL /* em_meta_artwork_get */ -}; - -static void -libvlc_log(void *data EINA_UNUSED, int level, - const libvlc_log_t *ctx EINA_UNUSED, - const char *fmt, va_list args) -{ - Eina_Log_Level eina_log_level; - const char *name, *header; - uintptr_t id; - - libvlc_log_get_object(ctx, &name, &header, &id); - switch (level) - { - case LIBVLC_DEBUG: - eina_log_level = EINA_LOG_LEVEL_DBG; - break; - - case LIBVLC_NOTICE: - eina_log_level = EINA_LOG_LEVEL_INFO; - break; - - case LIBVLC_WARNING: - eina_log_level = EINA_LOG_LEVEL_WARN; - break; - - case LIBVLC_ERROR: - default: - eina_log_level = EINA_LOG_LEVEL_ERR; - break; - } - eina_log_vprint(_emotion_libvlc_log_domain, eina_log_level, - "", name, id, fmt, args); -} - -static libvlc_instance_t * -libvlc_new_env_args(void) -{ - unsigned int argc = 0, i = 0; - const char **argv = NULL; - char *args_env, *args_dup = NULL, *str = NULL, *token, *saveptr; - libvlc_instance_t *instance = NULL; - - args_env = getenv("EMOTION_LIBVLC_ARGS"); - if (!args_env) - goto fallback; - - /* dup since strtok modify the str */ - args_dup = strdup(args_env); - if (!args_dup) - goto fallback; - - /* call strtok to count the numbers of arguments */ - str = strdup(args_dup); - if (!str) - goto fallback; - - token = strtok_r(str, " ", &saveptr); - while (token) - { - argc++; - token = strtok_r(NULL, " ", &saveptr); - } - if (!argc) - goto fallback; - - /* alloc argv */ - argv = calloc(1, argc * sizeof(char *)); - if (!argv) - goto fallback; - - /* call strtok to fill argv */ - free(str); - str = strdup(args_dup); - if (!str) - goto fallback; - - token = strtok_r(str, " ", &saveptr); - while (token && i < argc) - { - argv[i++] = token; - token = strtok_r(NULL, " ", &saveptr); - } - argc = i; - - for (i = 0; i < argc; ++i) - INF("libvlc_argv[%d]: %s", i, argv[i]); - - instance = libvlc_new(argc, argv); - -fallback: - free(args_dup); - free(str); - free(argv); - return instance ? instance : libvlc_new(0, NULL); -} - -Eina_Bool -libvlc_module_init(void) -{ - if (libvlc) - { - return EINA_TRUE; - } - - if (getenv("EMOTION_FPS_DEBUG")) debug_fps = EINA_TRUE; - - eina_threads_init(); - eina_log_threads_enable(); - _emotion_libvlc_log_domain = eina_log_domain_register - ("emotion-libvlc", EINA_COLOR_ORANGE); - if (_emotion_libvlc_log_domain < 0) - { - EINA_LOG_CRIT("Could not register log domain 'emotion-libvlc'"); - return EINA_FALSE; - } - - libvlc = libvlc_new_env_args(); - if (!libvlc) - { - CRI("could not create libvlc instance"); - goto error_register; - } - EINA_LOG_INFO("using libvlc: %s", libvlc_get_version()); - libvlc_log_set(libvlc, libvlc_log, NULL); - - if (!_emotion_module_register(&em_engine)) - { - ERR("Could not register module %p", &em_engine); - goto error_register; - } - - return EINA_TRUE; - -error_register: - if (libvlc) - { - libvlc_release(libvlc); - libvlc = NULL; - } - eina_log_domain_unregister(_emotion_libvlc_log_domain); - _emotion_libvlc_log_domain = -1; - return EINA_FALSE; -} - -void -libvlc_module_shutdown(void) -{ - if (!libvlc) - { - EINA_LOG_ERR("too many libvlc_module_shutdown()"); - return; - } - - _emotion_module_unregister(&em_engine); - - libvlc_release(libvlc); - libvlc = NULL; - - eina_log_domain_unregister(_emotion_libvlc_log_domain); - _emotion_libvlc_log_domain = -1; -} - -#ifndef EMOTION_STATIC_BUILD_LIBVLC - -EINA_MODULE_INIT(libvlc_module_init); -EINA_MODULE_SHUTDOWN(libvlc_module_shutdown); - -#endif diff --git a/src/modules/emotion/libvlc/meson.build b/src/modules/emotion/libvlc/meson.build deleted file mode 100644 index e5646a414d..0000000000 --- a/src/modules/emotion/libvlc/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -generic_src = files([ - 'emotion_libvlc.c', -]) - -generic_deps = [dependency('libvlc', version: '>= 3.0')] - -shared_module(emotion_loader, - generic_src, - include_directories : config_dir, - dependencies: [eina, evas, emotion, generic_deps], - install: true, - install_dir : mod_install_dir, - c_args : package_c_args, -) diff --git a/src/modules/emotion/meson.build b/src/modules/emotion/meson.build index e20729ad22..595557b710 100644 --- a/src/modules/emotion/meson.build +++ b/src/modules/emotion/meson.build @@ -1,19 +1,11 @@ -emotion_loaders = [ -'gstreamer1', -'libvlc', -'xine' -] - -if sys_windows == false - emotion_loaders += 'generic' -endif +emotion_loaders = [ 'gstreamer1' ] foreach emotion_loader : emotion_loaders generic_src = [] generic_deps = [] mod_install_dir = join_paths(dir_lib, 'emotion', 'modules', emotion_loader, version_name) - if get_option('emotion-loaders-disabler').contains(emotion_loader) == false + if get_option('gstreamer') == true subdir(emotion_loader) module_files += join_paths(mod_install_dir, 'lib'+emotion_loader+'.'+sys_mod_extension) config_h.set('EMOTION_BUILD_'+emotion_loader.to_upper(), 1) diff --git a/src/modules/emotion/xine/emotion_xine.c b/src/modules/emotion/xine/emotion_xine.c deleted file mode 100644 index dd84c1cbc7..0000000000 --- a/src/modules/emotion/xine/emotion_xine.c +++ /dev/null @@ -1,1707 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include - -#include "emotion_modules.h" -#include "emotion_xine.h" - -int _emotion_xine_log_domain = -1; -static int _emotion_init_count = 0; - -/* internal util calls */ -static void *_em_slave (void *par); -static void _em_slave_event (void *data, int type, void *arg); -static Eina_Bool _em_fd_active (void *data, Ecore_Fd_Handler *fdh); -static void _em_event (void *data, const xine_event_t *event); -static void _em_module_event (void *data, int type); -static Eina_Bool _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh); -//static int _em_timer (void *data); -static void *_em_get_pos_len_th(void *par); -static void _em_get_pos_len (Emotion_Xine_Video *ev); - -extern plugin_info_t emotion_xine_plugin_info[]; - -static void em_frame_done(void *ef); - -/* this is a slave controller thread for the xine module - libxine loves - * to deadlock, internally stall and otherwise have unpredictable behavior - * if we use the main process thread for many things - so a lot will be - * farmed off to this slave. its job is to handle opening, closing, file - * opening, recoder init etc. and all sorts of things can that often block. - * anything this thread needs to return, it will return via the event pipe. - */ -static void * -_em_slave(void *par) -{ - Emotion_Xine_Video *ev; - void *buf[2]; - int len; - - ev = (Emotion_Xine_Video *)par; - while ((len = read(ev->fd_slave_read, buf, sizeof(buf))) > 0) - { - if (len == sizeof(buf)) - { - Emotion_Xine_Event *eev; - - ev = buf[0]; - eev = buf[1]; - switch (eev->mtype) - { - case 0: /* noop */ - break; - case 1: /* init */ - { - ev->decoder = xine_new(); - xine_init(ev->decoder); - xine_register_plugins(ev->decoder, emotion_xine_plugin_info); - if (1) - { - xine_cfg_entry_t cf; - if (xine_config_lookup_entry(ev->decoder, "input.dvd_use_readahead", &cf)) - { - cf.num_value = 1; // 0 or 1 - xine_config_update_entry(ev->decoder, &cf); - } - } - DBG("OPEN VIDEO PLUGIN..."); - if (!ev->opt_no_video) - ev->video = xine_open_video_driver(ev->decoder, "emotion", - XINE_VISUAL_TYPE_NONE, ev); - DBG("RESULT: xine_open_video_driver() = %p", ev->video); - // Let xine autodetect the best audio output driver - if (!ev->opt_no_audio) - ev->audio = xine_open_audio_driver(ev->decoder, NULL, ev); - // ev->audio = xine_open_audio_driver(ev->decoder, "oss", ev); - // dont use alsa - alsa has oss emulation. - // ev->audio = xine_open_audio_driver(ev->decoder, "alsa", ev); - // ev->audio = xine_open_audio_driver(ev->decoder, "arts", ev); - // ev->audio = xine_open_audio_driver(ev->decoder, "esd", ev); - ev->stream = xine_stream_new(ev->decoder, ev->audio, ev->video); - ev->queue = xine_event_new_queue(ev->stream); - xine_event_create_listener_thread(ev->queue, _em_event, ev); - ev->opening = 0; - ev->play_ok = 1; - _em_module_event(ev, 1); /* event - open done */ - } - break; - case 3: /* shutdown */ - { - _em_module_event(ev, 3); - DBG("shutdown stop"); - xine_stop(ev->stream); - // pthread_mutex_lock(&(ev->get_pos_len_mutex)); - if (!ev->get_pos_thread_deleted) - { - DBG("closing get_pos thread, %p", ev); - pthread_mutex_lock(&(ev->get_pos_len_mutex)); - pthread_cond_broadcast(&(ev->get_pos_len_cond)); - pthread_mutex_unlock(&(ev->get_pos_len_mutex)); - while (ev->get_poslen); - } - DBG("dispose %p", ev); - xine_dispose(ev->stream); - DBG("dispose evq %p", ev); - xine_event_dispose_queue(ev->queue); - DBG("close video drv %p", ev); - if (ev->video) xine_close_video_driver(ev->decoder, ev->video); - DBG("wait for vo to go"); - while (ev->have_vo); - DBG("vo gone"); - DBG("close audio drv %p", ev); - if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio); - DBG("xine exit %p", ev); - xine_exit(ev->decoder); - DBG("DONE %p", ev); - close(ev->fd_write); - close(ev->fd_read); - close(ev->fd_ev_write); - close(ev->fd_ev_read); - close(ev->fd_slave_write); - close(ev->fd_slave_read); - ev->closing = 0; - if (eev->xine_event) free(eev->xine_event); - free(eev); - free(ev); - return NULL; - } - break; - case 2: /* file open */ - { - int pos_stream = 0; - int pos_time = 0; - int length_time = 0; - uint32_t v; - char *file; - - file = eev->xine_event; - DBG("OPEN STREAM %s", file); - if (xine_open(ev->stream, file)) - { - if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time)) - { - if (length_time == 0) - { - ev->pos = (double)pos_stream / 65535; - ev->len = 1.0; - ev->no_time = 1; - } - else - { - ev->pos = 0.0; - ev->len = (double)length_time / 1000.0; - } - } - else - { - ev->pos = 0.0; - ev->len = 1.0; - } - v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_FRAME_DURATION); - if (v > 0) ev->fps = 90000.0 / (double)v; - v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_WIDTH); - ev->w = v; - v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HEIGHT); - ev->h = v; - v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO); - ev->ratio = (double)v / 10000.0; - ev->just_loaded = 1; - ev->get_poslen = 0; - xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); - } - _em_module_event(ev, 2); /* event - open done */ - } - break; - case 11: /* file close */ - { - DBG("done %p", ev); - em_frame_done(ev); - DBG("stop %p", ev); - xine_stop(ev->stream); - DBG("close %p", ev); - xine_close(ev->stream); - DBG("close done %p", ev); - _em_module_event(ev, 11); - } - break; - case 4: /* play */ - { - double pos; - int pos_stream, pos_time, length_time; - - pos = *((double *)eev->xine_event); - if ((xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) && - (EINA_DBL_EQ(pos, ev->pos)) && - (!ev->just_loaded)) - { - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); - } - else - { - if (ev->no_time) - xine_play(ev->stream, pos * 65535, 0); - else - xine_play(ev->stream, 0, pos * 1000); - } - ev->just_loaded = 0; - - if (xine_get_pos_length(ev->stream, - &pos_stream, - &pos_time, - &length_time)) - { - if (length_time == 0) - { - ev->pos = (double)pos_stream / 65535; - ev->len = 1.0; - ev->no_time = 1; - } - else - { - ev->pos = (double)pos_time / 1000.0; - ev->len = (double)length_time / 1000.0; - } - } - _em_module_event(ev, 4); - } - break; - case 5: /* stop */ - { - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - _em_module_event(ev, 5); - } - break; - case 6: /* seek */ - { - double pos; - - pos = *((double *)eev->xine_event); - if (ev->no_time) - xine_play(ev->stream, pos * 65535, 0); - else - xine_play(ev->stream, 0, pos * 1000); - if (!ev->play) - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - _em_module_event(ev, 6); - } - break; - case 7: /* eject */ - { - xine_eject(ev->stream); - _em_module_event(ev, 7); - } - break; - case 8: /* spu mute */ - { - xine_set_param(ev->stream, XINE_PARAM_IGNORE_SPU, ev->spu_mute); - _em_module_event(ev, 8); - } - break; - case 9: /* channel */ - { - xine_set_param(ev->stream, XINE_PARAM_SPU_CHANNEL, ev->spu_channel); - _em_module_event(ev, 9); - } - break; - case 10: /* vol */ - { - xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); - _em_module_event(ev, 10); - } - break; - case 12: /* audio mute */ - { - xine_set_param(ev->stream, XINE_PARAM_AUDIO_MUTE, ev->audio_mute); - } - break; - case 13: /* audio mute */ - { - xine_set_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ev->audio_channel); - } - break; - case 14: /* audio mute */ - { - xine_set_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL, ev->video_channel); - } - break; - default: - break; - } - if (eev->xine_event) free(eev->xine_event); - free(eev); - } - } - return NULL; -} -static void -_em_slave_event(void *data, int type, void *arg) -{ - void *buf[2]; - Emotion_Xine_Event *new_ev; - Emotion_Xine_Video *ev; - - ev = data; - new_ev = calloc(1, sizeof(Emotion_Xine_Event)); - if (!new_ev) return; - new_ev->mtype = type; - new_ev->type = -1; - new_ev->xine_event = arg; - buf[0] = data; - buf[1] = new_ev; - if (write(ev->fd_slave_write, buf, sizeof(buf)) < 0) perror("write"); -} - -static void * -em_add(const Emotion_Engine *api EINA_UNUSED, - Evas_Object *obj, - const Emotion_Module_Options *opt) -{ - Emotion_Xine_Video *ev; - int fds[2]; - sigset_t oldset, newset; - - ev = calloc(1, sizeof(Emotion_Xine_Video)); - EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL); - ev->obj = obj; - - 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_ev_read = fds[0]; - ev->fd_ev_write = fds[1]; - fcntl(ev->fd_ev_read, F_SETFL, O_NONBLOCK); - ev->fd_ev_handler = ecore_main_fd_handler_add(ev->fd_ev_read, - ECORE_FD_READ, _em_fd_ev_active, ev, NULL, NULL); - ecore_main_fd_handler_active_set(ev->fd_ev_handler, ECORE_FD_READ); - } - if (pipe(fds) == 0) - { - ev->fd_slave_read = fds[0]; - ev->fd_slave_write = fds[1]; - if (fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK) != 0) - ERR("Can't fcntl() slave write fd"); - } - ev->volume = 0.8; - ev->delete_me = 0; - ev->get_pos_thread_deleted = 0; - ev->opening = 1; - ev->play_ok = 0; - - if (opt) - { - ev->opt_no_audio = opt->no_audio; - ev->opt_no_video = opt->no_video; - } - - pthread_cond_init(&(ev->get_pos_len_cond), NULL); - pthread_mutex_init(&(ev->get_pos_len_mutex), NULL); - sigemptyset(&newset); - sigaddset(&newset, SIGPIPE); - sigaddset(&newset, SIGALRM); - sigaddset(&newset, SIGCHLD); - sigaddset(&newset, SIGUSR1); - sigaddset(&newset, SIGUSR2); - sigaddset(&newset, SIGHUP); - sigaddset(&newset, SIGQUIT); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGTERM); -#ifdef SIGPWR - sigaddset(&newset, SIGPWR); -#endif - pthread_sigmask(SIG_BLOCK, &newset, &oldset); - pthread_create(&ev->get_pos_len_th, NULL, _em_get_pos_len_th, ev); - pthread_create(&ev->slave_th, NULL, _em_slave, ev); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - - pthread_detach(ev->slave_th); - _em_slave_event(ev, 1, NULL); - - ev->buffer = 1.0; - - return ev; -} - -static void -em_del(void *ef) -{ - Emotion_Xine_Video *ev = ef; - - ev->closing = 1; - ev->delete_me = 1; - DBG("del fds %p", ev); - ecore_main_fd_handler_del(ev->fd_handler); - ev->fd_handler = NULL; - ecore_main_fd_handler_del(ev->fd_ev_handler); - ev->fd_ev_handler = NULL; - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - - ev->closing = 1; - _em_slave_event(ev, 3, NULL); - DBG("done %p", ev); -} - -static Eina_Bool -em_file_open(void *ef, const char *file) -{ - Emotion_Xine_Video *ev = ef; - _em_slave_event(ev, 2, strdup(file)); - return EINA_TRUE; -} - -static void -em_file_close(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (!ev) return; - _em_slave_event(ev, 11, NULL); -} - -static void -em_play(void *ef, double pos) -{ - Emotion_Xine_Video *ev; - double *ppos; - - ev = (Emotion_Xine_Video *)ef; - ev->play = 1; - ev->play_ok = 0; - ppos = malloc(sizeof(double)); - *ppos = pos; - _em_slave_event(ev, 4, ppos); -} - -static void -em_stop(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - ev->play = 0; - ev->play_ok = 0; - _em_slave_event(ev, 5, NULL); -} - -static void -em_size_get(void *ef, int *w, int *h) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (w) *w = ev->w; - if (h) *h = ev->h; -} - -static void -em_pos_set(void *ef, double pos) -{ - Emotion_Xine_Video *ev; - double *ppos; - - ev = (Emotion_Xine_Video *)ef; - ppos = malloc(sizeof(double)); - *ppos = pos; - _em_slave_event(ev, 6, ppos); -} - -static double -em_len_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->len; -} - -static double -em_buffer_size_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->buffer; -} - -static int -em_fps_num_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return (int)(ev->fps * 10000.0); -} - -static int -em_fps_den_get(void *ef EINA_UNUSED) -{ - return 10000; -} - -static double -em_fps_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->fps; -} - -static double -em_pos_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - _em_get_pos_len(ev); - return ev->pos; -} - -static void -em_vis_set(void *ef, Emotion_Vis vis) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->vis == vis) return; - ev->vis = vis; -} - -static Emotion_Vis -em_vis_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - - return ev->vis; -} - -static Eina_Bool -em_vis_supported(void *ef EINA_UNUSED, Emotion_Vis vis EINA_UNUSED) -{ - return EINA_FALSE; -} - -static double -em_ratio_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->ratio; -} - -static int -em_video_handled(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO) && - xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED)); -} - -static int -em_audio_handled(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_AUDIO) && - xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_HANDLED)); -} - -static int -em_seekable(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE); -} - -static void -em_frame_done(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->cur_frame) - { - ev->fq--; - if (ev->cur_frame->done_func) - ev->cur_frame->done_func(ev->cur_frame->done_data); - ev->cur_frame = NULL; - } -} - -static Emotion_Format -em_format_get(void *ef) -{ - Emotion_Xine_Video *ev; - volatile Emotion_Xine_Video_Frame *fr; - - ev = (Emotion_Xine_Video *)ef; - fr = ev->cur_frame; - if (fr) return fr->format; - return EMOTION_FORMAT_YV12; -} - -static void -em_video_data_size_get(void *ef, int *w, int *h) -{ - Emotion_Xine_Video *ev; - volatile Emotion_Xine_Video_Frame *fr; - - ev = (Emotion_Xine_Video *)ef; - fr = ev->cur_frame; - if (!fr) - { - if (w) *w = 0; - if (h) *h = 0; - return; - } - if (w) *w = fr->w; - if (h) *h = fr->h; -} - -static int -em_yuv_rows_get(void *ef, int w EINA_UNUSED, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows) -{ - Emotion_Xine_Video *ev; - volatile Emotion_Xine_Video_Frame *fr; - - ev = (Emotion_Xine_Video *)ef; - fr = ev->cur_frame; - if (!fr) return 0; - if (fr->y) - { - int i; - - for (i = 0; i < h; i++) yrows[i] = fr->y + (i * fr->y_stride); - for (i = 0; i < (h / 2); i++) urows[i] = fr->u + (i * fr->u_stride); - for (i = 0; i < (h / 2); i++) vrows[i] = fr->v + (i * fr->v_stride); - return 1; - } - return 0; -} - -static int -em_bgra_data_get(void *ef, unsigned char **bgra_data) -{ - Emotion_Xine_Video *ev; - volatile Emotion_Xine_Video_Frame *fr; - - ev = (Emotion_Xine_Video *)ef; - fr = ev->cur_frame; - if (!fr) return 0; - if (fr->bgra_data) - { - *bgra_data = fr->bgra_data; - return 1; - } - return 0; -} - -static void -em_event_feed(void *ef, int event) -{ - Emotion_Xine_Video *ev; - xine_event_t xine_event; - - ev = (Emotion_Xine_Video *)ef; - if ((ev->opening) || (!ev->play_ok)) return; - xine_event.data_length = 0; - xine_event.data = NULL; - xine_event.stream = ev->stream; - gettimeofday(&xine_event.tv, NULL); - switch (event) - { - case EMOTION_EVENT_MENU1: - xine_event.type = XINE_EVENT_INPUT_MENU1; - break; - case EMOTION_EVENT_MENU2: - xine_event.type = XINE_EVENT_INPUT_MENU2; - break; - case EMOTION_EVENT_MENU3: - xine_event.type = XINE_EVENT_INPUT_MENU3; - break; - case EMOTION_EVENT_MENU4: - xine_event.type = XINE_EVENT_INPUT_MENU4; - break; - case EMOTION_EVENT_MENU5: - xine_event.type = XINE_EVENT_INPUT_MENU5; - break; - case EMOTION_EVENT_MENU6: - xine_event.type = XINE_EVENT_INPUT_MENU6; - break; - case EMOTION_EVENT_MENU7: - xine_event.type = XINE_EVENT_INPUT_MENU7; - break; - case EMOTION_EVENT_UP: - xine_event.type = XINE_EVENT_INPUT_UP; - break; - case EMOTION_EVENT_DOWN: - xine_event.type = XINE_EVENT_INPUT_DOWN; - break; - case EMOTION_EVENT_LEFT: - xine_event.type = XINE_EVENT_INPUT_LEFT; - break; - case EMOTION_EVENT_RIGHT: - xine_event.type = XINE_EVENT_INPUT_RIGHT; - break; - case EMOTION_EVENT_SELECT: - xine_event.type = XINE_EVENT_INPUT_SELECT; - break; - case EMOTION_EVENT_NEXT: - xine_event.type = XINE_EVENT_INPUT_NEXT; - break; - case EMOTION_EVENT_PREV: - xine_event.type = XINE_EVENT_INPUT_PREVIOUS; - break; - case EMOTION_EVENT_ANGLE_NEXT: - xine_event.type = XINE_EVENT_INPUT_ANGLE_NEXT; - break; - case EMOTION_EVENT_ANGLE_PREV: - xine_event.type = XINE_EVENT_INPUT_ANGLE_PREVIOUS; - break; - case EMOTION_EVENT_FORCE: - xine_event.type = XINE_EVENT_INPUT_BUTTON_FORCE; - break; - case EMOTION_EVENT_0: - xine_event.type = XINE_EVENT_INPUT_NUMBER_0; - break; - case EMOTION_EVENT_1: - xine_event.type = XINE_EVENT_INPUT_NUMBER_1; - break; - case EMOTION_EVENT_2: - xine_event.type = XINE_EVENT_INPUT_NUMBER_2; - break; - case EMOTION_EVENT_3: - xine_event.type = XINE_EVENT_INPUT_NUMBER_3; - break; - case EMOTION_EVENT_4: - xine_event.type = XINE_EVENT_INPUT_NUMBER_4; - break; - case EMOTION_EVENT_5: - xine_event.type = XINE_EVENT_INPUT_NUMBER_5; - break; - case EMOTION_EVENT_6: - xine_event.type = XINE_EVENT_INPUT_NUMBER_6; - break; - case EMOTION_EVENT_7: - xine_event.type = XINE_EVENT_INPUT_NUMBER_7; - break; - case EMOTION_EVENT_8: - xine_event.type = XINE_EVENT_INPUT_NUMBER_8; - break; - case EMOTION_EVENT_9: - xine_event.type = XINE_EVENT_INPUT_NUMBER_9; - break; - case EMOTION_EVENT_10: - xine_event.type = XINE_EVENT_INPUT_NUMBER_10_ADD; - break; - default: - return; - break; - } - xine_event_send(ev->stream, &xine_event); -} - -static void -em_event_mouse_button_feed(void *ef, int button EINA_UNUSED, int x, int y) -{ - Emotion_Xine_Video *ev; - xine_event_t xine_event; - xine_input_data_t xine_input; - - ev = (Emotion_Xine_Video *)ef; - if ((ev->opening) || (!ev->play_ok)) return; - xine_event.stream = ev->stream; - gettimeofday(&xine_event.tv, NULL); - xine_event.type = XINE_EVENT_INPUT_MOUSE_BUTTON; - xine_input.button = 1; - xine_input.x = x; - xine_input.y = y; - xine_event.data = &xine_input; - xine_event.data_length = sizeof(xine_input); - xine_event_send(ev->stream, &xine_event); -} - -static void -em_event_mouse_move_feed(void *ef, int x, int y) -{ - Emotion_Xine_Video *ev; - xine_event_t xine_event; - xine_input_data_t xine_input; - - ev = (Emotion_Xine_Video *)ef; - if ((ev->opening) || (!ev->play_ok)) return; - xine_event.stream = ev->stream; - gettimeofday(&xine_event.tv, NULL); - xine_event.type = XINE_EVENT_INPUT_MOUSE_MOVE; - xine_input.button = 0; - xine_input.x = x; - xine_input.y = y; - xine_event.data = &xine_input; - xine_event.data_length = sizeof(xine_input); - xine_event_send(ev->stream, &xine_event); -} - -static int -em_video_channel_count(void *ef) -{ - Emotion_Xine_Video *ev; - int v; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS); - if ((v < 1) && - xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) return 1; - return v; -} - -static void -em_video_channel_set(void *ef, int channel) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (channel < 0) channel = 0; - ev->video_channel = channel; - _em_slave_event(ev, 14, NULL); -} - -static int -em_video_channel_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL); -} - -static void -em_video_subtitle_file_set(void *video EINA_UNUSED, - const char *filepath EINA_UNUSED) -{ - DBG("video_subtitle_file_set not implemented for xine yet."); -} - -static const char * -em_video_subtitle_file_get(void *video EINA_UNUSED) -{ - DBG("video_subtitle_file_get not implemented for xine yet."); - return NULL; -} - -static const char * -em_video_channel_name_get(void *ef EINA_UNUSED, int channel EINA_UNUSED) -{ - return NULL; -} - -static void -em_video_channel_mute_set(void *ef, int mute) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - ev->video_mute = mute; -} - -static int -em_video_channel_mute_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->video_mute; -} - -static int -em_audio_channel_count(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL); -} - -static void -em_audio_channel_set(void *ef, int channel) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (channel < -1) channel = -1; - ev->audio_channel = channel; - _em_slave_event(ev, 13, NULL); -} - -static int -em_audio_channel_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL); -} - -static const char * -em_audio_channel_name_get(void *ef, int channel) -{ - Emotion_Xine_Video *ev; - static char lang[XINE_LANG_MAX + 1]; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening) return NULL; - lang[0] = 0; - if (xine_get_audio_lang(ev->stream, channel, lang)) return lang; - return NULL; -} - -static void -em_audio_channel_mute_set(void *ef, int mute) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - ev->audio_mute = mute; - _em_slave_event(ev, 12, NULL); -} - -static int -em_audio_channel_mute_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->audio_mute; -} - -static void -em_audio_channel_volume_set(void *ef, double vol) -{ - Emotion_Xine_Video *ev; - - if (vol < 0.0) vol = 0.0; - else if (vol > 1.0) vol = 1.0; - - ev = (Emotion_Xine_Video *)ef; - ev->volume = vol; - _em_slave_event(ev, 10, NULL); -} - -static double -em_audio_channel_volume_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return ev->volume; - ev->volume = xine_get_param(ev->stream, XINE_PARAM_AUDIO_VOLUME) / 100.0; - return ev->volume; -} - -static int -em_spu_channel_count(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL); -} - -static void -em_spu_channel_set(void *ef, int channel) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (channel < 0) channel = 0; - ev->spu_channel = channel; - _em_slave_event(ev, 9, NULL); -} - -static int -em_spu_channel_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL); -} - -static const char * -em_spu_channel_name_get(void *ef, int channel) -{ - Emotion_Xine_Video *ev; - static char lang[XINE_LANG_MAX + 1]; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening) return NULL; - lang[0] = 0; - if (xine_get_spu_lang(ev->stream, channel, lang)) return lang; - return NULL; -} - -static void -em_spu_channel_mute_set(void *ef, int mute) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - ev->spu_mute = mute; - _em_slave_event(ev, 8, NULL); -} - -static int -em_spu_channel_mute_get(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - return ev->spu_mute; -} - -static int -em_chapter_count(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - if (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS)) - return 99; - return 0; -} - -static void -em_chapter_set(void *ef EINA_UNUSED, int chapter EINA_UNUSED) -{ -} - -static int -em_chapter_get(void *ef EINA_UNUSED) -{ - return 0; -} - -static const char * -em_chapter_name_get(void *ef EINA_UNUSED, int chapter EINA_UNUSED) -{ - return NULL; -} - -static void -em_speed_set(void *ef EINA_UNUSED, double speed EINA_UNUSED) -{ -} - -static double -em_speed_get(void *ef EINA_UNUSED) -{ - return 1.0; -} - -static int -em_eject(void *ef) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - _em_slave_event(ev, 7, NULL); - return 1; -} - -static const char * -em_meta_get(void *ef, int meta) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if ((ev->opening) || (!ev->play_ok)) return NULL; - switch (meta) - { - case META_TRACK_TITLE: - return xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE); - break; - case META_TRACK_ARTIST: - return xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST); - break; - case META_TRACK_GENRE: - return xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE); - break; - case META_TRACK_COMMENT: - return xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT); - break; - case META_TRACK_ALBUM: - return xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM); - break; - case META_TRACK_YEAR: - return xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR); - break; - case META_TRACK_DISCID: - return xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID); - break; - default: - break; - } - return NULL; -} - -static Eina_Bool -_em_fd_active(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh) -{ - void *buf; - int fd, len; - Emotion_Xine_Video_Frame *fr; - - fd = ecore_main_fd_handler_fd_get(fdh); - if (fd < 0) return EINA_TRUE; - while ((len = read(fd, &buf, sizeof(buf))) > 0) - { - if (len == sizeof(buf)) - { - Emotion_Xine_Video *ev; - - fr = buf; - ev = _emotion_video_get(fr->obj); - if (ev) - { - em_frame_done(ev); - ev->cur_frame = fr; - _em_get_pos_len(ev); - if ((xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) && - (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED))) - { - if (ev->video_mute) em_frame_done(ev); - else _emotion_frame_new(fr->obj); - } - _emotion_frame_resize(fr->obj, fr->w, fr->h, fr->ratio); - _emotion_video_pos_update(fr->obj, ev->pos, ev->len); - } - } - } - return EINA_TRUE; -} - -static void -_em_event(void *data, const xine_event_t *event) -{ - void *buf[2]; - Emotion_Xine_Event *new_ev; - Emotion_Xine_Video *ev; - - ev = data; - new_ev = calloc(1, sizeof(Emotion_Xine_Event)); - if (!new_ev) return; - new_ev->mtype = 0; - new_ev->type = event->type; - if (event->data) - { - new_ev->xine_event = malloc(event->data_length); - if (!new_ev->xine_event) - { - free(new_ev); - return; - } - memcpy(new_ev->xine_event, event->data, event->data_length); - } - buf[0] = data; - buf[1] = new_ev; - if (write(ev->fd_ev_write, buf, sizeof(buf)) < 0) perror("write"); -} - -static void -_em_module_event(void *data, int type) -{ - void *buf[2]; - Emotion_Xine_Event *new_ev; - Emotion_Xine_Video *ev; - - ev = data; - new_ev = calloc(1, sizeof(Emotion_Xine_Event)); - if (!new_ev) return; - new_ev->mtype = type; - new_ev->type = -1; - buf[0] = data; - buf[1] = new_ev; - if (write(ev->fd_ev_write, buf, sizeof(buf)) < 0) perror("write"); -} - -static Eina_Bool -_em_audio_only_poller(void *data) -{ - Emotion_Xine_Video *ev; - - ev = data; - _em_get_pos_len(ev); - return EINA_TRUE; -} - -static Eina_Bool -_em_fd_ev_active(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh) -{ - int fd, len; - void *buf[2]; - - fd = ecore_main_fd_handler_fd_get(fdh); - while ((len = read(fd, buf, sizeof(buf))) > 0) - { - if (len == sizeof(buf)) - { - Emotion_Xine_Video *ev; - Emotion_Xine_Event *eev; - - ev = buf[0]; - eev = buf[1]; - if (eev->mtype != 0) - { - switch (eev->mtype) - { - case 1: /* init done */ - ev->play_ok = 1; - break; - case 2: /* open done */ - ev->play_ok = 1; - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - _emotion_open_done(ev->obj); - _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio); - break; - case 3: /* shutdown done */ - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - ev->play_ok = 1; - break; - case 4: /* play done */ - ev->play_ok = 1; - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - if ((!(xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO) && - xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED))) && - (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_AUDIO) && - xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_HANDLED))) - ev->anim = ecore_evas_animator_add(ev->obj, _em_audio_only_poller, ev); - _emotion_playback_started(ev->obj); - break; - case 5: /* stop done */ - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - ev->play_ok = 1; - break; - case 6: /* seek done */ - ev->play_ok = 1; - _emotion_seek_done(ev->obj); - _em_get_pos_len(ev); - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - break; - case 7: /* eject done */ - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - ev->play_ok = 1; - break; - case 8: /* spu mute done */ - ev->play_ok = 1; - break; - case 9: /* channel done */ - ev->play_ok = 1; - break; - case 10: /* volume done */ - ev->play_ok = 1; - break; - case 11: /* close done */ - if (ev->anim) - { - ecore_animator_del(ev->anim); - ev->anim = NULL; - } - ev->play_ok = 1; - break; - case 15: /* get pos done */ - if (!EINA_DBL_EQ(ev->last_pos, ev->pos)) - { - ev->last_pos = ev->pos; - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - } - break; - default: - break; - } - } - else - { - switch (eev->type) - { - case XINE_EVENT_UI_PLAYBACK_FINISHED: - { - ev->play = 0; - _emotion_decode_stop(ev->obj); - _emotion_playback_finished(ev->obj); - } - break; - case XINE_EVENT_UI_CHANNELS_CHANGED: - { - _emotion_channels_change(ev->obj); - } - break; - case XINE_EVENT_UI_SET_TITLE: - { - xine_ui_data_t *e; - - e = (xine_ui_data_t *)eev->xine_event; - _emotion_title_set(ev->obj, e->str); - } - break; - case XINE_EVENT_FRAME_FORMAT_CHANGE: - break; - case XINE_EVENT_UI_MESSAGE: - { - WRN("UI Message [FIXME: break this out to emotion api]"); - // e->type = error type(XINE_MSG_NO_ERROR, XINE_MSG_GENERAL_WARNING, XINE_MSG_UNKNOWN_HOST etc.) - // e->messages is a list of messages DOUBLE null terminated - } - break; - case XINE_EVENT_AUDIO_LEVEL: - { - _emotion_audio_level_change(ev->obj); - WRN("Audio Level [FIXME: break this out to emotion api]"); - // e->left (0->100) - // e->right - // e->mute - } - break; - case XINE_EVENT_PROGRESS: - { - xine_progress_data_t *e; - - e = (xine_progress_data_t *)eev->xine_event; - DBG("PROGRESS: %i", e->percent); - ev->buffer = e->percent; - _emotion_progress_set(ev->obj, (char *)e->description, (double)e->percent / 100.0); - } - break; - case XINE_EVENT_MRL_REFERENCE_EXT: - { - xine_mrl_reference_data_ext_t *e; - - e = (xine_mrl_reference_data_ext_t *)eev->xine_event; - _emotion_file_ref_set(ev->obj, e->mrl, e->alternative); - } - break; - case XINE_EVENT_UI_NUM_BUTTONS: - { - xine_ui_data_t *e; - - e = (xine_ui_data_t *)eev->xine_event; - _emotion_spu_button_num_set(ev->obj, e->num_buttons); - } - break; - case XINE_EVENT_SPU_BUTTON: - { - xine_spu_button_t *e; - - e = (xine_spu_button_t *)eev->xine_event; - if (e->direction == 1) - _emotion_spu_button_set(ev->obj, e->button); - else - _emotion_spu_button_set(ev->obj, -1); - } - break; - case XINE_EVENT_DROPPED_FRAMES: - { - xine_dropped_frames_t *e; - - e = (xine_dropped_frames_t *)eev->xine_event; - WRN("Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]", e->skipped_frames, e->discarded_frames); - // e->skipped_frames = % frames skipped * 10 - // e->discarded_frames = % frames skipped * 10 - } - break; - default: - // DBG("unknown event type %i", eev->type); - break; - } - } - if (eev->xine_event) free(eev->xine_event); - free(eev); - } - } - return EINA_TRUE; -} - -static void * -_em_get_pos_len_th(void *par) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)par; - - for (;;) - { - pthread_mutex_lock(&(ev->get_pos_len_mutex)); - pthread_cond_wait(&(ev->get_pos_len_cond), &(ev->get_pos_len_mutex)); - pthread_mutex_unlock(&(ev->get_pos_len_mutex)); - if (ev->get_poslen) - { - int pos_stream = 0; - int pos_time = 0; - int length_time = 0; - - if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time)) - { - if (length_time == 0) - { - ev->pos = (double)pos_stream / 65535; - ev->len = 1.0; - ev->no_time = 1; - } - else - { - ev->pos = (double)pos_time / 1000.0; - ev->len = (double)length_time / 1000.0; - ev->no_time = 0; - } - } - ev->get_poslen = 0; - _em_module_event(ev, 15); /* event - getpos done */ - //DBG("get pos %3.3f", ev->pos); - } - if (ev->delete_me) - { - ev->get_pos_thread_deleted = 1; - return NULL; - } - } - return NULL; -} - -static void -_em_get_pos_len(Emotion_Xine_Video *ev) -{ - if (!ev->play_ok) return; - ev->get_poslen = 1; - pthread_mutex_lock(&(ev->get_pos_len_mutex)); - pthread_cond_broadcast(&(ev->get_pos_len_cond)); - pthread_mutex_unlock(&(ev->get_pos_len_mutex)); -} - -static const Emotion_Engine em_engine = -{ - EMOTION_ENGINE_API_VERSION, - EMOTION_ENGINE_PRIORITY_DEFAULT, - "xine", - em_add, /* add */ - em_del, /* del */ - 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_len_get, /* len_get */ - em_buffer_size_get, /* buffer_size_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_set, /* vis_set */ - em_vis_get, /* vis_get */ - em_vis_supported, /* vis_supported */ - 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 */ - em_yuv_rows_get, /* 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_subtitle_file_set, /* video_subtitle_file_set */ - em_video_subtitle_file_get, /* video_subtitle_file_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, /* priority_set */ - NULL, /* priority_get */ - NULL /* em_meta_artwork_get */ -}; - -Eina_Bool -xine_module_init(void) -{ - if (_emotion_init_count > 0) - { - _emotion_init_count++; - return EINA_TRUE; - } - - eina_threads_init(); - eina_log_threads_enable(); - _emotion_xine_log_domain = eina_log_domain_register - ("emotion-xine", EINA_COLOR_LIGHTCYAN); - if (_emotion_xine_log_domain < 0) - { - EINA_LOG_CRIT("Could not register log domain 'emotion-xine'"); - return EINA_FALSE; - } - - if (!_emotion_module_register(&em_engine)) - { - CRI("Could not register module %p", &em_engine); - eina_log_domain_unregister(_emotion_xine_log_domain); - _emotion_xine_log_domain = -1; - return EINA_FALSE; - } - - _emotion_init_count = 1; - return EINA_TRUE; -} - -void -xine_module_shutdown(void) -{ - if (_emotion_init_count > 1) - { - _emotion_init_count--; - return; - } - else if (_emotion_init_count == 0) - { - EINA_LOG_ERR("too many xine_module_shutdown()"); - return; - } - _emotion_init_count = 0; - - _emotion_module_unregister(&em_engine); - - eina_log_domain_unregister(_emotion_xine_log_domain); - _emotion_xine_log_domain = -1; -} - -#ifndef EMOTION_STATIC_BUILD_XINE - -EINA_MODULE_INIT(xine_module_init); -EINA_MODULE_SHUTDOWN(xine_module_shutdown); - -#endif - -#if 0 -void -em_debug(Emotion_Xine_Video *ev) -{ - int has_chapters = 0; - int max_spu = 0; - int max_audio = 0; - int video_channels = 0; - int video_streams = 0; - int video_seekable = 0; - char *title; - char *comment; - char *artist; - char *genre; - char *album; - char *year; - char *cdindex_discid; - int video_channel = 0; - int audio_channel = 0; - int spu_channel = 0; - int video_ratio = 0; - int audio_mode = 0; - -// return; - has_chapters = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS); - max_spu = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL); - max_audio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL); - video_channels = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS); - video_streams = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_STREAMS); - video_seekable = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE); - title = xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE); - comment = xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT); - artist = xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST); - genre = xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE); - album = xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM); - year = xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR); - cdindex_discid = xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID); - video_channel = xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL); - audio_channel = xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL); - spu_channel = xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL); - video_ratio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO); - audio_mode = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_MODE); - DBG("has_chapters = %i", has_chapters); - DBG("max_spu = %i", max_spu); - DBG("max_audio = %i", max_audio); - DBG("video_channels = %i", video_channels); - DBG("video_streams = %i", video_streams); - DBG("video_seekable = %i", video_seekable); - DBG("title = %s", title); - DBG("comment = %s", comment); - DBG("artist = %s", artist); - DBG("genre = %s", genre); - DBG("album = %s", album); - DBG("year = %s", year); - DBG("cdindex_discid = %s", cdindex_discid); - DBG("video_channel = %i", video_channel); - DBG("audio_channel = %i", audio_channel); - DBG("spu_channels = %i", spu_channel); - DBG("video_ratio = %i", video_ratio); - DBG("audio_mode = %i", audio_mode); - { - int i; - - for (i = 0; i <= max_audio; i++) - { - char lang[XINE_LANG_MAX + 1]; - char buf[128] = "NONE"; - - lang[0] = 0; - if (xine_get_audio_lang(ev->stream, i, lang)) - eina_strlcpy(buf, lang, sizeof(buf)); - DBG(" AUDIO %i = %s", i, buf); - } - for (i = 0; i <= max_spu; i++) - { - char lang[XINE_LANG_MAX + 1]; - char buf[128] = "NONE"; - - lang[0] = 0; - if (xine_get_spu_lang(ev->stream, i, lang)) - eina_strlcpy(buf, lang, sizeof(buf)); - DBG(" SPU %i = %s", i, buf); - } - } -} -#endif diff --git a/src/modules/emotion/xine/emotion_xine.h b/src/modules/emotion/xine/emotion_xine.h deleted file mode 100644 index 9807624e14..0000000000 --- a/src/modules/emotion/xine/emotion_xine.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef EMOTION_XINE_H -#define EMOTION_XINE_H - -#include -#include -#include -#include -#include - -typedef struct _Emotion_Xine_Video Emotion_Xine_Video; -typedef struct _Emotion_Xine_Video_Frame Emotion_Xine_Video_Frame; -typedef struct _Emotion_Xine_Event Emotion_Xine_Event; - -struct _Emotion_Xine_Video -{ - xine_t *decoder; - xine_video_port_t *video; - xine_audio_port_t *audio; - xine_stream_t *stream; - xine_event_queue_t *queue; - volatile double len; - volatile double pos; - volatile double last_pos; - volatile double volume; - volatile double buffer; - double fps; - double ratio; - int w, h; - Evas_Object *obj; - volatile Emotion_Xine_Video_Frame *cur_frame; - volatile int get_poslen; - volatile int spu_channel; - volatile int audio_channel; - volatile int video_channel; - volatile int fq; - Emotion_Vis vis; - int fd_read; - int fd_write; - Ecore_Fd_Handler *fd_handler; - int fd_ev_read; - int fd_ev_write; - Ecore_Fd_Handler *fd_ev_handler; - Ecore_Animator *anim; - unsigned char play : 1; - unsigned char just_loaded : 1; - unsigned char video_mute : 1; - unsigned char audio_mute : 1; - unsigned char spu_mute : 1; - Eina_Bool opt_no_video : 1; - Eina_Bool opt_no_audio : 1; - volatile unsigned char delete_me : 1; - volatile unsigned char no_time : 1; - volatile unsigned char opening : 1; - volatile unsigned char closing : 1; - volatile unsigned char have_vo : 1; - volatile unsigned char play_ok : 1; - - pthread_t get_pos_len_th; - pthread_cond_t get_pos_len_cond; - pthread_mutex_t get_pos_len_mutex; - - pthread_t slave_th; - int fd_slave_read; - int fd_slave_write; - - unsigned char get_pos_thread_deleted : 1; -}; - -struct _Emotion_Xine_Video_Frame -{ - int w, h; - double ratio; - Emotion_Format format; - unsigned char *y, *u, *v; - unsigned char *bgra_data; - int y_stride, u_stride, v_stride; - Evas_Object *obj; - double timestamp; - void (*done_func)(void *data); - void *done_data; - void *frame; -}; - -struct _Emotion_Xine_Event -{ - int type; - void *xine_event; - int mtype; -}; - -#ifdef DBG -#undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_emotion_xine_log_domain, __VA_ARGS__) - -#ifdef INF -#undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_emotion_xine_log_domain, __VA_ARGS__) - -#ifdef WRN -#undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_emotion_xine_log_domain, __VA_ARGS__) - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_emotion_xine_log_domain, __VA_ARGS__) - -#ifdef CRI -#undef CRI -#endif -#define CRI(...) EINA_LOG_DOM_CRIT(_emotion_xine_log_domain, __VA_ARGS__) - -extern int _emotion_xine_log_domain; - -#endif diff --git a/src/modules/emotion/xine/emotion_xine_vo_out.c b/src/modules/emotion/xine/emotion_xine_vo_out.c deleted file mode 100644 index 01c18f8894..0000000000 --- a/src/modules/emotion/xine/emotion_xine_vo_out.c +++ /dev/null @@ -1,766 +0,0 @@ -/***************************************************************************/ -/*** emotion xine display engine ***/ -/***************************************************************************/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include - -#include -#include -#include - -#include "emotion_modules.h" -#include "emotion_xine.h" - -#include -#include -#include -#include -#include - -#define BLEND_BYTE(dst, src, o) (((src)*o + ((dst)*(0xf-o)))/0xf) - -/***************************************************************************/ -typedef struct _Emotion_Frame Emotion_Frame; -typedef struct _Emotion_Driver Emotion_Driver; -typedef struct _Emotion_Class Emotion_Class; -typedef struct _Emotion_Lut Emotion_Lut; - -struct _Emotion_Frame -{ - vo_frame_t vo_frame; - int width; - int height; - double ratio; - int format; - xine_t *xine; - - Emotion_Xine_Video_Frame frame; - unsigned char in_use : 1; -}; - -struct _Emotion_Driver -{ - vo_driver_t vo_driver; - config_values_t *config; - int ratio; - xine_t *xine; - Emotion_Xine_Video *ev; -}; - -struct _Emotion_Class -{ - video_driver_class_t driver_class; - config_values_t *config; - xine_t *xine; -}; - -struct _Emotion_Lut -{ - uint8_t cb : 8; - uint8_t cr : 8; - uint8_t y : 8; - uint8_t foo : 8; -} __attribute__ ((packed)); - -typedef void (*done_func_type)(void *data); - -/***************************************************************************/ -static void *_emotion_class_init (xine_t *xine, void *visual); -static void _emotion_class_dispose (video_driver_class_t *driver_class); -static char *_emotion_class_identifier_get (video_driver_class_t *driver_class); -static char *_emotion_class_description_get (video_driver_class_t *driver_class); - -static vo_driver_t *_emotion_open (video_driver_class_t *driver_class, const void *visual); -static void _emotion_dispose (vo_driver_t *vo_driver); - -static int _emotion_redraw (vo_driver_t *vo_driver); - -static uint32_t _emotion_capabilities_get (vo_driver_t *vo_driver); -static int _emotion_gui_data_exchange (vo_driver_t *vo_driver, int data_type, void *data); - -static int _emotion_property_set (vo_driver_t *vo_driver, int property, int value); -static int _emotion_property_get (vo_driver_t *vo_driver, int property); -static void _emotion_property_min_max_get (vo_driver_t *vo_driver, int property, int *min, int *max); - -static vo_frame_t *_emotion_frame_alloc (vo_driver_t *vo_driver); -static void _emotion_frame_dispose (vo_frame_t *vo_frame); -static void _emotion_frame_format_update (vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags); -static void _emotion_frame_display (vo_driver_t *vo_driver, vo_frame_t *vo_frame); -static void _emotion_frame_field (vo_frame_t *vo_frame, int which_field); - -static void _emotion_frame_data_free (Emotion_Frame *fr); -static void _emotion_frame_data_unlock (Emotion_Frame *fr); - -static void _emotion_overlay_begin (vo_driver_t *vo_driver, vo_frame_t *vo_frame, int changed); -static void _emotion_overlay_end (vo_driver_t *vo_driver, vo_frame_t *vo_frame); -static void _emotion_overlay_blend (vo_driver_t *vo_driver, vo_frame_t *vo_frame, vo_overlay_t *vo_overlay); - -static void _emotion_overlay_mem_blend_8 (uint8_t *mem, uint8_t val, uint8_t o, size_t sz); -static void _emotion_overlay_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitches[3]); - -static void _emotion_yuy2_to_bgra32 (int width, int height, unsigned char *src, unsigned char *dst); - -/***************************************************************************/ -static vo_info_t _emotion_info = -{ - 1, /* priority */ - XINE_VISUAL_TYPE_NONE /* visual type */ -}; - -plugin_info_t emotion_xine_plugin_info[] = -{ - { PLUGIN_VIDEO_OUT, 21, "emotion", XINE_VERSION_CODE, &_emotion_info, _emotion_class_init }, - { PLUGIN_VIDEO_OUT, 22, "emotion", XINE_VERSION_CODE, &_emotion_info, _emotion_class_init }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - -/***************************************************************************/ -static void * -_emotion_class_init(xine_t *xine, void *visual EINA_UNUSED) -{ - Emotion_Class *cl; - -// DBG(""); - cl = (Emotion_Class *) malloc(sizeof(Emotion_Class)); - if (!cl) return NULL; - cl->driver_class.open_plugin = _emotion_open; -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) - cl->driver_class.get_identifier = _emotion_class_identifier_get; - cl->driver_class.get_description = _emotion_class_description_get; -#else - cl->driver_class.identifier = _emotion_class_identifier_get(NULL); - cl->driver_class.description = _emotion_class_description_get(NULL); -#endif - cl->driver_class.dispose = _emotion_class_dispose; - cl->config = xine->config; - cl->xine = xine; - - return cl; -} - -static void -_emotion_class_dispose(video_driver_class_t *driver_class) -{ - Emotion_Class *cl; - - cl = (Emotion_Class *)driver_class; - free(cl); -} - -static char * -_emotion_class_identifier_get(video_driver_class_t *driver_class EINA_UNUSED) -{ - return "emotion"; -} - -static char * -_emotion_class_description_get(video_driver_class_t *driver_class EINA_UNUSED) -{ - return "Emotion xine video output plugin"; -} - -/***************************************************************************/ -static vo_driver_t * -_emotion_open(video_driver_class_t *driver_class, const void *visual) -{ - Emotion_Class *cl; - Emotion_Driver *dv; - - cl = (Emotion_Class *)driver_class; - /* visual here is the data ptr passed to xine_open_video_driver() */ -// DBG(""); - dv = (Emotion_Driver *)malloc(sizeof(Emotion_Driver)); - if (!dv) return NULL; - - dv->config = cl->config; - dv->xine = cl->xine; - dv->ratio = XINE_VO_ASPECT_AUTO; - dv->vo_driver.get_capabilities = _emotion_capabilities_get; - dv->vo_driver.alloc_frame = _emotion_frame_alloc; - dv->vo_driver.update_frame_format = _emotion_frame_format_update; - dv->vo_driver.overlay_begin = _emotion_overlay_begin; - dv->vo_driver.overlay_blend = _emotion_overlay_blend; - dv->vo_driver.overlay_end = _emotion_overlay_end; - dv->vo_driver.display_frame = _emotion_frame_display; - dv->vo_driver.get_property = _emotion_property_get; - dv->vo_driver.set_property = _emotion_property_set; - dv->vo_driver.get_property_min_max = _emotion_property_min_max_get; - dv->vo_driver.gui_data_exchange = _emotion_gui_data_exchange; - dv->vo_driver.dispose = _emotion_dispose; - dv->vo_driver.redraw_needed = _emotion_redraw; - dv->ev = (Emotion_Xine_Video *)visual; - dv->ev->have_vo = 1; - DBG("vo_driver = %p", &dv->vo_driver); - return &dv->vo_driver; -} - -static void -_emotion_dispose(vo_driver_t *vo_driver) -{ - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; - dv->ev->have_vo = 0; - DBG("vo_driver = %p", dv); - free(dv); -} - -/***************************************************************************/ -static int -_emotion_redraw(vo_driver_t *vo_driver EINA_UNUSED) -{ -// DBG(""); - return 0; -} - -/***************************************************************************/ -static uint32_t -_emotion_capabilities_get(vo_driver_t *vo_driver EINA_UNUSED) -{ -// DBG(""); - return VO_CAP_YV12 | VO_CAP_YUY2; -} - -/***************************************************************************/ -static int -_emotion_gui_data_exchange(vo_driver_t *vo_driver EINA_UNUSED, int data_type, void *data EINA_UNUSED) -{ -// DBG(""); - switch (data_type) - { - case XINE_GUI_SEND_COMPLETION_EVENT: - break; - case XINE_GUI_SEND_DRAWABLE_CHANGED: - break; - case XINE_GUI_SEND_EXPOSE_EVENT: - break; - case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: - break; - case XINE_GUI_SEND_VIDEOWIN_VISIBLE: - break; - case XINE_GUI_SEND_SELECT_VISUAL: - break; - default: - break; - } - return 0; -} - -/***************************************************************************/ -static int -_emotion_property_set(vo_driver_t *vo_driver, int property, int value) -{ - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// DBG(""); - switch (property) - { - case VO_PROP_ASPECT_RATIO: - if (value >= XINE_VO_ASPECT_NUM_RATIOS) - value = XINE_VO_ASPECT_AUTO; -// DBG("DRIVER RATIO SET %i!", value); - dv->ratio = value; - break; - default: - break; - } - return value; -} - -static int -_emotion_property_get(vo_driver_t *vo_driver, int property) -{ - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// DBG(""); - switch (property) - { - case VO_PROP_ASPECT_RATIO: - return dv->ratio; - break; - default: - break; - } - return 0; -} - -static void -_emotion_property_min_max_get(vo_driver_t *vo_driver EINA_UNUSED, int property EINA_UNUSED, int *min, int *max) -{ -// DBG(""); - *min = 0; - *max = 0; -} - -/***************************************************************************/ -static vo_frame_t * -_emotion_frame_alloc(vo_driver_t *vo_driver EINA_UNUSED) -{ - Emotion_Frame *fr; - -// DBG(""); - fr = (Emotion_Frame *)calloc(1, sizeof(Emotion_Frame)); - if (!fr) return NULL; - - fr->vo_frame.base[0] = NULL; - fr->vo_frame.base[1] = NULL; - fr->vo_frame.base[2] = NULL; - - fr->vo_frame.proc_slice = NULL; - fr->vo_frame.proc_frame = NULL; - fr->vo_frame.field = _emotion_frame_field; - fr->vo_frame.dispose = _emotion_frame_dispose; - fr->vo_frame.driver = vo_driver; - - return (vo_frame_t *)fr; -} - -static void -_emotion_frame_dispose(vo_frame_t *vo_frame) -{ - Emotion_Frame *fr; - - fr = (Emotion_Frame *)vo_frame; -// DBG(""); - _emotion_frame_data_free(fr); - free(fr); -} - -static void -_emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags EINA_UNUSED) -{ - Emotion_Driver *dv; - Emotion_Frame *fr; - - dv = (Emotion_Driver *)vo_driver; - fr = (Emotion_Frame *)vo_frame; - - if ((fr->width != (int)width) || (fr->height != (int)height) || - (fr->format != format) || (!fr->vo_frame.base[0])) - { -// DBG(""); - _emotion_frame_data_free(fr); - - fr->width = width; - fr->height = height; - fr->format = format; - - switch (format) - { - case XINE_IMGFMT_YV12: - { - int y_size, uv_size; - - fr->frame.format = EMOTION_FORMAT_YV12; - fr->vo_frame.pitches[0] = 8 * ((width + 7) / 8); - fr->vo_frame.pitches[1] = 8 * ((width + 15) / 16); - fr->vo_frame.pitches[2] = 8 * ((width + 15) / 16); - - y_size = fr->vo_frame.pitches[0] * height; - uv_size = fr->vo_frame.pitches[1] * ((height + 1) / 2); - - fr->vo_frame.base[0] = malloc(y_size + (2 * uv_size)); - fr->vo_frame.base[1] = fr->vo_frame.base[0] + y_size + uv_size; - fr->vo_frame.base[2] = fr->vo_frame.base[0] + y_size; - fr->frame.w = fr->width; - fr->frame.h = fr->height; - fr->frame.ratio = fr->vo_frame.ratio; - fr->frame.y = fr->vo_frame.base[0]; - fr->frame.u = fr->vo_frame.base[1]; - fr->frame.v = fr->vo_frame.base[2]; - fr->frame.bgra_data = NULL; - fr->frame.y_stride = fr->vo_frame.pitches[0]; - fr->frame.u_stride = fr->vo_frame.pitches[1]; - fr->frame.v_stride = fr->vo_frame.pitches[2]; - fr->frame.obj = dv->ev->obj; - } - break; - case XINE_IMGFMT_YUY2: - { - fr->frame.format = EMOTION_FORMAT_BGRA; - fr->vo_frame.pitches[0] = 8 * ((width + 3) / 4); - fr->vo_frame.pitches[1] = 0; - fr->vo_frame.pitches[2] = 0; - - fr->vo_frame.base[0] = malloc(fr->vo_frame.pitches[0] * height); - fr->vo_frame.base[1] = NULL; - fr->vo_frame.base[2] = NULL; - - fr->frame.w = fr->width; - fr->frame.h = fr->height; - fr->frame.ratio = fr->vo_frame.ratio; - fr->frame.y = NULL; - fr->frame.u = NULL; - fr->frame.v = NULL; - fr->frame.bgra_data = malloc(fr->width * fr->height * 4); - fr->frame.y_stride = 0; - fr->frame.u_stride = 0; - fr->frame.v_stride = 0; - fr->frame.obj = dv->ev->obj; - } - break; - default: - break; - } - if (((format == XINE_IMGFMT_YV12) - && ((!fr->vo_frame.base[0]) - || (!fr->vo_frame.base[1]) - || (!fr->vo_frame.base[2]))) - || ((format == XINE_IMGFMT_YUY2) - && ((!fr->vo_frame.base[0]) - || (!fr->frame.bgra_data)))) - { - _emotion_frame_data_free(fr); - } - } - fr->frame.ratio = fr->vo_frame.ratio; - fr->ratio = ratio; -} - -static void -_emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) -{ - Emotion_Driver *dv; - Emotion_Frame *fr; - - dv = (Emotion_Driver *)vo_driver; - fr = (Emotion_Frame *)vo_frame; -// DBG("fq %i %p", dv->ev->fq, dv->ev); -// if my frame queue is too deep ( > 4 frames) simply block and wait for them -// to drain -// while (dv->ev->fq > 4) usleep(1); - if (dv->ev) - { - void *buf; - - if (dv->ev->closing) return; - if (fr->format == XINE_IMGFMT_YUY2) - { - _emotion_yuy2_to_bgra32(fr->width, fr->height, fr->vo_frame.base[0], fr->frame.bgra_data); - } - - buf = &(fr->frame); - fr->frame.timestamp = (double)fr->vo_frame.vpts / 90000.0; - fr->frame.done_func = (done_func_type)_emotion_frame_data_unlock; - fr->frame.done_data = fr; -// DBG("FRAME FOR %p", dv->ev); - if (write(dv->ev->fd_write, &buf, sizeof(void *)) < 0) perror("write"); -// DBG("-- FRAME DEC %p == %i", fr->frame.obj, ret); - fr->in_use = 1; - dv->ev->fq++; - } - /* hmm - must find a way to sanely copy data out... FIXME problem */ -// fr->vo_frame.free(&fr->vo_frame); -} - -static void -_emotion_frame_field(vo_frame_t *vo_frame EINA_UNUSED, int which_field EINA_UNUSED) -{ -// DBG(""); -} - -/***************************************************************************/ -static void -_emotion_frame_data_free(Emotion_Frame *fr) -{ - if (fr->vo_frame.base[0]) - { - free(fr->vo_frame.base[0]); - fr->vo_frame.base[0] = NULL; - fr->vo_frame.base[1] = NULL; - fr->vo_frame.base[2] = NULL; - fr->frame.y = fr->vo_frame.base[0]; - fr->frame.u = fr->vo_frame.base[1]; - fr->frame.v = fr->vo_frame.base[2]; - } - if (fr->frame.bgra_data) - { - free(fr->frame.bgra_data); - fr->frame.bgra_data = NULL; - } -} - -static void -_emotion_frame_data_unlock(Emotion_Frame *fr) -{ -// DBG(""); - if (fr->in_use) - { - fr->vo_frame.free(&fr->vo_frame); - fr->in_use = 0; - } -} - -/***************************************************************************/ -static void -_emotion_overlay_begin(vo_driver_t *vo_driver EINA_UNUSED, vo_frame_t *vo_frame EINA_UNUSED, int changed EINA_UNUSED) -{ -// DBG(""); -} - -static void -_emotion_overlay_end(vo_driver_t *vo_driver EINA_UNUSED, vo_frame_t *vo_frame EINA_UNUSED) -{ -// DBG(""); -} - -static void -_emotion_overlay_blend(vo_driver_t *vo_driver EINA_UNUSED, vo_frame_t *vo_frame, vo_overlay_t *vo_overlay EINA_UNUSED) -{ - Emotion_Frame *fr; - - fr = (Emotion_Frame *)vo_frame; -// DBG(""); - _emotion_overlay_blend_yuv(fr->vo_frame.base, vo_overlay, - fr->width, fr->height, - fr->vo_frame.pitches); -} - -static void _emotion_overlay_mem_blend_8(uint8_t *mem, uint8_t val, uint8_t o, size_t sz) -{ - uint8_t *limit = mem + sz; - while (mem < limit) - { - *mem = BLEND_BYTE(*mem, val, o); - mem++; - } -} - -static void _emotion_overlay_blend_yuv(uint8_t *dst_base[3], vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitches[3]) -{ - Emotion_Lut *my_clut; - uint8_t *my_trans; - int src_width; - int src_height; - rle_elem_t *rle; - rle_elem_t *rle_limit; - int x_off; - int y_off; - int ymask, xmask; - int rle_this_bite; - int rle_remainder; - int rlelen; - int x, y; - int hili_right; - uint8_t clr = 0; - - src_width = img_overl->width; - src_height = img_overl->height; - rle = img_overl->rle; - rle_limit = rle + img_overl->num_rle; - x_off = img_overl->x; - y_off = img_overl->y; - - if (!rle) return; - - uint8_t *dst_y = dst_base[0] + dst_pitches[0] * y_off + x_off; - uint8_t *dst_cr = dst_base[2] + (y_off / 2) * dst_pitches[1] + (x_off / 2) + 1; - uint8_t *dst_cb = dst_base[1] + (y_off / 2) * dst_pitches[2] + (x_off / 2) + 1; - my_clut = (Emotion_Lut *) img_overl->hili_color; - my_trans = img_overl->hili_trans; - - /* avoid wraping overlay if drawing to small image */ - if( (x_off + img_overl->hili_right) < dst_width ) - hili_right = img_overl->hili_right; - else - hili_right = dst_width - 1 - x_off; - - /* avoid buffer overflow */ - if( (src_height + y_off) >= dst_height ) - src_height = dst_height - 1 - y_off; - - rlelen=rle_remainder=0; - for (y = 0; y < src_height; y++) - { - ymask = ((img_overl->hili_top > y) || (img_overl->hili_bottom < y)); - xmask = 0; - - for (x = 0; x < src_width;) - { - uint16_t o; - - if (rlelen == 0) - { - rle_remainder = rlelen = rle->len; - clr = rle->color; - rle++; - } - if (rle_remainder == 0) - { - rle_remainder = rlelen; - } - if ((rle_remainder + x) > src_width) - { - /* Do something for long rlelengths */ - rle_remainder = src_width - x; - } - - if (ymask == 0) - { - if (x <= img_overl->hili_left) - { - /* Starts outside clip area */ - if ((x + rle_remainder - 1) > img_overl->hili_left ) - { - /* Cutting needed, starts outside, ends inside */ - rle_this_bite = (img_overl->hili_left - x + 1); - rle_remainder -= rle_this_bite; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->color; - my_trans = img_overl->trans; - xmask = 0; - } - else - { - /* no cutting needed, starts outside, ends outside */ - rle_this_bite = rle_remainder; - rle_remainder = 0; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->color; - my_trans = img_overl->trans; - xmask = 0; - } - } - else if (x < hili_right) - { - /* Starts inside clip area */ - if ((x + rle_remainder) > hili_right ) - { - /* Cutting needed, starts inside, ends outside */ - rle_this_bite = (hili_right - x); - rle_remainder -= rle_this_bite; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->hili_color; - my_trans = img_overl->hili_trans; - xmask++; - } - else - { - /* no cutting needed, starts inside, ends inside */ - rle_this_bite = rle_remainder; - rle_remainder = 0; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->hili_color; - my_trans = img_overl->hili_trans; - xmask++; - } - } - else if (x >= hili_right) - { - /* Starts outside clip area, ends outsite clip area */ - if ((x + rle_remainder ) > src_width ) - { - /* Cutting needed, starts outside, ends at right edge */ - /* It should never reach here due to the earlier test of src_width */ - rle_this_bite = (src_width - x ); - rle_remainder -= rle_this_bite; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->color; - my_trans = img_overl->trans; - xmask = 0; - } - else - { - /* no cutting needed, starts outside, ends outside */ - rle_this_bite = rle_remainder; - rle_remainder = 0; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->color; - my_trans = img_overl->trans; - xmask = 0; - } - } - } - else - { - /* Outside clip are due to y */ - /* no cutting needed, starts outside, ends outside */ - rle_this_bite = rle_remainder; - rle_remainder = 0; - rlelen -= rle_this_bite; - my_clut = (Emotion_Lut *) img_overl->color; - my_trans = img_overl->trans; - xmask = 0; - } - o = my_trans[clr]; - if (o) - { - if (o >= 15) - { - memset(dst_y + x, my_clut[clr].y, rle_this_bite); - if (y & 1) - { - memset(dst_cr + (x >> 1), my_clut[clr].cr, (rle_this_bite+1) >> 1); - memset(dst_cb + (x >> 1), my_clut[clr].cb, (rle_this_bite+1) >> 1); - } - } - else - { - _emotion_overlay_mem_blend_8(dst_y + x, my_clut[clr].y, o, rle_this_bite); - if (y & 1) - { - /* Blending cr and cb should use a different function, with pre -128 to each sample */ - _emotion_overlay_mem_blend_8(dst_cr + (x >> 1), my_clut[clr].cr, o, (rle_this_bite+1) >> 1); - _emotion_overlay_mem_blend_8(dst_cb + (x >> 1), my_clut[clr].cb, o, (rle_this_bite+1) >> 1); - } - } - } - x += rle_this_bite; - if (rle >= rle_limit) - { - break; - } - } - if (rle >= rle_limit) - { - break; - } - - dst_y += dst_pitches[0]; - - if (y & 1) - { - dst_cr += dst_pitches[2]; - dst_cb += dst_pitches[1]; - } - } -} - -//TODO: Really need to improve this converter! -#define LIMIT(x) ((x) > 0xff ? 0xff : ((x) < 0 ? 0 : (x))) - -static void -_emotion_yuy2_to_bgra32(int width, int height, unsigned char *src, unsigned char *dst) -{ - int i, j; - unsigned char *y, *u, *v; - - y = src; - u = src + 1; - v = src + 3; - for (i = 0; i < width; i++) - { - for (j = 0; j < height; j++) - { - *dst++ = LIMIT(1.164 * (*y - 16) + 2.018 * (*u - 128)); - *dst++ = LIMIT(1.164 * (*y - 16) - 0.813 * (*v - 128) - 0.391 * (*u - 128)); - *dst++ = LIMIT(1.164 * (*y - 16) + 1.596 * (*v - 128)); - *dst++ = 0; - - y += 2; - if (j % 2 == 1) - { - u += 4; - v += 4; - } - } - } -} diff --git a/src/modules/emotion/xine/meson.build b/src/modules/emotion/xine/meson.build deleted file mode 100644 index 038d6d2eb1..0000000000 --- a/src/modules/emotion/xine/meson.build +++ /dev/null @@ -1,16 +0,0 @@ -generic_src = files([ - 'emotion_xine.h', - 'emotion_xine.c', - 'emotion_xine_vo_out.c', -]) - -generic_deps = dependency('libxine') - -shared_module(emotion_loader, - generic_src, - include_directories : config_dir, - dependencies: [eina, evas, emotion, generic_deps], - install: true, - install_dir : mod_install_dir, - c_args : package_c_args, -)