summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_asf.c189
-rw-r--r--src/demuxers/demux_qt.c19
-rw-r--r--src/demuxers/demux_real.c15
-rw-r--r--src/xine-engine/demux.c48
-rw-r--r--src/xine-engine/xine_internal.h6
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