[MPlayer-dev-eng] [PATCH] nsc playlist parser
Reimar Döffinger
Reimar.Doeffinger at stud.uni-karlsruhe.de
Tue Sep 6 18:48:46 CEST 2005
Hi,
I finally got around to implement the nsc decoder from
http://mplayerhq.hu/pipermail/mplayer-dev-eng/2005-January/032748.html
to a real playlist parser.
Unfortunately I have no working samples, so I have no idea if the thing
it extracts is the right one.
Please test and esp. provide samples.
Greetings,
Reimar Döffinger
-------------- next part --------------
Index: playtreeparser.c
===================================================================
RCS file: /cvsroot/mplayer/main/playtreeparser.c,v
retrieving revision 1.31
diff -u -r1.31 playtreeparser.c
--- playtreeparser.c 10 Sep 2004 20:53:22 -0000 1.31
+++ playtreeparser.c 6 Sep 2005 16:36:53 -0000
@@ -512,6 +512,116 @@
return entry;
}
+/**
+ * \brief decode the base64 used in nsc files
+ * \param in input string, 0-terminated
+ * \param buf output buffer, must point to memory suitable for realloc,
+ * will be NULL on failure.
+ * \return decoded length in bytes
+ */
+static int decode_nsc_base64(char *in, char **buf) {
+ int i, j, n;
+ if (in[0] != '0' || in[1] != '2')
+ goto err_out;
+ in += 2; // skip prefix
+ if (strlen(in) < 16) // error out if nothing to decode
+ goto err_out;
+ in += 12; // skip encoded string length
+ n = strlen(in) / 4;
+ *buf = realloc(*buf, n * 3);
+ for (i = 0; i < n; i++) {
+ uint8_t c[4];
+ for (j = 0; j < 4; j++) {
+ c[j] = in[4 * i + j];
+ if (c[j] >= '0' && c[j] <= '9') c[j] += 0 - '0';
+ else if (c[j] >= 'A' && c[j] <= 'Z') c[j] += 10 - 'A';
+ else if (c[j] >= 'a' && c[j] <= 'z') c[j] += 36 - 'a';
+ else if (c[j] == '{') c[j] = 62;
+ else if (c[j] == '}') c[j] = 63;
+ else goto err_out;
+ }
+ (*buf)[3 * i] = (c[0] << 2) | (c[1] >> 4);
+ (*buf)[3 * i + 1] = (c[1] << 4) | (c[2] >> 2);
+ (*buf)[3 * i + 2] = (c[2] << 6) | c[3];
+ }
+ return 3 * n;
+err_out:
+ if (*buf) free(*buf);
+ *buf = NULL;
+ return 0;
+}
+
+/**
+ * \brief "converts" utf16 to ascii by just discarding every second byte
+ * \param buf buffer to convert
+ * \param len lenght of buffer, must be > 0
+ */
+static void utf16_to_ascii(char *buf, int len) {
+ int i;
+ if (len <= 0) return;
+ for (i = 0; i < len / 2; i++)
+ buf[i] = buf[i * 2];
+ buf[i] = 0; // just in case
+}
+
+play_tree_t *parse_nsc(play_tree_parser_t* p) {
+ char *line, *addr = NULL, *url, *unicast_url = NULL;
+ int port = 0;
+ play_tree_t *entry = NULL;
+
+ mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying nsc playlist...\n");
+ while((line = play_tree_parser_get_line(p)) != NULL) {
+ strstrip(line);
+ if(!line[0]) // Ignore empties
+ continue;
+ if (strncasecmp(line,"[Address]", 9) == 0)
+ break; // nsc header found
+ else
+ return NULL;
+ }
+ mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected nsc playlist format\n");
+ play_tree_parser_stop_keeping(p);
+ while ((line = play_tree_parser_get_line(p)) != NULL) {
+ strstrip(line);
+ if (!line[0])
+ continue;
+ if (strncasecmp(line, "Unicast URL=", 12) == 0) {
+ int len = decode_nsc_base64(&line[12], &unicast_url);
+ if (len <= 0)
+ mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported Unicast URL encoding\n");
+ else
+ utf16_to_ascii(unicast_url, len);
+ } else if (strncasecmp(line, "IP Address=", 11) == 0) {
+ int len = decode_nsc_base64(&line[11], &addr);
+ if (len <= 0)
+ mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported IP Address encoding\n");
+ else
+ utf16_to_ascii(addr, len);
+ } else if (strncasecmp(line, "IP Port=", 8) == 0) {
+ port = strtol(&line[8], NULL, 0);
+ }
+ }
+
+#if 1
+ if (unicast_url) {
+ url = strdup(unicast_url);
+ } else
+#endif
+ if (addr && port) {
+ url = malloc(strlen(addr) + 7 + 20 + 1);
+ sprintf(url, "http://%s:%i", addr, port);
+ } else
+ goto out;
+
+ entry = play_tree_new();
+ play_tree_add_file(entry, url);
+ free(url);
+out:
+ if (addr) free(addr);
+ if (unicast_url) free(unicast_url);
+ return entry;
+}
+
play_tree_t*
embedded_playlist_parse(char *line) {
int f=DEMUXER_TYPE_PLAYLIST;
@@ -746,6 +856,10 @@
if(tree) break;
play_tree_parser_reset(p);
+ tree = parse_nsc(p);
+ if(tree) break;
+ play_tree_parser_reset(p);
+
// Here come the others formats ( textplain must stay the last one )
if (forced)
{
More information about the MPlayer-dev-eng
mailing list