summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--demux.cpp19
-rw-r--r--markad-standalone.cpp121
-rw-r--r--markad-standalone.h14
-rw-r--r--pes2es.cpp7
-rw-r--r--recv.cpp17
-rw-r--r--recv.h1
-rw-r--r--tools.cpp30
-rw-r--r--tools.h2
-rw-r--r--ts2pkt.cpp47
-rw-r--r--ts2pkt.h47
11 files changed, 238 insertions, 69 deletions
diff --git a/README b/README
index 4ed4247..8a2235e 100644
--- a/README
+++ b/README
@@ -14,4 +14,4 @@ See the file COPYING for more information.
Description:
-Noad marks advertisements in VDR recordings.
+MarkAd marks advertisements in VDR recordings.
diff --git a/demux.cpp b/demux.cpp
index 9c28c34..89855d7 100644
--- a/demux.cpp
+++ b/demux.cpp
@@ -48,7 +48,6 @@ void cMarkAdDemux::ProcessVDR(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt
if (!pes2audioes) pes2audioes=new cMarkAdPES2ES(recvnumber,"PES2ES audio");
if (!pes2audioes) return;
pes2audioes->Process(Pid,pkt,pktlen,Pkt,PktLen);
- return;
}
if ((Pid.Type==MARKAD_PIDTYPE_VIDEO_H262) || (Pid.Type==MARKAD_PIDTYPE_VIDEO_H264))
@@ -56,14 +55,14 @@ void cMarkAdDemux::ProcessVDR(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt
if (!pes2videoes) pes2videoes=new cMarkAdPES2ES(recvnumber,"PES2ES video",65536);
if (!pes2videoes) return;
pes2videoes->Process(Pid,pkt,pktlen,Pkt,PktLen);
- return;
}
+
return;
}
void cMarkAdDemux::ProcessTS(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen)
{
- if ((!Pkt) || (!PktLen) || (!Data)) return;
+ if ((!Pkt) || (!PktLen)) return;
*Pkt=NULL;
*PktLen=0;
@@ -80,14 +79,24 @@ void cMarkAdDemux::ProcessTS(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt,
if (!pes2audioes) pes2audioes=new cMarkAdPES2ES(recvnumber,"PES2ES audio");
if (!pes2audioes) return;
pes2audioes->Process(Pid,pkt,pktlen,Pkt,PktLen);
- return;
}
- if (pkt)
+ if ((Pid.Type==MARKAD_PIDTYPE_VIDEO_H262) || (Pid.Type==MARKAD_PIDTYPE_VIDEO_H264))
+ {
+ if ((pkt) && ((pkt[3] & 0xF0)==0xE0) && (pkt[4]!=0) && (pkt[5]!=0))
+ {
+ ts2pkt->InjectVideoPES(pkt,pktlen);
+ pkt=NULL;
+ pktlen=0;
+ }
+ }
+
+ if ((pkt) && (!*Pkt))
{
*Pkt=pkt;
*PktLen=pktlen;
}
+
return;
}
diff --git a/markad-standalone.cpp b/markad-standalone.cpp
index 53b400f..94c0d22 100644
--- a/markad-standalone.cpp
+++ b/markad-standalone.cpp
@@ -8,6 +8,8 @@
#include "markad-standalone.h"
+cMarkAdStandalone *cmasta=NULL;
+
void syslog_with_tid(int priority, const char *format, ...)
{
va_list ap;
@@ -57,7 +59,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
while ((dataread=read(f,data,datalen))>0)
{
-
+ if (abort) break;
MarkAdMark *mark;
if (common)
@@ -172,13 +174,19 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
void cMarkAdStandalone::Process(const char *Directory)
{
+ if (abort) return;
for (int i=1; i<=MaxFiles; i++)
{
+ if (abort) break;
if (!ProcessFile(Directory,i))
{
break;
}
}
+ if (abort)
+ {
+ isyslog("markad [%i]: aborted",recvnumber);
+ }
}
bool cMarkAdStandalone::CheckTS(const char *Directory)
@@ -216,60 +224,59 @@ bool cMarkAdStandalone::CheckTS(const char *Directory)
return true;
}
-void cMarkAdStandalone::CheckPATPMT(const char *Directory)
+bool cMarkAdStandalone::CheckPATPMT(const char *Directory)
{
char *buf;
- if (asprintf(&buf,"%s/00001.ts",Directory)==-1) return;
+ if (asprintf(&buf,"%s/00001.ts",Directory)==-1) return false;
int fd=open(buf,O_RDONLY);
free(buf);
- if (fd==-1) return;
+ if (fd==-1) return false;
uchar patpmt[376];
if (read(fd,patpmt,sizeof(patpmt))!=sizeof(patpmt))
{
close(fd);
- return;
+ return false;
}
close(fd);
// some checks
- if ((patpmt[0]!=0x47) || (patpmt[188]!=0x47)) return; // no TS-Sync
- if (((patpmt[1] & 0x5F)!=0x40) && (patpmt[2]!=0)) return; // no PAT
- if ((patpmt[3] & 0x10)!=0x10) return; // PAT not without AFC
- if ((patpmt[191] & 0x10)!=0x10) return; // PMT not without AFC
+ if ((patpmt[0]!=0x47) || (patpmt[188]!=0x47)) return false; // no TS-Sync
+ if (((patpmt[1] & 0x5F)!=0x40) && (patpmt[2]!=0)) return false; // no PAT
+ if ((patpmt[3] & 0x10)!=0x10) return false; // PAT not without AFC
+ if ((patpmt[191] & 0x10)!=0x10) return false; // PMT not without AFC
struct PAT *pat = (struct PAT *) &patpmt[5];
// more checks
- if (pat->reserved1!=3) return; // is always 11
- if (pat->reserved3!=7) return; // is always 111
+ if (pat->reserved1!=3) return false; // is always 11
+ if (pat->reserved3!=7) return false; // is always 111
int pid=pat->pid_L+(pat->pid_H<<8);
int pmtpid=((patpmt[189] & 0x1f)<<8)+patpmt[190];
- if (pid!=pmtpid) return; // pid in PAT differs from pid in PMT
+ if (pid!=pmtpid) return false; // pid in PAT differs from pid in PMT
struct PMT *pmt = (struct PMT *) &patpmt[193];
// still more checks
- if (pmt->reserved1!=3) return; // is always 11
- if (pmt->reserved2!=3) return; // is always 11
- if (pmt->reserved3!=7) return; // is always 111
- if (pmt->reserved4!=15) return; // is always 1111
+ if (pmt->reserved1!=3) return false; // is always 11
+ if (pmt->reserved2!=3) return false; // is always 11
+ if (pmt->reserved3!=7) return false; // is always 111
+ if (pmt->reserved4!=15) return false; // is always 1111
if ((pmt->program_number_H!=pat->program_number_H) ||
- (pmt->program_number_L!=pat->program_number_L)) return;
+ (pmt->program_number_L!=pat->program_number_L)) return false;
int desc_len=(pmt->program_info_length_H<<8)+pmt->program_info_length_L;
- if (desc_len>166) return; // beyond patpmt buffer
+ if (desc_len>166) return false; // beyond patpmt buffer
int section_end = 196+(pmt->section_length_H<<8)+pmt->section_length_L;
section_end-=4; // we don't care about the CRC32
- if (section_end>376) return; //beyond patpmt buffer
+ if (section_end>376) return false; //beyond patpmt buffer
int i=205+desc_len;
-
while (i<section_end)
{
struct ES_DESCRIPTOR *es=NULL;
@@ -281,8 +288,8 @@ void cMarkAdStandalone::CheckPATPMT(const char *Directory)
}
// oh no -> more checks!
- if (si->reserved1!=7) return;
- if (si->reserved2!=15) return;
+ if (si->reserved1!=7) return false;
+ if (si->reserved2!=15) return false;
int pid=(si->PID_H<<8)+si->PID_L;
@@ -318,12 +325,13 @@ void cMarkAdStandalone::CheckPATPMT(const char *Directory)
i+=(sizeof(struct STREAMINFO)+esinfo_len);
}
- return;
+ return true;
}
cMarkAdStandalone::cMarkAdStandalone(const char *Directory)
{
recvnumber=255;
+ abort=false;
memset(&macontext,0,sizeof(macontext));
macontext.General.StartTime=0;
@@ -345,12 +353,15 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory)
if (isTS)
{
- CheckPATPMT(Directory);
+ if (!CheckPATPMT(Directory))
+ {
+ esyslog("markad [%i]: no PAT/PMT found -> nothing to process",recvnumber);
+ abort=true;
+ }
macontext.General.APid.Num=0;
}
else
{
- macontext.General.APid.Num=0;
macontext.General.DPid.Num=-1;
macontext.General.VPid.Num=-1;
macontext.General.VPid.Type=MARKAD_PIDTYPE_VIDEO_H262;
@@ -369,7 +380,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory)
if (macontext.General.APid.Num)
{
- dsyslog("markad [%i]: using mp2 (0x%04x)",recvnumber,macontext.General.APid.Num);
+ dsyslog("markad [%i]: using MP2 (0x%04x)",recvnumber,macontext.General.APid.Num);
mp2_demux = new cMarkAdDemux(recvnumber);
}
else
@@ -379,7 +390,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory)
if (macontext.General.DPid.Num)
{
- dsyslog("markad [%i]: using ac3 (0x%04x)",recvnumber,macontext.General.DPid.Num);
+ dsyslog("markad [%i]: using AC3 (0x%04x)",recvnumber,macontext.General.DPid.Num);
ac3_demux = new cMarkAdDemux(recvnumber);
}
else
@@ -451,6 +462,21 @@ int usage()
return -1;
}
+void signal_handler(int sig)
+{
+ if (sig==SIGUSR1)
+ {
+ // TODO: what we are supposed to do?
+ }
+ else
+ {
+ if (cmasta)
+ {
+ cmasta->SetAbort();
+ }
+ }
+}
+
int main(int argc, char *argv[])
{
int c;
@@ -518,14 +544,17 @@ int main(int argc, char *argv[])
break;
case 'O':
-// osdMsg = 1;
+ // --OSD
+ break;
+
+ case 'o':
+ // --overlap
break;
case 's':
case 'l':
case 'c':
case 'j':
- case 'o':
case 'a':
case 'S':
case 'B':
@@ -552,9 +581,10 @@ int main(int argc, char *argv[])
//setMarkfileName(optarg); // TODO: implement this
break;
- case 2: // --verbose
- //if (isnumber(optarg))
- // verbosity = atoi(optarg);
+ case 2: // --loglevel
+ SysLogLevel=atoi(optarg);
+ if (SysLogLevel>10) SysLogLevel=10;
+ if (SysLogLevel<0) SysLogLevel=2;
break;
case 3: // --testmode
@@ -717,15 +747,6 @@ int main(int argc, char *argv[])
}
}
- // catch some signals
- /*
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
- signal(SIGABRT, signal_handler);
- signal(SIGSEGV, signal_handler);
- signal(SIGUSR1, signal_handler);
- */
-
// now do the work...
struct stat statbuf;
if (stat(recDir,&statbuf)==-1)
@@ -740,13 +761,19 @@ int main(int argc, char *argv[])
return -1;
}
- cMarkAdStandalone *cmasta = new cMarkAdStandalone(recDir);
- if (cmasta)
- {
- cmasta->Process(recDir);
- delete cmasta;
- }
+ cmasta = new cMarkAdStandalone(recDir);
+ if (!cmasta) return -1;
+
+ // ignore some signals
+ signal(SIGHUP, SIG_IGN);
+
+ // catch some signals
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+ signal(SIGUSR1, signal_handler);
+ cmasta->Process(recDir);
+ delete cmasta;
return 0;
}
diff --git a/markad-standalone.h b/markad-standalone.h
index b1dc0ce..145a9ea 100644
--- a/markad-standalone.h
+++ b/markad-standalone.h
@@ -131,15 +131,16 @@ unsigned reserved2:
4;
unsigned ES_info_length_L:
8;
-};
+ };
#pragma pack()
-struct ES_DESCRIPTOR {
+ struct ES_DESCRIPTOR
+ {
unsigned Descriptor_Tag:
8;
unsigned Descriptor_Length:
8;
-};
+ };
cMarkAdDemux *video_demux;
@@ -156,13 +157,18 @@ unsigned Descriptor_Length:
bool isTS;
int MaxFiles;
int framecnt;
+ bool abort;
void AddMark(MarkAdMark *Mark);
- void CheckPATPMT(const char *Directory);
+ bool CheckPATPMT(const char *Directory);
bool CheckTS(const char *Directory);
bool ProcessFile(const char *Directory, int Number);
public:
+ void SetAbort()
+ {
+ abort=true;
+ }
void Process(const char *Directory);
cMarkAdStandalone(const char *Directory);
~cMarkAdStandalone();
diff --git a/pes2es.cpp b/pes2es.cpp
index 8d09e45..724cfea 100644
--- a/pes2es.cpp
+++ b/pes2es.cpp
@@ -41,9 +41,13 @@ void cMarkAdPES2ES::Process(MarkAdPid Pid, uchar *PESData, int PESSize, uchar **
return;
}
- int Length=(peshdr->LenH<<8)+peshdr->LenL+sizeof(PESHDR);
+ if (peshdr->StreamID<=0xBC) return;
+
+ int Length=(peshdr->LenH<<8)+peshdr->LenL;
+ if (Length) Length+=sizeof(PESHDR);
if (Length!=PESSize)
{
+ if ((peshdr->StreamID & 0xF0)==0xE0) return;
Reset();
return;
}
@@ -87,7 +91,6 @@ void cMarkAdPES2ES::Process(MarkAdPid Pid, uchar *PESData, int PESSize, uchar **
buf=&PESData[bpos];
buflen=PESSize-bpos;
}
-
queue->Put(buf,buflen);
}
if (type) *ESData=queue->GetPacket(ESSize,type);
diff --git a/recv.cpp b/recv.cpp
index 48dbd35..7ed56aa 100644
--- a/recv.cpp
+++ b/recv.cpp
@@ -74,7 +74,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T
if (macontext.General.APid.Num)
{
- dsyslog("markad [%i]: using mp2",recvnumber);
+ dsyslog("markad [%i]: using MP2",recvnumber);
mp2_demux = new cMarkAdDemux(RecvNumber);
}
else
@@ -84,7 +84,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T
if (macontext.General.DPid.Num)
{
- dsyslog("markad [%i]: using ac3",recvnumber);
+ dsyslog("markad [%i]: using AC3",recvnumber);
ac3_demux = new cMarkAdDemux(RecvNumber);
}
else
@@ -107,6 +107,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T
marks.Load(Filename);
Index=NULL;
lastiframe=0;
+ framecnt=-1;
}
cMarkAdReceiver::~cMarkAdReceiver()
@@ -324,9 +325,17 @@ void cMarkAdReceiver::Action()
{
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
{
- mark=video->Process(lastiframe);
- AddMark(mark,3);
+ if (framecnt==-1)
+ {
+ framecnt=0;
+ }
+ else
+ {
+ mark=video->Process(lastiframe);
+ AddMark(mark,3);
+ }
}
+ if (framecnt!=-1) framecnt++;
}
}
tspkt+=len;
diff --git a/recv.h b/recv.h
index a5d2658..8060a21 100644
--- a/recv.h
+++ b/recv.h
@@ -57,6 +57,7 @@ private:
int recvnumber;
char *filename;
int lastiframe;
+ int framecnt;
char *strcatrealloc(char *dest, const char *src);
cMarks marks;
diff --git a/tools.cpp b/tools.cpp
index 6828216..6c4edc5 100644
--- a/tools.cpp
+++ b/tools.cpp
@@ -26,6 +26,36 @@ cMarkAdPaketQueue::~cMarkAdPaketQueue()
if (buffer) free(buffer);
}
+bool cMarkAdPaketQueue::Inject(uchar *Data, int Size)
+{
+ if (!buffer) return false;
+ if (outptr>Size)
+ {
+ uchar temp[Size+1];
+ memcpy(temp,Data,Size);
+ outptr-=Size;
+ memcpy(&buffer[outptr],temp,Size);
+ pktinfo.pkthdr=-1;
+ }
+ else
+ {
+ int oldSize=Length();
+ uchar tempold[oldSize+1];
+ memcpy(tempold,&buffer[outptr],oldSize);
+
+ uchar temp[Size+1];
+ memcpy(temp,Data,Size);
+
+ memcpy(buffer,temp,Size);
+ memcpy(buffer+Size,tempold,oldSize);
+
+ inptr=Size+oldSize;
+ outptr=0;
+ pktinfo.pkthdr=-1;
+ }
+ return true;
+}
+
bool cMarkAdPaketQueue::Put(uchar *Data, int Size)
{
if (!buffer) return false;
diff --git a/tools.h b/tools.h
index 4a182cb..90d01e6 100644
--- a/tools.h
+++ b/tools.h
@@ -129,7 +129,9 @@ public:
void Clear()
{
inptr=outptr=0;
+ pktinfo.pkthdr=-1;
}
+ bool Inject(uchar *Data, int Size);
bool Put(uchar *Data, int Size);
uchar *Get(int *Size);
diff --git a/ts2pkt.cpp b/ts2pkt.cpp
index ad26ebe..dc624ee 100644
--- a/ts2pkt.cpp
+++ b/ts2pkt.cpp
@@ -24,8 +24,8 @@ void cMarkAdTS2Pkt::Reset(int ErrIndex)
{
switch (ErrIndex)
{
- case MA_ERR_TOSMALL:
- dsyslog("markad [%i]: input to small",recvnumber);
+ case MA_ERR_TSSIZE:
+ dsyslog("markad [%i]: inbuf not 188 bytes",recvnumber);
break;
case MA_ERR_NOSYNC:
dsyslog("markad [%i]: found no sync",recvnumber);
@@ -37,16 +37,53 @@ void cMarkAdTS2Pkt::Reset(int ErrIndex)
dsyslog("markad [%i]: wrong AFC value",recvnumber);
break;
case MA_ERR_TOBIG:
- dsyslog("markad [%i]: buflen > 188",recvnumber);
+ dsyslog("markad [%i]: buflen > 188 bytes",recvnumber);
break;
case MA_ERR_NEG:
- dsyslog("markad [%i]: buflen < 0",recvnumber);
+ dsyslog("markad [%i]: buflen negative",recvnumber);
break;
}
counter=-1;
if (queue) queue->Clear();
}
+bool cMarkAdTS2Pkt::InjectVideoPES(uchar *PESData, int PESSize)
+{
+ if ((!PESData) || (!PESSize)) return false;
+
+ struct PESHDR *peshdr=(struct PESHDR *) PESData;
+
+ // first check some simple things
+ if ((peshdr->Sync1!=0) && (peshdr->Sync2!=0) && (peshdr->Sync3!=1)) return false;
+ if ((peshdr->StreamID & 0xF0)!=0xE0) return false;
+
+ int Length=(peshdr->LenH<<8)+peshdr->LenL;
+ if (Length) Length+=sizeof(PESHDR);
+ if (Length!=PESSize) return false;
+
+ struct PESHDROPT *peshdropt=(struct PESHDROPT *) &PESData[sizeof(struct PESHDR)];
+
+ uchar *buf;
+ int buflen;
+
+ if (peshdropt->MarkerBits==0x2)
+ {
+ // we have an optional PES header
+ int bpos=sizeof(struct PESHDR)+sizeof(struct PESHDROPT)+
+ peshdropt->Length;
+ buf=&PESData[bpos];
+ buflen=PESSize-bpos;
+ }
+ else
+ {
+ int bpos=sizeof(struct PESHDR);
+ buf=&PESData[bpos];
+ buflen=PESSize-bpos;
+ }
+ queue->Inject(buf,buflen);
+ return true;
+}
+
void cMarkAdTS2Pkt::Process(MarkAdPid Pid, uchar *TSData, int TSSize, uchar **PktData, int *PktSize)
{
if ((!PktData) || (!PktSize) || (!queue)) return;
@@ -57,7 +94,7 @@ void cMarkAdTS2Pkt::Process(MarkAdPid Pid, uchar *TSData, int TSSize, uchar **Pk
{
if (TSSize!=TS_SIZE)
{
- Reset(MA_ERR_TOSMALL);
+ Reset(MA_ERR_TSSIZE);
return; // we need a full packet
}
diff --git a/ts2pkt.h b/ts2pkt.h
index 3d4e49a..13efe54 100644
--- a/ts2pkt.h
+++ b/ts2pkt.h
@@ -58,13 +58,57 @@ unsigned Flags:
8;
};
+ struct PESHDR
+ {
+ uchar Sync1;
+ uchar Sync2;
+ uchar Sync3;
+ uchar StreamID;
+ uchar LenH;
+ uchar LenL;
+ };
+
+#pragma pack(1)
+ struct PESHDROPT
+ {
+unsigned OOC:
+ 1;
+unsigned CY:
+ 1;
+unsigned DAI:
+ 1;
+unsigned PESP:
+ 1;
+unsigned PESSC:
+ 2;
+unsigned MarkerBits:
+ 2;
+unsigned EXT:
+ 1;
+unsigned CRC:
+ 1;
+unsigned ACI:
+ 1;
+unsigned TM:
+ 1;
+unsigned RATE:
+ 1;
+unsigned ESCR:
+ 1;
+unsigned TSF:
+ 2;
+unsigned Length:
+ 8;
+ };
+#pragma pack()
+
int recvnumber;
int counter;
cMarkAdPaketQueue *queue;
#define MA_ERR_STARTUP 0
-#define MA_ERR_TOSMALL 1
+#define MA_ERR_TSSIZE 1
#define MA_ERR_NOSYNC 2
#define MA_ERR_SEQ 3
#define MA_ERR_AFC 4
@@ -75,6 +119,7 @@ public:
cMarkAdTS2Pkt(int RecvNumber, const char *QueueName="TS2Pkt", int QueueSize=32768);
~cMarkAdTS2Pkt();
void Process(MarkAdPid Pid,uchar *TSData, int TSSize, uchar **PktData, int *PktSize);
+ bool InjectVideoPES(uchar *PESData, int PESSize);
};
#endif