--- orig/xine-lib/include/xine.h.in Tue Apr 8 16:24:26 2003 +++ xine-lib/include/xine.h.in Sun Apr 13 03:38:53 2003 @@ -687,6 +687,7 @@ #define XINE_ERROR_NO_DEMUX_PLUGIN 2 #define XINE_ERROR_DEMUX_FAILED 3 #define XINE_ERROR_MALFORMED_MRL 4 +#define XINE_ERROR_INPUT_FAILED 5 /* * try to find out audio/spu language of given channel --- orig/xine-lib/src/xine-engine/load_plugins.c Sun Apr 6 03:17:11 2003 +++ xine-lib/src/xine-engine/load_plugins.c Sun Apr 13 03:44:18 2003 @@ -988,7 +988,7 @@ while (node) { input_plugin_t *plugin; - if ((plugin = ((input_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, mrl))) { + if ((plugin = ((input_class_t *)node->plugin_class)->get_instance(node->plugin_class, stream, mrl))) { pthread_mutex_unlock (&catalog->lock); return plugin; } @@ -1667,8 +1667,8 @@ pthread_mutex_lock (&catalog->lock); - vd->dispose (vd); + vd->dispose (vd); node->ref--; /* FIXME: unload plugin if no-longer used */ --- orig/xine-lib/src/xine-engine/xine.c Sun Mar 30 17:19:46 2003 +++ xine-lib/src/xine-engine/xine.c Sun Apr 13 03:41:11 2003 @@ -552,6 +552,13 @@ = strdup (stream->input_plugin->input_class->get_identifier (stream->input_plugin->input_class)); } + if (!stream->input_plugin->open(stream->input_plugin)) { + stream->input_plugin->dispose(stream->input_plugin); + stream->input_plugin = NULL; + stream->err = XINE_ERROR_INPUT_FAILED; + return 0; + } + if (*stream_setup) { while (stream_setup && *stream_setup && *(++stream_setup)) { diff -urw orig/xine-lib/src/input/input_cdda.c xine-lib/src/input/input_cdda.c --- orig/xine-lib/src/input/input_cdda.c Sun Apr 6 02:51:29 2003 +++ xine-lib/src/input/input_cdda.c Sat Apr 12 20:53:03 2003 @@ -1225,6 +1225,7 @@ _cdda_free_cddb_info(this); + if (this->fd != -1) close(this->fd); free(this->mrl); @@ -1232,69 +1233,31 @@ free(this); } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, - const char *data) { - - cdda_input_plugin_t *this; - cdda_input_class_t *class = (cdda_input_class_t *) cls_gen; +static int cdda_plugin_open (input_plugin_t *this_gen ) { + cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; + cdda_input_class_t *class = (cdda_input_class_t *) this_gen->input_class; cdrom_toc toc; int fd; - int track; - xine_cfg_entry_t enable_entry, server_entry, port_entry, cachedir_entry; - /* fetch the CD track to play */ - if (!strncasecmp (data, "cdda:", 5)) { - if (data[5] != '/') - track = atoi(&data[5]); - else - track = atoi(&data[6]); - /* CD tracks start at 1, reject illegal tracks */ - if (track <= 0) - return NULL; - } else - return NULL; +#ifdef LOG + printf("cdda_plugin_open\n"); +#endif /* get the CD TOC */ init_cdrom_toc(&toc); fd = open (class->cdda_device, O_RDONLY); if (fd == -1) - return NULL; + return 0; read_cdrom_toc(fd, &toc); - if ((toc.first_track > track) || - (toc.last_track < track)) { + if ((toc.first_track > (this->track + 1)) || + (toc.last_track < (this->track + 1))) { free_cdrom_toc(&toc); - return NULL; + return 0; } - this = (cdda_input_plugin_t *) xine_xmalloc (sizeof (cdda_input_plugin_t)); - this->stream = stream; this->fd = fd; - /* - * Lookup config entries. - */ - class->ip = this; - if(xine_config_lookup_entry(this->stream->xine, "input.cdda_use_cddb", - &enable_entry)) - enable_cddb_changed_cb(class, &enable_entry); - - if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_server", - &server_entry)) - server_changed_cb(class, &server_entry); - - if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_port", - &port_entry)) - port_changed_cb(class, &port_entry); - - if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_cachedir", - &cachedir_entry)) - cachedir_changed_cb(class, &cachedir_entry); - - - /* CD tracks start from 1; internal data structure indexes from 0 */ - this->track = track - 1; - /* set up the frame boundaries for this particular track */ this->first_frame = this->current_frame = toc.toc_entries[this->track].first_frame; @@ -1363,22 +1326,7 @@ } free_cdrom_toc(&toc); - - this->input_plugin.get_capabilities = cdda_plugin_get_capabilities; - this->input_plugin.read = cdda_plugin_read; - this->input_plugin.read_block = cdda_plugin_read_block; - this->input_plugin.seek = cdda_plugin_seek; - this->input_plugin.get_current_pos = cdda_plugin_get_current_pos; - this->input_plugin.get_length = cdda_plugin_get_length; - this->input_plugin.get_blocksize = cdda_plugin_get_blocksize; - this->input_plugin.get_mrl = cdda_plugin_get_mrl; - this->input_plugin.get_optional_data = cdda_plugin_get_optional_data; - this->input_plugin.dispose = cdda_plugin_dispose; - this->input_plugin.input_class = cls_gen; - - this->mrl = strdup(data); - - return &this->input_plugin; + return 1; } static char ** cdda_class_get_autoplay_list (input_class_t *this_gen, @@ -1413,6 +1361,78 @@ return this->autoplaylist; } +static input_plugin_t *cdda_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, + const char *mrl) { + + cdda_input_plugin_t *this; + cdda_input_class_t *class = (cdda_input_class_t *) cls_gen; + int track; + xine_cfg_entry_t enable_entry, server_entry, port_entry, cachedir_entry; + +#ifdef LOG + printf("cdda_class_get_instance\n"); +#endif + /* fetch the CD track to play */ + if (!strncasecmp (mrl, "cdda:", 5)) { + if (mrl[5] != '/') + track = atoi(&mrl[5]); + else + track = atoi(&mrl[6]); + /* CD tracks start at 1, reject illegal tracks */ + if (track <= 0) + return NULL; + } else + return NULL; + + + this = (cdda_input_plugin_t *) xine_xmalloc (sizeof (cdda_input_plugin_t)); + + class->ip = this; + this->stream = stream; + this->mrl = strdup(mrl); + + /* CD tracks start from 1; internal data structure indexes from 0 */ + this->track = track - 1; + this->cddb.track = NULL; + this->fd = -1; + + this->input_plugin.open = cdda_plugin_open; + this->input_plugin.get_capabilities = cdda_plugin_get_capabilities; + this->input_plugin.read = cdda_plugin_read; + this->input_plugin.read_block = cdda_plugin_read_block; + this->input_plugin.seek = cdda_plugin_seek; + this->input_plugin.get_current_pos = cdda_plugin_get_current_pos; + this->input_plugin.get_length = cdda_plugin_get_length; + this->input_plugin.get_blocksize = cdda_plugin_get_blocksize; + this->input_plugin.get_mrl = cdda_plugin_get_mrl; + this->input_plugin.get_optional_data = cdda_plugin_get_optional_data; + this->input_plugin.dispose = cdda_plugin_dispose; + this->input_plugin.input_class = cls_gen; + + /* + * Lookup config entries. + */ + class->ip = this; + if(xine_config_lookup_entry(this->stream->xine, "input.cdda_use_cddb", + &enable_entry)) + enable_cddb_changed_cb(class, &enable_entry); + + if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_server", + &server_entry)) + server_changed_cb(class, &server_entry); + + if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_port", + &port_entry)) + port_changed_cb(class, &port_entry); + + if(xine_config_lookup_entry(this->stream->xine, "input.cdda_cddb_cachedir", + &cachedir_entry)) + cachedir_changed_cb(class, &cachedir_entry); + + return &this->input_plugin; +} + + static char *cdda_class_get_identifier (input_class_t *this_gen) { return "cdda"; } @@ -1455,7 +1475,7 @@ this->config = xine->config; config = xine->config; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = cdda_class_get_instance; this->input_class.get_identifier = cdda_class_get_identifier; this->input_class.get_description = cdda_class_get_description; /* this->input_class.get_dir = cdda_class_get_dir; */ @@ -1494,7 +1514,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "CD", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_INPUT, 12, "CD", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_dvb.c xine-lib/src/input/input_dvb.c --- orig/xine-lib/src/input/input_dvb.c Wed Mar 26 12:06:54 2003 +++ xine-lib/src/input/input_dvb.c Sun Apr 13 03:08:21 2003 @@ -581,19 +581,27 @@ static void dvb_plugin_dispose (input_plugin_t *this_gen) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; + if (this->fd != -1) { close(this->fd); this->fd = -1; + } if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } + if (this->event_queue) xine_event_dispose_queue (this->event_queue); free (this->mrl); + + if (this->channels) free (this->channels); - tuner_dispose ( ((dvb_input_plugin_t *)this)->tuner ); + + if (this->tuner) + tuner_dispose (this->tuner); + free (this); } @@ -808,78 +816,46 @@ return channels; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, - xine_stream_t *stream, - const char *data) { - - dvb_input_class_t *cls = (dvb_input_class_t *) cls_gen; - dvb_input_plugin_t *this; +static int dvb_plugin_open (input_plugin_t *this_gen) { + dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; tuner_t *tuner; channel_t *channels; int num_channels; - char *mrl = (char *) data; - - if (strncasecmp (mrl, "dvb:/",5)) - return NULL; if ( !(tuner = tuner_init()) ) { printf ("input_dvb: cannot open dvb device\n"); - return NULL; + return 0; } if ( !(channels = load_channels(&num_channels, tuner->feinfo.type)) ) { tuner_dispose (tuner); - return NULL; + return 0; } - this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t)); - this->tuner = tuner; this->channels = channels; + this->num_channels = num_channels; - if ( sscanf (mrl, "dvb://%d", &this->channel) != 1) + if ( sscanf (this->mrl, "dvb://%d", &this->channel) != 1) this->channel = 0; if (!tuner_set_channel (this->tuner, &this->channels[this->channel])) { printf ("input_dvb: tuner_set_channel failed\n"); tuner_dispose(this->tuner); free(this->channels); - free (this); - return NULL; + return 0; } if ((this->fd = open (DVR_DEVICE, O_RDONLY)) < 0){ printf ("input_dvb: cannot open dvr device '%s'\n", DVR_DEVICE); tuner_dispose(this->tuner); free(this->channels); - free (this); - return NULL; + return 0; } - this->mrl = strdup(mrl); - this->curpos = 0; - this->nbc = nbc_init (stream); - nbc_set_high_water_mark (this->nbc, 80); - this->stream = stream; - this->tuner = tuner; - this->channels = channels; - this->num_channels = num_channels; this->osd = NULL; - this->input_plugin.get_capabilities = dvb_plugin_get_capabilities; - this->input_plugin.read = dvb_plugin_read; - this->input_plugin.read_block = dvb_plugin_read_block; - this->input_plugin.seek = dvb_plugin_seek; - this->input_plugin.get_current_pos = dvb_plugin_get_current_pos; - this->input_plugin.get_length = dvb_plugin_get_length; - this->input_plugin.get_blocksize = dvb_plugin_get_blocksize; - this->input_plugin.get_mrl = dvb_plugin_get_mrl; - this->input_plugin.get_optional_data = dvb_plugin_get_optional_data; - this->input_plugin.dispose = dvb_plugin_dispose; - this->input_plugin.input_class = cls_gen; - this->cls = cls; - pthread_mutex_init (&this->mutex, NULL); this->event_queue = xine_event_new_queue (this->stream); @@ -892,7 +868,45 @@ TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT3); - return (input_plugin_t *) this; + return 1; +} + +static input_plugin_t *dvb_class_get_instance (input_class_t *cls_gen, + xine_stream_t *stream, + const char *data) { + + dvb_input_class_t *cls = (dvb_input_class_t *) cls_gen; + dvb_input_plugin_t *this; + char *mrl = (char *) data; + + if (strncasecmp (mrl, "dvb:/",5)) + return NULL; + + this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t)); + + this->mrl = strdup(mrl); + this->cls = cls; + this->tuner = NULL; + this->channels = NULL; + this->fd = -1; + this->nbc = nbc_init (this->stream); + this->osd = NULL; + this->event_queue = NULL; + + this->input_plugin.open = dvb_plugin_open; + this->input_plugin.get_capabilities = dvb_plugin_get_capabilities; + this->input_plugin.read = dvb_plugin_read; + this->input_plugin.read_block = dvb_plugin_read_block; + this->input_plugin.seek = dvb_plugin_seek; + this->input_plugin.get_current_pos = dvb_plugin_get_current_pos; + this->input_plugin.get_length = dvb_plugin_get_length; + this->input_plugin.get_blocksize = dvb_plugin_get_blocksize; + this->input_plugin.get_mrl = dvb_plugin_get_mrl; + this->input_plugin.get_optional_data = dvb_plugin_get_optional_data; + this->input_plugin.dispose = dvb_plugin_dispose; + this->input_plugin.input_class = cls_gen; + + return &this->input_plugin; } /* @@ -932,7 +946,7 @@ this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = dvb_class_get_instance; this->input_class.get_identifier = dvb_class_get_identifier; this->input_class.get_description = dvb_class_get_description; this->input_class.get_dir = NULL; @@ -957,6 +971,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "DVB", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "DVB", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_dvd.c xine-lib/src/input/input_dvd.c --- orig/xine-lib/src/input/input_dvd.c Tue Apr 8 19:51:58 2003 +++ xine-lib/src/input/input_dvd.c Sun Apr 13 03:36:01 2003 @@ -366,11 +366,18 @@ trace_print("Called\n"); + if (this->event_queue) xine_event_dispose_queue (this->event_queue); + + if (this->dvdnav) { dvdnav_close(this->dvdnav); /* raise the freeing flag, so that the plugin will be freed as soon * as all buffers have returned to the libdvdnav read ahead cache */ this->freeing = 1; + } else { + pthread_mutex_destroy(&this->buf_mutex); + free(this); + } } @@ -1185,78 +1192,20 @@ } #endif -/* dvdnav CLASS functions */ +static int dvd_plugin_open (input_plugin_t *this_gen) { + dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; + dvd_input_class_t *class = (dvd_input_class_t*)this_gen->input_class; -/* - * Opens the DVD plugin. The MRL takes the following form: - * - * dvd:[dvd_path]/[vts[.program]] - * - * e.g. - * dvd:/ - Play (navigate) - * dvd:/1 - Play Title 1 - * dvd:/1.3 - Play Title 1, program 3 - * dvd:/dev/dvd2/ - Play (navigate) from /dev/dvd2 - * dvd:/dev/dvd2/1.3 - Play Title 1, program 3 from /dev/dvd2 - */ -static input_plugin_t *open_plugin (input_class_t *class_gen, xine_stream_t *stream, const char *data) { - dvd_input_plugin_t *this; - dvd_input_class_t *class = (dvd_input_class_t*)class_gen; char *locator; int last_slash = 0; dvdnav_status_t ret; char *intended_dvd_device; - xine_cfg_entry_t region_entry, lang_entry, cache_entry; xine_event_t event; static char *handled_mrl = "dvd:/"; + xine_cfg_entry_t region_entry, lang_entry, cache_entry; trace_print("Called\n"); - /* Check we can handle this MRL */ - if (strncasecmp (data, handled_mrl, strlen(handled_mrl) ) != 0) - return NULL; - - this = (dvd_input_plugin_t *) xine_xmalloc (sizeof (dvd_input_plugin_t)); - if (this == NULL) { - XINE_ASSERT(0, "input_dvd.c: xine_xmalloc failed!!!! You have run out of memory\n"); - } - - this->input_plugin.get_capabilities = dvd_plugin_get_capabilities; - this->input_plugin.read = dvd_plugin_read; - this->input_plugin.read_block = dvd_plugin_read_block; - this->input_plugin.seek = dvd_plugin_seek; - this->input_plugin.get_current_pos = dvd_plugin_get_current_pos; - this->input_plugin.get_length = dvd_plugin_get_length; - this->input_plugin.get_blocksize = dvd_plugin_get_blocksize; - this->input_plugin.get_mrl = dvd_plugin_get_mrl; - this->input_plugin.get_optional_data = dvd_plugin_get_optional_data; - this->input_plugin.dispose = dvd_plugin_dispose; - this->input_plugin.input_class = class_gen; - - this->stream = stream; - this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HAS_STILL] = 1; - - this->dvdnav = NULL; - this->opened = 0; - this->seekable = 0; - this->buttonN = 0; - this->typed_buttonN = 0; - this->pause_timer = 0; - this->pg_length = 0; - this->pgc_length = 0; - this->dvd_name = NULL; - this->mrl = strdup(data); -/* - this->mrls = NULL; - this->num_mrls = 0; -*/ - - pthread_mutex_init(&this->buf_mutex, NULL); - this->mem_stack = 0; - this->freeing = 0; - - this->event_queue = xine_event_new_queue (this->stream); - /* we already checked the "dvd:/" MRL above */ locator = &this->mrl[strlen(handled_mrl)]; while (*locator == '/') locator++; @@ -1318,9 +1267,6 @@ dvdnav_get_title_string(this->dvdnav, &this->dvd_name); - /* config callbacks may react now */ - class->ip = this; - /* Set region code */ if (xine_config_lookup_entry (this->stream->xine, "input.dvd_region", ®ion_entry)) @@ -1341,6 +1287,7 @@ &cache_entry)) seek_mode_cb(class, &cache_entry); + if(this->mode == MODE_TITLE) { int tt, i, pr, found; int titles, parts; @@ -1401,6 +1348,83 @@ update_title_display(this); + return 1; +} + +/* dvdnav CLASS functions */ + +/* + * Opens the DVD plugin. The MRL takes the following form: + * + * dvd:[dvd_path]/[vts[.program]] + * + * e.g. + * dvd:/ - Play (navigate) + * dvd:/1 - Play Title 1 + * dvd:/1.3 - Play Title 1, program 3 + * dvd:/dev/dvd2/ - Play (navigate) from /dev/dvd2 + * dvd:/dev/dvd2/1.3 - Play Title 1, program 3 from /dev/dvd2 + */ +static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *data) { + dvd_input_plugin_t *this; + dvd_input_class_t *class = (dvd_input_class_t*)class_gen; + static char *handled_mrl = "dvd:/"; + + trace_print("Called\n"); + + /* Check we can handle this MRL */ + if (strncasecmp (data, handled_mrl, strlen(handled_mrl) ) != 0) + return NULL; + + this = (dvd_input_plugin_t *) xine_xmalloc (sizeof (dvd_input_plugin_t)); + if (this == NULL) { + XINE_ASSERT(0, "input_dvd.c: xine_xmalloc failed!!!! You have run out of memory\n"); + } + + this->input_plugin.open = dvd_plugin_open; + this->input_plugin.get_capabilities = dvd_plugin_get_capabilities; + this->input_plugin.read = dvd_plugin_read; + this->input_plugin.read_block = dvd_plugin_read_block; + this->input_plugin.seek = dvd_plugin_seek; + this->input_plugin.get_current_pos = dvd_plugin_get_current_pos; + this->input_plugin.get_length = dvd_plugin_get_length; + this->input_plugin.get_blocksize = dvd_plugin_get_blocksize; + this->input_plugin.get_mrl = dvd_plugin_get_mrl; + this->input_plugin.get_optional_data = dvd_plugin_get_optional_data; + this->input_plugin.dispose = dvd_plugin_dispose; + this->input_plugin.input_class = class_gen; + + this->stream = stream; + this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HAS_STILL] = 1; + + this->dvdnav = NULL; + this->opened = 0; + this->seekable = 0; + this->buttonN = 0; + this->typed_buttonN = 0; + this->pause_timer = 0; + this->pg_length = 0; + this->pgc_length = 0; + this->dvd_name = NULL; + this->mrl = strdup(data); +/* + this->mrls = NULL; + this->num_mrls = 0; +*/ + +printf("dvd_class_get_instance2\n"); + pthread_mutex_init(&this->buf_mutex, NULL); + this->mem_stack = 0; + this->freeing = 0; + +printf("dvd_class_get_instance21\n"); + this->event_queue = xine_event_new_queue (this->stream); +printf("dvd_class_get_instance22\n"); + + /* config callbacks may react now */ + class->ip = this; + +printf("dvd_class_get_instance3\n"); return &this->input_plugin; } @@ -1476,7 +1500,7 @@ this = (dvd_input_class_t *) malloc (sizeof (dvd_input_class_t)); - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = dvd_class_get_instance; this->input_class.get_identifier = dvd_class_get_identifier; this->input_class.get_description = dvd_class_get_description; /* @@ -1990,6 +2014,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "DVD", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "DVD", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_file.c xine-lib/src/input/input_file.c --- orig/xine-lib/src/input/input_file.c Fri Apr 4 21:20:49 2003 +++ xine-lib/src/input/input_file.c Sun Apr 13 00:09:49 2003 @@ -184,6 +184,7 @@ static void file_plugin_dispose (input_plugin_t *this_gen ) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + if (this->fh != -1) close(this->fh); free (this->mrl); @@ -218,23 +219,39 @@ return uri; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, +static int file_plugin_open (input_plugin_t *this_gen ) { + file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + char *filename; + + #ifdef LOG + printf("file_plugin_open\n"); + #endif + if (!strncasecmp (this->mrl, "file:", 5)) + filename = decode_uri (&(this->mrl[5])); + else + filename = decode_uri(this->mrl); + + this->fh = open (filename, O_RDONLY); + + if (this->fh == -1) { + return 0; + } + + return 1; +} + +static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { /* file_input_class_t *cls = (file_input_class_t *) cls_gen; */ file_input_plugin_t *this; char *mrl = strdup(data); - char *filename; - int fh; - if (!strncasecmp (mrl, "file:", 5)) - filename = decode_uri (&mrl[5]); - else - filename = decode_uri(mrl); - - fh = open (filename, O_RDONLY); + #ifdef LOG + printf("file_class_get_instance\n"); + #endif - if (fh == -1) { + if ((strncasecmp (mrl, "file:", 5)) && (strstr (mrl, ":/"))) { free (mrl); return NULL; } @@ -242,8 +259,9 @@ this = (file_input_plugin_t *) xine_xmalloc (sizeof (file_input_plugin_t)); this->stream = stream; this->mrl = mrl; - this->fh = fh; + this->fh = -1; + this->input_plugin.open = file_plugin_open; this->input_plugin.get_capabilities = file_plugin_get_capabilities; this->input_plugin.read = file_plugin_read; this->input_plugin.read_block = file_plugin_read_block; @@ -780,7 +798,7 @@ this->config = xine->config; config = xine->config; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = file_class_get_instance; this->input_class.get_identifier = file_class_get_identifier; this->input_class.get_description = file_class_get_description; this->input_class.get_dir = file_class_get_dir; @@ -819,6 +837,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "FILE", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_INPUT, 12, "FILE", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_gnome_vfs.c xine-lib/src/input/input_gnome_vfs.c --- orig/xine-lib/src/input/input_gnome_vfs.c Mon Mar 3 08:37:23 2003 +++ xine-lib/src/input/input_gnome_vfs.c Sun Apr 13 00:11:18 2003 @@ -50,6 +50,7 @@ GnomeVFSHandle *fh; off_t curpos; char *mrl; + GnomeVFSURI *uri; /* Preview */ char preview[MAX_PREVIEW_SIZE]; @@ -237,10 +238,27 @@ gnome_vfs_close (this->fh); if (this->mrl) g_free (this->mrl); - + if (this->uri) + gnome_vfs_uri_unref (this->uri); g_free (this); } +static int +gnomevfs_plugin_open (input_plugin_t *this_gen ) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + + D("gnomevfs_klass_open: opening '%s'", this->mrl); + if (gnome_vfs_open_uri (&this->fh, this->uri, GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) + { + D("gnomevfs_klass_open: failed to open '%s'", this->mrl); + return 0; + } + + return 1; + +} + static void gnomevfs_klass_dispose (input_class_t *this_gen) { @@ -249,15 +267,15 @@ g_free (this); } + static input_plugin_t * -gnomevfs_klass_open (input_class_t *klass_gen, xine_stream_t *stream, +gnomevfs_klass_get_instance (input_class_t *klass_gen, xine_stream_t *stream, const char *mrl) { gnomevfs_input_t *this; - GnomeVFSHandle *fh; GnomeVFSURI *uri; - D("gnomevfs_klass_open: %s", mrl); + D("gnomevfs_klass_get_instance: %s", mrl); uri = gnome_vfs_uri_new (mrl); if (uri == NULL) @@ -275,19 +293,14 @@ return NULL; } - D("gnomevfs_klass_open: opening '%s'", mrl); - if (gnome_vfs_open_uri (&fh, uri, GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) - { - D("gnomevfs_klass_open: failed to open '%s'", mrl); - return NULL; - } - D("Creating the structure for stream '%s'", mrl); this = g_new0 (gnomevfs_input_t, 1); this->stream = stream; - this->fh = fh; + this->fh = NULL; this->mrl = g_strdup (mrl); + this->uri = uri; + this->input_plugin.open = gnomevfs_plugin_open; this->input_plugin.get_capabilities = gnomevfs_plugin_get_capabilities; this->input_plugin.read = gnomevfs_plugin_read; this->input_plugin.read_block = gnomevfs_plugin_read_block; @@ -321,7 +334,7 @@ this = g_new0 (gnomevfs_input_class_t, 1); this->xine = xine; - this->input_class.open_plugin = gnomevfs_klass_open; + this->input_class.get_instance = gnomevfs_klass_get_instance; this->input_class.get_identifier = gnomevfs_klass_get_identifier; this->input_class.get_description = gnomevfs_klass_get_description; this->input_class.get_dir = NULL; @@ -333,7 +346,7 @@ } plugin_info_t xine_plugin_info[] = { - { PLUGIN_INPUT, 11, "gnomevfs", XINE_VERSION_CODE, NULL, + { PLUGIN_INPUT, 12, "gnomevfs", XINE_VERSION_CODE, NULL, init_input_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_http.c xine-lib/src/input/input_http.c --- orig/xine-lib/src/input/input_http.c Mon Mar 17 12:59:41 2003 +++ xine-lib/src/input/input_http.c Sun Apr 13 03:10:01 2003 @@ -108,7 +108,7 @@ } http_input_class_t; static int http_plugin_host_connect_attempt (struct in_addr ia, int port, - xine_t *xine) { + http_input_plugin_t *this) { int s; struct sockaddr_in sin; @@ -116,7 +116,8 @@ s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (s==-1) { - xine_log (xine, XINE_LOG_MSG, _("input_http: failed to open socket\n")); + xine_message(this->stream, XINE_MSG_GENERAL_WARNING, "failed to open socket", NULL); + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: failed to open socket\n")); return -1; } @@ -125,7 +126,8 @@ sin.sin_port = htons(port); if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS) { - xine_log (xine, XINE_LOG_MSG, _("input_http: cannot connect to host\n")); + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "cannot connect to host", NULL); + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: cannot connect to host\n")); close(s); return -1; } @@ -133,26 +135,27 @@ return s; } -static int http_plugin_host_connect (const char *host, int port, xine_t *xine) { +static int http_plugin_host_connect (const char *host, int port, http_input_plugin_t *this) { struct hostent *h; int i; int s; h=gethostbyname(host); if (h==NULL) { - xine_log (xine, XINE_LOG_MSG, _("input_http: unable to resolve >%s<\n"), host); + xine_message(this->stream, XINE_MSG_UNKNOWN_HOST, "unable to resolve ", host, NULL); + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: unable to resolve >%s<\n"), host); return -1; } for(i=0; h->h_addr_list[i]; i++) { struct in_addr ia; memcpy(&ia, h->h_addr_list[i], 4); - s=http_plugin_host_connect_attempt(ia, port, xine); + s=http_plugin_host_connect_attempt(ia, port, this); if(s != -1) return s; } - xine_log (xine, XINE_LOG_MSG, _("http: unable to connect to >%s<\n"), host); + xine_log (this->stream->xine, XINE_LOG_MSG, _("http: unable to connect to >%s<\n"), host); return -1; } @@ -448,11 +451,13 @@ timeout.tv_usec = 0; if (select (this->fh+1, &rset, NULL, NULL, &timeout) <= 0) { + xine_message(this->stream, XINE_MSG_READ_ERROR, "network timeout", NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: timeout\n")); return 0; } continue; } + xine_message(this->stream, XINE_MSG_READ_ERROR, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno); return 0; } @@ -635,8 +640,10 @@ static void http_plugin_dispose (input_plugin_t *this_gen ) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + if (this->fh != -1) { close(this->fh); this->fh = -1; + } if (this->nbc) { nbc_close (this->nbc); @@ -646,29 +653,14 @@ free (this_gen); } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, - const char *mrl) { - /* http_input_class_t *cls = (http_input_class_t *) cls_gen;*/ - http_input_plugin_t *this; +static int http_plugin_open (input_plugin_t *this_gen ) { + http_input_plugin_t *this = (http_input_plugin_t *) this_gen; char *proxy; int done,len,linenum; int shoutcast = 0, httpcode; - this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t)); this->shoutcast_pos = 0; - - strncpy (this->mrlbuf, mrl, BUFSIZE); - strncpy (this->mrlbuf2, mrl, BUFSIZE); - this->mrl = this->mrlbuf2; - - if (strncasecmp (this->mrlbuf, "http://", 7)) { - free (this); - return NULL; - } - - this->stream = stream; - this->proxybuf[0] = '\0'; proxy = getenv("http_proxy"); @@ -678,8 +670,7 @@ if (http_plugin_parse_url (this->proxybuf, &this->proxyuser, &this->proxypassword, &this->proxyhost, &this->proxyport, NULL)) { - free (this); - return NULL; + return 0; } if (this->proxyport == 0) @@ -688,15 +679,14 @@ if (this->proxyuser != NULL) if (http_plugin_basicauth (this->proxyuser, this->proxypassword, this->proxyauth, BUFSIZE)) { - free (this); - return NULL; + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "proxy error", NULL); + return 0; } } if (http_plugin_parse_url (this->mrlbuf, &this->user, &this->password, &this->host, &this->port, &this->filename)) { - free (this); - return NULL; + return 0; } if(this->port == 0) @@ -704,8 +694,8 @@ if (this->user != NULL) if (http_plugin_basicauth (this->user, this->password, this->auth, BUFSIZE)) { - free (this); - return NULL; + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "basic auth error", NULL); + return 0; } { @@ -725,16 +715,14 @@ } if (proxy != NULL) - this->fh = http_plugin_host_connect (this->proxyhost, this->proxyport, - this->stream->xine); + this->fh = http_plugin_host_connect (this->proxyhost, this->proxyport, this); else - this->fh = http_plugin_host_connect (this->host, this->port, this->stream->xine); + this->fh = http_plugin_host_connect (this->host, this->port, this); this->curpos = 0; if (this->fh == -1) { - free (this); - return NULL; + return 0; } if (proxy != NULL) @@ -771,9 +759,9 @@ strcat (this->buf, "\015\012"); if (write (this->fh, this->buf, strlen(this->buf)) != strlen(this->buf)) { + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL); printf ("input_http: couldn't send request\n"); - free (this); - return NULL ; + return 0; } #ifdef LOG @@ -798,9 +786,9 @@ xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: EAGAIN\n")); continue; default: + xine_message(this->stream, XINE_MSG_READ_ERROR, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error\n")); - free (this); - return NULL; + return 0; } } @@ -829,10 +817,10 @@ /* icecast ? */ if (sscanf(this->buf, "ICY %d OK", &httpcode) != 1) { + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "invalid http answer", NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: invalid http answer\n")); - free (this); - return NULL; + return 0; } else { shoutcast = 1; done = 1; @@ -844,11 +832,12 @@ _("input_http: 3xx redirection: >%d %s<\n"), httpcode, httpstatus); } else if (httpcode < 200 || httpcode >= 300) { + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "http status not 2xx: ", + httpstatus, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), httpcode, httpstatus); - free (this); - return NULL; + return 0; } } else { if (this->contentlength == 0) { @@ -868,8 +857,9 @@ printf ("input_http: trying to open target of redirection: >%s<\n", href); #endif - free (this); - return open_plugin (cls_gen, stream, href); + free (this->mrl); + this->mrl = href; + return http_plugin_open(this_gen); } } @@ -885,10 +875,6 @@ printf ("input_http: end of headers\n"); #endif - this->nbc = nbc_init (this->stream); - - nbc_set_high_water_mark(this->nbc, 30); - /* * fill preview buffer */ @@ -910,9 +896,9 @@ this->mrlbuf2[3] = ' '; if (read_shoutcast_header(this)) { /* problem when reading shoutcast header */ - printf ("troubles with shoutcast header\n"); - free (this); - return NULL; + xine_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "can't read shoutcast header", NULL); + printf ("can't read shoutcast header\n"); + return 0; } this->shoutcast_mode = 1; this->shoutcast_pos = 0; @@ -920,6 +906,31 @@ this->shoutcast_mode = 0; } + return 1; +} + +/* + * http input plugin class + */ +static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, + const char *mrl) { + + /* http_input_class_t *cls = (http_input_class_t *) cls_gen;*/ + http_input_plugin_t *this; + + if (strncasecmp (mrl, "http://", 7)) { + return NULL; + } + this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t)); + + strncpy (this->mrlbuf, mrl, BUFSIZE); + strncpy (this->mrlbuf2, mrl, BUFSIZE); + this->mrl = this->mrlbuf2; + this->stream = stream; + this->fh = -1; + this->nbc = nbc_init (this->stream); + + this->input_plugin.open = http_plugin_open; this->input_plugin.get_capabilities = http_plugin_get_capabilities; this->input_plugin.read = http_plugin_read; this->input_plugin.read_block = http_plugin_read_block; @@ -935,10 +946,6 @@ return &this->input_plugin; } -/* - * http input plugin class - */ - static char *http_class_get_description (input_class_t *this_gen) { return _("http input plugin"); } @@ -964,7 +971,7 @@ this->config = xine->config; config = xine->config; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = http_class_get_instance; this->input_class.get_identifier = http_class_get_identifier; this->input_class.get_description = http_class_get_description; this->input_class.get_dir = NULL; @@ -981,7 +988,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "http", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "http", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_mms.c xine-lib/src/input/input_mms.c --- orig/xine-lib/src/input/input_mms.c Fri Feb 28 03:51:48 2003 +++ xine-lib/src/input/input_mms.c Sun Apr 13 03:10:29 2003 @@ -71,6 +71,7 @@ typedef struct { input_plugin_t input_plugin; + xine_stream_t *stream; mms_t *mms; mmsh_t *mmsh; @@ -250,18 +251,14 @@ static void mms_plugin_dispose (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; - if (this->mms) { - switch (this->protocol) { - case PROTOCOL_MMST: + if (this->mms) mms_close (this->mms); - break; - case PROTOCOL_MMSH: + + if (this->mmsh) mmsh_close (this->mmsh); - break; - } + this->mms = NULL; this->mmsh = NULL; - } if (this->nbc) { nbc_close (this->nbc); @@ -322,13 +319,45 @@ } } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, +static int mms_plugin_open (input_plugin_t *this_gen) { + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + mms_t *mms = NULL; + mmsh_t *mmsh = NULL; + + switch (this->protocol) { + case PROTOCOL_UNDEFINED: + mms = mms_connect (this->stream, this->mrl, this->bandwidth); + if (mms) { + this->protocol = PROTOCOL_MMST; + } else { + mmsh = mmsh_connect (this->stream, this->mrl, this->bandwidth); + this->protocol = PROTOCOL_MMSH; + } + break; + case PROTOCOL_MMST: + mms = mms_connect (this->stream, this->mrl, this->bandwidth); + break; + case PROTOCOL_MMSH: + mmsh = mmsh_connect (this->stream, this->mrl, this->bandwidth); + break; + } + + if (!mms && !mmsh) { + return 0; + } + + this->mms = mms; + this->mmsh = mmsh; + this->curpos = 0; + + return 1; +} + +static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { mms_input_class_t *cls = (mms_input_class_t *) cls_gen; mms_input_plugin_t *this; - mms_t *mms = NULL; - mmsh_t *mmsh = NULL; char *mrl = strdup(data); xine_cfg_entry_t bandwidth_entry; int protocol; @@ -350,42 +379,20 @@ this = (mms_input_plugin_t *) malloc (sizeof (mms_input_plugin_t)); cls->ip = this; + this->stream = stream; + this->mms = NULL; + this->mmsh = NULL; + this->protocol = protocol; + this->mrl = mrl; + this->curpos = 0; + this->nbc = nbc_init (this->stream); if (xine_config_lookup_entry (stream->xine, "input.mms_network_bandwidth", &bandwidth_entry)) { bandwidth_changed_cb(cls, &bandwidth_entry); } - switch (protocol) { - case PROTOCOL_UNDEFINED: - mms = mms_connect (stream, mrl, this->bandwidth); - if (mms) { - protocol = PROTOCOL_MMST; - } else { - mmsh = mmsh_connect (stream, mrl, this->bandwidth); - protocol = PROTOCOL_MMSH; - } - break; - case PROTOCOL_MMST: - mms = mms_connect (stream, mrl, this->bandwidth); - break; - case PROTOCOL_MMSH: - mmsh = mmsh_connect (stream, mrl, this->bandwidth); - break; - } - - if (!mms && !mmsh) { - free (mrl); - return NULL; - } - - this->mms = mms; - this->mmsh = mmsh; - this->protocol = protocol; - this->mrl = mrl; - this->curpos = 0; - this->nbc = nbc_init (stream); - + this->input_plugin.open = mms_plugin_open; this->input_plugin.get_capabilities = mms_plugin_get_capabilities; this->input_plugin.read = mms_plugin_read; this->input_plugin.read_block = mms_plugin_read_block; @@ -429,7 +436,7 @@ this->xine = xine; this->ip = NULL; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = mms_class_get_instance; this->input_class.get_identifier = mms_class_get_identifier; this->input_class.get_description = mms_class_get_description; this->input_class.get_dir = NULL; @@ -451,6 +458,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "mms", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "mms", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_net.c xine-lib/src/input/input_net.c --- orig/xine-lib/src/input/input_net.c Fri Jan 31 15:06:13 2003 +++ xine-lib/src/input/input_net.c Sun Apr 13 03:10:50 2003 @@ -298,8 +298,10 @@ static void net_plugin_dispose (input_plugin_t *this_gen ) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; + if (this->fh != -1) { close(this->fh); this->fh = -1; + } free (this->mrl); @@ -311,32 +313,13 @@ free (this_gen); } - -static input_plugin_t *net_plugin_open (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { - /* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */ - net_input_plugin_t *this = xine_xmalloc(sizeof(net_input_plugin_t)); +static int net_plugin_open (input_plugin_t *this_gen ) { + net_input_plugin_t *this = (net_input_plugin_t *) this_gen; char *filename; char *pptr; int port = 7658; - this->mrl = strdup(mrl); - this->stream = stream; - - if (!strncasecmp (mrl, "tcp://", 6)) { filename = (char *) &this->mrl[6]; - - if((!filename) || (strlen(filename) == 0)) { - free (this->mrl); - free (this); - return NULL; - } - - } else { - free (this->mrl); - free (this); - return NULL; - } - pptr=strrchr(filename, ':'); if(pptr) { *pptr++ = 0; @@ -347,24 +330,44 @@ this->curpos = 0; if (this->fh == -1) { - free (this->mrl); - free (this); - return NULL; + return 0; } - this->nbc = nbc_init (this->stream); - /* * fill preview buffer */ + this->preview_size = read (this->fh, this->preview, MAX_PREVIEW_SIZE); this->preview_pos = 0; - this->preview_size = 0; + this->curpos = 0; - this->preview_size = read (this->fh, this->preview, MAX_PREVIEW_SIZE); + return 1; +} - this->preview_pos = 0; +static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { + /* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */ + net_input_plugin_t *this; + char *filename; + + if (!strncasecmp (mrl, "tcp://", 6)) { + filename = (char *) &mrl[6]; + + if((!filename) || (strlen(filename) == 0)) { + return NULL; + } + } else { + return NULL; + } + + this = xine_xmalloc(sizeof(net_input_plugin_t)); + this->mrl = strdup(mrl); + this->stream = stream; + this->fh = -1; this->curpos = 0; + this->nbc = nbc_init (this->stream); + this->preview_pos = 0; + this->preview_size = 0; + this->input_plugin.open = net_plugin_open; this->input_plugin.get_capabilities = net_plugin_get_capabilities; this->input_plugin.read = net_plugin_read; this->input_plugin.read_block = net_plugin_read_block; @@ -377,7 +380,6 @@ this->input_plugin.dispose = net_plugin_dispose; this->input_plugin.input_class = cls_gen; - return &this->input_plugin; } @@ -408,7 +410,7 @@ this->config = xine->config; this->xine = xine; - this->input_class.open_plugin = net_plugin_open; + this->input_class.get_instance = net_class_get_instance; this->input_class.get_description = net_class_get_description; this->input_class.get_identifier = net_class_get_identifier; this->input_class.get_dir = NULL; @@ -425,7 +427,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "tcp", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "tcp", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_plugin.h xine-lib/src/input/input_plugin.h --- orig/xine-lib/src/input/input_plugin.h Fri Feb 28 03:51:48 2003 +++ xine-lib/src/input/input_plugin.h Sat Apr 12 18:13:41 2003 @@ -29,7 +29,7 @@ #include "buffer.h" #include "configfile.h" -#define INPUT_PLUGIN_IFACE_VERSION 11 +#define INPUT_PLUGIN_IFACE_VERSION 12 typedef struct input_class_s input_class_t ; typedef struct input_plugin_s input_plugin_t; @@ -37,9 +37,10 @@ struct input_class_s { /* - * open a new instance of this plugin class + * create a new instance of this plugin class + * return NULL if the plugin does'nt handle the given mrl */ - input_plugin_t* (*open_plugin) (input_class_t *this, xine_stream_t *stream, const char *mrl); + input_plugin_t* (*get_instance) (input_class_t *this, xine_stream_t *stream, const char *mrl); /* * return short, human readable identifier for this plugin class @@ -78,6 +79,12 @@ }; struct input_plugin_s { + + /* + * open the stream + * return 0 if an error occured + */ + int (*open) (input_plugin_t *this); /* * return capabilities of the current playable entity. See diff -urw orig/xine-lib/src/input/input_pnm.c xine-lib/src/input/input_pnm.c --- orig/xine-lib/src/input/input_pnm.c Fri Feb 28 03:51:48 2003 +++ xine-lib/src/input/input_pnm.c Sun Apr 13 03:11:18 2003 @@ -62,6 +62,8 @@ typedef struct { input_plugin_t input_plugin; + xine_stream_t *stream; + pnm_t *pnm; char *mrl; @@ -207,38 +209,46 @@ return INPUT_OPTIONAL_UNSUPPORTED; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, - const char *data) { +static int pnm_plugin_open (input_plugin_t *this_gen) { + pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; - /* pnm_input_class_t *cls = (pnm_input_class_t *) cls_gen; */ - pnm_input_plugin_t *this; pnm_t *pnm; - char *mrl = strdup(data); #ifdef LOG - printf ("input_pnm: trying to open '%s'\n", mrl); + printf ("input_pnm: trying to open '%s'\n", this->mrl); #endif - if (strncasecmp (mrl, "pnm://", 6)) { - free (mrl); - return NULL; + pnm = pnm_connect (this->mrl); + + if (!pnm) { + return 0; + } + + this->pnm = pnm; + + return 1; } - pnm = pnm_connect (mrl); +static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, + const char *data) { - if (!pnm) { + /* pnm_input_class_t *cls = (pnm_input_class_t *) cls_gen; */ + pnm_input_plugin_t *this; + char *mrl = strdup(data); + + if (strncasecmp (mrl, "pnm://", 6)) { free (mrl); return NULL; } this = (pnm_input_plugin_t *) xine_xmalloc (sizeof (pnm_input_plugin_t)); - this->pnm = pnm; + this->stream = stream; + this->pnm = NULL; this->mrl = mrl; - this->nbc = nbc_init (stream); - - nbc_set_high_water_mark(this->nbc, 50); + this->nbc = nbc_init (this->stream); + this->input_plugin.open = pnm_plugin_open; this->input_plugin.get_capabilities = pnm_plugin_get_capabilities; this->input_plugin.read = pnm_plugin_read; this->input_plugin.read_block = pnm_plugin_read_block; @@ -280,7 +290,7 @@ this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = pnm_class_get_instance; this->input_class.get_identifier = pnm_class_get_identifier; this->input_class.get_description = pnm_class_get_description; this->input_class.get_dir = NULL; @@ -297,7 +307,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "pnm", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "pnm", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_pvr.c xine-lib/src/input/input_pvr.c --- orig/xine-lib/src/input/input_pvr.c Mon Mar 31 17:34:16 2003 +++ xine-lib/src/input/input_pvr.c Sun Apr 13 03:11:54 2003 @@ -1209,14 +1209,20 @@ this->scr->scr.exit(&this->scr->scr); } + if (this->event_queue) xine_event_dispose_queue (this->event_queue); + if (this->dev_fd != -1) close(this->dev_fd); pvr_finish_recording(this); free (this->mrl); + + if (this->tmp_prefix) free (this->tmp_prefix); + + if (this->save_prefix) free (this->save_prefix); show = xine_list_first_content (this->saved_shows); @@ -1226,38 +1232,79 @@ show = xine_list_next_content (this->saved_shows); } xine_list_free(this->saved_shows); + free (this); +} + +static int pvr_plugin_open (input_plugin_t *this_gen ) { + pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; + char *aux; + int dev_fd; + int64_t time; + int err; + aux = &this->mrl[4]; - free (this); + dev_fd = open (PVR_DEVICE, O_RDWR); + if (dev_fd == -1) { + printf("input_pvr: error opening device %s\n", PVR_DEVICE ); + return 0; + } + + this->dev_fd = dev_fd; + + /* register our own scr provider */ + time = this->stream->xine->clock->get_current_time(this->stream->xine->clock); + this->scr = pvrscr_init(); + this->scr->scr.start(&this->scr->scr, time); + this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr); + this->scr_tunning = 0; + + this->event_queue = xine_event_new_queue (this->stream); + + /* enable resample method */ + this->stream->xine->config->update_num(this->stream->xine->config,"audio.av_sync_method",1); + + this->session = 0; + this->rec_fd = -1; + this->play_fd = -1; + this->first_page = 0; + this->show_page = 0; + this->save_page = -1; + this->input = -1; + this->channel = -1; + this->pvr_playing = 1; + this->preview_buffers = NUM_PREVIEW_BUFFERS; + + this->saved_id = 0; + + this->pvr_running = 1; + + if ((err = pthread_create (&this->pvr_thread, + NULL, pvr_loop, this)) != 0) { + fprintf (stderr, "input_pvr: can't create new thread (%s)\n", + strerror(err)); + abort(); + } + + return 1; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, +static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { pvr_input_class_t *cls = (pvr_input_class_t *) cls_gen; pvr_input_plugin_t *this; char *mrl = strdup(data); char *aux; - int dev_fd; - int64_t time; - int err; if (strncasecmp (mrl, "pvr:", 4)) return NULL; aux = &mrl[4]; - dev_fd = open (PVR_DEVICE, O_RDWR); - - if (dev_fd == -1) { - printf("input_pvr: error opening device %s\n", PVR_DEVICE ); - free (mrl); - return NULL; - } - this = (pvr_input_plugin_t *) xine_xmalloc (sizeof (pvr_input_plugin_t)); this->class = cls; this->stream = stream; - this->dev_fd = dev_fd; + this->dev_fd = -1; this->mrl = mrl; this->max_page_age = 3; @@ -1290,6 +1337,7 @@ printf("input_pvr: max_page_age=%d\n", this->max_page_age); #endif + this->input_plugin.open = pvr_plugin_open; this->input_plugin.get_capabilities = pvr_plugin_get_capabilities; this->input_plugin.read = pvr_plugin_read; this->input_plugin.read_block = pvr_plugin_read_block; @@ -1302,46 +1350,16 @@ this->input_plugin.dispose = pvr_plugin_dispose; this->input_plugin.input_class = cls_gen; - /* register our own scr provider */ - time = this->stream->xine->clock->get_current_time(this->stream->xine->clock); - this->scr = pvrscr_init(); - this->scr->scr.start(&this->scr->scr, time); - this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr); - this->scr_tunning = 0; - - this->event_queue = xine_event_new_queue (this->stream); - - /* enable resample method */ - stream->xine->config->update_num(stream->xine->config,"audio.av_sync_method",1); - - this->session = 0; - this->rec_fd = -1; - this->play_fd = -1; - this->first_page = 0; - this->show_page = 0; - this->save_page = -1; + this->scr = NULL; + this->event_queue = NULL; this->save_name = NULL; - this->input = -1; - this->channel = -1; - this->pvr_playing = 1; - this->preview_buffers = NUM_PREVIEW_BUFFERS; - - this->saved_id = 0; this->saved_shows = xine_list_new(); - this->pvr_running = 1; pthread_mutex_init (&this->lock, NULL); pthread_mutex_init (&this->dev_lock, NULL); pthread_cond_init (&this->has_valid_data,NULL); pthread_cond_init (&this->wake_pvr,NULL); - if ((err = pthread_create (&this->pvr_thread, - NULL, pvr_loop, this)) != 0) { - fprintf (stderr, "input_pvr: can't create new thread (%s)\n", - strerror(err)); - abort(); - } - return &this->input_plugin; } @@ -1376,7 +1394,7 @@ this->config = xine->config; config = xine->config; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = pvr_class_get_instance; this->input_class.get_identifier = pvr_class_get_identifier; this->input_class.get_description = pvr_class_get_description; this->input_class.get_dir = NULL; @@ -1393,7 +1411,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "pvr", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_INPUT, 12, "pvr", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_rtp.c xine-lib/src/input/input_rtp.c --- orig/xine-lib/src/input/input_rtp.c Wed Mar 5 18:16:21 2003 +++ xine-lib/src/input/input_rtp.c Sun Apr 13 01:47:13 2003 @@ -113,6 +113,8 @@ char *mrl; config_values_t *config; + char *filename; + int port; int is_rtp; int fh; @@ -135,6 +137,7 @@ pthread_t reader_thread; int curpos; + int rtp_running; } rtp_input_plugin_t; @@ -174,14 +177,15 @@ if ((setsockopt(s, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))) < 0) { LOG_MSG_STDERR(xine, _("setsockopt(SO_RCVBUF): %s.\n"), strerror(errno)); - abort(); + return -1; } /* datagram socket */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) { LOG_MSG_STDERR(xine, _("bind(): %s.\n"), strerror(errno)); - abort(); + return -1; } + /* multicast ? */ if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe) { #ifdef HAVE_IP_MREQN @@ -199,7 +203,7 @@ if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn))) { LOG_MSG_STDERR(xine, _("setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n"), strerror(errno)); - abort(); + return -1; } } @@ -529,29 +533,65 @@ static void rtp_plugin_dispose (input_plugin_t *this_gen ) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; - LOG_MSG(this->stream->xine, _("RTP: stopping reading thread...\n")); + if (this->rtp_running) { + LOG_MSG(this->stream->xine, _("RTP: stopping reading thread...\n")); pthread_cancel(this->reader_thread); pthread_join(this->reader_thread, NULL); - LOG_MSG(this->stream->xine, _("RTP: reading thread terminated\n")); + } + + if (this->fh != -1) close(this->fh); + free(this->buffer); free(this->mrl); free(this); } -static input_plugin_t *rtp_plugin_open (input_class_t *cls_gen, +static int rtp_plugin_open (input_plugin_t *this_gen ) { + rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; + int err; + + LOG_MSG(this->stream->xine, _("Opening >%s<\n"), this->filename); + + this->fh = host_connect(this->filename, this->port, this->stream->xine); + + if (this->fh == -1) { + return 0; + } + + this->last_input_error = 0; + this->input_eof = 0; + this->curpos = 0; + this->rtp_running = 1; + + if ((err = pthread_create(&this->reader_thread, NULL, + input_plugin_read_loop, (void *)this)) != 0) { + LOG_MSG_STDERR(this->stream->xine, + _("input_rtp: can't create new thread (%s)\n"), + strerror(err)); + abort(); + } + + this->preview_timeout.tv_sec = time(NULL) + 5; + this->preview_timeout.tv_nsec = 0; + + return 1; +} + +static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, - const char *mrl) { + const char *data) { rtp_input_plugin_t *this; - const char *filename = NULL; + char *filename = NULL; char *pptr; - int port = 7658; - int err; + char *mrl; int is_rtp = 0; + int port = 7658; + mrl = strdup(data); if (!strncasecmp (mrl, "rtp://", 6)) { filename = &mrl[6]; is_rtp = 1; @@ -561,14 +601,25 @@ is_rtp = 0; } - if (filename == NULL || strlen(filename) == 0) + if (filename == NULL || strlen(filename) == 0) { + free(mrl); return NULL; + } + + pptr=strrchr(filename, ':'); + if (pptr) { + *pptr++ = 0; + sscanf(pptr,"%d", &port); + } this = (rtp_input_plugin_t *) malloc(sizeof(rtp_input_plugin_t)); this->stream = stream; - - this->mrl = strdup(mrl); + this->mrl = mrl; + this->filename = filename; + this->port = port; this->is_rtp = is_rtp; + this->fh = -1; + this->rtp_running = 0; pthread_mutex_init(&this->buffer_mutex, NULL); pthread_cond_init(&this->buffer_notempty, NULL); @@ -578,35 +629,10 @@ this->buffer_start = 0; this->buffer_length = 0; - LOG_MSG(this->stream->xine, _("Opening >%s<\n"), filename); - - pptr=strrchr(filename, ':'); - if(pptr) { - *pptr++ = 0; - sscanf(pptr,"%d", &port); - } - - this->fh = host_connect(filename, port, this->stream->xine); - - if (this->fh == -1) { - return 0; - } - - this->last_input_error = 0; - this->input_eof = 0; - this->curpos = 0; - - if ((err = pthread_create(&this->reader_thread, NULL, - input_plugin_read_loop, (void *)this)) != 0) { - LOG_MSG_STDERR(this->stream->xine, - _("input_rtp: can't create new thread (%s)\n"), - strerror(err)); - abort(); - } - this->preview_timeout.tv_sec = time(NULL) + 5; this->preview_timeout.tv_nsec = 0; + this->input_plugin.open = rtp_plugin_open; this->input_plugin.get_capabilities = rtp_plugin_get_capabilities; this->input_plugin.read = rtp_plugin_read; this->input_plugin.read_block = NULL; @@ -619,7 +645,7 @@ this->input_plugin.dispose = rtp_plugin_dispose; this->input_plugin.input_class = cls_gen; - return (input_plugin_t *) this; + return &this->input_plugin; } @@ -649,7 +675,7 @@ this->config = xine->config; this->xine = xine; - this->input_class.open_plugin = rtp_plugin_open; + this->input_class.get_instance = rtp_class_get_instance; this->input_class.get_description = rtp_class_get_description; this->input_class.get_identifier = rtp_class_get_identifier; this->input_class.get_dir = NULL; @@ -667,7 +693,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "rtp", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "rtp", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_rtsp.c xine-lib/src/input/input_rtsp.c --- orig/xine-lib/src/input/input_rtsp.c Fri Feb 28 03:51:48 2003 +++ xine-lib/src/input/input_rtsp.c Sun Apr 13 03:12:44 2003 @@ -212,36 +212,44 @@ return INPUT_OPTIONAL_UNSUPPORTED; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, - const char *data) { +static int rtsp_plugin_open (input_plugin_t *this_gen) { + rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; - /* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */ - rtsp_input_plugin_t *this; rtsp_session_t *rtsp; - char *mrl = strdup(data); #ifdef LOG printf ("input_rtsp: trying to open '%s'\n", mrl); #endif - if (strncasecmp (mrl, "rtsp://", 6)) { - free (mrl); - return NULL; - } - - rtsp = rtsp_session_start(mrl); + rtsp = rtsp_session_start(this->mrl); if (!rtsp) { - free (mrl); #ifdef LOG printf ("input_rtsp: returning null.\n"); #endif + return 0; + } + + this->rtsp = rtsp; + + return 1; +} + +static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, + const char *data) { + + /* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */ + rtsp_input_plugin_t *this; + char *mrl = strdup(data); + + if (strncasecmp (mrl, "rtsp://", 6)) { + free (mrl); return NULL; } this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t)); - this->rtsp = rtsp; + this->rtsp = NULL; this->mrl = mrl; /* since we handle only real streams yet, we can savely add * an .rm extention to force handling by demux_real. @@ -250,8 +258,8 @@ sprintf(this->public_mrl, "%s.rm", this->mrl); this->nbc = nbc_init (stream); - nbc_set_high_water_mark(this->nbc, 50); + this->input_plugin.open = rtsp_plugin_open; this->input_plugin.get_capabilities = rtsp_plugin_get_capabilities; this->input_plugin.read = rtsp_plugin_read; this->input_plugin.read_block = rtsp_plugin_read_block; @@ -293,7 +301,7 @@ this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = rtsp_class_get_instance; this->input_class.get_identifier = rtsp_class_get_identifier; this->input_class.get_description = rtsp_class_get_description; this->input_class.get_dir = NULL; @@ -310,7 +318,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "rtsp", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "rtsp", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_stdin_fifo.c xine-lib/src/input/input_stdin_fifo.c --- orig/xine-lib/src/input/input_stdin_fifo.c Fri Mar 21 00:26:11 2003 +++ xine-lib/src/input/input_stdin_fifo.c Sun Apr 13 02:25:48 2003 @@ -109,8 +109,8 @@ FD_ZERO (&rset); FD_SET (this->fh, &rset); - timeout.tv_sec = 0; - timeout.tv_usec = 10000; + timeout.tv_sec = 30; + timeout.tv_usec = 0; if (select (this->fh+1, &rset, NULL, NULL, &timeout) <= 0) { nbc_check_buffers (this->nbc); @@ -272,7 +272,7 @@ if (this->nbc) nbc_close (this->nbc); - if (this->fh != STDIN_FILENO) + if ((this->fh != STDIN_FILENO) && (this->fh != -1)) close(this->fh); free (this->mrl); @@ -295,8 +295,53 @@ return INPUT_OPTIONAL_UNSUPPORTED; } +static int stdin_plugin_open (input_plugin_t *this_gen ) { + stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; + +#ifdef LOG + printf ("input_stdin_fifo: trying to open '%s'...\n", + mrl); +#endif + + if (this->fh == -1) { + char *filename; + + filename = (char *) &this->mrl[5]; + this->fh = open (filename, O_RDONLY); + +#ifdef LOG + printf("input_stdin_fifo: filename '%s'\n", filename); +#endif + + if (this->fh == -1) { + printf ("stdin: failed to open '%s'\n", + filename); + return 0; + } + } + + + /* + * mrl accepted and opened successfully at this point + * + * => create plugin instance + */ + + this->curpos = 0; + + /* + * fill preview buffer + */ + + this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview, + MAX_PREVIEW_SIZE); + this->preview_pos = 0; + + return 1; +} -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, + +static input_plugin_t *stdin_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { /* stdin_input_class_t *cls = (stdin_input_class_t *) cls_gen; */ @@ -305,11 +350,6 @@ int fh; -#ifdef LOG - printf ("input_stdin_fifo: trying to open '%s'...\n", - mrl); -#endif - if (!strncasecmp(mrl, "stdin:/", 7) || !strncmp(mrl, "-", 1)) { @@ -319,17 +359,10 @@ char *filename; filename = (char *) &mrl[5]; - - fh = open (filename, O_RDONLY); - + fh = -1; +#ifdef LOG printf("input_stdin_fifo: filename '%s'\n", filename); - - if (fh == -1) { - printf ("stdin: failed to open '%s'\n", - filename); - free (mrl); - return NULL; - } +#endif } else { free (mrl); return NULL; @@ -345,7 +378,11 @@ this = (stdin_input_plugin_t *) xine_xmalloc(sizeof(stdin_input_plugin_t)); this->stream = stream; + this->curpos = 0; + this->mrl = mrl; + this->fh = fh; + this->input_plugin.open = stdin_plugin_open; this->input_plugin.get_capabilities = stdin_plugin_get_capabilities; this->input_plugin.read = stdin_plugin_read; this->input_plugin.read_block = stdin_plugin_read_block; @@ -358,24 +395,11 @@ this->input_plugin.get_optional_data = stdin_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; - this->curpos = 0; - this->mrl = mrl; - this->fh = fh; - /* * buffering control */ - this->nbc = nbc_init (this->stream); - /* - * fill preview buffer - */ - - this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview, - MAX_PREVIEW_SIZE); - this->preview_pos = 0; - return &this->input_plugin; } @@ -401,11 +425,12 @@ stdin_input_class_t *this; + printf ("input_stdin_fifo: init_class\n"); this = (stdin_input_class_t *) xine_xmalloc (sizeof (stdin_input_class_t)); this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = stdin_class_get_instance; this->input_class.get_identifier = stdin_class_get_identifier; this->input_class.get_description = stdin_class_get_description; this->input_class.get_dir = NULL; @@ -422,6 +447,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "stdin", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "stdin", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_v4l.c xine-lib/src/input/input_v4l.c --- orig/xine-lib/src/input/input_v4l.c Fri Feb 28 03:51:48 2003 +++ xine-lib/src/input/input_v4l.c Sun Apr 13 02:47:35 2003 @@ -72,6 +72,7 @@ typedef struct { input_plugin_t input_plugin; + xine_stream_t *stream; char *mrl; off_t curpos; @@ -267,6 +268,7 @@ if(this->mrl) free(this->mrl); + if (this->video_fd != -1) close(this->video_fd); free (this); @@ -285,29 +287,17 @@ return INPUT_OPTIONAL_UNSUPPORTED; } - -static input_plugin_t *open_plugin (input_class_t *cls_gen, - xine_stream_t *stream, const char *data) { +static int v4l_plugin_open (input_plugin_t *this_gen) { + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ - v4l_input_plugin_t *this; int i, j, ret, found; - char *mrl = strdup(data); #ifdef LOG printf ("input_v4l: trying to open '%s'\n", mrl); #endif found = 0; - if (strncasecmp (mrl, "v4l:", 4)) { - free (mrl); - return NULL; - } - - this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t)); - - this->mrl = mrl; - /* * pre-alloc a bunch of frames */ @@ -320,24 +310,21 @@ #ifdef LOG printf ("input_v4l: cannot open v4l device\n"); #endif - free(this); - return NULL; + return 0; } if (ioctl(this->video_fd,VIDIOCGCAP,&this->video_cap) < 0) { #ifdef LOG printf ("input_v4l: VIDIOCGCAP ioctl went wrong\n"); #endif - free(this); - return NULL; + return 0; } if (!(this->video_cap.type & VID_TYPE_CAPTURE)) { #ifdef LOG printf ("input_v4l: grab device does not handle capture\n"); #endif - free(this); - return NULL; + return 0; } /* figure out the resolution */ @@ -357,8 +344,7 @@ #ifdef LOG printf ("input_v4l: grab device does not support any preset resolutions"); #endif - free(this); - return NULL; + return 0; } for (i=0; ivideo_buf) { perror("mmap"); close (this->video_fd); - free(this); - return NULL; + return 0; } this->gb_frame = 0; @@ -471,8 +456,7 @@ } #endif close (this->video_fd); - free (this); - return NULL; + return 0; } this->frame_format = this->gb_buf.format; this->use_mmap = 1; @@ -487,11 +471,35 @@ break; } - stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = resolutions[j].width; - stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = resolutions[j].height; + this->stream->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = resolutions[j].width; + this->stream->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = resolutions[j].height; this->start_time=0; + return 1; +} + +static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen, + xine_stream_t *stream, const char *data) { + + /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ + v4l_input_plugin_t *this; + char *mrl = strdup(data); + + if (strncasecmp (mrl, "v4l:", 4)) { + free (mrl); + return NULL; + } + + this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t)); + + this->stream = stream; + this->mrl = mrl; + this->video_fd = -1; + pthread_mutex_init (&this->frames_lock, NULL); + pthread_cond_init (&this->frame_freed, NULL); + + this->input_plugin.open = v4l_plugin_open; this->input_plugin.get_capabilities = v4l_plugin_get_capabilities; this->input_plugin.read = v4l_plugin_read; this->input_plugin.read_block = v4l_plugin_read_block; @@ -533,7 +541,7 @@ this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = v4l_class_get_instance; this->input_class.get_identifier = v4l_class_get_identifier; this->input_class.get_description = v4l_class_get_description; this->input_class.get_dir = NULL; @@ -550,7 +558,7 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "v4l", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "v4l", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff -urw orig/xine-lib/src/input/input_vcd.c xine-lib/src/input/input_vcd.c --- orig/xine-lib/src/input/input_vcd.c Sun Apr 6 02:51:29 2003 +++ xine-lib/src/input/input_vcd.c Sun Apr 13 03:02:30 2003 @@ -797,6 +797,7 @@ vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + if (this->fd != -1) close(this->fd); free (this->mrl); @@ -815,51 +816,21 @@ return INPUT_OPTIONAL_UNSUPPORTED; } -static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream, - const char *data) { - - vcd_input_class_t *cls = (vcd_input_class_t *) cls_gen; - vcd_input_plugin_t *this; - char *mrl = strdup(data); +static int vcd_plugin_open (input_plugin_t *this_gen) { + vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; + vcd_input_class_t *cls = this->cls; char *filename; int fd; - if (strncasecmp (mrl, "vcd:/",5)) { - free (mrl); - return 0; - } - fd = open (cls->device, O_RDONLY); - if (fd == -1) { - free (mrl); return 0; } - this = (vcd_input_plugin_t *) xine_xmalloc(sizeof(vcd_input_plugin_t)); - - this->stream = stream; - this->mrl = mrl; this->fd = fd; - this->input_plugin.get_capabilities = vcd_plugin_get_capabilities; - this->input_plugin.read = vcd_plugin_read; - this->input_plugin.read_block = vcd_plugin_read_block; - this->input_plugin.seek = vcd_plugin_seek; - this->input_plugin.get_current_pos = vcd_plugin_get_current_pos; - this->input_plugin.get_length = vcd_plugin_get_length; - this->input_plugin.get_blocksize = vcd_plugin_get_blocksize; - this->input_plugin.get_mrl = vcd_plugin_get_mrl; - this->input_plugin.get_optional_data = vcd_plugin_get_optional_data; - this->input_plugin.dispose = vcd_plugin_dispose; - this->input_plugin.input_class = cls_gen; - this->cls = cls; - if (input_vcd_read_toc (this->cls, this->fd)) { - close (this->fd); - free (this); - free (mrl); - return NULL; + return 0; } filename = (char *) &this->mrl[5]; @@ -867,19 +838,13 @@ if (sscanf (filename, "%d", &this->cur_track) != 1) { printf ("input_vcd: malformed MRL. Use vcd:/\n"); - close (this->fd); - free (this); - free (mrl); - return NULL; + return 0; } if (this->cur_track>=this->cls->total_tracks) { printf ("input_vcd: invalid track %d (valid range: 0 .. %d)\n", this->cur_track, this->cls->total_tracks-1); - close (this->fd); - free (this); - free (mrl); - return NULL; + return 0; } #if defined (__linux__) || defined(__sun) @@ -901,6 +866,40 @@ } #endif + return 1; +} + +static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, + const char *data) { + + vcd_input_class_t *cls = (vcd_input_class_t *) cls_gen; + vcd_input_plugin_t *this; + char *mrl = strdup(data); + + if (strncasecmp (mrl, "vcd:/",5)) { + free (mrl); + return 0; + } + + this = (vcd_input_plugin_t *) xine_xmalloc(sizeof(vcd_input_plugin_t)); + + this->stream = stream; + this->mrl = mrl; + this->fd = -1; + + this->input_plugin.open = vcd_plugin_open; + this->input_plugin.get_capabilities = vcd_plugin_get_capabilities; + this->input_plugin.read = vcd_plugin_read; + this->input_plugin.read_block = vcd_plugin_read_block; + this->input_plugin.seek = vcd_plugin_seek; + this->input_plugin.get_current_pos = vcd_plugin_get_current_pos; + this->input_plugin.get_length = vcd_plugin_get_length; + this->input_plugin.get_blocksize = vcd_plugin_get_blocksize; + this->input_plugin.get_mrl = vcd_plugin_get_mrl; + this->input_plugin.get_optional_data = vcd_plugin_get_optional_data; + this->input_plugin.dispose = vcd_plugin_dispose; + this->input_plugin.input_class = cls_gen; + this->cls = cls; return &this->input_plugin; } @@ -1071,7 +1070,7 @@ this->xine = xine; - this->input_class.open_plugin = open_plugin; + this->input_class.get_instance = vcd_class_get_instance; this->input_class.get_identifier = vcd_class_get_identifier; this->input_class.get_description = vcd_class_get_description; this->input_class.get_dir = vcd_class_get_dir; @@ -1099,6 +1098,6 @@ plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 11, "VCD", XINE_VERSION_CODE, NULL, init_class }, + { PLUGIN_INPUT, 12, "VCD", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } };