diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2008-09-06 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2008-09-06 18:00:00 +0200 |
commit | c848ab793a302dc067663ec4a06395745e443c9d (patch) | |
tree | a6c65facbf68864b9523152560a4ae23a6ad2f16 /remux.h | |
parent | 771986b89fc19b4ae65179ccf7dd8082512f8b7d (diff) | |
download | vdr-patch-lnbsharing-c848ab793a302dc067663ec4a06395745e443c9d.tar.gz vdr-patch-lnbsharing-c848ab793a302dc067663ec4a06395745e443c9d.tar.bz2 |
Version 1.7.1vdr-1.7.1
- Adapted the tuning code to the new DVBFE_SET_DELSYS API (thanks to Reinhard Nissl).
VDR now uses the driver from http://jusst.de/hg/multiproto_plus.
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Removed obsolete $(NCURSESLIB) from the Makefile.
- Implemented handling the standard component descriptor for AC3 (stream=4), as it
will soon be used by the German ARD channels (thanks to Michael Pennewiß for
advance information about this change). The previously used "Premiere pseudo
standard" (stream=2, type=5) still works, but has apparently been wrongfully used
by broadcasters from the beginning.
- Added missing description of the 'S' channel parameter to vdr.5 (reported by
Reinhard Nissl).
- The SVDRP signon message now indicates the character encoding in use, as in
"220 video SVDRP VideoDiskRecorder 1.7.1; Fri May 2 16:17:10 2008; ISO-8859-1".
This may be useful for instance for external tools that provide EPG data, so that
they can correctly encode the strings.
- No longer calling FcFini() to avoid problems with older (broken) versions of
fontconfig (suggested by Edgar Toernig).
- Removed the compile time option VFAT to allow users of precompiled binary
distributions to have full control over whether or not to use the --vfat option
at runtime (suggested by Michael Nork).
- First step towards switching to TS (Transport Stream) as recording format:
+ The new function cDevice::PlayTs() is used to play TS packets.
+ The new functions cDevice::PlayTsVideo() and cDevice::PlayTsAudio()
are used to play video and audio TS packets, respectively.
+ The new function cAudio::PlayTs() is used to play audio TS packets.
+ The new class cPatPmtGenerator is used to generate a PAT/PMT pair that precedes
the TS data in Transfer Mode.
+ The new class cPatPmtParser is used by cDevice to parse the PAT/PMT data in a
TS in order to find out which streams it contains.
+ The new class cTsToPes is used to convert TS packets to a PES packet.
+ cTransfer no longer uses cRemux, and doesn't run a separate thread any more.
It just generates a PAT/PMT and sends all received TS packets to the primary
device's PlayTs().
+ Live subtitle display no longer uses a ring buffer and separate thread.
+ cPesAssembler has been removed. Old VDR recordings only contain complete PES
packets.
+ Since a TS needs to have a PAT/PMT, which requires the video stream type to
be explicitly given, the format of the VPID field in the channels.conf file
and the SVDRP commands NEWC/MODC/LSTC has been extended. The video stream type
now follows the VPID and optional PPID, separated by an '=' sign.
- Updated the sources.conf file (thanks to Oleg Roitburd).
- Fixed a possible integer overflow in GetAbsTime() (thanks to Alexander Rieger).
- Fixed a problem with calling isyslog() from within the SignalHandler() (thanks
to Udo Richter).
- Replaced the Finnish language code "smi" with "suo" (thanks to Rolf Ahrenberg).
- Fixed wrong value for TableIdBAT in libsi/si.h (thanks to Winfried Köhler).
- Errors in config files no longer keep VDR from starting.
- Removed unneeded include files <linux/dvb/dmx.h> und <time.h> from remux.h
(reported by Tobias Grimm).
Diffstat (limited to 'remux.h')
-rw-r--r-- | remux.h | 193 |
1 files changed, 190 insertions, 3 deletions
@@ -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 <time.h> //XXX FIXME: DVB/linux/dvb/dmx.h should include <time.h> itself!!! -#include <linux/dvb/dmx.h> +#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 |