From 27b768a40f33b229ee832d22f24696565b812f98 Mon Sep 17 00:00:00 2001 From: Jochen Dolze Date: Sun, 20 Sep 2009 20:30:22 +0200 Subject: First commit --- ts2pes.cpp | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 ts2pes.cpp (limited to 'ts2pes.cpp') diff --git a/ts2pes.cpp b/ts2pes.cpp new file mode 100644 index 0000000..c75b672 --- /dev/null +++ b/ts2pes.cpp @@ -0,0 +1,233 @@ +/* + * 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; + streamsize=0; + counter=-1; + sync=false; +} + +int cMarkAdTS2PES::FindPESHeader(uchar *TSData, int TSSize, int *StreamSize) +{ + unsigned long scanner=0xFFFFFFFF; + int i; + for (i=0; i=0xBC) + { + *StreamSize=(TSData[i+1]<<8)+TSData[i+2]; + if (*StreamSize) (*StreamSize)+=6; // 6 Byte PES-Header + } + } + return i-3; + } + return -1; +} + +int cMarkAdTS2PES::Process(int Pid, uchar *TSData, int TSSize, uchar **PESData, int *PESSize) +{ + if ((!PESData) || (!PESSize)) 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!=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; + } + 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 peshdr=FindPESHeader(pesdata, pessize, &streamsize); + if (peshdr==0) + { + if (!streamsize) + { + peshdr=FindPESHeader(pesdata+3,pessize-3,NULL); + if (peshdr>0) peshdr+=3; + } + else + { + if (pessize>streamsize) + { + int size=pessize-streamsize; + + *PESData=pesdata; + *PESSize=streamsize; + if (pesdatalast) free(pesdatalast); + pesdatalast=pesdata; + pesdata=NULL; + pessize=0; + + void *ptr=malloc(size); + if (!ptr) return -1; + memcpy(ptr,(*PESData)+streamsize,size); + bytes_processed-=size; + pessize=size; + pesdata=(uchar *) ptr; + data_left=true; + streamsize=0; + } + } + } + if (peshdr>0) + { + // start of next PES paket found + if (pesdata) + { + // return old data + *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,(*PESData)+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; +} -- cgit v1.2.3