FireBirdLib - Topfield TMS PVR TAP Programming Library
PSBuffer_ProcessTSPacket.c
Go to the documentation of this file.
1#include "libFireBird.h"
2
3bool PSBuffer_ProcessTSPacket(tPSBuffer *PSBuffer, const byte *TSBuffer, ulong64 FileOffset)
4{
6
7 word PID;
8 byte PointerField;
9 bool AdaptationField;
10 byte AdaptationFieldLen;
11 bool CCError;
12 bool TSError;
13 bool Crypted;
14 bool Result;
15
16 //Removed all memset() because they are really slow
17
18 static void CopyPayload(int PayloadOffset, int PayloadLen)
19 {
20 int i;
21 ulong64 *pi64;
22 ulong64 fo;
23
24 memcpy(PSBuffer->pInBufferData, (void *) &TSBuffer[PayloadOffset], PayloadLen);
25
26 fo = FileOffset + PayloadOffset;
27 pi64 = &PSBuffer->pInBuffer->FileOffset[PSBuffer->InBufferDataIndex];
28 for(i = 0; i < PayloadLen; i++)
29 {
30 *pi64 = fo;
31 pi64++;
32 fo++;
33 }
34 PSBuffer->pInBufferData += PayloadLen;
35 PSBuffer->InBufferDataIndex += PayloadLen;
36 }
37
38 Result = FALSE;
39 //Adaptation field gibt es nur bei PES-Paketen, werden hier aber ignoriert
40 //PointerField gibt es nur bei PSI-Paketen
41
42 //Stimmt die PID?
43 PID = ((TSBuffer[1] & 0x1f) << 8) | TSBuffer[2];
44 AdaptationFieldLen = 0;
45
46 //Nur weitermachen, wenn PID stimmt und Payload vorhanden ist
47 if((PID == PSBuffer->PID) && ((TSBuffer[3] & 0x10) != 0))
48 {
49 if(PSBuffer->InBufferDataIndex >= PSBuffer->BufferSize)
50 {
51 if((PSBuffer->ErrorFlag & 0x01) == 0)
52 {
53 TAP_Print(" PS buffer overflow while parsing PID 0x%4.4x", PSBuffer->PID);
54 PSBuffer->ErrorFlag = PSBuffer->ErrorFlag | 1;
55 }
56 }
57 else
58 {
59 //Continuity Counter ok? Falls nicht Buffer komplett verwerfen
60 if(PSBuffer->LastContCounter != 255)
61 PSBuffer->LastContCounter = (PSBuffer->LastContCounter + 1) & 0x0f;
62
63 TSError = (TSBuffer[1] & 0x80) != 0;
64 Crypted = (TSBuffer[3] & 0xc0) != 0;
65 CCError = ((TSBuffer[3] & 0x0f) != PSBuffer->LastContCounter) && (PSBuffer->LastContCounter != 255);
66
67 if(!TSError && !Crypted && !CCError)
68 {
69 if((TSBuffer[3] & 0x20) != 0)
70 {
71 AdaptationField = TRUE;
72 AdaptationFieldLen = TSBuffer[4];
73 }
74 else
75 {
76 AdaptationField = FALSE;
77 }
78
79 //Startet ein neues Paket?
80 if((TSBuffer[1] & 0x40) != 0)
81 {
82 if(PID <= 0x001f)
83 PointerField = TSBuffer[4];
84 else
85 PointerField = 0;
86
87 if(PSBuffer->InBufferDataIndex != 0)
88 {
89 //Restliche Bytes umkopieren
90 if(PointerField != 0)
91 CopyPayload(5, PointerField);
92
93 //Puffer mit den abfragbaren Daten zuweisen
94 PSBuffer->pOutBuffer = &PSBuffer->Buffer[PSBuffer->InBufferIndex];
95 PSBuffer->pOutBuffer->DataLen = PSBuffer->InBufferDataIndex;
96 Result = TRUE;
97
98 PSBuffer->InBufferIndex = 1 - PSBuffer->InBufferIndex;
99 PSBuffer->PSFileCtr++;
100 }
101
102 //Neuen Puffer aktivieren und initialisieren
103 PSBuffer->pInBuffer = &PSBuffer->Buffer[PSBuffer->InBufferIndex];
104 PSBuffer->pInBufferData = &PSBuffer->pInBuffer->PSData[0];
105 PSBuffer->InBufferDataIndex = 0;
106 //memset(PSBuffer->pInBufferData, 0, PSBuffer->BufferSize);
107
108 //Erste Daten kopieren
109 if(PID <= 0x001f)
110 CopyPayload(5 + PointerField, 183 - PointerField); //PSI Data mit PointerField
111 else
112 {
113 if(AdaptationField)
114 CopyPayload(5 + AdaptationFieldLen, 183 - AdaptationFieldLen); //PES-Paket mit zu ignorierendem Adaptation-Field
115 else
116 CopyPayload(4, 184); //PES-Paket ohne Adaptation-Field
117 }
118 }
119 else
120 {
121 //Weiterkopieren
122 if(PSBuffer->InBufferDataIndex != 0)
123 {
124 if(AdaptationField)
125 CopyPayload(5 + AdaptationFieldLen, 183 - AdaptationFieldLen); //PES-Paket mit zu ignorierendem Adaptation-Field
126 else
127 CopyPayload(4, 184); //PES-Paket ohne Adaptation-Field
128 }
129 }
130 }
131 else
132 {
133 if(CCError)
134 {
135 //WriteLog(Format(' CC error while parsing PID 0x%4.4x, file offset 0x%8.8llx', [PSBuffer->PID, FileOffset]), 1);
136
137 PSBuffer->pInBufferData = &PSBuffer->pInBuffer->PSData[0];
138 //memset(PSBuffer->pInBufferData, 0, PSBuffer->BufferSize);
139 PSBuffer->InBufferDataIndex = 0;
140 }
141
142 if(TSError)
143 {
144 //WriteLog(Format(' TransporStreamError error while parsing PID 0x%4.4x, file offset 0x%8.8llx', [PSBuffer->PID, FileOffset]), 1);
145
146 PSBuffer->pInBufferData = &PSBuffer->pInBuffer->PSData[0];
147 //memset(PSBuffer->pInBufferData, 0, PSBuffer->BufferSize);
148 PSBuffer->InBufferDataIndex = 0;
149 }
150
151 if(Crypted)
152 {
153 //WriteLog(Format(' packet marked as crypted while parsing PID 0x%4.4x, file offset 0x%8.8llx', [PSBuffer->PID, FileOffset]), 1);
154
155 PSBuffer->pInBufferData = &PSBuffer->pInBuffer->PSData[0];
156 //memset(PSBuffer->pInBufferData, 0, PSBuffer->BufferSize);
157 PSBuffer->InBufferDataIndex = 0;
158 }
159 }
160 }
161
162 PSBuffer->LastContCounter = TSBuffer[3] & 0x0f;
163 }
164
165 TRACEEXIT();
166 return Result;
167}
bool PSBuffer_ProcessTSPacket(tPSBuffer *PSBuffer, const byte *TSBuffer, ulong64 FileOffset)
#define TAP_Print
Definition: libFireBird.h:181
#define TRACEEXIT()
Definition: libFireBird.h:1244
#define TRACEENTER()
Definition: libFireBird.h:1243
int DataLen
Definition: libFireBird.h:2455
byte * PSData
Definition: libFireBird.h:2454
ulong64 * FileOffset
Definition: libFireBird.h:2456
int BufferSize
Definition: libFireBird.h:2467
byte ErrorFlag
Definition: libFireBird.h:2471
tBuffer * pInBuffer
Definition: libFireBird.h:2465
byte LastContCounter
Definition: libFireBird.h:2469
int InBufferDataIndex
Definition: libFireBird.h:2468
byte InBufferIndex
Definition: libFireBird.h:2464
tBuffer * pOutBuffer
Definition: libFireBird.h:2463
byte * pInBufferData
Definition: libFireBird.h:2466
tBuffer Buffer[2]
Definition: libFireBird.h:2462