23#define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
24#define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
26#define MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION 6
27#define WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION (MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION / 2)
28#define WRN_TS_PACKETS_FOR_FRAME_DETECTOR (MIN_TS_PACKETS_FOR_FRAME_DETECTOR / 2)
30#define EMPTY_SCANNER (0xFFFFFFFF)
37 if ((Data[6] & 0xC0) == 0x80) {
45 if (ContinuationHeader)
46 *ContinuationHeader = ((Data[6] == 0x80) && !Data[7] && !Data[8]);
55 for (
int i = 0; i < 16; i++) {
71 if (ContinuationHeader)
72 *ContinuationHeader =
false;
86 if (ContinuationHeader)
87 *ContinuationHeader =
true;
98#define VIDEO_STREAM_S 0xE0
107 if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 3] == 0xB8) {
108 if (!(Data[i + 7] & 0x40))
113 dsyslog(
"SetBrokenLink: no GOP header found in video packet");
116 dsyslog(
"SetBrokenLink: no video packet in frame");
123 p[1] &= ~TS_PAYLOAD_START;
125 p[3] &= ~TS_PAYLOAD_EXISTS;
128 memset(p + 6, 0xFF,
TS_SIZE - 6);
141 p[10] = (b << 7) | (p[10] & 0x7E) | ((e >> 8) & 0x01);
147int TsSync(
const uchar *Data,
int Length,
const char *File,
const char *Function,
int Line)
155 if (Skipped && File && Function && Line)
156 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet at %s/%s(%d)", Skipped, File, Function, Line);
218 p[ 9] = ((Pts >> 29) & 0x0E) | (p[9] & 0xF1);
220 p[11] = ((Pts >> 14) & 0xFE) | 0x01;
222 p[13] = ((Pts << 1) & 0xFE) | 0x01;
227 p[14] = ((Dts >> 29) & 0x0E) | (p[14] & 0xF1);
229 p[16] = ((Dts >> 14) & 0xFE) | 0x01;
231 p[18] = ((Dts << 1) & 0xFE) | 0x01;
236 int64_t d = Pts2 - Pts1;
256 Setup(Data, Length, Pid);
330 if (Index >= 0 && Index <
length)
336 int OldIndex =
index;
341 Scanner = (Scanner << 8) |
GetByte();
368 Packet[3] = Packet[3] & ~TS_ADAPT_FIELD_EXISTS;
381 Packet[3] = Packet[3] & ~TS_PAYLOAD_EXISTS;
387 if (Offset == 4 && Offset < NewPayload)
389 if (Offset == 5 && Offset < NewPayload)
390 Packet[Offset++] = 0;
391 while (Offset < NewPayload)
392 Packet[Offset++] = 0xff;
409 TsPacket[3] = (TsPacket[3] & 0xF0) | Counter;
410 if (++Counter > 0x0F)
416 if (++Version > 0x1F)
433 Target[i++] = 0xE0 | (Pid >> 8);
456 Target[i++] = *Language++;
457 Target[i++] = *Language++;
458 Target[i++] = *Language++;
459 Target[i++] = SubtitlingType;
460 Target[i++] = CompositionPageId >> 8;
461 Target[i++] = CompositionPageId & 0xFF;
462 Target[i++] = AncillaryPageId >> 8;
463 Target[i++] = AncillaryPageId & 0xFF;
473 Target[Length] = 0x00;
474 for (
const char *End = Language + strlen(Language); Language < End; ) {
475 Target[i++] = *Language++;
476 Target[i++] = *Language++;
477 Target[i++] = *Language++;
479 Target[Length] += 0x04;
480 if (*Language ==
'+')
491 Target[i++] = crc >> 24;
492 Target[i++] = crc >> 16;
493 Target[i++] = crc >> 8;
499#define P_PMT_PID 0x0084
504 bool Used[
MAXPID] = {
false };
505#define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
506#define SETPIDS(l) { const int *p = l; while (*p) { SETPID(*p); p++; } }
519 memset(
pat, 0xFF,
sizeof(
pat));
527 int PayloadStart = i;
530 int SectionLength = i;
539 p[i++] = 0xE0 | (
pmtPid >> 8);
541 pat[SectionLength] = i - SectionLength - 1 + 4;
550 memset(buf, 0xFF,
sizeof(buf));
553 int Vpid = Channel->
Vpid();
554 int Ppid = Channel->
Ppid();
558 int SectionLength = i;
566 p[i++] = 0xE0 | (Ppid >> 8);
573 for (
int n = 0; Channel->
Apid(n); n++) {
575 const char *Alang = Channel->
Alang(n);
578 for (
int n = 0; Channel->
Dpid(n); n++) {
583 for (
int n = 0; Channel->
Spid(n); n++) {
588 int sl = i - SectionLength - 2 + 4;
589 buf[SectionLength] |= (sl >> 8) & 0x0F;
590 buf[SectionLength + 1] = sl;
667 Data += PayloadOffset;
668 Length -= PayloadOffset;
670 if ((Length -= Data[0] + 1) <= 0)
692 esyslog(
"ERROR: can't parse PAT");
700 Data += PayloadOffset;
701 Length -= PayloadOffset;
705 if ((Length -= Data[0] + 1) <= 0)
709 if (Length <=
int(
sizeof(
pmt))) {
710 memcpy(
pmt, Data, Length);
714 esyslog(
"ERROR: PMT packet length too big (%d byte)!", Length);
726 esyslog(
"ERROR: PMT section length too big (%d byte)!",
pmtSize + Length);
781 char *s =
alangs[NumApids];
831 char *s =
slangs[NumSpids];
865 dpids[NumDpids] = dpid;
951 esyslog(
"ERROR: can't parse PMT");
960 int Pid =
TsPid(Data);
993 int L = (M < 3) ? 1 : 0;
994 return 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
1004 *p++ = ParentalRating;
1010 uchar *PayloadStart;
1011 uchar *SectionStart;
1012 uchar *DescriptorsStart;
1013 memset(
eit, 0xFF,
sizeof(
eit));
1015 time_t t = time(NULL) - 3600;
1016 tm *tm = localtime_r(&t, &tm_r);
1017 uint16_t MJD =
YMDtoMJD(tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
1023 *p++ = 0x10 | (
counter++ & 0x0F);
1054 DescriptorsStart = p;
1057 *(SectionStart - 1) = p - SectionStart + 4;
1058 *(DescriptorsStart - 1) = p - DescriptorsStart;
1060 int crc =
SI::CRC32::crc32((
char *)PayloadStart, p - PayloadStart, 0xFFFFFFFF);
1100 esyslog(
"ERROR: out of memory");
1109#define MAXPESLENGTH 0xFFF0
1129 memmove(p,
data, 4);
1174void BlockDump(
const char *Name,
const u_char *Data,
int Length)
1176 printf(
"--- %s\n", Name);
1177 for (
int i = 0; i < Length; i++) {
1178 if (i && (i % 16) == 0)
1180 printf(
" %02X", Data[i]);
1185void TsDump(
const char *Name,
const u_char *Data,
int Length)
1187 printf(
"%s: %04X", Name, Length);
1188 int n =
min(Length, 20);
1189 for (
int i = 0; i < n; i++)
1190 printf(
" %02X", Data[i]);
1193 n =
max(n, Length - 10);
1194 for (n =
max(n, Length - 10); n < Length; n++)
1195 printf(
" %02X", Data[n]);
1200void PesDump(
const char *Name,
const u_char *Data,
int Length)
1202 TsDump(Name, Data, Length);
1254 virtual int Parse(
const uchar *Data,
int Length,
int Pid);
1294 virtual int Parse(
const uchar *Data,
int Length,
int Pid);
1308 bool SeenPayloadStart =
false;
1311 SeenPayloadStart =
true;
1317 uint32_t OldScanner =
scanner;
1319 if (!SeenPayloadStart && tsPayload.
AtTsStart())
1329 int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
1330 uchar FrameType = (b2 >> 3) & 0x07;
1331 if (tsPayload.
Find(0x000001B5)) {
1332 if (((tsPayload.
GetByte() & 0xF0) >> 4) == 0x08) {
1335 if (PictureStructure == 0x02)
1349 static const char FrameTypes[] =
"?IPBD???";
1362 uchar frame_rate_value = b & 0x0F;
1363 if (frame_rate_value > 0 && frame_rate_value <= 8)
1367 if ((tsPayload.
GetByte() & 0xF0) == 0x10) {
1381 return tsPayload.
Used();
1422 virtual int Parse(
const uchar *Data,
int Length,
int Pid);
1463 return (
byte & (1 <<
bit--)) ? 1 : 0;
1477 for (
int b = 0; !b && z < 32; z++)
1479 return (1 << z) - 1 +
GetBits(z);
1486 if ((v & 0x01) != 0)
1489 return -int32_t(v / 2);
1507 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1509 switch (NalUnitType) {
1546 int chroma_format_idc = 0;
1552 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc ==118 || profile_idc == 128) {
1554 if (chroma_format_idc == 3)
1560 for (
int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); i++) {
1562 int SizeOfScalingList = (i < 6) ? 16 : 64;
1565 for (
int j = 0; j < SizeOfScalingList; j++) {
1567 NextScale = (LastScale +
GetGolombSe() + 256) % 256;
1569 LastScale = NextScale;
1577 if (pic_order_cnt_type == 0)
1579 else if (pic_order_cnt_type == 1) {
1598 bool frame_cropping_flag =
GetBit();
1599 if (frame_cropping_flag) {
1603 uint16_t frame_crop_bottom_offset =
GetGolombUe();
1604 uint16_t CropUnitX = 1;
1607 if (chroma_format_idc == 1) {
1611 else if (chroma_format_idc == 2)
1614 frame_Width -= CropUnitX * (frame_crop_left_offset + frame_crop_right_offset);
1615 frame_Height -= CropUnitY * (frame_crop_top_offset + frame_crop_bottom_offset);
1622 int aspect_ratio_idc =
GetBits(8);
1623 if (aspect_ratio_idc == 255)
1638 uint32_t num_units_in_tick =
GetBits(32);
1639 uint32_t time_scale =
GetBits(32);
1640 if (num_units_in_tick > 0)
1664 static const char SliceTypes[] =
"PBIpi";
1665 dbgframes(
"%c", SliceTypes[slice_type % 5]);
1719 virtual int Parse(
const uchar *Data,
int Length,
int Pid);
1737 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1764 uint8_t sub_layer_profile_present_flag[8];
1765 uint8_t sub_layer_level_present_flag[8];
1767 int sps_max_sub_layers_minus1 =
GetBits(3);
1775 bool general_progressive_source_flag =
GetBit();
1785 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1786 sub_layer_profile_present_flag[i] =
GetBit();
1787 sub_layer_level_present_flag[i] =
GetBit();
1789 if (sps_max_sub_layers_minus1 > 0) {
1790 for (
int i = sps_max_sub_layers_minus1; i < 8; i++ )
1793 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1794 if (sub_layer_profile_present_flag[i] )
1796 if (sub_layer_level_present_flag[i])
1802 if (chroma_format_idc == 3)
1806 bool conformance_window_flag =
GetBit();
1807 if (conformance_window_flag) {
1812 uint16_t SubWidthC = 1;
1813 uint16_t SubHeightC = 1;
1815 if (chroma_format_idc == 1) {
1819 else if (chroma_format_idc == 2)
1822 frameWidth -= SubWidthC * (conf_win_left_offset + conf_win_right_offset);
1823 frameHeight -= SubHeightC * (conf_win_top_offset + conf_win_bottom_offset);
1827 int log2_max_pic_order_cnt_lsb_minus4 =
GetGolombUe();
1828 int sps_sub_layer_ordering_info_present_flag =
GetBit();
1829 for (
int i = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1; i <= sps_max_sub_layers_minus1; ++i) {
1843 for (
int sizeId = 0; sizeId < 4; ++sizeId) {
1844 for (
int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
1848 int coefNum =
min(64, (1 << (4 + (sizeId << 1))));
1851 for (
int i = 0; i < coefNum; ++i)
1866 uint32_t num_short_term_ref_pic_sets =
GetGolombUe();
1867 uint32_t NumDeltaPocs[num_short_term_ref_pic_sets];
1868 for (uint32_t stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; ++stRpsIdx) {
1870 bool inter_ref_pic_set_prediction_flag =
false;
1872 inter_ref_pic_set_prediction_flag =
GetBit();
1873 if (inter_ref_pic_set_prediction_flag) {
1874 uint32_t RefRpsIdx, delta_idx_minus1 = 0;
1875 if (stRpsIdx == num_short_term_ref_pic_sets)
1879 RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
1880 NumDeltaPocs[stRpsIdx] = 0;
1881 for (uint32_t j = 0; j <= NumDeltaPocs[RefRpsIdx]; ++j) {
1884 NumDeltaPocs[stRpsIdx]++;
1887 NumDeltaPocs[stRpsIdx]++;
1893 for (uint32_t j = 0; j < num_negative_pics; ++j) {
1897 for (uint32_t j = 0; j < num_positive_pics; ++j) {
1901 NumDeltaPocs[stRpsIdx] = num_negative_pics + num_positive_pics;
1906 uint32_t num_long_term_ref_pics_sps =
GetGolombUe();
1907 for (uint32_t i = 0; i < num_long_term_ref_pics_sps; ++i) {
1908 GetBits(log2_max_pic_order_cnt_lsb_minus4 + 4);
1916 int aspect_ratio_idc =
GetBits(8);
1917 if (aspect_ratio_idc == 255)
1939 uint32_t vui_num_units_in_tick =
GetBits(32);
1940 uint32_t vui_time_scale =
GetBits(32);
1941 if (vui_num_units_in_tick > 0)
1969 if (*(uint32_t *)p1 < *(uint32_t *)p2)
return -1;
1970 if (*(uint32_t *)p1 > *(uint32_t *)p2)
return 1;
1983 else if (
type == 0x1B)
1985 else if (
type == 0x24)
1990 esyslog(
"ERROR: unknown stream type %d (PID %d) in frame detector",
type,
pid);
2001 if (
int Skipped =
TS_SYNC(Data, Length))
2002 return Processed + Skipped;
2006 int Pid =
TsPid(Data);
2078 else if (abs(Delta - 3600) <= 1)
2080 else if (Delta % 3003 == 0)
2082 else if (abs(Delta - 1800) <= 1)
2084 else if (Delta == 1501)
2105 Processed += Handled;
2136 int LastKeepByte = -1;
2145 for (
int i=0; i<size; i++) {
2151 bool DropByte =
false;
2178 if (Payload[i] == 0xFF)
2182 else if (Payload[i] == 0x80)
2189 dsyslog(
"cNaluDumper: Unexpected NALU fill data: %02x", Payload[i]);
2191 if (LastKeepByte == -1)
2203 if (LastKeepByte == -1)
2231 dsyslog(
"cNaluDumper: TS continuity offset %i", Offset);
2275 if (DropThisPayload && HasAdaption)
2279 DropThisPayload =
false;
2282 if (DropThisPayload)
2315 esyslog(
"cNaluStreamProcessor::PutBuffer: New data before old data was processed!");
2338 if (tempLength < TS_SIZE && length > 0)
2360 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
2364 OutLength = Skipped;
2396 uchar *OutEnd = Out;
2404 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
2408 memcpy(OutEnd,
data, Skipped);
2449 OutLength = (OutEnd - Out);
2450 return OutLength > 0 ? Out : NULL;
static u_int32_t crc32(const char *d, int len, u_int32_t CRCvalue)
Descriptor * getNext(Iterator &it)
DescriptorTag getDescriptorTag() const
StructureLoop< Language > languageLoop
bool getCurrentNextIndicator() const
int getSectionNumber() const
int getLastSectionNumber() const
int getVersionNumber() const
StructureLoop< Association > associationLoop
int getTransportStreamId() const
DescriptorLoop streamDescriptors
int getStreamType() const
StructureLoop< Stream > streamLoop
int getSubtitlingType() const
int getAncillaryPageId() const
int getCompositionPageId() const
StructureLoop< Subtitling > subtitlingLoop
virtual int Parse(const uchar *Data, int Length, int Pid)
Parses the given Data, which is a sequence of Length bytes of TS packets.
const int * Dpids(void) const
uint16_t AncillaryPageId(int i) const
uint16_t CompositionPageId(int i) const
const char * Slang(int i) const
uchar SubtitlingType(int i) const
const char * Dlang(int i) const
const int * Apids(void) const
const char * Alang(int i) const
const int * Spids(void) const
static cDevice * PrimaryDevice(void)
Returns the primary device.
void EnsureAudioTrack(bool Force=false)
Makes sure an audio track is selected that is actually available.
void ClrAvailableTracks(bool DescriptionsOnly=false, bool IdsOnly=false)
Clears the list of currently available tracks.
void EnsureSubtitleTrack(void)
Makes sure one of the preferred language subtitle tracks is selected.
bool SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language=NULL, const char *Description=NULL)
Sets the track of the given Type and Index to the given values.
uchar * AddParentalRatingDescriptor(uchar *p, uchar ParentalRating=0)
uint16_t YMDtoMJD(int Y, int M, int D)
uchar * Generate(int Sid)
uint32_t ptsValues[MaxPtsValues]
cFrameDetector(int Pid=0, int Type=0)
Sets up a frame detector for the given Pid and stream Type.
int Analyze(const uchar *Data, int Length)
Analyzes the TS packets pointed to by Data.
void SetPid(int Pid, int Type)
Sets the Pid and stream Type to detect frames for.
uint16_t FrameWidth(void)
void SetDebug(bool Debug)
double FramesPerSecond(void)
bool IndependentFrame(void)
int iFrameTemporalReferenceOffset
virtual int Parse(const uchar *Data, int Length, int Pid)=0
Parses the given Data, which is a sequence of Length bytes of TS packets.
uint16_t FrameHeight(void)
int IFrameTemporalReferenceOffset(void)
uint32_t GetBits(int Bits)
void ParseAccessUnitDelimiter(void)
@ nutSequenceParameterSet
bool separate_colour_plane_flag
bool gotAccessUnitDelimiter
virtual int Parse(const uchar *Data, int Length, int Pid)
Parses the given Data, which is a sequence of Length bytes of TS packets.
uint32_t GetGolombUe(void)
uchar GetByte(bool Raw=false)
Gets the next data byte.
void ParseSliceHeader(void)
void ParseSequenceParameterSet(void)
bool gotSequenceParameterSet
int32_t GetGolombSe(void)
cH264Parser(void)
Sets up a new H.264 parser.
virtual int Parse(const uchar *Data, int Length, int Pid)
Parses the given Data, which is a sequence of Length bytes of TS packets.
@ nutSliceSegmentIDRWRADL
@ nutSliceSegmentBLAWRADL
@ nutSliceSegmentTrailingR
@ nutSequenceParameterSet
@ nutSliceSegmentTrailingN
void ParseSequenceParameterSet(void)
bool seenIndependentFrame
int lastIFrameTemporalReference
virtual int Parse(const uchar *Data, int Length, int Pid)
Parses the given Data, which is a sequence of Length bytes of TS packets.
const double frame_rate_table[9]
void ProcessPayload(unsigned char *Payload, int size, bool PayloadStart, sPayloadInfo &Info)
eNaluFillState NaluFillState
bool ProcessTSPacket(unsigned char *Packet)
cPatPmtParser * pPatPmtParser
long long int DroppedPackets
long long int TotalPackets
uchar tempBuffer[TS_SIZE]
void PutBuffer(uchar *Data, int Length)
uchar * GetBuffer(int &OutLength)
int MakeCRC(uchar *Target, const uchar *Data, int Length)
uchar * GetPmt(int &Index)
Returns a pointer to the Index'th TS packet of the PMT section.
void SetChannel(const cChannel *Channel)
Sets the Channel for which the PAT/PMT shall be generated.
void IncEsInfoLength(int Length)
void IncCounter(int &Counter, uchar *TsPacket)
cPatPmtGenerator(const cChannel *Channel=NULL)
void SetVersions(int PatVersion, int PmtVersion)
Sets the version numbers for the generated PAT and PMT, in case this generator is used to,...
int MakeAC3Descriptor(uchar *Target, uchar Type)
void GeneratePat(void)
Generates a PAT section for later use with GetPat().
uchar * GetPat(void)
Returns a pointer to the PAT section, which consists of exactly one TS packet.
uchar pmt[MAX_PMT_TS][TS_SIZE]
int MakeLanguageDescriptor(uchar *Target, const char *Language)
void GeneratePmt(const cChannel *Channel)
Generates a PMT section for the given Channel, for later use with GetPmt().
void GeneratePmtPid(const cChannel *Channel)
Generates a PMT pid that doesn't collide with any of the actual pids of the Channel.
int MakeStream(uchar *Target, uchar Type, int Pid)
int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId)
void IncVersion(int &Version)
bool GetVersions(int &PatVersion, int &PmtVersion) const
Returns true if a valid PAT/PMT has been parsed and stores the current version numbers in the given v...
int Vtype(void) const
Returns the video stream type as defined by the current PMT, or 0 if no video stream type has been de...
uchar pmt[MAX_SECTION_SIZE]
cPatPmtParser(bool UpdatePrimaryDevice=false)
void Reset(void)
Resets the parser.
void ParsePat(const uchar *Data, int Length)
Parses the PAT data from the single TS packet in Data.
char dlangs[MAXDPIDS][MAXLANGCODE2]
bool ParsePatPmt(const uchar *Data, int Length)
Parses the given Data (which may consist of several TS packets, typically an entire frame) and extrac...
int pmtPids[MAX_PMT_PIDS+1]
uchar subtitlingTypes[MAXSPIDS]
uint16_t ancillaryPageIds[MAXSPIDS]
int SectionLength(const uchar *Data, int Length)
void ParsePmt(const uchar *Data, int Length)
Parses the PMT data from the single TS packet in Data.
bool IsPmtPid(int Pid) const
Returns true if Pid the one of the PMT pids as defined by the current PAT.
uint16_t compositionPageIds[MAXSPIDS]
char alangs[MAXAPIDS][MAXLANGCODE2]
int Vpid(void) const
Returns the video pid as defined by the current PMT, or 0 if no video pid has been detected,...
char slangs[MAXSPIDS][MAXLANGCODE2]
static void SetBrokenLink(uchar *Data, int Length)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
bool AtPayloadStart(void)
Returns true if this payload handler is currently pointing to the first byte of a TS packet that star...
int Used(void)
Returns the number of raw bytes that have already been used (e.g.
bool Eof(void) const
Returns true if all available bytes of the TS payload have been processed.
void SetByte(uchar Byte, int Index)
Sets the TS data byte at the given Index to the value Byte.
uchar GetByte(void)
Gets the next byte of the TS payload, skipping any intermediate TS header data.
bool AtTsStart(void)
Returns true if this payload handler is currently pointing to first byte of a TS packet.
int GetLastIndex(void)
Returns the index into the TS data of the payload byte that has most recently been read.
void Setup(uchar *Data, int Length, int Pid=-1)
Sets up this TS payload handler with the given Data, which points to a sequence of Length bytes of co...
bool SkipPesHeader(void)
Skips all bytes belonging to the PES header of the payload.
void Statistics(void) const
May be called after a new frame has been detected, and will log a warning if the number of TS packets...
bool Find(uint32_t Code)
Searches for the four byte sequence given in Code and returns true if it was found within the payload...
bool SkipBytes(int Bytes)
Skips the given number of bytes in the payload and returns true if there is still data left to read.
void PutTs(const uchar *Data, int Length)
Puts the payload data of the single TS packet at Data into the converter.
void SetRepeatLast(void)
Makes the next call to GetPes() return exactly the same data as the last one (provided there was no c...
const uchar * GetPes(int &Length)
Gets a pointer to the complete PES packet, or NULL if the packet is not complete yet.
void Reset(void)
Resets the converter.
const char * I18nNormalizeLanguageCode(const char *Code)
Returns a 3 letter language code that may not be zero terminated.
@ EnhancedAC3DescriptorTag
@ SubtitlingDescriptorTag
@ ISO639LanguageDescriptorTag
@ ParentalRatingDescriptorTag
#define DEFAULTFRAMESPERSECOND
void TsSetPcr(uchar *p, int64_t Pcr)
#define WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION
#define WRN_TS_PACKETS_FOR_FRAME_DETECTOR
void PesDump(const char *Name, const u_char *Data, int Length)
int64_t PtsDiff(int64_t Pts1, int64_t Pts2)
Returns the difference between two PTS values.
void TsHidePayload(uchar *p)
static int CmpUint32(const void *p1, const void *p2)
void PesSetDts(uchar *p, int64_t Dts)
int64_t TsGetDts(const uchar *p, int l)
void TsExtendAdaptionField(unsigned char *Packet, int ToLength)
void TsSetDts(uchar *p, int l, int64_t Dts)
void TsSetPts(uchar *p, int l, int64_t Pts)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
void PesSetPts(uchar *p, int64_t Pts)
int64_t TsGetPts(const uchar *p, int l)
void BlockDump(const char *Name, const u_char *Data, int Length)
int TsSync(const uchar *Data, int Length, const char *File, const char *Function, int Line)
void TsDump(const char *Name, const u_char *Data, int Length)
#define MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION
bool TsError(const uchar *p)
int TsPid(const uchar *p)
bool TsHasPayload(const uchar *p)
int PesPayloadOffset(const uchar *p)
bool TsIsScrambled(const uchar *p)
void TsSetContinuityCounter(uchar *p, uchar Counter)
uchar TsContinuityCounter(const uchar *p)
int TsGetPayload(const uchar **p)
bool PesHasPts(const uchar *p)
bool PesLongEnough(int Length)
int64_t PesGetDts(const uchar *p)
#define TS_ADAPT_FIELD_EXISTS
int64_t PesGetPts(const uchar *p)
bool TsPayloadStart(const uchar *p)
#define TS_SYNC(Data, Length)
int TsPayloadOffset(const uchar *p)
bool PesHasDts(const uchar *p)
bool PesHasLength(const uchar *p)
bool TsHasAdaptationField(const uchar *p)
void TsExtendAdaptionField(unsigned char *Packet, int ToLength)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader=NULL)
#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR
int PesLength(const uchar *p)
int DropPayloadStartBytes