summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Freyermuth <o.freyermuth@googlemail.com>2014-12-30 20:34:22 +0100
committerwm4 <wm4@nowhere>2015-01-06 19:52:27 +0100
commit3abf26f019fa780877b64be16d1b82c1311fab5c (patch)
treeb2fb8fd051eb9a48e3d63a2b42dba30663ef9931
parentae81cb43430090c4a08dbd9cc3a1d182c20e97e5 (diff)
downloadmpv-3abf26f019fa780877b64be16d1b82c1311fab5c.tar.bz2
mpv-3abf26f019fa780877b64be16d1b82c1311fab5c.tar.xz
dvb_tune: (DVB-S) Initial S2API support.
Also allows demuxers to buffer, and we explicitly discard stale QPSK events. Inspiration taken from the szap-s2 implementation. S2API is only used if available and for DVB-S cards - it might also be useful to have that for DVB-T2 / DVB-C2 tuning later, but I do not have the HW / no DVB-T2 broadcasting station nearby to test functionality. This should do no functional changes, only usage of the different API. The S2API is more extensible and a requirement for all the HD-deliveries (e.g. DVB-S2) and since 2.6.28 is the successor of the old API. Tuning to DVB-S2 channels actually already "works" like this if the delivery is hardcoded in - for a fully working implementation, the channels.conf.sat would need an additional field indicating the delivery type (VDR-type channels.conf have that). This commit also: - Cleans up some debug output. - Moves an unneeded usleep(100000) (only needed for diseqc switching for SAT) into the DVB-S-only part of the implementation.
-rw-r--r--stream/dvb_tune.c92
1 files changed, 79 insertions, 13 deletions
diff --git a/stream/dvb_tune.c b/stream/dvb_tune.c
index 056592bceb..3178dc3ab2 100644
--- a/stream/dvb_tune.c
+++ b/stream/dvb_tune.c
@@ -170,10 +170,16 @@ int dvb_set_ts_filt(dvb_priv_t *priv, int fd, uint16_t pid, dmx_pes_type_t pesty
pesFilterParams.pes_type = pestype;
pesFilterParams.flags = DMX_IMMEDIATE_START;
+ {
+ int buffersize = 64 * 1024;
+ if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0)
+ MP_ERR(priv, "ERROR IN DMX_SET_BUFFER_SIZE %i for fd %d: ERRNO: %d\n", pid, fd, errno);
+ }
+
errno = 0;
if ((i = ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams)) < 0)
{
- MP_ERR(priv, "ERROR IN SETTING DMX_FILTER %i for fd %d: ERRNO: %d", pid, fd, errno);
+ MP_ERR(priv, "ERROR IN SETTING DMX_FILTER %i for fd %d: ERRNO: %d\n", pid, fd, errno);
return 0;
}
@@ -326,7 +332,7 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec, unsigned int f
struct dvb_frontend_parameters feparams;
struct dvb_frontend_info fe_info;
- MP_VERBOSE(priv, "TUNE_IT, fd_frontend %d, fd_sec %d\nfreq %lu, srate %lu, pol %c, tone %i, specInv, diseqc %u, fe_modulation_t modulation,fe_code_rate_t HP_CodeRate, fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth\n",
+ MP_VERBOSE(priv, "TUNE_IT, fd_frontend %d, fd_sec %d\nfreq %lu, srate %lu, pol %c, tone %i, diseqc %u\n",
fd_frontend, fd_sec, (long unsigned int)freq, (long unsigned int)srate, pol, tone, diseqc);
@@ -339,6 +345,15 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec, unsigned int f
MP_VERBOSE(priv, "Using DVB card \"%s\"\n", fe_info.name);
+ {
+ /* discard stale QPSK events */
+ struct dvb_frontend_event ev;
+ while (true) {
+ if (ioctl(fd_frontend, FE_GET_EVENT, &ev) == -1)
+ break;
+ }
+ }
+
switch(fe_info.type)
{
case FE_OFDM:
@@ -353,8 +368,14 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec, unsigned int f
feparams.u.ofdm.guard_interval=guardInterval;
feparams.u.ofdm.hierarchy_information=hier;
MP_VERBOSE(priv, "tuning DVB-T to %d Hz, bandwidth: %d\n",freq, bandwidth);
+ if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
+ {
+ MP_ERR(priv, "ERROR tuning channel\n");
+ return -1;
+ }
break;
case FE_QPSK:
+ // DVB-S
if (freq > 2200000)
{
// this must be an absolute frequency
@@ -383,39 +404,84 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec, unsigned int f
MP_VERBOSE(priv, "tuning DVB-S to Freq: %u, Pol: %c Srate: %d, 22kHz: %s, LNB: %d\n",freq,pol,srate,hi_lo ? "on" : "off", diseqc);
if(do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0)
- MP_VERBOSE(priv, "DISEQC SETTING SUCCEDED\n");
+ MP_VERBOSE(priv, "DISEQC setting succeeded\n");
else
{
- MP_ERR(priv, "DISEQC SETTING FAILED\n");
+ MP_ERR(priv, "DISEQC setting failed\n");
return -1;
}
+ usleep(100000);
+
+#ifdef DVB_USE_S2API
+ /* S2API is the DVB API new since 2.6.28.
+ * It is needed to tune to new delivery systems, e.g. DVB-S2.
+ * It takes a struct with a list of pairs of command + parameter.
+ */
+
+ fe_delivery_system_t delsys = SYS_DVBS;
+ fe_rolloff_t rolloff = ROLLOFF_AUTO;
+ int stream_id = NO_STREAM_ID_FILTER;
+
+ struct dtv_property p[] = {
+ { .cmd = DTV_DELIVERY_SYSTEM, .u.data = delsys },
+ { .cmd = DTV_FREQUENCY, .u.data = freq },
+ { .cmd = DTV_MODULATION, .u.data = modulation },
+ { .cmd = DTV_SYMBOL_RATE, .u.data = srate },
+ { .cmd = DTV_INNER_FEC, .u.data = HP_CodeRate },
+ { .cmd = DTV_INVERSION, .u.data = specInv },
+ { .cmd = DTV_ROLLOFF, .u.data = rolloff },
+ { .cmd = DTV_PILOT, .u.data = PILOT_AUTO },
+ { .cmd = DTV_STREAM_ID, .u.data = stream_id },
+ { .cmd = DTV_TUNE },
+ };
+ struct dtv_properties cmdseq = {
+ .num = sizeof(p)/sizeof(p[0]),
+ .props = p
+ };
+ MP_VERBOSE(priv, "Tuning via S2API.\n");
+ if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq)) == -1)
+ {
+ MP_ERR(priv, "ERROR tuning channel\n");
+ return -1;
+ }
+#else
+ MP_VERBOSE(priv, "Tuning via DVB-API version 3.\n");
+ if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
+ {
+ MP_ERR(priv, "ERROR tuning channel\n");
+ return -1;
+ }
+#endif
break;
case FE_QAM:
- MP_VERBOSE(priv, "tuning DVB-C to %d, srate=%d\n",freq,srate);
feparams.frequency=freq;
feparams.inversion=specInv;
feparams.u.qam.symbol_rate = srate;
feparams.u.qam.fec_inner = HP_CodeRate;
feparams.u.qam.modulation = modulation;
+ MP_VERBOSE(priv, "tuning DVB-C to %d, srate=%d\n",freq,srate);
+ if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
+ {
+ MP_ERR(priv, "ERROR tuning channel\n");
+ return -1;
+ }
break;
#ifdef DVB_ATSC
case FE_ATSC:
- MP_VERBOSE(priv, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
feparams.frequency=freq;
feparams.u.vsb.modulation = modulation;
+ MP_VERBOSE(priv, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
+ if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
+ {
+ MP_ERR(priv, "ERROR tuning channel\n");
+ return -1;
+ }
break;
#endif
default:
MP_VERBOSE(priv, "Unknown FE type. Aborting\n");
return 0;
}
- usleep(100000);
-
- if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
- {
- MP_ERR(priv, "ERROR tuning channel\n");
- return -1;
- }
return check_status(priv, fd_frontend, timeout);
}