Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegts.c @ 34f633df

History | View | Annotate | Download (40.5 KB)

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