diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_asf.c | 152 | ||||
-rw-r--r-- | src/demuxers/demux_real.c | 4 | ||||
-rw-r--r-- | src/input/input_file.c | 36 |
3 files changed, 152 insertions, 40 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index c20452847..36732825e 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.102 2003/01/29 02:33:35 miguelfreitas Exp $ + * $Id: demux_asf.c,v 1.103 2003/01/29 18:53:54 miguelfreitas Exp $ * * demultiplexer for asf streams * @@ -43,6 +43,7 @@ #include "demux.h" #include "xineutils.h" #include "asfheader.h" +#include "xmlparser.h" /* #define LOG @@ -147,6 +148,7 @@ typedef struct demux_asf_s { /* first packet position */ int64_t first_packet_pos; + int reference_mode; } demux_asf_t ; typedef struct { @@ -1248,7 +1250,119 @@ static void asf_read_packet(demux_asf_t *this) { this->packet_size_left -= frag_len; } } + +/* + * parse .asx playlist files + */ +static int demux_asf_parse_references( demux_asf_t *this) { + + char *buf = NULL; + 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; + + + /* read file to memory. + * warning: dumb code, but hopefuly ok since reference file is small */ + do { + buf_size += 1024; + buf = realloc(buf, buf_size+1); + + len = this->input->read(this->input, &buf[buf_used], buf_size-buf_used); + + if( len > 0 ) + buf_used += len; + + /* 50k of reference file? no way. something must be wrong */ + if( buf_used > 50*1024 ) + break; + } while( len > 0 ); + if(buf_used) + buf[buf_used] = '\0'; + + xml_parser_init(buf, buf_used, XML_PARSER_CASE_INSENSITIVE); + if((result = xml_parser_build_tree(&xml_tree)) != XML_PARSER_OK) + goto __failure; + + if(!strcasecmp(xml_tree->name, "ASX")) { + + asx_prop = xml_tree->props; + + while((asx_prop) && (strcasecmp(asx_prop->name, "VERSION"))) + asx_prop = asx_prop->next; + + if(asx_prop) { + 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; + while(asx_ref) { + + if(!strcasecmp(asx_ref->name, "REF")) { + + for(asx_prop = asx_ref->props; asx_prop; asx_prop = asx_prop->next) { + + if(!strcasecmp(asx_prop->name, "HREF")) { + + if(!href) + href = asx_prop->value; + } + if(href) + break; + } + } + 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); + } + href = NULL; + } + asx_entry = asx_entry->next; + } + } + else + printf("demux_asf: Wrong ASX version: %s\n", asx_prop->value); + + } + else + printf("demux_asf: Unable to find VERSION tag from ASX.\n"); + } + else + printf("demux_asf: Unsupported XML type: '%s'.\n", xml_tree->name); + + xml_parser_free_tree(xml_tree); +__failure: + free(buf); + + this->status = DEMUX_FINISHED; + return this->status; +} + + /* * xine specific functions start here */ @@ -1257,6 +1371,9 @@ static int demux_asf_send_chunk (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; + if(this->reference_mode) + return demux_asf_parse_references(this); + asf_read_packet (this); return this->status; @@ -1323,6 +1440,11 @@ static void demux_asf_send_headers (demux_plugin_t *this_gen) { if (this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) this->input->seek (this->input, 0, SEEK_SET); + if (this->reference_mode) { + xine_demux_control_start(this->stream); + return; + } + if (!asf_read_header (this)) { printf ("demux_asf: asf_read_header failed.\n"); @@ -1468,7 +1590,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, input_plugin_t *input) { demux_asf_t *this; - uint8_t buf[8192]; + uint8_t buf[4096]; int len; switch (stream->content_detection_method) { @@ -1483,7 +1605,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, if (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) { input->seek (input, 0, SEEK_SET); - if (input->read (input, buf, 8192) != 8192) + if ( (len=input->read (input, buf, 1024)) <= 0) return NULL; #ifdef LOG @@ -1493,8 +1615,12 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, } else return NULL; } - if (memcmp(buf, &guids[GUID_ASF_HEADER].guid, sizeof(GUID))) - return NULL; + + if (memcmp(buf, &guids[GUID_ASF_HEADER].guid, sizeof(GUID))) { + buf[len] = '\0'; + if( !strstr(buf,"asx") && !strstr(buf,"ASX") ) + return NULL; + } #ifdef LOG printf ("demux_asf: file starts with an asf header\n"); @@ -1538,6 +1664,22 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this = xine_xmalloc (sizeof (demux_asf_t)); this->stream = stream; this->input = input; + + /* + * check for reference stream + */ + this->reference_mode = 0; + len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); + if ( (len == INPUT_OPTIONAL_UNSUPPORTED) && + (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) ) { + input->seek (input, 0, SEEK_SET); + len=input->read (input, buf, 1024); + } + if(len > 0) { + buf[len] = '\0'; + if( strstr(buf,"asx") || strstr(buf,"ASX") ) + this->reference_mode = 1; + } this->demux_plugin.send_headers = demux_asf_send_headers; this->demux_plugin.send_chunk = demux_asf_send_chunk; diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index f0d082071..ecdc4d883 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -28,7 +28,7 @@ * * Based on FFmpeg's libav/rm.c. * - * $Id: demux_real.c,v 1.38 2003/01/29 02:33:36 miguelfreitas Exp $ + * $Id: demux_real.c,v 1.39 2003/01/29 18:53:56 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -1222,7 +1222,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str input->seek(input, 0, SEEK_SET); - if ((len = input->read(input, buf, 1024))) { + if ( (len = input->read(input, buf, 1024)) > 0) { if (real_check_stream_type(buf,len) == 2) this->reference_mode = 1; } diff --git a/src/input/input_file.c b/src/input/input_file.c index 372e864a8..56da22106 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.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: input_file.c,v 1.73 2003/01/04 14:48:12 miguelfreitas Exp $ + * $Id: input_file.c,v 1.74 2003/01/29 18:53:59 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -64,8 +64,6 @@ typedef struct { int fh; char *mrl; - FILE *sub; - } file_input_plugin_t; @@ -194,13 +192,6 @@ static char* file_plugin_get_mrl (input_plugin_t *this_gen) { static int file_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { - file_input_plugin_t *this = (file_input_plugin_t *) this_gen; - -#ifdef LOG - printf ("input_file: get optional data, type %08x, sub %p\n", - data_type, this->sub); -#endif - return INPUT_OPTIONAL_UNSUPPORTED; } @@ -209,9 +200,6 @@ static void file_plugin_dispose (input_plugin_t *this_gen ) { close(this->fh); - if (this->sub) - fclose (this->sub); - free (this->mrl); free (this); @@ -247,11 +235,10 @@ static char *decode_uri (char *uri) { static input_plugin_t *open_plugin (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_class_t *cls = (file_input_class_t *) cls_gen; */ file_input_plugin_t *this; - FILE *sub; char *mrl = strdup(data); - char *filename, *subtitle; + char *filename; int fh; if (!strncasecmp (mrl, "file:", 5)) @@ -259,22 +246,6 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea else filename = mrl; - /* FIXME: find a better solution (multiple streams) for text subtitles */ - subtitle = strrchr (filename, '?'); - if (subtitle) { - *subtitle = 0; - subtitle++; - - xine_log (cls->xine, XINE_LOG_MSG, - _("input_file: trying to open subtitle file '%s'\n"), - subtitle); - - sub = fopen (subtitle, "r"); - - } else - sub = NULL; - - fh = open (filename, O_RDONLY); if (fh == -1) { @@ -286,7 +257,6 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea this->stream = stream; this->mrl = mrl; this->fh = fh; - this->sub = sub; this->input_plugin.get_capabilities = file_plugin_get_capabilities; this->input_plugin.read = file_plugin_read; |