Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ 828bb5f1

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