From: Claudio C. <kl...@us...> - 2007-01-22 18:33:04
|
Update of /cvsroot/xine/xine-plugin/src In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv22688 Modified Files: playlist.c playlist.h plugin.c Log Message: Added support for XSPF playlists. Index: playlist.c =================================================================== RCS file: /cvsroot/xine/xine-plugin/src/playlist.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- playlist.c 11 Jan 2007 15:07:46 -0000 1.12 +++ playlist.c 22 Jan 2007 18:32:59 -0000 1.13 @@ -42,9 +42,6 @@ #include "playlist.h" -/* Whether to use xine's xml parser. */ -#define USE_XML_PARSER 1 - /******************************************************************************/ static inline char *trim (char *s) { @@ -65,61 +62,8 @@ return trim (buf); } -#if !(USE_XML_PARSER) -static char *get_tag (FILE *fp, char *buf, int size) { - int c, i = 0; - - do { - c = getc (fp); - if (c < 0) - return NULL; - } while (c != '<'); - - do { - c = getc (fp); - if (c < 0) - return NULL; - buf[i++] = c; - } while (i < size && c != '>'); - - buf[i - 1] = '\0'; - if (i > 1 && buf[i-2] == '/') - buf[i-2] = '\0'; - - return buf; -} - -static char *get_prop (char *tag, const char *prop, const int prop_len) { - char *p, *e; - - while ((p = strstr (tag, prop))) { - p += prop_len; - while (isspace (*p)) - p++; - if (*p == '=') { - p++; - while (isspace (*p)) - p++; - if (*p == '"') { - e = strchr (++p, '"'); - } - else { - e = p; - while (*e && !isspace (*e)) - e++; - } - if (e > p) - return strndup (p, e-p); - } - tag = p; - } - - return NULL; -} -#endif - static int parse_time (const char *str) { - float h, m, s; + int h, m, s; if (!str) return 0; @@ -129,8 +73,8 @@ else if (!strncmp (str, "smpte=", 6)) str += 6; - if (sscanf (str, "%f:%f:%f", &h, &m, &s ) == 3) - return (double)(h * 3600.0 + m * 60.0 + s) * 1000.0; + if (sscanf (str, "%02d:%02d:%02d", &h, &m, &s ) == 3) + return (double)(h * 3600 + m * 60 + s) * 1000.0; return strtod (str, NULL) * 1000.0; } @@ -168,10 +112,6 @@ if (tmp) line = tmp + 1; } - /* Ignore metainfo */ - tmp = strrchr (line, '?'); - if (tmp) - *tmp = '\0'; if (*line && playlist_insert (list, line, 0)) num++; } @@ -197,7 +137,6 @@ return num; } -#if USE_XML_PARSER static int asx_playlist_parse (FILE *fp, playlist_entry_t **list) { void *ptr; size_t size; @@ -265,65 +204,7 @@ return num; } -#else -static int asx_playlist_parse (FILE *fp, playlist_entry_t **list) { - char buf[4096]; - char *tag, *tmp; - int got_tag = 0; - int num = 0; - char *src = NULL; - int start = 0; - - while ((tag = get_tag (fp, buf, sizeof(buf)))) { - got_tag = 1; - if (!strncasecmp (tag, "entry", 5)) { - if (src) - free (src); - src = NULL; - start = 0; - } - else if (!strncasecmp (tag, "ref ", 4)) { - if (src) - free (src); - src = get_prop (tag+4, "href", 4) ? : get_prop (tag+4, "HREF", 4); - } - else if (!strncasecmp (tag, "starttime ", 10)) { - tmp = get_prop (tag+10, "value", 5) ? : get_prop (tag+10, "VALUE", 5); - if (tmp) { - start = parse_time (tmp); - free (tmp); - } - } - else if (!strncasecmp (tag, "/entry", 6)) { - if (src) { - if (playlist_insert (list, src, start)) - num++; - free (src); - src = NULL; - start = 0; - } - } - } - - if (!got_tag) { - /* No tags found? Might be a references list. */ - rewind (fp); - while ((src = get_line (fp, buf, sizeof(buf)))) { - if (!strncmp (src, "Ref", 3)) { - src = strchr (src+3, '='); - if (src && *(src+1)) { - if (playlist_insert (list, src+1, 0)) - num++; - } - } - } - } - return num; -} -#endif - -#if USE_XML_PARSER static int smil_playlist_parse (FILE *fp, playlist_entry_t **list) { void *ptr; size_t size; @@ -384,43 +265,61 @@ return num; } -#else -static int smil_playlist_parse (FILE *fp, playlist_entry_t **list) { - char buf[4096]; - char *tag, *src, *tmp; - int got_tag = 0; - int num = 0; - - while ((tag = get_tag (fp, buf, sizeof(buf)))) { - got_tag = 1; - if (!strncmp (tag, "audio ", 6) || !strncmp (tag, "video ", 6)) { - src = get_prop (tag+6, "src", 3); - if (src) { - int start = 0; - - tmp = get_prop (tag+6, "clipBegin", 9) ? : - get_prop (tag+6, "clip-begin", 10); - if (tmp) { - start = parse_time (tmp); - free (tmp); + +static int xspf_playlist_parse (FILE *fp, playlist_entry_t **list) { + void *ptr; + size_t size; + xml_node_t *root, *node, *tmp; + int num = 0; + + fseek (fp, 0, SEEK_END); + size = ftell (fp); + fseek (fp, 0, SEEK_SET); + + ptr = mmap (NULL, size, PROT_READ, MAP_SHARED, fileno(fp), 0); + if (ptr == MAP_FAILED) { + perror ("mmap() failed"); + return 0; + } + + xml_parser_init (ptr, size, XML_PARSER_CASE_SENSITIVE); + + if (xml_parser_build_tree (&root) >= 0) { + for (node = root; node; node = node->next) { + if (!strcmp (node->name, "playlist")) + break; + } + if (node) { + for (node = node->child; node; node = node->next) { + if (!strcmp (node->name, "trackList")) + break; + } + } + if (node) { + for (node = node->child; node; node = node->next) { + if (!strcmp (node->name, "track")) { + char *src = NULL; + + for (tmp = node->child; tmp; tmp = tmp->next) { + if (!strcmp (tmp->name, "location")) { + src = tmp->data; + break; + } + } + + if (src && playlist_insert (list, trim(src), 0)) + num++; } - - if (playlist_insert (list, src, start)) - num++; - free (src); } } + + xml_parser_free_tree (root); } - if (!got_tag) { - /* No tags found? Might be a RAM playlist. */ - rewind (fp); - num = ram_playlist_parse (fp, list); - } - + munmap (ptr, size); + return num; } -#endif /******************************************************************************/ @@ -446,6 +345,8 @@ return XINE_PLT_ASX; if (!strcmp (tmp, "smil")) return XINE_PLT_SMI; + if (!strcmp (tmp, "xspf+xml")) + return XINE_PLT_XSPF; } if (filename) { @@ -465,6 +366,8 @@ if (!strcasecmp (tmp, ".smi") || !strcasecmp (tmp, ".smil")) return XINE_PLT_SMI; + if (!strcasecmp (tmp, ".xspf")) + return XINE_PLT_XSPF; } } @@ -495,6 +398,9 @@ case XINE_PLT_SMI: num = smil_playlist_parse (fp, list); break; + case XINE_PLT_XSPF: + num = xspf_playlist_parse (fp, list); + break; default: break; } Index: playlist.h =================================================================== RCS file: /cvsroot/xine/xine-plugin/src/playlist.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- playlist.h 19 Jan 2007 14:30:22 -0000 1.6 +++ playlist.h 22 Jan 2007 18:32:59 -0000 1.7 @@ -116,6 +116,7 @@ XINE_PLT_PLS, XINE_PLT_ASX, XINE_PLT_SMI, + XINE_PLT_XSPF, }; /* Detect playlist file type. */ Index: plugin.c =================================================================== RCS file: /cvsroot/xine/xine-plugin/src/plugin.c,v retrieving revision 1.67 retrieving revision 1.68 diff -u -r1.67 -r1.68 --- plugin.c 22 Jan 2007 17:52:54 -0000 1.67 +++ plugin.c 22 Jan 2007 18:32:59 -0000 1.68 @@ -1231,6 +1231,7 @@ #define BUILTIN_MIMETYPES "audio/x-scpls: pls: Winamp playlist;" \ "application/smil: smi, smil: SMIL playlist;" \ + "application/xspf+xml: xspf: XSPF playlist;" \ "application/x-xine-plugin: : Xine plugin" /* Called only once after installation. */ |