13 #include "libsi/section.h"
14 #include "libsi/descriptor.h"
23 #define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
24 #define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
31 if ((Data[6] & 0xC0) == 0x80) {
35 PesPayloadOffset = 6 + 3 + Data[8];
36 if (Count < PesPayloadOffset)
39 if (ContinuationHeader)
40 *ContinuationHeader = ((Data[6] == 0x80) && !Data[7] && !Data[8]);
49 for (
int i = 0; i < 16; i++) {
50 if (Data[PesPayloadOffset] != 0xFF)
53 if (Count <= ++PesPayloadOffset)
58 if ((Data[PesPayloadOffset] & 0xC0) == 0x40) {
59 PesPayloadOffset += 2;
61 if (Count <= PesPayloadOffset)
65 if (ContinuationHeader)
66 *ContinuationHeader =
false;
68 if ((Data[PesPayloadOffset] & 0xF0) == 0x20) {
70 PesPayloadOffset += 5;
72 else if ((Data[PesPayloadOffset] & 0xF0) == 0x30) {
74 PesPayloadOffset += 10;
76 else if (Data[PesPayloadOffset] == 0x0F) {
80 if (ContinuationHeader)
81 *ContinuationHeader =
true;
86 if (Count < PesPayloadOffset)
92 #define VIDEO_STREAM_S 0xE0
100 for (
int i = PesPayloadOffset; i < Length - 7; i++) {
101 if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 3] == 0xB8) {
102 if (!(Data[i + 7] & 0x40))
107 dsyslog(
"SetBrokenLink: no GOP header found in video packet");
110 dsyslog(
"SetBrokenLink: no video packet in frame");
130 bool Processed[
MAXPID] = {
false };
135 if (!Processed[Pid]) {
139 Processed[Pid] =
true;
163 TsPacket[3] = (TsPacket[3] & 0xF0) | Counter;
164 if (++Counter > 0x0F)
170 if (++Version > 0x1F)
187 Target[i++] = 0xE0 | (Pid >> 8);
210 Target[i++] = *Language++;
211 Target[i++] = *Language++;
212 Target[i++] = *Language++;
213 Target[i++] = SubtitlingType;
214 Target[i++] = CompositionPageId >> 8;
215 Target[i++] = CompositionPageId & 0xFF;
216 Target[i++] = AncillaryPageId >> 8;
217 Target[i++] = AncillaryPageId & 0xFF;
228 for (
int n = 0; n < pageCount; n++) {
230 Target[i++] = *Language++;
231 Target[i++] = *Language++;
232 Target[i++] = *Language++;
233 Target[i++] = (pages[n].
ttxtType << 3) + pages[n].ttxtMagazine;
250 Target[Length] = 0x00;
251 for (
const char *End = Language + strlen(Language); Language < End; ) {
252 Target[i++] = *Language++;
253 Target[i++] = *Language++;
254 Target[i++] = *Language++;
256 Target[Length] += 0x04;
257 if (*Language ==
'+')
268 Target[i++] = crc >> 24;
269 Target[i++] = crc >> 16;
270 Target[i++] = crc >> 8;
275 #define P_TSID 0x8008 // pseudo TS ID
276 #define P_PMT_PID 0x0084 // pseudo PMT pid
277 #define MAXPID 0x2000 // the maximum possible number of pids
281 bool Used[
MAXPID] = {
false };
282 #define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
283 #define SETPIDS(l) { const int *p = l; while (*p) { SETPID(*p); p++; } }
296 memset(
pat, 0xFF,
sizeof(
pat));
304 int PayloadStart = i;
307 int SectionLength = i;
316 p[i++] = 0xE0 | (
pmtPid >> 8);
318 pat[SectionLength] = i - SectionLength - 1 + 4;
327 memset(buf, 0xFF,
sizeof(buf));
330 int Vpid = Channel->
Vpid();
331 int Ppid = Channel->
Ppid();
332 int Tpid = Channel->
Tpid();
336 int SectionLength = i;
344 p[i++] = 0xE0 | (Ppid >> 8);
351 for (
int n = 0; Channel->
Apid(n); n++) {
353 const char *Alang = Channel->
Alang(n);
356 for (
int n = 0; Channel->
Dpid(n); n++) {
361 for (
int n = 0; Channel->
Spid(n); n++) {
370 int sl = i - SectionLength - 2 + 4;
371 buf[SectionLength] |= (sl >> 8) & 0x0F;
372 buf[SectionLength + 1] = sl;
449 Data += PayloadOffset;
450 Length -= PayloadOffset;
452 if ((Length -= Data[0] + 1) <= 0)
471 esyslog(
"ERROR: can't parse PAT");
479 Data += PayloadOffset;
480 Length -= PayloadOffset;
484 if ((Length -= Data[0] + 1) <= 0)
488 if (Length <=
int(
sizeof(
pmt))) {
489 memcpy(
pmt, Data, Length);
493 esyslog(
"ERROR: PMT packet length too big (%d byte)!", Length);
505 esyslog(
"ERROR: PMT section length too big (%d byte)!",
pmtSize + Length);
561 char *s =
alangs[NumApids];
611 char *s =
slangs[NumSpids];
667 dpids[NumDpids] = dpid;
717 esyslog(
"ERROR: can't parse PMT");
760 esyslog(
"ERROR: out of memory");
769 #define MAXPESLENGTH 0xFFF0
836 printf(
"--- %s\n", Name);
837 for (
int i = 0; i < Length; i++) {
838 if (i && (i % 16) == 0)
840 printf(
" %02X", Data[i]);
847 printf(
"%s: %04X", Name, Length);
848 int n =
min(Length, 20);
849 for (
int i = 0; i < n; i++)
850 printf(
" %02X", Data[i]);
853 n =
max(n, Length - 10);
854 for (n =
max(n, Length - 10); n < Length; n++)
855 printf(
" %02X", Data[n]);
862 TsDump(Name, Data, Length);
867 #define EMPTY_SCANNER (0xFFFFFFFF)
886 if (*(uint32_t *)p1 < *(uint32_t *)p2)
return -1;
887 if (*(uint32_t *)p1 > *(uint32_t *)p2)
return 1;
918 esyslog(
"ERROR: out of data while skipping TS packets in cFrameDetector");
922 return FrameTypeOffset;
927 bool SeenPayloadStart =
false;
928 bool SeenAccessUnitDelimiter =
false;
936 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
937 return Processed + Skipped;
940 int Pid =
TsPid(Data);
943 SeenPayloadStart =
true;
975 if (abs(Delta - 3600) <= 1)
977 else if (Delta % 3003 == 0)
979 else if (abs(Delta - 1800) <= 1) {
988 else if (Delta == 1501)
1026 if (
synced && !SeenPayloadStart && Processed)
1028 int FrameTypeOffset = i + 2;
1029 if (FrameTypeOffset >= TS_SIZE)
1030 i =
SkipPackets(Data, Length, Processed, FrameTypeOffset);
1032 uchar FrameType = (Data[FrameTypeOffset] >> 3) & 0x07;
1053 if (
synced && !SeenPayloadStart && Processed)
1055 SeenAccessUnitDelimiter =
true;
1057 else if (SeenAccessUnitDelimiter &&
scanner == 0x00000001) {
1058 SeenAccessUnitDelimiter =
false;
1059 int FrameTypeOffset = i + 1;
1060 if (FrameTypeOffset >= TS_SIZE)
1061 i =
SkipPackets(Data, Length, Processed, FrameTypeOffset);
1063 uchar FrameType = Data[FrameTypeOffset] & 0x1F;
1101 default:
esyslog(
"ERROR: unknown stream type %d (PID %d) in frame detector",
type,
pid);