diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_asf.c | 189 | ||||
-rw-r--r-- | src/demuxers/demux_qt.c | 19 | ||||
-rw-r--r-- | src/demuxers/demux_real.c | 15 | ||||
-rw-r--r-- | src/xine-engine/demux.c | 48 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 6 |
5 files changed, 170 insertions, 107 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index 9198be415..b1aae7f45 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_asf.c,v 1.170 2005/06/09 20:33:46 tmattern Exp $ + * $Id: demux_asf.c,v 1.171 2005/07/17 23:11:44 dsalt Exp $ * * demultiplexer for asf streams * @@ -1536,8 +1536,6 @@ static int demux_asf_parse_http_references( demux_asf_t *this) { int buf_used = 0; int len; char *href = NULL; - xine_mrl_reference_data_t *data; - xine_event_t uevent; char *mrl; int free_href = 0; @@ -1588,15 +1586,7 @@ static int demux_asf_parse_http_references( demux_asf_t *this) { } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: http ref: %s\n", href); - uevent.type = XINE_EVENT_MRL_REFERENCE; - uevent.stream = this->stream; - uevent.data_length = strlen(href) + sizeof(xine_mrl_reference_data_t); - data = malloc(uevent.data_length); - uevent.data = data; - strcpy(data->mrl, href); - data->alternative = 0; - xine_event_send(this->stream, &uevent); - free(data); + _x_demux_send_mrl_reference (this->stream, 0, mrl, NULL, 0, 0); if (free_href) free(href); @@ -1618,8 +1608,6 @@ static int demux_asf_parse_asf_references( demux_asf_t *this) { int buf_size = 0; int buf_used = 0; int len; - xine_mrl_reference_data_t *data; - xine_event_t uevent; int i; /* read file to memory. @@ -1654,15 +1642,7 @@ static int demux_asf_parse_asf_references( demux_asf_t *this) { } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf ref: %s\n", ptr); - uevent.type = XINE_EVENT_MRL_REFERENCE; - uevent.stream = this->stream; - uevent.data_length = strlen(ptr) + sizeof(xine_mrl_reference_data_t); - data = malloc(uevent.data_length); - uevent.data = data; - strcpy(data->mrl, ptr); - data->alternative = 0; - xine_event_send(this->stream, &uevent); - free(data); + _x_demux_send_mrl_reference (this->stream, 0, ptr, NULL, 0, 0); } free (buf); @@ -1671,6 +1651,29 @@ static int demux_asf_parse_asf_references( demux_asf_t *this) { return this->status; } + +/* .asx playlist parser helper functions */ +static uint32_t asx_get_time_value (const xml_node_t *node) +{ + const char *value = xml_parser_get_property (node, "VALUE"); + + if (value) + { + int hours, minutes; + double seconds; + + if (sscanf (value, "%d:%d:%lf", &hours, &minutes, &seconds) == 3) + return hours * 3600000 + minutes * 60000 + seconds; + + if (sscanf (value, "%d:%lf", &minutes, &seconds) == 3) + return minutes * 60000 + seconds * 1000; + + /* FIXME: single element is minutes or seconds? */ + } + + return 0; /* value not found */ +} + /* * parse .asx playlist files */ @@ -1680,10 +1683,7 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) { int buf_size = 0; int buf_used = 0; int len; - xine_mrl_reference_data_t *data; - xine_event_t uevent; xml_node_t *xml_tree, *asx_entry, *asx_ref; - xml_property_t *asx_prop; int result; @@ -1711,75 +1711,108 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) { goto failure; if(!strcasecmp(xml_tree->name, "ASX")) { + /* Attributes: VERSION, PREVIEWMODE, BANNERBAR + * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION, ENTRY, + ENTRYREF, MOREINFO, PARAM, REPEAT, TITLE + */ - asx_prop = xml_tree->props; - - while((asx_prop) && (strcasecmp(asx_prop->name, "VERSION"))) - asx_prop = asx_prop->next; + const char *version = xml_parser_get_property (xml_tree, "VERSION"); - if(asx_prop) { + if (version) { int version_major, version_minor = 0; - if((((sscanf(asx_prop->value, "%d.%d", &version_major, &version_minor)) == 2) || - ((sscanf(asx_prop->value, "%d", &version_major)) == 1)) && - ((version_major == 3) && (version_minor == 0))) { - - asx_entry = xml_tree->child; - while(asx_entry) { - if((!strcasecmp(asx_entry->name, "ENTRY")) || - (!strcasecmp(asx_entry->name, "ENTRYREF"))) { - char *href = NULL; - - asx_ref = asx_entry->child; - if (!asx_ref && !strcasecmp(asx_entry->name, "ENTRYREF")) { - for(asx_prop = asx_entry->props; asx_prop; asx_prop = asx_prop->next) - - if(!strcasecmp(asx_prop->name, "HREF")) { - - href = asx_prop->value; + if((sscanf (version, "%d.%d", &version_major, &version_minor) == 2 || + sscanf (version, "%d", &version_major) == 1) && + (version_major == 3 && version_minor == 0)) + { + const char *base_href = NULL; - if(href) - break; + for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next) + { + const char *ref_base_href = base_href; + + if (!strcasecmp (asx_entry->name, "ENTRY")) + { + /* Attributes: CLIENTSKIP, SKIPIFREF + * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION, + ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER, + STARTTIME, TITLE + */ + const char *href = NULL; + const char *title = NULL; + uint32_t start_time = -1; + uint32_t duration = -1; + + for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next) + { + if (!strcasecmp(asx_ref->name, "REF")) + { + xml_node_t *asx_sub; + /* Attributes: HREF + * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME + */ + + /* FIXME: multiple REFs => alternative streams + * (and per-ref start times and durations?). + * Just the one title, though. + */ + href = xml_parser_get_property (asx_ref, "HREF"); + + for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next) + { + if (!strcasecmp (asx_sub->name, "STARTTIME")) + start_time = asx_get_time_value (asx_sub); + else if (!strcasecmp (asx_sub->name, "DURATION")) + duration = asx_get_time_value (asx_sub); } - } - - while(asx_ref) { - - if(!strcasecmp(asx_ref->name, "REF")) { + } - for(asx_prop = asx_ref->props; asx_prop; asx_prop = asx_prop->next) { + else if (!strcasecmp (asx_ref->name, "TITLE")) + { + if (!title) + title = asx_ref->data; + } - if(!strcasecmp(asx_prop->name, "HREF")) { + else if (!strcasecmp (asx_ref->name, "STARTTIME")) + { + if (start_time < 0) + start_time = asx_get_time_value (asx_ref); + } - if(!href) - href = asx_prop->value; - } - if(href) - break; - } + else if (!strcasecmp (asx_ref->name, "DURATION")) + { + if (duration < 0) + duration = asx_get_time_value (asx_ref); } - asx_ref = asx_ref->next; - } - if(href && strlen(href)) { - uevent.type = XINE_EVENT_MRL_REFERENCE; - uevent.stream = this->stream; - uevent.data_length = strlen(href)+sizeof(xine_mrl_reference_data_t); - data = malloc(uevent.data_length); - uevent.data = data; - strcpy(data->mrl, href); - data->alternative = 0; - xine_event_send(this->stream, &uevent); - free(data); + else if (!strcasecmp (asx_ref->name, "BASE")) + /* Attributes: HREF */ + ref_base_href = xml_parser_get_property (asx_entry, "HREF"); } - href = NULL; + + /* FIXME: prepend ref_base_href to href */ + if (href && *href) + _x_demux_send_mrl_reference (this->stream, 0, href, title, + start_time < 0 ? 0 : start_time, + duration < 0 ? -1 : duration); } - asx_entry = asx_entry->next; + + else if (!strcasecmp (asx_entry->name, "ENTRYREF")) + { + /* Attributes: HREF, CLIENTBIND */ + const char *href = xml_parser_get_property (asx_entry, "HREF"); + if (href && *href) + _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1); + } + + else if (!strcasecmp (asx_entry->name, "BASE")) + /* Attributes: HREF */ + base_href = xml_parser_get_property (asx_entry, "HREF"); } } else xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("demux_asf: Wrong ASX version: %s\n"), asx_prop->value); + _("demux_asf: Wrong ASX version: %s\n"), version); } else diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 83b1c09b0..98436144b 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -30,7 +30,7 @@ * build_frame_table * free_qt_info * - * $Id: demux_qt.c,v 1.201 2005/06/17 16:53:25 jstembridge Exp $ + * $Id: demux_qt.c,v 1.202 2005/07/17 23:11:44 dsalt Exp $ * */ @@ -2193,8 +2193,6 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { qt_trak *audio_trak = NULL; int dispatch_audio; /* boolean for deciding which trak to dispatch */ int64_t pts_diff; - xine_event_t uevent; - xine_mrl_reference_data_t *data; /* if this is DRM-protected content, finish playback before it even * tries to start */ @@ -2206,18 +2204,9 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { /* check if it's time to send a reference up to the UI */ if (this->qt->chosen_reference != -1) { - uevent.type = XINE_EVENT_MRL_REFERENCE; - uevent.stream = this->stream; - uevent.data_length = - strlen(this->qt->references[this->qt->chosen_reference].url) + - sizeof(xine_mrl_reference_data_t); - data = malloc(uevent.data_length); - uevent.data = data; - strcpy(data->mrl, this->qt->references[this->qt->chosen_reference].url); - data->alternative = 0; - xine_event_send(this->stream, &uevent); - free(data); - + _x_demux_send_mrl_reference (this->stream, 0, + this->qt->references[this->qt->chosen_reference].url, + NULL, 0, 0); this->status = DEMUX_FINISHED; return this->status; } diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 930cc55d9..0fbf567a2 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -31,7 +31,7 @@ * * Based on FFmpeg's libav/rm.c. * - * $Id: demux_real.c,v 1.105 2005/06/04 11:05:59 jstembridge Exp $ + * $Id: demux_real.c,v 1.106 2005/07/17 23:11:44 dsalt Exp $ */ #ifdef HAVE_CONFIG_H @@ -781,8 +781,6 @@ static int demux_real_parse_references( demux_real_t *this) { int len, i, j; int alternative = 0; int comment = 0; - xine_mrl_reference_data_t *data; - xine_event_t uevent; lprintf("parsing references\n"); @@ -831,15 +829,8 @@ static int demux_real_parse_references( demux_real_t *this) { buf[j]='\0'; lprintf("reference [%s] found\n", &buf[i]); - uevent.type = XINE_EVENT_MRL_REFERENCE; - uevent.stream = this->stream; - uevent.data_length = strlen(&buf[i])+sizeof(xine_mrl_reference_data_t); - data = malloc(uevent.data_length); - uevent.data = data; - strcpy(data->mrl, &buf[i]); - data->alternative = alternative; - xine_event_send(this->stream, &uevent); - free(data); + _x_demux_send_mrl_reference (this->stream, alternative, + &buf[i], NULL, 0, 0); i = j; } diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index 3a2634e26..90f2d3a99 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -20,7 +20,7 @@ * Demuxer helper functions * hide some xine engine details from demuxers and reduce code duplication * - * $Id: demux.c,v 1.57 2005/03/20 18:41:55 tmattern Exp $ + * $Id: demux.c,v 1.58 2005/07/17 23:11:45 dsalt Exp $ */ @@ -600,3 +600,49 @@ int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, return 0; } + +/* + * Helper function for sending MRL reference events + */ +void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, + const char *mrl, const char *title, + int start_time, int duration) +{ + xine_event_t event; + union { + xine_mrl_reference_data_ext_t *e; + xine_mrl_reference_data_t *b; + } data; + int mrl_len = strlen (mrl); + + if (!title) + title = ""; + + /* extended MRL reference event */ + + event.stream = stream; + event.data_length = offsetof (xine_mrl_reference_data_ext_t, mrl) + + mrl_len + strlen (title) + 2; + data.e = event.data = malloc (event.data_length); + + data.e->alternative = alternative; + data.e->start_time = start_time; + data.e->duration = duration; + strcpy (data.e->mrl, mrl); + strcpy (data.e->mrl + mrl_len + 1, title ? title : ""); + + event.type = XINE_EVENT_MRL_REFERENCE_EXT; + xine_event_send (stream, &event); + + /* plain MRL reference event */ + + event.data_length = offsetof (xine_mrl_reference_data_t, mrl) + mrl_len + 1; + + /*data.b->alternative = alternative;*/ + strcpy (data.b->mrl, mrl); + + event.type = XINE_EVENT_MRL_REFERENCE; + xine_event_send (stream, &event); + + free (data.e); +} diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 301b79a8a..81a9f6ac1 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_internal.h,v 1.165 2005/06/13 00:32:15 miguelfreitas Exp $ + * $Id: xine_internal.h,v 1.166 2005/07/17 23:11:45 dsalt Exp $ * */ @@ -419,6 +419,10 @@ int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, int input_time, int total_time, uint32_t frame_number); +void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, + const char *mrl, const char *title, + int start_time, int duration); + /* * plugin_loader functions |