Beispiel #1
0
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;
}
Beispiel #2
0
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;
}