Move DVB MUX setup to a file of its own

Add support for standard linux DVB mux descriptor files
This commit is contained in:
Andreas Öman 2007-08-16 12:21:10 +00:00
parent ec85f10beb
commit 76430bf643
4 changed files with 311 additions and 71 deletions

View file

@ -6,7 +6,7 @@ SRCS += pvr.c pvr_rec.c
SRCS += epg.c epg_xmltv.c
SRCS += dvb.c dvb_support.c dvb_pmt.c dvb_dvr.c
SRCS += dvb.c dvb_support.c dvb_pmt.c dvb_dvr.c dvb_muxconfig.c
SRCS += iptv_input.c iptv_output.c

79
dvb.c
View file

@ -44,6 +44,7 @@
#include "dvb_support.h"
#include "dvb_pmt.h"
#include "dvb_dvr.h"
#include "dvb_muxconfig.h"
struct th_dvb_mux_list dvb_muxes;
struct th_dvb_adapter_list dvb_adapters_probing;
@ -57,8 +58,6 @@ static int dvb_tune_tdmi(th_dvb_mux_instance_t *tdmi, int maylog);
static void *dvb_monitor_thread(void *aux);
static void dvb_add_muxes(void);
static void tdmi_check_scan_status(th_dvb_mux_instance_t *tdmi);
static void dvb_start_initial_scan(th_dvb_mux_instance_t *tdmi);
@ -129,11 +128,17 @@ dvb_init(void)
dvb_add_adapter(path);
}
dvb_add_muxes();
dvb_mux_setup();
LIST_FOREACH(tda, &dvb_adapters_probing, tda_link) {
tdmi = LIST_FIRST(&tda->tda_muxes_configured);
dvb_start_initial_scan(tdmi);
if(tdmi == NULL) {
syslog(LOG_WARNING,
"No muxes configured on \"%s\" DVB adapter unused",
tda->tda_name);
} else {
dvb_start_initial_scan(tdmi);
}
}
}
@ -288,72 +293,6 @@ dvb_tune(th_dvb_adapter_t *tda, th_dvb_mux_t *tdm, int maylog)
static void
dvb_add_mux_instance(th_dvb_adapter_t *tda, th_dvb_mux_t *tdm)
{
th_dvb_mux_instance_t *tdmi;
tdmi = calloc(1, sizeof(th_dvb_mux_instance_t));
tdmi->tdmi_status = TDMI_CONFIGURED;
tdmi->tdmi_mux = tdm;
tdmi->tdmi_adapter = tda;
LIST_INSERT_HEAD(&tda->tda_muxes_configured, tdmi, tdmi_adapter_link);
LIST_INSERT_HEAD(&tdm->tdm_instances, tdmi, tdmi_mux_link);
}
static void
dvb_add_muxes(void)
{
th_dvb_mux_t *tdm;
th_dvb_adapter_t *tda;
config_entry_t *ce;
const char *s;
struct dvb_frontend_parameters *fe_param;
char buf[100];
TAILQ_FOREACH(ce, &config_list, ce_link) {
if(ce->ce_type == CFG_SUB && !strcasecmp("dvbmux", ce->ce_key)) {
if((s = config_get_str_sub(&ce->ce_sub, "name", NULL)) == NULL)
continue;
tdm = calloc(1, sizeof(th_dvb_mux_t));
fe_param = &tdm->tdm_fe_params;
fe_param->inversion = INVERSION_AUTO;
fe_param->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
fe_param->u.ofdm.code_rate_HP = FEC_2_3;
fe_param->u.ofdm.code_rate_LP = FEC_1_2;
fe_param->u.ofdm.constellation = QAM_64;
fe_param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
fe_param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
fe_param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
fe_param->frequency =
atoi(config_get_str_sub(&ce->ce_sub, "frequency", "0"));
tdm->tdm_name = strdup(s);
snprintf(buf, sizeof(buf), "DVB-T: %s (%.1f MHz)", s,
(float)fe_param->frequency / 1000000.0f);
tdm->tdm_title = strdup(buf);
LIST_INSERT_HEAD(&dvb_muxes, tdm, tdm_global_link);
LIST_FOREACH(tda, &dvb_adapters_probing, tda_link) {
dvb_add_mux_instance(tda, tdm);
}
}
}
}
static void
dvb_monitor_current_mux(th_dvb_adapter_t *tda)

277
dvb_muxconfig.c Normal file
View file

@ -0,0 +1,277 @@
/*
* TV headend - Code for configuring DVB muxes
* This code is based on code from linux dvb-apps
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <linux/dvb/frontend.h>
#include "tvhead.h"
#include "dvb.h"
#include "dvb_muxconfig.h"
static void
dvb_add_mux_instance(th_dvb_adapter_t *tda, th_dvb_mux_t *tdm)
{
th_dvb_mux_instance_t *tdmi;
tdmi = calloc(1, sizeof(th_dvb_mux_instance_t));
tdmi->tdmi_status = TDMI_CONFIGURED;
tdmi->tdmi_mux = tdm;
tdmi->tdmi_adapter = tda;
LIST_INSERT_HEAD(&tda->tda_muxes_configured, tdmi, tdmi_adapter_link);
LIST_INSERT_HEAD(&tdm->tdm_instances, tdmi, tdmi_mux_link);
}
static void
dvb_add_mux(struct dvb_frontend_parameters *fe_param, const char *name)
{
th_dvb_mux_t *tdm;
th_dvb_adapter_t *tda;
char buf[100];
tdm = calloc(1, sizeof(th_dvb_mux_t));
memcpy(&tdm->tdm_fe_params, fe_param,
sizeof(struct dvb_frontend_parameters));
if(name == NULL) {
snprintf(buf, sizeof(buf), "DVB-%d", fe_param->frequency);
tdm->tdm_name = strdup(buf);
snprintf(buf, sizeof(buf), "DVB-T: %.1f MHz",
(float)fe_param->frequency / 1000000.0f);
} else {
tdm->tdm_name = strdup(name);
snprintf(buf, sizeof(buf), "DVB-T: %.1f MHz (%s)",
(float)fe_param->frequency / 1000000.0f, name);
}
tdm->tdm_title = strdup(buf);
LIST_INSERT_HEAD(&dvb_muxes, tdm, tdm_global_link);
LIST_FOREACH(tda, &dvb_adapters_probing, tda_link) {
dvb_add_mux_instance(tda, tdm);
}
}
struct strtab {
const char *str;
int val;
};
static struct strtab fectab[] = {
{ "NONE", FEC_NONE },
{ "1/2", FEC_1_2 },
{ "2/3", FEC_2_3 },
{ "3/4", FEC_3_4 },
{ "4/5", FEC_4_5 },
{ "5/6", FEC_5_6 },
{ "6/7", FEC_6_7 },
{ "7/8", FEC_7_8 },
{ "8/9", FEC_8_9 },
{ "AUTO", FEC_AUTO }
};
static struct strtab qamtab[] = {
{ "QPSK", QPSK },
{ "QAM16", QAM_16 },
{ "QAM32", QAM_32 },
{ "QAM64", QAM_64 },
{ "QAM128", QAM_128 },
{ "QAM256", QAM_256 },
{ "AUTO", QAM_AUTO },
{ "8VSB", VSB_8 },
{ "16VSB", VSB_16 }
};
static struct strtab bwtab[] = {
{ "8MHz", BANDWIDTH_8_MHZ },
{ "7MHz", BANDWIDTH_7_MHZ },
{ "6MHz", BANDWIDTH_6_MHZ },
{ "AUTO", BANDWIDTH_AUTO }
};
static struct strtab modetab[] = {
{ "2k", TRANSMISSION_MODE_2K },
{ "8k", TRANSMISSION_MODE_8K },
{ "AUTO", TRANSMISSION_MODE_AUTO }
};
static struct strtab guardtab[] = {
{ "1/32", GUARD_INTERVAL_1_32 },
{ "1/16", GUARD_INTERVAL_1_16 },
{ "1/8", GUARD_INTERVAL_1_8 },
{ "1/4", GUARD_INTERVAL_1_4 },
{ "AUTO", GUARD_INTERVAL_AUTO },
};
static struct strtab hiertab[] = {
{ "NONE", HIERARCHY_NONE },
{ "1", HIERARCHY_1 },
{ "2", HIERARCHY_2 },
{ "4", HIERARCHY_4 },
{ "AUTO", HIERARCHY_AUTO }
};
static int
str2val0(const char *str, struct strtab tab[], int l)
{
int i;
for(i = 0; i < l; i++)
if(!strcasecmp(str, tab[i].str))
return tab[i].val;
return -1;
}
#define str2val(str, tab) str2val0(str, tab, sizeof(tab) / sizeof(tab[0]))
static void
dvb_t_config(const char *l)
{
unsigned long freq;
char bw[20], fec[20], fec2[20], qam[20], mode[20], guard[20], hier[20];
struct dvb_frontend_parameters f;
int r;
r = sscanf(l, "%lu %10s %10s %10s %10s %10s %10s %10s",
&freq, bw, fec, fec2, qam, mode, guard, hier);
if(r != 8)
return;
memset(&f, 0, sizeof(f));
f.inversion = INVERSION_AUTO;
f.frequency = freq;
f.u.ofdm.bandwidth = str2val(bw, bwtab);
f.u.ofdm.constellation = str2val(qam, qamtab);
f.u.ofdm.transmission_mode = str2val(mode, modetab);
f.u.ofdm.guard_interval = str2val(guard, guardtab);
f.u.ofdm.hierarchy_information = str2val(hier, hiertab);
r = str2val(fec, fectab);
f.u.ofdm.code_rate_HP = r == FEC_NONE ? FEC_AUTO : r;
r = str2val(fec2, fectab);
f.u.ofdm.code_rate_LP = r == FEC_NONE ? FEC_AUTO : r;
dvb_add_mux(&f, NULL);
}
static void
dvb_muxfile_add(const char *fname)
{
FILE *fp;
char line[200];
fp = fopen(fname, "r");
if(fp == NULL) {
syslog(LOG_ERR, "dvb: Unable to open file %s -- %s",
fname, strerror(errno));
}
while(!feof(fp)) {
memset(line, 0, sizeof(line));
if(fgets(line, sizeof(line) - 1, fp) == NULL)
break;
switch(line[0]) {
case '#':
break;
case 'T':
dvb_t_config(line + 1);
break;
default:
break;
}
}
}
static void
dvb_add_configured_muxes(void)
{
config_entry_t *ce;
const char *s;
struct dvb_frontend_parameters fe_param;
TAILQ_FOREACH(ce, &config_list, ce_link) {
if(ce->ce_type == CFG_SUB && !strcasecmp("dvbmux", ce->ce_key)) {
if((s = config_get_str_sub(&ce->ce_sub, "name", NULL)) == NULL)
continue;
fe_param.inversion = INVERSION_AUTO;
fe_param.u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
fe_param.u.ofdm.code_rate_HP = FEC_2_3;
fe_param.u.ofdm.code_rate_LP = FEC_1_2;
fe_param.u.ofdm.constellation = QAM_64;
fe_param.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
fe_param.u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
fe_param.u.ofdm.hierarchy_information = HIERARCHY_NONE;
fe_param.frequency =
atoi(config_get_str_sub(&ce->ce_sub, "frequency", "0"));
dvb_add_mux(&fe_param, s);
}
}
}
void
dvb_mux_setup(void)
{
const char *s;
s = config_get_str("muxfile", NULL);
if(s != NULL)
dvb_muxfile_add(s);
dvb_add_configured_muxes();
}

24
dvb_muxconfig.h Normal file
View file

@ -0,0 +1,24 @@
/*
* TV headend - Code for configuring DVB muxes
* Copyright (C) 2007 Andreas Öman
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DVB_MUXCONFIG_H_
#define DVB_MUXCONFIG_H_
void dvb_mux_setup(void);
#endif /* DVB_MUXCONFIG_H */