diff options
-rw-r--r-- | HISTORY | 6 | ||||
-rw-r--r-- | siinfo.c | 174 | ||||
-rw-r--r-- | siinfo.h | 2 | ||||
-rw-r--r-- | teletext.h | 2 | ||||
-rw-r--r-- | ttxtsubs.c | 4 | ||||
-rw-r--r-- | ttxtsubsfilter.c | 6 | ||||
-rw-r--r-- | ttxtsubsreceiver.c | 6 | ||||
-rw-r--r-- | vdrttxtsubshooks.h | 2 |
8 files changed, 149 insertions, 53 deletions
@@ -1,6 +1,12 @@ VDR Plugin 'ttxtsubs' Revision History -------------------------------------- +2003-06-22: Version 0.0.3b +- Work around for problem with stray segments at channel (frequency) + change with driver in hw_sections=0 mode +- Removed some g++ 3.3 warnings +- Skipping non dvb devices when calculating /dev/dvb/adapter no + 2003-06-20: Version 0.0.3 - Small adjustments for VDR 1.2.1 @@ -14,6 +14,9 @@ #include <string.h> #include <errno.h> +#include <vdr/device.h> +#include <vdr/dvbdevice.h> + #include "linux/dvb/dmx.h" #include "siinfo.h" @@ -158,6 +161,8 @@ static int CollectSections(int card_no, int pid, int table_id, char **sects, int char name[100]; time_t start_time; + // printf("CollectSections %d/%d\n", pid, table_id); // XXXX + snprintf(name, sizeof(name), "/dev/dvb/adapter%d/demux0", card_no); memset(sects, 0, sizeof(char*) * 256); @@ -166,7 +171,7 @@ static int CollectSections(int card_no, int pid, int table_id, char **sects, int perror("DEMUX DEVICE 1: "); return -1; } - + // printf("ttxtsubs: siinfo.c: checking pid %d\n", pid); // XXXX if(SetSectFilt(fd, pid, table_id, 0xff)) { ret = -1; goto bail; @@ -188,6 +193,7 @@ static int CollectSections(int card_no, int pid, int table_id, char **sects, int p = (char *) malloc(SECTSIZE); n = read_timeout(fd, p, SECTSIZE, 250); + if(n < 8) continue; @@ -227,13 +233,59 @@ static int CollectSections(int card_no, int pid, int table_id, char **sects, int return ret; } +// When using a full featured card with hw_sections=0, at frequency change +// there seems to sometimes be left one (or more?) section block from the +// previous channel somewhere in the pipe. Whe need to remove that. +static void DiscardBufferedSections(int card_no, uint16_t pid, int table_id) +{ + int fd; + char name[100]; + int ret = -1; + int n = 0; + char buf[SECTSIZE]; + + snprintf(name, sizeof(name), "/dev/dvb/adapter%d/demux0", card_no); + + if((fd = open(name, O_RDWR)) < 0){ + perror("DEMUX DEVICE 1: "); + return; + } + + if(SetSectFilt(fd, pid, table_id, 0xff)) { + goto bail; + } + + // first read one section + read_timeout(fd, buf, SECTSIZE, 1000); + + // this loop doesn't seem to be needed + do { + struct pollfd pi; + pi.fd = fd; + pi.events = POLLIN | POLLERR | POLLHUP | POLLNVAL; + + ret = poll(&pi, 1, 0); + if(ret > 0 && (pi.revents & POLLIN)) { + read(fd, buf, SECTSIZE); + n++; + } + } while (ret > 0); + + if(n) + printf("\nttxtsubs: DiscardBufferedSections: Discarded %d extra buffered sections\n\n", n + 1); // XXX + bail: + close(fd); +} + static void FreeSects(char **sects) { int i; for(i = 0; i < 256; i++) { - if(sects[i]) + if(sects[i]) { free(sects[i]); + sects[i] = NULL; + } } } @@ -358,6 +410,8 @@ static int FindTtxtInfoInPMT(int card_no, int pid, int vpid, struct ttxtinfo *in char *pmtsects[256]; int numsects; + // printf("FindTtxtInfoInPMT pid: %d, vpid: %d\n", pid, vpid); // XXXX + ret = CollectSections(card_no, pid, 0x02, pmtsects, &numsects); if(ret) goto bail; @@ -375,13 +429,33 @@ static int FindTtxtInfoInPMT(int card_no, int pid, int vpid, struct ttxtinfo *in return ret; } +/* + * Get dvb device number from device index + * this is needed for those having cards which aren't dvb cards, like + * mpeg decoders. It will probably break if there are unused devices. + */ +int DeviceToCardNo(int device_no) +{ + int card_no = -1; + int i; + + for(i = 0; i <= device_no; i++) { + cDevice *d = cDevice::GetDevice(i); + cDvbDevice *dd = dynamic_cast<cDvbDevice*>(d); + if(dd) + card_no++; + } + + return card_no; +} + /* * find the ttxt_info in the PMT via the PAT, try first with the SID * and if that fails with the VPID * return <> 0 on error; */ -int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) +int GetTtxtInfo(int device_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) { int ret; char *patsects[256]; @@ -390,62 +464,78 @@ int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) int j; uint16_t pmt_pid = 0; int foundinfo = 0; + int card_no; + int retry; memset((char *) info, 0, sizeof(*info)); - ret = CollectSections(card_no, 0, 0, patsects, &numsects); - if(ret) - goto bail; - - if(sid != 0) { - int found; + for(retry = 0; retry <= 1 && !foundinfo; retry++) { // XXX retry two times due to flaky pat scanning with hw_sections=0 - for(i = 0, found = 0; i < numsects && !found; i++) { - int numdescrs; - struct PAT_sect *s = (struct PAT_sect *) patsects[i]; - - numdescrs = ((ntohs(s->syntax_len) & 0x3FF) - 7) / 4; - - for(j = 0; j < numdescrs && !found; j++) { - uint16_t pno = ntohs(s->d[j].program_number); + // printf("GetTtxtInfo A sid: %d, vpid: %d\n", sid, vpid); // XXXX - if(pno == 0) - continue; // network pid - - if(pno == sid) { - pmt_pid = ntohs(s->d[j].res_PMTPID) & 0x1fff; - found = 1; - } - } + card_no = DeviceToCardNo(device_no); + if(card_no == -1) { + fprintf(stderr, "ttxtsubs: GetTtxtInfo - couldn't find a card for device %d\n", card_no); } - } - if(pmt_pid != 0) { - ret = FindTtxtInfoInPMT(card_no, pmt_pid, 0, info, &foundinfo); - } else { - // SID not found, try searching VID in all SIDS - if(vpid != 0) { - int done; - for(i = 0, done = 0; i < numsects && !done; i++) { + DiscardBufferedSections(card_no, 0, 0); + + ret = CollectSections(card_no, 0, 0, patsects, &numsects); + if(ret) + goto bail; + + if(sid != 0) { + int found; + + for(i = 0, found = 0; i < numsects && !found; i++) { int numdescrs; struct PAT_sect *s = (struct PAT_sect *) patsects[i]; - + numdescrs = ((ntohs(s->syntax_len) & 0x3FF) - 7) / 4; - for(j = 0; j < numdescrs && !done; j++) { + for(j = 0; j < numdescrs && !found; j++) { uint16_t pno = ntohs(s->d[j].program_number); if(pno == 0) continue; // network pid - pmt_pid = ntohs(s->d[j].res_PMTPID) & 0x1fff; - - ret = FindTtxtInfoInPMT(card_no, pmt_pid, vpid, info, &foundinfo); - if(ret) { - done = 1; + if(pno == sid) { + pmt_pid = ntohs(s->d[j].res_PMTPID) & 0x1fff; + found = 1; + } + } + } + } + + if(pmt_pid != 0) { + // printf("GetTtxtInfo B pmt_pid: %d, vpid: %d\n", pmt_pid, vpid); // XXXX + ret = FindTtxtInfoInPMT(card_no, pmt_pid, 0, info, &foundinfo); + } else { + // SID not found, try searching VID in all SIDS + if(vpid != 0) { + int done; + for(i = 0, done = 0; i < numsects && !done; i++) { + int numdescrs; + struct PAT_sect *s = (struct PAT_sect *) patsects[i]; + + numdescrs = ((ntohs(s->syntax_len) & 0x3FF) - 7) / 4; + + for(j = 0; j < numdescrs && !done; j++) { + uint16_t pno = ntohs(s->d[j].program_number); + + if(pno == 0) + continue; // network pid + + pmt_pid = ntohs(s->d[j].res_PMTPID) & 0x1fff; + + // printf("GetTtxtInfo C pmt_pid: %d, vpid: %d\n", pmt_pid, vpid); // XXXX + ret = FindTtxtInfoInPMT(card_no, pmt_pid, vpid, info, &foundinfo); + if(ret) { + done = 1; + } + if(foundinfo) + done = 1; } - if(foundinfo) - done = 1; } } } @@ -29,7 +29,7 @@ struct ttxtinfo { * and if that fails with the VPID * return <> 0 on error; */ -int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info); +int GetTtxtInfo(int device_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info); void FreeTtxtInfoData(struct ttxtinfo *info); @@ -98,4 +98,4 @@ void dump_hex(char *msg, const uint8_t *p, int len); // invert tab for last 42 bytes in packets extern unsigned char invtab[256]; -#endif __TS_TELETEXT_H +#endif @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: ttxtsubs.c,v 1.15 2003/06/20 02:35:37 ragge Exp $ + * $Id: ttxtsubs.c,v 1.16 2003/06/22 23:24:41 ragge Exp $ */ #include <vdr/plugin.h> @@ -18,7 +18,7 @@ #include "siinfo.h" #include "ttxtsubs.h" -static const char *VERSION = "0.0.3"; +static const char *VERSION = "0.0.3b"; static const char *DESCRIPTION = "Teletext subtitles"; //static const char *MAINMENUENTRY = "Ttxtsubs"; diff --git a/ttxtsubsfilter.c b/ttxtsubsfilter.c index a50a3fb..b997e82 100644 --- a/ttxtsubsfilter.c +++ b/ttxtsubsfilter.c @@ -141,11 +141,11 @@ void cTtxtSubsFilter::MakeY0(char *outdata, char *indata, uint16_t newpageno) memcpy(o->data + 2, i->data + 2, 6); // new text - char txtbuf[32]; + unsigned char txtbuf[32]; size_t txtlen; size_t n; - txtlen = snprintf(txtbuf, 32, "%03x", newpageno < 0x100 ? newpageno + 0x800 : newpageno); + txtlen = snprintf((char *) txtbuf, 32, "%03x", newpageno < 0x100 ? newpageno + 0x800 : newpageno); for(n = 0; n < txtlen; n++) { if(parity(txtbuf[n])) @@ -154,5 +154,5 @@ void cTtxtSubsFilter::MakeY0(char *outdata, char *indata, uint16_t newpageno) o->data[n + 8] = invtab[txtbuf[n]]; // XXX wrong parity? } for(; n < 32; n++) - o->data[n + 8] = invtab[' ']; // space already has right parity + o->data[n + 8] = invtab[(unsigned char) ' ']; // space already has right parity } diff --git a/ttxtsubsreceiver.c b/ttxtsubsreceiver.c index 494d5c6..b8473e6 100644 --- a/ttxtsubsreceiver.c +++ b/ttxtsubsreceiver.c @@ -196,7 +196,7 @@ void cTtxtSubsReceiver::AddIndexInfo(char *lang, int type, uint16_t page) txtlen = snprintf((char *) buf, 32, "%03x", mIndexPageNo); copy_inv_par(d->data + 8, buf, txtlen); for(int i = txtlen; i < 32; i++) - d->data[i+8] = invtab[' ']; // space already has correct parity + d->data[i+8] = invtab[(unsigned char) ' ']; // space already has correct parity //print_line((char *) mIndexPage[mIndexPageLines]); // XXX @@ -208,7 +208,7 @@ void cTtxtSubsReceiver::AddIndexInfo(char *lang, int type, uint16_t page) txtlen = strlen(header); copy_inv_par(d->data, (uint8_t *) header, txtlen); for(int i = txtlen; i < 40; i++) - d->data[i] = invtab[' ']; // space already has correct parity + d->data[i] = invtab[(unsigned char) ' ']; // space already has correct parity //print_line((char *) mIndexPage[mIndexPageLines]); // XXX @@ -221,7 +221,7 @@ void cTtxtSubsReceiver::AddIndexInfo(char *lang, int type, uint16_t page) if(mIndexPageCol == 0) { init_line(mIndexPage[mIndexPageLines], mIndexPageLines, mIndexPageNo >> 8); for(int i = 0; i < 40; i++) - d->data[i+8] = invtab[' ']; // space already has correct parity + d->data[i+8] = invtab[(unsigned char) ' ']; // space already has correct parity } if(page < 0x100) diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h index b2a1dcd..cfcd6a5 100644 --- a/vdrttxtsubshooks.h +++ b/vdrttxtsubshooks.h @@ -33,4 +33,4 @@ class cVDRTtxtsubsHookListener { static cVDRTtxtsubsHookListener *Hook(void); }; -#endif __VDRTTXTSUBSHOOKS_H +#endif |