From ef463aa1038eec1bf01216f87b1681fdf4973793 Mon Sep 17 00:00:00 2001 From: Oliver Freyermuth Date: Wed, 31 Dec 2014 03:27:33 +0100 Subject: [PATCH] stream_dvb: Extend token-list for pid-parsing, magically allows to parse VDR-style PID-lists. I also added a comment explaining the potentially occuring structures for future reference. For tokenization, a custom strtok_r implementation is used, inspired by strtok_r as implemented in musl and ffmpeg, hopefully slightly more readable (av_strtok_r is not available in libav, and strtok_r is not available everywhere). --- stream/stream_dvb.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index 13356c5cf2..7ebcd8fc1b 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -138,12 +138,42 @@ static void parse_vdr_par_string(const char* vdr_par_str, dvb_channel_t* ptr) { } } +static char* dvb_strtok_r(char* s, const char* sep, char** p) { + if (!s && !(s = *p)) { + return NULL; + } + + /* Skip leading separators. */ + s += strspn(s, sep); + + /* s points at first non-separator, or end of string. */ + if (!*s) { + return (*p = 0); + } + + /* Move *p to next separator. */ + *p = s + strcspn(s, sep); + if (**p) { + *(*p)++ = 0; + } else { + *p = 0; + } + return s; +} + static bool parse_pid_string(struct mp_log *log, char* pid_string, dvb_channel_t* ptr) { if (pid_string[0]) { int pcnt = 0; - const char* tokens = "+"; + /** These tokens also catch vdr-style PID lists. + * They can contain 123=deu@3,124=eng+jap@4;125 + * 3 and 4 are codes for codec type, =langLeft+langRight is allowed, + * and ; may separate a dolby channel. + * With the numChars-test and the full token-list, all is handled gracefully. + */ + const char* tokens = "+,;"; char* pidPart; - pidPart = strtok(pid_string, tokens); + char* savePtr; + pidPart = dvb_strtok_r(pid_string, tokens, &savePtr); while (pidPart != NULL) { if (ptr->pids_cnt >= DMX_FILTER_SIZE-1) { mp_verbose(log, "Maximum number of PIDs for one channel reached, ignoring further ones!\n"); @@ -156,7 +186,7 @@ static bool parse_pid_string(struct mp_log *log, char* pid_string, dvb_channel_t ptr->pids[ptr->pids_cnt] = pid; ptr->pids_cnt++; } - pidPart = strtok(NULL, tokens); + pidPart = dvb_strtok_r(NULL, tokens, &savePtr); } if (pcnt > 0) { return true;