summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Grimm <tobias@e-tobi.loc>2008-12-13 10:47:51 +0100
committerTobias Grimm <tobias@e-tobi.loc>2008-12-13 10:47:51 +0100
commite98281852544a159522de0e561ac64c23c447468 (patch)
tree1fedc0c55429cbdc639f768b34e72a02e6dc9a9d
parent24caa0c99ed1482655d1832d5e23ec69a6d10962 (diff)
downloadvdr-plugin-ttxtsubs-0.0.3b.tar.gz
vdr-plugin-ttxtsubs-0.0.3b.tar.bz2
- Work around for problem with stray segments at channel (frequency)v0.0.3b
change with driver in hw_sections=0 mode - Removed some g++ 3.3 warnings - Skipping non dvb devices when calculating /dev/dvb/adapter no
-rw-r--r--HISTORY6
-rw-r--r--siinfo.c174
-rw-r--r--siinfo.h2
-rw-r--r--teletext.h2
-rw-r--r--ttxtsubs.c4
-rw-r--r--ttxtsubsfilter.c6
-rw-r--r--ttxtsubsreceiver.c6
-rw-r--r--vdrttxtsubshooks.h2
8 files changed, 149 insertions, 53 deletions
diff --git a/HISTORY b/HISTORY
index 3d24c42..d9e817f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/siinfo.c b/siinfo.c
index 04ed7a6..896f5b0 100644
--- a/siinfo.c
+++ b/siinfo.c
@@ -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;
}
}
}
diff --git a/siinfo.h b/siinfo.h
index 16ac445..96211c7 100644
--- a/siinfo.h
+++ b/siinfo.h
@@ -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);
diff --git a/teletext.h b/teletext.h
index fa1b519..ad1c536 100644
--- a/teletext.h
+++ b/teletext.h
@@ -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
diff --git a/ttxtsubs.c b/ttxtsubs.c
index e206a99..50e23b2 100644
--- a/ttxtsubs.c
+++ b/ttxtsubs.c
@@ -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