/** * Reads TS data from the tuner. * @return number of bytes read, 0 on EOF, -1 if no data (yet). */ ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len) { struct pollfd ufd[2]; int n; #ifdef HAVE_DVBPSI if (d->cam != NULL) en50221_Poll (d->cam); #endif ufd[0].fd = d->demux; ufd[0].events = POLLIN; if (d->frontend != -1) { ufd[1].fd = d->frontend; ufd[1].events = POLLIN; n = 2; } else n = 1; if (poll (ufd, n, 500 /* FIXME */) < 0) return -1; if (d->frontend != -1 && ufd[1].revents) { struct dvb_frontend_event ev; if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0) { if (errno == EOVERFLOW) { msg_Err (d->obj, "cannot dequeue events fast enough!"); return -1; } msg_Err (d->obj, "cannot dequeue frontend event: %m"); return 0; } msg_Dbg (d->obj, "frontend status: 0x%02X", (unsigned)ev.status); } if (ufd[0].revents) { ssize_t val = read (d->demux, buf, len); if (val == -1 && (errno != EAGAIN && errno != EINTR)) { if (errno == EOVERFLOW) { msg_Err (d->obj, "cannot demux data fast enough!"); return -1; } msg_Err (d->obj, "cannot demux: %m"); return 0; } return val; } return -1; }
/** * Reads TS data from the tuner. * @return number of bytes read, 0 on EOF, -1 if no data (yet). */ ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len, int ms) { struct pollfd ufd[2]; int n; if (d->cam != NULL) en50221_Poll (d->cam); ufd[0].fd = d->demux; ufd[0].events = POLLIN; if (d->frontend != -1) { ufd[1].fd = d->frontend; ufd[1].events = POLLPRI; n = 2; } else n = 1; errno = 0; n = vlc_poll_i11e (ufd, n, ms); if (n == 0) errno = EAGAIN; if (n <= 0) return -1; if (d->frontend != -1 && ufd[1].revents) { struct dvb_frontend_event ev; if (ioctl (d->frontend, FE_GET_EVENT, &ev) < 0) { if (errno == EOVERFLOW) { msg_Err (d->obj, "cannot dequeue events fast enough!"); return -1; } msg_Err (d->obj, "cannot dequeue frontend event: %s", vlc_strerror_c(errno)); return 0; } dvb_frontend_status(d->obj, ev.status); } if (ufd[0].revents) { ssize_t val = read (d->demux, buf, len); if (val == -1 && (errno != EAGAIN && errno != EINTR)) { if (errno == EOVERFLOW) { msg_Err (d->obj, "cannot demux data fast enough!"); return -1; } msg_Err (d->obj, "cannot demux: %s", vlc_strerror_c(errno)); return 0; } return val; } return -1; }
/***************************************************************************** * 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; }