From: Darren S. <ds...@us...> - 2005-07-17 23:11:54
|
Update of /cvsroot/xine/xine-lib/src/demuxers In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13737/src/demuxers Modified Files: demux_asf.c demux_qt.c demux_real.c Log Message: Improve ASX parsing. Add an extended MRL reference event which includes the item title, start time and duration. (Both events are sent; front ends should only listen for one of them.) Index: demux_asf.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/demuxers/demux_asf.c,v retrieving revision 1.170 retrieving revision 1.171 diff -u -r1.170 -r1.171 --- demux_asf.c 9 Jun 2005 20:33:46 -0000 1.170 +++ demux_asf.c 17 Jul 2005 23:11:44 -0000 1.171 @@ -1536,8 +1536,6 @@ 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 @@ } 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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(href) - break; + 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; + + 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 Index: demux_qt.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/demuxers/demux_qt.c,v retrieving revision 1.201 retrieving revision 1.202 diff -u -r1.201 -r1.202 --- demux_qt.c 17 Jun 2005 16:53:25 -0000 1.201 +++ demux_qt.c 17 Jul 2005 23:11:44 -0000 1.202 @@ -2193,8 +2193,6 @@ 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 @@ /* 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; } Index: demux_real.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/demuxers/demux_real.c,v retrieving revision 1.105 retrieving revision 1.106 diff -u -r1.105 -r1.106 --- demux_real.c 4 Jun 2005 11:05:59 -0000 1.105 +++ demux_real.c 17 Jul 2005 23:11:44 -0000 1.106 @@ -781,8 +781,6 @@ 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 @@ 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; } |