Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ 5509bffa

History | View | Annotate | Download (42.5 KB)

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