Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ ec23a472

History | View | Annotate | Download (26.1 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 16000
27

    
28
static int add_pes_stream(AVFormatContext *s, int pid);
29

    
30
enum MpegTSFilterType {
31
    MPEGTS_PES,
32
    MPEGTS_SECTION,
33
};
34

    
35
/* XXX: suppress 'pkt' parameter */
36
typedef void PESCallback(void *opaque, const uint8_t *buf, int len, int is_start);
37

    
38
typedef struct MpegTSPESFilter {
39
    PESCallback *pes_cb;
40
    void *opaque;
41
} MpegTSPESFilter;
42

    
43
typedef void SectionCallback(void *opaque, const uint8_t *buf, int len);
44

    
45
typedef void SetServiceCallback(void *opaque, int ret);
46

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

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

    
67
typedef struct MpegTSService {
68
    int running:1;
69
    int sid;
70
    char *provider_name;
71
    char *name;
72
} MpegTSService;
73

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

    
81
    /* data needed to handle file based ts */
82
    int stop_parse; /* stop parsing loop */
83
    AVPacket *pkt; /* packet containing av data */
84

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

    
99
    MpegTSFilter *pids[NB_PID_MAX];
100
} MpegTSContext;
101

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

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

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

    
144
MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, 
145
                                         SectionCallback *section_cb, void *opaque,
146
                                         int check_crc)
147

    
148
{
149
    MpegTSFilter *filter;
150
    MpegTSSectionFilter *sec;
151

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

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

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

    
195
void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
196
{
197
    int pid;
198

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

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

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

    
226
typedef struct SectionHeader {
227
    uint8_t tid;
228
    uint16_t id;
229
    uint8_t version;
230
    uint8_t sec_num;
231
    uint8_t last_sec_num;
232
} SectionHeader;
233

    
234
static inline int get8(const uint8_t **pp, const uint8_t *p_end)
235
{
236
    const uint8_t *p;
237
    int c;
238

    
239
    p = *pp;
240
    if (p >= p_end)
241
        return -1;
242
    c = *p++;
243
    *pp = p;
244
    return c;
245
}
246

    
247
static inline int get16(const uint8_t **pp, const uint8_t *p_end)
248
{
249
    const uint8_t *p;
250
    int c;
251

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

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

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

    
284
static int parse_section_header(SectionHeader *h, 
285
                                const uint8_t **pp, const uint8_t *p_end)
286
{
287
    int val;
288

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

    
313
static MpegTSService *new_service(MpegTSContext *ts, int sid, 
314
                                  char *provider_name, char *name)
315
{
316
    MpegTSService *service;
317

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

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

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

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

    
380
#ifdef DEBUG_SI
381
        printf("stream_type=%d pid=0x%x\n", stream_type, pid);
382
#endif
383

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

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

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

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

    
445
 found:
446
    mpegts_close_filter(ts, ts->pat_filter);
447
    ts->pat_filter = NULL;
448
}
449

    
450
void mpegts_set_service(MpegTSContext *ts, int sid,
451
                        SetServiceCallback *set_service_cb, void *opaque)
452
{
453
    ts->set_service_cb = set_service_cb;
454
    ts->set_service_opaque = opaque;
455
    ts->req_sid = sid;
456
    ts->pat_filter = mpegts_open_section_filter(ts, PAT_PID, 
457
                                                pat_cb, ts, 1);
458
}
459

    
460
static void sdt_cb(void *opaque, const uint8_t *section, int section_len)
461
{
462
    MpegTSContext *ts = opaque;
463
    SectionHeader h1, *h = &h1;
464
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
465
    int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
466
    char *name, *provider_name;
467

    
468
#ifdef DEBUG_SI
469
    printf("SDT:\n");
470
    av_hex_dump((uint8_t *)section, section_len);
471
#endif
472

    
473
    p_end = section + section_len - 4;
474
    p = section;
475
    if (parse_section_header(h, &p, p_end) < 0)
476
        return;
477
    if (h->tid != SDT_TID)
478
        return;
479
    onid = get16(&p, p_end);
480
    if (onid < 0)
481
        return;
482
    val = get8(&p, p_end);
483
    if (val < 0)
484
        return;
485
    for(;;) {
486
        sid = get16(&p, p_end);
487
        if (sid < 0)
488
            break;
489
        val = get8(&p, p_end);
490
        if (val < 0)
491
            break;
492
        desc_list_len = get16(&p, p_end) & 0xfff;
493
        if (desc_list_len < 0)
494
            break;
495
        desc_list_end = p + desc_list_len;
496
        if (desc_list_end > p_end)
497
            break;
498
        for(;;) {
499
            desc_tag = get8(&p, desc_list_end);
500
            if (desc_tag < 0)
501
                break;
502
            desc_len = get8(&p, desc_list_end);
503
            desc_end = p + desc_len;
504
            if (desc_end > desc_list_end)
505
                break;
506
#ifdef DEBUG_SI
507
            printf("tag: 0x%02x len=%d\n", desc_tag, desc_len);
508
#endif
509
            switch(desc_tag) {
510
            case 0x48:
511
                service_type = get8(&p, p_end);
512
                if (service_type < 0)
513
                    break;
514
                provider_name = getstr8(&p, p_end);
515
                if (!provider_name)
516
                    break;
517
                name = getstr8(&p, p_end);
518
                if (!name)
519
                    break;
520
                new_service(ts, sid, provider_name, name);
521
                break;
522
            default:
523
                break;
524
            }
525
            p = desc_end;
526
        }
527
        p = desc_list_end;
528
    }
529
    ts->stop_parse = 1;
530

    
531
    /* remove filter */
532
    mpegts_close_filter(ts, ts->sdt_filter);
533
    ts->sdt_filter = NULL;
534
}
535

    
536
/* scan services an a transport stream by looking at the sdt */
537
void mpegts_scan_sdt(MpegTSContext *ts)
538
{
539
    ts->sdt_filter = mpegts_open_section_filter(ts, SDT_PID, 
540
                                                sdt_cb, ts, 1);
541
}
542

    
543

    
544
/* TS stream handling */
545

    
546
enum MpegTSState {
547
    MPEGTS_HEADER = 0,
548
    MPEGTS_PESHEADER_FILL,
549
    MPEGTS_PAYLOAD,
550
    MPEGTS_SKIP,
551
};
552

    
553
/* enough for PES header + length */
554
#define PES_START_SIZE 9
555
#define MAX_PES_HEADER_SIZE (9 + 255)
556

    
557
typedef struct PESContext {
558
    int pid;
559
    AVFormatContext *stream;
560
    AVStream *st;
561
    enum MpegTSState state;
562
    /* used to get the format */
563
    int data_index;
564
    int total_size;
565
    int pes_header_size;
566
    int64_t pts, dts;
567
    uint8_t header[MAX_PES_HEADER_SIZE];
568
} PESContext;
569

    
570
static int64_t get_pts(const uint8_t *p)
571
{
572
    int64_t pts;
573
    int val;
574

    
575
    pts = (int64_t)((p[0] >> 1) & 0x07) << 30;
576
    val = (p[1] << 8) | p[2];
577
    pts |= (int64_t)(val >> 1) << 15;
578
    val = (p[3] << 8) | p[4];
579
    pts |= (int64_t)(val >> 1);
580
    return pts;
581
}
582

    
583
/* return non zero if a packet could be constructed */
584
static void mpegts_push_data(void *opaque,
585
                             const uint8_t *buf, int buf_size, int is_start)
586
{
587
    PESContext *pes = opaque;
588
    MpegTSContext *ts = pes->stream->priv_data;
589
    AVStream *st;
590
    const uint8_t *p;
591
    int len, code, codec_type, codec_id;
592
    
593
    if (is_start) {
594
        pes->state = MPEGTS_HEADER;
595
        pes->data_index = 0;
596
    }
597
    p = buf;
598
    while (buf_size > 0) {
599
        switch(pes->state) {
600
        case MPEGTS_HEADER:
601
            len = PES_START_SIZE - pes->data_index;
602
            if (len > buf_size)
603
                len = buf_size;
604
            memcpy(pes->header + pes->data_index, p, len);
605
            pes->data_index += len;
606
            p += len;
607
            buf_size -= len;
608
            if (pes->data_index == PES_START_SIZE) {
609
                /* we got all the PES or section header. We can now
610
                   decide */
611
#if 0
612
                av_hex_dump(pes->header, pes->data_index);
613
#endif
614
                if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
615
                    pes->header[2] == 0x01) {
616
                    /* it must be an mpeg2 PES stream */
617
                    code = pes->header[3] | 0x100;
618
                    if (!((code >= 0x1c0 && code <= 0x1df) ||
619
                          (code >= 0x1e0 && code <= 0x1ef) ||
620
                          (code == 0x1bd)))
621
                        goto skip;
622
                    if (!pes->st) {
623
                        /* allocate stream */
624
                        if (code >= 0x1c0 && code <= 0x1df) {
625
                            codec_type = CODEC_TYPE_AUDIO;
626
                            codec_id = CODEC_ID_MP2;
627
                        } else if (code == 0x1bd) {
628
                            codec_type = CODEC_TYPE_AUDIO;
629
                            codec_id = CODEC_ID_AC3;
630
                        } else {
631
                            codec_type = CODEC_TYPE_VIDEO;
632
                            codec_id = CODEC_ID_MPEG1VIDEO;
633
                        }
634
                        st = av_new_stream(pes->stream, pes->pid);
635
                        if (st) {
636
                            st->priv_data = pes;
637
                            st->codec.codec_type = codec_type;
638
                            st->codec.codec_id = codec_id;
639
                            pes->st = st;
640
                        }
641
                    }
642
                    pes->state = MPEGTS_PESHEADER_FILL;
643
                    pes->total_size = (pes->header[4] << 8) | pes->header[5];
644
                    /* NOTE: a zero total size means the PES size is
645
                       unbounded */
646
                    if (pes->total_size)
647
                        pes->total_size += 6;
648
                    pes->pes_header_size = pes->header[8] + 9;
649
                } else {
650
                    /* otherwise, it should be a table */
651
                    /* skip packet */
652
                skip:
653
                    pes->state = MPEGTS_SKIP;
654
                    continue;
655
                }
656
            }
657
            break;
658
            /**********************************************/
659
            /* PES packing parsing */
660
        case MPEGTS_PESHEADER_FILL:
661
            len = pes->pes_header_size - pes->data_index;
662
            if (len > buf_size)
663
                len = buf_size;
664
            memcpy(pes->header + pes->data_index, p, len);
665
            pes->data_index += len;
666
            p += len;
667
            buf_size -= len;
668
            if (pes->data_index == pes->pes_header_size) {
669
                const uint8_t *r;
670
                unsigned int flags;
671

    
672
                flags = pes->header[7];
673
                r = pes->header + 9;
674
                pes->pts = AV_NOPTS_VALUE;
675
                pes->dts = AV_NOPTS_VALUE;
676
                if ((flags & 0xc0) == 0x80) {
677
                    pes->pts = get_pts(r);
678
                    r += 5;
679
                } else if ((flags & 0xc0) == 0xc0) {
680
                    pes->pts = get_pts(r);
681
                    r += 5;
682
                    pes->dts = get_pts(r);
683
                    r += 5;
684
                }
685
                /* we got the full header. We parse it and get the payload */
686
                pes->state = MPEGTS_PAYLOAD;
687
            }
688
            break;
689
        case MPEGTS_PAYLOAD:
690
            if (pes->total_size) {
691
                len = pes->total_size - pes->data_index;
692
                if (len > buf_size)
693
                    len = buf_size;
694
            } else {
695
                len = buf_size;
696
            }
697
            if (len > 0) {
698
                AVPacket *pkt = ts->pkt;
699
                if (pes->st && av_new_packet(pkt, len) == 0) {
700
                    memcpy(pkt->data, p, len);
701
                    pkt->stream_index = pes->st->index;
702
                    pkt->pts = pes->pts;
703
                    /* reset pts values */
704
                    pes->pts = AV_NOPTS_VALUE;
705
                    pes->dts = AV_NOPTS_VALUE;
706
                    ts->stop_parse = 1;
707
                    return;
708
                }
709
            }
710
            buf_size = 0;
711
            break;
712
        case MPEGTS_SKIP:
713
            buf_size = 0;
714
            break;
715
        }
716
    }
717
}
718

    
719
static int add_pes_stream(AVFormatContext *s, int pid)
720
{
721
    MpegTSContext *ts = s->priv_data;
722
    MpegTSFilter *tss;
723
    PESContext *pes;
724

    
725
    /* if no pid found, then add a pid context */
726
    pes = av_mallocz(sizeof(PESContext));
727
    if (!pes)
728
        return -1;
729
    pes->stream = s;
730
    pes->pid = pid;
731
    tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
732
    if (!tss) {
733
        av_free(pes);
734
        return -1;
735
    }
736
    return 0;
737
}
738

    
739
/* handle one TS packet */
740
static void handle_packet(AVFormatContext *s, uint8_t *packet)
741
{
742
    MpegTSContext *ts = s->priv_data;
743
    MpegTSFilter *tss;
744
    int len, pid, cc, cc_ok, afc, is_start;
745
    const uint8_t *p, *p_end;
746

    
747
    pid = ((packet[1] & 0x1f) << 8) | packet[2];
748
    is_start = packet[1] & 0x40;
749
    tss = ts->pids[pid];
750
    if (ts->auto_guess && tss == NULL && is_start) {
751
        add_pes_stream(s, pid);
752
        tss = ts->pids[pid];
753
    }
754
    if (!tss)
755
        return;
756

    
757
    /* continuity check (currently not used) */
758
    cc = (packet[3] & 0xf);
759
    cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
760
    tss->last_cc = cc;
761
    
762
    /* skip adaptation field */
763
    afc = (packet[3] >> 4) & 3;
764
    p = packet + 4;
765
    if (afc == 0) /* reserved value */
766
        return;
767
    if (afc == 2) /* adaptation field only */
768
        return;
769
    if (afc == 3) {
770
        /* skip adapation field */
771
        p += p[0] + 1;
772
    }
773
    /* if past the end of packet, ignore */
774
    p_end = packet + TS_PACKET_SIZE;
775
    if (p >= p_end)
776
        return;
777
    
778
    if (tss->type == MPEGTS_SECTION) {
779
        if (is_start) {
780
            /* pointer field present */
781
            len = *p++;
782
            if (p + len > p_end)
783
                return;
784
            if (len && cc_ok) {
785
                /* write remaning section bytes */
786
                write_section_data(s, tss, 
787
                                   p, len, 0);
788
            }
789
            p += len;
790
            if (p < p_end) {
791
                write_section_data(s, tss, 
792
                                   p, p_end - p, 1);
793
            }
794
        } else {
795
            if (cc_ok) {
796
                write_section_data(s, tss, 
797
                                   p, p_end - p, 0);
798
                }
799
        }
800
    } else {
801
        tss->u.pes_filter.pes_cb(tss->u.pes_filter.opaque, 
802
                                 p, p_end - p, is_start);
803
    }
804
}
805

    
806
static int handle_packets(AVFormatContext *s, int nb_packets)
807
{
808
    MpegTSContext *ts = s->priv_data;
809
    ByteIOContext *pb = &s->pb;
810
    uint8_t packet[TS_FEC_PACKET_SIZE];
811
    int packet_num, len;
812
    int i, found = 0;
813
    int64_t pos;
814

    
815
    ts->stop_parse = 0;
816
    packet_num = 0;
817
    for(;;) {
818
        if (ts->stop_parse)
819
            break;
820
        packet_num++;
821
        if (nb_packets != 0 && packet_num >= nb_packets)
822
            break;
823
        pos = url_ftell(pb);
824
        len = get_buffer(pb, packet, ts->raw_packet_size);
825
        if (len != ts->raw_packet_size)
826
            return AVERROR_IO;
827
        /* check paquet sync byte */
828
        if (packet[0] != 0x47)
829
        {
830
           //printf("bad packet: 0x%x\n", packet[0]);
831
           found = 0;
832
           for (i = 0; i < ts->raw_packet_size; i++)
833
           {
834
               if (packet[i] == 0x47)
835
               {
836
                   found = 1;
837
                   //printf("packet start at: %d\n", i);
838
                   break;
839
               }
840
           }
841
           
842
           if (found)
843
           {
844
               url_fseek(pb, pos + i, SEEK_SET);
845
               continue;
846
           }
847
           return AVERROR_INVALIDDATA;
848
        }
849
        handle_packet(s, packet);
850
    }
851
    return 0;
852
}
853

    
854
static int mpegts_probe(AVProbeData *p)
855
{
856
    int size;
857
    size = get_packet_size(p->buf, p->buf_size);
858
    if (size < 0)
859
        return 0;
860
    return AVPROBE_SCORE_MAX - 1;
861
}
862

    
863
void set_service_cb(void *opaque, int ret)
864
{
865
    MpegTSContext *ts = opaque;
866
    ts->set_service_ret = ret;
867
    ts->stop_parse = 1;
868
}
869

    
870
static int mpegts_read_header(AVFormatContext *s,
871
                              AVFormatParameters *ap)
872
{
873
    MpegTSContext *ts = s->priv_data;
874
    ByteIOContext *pb = &s->pb;
875
    uint8_t buf[1024];
876
    int len;
877
    int64_t pos;
878
    MpegTSService *service;
879
    
880
    /* read the first 1024 bytes to get packet size */
881
    pos = url_ftell(pb);
882
    len = get_buffer(pb, buf, sizeof(buf));
883
    if (len != sizeof(buf))
884
        goto fail;
885
    ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
886
    if (ts->raw_packet_size <= 0)
887
        goto fail;
888
    ts->auto_guess = 0;
889
    
890
    if (!ts->auto_guess) {
891
        int sid = -1;
892
        ts->set_service_ret = -1;
893

    
894
        /* first do a scaning to get all the services */
895
        url_fseek(pb, pos, SEEK_SET);
896
        mpegts_scan_sdt(ts);
897
        
898
        handle_packets(s, MAX_SCAN_PACKETS);
899

    
900
        if (ts->nb_services > 0)
901
        {
902
            /* tune to first service found */
903
            service = ts->services[0];
904
            sid = service->sid;
905
#ifdef DEBUG_SI
906
            printf("tuning to '%s'\n", service->name);
907
#endif
908
        }
909

    
910
        /* now find the info for the first service if we found any,
911
           otherwise try to filter all PATs */
912

    
913
        url_fseek(pb, pos, SEEK_SET);
914
        ts->stream = s;
915
        mpegts_set_service(ts, sid, set_service_cb, ts);
916

    
917
        handle_packets(s, MAX_SCAN_PACKETS);
918

    
919
        /* if could not find service, exit */
920
        if (ts->set_service_ret != 0)
921
            return -1;
922

    
923
#ifdef DEBUG_SI
924
        printf("tuning done\n");
925
#endif
926
    }
927

    
928
    url_fseek(pb, pos, SEEK_SET);
929
    return 0;
930
 fail:
931
    return -1;
932
}
933

    
934
static int mpegts_read_packet(AVFormatContext *s,
935
                              AVPacket *pkt)
936
{
937
    MpegTSContext *ts = s->priv_data;
938
    ts->pkt = pkt;
939
    return handle_packets(s, 0);
940
}
941

    
942
static int mpegts_read_close(AVFormatContext *s)
943
{
944
    MpegTSContext *ts = s->priv_data;
945
    int i;
946
    for(i=0;i<NB_PID_MAX;i++)
947
        av_free(ts->pids[i]);
948
    return 0;
949
}
950

    
951
AVInputFormat mpegts_demux = {
952
    "mpegts",
953
    "MPEG2 transport stream format",
954
    sizeof(MpegTSContext),
955
    mpegts_probe,
956
    mpegts_read_header,
957
    mpegts_read_packet,
958
    mpegts_read_close,
959
    .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS,
960
};
961

    
962
int mpegts_init(void)
963
{
964
    av_register_input_format(&mpegts_demux);
965
    av_register_output_format(&mpegts_mux);
966
    return 0;
967
}