summaryrefslogtreecommitdiff
path: root/command/demux.cpp
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2011-03-25 16:07:51 +0100
committerJochen Dolze <vdr@dolze.de>2011-03-25 16:07:51 +0100
commit6adc2d76929fb8549689080c3510d3ff926ef4d2 (patch)
tree8ac6828cf73998d79662d7814ec43c209b27cbe3 /command/demux.cpp
parentb0c05b03c5ddf44ea4e3d2b9382dcb9e3ed902bc (diff)
downloadvdr-plugin-markad-6adc2d76929fb8549689080c3510d3ff926ef4d2.tar.gz
vdr-plugin-markad-6adc2d76929fb8549689080c3510d3ff926ef4d2.tar.bz2
Fixed TS afc error which led to "demux error"
Added more error messages and stream numbers
Diffstat (limited to 'command/demux.cpp')
-rw-r--r--command/demux.cpp156
1 files changed, 115 insertions, 41 deletions
diff --git a/command/demux.cpp b/command/demux.cpp
index 88f3048..1b89895 100644
--- a/command/demux.cpp
+++ b/command/demux.cpp
@@ -34,16 +34,18 @@ cPaketQueue::cPaketQueue(const char *Name, int Size)
memset(&pktinfo,0,sizeof(pktinfo));
percent=-1;
mpercent=0;
+ inptr=outptr=0;
+ skipped=0;
Clear();
}
void cPaketQueue::Clear()
{
+ skipped+=(inptr-outptr);
inptr=outptr=0;
pktinfo.pkthdr=-1;
scanner=0xFFFFFFFF;
scannerstart=-1;
- skipped=0;
}
cPaketQueue::~cPaketQueue()
@@ -451,7 +453,6 @@ uchar *cPaketQueue::GetPacket(int *Size, int Type)
*Size=0;
if (Length()<4) return NULL;
- skipped=0;
if (pktinfo.pkthdr==-1)
{
scanner=0xFFFFFFFF;
@@ -480,7 +481,7 @@ uchar *cPaketQueue::GetPacket(int *Size, int Type)
{
if (pktinfo.pkthdr!=outptr)
{
- skipped=pktinfo.pkthdr-outptr;
+ skipped+=(pktinfo.pkthdr-outptr);
}
}
scannerstart=pktinfo.pkthdr+pktinfo.pktsyncsize;
@@ -584,21 +585,29 @@ cTS2Pkt::~cTS2Pkt()
}
}
-void cTS2Pkt::Clear()
+void cTS2Pkt::Clear(AvPacket *Pkt)
{
+ if (!Pkt)
+ {
+ skipped=0;
+ noticeFILLER=false;
+ lasterror=ERR_INIT;
+ }
+ else
+ {
+ Pkt->Length=0;
+ Pkt->Type=0;
+ Pkt->Stream=0;
+ }
sync=false;
counter=-1;
- skipped=0;
- noticeFILLER=false;
- noticeSEQUENCE=false;
- noticeSTREAM=false;
- noticeTSERR=false;
if (queue) queue->Clear();
}
bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
{
if (!Pkt) return false;
+ if (!queue) return false;
if (TSData)
{
if (TSSize!=TS_SIZE) return false;
@@ -615,23 +624,30 @@ bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
{
if (counter==(int) tshdr->Counter)
{
+ if (lasterror!=ERR_DUPLICATE)
+ {
+ lasterror=ERR_DUPLICATE;
+ esyslog("duplicate packet, skipping (0x%04x)",pid);
+ }
+ Pkt->Length=0;
+ Pkt->Type=0;
+ Pkt->Stream=0;
skipped+=TS_SIZE;
- return true; // duplicate paket -> just ignore
+ return true; // duplicate packet -> just ignore
}
// sequence error
- if (!noticeSEQUENCE)
+ if (lasterror!=ERR_SEQUENCE)
{
- noticeSEQUENCE=true;
- isyslog("sequence error");
+ lasterror=ERR_SEQUENCE;
+ esyslog("sequence error (0x%04x)",pid);
}
- if (queue)
+ Clear(Pkt);
+ skipped+=queue->Skipped();
+ if (!tshdr->PayloadStart)
{
- skipped+=queue->Length();
- queue->Clear();
+ skipped+=TS_SIZE;
+ return true;
}
- counter=-1;
- sync=false;
- if (!tshdr->PayloadStart) return true;
}
counter=tshdr->Counter;
@@ -641,20 +657,33 @@ bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
}
if (!sync)
{
- if (firstsync) skipped+=TS_SIZE; // only count skipped bytes after first sync
+ Clear(Pkt);
+ if (firstsync)
+ {
+ if (lasterror==ERR_INIT)
+ {
+ lasterror=ERR_SYNC;
+ esyslog("out of sync (0x%04x)",pid);
+ }
+ skipped+=TS_SIZE; // only count skipped bytes after first sync
+ skipped+=queue->Skipped();
+ }
return true; // not synced
}
// we just ignore the infos in the adaption field (e.g. OPCR/PCR)
if ((tshdr->AFC!=1) && (tshdr->AFC!=3))
{
+ Pkt->Length=0;
+ Pkt->Type=0;
+ Pkt->Stream=0;
return true;
}
- if ((tshdr->TError) && (!noticeTSERR))
+ if ((tshdr->TError) && (lasterror!=ERR_HDRBIT))
{
- noticeTSERR=true;
- isyslog("stream error bit set");
+ lasterror=ERR_HDRBIT;
+ esyslog("stream error bit set (0x%04x)",pid);
}
int buflen=TS_SIZE+1;
@@ -671,7 +700,18 @@ bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
{
// adaption field + payload
int alen=TSData[4]+1;
- if (alen>(TS_SIZE-(int) sizeof(struct TSHDR))) alen=TS_SIZE-(int) sizeof(struct TSHDR);
+ if (alen>(TS_SIZE-(int) sizeof(struct TSHDR)))
+ {
+ if (lasterror!=ERR_AFCLEN)
+ {
+ lasterror=ERR_AFCLEN;
+ esyslog("afc length error (0x%04x)",pid);
+ }
+ Clear(Pkt);
+ skipped+=queue->Skipped();
+ skipped+=TS_SIZE;
+ return true;
+ }
buflen=TS_SIZE-(sizeof(struct TSHDR)+alen);
buf=&TSData[sizeof(struct TSHDR)+alen];
}
@@ -686,21 +726,15 @@ bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
{
if ((buf[0]!=0) && (buf[1]!=0))
{
- if (!noticeSTREAM)
+ if (lasterror!=ERR_PAYLOAD)
{
- isyslog("stream error");
- noticeSTREAM=true;
+ lasterror=ERR_PAYLOAD;
+ esyslog("payload start error (0x%04x)",pid);
}
+ Clear(Pkt);
+ skipped+=queue->Skipped();
skipped+=TS_SIZE;
- sync=false;
- if (buflen<7) return false;
- // add a pseudo padding stream
- buf[0]=0;
- buf[1]=0;
- buf[2]=1;
- buf[3]=0xbe;
- buf[4]=0;
- buf[5]=buflen-6;
+ return true;
}
}
queue->Put(buf,buflen);
@@ -710,24 +744,28 @@ bool cTS2Pkt::Process(uchar *TSData, int TSSize, AvPacket *Pkt)
if (Pkt->Data)
{
Pkt->Type=h264 ? PACKET_H264 : PACKET_H262;
+ Pkt->Stream=pid;
if ((h264) && ((Pkt->Data[4] & 0x1F)==0x0C))
{
if (!noticeFILLER)
{
- isyslog("H264 video stream with filler nalu");
+ isyslog("H264 video stream with filler nalu (0x%04x)",pid);
noticeFILLER=true;
}
skipped+=Pkt->Length; // thats not accurate!
Pkt->Data=NULL;
Pkt->Length=0;
Pkt->Type=0;
+ Pkt->Stream=0;
}
}
else
{
Pkt->Length=0;
Pkt->Type=0;
+ Pkt->Stream=0;
}
+ skipped+=queue->Skipped();
return true;
}
@@ -751,7 +789,9 @@ cPES2ES::~cPES2ES()
void cPES2ES::Clear()
{
+ stream=0;
skipped=0;
+ lasterror=0;
if (queue) queue->Clear();
}
@@ -772,6 +812,11 @@ bool cPES2ES::Process(uchar *PESData, int PESSize, AvPacket *ESPkt)
Length+=sizeof(PESHDR);
if (Length!=PESSize)
{
+ if (lasterror!=ERR_LENGTH)
+ {
+ esyslog("length mismatch (0x%02X)",peshdr->StreamID);
+ lasterror=ERR_LENGTH;
+ }
skipped+=Length;
return true;
}
@@ -779,7 +824,13 @@ bool cPES2ES::Process(uchar *PESData, int PESSize, AvPacket *ESPkt)
if (peshdr->StreamID==0xBE)
{
+ if (lasterror!=ERR_PADDING)
+ {
+ esyslog("found padding stream (0x%02X)",peshdr->StreamID);
+ lasterror=ERR_PADDING;
+ }
queue->Clear();
+ skipped+=queue->Skipped();
return true;
}
@@ -800,7 +851,7 @@ bool cPES2ES::Process(uchar *PESData, int PESSize, AvPacket *ESPkt)
default:
break;
}
-
+ stream=peshdr->StreamID;
struct PESHDROPT *peshdropt=(struct PESHDROPT *) &PESData[sizeof(struct PESHDR)];
uchar *buf;
@@ -834,11 +885,13 @@ bool cPES2ES::Process(uchar *PESData, int PESSize, AvPacket *ESPkt)
if (ESPkt->Data)
{
ESPkt->Type=ptype;
+ ESPkt->Stream=stream;
}
else
{
ESPkt->Type=0;
ESPkt->Length=0;
+ ESPkt->Stream=0;
}
skipped+=queue->Skipped();
return true;
@@ -917,6 +970,7 @@ void cDemux::Clear()
last_bplen=0;
from_oldfile=0;
stream_or_pid=0;
+ lasterror=ERR_INIT;
}
bool cDemux::isvideopes(uchar *data, int count)
@@ -969,6 +1023,11 @@ int cDemux::fillqueue(uchar *data, int count, int &stream_or_pid, int &packetsiz
}
else
{
+ if (lasterror!=ERR_JUNK)
+ {
+ esyslog("unusable data, skipping");
+ lasterror=ERR_JUNK;
+ }
skipped++;
stream_or_pid=0;
packetsize=1;
@@ -981,6 +1040,11 @@ int cDemux::fillqueue(uchar *data, int count, int &stream_or_pid, int &packetsiz
if (ret==-1) return -1;
if (ret)
{
+ if (lasterror!=ERR_JUNK)
+ {
+ esyslog("unusable data, skipping");
+ lasterror=ERR_JUNK;
+ }
skipped++;
stream_or_pid=0;
packetsize=1;
@@ -1002,7 +1066,7 @@ int cDemux::fillqueue(uchar *data, int count, int &stream_or_pid, int &packetsiz
}
if (!TS)
{
- // check length of PES-paket
+ // check length of PES-packet
qData=queue->Peek(packetsize+PEEKBUF);
if (qData)
{
@@ -1013,6 +1077,11 @@ int cDemux::fillqueue(uchar *data, int count, int &stream_or_pid, int &packetsiz
if (start>0)
{
// broken PES in queue, skip it
+ if (lasterror!=ERR_BROKEN)
+ {
+ esyslog("broken PES in queue, skipping");
+ lasterror=ERR_BROKEN;
+ }
packetsize=start;
skipped+=start;
stream_or_pid=0;
@@ -1045,6 +1114,11 @@ int cDemux::fillqueue(uchar *data, int count, int &stream_or_pid, int &packetsiz
if (start>0)
{
// broken TS in queue, skip it
+ if (lasterror!=ERR_BROKEN)
+ {
+ esyslog("broken TS in queue, skipping");
+ lasterror=ERR_BROKEN;
+ }
packetsize=start;
skipped+=start;
stream_or_pid=0;
@@ -1259,7 +1333,7 @@ int cDemux::Process(uchar *Data, int Count, AvPacket *pkt)
}
else if (stream_or_pid==dpid)
{
- AvPacket tpkt={NULL,0,0};
+ AvPacket tpkt={NULL,0,0,0};
if (!ts2pkt_dpid) ts2pkt_dpid=new cTS2Pkt(dpid,"TS2PES AC3");
if (!ts2pkt_dpid->Process(bpkt,bplen,&tpkt)) return -1;
if (!pes2audioes_ac3) pes2audioes_ac3=new cPES2ES(PACKET_AC3,"PES2AC3");
@@ -1267,7 +1341,7 @@ int cDemux::Process(uchar *Data, int Count, AvPacket *pkt)
}
else if (stream_or_pid==apid)
{
- AvPacket tpkt={NULL,0,0};
+ AvPacket tpkt={NULL,0,0,0};
if (!ts2pkt_apid) ts2pkt_apid=new cTS2Pkt(apid,"TS2PES MP2",16384);
if (!ts2pkt_apid->Process(bpkt,bplen,&tpkt)) return -1;
if (!pes2audioes_mp2) pes2audioes_mp2=new cPES2ES(PACKET_MP2,"PES2MP2",16384);