[BUG] Pat table lost PMT-pid
Hi, I have problem with getstream. After long time of working, getstream sending stream with all needed pids, but pat-table sends without pmt pid. Here is example of UDP-stream dump with PNR=1 and PMT=4110 Broken stream: http://magnus.wnet.ua/dump_notworking.ts After restarting of getstream: http://magnus.wnet.ua/dump_working.ts Here is VLC log of broken PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=0 Here is VLC log of good PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=4110
I experience the same behaviour. From time to time, some programmes become unplayable in VLC (mplayer works). Restarting getstream helps. Analyzing broken stream in dvbsnoop shows: $ dvbsnoop -s ts -if ct2bad.ts -tssubdecode 0x0000 ---output omitted--- Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 0 (0x0000) After restarting dvbstream: Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 512 (0x0200) -- Ondrej Caletka Sergei Gurjev napsal(a):
Hi,
I have problem with getstream. After long time of working, getstream sending stream with all needed pids, but pat-table sends without pmt pid.
Here is example of UDP-stream dump with PNR=1 and PMT=4110 Broken stream: http://magnus.wnet.ua/dump_notworking.ts After restarting of getstream: http://magnus.wnet.ua/dump_working.ts
Here is VLC log of broken PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=0
Here is VLC log of good PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=4110
_______________________________________________ Getstream mailing list Getstream@gt.owl.de http://gt.owl.de/mailman/listinfo/getstream
I have noticed this in version 2 of getstream it doesn't seem to be present in version 1. When I get a chance I'll see if I can find what the cause is. Sean -----Original Message----- From: getstream-bounces@gt.owl.de [mailto:getstream-bounces@gt.owl.de] On Behalf Of Ondrej Caletka Sent: 14 May 2009 20:50 To: getstream@gt.owl.de Subject: Re: [BUG] Pat table lost PMT-pid I experience the same behaviour. From time to time, some programmes become unplayable in VLC (mplayer works). Restarting getstream helps. Analyzing broken stream in dvbsnoop shows: $ dvbsnoop -s ts -if ct2bad.ts -tssubdecode 0x0000 ---output omitted--- Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 0 (0x0000) After restarting dvbstream: Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 512 (0x0200) -- Ondrej Caletka Sergei Gurjev napsal(a):
Hi,
I have problem with getstream. After long time of working, getstream sending stream with all needed pids, but pat-table sends without pmt pid.
Here is example of UDP-stream dump with PNR=1 and PMT=4110 Broken stream: http://magnus.wnet.ua/dump_notworking.ts After restarting of getstream: http://magnus.wnet.ua/dump_working.ts
Here is VLC log of broken PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=0
Here is VLC log of good PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=4110
_______________________________________________ Getstream mailing list Getstream@gt.owl.de http://gt.owl.de/mailman/listinfo/getstream
_______________________________________________ Getstream mailing list Getstream@gt.owl.de http://gt.owl.de/mailman/listinfo/getstream
I found out that the problem may not be in the getstream itself. Same error is occasionally reported from dvbscan: Here is output of two consequential scans on tuned DVB adapter (tuned by running getstream): dvb@dvb-t ~ $ dvbscan -c -a3 using '/dev/dvb/adapter3/frontend0' and '/dev/dvb/adapter3/demux0' 0x0000 0x0001: pmt_pid 0x0000 O2 -- CT1 (HD Test) (???) 0x0000 0x0002: pmt_pid 0x0000 O2 -- Nova (MPEG-4 HD) (running) 0x0000 0x0003: pmt_pid 0x0000 O2 -- O2 Info (MPEG-2) (running) 0x0000 0x0004: pmt_pid 0x0000 O2 -- Test 4 (MPEG-2) (running) dumping lists (4 services) CT1 (HD Test) (0x0001) 01: PCR == V V 0x044d A 0x044e (cze) Nova (MPEG-4 HD) (0x0002) 01: PCR == V V 0x04b1 A 0x04b2 (cze) 0x0810 (cze) O2 Info (MPEG-2) (0x0003) 01: PCR == V V 0x0515 A 0x0516 (cze) Test 4 (MPEG-2) (0x0004) 01: PCR == V V 0x0579 A 0x057a (eng) Done. dvb@dvb-t ~ $ dvbscan -c -a3 using '/dev/dvb/adapter3/frontend0' and '/dev/dvb/adapter3/demux0' 0x0000 0x0001: pmt_pid 0x044c O2 -- CT1 (HD Test) (???) 0x0000 0x0002: pmt_pid 0x04b0 O2 -- Nova (MPEG-4 HD) (running) 0x0000 0x0003: pmt_pid 0x0514 O2 -- O2 Info (MPEG-2) (running) 0x0000 0x0004: pmt_pid 0x0578 O2 -- Test 4 (MPEG-2) (running) dumping lists (4 services) CT1 (HD Test) (0x0001) 01: PCR == V V 0x044d A 0x044e (cze) Nova (MPEG-4 HD) (0x0002) 01: PCR == V V 0x04b1 A 0x04b2 (cze) 0x0810 (cze) O2 Info (MPEG-2) (0x0003) 01: PCR == V V 0x0515 A 0x0516 (cze) Test 4 (MPEG-2) (0x0004) 01: PCR == V V 0x0579 A 0x057a (eng) Done. So I think maybe the simplest solution would be to patch the getstream not to update PAT table with invalid PMT pids. -- Ondrej Caletka Ondřej Caletka napsal(a):
I experience the same behaviour. From time to time, some programmes become unplayable in VLC (mplayer works). Restarting getstream helps.
Analyzing broken stream in dvbsnoop shows: $ dvbsnoop -s ts -if ct2bad.ts -tssubdecode 0x0000 ---output omitted--- Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 0 (0x0000)
After restarting dvbstream: Program_number: 258 (0x0102) reserved: 0 (0x00) Program_map_PID: 512 (0x0200)
-- Ondrej Caletka
Sergei Gurjev napsal(a):
Hi,
I have problem with getstream. After long time of working, getstream sending stream with all needed pids, but pat-table sends without pmt pid.
Here is example of UDP-stream dump with PNR=1 and PMT=4110 Broken stream: http://magnus.wnet.ua/dump_notworking.ts After restarting of getstream: http://magnus.wnet.ua/dump_working.ts
Here is VLC log of broken PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=0
Here is VLC log of good PAT: [00000427] ts demux debug: PATCallBack called [00000427] ts demux debug: new PAT ts_id=0 version=0 current_next=1 [00000427] ts demux debug: * number=1 pid=4110
_______________________________________________ Getstream mailing list Getstream@gt.owl.de http://gt.owl.de/mailman/listinfo/getstream
_______________________________________________ Getstream mailing list Getstream@gt.owl.de http://gt.owl.de/mailman/listinfo/getstream
Ondřej Caletka napsal(a):
So I think maybe the simplest solution would be to patch the getstream not to update PAT table with invalid PMT pids.
Here is the patch. Hope it will help fixing this random outages. I think the problem is in Airstar 2 DVB-T card, or its driver, as it never happened to other cards I use. -- Ondrej Caletka --- pat.c.old 2009-02-27 10:05:57.000000000 +0100 +++ pat.c 2010-01-16 22:31:23.000000000 +0100 @@ -217,6 +217,11 @@ for(pl=g_list_first(current->program);pl;pl=g_list_next(pl)) { pcur=pl->data; + if (pcur->pid == 0) { + logwrite(LOG_ERROR, "pat: Invalid PMT pid 0 for pnr %d", pcur->pnr); + continue; + } + /* Do we have a current PAT ? */ if (!last) { pmt_pidfrompat(a, pcur->pnr, pcur->pid);
On Sat, Jan 16, 2010 at 10:44:53PM +0100, Ondřej Caletka wrote:
Ondřej Caletka napsal(a):
So I think maybe the simplest solution would be to patch the getstream not to update PAT table with invalid PMT pids.
Here is the patch. Hope it will help fixing this random outages. I think the problem is in Airstar 2 DVB-T card, or its driver, as it never happened to other cards I use.
But the point is - we do the whole PAT reassembly ourselves instead of letting kernel do it. We check the sections checksum prior to using it - so there is no accidental way of breaking this IMHO.
--- pat.c.old 2009-02-27 10:05:57.000000000 +0100 +++ pat.c 2010-01-16 22:31:23.000000000 +0100 @@ -217,6 +217,11 @@ for(pl=g_list_first(current->program);pl;pl=g_list_next(pl)) { pcur=pl->data;
+ if (pcur->pid == 0) { + logwrite(LOG_ERROR, "pat: Invalid PMT pid 0 for pnr %d", pcur->pnr); + continue; + } + /* Do we have a current PAT ? */ if (!last) { pmt_pidfrompat(a, pcur->pnr, pcur->pid);
Thanks - took a while to get the code into my brain again - This solves an accidental zero pmt pid in the PAT - i'd like to make shure we are not just papering over a different bug ... Is the PAT broken? Do we overrun the PAT section under certain conditions while parsing? If you had time i'd like to see the output of this debug patch - it'll debug the whole psi sections in case we stumple on a zero pmt pid (this is just compile tested) diff --git a/pat.c b/pat.c index a8d08f5..08b4782 100644 --- a/pat.c +++ b/pat.c @@ -181,6 +181,11 @@ struct pat_s *pat_parse(struct adapter_s *a) { pat_pnrfrompat(s, pnr), pat_pidfrompat(s, pnr)); + if (!pat_pidfrompat(s, pnr)) { + logwrite(LOG_ERROR, "Broken PAT with pid == 0 for pnr %04x\n", pnr); + psi_dump(&a->pat.psi); + } + next->progcount++; } } diff --git a/psi.c b/psi.c index 76aab94..1ccc1ab 100644 --- a/psi.c +++ b/psi.c @@ -291,3 +291,16 @@ int psi_update_table(struct psi_s *psi, struct psisec_s *section) { return 1; } + +void psi_dump(struct psi_s *psi) { + int secnum, last; + struct psisec_s *sec; + + last=psi_last_section_number(psi->section[0]); + + for(secnum=0;secnum<=last;secnum++) { + logwrite(LOG_ERROR, "Section %d of %d\n", secnum, last); + sec=psi->section[secnum]; + dump_hex(LOG_ERROR, "sec: ", sec->data, sec->valid); + } +} diff --git a/psi.h b/psi.h index 14c46c3..b8d5b6c 100644 --- a/psi.h +++ b/psi.h @@ -153,5 +153,6 @@ struct psisec_s *psi_section_clone(struct psisec_s *section); unsigned int psi_segment_and_send(struct psisec_s *section, unsigned int pid, uint8_t cc, void (*callback)(void *data, void *arg), void *arg); int psi_update_table(struct psi_s *psi, struct psisec_s *section); +void psi_dump(struct psi_s *psi); #endif Flo -- Florian Lohoff f@zz.de "Es ist ein grobes Missverständnis und eine Fehlwahrnehmung, dem Staat im Internet Zensur- und Überwachungsabsichten zu unterstellen." - - Bundesminister Dr. Wolfgang Schäuble -- 10. Juli in Berlin
Hi again, I have implemented the patches. I have also patched the logger for ability to log into file as I didn't manage to redirect output using start-stop-deamon.. I will let you know when the logs would say something interresting. Last time it took about 4 months till it stopped working… :) -- Ondrej Florian Lohoff napsal(a):
Thanks - took a while to get the code into my brain again - This solves an accidental zero pmt pid in the PAT - i'd like to make shure we are not just papering over a different bug ...
Is the PAT broken? Do we overrun the PAT section under certain conditions while parsing?
If you had time i'd like to see the output of this debug patch - it'll debug the whole psi sections in case we stumple on a zero pmt pid (this is just compile tested)
Flo
--- getstream-old/getstream.c 2009-08-01 12:01:35.000000000 +0200 +++ getstream/getstream.c 2010-01-17 11:19:21.000000000 +0100 @@ -98,7 +98,7 @@ static void usage(void ) { - fprintf(stderr, "-c <config file> -d -t <timeout>\n"); + fprintf(stderr, "-c <config file> -d -t <timeout> -l <logfile>\n"); exit(-1); } @@ -110,8 +110,10 @@ int timeout=0; GList *al; struct config_s *config=NULL; + + logwrite_init(); - while((ch=getopt(argc, argv, "c:dt:")) != -1) { + while((ch=getopt(argc, argv, "c:dt:l:")) != -1) { switch(ch) { case 'c': config=readconfig(optarg); @@ -124,6 +126,10 @@ case 't': timeout=strtol(optarg, NULL, 10); break; + case 'l': + if (logwrite_set_output(optarg) == 0) + exit(1); + break; default: usage(); break; diff -u getstream-old/getstream.h getstream/getstream.h --- getstream-old/getstream.h 2009-08-01 12:01:35.000000000 +0200 +++ getstream/getstream.h 2010-01-17 11:19:37.000000000 +0100 @@ -403,8 +403,10 @@ * * */ +void logwrite_init(); void logwrite_inc_level(void ); void logwrite(int level, const char *format, ...); +int logwrite_set_output(const char * file); enum { LOG_ERROR, --- getstream-old/logging.c 2009-08-01 12:01:35.000000000 +0200 +++ getstream/logging.c 2010-01-17 11:23:11.000000000 +0100 @@ -1,12 +1,20 @@ #include <stdio.h> #include <stdarg.h> #include <stdlib.h> +#include <string.h> +#include <errno.h> #include <sys/param.h> #include <time.h> #include "getstream.h" int loglevel=LOG_ERROR; +static FILE * logfile; + +void logwrite_init() { + if (!logfile) + logfile = stdout; +} void logwrite_inc_level() { loglevel++; @@ -32,8 +40,20 @@ strftime(timedate, sizeof(timedate), "%Y-%m-%d %H:%M:%S", tm); - printf("%s.%03d %s\n", + fprintf(logfile, "%s.%03d %s\n", timedate, (int) tv.tv_usec/1000, logbuffer); + + fflush(logfile); } + +int logwrite_set_output(const char * file) { + logfile = fopen(file, "a"); + if (logfile == NULL) { + fprintf(stderr, "Log file open failed: %s\n", strerror(errno)); + return 0; + } + return 1; +} +
participants (4)
-
Florian Lohoff -
Ondřej Caletka -
Sean Lowry -
Sergei Gurjev