summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrim <rozhuk.im@gmail.com>2017-12-15 15:37:30 +0300
committerKevin Mitchell <kevmitch@gmail.com>2017-12-16 23:24:55 -0800
commit04d04033e66934b9799d52c80515908e29daa2dc (patch)
treec00ea5b71cb7a063630b74a419a7b9df70e9ebaa
parent3c4667c862dba05d89d0fd24a198bb49c8c47cb8 (diff)
downloadmpv-04d04033e66934b9799d52c80515908e29daa2dc.tar.bz2
mpv-04d04033e66934b9799d52c80515908e29daa2dc.tar.xz
dvb: Add multiple frontends support: MAX_FRONTENDS now 8.
-rw-r--r--stream/dvb_tune.c25
-rw-r--r--stream/dvb_tune.h3
-rw-r--r--stream/dvbin.h9
-rw-r--r--stream/stream_dvb.c150
4 files changed, 99 insertions, 88 deletions
diff --git a/stream/dvb_tune.c b/stream/dvb_tune.c
index 7c24af104e..d9b350f876 100644
--- a/stream/dvb_tune.c
+++ b/stream/dvb_tune.c
@@ -1,7 +1,7 @@
/* dvbtune - tune.c
Copyright (C) Dave Chapman 2001,2002
- Copyright (C) Rozhuk Ivan <rozhuk.im@gmail.com> 2016
+ Copyright (C) Rozhuk Ivan <rozhuk.im@gmail.com> 2016 - 2017
Modified for use with MPlayer, for details see the changelog at
http://svn.mplayerhq.hu/mplayer/trunk/
@@ -82,7 +82,7 @@ unsigned int dvb_get_tuner_delsys_mask(int fe_fd, struct mp_log *log)
#ifdef DVB_USE_S2API
/* S2API is the DVB API new since 2.6.28.
It allows to query frontends with multiple delivery systems. */
- mp_verbose(log, "Querying tuner type via DVBv5 API for frontend FD %d\n",
+ mp_verbose(log, "Querying tuner frontend type via DVBv5 API for frontend FD %d\n",
fe_fd);
prop[0].cmd = DTV_ENUM_DELSYS;
if (ioctl(fe_fd, FE_GET_PROPERTY, &cmdseq) < 0) {
@@ -98,14 +98,14 @@ unsigned int dvb_get_tuner_delsys_mask(int fe_fd, struct mp_log *log)
for (i = 0; i < delsys_count; i++) {
delsys = (unsigned int)prop[0].u.buffer.data[i];
DELSYS_SET(ret_mask, delsys);
- mp_verbose(log, "DVBv5: Tuner type seems to be %s\n", get_dvb_delsys(delsys));
+ mp_verbose(log, "DVBv5: Tuner frontend type seems to be %s\n", get_dvb_delsys(delsys));
}
return ret_mask;
old_api:
#endif
- mp_verbose(log, "Querying tuner type via pre-DVBv5 API for frontend FD %d\n",
+ mp_verbose(log, "Querying tuner frontend type via pre-DVBv5 API for frontend FD %d\n",
fe_fd);
memset(&fe_info, 0x00, sizeof(struct dvb_frontend_info));
@@ -119,7 +119,7 @@ old_api:
prop[0].u.data = 0x0300; /* Fail, assume 3.0 */
}
- mp_verbose(log, "DVBv3: Queried tuner type of device named '%s', FD: %d\n",
+ mp_verbose(log, "DVBv3: Queried tuner frontend type of device named '%s', FD: %d\n",
fe_info.name, fe_fd);
switch (fe_info.type) {
case FE_OFDM:
@@ -158,29 +158,30 @@ old_api:
break;
#endif
default:
- mp_err(log, "DVBv3: Unknown tuner type: %d\n", fe_info.type);
+ mp_err(log, "DVBv3: Unknown tuner frontend type: %d\n", fe_info.type);
return ret_mask;
}
for (delsys = 0; delsys < SYS_DVB__COUNT__; delsys ++) {
if (!DELSYS_IS_SET(ret_mask, delsys))
continue; /* Skip unsupported. */
- mp_verbose(log, "DVBv3: Tuner type seems to be %s\n", get_dvb_delsys(delsys));
+ mp_verbose(log, "DVBv3: Tuner frontend type seems to be %s\n", get_dvb_delsys(delsys));
}
return ret_mask;
}
-int dvb_open_devices(dvb_priv_t *priv, unsigned int n, unsigned int demux_cnt)
+int dvb_open_devices(dvb_priv_t *priv, unsigned int adapter,
+ unsigned int frontend, unsigned int demux_cnt)
{
unsigned int i;
char frontend_dev[PATH_MAX], dvr_dev[PATH_MAX], demux_dev[PATH_MAX];
-
dvb_state_t* state = priv->state;
- snprintf(frontend_dev, sizeof(frontend_dev), "/dev/dvb/adapter%u/frontend0", n);
- snprintf(dvr_dev, sizeof(dvr_dev), "/dev/dvb/adapter%u/dvr0", n);
- snprintf(demux_dev, sizeof(demux_dev), "/dev/dvb/adapter%u/demux0", n);
+ snprintf(frontend_dev, sizeof(frontend_dev), "/dev/dvb/adapter%u/frontend%u", adapter, frontend);
+ snprintf(dvr_dev, sizeof(dvr_dev), "/dev/dvb/adapter%u/dvr0", adapter);
+ snprintf(demux_dev, sizeof(demux_dev), "/dev/dvb/adapter%u/demux0", adapter);
+ MP_VERBOSE(priv, "DVB_OPEN_DEVICES: frontend: %s\n", frontend_dev);
state->fe_fd = open(frontend_dev, O_RDWR | O_NONBLOCK | O_CLOEXEC);
if (state->fe_fd < 0) {
MP_ERR(priv, "ERROR OPENING FRONTEND DEVICE %s: ERRNO %d\n",
diff --git a/stream/dvb_tune.h b/stream/dvb_tune.h
index 756f730008..d7a790171f 100644
--- a/stream/dvb_tune.h
+++ b/stream/dvb_tune.h
@@ -26,7 +26,8 @@ struct mp_log;
const char *get_dvb_delsys(unsigned int delsys);
unsigned int dvb_get_tuner_delsys_mask(int fe_fd, struct mp_log *log);
-int dvb_open_devices(dvb_priv_t *priv, unsigned int n, unsigned int demux_cnt);
+int dvb_open_devices(dvb_priv_t *priv, unsigned int adapter,
+ unsigned int frontend, unsigned int demux_cnt);
int dvb_fix_demuxes(dvb_priv_t *priv, unsigned int cnt);
int dvb_set_ts_filt(dvb_priv_t *priv, int fd, uint16_t pid, dmx_pes_type_t pestype);
int dvb_get_pmt_pid(dvb_priv_t *priv, int card, int service_id);
diff --git a/stream/dvbin.h b/stream/dvbin.h
index 284ccbd450..01a70588a5 100644
--- a/stream/dvbin.h
+++ b/stream/dvbin.h
@@ -26,6 +26,9 @@
#include <linux/dvb/audio.h>
#include <linux/dvb/version.h>
+#define MAX_ADAPTERS 16
+#define MAX_FRONTENDS 8
+
#undef DVB_ATSC
#if defined(DVB_API_VERSION_MINOR)
@@ -69,7 +72,8 @@ typedef struct {
unsigned int freq, srate, diseqc;
char pol;
unsigned int tpid, dpid1, dpid2, progid, ca, pids[DMX_FILTER_SIZE], pids_cnt;
- bool is_dvb_x2;
+ bool is_dvb_x2; /* Used only in dvb_get_channels() and parse_vdr_par_string(), use delsys. */
+ unsigned int frontend;
unsigned int delsys;
unsigned int stream_id;
unsigned int service_id;
@@ -90,7 +94,7 @@ typedef struct {
typedef struct {
int devno;
- unsigned int delsys_mask;
+ unsigned int delsys_mask[MAX_FRONTENDS];
dvb_channels_list_t *list;
} dvb_adapter_config_t;
@@ -98,6 +102,7 @@ typedef struct {
unsigned int adapters_count;
dvb_adapter_config_t *adapters;
unsigned int cur_adapter;
+ unsigned int cur_frontend;
int fe_fd;
int dvr_fd;
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c
index c53753ad31..02c5878ca9 100644
--- a/stream/stream_dvb.c
+++ b/stream/stream_dvb.c
@@ -2,7 +2,7 @@
dvbstream
(C) Dave Chapman <dave@dchapman.com> 2001, 2002.
- (C) Rozhuk Ivan <rozhuk.im@gmail.com> 2016
+ (C) Rozhuk Ivan <rozhuk.im@gmail.com> 2016 - 2017
Original authors: Nico, probably Arpi
@@ -62,7 +62,6 @@
#error GPL only
#endif
-#define MAX_ADAPTERS 16
#define CHANNEL_LINE_LEN 256
#define min(a, b) ((a) <= (b) ? (a) : (b))
@@ -253,6 +252,7 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log,
dvb_channels_list_t *list_add,
int cfg_full_transponder,
char *filename,
+ unsigned int frontend,
int delsys, unsigned int delsys_mask)
{
dvb_channels_list_t *list = list_add;
@@ -331,6 +331,7 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log,
ptr->freq = 0;
ptr->service_id = -1;
ptr->is_dvb_x2 = false;
+ ptr->frontend = frontend;
ptr->delsys = delsys;
ptr->diseqc = 0;
ptr->stream_id = NO_STREAM_ID_FILTER;
@@ -791,9 +792,10 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n)
state->retry = 0;
//empty both the stream's and driver's buffer
while (dvb_streaming_read(stream, buf, sizeof(buf)) > 0) {}
- if (state->cur_adapter != adapter) {
+ if (state->cur_adapter != adapter ||
+ state->cur_frontend != channel->frontend) {
dvbin_close(stream);
- if (!dvb_open_devices(priv, devno, channel->pids_cnt)) {
+ if (!dvb_open_devices(priv, devno, channel->frontend, channel->pids_cnt)) {
MP_ERR(stream, "DVB_SET_CHANNEL, COULDN'T OPEN DEVICES OF "
"ADAPTER: %d, EXIT\n", devno);
return 0;
@@ -805,14 +807,13 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n)
return 0;
}
} else {
- if (!dvb_open_devices(priv, devno, channel->pids_cnt)) {
+ if (!dvb_open_devices(priv, devno, channel->frontend, channel->pids_cnt)) {
MP_ERR(stream, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF "
"ADAPTER: %d, EXIT\n", devno);
return 0;
}
}
- state->cur_adapter = adapter;
state->retry = 5;
new_list->current = n;
MP_VERBOSE(stream, "DVB_SET_CHANNEL: new channel name=%s, adapter: %d, "
@@ -830,8 +831,10 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n)
return 0;
}
- state->last_freq = channel->freq;
state->is_on = 1;
+ state->last_freq = channel->freq;
+ state->cur_adapter = adapter;
+ state->cur_frontend = channel->frontend;
if (channel->service_id != -1) {
/* We need the PMT-PID in addition.
@@ -994,6 +997,8 @@ void dvbin_close(stream_t *stream)
state->fe_fd = state->dvr_fd = -1;
state->is_on = 0;
+ state->cur_adapter = -1;
+ state->cur_frontend = -1;
pthread_mutex_lock(&global_dvb_state_lock);
dvb_free_state(state);
@@ -1044,8 +1049,6 @@ static int dvb_streaming_start(stream_t *stream, char *progname)
}
-
-
static int dvb_open(stream_t *stream)
{
// I don't force the file format because, although it's almost always TS,
@@ -1081,6 +1084,7 @@ static int dvb_open(stream_t *stream)
// The following setup only has to be done once.
state->cur_adapter = -1;
+ state->cur_frontend = -1;
for (i = 0; i < state->adapters_count; i++) {
if (state->adapters[i].devno == priv->cfg_devno) {
state->cur_adapter = i;
@@ -1133,7 +1137,7 @@ dvb_state_t *dvb_get_state(stream_t *stream)
struct mp_log *log = stream->log;
struct mpv_global *global = stream->global;
dvb_priv_t *priv = stream->priv;
- unsigned int delsys, delsys_mask, size;
+ unsigned int delsys, delsys_mask[MAX_FRONTENDS], size;
char filename[PATH_MAX], *conf_file;
const char *conf_file_name;
void *talloc_ctx;
@@ -1169,75 +1173,74 @@ dvb_state_t *dvb_get_state(stream_t *stream)
state->switching_channel = false;
state->stream_used = true;
state->fe_fd = state->dvr_fd = -1;
- for (int i = 0; i < MAX_ADAPTERS; i++) {
- snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend0", i);
- int fd = open(filename, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
- if (fd < 0) {
- mp_verbose(log, "DVB_CONFIG, can't open device %s, skipping\n",
- filename);
- continue;
- }
-
- mp_verbose(log, "Opened device %s, FD: %d\n", filename, fd);
- delsys_mask = dvb_get_tuner_delsys_mask(fd, log);
- delsys_mask &= DELSYS_SUPP_MASK; /* Filter unsupported delivery systems. */
- close(fd);
- if (delsys_mask == 0) {
- mp_verbose(log, "Frontend device %s has no supported delivery systems.\n",
- filename);
- continue; /* Skip tuner. */
- }
- mp_verbose(log, "Frontend device %s offers some supported delivery systems.\n",
- filename);
- /* Create channel list for adapter. */
+ for (unsigned int i = 0; i < MAX_ADAPTERS; i++) {
list = NULL;
- for (delsys = 0; delsys < SYS_DVB__COUNT__; delsys++) {
- if (!DELSYS_IS_SET(delsys_mask, delsys))
- continue; /* Skip unsupported. */
-
- switch (delsys) {
- case SYS_DVBC_ANNEX_A:
- case SYS_DVBC_ANNEX_C:
- conf_file_name = "channels.conf.cbl";
- break;
- case SYS_ATSC:
- conf_file_name = "channels.conf.atsc";
- break;
- case SYS_DVBT:
- if (DELSYS_IS_SET(delsys_mask, SYS_DVBT2))
- continue; /* Add all channels later with T2. */
- /* PASSTOUTH */
- case SYS_DVBT2:
- conf_file_name = "channels.conf.ter";
- break;
- case SYS_DVBS:
- if (DELSYS_IS_SET(delsys_mask, SYS_DVBS2))
- continue; /* Add all channels later with S2. */
- /* PASSTOUTH */
- case SYS_DVBS2:
- conf_file_name = "channels.conf.sat";
- break;
- default:
+ for (unsigned int f = 0; f < MAX_FRONTENDS; f++) {
+ snprintf(filename, sizeof(filename), "/dev/dvb/adapter%u/frontend%u", i, f);
+ int fd = open(filename, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fd < 0)
continue;
+
+ mp_verbose(log, "Opened device %s, FD: %d\n", filename, fd);
+ delsys_mask[f] = dvb_get_tuner_delsys_mask(fd, log);
+ delsys_mask[f] &= DELSYS_SUPP_MASK; /* Filter unsupported delivery systems. */
+ close(fd);
+ if (delsys_mask[f] == 0) {
+ mp_verbose(log, "Frontend device %s has no supported delivery systems.\n",
+ filename);
+ continue; /* Skip tuner. */
}
+ mp_verbose(log, "Frontend device %s offers some supported delivery systems.\n",
+ filename);
+ /* Create channel list for adapter. */
+ for (delsys = 0; delsys < SYS_DVB__COUNT__; delsys++) {
+ if (!DELSYS_IS_SET(delsys_mask[f], delsys))
+ continue; /* Skip unsupported. */
+
+ switch (delsys) {
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_C:
+ conf_file_name = "channels.conf.cbl";
+ break;
+ case SYS_ATSC:
+ conf_file_name = "channels.conf.atsc";
+ break;
+ case SYS_DVBT:
+ if (DELSYS_IS_SET(delsys_mask[f], SYS_DVBT2))
+ continue; /* Add all channels later with T2. */
+ /* PASSTOUTH */
+ case SYS_DVBT2:
+ conf_file_name = "channels.conf.ter";
+ break;
+ case SYS_DVBS:
+ if (DELSYS_IS_SET(delsys_mask[f], SYS_DVBS2))
+ continue; /* Add all channels later with S2. */
+ /* PASSTOUTH */
+ case SYS_DVBS2:
+ conf_file_name = "channels.conf.sat";
+ break;
+ default:
+ continue;
+ }
- if (priv->cfg_file && priv->cfg_file[0]) {
- talloc_ctx = NULL;
- conf_file = priv->cfg_file;
- } else {
- talloc_ctx = talloc_new(NULL);
- conf_file = mp_find_config_file(talloc_ctx, global, conf_file_name);
- if (conf_file) {
- mp_verbose(log, "Ignoring other channels.conf files.\n");
+ if (priv->cfg_file && priv->cfg_file[0]) {
+ talloc_ctx = NULL;
+ conf_file = priv->cfg_file;
} else {
- conf_file = mp_find_config_file(talloc_ctx, global,
- "channels.conf");
+ talloc_ctx = talloc_new(NULL);
+ conf_file = mp_find_config_file(talloc_ctx, global, conf_file_name);
+ if (conf_file) {
+ mp_verbose(log, "Ignoring other channels.conf files.\n");
+ } else {
+ conf_file = mp_find_config_file(talloc_ctx, global,
+ "channels.conf");
+ }
}
- }
- list = dvb_get_channels(log, list, priv->cfg_full_transponder, conf_file,
- delsys, delsys_mask);
- talloc_free(talloc_ctx);
+ list = dvb_get_channels(log, list, priv->cfg_full_transponder,
+ conf_file, f, delsys, delsys_mask[f]);
+ talloc_free(talloc_ctx);
+ }
}
/* Add adapter with non zero channel list. */
if (list == NULL)
@@ -1256,7 +1259,8 @@ dvb_state_t *dvb_get_state(stream_t *stream)
state->adapters = adapters;
state->adapters[state->adapters_count].devno = i;
- state->adapters[state->adapters_count].delsys_mask = delsys_mask;
+ memcpy(&state->adapters[state->adapters_count].delsys_mask,
+ &delsys_mask, (sizeof(unsigned int) * MAX_FRONTENDS));
state->adapters[state->adapters_count].list = list;
state->adapters_count++;
}