/* Read EIT segments from DVB-demuxer or file. {{{ */ static void readEventTables(void) { int r, n = 0; char buf[1<<12], *bhead = buf; /* The dvb demultiplexer simply outputs individual whole packets (good), * but reading captured data from a file needs re-chunking. (bad). */ do { if (n < sizeof(struct si_tab)) goto read_more; struct si_tab *tab = (struct si_tab *)bhead; if (GetTableId(tab) == 0) goto read_more; size_t l = sizeof(struct si_tab) + GetSectionLength(tab); if (n < l) goto read_more; packet_count++; if (_dvb_crc32((uint8_t *)bhead, l) != 0) { /* data or length is wrong. skip bytewise. */ //l = 1; // FIXME crcerr_count++; } else parseEIT(bhead, l); status(); /* remove packet */ n -= l; bhead += l; continue; read_more: /* move remaining data to front of buffer */ if (n > 0) memmove(buf, bhead, n); /* fill with fresh data */ r = read(STDIN_FILENO, buf+n, sizeof(buf)-n); bhead = buf; n += r; } while (r > 0); } /*}}}*/
/* * Read EIT segments from DVB-demuxer */ void readEventTables(int format, cFilter* filters) { int r = 0; u_char buf[1 << 12]; size_t l; int compressed; int uncompressed; float ratio; int64_t lastReadTime = 0; if (filters) { alarm(0); setTimeoutDeadline(); lastReadTime = getTime(); } while (1) { int pid = DVB_EIT_PID; if (filters) { if ((getTime() - finishTime) >= 0) { log_message(DEBUG, "timeout occurred"); break; } r = 0; int fd = filters->Poll(5000, &pid); if (fd > 0) { r = read(fd, buf, sizeof(buf)); if (r > 0) { lastReadTime = getTime(); } else if (r == 0) { if ((getTime() - lastReadTime) > 2000) { log_message(DEBUG, "did not read any more"); break; } } else { if (errno != ETIMEDOUT) log_message(ERROR, "pid read error %d", errno); } } } else { r = read(STDIN_FILENO, buf, sizeof(buf)); if (r < 0) { log_message(DEBUG, "did not read any more"); break; } } packet_count++; struct si_tab *tab = (struct si_tab *) buf; if (GetTableId(tab) == 0) { continue; } l = sizeof(struct si_tab) + GetSectionLength(tab); log_message(TRACE, "tableid %d len %d totallen %d.", GetTableId(tab), l, r); if (!SI::CRC32::isValid((const char *) buf, r)) { log_message(ERROR, "data or length is wrong for pid %d (0x%x) tableid %d (0x%x), len %d. skipping packet.",pid, pid, GetTableId(tab), GetTableId(tab), r); crcerr_count++; if (pid == DVB_TDT_PID && GetTableId(tab) == 112) { } } else { switch (pid) { case DVB_EIT_PID: parseEIT(buf, l); break; case DVB_SDT_PID: parseSDT(buf, l, &fullChannels); break; case DVB_TDT_PID: break; } } log_message( TRACE, "Status: %d pkts, %d prgms, %d updates, %d invalid, %d CRC err", packet_count, programme_count, update_count, invalid_date_count, crcerr_count); } uncompressed = get_stat("freesathuffman.uncompressed"); compressed = get_stat("freesathuffman.compressed"); ratio = (compressed>0)?uncompressed / compressed:1; log_message(DEBUG, "freesat huffman average expansion ratio: %f", ratio); }