added fake codec CODEC_ID_MPEG2TS of type CODEC_TYPE_DATA (needed for simpler handlin...
[libav.git] / libavformat / mpegts.c
CommitLineData
fe9cf0d4
FB
1/*
2 * MPEG2 transport stream (aka DVB) demux
5dbafeb7 3 * Copyright (c) 2002-2003 Fabrice Bellard.
fe9cf0d4 4 *
19720f15
FB
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.
fe9cf0d4 9 *
19720f15 10 * This library is distributed in the hope that it will be useful,
fe9cf0d4 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
fe9cf0d4 14 *
19720f15
FB
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
fe9cf0d4
FB
18 */
19#include "avformat.h"
20
5dbafeb7 21#include "mpegts.h"
fe9cf0d4 22
5dbafeb7
FB
23//#define DEBUG_SI
24
25/* 1.0 second at 24Mbit/s */
fc48fe84
FB
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
5dbafeb7
FB
31
32static int add_pes_stream(AVFormatContext *s, int pid);
33
34enum MpegTSFilterType {
35 MPEGTS_PES,
36 MPEGTS_SECTION,
fe9cf0d4
FB
37};
38
5dbafeb7 39typedef void PESCallback(void *opaque, const uint8_t *buf, int len, int is_start);
fe9cf0d4 40
5dbafeb7
FB
41typedef struct MpegTSPESFilter {
42 PESCallback *pes_cb;
43 void *opaque;
44} MpegTSPESFilter;
45
46typedef void SectionCallback(void *opaque, const uint8_t *buf, int len);
47
48typedef void SetServiceCallback(void *opaque, int ret);
49
50typedef 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
60typedef struct MpegTSFilter {
fe9cf0d4 61 int pid;
fe9cf0d4 62 int last_cc; /* last cc code (-1 if first packet) */
5dbafeb7
FB
63 enum MpegTSFilterType type;
64 union {
65 MpegTSPESFilter pes_filter;
66 MpegTSSectionFilter section_filter;
67 } u;
68} MpegTSFilter;
69
70typedef struct MpegTSService {
71 int running:1;
72 int sid;
73 char *provider_name;
74 char *name;
75} MpegTSService;
fe9cf0d4
FB
76
77typedef struct MpegTSContext {
5dbafeb7
FB
78 /* user data */
79 AVFormatContext *stream;
fe9cf0d4 80 int raw_packet_size; /* raw packet size, including FEC if present */
5dbafeb7
FB
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];
fe9cf0d4
FB
103} MpegTSContext;
104
5dbafeb7
FB
105static 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
147MpegTSFilter *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
176MpegTSFilter *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
198void 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
fe9cf0d4 209/* autodetect fec presence. Must have at least 1024 bytes */
5dbafeb7 210static int get_packet_size(const uint8_t *buf, int size)
fe9cf0d4
FB
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
5dbafeb7
FB
229typedef 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
237static inline int get8(const uint8_t **pp, const uint8_t *p_end)
fe9cf0d4 238{
5dbafeb7
FB
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;
fe9cf0d4
FB
248}
249
5dbafeb7
FB
250static 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 */
265static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
fe9cf0d4 266{
fe9cf0d4 267 int len;
5dbafeb7
FB
268 const uint8_t *p;
269 char *str;
fe9cf0d4 270
5dbafeb7
FB
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
287static 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;
fe9cf0d4 313 return 0;
5dbafeb7
FB
314}
315
316static 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
336static 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
ce34182d 354 if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
5dbafeb7
FB
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) {
ce34182d
MN
389 case STREAM_TYPE_AUDIO_MPEG1:
390 case STREAM_TYPE_AUDIO_MPEG2:
391 case STREAM_TYPE_VIDEO_MPEG1:
392 case STREAM_TYPE_VIDEO_MPEG2:
ec23a472 393 case STREAM_TYPE_AUDIO_AC3:
5dbafeb7
FB
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
407static 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 {
fc48fe84 438 if (ts->req_sid == sid) {
5dbafeb7
FB
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
fc48fe84
FB
453/* add all services found in the PAT */
454static 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
5dbafeb7
FB
506void 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
516static 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
fc48fe84 592/* scan services in a transport stream by looking at the SDT */
5dbafeb7
FB
593void mpegts_scan_sdt(MpegTSContext *ts)
594{
595 ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID,
596 sdt_cb, ts, 1);
597}
598
fc48fe84
FB
599/* scan services in a transport stream by looking at the PAT (better
600 than nothing !) */
601void mpegts_scan_pat(MpegTSContext *ts)
602{
603 ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID,
604 pat_scan_cb, ts, 1);
605}
5dbafeb7
FB
606
607/* TS stream handling */
608
609enum 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
620typedef 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
633static 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;
fe9cf0d4
FB
644}
645
646/* return non zero if a packet could be constructed */
5dbafeb7
FB
647static void mpegts_push_data(void *opaque,
648 const uint8_t *buf, int buf_size, int is_start)
fe9cf0d4 649{
5dbafeb7
FB
650 PESContext *pes = opaque;
651 MpegTSContext *ts = pes->stream->priv_data;
fe9cf0d4 652 AVStream *st;
5dbafeb7 653 const uint8_t *p;
fe9cf0d4 654 int len, code, codec_type, codec_id;
5dbafeb7 655
fe9cf0d4 656 if (is_start) {
5dbafeb7
FB
657 pes->state = MPEGTS_HEADER;
658 pes->data_index = 0;
fe9cf0d4
FB
659 }
660 p = buf;
661 while (buf_size > 0) {
5dbafeb7 662 switch(pes->state) {
fe9cf0d4 663 case MPEGTS_HEADER:
5dbafeb7
FB
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;
fe9cf0d4
FB
669 p += len;
670 buf_size -= len;
5dbafeb7 671 if (pes->data_index == PES_START_SIZE) {
fe9cf0d4
FB
672 /* we got all the PES or section header. We can now
673 decide */
674#if 0
5dbafeb7 675 av_hex_dump(pes->header, pes->data_index);
fe9cf0d4 676#endif
5dbafeb7
FB
677 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
678 pes->header[2] == 0x01) {
fe9cf0d4 679 /* it must be an mpeg2 PES stream */
5dbafeb7 680 code = pes->header[3] | 0x100;
fe9cf0d4 681 if (!((code >= 0x1c0 && code <= 0x1df) ||
ec23a472
IR
682 (code >= 0x1e0 && code <= 0x1ef) ||
683 (code == 0x1bd)))
fe9cf0d4 684 goto skip;
5dbafeb7 685 if (!pes->st) {
fe9cf0d4
FB
686 /* allocate stream */
687 if (code >= 0x1c0 && code <= 0x1df) {
688 codec_type = CODEC_TYPE_AUDIO;
689 codec_id = CODEC_ID_MP2;
ec23a472
IR
690 } else if (code == 0x1bd) {
691 codec_type = CODEC_TYPE_AUDIO;
692 codec_id = CODEC_ID_AC3;
fe9cf0d4
FB
693 } else {
694 codec_type = CODEC_TYPE_VIDEO;
695 codec_id = CODEC_ID_MPEG1VIDEO;
696 }
5dbafeb7 697 st = av_new_stream(pes->stream, pes->pid);
fe9cf0d4 698 if (st) {
5dbafeb7 699 st->priv_data = pes;
fe9cf0d4
FB
700 st->codec.codec_type = codec_type;
701 st->codec.codec_id = codec_id;
5dbafeb7 702 pes->st = st;
fe9cf0d4
FB
703 }
704 }
5dbafeb7
FB
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;
fe9cf0d4
FB
712 } else {
713 /* otherwise, it should be a table */
714 /* skip packet */
715 skip:
5dbafeb7 716 pes->state = MPEGTS_SKIP;
fe9cf0d4
FB
717 continue;
718 }
719 }
720 break;
721 /**********************************************/
722 /* PES packing parsing */
723 case MPEGTS_PESHEADER_FILL:
5dbafeb7
FB
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;
fe9cf0d4
FB
729 p += len;
730 buf_size -= len;
5dbafeb7
FB
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 }
fe9cf0d4
FB
751 break;
752 case MPEGTS_PAYLOAD:
5dbafeb7
FB
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 }
fe9cf0d4 760 if (len > 0) {
5dbafeb7
FB
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;
fe9cf0d4 771 }
fe9cf0d4
FB
772 }
773 buf_size = 0;
774 break;
775 case MPEGTS_SKIP:
776 buf_size = 0;
777 break;
778 }
779 }
5dbafeb7
FB
780}
781
782static 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 }
fe9cf0d4
FB
799 return 0;
800}
801
5dbafeb7
FB
802/* handle one TS packet */
803static void handle_packet(AVFormatContext *s, uint8_t *packet)
fe9cf0d4
FB
804{
805 MpegTSContext *ts = s->priv_data;
5dbafeb7
FB
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;
fe9cf0d4 824
5dbafeb7
FB
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);
fc48fe84 861 }
5dbafeb7
FB
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
fc48fe84
FB
869/* XXX: try to find a better synchro over several packets (use
870 get_packet_size() ?) */
871static 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
5dbafeb7
FB
889static 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;
ec23a472 895 int64_t pos;
5dbafeb7
FB
896
897 ts->stop_parse = 0;
898 packet_num = 0;
fe9cf0d4 899 for(;;) {
5dbafeb7
FB
900 if (ts->stop_parse)
901 break;
902 packet_num++;
903 if (nb_packets != 0 && packet_num >= nb_packets)
904 break;
ec23a472 905 pos = url_ftell(pb);
fe9cf0d4
FB
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 */
fc48fe84
FB
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;
ec23a472 917 }
5dbafeb7
FB
918 handle_packet(s, packet);
919 }
920 return 0;
921}
fe9cf0d4 922
5dbafeb7
FB
923static int mpegts_probe(AVProbeData *p)
924{
fc48fe84 925#if 1
5dbafeb7
FB
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;
fc48fe84
FB
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
5dbafeb7
FB
938}
939
940void 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
947static 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];
fc48fe84 953 int len, sid;
5dbafeb7
FB
954 int64_t pos;
955 MpegTSService *service;
fe9cf0d4 956
5dbafeb7
FB
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) {
ce34182d 968 ts->set_service_ret = -1;
5dbafeb7
FB
969
970 /* first do a scaning to get all the services */
971 url_fseek(pb, pos, SEEK_SET);
972 mpegts_scan_sdt(ts);
fc48fe84 973
5dbafeb7 974 handle_packets(s, MAX_SCAN_PACKETS);
ce34182d 975
fc48fe84
FB
976 if (ts->nb_services <= 0) {
977 /* no SDT found, we try to look at the PAT */
66535069
DL
978
979 /* First remove the SDT filters from each PID */
980 int i;
981 for (i=0; i < NB_PID_MAX; i++) {
982 if (ts->pids[i])
983 mpegts_close_filter(ts, ts->pids[i]);
984 }
fc48fe84
FB
985 url_fseek(pb, pos, SEEK_SET);
986 mpegts_scan_pat(ts);
987
988 handle_packets(s, MAX_SCAN_PACKETS);
989 }
990
991 if (ts->nb_services <= 0)
992 return -1;
993
994 /* tune to first service found */
995 service = ts->services[0];
996 sid = service->sid;
5dbafeb7 997#ifdef DEBUG_SI
fc48fe84 998 printf("tuning to '%s'\n", service->name);
5dbafeb7 999#endif
ce34182d
MN
1000
1001 /* now find the info for the first service if we found any,
1002 otherwise try to filter all PATs */
1003
1004 url_fseek(pb, pos, SEEK_SET);
5dbafeb7 1005 ts->stream = s;
ce34182d
MN
1006 mpegts_set_service(ts, sid, set_service_cb, ts);
1007
5dbafeb7
FB
1008 handle_packets(s, MAX_SCAN_PACKETS);
1009
1010 /* if could not find service, exit */
1011 if (ts->set_service_ret != 0)
1012 return -1;
1013
1014#ifdef DEBUG_SI
1015 printf("tuning done\n");
1016#endif
fe9cf0d4 1017 }
5dbafeb7
FB
1018
1019 url_fseek(pb, pos, SEEK_SET);
fe9cf0d4 1020 return 0;
5dbafeb7
FB
1021 fail:
1022 return -1;
1023}
1024
1025static int mpegts_read_packet(AVFormatContext *s,
1026 AVPacket *pkt)
1027{
1028 MpegTSContext *ts = s->priv_data;
1029 ts->pkt = pkt;
1030 return handle_packets(s, 0);
fe9cf0d4
FB
1031}
1032
1033static int mpegts_read_close(AVFormatContext *s)
1034{
1035 MpegTSContext *ts = s->priv_data;
1036 int i;
1037 for(i=0;i<NB_PID_MAX;i++)
754ebe34 1038 av_free(ts->pids[i]);
fe9cf0d4
FB
1039 return 0;
1040}
1041
1042AVInputFormat mpegts_demux = {
1043 "mpegts",
1044 "MPEG2 transport stream format",
1045 sizeof(MpegTSContext),
1046 mpegts_probe,
1047 mpegts_read_header,
1048 mpegts_read_packet,
1049 mpegts_read_close,
bb76a117 1050 .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS,
fe9cf0d4
FB
1051};
1052
1053int mpegts_init(void)
1054{
1055 av_register_input_format(&mpegts_demux);
764ef400 1056#ifdef CONFIG_ENCODERS
5dbafeb7 1057 av_register_output_format(&mpegts_mux);
764ef400 1058#endif
fe9cf0d4
FB
1059 return 0;
1060}