diff --git a/legacy/emotion/src/bin/emotion_test_main.c b/legacy/emotion/src/bin/emotion_test_main.c index 423dafb603..b044e7e4e1 100644 --- a/legacy/emotion/src/bin/emotion_test_main.c +++ b/legacy/emotion/src/bin/emotion_test_main.c @@ -477,7 +477,7 @@ video_obj_frame_resize_cb(void *data, Evas_Object *obj, void *event_info) emotion_object_size_get(obj, &iw, &ih); ratio = emotion_object_ratio_get(obj); printf("HANDLE %ix%i @ %3.3f\n", iw, ih, ratio); - if (ratio > 0.0) iw = ih * ratio; + if (ratio > 0.0) iw = (ih * ratio) + 0.5; edje_extern_object_min_size_set(obj, iw, ih); edje_object_part_swallow(oe, "video_swallow", obj); edje_object_size_min_calc(oe, &w, &h); diff --git a/legacy/emotion/src/lib/Emotion.h b/legacy/emotion/src/lib/Emotion.h index 82a06826b1..e55757f0c3 100644 --- a/legacy/emotion/src/lib/Emotion.h +++ b/legacy/emotion/src/lib/Emotion.h @@ -87,6 +87,7 @@ extern "C" { /* api calls available */ EAPI Evas_Object *emotion_object_add (Evas *evas); +EAPI void emotion_object_module_option_set (Evas_Object *obj, const char *opt, const char *val); EAPI Evas_Bool emotion_object_init (Evas_Object *obj, const char *module_filename); EAPI void emotion_object_file_set (Evas_Object *obj, const char *filename); EAPI const char *emotion_object_file_get (Evas_Object *obj); diff --git a/legacy/emotion/src/lib/emotion_private.h b/legacy/emotion/src/lib/emotion_private.h index 68abdfd32f..4354d50a3e 100644 --- a/legacy/emotion/src/lib/emotion_private.h +++ b/legacy/emotion/src/lib/emotion_private.h @@ -23,6 +23,7 @@ typedef enum _Emotion_Format Emotion_Format; typedef enum _Emotion_Vis Emotion_Vis; typedef struct _Emotion_Video_Module Emotion_Video_Module; +typedef struct _Emotion_Module_Options Emotion_Module_Options; enum _Emotion_Format { @@ -55,9 +56,15 @@ enum _Emotion_Vis EMOTION_VIS_LIBVISUAL_PLASMA }; +struct _Emotion_Module_Options +{ + unsigned char no_video : 1; + unsigned char no_audio : 1; +}; + struct _Emotion_Video_Module { - unsigned char (*init) (Evas_Object *obj, void **video); + unsigned char (*init) (Evas_Object *obj, void **video, Emotion_Module_Options *opt); int (*shutdown) (void *video); unsigned char (*file_open) (const char *file, Evas_Object *obj, void *video); void (*file_close) (void *ef); diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c index e071df7a1d..71a81a1c40 100644 --- a/legacy/emotion/src/lib/emotion_smart.c +++ b/legacy/emotion/src/lib/emotion_smart.c @@ -62,6 +62,8 @@ struct _Smart_Data int button_num; int button; } spu; + + Emotion_Module_Options module_options; }; static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info); @@ -95,18 +97,20 @@ _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module ** { void *handle; char buf[4096]; + Smart_Data *sd; + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); snprintf(buf, sizeof(buf), "%s%s", PACKAGE_LIB_DIR"/emotion/", name); handle = dlopen(buf, RTLD_NOW | RTLD_GLOBAL); if (handle) { - unsigned char (*func_module_open)(Evas_Object *, Emotion_Video_Module **, void **); + unsigned char (*func_module_open)(Evas_Object *, Emotion_Video_Module **, void **, Emotion_Module_Options *); func_module_open = dlsym(handle, "module_open"); if (func_module_open) { - if (func_module_open(obj, mod, video)) + if (func_module_open(obj, mod, video, &(sd->module_options))) { (*mod)->handle = handle; return 1; @@ -132,7 +136,12 @@ _emotion_module_close(Emotion_Video_Module *mod, void *video) handle = mod->handle; module_close = dlsym(handle, "module_close"); if ((module_close) && (video)) module_close(mod, video); - dlclose(handle); + /* FIXME: we can't go dlclosing here as a thread still may be running from + * the module - this in theory will leak- but it shouldnt be too bad and + * mean that once a module is dlopened() it cant be closed - its refcount + * will just keep going up + */ +// dlclose(handle); } /*******************************/ @@ -148,6 +157,23 @@ emotion_object_add(Evas *evas) return evas_object_smart_add(evas, smart); } +EAPI void +emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *val) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if ((!opt) || (!val)) return; + if (!strcmp(opt, "video")) + { + if (!strcmp(val, "off")) sd->module_options.no_video = 1; + } + else if (!strcmp(opt, "audio")) + { + if (!strcmp(val, "off")) sd->module_options.no_audio = 1; + } +} + EAPI Evas_Bool emotion_object_init(Evas_Object *obj, const char *module_filename) { @@ -172,10 +198,12 @@ emotion_object_init(Evas_Object *obj, const char *module_filename) sd->seek_pos = 0; sd->len = 0; - if (!sd->module || !sd->video) - if (!_emotion_module_open(module_filename, obj, &sd->module, &sd->video)) - return 0; - + if ((!sd->module) || (!sd->video)) + { + if (!_emotion_module_open(module_filename, obj, + &sd->module, &sd->video)) + return 0; + } return 1; } @@ -1119,6 +1147,7 @@ static void _smart_add(Evas_Object * obj) { Smart_Data *sd; + unsigned int *pixel; sd = calloc(1, sizeof(Smart_Data)); if (!sd) return; @@ -1130,6 +1159,12 @@ _smart_add(Evas_Object * obj) sd->ratio = 1.0; sd->spu.button = -1; evas_object_image_alpha_set(sd->obj, 0); + pixel = evas_object_image_data_get(obj, 1); + if (pixel) + { + *pixel = 0xff000000; + evas_object_image_data_set(obj, pixel); + } evas_object_smart_data_set(obj, sd); } @@ -1141,7 +1176,9 @@ _smart_del(Evas_Object * obj) if (!sd) return; printf("DEL: sd->video = %p\n", sd->video); if (sd->video) sd->module->file_close(sd->video); + printf("MOD CLOSE: sd->video = %p\n", sd->video); _emotion_module_close(sd->module, sd->video); + printf("DEL SD: sd = %p\n", sd); evas_object_del(sd->obj); if (sd->file) free(sd->file); if (sd->job) ecore_job_del(sd->job); diff --git a/legacy/emotion/src/modules/emotion_gstreamer.c b/legacy/emotion/src/modules/emotion_gstreamer.c index 18054cbcc6..3b2573a0e4 100644 --- a/legacy/emotion/src/modules/emotion_gstreamer.c +++ b/legacy/emotion/src/modules/emotion_gstreamer.c @@ -16,7 +16,8 @@ static int _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh); /* Interface */ static unsigned char em_init (Evas_Object *obj, - void **emotion_video); + void **emotion_video, + Emotion_Module_Options *opt); static int em_shutdown (void *video); @@ -224,7 +225,8 @@ static Emotion_Video_Module em_module = static unsigned char em_init(Evas_Object *obj, - void **emotion_video) + void **emotion_video, + Emotion_Module_Options *opt) { Emotion_Gstreamer_Video *ev; GError *error; @@ -1249,7 +1251,8 @@ em_meta_get(void *video, int meta) unsigned char module_open(Evas_Object *obj, Emotion_Video_Module **module, - void **video) + void **video, + Emotion_Module_Options *opt) { if (!module) return 0; diff --git a/legacy/emotion/src/modules/emotion_xine.c b/legacy/emotion/src/modules/emotion_xine.c index e9cb98fe60..4ec54903ea 100644 --- a/legacy/emotion/src/modules/emotion_xine.c +++ b/legacy/emotion/src/modules/emotion_xine.c @@ -2,228 +2,395 @@ #include "emotion_private.h" #include "emotion_xine.h" -static unsigned char em_init(Evas_Object *obj, void **emotion_video); -static int em_shutdown(void *video); -static unsigned char em_file_open(const char *file, Evas_Object *obj, void *video); -static void em_file_close(void *ef); -static void em_play(void *ef, double pos); -static void em_stop(void *ef); -static void em_size_get(void *ef, int *w, int *h); -static void em_pos_set(void *ef, double pos); -static void em_vis_set(void *video, Emotion_Vis vis); -static double em_len_get(void *ef); -static int em_fps_num_get(void *ef); -static int em_fps_den_get(void *ef); -static double em_fps_get(void *ef); -static double em_pos_get(void *ef); -static Emotion_Vis em_vis_get(void *video); -static double em_ratio_get(void *ef); -static int em_seekable(void *ef); -static void em_frame_done(void *ef); -static Emotion_Format em_format_get(void *ef); -static void em_video_data_size_get(void *ef, int *w, int *h); -static int em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows); -static int em_bgra_data_get(void *ef, unsigned char **bgra_data); -static void em_event_feed(void *ef, int event); -static void em_event_mouse_button_feed(void *ef, int button, int x, int y); -static void em_event_mouse_move_feed(void *ef, int x, int y); -static int em_video_channel_count(void *ef); -static void em_video_channel_set(void *ef, int channel); -static int em_video_channel_get(void *ef); -static const char *em_video_channel_name_get(void *ef, int channel); -static void em_video_channel_mute_set(void *ef, int mute); -static int em_video_channel_mute_get(void *ef); -static int em_audio_channel_count(void *ef); -static void em_audio_channel_set(void *ef, int channel); -static int em_audio_channel_get(void *ef); -static const char *em_audio_channel_name_get(void *ef, int channel); -static void em_audio_channel_mute_set(void *ef, int mute); -static int em_audio_channel_mute_get(void *ef); -static void em_audio_channel_volume_set(void *ef, double vol); -static double em_audio_channel_volume_get(void *ef); -static int em_spu_channel_count(void *ef); -static void em_spu_channel_set(void *ef, int channel); -static int em_spu_channel_get(void *ef); -static const char *em_spu_channel_name_get(void *ef, int channel); -static void em_spu_channel_mute_set(void *ef, int mute); -static int em_spu_channel_mute_get(void *ef); -static int em_chapter_count(void *ef); -static void em_chapter_set(void *ef, int chapter); -static int em_chapter_get(void *ef); -static const char *em_chapter_name_get(void *ef, int chapter); -static void em_speed_set(void *ef, double speed); -static double em_speed_get(void *ef); -static int em_eject(void *ef); -static const char *em_meta_get(Emotion_Xine_Video *ev, int meta); +/* module api */ +static unsigned char em_init (Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt); +static int em_shutdown (void *ef); +static unsigned char em_file_open (const char *file, Evas_Object *obj, void *ef); +static void em_file_close (void *ef); +static void em_play (void *ef, double pos); +static void em_stop (void *ef); +static void em_size_get (void *ef, int *w, int *h); +static void em_pos_set (void *ef, double pos); +static void em_vis_set (void *ef, Emotion_Vis vis); +static double em_len_get (void *ef); +static int em_fps_num_get (void *ef); +static int em_fps_den_get (void *ef); +static double em_fps_get (void *ef); +static double em_pos_get (void *ef); +static Emotion_Vis em_vis_get (void *ef); +static double em_ratio_get (void *ef); +static int em_seekable (void *ef); +static void em_frame_done (void *ef); +static Emotion_Format em_format_get (void *ef); +static void em_video_data_size_get (void *ef, int *w, int *h); +static int em_yuv_rows_get (void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows); +static int em_bgra_data_get (void *ef, unsigned char **bgra_data); +static void em_event_feed (void *ef, int event); +static void em_event_mouse_button_feed (void *ef, int button, int x, int y); +static void em_event_mouse_move_feed (void *ef, int x, int y); +static int em_video_channel_count (void *ef); +static void em_video_channel_set (void *ef, int channel); +static int em_video_channel_get (void *ef); +static const char *em_video_channel_name_get (void *ef, int channel); +static void em_video_channel_mute_set (void *ef, int mute); +static int em_video_channel_mute_get (void *ef); +static int em_audio_channel_count (void *ef); +static void em_audio_channel_set (void *ef, int channel); +static int em_audio_channel_get (void *ef); +static const char *em_audio_channel_name_get (void *ef, int channel); +static void em_audio_channel_mute_set (void *ef, int mute); +static int em_audio_channel_mute_get (void *ef); +static void em_audio_channel_volume_set(void *ef, double vol); +static double em_audio_channel_volume_get(void *ef); +static int em_spu_channel_count (void *ef); +static void em_spu_channel_set (void *ef, int channel); +static int em_spu_channel_get (void *ef); +static const char *em_spu_channel_name_get (void *ef, int channel); +static void em_spu_channel_mute_set (void *ef, int mute); +static int em_spu_channel_mute_get (void *ef); +static int em_chapter_count (void *ef); +static void em_chapter_set (void *ef, int chapter); +static int em_chapter_get (void *ef); +static const char *em_chapter_name_get (void *ef, int chapter); +static void em_speed_set (void *ef, double speed); +static double em_speed_get (void *ef); +static int em_eject (void *ef); +static const char *em_meta_get (void *ef, int meta); -static void *_em_seek (void *par); -static int _em_fd_active (void *data, Ecore_Fd_Handler *fdh); -static void _em_event (void *data, const xine_event_t *event); -static int _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh); -static int _em_timer (void *data); +/* internal util calls */ +static void *_em_slave (void *par); +static void _em_slave_event (void *data, int type, void *arg); +static int _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 int _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); +static void _em_get_pos_len (Emotion_Xine_Video *ev); extern plugin_info_t emotion_xine_plugin_info[]; - -static unsigned char -em_init(Evas_Object *obj, void **emotion_video) + +/* 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; - int fds[2]; + 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; - if (!emotion_video) - return 0; + ev = buf[0]; + eev = buf[1]; + switch (eev->mtype) + { + case 0: /* noop */ + break; + case 1: /* init */ + { + 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); + } + } + printf("OPEN VIDEO PLUGIN...\n"); + if (!ev->opt_no_video) + ev->video = xine_open_video_driver(ev->decoder, "emotion", + XINE_VISUAL_TYPE_NONE, ev); + printf("RESULT: xine_open_video_driver() = %p\n", 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; + _em_module_event(ev, 1); /* event - open done */ + } + break; + case 3: /* shutdown */ + { + _em_module_event(ev, 3); + printf("EX shutdown stop\n"); + xine_stop(ev->stream); + // pthread_mutex_lock(&(ev->get_pos_len_mutex)); + if (!ev->get_pos_thread_deleted) + { + printf("closing get_pos thread, %p\n", ev); + pthread_cond_broadcast(&(ev->get_pos_len_cond)); + while (ev->get_poslen); + } + printf("EX dispose %p\n", ev); + xine_dispose(ev->stream); + printf("EX dispose evq %p\n", ev); + xine_event_dispose_queue(ev->queue); + printf("EX close video drv %p\n", ev); + if (ev->video) xine_close_video_driver(ev->decoder, ev->video); + printf("EX wait for vo to go\n"); + while (ev->have_vo); + printf("EX vo gone\n"); + printf("EX close audio drv %p\n", ev); + if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio); + printf("EX xine exit %p\n", ev); + xine_exit(ev->decoder); + printf("EX DONE %p\n", 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; + printf("OPN STREAM %s\n", 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; + } + _em_module_event(ev, 2); /* event - open done */ + } + break; + case 11: /* file close */ + { + printf("EX done %p\n", ev); + em_frame_done(ev); + printf("EX stop %p\n", ev); + xine_stop(ev->stream); + printf("EX close %p\n", ev); + xine_close(ev->stream); + printf("EX close done %p\n", 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) && + (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->seeked_pos != ev->seek_to_pos) + { + 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); + ev->seeked_pos = ev->seek_to_pos; + } + _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 */ + { + double vol; + + vol = *((double *)eev->xine_event); + if (vol < 0.0) vol = 0.0; + if (vol > 1.0) vol = 1.0; + xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, vol * 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; + write(ev->fd_slave_write, buf, sizeof(buf)); +} + +static unsigned char +em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt) +{ + Emotion_Xine_Video *ev; + int fds[2]; + + if (!emotion_video) return 0; ev = calloc(1, sizeof(Emotion_Xine_Video)); if (!ev) return 0; ev->obj = obj; - + ev->decoder = xine_new(); if (!ev->decoder) { free(ev); return 0; } - 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); - } - } - /* some notes on parameters we could swizzle for certain inputs */ - if (0) - { - xine_cfg_entry_t cf; - - if (xine_config_lookup_entry(ev->decoder, "video.num_buffers", &cf)) - { - cf.num_value = 1; - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.dvd_device", &cf)) - { - cf.str_value = "/dev/dvd"; - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.css_decryption_method", &cf)) - { - cf.str_value = "key"; // "key" "disk" "title" - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.dvd_region", &cf)) - { - cf.num_value = 0; // 0 ... 1 - 8 - xine_config_update_entry(ev->decoder, &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); - } - // these are used any time in runtime - so changing affects all dvd's - if (xine_config_lookup_entry(ev->decoder, "input.dvd_skip_behaviour", &cf)) - { - cf.str_value = "skip program"; // "skip program" "skip part" "skip title" - xine_config_update_entry(ev->decoder, &cf); - } - // these are used any time in runtime - so changing affects all dvd's - if (xine_config_lookup_entry(ev->decoder, "input.dvd_seek_behaviour", &cf)) - { - cf.str_value = "seek in program chain"; // "seek in program chain" "seek in program" - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.v4l_video_device_path", &cf)) - { - cf.str_value = "/dev/video0"; - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.cdda_use_cddb", &cf)) - { - cf.num_value = 0; // 0 or 1 - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "input.cdda_device", &cf)) - { - cf.str_value = "/dev/cdrom"; - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "audio.oss_device_name", &cf)) - { - cf.str_value = "/dev/dsp"; - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "audio.oss_device_number", &cf)) - { - cf.num_value = -1; // -1 or 0 1 2 ... - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "audio.alsa_mmap_enable", &cf)) - { - cf.num_value = 1; // 0 or 1 - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "codec.a52_surround_downmix", &cf)) - { - cf.num_value = 1; // 0 or 1 - xine_config_update_entry(ev->decoder, &cf); - } - if (xine_config_lookup_entry(ev->decoder, "vcd.default_device", &cf)) - { - cf.str_value = "/dev/cdrom"; - xine_config_update_entry(ev->decoder, &cf); - } - } - if (0) - { - xine_mrl_t **mrls; - int mrls_num; - - mrls = xine_get_browse_mrls(ev->decoder, "dvd", "dvd://", &mrls_num); - printf("mrls = %p\n", mrls); - if (mrls) - { - int i; - - for (i = 0; i < mrls_num; i++) - { - printf("MRL: origin \"%s\" mrl \"%s\" link \"%s\" type %x size %i\n", - mrls[i]->origin, mrls[i]->mrl, mrls[i]->link, - (int)mrls[i]->type, (int)mrls[i]->size); - } - } - } - if (0) - { - char **auto_play_mrls; - int auto_play_num; - - auto_play_mrls = xine_get_autoplay_mrls(ev->decoder, "dvd", &auto_play_num); - printf("auto_play_mrls = %p\n", auto_play_mrls); - if (auto_play_mrls) - { - int i; - - for (i = 0; i < auto_play_num; i++) - printf("MRL: %s\n", auto_play_mrls[i]); - } - } 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); + 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]; @@ -233,128 +400,64 @@ em_init(Evas_Object *obj, void **emotion_video) ECORE_FD_READ, _em_fd_ev_active, ev, NULL, NULL); ecore_main_fd_handler_active_set(ev->fd_ev_handler, ECORE_FD_READ); } - ev->fd = ev->fd_write; - - printf("OPEN VIDEO PLUGIN...\n"); - ev->video = xine_open_video_driver(ev->decoder, "emotion", - XINE_VISUAL_TYPE_NONE, ev); - printf("RESULT: xine_open_video_driver() = %p\n", ev->video); - // Let xine autodetect the best audio output driver - 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); - + if (pipe(fds) == 0) + { + ev->fd_slave_read = fds[0]; + ev->fd_slave_write = fds[1]; + fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK); + } ev->delete_me = 0; ev->get_pos_thread_deleted = 0; - ev->seek_thread_deleted = 0; - pthread_cond_init(&(ev->seek_cond), NULL); + ev->opening = 1; + + 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->seek_mutex), NULL); pthread_mutex_init(&(ev->get_pos_len_mutex), NULL); - pthread_create(&ev->seek_th, NULL, _em_seek, ev); pthread_create(&ev->get_pos_len_th, NULL, _em_get_pos_len_th, ev); - *emotion_video = ev; + pthread_create(&ev->slave_th, NULL, _em_slave, ev); + pthread_detach(ev->slave_th); + _em_slave_event(ev, 1, NULL); + *emotion_video = ev; return 1; } static int -em_shutdown(void *video) +em_shutdown(void *ef) { Emotion_Xine_Video *ev; - ev = (Emotion_Xine_Video *)video; - + ev = (Emotion_Xine_Video *)ef; + ev->closing = 1; ev->delete_me = 1; -// pthread_mutex_lock(&(ev->seek_mutex)); - if (!ev->seek_thread_deleted) - { - printf("closing seek thread %p\n", ev); - pthread_cond_broadcast(&(ev->seek_cond)); - while (ev->seek_to); - } - -// pthread_mutex_lock(&(ev->get_pos_len_mutex)); - if (!ev->get_pos_thread_deleted) - { - printf("closing get_pos thread, %p\n", ev); - pthread_cond_broadcast(&(ev->get_pos_len_cond)); - while (ev->get_poslen); - } - - printf("EX dispose %p\n", ev); - xine_dispose(ev->stream); - printf("EX dispose evq %p\n", ev); - xine_event_dispose_queue(ev->queue); - printf("EX close video drv %p\n", ev); - if (ev->video) xine_close_video_driver(ev->decoder, ev->video); - printf("EX close audio drv %p\n", ev); - if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio); - printf("EX del fds %p\n", ev); + printf("EXM del fds %p\n", ev); ecore_main_fd_handler_del(ev->fd_handler); - close(ev->fd_write); - close(ev->fd_read); ecore_main_fd_handler_del(ev->fd_ev_handler); - close(ev->fd_ev_write); - close(ev->fd_ev_read); - xine_exit(ev->decoder); - free(ev); + + ev->closing = 1; + _em_slave_event(ev, 3, NULL); + printf("EXM done %p\n", ev); return 1; } static unsigned char -em_file_open(const char *file, Evas_Object *obj, void *video) +em_file_open(const char *file, Evas_Object *obj, void *ef) { - Emotion_Xine_Video *ev = (Emotion_Xine_Video *)video; + Emotion_Xine_Video *ev; int pos_stream = 0; int pos_time = 0; int length_time = 0; uint32_t v; - if (!ev) - return 0; - - if (!xine_open(ev->stream, file)) - return 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 = 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; - ev->seek_to = 0; - -// em_debug(ev); + ev = (Emotion_Xine_Video *)ef; + if (!ev) return 0; + _em_slave_event(ev, 2, strdup(file)); return 1; } @@ -365,29 +468,7 @@ em_file_close(void *ef) ev = (Emotion_Xine_Video *)ef; if (!ev) return; - printf("EX pause end... %p\n", ev); - if (!emotion_object_play_get(ev->obj)) -// if (xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) - { - printf(" ... unpause %p\n", ev); - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); - } -// xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - printf("EX done %p\n", ev); - em_frame_done(ev); -// printf("EX seek 0 %p\n", ev); -// xine_play(ev->stream, 0, 0); - printf("EX: fq %i %p\n", ev->fq, ev); - printf("EX stop %p\n", ev); - xine_stop(ev->stream); - printf("EX close %p\n", ev); - xine_close(ev->stream); - printf("EX del timer %p\n", ev); - if (ev->timer) - { - ecore_timer_del(ev->timer); - ev->timer = NULL; - } + _em_slave_event(ev, 11, NULL); } static void @@ -397,50 +478,13 @@ em_play(void *ef, double pos) int pos_stream = 0; int pos_time = 0; int length_time = 0; + double *ppos; ev = (Emotion_Xine_Video *)ef; ev->play = 1; - if ((xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) && - (pos == ev->pos) && - (!ev->just_loaded)) - { - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); - } - else - { - ev->seek_to_pos = -0.1; - em_pos_set(ef, pos); - } - 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; - } - } - - if ((xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) && - (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED))) - _emotion_frame_new(ev->obj); - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - 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->timer) - ev->timer = ecore_timer_add(1.0 / 30.0, _em_timer, ev); - } + ppos = malloc(sizeof(double)); + *ppos = pos; + _em_slave_event(ev, 4, ppos); } static void @@ -450,12 +494,7 @@ em_stop(void *ef) ev = (Emotion_Xine_Video *)ef; ev->play = 0; - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - if (ev->timer) - { - ecore_timer_del(ev->timer); - ev->timer = NULL; - } + _em_slave_event(ev, 5, NULL); } static void @@ -472,16 +511,14 @@ static void em_pos_set(void *ef, double pos) { Emotion_Xine_Video *ev; + double *ppos; ev = (Emotion_Xine_Video *)ef; - - if (ev->seek_to_pos == pos) return; -// if (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE)) - { - ev->seek_to_pos = pos; - ev->seek_to = 1; - pthread_cond_broadcast(&(ev->seek_cond)); - } + if (pos == ev->seek_to_pos) return; + ppos = malloc(sizeof(double)); + *ppos = pos; + ev->seek_to_pos = pos; + _em_slave_event(ev, 6, ppos); } static void @@ -491,7 +528,6 @@ em_vis_set(void *ef, Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; - if (ev->vis == vis) return; ev->vis = vis; } @@ -566,6 +602,7 @@ em_video_handled(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) 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)); } @@ -576,6 +613,7 @@ em_audio_handled(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) 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)); } @@ -586,6 +624,7 @@ em_seekable(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return 0; return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE); } @@ -612,7 +651,6 @@ em_format_get(void *ef) ev = (Emotion_Xine_Video *)ef; fr = ev->cur_frame; - if (fr) return fr->format; return EMOTION_FORMAT_YV12; } @@ -680,6 +718,7 @@ em_event_feed(void *ef, int event) xine_event_t xine_event; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return; xine_event.data_length = 0; xine_event.data = NULL; xine_event.stream = ev->stream; @@ -785,6 +824,7 @@ em_event_mouse_button_feed(void *ef, int button, int x, int y) xine_input_data_t xine_input; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return; xine_event.stream = ev->stream; gettimeofday(&xine_event.tv, NULL); xine_event.type = XINE_EVENT_INPUT_MOUSE_BUTTON; @@ -804,6 +844,7 @@ em_event_mouse_move_feed(void *ef, int x, int y) xine_input_data_t xine_input; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return; xine_event.stream = ev->stream; gettimeofday(&xine_event.tv, NULL); xine_event.type = XINE_EVENT_INPUT_MOUSE_MOVE; @@ -835,7 +876,8 @@ em_video_channel_set(void *ef, int channel) ev = (Emotion_Xine_Video *)ef; if (channel < 0) channel = 0; - xine_set_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL, channel); + ev->video_channel = channel; + _em_slave_event(ev, 14, NULL); } static int @@ -890,7 +932,8 @@ em_audio_channel_set(void *ef, int channel) ev = (Emotion_Xine_Video *)ef; if (channel < -1) channel = -1; - xine_set_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, channel); + ev->audio_channel = channel; + _em_slave_event(ev, 13, NULL); } static int @@ -921,7 +964,7 @@ em_audio_channel_mute_set(void *ef, int mute) ev = (Emotion_Xine_Video *)ef; ev->audio_mute = mute; - xine_set_param(ev->stream, XINE_PARAM_AUDIO_MUTE, ev->audio_mute); + _em_slave_event(ev, 12, NULL); } static int @@ -937,11 +980,12 @@ static void em_audio_channel_volume_set(void *ef, double vol) { Emotion_Xine_Video *ev; + double *ppos; ev = (Emotion_Xine_Video *)ef; - if (vol < 0.0) vol = 0.0; - if (vol > 1.0) vol = 1.0; - xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, vol * 100); + ppos = malloc(sizeof(double)); + *ppos = vol; + _em_slave_event(ev, 10, ppos); } static double @@ -950,6 +994,7 @@ em_audio_channel_volume_get(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return 0; return (double)xine_get_param(ev->stream, XINE_PARAM_AUDIO_VOLUME) / 100.0; } @@ -959,6 +1004,7 @@ em_spu_channel_count(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return 0; return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL); } @@ -969,7 +1015,8 @@ em_spu_channel_set(void *ef, int channel) ev = (Emotion_Xine_Video *)ef; if (channel < 0) channel = 0; - xine_set_param(ev->stream, XINE_PARAM_SPU_CHANNEL, channel); + ev->spu_channel = channel; + _em_slave_event(ev, 9, NULL); } static int @@ -978,6 +1025,7 @@ em_spu_channel_get(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return 0; return xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL); } @@ -988,6 +1036,7 @@ em_spu_channel_name_get(void *ef, int channel) 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; @@ -1000,7 +1049,7 @@ em_spu_channel_mute_set(void *ef, int mute) ev = (Emotion_Xine_Video *)ef; ev->spu_mute = mute; - xine_set_param(ev->stream, XINE_PARAM_IGNORE_SPU, ev->spu_mute); + _em_slave_event(ev, 8, NULL); } static int @@ -1018,6 +1067,7 @@ em_chapter_count(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return 0; if (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS)) return 99; return 0; @@ -1072,13 +1122,17 @@ em_eject(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; - xine_eject(ev->stream); + _em_slave_event(ev, 7, NULL); return 1; } static const char * -em_meta_get(Emotion_Xine_Video *ev, int meta) +em_meta_get(void *ef, int meta) { + Emotion_Xine_Video *ev; + + ev = (Emotion_Xine_Video *)ef; + if (ev->opening) return NULL; switch (meta) { case META_TRACK_TITLE: @@ -1108,41 +1162,6 @@ em_meta_get(Emotion_Xine_Video *ev, int meta) return NULL; } -static void * -_em_seek(void *par) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)par; - pthread_mutex_lock(&(ev->seek_mutex)); - for (;;) - { - double ppos; - - pthread_cond_wait(&(ev->seek_cond), &(ev->seek_mutex)); - if (ev->seek_to) - { - ppos = ev->seek_to_pos; - if (ppos > ev->len) - ppos = ev->len; - if (ev->no_time) - xine_play(ev->stream, ppos * 65535, 0); - else - xine_play(ev->stream, 0, ppos * 1000); - ev->seek_to = 0; - - if (!ev->play) - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - } - if (ev->delete_me) - { - ev->seek_thread_deleted = 1; - return NULL; - } - } - return NULL; -} - static int _em_fd_active(void *data, Ecore_Fd_Handler *fdh) { @@ -1188,6 +1207,7 @@ _em_event(void *data, const xine_event_t *event) 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) { @@ -1204,6 +1224,23 @@ _em_event(void *data, const xine_event_t *event) write(ev->fd_ev_write, buf, sizeof(buf)); } +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; + write(ev->fd_ev_write, buf, sizeof(buf)); +} + static int _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) { @@ -1221,110 +1258,112 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) ev = buf[0]; eev = buf[1]; - switch (eev->type) + if (eev->mtype != 0) { - case XINE_EVENT_UI_PLAYBACK_FINISHED: + } + else + { + switch (eev->type) { - if (ev->timer) + case XINE_EVENT_UI_PLAYBACK_FINISHED: { - ecore_timer_del(ev->timer); - ev->timer = NULL; + ev->play = 0; + _emotion_decode_stop(ev->obj); + _emotion_playback_finished(ev->obj); } - 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: + { + xine_format_change_data_t *e; + + e = (xine_format_change_data_t *)eev->xine_event; + } + break; + case XINE_EVENT_UI_MESSAGE: + { + xine_ui_message_data_t *e; + + e = (xine_ui_message_data_t *)eev->xine_event; + printf("EV: UI Message [FIXME: break this out to emotion api]\n"); + // 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: + { + xine_audio_level_data_t *e; + + e = (xine_audio_level_data_t *)eev->xine_event; + _emotion_audio_level_change(ev->obj); + printf("EV: Audio Level [FIXME: break this out to emotion api]\n"); + // 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; + printf("PROGRESS: %i\n", e->percent); + _emotion_progress_set(ev->obj, (char *)e->description, (double)e->percent / 100.0); + } + break; + case XINE_EVENT_MRL_REFERENCE: + { + xine_mrl_reference_data_t *e; + + e = (xine_mrl_reference_data_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; + printf("EV: Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]\n", e->skipped_frames, e->discarded_frames); + // e->skipped_frames = % frames skipped * 10 + // e->discarded_frames = % frames skipped * 10 + } + break; + default: + // printf("EV: unknown event type %i\n", eev->type); + break; } - 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: - { - xine_format_change_data_t *e; - - e = (xine_format_change_data_t *)eev->xine_event; - } - break; - case XINE_EVENT_UI_MESSAGE: - { - xine_ui_message_data_t *e; - - e = (xine_ui_message_data_t *)eev->xine_event; - printf("EV: UI Message [FIXME: break this out to emotion api]\n"); - // 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: - { - xine_audio_level_data_t *e; - - e = (xine_audio_level_data_t *)eev->xine_event; - _emotion_audio_level_change(ev->obj); - printf("EV: Audio Level [FIXME: break this out to emotion api]\n"); - // 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; - _emotion_progress_set(ev->obj, (char *)e->description, (double)e->percent / 100.0); - } - break; - case XINE_EVENT_MRL_REFERENCE: - { - xine_mrl_reference_data_t *e; - - e = (xine_mrl_reference_data_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; - printf("EV: Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]\n", e->skipped_frames, e->discarded_frames); - // e->skipped_frames = % frames skipped * 10 - // e->discarded_frames = % frames skipped * 10 - } - break; - default: -// printf("EV: unknown event type %i\n", eev->type); - break; } if (eev->xine_event) free(eev->xine_event); free(eev); @@ -1333,20 +1372,6 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) return 1; } -static int -_em_timer(void *data) -{ - Emotion_Xine_Video *ev; - - ev = data; - _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))) - _emotion_frame_new(ev->obj); - _emotion_video_pos_update(ev->obj, ev->pos, ev->len); - return 1; -} - static void * _em_get_pos_len_th(void *par) { @@ -1399,7 +1424,7 @@ _em_get_pos_len(Emotion_Xine_Video *ev) pthread_cond_broadcast(&(ev->get_pos_len_cond)); } -static Emotion_Video_Module em_module = +const static Emotion_Video_Module em_module = { em_init, /* init */ em_shutdown, /* shutdown */ @@ -1459,12 +1484,12 @@ static Emotion_Video_Module em_module = }; unsigned char -module_open(Evas_Object *obj, Emotion_Video_Module **module, void **video) +module_open(Evas_Object *obj, Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt) { if (!module) return 0; - if (!em_module.init(obj, video)) + if (!em_module.init(obj, video, opt)) return 0; *module = &em_module; diff --git a/legacy/emotion/src/modules/emotion_xine.h b/legacy/emotion/src/modules/emotion_xine.h index 0b2affbed7..a71272cd83 100644 --- a/legacy/emotion/src/modules/emotion_xine.h +++ b/legacy/emotion/src/modules/emotion_xine.h @@ -18,7 +18,6 @@ struct _Emotion_Xine_Video xine_audio_port_t *audio; xine_stream_t *stream; xine_event_queue_t *queue; - int fd; volatile double len; volatile double pos; double fps; @@ -26,13 +25,15 @@ struct _Emotion_Xine_Video int w, h; Evas_Object *obj; volatile Emotion_Xine_Video_Frame *cur_frame; - volatile int seek_to; volatile int get_poslen; + volatile int spu_channel; + volatile int audio_channel; + volatile int video_channel; volatile double seek_to_pos; + volatile double seeked_pos; volatile int fq; Emotion_Vis vis; - Ecore_Timer *timer; - int fd_read; + int fd_read; int fd_write; Ecore_Fd_Handler *fd_handler; int fd_ev_read; @@ -43,41 +44,48 @@ struct _Emotion_Xine_Video unsigned char video_mute : 1; unsigned char audio_mute : 1; unsigned char spu_mute : 1; + unsigned char opt_no_video : 1; + unsigned char opt_no_audio : 1; volatile unsigned char delete_me : 1; volatile unsigned char no_time : 1; + volatile unsigned char opening : 1; + volatile unsigned char closing : 1; + volatile unsigned char have_vo : 1; - pthread_t seek_th; pthread_t get_pos_len_th; - pthread_cond_t seek_cond; pthread_cond_t get_pos_len_cond; - pthread_mutex_t seek_mutex; pthread_mutex_t get_pos_len_mutex; - unsigned char seek_thread_deleted : 1; + + 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; + 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; - char *xine_event; + int type; + void *xine_event; + int mtype; }; -unsigned char module_open(Evas_Object *obj, Emotion_Video_Module **module, void **video); +unsigned char module_open(Evas_Object *obj, Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt); void module_close(Emotion_Video_Module *module, void *video); #endif diff --git a/legacy/emotion/src/modules/emotion_xine_vo_out.c b/legacy/emotion/src/modules/emotion_xine_vo_out.c index 6c5f5ae91d..81d7fcf61d 100644 --- a/legacy/emotion/src/modules/emotion_xine_vo_out.c +++ b/legacy/emotion/src/modules/emotion_xine_vo_out.c @@ -185,7 +185,8 @@ _emotion_open(video_driver_class_t *driver_class, const void *visual) dv->vo_driver.dispose = _emotion_dispose; dv->vo_driver.redraw_needed = _emotion_redraw; dv->ev = (Emotion_Xine_Video *)visual; -// printf("driver ret %p\n", &dv->vo_driver); + dv->ev->have_vo = 1; + printf("emotion: _emotion_open = %p\n", &dv->vo_driver); return &dv->vo_driver; } @@ -195,7 +196,8 @@ _emotion_dispose(vo_driver_t *vo_driver) Emotion_Driver *dv; dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_dispose()\n"); + dv->ev->have_vo = 0; + printf("emotion: _emotion_dispose(%p)\n", dv); free(dv); } @@ -439,12 +441,13 @@ _emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) // printf("EX VO: fq %i %p\n", 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); +// while (dv->ev->fq > 4) usleep(1); if (dv->ev) { void *buf; int ret; + 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); @@ -455,10 +458,10 @@ _emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) fr->frame.done_func = _emotion_frame_data_unlock; fr->frame.done_data = fr; // printf("FRAME FOR %p\n", dv->ev); - ret = write(dv->ev->fd, &buf, sizeof(void *)); + ret = write(dv->ev->fd_write, &buf, sizeof(void *)); // printf("-- FRAME DEC %p == %i\n", fr->frame.obj, ret); fr->in_use = 1; - dv->ev->fq++; +// dv->ev->fq++; } /* hmm - must find a way to sanely copy data out... FIXME problem */ // fr->vo_frame.free(&fr->vo_frame);