mpeg.c 26.1 KB
Newer Older
F
Fabrice Bellard 已提交
1
/*
2
 * MPEG1/2 demuxer
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
F
Fabrice Bellard 已提交
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
F
Fabrice Bellard 已提交
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.
F
Fabrice Bellard 已提交
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
F
Fabrice Bellard 已提交
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
F
Fabrice Bellard 已提交
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
F
Fabrice Bellard 已提交
16
 *
F
Fabrice Bellard 已提交
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
F
Fabrice Bellard 已提交
20
 */
21

F
Fabrice Bellard 已提交
22
#include "avformat.h"
23
#include "internal.h"
24
#include "mpeg.h"
F
Fabrice Bellard 已提交
25

C
Clément Bœsch 已提交
26 27 28 29 30
#if CONFIG_VOBSUB_DEMUXER
# include "subtitles.h"
# include "libavutil/bprint.h"
#endif

31 32 33
#undef NDEBUG
#include <assert.h>

F
Fabrice Bellard 已提交
34 35 36 37 38
/*********************************************/
/* demux code */

#define MAX_SYNC_SIZE 100000

39
static int check_pes(const uint8_t *p, const uint8_t *end){
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    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;
}

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

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

68 69
    for(i=0; i<p->buf_size; i++){
        code = (code<<8) + p->buf[i];
70
        if ((code & 0xffffff00) == 0x100) {
71
            int len= p->buf[i+1] << 8 | p->buf[i+2];
M
typo  
Michael Niedermayer 已提交
72
            int pes= check_pes(p->buf+i, p->buf+p->buf_size);
73
            int pack = check_pack_header(p->buf+i);
74

75
            if(code == SYSTEM_HEADER_START_CODE) sys++;
76
            else if(code == PACK_START_CODE && pack) pspack++;
M
Michael Niedermayer 已提交
77
            else if((code & 0xf0) == VIDEO_ID &&  pes) vid++;
78 79 80 81
            // 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;}
82
            else if(code == 0x1fd             &&  pes) vid++; //VC1
83 84 85

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

90
    if(vid+audio > invalid+1)     /* invalid VDR files nd short PES streams */
91 92
        score= AVPROBE_SCORE_MAX/4;

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

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


F
Fabrice Bellard 已提交
107
typedef struct MpegDemuxContext {
M
Måns Rullgård 已提交
108
    int32_t header_state;
109
    unsigned char psm_es_type[256];
110
    int sofdec;
C
Clément Bœsch 已提交
111 112 113 114
#if CONFIG_VOBSUB_DEMUXER
    AVFormatContext *sub_ctx;
    FFDemuxSubtitlesQueue q;
#endif
F
Fabrice Bellard 已提交
115 116
} MpegDemuxContext;

117
static int mpegps_read_header(AVFormatContext *s)
F
Fabrice Bellard 已提交
118 119
{
    MpegDemuxContext *m = s->priv_data;
M
Måns Rullgård 已提交
120 121
    const char *sofdec = "Sofdec";
    int v, i = 0;
122
    int64_t last_pos = avio_tell(s->pb);
123

F
Fabrice Bellard 已提交
124 125 126
    m->header_state = 0xff;
    s->ctx_flags |= AVFMTCTX_NOHEADER;

M
Måns Rullgård 已提交
127 128
    m->sofdec = -1;
    do {
129
        v = avio_r8(s->pb);
M
Måns Rullgård 已提交
130 131
        m->sofdec++;
    } while (v == sofdec[i] && i++ < 6);
132

133 134
    m->sofdec = (m->sofdec == 6) ? 1 : 0;

135 136 137
    if (!m->sofdec)
       avio_seek(s->pb, last_pos, SEEK_SET);

F
Fabrice Bellard 已提交
138 139 140 141
    /* no need to do more */
    return 0;
}

142
static int64_t get_pts(AVIOContext *pb, int c)
F
Fabrice Bellard 已提交
143
{
144 145
    uint8_t buf[5];

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

    return ff_parse_pes_pts(buf);
F
Fabrice Bellard 已提交
150 151
}

152
static int find_next_start_code(AVIOContext *pb, int *size_ptr,
M
Måns Rullgård 已提交
153
                                int32_t *header_state)
F
Fabrice Bellard 已提交
154 155 156 157 158 159 160 161 162
{
    unsigned int state, v;
    int val, n;

    state = *header_state;
    n = *size_ptr;
    while (n > 0) {
        if (url_feof(pb))
            break;
163
        v = avio_r8(pb);
F
Fabrice Bellard 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
        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;
}

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

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

    /* skip program_stream_info */
195
    avio_skip(pb, ps_info_length);
196
    es_map_length = avio_rb16(pb);
197 198 199

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

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

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

F
Fabrice Bellard 已提交
241 242 243 244
    if (startcode == PACK_START_CODE)
        goto redo;
    if (startcode == SYSTEM_HEADER_START_CODE)
        goto redo;
M
Måns Rullgård 已提交
245
    if (startcode == PADDING_STREAM) {
246
        avio_skip(s->pb, avio_rb16(s->pb));
M
Måns Rullgård 已提交
247 248 249
        goto redo;
    }
    if (startcode == PRIVATE_STREAM_2) {
250
        len = avio_rb16(s->pb);
M
Måns Rullgård 已提交
251 252
        if (!m->sofdec) {
            while (len-- >= 6) {
253
                if (avio_r8(s->pb) == 'S') {
M
Måns Rullgård 已提交
254
                    uint8_t buf[5];
255
                    avio_read(s->pb, buf, sizeof(buf));
M
Måns Rullgård 已提交
256 257 258 259 260 261 262
                    m->sofdec = !memcmp(buf, "ofdec", 5);
                    len -= sizeof(buf);
                    break;
                }
            }
            m->sofdec -= !m->sofdec;
        }
263
        avio_skip(s->pb, len);
F
Fabrice Bellard 已提交
264 265
        goto redo;
    }
266
    if (startcode == PROGRAM_STREAM_MAP) {
267
        mpegps_psm_parse(m, s->pb);
268 269
        goto redo;
    }
270

F
Fabrice Bellard 已提交
271 272 273
    /* find matching stream */
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
274
          (startcode == 0x1bd) || (startcode == 0x1fd)))
F
Fabrice Bellard 已提交
275
        goto redo;
F
Fabrice Bellard 已提交
276
    if (ppos) {
277
        *ppos = avio_tell(s->pb) - 4;
F
Fabrice Bellard 已提交
278
    }
279
    len = avio_rb16(s->pb);
M
Michael Niedermayer 已提交
280
    pts =
281
    dts = AV_NOPTS_VALUE;
F
Fabrice Bellard 已提交
282 283
    /* stuffing */
    for(;;) {
F
Fabrice Bellard 已提交
284
        if (len < 1)
285
            goto error_redo;
286
        c = avio_r8(s->pb);
F
Fabrice Bellard 已提交
287 288
        len--;
        /* XXX: for mpeg1, should test only bit 7 */
289
        if (c != 0xff)
F
Fabrice Bellard 已提交
290 291 292 293
            break;
    }
    if ((c & 0xc0) == 0x40) {
        /* buffer scale & size */
294 295
        avio_r8(s->pb);
        c = avio_r8(s->pb);
F
Fabrice Bellard 已提交
296 297
        len -= 2;
    }
M
Michael Niedermayer 已提交
298
    if ((c & 0xe0) == 0x20) {
299
        dts = pts = get_pts(s->pb, c);
F
Fabrice Bellard 已提交
300
        len -= 4;
M
Michael Niedermayer 已提交
301
        if (c & 0x10){
302
            dts = get_pts(s->pb, -1);
M
Michael Niedermayer 已提交
303 304
            len -= 5;
        }
F
Fabrice Bellard 已提交
305 306
    } else if ((c & 0xc0) == 0x80) {
        /* mpeg 2 PES */
307 308
        flags = avio_r8(s->pb);
        header_len = avio_r8(s->pb);
F
Fabrice Bellard 已提交
309 310
        len -= 2;
        if (header_len > len)
311
            goto error_redo;
M
Michael Niedermayer 已提交
312
        len -= header_len;
M
Michael Niedermayer 已提交
313
        if (flags & 0x80) {
314
            dts = pts = get_pts(s->pb, -1);
F
Fabrice Bellard 已提交
315
            header_len -= 5;
M
Michael Niedermayer 已提交
316
            if (flags & 0x40) {
317
                dts = get_pts(s->pb, -1);
M
Michael Niedermayer 已提交
318 319
                header_len -= 5;
            }
F
Fabrice Bellard 已提交
320
        }
321 322 323 324
        if (flags & 0x3f && header_len == 0){
            flags &= 0xC0;
            av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
        }
325
        if (flags & 0x01) { /* PES extension */
326
            pes_ext = avio_r8(s->pb);
327 328 329 330
            header_len--;
            /* Skip PES private data, program packet sequence counter and P-STD buffer */
            skip = (pes_ext >> 4) & 0xb;
            skip += skip & 0x9;
331 332 333 334
            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;
            }
335
            avio_skip(s->pb, skip);
336 337 338
            header_len -= skip;

            if (pes_ext & 0x01) { /* PES extension 2 */
339
                ext2_len = avio_r8(s->pb);
340 341
                header_len--;
                if ((ext2_len & 0x7f) > 0) {
342
                    id_ext = avio_r8(s->pb);
343 344 345 346 347 348
                    if ((id_ext & 0x80) == 0)
                        startcode = ((startcode & 0xff) << 8) | id_ext;
                    header_len--;
                }
            }
        }
M
Michael Niedermayer 已提交
349 350
        if(header_len < 0)
            goto error_redo;
351
        avio_skip(s->pb, header_len);
F
Fabrice Bellard 已提交
352
    }
353 354 355
    else if( c!= 0xf )
        goto redo;

356
    if (startcode == PRIVATE_STREAM_1) {
357
        startcode = avio_r8(s->pb);
F
Fabrice Bellard 已提交
358 359
        len--;
    }
360 361
    if(len<0)
        goto error_redo;
362 363 364
    if(dts != AV_NOPTS_VALUE && ppos){
        int i;
        for(i=0; i<s->nb_streams; i++){
365
            if(startcode == s->streams[i]->id &&
366
               s->pb->seekable /* index useless on streams anyway */) {
367
                ff_reduce_index(s, i);
M
Michael Niedermayer 已提交
368
                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
369 370 371
            }
        }
    }
372

F
Fabrice Bellard 已提交
373 374 375 376 377 378 379 380 381
    *pstart_code = startcode;
    *ppts = pts;
    *pdts = dts;
    return len;
}

static int mpegps_read_packet(AVFormatContext *s,
                              AVPacket *pkt)
{
382
    MpegDemuxContext *m = s->priv_data;
F
Fabrice Bellard 已提交
383
    AVStream *st;
384
    int len, startcode, i, es_type, ret;
385
    int lpcm_header_len = -1; //Init to supress warning
386
    int request_probe= 0;
387
    enum AVCodecID codec_id = AV_CODEC_ID_NONE;
388
    enum AVMediaType type;
389
    int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
F
Fabrice Bellard 已提交
390 391

 redo:
392
    len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
F
Fabrice Bellard 已提交
393 394
    if (len < 0)
        return len;
395

396 397 398 399 400 401
    if (startcode >= 0x80 && startcode <= 0xcf) {
        if(len < 4)
            goto skip;

        /* audio: skip header */
        avio_r8(s->pb);
M
Michael Niedermayer 已提交
402
        lpcm_header_len = avio_rb16(s->pb);
403 404 405 406 407 408 409 410
        len -= 3;
        if (startcode >= 0xb0 && startcode <= 0xbf) {
            /* MLP/TrueHD audio has a 4-byte header */
            avio_r8(s->pb);
            len--;
        }
    }

F
Fabrice Bellard 已提交
411 412 413 414 415 416
    /* now find stream */
    for(i=0;i<s->nb_streams;i++) {
        st = s->streams[i];
        if (st->id == startcode)
            goto found;
    }
417 418 419

    es_type = m->psm_es_type[startcode & 0xff];
        if(es_type == STREAM_TYPE_VIDEO_MPEG1){
420
            codec_id = AV_CODEC_ID_MPEG2VIDEO;
421
            type = AVMEDIA_TYPE_VIDEO;
422
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){
423
            codec_id = AV_CODEC_ID_MPEG2VIDEO;
424
            type = AVMEDIA_TYPE_VIDEO;
425 426
        } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||
                  es_type == STREAM_TYPE_AUDIO_MPEG2){
427
            codec_id = AV_CODEC_ID_MP3;
428
            type = AVMEDIA_TYPE_AUDIO;
429
        } else if(es_type == STREAM_TYPE_AUDIO_AAC){
430
            codec_id = AV_CODEC_ID_AAC;
431
            type = AVMEDIA_TYPE_AUDIO;
432
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
433
            codec_id = AV_CODEC_ID_MPEG4;
434
            type = AVMEDIA_TYPE_VIDEO;
435
        } else if(es_type == STREAM_TYPE_VIDEO_H264){
436
            codec_id = AV_CODEC_ID_H264;
437
            type = AVMEDIA_TYPE_VIDEO;
438
        } else if(es_type == STREAM_TYPE_AUDIO_AC3){
439
            codec_id = AV_CODEC_ID_AC3;
440
            type = AVMEDIA_TYPE_AUDIO;
441
    } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
442 443
        static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
        unsigned char buf[8];
444
        avio_read(s->pb, buf, 8);
A
Anton Khirnov 已提交
445
        avio_seek(s->pb, -8, SEEK_CUR);
446
        if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
447
            codec_id = AV_CODEC_ID_CAVS;
448
        else
449
            request_probe= 1;
450
        type = AVMEDIA_TYPE_VIDEO;
451
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
452
        type = AVMEDIA_TYPE_AUDIO;
453
        codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2;
454
    } else if (startcode >= 0x80 && startcode <= 0x87) {
455
        type = AVMEDIA_TYPE_AUDIO;
456
        codec_id = AV_CODEC_ID_AC3;
M
Michael Niedermayer 已提交
457
    } else if (  ( startcode >= 0x88 && startcode <= 0x8f)
458 459
               ||( startcode >= 0x98 && startcode <= 0x9f)) {
        /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
460
        type = AVMEDIA_TYPE_AUDIO;
461
        codec_id = AV_CODEC_ID_DTS;
462
    } else if (startcode >= 0xa0 && startcode <= 0xaf) {
463
        type = AVMEDIA_TYPE_AUDIO;
M
Michael Niedermayer 已提交
464
        if(lpcm_header_len == 6) {
465
            codec_id = AV_CODEC_ID_MLP;
M
Michael Niedermayer 已提交
466
        } else {
467 468
            /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
            codec_id = AV_CODEC_ID_PCM_DVD;
M
Michael Niedermayer 已提交
469
        }
470
    } else if (startcode >= 0xb0 && startcode <= 0xbf) {
471
        type = AVMEDIA_TYPE_AUDIO;
472
        codec_id = AV_CODEC_ID_TRUEHD;
473 474
    } else if (startcode >= 0xc0 && startcode <= 0xcf) {
        /* Used for both AC-3 and E-AC-3 in EVOB files */
475
        type = AVMEDIA_TYPE_AUDIO;
476
        codec_id = AV_CODEC_ID_AC3;
477
    } else if (startcode >= 0x20 && startcode <= 0x3f) {
478
        type = AVMEDIA_TYPE_SUBTITLE;
479
        codec_id = AV_CODEC_ID_DVD_SUBTITLE;
480
    } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
481
        type = AVMEDIA_TYPE_VIDEO;
482
        codec_id = AV_CODEC_ID_VC1;
483 484 485
    } else {
    skip:
        /* skip packet */
486
        avio_skip(s->pb, len);
487 488
        goto redo;
    }
489
    /* no stream found: add a new stream */
490
    st = avformat_new_stream(s, NULL);
491
    if (!st)
492
        goto skip;
493
    st->id = startcode;
494 495
    st->codec->codec_type = type;
    st->codec->codec_id = codec_id;
496
    st->request_probe     = request_probe;
497
    if (codec_id != AV_CODEC_ID_PCM_S16BE)
A
Aurelien Jacobs 已提交
498
        st->need_parsing = AVSTREAM_PARSE_FULL;
F
Fabrice Bellard 已提交
499
 found:
500
    if(st->discard >= AVDISCARD_ALL)
501
        goto skip;
502
    if (startcode >= 0xa0 && startcode <= 0xaf) {
503
      if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) {
M
Michael Niedermayer 已提交
504 505 506 507 508
            if (len < 6)
                goto skip;
            avio_skip(s->pb, 6);
            len -=6;
      } else {
509 510 511 512 513 514
        int b1, freq;

        /* for LPCM, we just skip the header and consider it is raw
           audio data */
        if (len <= 3)
            goto skip;
515 516 517
        avio_r8(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
        b1 = avio_r8(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
        avio_r8(s->pb); /* dynamic range control (0x80 = off) */
518 519
        len -= 3;
        freq = (b1 >> 4) & 3;
520 521
        st->codec->sample_rate = lpcm_freq_tab[freq];
        st->codec->channels = 1 + (b1 & 7);
522
        st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4;
523 524
        st->codec->bit_rate = st->codec->channels *
                              st->codec->sample_rate *
525 526
                              st->codec->bits_per_coded_sample;
        if (st->codec->bits_per_coded_sample == 16)
527
            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
528
        else if (st->codec->bits_per_coded_sample == 28)
529
            return AVERROR(EINVAL);
M
Michael Niedermayer 已提交
530
      }
531
    }
532
    ret = av_get_packet(s->pb, pkt, len);
F
Fabrice Bellard 已提交
533
    pkt->pts = pts;
F
Fabrice Bellard 已提交
534
    pkt->dts = dts;
535
    pkt->pos = dummy_pos;
536
    pkt->stream_index = st->index;
537
    av_dlog(s, "%d: pts=%0.3f dts=%0.3f size=%d\n",
538 539
            pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
            pkt->size);
540

541
    return (ret < 0) ? ret : 0;
F
Fabrice Bellard 已提交
542 543
}

544
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
545
                               int64_t *ppos, int64_t pos_limit)
F
Fabrice Bellard 已提交
546 547 548 549 550
{
    int len, startcode;
    int64_t pos, pts, dts;

    pos = *ppos;
A
Anton Khirnov 已提交
551
    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
552 553
        return AV_NOPTS_VALUE;

F
Fabrice Bellard 已提交
554
    for(;;) {
555
        len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
F
Fabrice Bellard 已提交
556
        if (len < 0) {
557
            av_dlog(s, "none (ret=%d)\n", len);
F
Fabrice Bellard 已提交
558 559
            return AV_NOPTS_VALUE;
        }
560
        if (startcode == s->streams[stream_index]->id &&
F
Fabrice Bellard 已提交
561 562 563
            dts != AV_NOPTS_VALUE) {
            break;
        }
564
        avio_skip(s->pb, len);
F
Fabrice Bellard 已提交
565
    }
566 567
    av_dlog(s, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
            pos, dts, dts / 90000.0);
F
Fabrice Bellard 已提交
568
    *ppos = pos;
569
    return dts;
F
Fabrice Bellard 已提交
570 571
}

572
AVInputFormat ff_mpegps_demuxer = {
573
    .name           = "mpeg",
574
    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),
575 576 577 578 579
    .priv_data_size = sizeof(MpegDemuxContext),
    .read_probe     = mpegps_probe,
    .read_header    = mpegps_read_header,
    .read_packet    = mpegps_read_packet,
    .read_timestamp = mpegps_read_dts,
580
    .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
F
Fabrice Bellard 已提交
581
};
C
Clément Bœsch 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594 595

#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)
{
596
    int i, ret = 0, header_parsed = 0, langidx = 0;
C
Clément Bœsch 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 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 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
    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;
            }

            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;
            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;

            if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"PRIx64,
                       &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);

            sub = ff_subtitles_queue_insert(&vobsub->q, "", 0, 0);
            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;

    ff_subtitles_queue_finalize(&vobsub->q);

    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);
728
        sub_st->codec->extradata_size = header.len;
C
Clément Bœsch 已提交
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 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 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
    }
    av_free(header_str);

end:
    av_free(sub_name);
    return ret;
}

static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MpegDemuxContext *vobsub = s->priv_data;
    FFDemuxSubtitlesQueue *q = &vobsub->q;
    AVIOContext *pb = vobsub->sub_ctx->pb;
    int ret, psize, len16 = -1;
    AVPacket idx_pkt;

    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;

        ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
        if (ret < 0)
            return ret;
        to_read = ret & 0xffff;

        /* this prevents reads above the current packet */
        if (pkt->size + to_read > psize)
            break;

        /* if the len is computed, we check for overread */
        if (len16 != -1 && pkt->size + to_read > len16)
            break;

        /* 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)
            return ret;

        n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
        if (n < to_read)
            pkt->size -= to_read - n;

        /* first chunk contains the total len of the packet to raise */
        if (len16 == -1 && n > 2)
            len16 = AV_RB16(pkt->data);
    } while (len16 != -1 && pkt->size != len16);

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

    return 0;
}

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;
    return ff_subtitles_queue_seek(&vobsub->q, s, stream_index,
                                   min_ts, ts, max_ts, flags);
}

static int vobsub_read_close(AVFormatContext *s)
{
    MpegDemuxContext *vobsub = s->priv_data;
    ff_subtitles_queue_clean(&vobsub->q);
    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