diff options
author | wm4 <wm4@nowhere> | 2017-02-14 13:30:59 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-02-14 13:31:06 +0100 |
commit | 05f63edc7bcede1c0e1b8580b3f973d09e774a08 (patch) | |
tree | 4bb937df91a5e65b1ebfb8368104447e5a159131 /stream/stream_dvb.c | |
parent | 3e474f4654236beec584d306cfb3e8563f677516 (diff) | |
download | mpv-05f63edc7bcede1c0e1b8580b3f973d09e774a08.tar.bz2 mpv-05f63edc7bcede1c0e1b8580b3f973d09e774a08.tar.xz |
Revert "dvb: add support for DVB-T2"
This reverts commit df91e492fd3365cf7db9c6ba4a721f8fcce0521c.
Multiple issues such as weird code with undefined behavior (like
(like conf_file*). The PR wasn't properly reviewed anyway (my error),
so this commit should be reviewed and then merged again.
Diffstat (limited to 'stream/stream_dvb.c')
-rw-r--r-- | stream/stream_dvb.c | 736 |
1 files changed, 344 insertions, 392 deletions
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index efa13d54ad..01ec6c2e77 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -2,7 +2,6 @@ dvbstream (C) Dave Chapman <dave@dchapman.com> 2001, 2002. - (C) Rozhuk Ivan <rozhuk.im@gmail.com> 2016 Original authors: Nico, probably Arpi @@ -58,35 +57,32 @@ #include "dvbin.h" #include "dvb_tune.h" -#define MAX_ADAPTERS 16 +#define MAX_CHANNELS 8 #define CHANNEL_LINE_LEN 256 #define min(a, b) ((a) <= (b) ? (a) : (b)) -#define OPT_BASE_STRUCT dvb_priv_t +#define OPT_BASE_STRUCT struct dvb_params -static dvb_state_t *global_dvb_state = NULL; +static dvb_state_t* global_dvb_state = NULL; static pthread_mutex_t global_dvb_state_lock = PTHREAD_MUTEX_INITIALIZER; const struct m_sub_options stream_dvb_conf = { .opts = (const m_option_t[]) { OPT_STRING("prog", cfg_prog, 0), - OPT_INTRANGE("card", cfg_devno, 0, 1, 4), + OPT_INTRANGE("card", cfg_card, 0, 1, 4), OPT_INTRANGE("timeout", cfg_timeout, 0, 1, 30), OPT_STRING("file", cfg_file, M_OPT_FILE), OPT_FLAG("full-transponder", cfg_full_transponder, 0), {0} }, - .size = sizeof(dvb_priv_t), - .defaults = &(const dvb_priv_t){ - .cfg_prog = NULL, - .cfg_devno = 0, + .size = sizeof(struct dvb_params), + .defaults = &(const struct dvb_params){ + .cfg_prog = "", + .cfg_card = 1, .cfg_timeout = 30, }, }; -void dvbin_close(stream_t *stream); - - static void parse_vdr_par_string(const char *vdr_par_str, dvb_channel_t *ptr) { //FIXME: There is more information in this parameter string, especially related @@ -106,9 +102,9 @@ static void parse_vdr_par_string(const char *vdr_par_str, dvb_channel_t *ptr) case 'S': vdr_par++; if (*vdr_par == '1') { - ptr->is_dvb_x2 = true; + ptr->is_dvb_s2 = true; } else { - ptr->is_dvb_x2 = false; + ptr->is_dvb_s2 = false; } vdr_par++; break; @@ -197,13 +193,12 @@ static bool parse_pid_string(struct mp_log *log, char *pid_string, return false; } -static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, - dvb_channels_list_t *list_add, +static dvb_channels_list *dvb_get_channels(struct mp_log *log, int cfg_full_transponder, char *filename, - int delsys, unsigned int delsys_mask) + int type) { - dvb_channels_list_t *list = list_add; + dvb_channels_list *list; FILE *f; char line[CHANNEL_LINE_LEN], *colon; @@ -226,24 +221,22 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, 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: %s\n", - filename, get_dvb_delsys(delsys)); + mp_verbose(log, "CONFIG_READ FILE: %s, type: %d\n", filename, type); if ((f = fopen(filename, "r")) == NULL) { mp_fatal(log, "CAN'T READ CONFIG FILE %s\n", filename); return NULL; } + list = malloc(sizeof(dvb_channels_list)); if (list == NULL) { - list = malloc(sizeof(dvb_channels_list_t)); - if (list == NULL) { - fclose(f); - mp_verbose(log, "DVB_GET_CHANNELS: couldn't malloc enough memory\n"); - return NULL; - } - memset(list, 0, sizeof(dvb_channels_list_t)); + fclose(f); + mp_verbose(log, "DVB_GET_CHANNELS: couldn't malloc enough memory\n"); + return NULL; } ptr = &chn; + list->NUM_CHANNELS = 0; + list->channels = NULL; while (!feof(f)) { if (fgets(line, CHANNEL_LINE_LEN, f) == NULL) continue; @@ -251,10 +244,6 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, if ((line[0] == '#') || (strlen(line) == 0)) continue; - memset(ptr, 0, sizeof(dvb_channel_t)); - vpid_str[0] = apid_str[0] = tpid_str[0] = 0; - vdr_loc_str[0] = vdr_par_str[0] = 0; - colon = strchr(line, ':'); if (colon) { k = colon - line; @@ -265,30 +254,23 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, 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)); + 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)); + av_strlcpy(ptr->name, line, channel_name_length + 1); } else { continue; } k++; + vpid_str[0] = apid_str[0] = tpid_str[0] = 0; + vdr_loc_str[0] = vdr_par_str[0] = 0; ptr->pids_cnt = 0; ptr->freq = 0; + ptr->is_dvb_s2 = false; ptr->service_id = -1; - ptr->is_dvb_x2 = false; - ptr->delsys = delsys; - ptr->diseqc = 0; ptr->stream_id = NO_STREAM_ID_FILTER; ptr->inv = INVERSION_AUTO; - ptr->bw = BANDWIDTH_AUTO; - ptr->cr = FEC_AUTO; - ptr->cr_lp = FEC_AUTO; - ptr->mod = QAM_AUTO; - ptr->hier = HIERARCHY_AUTO; - ptr->gi = GUARD_INTERVAL_AUTO; - ptr->trans = TRANSMISSION_MODE_AUTO; // Check if VDR-type channels.conf-line - then full line is consumed by the scan. int num_chars = 0; @@ -301,40 +283,12 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, // It's a VDR-style config line. parse_vdr_par_string(vdr_par_str, ptr); // We still need the special SAT-handling here. - switch (delsys) { - case SYS_DVBT: - case SYS_DVBT2: - /* Fix delsys value. */ - if (ptr->is_dvb_x2) { - ptr->delsys = delsys = SYS_DVBT2; - } else { - ptr->delsys = delsys = SYS_DVBT; - } - if (!DELSYS_IS_SET(delsys_mask, delsys)) - continue; /* Skip channel. */ - /* PASSTROUTH */ - case SYS_DVBC_ANNEX_A: - case SYS_DVBC_ANNEX_C: - case SYS_ATSC: - mp_verbose(log, "VDR, %s, NUM: %d, NUM_FIELDS: %d, NAME: %s, " - "FREQ: %d, SRATE: %d", - get_dvb_delsys(delsys), - list->NUM_CHANNELS, fields, - ptr->name, ptr->freq, ptr->srate); - break; - case SYS_DVBS: - case SYS_DVBS2: - /* Fix delsys value. */ - if (ptr->is_dvb_x2) { - ptr->delsys = delsys = SYS_DVBS2; - } else { - ptr->delsys = delsys = SYS_DVBS; - } - if (!DELSYS_IS_SET(delsys_mask, delsys)) - continue; /* Skip channel. */ - + 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; if (vdr_loc_str[0]) { // In older vdr config format, this field contained the DISEQc information. @@ -354,71 +308,58 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, } } - mp_verbose(log, "%s NUM: %d, NUM_FIELDS: %d, NAME: %s, " + mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, " "FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d, S2: %s, " - "StreamID: %d, SID: %d", - get_dvb_delsys(delsys), - list->NUM_CHANNELS, + "StreamID: %d, SID: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, - ptr->diseqc, (delsys == SYS_DVBS2) ? "yes" : "no", + ptr->diseqc, ptr->is_dvb_s2 ? "yes" : "no", ptr->stream_id, ptr->service_id); - break; - default: - break; + } 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 { - switch (delsys) { - case SYS_DVBT: - case SYS_DVBT2: - 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, "%s, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d", - get_dvb_delsys(delsys), list->NUM_CHANNELS, - fields, ptr->name, ptr->freq); - break; - case SYS_DVBC_ANNEX_A: - case SYS_DVBC_ANNEX_C: - fields = sscanf(&line[k], cbl_conf, - &ptr->freq, inv, &ptr->srate, - cr, mod, vpid_str, apid_str); - mp_verbose(log, "%s, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " - "SRATE: %d", - get_dvb_delsys(delsys), - list->NUM_CHANNELS, fields, ptr->name, - ptr->freq, ptr->srate); - break; + } 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) { + fields = sscanf(&line[k], cbl_conf, + &ptr->freq, inv, &ptr->srate, + cr, mod, vpid_str, apid_str); + mp_verbose(log, "CBL, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " + "SRATE: %d", list->NUM_CHANNELS, fields, ptr->name, + ptr->freq, ptr->srate); + } #ifdef DVB_ATSC - case SYS_ATSC: - fields = sscanf(&line[k], atsc_conf, - &ptr->freq, mod, vpid_str, apid_str); - mp_verbose(log, "%s, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n", - get_dvb_delsys(delsys), list->NUM_CHANNELS, - fields, ptr->name, ptr->freq); - break; + else if (type == TUNER_ATSC) { + fields = sscanf(&line[k], atsc_conf, + &ptr->freq, mod, vpid_str, apid_str); + mp_verbose(log, "ATSC, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n", + list->NUM_CHANNELS, fields, ptr->name, ptr->freq); + } #endif - case SYS_DVBS: - case SYS_DVBS2: - fields = sscanf(&line[k], sat_conf, - &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, - vpid_str, - apid_str); - ptr->pol = mp_toupper(ptr->pol); - ptr->freq *= 1000UL; - ptr->srate *= 1000UL; - if ((ptr->diseqc > 4) || (ptr->diseqc < 0)) - continue; - if (ptr->diseqc > 0) - ptr->diseqc--; - mp_verbose(log, "%s, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " - "SRATE: %d, POL: %c, DISEQC: %d", - get_dvb_delsys(delsys), - list->NUM_CHANNELS, fields, ptr->name, ptr->freq, - ptr->srate, ptr->pol, ptr->diseqc); - break; - default: - break; - } + else { //SATELLITE + fields = sscanf(&line[k], sat_conf, + &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, + vpid_str, + apid_str); + ptr->pol = mp_toupper(ptr->pol); + ptr->freq *= 1000UL; + ptr->srate *= 1000UL; + ptr->tone = -1; + ptr->inv = INVERSION_AUTO; + ptr->cr = FEC_AUTO; + if ((ptr->diseqc > 4) || (ptr->diseqc < 0)) + continue; + if (ptr->diseqc > 0) + ptr->diseqc--; + mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " + "SRATE: %d, POL: %c, DISEQC: %d", + list->NUM_CHANNELS, fields, ptr->name, ptr->freq, + ptr->srate, ptr->pol, ptr->diseqc); } if (parse_pid_string(log, vpid_str, ptr)) @@ -484,15 +425,13 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, mp_verbose(log, " %d ", ptr->pids[cnt]); mp_verbose(log, "\n"); - switch (delsys) { - case SYS_DVBT: - case SYS_DVBT2: - case SYS_DVBC_ANNEX_A: - case SYS_DVBC_ANNEX_C: + if ((type == TUNER_TER) || (type == TUNER_CBL)) { if (!strcmp(inv, "INVERSION_ON")) { ptr->inv = INVERSION_ON; } else if (!strcmp(inv, "INVERSION_OFF")) { ptr->inv = INVERSION_OFF; + } else { + ptr->inv = INVERSION_AUTO; } @@ -514,15 +453,13 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, ptr->cr = FEC_7_8; } else if (!strcmp(cr, "FEC_NONE")) { ptr->cr = FEC_NONE; + } else { + ptr->cr = FEC_AUTO; } } - switch (delsys) { - case SYS_DVBT: - case SYS_DVBT2: - case SYS_DVBC_ANNEX_A: - case SYS_DVBC_ANNEX_C: - case SYS_ATSC: + + if (type == TUNER_TER || type == TUNER_CBL || type == TUNER_ATSC) { if (!strcmp(mod, "QAM_128")) { ptr->mod = QAM_128; } else if (!strcmp(mod, "QAM_256")) { @@ -538,23 +475,20 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, ptr->mod = VSB_8; } else if (!strcmp(mod, "VSB_16") || !strcmp(mod, "16VSB")) { ptr->mod = VSB_16; + } else if (!strcmp(mod, "QAM_AUTO")) { + ptr->mod = QAM_AUTO; } + #endif } - switch (delsys) { - case SYS_DVBT: - case SYS_DVBT2: - if (!strcmp(bw, "BANDWIDTH_5_MHZ")) { - ptr->bw = BANDWIDTH_5_MHZ; - } else if (!strcmp(bw, "BANDWIDTH_6_MHZ")) { + if (type == TUNER_TER) { + if (!strcmp(bw, "BANDWIDTH_6_MHZ")) { ptr->bw = BANDWIDTH_6_MHZ; } else if (!strcmp(bw, "BANDWIDTH_7_MHZ")) { ptr->bw = BANDWIDTH_7_MHZ; } else if (!strcmp(bw, "BANDWIDTH_8_MHZ")) { ptr->bw = BANDWIDTH_8_MHZ; - } else if (!strcmp(bw, "BANDWIDTH_10_MHZ")) { - ptr->bw = BANDWIDTH_10_MHZ; } @@ -574,6 +508,8 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, ptr->gi = GUARD_INTERVAL_1_8; } else if (!strcmp(gi, "GUARD_INTERVAL_1_4")) { ptr->gi = GUARD_INTERVAL_1_4; + } else { + ptr->gi = GUARD_INTERVAL_AUTO; } if (!strcmp(tmp_lcr, "FEC_1_2")) { @@ -594,6 +530,8 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, ptr->cr_lp = FEC_7_8; } else if (!strcmp(tmp_lcr, "FEC_NONE")) { ptr->cr_lp = FEC_NONE; + } else { + ptr->cr_lp = FEC_AUTO; } @@ -603,7 +541,9 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, ptr->hier = HIERARCHY_2; } else if (!strcmp(tmp_hier, "HIERARCHY_4")) { ptr->hier = HIERARCHY_4; - } else if (!strcmp(tmp_hier, "HIERARCHY_NONE")) { + } else if (!strcmp(tmp_hier, "HIERARCHY_AUTO")) { + ptr->hier = HIERARCHY_AUTO; + } else { ptr->hier = HIERARCHY_NONE; } } @@ -630,6 +570,7 @@ static dvb_channels_list_t *dvb_get_channels(struct mp_log *log, return NULL; } + list->current = 0; return list; } @@ -637,15 +578,16 @@ void dvb_free_state(dvb_state_t *state) { int i, j; - for (i = 0; i < state->adapters_count; i++) { - if (!state->adapters[i].list) + for (i = 0; i < state->count; i++) { + free(state->cards[i].name); + if (!state->cards[i].list) continue; - if (state->adapters[i].list->channels) { - for (j = 0; j < state->adapters[i].list->NUM_CHANNELS; j++) - free(state->adapters[i].list->channels[j].name); - free(state->adapters[i].list->channels); + if (state->cards[i].list->channels) { + for (j = 0; j < state->cards[i].list->NUM_CHANNELS; j++) + free(state->cards[i].list->channels[j].name); + free(state->cards[i].list->channels); } - free(state->adapters[i].list); + free(state->cards[i].list); } free(state); } @@ -655,41 +597,47 @@ static int dvb_streaming_read(stream_t *stream, char *buffer, int size) struct pollfd pfds[1]; int pos = 0, tries, rk, fd; dvb_priv_t *priv = (dvb_priv_t *) stream->priv; - dvb_state_t *state = priv->state; + dvb_state_t* state = priv->state; MP_TRACE(stream, "dvb_streaming_read(%d)\n", size); - tries = state->retry; + tries = state->retry + 1; + fd = state->dvr_fd; while (pos < size) { - rk = read(fd, &buffer[pos], (size - pos)); - if (rk <= 0) { - if (pos || tries == 0) - break; - tries --; - pfds[0].fd = fd; - pfds[0].events = POLLIN | POLLPRI; - if (poll(pfds, 1, 500) <= 0) { - MP_ERR(stream, "dvb_streaming_read, failed with " - "errno %d when reading %d bytes\n", errno, size - pos); - errno = 0; - break; - } - continue; + pfds[0].fd = fd; + pfds[0].events = POLLIN | POLLPRI; + + rk = size - pos; + if (poll(pfds, 1, 500) <= 0) { + MP_ERR(stream, "dvb_streaming_read, attempt N. %d failed with " + "errno %d when reading %d bytes\n", tries, errno, size - pos); + errno = 0; + if (--tries > 0) + continue; + break; + } + if ((rk = read(fd, &buffer[pos], rk)) > 0) { + pos += rk; + MP_TRACE(stream, "ret (%d) bytes\n", pos); + } else { + MP_ERR(stream, "dvb_streaming_read, poll ok but read failed with " + "errno %d when reading %d bytes, size: %d, pos: %d\n", + errno, size - pos, size, pos); } - pos += rk; - MP_TRACE(stream, "ret (%d) bytes\n", pos); } if (!pos) - MP_ERR(stream, "dvb_streaming_read, return 0 bytes\n"); + MP_ERR(stream, "dvb_streaming_read, return %d bytes\n", pos); return pos; } -int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n) +static void dvbin_close(stream_t *stream); + +int dvb_set_channel(stream_t *stream, int card, int n) { - dvb_channels_list_t *new_list; + dvb_channels_list *new_list; dvb_channel_t *channel; dvb_priv_t *priv = stream->priv; char buf[4096]; @@ -697,33 +645,33 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n) int devno; int i; - if (adapter >= state->adapters_count) { - MP_ERR(stream, "dvb_set_channel: INVALID internal ADAPTER NUMBER: %d vs %d, abort\n", - adapter, state->adapters_count); + if ((card < 0) || (card > state->count)) { + MP_ERR(stream, "dvb_set_channel: INVALID CARD NUMBER: %d vs %d, abort\n", + card, state->count); return 0; } - devno = state->adapters[adapter].devno; - new_list = state->adapters[adapter].list; - if (n > new_list->NUM_CHANNELS) { + devno = state->cards[card].devno; + new_list = state->cards[card].list; + if ((n > new_list->NUM_CHANNELS) || (n < 0)) { MP_ERR(stream, "dvb_set_channel: INVALID CHANNEL NUMBER: %d, for " - "adapter %d, abort\n", n, devno); + "card %d, abort\n", n, card); return 0; } channel = &(new_list->channels[n]); if (state->is_on) { //the fds are already open and we have to stop the demuxers - /* Remove all demuxes. */ - dvb_fix_demuxes(priv, 0); + for (i = 0; i < state->demux_fds_cnt; i++) + dvb_demux_stop(state->demux_fds[i]); 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) { + while (dvb_streaming_read(stream, buf, 4096) > 0) {} + if (state->card != card) { dvbin_close(stream); if (!dvb_open_devices(priv, devno, channel->pids_cnt)) { MP_ERR(stream, "DVB_SET_CHANNEL, COULDN'T OPEN DEVICES OF " - "ADAPTER: %d, EXIT\n", devno); + "CARD: %d, EXIT\n", card); return 0; } } else { @@ -735,23 +683,24 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n) } else { if (!dvb_open_devices(priv, devno, channel->pids_cnt)) { MP_ERR(stream, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF " - "ADAPTER: %d, EXIT\n", devno); + "CARD: %d, EXIT\n", card); return 0; } } - state->cur_adapter = adapter; + state->card = card; + state->list = new_list; state->retry = 5; new_list->current = n; - MP_VERBOSE(stream, "DVB_SET_CHANNEL: new channel name=%s, adapter: %d, " - "channel %d\n", channel->name, devno, n); + MP_VERBOSE(stream, "DVB_SET_CHANNEL: new channel name=%s, card: %d, " + "channel %d\n", channel->name, card, n); stream_drop_buffers(stream); if (channel->freq != state->last_freq) { - if (!dvb_tune(priv, channel->delsys, channel->freq, - channel->pol, channel->srate, channel->diseqc, - channel->stream_id, channel->inv, + if (!dvb_tune(priv, channel->freq, channel->pol, channel->srate, + channel->diseqc, channel->tone, + channel->is_dvb_s2, channel->stream_id, channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier, priv->cfg_timeout)) @@ -769,7 +718,7 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n) MP_VERBOSE(stream, "DVB_SET_CHANNEL: PMT-PID for service %d " "not resolved yet, parsing PAT...\n", channel->service_id); - int pmt_pid = dvb_get_pmt_pid(priv, adapter, channel->service_id); + int pmt_pid = dvb_get_pmt_pid(priv, card, channel->service_id); MP_VERBOSE(stream, "DVB_SET_CHANNEL: Found PMT-PID: %d\n", pmt_pid); channel->pids[i] = pmt_pid; @@ -795,13 +744,14 @@ int dvb_set_channel(stream_t *stream, unsigned int adapter, unsigned int n) int dvb_step_channel(stream_t *stream, int dir) { - unsigned int new_current; + int new_current; + dvb_channels_list *list; dvb_priv_t *priv = stream->priv; - dvb_state_t *state = priv->state; - dvb_channels_list_t *list = state->adapters[state->cur_adapter].list; + dvb_state_t* state = priv->state; MP_VERBOSE(stream, "DVB_STEP_CHANNEL dir %d\n", dir); + list = state->list; if (list == NULL) { MP_ERR(stream, "dvb_step_channel: NULL list_ptr, quit\n"); return 0; @@ -810,33 +760,43 @@ int dvb_step_channel(stream_t *stream, int dir) new_current = (list->NUM_CHANNELS + list->current + (dir >= 0 ? 1 : -1)) % list->NUM_CHANNELS; - return dvb_set_channel(stream, state->cur_adapter, new_current); + return dvb_set_channel(stream, state->card, new_current); } static int dvbin_stream_control(struct stream *s, int cmd, void *arg) { int r; - dvb_priv_t *priv = (dvb_priv_t *) s->priv; - dvb_state_t *state = priv->state; - dvb_channels_list_t *list = NULL; - - switch (cmd) { case STREAM_CTRL_DVB_SET_CHANNEL: { - unsigned int *iarg = arg; - MP_VERBOSE(s, "dvbin_stream_control: cmd STREAM_CTRL_DVB_SET_CHANNEL: %i, %i\n", iarg[1], iarg[0]); + int *iarg = arg; r = dvb_set_channel(s, iarg[1], iarg[0]); if (r) { // Stream will be pulled down after channel switch, // persist state. + dvb_priv_t *priv = (dvb_priv_t *) s->priv; + dvb_state_t* state = priv->state; state->switching_channel = true; return STREAM_OK; } return STREAM_ERROR; } - case STREAM_CTRL_DVB_STEP_CHANNEL: { - MP_VERBOSE(s, "dvbin_stream_control: cmd STREAM_CTRL_DVB_STEP_CHANNEL: %i\n", (*(int *)arg)); - r = dvb_step_channel(s, (*(int *)arg)); + case STREAM_CTRL_DVB_SET_CHANNEL_NAME: { + char *progname = *((char**)arg); + dvb_priv_t *priv = (dvb_priv_t *) s->priv; + dvb_state_t* state = priv->state; + int new_channel = -1; + for (int i=0; i < state->list->NUM_CHANNELS; ++i) { + if (!strcmp(state->list->channels[i].name, progname)) { + new_channel = i; + break; + } + } + if (new_channel == -1) { + MP_ERR(s, "Program '%s' not found for card %d!\n", + progname, state->card); + return STREAM_ERROR; + } + r = dvb_set_channel(s, state->card, new_channel); if (r) { // Stream will be pulled down after channel switch, // persist state. @@ -845,62 +805,44 @@ static int dvbin_stream_control(struct stream *s, int cmd, void *arg) } return STREAM_ERROR; } - } - - - if (state->cur_adapter >= state->adapters_count) - return STREAM_ERROR; - list = state->adapters[state->cur_adapter].list; - - switch (cmd) { - case STREAM_CTRL_GET_TV_FREQ: - (*(unsigned int*)arg) = list->channels[list->current].freq; - return STREAM_ERROR; - case STREAM_CTRL_DVB_SET_CHANNEL_NAME: { - char *progname = *((char**)arg); - unsigned int new_channel = (~(unsigned int)0); - MP_VERBOSE(s, "dvbin_stream_control: cmd STREAM_CTRL_DVB_SET_CHANNEL_NAME: %s\n", progname); - for (unsigned int i=0; i < list->NUM_CHANNELS; ++i) { - if (!strcmp(list->channels[i].name, progname)) { - new_channel = i; - break; - } - } - if (new_channel == -1) { - MP_ERR(s, "Program '%s' not found for adapter %d!\n", - progname, state->adapters[state->cur_adapter].devno); - return STREAM_ERROR; - } - r = dvb_set_channel(s, state->cur_adapter, new_channel); + case STREAM_CTRL_DVB_STEP_CHANNEL: { + r = dvb_step_channel(s, *(int *)arg); if (r) { // Stream will be pulled down after channel switch, // persist state. + dvb_priv_t *priv = (dvb_priv_t *) s->priv; + dvb_state_t* state = priv->state; state->switching_channel = true; return STREAM_OK; } return STREAM_ERROR; } case STREAM_CTRL_DVB_GET_CHANNEL_NAME: { - MP_VERBOSE(s, "dvbin_stream_control: cmd STREAM_CTRL_DVB_GET_CHANNEL_NAME\n"); - char *progname = list->channels[list->current].name; - *(char **)arg = talloc_strdup(NULL, progname); - return STREAM_OK; + dvb_priv_t *priv = (dvb_priv_t *) s->priv; + dvb_state_t* state = priv->state; + int current_channel = state->list->current; + char* progname = state->list->channels[current_channel].name; + *(char **)arg = talloc_strdup(NULL, progname); + return STREAM_OK; } case STREAM_CTRL_GET_METADATA: { - struct mp_tags *metadata = talloc_zero(NULL, struct mp_tags); - char *progname = list->channels[list->current].name; - mp_tags_set_str(metadata, "title", progname); - *(struct mp_tags **)arg = metadata; - return STREAM_OK; + struct mp_tags* metadata = talloc_zero(NULL, struct mp_tags); + dvb_priv_t *priv = (dvb_priv_t *) s->priv; + dvb_state_t* state = priv->state; + int current_channel = state->list->current; + char* progname = state->list->channels[current_channel].name; + mp_tags_set_str(metadata, "title", progname); + *(struct mp_tags **)arg = metadata; + return STREAM_OK; } } return STREAM_UNSUPPORTED; } -void dvbin_close(stream_t *stream) +static void dvbin_close(stream_t *stream) { dvb_priv_t *priv = (dvb_priv_t *) stream->priv; - dvb_state_t *state = priv->state; + dvb_state_t* state = priv->state; if (state->switching_channel && state->is_on) { // Prevent state destruction, reset channel-switch. @@ -918,6 +860,7 @@ void dvbin_close(stream_t *stream) close(state->demux_fds[i]); } close(state->dvr_fd); + close(state->fe_fd); state->fe_fd = state->dvr_fd = -1; @@ -929,39 +872,39 @@ void dvbin_close(stream_t *stream) pthread_mutex_unlock(&global_dvb_state_lock); } -static int dvb_streaming_start(stream_t *stream, char *progname) +static int dvb_streaming_start(stream_t *stream, int tuner_type, char *progname) { int i; dvb_channel_t *channel = NULL; dvb_priv_t *priv = stream->priv; - dvb_state_t *state = priv->state; - dvb_channels_list_t *list; + dvb_state_t* state = priv->state; + dvb_priv_t *opts = priv; - if (progname == NULL) - return 0; - MP_VERBOSE(stream, "\r\ndvb_streaming_start(PROG: %s, ADAPTER: %d)\n", - progname, priv->cfg_devno); + MP_VERBOSE(stream, "\r\ndvb_streaming_start(PROG: %s, CARD: %d)\n", + opts->cfg_prog, opts->cfg_card); state->is_on = 0; - list = state->adapters[state->cur_adapter].list; - for (i = 0; i < list->NUM_CHANNELS; i ++) { - if (!strcmp(list->channels[i].name, progname)) { - channel = &(list->channels[i]); - break; - } + + i = 0; + while ((channel == NULL) && i < state->list->NUM_CHANNELS) { + if (!strcmp(state->list->channels[i].name, progname)) + channel = &(state->list->channels[i]); + + i++; } - if (channel == NULL) { + if (channel != NULL) { + state->list->current = i - 1; + MP_VERBOSE(stream, "PROGRAM NUMBER %d: name=%s, freq=%u\n", i - 1, + channel->name, channel->freq); + } else { MP_ERR(stream, "\n\nDVBIN: no such channel \"%s\"\n\n", progname); return 0; } - list->current = i; - MP_VERBOSE(stream, "PROGRAM NUMBER %d: name=%s, freq=%u\n", i, - channel->name, channel->freq); - if (!dvb_set_channel(stream, state->cur_adapter, list->current)) { - MP_ERR(stream, "ERROR, COULDN'T SET CHANNEL %i: \"%s\"\n", list->current, progname); + if (!dvb_set_channel(stream, state->card, state->list->current)) { + MP_ERR(stream, "ERROR, COULDN'T SET CHANNEL %i: ", state->list->current); dvbin_close(stream); return 0; } @@ -978,27 +921,27 @@ static int dvb_open(stream_t *stream) { // I don't force the file format because, although it's almost always TS, // there are some providers that stream an IP multicast with M$ Mpeg4 inside - dvb_priv_t *priv = NULL; char *progname; - int i; + int tuner_type = 0, i; pthread_mutex_lock(&global_dvb_state_lock); if (global_dvb_state && global_dvb_state->stream_used) { - MP_ERR(stream, "DVB stream already in use, only one DVB stream can exist at a time!\n"); + MP_ERR(stream, "DVB stream already in use, only one DVB stream can exist at a time!"); pthread_mutex_unlock(&global_dvb_state_lock); - goto err_out; + return STREAM_ERROR; } stream->priv = mp_get_config_group(stream, stream->global, &stream_dvb_conf); - dvb_state_t *state = dvb_get_state(stream); + dvb_state_t* state = dvb_get_state(stream); + + dvb_priv_t *p = stream->priv; + p->log = stream->log; - priv = stream->priv; - priv->state = state; - priv->log = stream->log; + p->state = state; if (state == NULL) { MP_ERR(stream, "DVB CONFIGURATION IS EMPTY, exit\n"); pthread_mutex_unlock(&global_dvb_state_lock); - goto err_out; + return STREAM_ERROR; } state->stream_used = true; pthread_mutex_unlock(&global_dvb_state_lock); @@ -1007,97 +950,101 @@ static int dvb_open(stream_t *stream) // State could be already initialized, for example, we just did a channel switch. // The following setup only has to be done once. - state->cur_adapter = -1; - for (i = 0; i < state->adapters_count; i++) { - if (state->adapters[i].devno == priv->cfg_devno) { - state->cur_adapter = i; + state->card = -1; + for (i = 0; i < state->count; i++) { + if (state->cards[i].devno + 1 == p->cfg_card) { + state->card = i; break; } } - if (state->cur_adapter == -1) { - MP_ERR(stream, "NO CONFIGURATION FOUND FOR ADAPTER N. %d, exit\n", - priv->cfg_devno); - goto err_out; + if |