FF_DEBUG_PICT_INFO and CODEC_FLAG_GRAY support
[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 23//#define DEBUG_SI
27f388aa 24//#define DEBUG_SEEK
5dbafeb7
FB
25
26/* 1.0 second at 24Mbit/s */
fc48fe84
FB
27#define MAX_SCAN_PACKETS 32000
28
29/* maximum size in which we look for synchronisation if
30 synchronisation is lost */
31#define MAX_RESYNC_SIZE 4096
5dbafeb7 32
278de475 33static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type);
5dbafeb7
FB
34
35enum MpegTSFilterType {
36 MPEGTS_PES,
37 MPEGTS_SECTION,
fe9cf0d4
FB
38};
39
5dbafeb7 40typedef void PESCallback(void *opaque, const uint8_t *buf, int len, int is_start);
fe9cf0d4 41
5dbafeb7
FB
42typedef struct MpegTSPESFilter {
43 PESCallback *pes_cb;
44 void *opaque;
45} MpegTSPESFilter;
46
47typedef void SectionCallback(void *opaque, const uint8_t *buf, int len);
48
49typedef void SetServiceCallback(void *opaque, int ret);
50
51typedef struct MpegTSSectionFilter {
52 int section_index;
53 int section_h_size;
54 uint8_t *section_buf;
55 int check_crc:1;
56 int end_of_section_reached:1;
57 SectionCallback *section_cb;
58 void *opaque;
59} MpegTSSectionFilter;
60
61typedef struct MpegTSFilter {
fe9cf0d4 62 int pid;
fe9cf0d4 63 int last_cc; /* last cc code (-1 if first packet) */
5dbafeb7
FB
64 enum MpegTSFilterType type;
65 union {
66 MpegTSPESFilter pes_filter;
67 MpegTSSectionFilter section_filter;
68 } u;
69} MpegTSFilter;
70
71typedef struct MpegTSService {
72 int running:1;
73 int sid;
74 char *provider_name;
75 char *name;
76} MpegTSService;
fe9cf0d4 77
b45a7a18 78struct MpegTSContext {
5dbafeb7
FB
79 /* user data */
80 AVFormatContext *stream;
fe9cf0d4 81 int raw_packet_size; /* raw packet size, including FEC if present */
5dbafeb7
FB
82 int auto_guess; /* if true, all pids are analized to find streams */
83 int set_service_ret;
84
b45a7a18
FB
85 int mpeg2ts_raw; /* force raw MPEG2 transport stream output, if possible */
86 int mpeg2ts_compute_pcr; /* compute exact PCR for each transport stream packet */
87
88 /* used to estimate the exact PCR */
89 int64_t cur_pcr;
90 int pcr_incr;
27f388aa
FB
91 int pcr_pid;
92
5dbafeb7
FB
93 /* data needed to handle file based ts */
94 int stop_parse; /* stop parsing loop */
95 AVPacket *pkt; /* packet containing av data */
96
97 /******************************************/
98 /* private mpegts data */
99 /* scan context */
100 MpegTSFilter *sdt_filter;
101 int nb_services;
102 MpegTSService **services;
103
104 /* set service context (XXX: allocated it ?) */
105 SetServiceCallback *set_service_cb;
106 void *set_service_opaque;
107 MpegTSFilter *pat_filter;
108 MpegTSFilter *pmt_filter;
109 int req_sid;
110
111 MpegTSFilter *pids[NB_PID_MAX];
b45a7a18 112};
fe9cf0d4 113
5dbafeb7
FB
114static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
115 const uint8_t *buf, int buf_size, int is_start)
116{
117 MpegTSSectionFilter *tss = &tss1->u.section_filter;
118 int len;
119 unsigned int crc;
120
121 if (is_start) {
122 memcpy(tss->section_buf, buf, buf_size);
123 tss->section_index = buf_size;
124 tss->section_h_size = -1;
125 tss->end_of_section_reached = 0;
126 } else {
127 if (tss->end_of_section_reached)
128 return;
129 len = 4096 - tss->section_index;
130 if (buf_size < len)
131 len = buf_size;
132 memcpy(tss->section_buf + tss->section_index, buf, len);
133 tss->section_index += len;
134 }
135
136 /* compute section length if possible */
137 if (tss->section_h_size == -1 && tss->section_index >= 3) {
138 len = (((tss->section_buf[1] & 0xf) << 8) | tss->section_buf[2]) + 3;
139 if (len > 4096)
140 return;
141 tss->section_h_size = len;
142 }
143
144 if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
145 if (tss->check_crc) {
146 crc = mpegts_crc32(tss->section_buf, tss->section_h_size);
147 if (crc != 0)
148 goto invalid_crc;
149 }
150 tss->section_cb(tss->opaque, tss->section_buf, tss->section_h_size);
151 invalid_crc:
152 tss->end_of_section_reached = 1;
153 }
154}
155
156MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid,
157 SectionCallback *section_cb, void *opaque,
158 int check_crc)
159
160{
161 MpegTSFilter *filter;
162 MpegTSSectionFilter *sec;
b45a7a18
FB
163
164#ifdef DEBUG_SI
165 printf("Filter: pid=0x%x\n", pid);
166#endif
5dbafeb7
FB
167 if (pid >= NB_PID_MAX || ts->pids[pid])
168 return NULL;
169 filter = av_mallocz(sizeof(MpegTSFilter));
170 if (!filter)
171 return NULL;
172 ts->pids[pid] = filter;
173 filter->type = MPEGTS_SECTION;
174 filter->pid = pid;
175 filter->last_cc = -1;
176 sec = &filter->u.section_filter;
177 sec->section_cb = section_cb;
178 sec->opaque = opaque;
179 sec->section_buf = av_malloc(MAX_SECTION_SIZE);
180 sec->check_crc = check_crc;
181 if (!sec->section_buf) {
182 av_free(filter);
183 return NULL;
184 }
185 return filter;
186}
187
188MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
189 PESCallback *pes_cb,
190 void *opaque)
191{
192 MpegTSFilter *filter;
193 MpegTSPESFilter *pes;
194
195 if (pid >= NB_PID_MAX || ts->pids[pid])
196 return NULL;
197 filter = av_mallocz(sizeof(MpegTSFilter));
198 if (!filter)
199 return NULL;
200 ts->pids[pid] = filter;
201 filter->type = MPEGTS_PES;
202 filter->pid = pid;
203 filter->last_cc = -1;
204 pes = &filter->u.pes_filter;
205 pes->pes_cb = pes_cb;
206 pes->opaque = opaque;
207 return filter;
208}
209
210void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
211{
212 int pid;
213
214 pid = filter->pid;
215 if (filter->type == MPEGTS_SECTION)
216 av_freep(&filter->u.section_filter.section_buf);
217 av_free(filter);
218 ts->pids[pid] = NULL;
219}
220
fe9cf0d4 221/* autodetect fec presence. Must have at least 1024 bytes */
5dbafeb7 222static int get_packet_size(const uint8_t *buf, int size)
fe9cf0d4
FB
223{
224 int i;
225
226 if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
227 return -1;
228 for(i=0;i<5;i++) {
229 if (buf[i * TS_PACKET_SIZE] != 0x47)
230 goto try_fec;
231 }
232 return TS_PACKET_SIZE;
233 try_fec:
234 for(i=0;i<5;i++) {
235 if (buf[i * TS_FEC_PACKET_SIZE] != 0x47)
236 return -1;
237 }
238 return TS_FEC_PACKET_SIZE;
239}
240
5dbafeb7
FB
241typedef struct SectionHeader {
242 uint8_t tid;
243 uint16_t id;
244 uint8_t version;
245 uint8_t sec_num;
246 uint8_t last_sec_num;
247} SectionHeader;
248
249static inline int get8(const uint8_t **pp, const uint8_t *p_end)
fe9cf0d4 250{
5dbafeb7
FB
251 const uint8_t *p;
252 int c;
253
254 p = *pp;
255 if (p >= p_end)
256 return -1;
257 c = *p++;
258 *pp = p;
259 return c;
fe9cf0d4
FB
260}
261
5dbafeb7
FB
262static inline int get16(const uint8_t **pp, const uint8_t *p_end)
263{
264 const uint8_t *p;
265 int c;
266
267 p = *pp;
268 if ((p + 1) >= p_end)
269 return -1;
270 c = (p[0] << 8) | p[1];
271 p += 2;
272 *pp = p;
273 return c;
274}
275
276/* read and allocate a DVB string preceeded by its length */
277static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
fe9cf0d4 278{
fe9cf0d4 279 int len;
5dbafeb7
FB
280 const uint8_t *p;
281 char *str;
fe9cf0d4 282
5dbafeb7
FB
283 p = *pp;
284 len = get8(&p, p_end);
285 if (len < 0)
286 return NULL;
287 if ((p + len) > p_end)
288 return NULL;
289 str = av_malloc(len + 1);
290 if (!str)
291 return NULL;
292 memcpy(str, p, len);
293 str[len] = '\0';
294 p += len;
295 *pp = p;
296 return str;
297}
298
299static int parse_section_header(SectionHeader *h,
300 const uint8_t **pp, const uint8_t *p_end)
301{
302 int val;
303
304 val = get8(pp, p_end);
305 if (val < 0)
306 return -1;
307 h->tid = val;
308 *pp += 2;
309 val = get16(pp, p_end);
310 if (val < 0)
311 return -1;
312 h->id = val;
313 val = get8(pp, p_end);
314 if (val < 0)
315 return -1;
316 h->version = (val >> 1) & 0x1f;
317 val = get8(pp, p_end);
318 if (val < 0)
319 return -1;
320 h->sec_num = val;
321 val = get8(pp, p_end);
322 if (val < 0)
323 return -1;
324 h->last_sec_num = val;
fe9cf0d4 325 return 0;
5dbafeb7
FB
326}
327
328static MpegTSService *new_service(MpegTSContext *ts, int sid,
329 char *provider_name, char *name)
330{
331 MpegTSService *service;
332
333#ifdef DEBUG_SI
334 printf("new_service: sid=0x%04x provider='%s' name='%s'\n",
335 sid, provider_name, name);
336#endif
337
338 service = av_mallocz(sizeof(MpegTSService));
339 if (!service)
340 return NULL;
341 service->sid = sid;
342 service->provider_name = provider_name;
343 service->name = name;
344 dynarray_add(&ts->services, &ts->nb_services, service);
345 return service;
346}
347
348static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
349{
350 MpegTSContext *ts = opaque;
351 SectionHeader h1, *h = &h1;
352 const uint8_t *p, *p_end;
353 int program_info_length, pcr_pid, pid, stream_type, desc_length;
354
355#ifdef DEBUG_SI
356 printf("PMT:\n");
357 av_hex_dump((uint8_t *)section, section_len);
358#endif
359 p_end = section + section_len - 4;
360 p = section;
361 if (parse_section_header(h, &p, p_end) < 0)
362 return;
363#ifdef DEBUG_SI
364 printf("sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num);
365#endif
ce34182d 366 if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
5dbafeb7
FB
367 return;
368
369 pcr_pid = get16(&p, p_end) & 0x1fff;
370 if (pcr_pid < 0)
371 return;
27f388aa 372 ts->pcr_pid = pcr_pid;
5dbafeb7
FB
373#ifdef DEBUG_SI
374 printf("pcr_pid=0x%x\n", pcr_pid);
375#endif
376 program_info_length = get16(&p, p_end) & 0xfff;
377 if (program_info_length < 0)
378 return;
379 p += program_info_length;
380 if (p >= p_end)
381 return;
382 for(;;) {
383 stream_type = get8(&p, p_end);
384 if (stream_type < 0)
385 break;
386 pid = get16(&p, p_end) & 0x1fff;
387 if (pid < 0)
388 break;
389 desc_length = get16(&p, p_end) & 0xfff;
390 if (desc_length < 0)
391 break;
392 p += desc_length;
393 if (p > p_end)
394 return;
395
396#ifdef DEBUG_SI
397 printf("stream_type=%d pid=0x%x\n", stream_type, pid);
398#endif
399
400 /* now create ffmpeg stream */
401 switch(stream_type) {
ce34182d
MN
402 case STREAM_TYPE_AUDIO_MPEG1:
403 case STREAM_TYPE_AUDIO_MPEG2:
404 case STREAM_TYPE_VIDEO_MPEG1:
405 case STREAM_TYPE_VIDEO_MPEG2:
278de475
MR
406 case STREAM_TYPE_VIDEO_MPEG4:
407 case STREAM_TYPE_VIDEO_H264:
408 case STREAM_TYPE_AUDIO_AAC:
ec23a472 409 case STREAM_TYPE_AUDIO_AC3:
278de475 410 add_pes_stream(ts, pid, stream_type);
5dbafeb7
FB
411 break;
412 default:
413 /* we ignore the other streams */
414 break;
415 }
416 }
417 /* all parameters are there */
418 ts->set_service_cb(ts->set_service_opaque, 0);
419 mpegts_close_filter(ts, ts->pmt_filter);
420 ts->pmt_filter = NULL;
421}
422
423static void pat_cb(void *opaque, const uint8_t *section, int section_len)
424{
425 MpegTSContext *ts = opaque;
426 SectionHeader h1, *h = &h1;
427 const uint8_t *p, *p_end;
428 int sid, pmt_pid;
429
430#ifdef DEBUG_SI
431 printf("PAT:\n");
432 av_hex_dump((uint8_t *)section, section_len);
433#endif
434 p_end = section + section_len - 4;
435 p = section;
436 if (parse_section_header(h, &p, p_end) < 0)
437 return;
438 if (h->tid != PAT_TID)
439 return;
440
441 for(;;) {
442 sid = get16(&p, p_end);
443 if (sid < 0)
444 break;
445 pmt_pid = get16(&p, p_end) & 0x1fff;
446 if (pmt_pid < 0)
447 break;
448#ifdef DEBUG_SI
449 printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
450#endif
451 if (sid == 0x0000) {
452 /* NIT info */
453 } else {
fc48fe84 454 if (ts->req_sid == sid) {
5dbafeb7
FB
455 ts->pmt_filter = mpegts_open_section_filter(ts, pmt_pid,
456 pmt_cb, ts, 1);
457 goto found;
458 }
459 }
460 }
461 /* not found */
462 ts->set_service_cb(ts->set_service_opaque, -1);
463
464 found:
465 mpegts_close_filter(ts, ts->pat_filter);
466 ts->pat_filter = NULL;
467}
468
fc48fe84
FB
469/* add all services found in the PAT */
470static void pat_scan_cb(void *opaque, const uint8_t *section, int section_len)
471{
472 MpegTSContext *ts = opaque;
473 SectionHeader h1, *h = &h1;
474 const uint8_t *p, *p_end;
475 int sid, pmt_pid;
476 char *provider_name, *name;
477 char buf[256];
478
479#ifdef DEBUG_SI
480 printf("PAT:\n");
481 av_hex_dump((uint8_t *)section, section_len);
482#endif
483 p_end = section + section_len - 4;
484 p = section;
485 if (parse_section_header(h, &p, p_end) < 0)
486 return;
487 if (h->tid != PAT_TID)
488 return;
489
490 for(;;) {
491 sid = get16(&p, p_end);
492 if (sid < 0)
493 break;
494 pmt_pid = get16(&p, p_end) & 0x1fff;
495 if (pmt_pid < 0)
496 break;
497#ifdef DEBUG_SI
498 printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
499#endif
500 if (sid == 0x0000) {
501 /* NIT info */
502 } else {
503 /* add the service with a dummy name */
504 snprintf(buf, sizeof(buf), "Service %x\n", sid);
505 name = av_strdup(buf);
506 provider_name = av_strdup("");
507 if (name && provider_name) {
508 new_service(ts, sid, provider_name, name);
509 } else {
510 av_freep(&name);
511 av_freep(&provider_name);
512 }
513 }
514 }
515 ts->stop_parse = 1;
516
517 /* remove filter */
518 mpegts_close_filter(ts, ts->pat_filter);
519 ts->pat_filter = NULL;
520}
521
5dbafeb7
FB
522void mpegts_set_service(MpegTSContext *ts, int sid,
523 SetServiceCallback *set_service_cb, void *opaque)
524{
525 ts->set_service_cb = set_service_cb;
526 ts->set_service_opaque = opaque;
527 ts->req_sid = sid;
528 ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID,
529 pat_cb, ts, 1);
530}
531
532static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
533{
534 MpegTSContext *ts = opaque;
535 SectionHeader h1, *h = &h1;
536 const uint8_t *p, *p_end, *desc_list_end, *desc_end;
537 int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
538 char *name, *provider_name;
539
540#ifdef DEBUG_SI
541 printf("SDT:\n");
542 av_hex_dump((uint8_t *)section, section_len);
543#endif
544
545 p_end = section + section_len - 4;
546 p = section;
547 if (parse_section_header(h, &p, p_end) < 0)
548 return;
549 if (h->tid != SDT_TID)
550 return;
551 onid = get16(&p, p_end);
552 if (onid < 0)
553 return;
554 val = get8(&p, p_end);
555 if (val < 0)
556 return;
557 for(;;) {
558 sid = get16(&p, p_end);
559 if (sid < 0)
560 break;
561 val = get8(&p, p_end);
562 if (val < 0)
563 break;
564 desc_list_len = get16(&p, p_end) & 0xfff;
565 if (desc_list_len < 0)
566 break;
567 desc_list_end = p + desc_list_len;
568 if (desc_list_end > p_end)
569 break;
570 for(;;) {
571 desc_tag = get8(&p, desc_list_end);
572 if (desc_tag < 0)
573 break;
574 desc_len = get8(&p, desc_list_end);
575 desc_end = p + desc_len;
576 if (desc_end > desc_list_end)
577 break;
578#ifdef DEBUG_SI
579 printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
580#endif
581 switch(desc_tag) {
582 case 0x48:
583 service_type = get8(&p, p_end);
584 if (service_type < 0)
585 break;
586 provider_name = getstr8(&p, p_end);
587 if (!provider_name)
588 break;
589 name = getstr8(&p, p_end);
590 if (!name)
591 break;
592 new_service(ts, sid, provider_name, name);
593 break;
594 default:
595 break;
596 }
597 p = desc_end;
598 }
599 p = desc_list_end;
600 }
601 ts->stop_parse = 1;
602
603 /* remove filter */
604 mpegts_close_filter(ts, ts->sdt_filter);
605 ts->sdt_filter = NULL;
606}
607
fc48fe84 608/* scan services in a transport stream by looking at the SDT */
5dbafeb7
FB
609void mpegts_scan_sdt(MpegTSContext *ts)
610{
611 ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID,
612 sdt_cb, ts, 1);
613}
614
fc48fe84
FB
615/* scan services in a transport stream by looking at the PAT (better
616 than nothing !) */
617void mpegts_scan_pat(MpegTSContext *ts)
618{
619 ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID,
620 pat_scan_cb, ts, 1);
621}
5dbafeb7
FB
622
623/* TS stream handling */
624
625enum MpegTSState {
626 MPEGTS_HEADER = 0,
627 MPEGTS_PESHEADER_FILL,
628 MPEGTS_PAYLOAD,
629 MPEGTS_SKIP,
630};
631
632/* enough for PES header + length */
633#define PES_START_SIZE 9
634#define MAX_PES_HEADER_SIZE (9 + 255)
635
636typedef struct PESContext {
637 int pid;
278de475 638 int stream_type;
b45a7a18 639 MpegTSContext *ts;
5dbafeb7
FB
640 AVFormatContext *stream;
641 AVStream *st;
642 enum MpegTSState state;
643 /* used to get the format */
644 int data_index;
645 int total_size;
646 int pes_header_size;
647 int64_t pts, dts;
648 uint8_t header[MAX_PES_HEADER_SIZE];
649} PESContext;
650
651static int64_t get_pts(const uint8_t *p)
652{
653 int64_t pts;
654 int val;
655
656 pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
657 val = (p[1] << 8) | p[2];
658 pts |= (int64_t)(val >> 1) << 15;
659 val = (p[3] << 8) | p[4];
660 pts |= (int64_t)(val >> 1);
661 return pts;
fe9cf0d4
FB
662}
663
664/* return non zero if a packet could be constructed */
5dbafeb7
FB
665static void mpegts_push_data(void *opaque,
666 const uint8_t *buf, int buf_size, int is_start)
fe9cf0d4 667{
5dbafeb7 668 PESContext *pes = opaque;
b45a7a18 669 MpegTSContext *ts = pes->ts;
fe9cf0d4 670 AVStream *st;
5dbafeb7 671 const uint8_t *p;
fe9cf0d4 672 int len, code, codec_type, codec_id;
5dbafeb7 673
fe9cf0d4 674 if (is_start) {
5dbafeb7
FB
675 pes->state = MPEGTS_HEADER;
676 pes->data_index = 0;
fe9cf0d4
FB
677 }
678 p = buf;
679 while (buf_size > 0) {
5dbafeb7 680 switch(pes->state) {
fe9cf0d4 681 case MPEGTS_HEADER:
5dbafeb7
FB
682 len = PES_START_SIZE - pes->data_index;
683 if (len > buf_size)
684 len = buf_size;
685 memcpy(pes->header + pes->data_index, p, len);
686 pes->data_index += len;
fe9cf0d4
FB
687 p += len;
688 buf_size -= len;
5dbafeb7 689 if (pes->data_index == PES_START_SIZE) {
fe9cf0d4
FB
690 /* we got all the PES or section header. We can now
691 decide */
692#if 0
5dbafeb7 693 av_hex_dump(pes->header, pes->data_index);
fe9cf0d4 694#endif
5dbafeb7
FB
695 if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
696 pes->header[2] == 0x01) {
fe9cf0d4 697 /* it must be an mpeg2 PES stream */
5dbafeb7 698 code = pes->header[3] | 0x100;
fe9cf0d4 699 if (!((code >= 0x1c0 && code <= 0x1df) ||
ec23a472
IR
700 (code >= 0x1e0 && code <= 0x1ef) ||
701 (code == 0x1bd)))
fe9cf0d4 702 goto skip;
5dbafeb7 703 if (!pes->st) {
fe9cf0d4 704 /* allocate stream */
278de475
MR
705 switch(pes->stream_type){
706 case STREAM_TYPE_AUDIO_MPEG1:
707 case STREAM_TYPE_AUDIO_MPEG2:
fe9cf0d4 708 codec_type = CODEC_TYPE_AUDIO;
278de475
MR
709 codec_id = CODEC_ID_MP3;
710 break;
711 case STREAM_TYPE_VIDEO_MPEG1:
712 case STREAM_TYPE_VIDEO_MPEG2:
713 codec_type = CODEC_TYPE_VIDEO;
714 codec_id = CODEC_ID_MPEG2VIDEO;
715 break;
716 case STREAM_TYPE_VIDEO_MPEG4:
717 codec_type = CODEC_TYPE_VIDEO;
718 codec_id = CODEC_ID_MPEG4;
719 break;
720 case STREAM_TYPE_VIDEO_H264:
721 codec_type = CODEC_TYPE_VIDEO;
722 codec_id = CODEC_ID_H264;
723 break;
724 case STREAM_TYPE_AUDIO_AAC:
725 codec_type = CODEC_TYPE_AUDIO;
726 codec_id = CODEC_ID_AAC;
727 break;
728 case STREAM_TYPE_AUDIO_AC3:
ec23a472
IR
729 codec_type = CODEC_TYPE_AUDIO;
730 codec_id = CODEC_ID_AC3;
278de475
MR
731 break;
732 default:
733 if (code >= 0x1c0 && code <= 0x1df) {
734 codec_type = CODEC_TYPE_AUDIO;
735 codec_id = CODEC_ID_MP2;
736 } else if (code == 0x1bd) {
737 codec_type = CODEC_TYPE_AUDIO;
738 codec_id = CODEC_ID_AC3;
739 } else {
740 codec_type = CODEC_TYPE_VIDEO;
741 codec_id = CODEC_ID_MPEG1VIDEO;
742 }
743 break;
fe9cf0d4 744 }
5dbafeb7 745 st = av_new_stream(pes->stream, pes->pid);
fe9cf0d4 746 if (st) {
5dbafeb7 747 st->priv_data = pes;
fe9cf0d4
FB
748 st->codec.codec_type = codec_type;
749 st->codec.codec_id = codec_id;
27f388aa 750 st->need_parsing = 1;
5dbafeb7 751 pes->st = st;
fe9cf0d4
FB
752 }
753 }
5dbafeb7
FB
754 pes->state = MPEGTS_PESHEADER_FILL;
755 pes->total_size = (pes->header[4] << 8) | pes->header[5];
756 /* NOTE: a zero total size means the PES size is
757 unbounded */
758 if (pes->total_size)
759 pes->total_size += 6;
760 pes->pes_header_size = pes->header[8] + 9;
fe9cf0d4
FB
761 } else {
762 /* otherwise, it should be a table */
763 /* skip packet */
764 skip:
5dbafeb7 765 pes->state = MPEGTS_SKIP;
fe9cf0d4
FB
766 continue;
767 }
768 }
769 break;
770 /**********************************************/
771 /* PES packing parsing */
772 case MPEGTS_PESHEADER_FILL:
5dbafeb7
FB
773 len = pes->pes_header_size - pes->data_index;
774 if (len > buf_size)
775 len = buf_size;
776 memcpy(pes->header + pes->data_index, p, len);
777 pes->data_index += len;
fe9cf0d4
FB
778 p += len;
779 buf_size -= len;
5dbafeb7
FB
780 if (pes->data_index == pes->pes_header_size) {
781 const uint8_t *r;
782 unsigned int flags;
783
784 flags = pes->header[7];
785 r = pes->header + 9;
786 pes->pts = AV_NOPTS_VALUE;
787 pes->dts = AV_NOPTS_VALUE;
788 if ((flags & 0xc0) == 0x80) {
789 pes->pts = get_pts(r);
790 r += 5;
791 } else if ((flags & 0xc0) == 0xc0) {
792 pes->pts = get_pts(r);
793 r += 5;
794 pes->dts = get_pts(r);
795 r += 5;
796 }
797 /* we got the full header. We parse it and get the payload */
798 pes->state = MPEGTS_PAYLOAD;
799 }
fe9cf0d4
FB
800 break;
801 case MPEGTS_PAYLOAD:
5dbafeb7
FB
802 if (pes->total_size) {
803 len = pes->total_size - pes->data_index;
804 if (len > buf_size)
805 len = buf_size;
806 } else {
807 len = buf_size;
808 }
fe9cf0d4 809 if (len > 0) {
5dbafeb7
FB
810 AVPacket *pkt = ts->pkt;
811 if (pes->st && av_new_packet(pkt, len) == 0) {
812 memcpy(pkt->data, p, len);
813 pkt->stream_index = pes->st->index;
814 pkt->pts = pes->pts;
815 /* reset pts values */
816 pes->pts = AV_NOPTS_VALUE;
817 pes->dts = AV_NOPTS_VALUE;
818 ts->stop_parse = 1;
819 return;
fe9cf0d4 820 }
fe9cf0d4
FB
821 }
822 buf_size = 0;
823 break;
824 case MPEGTS_SKIP:
825 buf_size = 0;
826 break;
827 }
828 }
5dbafeb7
FB
829}
830
278de475 831static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type)
5dbafeb7 832{
5dbafeb7
FB
833 MpegTSFilter *tss;
834 PESContext *pes;
835
836 /* if no pid found, then add a pid context */
837 pes = av_mallocz(sizeof(PESContext));
838 if (!pes)
839 return -1;
b45a7a18
FB
840 pes->ts = ts;
841 pes->stream = ts->stream;
5dbafeb7 842 pes->pid = pid;
278de475 843 pes->stream_type = stream_type;
5dbafeb7
FB
844 tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
845 if (!tss) {
846 av_free(pes);
847 return -1;
848 }
fe9cf0d4
FB
849 return 0;
850}
851
5dbafeb7 852/* handle one TS packet */
b45a7a18 853static void handle_packet(MpegTSContext *ts, const uint8_t *packet)
fe9cf0d4 854{
b45a7a18 855 AVFormatContext *s = ts->stream;
5dbafeb7
FB
856 MpegTSFilter *tss;
857 int len, pid, cc, cc_ok, afc, is_start;
858 const uint8_t *p, *p_end;
859
860 pid = ((packet[1] & 0x1f) << 8) | packet[2];
861 is_start = packet[1] & 0x40;
862 tss = ts->pids[pid];
863 if (ts->auto_guess && tss == NULL && is_start) {
278de475 864 add_pes_stream(ts, pid, 0);
5dbafeb7
FB
865 tss = ts->pids[pid];
866 }
867 if (!tss)
868 return;
869
870 /* continuity check (currently not used) */
871 cc = (packet[3] & 0xf);
872 cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
873 tss->last_cc = cc;
fe9cf0d4 874
5dbafeb7
FB
875 /* skip adaptation field */
876 afc = (packet[3] >> 4) & 3;
877 p = packet + 4;
878 if (afc == 0) /* reserved value */
879 return;
880 if (afc == 2) /* adaptation field only */
881 return;
882 if (afc == 3) {
883 /* skip adapation field */
884 p += p[0] + 1;
885 }
886 /* if past the end of packet, ignore */
887 p_end = packet + TS_PACKET_SIZE;
888 if (p >= p_end)
889 return;
890
891 if (tss->type == MPEGTS_SECTION) {
892 if (is_start) {
893 /* pointer field present */
894 len = *p++;
895 if (p + len > p_end)
896 return;
897 if (len && cc_ok) {
898 /* write remaning section bytes */
899 write_section_data(s, tss,
900 p, len, 0);
901 }
902 p += len;
903 if (p < p_end) {
904 write_section_data(s, tss,
905 p, p_end - p, 1);
906 }
907 } else {
908 if (cc_ok) {
909 write_section_data(s, tss,
910 p, p_end - p, 0);
fc48fe84 911 }
5dbafeb7
FB
912 }
913 } else {
914 tss->u.pes_filter.pes_cb(tss->u.pes_filter.opaque,
915 p, p_end - p, is_start);
916 }
917}
918
fc48fe84
FB
919/* XXX: try to find a better synchro over several packets (use
920 get_packet_size() ?) */
b45a7a18 921static int mpegts_resync(ByteIOContext *pb)
fc48fe84 922{
fc48fe84
FB
923 int c, i;
924
925 for(i = 0;i < MAX_RESYNC_SIZE; i++) {
926 c = url_fgetc(pb);
927 if (c < 0)
928 return -1;
929 if (c == 0x47) {
930 url_fseek(pb, -1, SEEK_CUR);
931 return 0;
932 }
933 }
934 /* no sync found */
935 return -1;
936}
937
b45a7a18
FB
938/* return -1 if error or EOF. Return 0 if OK. */
939static int read_packet(ByteIOContext *pb, uint8_t *buf, int raw_packet_size)
5dbafeb7 940{
b45a7a18
FB
941 int skip, len;
942
943 for(;;) {
944 len = get_buffer(pb, buf, TS_PACKET_SIZE);
945 if (len != TS_PACKET_SIZE)
946 return AVERROR_IO;
947 /* check paquet sync byte */
948 if (buf[0] != 0x47) {
949 /* find a new packet start */
950 url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR);
951 if (mpegts_resync(pb) < 0)
952 return AVERROR_INVALIDDATA;
953 else
954 continue;
955 } else {
956 skip = raw_packet_size - TS_PACKET_SIZE;
957 if (skip > 0)
958 url_fskip(pb, skip);
959 break;
960 }
961 }
962 return 0;
963}
964
965static int handle_packets(MpegTSContext *ts, int nb_packets)
966{
967 AVFormatContext *s = ts->stream;
5dbafeb7 968 ByteIOContext *pb = &s->pb;
b45a7a18
FB
969 uint8_t packet[TS_PACKET_SIZE];
970 int packet_num, ret;
5dbafeb7
FB
971
972 ts->stop_parse = 0;
973 packet_num = 0;
fe9cf0d4 974 for(;;) {
5dbafeb7
FB
975 if (ts->stop_parse)
976 break;
977 packet_num++;
978 if (nb_packets != 0 && packet_num >= nb_packets)
979 break;
b45a7a18
FB
980 ret = read_packet(pb, packet, ts->raw_packet_size);
981 if (ret != 0)
982 return ret;
983 handle_packet(ts, packet);
5dbafeb7
FB
984 }
985 return 0;
986}
fe9cf0d4 987
5dbafeb7
FB
988static int mpegts_probe(AVProbeData *p)
989{
fc48fe84 990#if 1
5dbafeb7
FB
991 int size;
992 size = get_packet_size(p->buf, p->buf_size);
993 if (size < 0)
994 return 0;
995 return AVPROBE_SCORE_MAX - 1;
fc48fe84
FB
996#else
997 /* only use the extension for safer guess */
998 if (match_ext(p->filename, "ts"))
999 return AVPROBE_SCORE_MAX;
1000 else
1001 return 0;
1002#endif
5dbafeb7
FB
1003}
1004
1005void set_service_cb(void *opaque, int ret)
1006{
1007 MpegTSContext *ts = opaque;
1008 ts->set_service_ret = ret;
1009 ts->stop_parse = 1;
1010}
1011
b45a7a18
FB
1012/* return the 90 kHz PCR and the extension for the 27 MHz PCR. return
1013 (-1) if not available */
1014static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
1015 const uint8_t *packet)
1016{
1017 int afc, len, flags;
1018 const uint8_t *p;
1019 unsigned int v;
1020
1021 afc = (packet[3] >> 4) & 3;
1022 if (afc <= 1)
1023 return -1;
1024 p = packet + 4;
1025 len = p[0];
1026 p++;
1027 if (len == 0)
1028 return -1;
1029 flags = *p++;
1030 len--;
1031 if (!(flags & 0x10))
1032 return -1;
1033 if (len < 6)
1034 return -1;
1035 v = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
1036 *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7);
1037 *ppcr_low = ((p[4] & 1) << 8) | p[5];
1038 return 0;
1039}
1040
5dbafeb7
FB
1041static int mpegts_read_header(AVFormatContext *s,
1042 AVFormatParameters *ap)
1043{
1044 MpegTSContext *ts = s->priv_data;
1045 ByteIOContext *pb = &s->pb;
1046 uint8_t buf[1024];
fc48fe84 1047 int len, sid;
5dbafeb7
FB
1048 int64_t pos;
1049 MpegTSService *service;
fe9cf0d4 1050
b45a7a18
FB
1051 if (ap) {
1052 ts->mpeg2ts_raw = ap->mpeg2ts_raw;
1053 ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr;
1054 }
1055
5dbafeb7
FB
1056 /* read the first 1024 bytes to get packet size */
1057 pos = url_ftell(pb);
1058 len = get_buffer(pb, buf, sizeof(buf));
1059 if (len != sizeof(buf))
1060 goto fail;
1061 ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
1062 if (ts->raw_packet_size <= 0)
1063 goto fail;
b45a7a18 1064 ts->stream = s;
5dbafeb7 1065 ts->auto_guess = 0;
5dbafeb7 1066
b45a7a18
FB
1067 if (!ts->mpeg2ts_raw) {
1068 /* normal demux */
fc48fe84 1069
b45a7a18
FB
1070 if (!ts->auto_guess) {
1071 ts->set_service_ret = -1;
ce34182d 1072
b45a7a18 1073 /* first do a scaning to get all the services */
fc48fe84 1074 url_fseek(pb, pos, SEEK_SET);
b45a7a18 1075 mpegts_scan_sdt(ts);
fc48fe84 1076
b45a7a18
FB
1077 handle_packets(ts, MAX_SCAN_PACKETS);
1078
1079 if (ts->nb_services <= 0) {
1080 /* no SDT found, we try to look at the PAT */
1081
1082 /* First remove the SDT filters from each PID */
1083 int i;
1084 for (i=0; i < NB_PID_MAX; i++) {
1085 if (ts->pids[i])
1086 mpegts_close_filter(ts, ts->pids[i]);
1087 }
1088 url_fseek(pb, pos, SEEK_SET);
1089 mpegts_scan_pat(ts);
1090
1091 handle_packets(ts, MAX_SCAN_PACKETS);
1092 }
1093
1094 if (ts->nb_services <= 0)
1095 return -1;
1096
1097 /* tune to first service found */
1098 service = ts->services[0];
1099 sid = service->sid;
5dbafeb7 1100#ifdef DEBUG_SI
b45a7a18 1101 printf("tuning to '%s'\n", service->name);
5dbafeb7 1102#endif
b45a7a18
FB
1103
1104 /* now find the info for the first service if we found any,
1105 otherwise try to filter all PATs */
1106
1107 url_fseek(pb, pos, SEEK_SET);
1108 mpegts_set_service(ts, sid, set_service_cb, ts);
1109
1110 handle_packets(ts, MAX_SCAN_PACKETS);
1111
1112 /* if could not find service, exit */
1113 if (ts->set_service_ret != 0)
1114 return -1;
1115
1116#ifdef DEBUG_SI
1117 printf("tuning done\n");
1118#endif
1119 }
1120 s->ctx_flags |= AVFMTCTX_NOHEADER;
1121 } else {
1122 AVStream *st;
1123 int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l;
1124 int64_t pcrs[2], pcr_h;
1125 int packet_count[2];
1126 uint8_t packet[TS_PACKET_SIZE];
1127
1128 /* only read packets */
ce34182d 1129
b45a7a18
FB
1130 s->pts_num = 1;
1131 s->pts_den = 27000000;
1132
1133 st = av_new_stream(s, 0);
1134 if (!st)
1135 goto fail;
1136 st->codec.codec_type = CODEC_TYPE_DATA;
1137 st->codec.codec_id = CODEC_ID_MPEG2TS;
1138
1139 /* we iterate until we find two PCRs to estimate the bitrate */
1140 pcr_pid = -1;
1141 nb_pcrs = 0;
1142 nb_packets = 0;
1143 for(;;) {
1144 ret = read_packet(&s->pb, packet, ts->raw_packet_size);
1145 if (ret < 0)
1146 return -1;
1147 pid = ((packet[1] & 0x1f) << 8) | packet[2];
1148 if ((pcr_pid == -1 || pcr_pid == pid) &&
1149 parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
1150 pcr_pid = pid;
1151 packet_count[nb_pcrs] = nb_packets;
1152 pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
1153 nb_pcrs++;
1154 if (nb_pcrs >= 2)
1155 break;
1156 }
1157 nb_packets++;
1158 }
27f388aa 1159 ts->pcr_pid = pcr_pid;
5dbafeb7 1160
b45a7a18
FB
1161 /* NOTE1: the bitrate is computed without the FEC */
1162 /* NOTE2: it is only the bitrate of the start of the stream */
1163 ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]);
1164 ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0];
1165 s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr;
1166 st->codec.bit_rate = s->bit_rate;
1167 st->start_time = ts->cur_pcr * 1000000.0 / 27.0e6;
1168#if 0
1169 printf("start=%0.3f pcr=%0.3f incr=%d\n",
1170 st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
5dbafeb7 1171#endif
fe9cf0d4 1172 }
5dbafeb7
FB
1173
1174 url_fseek(pb, pos, SEEK_SET);
fe9cf0d4 1175 return 0;
5dbafeb7
FB
1176 fail:
1177 return -1;
1178}
1179
b45a7a18
FB
1180#define MAX_PACKET_READAHEAD ((128 * 1024) / 188)
1181
1182static int mpegts_raw_read_packet(AVFormatContext *s,
1183 AVPacket *pkt)
1184{
1185 MpegTSContext *ts = s->priv_data;
1186 int ret, i;
1187 int64_t pcr_h, next_pcr_h, pos;
1188 int pcr_l, next_pcr_l;
1189 uint8_t pcr_buf[12];
1190
1191 if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
1192 return -ENOMEM;
1193 ret = read_packet(&s->pb, pkt->data, ts->raw_packet_size);
1194 if (ret < 0) {
1195 av_free_packet(pkt);
1196 return ret;
1197 }
1198 if (ts->mpeg2ts_compute_pcr) {
1199 /* compute exact PCR for each packet */
1200 if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {
1201 /* we read the next PCR (XXX: optimize it by using a bigger buffer */
1202 pos = url_ftell(&s->pb);
1203 for(i = 0; i < MAX_PACKET_READAHEAD; i++) {
1204 url_fseek(&s->pb, pos + i * ts->raw_packet_size, SEEK_SET);
1205 get_buffer(&s->pb, pcr_buf, 12);
1206 if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) {
1207 /* XXX: not precise enough */
1208 ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) /
1209 (i + 1);
1210 break;
1211 }
1212 }
1213 url_fseek(&s->pb, pos, SEEK_SET);
1214 /* no next PCR found: we use previous increment */
1215 ts->cur_pcr = pcr_h * 300 + pcr_l;
1216 }
1217 pkt->pts = ts->cur_pcr;
1218 pkt->duration = ts->pcr_incr;
1219 ts->cur_pcr += ts->pcr_incr;
1220 }
1221 pkt->stream_index = 0;
1222 return 0;
1223}
1224
5dbafeb7
FB
1225static int mpegts_read_packet(AVFormatContext *s,
1226 AVPacket *pkt)
1227{
1228 MpegTSContext *ts = s->priv_data;
b45a7a18
FB
1229
1230 if (!ts->mpeg2ts_raw) {
1231 ts->pkt = pkt;
1232 return handle_packets(ts, 0);
1233 } else {
1234 return mpegts_raw_read_packet(s, pkt);
1235 }
fe9cf0d4
FB
1236}
1237
1238static int mpegts_read_close(AVFormatContext *s)
1239{
1240 MpegTSContext *ts = s->priv_data;
1241 int i;
1242 for(i=0;i<NB_PID_MAX;i++)
754ebe34 1243 av_free(ts->pids[i]);
fe9cf0d4
FB
1244 return 0;
1245}
1246
27f388aa
FB
1247static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
1248 int64_t *ppos, int find_next)
1249{
1250 MpegTSContext *ts = s->priv_data;
1251 int64_t pos, timestamp;
1252 uint8_t buf[TS_PACKET_SIZE];
1253 int pcr_l, pid;
1254
1255 pos = *ppos;
1256 if (find_next) {
1257 for(;;) {
1258 url_fseek(&s->pb, pos, SEEK_SET);
1259 if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
1260 return AV_NOPTS_VALUE;
1261 pid = ((buf[1] & 0x1f) << 8) | buf[2];
1262 if (pid == ts->pcr_pid &&
1263 parse_pcr(&timestamp, &pcr_l, buf) == 0) {
1264 break;
1265 }
1266 pos += ts->raw_packet_size;
1267 }
1268 } else {
1269 for(;;) {
1270 pos -= ts->raw_packet_size;
1271 if (pos < 0)
1272 return AV_NOPTS_VALUE;
1273 url_fseek(&s->pb, pos, SEEK_SET);
1274 if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
1275 return AV_NOPTS_VALUE;
1276 pid = ((buf[1] & 0x1f) << 8) | buf[2];
1277 if (pid == ts->pcr_pid &&
1278 parse_pcr(&timestamp, &pcr_l, buf) == 0) {
1279 break;
1280 }
1281 }
1282 }
1283 *ppos = pos;
1284 return timestamp;
1285}
1286
1287typedef int64_t ReadTimestampFunc(AVFormatContext *s, int stream_index,
1288 int64_t *ppos, int find_next);
1289
1290static int64_t do_block_align(int64_t val, int block_align)
1291{
1292 return (val / block_align) * block_align;
1293}
1294
1295/* XXX: use it in other formats */
1296static int timestamp_read_seek(AVFormatContext *s,
1297 int stream_index, int64_t timestamp,
1298 ReadTimestampFunc *read_timestamp,
1299 int block_align)
1300{
1301 int64_t pos_min, pos_max, pos;
1302 int64_t dts_min, dts_max, dts;
1303
1304#ifdef DEBUG_SEEK
1305 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0);
1306#endif
1307
1308 pos_min = 0;
1309 dts_min = read_timestamp(s, stream_index, &pos_min, 1);
1310 if (dts_min == AV_NOPTS_VALUE) {
1311 /* we can reach this case only if no PTS are present in
1312 the whole stream */
1313 return -1;
1314 }
1315 pos_max = do_block_align(url_filesize(url_fileno(&s->pb)), block_align) -
1316 block_align;
1317 dts_max = read_timestamp(s, stream_index, &pos_max, 0);
1318
1319 while (pos_min <= pos_max) {
1320#ifdef DEBUG_SEEK
1321 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n",
1322 pos_min, pos_max,
1323 dts_min / 90000.0, dts_max / 90000.0);
1324#endif
1325 if (timestamp <= dts_min) {
1326 pos = pos_min;
1327 goto found;
1328 } else if (timestamp >= dts_max) {
1329 pos = pos_max;
1330 goto found;
1331 } else {
1332 /* interpolate position (better than dichotomy) */
1333 pos = (int64_t)((double)(pos_max - pos_min) *
1334 (double)(timestamp - dts_min) /
1335 (double)(dts_max - dts_min)) + pos_min;
1336 pos = do_block_align(pos, block_align);
1337 }
1338#ifdef DEBUG_SEEK
1339 printf("pos=0x%llx\n", pos);
1340#endif
1341 /* read the next timestamp */
1342 dts = read_timestamp(s, stream_index, &pos, 1);
1343 /* check if we are lucky */
1344 if (dts == AV_NOPTS_VALUE) {
1345 /* should never happen */
1346 pos = pos_min;
1347 goto found;
1348 } else if (timestamp == dts) {
1349 goto found;
1350 } else if (timestamp < dts) {
1351 pos_max = pos;
1352 dts_max = read_timestamp(s, stream_index, &pos_max, 0);
1353 if (dts_max == AV_NOPTS_VALUE) {
1354 /* should never happen */
1355 break;
1356 } else if (timestamp >= dts_max) {
1357 pos = pos_max;
1358 goto found;
1359 }
1360 } else {
1361 pos_min = pos + block_align;
1362 dts_min = read_timestamp(s, stream_index, &pos_min, 1);
1363 if (dts_min == AV_NOPTS_VALUE) {
1364 /* should never happen */
1365 goto found;
1366 } else if (timestamp <= dts_min) {
1367 goto found;
1368 }
1369 }
1370 }
1371 pos = pos_min;
1372 found:
1373#ifdef DEBUG_SEEK
1374 pos_min = pos;
1375 dts_min = read_timestamp(s, stream_index, &pos_min, 1);
1376 pos_min += block_align;
1377 dts_max = read_timestamp(s, stream_index, &pos_min, 1);
1378 printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n",
1379 pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0);
1380#endif
1381 /* do the seek */
1382 url_fseek(&s->pb, pos, SEEK_SET);
1383 return 0;
1384}
1385
1386static int mpegts_read_seek(AVFormatContext *s,
1387 int stream_index, int64_t timestamp)
1388{
1389 MpegTSContext *ts = s->priv_data;
1390
1391 timestamp = (timestamp * 90000) / AV_TIME_BASE;
1392
1393 return timestamp_read_seek(s, stream_index, timestamp,
1394 mpegts_get_pcr, ts->raw_packet_size);
1395}
1396
b45a7a18
FB
1397/**************************************************************/
1398/* parsing functions - called from other demuxers such as RTP */
1399
1400MpegTSContext *mpegts_parse_open(AVFormatContext *s)
1401{
1402 MpegTSContext *ts;
1403
1404 ts = av_mallocz(sizeof(MpegTSContext));
1405 if (!ts)
1406 return NULL;
1407 /* no stream case, currently used by RTP */
1408 ts->raw_packet_size = TS_PACKET_SIZE;
1409 ts->stream = s;
1410 ts->auto_guess = 1;
1411 return ts;
1412}
1413
1414/* return the consumed length if a packet was output, or -1 if no
1415 packet is output */
1416int mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
1417 const uint8_t *buf, int len)
1418{
1419 int len1;
1420
1421 len1 = len;
1422 ts->pkt = pkt;
1423 ts->stop_parse = 0;
1424 for(;;) {
1425 if (ts->stop_parse)
1426 break;
1427 if (len < TS_PACKET_SIZE)
1428 return -1;
1429 if (buf[0] != 0x47) {
1430 buf--;
1431 len--;
1432 } else {
1433 handle_packet(ts, buf);
1434 buf += TS_PACKET_SIZE;
1435 len -= TS_PACKET_SIZE;
1436 }
1437 }
1438 return len1 - len;
1439}
1440
1441void mpegts_parse_close(MpegTSContext *ts)
1442{
1443 int i;
1444
1445 for(i=0;i<NB_PID_MAX;i++)
1446 av_free(ts->pids[i]);
1447 av_free(ts);
1448}
1449
fe9cf0d4
FB
1450AVInputFormat mpegts_demux = {
1451 "mpegts",
1452 "MPEG2 transport stream format",
1453 sizeof(MpegTSContext),
1454 mpegts_probe,
1455 mpegts_read_header,
1456 mpegts_read_packet,
1457 mpegts_read_close,
27f388aa 1458 mpegts_read_seek,
b45a7a18 1459 .flags = AVFMT_SHOW_IDS,
fe9cf0d4
FB
1460};
1461
1462int mpegts_init(void)
1463{
1464 av_register_input_format(&mpegts_demux);
764ef400 1465#ifdef CONFIG_ENCODERS
5dbafeb7 1466 av_register_output_format(&mpegts_mux);
764ef400 1467#endif
fe9cf0d4
FB
1468 return 0;
1469}