Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ 20cd83e2

History | View | Annotate | Download (43 KB)

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