mpeg.c 30.9 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1
/*
2
 * MPEG1/2 demuxer
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21

Fabrice Bellard's avatar
Fabrice Bellard committed
22
#include "avformat.h"
23
#include "internal.h"
24
#include "mpeg.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
25

Clément Bœsch's avatar
Clément Bœsch committed
26 27 28 29 30
#if CONFIG_VOBSUB_DEMUXER
# include "subtitles.h"
# include "libavutil/bprint.h"
#endif

31 32
#undef NDEBUG
#include <assert.h>
33
#include "libavutil/avassert.h"
34

Fabrice Bellard's avatar
Fabrice Bellard committed
35 36 37 38 39
/*********************************************/
/* demux code */

#define MAX_SYNC_SIZE 100000

40
static int check_pes(const uint8_t *p, const uint8_t *end){
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
    int pes1;
    int pes2=      (p[3] & 0xC0) == 0x80
                && (p[4] & 0xC0) != 0x40
                &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0));

    for(p+=3; p<end && *p == 0xFF; p++);
    if((*p&0xC0) == 0x40) p+=2;
    if((*p&0xF0) == 0x20){
        pes1= p[0]&p[2]&p[4]&1;
    }else if((*p&0xF0) == 0x30){
        pes1= p[0]&p[2]&p[4]&p[5]&p[7]&p[9]&1;
    }else
        pes1 = *p == 0x0F;

    return pes1||pes2;
}

58 59 60 61
static int check_pack_header(const uint8_t *buf) {
    return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
}

62 63
static int mpegps_probe(AVProbeData *p)
{
64
    uint32_t code= -1;
65
    int sys=0, pspack=0, priv1=0, vid=0, audio=0, invalid=0;
66
    int i;
67
    int score=0;
68

69 70
    for(i=0; i<p->buf_size; i++){
        code = (code<<8) + p->buf[i];
71
        if ((code & 0xffffff00) == 0x100) {
72
            int len= p->buf[i+1] << 8 | p->buf[i+2];
Michael Niedermayer's avatar
Michael Niedermayer committed
73
            int pes= check_pes(p->buf+i, p->buf+p->buf_size);
74
            int pack = check_pack_header(p->buf+i);
75

76
            if(code == SYSTEM_HEADER_START_CODE) sys++;
77
            else if(code == PACK_START_CODE && pack) pspack++;
Michael Niedermayer's avatar
Michael Niedermayer committed
78
            else if((code & 0xf0) == VIDEO_ID &&  pes) vid++;
79 80 81 82
            // skip pes payload to avoid start code emulation for private
            // and audio streams
            else if((code & 0xe0) == AUDIO_ID &&  pes) {audio++; i+=len;}
            else if(code == PRIVATE_STREAM_1  &&  pes) {priv1++; i+=len;}
83
            else if(code == 0x1fd             &&  pes) vid++; //VC1
84 85 86

            else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;
            else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;
87
            else if(code == PRIVATE_STREAM_1  && !pes) invalid++;
88
        }
89
    }
90

91
    if(vid+audio > invalid+1)     /* invalid VDR files nd short PES streams */
92
        score = AVPROBE_SCORE_EXTENSION / 2;
93

94
    if(sys>invalid && sys*9 <= pspack*10)
95
        return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
96
    if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
97
        return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
98
    if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
99
        return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2;
100 101

    //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
102
    //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
103
    //Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
104
    return score;
105 106 107
}


Fabrice Bellard's avatar
Fabrice Bellard committed
108
typedef struct MpegDemuxContext {
109
    int32_t header_state;
110
    unsigned char psm_es_type[256];
111
    int sofdec;
112
    int dvd;
113
    int imkh_cctv;
Clément Bœsch's avatar
Clément Bœsch committed
114 115
#if CONFIG_VOBSUB_DEMUXER
    AVFormatContext *sub_ctx;
116
    FFDemuxSubtitlesQueue q[32];
Clément Bœsch's avatar
Clément Bœsch committed
117
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
118 119
} MpegDemuxContext;

120
static int mpegps_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
121 122
{
    MpegDemuxContext *m = s->priv_data;
123
    char buffer[7];
124
    int64_t last_pos = avio_tell(s->pb);
125

Fabrice Bellard's avatar
Fabrice Bellard committed
126 127 128
    m->header_state = 0xff;
    s->ctx_flags |= AVFMTCTX_NOHEADER;

129 130 131 132 133 134
    avio_get_str(s->pb, 6, buffer, sizeof(buffer));
    if (!memcmp("IMKH", buffer, 4)) {
        m->imkh_cctv = 1;
    } else if (!memcmp("Sofdec", buffer, 6)) {
        m->sofdec = 1;
    } else
135 136
       avio_seek(s->pb, last_pos, SEEK_SET);

Fabrice Bellard's avatar
Fabrice Bellard committed
137 138 139 140
    /* no need to do more */
    return 0;
}

141
static int64_t get_pts(AVIOContext *pb, int c)
Fabrice Bellard's avatar
Fabrice Bellard committed
142
{
143 144
    uint8_t buf[5];

145 146
    buf[0] = c<0 ? avio_r8(pb) : c;
    avio_read(pb, buf+1, 4);
147 148

    return ff_parse_pes_pts(buf);
Fabrice Bellard's avatar
Fabrice Bellard committed
149 150
}

151
static int find_next_start_code(AVIOContext *pb, int *size_ptr,
152
                                int32_t *header_state)
Fabrice Bellard's avatar
Fabrice Bellard committed
153 154 155 156 157 158 159 160 161
{
    unsigned int state, v;
    int val, n;

    state = *header_state;
    n = *size_ptr;
    while (n > 0) {
        if (url_feof(pb))
            break;
162
        v = avio_r8(pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
        n--;
        if (state == 0x000001) {
            state = ((state << 8) | v) & 0xffffff;
            val = state;
            goto found;
        }
        state = ((state << 8) | v) & 0xffffff;
    }
    val = -1;
 found:
    *header_state = state;
    *size_ptr = n;
    return val;
}

178
/**
179
 * Extract stream types from a program stream map
180
 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
181
 *
182 183
 * @return number of bytes occupied by PSM in the bitstream
 */
184
static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb)
185 186 187
{
    int psm_length, ps_info_length, es_map_length;

188 189 190 191
    psm_length = avio_rb16(pb);
    avio_r8(pb);
    avio_r8(pb);
    ps_info_length = avio_rb16(pb);
192 193

    /* skip program_stream_info */
194
    avio_skip(pb, ps_info_length);
195
    es_map_length = avio_rb16(pb);
196 197
    /* Ignore es_map_length, trust psm_length */
    es_map_length = psm_length - ps_info_length - 10;
198 199 200

    /* at least one es available? */
    while (es_map_length >= 4){
201 202 203
        unsigned char type      = avio_r8(pb);
        unsigned char es_id     = avio_r8(pb);
        uint16_t es_info_length = avio_rb16(pb);
204 205 206
        /* remember mapping from stream id to stream type */
        m->psm_es_type[es_id] = type;
        /* skip program_stream_info */
207
        avio_skip(pb, es_info_length);
208 209
        es_map_length -= 4 + es_info_length;
    }
210
    avio_rb32(pb); /* crc32 */
211 212 213
    return 2 + psm_length;
}

214
/* read the next PES header. Return its position in ppos
Fabrice Bellard's avatar
Fabrice Bellard committed
215 216 217
   (if not NULL), and its start code, pts and dts.
 */
static int mpegps_read_pes_header(AVFormatContext *s,
218
                                  int64_t *ppos, int *pstart_code,
219
                                  int64_t *ppts, int64_t *pdts)
Fabrice Bellard's avatar
Fabrice Bellard committed
220 221
{
    MpegDemuxContext *m = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
222
    int len, size, startcode, c, flags, header_len;
223
    int pes_ext, ext2_len, id_ext, skip;
224
    int64_t pts, dts;
225
    int64_t last_sync= avio_tell(s->pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
226

227
 error_redo:
228
        avio_seek(s->pb, last_sync, SEEK_SET);
Fabrice Bellard's avatar
Fabrice Bellard committed
229
 redo:
Fabrice Bellard's avatar
Fabrice Bellard committed
230 231 232
        /* next start code (should be immediately after) */
        m->header_state = 0xff;
        size = MAX_SYNC_SIZE;
233
        startcode = find_next_start_code(s->pb, &size, &m->header_state);
234
        last_sync = avio_tell(s->pb);
235 236 237 238 239 240 241
    if (startcode < 0){
        if(url_feof(s->pb))
            return AVERROR_EOF;
        //FIXME we should remember header_state
        return AVERROR(EAGAIN);
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
242 243 244 245
    if (startcode == PACK_START_CODE)
        goto redo;
    if (startcode == SYSTEM_HEADER_START_CODE)
        goto redo;
246
    if (startcode == PADDING_STREAM) {
247
        avio_skip(s->pb, avio_rb16(s->pb));
248 249 250 251
        goto redo;
    }
    if (startcode == PRIVATE_STREAM_2) {
        if (!m->sofdec) {
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
            /* Need to detect whether this from a DVD or a 'Sofdec' stream */
            int len = avio_rb16(s->pb);
            int bytesread = 0;
            uint8_t *ps2buf = av_malloc(len);

            if (ps2buf) {
                bytesread = avio_read(s->pb, ps2buf, len);

                if (bytesread != len) {
                    avio_skip(s->pb, len - bytesread);
                } else {
                    uint8_t *p = 0;
                    if (len >= 6)
                        p = memchr(ps2buf, 'S', len - 5);

                    if (p)
                        m->sofdec = !memcmp(p+1, "ofdec", 5);

                    m->sofdec -= !m->sofdec;

                    if (m->sofdec < 0) {
                        if (len == 980  && ps2buf[0] == 0) {
                            /* PCI structure? */
                            uint32_t startpts = AV_RB32(ps2buf + 0x0d);
                            uint32_t endpts = AV_RB32(ps2buf + 0x11);
                            uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
                            uint8_t mins  = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
                            uint8_t secs  = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);

                            m->dvd = (hours <= 23 &&
                                      mins  <= 59 &&
                                      secs  <= 59 &&
                                      (ps2buf[0x19] & 0x0f) < 10 &&
                                      (ps2buf[0x1a] & 0x0f) < 10 &&
                                      (ps2buf[0x1b] & 0x0f) < 10 &&
                                      endpts >= startpts);
                        } else if (len == 1018 && ps2buf[0] == 1) {
                            /* DSI structure? */
                            uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
                            uint8_t mins  = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
                            uint8_t secs  = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);

                            m->dvd = (hours <= 23 &&
                                      mins  <= 59 &&
                                      secs  <= 59 &&
                                      (ps2buf[0x1d] & 0x0f) < 10 &&
                                      (ps2buf[0x1e] & 0x0f) < 10 &&
                                      (ps2buf[0x1f] & 0x0f) < 10);
                        }
                    }
302
                }
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320

                av_free(ps2buf);

                /* If this isn't a DVD packet or no memory
                 * could be allocated, just ignore it.
                 * If we did, move back to the start of the
                 * packet (plus 'length' field) */
                if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) {
                    /* Skip back failed.
                     * This packet will be lost but that can't be helped
                     * if we can't skip back
                     */
                    goto redo;
                }
            } else {
                /* No memory */
                avio_skip(s->pb, len);
                goto redo;
321
            }
322 323 324 325
        } else if (!m->dvd) {
            int len = avio_rb16(s->pb);
            avio_skip(s->pb, len);
            goto redo;
326
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
327
    }
328
    if (startcode == PROGRAM_STREAM_MAP) {
329
        mpegps_psm_parse(m, s->pb);
330 331
        goto redo;
    }
332

Fabrice Bellard's avatar
Fabrice Bellard committed
333 334 335
    /* find matching stream */
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
336 337 338
          (startcode == 0x1bd) ||
          (startcode == PRIVATE_STREAM_2) ||
          (startcode == 0x1fd)))
Fabrice Bellard's avatar
Fabrice Bellard committed
339
        goto redo;
Fabrice Bellard's avatar
Fabrice Bellard committed
340
    if (ppos) {
341
        *ppos = avio_tell(s->pb) - 4;
Fabrice Bellard's avatar
Fabrice Bellard committed
342
    }
343
    len = avio_rb16(s->pb);
Michael Niedermayer's avatar
Michael Niedermayer committed
344
    pts =
345
    dts = AV_NOPTS_VALUE;
346 347
    if (startcode != PRIVATE_STREAM_2)
    {
Fabrice Bellard's avatar
Fabrice Bellard committed
348 349
    /* stuffing */
    for(;;) {
Fabrice Bellard's avatar
Fabrice Bellard committed
350
        if (len < 1)
351
            goto error_redo;
352
        c = avio_r8(s->pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
353 354
        len--;
        /* XXX: for mpeg1, should test only bit 7 */
355
        if (c != 0xff)
Fabrice Bellard's avatar
Fabrice Bellard committed
356 357 358 359
            break;
    }
    if ((c & 0xc0) == 0x40) {
        /* buffer scale & size */
360 361
        avio_r8(s->pb);
        c = avio_r8(s->pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
362 363
        len -= 2;
    }
364
    if ((c & 0xe0) == 0x20) {
365
        dts = pts = get_pts(s->pb, c);
Fabrice Bellard's avatar
Fabrice Bellard committed
366
        len -= 4;
367
        if (c & 0x10){
368
            dts = get_pts(s->pb, -1);
369 370
            len -= 5;
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
371 372
    } else if ((c & 0xc0) == 0x80) {
        /* mpeg 2 PES */
373 374
        flags = avio_r8(s->pb);
        header_len = avio_r8(s->pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
375 376
        len -= 2;
        if (header_len > len)
377
            goto error_redo;
Michael Niedermayer's avatar
Michael Niedermayer committed
378
        len -= header_len;
379
        if (flags & 0x80) {
380
            dts = pts = get_pts(s->pb, -1);
Fabrice Bellard's avatar
Fabrice Bellard committed
381
            header_len -= 5;
382
            if (flags & 0x40) {
383
                dts = get_pts(s->pb, -1);
384 385
                header_len -= 5;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
386
        }
387 388 389 390
        if (flags & 0x3f && header_len == 0){
            flags &= 0xC0;
            av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
        }
391
        if (flags & 0x01) { /* PES extension */
392
            pes_ext = avio_r8(s->pb);
393 394 395 396
            header_len--;
            /* Skip PES private data, program packet sequence counter and P-STD buffer */
            skip = (pes_ext >> 4) & 0xb;
            skip += skip & 0x9;
397 398 399 400
            if (pes_ext & 0x40 || skip > header_len){
                av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext);
                pes_ext=skip=0;
            }
401
            avio_skip(s->pb, skip);
402 403 404
            header_len -= skip;

            if (pes_ext & 0x01) { /* PES extension 2 */
405
                ext2_len = avio_r8(s->pb);
406 407
                header_len--;
                if ((ext2_len & 0x7f) > 0) {
408
                    id_ext = avio_r8(s->pb);
409 410 411 412 413 414
                    if ((id_ext & 0x80) == 0)
                        startcode = ((startcode & 0xff) << 8) | id_ext;
                    header_len--;
                }
            }
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
415 416
        if(header_len < 0)
            goto error_redo;
417
        avio_skip(s->pb, header_len);
Fabrice Bellard's avatar
Fabrice Bellard committed
418
    }
419 420
    else if( c!= 0xf )
        goto redo;
421
    }
422

423
    if (startcode == PRIVATE_STREAM_1) {
424
        startcode = avio_r8(s->pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
425 426
        len--;
    }
427 428
    if(len<0)
        goto error_redo;
429 430 431
    if(dts != AV_NOPTS_VALUE && ppos){
        int i;
        for(i=0; i<s->nb_streams; i++){
432
            if(startcode == s->streams[i]->id &&
433
               s->pb->seekable /* index useless on streams anyway */) {
434
                ff_reduce_index(s, i);
435
                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
436 437 438
            }
        }
    }
439

Fabrice Bellard's avatar
Fabrice Bellard committed
440 441 442 443 444 445 446 447 448
    *pstart_code = startcode;
    *ppts = pts;
    *pdts = dts;
    return len;
}

static int mpegps_read_packet(AVFormatContext *s,
                              AVPacket *pkt)
{
449
    MpegDemuxContext *m = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
450
    AVStream *st;
451
    int len, startcode, i, es_type, ret;
452
    int lpcm_header_len = -1; //Init to supress warning
453
    int request_probe= 0;
454
    enum AVCodecID codec_id = AV_CODEC_ID_NONE;
455
    enum AVMediaType type;
456
    int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
Fabrice Bellard's avatar
Fabrice Bellard committed
457 458

 redo:
459
    len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
Fabrice Bellard's avatar
Fabrice Bellard committed
460 461
    if (len < 0)
        return len;
462

463 464 465 466 467 468
    if (startcode >= 0x80 && startcode <= 0xcf) {
        if(len < 4)
            goto skip;

        /* audio: skip header */
        avio_r8(s->pb);
469
        lpcm_header_len = avio_rb16(s->pb);
470 471 472 473 474 475 476 477
        len -= 3;
        if (startcode >= 0xb0 && startcode <= 0xbf) {
            /* MLP/TrueHD audio has a 4-byte header */
            avio_r8(s->pb);
            len--;
        }
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
478 479 480 481 482 483
    /* now find stream */
    for(i=0;i<s->nb_streams;i++) {
        st = s->streams[i];
        if (st->id == startcode)
            goto found;
    }
484 485 486

    es_type = m->psm_es_type[startcode & 0xff];
        if(es_type == STREAM_TYPE_VIDEO_MPEG1){
487
            codec_id = AV_CODEC_ID_MPEG2VIDEO;
488
            type = AVMEDIA_TYPE_VIDEO;
489
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){
490
            codec_id = AV_CODEC_ID_MPEG2VIDEO;
491
            type = AVMEDIA_TYPE_VIDEO;
492 493
        } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||
                  es_type == STREAM_TYPE_AUDIO_MPEG2){
494
            codec_id = AV_CODEC_ID_MP3;
495
            type = AVMEDIA_TYPE_AUDIO;
496
        } else if(es_type == STREAM_TYPE_AUDIO_AAC){
497
            codec_id = AV_CODEC_ID_AAC;
498
            type = AVMEDIA_TYPE_AUDIO;
499
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
500
            codec_id = AV_CODEC_ID_MPEG4;
501
            type = AVMEDIA_TYPE_VIDEO;
502
        } else if(es_type == STREAM_TYPE_VIDEO_H264){
503
            codec_id = AV_CODEC_ID_H264;
504
            type = AVMEDIA_TYPE_VIDEO;
505
        } else if(es_type == STREAM_TYPE_AUDIO_AC3){
506
            codec_id = AV_CODEC_ID_AC3;
507
            type = AVMEDIA_TYPE_AUDIO;
508 509 510
        } else if(m->imkh_cctv && es_type == 0x91){
            codec_id = AV_CODEC_ID_PCM_MULAW;
            type = AVMEDIA_TYPE_AUDIO;
511
    } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
512 513
        static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
        unsigned char buf[8];
514
        avio_read(s->pb, buf, 8);
515
        avio_seek(s->pb, -8, SEEK_CUR);
516
        if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
517
            codec_id = AV_CODEC_ID_CAVS;
518
        else
519
            request_probe= 1;
520
        type = AVMEDIA_TYPE_VIDEO;
521 522 523
    } else if (startcode == PRIVATE_STREAM_2) {
        type = AVMEDIA_TYPE_DATA;
        codec_id = AV_CODEC_ID_DVD_NAV;
524
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
525
        type = AVMEDIA_TYPE_AUDIO;
526 527 528 529 530 531 532
        if (m->sofdec > 0) {
            codec_id = AV_CODEC_ID_ADPCM_ADX;
            // Auto-detect AC-3
            request_probe = 50;
        } else {
            codec_id = AV_CODEC_ID_MP2;
        }
533
    } else if (startcode >= 0x80 && startcode <= 0x87) {
534
        type = AVMEDIA_TYPE_AUDIO;
535
        codec_id = AV_CODEC_ID_AC3;
Michael Niedermayer's avatar
Michael Niedermayer committed
536
    } else if (  ( startcode >= 0x88 && startcode <= 0x8f)
537 538
               ||( startcode >= 0x98 && startcode <= 0x9f)) {
        /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
539
        type = AVMEDIA_TYPE_AUDIO;
540
        codec_id = AV_CODEC_ID_DTS;
541
    } else if (startcode >= 0xa0 && startcode <= 0xaf) {
542
        type = AVMEDIA_TYPE_AUDIO;
543
        if(lpcm_header_len == 6) {
544
            codec_id = AV_CODEC_ID_MLP;
545
        } else {
546
            codec_id = AV_CODEC_ID_PCM_DVD;
547
        }
548
    } else if (startcode >= 0xb0 && startcode <= 0xbf) {
549
        type = AVMEDIA_TYPE_AUDIO;
550
        codec_id = AV_CODEC_ID_TRUEHD;
551 552
    } else if (startcode >= 0xc0 && startcode <= 0xcf) {
        /* Used for both AC-3 and E-AC-3 in EVOB files */
553
        type = AVMEDIA_TYPE_AUDIO;
554
        codec_id = AV_CODEC_ID_AC3;
555
    } else if (startcode >= 0x20 && startcode <= 0x3f) {
556
        type = AVMEDIA_TYPE_SUBTITLE;
557
        codec_id = AV_CODEC_ID_DVD_SUBTITLE;
558
    } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
559
        type = AVMEDIA_TYPE_VIDEO;
560
        codec_id = AV_CODEC_ID_VC1;
561 562 563
    } else {
    skip:
        /* skip packet */
564
        avio_skip(s->pb, len);
565 566
        goto redo;
    }
567
    /* no stream found: add a new stream */
568
    st = avformat_new_stream(s, NULL);
569
    if (!st)
570
        goto skip;
571
    st->id = startcode;
572 573
    st->codec->codec_type = type;
    st->codec->codec_id = codec_id;
574 575 576 577 578
    if (st->codec->codec_id == AV_CODEC_ID_PCM_MULAW) {
        st->codec->channels = 1;
        st->codec->channel_layout = AV_CH_LAYOUT_MONO;
        st->codec->sample_rate = 8000;
    }
579
    st->request_probe     = request_probe;
580
    st->need_parsing = AVSTREAM_PARSE_FULL;
Fabrice Bellard's avatar
Fabrice Bellard committed
581
 found:
582
    if(st->discard >= AVDISCARD_ALL)
583
        goto skip;
584
    if (startcode >= 0xa0 && startcode <= 0xaf) {
585
      if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) {
586 587 588 589 590
            if (len < 6)
                goto skip;
            avio_skip(s->pb, 6);
            len -=6;
      }
591
    }
592
    ret = av_get_packet(s->pb, pkt, len);
Fabrice Bellard's avatar
Fabrice Bellard committed
593
    pkt->pts = pts;
Fabrice Bellard's avatar
Fabrice Bellard committed
594
    pkt->dts = dts;
595
    pkt->pos = dummy_pos;
596
    pkt->stream_index = st->index;
597
    av_dlog(s, "%d: pts=%0.3f dts=%0.3f size=%d\n",
598 599
            pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
            pkt->size);
600

601
    return (ret < 0) ? ret : 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
602 603
}

604
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
605
                               int64_t *ppos, int64_t pos_limit)
Fabrice Bellard's avatar
Fabrice Bellard committed
606 607 608 609 610
{
    int len, startcode;
    int64_t pos, pts, dts;

    pos = *ppos;
611
    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
612 613
        return AV_NOPTS_VALUE;

Fabrice Bellard's avatar
Fabrice Bellard committed
614
    for(;;) {
615
        len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
Fabrice Bellard's avatar
Fabrice Bellard committed
616
        if (len < 0) {
617
            av_dlog(s, "none (ret=%d)\n", len);
Fabrice Bellard's avatar
Fabrice Bellard committed
618 619
            return AV_NOPTS_VALUE;
        }
620
        if (startcode == s->streams[stream_index]->id &&
Fabrice Bellard's avatar
Fabrice Bellard committed
621 622 623
            dts != AV_NOPTS_VALUE) {
            break;
        }
624
        avio_skip(s->pb, len);
Fabrice Bellard's avatar
Fabrice Bellard committed
625
    }
626 627
    av_dlog(s, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
            pos, dts, dts / 90000.0);
Fabrice Bellard's avatar
Fabrice Bellard committed
628
    *ppos = pos;
629
    return dts;
Fabrice Bellard's avatar
Fabrice Bellard committed
630 631
}

632
AVInputFormat ff_mpegps_demuxer = {
633
    .name           = "mpeg",
634
    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),
635 636 637 638 639
    .priv_data_size = sizeof(MpegDemuxContext),
    .read_probe     = mpegps_probe,
    .read_header    = mpegps_read_header,
    .read_packet    = mpegps_read_packet,
    .read_timestamp = mpegps_read_dts,
640
    .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
Fabrice Bellard's avatar
Fabrice Bellard committed
641
};
Clément Bœsch's avatar
Clément Bœsch committed
642 643 644 645 646 647 648 649 650 651 652 653 654 655

#if CONFIG_VOBSUB_DEMUXER

#define REF_STRING "# VobSub index file,"

static int vobsub_probe(AVProbeData *p)
{
    if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int vobsub_read_header(AVFormatContext *s)
{
656
    int i, ret = 0, header_parsed = 0, langidx = 0;
Clément Bœsch's avatar
Clément Bœsch committed
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
    MpegDemuxContext *vobsub = s->priv_data;
    char *sub_name = NULL;
    size_t fname_len;
    char *ext, *header_str;
    AVBPrint header;
    int64_t delay = 0;
    AVStream *st = NULL;

    sub_name = av_strdup(s->filename);
    fname_len = strlen(sub_name);
    ext = sub_name - 3 + fname_len;
    if (fname_len < 4 || *(ext - 1) != '.') {
        av_log(s, AV_LOG_ERROR, "The input index filename is too short "
               "to guess the associated .SUB file\n");
        ret = AVERROR_INVALIDDATA;
        goto end;
    }
    memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
    av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name);
    ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name);
        goto end;
    }

    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
    while (!url_feof(s->pb)) {
        char line[2048];
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (!strncmp(line, "id:", 3)) {
            int n, stream_id = 0;
            char id[64] = {0};

            n = sscanf(line, "id: %63[^,], index: %u", id, &stream_id);
            if (n != 2) {
                av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "
                       "assuming 'id: und, index: 0'\n", line);
                strcpy(id, "und");
                stream_id = 0;
            }

704 705 706 707 708 709
            if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {
                av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");
                ret = AVERROR(EINVAL);
                goto end;
            }

Clément Bœsch's avatar
Clément Bœsch committed
710 711 712 713 714 715 716 717
            st = avformat_new_stream(s, NULL);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto end;
            }
            st->id = stream_id;
            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
            st->codec->codec_id   = AV_CODEC_ID_DVD_SUBTITLE;
718
            avpriv_set_pts_info(st, 64, 1, 1000);
Clément Bœsch's avatar
Clément Bœsch committed
719 720 721 722 723 724 725 726 727 728
            av_dict_set(&st->metadata, "language", id, 0);
            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
            header_parsed = 1;

        } else if (st && !strncmp(line, "timestamp:", 10)) {
            AVPacket *sub;
            int hh, mm, ss, ms;
            int64_t pos, timestamp;
            const char *p = line + 10;

729 730 731 732 733 734
            if (!s->nb_streams) {
                av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");
                ret = AVERROR_INVALIDDATA;
                goto end;
            }

735
            if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
Clément Bœsch's avatar
Clément Bœsch committed
736 737 738 739 740 741 742 743
                       &hh, &mm, &ss, &ms, &pos) != 5) {
                av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "
                       "abort parsing\n", line);
                break;
            }
            timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;
            timestamp = av_rescale_q(timestamp, (AVRational){1,1000}, st->time_base);

744
            sub = ff_subtitles_queue_insert(&vobsub->q[s->nb_streams - 1], "", 0, 0);
Clément Bœsch's avatar
Clément Bœsch committed
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
            if (!sub) {
                ret = AVERROR(ENOMEM);
                goto end;
            }
            sub->pos = pos;
            sub->pts = timestamp;
            sub->stream_index = s->nb_streams - 1;

        } else if (st && !strncmp(line, "alt:", 4)) {
            const char *p = line + 4;

            while (*p == ' ')
                p++;
            av_dict_set(&st->metadata, "title", p, 0);
            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", st->id, p);
            header_parsed = 1;

        } else if (!strncmp(line, "delay:", 6)) {
            int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;
            const char *p = line + 6;

            while (*p == ' ')
                p++;
            if (*p == '-' || *p == '+') {
                sign = *p == '-' ? -1 : 1;
                p++;
            }
            sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);
            delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;

        } else if (!strncmp(line, "langidx:", 8)) {
            const char *p = line + 8;

            if (sscanf(p, "%d", &langidx) != 1)
                av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");

        } else if (!header_parsed) {
            if (line[0] && line[0] != '#')
                av_bprintf(&header, "%s\n", line);
        }
    }

    if (langidx < s->nb_streams)
        s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;

790 791 792 793
    for (i = 0; i < s->nb_streams; i++) {
        vobsub->q[i].sort = SUB_SORT_POS_TS;
        ff_subtitles_queue_finalize(&vobsub->q[i]);
    }
Clément Bœsch's avatar
Clément Bœsch committed
794 795 796 797 798 799 800 801 802 803

    if (!av_bprint_is_complete(&header)) {
        av_bprint_finalize(&header, NULL);
        ret = AVERROR(ENOMEM);
        goto end;
    }
    av_bprint_finalize(&header, &header_str);
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *sub_st = s->streams[i];
        sub_st->codec->extradata      = av_strdup(header_str);
804
        sub_st->codec->extradata_size = header.len;
Clément Bœsch's avatar
Clément Bœsch committed
805 806 807 808 809 810 811 812
    }
    av_free(header_str);

end:
    av_free(sub_name);
    return ret;
}

813 814
#define FAIL(r) do { ret = r; goto fail; } while (0)

Clément Bœsch's avatar
Clément Bœsch committed
815 816 817
static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MpegDemuxContext *vobsub = s->priv_data;
818
    FFDemuxSubtitlesQueue *q;
Clément Bœsch's avatar
Clément Bœsch committed
819
    AVIOContext *pb = vobsub->sub_ctx->pb;
820
    int ret, psize, total_read = 0, i;
Clément Bœsch's avatar
Clément Bœsch committed
821 822
    AVPacket idx_pkt;

823 824 825 826 827 828 829 830 831 832 833
    int64_t min_ts = INT64_MAX;
    int sid = 0;
    for (i = 0; i < s->nb_streams; i++) {
        FFDemuxSubtitlesQueue *tmpq = &vobsub->q[i];
        int64_t ts = tmpq->subs[tmpq->current_sub_idx].pts;
        if (ts < min_ts) {
            min_ts = ts;
            sid = i;
        }
    }
    q = &vobsub->q[sid];
Clément Bœsch's avatar
Clément Bœsch committed
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
    ret = ff_subtitles_queue_read_packet(q, &idx_pkt);
    if (ret < 0)
        return ret;

    /* compute maximum packet size using the next packet position. This is
     * useful when the len in the header is non-sense */
    if (q->current_sub_idx < q->nb_subs) {
        psize = q->subs[q->current_sub_idx].pos - idx_pkt.pos;
    } else {
        int64_t fsize = avio_size(pb);
        psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos;
    }

    avio_seek(pb, idx_pkt.pos, SEEK_SET);

    av_init_packet(pkt);
    pkt->size = 0;
    pkt->data = NULL;

    do {
        int n, to_read, startcode;
        int64_t pts, dts;
856 857
        int64_t old_pos = avio_tell(pb), new_pos;
        int pkt_size;
Clément Bœsch's avatar
Clément Bœsch committed
858 859

        ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
860 861 862
        if (ret < 0) {
            if (pkt->size) // raise packet even if incomplete
                break;
863
            FAIL(ret);
864
        }
Clément Bœsch's avatar
Clément Bœsch committed
865
        to_read = ret & 0xffff;
866 867
        new_pos = avio_tell(pb);
        pkt_size = ret + (new_pos - old_pos);
Clément Bœsch's avatar
Clément Bœsch committed
868 869

        /* this prevents reads above the current packet */
870
        if (total_read + pkt_size > psize)
Clément Bœsch's avatar
Clément Bœsch committed
871
            break;
872
        total_read += pkt_size;
Clément Bœsch's avatar
Clément Bœsch committed
873 874 875 876 877 878 879

        /* the current chunk doesn't match the stream index (unlikely) */
        if ((startcode & 0x1f) != idx_pkt.stream_index)
            break;

        ret = av_grow_packet(pkt, to_read);
        if (ret < 0)
880
            FAIL(ret);
Clément Bœsch's avatar
Clément Bœsch committed
881 882 883 884

        n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
        if (n < to_read)
            pkt->size -= to_read - n;
885
    } while (total_read < psize);
Clément Bœsch's avatar
Clément Bœsch committed
886 887 888 889 890

    pkt->pts = pkt->dts = idx_pkt.pts;
    pkt->pos = idx_pkt.pos;
    pkt->stream_index = idx_pkt.stream_index;

891
    av_free_packet(&idx_pkt);
Clément Bœsch's avatar
Clément Bœsch committed
892
    return 0;
893 894

fail:
895
    av_free_packet(pkt);
896 897
    av_free_packet(&idx_pkt);
    return ret;
Clément Bœsch's avatar
Clément Bœsch committed
898 899 900 901 902 903
}

static int vobsub_read_seek(AVFormatContext *s, int stream_index,
                            int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
    MpegDemuxContext *vobsub = s->priv_data;
904 905 906 907 908

    /* Rescale requested timestamps based on the first stream (timebase is the
     * same for all subtitles stream within a .idx/.sub). Rescaling is done just
     * like in avformat_seek_file(). */
    if (stream_index == -1 && s->nb_streams != 1) {
909
        int i, ret = 0;
910 911 912 913 914 915 916 917
        AVRational time_base = s->streams[0]->time_base;
        ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
        min_ts = av_rescale_rnd(min_ts, time_base.den,
                                time_base.num * (int64_t)AV_TIME_BASE,
                                AV_ROUND_UP   | AV_ROUND_PASS_MINMAX);
        max_ts = av_rescale_rnd(max_ts, time_base.den,
                                time_base.num * (int64_t)AV_TIME_BASE,
                                AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
918 919 920 921 922 923 924
        for (i = 0; i < s->nb_streams; i++) {
            int r = ff_subtitles_queue_seek(&vobsub->q[i], s, stream_index,
                                            min_ts, ts, max_ts, flags);
            if (r < 0)
                ret = r;
        }
        return ret;
925 926
    }

927 928
    if (stream_index == -1) // only 1 stream
        stream_index = 0;
929
    return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
Clément Bœsch's avatar
Clément Bœsch committed
930 931 932 933 934
                                   min_ts, ts, max_ts, flags);
}

static int vobsub_read_close(AVFormatContext *s)
{
935
    int i;
Clément Bœsch's avatar
Clément Bœsch committed
936
    MpegDemuxContext *vobsub = s->priv_data;
937 938 939

    for (i = 0; i < s->nb_streams; i++)
        ff_subtitles_queue_clean(&vobsub->q[i]);
Clément Bœsch's avatar
Clément Bœsch committed
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
    if (vobsub->sub_ctx)
        avformat_close_input(&vobsub->sub_ctx);
    return 0;
}

AVInputFormat ff_vobsub_demuxer = {
    .name           = "vobsub",
    .long_name      = NULL_IF_CONFIG_SMALL("VobSub subtitle format"),
    .priv_data_size = sizeof(MpegDemuxContext),
    .read_probe     = vobsub_probe,
    .read_header    = vobsub_read_header,
    .read_packet    = vobsub_read_packet,
    .read_seek2     = vobsub_read_seek,
    .read_close     = vobsub_read_close,
    .flags          = AVFMT_SHOW_IDS,
    .extensions     = "idx",
};
#endif