Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ 8c653280

History | View | Annotate | Download (28.3 KB)

1
/*
2
 * MPEG2 transport stream (aka DVB) demux
3
 * Copyright (c) 2002-2003 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include "avformat.h"
20

    
21
#include "mpegts.h"
22

    
23
//#define DEBUG_SI
24

    
25
/* 1.0 second at 24Mbit/s */
26
#define MAX_SCAN_PACKETS 32000
27

    
28
/* maximum size in which we look for synchronisation if
29
   synchronisation is lost */
30
#define MAX_RESYNC_SIZE 4096
31

    
32
static int add_pes_stream(AVFormatContext *s, int pid);
33

    
34
enum MpegTSFilterType {
35
    MPEGTS_PES,
36
    MPEGTS_SECTION,
37
};
38

    
39
typedef void PESCallback(void *opaque, const uint8_t *buf, int len, int is_start);
40

    
41
typedef struct MpegTSPESFilter {
42
    PESCallback *pes_cb;
43
    void *opaque;
44
} MpegTSPESFilter;
45

    
46
typedef void SectionCallback(void *opaque, const uint8_t *buf, int len);
47

    
48
typedef void SetServiceCallback(void *opaque, int ret);
49

    
50
typedef struct MpegTSSectionFilter {
51
    int section_index;
52
    int section_h_size;
53
    uint8_t *section_buf;
54
    int check_crc:1;
55
    int end_of_section_reached:1;
56
    SectionCallback *section_cb;
57
    void *opaque;
58
} MpegTSSectionFilter;
59

    
60
typedef struct MpegTSFilter {
61
    int pid;
62
    int last_cc; /* last cc code (-1 if first packet) */
63
    enum MpegTSFilterType type;
64
    union {
65
        MpegTSPESFilter pes_filter;
66
        MpegTSSectionFilter section_filter;
67
    } u;
68
} MpegTSFilter;
69

    
70
typedef struct MpegTSService {
71
    int running:1;
72
    int sid;
73
    char *provider_name;
74
    char *name;
75
} MpegTSService;
76

    
77
typedef struct MpegTSContext {
78
    /* user data */
79
    AVFormatContext *stream;
80
    int raw_packet_size; /* raw packet size, including FEC if present */
81
    int auto_guess; /* if true, all pids are analized to find streams */
82
    int set_service_ret;
83

    
84
    /* data needed to handle file based ts */
85
    int stop_parse; /* stop parsing loop */
86
    AVPacket *pkt; /* packet containing av data */
87

    
88
    /******************************************/
89
    /* private mpegts data */
90
    /* scan context */
91
    MpegTSFilter *sdt_filter;
92
    int nb_services;
93
    MpegTSService **services;
94
    
95
    /* set service context (XXX: allocated it ?) */
96
    SetServiceCallback *set_service_cb;
97
    void *set_service_opaque;
98
    MpegTSFilter *pat_filter;
99
    MpegTSFilter *pmt_filter;
100
    int req_sid;
101

    
102
    MpegTSFilter *pids[NB_PID_MAX];
103
} MpegTSContext;
104

    
105
static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
106
                               const uint8_t *buf, int buf_size, int is_start)
107
{
108
    MpegTSSectionFilter *tss = &tss1->u.section_filter;
109
    int len;
110
    unsigned int crc;
111
    
112
    if (is_start) {
113
        memcpy(tss->section_buf, buf, buf_size);
114
        tss->section_index = buf_size;
115
        tss->section_h_size = -1;
116
        tss->end_of_section_reached = 0;
117
    } else {
118
        if (tss->end_of_section_reached)
119
            return;
120
        len = 4096 - tss->section_index;
121
        if (buf_size < len)
122
            len = buf_size;
123
        memcpy(tss->section_buf + tss->section_index, buf, len);
124
        tss->section_index += len;
125
    }
126

    
127
    /* compute section length if possible */
128
    if (tss->section_h_size == -1 && tss->section_index >= 3) {
129
        len = (((tss->section_buf[1] & 0xf) << 8) | tss->section_buf[2]) + 3;
130
        if (len > 4096)
131
            return;
132
        tss->section_h_size = len;
133
    }
134

    
135
    if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
136
        if (tss->check_crc) {
137
            crc = mpegts_crc32(tss->section_buf, tss->section_h_size);
138
            if (crc != 0)
139
                goto invalid_crc;
140
        }
141
        tss->section_cb(tss->opaque, tss->section_buf, tss->section_h_size);
142
    invalid_crc:
143
        tss->end_of_section_reached = 1;
144
    }
145
}
146

    
147
MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, 
148
                                         SectionCallback *section_cb, void *opaque,
149
                                         int check_crc)
150

    
151
{
152
    MpegTSFilter *filter;
153
    MpegTSSectionFilter *sec;
154

    
155
    if (pid >= NB_PID_MAX || ts->pids[pid])
156
        return NULL;
157
    filter = av_mallocz(sizeof(MpegTSFilter));
158
    if (!filter) 
159
        return NULL;
160
    ts->pids[pid] = filter;
161
    filter->type = MPEGTS_SECTION;
162
    filter->pid = pid;
163
    filter->last_cc = -1;
164
    sec = &filter->u.section_filter;
165
    sec->section_cb = section_cb;
166
    sec->opaque = opaque;
167
    sec->section_buf = av_malloc(MAX_SECTION_SIZE);
168
    sec->check_crc = check_crc;
169
    if (!sec->section_buf) {
170
        av_free(filter);
171
        return NULL;
172
    }
173
    return filter;
174
}
175

    
176
MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, 
177
                                     PESCallback *pes_cb,
178
                                     void *opaque)
179
{
180
    MpegTSFilter *filter;
181
    MpegTSPESFilter *pes;
182

    
183
    if (pid >= NB_PID_MAX || ts->pids[pid])
184
        return NULL;
185
    filter = av_mallocz(sizeof(MpegTSFilter));
186
    if (!filter) 
187
        return NULL;
188
    ts->pids[pid] = filter;
189
    filter->type = MPEGTS_PES;
190
    filter->pid = pid;
191
    filter->last_cc = -1;
192
    pes = &filter->u.pes_filter;
193
    pes->pes_cb = pes_cb;
194
    pes->opaque = opaque;
195
    return filter;
196
}
197

    
198
void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
199
{
200
    int pid;
201

    
202
    pid = filter->pid;
203
    if (filter->type == MPEGTS_SECTION)
204
        av_freep(&filter->u.section_filter.section_buf);
205
    av_free(filter);
206
    ts->pids[pid] = NULL;
207
}
208

    
209
/* autodetect fec presence. Must have at least 1024 bytes  */
210
static int get_packet_size(const uint8_t *buf, int size)
211
{
212
    int i;
213

    
214
    if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
215
        return -1;
216
    for(i=0;i<5;i++) {
217
        if (buf[i * TS_PACKET_SIZE] != 0x47)
218
            goto try_fec;
219
    }
220
    return TS_PACKET_SIZE;
221
 try_fec:
222
    for(i=0;i<5;i++) {
223
        if (buf[i * TS_FEC_PACKET_SIZE] != 0x47)
224
            return -1;
225
    }
226
    return TS_FEC_PACKET_SIZE;
227
}
228

    
229
typedef struct SectionHeader {
230
    uint8_t tid;
231
    uint16_t id;
232
    uint8_t version;
233
    uint8_t sec_num;
234
    uint8_t last_sec_num;
235
} SectionHeader;
236

    
237
static inline int get8(const uint8_t **pp, const uint8_t *p_end)
238
{
239
    const uint8_t *p;
240
    int c;
241

    
242
    p = *pp;
243
    if (p >= p_end)
244
        return -1;
245
    c = *p++;
246
    *pp = p;
247
    return c;
248
}
249

    
250
static inline int get16(const uint8_t **pp, const uint8_t *p_end)
251
{
252
    const uint8_t *p;
253
    int c;
254

    
255
    p = *pp;
256
    if ((p + 1) >= p_end)
257
        return -1;
258
    c = (p[0] << 8) | p[1];
259
    p += 2;
260
    *pp = p;
261
    return c;
262
}
263

    
264
/* read and allocate a DVB string preceeded by its length */
265
static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
266
{
267
    int len;
268
    const uint8_t *p;
269
    char *str;
270

    
271
    p = *pp;
272
    len = get8(&p, p_end);
273
    if (len < 0)
274
        return NULL;
275
    if ((p + len) > p_end)
276
        return NULL;
277
    str = av_malloc(len + 1);
278
    if (!str)
279
        return NULL;
280
    memcpy(str, p, len);
281
    str[len] = '\0';
282
    p += len;
283
    *pp = p;
284
    return str;
285
}
286

    
287
static int parse_section_header(SectionHeader *h, 
288
                                const uint8_t **pp, const uint8_t *p_end)
289
{
290
    int val;
291

    
292
    val = get8(pp, p_end);
293
    if (val < 0)
294
        return -1;
295
    h->tid = val;
296
    *pp += 2;
297
    val = get16(pp, p_end);
298
    if (val < 0)
299
        return -1;
300
    h->id = val;
301
    val = get8(pp, p_end);
302
    if (val < 0)
303
        return -1;
304
    h->version = (val >> 1) & 0x1f;
305
    val = get8(pp, p_end);
306
    if (val < 0)
307
        return -1;
308
    h->sec_num = val;
309
    val = get8(pp, p_end);
310
    if (val < 0)
311
        return -1;
312
    h->last_sec_num = val;
313
    return 0;
314
}
315

    
316
static MpegTSService *new_service(MpegTSContext *ts, int sid, 
317
                                  char *provider_name, char *name)
318
{
319
    MpegTSService *service;
320

    
321
#ifdef DEBUG_SI
322
    printf("new_service: sid=0x%04x provider='%s' name='%s'\n", 
323
           sid, provider_name, name);
324
#endif
325

    
326
    service = av_mallocz(sizeof(MpegTSService));
327
    if (!service)
328
        return NULL;
329
    service->sid = sid;
330
    service->provider_name = provider_name;
331
    service->name = name;
332
    dynarray_add(&ts->services, &ts->nb_services, service);
333
    return service;
334
}
335

    
336
static void pmt_cb(void *opaque, const uint8_t *section, int section_len)
337
{
338
    MpegTSContext *ts = opaque;
339
    SectionHeader h1, *h = &h1;
340
    const uint8_t *p, *p_end;
341
    int program_info_length, pcr_pid, pid, stream_type, desc_length;
342
    
343
#ifdef DEBUG_SI
344
    printf("PMT:\n");
345
    av_hex_dump((uint8_t *)section, section_len);
346
#endif
347
    p_end = section + section_len - 4;
348
    p = section;
349
    if (parse_section_header(h, &p, p_end) < 0)
350
        return;
351
#ifdef DEBUG_SI
352
    printf("sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num);
353
#endif
354
    if (h->tid != PMT_TID || (ts->req_sid >= 0 && h->id != ts->req_sid) )
355
        return;
356

    
357
    pcr_pid = get16(&p, p_end) & 0x1fff;
358
    if (pcr_pid < 0)
359
        return;
360
#ifdef DEBUG_SI
361
    printf("pcr_pid=0x%x\n", pcr_pid);
362
#endif
363
    program_info_length = get16(&p, p_end) & 0xfff;
364
    if (program_info_length < 0)
365
        return;
366
    p += program_info_length;
367
    if (p >= p_end)
368
        return;
369
    for(;;) {
370
        stream_type = get8(&p, p_end);
371
        if (stream_type < 0)
372
            break;
373
        pid = get16(&p, p_end) & 0x1fff;
374
        if (pid < 0)
375
            break;
376
        desc_length = get16(&p, p_end) & 0xfff;
377
        if (desc_length < 0)
378
            break;
379
        p += desc_length;
380
        if (p > p_end)
381
            return;
382

    
383
#ifdef DEBUG_SI
384
        printf("stream_type=%d pid=0x%x\n", stream_type, pid);
385
#endif
386

    
387
        /* now create ffmpeg stream */
388
        switch(stream_type) {
389
        case STREAM_TYPE_AUDIO_MPEG1:
390
        case STREAM_TYPE_AUDIO_MPEG2:
391
        case STREAM_TYPE_VIDEO_MPEG1:
392
        case STREAM_TYPE_VIDEO_MPEG2:
393
        case STREAM_TYPE_AUDIO_AC3:
394
            add_pes_stream(ts->stream, pid);
395
            break;
396
        default:
397
            /* we ignore the other streams */
398
            break;
399
        }
400
    }
401
    /* all parameters are there */
402
    ts->set_service_cb(ts->set_service_opaque, 0);
403
    mpegts_close_filter(ts, ts->pmt_filter);
404
    ts->pmt_filter = NULL;
405
}
406

    
407
static void pat_cb(void *opaque, const uint8_t *section, int section_len)
408
{
409
    MpegTSContext *ts = opaque;
410
    SectionHeader h1, *h = &h1;
411
    const uint8_t *p, *p_end;
412
    int sid, pmt_pid;
413

    
414
#ifdef DEBUG_SI
415
    printf("PAT:\n");
416
    av_hex_dump((uint8_t *)section, section_len);
417
#endif
418
    p_end = section + section_len - 4;
419
    p = section;
420
    if (parse_section_header(h, &p, p_end) < 0)
421
        return;
422
    if (h->tid != PAT_TID)
423
        return;
424

    
425
    for(;;) {
426
        sid = get16(&p, p_end);
427
        if (sid < 0)
428
            break;
429
        pmt_pid = get16(&p, p_end) & 0x1fff;
430
        if (pmt_pid < 0)
431
            break;
432
#ifdef DEBUG_SI
433
        printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
434
#endif
435
        if (sid == 0x0000) {
436
            /* NIT info */
437
        } else {
438
            if (ts->req_sid == sid) {
439
                ts->pmt_filter = mpegts_open_section_filter(ts, pmt_pid, 
440
                                                            pmt_cb, ts, 1);
441
                goto found;
442
            }
443
        }
444
    }
445
    /* not found */
446
    ts->set_service_cb(ts->set_service_opaque, -1);
447

    
448
 found:
449
    mpegts_close_filter(ts, ts->pat_filter);
450
    ts->pat_filter = NULL;
451
}
452

    
453
/* add all services found in the PAT */
454
static void pat_scan_cb(void *opaque, const uint8_t *section, int section_len)
455
{
456
    MpegTSContext *ts = opaque;
457
    SectionHeader h1, *h = &h1;
458
    const uint8_t *p, *p_end;
459
    int sid, pmt_pid;
460
    char *provider_name, *name;
461
    char buf[256];
462

    
463
#ifdef DEBUG_SI
464
    printf("PAT:\n");
465
    av_hex_dump((uint8_t *)section, section_len);
466
#endif
467
    p_end = section + section_len - 4;
468
    p = section;
469
    if (parse_section_header(h, &p, p_end) < 0)
470
        return;
471
    if (h->tid != PAT_TID)
472
        return;
473

    
474
    for(;;) {
475
        sid = get16(&p, p_end);
476
        if (sid < 0)
477
            break;
478
        pmt_pid = get16(&p, p_end) & 0x1fff;
479
        if (pmt_pid < 0)
480
            break;
481
#ifdef DEBUG_SI
482
        printf("sid=0x%x pid=0x%x\n", sid, pmt_pid);
483
#endif
484
        if (sid == 0x0000) {
485
            /* NIT info */
486
        } else {
487
            /* add the service with a dummy name */
488
            snprintf(buf, sizeof(buf), "Service %x\n", sid);
489
            name = av_strdup(buf);
490
            provider_name = av_strdup("");
491
            if (name && provider_name) {
492
                new_service(ts, sid, provider_name, name);
493
            } else {
494
                av_freep(&name);
495
                av_freep(&provider_name);
496
            }
497
        }
498
    }
499
    ts->stop_parse = 1;
500

    
501
    /* remove filter */
502
    mpegts_close_filter(ts, ts->pat_filter);
503
    ts->pat_filter = NULL;
504
}
505

    
506
void mpegts_set_service(MpegTSContext *ts, int sid,
507
                        SetServiceCallback *set_service_cb, void *opaque)
508
{
509
    ts->set_service_cb = set_service_cb;
510
    ts->set_service_opaque = opaque;
511
    ts->req_sid = sid;
512
    ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID, 
513
                                                pat_cb, ts, 1);
514
}
515

    
516
static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
517
{
518
    MpegTSContext *ts = opaque;
519
    SectionHeader h1, *h = &h1;
520
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
521
    int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
522
    char *name, *provider_name;
523

    
524
#ifdef DEBUG_SI
525
    printf("SDT:\n");
526
    av_hex_dump((uint8_t *)section, section_len);
527
#endif
528

    
529
    p_end = section + section_len - 4;
530
    p = section;
531
    if (parse_section_header(h, &p, p_end) < 0)
532
        return;
533
    if (h->tid != SDT_TID)
534
        return;
535
    onid = get16(&p, p_end);
536
    if (onid < 0)
537
        return;
538
    val = get8(&p, p_end);
539
    if (val < 0)
540
        return;
541
    for(;;) {
542
        sid = get16(&p, p_end);
543
        if (sid < 0)
544
            break;
545
        val = get8(&p, p_end);
546
        if (val < 0)
547
            break;
548
        desc_list_len = get16(&p, p_end) & 0xfff;
549
        if (desc_list_len < 0)
550
            break;
551
        desc_list_end = p + desc_list_len;
552
        if (desc_list_end > p_end)
553
            break;
554
        for(;;) {
555
            desc_tag = get8(&p, desc_list_end);
556
            if (desc_tag < 0)
557
                break;
558
            desc_len = get8(&p, desc_list_end);
559
            desc_end = p + desc_len;
560
            if (desc_end > desc_list_end)
561
                break;
562
#ifdef DEBUG_SI
563
            printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
564
#endif
565
            switch(desc_tag) {
566
            case 0x48:
567
                service_type = get8(&p, p_end);
568
                if (service_type < 0)
569
                    break;
570
                provider_name = getstr8(&p, p_end);
571
                if (!provider_name)
572
                    break;
573
                name = getstr8(&p, p_end);
574
                if (!name)
575
                    break;
576
                new_service(ts, sid, provider_name, name);
577
                break;
578
            default:
579
                break;
580
            }
581
            p = desc_end;
582
        }
583
        p = desc_list_end;
584
    }
585
    ts->stop_parse = 1;
586

    
587
    /* remove filter */
588
    mpegts_close_filter(ts, ts->sdt_filter);
589
    ts->sdt_filter = NULL;
590
}
591

    
592
/* scan services in a transport stream by looking at the SDT */
593
void mpegts_scan_sdt(MpegTSContext *ts)
594
{
595
    ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID, 
596
                                                sdt_cb, ts, 1);
597
}
598

    
599
/* scan services in a transport stream by looking at the PAT (better
600
   than nothing !) */
601
void mpegts_scan_pat(MpegTSContext *ts)
602
{
603
    ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID, 
604
                                                pat_scan_cb, ts, 1);
605
}
606

    
607
/* TS stream handling */
608

    
609
enum MpegTSState {
610
    MPEGTS_HEADER = 0,
611
    MPEGTS_PESHEADER_FILL,
612
    MPEGTS_PAYLOAD,
613
    MPEGTS_SKIP,
614
};
615

    
616
/* enough for PES header + length */
617
#define PES_START_SIZE 9
618
#define MAX_PES_HEADER_SIZE (9 + 255)
619

    
620
typedef struct PESContext {
621
    int pid;
622
    AVFormatContext *stream;
623
    AVStream *st;
624
    enum MpegTSState state;
625
    /* used to get the format */
626
    int data_index;
627
    int total_size;
628
    int pes_header_size;
629
    int64_t pts, dts;
630
    uint8_t header[MAX_PES_HEADER_SIZE];
631
} PESContext;
632

    
633
static int64_t get_pts(const uint8_t *p)
634
{
635
    int64_t pts;
636
    int val;
637

    
638
    pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
639
    val = (p[1] << 8) | p[2];
640
    pts |= (int64_t)(val >> 1) << 15;
641
    val = (p[3] << 8) | p[4];
642
    pts |= (int64_t)(val >> 1);
643
    return pts;
644
}
645

    
646
/* return non zero if a packet could be constructed */
647
static void mpegts_push_data(void *opaque,
648
                             const uint8_t *buf, int buf_size, int is_start)
649
{
650
    PESContext *pes = opaque;
651
    MpegTSContext *ts = pes->stream->priv_data;
652
    AVStream *st;
653
    const uint8_t *p;
654
    int len, code, codec_type, codec_id;
655
    
656
    if (is_start) {
657
        pes->state = MPEGTS_HEADER;
658
        pes->data_index = 0;
659
    }
660
    p = buf;
661
    while (buf_size > 0) {
662
        switch(pes->state) {
663
        case MPEGTS_HEADER:
664
            len = PES_START_SIZE - pes->data_index;
665
            if (len > buf_size)
666
                len = buf_size;
667
            memcpy(pes->header + pes->data_index, p, len);
668
            pes->data_index += len;
669
            p += len;
670
            buf_size -= len;
671
            if (pes->data_index == PES_START_SIZE) {
672
                /* we got all the PES or section header. We can now
673
                   decide */
674
#if 0
675
                av_hex_dump(pes->header, pes->data_index);
676
#endif
677
                if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
678
                    pes->header[2] == 0x01) {
679
                    /* it must be an mpeg2 PES stream */
680
                    code = pes->header[3] | 0x100;
681
                    if (!((code >= 0x1c0 && code <= 0x1df) ||
682
                          (code >= 0x1e0 && code <= 0x1ef) ||
683
                          (code == 0x1bd)))
684
                        goto skip;
685
                    if (!pes->st) {
686
                        /* allocate stream */
687
                        if (code >= 0x1c0 && code <= 0x1df) {
688
                            codec_type = CODEC_TYPE_AUDIO;
689
                            codec_id = CODEC_ID_MP2;
690
                        } else if (code == 0x1bd) {
691
                            codec_type = CODEC_TYPE_AUDIO;
692
                            codec_id = CODEC_ID_AC3;
693
                        } else {
694
                            codec_type = CODEC_TYPE_VIDEO;
695
                            codec_id = CODEC_ID_MPEG1VIDEO;
696
                        }
697
                        st = av_new_stream(pes->stream, pes->pid);
698
                        if (st) {
699
                            st->priv_data = pes;
700
                            st->codec.codec_type = codec_type;
701
                            st->codec.codec_id = codec_id;
702
                            pes->st = st;
703
                        }
704
                    }
705
                    pes->state = MPEGTS_PESHEADER_FILL;
706
                    pes->total_size = (pes->header[4] << 8) | pes->header[5];
707
                    /* NOTE: a zero total size means the PES size is
708
                       unbounded */
709
                    if (pes->total_size)
710
                        pes->total_size += 6;
711
                    pes->pes_header_size = pes->header[8] + 9;
712
                } else {
713
                    /* otherwise, it should be a table */
714
                    /* skip packet */
715
                skip:
716
                    pes->state = MPEGTS_SKIP;
717
                    continue;
718
                }
719
            }
720
            break;
721
            /**********************************************/
722
            /* PES packing parsing */
723
        case MPEGTS_PESHEADER_FILL:
724
            len = pes->pes_header_size - pes->data_index;
725
            if (len > buf_size)
726
                len = buf_size;
727
            memcpy(pes->header + pes->data_index, p, len);
728
            pes->data_index += len;
729
            p += len;
730
            buf_size -= len;
731
            if (pes->data_index == pes->pes_header_size) {
732
                const uint8_t *r;
733
                unsigned int flags;
734

    
735
                flags = pes->header[7];
736
                r = pes->header + 9;
737
                pes->pts = AV_NOPTS_VALUE;
738
                pes->dts = AV_NOPTS_VALUE;
739
                if ((flags & 0xc0) == 0x80) {
740
                    pes->pts = get_pts(r);
741
                    r += 5;
742
                } else if ((flags & 0xc0) == 0xc0) {
743
                    pes->pts = get_pts(r);
744
                    r += 5;
745
                    pes->dts = get_pts(r);
746
                    r += 5;
747
                }
748
                /* we got the full header. We parse it and get the payload */
749
                pes->state = MPEGTS_PAYLOAD;
750
            }
751
            break;
752
        case MPEGTS_PAYLOAD:
753
            if (pes->total_size) {
754
                len = pes->total_size - pes->data_index;
755
                if (len > buf_size)
756
                    len = buf_size;
757
            } else {
758
                len = buf_size;
759
            }
760
            if (len > 0) {
761
                AVPacket *pkt = ts->pkt;
762
                if (pes->st && av_new_packet(pkt, len) == 0) {
763
                    memcpy(pkt->data, p, len);
764
                    pkt->stream_index = pes->st->index;
765
                    pkt->pts = pes->pts;
766
                    /* reset pts values */
767
                    pes->pts = AV_NOPTS_VALUE;
768
                    pes->dts = AV_NOPTS_VALUE;
769
                    ts->stop_parse = 1;
770
                    return;
771
                }
772
            }
773
            buf_size = 0;
774
            break;
775
        case MPEGTS_SKIP:
776
            buf_size = 0;
777
            break;
778
        }
779
    }
780
}
781

    
782
static int add_pes_stream(AVFormatContext *s, int pid)
783
{
784
    MpegTSContext *ts = s->priv_data;
785
    MpegTSFilter *tss;
786
    PESContext *pes;
787

    
788
    /* if no pid found, then add a pid context */
789
    pes = av_mallocz(sizeof(PESContext));
790
    if (!pes)
791
        return -1;
792
    pes->stream = s;
793
    pes->pid = pid;
794
    tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
795
    if (!tss) {
796
        av_free(pes);
797
        return -1;
798
    }
799
    return 0;
800
}
801

    
802
/* handle one TS packet */
803
static void handle_packet(AVFormatContext *s, uint8_t *packet)
804
{
805
    MpegTSContext *ts = s->priv_data;
806
    MpegTSFilter *tss;
807
    int len, pid, cc, cc_ok, afc, is_start;
808
    const uint8_t *p, *p_end;
809

    
810
    pid = ((packet[1] & 0x1f) << 8) | packet[2];
811
    is_start = packet[1] & 0x40;
812
    tss = ts->pids[pid];
813
    if (ts->auto_guess && tss == NULL && is_start) {
814
        add_pes_stream(s, pid);
815
        tss = ts->pids[pid];
816
    }
817
    if (!tss)
818
        return;
819

    
820
    /* continuity check (currently not used) */
821
    cc = (packet[3] & 0xf);
822
    cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
823
    tss->last_cc = cc;
824
    
825
    /* skip adaptation field */
826
    afc = (packet[3] >> 4) & 3;
827
    p = packet + 4;
828
    if (afc == 0) /* reserved value */
829
        return;
830
    if (afc == 2) /* adaptation field only */
831
        return;
832
    if (afc == 3) {
833
        /* skip adapation field */
834
        p += p[0] + 1;
835
    }
836
    /* if past the end of packet, ignore */
837
    p_end = packet + TS_PACKET_SIZE;
838
    if (p >= p_end)
839
        return;
840
    
841
    if (tss->type == MPEGTS_SECTION) {
842
        if (is_start) {
843
            /* pointer field present */
844
            len = *p++;
845
            if (p + len > p_end)
846
                return;
847
            if (len && cc_ok) {
848
                /* write remaning section bytes */
849
                write_section_data(s, tss, 
850
                                   p, len, 0);
851
            }
852
            p += len;
853
            if (p < p_end) {
854
                write_section_data(s, tss, 
855
                                   p, p_end - p, 1);
856
            }
857
        } else {
858
            if (cc_ok) {
859
                write_section_data(s, tss, 
860
                                   p, p_end - p, 0);
861
            }
862
        }
863
    } else {
864
        tss->u.pes_filter.pes_cb(tss->u.pes_filter.opaque, 
865
                                 p, p_end - p, is_start);
866
    }
867
}
868

    
869
/* XXX: try to find a better synchro over several packets (use
870
   get_packet_size() ?) */
871
static int mpegts_resync(AVFormatContext *s)
872
{
873
    ByteIOContext *pb = &s->pb;
874
    int c, i;
875

    
876
    for(i = 0;i < MAX_RESYNC_SIZE; i++) {
877
        c = url_fgetc(pb);
878
        if (c < 0)
879
            return -1;
880
        if (c == 0x47) {
881
            url_fseek(pb, -1, SEEK_CUR);
882
            return 0;
883
        }
884
    }
885
    /* no sync found */
886
    return -1;
887
}
888

    
889
static int handle_packets(AVFormatContext *s, int nb_packets)
890
{
891
    MpegTSContext *ts = s->priv_data;
892
    ByteIOContext *pb = &s->pb;
893
    uint8_t packet[TS_FEC_PACKET_SIZE];
894
    int packet_num, len;
895
    int64_t pos;
896

    
897
    ts->stop_parse = 0;
898
    packet_num = 0;
899
    for(;;) {
900
        if (ts->stop_parse)
901
            break;
902
        packet_num++;
903
        if (nb_packets != 0 && packet_num >= nb_packets)
904
            break;
905
        pos = url_ftell(pb);
906
        len = get_buffer(pb, packet, ts->raw_packet_size);
907
        if (len != ts->raw_packet_size)
908
            return AVERROR_IO;
909
        /* check paquet sync byte */
910
        if (packet[0] != 0x47) {
911
            /* find a new packet start */
912
            url_fseek(pb, -ts->raw_packet_size, SEEK_CUR);
913
            if (mpegts_resync(s) < 0)
914
                return AVERROR_INVALIDDATA;
915
            else
916
                continue;
917
        }
918
        handle_packet(s, packet);
919
    }
920
    return 0;
921
}
922

    
923
static int mpegts_probe(AVProbeData *p)
924
{
925
#if 1
926
    int size;
927
    size = get_packet_size(p->buf, p->buf_size);
928
    if (size < 0)
929
        return 0;
930
    return AVPROBE_SCORE_MAX - 1;
931
#else
932
    /* only use the extension for safer guess */
933
    if (match_ext(p->filename, "ts"))
934
        return AVPROBE_SCORE_MAX;
935
    else
936
        return 0;
937
#endif
938
}
939

    
940
void set_service_cb(void *opaque, int ret)
941
{
942
    MpegTSContext *ts = opaque;
943
    ts->set_service_ret = ret;
944
    ts->stop_parse = 1;
945
}
946

    
947
static int mpegts_read_header(AVFormatContext *s,
948
                              AVFormatParameters *ap)
949
{
950
    MpegTSContext *ts = s->priv_data;
951
    ByteIOContext *pb = &s->pb;
952
    uint8_t buf[1024];
953
    int len, sid;
954
    int64_t pos;
955
    MpegTSService *service;
956
    
957
    /* read the first 1024 bytes to get packet size */
958
    pos = url_ftell(pb);
959
    len = get_buffer(pb, buf, sizeof(buf));
960
    if (len != sizeof(buf))
961
        goto fail;
962
    ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
963
    if (ts->raw_packet_size <= 0)
964
        goto fail;
965
    ts->auto_guess = 0;
966
    
967
    if (!ts->auto_guess) {
968
        ts->set_service_ret = -1;
969

    
970
        /* first do a scaning to get all the services */
971
        url_fseek(pb, pos, SEEK_SET);
972
        mpegts_scan_sdt(ts);
973

    
974
        handle_packets(s, MAX_SCAN_PACKETS);
975

    
976
        if (ts->nb_services <= 0) {
977
            /* no SDT found, we try to look at the PAT */
978
            
979
            url_fseek(pb, pos, SEEK_SET);
980
            mpegts_scan_pat(ts);
981
            
982
            handle_packets(s, MAX_SCAN_PACKETS);
983
        }
984
        
985
        if (ts->nb_services <= 0)
986
            return -1;
987
        
988
        /* tune to first service found */
989
        service = ts->services[0];
990
        sid = service->sid;
991
#ifdef DEBUG_SI
992
        printf("tuning to '%s'\n", service->name);
993
#endif
994

    
995
        /* now find the info for the first service if we found any,
996
           otherwise try to filter all PATs */
997

    
998
        url_fseek(pb, pos, SEEK_SET);
999
        ts->stream = s;
1000
        mpegts_set_service(ts, sid, set_service_cb, ts);
1001

    
1002
        handle_packets(s, MAX_SCAN_PACKETS);
1003

    
1004
        /* if could not find service, exit */
1005
        if (ts->set_service_ret != 0)
1006
            return -1;
1007

    
1008
#ifdef DEBUG_SI
1009
        printf("tuning done\n");
1010
#endif
1011
    }
1012

    
1013
    url_fseek(pb, pos, SEEK_SET);
1014
    return 0;
1015
 fail:
1016
    return -1;
1017
}
1018

    
1019
static int mpegts_read_packet(AVFormatContext *s,
1020
                              AVPacket *pkt)
1021
{
1022
    MpegTSContext *ts = s->priv_data;
1023
    ts->pkt = pkt;
1024
    return handle_packets(s, 0);
1025
}
1026

    
1027
static int mpegts_read_close(AVFormatContext *s)
1028
{
1029
    MpegTSContext *ts = s->priv_data;
1030
    int i;
1031
    for(i=0;i<NB_PID_MAX;i++)
1032
        av_free(ts->pids[i]);
1033
    return 0;
1034
}
1035

    
1036
AVInputFormat mpegts_demux = {
1037
    "mpegts",
1038
    "MPEG2 transport stream format",
1039
    sizeof(MpegTSContext),
1040
    mpegts_probe,
1041
    mpegts_read_header,
1042
    mpegts_read_packet,
1043
    mpegts_read_close,
1044
    .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS,
1045
};
1046

    
1047
int mpegts_init(void)
1048
{
1049
    av_register_input_format(&mpegts_demux);
1050
    av_register_output_format(&mpegts_mux);
1051
    return 0;
1052
}