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