1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-20 18:28:01 +00:00

playtreeparser.c: Add playlist parser for .nsc files

Tested to properly decode .nsc files, but not properly tested since
no publically available stream could be found.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32710 b3059339-0415-0410-9bf9-f77b7e298cf2

Remove pointless NULL checks before free.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32715 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
reimar 2010-12-12 19:25:43 +00:00 committed by Uoti Urpala
parent 597dc5a388
commit 937b086606

View File

@ -680,6 +680,116 @@ parse_textplain(play_tree_parser_t* p) {
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 {
mp_msg(MSGT_PLAYTREE, MSGL_ERR, "Invalid character %c (0x%02"PRIx8")\n", c[j], c[j]);
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:
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
}
static 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 (unicast_url)
url = strdup(unicast_url);
else 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:
free(addr);
free(unicast_url);
return entry;
}
play_tree_t*
parse_playtree(stream_t *stream, struct m_config *mconfig, int forced) {
play_tree_parser_t* p;
@ -840,6 +950,10 @@ play_tree_parser_get_play_tree(play_tree_parser_t* p, int forced) {
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)
{