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);
164 if (Pid < 0 ||
TsPid(p) == Pid) {
220 p[ 9] = ((Pts >> 29) & 0x0E) | (p[9] & 0xF1);
222 p[11] = ((Pts >> 14) & 0xFE) | 0x01;
224 p[13] = ((Pts << 1) & 0xFE) | 0x01;
229 p[14] = ((Dts >> 29) & 0x0E) | (p[14] & 0xF1);
231 p[16] = ((Dts >> 14) & 0xFE) | 0x01;
233 p[18] = ((Dts << 1) & 0xFE) | 0x01;
238 int64_t d = Pts2 - Pts1;
258 Setup(Data, Length, Pid);
334 if (Index >= 0 && Index <
length)
340 int OldIndex =
index;
345 Scanner = (Scanner << 8) |
GetByte();
377 TsPacket[3] = (TsPacket[3] & 0xF0) | Counter;
378 if (++Counter > 0x0F)
384 if (++Version > 0x1F)
401 Target[i++] = 0xE0 | (Pid >> 8);
424 Target[i++] = *Language++;
425 Target[i++] = *Language++;
426 Target[i++] = *Language++;
427 Target[i++] = SubtitlingType;
428 Target[i++] = CompositionPageId >> 8;
429 Target[i++] = CompositionPageId & 0xFF;
430 Target[i++] = AncillaryPageId >> 8;
431 Target[i++] = AncillaryPageId & 0xFF;
441 Target[Length] = 0x00;
442 for (
const char *End = Language + strlen(Language); Language < End; ) {
443 Target[i++] = *Language++;
444 Target[i++] = *Language++;
445 Target[i++] = *Language++;
447 Target[Length] += 0x04;
448 if (*Language ==
'+')
459 Target[i++] = crc >> 24;
460 Target[i++] = crc >> 16;
461 Target[i++] = crc >> 8;
467#define P_PMT_PID 0x0084
472 bool Used[
MAXPID] = {
false };
473#define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
474#define SETPIDS(l) { const int *p = l; while (*p) { SETPID(*p); p++; } }
487 memset(
pat, 0xFF,
sizeof(
pat));
495 int PayloadStart = i;
498 int SectionLength = i;
507 p[i++] = 0xE0 | (
pmtPid >> 8);
509 pat[SectionLength] = i - SectionLength - 1 + 4;
518 memset(buf, 0xFF,
sizeof(buf));
521 int Vpid = Channel->
Vpid();
522 int Ppid = Channel->
Ppid();
526 int SectionLength = i;
534 p[i++] = 0xE0 | (Ppid >> 8);
541 for (
int n = 0; Channel->
Apid(n); n++) {
543 const char *Alang = Channel->
Alang(n);
546 for (
int n = 0; Channel->
Dpid(n); n++) {
551 for (
int n = 0; Channel->
Spid(n); n++) {
556 int sl = i - SectionLength - 2 + 4;
557 buf[SectionLength] |= (sl >> 8) & 0x0F;
558 buf[SectionLength + 1] = sl;
635 Data += PayloadOffset;
636 Length -= PayloadOffset;
638 if ((Length -= Data[0] + 1) <= 0)
660 esyslog(
"ERROR: can't parse PAT");
668 Data += PayloadOffset;
669 Length -= PayloadOffset;
673 if ((Length -= Data[0] + 1) <= 0)
677 if (Length <=
int(
sizeof(
pmt))) {
678 memcpy(
pmt, Data, Length);
682 esyslog(
"ERROR: PMT packet length too big (%d byte)!", Length);
694 esyslog(
"ERROR: PMT section length too big (%d byte)!",
pmtSize + Length);
749 char *s =
alangs[NumApids];
799 char *s =
slangs[NumSpids];
833 dpids[NumDpids] = dpid;
919 esyslog(
"ERROR: can't parse PMT");
928 int Pid =
TsPid(Data);
961 int L = (M < 3) ? 1 : 0;
962 return 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
972 *p++ = ParentalRating;
980 uchar *DescriptorsStart;
981 memset(
eit, 0xFF,
sizeof(
eit));
983 time_t t = time(NULL) - 3600;
984 tm *tm = localtime_r(&t, &tm_r);
985 uint16_t MJD =
YMDtoMJD(tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
991 *p++ = 0x10 | (
counter++ & 0x0F);
1022 DescriptorsStart = p;
1025 *(SectionStart - 1) = p - SectionStart + 4;
1026 *(DescriptorsStart - 1) = p - DescriptorsStart;
1028 int crc =
SI::CRC32::crc32((
char *)PayloadStart, p - PayloadStart, 0xFFFFFFFF);
1068 esyslog(
"ERROR: out of memory");
1077#define MAXPESLENGTH 0xFFF0
1097 memmove(p,
data, 4);
1142void BlockDump(
const char *Name,
const u_char *Data,
int Length)
1144 printf(
"--- %s\n", Name);
1145 for (
int i = 0; i < Length; i++) {
1146 if (i && (i % 16) == 0)
1148 printf(
" %02X", Data[i]);
1153void TsDump(
const char *Name,
const u_char *Data,
int Length)
1155 printf(
"%s: %04X", Name, Length);
1156 int n =
min(Length, 20);
1157 for (
int i = 0; i < n; i++)
1158 printf(
" %02X", Data[i]);
1161 n =
max(n, Length - 10);
1162 for (n =
max(n, Length - 10); n < Length; n++)
1163 printf(
" %02X", Data[n]);
1168void PesDump(
const char *Name,
const u_char *Data,
int Length)
1170 TsDump(Name, Data, Length);
1225 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1265 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1279 bool SeenPayloadStart =
false;
1282 SeenPayloadStart =
true;
1288 uint32_t OldScanner =
scanner;
1290 if (!SeenPayloadStart && tsPayload.
AtTsStart())
1300 int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
1301 uchar FrameType = (b2 >> 3) & 0x07;
1302 if (tsPayload.
Find(0x000001B5)) {
1303 if (((tsPayload.
GetByte() & 0xF0) >> 4) == 0x08) {
1306 if (PictureStructure == 0x02)
1320 static const char FrameTypes[] =
"?IPBD???";
1340 uchar frame_rate_value = b & 0x0F;
1341 if (frame_rate_value > 0 && frame_rate_value <= 8)
1345 if ((tsPayload.
GetByte() & 0xF0) == 0x10) {
1359 return tsPayload.
Used();
1400 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1441 return (
byte & (1 <<
bit--)) ? 1 : 0;
1455 for (
int b = 0; !b && z < 32; z++)
1457 return (1 << z) - 1 +
GetBits(z);
1464 if ((v & 0x01) != 0)
1467 return -int32_t(v / 2);
1485 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1487 switch (NalUnitType) {
1524 int chroma_format_idc = 0;
1530 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) {
1532 if (chroma_format_idc == 3)
1538 for (
int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); i++) {
1540 int SizeOfScalingList = (i < 6) ? 16 : 64;
1543 for (
int j = 0; j < SizeOfScalingList; j++) {
1545 NextScale = (LastScale +
GetGolombSe() + 256) % 256;
1547 LastScale = NextScale;
1555 if (pic_order_cnt_type == 0)
1557 else if (pic_order_cnt_type == 1) {
1576 bool frame_cropping_flag =
GetBit();
1577 if (frame_cropping_flag) {
1581 uint16_t frame_crop_bottom_offset =
GetGolombUe();
1582 uint16_t CropUnitX = 1;
1585 if (chroma_format_idc == 1) {
1589 else if (chroma_format_idc == 2)
1592 frame_Width -= CropUnitX * (frame_crop_left_offset + frame_crop_right_offset);
1593 frame_Height -= CropUnitY * (frame_crop_top_offset + frame_crop_bottom_offset);
1594 if (frame_Height > 1080 && frame_Height <= 1090)
1595 frame_Height = 1080;
1602 int aspect_ratio_idc =
GetBits(8);
1603 if (aspect_ratio_idc == 255)
1605 else if (
frameHeight >= 720 && (aspect_ratio_idc == 1 || aspect_ratio_idc == 14 || aspect_ratio_idc == 15 || aspect_ratio_idc == 16))
1621 uint32_t num_units_in_tick =
GetBits(32);
1622 uint32_t time_scale =
GetBits(32);
1623 if (num_units_in_tick > 0)
1647 static const char SliceTypes[] =
"PBIpi";
1648 dbgframes(
"%c", SliceTypes[slice_type % 5]);
1702 virtual int Parse(
const uchar *Data,
int Length,
int Pid)
override;
1720 if ((
scanner & 0xFFFFFF00) == 0x00000100) {
1747 uint8_t sub_layer_profile_present_flag[8];
1748 uint8_t sub_layer_level_present_flag[8];
1750 int sps_max_sub_layers_minus1 =
GetBits(3) & 7;
1758 bool general_progressive_source_flag =
GetBit();
1768 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1769 sub_layer_profile_present_flag[i] =
GetBit();
1770 sub_layer_level_present_flag[i] =
GetBit();
1772 if (sps_max_sub_layers_minus1 > 0) {
1773 for (
int i = sps_max_sub_layers_minus1; i < 8; i++ )
1776 for (
int i = 0; i < sps_max_sub_layers_minus1; i++ ) {
1777 if (sub_layer_profile_present_flag[i] )
1779 if (sub_layer_level_present_flag[i])
1785 if (chroma_format_idc == 3)
1789 bool conformance_window_flag =
GetBit();
1790 if (conformance_window_flag) {
1795 uint16_t SubWidthC = 1;
1796 uint16_t SubHeightC = 1;
1798 if (chroma_format_idc == 1) {
1802 else if (chroma_format_idc == 2)
1805 frameWidth -= SubWidthC * (conf_win_left_offset + conf_win_right_offset);
1806 frameHeight -= SubHeightC * (conf_win_top_offset + conf_win_bottom_offset);
1810 int log2_max_pic_order_cnt_lsb_minus4 =
GetGolombUe();
1811 int sps_sub_layer_ordering_info_present_flag =
GetBit();
1812 for (
int i = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1; i <= sps_max_sub_layers_minus1; ++i) {
1826 for (
int sizeId = 0; sizeId < 4; ++sizeId) {
1827 for (
int matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
1831 int coefNum =
min(64, (1 << (4 + (sizeId << 1))));
1834 for (
int i = 0; i < coefNum; ++i)
1849 uint32_t num_short_term_ref_pic_sets =
GetGolombUe();
1850 uint32_t NumDeltaPocs[num_short_term_ref_pic_sets];
1851 for (uint32_t stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; ++stRpsIdx) {
1853 bool inter_ref_pic_set_prediction_flag =
false;
1855 inter_ref_pic_set_prediction_flag =
GetBit();
1856 if (inter_ref_pic_set_prediction_flag) {
1857 uint32_t RefRpsIdx, delta_idx_minus1 = 0;
1858 if (stRpsIdx == num_short_term_ref_pic_sets)
1862 RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
1863 NumDeltaPocs[stRpsIdx] = 0;
1864 for (uint32_t j = 0; j <= NumDeltaPocs[RefRpsIdx]; ++j) {
1867 NumDeltaPocs[stRpsIdx]++;
1870 NumDeltaPocs[stRpsIdx]++;
1876 for (uint32_t j = 0; j < num_negative_pics; ++j) {
1880 for (uint32_t j = 0; j < num_positive_pics; ++j) {
1884 NumDeltaPocs[stRpsIdx] = num_negative_pics + num_positive_pics;
1889 uint32_t num_long_term_ref_pics_sps =
GetGolombUe();
1890 for (uint32_t i = 0; i < num_long_term_ref_pics_sps; ++i) {
1891 GetBits(log2_max_pic_order_cnt_lsb_minus4 + 4);
1899 int aspect_ratio_idc =
GetBits(8);
1900 if (aspect_ratio_idc == 255)
1902 else if (aspect_ratio_idc == 1 || aspect_ratio_idc == 14)
1925 uint32_t vui_num_units_in_tick =
GetBits(32);
1926 uint32_t vui_time_scale =
GetBits(32);
1927 if (vui_num_units_in_tick > 0)
1949#define TS_CC_UNKNOWN 0xFF
1956 void Report(
int Pid,
const char *Message);
1987 fprintf(stderr,
"%s: TS error #%d on PID %d (%s)\n", *
TimeToString(time(NULL)),
errors, Pid, Message);
2000 int Pid =
TsPid(Data);
2006 Report(Pid,
"scrambled");
2012 Report(Pid,
"continuity");
2026 return PtsDiff(*(
const int64_t *)b, *(
const int64_t *)a);
2041 void AddPts(int64_t Pts,
bool IndependentFrame =
false);
2062 if (
pts.Size() > 1) {
2065 int Delta = INT_MAX;
2066 for (
int i = 1; i <
pts.Size(); i++) {
2068 if (d > 0 && d < Delta)
2071 if (Delta < INT_MAX)
2077 int Number =
pts.Size();
2078 if (Number > 0 &&
pts[Number - 1] ==
lastPts) {
2080 pts.Remove(Number - 1);
2083 for (
int i = 1; i < Number; i++) {
2096 pts.Remove(0, Number - 1);
2097 if (
pts.Size() == 1)
2104 if (IndependentFrame) {
2154 return Errors || Missing;
2204 if (*(uint32_t *)p1 < *(uint32_t *)p2)
return -1;
2205 if (*(uint32_t *)p1 > *(uint32_t *)p2)
return 1;
2218 else if (
type == 0x1B)
2220 else if (
type == 0x24)
2225 esyslog(
"ERROR: unknown stream type %d (PID %d) in frame detector",
type,
pid);
2238 *PreviousErrors =
tsChecker->NewErrors();
2239 if (MissingFrames) {
2275 if (
int Skipped =
TS_SYNC(Data, Length))
2276 return Processed + Skipped;
2280 int Pid =
TsPid(Data);
2292 int n =
parser->Parse(Data, Length,
pid);
2294 if (
parser->NewFrame()) {
2303 if (
parser->FramesPerSecond() > 0.0) {
2352 Div +=
parser->IFrameTemporalReferenceOffset();
2360 else if (abs(Delta - 3600) <= 1)
2362 else if (Delta % 3003 == 0)
2364 else if (abs(Delta - 1800) <= 1)
2366 else if (Delta == 1501)
2395 Processed += Handled;
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)
int TotalErrors(void)
Returns the total number of all errors and missing frames detected in the data given to the calls to ...
bool Check(const uchar *Data, int Length, bool Independent, bool &Errors, bool &Missing, bool Final, int Pid)
Check Length bytes of the given Data (which must be a complete frame), with Independent telling wheth...
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.
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)
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)
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)
int64_t TsGetPts(const uchar *p, int l, int Pid)
#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)
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)
int64_t TsGetPts(const uchar *p, int l, int Pid=-1)
bool PesHasLength(const uchar *p)
bool TsHasAdaptationField(const uchar *p)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader=NULL)
#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR
int PesLength(const uchar *p)