mpeg ts demux uses DVB SI info and generates correct PTS info - added prototype mpeg...
[ffmpeg.git] / 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 || 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:
387         case STREAM_TYPE_VIDEO:
388             add_pes_stream(ts->stream, pid);
389             break;
390         default:
391             /* we ignore the other streams */
392             break;
393         }
394     }
395     /* all parameters are there */
396     ts->set_service_cb(ts->set_service_opaque, 0);
397     mpegts_close_filter(ts, ts->pmt_filter);
398     ts->pmt_filter = NULL;
399 }
400
401 static void pat_cb(void *opaque, const uint8_t *section, int section_len)
402 {
403     MpegTSContext *ts = opaque;
404     SectionHeader h1, *h = &h1;
405     const uint8_t *p, *p_end;
406     int sid, pmt_pid;
407
408 #ifdef DEBUG_SI
409     printf("PAT:\n");
410     av_hex_dump((uint8_t *)section, section_len);
411 #endif
412     p_end = section + section_len - 4;
413     p = section;
414     if (parse_section_header(h, &p, p_end) < 0)
415         return;
416     if (h->tid != PAT_TID)
417         return;
418
419     for(;;) {
420         sid = get16(&p, p_end);
421         if (sid < 0)
422             break;
423         pmt_pid = get16(&p, p_end) & 0x1fff;
424         if (pmt_pid < 0)
425             break;
426 #ifdef DEBUG_SI
427         printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
428 #endif
429         if (sid == 0x0000) {
430             /* NIT info */
431         } else {
432             if (ts->req_sid == sid) {
433                 ts->pmt_filter = mpegts_open_section_filter(ts, pmt_pid, 
434                                                             pmt_cb, ts, 1);
435                 goto found;
436             }
437         }
438     }
439     /* not found */
440     ts->set_service_cb(ts->set_service_opaque, -1);
441
442  found:
443     mpegts_close_filter(ts, ts->pat_filter);
444     ts->pat_filter = NULL;
445 }
446
447 void mpegts_set_service(MpegTSContext *ts, int sid,
448                         SetServiceCallback *set_service_cb, void *opaque)
449 {
450     ts->set_service_cb = set_service_cb;
451     ts->set_service_opaque = opaque;
452     ts->req_sid = sid;
453     ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID, 
454                                                 pat_cb, ts, 1);
455 }
456
457 static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
458 {
459     MpegTSContext *ts = opaque;
460     SectionHeader h1, *h = &h1;
461     const uint8_t *p, *p_end, *desc_list_end, *desc_end;
462     int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
463     char *name, *provider_name;
464
465 #ifdef DEBUG_SI
466     printf("SDT:\n");
467     av_hex_dump((uint8_t *)section, section_len);
468 #endif
469
470     p_end = section + section_len - 4;
471     p = section;
472     if (parse_section_header(h, &p, p_end) < 0)
473         return;
474     if (h->tid != SDT_TID)
475         return;
476     onid = get16(&p, p_end);
477     if (onid < 0)
478         return;
479     val = get8(&p, p_end);
480     if (val < 0)
481         return;
482     for(;;) {
483         sid = get16(&p, p_end);
484         if (sid < 0)
485             break;
486         val = get8(&p, p_end);
487         if (val < 0)
488             break;
489         desc_list_len = get16(&p, p_end) & 0xfff;
490         if (desc_list_len < 0)
491             break;
492         desc_list_end = p + desc_list_len;
493         if (desc_list_end > p_end)
494             break;
495         for(;;) {
496             desc_tag = get8(&p, desc_list_end);
497             if (desc_tag < 0)
498                 break;
499             desc_len = get8(&p, desc_list_end);
500             desc_end = p + desc_len;
501             if (desc_end > desc_list_end)
502                 break;
503 #ifdef DEBUG_SI
504             printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
505 #endif
506             switch(desc_tag) {
507             case 0x48:
508                 service_type = get8(&p, p_end);
509                 if (service_type < 0)
510                     break;
511                 provider_name = getstr8(&p, p_end);
512                 if (!provider_name)
513                     break;
514                 name = getstr8(&p, p_end);
515                 if (!name)
516                     break;
517                 new_service(ts, sid, provider_name, name);
518                 break;
519             default:
520                 break;
521             }
522             p = desc_end;
523         }
524         p = desc_list_end;
525     }
526     ts->stop_parse = 1;
527
528     /* remove filter */
529     mpegts_close_filter(ts, ts->sdt_filter);
530     ts->sdt_filter = NULL;
531 }
532
533 /* scan services an a transport stream by looking at the sdt */
534 void mpegts_scan_sdt(MpegTSContext *ts)
535 {
536     ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID, 
537                                                 sdt_cb, ts, 1);
538 }
539
540
541 /* TS stream handling */
542
543 enum MpegTSState {
544     MPEGTS_HEADER = 0,
545     MPEGTS_PESHEADER_FILL,
546     MPEGTS_PAYLOAD,
547     MPEGTS_SKIP,
548 };
549
550 /* enough for PES header + length */
551 #define PES_START_SIZE 9
552 #define MAX_PES_HEADER_SIZE (9 + 255)
553
554 typedef struct PESContext {
555     int pid;
556     AVFormatContext *stream;
557     AVStream *st;
558     enum MpegTSState state;
559     /* used to get the format */
560     int data_index;
561     int total_size;
562     int pes_header_size;
563     int64_t pts, dts;
564     uint8_t header[MAX_PES_HEADER_SIZE];
565 } PESContext;
566
567 static int64_t get_pts(const uint8_t *p)
568 {
569     int64_t pts;
570     int val;
571
572     pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
573     val = (p[1] << 8) | p[2];
574     pts |= (int64_t)(val >> 1) << 15;
575     val = (p[3] << 8) | p[4];
576     pts |= (int64_t)(val >> 1);
577     return pts;
578 }
579
580 /* return non zero if a packet could be constructed */
581 static void mpegts_push_data(void *opaque,
582                              const uint8_t *buf, int buf_size, int is_start)
583 {
584     PESContext *pes = opaque;
585     MpegTSContext *ts = pes->stream->priv_data;
586     AVStream *st;
587     const uint8_t *p;
588     int len, code, codec_type, codec_id;
589     
590     if (is_start) {
591         pes->state = MPEGTS_HEADER;
592         pes->data_index = 0;
593     }
594     p = buf;
595     while (buf_size > 0) {
596         switch(pes->state) {
597         case MPEGTS_HEADER:
598             len = PES_START_SIZE - pes->data_index;
599             if (len > buf_size)
600                 len = buf_size;
601             memcpy(pes->header + pes->data_index, p, len);
602             pes->data_index += len;
603             p += len;
604             buf_size -= len;
605             if (pes->data_index == PES_START_SIZE) {
606                 /* we got all the PES or section header. We can now
607                    decide */
608 #if 0
609                 av_hex_dump(pes->header, pes->data_index);
610 #endif
611                 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
612                     pes->header[2] == 0x01) {
613                     /* it must be an mpeg2 PES stream */
614                     /* XXX: add AC3 support */
615                     code = pes->header[3] | 0x100;
616                     if (!((code >= 0x1c0 && code <= 0x1df) ||
617                           (code >= 0x1e0 && code <= 0x1ef)))
618                         goto skip;
619                     if (!pes->st) {
620                         /* allocate stream */
621                         if (code >= 0x1c0 && code <= 0x1df) {
622                             codec_type = CODEC_TYPE_AUDIO;
623                             codec_id = CODEC_ID_MP2;
624                         } else {
625                             codec_type = CODEC_TYPE_VIDEO;
626                             codec_id = CODEC_ID_MPEG1VIDEO;
627                         }
628                         st = av_new_stream(pes->stream, pes->pid);
629                         if (st) {
630                             st->priv_data = pes;
631                             st->codec.codec_type = codec_type;
632                             st->codec.codec_id = codec_id;
633                             pes->st = st;
634                         }
635                     }
636                     pes->state = MPEGTS_PESHEADER_FILL;
637                     pes->total_size = (pes->header[4] << 8) | pes->header[5];
638                     /* NOTE: a zero total size means the PES size is
639                        unbounded */
640                     if (pes->total_size)
641                         pes->total_size += 6;
642                     pes->pes_header_size = pes->header[8] + 9;
643                 } else {
644                     /* otherwise, it should be a table */
645                     /* skip packet */
646                 skip:
647                     pes->state = MPEGTS_SKIP;
648                     continue;
649                 }
650             }
651             break;
652             /**********************************************/
653             /* PES packing parsing */
654         case MPEGTS_PESHEADER_FILL:
655             len = pes->pes_header_size - pes->data_index;
656             if (len > buf_size)
657                 len = buf_size;
658             memcpy(pes->header + pes->data_index, p, len);
659             pes->data_index += len;
660             p += len;
661             buf_size -= len;
662             if (pes->data_index == pes->pes_header_size) {
663                 const uint8_t *r;
664                 unsigned int flags;
665
666                 flags = pes->header[7];
667                 r = pes->header + 9;
668                 pes->pts = AV_NOPTS_VALUE;
669                 pes->dts = AV_NOPTS_VALUE;
670                 if ((flags & 0xc0) == 0x80) {
671                     pes->pts = get_pts(r);
672                     r += 5;
673                 } else if ((flags & 0xc0) == 0xc0) {
674                     pes->pts = get_pts(r);
675                     r += 5;
676                     pes->dts = get_pts(r);
677                     r += 5;
678                 }
679                 /* we got the full header. We parse it and get the payload */
680                 pes->state = MPEGTS_PAYLOAD;
681             }
682             break;
683         case MPEGTS_PAYLOAD:
684             if (pes->total_size) {
685                 len = pes->total_size - pes->data_index;
686                 if (len > buf_size)
687                     len = buf_size;
688             } else {
689                 len = buf_size;
690             }
691             if (len > 0) {
692                 AVPacket *pkt = ts->pkt;
693                 if (pes->st && av_new_packet(pkt, len) == 0) {
694                     memcpy(pkt->data, p, len);
695                     pkt->stream_index = pes->st->index;
696                     pkt->pts = pes->pts;
697                     /* reset pts values */
698                     pes->pts = AV_NOPTS_VALUE;
699                     pes->dts = AV_NOPTS_VALUE;
700                     ts->stop_parse = 1;
701                     return;
702                 }
703             }
704             buf_size = 0;
705             break;
706         case MPEGTS_SKIP:
707             buf_size = 0;
708             break;
709         }
710     }
711 }
712
713 static int add_pes_stream(AVFormatContext *s, int pid)
714 {
715     MpegTSContext *ts = s->priv_data;
716     MpegTSFilter *tss;
717     PESContext *pes;
718
719     /* if no pid found, then add a pid context */
720     pes = av_mallocz(sizeof(PESContext));
721     if (!pes)
722         return -1;
723     pes->stream = s;
724     pes->pid = pid;
725     tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
726     if (!tss) {
727         av_free(pes);
728         return -1;
729     }
730     return 0;
731 }
732
733 /* handle one TS packet */
734 static void handle_packet(AVFormatContext *s, uint8_t *packet)
735 {
736     MpegTSContext *ts = s->priv_data;
737     MpegTSFilter *tss;
738     int len, pid, cc, cc_ok, afc, is_start;
739     const uint8_t *p, *p_end;
740
741     pid = ((packet[1] & 0x1f) << 8) | packet[2];
742     is_start = packet[1] & 0x40;
743     tss = ts->pids[pid];
744     if (ts->auto_guess && tss == NULL && is_start) {
745         add_pes_stream(s, pid);
746         tss = ts->pids[pid];
747     }
748     if (!tss)
749         return;
750
751     /* continuity check (currently not used) */
752     cc = (packet[3] & 0xf);
753     cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
754     tss->last_cc = cc;
755     
756     /* skip adaptation field */
757     afc = (packet[3] >> 4) & 3;
758     p = packet + 4;
759     if (afc == 0) /* reserved value */
760         return;
761     if (afc == 2) /* adaptation field only */
762         return;
763     if (afc == 3) {
764         /* skip adapation field */
765         p += p[0] + 1;
766     }
767     /* if past the end of packet, ignore */
768     p_end = packet + TS_PACKET_SIZE;
769     if (p >= p_end)
770         return;
771     
772     if (tss->type == MPEGTS_SECTION) {
773         if (is_start) {
774             /* pointer field present */
775             len = *p++;
776             if (p + len > p_end)
777                 return;
778             if (len && cc_ok) {
779                 /* write remaning section bytes */
780                 write_section_data(s, tss, 
781                                    p, len, 0);
782             }
783             p += len;
784             if (p < p_end) {
785                 write_section_data(s, tss, 
786                                    p, p_end - p, 1);
787             }
788         } else {
789             if (cc_ok) {
790                 write_section_data(s, tss, 
791                                    p, p_end - p, 0);
792                 }
793         }
794     } else {
795         tss->u.pes_filter.pes_cb(tss->u.pes_filter.opaque, 
796                                  p, p_end - p, is_start);
797     }
798 }
799
800 static int handle_packets(AVFormatContext *s, int nb_packets)
801 {
802     MpegTSContext *ts = s->priv_data;
803     ByteIOContext *pb = &s->pb;
804     uint8_t packet[TS_FEC_PACKET_SIZE];
805     int packet_num, len;
806
807     ts->stop_parse = 0;
808     packet_num = 0;
809     for(;;) {
810         if (ts->stop_parse)
811             break;
812         packet_num++;
813         if (nb_packets != 0 && packet_num >= nb_packets)
814             break;
815         len = get_buffer(pb, packet, ts->raw_packet_size);
816         if (len != ts->raw_packet_size)
817             return AVERROR_IO;
818         /* check paquet sync byte */
819         /* XXX: accept to resync ? */
820         if (packet[0] != 0x47)
821             return AVERROR_INVALIDDATA;
822         handle_packet(s, packet);
823     }
824     return 0;
825 }
826
827 static int mpegts_probe(AVProbeData *p)
828 {
829     int size;
830     size = get_packet_size(p->buf, p->buf_size);
831     if (size < 0)
832         return 0;
833     return AVPROBE_SCORE_MAX - 1;
834 }
835
836 void set_service_cb(void *opaque, int ret)
837 {
838     MpegTSContext *ts = opaque;
839     ts->set_service_ret = ret;
840     ts->stop_parse = 1;
841 }
842
843 static int mpegts_read_header(AVFormatContext *s,
844                               AVFormatParameters *ap)
845 {
846     MpegTSContext *ts = s->priv_data;
847     ByteIOContext *pb = &s->pb;
848     uint8_t buf[1024];
849     int len;
850     int64_t pos;
851     MpegTSService *service;
852     
853     /* read the first 1024 bytes to get packet size */
854     pos = url_ftell(pb);
855     len = get_buffer(pb, buf, sizeof(buf));
856     if (len != sizeof(buf))
857         goto fail;
858     ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
859     if (ts->raw_packet_size <= 0)
860         goto fail;
861     ts->auto_guess = 0;
862     
863     if (!ts->auto_guess) {
864
865         /* first do a scaning to get all the services */
866         url_fseek(pb, pos, SEEK_SET);
867         mpegts_scan_sdt(ts);
868         
869         handle_packets(s, MAX_SCAN_PACKETS);
870         
871         /* if no service found, no need to do anything */
872         if (ts->nb_services <= 0)
873             return -1;
874         
875         /* now find the info for the first service */
876         
877         url_fseek(pb, pos, SEEK_SET);
878         service = ts->services[0];
879 #ifdef DEBUG_SI
880         printf("tuning to '%s'\n", service->name);
881 #endif
882         /* tune to first service found */
883         ts->stream = s;
884         mpegts_set_service(ts, service->sid, set_service_cb, ts);
885         
886         handle_packets(s, MAX_SCAN_PACKETS);
887
888         /* if could not find service, exit */
889         if (ts->set_service_ret != 0)
890             return -1;
891
892 #ifdef DEBUG_SI
893         printf("tuning done\n");
894 #endif
895     }
896
897     url_fseek(pb, pos, SEEK_SET);
898     return 0;
899  fail:
900     return -1;
901 }
902
903 static int mpegts_read_packet(AVFormatContext *s,
904                               AVPacket *pkt)
905 {
906     MpegTSContext *ts = s->priv_data;
907     ts->pkt = pkt;
908     return handle_packets(s, 0);
909 }
910
911 static int mpegts_read_close(AVFormatContext *s)
912 {
913     MpegTSContext *ts = s->priv_data;
914     int i;
915     for(i=0;i<NB_PID_MAX;i++)
916         av_free(ts->pids[i]);
917     return 0;
918 }
919
920 AVInputFormat mpegts_demux = {
921     "mpegts",
922     "MPEG2 transport stream format",
923     sizeof(MpegTSContext),
924     mpegts_probe,
925     mpegts_read_header,
926     mpegts_read_packet,
927     mpegts_read_close,
928     .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS,
929 };
930
931 int mpegts_init(void)
932 {
933     av_register_input_format(&mpegts_demux);
934     av_register_output_format(&mpegts_mux);
935     return 0;
936 }