VirtualBox

source: vbox/trunk/src/libs/ffmpeg-20060710/libavformat/mpegts.c@ 11551

Last change on this file since 11551 was 5776, checked in by vboxsync, 17 years ago

ffmpeg: exported to OSE

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette