Ejemplo n.º 1
0
Archivo: access.c Proyecto: etix/vlc
static int ScanReadCallback( scan_t *p_scan, void *p_privdata,
                             unsigned i_probe_timeout, size_t i_packets_max,
                             uint8_t *p_packet, size_t *pi_count )
{
    access_t *p_access = (access_t *) p_privdata;
    access_sys_t *p_sys = p_access->p_sys;
    *pi_count = 0;

    /* Initialize file descriptor sets */
    struct pollfd ufds[2];

    ufds[0].fd = p_sys->dvb.i_handle;
    ufds[0].events = POLLIN;
    ufds[1].fd = p_sys->dvb.i_frontend_handle;
    ufds[1].events = POLLPRI;

    frontend_status_t status;
    FrontendGetStatus( &p_sys->dvb, &status );
    bool b_has_lock = status.b_has_lock;

    mtime_t i_scan_start = mdate();

    for( ; *pi_count == 0; )
    {
        /* Find if some data is available */
        int i_ret;

        mtime_t i_timeout = b_has_lock ? i_probe_timeout:
                                         DVB_SCAN_MAX_LOCK_TIME;

        do
        {
            mtime_t i_poll_timeout = i_scan_start - mdate() + i_timeout;

            i_ret = 0;

            if( vlc_killed() || scan_IsCancelled( p_scan ) )
                break;

            if( i_poll_timeout >= 0 )
                i_ret = vlc_poll_i11e( ufds, 2, i_poll_timeout / 1000 );
        }
        while( i_ret < 0 && errno == EINTR );

        if( i_ret < 0 )
        {
            return VLC_EGENERIC;
        }
        else if( i_ret == 0 )
        {
            return VLC_ENOITEM;
        }

        if( ufds[1].revents )
        {
            FrontendPoll( VLC_OBJECT(p_access), &p_sys->dvb );

            FrontendGetStatus( &p_sys->dvb, &status );
            if( status.b_has_lock && !b_has_lock )
            {
                i_scan_start = mdate();
                b_has_lock = true;
            }
        }

        if ( ufds[0].revents )
        {
            ssize_t i_read = read( p_sys->dvb.i_handle, p_packet, TS_PACKET_SIZE * i_packets_max );
            if( i_read < 0 )
            {
                msg_Warn( p_access, "read failed: %s", vlc_strerror_c(errno) );
                break;
            }
            else
            {
                *pi_count = i_read / TS_PACKET_SIZE;
            }
        }
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * dvb_Read
 *****************************************************************************/
block_t *dvb_Read( mtime_t i_poll_timeout )
{
    struct pollfd ufds[4];
    int i_ret, i_nb_fd = 2;
    block_t *p_blocks = NULL;

    memset( ufds, 0, sizeof(ufds) );
    ufds[0].fd = i_dvr;
    ufds[0].events = POLLIN;
    ufds[1].fd = i_frontend;
    ufds[1].events = POLLERR | POLLPRI;
    if ( i_comm_fd != -1 )
    {
        ufds[i_nb_fd].fd = i_comm_fd;
        ufds[i_nb_fd].events = POLLIN;
        i_nb_fd++;
    }
    if ( i_ca_handle && i_ca_type == CA_CI_LINK )
    {
        ufds[i_nb_fd].fd = i_ca_handle;
        ufds[i_nb_fd].events = POLLIN;
        i_nb_fd++;
    }

    i_ret = poll( ufds, i_nb_fd, (i_poll_timeout + 999) / 1000 );

    i_wallclock = mdate();

    if ( i_ret < 0 )
    {
        if( errno != EINTR )
            msg_Err( NULL, "poll error: %s", strerror(errno) );
        return NULL;
    }

    if ( ufds[1].revents )
        FrontendPoll();

    if ( ufds[0].revents )
    {
        p_blocks = DVRRead();
        i_wallclock = mdate();
    }

    if ( p_blocks != NULL )
        i_last_packet = i_wallclock;
    else if ( !i_frontend_timeout
              && i_wallclock > i_last_packet + DVR_READ_TIMEOUT )
    {
        msg_Warn( NULL, "no DVR output, resetting" );
        FrontendSet(false);
        en50221_Reset();
    }

    if ( i_ca_handle && i_ca_type == CA_CI_LINK )
    {
        if ( ufds[i_nb_fd - 1].revents )
        {
            en50221_Read();
            i_ca_next_event = i_wallclock + CA_POLL_PERIOD;
        }
        else if ( i_wallclock > i_ca_next_event )
        {
            en50221_Poll();
            i_ca_next_event = i_wallclock + CA_POLL_PERIOD;
        }
    }

    if ( i_frontend_timeout && i_wallclock > i_frontend_timeout )
    {
        if ( i_quit_timeout_duration )
        {
            msg_Err( NULL, "no lock" );
            switch (i_print_type) {
            case PRINT_XML:
                printf("</TS>\n");
                break;
            default:
                break;
            }
            exit(EXIT_STATUS_FRONTEND_TIMEOUT);
        }
        msg_Warn( NULL, "no lock, tuning again" );
        FrontendSet(false);
    }

    if ( i_comm_fd != -1 && ufds[2].revents )
        comm_Read();

    return p_blocks;
}