OSDN Git Service

ソースコード登録
[tsparser/tsparser.git] / src / TS / ts_packet.cpp
1
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdio.h>
5
6 #include "ts_packet.h"
7
8 using namespace TS;
9
10 Header::Header()
11 {
12         memset( header, 0x00, TS_HEADER_SZIE);
13         header[ 0] = SYNC;
14 }
15
16 Header::~Header()
17 {
18 }
19
20 int Header::getBytes( uint8_t *buf, uint32_t size)
21 {
22         if( size < TS_HEADER_SZIE) {
23                 return -1;
24         }
25
26         memcpy( buf, header, TS_HEADER_SZIE);
27
28         return TS_HEADER_SZIE;
29 }
30
31 int Header::parse( const uint8_t *buf, uint32_t len)
32 {
33         if( len < TS_HEADER_SZIE) {
34                 return -1;
35         }
36
37         memcpy( header, buf, TS_HEADER_SZIE);
38
39 #ifdef PACKET_DEBUG
40         sync_byte                                               = (buf[ 0] >> 0) & 0xff;
41         transport_error_indicator               = (buf[ 1] >> 7) & 0x01;
42         payload_unit_start_indicator    = (buf[ 1] >> 6) & 0x01;
43         transport_priority                              = (buf[ 1] >> 5) & 0x01;
44         pid                                                             = ((buf[ 1] & 0x1f) << 8) + buf[ 2];
45         transport_scrambling_control    = (buf[ 3] >> 6) & 0x03;
46         adaptation_field_control                = (buf[ 3] >> 4) & 0x03;
47         continuity_counter                              = (buf[ 3] >> 0) & 0x0f;
48 #endif
49
50         return TS_HEADER_SZIE;
51 }
52
53 AdaptationField::AdaptationField()
54 {
55         adaptation_field        = NULL;
56
57         field_data                      = NULL;
58         field_data_length       = 0;
59
60 #ifdef PACKET_DEBUG
61         adaptation_field_length                                 = 0x00;
62         discontinuity_indicator                                 = 0x00;
63         random_access_indicator                                 = 0x00;
64         elementary_stream_priority_indicator    = 0x00;
65         PCR_flag                                                                = 0x00;
66         OPCR_flag                                                               = 0x00;
67         splicing_point_flag                                             = 0x00;
68         transport_private_data_flag                             = 0x00;
69         adaptation_field_extension_flag                 = 0x00;
70 #endif
71 }
72
73 AdaptationField::AdaptationField( AdaptationField &src)
74 {
75         src.copy( *this);
76 }
77
78 AdaptationField::~AdaptationField()
79 {
80         clear();
81 }
82
83 AdaptationField& AdaptationField::operator=( AdaptationField &src)
84 {
85         src.copy( *this);
86         return *this;
87 }
88
89 int AdaptationField::getBytes( uint8_t *buf, uint32_t size)
90 {
91         int      index = 0;
92         const uint8_t af_len = getAdaptationFieldLength();
93
94         if( size < af_len + 1) {
95                 return -1;
96         }
97
98         memcpy( buf, adaptation_field, af_len + 1);
99
100         return af_len + 1;
101 }
102
103 int AdaptationField::parse( uint8_t *buf, uint32_t len)
104 {
105         int                     index = 0;
106         uint8_t         af_len;
107
108         if( len < 1) {
109                 return -1;
110         }
111
112         af_len = buf[ 0];
113         index++;
114         if( len < af_len + index) {
115                 return -1;
116         }
117
118         clear();
119         adaptation_field = new uint8_t[ af_len + index];
120         memcpy( adaptation_field, buf, af_len + index);
121
122 #ifdef PACKET_DEBUG
123         adaptation_field_length                                 = af_len;
124 #endif
125
126         if( af_len > 0) {
127 #ifdef PACKET_DEBUG
128                 discontinuity_indicator                                 = (buf[ index] >> 7) & 0x01;
129                 random_access_indicator                                 = (buf[ index] >> 6) & 0x01;
130                 elementary_stream_priority_indicator    = (buf[ index] >> 5) & 0x01;
131                 PCR_flag                                                                = (buf[ index] >> 4) & 0x01;
132                 OPCR_flag                                                               = (buf[ index] >> 3) & 0x01;
133                 splicing_point_flag                                             = (buf[ index] >> 2) & 0x01;
134                 transport_private_data_flag                             = (buf[ index] >> 1) & 0x01;
135                 adaptation_field_extension_flag                 = (buf[ index] >> 0) & 0x01;
136 #endif
137                 index++;
138
139                 field_data_length = af_len - 1;
140                 if( field_data_length > 0) {
141                         field_data = &adaptation_field[ index];
142                 }
143                 index += field_data_length;
144         }
145
146         return index;
147 }
148
149
150 void AdaptationField::copy( AdaptationField &dst)
151 {
152         const uint8_t af_len = getAdaptationFieldLength();
153
154         dst.clear();
155         if( adaptation_field) {
156                 dst.adaptation_field = new uint8_t[ af_len + 1];
157                 memcpy( dst.adaptation_field, adaptation_field, af_len + 1);
158
159                 if( field_data_length > 0) {
160                         dst.field_data_length   = field_data_length;
161                         dst.field_data                  = &dst.adaptation_field[ 2];
162                 }
163         }
164
165 #ifdef PACKET_DEBUG
166         dst.adaptation_field_length                                     = adaptation_field_length;
167         dst.discontinuity_indicator                                     = discontinuity_indicator;
168         dst.random_access_indicator                                     = random_access_indicator;
169         dst.elementary_stream_priority_indicator        = elementary_stream_priority_indicator;
170         dst.PCR_flag                                                            = PCR_flag;
171         dst.OPCR_flag                                                           = OPCR_flag;
172         dst.splicing_point_flag                                         = splicing_point_flag;
173         dst.transport_private_data_flag                         = transport_private_data_flag;
174         dst.adaptation_field_extension_flag                     = adaptation_field_extension_flag;
175 #endif
176 }
177
178 void AdaptationField::clear()
179 {
180         if( adaptation_field) {
181                 delete[] adaptation_field;
182         }
183         adaptation_field        = NULL;
184         field_data                      = NULL;
185         field_data_length       = 0;
186 }
187
188 TSPacket::TSPacket( Header *h, AdaptationField *af, uint8_t *p, uint32_t p_len)
189 {
190         header                          = h;
191         adaptation_field        = af;
192         
193         if( p_len > 0) {
194                 payload = new uint8_t[ p_len];
195                 memcpy( payload, p, p_len);
196                 payload_length = p_len;
197         }
198         else {
199                 payload                 = NULL;
200                 payload_length  = 0;
201         }
202 }
203
204 TSPacket::~TSPacket()
205 {
206         if( header) {
207                 delete header;
208                 header = NULL;
209         }
210         if( adaptation_field) {
211                 delete adaptation_field;
212                 adaptation_field = NULL;
213         }
214         if( payload) {
215                 delete[] payload;
216                 payload = NULL;
217         }
218         payload_length = 0;
219 }
220
221 uint16_t TSPacket::getPID()
222 {
223         return header->getPid();
224 }
225
226 Header* TSPacket::getHeader()
227 {
228         return header;
229 }
230
231 AdaptationField* TSPacket::getAdaptationField()
232 {
233         return adaptation_field;
234 }
235 uint32_t TSPacket::getPayloadLength()
236 {
237         return payload_length;
238 }
239
240 uint32_t TSPacket::getPayload( uint8_t **p)
241 {
242         *p = payload;
243         return payload_length;
244 }
245
246 int TSPacket::getBytes( uint8_t *buf, uint32_t size)
247 {
248         int     index = 0;
249         int w;
250
251         if( size < TS_PACKET_SIZE) {
252                 return -1;
253         }
254
255         w = header->getBytes( &buf[ index], size - index);
256         if( w != Header::TS_HEADER_SZIE) {
257                 return -1;
258         }
259         index += w;
260
261         if( adaptation_field) {
262                 w = adaptation_field->getBytes( &buf[ index], size - index);
263                 if( w < 0) {
264                         return -1;
265                 }
266                 index += w;
267         }
268
269         if( index + payload_length > TS_PACKET_SIZE) {
270                 return -1;
271         }
272         memcpy( &buf[ index], payload, payload_length);
273         index += payload_length;
274
275         if( index < TS_PACKET_SIZE) {
276                 memset( &buf[ index], 0xff, TS_PACKET_SIZE - index);
277                 index += (TS_PACKET_SIZE - index);
278         }
279
280         return index;
281 }
282
283
284 TSPacket* TSPacket::parse( uint8_t *buf, uint32_t len, uint32_t *read_len)
285 {
286         TSPacket                *p      = NULL;
287         Header                  *h      = NULL;
288         AdaptationField *af     = NULL;
289         int index                       = 0;
290         int sync_index          = 0;
291         int payload_len         = 0;
292         int read;
293         
294         *read_len = 0;
295
296         if( (index = TSPacket::sync( buf, len)) == -1) {
297                 goto ERR;
298         }
299         if( sync_index != 0) {
300                 fprintf( stderr, "sync index = %d\n", sync_index);
301         }
302
303         if( len - index < TS_PACKET_SIZE) {
304                 goto ERR;
305         }
306         sync_index = index;
307
308         h = new Header();
309         if( !h) {
310                 goto ERR;
311         }
312         if( (read = h->parse( &buf[ index], len - index)) == -1) {
313                 goto ERR;
314         }
315         index += read;
316
317         if( h->getTransportErrorIndicator()) {
318                 //fprintf( stderr, "transport_error_indicator = 1, PID = 0x%04X\n", h->getPid());
319                 goto ERR;
320         }
321
322         if( h->getAdaptationFieldControl() == 0x02 || h->getAdaptationFieldControl() == 0x03) {
323                 af      = new AdaptationField();
324                 if( !af) {
325                         goto ERR;
326                 }
327                 if( (read = af->parse( &buf[ index], len - index)) == -1) {
328                         goto ERR;
329                 }
330                 index += read;
331         }
332         payload_len = TS_PACKET_SIZE - (index - sync_index);
333         if( payload_len < 0) {
334                 payload_len = 0;
335         }
336
337         p = new TSPacket( h, af, &buf[ index], payload_len);
338         if( !p) {
339                 goto ERR;
340         }
341         index += payload_len;
342         *read_len = index;
343
344         return p;
345
346 ERR:
347         if( h) {
348                 delete h;
349         }
350         if( af) {
351                 delete af;
352         }
353         if( p) {
354                 delete p;
355         }
356
357         return NULL;
358
359 }
360
361 TSPacket* TSPacket::create( Header *h, AdaptationField *af, uint8_t *p, uint32_t p_len)
362 {
363         TSPacket *ts = new TSPacket( h, af, p, p_len);
364
365         return ts;
366 }
367
368 int TSPacket::sync( uint8_t *buf, uint32_t len)
369 {
370         uint32_t        i;
371         int                     sync_index = -1;
372         for( i = 0; i < len; i++) {
373                 if( buf[ i] == Header::SYNC) {
374                         sync_index = (int)i;
375                         break;
376                 }
377         }
378         return sync_index;
379 }
380
381
382