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; }
/***************************************************************************** * 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; }