summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorOliver Freyermuth <o.freyermuth@googlemail.com>2014-12-31 01:57:26 +0100
committerwm4 <wm4@nowhere>2015-01-06 19:52:27 +0100
commit0c42484d8e7b064b69d92f209cf2cb082f756b97 (patch)
tree0dba89225011c1ea010931dfafc10102fa1e9f56 /stream
parentbef1893cd586f590bdc237c3b3c732c69d7479f8 (diff)
downloadmpv-0c42484d8e7b064b69d92f209cf2cb082f756b97.tar.bz2
mpv-0c42484d8e7b064b69d92f209cf2cb082f756b97.tar.xz
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.
Diffstat (limited to 'stream')
-rw-r--r--stream/stream_dvb.c104
1 files 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;
}