From 0c42484d8e7b064b69d92f209cf2cb082f756b97 Mon Sep 17 00:00:00 2001 From: Oliver Freyermuth Date: Wed, 31 Dec 2014 01:57:26 +0100 Subject: stream_dvb: Very basic vdr-type channels.conf support. Still incomplete. Initialize is_dvb_s2 boolean in channel-struct. We first check whether the channels.conf-line at hand is sscanf'able with a vdr-style pattern. If yes, we assume it is a vdr-channel-config (we check whether sscanf consumed the full line). The vdr-style config also contains a parameter-string which contains information about polarization + delivery type (e.g. DVB-S2). With this change, S2-tuning works with a VDR-channel list. Missing (later commits): - vdr-parameter-string also contains other information, e.g. invert-flag, needs to be parsed. - Diseqc-lnb-number is not present in VDR-config (I believe it is handled via the location-parameter + lnb-config there). For backwards compatibility, the location-parameter can be the lnb-number - we should test whether it is an int and assume this in this case. - VID, AID and TID-lists are extremely ugly in their syntax for VDR. At the moment, only the first number is parsed (and TID fully ignored), needs to be fixed. --- stream/stream_dvb.c | 104 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index d754e6994b..d20d8463fd 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -88,6 +88,35 @@ const struct m_sub_options stream_dvb_conf = { }, }; +static void parse_vdr_par_string(const char* vdr_par_str, dvb_channel_t* ptr) { + if (vdr_par_str[0]) { + const char* vdr_par = &vdr_par_str[0]; + while (vdr_par && *vdr_par) { + switch (mp_toupper(*vdr_par)) { + case 'H': + ptr->pol = 'H'; + vdr_par++; + break; + case 'V': + ptr->pol = 'V'; + vdr_par++; + break; + case 'S': + vdr_par++; + if (*vdr_par == '1') { + ptr->is_dvb_s2 = true; + } else { + ptr->is_dvb_s2 = false; + } + vdr_par++; + break; + default: + vdr_par++; + } + } + } +} + static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, int type) { dvb_channels_list *list; @@ -100,12 +129,14 @@ static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, i int fields, cnt, pcnt, k; int has8192, has0; dvb_channel_t *ptr, *tmp, chn; - char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256], transm[256], gi[256], vpid_str[256], apid_str[256]; + char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256], transm[256], gi[256], vpid_str[256], apid_str[256], vdr_par_str[256]; const char *cbl_conf = "%d:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n"; const char *sat_conf = "%d:%c:%d:%d:%255[^:]:%255[^:]\n"; const char *ter_conf = "%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n"; const char *atsc_conf = "%d:%255[^:]:%255[^:]:%255[^:]\n"; + const char *vdr_conf = "%d:%255[^:]:%*255[^:]:%d:%255[^:]:%255[^:]:%*255[^:]:%*255[^:]:%*d:%*d:%*d:%*d\n%n"; + mp_verbose(log, "CONFIG_READ FILE: %s, type: %d\n", filename, type); if((f=fopen(filename, "r"))==NULL) { @@ -133,32 +164,58 @@ static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, i continue; colon = strchr(line, ':'); - if(colon) - { - k = colon - line; - if(!k) - continue; - ptr->name = malloc(k+1); - if(! ptr->name) - continue; - av_strlcpy(ptr->name, line, k+1); + if (colon) { + k = colon - line; + if(!k) + continue; + // In some modern VDR-style configs, channel name also has bouquet after ;. + // Parse that off, we ignore it. + char* bouquet_sep = strchr(line, ';'); + int channel_name_length = k; + if (bouquet_sep && bouquet_sep < colon) { + channel_name_length = bouquet_sep - line; + } + ptr->name = malloc(channel_name_length+1); + if(! ptr->name) + continue; + av_strlcpy(ptr->name, line, channel_name_length+1); + } else { + continue; } - else - continue; k++; - apid_str[0] = vpid_str[0] = 0; + vpid_str[0] = apid_str[0] = vdr_par_str[0] = 0; ptr->pids_cnt = 0; ptr->freq = 0; - if(type == TUNER_TER) - { + ptr->is_dvb_s2 = false; + + // Check if VDR-type channels.conf-line - then full line is consumed by the scan. + int num_chars = 0; + fields = sscanf(&line[k], vdr_conf, + &ptr->freq, vdr_par_str, &ptr->srate, vpid_str, apid_str, &num_chars); + + if (num_chars == strlen(&line[k])) { + // It's a VDR-style config line. + parse_vdr_par_string(vdr_par_str, ptr); + // We still need the special SAT-handling here. + if (type != TUNER_TER && type != TUNER_CBL && type != TUNER_ATSC) { + ptr->freq *= 1000UL; + ptr->srate *= 1000UL; + ptr->tone = -1; + ptr->inv = INVERSION_AUTO; + ptr->cr = FEC_AUTO; + mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d, POL: %c, S2: %s", + list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->is_dvb_s2 ? "yes" : "no"); + } else { + mp_verbose(log, "VDR, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d", + list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate); + } + } else if (type == TUNER_TER) { fields = sscanf(&line[k], ter_conf, &ptr->freq, inv, bw, cr, tmp_lcr, mod, transm, gi, tmp_hier, vpid_str, apid_str); mp_verbose(log, "TER, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq); - } - else if(type == TUNER_CBL) - { + } else if (type == TUNER_CBL) { fields = sscanf(&line[k], cbl_conf, &ptr->freq, inv, &ptr->srate, cr, mod, vpid_str, apid_str); @@ -166,7 +223,7 @@ static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, i list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate); } #ifdef DVB_ATSC - else if(type == TUNER_ATSC) + else if (type == TUNER_ATSC) { fields = sscanf(&line[k], atsc_conf, &ptr->freq, mod, vpid_str, apid_str); @@ -177,7 +234,7 @@ static dvb_channels_list *dvb_get_channels(struct mp_log *log, char *filename, i else //SATELLITE { fields = sscanf(&line[k], sat_conf, - &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, vpid_str, apid_str); + &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, vpid_str, apid_str); ptr->pol = mp_toupper(ptr->pol); ptr->freq *= 1000UL; ptr->srate *= 1000UL; @@ -510,7 +567,7 @@ int dvb_set_channel(stream_t *stream, int card, int n) if(channel->freq != priv->last_freq) if (! dvb_tune(priv, channel->freq, channel->pol, channel->srate, channel->diseqc, channel->tone, - channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->cfg_timeout)) + channel->is_dvb_s2, channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->cfg_timeout)) return 0; priv->last_freq = channel->freq; @@ -519,10 +576,9 @@ int dvb_set_channel(stream_t *stream, int card, int n) //sets demux filters and restart the stream for(i = 0; i < channel->pids_cnt; i++) { - if(! dvb_set_ts_filt(priv,priv->demux_fds[i], channel->pids[i], DMX_PES_OTHER)) - return 0; + if (!dvb_set_ts_filt(priv,priv->demux_fds[i], channel->pids[i], DMX_PES_OTHER)) + return 0; } - return 1; } -- cgit v1.2.3