]> git.sesse.net Git - ffmpeg/blob - libavformat/mpegts.c
ab621dbb817914f9e04756fa5db483af506d020f
[ffmpeg] / libavformat / mpegts.c
1 /*
2  * MPEG2 transport stream (aka DVB) demux
3  * Copyright (c) 2002-2003 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "avformat.h"
20
21 #include "mpegts.h"
22
23 //#define DEBUG_SI
24
25 /* 1.0 second at 24Mbit/s */
26 #define MAX_SCAN_PACKETS 16000
27
28 static int add_pes_stream(AVFormatContext *s, int pid);
29
30 enum MpegTSFilterType {
31     MPEGTS_PES,
32     MPEGTS_SECTION,
33 };
34
35 /* XXX: suppress 'pkt' parameter */
36 typedef void PESCallback(void *opaque, const uint8_t *buf, int len, int is_start);
37
38 typedef struct MpegTSPESFilter {
39     PESCallback *pes_cb;
40     void *opaque;
41 } MpegTSPESFilter;
42
43 typedef void SectionCallback(void *opaque, const uint8_t *buf, int len);
44
45 typedef void SetServiceCallback(void *opaque, int ret);
46
47 typedef struct MpegTSSectionFilter {
48     int section_index;
49     int section_h_size;
50     uint8_t *section_buf;
51     int check_crc:1;
52     int end_of_section_reached:1;
53     SectionCallback *section_cb;
54     void *opaque;
55 } MpegTSSectionFilter;
56
57 typedef struct MpegTSFilter {
58     int pid;
59     int last_cc; /* last cc code (-1 if first packet) */
60     enum MpegTSFilterType type;
61     union {
62         MpegTSPESFilter pes_filter;
63         MpegTSSectionFilter section_filter;
64     } u;
65 } MpegTSFilter;
66
67 typedef struct MpegTSService {
68     int running:1;
69     int sid;
70     char *provider_name;
71     char *name;
72 } MpegTSService;
73
74 typedef struct MpegTSContext {
75     /* user data */
76     AVFormatContext *stream;
77     int raw_packet_size; /* raw packet size, including FEC if present */
78     int auto_guess; /* if true, all pids are analized to find streams */
79     int set_service_ret;
80
81     /* data needed to handle file based ts */
82     int stop_parse; /* stop parsing loop */
83     AVPacket *pkt; /* packet containing av data */
84
85     /******************************************/
86     /* private mpegts data */
87     /* scan context */
88     MpegTSFilter *sdt_filter;
89     int nb_services;
90     MpegTSService **services;
91     
92     /* set service context (XXX: allocated it ?) */
93     SetServiceCallback *set_service_cb;
94     void *set_service_opaque;
95     MpegTSFilter *pat_filter;
96     MpegTSFilter *pmt_filter;
97     int req_sid;
98
99     MpegTSFilter *pids[NB_PID_MAX];
100 } MpegTSContext;
101
102 static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
103                                const uint8_t *buf, int buf_size, int is_start)
104 {
105     MpegTSSectionFilter *tss = &tss1->u.section_filter;
106     int len;
107     unsigned int crc;
108     
109     if (is_start) {
110         memcpy(tss->section_buf, buf, buf_size);
111         tss->section_index = buf_size;
112         tss->section_h_size = -1;
113         tss->end_of_section_reached = 0;
114     } else {
115         if (tss->end_of_section_reached)
116             return;
117         len = 4096 - tss->section_index;
118         if (buf_size < len)
119             len = buf_size;
120         memcpy(tss->section_buf + tss->section_index, buf, len);
121         tss->section_index += len;
122     }
123
124     /* compute section length if possible */
125     if (tss->section_h_size == -1 && tss->section_index >= 3) {
126         len = (((tss->section_buf[1] & 0xf) << 8) | tss->section_buf[2]) + 3;
127         if (len > 4096)
128             return;
129         tss->section_h_size = len;
130     }
131
132     if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
133         if (tss->check_crc) {
134             crc = mpegts_crc32(tss->section_buf, tss->section_h_size);
135             if (crc != 0)
136                 goto invalid_crc;
137         }
138         tss->section_cb(tss->opaque, tss->section_buf, tss->section_h_size);
139     invalid_crc:
140         tss->end_of_section_reached = 1;
141     }
142 }
143
144 MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, 
145                                          SectionCallback *section_cb, void *opaque,
146                                          int check_crc)
147
148 {
149     MpegTSFilter *filter;
150     MpegTSSectionFilter *sec;
151
152     if (pid >= NB_PID_MAX || ts->pids[pid])
153         return NULL;
154     filter = av_mallocz(sizeof(MpegTSFilter));
155     if (!filter) 
156         return NULL;
157     ts->pids[pid] = filter;
158     filter->type = MPEGTS_SECTION;
159     filter->pid = pid;
160     filter->last_cc = -1;
161     sec = &filter->u.section_filter;
162     sec->section_cb = section_cb;
163     sec->opaque = opaque;
164     sec->section_buf = av_malloc(MAX_SECTION_SIZE);
165     sec->check_crc = check_crc;
166     if (!sec->section_buf) {
167         av_free(filter);
168         return NULL;
169     }
170     return filter;
171 }
172
173 MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, 
174                                      PESCallback *pes_cb,
175                                      void *opaque)
176 {
177     MpegTSFilter *filter;
178     MpegTSPESFilter *pes;
179
180     if (pid >= NB_PID_MAX || ts->pids[pid])
181         return NULL;
182     filter = av_mallocz(sizeof(MpegTSFilter));
183     if (!filter) 
184         return NULL;
185     ts->pids[pid] = filter;
186     filter->type = MPEGTS_PES;
187     filter->pid = pid;
188     filter->last_cc = -1;
189     pes = &filter->u.pes_filter;
190     pes->pes_cb = pes_cb;
191     pes->opaque = opaque;
192     return filter;
193 }
194
195 void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
196 {
197     int pid;
198
199     pid = filter->pid;
200     if (filter->type == MPEGTS_SECTION)
201         av_freep(&filter->u.section_filter.section_buf);
202     av_free(filter);
203     ts->pids[pid] = NULL;
204 }
205
206 /* autodetect fec presence. Must have at least 1024 bytes  */
207 static int get_packet_size(const uint8_t *buf, int size)
208 {
209     int i;
210
211     if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
212         return -1;
213     for(i=0;i<5;i++) {
214         if (buf[i * TS_PACKET_SIZE] != 0x47)
215             goto try_fec;
216     }
217     return TS_PACKET_SIZE;
218  try_fec:
219     for(i=0;i<5;i++) {
220         if (buf[i * TS_FEC_PACKET_SIZE] != 0x47)
221             return -1;
222     }
223     return TS_FEC_PACKET_SIZE;
224 }
225
226 typedef struct SectionHeader {
227     uint8_t tid;
228     uint16_t id;
229     uint8_t version;
230     uint8_t sec_num;
231     uint8_t last_sec_num;
232 } SectionHeader;
233
234 static inline int get8(const uint8_t **pp, const uint8_t *p_end)
235 {
236     const uint8_t *p;
237     int c;
238
239     p = *pp;
240     if (p >= p_end)
241         return -1;
242     c = *p++;
243     *pp = p;
244     return c;
245 }
246
247 static inline int get16(const uint8_t **pp, const uint8_t *p_end)
248 {
249     const uint8_t *p;
250     int c;
251
252     p = *pp;
253     if ((p + 1) >= p_end)
254         return -1;
255     c = (p[0] << 8) | p[1];
256     p += 2;
257     *pp = p;
258     return c;
259 }
260
261 /* read and allocate a DVB string preceeded by its length */
262 static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
263 {
264     int len;
265     const uint8_t *p;
266     char *str;
267
268     p = *pp;
269     len = get8(&p, p_end);
270     if (len < 0)
271         return NULL;
272     if ((p + len) > p_end)
273         return NULL;
274     str = av_malloc(len + 1);
275     if (!str)
276         return NULL;
277     memcpy(str, p, len);
278     str[len] = '\0';
279     p += len;
280     *pp = p;
281     return str;
282 }
283
284 static int parse_section_header(SectionHeader *h, 
285                                 const uint8_t **pp, const uint8_t *p_end)
286 {
287     int val;
288
289     val = get8(pp, p_end);
290     if (val < 0)
291         return -1;
292     h->tid = val;
293     *pp += 2;
294     val = get16(pp, p_end);
295     if (val < 0)
296         return -1;
297     h->id = val;
298     val = get8(pp, p_end);
299     if (val < 0)
300         return -1;
301     h->version = (val >> 1) & 0x1f;
302     val = get8(pp, p_end);
303     if (val < 0)
304         return -1;
305     h->sec_num = val;
306     val = get8(pp, p_end);
307     if (val < 0)
308         return -1;
309     h->last_sec_num = val;
310     return 0;
311 }
312
313 static MpegTSService *new_service(MpegTSContext *ts, int sid, 
314                                   char *provider_name, char *name)
315 {
316     MpegTSService *service;
317
318 #ifdef DEBUG_SI
319     printf("new_service: sid=0x%04x provider='%s' name='%s'\n", 
320            sid, provider_name, name);
321 #endif
322
323     service = av_mallocz(sizeof(MpegTSService));
324     if (!service)
325         return NULL;
326     service->sid = sid;
327     service->provider_name = provider_name;
328     service->name = name;
329     dynarray_add(&ts->services, &ts->nb_services, service);
330     return service;
331 }
332
333 static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
334 {
335     MpegTSContext *ts = opaque;
336     SectionHeader h1, *h = &h1;
337     const uint8_t *p, *p_end;
338     int program_info_length, pcr_pid, pid, stream_type, desc_length;
339     
340 #ifdef DEBUG_SI
341     printf("PMT:\n");
342     av_hex_dump((uint8_t *)section, section_len);
343 #endif
344     p_end = section + section_len - 4;
345     p = section;
346     if (parse_section_header(h, &p, p_end) < 0)
347         return;
348 #ifdef DEBUG_SI
349     printf("sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num);
350 #endif
351     if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
352         return;
353
354     pcr_pid = get16(&p, p_end) & 0x1fff;
355     if (pcr_pid < 0)
356         return;
357 #ifdef DEBUG_SI
358     printf("pcr_pid=0x%x\n", pcr_pid);
359 #endif
360     program_info_length = get16(&p, p_end) & 0xfff;
361     if (program_info_length < 0)
362         return;
363     p += program_info_length;
364     if (p >= p_end)
365         return;
366     for(;;) {
367         stream_type = get8(&p, p_end);
368         if (stream_type < 0)
369             break;
370         pid = get16(&p, p_end) & 0x1fff;
371         if (pid < 0)
372             break;
373         desc_length = get16(&p, p_end) & 0xfff;
374         if (desc_length < 0)
375             break;
376         p += desc_length;
377         if (p > p_end)
378             return;
379
380 #ifdef DEBUG_SI
381         printf("stream_type=%d pid=0x%x\n", stream_type, pid);
382 #endif
383
384         /* now create ffmpeg stream */
385         switch(stream_type) {
386         case STREAM_TYPE_AUDIO_MPEG1:
387         case STREAM_TYPE_AUDIO_MPEG2:
388         case STREAM_TYPE_VIDEO_MPEG1:
389         case STREAM_TYPE_VIDEO_MPEG2:
390             add_pes_stream(ts->stream, pid);
391             break;
392         default:
393             /* we ignore the other streams */
394             break;
395         }
396     }
397     /* all parameters are there */
398     ts->set_service_cb(ts->set_service_opaque, 0);
399     mpegts_close_filter(ts, ts->pmt_filter);
400     ts->pmt_filter = NULL;
401 }
402
403 static void pat_cb(void *opaque, const uint8_t *section, int section_len)
404 {
405     MpegTSContext *ts = opaque;
406     SectionHeader h1, *h = &h1;
407     const uint8_t *p, *p_end;
408     int sid, pmt_pid;
409
410 #ifdef DEBUG_SI
411     printf("PAT:\n");
412     av_hex_dump((uint8_t *)section, section_len);
413 #endif
414     p_end = section + section_len - 4;
415     p = section;
416     if (parse_section_header(h, &p, p_end) < 0)
417         return;
418     if (h->tid != PAT_TID)
419         return;
420
421     for(;;) {
422         sid = get16(&p, p_end);
423         if (sid < 0)
424             break;
425         pmt_pid = get16(&p, p_end) & 0x1fff;
426         if (pmt_pid < 0)
427             break;
428 #ifdef DEBUG_SI
429         printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
430 #endif
431         if (sid == 0x0000) {
432             /* NIT info */
433         } else {
434             if (ts->req_sid == sid || ts->req_sid < 0) {
435                 ts->pmt_filter = mpegts_open_section_filter(ts, pmt_pid, 
436                                                             pmt_cb, ts, 1);
437                 goto found;
438             }
439         }
440     }
441     /* not found */
442     ts->set_service_cb(ts->set_service_opaque, -1);
443
444  found:
445     mpegts_close_filter(ts, ts->pat_filter);
446     ts->pat_filter = NULL;
447 }
448
449 void mpegts_set_service(MpegTSContext *ts, int sid,
450                         SetServiceCallback *set_service_cb, void *opaque)
451 {
452     ts->set_service_cb = set_service_cb;
453     ts->set_service_opaque = opaque;
454     ts->req_sid = sid;
455     ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID, 
456                                                 pat_cb, ts, 1);
457 }
458
459 static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
460 {
461     MpegTSContext *ts = opaque;
462     SectionHeader h1, *h = &h1;
463     const uint8_t *p, *p_end, *desc_list_end, *desc_end;
464     int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
465     char *name, *provider_name;
466
467 #ifdef DEBUG_SI
468     printf("SDT:\n");
469     av_hex_dump((uint8_t *)section, section_len);
470 #endif
471
472     p_end = section + section_len - 4;
473     p = section;
474     if (parse_section_header(h, &p, p_end) < 0)
475         return;
476     if (h->tid != SDT_TID)
477         return;
478     onid = get16(&p, p_end);
479     if (onid < 0)
480         return;
481     val = get8(&p, p_end);
482     if (val < 0)
483         return;
484     for(;;) {
485         sid = get16(&p, p_end);
486         if (sid < 0)
487             break;
488         val = get8(&p, p_end);
489         if (val < 0)
490             break;
491         desc_list_len = get16(&p, p_end) & 0xfff;
492         if (desc_list_len < 0)
493             break;
494         desc_list_end = p + desc_list_len;
495         if (desc_list_end > p_end)
496             break;
497         for(;;) {
498             desc_tag = get8(&p, desc_list_end);
499             if (desc_tag < 0)
500                 break;
501             desc_len = get8(&p, desc_list_end);
502             desc_end = p + desc_len;
503             if (desc_end > desc_list_end)
504                 break;
505 #ifdef DEBUG_SI
506             printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
507 #endif
508             switch(desc_tag) {
509             case 0x48:
510                 service_type = get8(&p, p_end);
511                 if (service_type < 0)
512                     break;
513                 provider_name = getstr8(&p, p_end);
514                 if (!provider_name)
515                     break;
516                 name = getstr8(&p, p_end);
517                 if (!name)
518                     break;
519                 new_service(ts, sid, provider_name, name);
520                 break;
521             default:
522                 break;
523             }
524             p = desc_end;
525         }
526         p = desc_list_end;
527     }
528     ts->stop_parse = 1;
529
530     /* remove filter */
531     mpegts_close_filter(ts, ts->sdt_filter);
532     ts->sdt_filter = NULL;
533 }
534
535 /* scan services an a transport stream by looking at the sdt */
536 void mpegts_scan_sdt(MpegTSContext *ts)
537 {
538     ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID, 
539                                                 sdt_cb, ts, 1);
540 }
541
542
543 /* TS stream handling */
544
545 enum MpegTSState {
546     MPEGTS_HEADER = 0,
547     MPEGTS_PESHEADER_FILL,
548     MPEGTS_PAYLOAD,
549     MPEGTS_SKIP,
550 };
551
552 /* enough for PES header + length */
553 #define PES_START_SIZE 9
554 #define MAX_PES_HEADER_SIZE (9 + 255)
555
556 typedef struct PESContext {
557     int pid;
558     AVFormatContext *stream;
559     AVStream *st;
560     enum MpegTSState state;
561     /* used to get the format */
562     int data_index;
563     int total_size;
564     int pes_header_size;
565     int64_t pts, dts;
566     uint8_t header[MAX_PES_HEADER_SIZE];
567 } PESContext;
568
569 static int64_t get_pts(const uint8_t *p)
570 {
571     int64_t pts;
572     int val;
573
574     pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
575     val = (p[1] << 8) | p[2];
576     pts |= (int64_t)(val >> 1) << 15;
577     val = (p[3] << 8) | p[4];
578     pts |= (int64_t)(val >> 1);
579     return pts;
580 }
581
582 /* return non zero if a packet could be constructed */
583 static void mpegts_push_data(void *opaque,
584                              const uint8_t *buf, int buf_size, int is_start)
585 {
586     PESContext *pes = opaque;
587     MpegTSContext *ts = pes->stream->priv_data;
588     AVStream *st;
589     const uint8_t *p;
590     int len, code, codec_type, codec_id;
591     
592     if (is_start) {
593         pes->state = MPEGTS_HEADER;
594         pes->data_index = 0;
595     }
596     p = buf;
597     while (buf_size > 0) {
598         switch(pes->state) {
599         case MPEGTS_HEADER:
600             len = PES_START_SIZE - pes->data_index;
601             if (len > buf_size)
602                 len = buf_size;
603             memcpy(pes->header + pes->data_index, p, len);
604             pes->data_index += len;
605             p += len;
606             buf_size -= len;
607             if (pes->data_index == PES_START_SIZE) {
608                 /* we got all the PES or section header. We can now
609                    decide */
610 #if 0
611                 av_hex_dump(pes->header, pes->data_index);
612 #endif
613                 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
614                     pes->header[2] == 0x01) {
615                     /* it must be an mpeg2 PES stream */
616                     /* XXX: add AC3 support */
617                     code = pes->header[3] | 0x100;
618                     if (!((code >= 0x1c0 && code <= 0x1df) ||
619                           (code >= 0x1e0 && code <= 0x1ef)))
620                         goto skip;
621                     if (!pes->st) {
622                         /* allocate stream */
623                         if (code >= 0x1c0 && code <= 0x1df) {
624                             codec_type = CODEC_TYPE_AUDIO;
625                             codec_id = CODEC_ID_MP2;
626                         } else {
627                             codec_type = CODEC_TYPE_VIDEO;
628                             codec_id = CODEC_ID_MPEG1VIDEO;
629                         }
630                         st = av_new_stream(pes->stream, pes->pid);
631                         if (st) {
632                             st->priv_data = pes;
633                             st->codec.codec_type = codec_type;
634                             st->codec.codec_id = codec_id;
635                             pes->st = st;
636                         }
637                     }
638                     pes->state = MPEGTS_PESHEADER_FILL;
639                     pes->total_size = (pes->header[4] << 8) | pes->header[5];
640                     /* NOTE: a zero total size means the PES size is
641                        unbounded */
642                     if (pes->total_size)
643                         pes->total_size += 6;
644                     pes->pes_header_size = pes->header[8] + 9;
645                 } else {
646                     /* otherwise, it should be a table */
647                     /* skip packet */
648                 skip:
649                     pes->state = MPEGTS_SKIP;
650                     continue;
651                 }
652             }
653             break;
654             /**********************************************/
655             /* PES packing parsing */
656         case MPEGTS_PESHEADER_FILL:
657             len = pes->pes_header_size - pes->data_index;
658             if (len > buf_size)
659                 len = buf_size;
660             memcpy(pes->header + pes->data_index, p, len);
661             pes->data_index += len;
662             p += len;
663             buf_size -= len;
664             if (pes->data_index == pes->pes_header_size) {
665                 const uint8_t *r;
666                 unsigned int flags;
667
668                 flags = pes->header[7];
669                 r = pes->header + 9;
670                 pes->pts = AV_NOPTS_VALUE;
671                 pes->dts = AV_NOPTS_VALUE;
672                 if ((flags & 0xc0) == 0x80) {
673                     pes->pts = get_pts(r);
674                     r += 5;
675                 } else if ((flags & 0xc0) == 0xc0) {
676                     pes->pts = get_pts(r);
677                     r += 5;
678                     pes->dts = get_pts(r);
679                     r += 5;
680                 }
681                 /* we got the full header. We parse it and get the payload */
682                 pes->state = MPEGTS_PAYLOAD;
683             }
684             break;
685         case MPEGTS_PAYLOAD:
686             if (pes->total_size) {
687                 len = pes->total_size - pes->data_index;
688                 if (len > buf_size)
689                     len = buf_size;
690             } else {
691                 len = buf_size;
692             }
693             if (len > 0) {
694                 AVPacket *pkt = ts->pkt;
695                 if (pes->st && av_new_packet(pkt, len) == 0) {
696                     memcpy(pkt->data, p, len);
697                     pkt->stream_index = pes->st->index;
698                     pkt->pts = pes->pts;
699                     /* reset pts values */
700                     pes->pts = AV_NOPTS_VALUE;
701                     pes->dts = AV_NOPTS_VALUE;
702                     ts->stop_parse = 1;
703                     return;
704                 }
705             }
706             buf_size = 0;
707             break;
708         case MPEGTS_SKIP:
709             buf_size = 0;
710             break;
711         }
712     }
713 }
714
715 static int add_pes_stream(AVFormatContext *s, int pid)
716 {
717     MpegTSContext *ts = s->priv_data;
718     MpegTSFilter *tss;
719     PESContext *pes;
720
721     /* if no pid found, then add a pid context */
722     pes = av_mallocz(sizeof(PESContext));
723     if (!pes)
724         return -1;
725     pes->stream = s;
726     pes->pid = pid;
727     tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
728     if (!tss) {
729         av_free(pes);
730         return -1;
731     }
732     return 0;
733 }
734
735 /* handle one TS packet */
736 static void handle_packet(AVFormatContext *s, uint8_t *packet)
737 {
738     MpegTSContext *ts = s->priv_data;
739     MpegTSFilter *tss;
740     int len, pid, cc, cc_ok, afc, is_start;
741     const uint8_t *p, *p_end;
742
743     pid = ((packet[1] & 0x1f) << 8) | packet[2];
744     is_start = packet[1] & 0x40;
745     tss = ts->pids[pid];
746     if (ts->auto_guess && tss == NULL && is_start) {
747         add_pes_stream(s, pid);
748         tss = ts->pids[pid];
749     }
750     if (!tss)
751         return;
752
753     /* continuity check (currently not used) */
754     cc = (packet[3] & 0xf);
755     cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
756     tss->last_cc = cc;
757     
758     /* skip adaptation field */
759     afc = (packet[3] >> 4) & 3;
760     p = packet + 4;
761     if (afc == 0) /* reserved value */
762         return;
763     if (afc == 2) /* adaptation field only */
764         return;
765     if (afc == 3) {
766         /* skip adapation field */
767         p += p[0] + 1;
768     }
769     /* if past the end of packet, ignore */
770     p_end = packet + TS_PACKET_SIZE;
771     if (p >= p_end)
772         return;
773     
774     if (tss->type == MPEGTS_SECTION) {
775         if (is_start) {
776             /* pointer field present */
777             len = *p++;
778             if (p + len > p_end)
779                 return;
780             if (len && cc_ok) {
781                 /* write remaning section bytes */
782                 write_section_data(s, tss, 
783                                    p, len, 0);
784             }
785             p += len;
786             if (p < p_end) {
787                 write_section_data(s, tss, 
788                                    p, p_end - p, 1);
789             }
790         } else {
791             if (cc_ok) {
792                 write_section_data(s, tss, 
793                                    p, p_end - p, 0);
794                 }
795         }
796     } else {
797         tss->u.pes_filter.pes_cb(tss->u.pes_filter.opaque, 
798                                  p, p_end - p, is_start);
799     }
800 }
801
802 static int handle_packets(AVFormatContext *s, int nb_packets)
803 {
804     MpegTSContext *ts = s->priv_data;
805     ByteIOContext *pb = &s->pb;
806     uint8_t packet[TS_FEC_PACKET_SIZE];
807     int packet_num, len;
808
809     ts->stop_parse = 0;
810     packet_num = 0;
811     for(;;) {
812         if (ts->stop_parse)
813             break;
814         packet_num++;
815         if (nb_packets != 0 && packet_num >= nb_packets)
816             break;
817         len = get_buffer(pb, packet, ts->raw_packet_size);
818         if (len != ts->raw_packet_size)
819             return AVERROR_IO;
820         /* check paquet sync byte */
821         /* XXX: accept to resync ? */
822         if (packet[0] != 0x47)
823             return AVERROR_INVALIDDATA;
824         handle_packet(s, packet);
825     }
826     return 0;
827 }
828
829 static int mpegts_probe(AVProbeData *p)
830 {
831     int size;
832     size = get_packet_size(p->buf, p->buf_size);
833     if (size < 0)
834         return 0;
835     return AVPROBE_SCORE_MAX - 1;
836 }
837
838 void set_service_cb(void *opaque, int ret)
839 {
840     MpegTSContext *ts = opaque;
841     ts->set_service_ret = ret;
842     ts->stop_parse = 1;
843 }
844
845 static int mpegts_read_header(AVFormatContext *s,
846                               AVFormatParameters *ap)
847 {
848     MpegTSContext *ts = s->priv_data;
849     ByteIOContext *pb = &s->pb;
850     uint8_t buf[1024];
851     int len;
852     int64_t pos;
853     MpegTSService *service;
854     
855     /* read the first 1024 bytes to get packet size */
856     pos = url_ftell(pb);
857     len = get_buffer(pb, buf, sizeof(buf));
858     if (len != sizeof(buf))
859         goto fail;
860     ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
861     if (ts->raw_packet_size <= 0)
862         goto fail;
863     ts->auto_guess = 0;
864     
865     if (!ts->auto_guess) {
866         int sid = -1;
867         ts->set_service_ret = -1;
868
869         /* first do a scaning to get all the services */
870         url_fseek(pb, pos, SEEK_SET);
871         mpegts_scan_sdt(ts);
872         
873         handle_packets(s, MAX_SCAN_PACKETS);
874
875         if (ts->nb_services > 0)
876         {
877             /* tune to first service found */
878             service = ts->services[0];
879             sid = service->sid;
880 #ifdef DEBUG_SI
881             printf("tuning to '%s'\n", service->name);
882 #endif
883         }
884
885         /* now find the info for the first service if we found any,
886            otherwise try to filter all PATs */
887
888         url_fseek(pb, pos, SEEK_SET);
889         ts->stream = s;
890         mpegts_set_service(ts, sid, set_service_cb, ts);
891
892         handle_packets(s, MAX_SCAN_PACKETS);
893
894         /* if could not find service, exit */
895         if (ts->set_service_ret != 0)
896             return -1;
897
898 #ifdef DEBUG_SI
899         printf("tuning done\n");
900 #endif
901     }
902
903     url_fseek(pb, pos, SEEK_SET);
904     return 0;
905  fail:
906     return -1;
907 }
908
909 static int mpegts_read_packet(AVFormatContext *s,
910                               AVPacket *pkt)
911 {
912     MpegTSContext *ts = s->priv_data;
913     ts->pkt = pkt;
914     return handle_packets(s, 0);
915 }
916
917 static int mpegts_read_close(AVFormatContext *s)
918 {
919     MpegTSContext *ts = s->priv_data;
920     int i;
921     for(i=0;i<NB_PID_MAX;i++)
922         av_free(ts->pids[i]);
923     return 0;
924 }
925
926 AVInputFormat mpegts_demux = {
927     "mpegts",
928     "MPEG2 transport stream format",
929     sizeof(MpegTSContext),
930     mpegts_probe,
931     mpegts_read_header,
932     mpegts_read_packet,
933     mpegts_read_close,
934     .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS,
935 };
936
937 int mpegts_init(void)
938 {
939     av_register_input_format(&mpegts_demux);
940     av_register_output_format(&mpegts_mux);
941     return 0;
942 }