From c848ab793a302dc067663ec4a06395745e443c9d Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 6 Sep 2008 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.7.1=20-=20Adapted=20the=20tuning=20code=20t?= =?UTF-8?q?o=20the=20new=20DVBFE=5FSET=5FDELSYS=20API=20(thanks=20to=20Rei?= =?UTF-8?q?nhard=20Nissl).=20=20=20VDR=20now=20uses=20the=20driver=20from?= =?UTF-8?q?=20http://jusst.de/hg/multiproto=5Fplus.=20-=20Updated=20the=20?= =?UTF-8?q?Italian=20OSD=20texts=20(thanks=20to=20Diego=20Pierotto).=20-?= =?UTF-8?q?=20Removed=20obsolete=20$(NCURSESLIB)=20from=20the=20Makefile.?= =?UTF-8?q?=20-=20Implemented=20handling=20the=20standard=20component=20de?= =?UTF-8?q?scriptor=20for=20AC3=20(stream=3D4),=20as=20it=20=20=20will=20s?= =?UTF-8?q?oon=20be=20used=20by=20the=20German=20ARD=20channels=20(thanks?= =?UTF-8?q?=20to=20Michael=20Pennewi=C3=9F=20for=20=20=20advance=20informa?= =?UTF-8?q?tion=20about=20this=20change).=20The=20previously=20used=20"Pre?= =?UTF-8?q?miere=20pseudo=20=20=20standard"=20(stream=3D2,=20type=3D5)=20s?= =?UTF-8?q?till=20works,=20but=20has=20apparently=20been=20wrongfully=20us?= =?UTF-8?q?ed=20=20=20by=20broadcasters=20from=20the=20beginning.=20-=20Ad?= =?UTF-8?q?ded=20missing=20description=20of=20the=20'S'=20channel=20parame?= =?UTF-8?q?ter=20to=20vdr.5=20(reported=20by=20=20=20Reinhard=20Nissl).=20?= =?UTF-8?q?-=20The=20SVDRP=20signon=20message=20now=20indicates=20the=20ch?= =?UTF-8?q?aracter=20encoding=20in=20use,=20as=20in=20=20=20"220=20video?= =?UTF-8?q?=20SVDRP=20VideoDiskRecorder=201.7.1;=20Fri=20May=20=202=2016:1?= =?UTF-8?q?7:10=202008;=20ISO-8859-1".=20=20=20This=20may=20be=20useful=20?= =?UTF-8?q?for=20instance=20for=20external=20tools=20that=20provide=20EPG?= =?UTF-8?q?=20data,=20so=20that=20=20=20they=20can=20correctly=20encode=20?= =?UTF-8?q?the=20strings.=20-=20No=20longer=20calling=20FcFini()=20to=20av?= =?UTF-8?q?oid=20problems=20with=20older=20(broken)=20versions=20of=20=20?= =?UTF-8?q?=20fontconfig=20(suggested=20by=20Edgar=20Toernig).=20-=20Remov?= =?UTF-8?q?ed=20the=20compile=20time=20option=20VFAT=20to=20allow=20users?= =?UTF-8?q?=20of=20precompiled=20binary=20=20=20distributions=20to=20have?= =?UTF-8?q?=20full=20control=20over=20whether=20or=20not=20to=20use=20the?= =?UTF-8?q?=20--vfat=20option=20=20=20at=20runtime=20(suggested=20by=20Mic?= =?UTF-8?q?hael=20Nork).=20-=20First=20step=20towards=20switching=20to=20T?= =?UTF-8?q?S=20(Transport=20Stream)=20as=20recording=20format:=20=20=20+?= =?UTF-8?q?=20The=20new=20function=20cDevice::PlayTs()=20is=20used=20to=20?= =?UTF-8?q?play=20TS=20packets.=20=20=20+=20The=20new=20functions=20cDevic?= =?UTF-8?q?e::PlayTsVideo()=20and=20cDevice::PlayTsAudio()=20=20=20=20=20a?= =?UTF-8?q?re=20used=20to=20play=20video=20and=20audio=20TS=20packets,=20r?= =?UTF-8?q?espectively.=20=20=20+=20The=20new=20function=20cAudio::PlayTs(?= =?UTF-8?q?)=20is=20used=20to=20play=20audio=20TS=20packets.=20=20=20+=20T?= =?UTF-8?q?he=20new=20class=20cPatPmtGenerator=20is=20used=20to=20generate?= =?UTF-8?q?=20a=20PAT/PMT=20pair=20that=20precedes=20=20=20=20=20the=20TS?= =?UTF-8?q?=20data=20in=20Transfer=20Mode.=20=20=20+=20The=20new=20class?= =?UTF-8?q?=20cPatPmtParser=20is=20used=20by=20cDevice=20to=20parse=20the?= =?UTF-8?q?=20PAT/PMT=20data=20in=20a=20=20=20=20=20TS=20in=20order=20to?= =?UTF-8?q?=20find=20out=20which=20streams=20it=20contains.=20=20=20+=20Th?= =?UTF-8?q?e=20new=20class=20cTsToPes=20is=20used=20to=20convert=20TS=20pa?= =?UTF-8?q?ckets=20to=20a=20PES=20packet.=20=20=20+=20cTransfer=20no=20lon?= =?UTF-8?q?ger=20uses=20cRemux,=20and=20doesn't=20run=20a=20separate=20thr?= =?UTF-8?q?ead=20any=20more.=20=20=20=20=20It=20just=20generates=20a=20PAT?= =?UTF-8?q?/PMT=20and=20sends=20all=20received=20TS=20packets=20to=20the?= =?UTF-8?q?=20primary=20=20=20=20=20device's=20PlayTs().=20=20=20+=20Live?= =?UTF-8?q?=20subtitle=20display=20no=20longer=20uses=20a=20ring=20buffer?= =?UTF-8?q?=20and=20separate=20thread.=20=20=20+=20cPesAssembler=20has=20b?= =?UTF-8?q?een=20removed.=20Old=20VDR=20recordings=20only=20contain=20comp?= =?UTF-8?q?lete=20PES=20=20=20=20=20packets.=20=20=20+=20Since=20a=20TS=20?= =?UTF-8?q?needs=20to=20have=20a=20PAT/PMT,=20which=20requires=20the=20vid?= =?UTF-8?q?eo=20stream=20type=20to=20=20=20=20=20be=20explicitly=20given,?= =?UTF-8?q?=20the=20format=20of=20the=20VPID=20field=20in=20the=20channels?= =?UTF-8?q?.conf=20file=20=20=20=20=20and=20the=20SVDRP=20commands=20NEWC/?= =?UTF-8?q?MODC/LSTC=20has=20been=20extended.=20The=20video=20stream=20typ?= =?UTF-8?q?e=20=20=20=20=20now=20follows=20the=20VPID=20and=20optional=20P?= =?UTF-8?q?PID,=20separated=20by=20an=20'=3D'=20sign.=20-=20Updated=20the?= =?UTF-8?q?=20sources.conf=20file=20(thanks=20to=20Oleg=20Roitburd).=20-?= =?UTF-8?q?=20Fixed=20a=20possible=20integer=20overflow=20in=20GetAbsTime(?= =?UTF-8?q?)=20(thanks=20to=20Alexander=20Rieger).=20-=20Fixed=20a=20probl?= =?UTF-8?q?em=20with=20calling=20isyslog()=20from=20within=20the=20SignalH?= =?UTF-8?q?andler()=20(thanks=20=20=20to=20Udo=20Richter).=20-=20Replaced?= =?UTF-8?q?=20the=20Finnish=20language=20code=20"smi"=20with=20"suo"=20(th?= =?UTF-8?q?anks=20to=20Rolf=20Ahrenberg).=20-=20Fixed=20wrong=20value=20fo?= =?UTF-8?q?r=20TableIdBAT=20in=20libsi/si.h=20(thanks=20to=20Winfried=20K?= =?UTF-8?q?=C3=B6hler).=20-=20Errors=20in=20config=20files=20no=20longer?= =?UTF-8?q?=20keep=20VDR=20from=20starting.=20-=20Removed=20unneeded=20inc?= =?UTF-8?q?lude=20files=20=20und=20=20from=20remu?= =?UTF-8?q?x.h=20=20=20(reported=20by=20Tobias=20Grimm).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- remux.h | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 3 deletions(-) (limited to 'remux.h') diff --git a/remux.h b/remux.h index d996957..fe792eb 100644 --- a/remux.h +++ b/remux.h @@ -4,14 +4,13 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 2.0 2007/09/02 10:19:06 kls Exp $ + * $Id: remux.h 2.2 2008/09/06 14:48:28 kls Exp $ */ #ifndef __REMUX_H #define __REMUX_H -#include //XXX FIXME: DVB/linux/dvb/dmx.h should include itself!!! -#include +#include "channels.h" #include "ringbuffer.h" #include "tools.h" @@ -81,4 +80,192 @@ public: static int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); }; +// Some TS handling tools. +// The following functions all take a pointer to one complete TS packet. + +#define TS_SYNC_BYTE 0x47 +#define TS_SIZE 188 +#define TS_ADAPT_FIELD_EXISTS 0x20 +#define TS_PAYLOAD_EXISTS 0x10 +#define TS_CONT_CNT_MASK 0x0F +#define TS_PAYLOAD_START 0x40 +#define TS_ERROR 0x80 +#define TS_PID_MASK_HI 0x1F + +inline int TsHasPayload(const uchar *p) +{ + return p[3] & TS_PAYLOAD_EXISTS; +} + +inline int TsPayloadStart(const uchar *p) +{ + return p[1] & TS_PAYLOAD_START; +} + +inline int TsError(const uchar *p) +{ + return p[1] & TS_ERROR; +} + +inline int TsPid(const uchar *p) +{ + return (p[1] & TS_PID_MASK_HI) * 256 + p[2]; +} + +inline int TsPayloadOffset(const uchar *p) +{ + return (p[3] & TS_ADAPT_FIELD_EXISTS) ? p[4] + 5 : 4; +} + +inline int TsGetPayload(const uchar **p) +{ + int o = TsPayloadOffset(*p); + *p += o; + return TS_SIZE - o; +} + +inline int TsContinuityCounter(const uchar *p) +{ + return p[3] & TS_CONT_CNT_MASK; +} + +// Some PES handling tools: +// The following functions that take a pointer to PES data all assume that +// there is enough data so that PesLongEnough() returns true. + +inline bool PesLongEnough(int Length) +{ + return Length >= 6; +} + +inline int PesLength(const uchar *p) +{ + return 6 + p[4] * 256 + p[5]; +} + +inline int PesPayloadOffset(const uchar *p) +{ + return 9 + p[8]; +} + +inline int64_t PesGetPts(const uchar *p) +{ + if ((p[7] & 0x80) && p[8] >= 5) { + return ((((int64_t)p[ 9]) & 0x0E) << 29) | + (( (int64_t)p[10]) << 22) | + ((((int64_t)p[11]) & 0xFE) << 14) | + (( (int64_t)p[12]) << 7) | + ((((int64_t)p[13]) & 0xFE) >> 1); + } + return 0; +} + +// PAT/PMT Generator: + +#define MAX_SECTION_SIZE 4096 // maximum size of an SI section +#define MAX_PMT_TS (MAX_SECTION_SIZE / TS_SIZE + 1) + +class cPatPmtGenerator { +private: + uchar pat[TS_SIZE]; // the PAT always fits into a single TS packet + uchar pmt[MAX_PMT_TS][TS_SIZE]; // the PMT may well extend over several TS packets + int numPmtPackets; + int patCounter; + int pmtCounter; + int patVersion; + int pmtVersion; + uchar *esInfoLength; + void IncCounter(int &Counter, uchar *TsPacket); + void IncVersion(int &Version); + void IncEsInfoLength(int Length); +protected: + int MakeStream(uchar *Target, uchar Type, int Pid); + int MakeAC3Descriptor(uchar *Target); + int MakeSubtitlingDescriptor(uchar *Target, const char *Language); + int MakeLanguageDescriptor(uchar *Target, const char *Language); + int MakeCRC(uchar *Target, const uchar *Data, int Length); +public: + cPatPmtGenerator(void); + void GeneratePat(void); + ///< Generates a PAT section for later use with GetPat(). + ///< This function is called by default from the constructor. + void GeneratePmt(tChannelID ChannelID); + ///< Generates a PMT section for the given ChannelId, for later use + ///< with GetPmt(). + uchar *GetPat(void); + ///< Returns a pointer to the PAT section, which consist of exactly + ///< one TS packet. + uchar *GetPmt(int &Index); + ///< Returns a pointer to the Index'th TS packet of the PMT section. + ///< Index must be initialized to 0 and will be incremented by each + ///< call to GetPmt(). Returns NULL is all packets of the PMT section + ///< have been fetched.. + }; + +// PAT/PMT Parser: + +class cPatPmtParser { +private: + uchar pmt[MAX_SECTION_SIZE]; + int pmtSize; + int pmtPid; + int vpid; + int vtype; +protected: + int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } +public: + cPatPmtParser(void); + void ParsePat(const uchar *Data, int Length); + ///< Parses the given PAT Data, which is the payload of a single TS packet + ///< from the PAT stream. The PAT may consist only of a single TS packet. + void ParsePmt(const uchar *Data, int Length); + ///< Parses the given PMT Data, which is the payload of a single TS packet + ///< from the PMT stream. The PMT may consist of several TS packets, which + ///< are delivered to the parser through several subsequent calls to + ///< ParsePmt(). The whole PMT data will be processed once the last packet + ///< has been received. + int PmtPid(void) { return pmtPid; } + ///< Returns the PMT pid as defined by the current PAT. + ///< If no PAT has been received yet, -1 will be returned. + int Vpid(void) { return vpid; } + ///< Returns the video pid as defined by the current PMT. + int Vtype(void) { return vtype; } + }; + +// TS to PES converter: +// Puts together the payload of several TS packets that form one PES +// packet. + +class cTsToPes { +private: + uchar *data; + int size; + int length; + bool synced; +public: + cTsToPes(void); + ~cTsToPes(); + void PutTs(const uchar *Data, int Length); + ///< Puts the payload data of the single TS packet at Data into the converter. + ///< Length is always 188. + ///< If the given TS packet starts a new PES payload packet, the converter + ///< will be automatically reset. Any packets before the first one that starts + ///< a new PES payload packet will be ignored. + const uchar *GetPes(int &Length); + ///< Gets a pointer to the complete PES packet, or NULL if the packet + ///< is not complete yet. If the packet is complete, Length will contain + ///< the total packet length. The returned pointer is only valid until + ///< the next call to PutTs() or Reset(), or until this object is destroyed. + void Reset(void); + ///< Resets the converter. This needs to be called after a PES packet has + ///< been fetched by a call to GetPes(), and before the next call to + ///< PutTs(). + }; + +// Some helper functions for debugging: + +void BlockDump(const char *Name, const u_char *Data, int Length); +void TsDump(const char *Name, const u_char *Data, int Length); +void PesDump(const char *Name, const u_char *Data, int Length); + #endif // __REMUX_H -- cgit v1.2.3