From 404b1e87e9d1f8854cbbd5a438ec4791b6ed296b Mon Sep 17 00:00:00 2001 From: Jochen Dolze Date: Fri, 25 Sep 2009 21:25:30 +0200 Subject: Updated demux, ts2pkt --- Makefile | 2 +- demux.cpp | 67 ++++++++--- demux.h | 21 +++- markad-standalone.cpp | 60 +++++++--- recv.cpp | 12 +- ts2pes.cpp | 269 ----------------------------------------- ts2pes.h | 107 ----------------- ts2pkt.cpp | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++ ts2pkt.h | 127 ++++++++++++++++++++ 9 files changed, 562 insertions(+), 426 deletions(-) delete mode 100644 ts2pes.cpp delete mode 100644 ts2pes.h create mode 100644 ts2pkt.cpp create mode 100644 ts2pkt.h diff --git a/Makefile b/Makefile index a55426c..4c17bcd 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ endif ### The object files (add further files here): OBJS-CMD = markad-standalone.o -OBJS-COMMON = demux.o video.o audio.o decoder.o common.o ts2pes.o pes2audioes.o +OBJS-COMMON = demux.o video.o audio.o decoder.o common.o ts2pkt.o pes2audioes.o OBJS = $(PLUGIN).o recv.o status.o $(OBJS-COMMON) ### The main target: diff --git a/demux.cpp b/demux.cpp index 96748a2..a0aec72 100644 --- a/demux.cpp +++ b/demux.cpp @@ -8,38 +8,67 @@ #include "demux.h" -cMarkAdDemux::cMarkAdDemux() +cMarkAdDemux::cMarkAdDemux(int RecvNumber) { - ts2pes=new cMarkAdTS2PES(); + ts2pkt=new cMarkAdTS2Pkt(RecvNumber); pes2audioes=NULL; - pespkt=NULL; + pkt=NULL; pesptr=NULL; - peslen=0; + pktlen=0; + tsdata=tsptr=NULL; + tssize=0; } cMarkAdDemux::~cMarkAdDemux() { - if (ts2pes) delete ts2pes; + if (ts2pkt) delete ts2pkt; if (pes2audioes) delete pes2audioes; + if (tsdata) free(tsdata); } int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen) { - if ((!Data) && (!Count) && (!ts2pes) && (!pes2audioes) || + if ((!Data) && (!Count) && (!ts2pkt) && (!pes2audioes) || (!Pkt) || (!PktLen) || (!Pid.Num)) return -1; *Pkt=NULL; *PktLen=0; int len=-1; // we don't want loops - if (!peslen) + if (!pktlen) { - len=ts2pes->Process(Pid,Data,Count,&pespkt,&peslen); + if (tssizeProcess(Pid,tsdata,tssize,&pkt,&pktlen); + + int bufleftsize=tssize-len; + uchar *ptr=(uchar *) malloc(bufleftsize); + if (!ptr) return -1; + memcpy(ptr,tsdata+len,bufleftsize); + + free(tsdata); + tsdata=ptr; + tssize=bufleftsize; + if (tssize=0xc0) && (pespkt[3]<=0xDF)) || (pespkt[3]==0xBD)) + if ((((pkt[3]>=0xc0) && (pkt[3]<=0xDF)) || (pkt[3]==0xBD)) && (!pesptr)) { if (!pes2audioes) @@ -48,7 +77,7 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in } if (pes2audioes) { - pesptr=pespkt; + pesptr=pkt; } else { @@ -61,9 +90,9 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in if (len==-1) len=0; uchar *esdata; int essize; - while (peslen>0) + while (pktlen>0) { - int len2=pes2audioes->Process(pesptr,peslen,&esdata,&essize); + int len2=pes2audioes->Process(pesptr,pktlen,&esdata,&essize); if (len2<0) { break; @@ -76,8 +105,8 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in *PktLen=essize; } pesptr+=len2; - peslen-=len2; - if (!peslen) pesptr=NULL; + pktlen-=len2; + if (!pktlen) pesptr=NULL; break; } } @@ -85,10 +114,10 @@ int cMarkAdDemux::Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, in } else { - *Pkt=pespkt; - *PktLen=peslen; - pespkt=pesptr=NULL; - peslen=0; + *Pkt=pkt; + *PktLen=pktlen; + pkt=pesptr=NULL; + pktlen=0; } } return len; diff --git a/demux.h b/demux.h index 00e8727..d0b8265 100644 --- a/demux.h +++ b/demux.h @@ -9,20 +9,29 @@ #ifndef __demux_h_ #define __demux_h_ +#ifndef TS_SIZE +#define TS_SIZE 188 +#endif + #include "global.h" -#include "ts2pes.h" +#include "ts2pkt.h" #include "pes2audioes.h" class cMarkAdDemux { private: - cMarkAdTS2PES *ts2pes; + cMarkAdTS2Pkt *ts2pkt; cMarkAdPES2AudioES *pes2audioes; - uchar *pespkt; - uchar *pesptr; // pointer into pespkt - int peslen; + uchar *pkt; + uchar *pesptr; // pointer into pkt + + uchar *tsdata; + int tssize; + uchar *tsptr; + + int pktlen; public: - cMarkAdDemux(); + cMarkAdDemux(int RecvNumber); ~cMarkAdDemux(); int Process(MarkAdPid Pid, uchar *Data, int Count, uchar **Pkt, int *PktLen); }; diff --git a/markad-standalone.cpp b/markad-standalone.cpp index ed57ceb..3e6e8d1 100644 --- a/markad-standalone.cpp +++ b/markad-standalone.cpp @@ -125,16 +125,23 @@ bool cMarkAdStandalone::ProcessFile(int Number) if (!dir) return false; if (!Number) return false; - uchar data[2048]; + uchar *data; int datalen; + int dataread; char *fbuf; if (index->isTS()) { + datalen=70688; // multiple of 188 + data=(uchar *) malloc(datalen); + if (!data) return false; asprintf(&fbuf,"%s/%05i.ts",dir,Number); } else { + datalen=69632; // VDR paket size + data=(uchar *) malloc(datalen); + if (!data)return false; asprintf(&fbuf,"%s/%03i.vdr",dir,Number); } if (!fbuf) return false; @@ -144,10 +151,10 @@ bool cMarkAdStandalone::ProcessFile(int Number) if (f==-1) return false; int lastiframe; - while ((datalen=read(f,&data,sizeof(data))>0)) + while ((dataread=read(f,data,datalen))>0) { - lastiframe=LastIFrame(Number,lseek(f,0,SEEK_CUR)-datalen); + lastiframe=LastIFrame(Number,lseek(f,0,SEEK_CUR)-dataread); MarkAdMark *mark; if (common) @@ -162,7 +169,7 @@ bool cMarkAdStandalone::ProcessFile(int Number) int pktlen; uchar *tspkt = data; - int tslen = datalen; + int tslen = dataread; while (tslen>0) { @@ -180,7 +187,6 @@ bool cMarkAdStandalone::ProcessFile(int Number) { mark=video->Process(lastiframe); AddMark(mark); - } } tspkt+=len; @@ -195,7 +201,7 @@ bool cMarkAdStandalone::ProcessFile(int Number) int pktlen; uchar *tspkt = data; - int tslen = datalen; + int tslen = dataread; while (tslen>0) { @@ -226,7 +232,7 @@ bool cMarkAdStandalone::ProcessFile(int Number) int pktlen; uchar *tspkt = data; - int tslen = datalen; + int tslen = dataread; while (tslen>0) { @@ -250,8 +256,9 @@ bool cMarkAdStandalone::ProcessFile(int Number) tslen-=len; } } - } + } } + free(data); close(f); return true; } @@ -279,30 +286,47 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory) { dir=strdup(Directory); + index = new cMarkAdIndex(Directory); + if (!index) + { + video_demux=ac3_demux=mp2_demux=NULL; + decoder=NULL; + video=NULL; + audio=NULL; + common=NULL; + return; + } + memset(&macontext,0,sizeof(macontext)); macontext.General.StartTime=0; macontext.General.EndTime=time(NULL)+(7*86400); macontext.General.DPid.Type=MARKAD_PIDTYPE_AUDIO_AC3; macontext.General.APid.Type=MARKAD_PIDTYPE_AUDIO_MP2; - macontext.General.VPid.Type=MARKAD_PIDTYPE_VIDEO_H262; + if (index->isTS()) + { + macontext.General.VPid.Type=MARKAD_PIDTYPE_VIDEO_H264; + } + else + { + macontext.General.VPid.Type=MARKAD_PIDTYPE_VIDEO_H262; + } - macontext.General.VPid.Num=0x100; - macontext.General.DPid.Num=0x102; - macontext.General.APid.Num=0x101; + macontext.General.VPid.Num=0x3ff; +// macontext.General.DPid.Num=0x403; + macontext.General.APid.Num=0x0; - video_demux = new cMarkAdDemux(); + video_demux = new cMarkAdDemux(255); -// mp2_demux = new cMarkAdDemux(); +// mp2_demux = new cMarkAdDemux(255); mp2_demux=NULL; - ac3_demux = new cMarkAdDemux(); - decoder = new cMarkAdDecoder(255,false,false); + ac3_demux = new cMarkAdDemux(255); + decoder = new cMarkAdDecoder(255,index->isTS(), + macontext.General.DPid.Num!=0); video = new cMarkAdVideo(255,&macontext); audio = new cMarkAdAudio(255,&macontext); common = new cMarkAdCommon(255,&macontext); - - index = new cMarkAdIndex(Directory); } cMarkAdStandalone::~cMarkAdStandalone() diff --git a/recv.cpp b/recv.cpp index 447d82a..f105aa4 100644 --- a/recv.cpp +++ b/recv.cpp @@ -55,7 +55,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T } // macontext.General.APid.Pid=Timer->Channel()->Apid(0); // TODO ... better solution? -// macontext.General.DPid.Type=MARKAD_PIDTYPE_AUDIO_MP2; +// macontext.General.APid.Type=MARKAD_PIDTYPE_AUDIO_MP2; macontext.General.DPid.Num=Timer->Channel()->Dpid(0); // TODO ... better solution? macontext.General.DPid.Type=MARKAD_PIDTYPE_AUDIO_AC3; @@ -64,9 +64,9 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T if (macontext.General.VPid.Num) { - dsyslog("markad [%i]: using video",recvnumber); + dsyslog("markad [%i]: using %s-video",recvnumber,useH264 ? "H262": "H264"); video=new cMarkAdVideo(RecvNumber,&macontext); - video_demux = new cMarkAdDemux(); + video_demux = new cMarkAdDemux(RecvNumber); } else { @@ -77,7 +77,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T if (macontext.General.APid.Num) { dsyslog("markad [%i]: using mp2",recvnumber); - mp2_demux = new cMarkAdDemux(); + mp2_demux = new cMarkAdDemux(RecvNumber); } else { @@ -87,7 +87,7 @@ cMarkAdReceiver::cMarkAdReceiver(int RecvNumber, const char *Filename, cTimer *T if (macontext.General.DPid.Num) { dsyslog("markad [%i]: using ac3",recvnumber); - ac3_demux = new cMarkAdDemux(); + ac3_demux = new cMarkAdDemux(RecvNumber); } else { @@ -274,7 +274,7 @@ void cMarkAdReceiver::Action() } if (t.Elapsed()>100) { - isyslog("markad [%i]: 100ms exceeded -> %Li", + isyslog("markad [%i]: 100ms exceeded -> %Lims", recvnumber,t.Elapsed()); } } diff --git a/ts2pes.cpp b/ts2pes.cpp deleted file mode 100644 index 702fff8..0000000 --- a/ts2pes.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - * ts2pes.cpp: A plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id$ - */ - -#include "ts2pes.h" - -#include - -cMarkAdTS2PES::cMarkAdTS2PES() -{ - pesdata=NULL; - pesdatalast=NULL; - Reset(); -} - -cMarkAdTS2PES::~cMarkAdTS2PES() -{ - if (pesdata) free(pesdata); - if (pesdatalast) free(pesdatalast); -} - -void cMarkAdTS2PES::Reset() -{ - if (pesdata) free(pesdata); - pesdata=NULL; - pessize=0; - data_left=false; - counter=-1; - sync=false; -} - -int cMarkAdTS2PES::FindPESHeader(uchar *TSData, int TSSize, int *StreamSize, - int *HeaderSize) -{ - if ((!TSData) || (!TSSize)) return -1; -#define PESHDRSIZE 6 - if (StreamSize) (*StreamSize)=0; - if (HeaderSize) (*HeaderSize)=3; - //unsigned long scanner=0xFFFFFFFF; - int i=0; -long scanner=-1; - - for (i=0; i=0xBC) - { - (*StreamSize)=(TSData[i+1]<<8)+TSData[i+2]; - if (*StreamSize) (*StreamSize)+=6; // 6 Byte PES-Header - } - } - if ((HeaderSize) && ((i+6)MarkerBits==0x2) - { - (*HeaderSize)=PESHDRSIZE+sizeof(struct PESHDROPT)+ - peshdropt->Length; - } - else - { - (*HeaderSize)=PESHDRSIZE; - } - } - return i-3; - } - return -1; -} - -int cMarkAdTS2PES::Process(MarkAdPid Pid, uchar *TSData, int TSSize, uchar **PESData, int *PESSize) -{ - if ((!PESData) || (!PESSize) || (!TSData) || (!TSSize)) return -1; - *PESData=NULL; - *PESSize=0; - - int buflen=TS_SIZE+1; - uchar *buf=NULL; - - int bytes_processed; - - if (!data_left) - { - // search for TS packet sync - int i; - for (i=0; iPidH << 8) | tshdr->PidL; - if (Pid.Num!=pid) - { - return TS_SIZE; // not for us - } - - if ((tshdr->PayloadStart==0) && (!sync)) - { - return TS_SIZE; - } - else - { - sync=true; - } - - if ((counter!=-1) && (((counter+1) & 0xF)!=tshdr->Counter)) - { - // sequence error - Reset(); - return TS_SIZE; - } - counter=tshdr->Counter; - - if ((tshdr->AFC<=0) || (tshdr->AFC>3)) - { - Reset(); - return TS_SIZE; - } - - // we just ignore the infos in the adaption field (e.g. OPCR/PCR) - if ((tshdr->AFC!=1) && (tshdr->AFC!=3)) - { - return TS_SIZE; - } - - if (tshdr->AFC==1) - { - // payload only - buflen=TS_SIZE-sizeof(struct TSHDR); - buf=&TSData[sizeof(struct TSHDR)]; - } - - if (tshdr->AFC==3) - { - // adaption field + payload - struct TSADAPT *tsadapt = (struct TSADAPT *) &TSData[4]; - int alen=tsadapt->Len+1; - buflen=TS_SIZE-(sizeof(struct TSHDR)+alen); - buf=&TSData[sizeof(struct TSHDR)+alen]; - } - - if (buflen>TS_SIZE) - { - // size to large - Reset(); - return TS_SIZE; - } - if (buflen<0) - { - // error in size - Reset(); - return TS_SIZE; - } - - bytes_processed=TS_SIZE-buflen; - - pesdata=(uchar *) realloc(pesdata,pessize+buflen); - if (!pesdata) - { - pessize=0; - return -1; - } - memcpy(pesdata+pessize,buf,buflen); - pessize+=buflen; - bytes_processed+=buflen; - } - else - { - bytes_processed=pessize; - data_left=false; - } - - int streamsize=0; - int peshdrsize=3; // size of sync (just as start) - int peshdr=FindPESHeader(pesdata, pessize, &streamsize, &peshdrsize); - - if (peshdr==0) - { - if (!streamsize) - { - peshdr=FindPESHeader(pesdata+peshdrsize,pessize-peshdrsize,NULL,NULL); - if (peshdr>=0) - { - peshdr+=peshdrsize; - } - } - else - { - if (pessize>streamsize) - { - int size=pessize-streamsize; - uchar *pesptr=pesdata; - *PESData=pesdata; - *PESSize=streamsize; - if (pesdatalast) free(pesdatalast); - pesdatalast=pesdata; - pesdata=NULL; - pessize=0; - - void *ptr=malloc(size); - if (!ptr) return -1; - memcpy(ptr,pesptr+streamsize,size); - bytes_processed-=size; - pessize=size; - pesdata=(uchar *) ptr; - data_left=true; - } - } - } - - if (peshdr>0) - { - // start of next PES paket found - if (pesdata) - { - if ((pesdata[0]==0) && (pesdata[1]==0) && (pesdata[2]==1)) - { - // return old data - uchar *pesptr=pesdata; - *PESData=pesdata; - *PESSize=peshdr; - if (pesdatalast) free(pesdatalast); - pesdatalast=pesdata; - int size=pessize-peshdr; - pesdata=NULL; - pessize=0; - - if (size>0) - { - void *ptr=malloc(size); - if (!ptr) return -1; - memcpy(ptr,pesptr+peshdr,size); - bytes_processed-=size; - pessize=size; - pesdata=(uchar *) ptr; - data_left=true; - } - else - { - // TODO: not sure if this is ok - bytes_processed-=size; - } - } - } - } - return bytes_processed; -} diff --git a/ts2pes.h b/ts2pes.h deleted file mode 100644 index 2511eb3..0000000 --- a/ts2pes.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ts2pes.h: A plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - * - * $Id$ - */ - -#ifndef __ts2pes_h_ -#define __ts2pes_h_ - -#ifndef TS_SIZE -#define TS_SIZE 188 -#endif - -#ifndef uchar -typedef unsigned char uchar; -#endif - -#include -#include - -#include "global.h" - -class cMarkAdTS2PES -{ -private: - struct TSHDR - { -unsigned Sync: - 8; -unsigned PidH: - 5; -unsigned Priority: - 1; -unsigned PayloadStart: - 1; -unsigned TError: - 1; -unsigned PidL: - 8; -unsigned Counter: - 4; -unsigned AFC: - 2; -unsigned TSC: - 2; - }; - - struct TSADAPT - { -unsigned Len: - 8; -unsigned Flags: - 8; - }; - -#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() - - uchar *pesdatalast; - uchar *pesdata; - int pessize; - bool data_left; - int counter; - bool sync; - - void Reset(); - int FindPESHeader(uchar *TSData, int TSSize, int *StreamSize, int *HeaderSize); -public: - cMarkAdTS2PES(); - ~cMarkAdTS2PES(); - int Process(MarkAdPid Pid,uchar *TSData, int TSSize, uchar **PESData, int *PESSize); -}; - -#endif diff --git a/ts2pkt.cpp b/ts2pkt.cpp new file mode 100644 index 0000000..08139b6 --- /dev/null +++ b/ts2pkt.cpp @@ -0,0 +1,323 @@ +/* + * ts2pkt.cpp: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id$ + */ + +#include "ts2pkt.h" + +cMarkAdTS2Pkt::cMarkAdTS2Pkt(int RecvNumber) +{ + recvnumber=RecvNumber; + pktdata=NULL; + pktdatalast=NULL; + Reset(); +} + +cMarkAdTS2Pkt::~cMarkAdTS2Pkt() +{ + if (pktdata) free(pktdata); + if (pktdatalast) free(pktdatalast); +} + +void cMarkAdTS2Pkt::Reset(int ErrIndex) +{ + switch (ErrIndex) + { + case MA_ERR_TOSMALL: + dsyslog("markad [%i]: input to small",recvnumber); + break; + case MA_ERR_NOSYNC: + dsyslog("markad [%i]: found no sync",recvnumber); + break; + case MA_ERR_SEQ: + dsyslog("markad [%i]: sequence error",recvnumber); + break; + case MA_ERR_AFC: + dsyslog("markad [%i]: wrong AFC value",recvnumber); + break; + case MA_ERR_TOBIG: + dsyslog("markad [%i]: buflen > 188",recvnumber); + break; + case MA_ERR_NEG: + dsyslog("markad [%i]: buflen < 0",recvnumber); + break; + case MA_ERR_MEM: + dsyslog("markad [%i]: out of memory",recvnumber); + break; + } + + if (pktdata) free(pktdata); + pktdata=NULL; + pktsize=0; + dataleft=false; + counter=-1; + pktinfo.pkthdr=-1; + isPES=false; +} + +bool cMarkAdTS2Pkt::CheckStreamID(MarkAdPid Pid, uchar *Data, int Size) +{ + if ((!Data) || (!Size)) return false; + if (Size<3) return false; + int streamid=Data[3]; + + switch (Pid.Type) + { + case MARKAD_PIDTYPE_AUDIO_AC3: + if (streamid!=0xBD) return false; + return true; + break; + case MARKAD_PIDTYPE_AUDIO_MP2: + if ((streamid & 0xF0)!=0xC0) return false; + return true; + break; + case MARKAD_PIDTYPE_VIDEO_H262: + case MARKAD_PIDTYPE_VIDEO_H264: + if ((streamid>=0xBC) && (streamid<0xE0)) return false; + if (streamid>0xEF) return false; + return true; + break; + default: + return false; + } + return false; +} + +int cMarkAdTS2Pkt::FindPktHeader(uchar *Data, int Size, int *StreamSize, + int *HeaderSize) +{ +#define PESHDRSIZE 6 + if ((!Data) || (!Size)) return -1; + if (StreamSize) (*StreamSize)=0; + if (HeaderSize) (*HeaderSize)=3; + + unsigned long scanner=0xFFFFFFFF; + int i; + + for (i=0; i=0xBC) // do we have a PES packet? + { + (*StreamSize)=(Data[i+1]<<8)+Data[i+2]; + if (*StreamSize) (*StreamSize)+=PESHDRSIZE; // 6 Byte PES-Header + + if ((HeaderSize) && ((i+PESHDRSIZE)MarkerBits==0x2) + { + (*HeaderSize)=PESHDRSIZE+sizeof(struct PESHDROPT)+ + peshdropt->Length; + } + else + { + (*HeaderSize)=PESHDRSIZE; + } + } + } + } + return i-3; + } + return -1; +} + +int cMarkAdTS2Pkt::Process(MarkAdPid Pid, uchar *TSData, int TSSize, uchar **PktData, int *PktSize) +{ + if ((!PktData) || (!PktSize) || (!TSData) || (!TSSize)) return -1; + *PktData=NULL; + *PktSize=0; + + int buflen=TS_SIZE+1; + uchar *buf=NULL; + + int bytes_processed; // pointer in TSData + + if (!dataleft) + { + if (TSSizePidH << 8) | tshdr->PidL; + if (Pid.Num!=pid) + { + return TS_SIZE; // not for us + } + + if ((counter!=-1) && (((counter+1) & 0xF)!=tshdr->Counter)) + { + // sequence error + Reset(MA_ERR_SEQ); + return TS_SIZE; + } + counter=tshdr->Counter; + + if ((tshdr->AFC<=0) || (tshdr->AFC>3)) + { + Reset(MA_ERR_AFC); + return TS_SIZE; + } + + // we just ignore the infos in the adaption field (e.g. OPCR/PCR) + if ((tshdr->AFC!=1) && (tshdr->AFC!=3)) + { + return TS_SIZE; + } + + if (tshdr->AFC==1) + { + // payload only + buflen=TS_SIZE-sizeof(struct TSHDR); + buf=&TSData[sizeof(struct TSHDR)]; + } + + if (tshdr->AFC==3) + { + // adaption field + payload + struct TSADAPT *tsadapt = (struct TSADAPT *) &TSData[4]; + int alen=tsadapt->Len+1; + buflen=TS_SIZE-(sizeof(struct TSHDR)+alen); + buf=&TSData[sizeof(struct TSHDR)+alen]; + } + + if (buflen>TS_SIZE) + { + // size to large + Reset(MA_ERR_TOBIG); + return TS_SIZE; + } + if (buflen<0) + { + // error in size + Reset(MA_ERR_NEG); + return TS_SIZE; + } + + } + pktdata=(uchar *) realloc(pktdata,pktsize+buflen); + if (!pktdata) + { + Reset(MA_ERR_MEM); + return -1; + } + memcpy(pktdata+pktsize,buf,buflen); + pktsize+=buflen; + if (isPES) + { + bytes_processed=buflen; + } + else + { + bytes_processed=TS_SIZE; + } + } + else + { + bytes_processed=pktsize; + dataleft=false; + } + + if (pktinfo.pkthdr==-1) + { + pktinfo.pkthdr=FindPktHeader(pktdata, pktsize, &pktinfo.streamsize, &pktinfo.pkthdrsize); + if (pktinfo.pkthdr==-1) + { + return bytes_processed; // not found any header -> next paket + } + } + + int streamsize=0; + int pkthdrsize; + int pkthdr=FindPktHeader(pktdata+pktinfo.pkthdr+pktinfo.pkthdrsize, + pktsize-(pktinfo.pkthdr+pktinfo.pkthdrsize),&streamsize,&pkthdrsize); + + if (pkthdr==-1) + { + return bytes_processed; // no next header -> next packet + } + + pkthdr+=(pktinfo.pkthdrsize+pktinfo.pkthdr); + + // found paket between pktinfo.pkthdr and pkthdr + int size = pkthdr-pktinfo.pkthdr; + if (size + +#ifndef TS_SIZE +#define TS_SIZE 188 +#endif + +#ifndef uchar +typedef unsigned char uchar; +#endif + +#include +#include + +#include "global.h" + +class cMarkAdTS2Pkt +{ +private: + struct TSHDR + { +unsigned Sync: + 8; +unsigned PidH: + 5; +unsigned Priority: + 1; +unsigned PayloadStart: + 1; +unsigned TError: + 1; +unsigned PidL: + 8; +unsigned Counter: + 4; +unsigned AFC: + 2; +unsigned TSC: + 2; + }; + + struct TSADAPT + { +unsigned Len: + 8; +unsigned Flags: + 8; + }; + +#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() + + struct pktinfo + { + int pkthdr; + int pkthdrsize; + int streamsize; + } pktinfo; + + int recvnumber; + + bool isPES; + uchar *pktdatalast; + uchar *pktdata; + int pktsize; + bool dataleft; + int counter; + +#define MA_ERR_STARTUP 0 +#define MA_ERR_TOSMALL 1 +#define MA_ERR_NOSYNC 2 +#define MA_ERR_SEQ 3 +#define MA_ERR_AFC 4 +#define MA_ERR_TOBIG 5 +#define MA_ERR_NEG 6 +#define MA_ERR_MEM 7 + void Reset(int ErrIndex=MA_ERR_STARTUP); + int FindPktHeader(uchar *TSData, int TSSize, int *StreamSize, int *HeaderSize); + bool CheckStreamID(MarkAdPid Pid, uchar *Data, int Size); +public: + cMarkAdTS2Pkt(int RecvNumber); + ~cMarkAdTS2Pkt(); + int Process(MarkAdPid Pid,uchar *TSData, int TSSize, uchar **PktData, int *PktSize); +}; + +#endif -- cgit v1.2.3