int dvb_set_channel(stream_t *stream, int card, int n) { dvb_channels_list *new_list; dvb_channel_t *channel; dvb_priv_t *priv = stream->priv; char buf[4096]; dvb_config_t *conf = (dvb_config_t *) priv->config; int devno; int i; if((card < 0) || (card > conf->count)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CARD NUMBER: %d vs %d, abort\n", card, conf->count); return 0; } devno = conf->cards[card].devno; new_list = conf->cards[card].list; if((n > new_list->NUM_CHANNELS) || (n < 0)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CHANNEL NUMBER: %d, for card %d, abort\n", n, card); return 0; } channel = &(new_list->channels[n]); if(priv->is_on) //the fds are already open and we have to stop the demuxers { for(i = 0; i < priv->demux_fds_cnt; i++) dvb_demux_stop(priv->demux_fds[i]); priv->retry = 0; while(dvb_streaming_read(stream, buf, 4096) > 0); //empty both the stream's and driver's buffer if(priv->card != card) { dvbin_close(stream); if(! dvb_open_devices(priv, devno, channel->pids_cnt)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card); return 0; } } else //close all demux_fds with pos > pids required for the new channel or open other demux_fds if we have too few { if(! dvb_fix_demuxes(priv, channel->pids_cnt)) return 0; } } else { if(! dvb_open_devices(priv, devno, channel->pids_cnt)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card); return 0; } } priv->card = card; priv->list = new_list; priv->retry = 5; new_list->current = n; priv->fd = priv->dvr_fd; mp_msg(MSGT_DEMUX, MSGL_V, "DVB_SET_CHANNEL: new channel name=%s, card: %d, channel %d\n", channel->name, card, n); stream->buf_pos = stream->buf_len = 0; stream->pos = 0; 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)) return 0; priv->last_freq = channel->freq; priv->is_on = 1; //sets demux filters and restart the stream for(i = 0; i < channel->pids_cnt; i++) { if(! dvb_set_ts_filt(priv->demux_fds[i], channel->pids[i], DMX_PES_OTHER)) return 0; } return 1; }
int dvb_set_channel(stream_t *stream, int card, int n) { dvb_channels_list *new_list; dvb_channel_t *channel; dvb_priv_t *priv = stream->priv; char buf[4096]; dvb_state_t *state = (dvb_state_t *) priv->state; int devno; int i; 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->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 " "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 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, 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 " "CARD: %d, EXIT\n", card); return 0; } } else { // close all demux_fds with pos > pids required for the new channel // or open other demux_fds if we have too few if (!dvb_fix_demuxes(priv, channel->pids_cnt)) return 0; } } else { if (!dvb_open_devices(priv, devno, channel->pids_cnt)) { MP_ERR(stream, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF " "CARD: %d, EXIT\n", card); return 0; } } state->card = card; state->list = new_list; state->retry = 5; new_list->current = 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->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)) return 0; } state->last_freq = channel->freq; state->is_on = 1; if (channel->service_id != -1) { /* We need the PMT-PID in addition. If it has not yet beem resolved, do it now. */ for (i = 0; i < channel->pids_cnt; i++) { if (channel->pids[i] == -1) { 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, card, channel->service_id); MP_VERBOSE(stream, "DVB_SET_CHANNEL: Found PMT-PID: %d\n", pmt_pid); channel->pids[i] = pmt_pid; } } } // sets demux filters and restart the stream for (i = 0; i < channel->pids_cnt; i++) { if (channel->pids[i] == -1) { // In case PMT was not resolved, skip it here. MP_ERR(stream, "DVB_SET_CHANNEL: PMT-PID not found, " "teletext-decoding may fail.\n"); } else { if (!dvb_set_ts_filt(priv, state->demux_fds[i], channel->pids[i], DMX_PES_OTHER)) return 0; } } return 1; }