move emotion to fix latency on video load, deadlocks on stop/shutdown etc.

SVN revision: 28679
This commit is contained in:
Carsten Haitzler 2007-03-13 02:30:14 +00:00
parent 66954e5331
commit 2dbc5651d4
8 changed files with 656 additions and 572 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);