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");
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);
332 if (Index >= 0 && Index <
length)
338 int OldIndex =
index;
343 Scanner = (Scanner << 8) |
GetByte();
389 if (Offset == 4 && Offset < NewPayload)
391 if (Offset == 5 && Offset < NewPayload)
392 Packet[Offset++] = 0;
393 while (Offset < NewPayload)
394 Packet[Offset++] = 0xff;
411 TsPacket[3] = (TsPacket[3] & 0xF0) | Counter;
412 if (++Counter > 0x0F)
418 if (++Version > 0x1F)
435 Target[i++] = 0xE0 | (Pid >> 8);
458 Target[i++] = *Language++;
459 Target[i++] = *Language++;
460 Target[i++] = *Language++;
461 Target[i++] = SubtitlingType;
462 Target[i++] = CompositionPageId >> 8;
463 Target[i++] = CompositionPageId & 0xFF;
464 Target[i++] = AncillaryPageId >> 8;
465 Target[i++] = AncillaryPageId & 0xFF;
475 Target[Length] = 0x00;
476 for (
const char *End = Language + strlen(Language); Language < End; ) {
477 Target[i++] = *Language++;
478 Target[i++] = *Language++;
479 Target[i++] = *Language++;
481 Target[Length] += 0x04;
482 if (*Language ==
'+')
493 Target[i++] = crc >> 24;
494 Target[i++] = crc >> 16;
495 Target[i++] = crc >> 8;
501#define P_PMT_PID 0x0084
506 bool Used[
MAXPID] = {
false };
507#define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
508#define SETPIDS(l) { const int *p = l; while (*p) { SETPID(*p); p++; } }
521 memset(
pat, 0xFF,
sizeof(
pat));
529 int PayloadStart = i;
532 int SectionLength = i;
541 p[i++] = 0xE0 | (
pmtPid >> 8);
543 pat[SectionLength] = i - SectionLength - 1 + 4;
552 memset(buf, 0xFF,
sizeof(buf));
555 int Vpid = Channel->
Vpid();
556 int Ppid = Channel->
Ppid();
560 int SectionLength = i;
568 p[i++] = 0xE0 | (Ppid >> 8);
575 for (
int n = 0; Channel->
Apid(n); n++) {
577 const char *Alang = Channel->
Alang(n);
580 for (
int n = 0; Channel->
Dpid(n); n++) {
585 for (
int n = 0; Channel->
Spid(n); n++) {
590 int sl = i - SectionLength - 2 + 4;
591 buf[SectionLength] |= (sl >> 8) & 0x0F;
592 buf[SectionLength + 1] = sl;
669 Data += PayloadOffset;
670 Length -= PayloadOffset;
672 if ((Length -= Data[0] + 1) <= 0)
694 esyslog(
"ERROR: can't parse PAT");
702 Data += PayloadOffset;
703 Length -= PayloadOffset;
707 if ((Length -= Data[0] + 1) <= 0)
711 if (Length <=
int(
sizeof(
pmt))) {
712 memcpy(
pmt, Data, Length);
716 esyslog(
"ERROR: PMT packet length too big (%d byte)!", Length);
728 esyslog(
"ERROR: PMT section length too big (%d byte)!",
pmtSize + Length);
783 char *s =
alangs[NumApids];
833 char *s =
slangs[NumSpids];
867 dpids[NumDpids] = dpid;
953 esyslog(
"ERROR: can't parse PMT");
962 int Pid =
TsPid(Data);
995 int L = (M < 3) ? 1 : 0;
996 return 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
1006 *p++ = ParentalRating;
1012 uchar *PayloadStart;
1013 uchar *SectionStart;
1014 uchar *DescriptorsStart;
1015 memset(
eit, 0xFF,
sizeof(
eit));
1017 time_t t = time(NULL) - 3600;
1018 tm *tm = localtime_r(&t, &tm_r);
1019 uint16_t MJD =
YMDtoMJD(tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
1025 *p++ = 0x10 | (
counter++ & 0x0F);
1056 DescriptorsStart = p;
1059 *(SectionStart - 1) = p - SectionStart + 4;
1060 *(DescriptorsStart - 1) = p - DescriptorsStart;
1062 int crc =
SI::CRC32::crc32((
char *)PayloadStart, p - PayloadStart, 0xFFFFFFFF);
1102 esyslog(
"ERROR: out of memory");
1111#define MAXPESLENGTH 0xFFF0
1131 memmove(p,
data, 4);
1176void BlockDump(
const char *Name,
const u_char *Data,
int Length)
1178 printf(
"--- %s\n", Name);
1179 for (
int i = 0; i < Length; i++) {
1180 if (i && (i % 16) == 0)
1182 printf(
" %02X", Data[i]);
1187void TsDump(
const char *Name,
const u_char *Data,
int Length)
1189 printf(
"%s: %04X", Name, Length);
1190 int n =
min(Length, 20);
1191 for (
int i = 0; i < n; i++)
1192 printf(
" %02X", Data[i]);
1195 n =
max(n, Length - 10);
1196 for (n =
max(n, Length - 10); n < Length; n++)
1197 printf(
" %02X", Data[n]);
1202void PesDump(
const char *Name,
const u_char *Data,
int Length)
1204 TsDump(Name, Data, Length);
1259 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1299 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1313 bool SeenPayloadStart =
false;
1316 SeenPayloadStart =
true;
1322 uint32_t OldScanner =
scanner;
1324 if (!SeenPayloadStart && tsPayload.
AtTsStart())
1334 int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
1335 uchar FrameType = (b2 >> 3) & 0x07;
1336 if (tsPayload.
Find(0x000001B5)) {
1337 if (((tsPayload.
GetByte() & 0xF0) >> 4) == 0x08) {
1340 if (PictureStructure == 0x02)
1354 static const char FrameTypes[] =
"?IPBD???";
1374 uchar frame_rate_value = b & 0x0F;
1375 if (frame_rate_value > 0 && frame_rate_value <= 8)
1379 if ((tsPayload.
GetByte() & 0xF0) == 0x10) {
1393 return tsPayload.
Used();
1434 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1475 return (
byte & (1 <<
bit--)) ? 1 : 0;
1489 for (
int b = 0; !b && z < 32; z++)
1491 return (1 << z) - 1 +
GetBits(z);
1498 if ((v & 0x01) != 0)
1501 return -int32_t(v / 2);
1519 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1521 switch (NalUnitType) {
1558 int chroma_format_idc = 0;
1564 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) {
1566 if (chroma_format_idc == 3)
1572 for (
int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); i++) {
1574 int SizeOfScalingList = (i < 6) ? 16 : 64;
1577 for (
int j = 0; j < SizeOfScalingList; j++) {
1579 NextScale = (LastScale +
GetGolombSe() + 256) % 256;
1581 LastScale = NextScale;
1589 if (pic_order_cnt_type == 0)
1591 else if (pic_order_cnt_type == 1) {
1610 bool frame_cropping_flag =
GetBit();
1611 if (frame_cropping_flag) {
1615 uint16_t frame_crop_bottom_offset =
GetGolombUe();
1616 uint16_t CropUnitX = 1;
1619 if (chroma_format_idc == 1) {
1623 else if (chroma_format_idc == 2)
1626 frame_Width -= CropUnitX * (frame_crop_left_offset + frame_crop_right_offset);
1627 frame_Height -= CropUnitY * (frame_crop_top_offset + frame_crop_bottom_offset);
1628 if (frame_Height > 1080 && frame_Height <= 1090)
1629 frame_Height = 1080;
1636 int aspect_ratio_idc =
GetBits(8);
1637 if (aspect_ratio_idc == 255)
1639 else if (
frameHeight >= 720 && (aspect_ratio_idc == 1 || aspect_ratio_idc == 14 || aspect_ratio_idc == 15 || aspect_ratio_idc == 16))
1655 uint32_t num_units_in_tick =
GetBits(32);
1656 uint32_t time_scale =
GetBits(32);
1657 if (num_units_in_tick > 0)
1681 static const char SliceTypes[] =
"PBIpi";
1682 dbgframes(
"%c", SliceTypes[slice_type % 5]);
1736 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1754 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1781 uint8_t sub_layer_profile_present_flag[8];
1782 uint8_t sub_layer_level_present_flag[8];
1784 int sps_max_sub_layers_minus1 =
GetBits(3) & 7;
1792 bool general_progressive_source_flag =
GetBit();
1802 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1803 sub_layer_profile_present_flag[i] =
GetBit();
1804 sub_layer_level_present_flag[i] =
GetBit();
1806 if (sps_max_sub_layers_minus1 > 0) {
1807 for (
int i = sps_max_sub_layers_minus1; i < 8; i++ )
1810 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1811 if (sub_layer_profile_present_flag[i] )
1813 if (sub_layer_level_present_flag[i])
1819 if (chroma_format_idc == 3)
1823 bool conformance_window_flag =
GetBit();
1824 if (conformance_window_flag) {
1829 uint16_t SubWidthC = 1;
1830 uint16_t SubHeightC = 1;
1832 if (chroma_format_idc == 1) {
1836 else if (chroma_format_idc == 2)
1839 frameWidth -= SubWidthC * (conf_win_left_offset + conf_win_right_offset);
1840 frameHeight -= SubHeightC * (conf_win_top_offset + conf_win_bottom_offset);
1844 int log2_max_pic_order_cnt_lsb_minus4 =
GetGolombUe();
1845 int sps_sub_layer_ordering_info_present_flag =
GetBit();
1846 for (
int i = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1; i <= sps_max_sub_layers_minus1; ++i) {
1860 for (
int sizeId = 0; sizeId < 4; ++sizeId) {
1861 for (
int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
1865 int coefNum =
min(64, (1 << (4 + (sizeId << 1))));
1868 for (
int i = 0; i < coefNum; ++i)
1883 uint32_t num_short_term_ref_pic_sets =
GetGolombUe();
1884 uint32_t NumDeltaPocs[num_short_term_ref_pic_sets];
1885 for (uint32_t stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; ++stRpsIdx) {
1887 bool inter_ref_pic_set_prediction_flag =
false;
1889 inter_ref_pic_set_prediction_flag =
GetBit();
1890 if (inter_ref_pic_set_prediction_flag) {
1891 uint32_t RefRpsIdx, delta_idx_minus1 = 0;
1892 if (stRpsIdx == num_short_term_ref_pic_sets)
1896 RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
1897 NumDeltaPocs[stRpsIdx] = 0;
1898 for (uint32_t j = 0; j <= NumDeltaPocs[RefRpsIdx]; ++j) {
1901 NumDeltaPocs[stRpsIdx]++;
1904 NumDeltaPocs[stRpsIdx]++;
1910 for (uint32_t j = 0; j < num_negative_pics; ++j) {
1914 for (uint32_t j = 0; j < num_positive_pics; ++j) {
1918 NumDeltaPocs[stRpsIdx] = num_negative_pics + num_positive_pics;
1923 uint32_t num_long_term_ref_pics_sps =
GetGolombUe();
1924 for (uint32_t i = 0; i < num_long_term_ref_pics_sps; ++i) {
1925 GetBits(log2_max_pic_order_cnt_lsb_minus4 + 4);
1933 int aspect_ratio_idc =
GetBits(8);
1934 if (aspect_ratio_idc == 255)
1936 else if (aspect_ratio_idc == 1 || aspect_ratio_idc == 14)
1959 uint32_t vui_num_units_in_tick =
GetBits(32);
1960 uint32_t vui_time_scale =
GetBits(32);
1961 if (vui_num_units_in_tick > 0)
1983#define TS_CC_UNKNOWN 0xFF
1990 void Report(
int Pid,
const char *Message);
2021 fprintf(stderr,
"%s: TS error #%d on PID %d (%s)\n", *
TimeToString(time(NULL)),
errors, Pid, Message);
2034 int Pid =
TsPid(Data);
2040 Report(Pid,
"scrambled");
2046 Report(Pid,
"continuity");
2060 return PtsDiff(*(
const int64_t *)b, *(
const int64_t *)a);
2075 void AddPts(int64_t Pts,
bool IndependentFrame =
false);
2096 if (
pts.Size() > 1) {
2099 int Delta = INT_MAX;
2100 for (
int i = 1; i <
pts.Size(); i++) {
2102 if (d > 0 && d < Delta)
2105 if (Delta < INT_MAX)
2111 int Number =
pts.Size();
2112 if (Number > 0 &&
pts[Number - 1] ==
lastPts) {
2114 pts.Remove(Number - 1);
2117 for (
int i = 1; i < Number; i++) {
2130 pts.Remove(0, Number - 1);
2131 if (
pts.Size() == 1)
2138 if (IndependentFrame) {
2188 return Errors || Missing;
2238 if (*(uint32_t *)p1 < *(uint32_t *)p2)
return -1;
2239 if (*(uint32_t *)p1 > *(uint32_t *)p2)
return 1;
2252 else if (
type == 0x1B)
2254 else if (
type == 0x24)
2259 esyslog(
"ERROR: unknown stream type %d (PID %d) in frame detector",
type,
pid);
2272 *PreviousErrors =
tsChecker->NewErrors();
2273 if (MissingFrames) {
2309 if (
int Skipped =
TS_SYNC(Data, Length))
2310 return Processed + Skipped;
2314 int Pid =
TsPid(Data);
2326 int n =
parser->Parse(Data, Length,
pid);
2328 if (
parser->NewFrame()) {
2337 if (
parser->FramesPerSecond() > 0.0) {
2386 Div +=
parser->IFrameTemporalReferenceOffset();
2394 else if (abs(Delta - 3600) <= 1)
2396 else if (Delta % 3003 == 0)
2398 else if (abs(Delta - 1800) <= 1)
2400 else if (Delta == 1501)
2429 Processed += Handled;
2460 int LastKeepByte = -1;
2469 for (
int i=0; i<size; i++) {
2475 bool DropByte =
false;
2502 if (Payload[i] == 0xFF)
2506 else if (Payload[i] == 0x80)
2513 dsyslog(
"cNaluDumper: Unexpected NALU fill data: %02x", Payload[i]);
2515 if (LastKeepByte == -1)
2527 if (LastKeepByte == -1)
2555 dsyslog(
"cNaluDumper: TS continuity offset %i", Offset);
2599 if (DropThisPayload && HasAdaption)
2603 DropThisPayload =
false;
2606 if (DropThisPayload)
2639 esyslog(
"cNaluStreamProcessor::PutBuffer: New data before old data was processed!");
2684 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
2688 OutLength = Skipped;
2720 uchar *OutEnd = Out;
2728 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
2732 memcpy(OutEnd,
data, Skipped);
2773 OutLength = (OutEnd - Out);
2774 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) override
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)
bool Check(const uchar *Data, int Length, bool Independent, bool &Errors, bool &Missing, bool Final)
Check Length bytes of the given Data (which must be a complete frame), with Independent telling wheth...
int TotalErrors(void)
Returns the total number of all errors and missing frames detected in the data given to the calls to ...
uint32_t ptsValues[MaxPtsValues]
int Errors(bool *PreviousErrors=NULL, bool *MissingFrames=NULL)
Returns the total number of errors so far.
bool NewFrame(int *PreviousErrors=NULL, int *MissingFrames=NULL)
int Analyze(const uchar *Data, int Length, bool ErrorCheck=true)
Analyzes the TS packets pointed to by Data.
cFrameDetector(int Pid=0, int Type=0)
Sets up a frame detector for the given Pid and stream Type.
void SetLastPts(int64_t LastPts)
If this is a resumed recording, call this function with the last PTS of the previous recording.
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.
eAspectRatio AspectRatio(void)
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) override
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) override
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
const double frame_rate_table[9]
virtual int Parse(const uchar *Data, int Length, int Pid) override
Parses the given Data, which is a sequence of Length bytes of TS packets.
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...
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]
char slangs[MAXSPIDS][MAXLANGCODE2]
void SetFrameDelta(int FrameDelta)
void AddPts(int64_t Pts, bool IndependentFrame=false)
static void SetBrokenLink(uchar *Data, int Length)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
void CheckTs(const uchar *Data, int Length)
void Report(int Pid, const char *Message)
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)
const char * AspectRatioTexts[]
#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.
const char * ScanTypeChars
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)
static int ComparePts(const void *a, const void *b)
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)
#define TS_PAYLOAD_EXISTS
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)
int64_t TsGetPts(const uchar *p, int l)
int DropPayloadStartBytes