Revision e3d1cd8e

View differences:

libavformat/mpeg.c
91 91
#define DTS_ID   0x8a
92 92
#define LPCM_ID  0xa0
93 93

  
94
#define STREAM_TYPE_VIDEO_MPEG1     0x01
95
#define STREAM_TYPE_VIDEO_MPEG2     0x02
96
#define STREAM_TYPE_AUDIO_MPEG1     0x03
97
#define STREAM_TYPE_AUDIO_MPEG2     0x04
98
#define STREAM_TYPE_PRIVATE_SECTION 0x05
99
#define STREAM_TYPE_PRIVATE_DATA    0x06
100
#define STREAM_TYPE_AUDIO_AAC       0x0f
101
#define STREAM_TYPE_VIDEO_MPEG4     0x10
102
#define STREAM_TYPE_VIDEO_H264      0x1b
103

  
104
#define STREAM_TYPE_AUDIO_AC3       0x81
105
#define STREAM_TYPE_AUDIO_DTS       0x8a
106

  
94 107
static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
95 108

  
96 109
#ifdef CONFIG_ENCODERS
......
1268 1281

  
1269 1282
typedef struct MpegDemuxContext {
1270 1283
    int header_state;
1284
    unsigned char psm_es_type[256];
1271 1285
} MpegDemuxContext;
1272 1286

  
1273 1287
static int mpegps_read_header(AVFormatContext *s,
......
1358 1372
}
1359 1373
#endif
1360 1374

  
1375
/**
1376
 * Extracts stream types from a program stream map
1377
 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
1378
 * 
1379
 * @return number of bytes occupied by PSM in the bitstream
1380
 */
1381
static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb)
1382
{
1383
    int psm_length, ps_info_length, es_map_length;
1384

  
1385
    psm_length = get_be16(pb);
1386
    get_byte(pb);
1387
    get_byte(pb);
1388
    ps_info_length = get_be16(pb);
1389

  
1390
    /* skip program_stream_info */
1391
    url_fskip(pb, ps_info_length);
1392
    es_map_length = get_be16(pb);
1393

  
1394
    /* at least one es available? */
1395
    while (es_map_length >= 4){
1396
        unsigned char type = get_byte(pb);
1397
        unsigned char es_id = get_byte(pb);
1398
        uint16_t es_info_length = get_be16(pb);
1399
        /* remember mapping from stream id to stream type */
1400
        m->psm_es_type[es_id] = type;
1401
        /* skip program_stream_info */
1402
        url_fskip(pb, es_info_length);
1403
        es_map_length -= 4 + es_info_length;
1404
    }
1405
    get_be32(pb); /* crc32 */
1406
    return 2 + psm_length;
1407
}
1408

  
1361 1409
/* read the next PES header. Return its position in ppos 
1362 1410
   (if not NULL), and its start code, pts and dts.
1363 1411
 */
......
1389 1437
        url_fskip(&s->pb, len);
1390 1438
        goto redo;
1391 1439
    }
1440
    if (startcode == PROGRAM_STREAM_MAP) {
1441
        mpegps_psm_parse(m, &s->pb);
1442
        goto redo;
1443
    }
1444
    
1392 1445
    /* find matching stream */
1393 1446
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
1394 1447
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
......
1463 1516
    else if( c!= 0xf )
1464 1517
        goto redo;
1465 1518

  
1466
    if (startcode == 0x1bd) {
1519
    if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
1467 1520
        if (len < 1)
1468 1521
            goto redo;
1469 1522
        startcode = get_byte(&s->pb);
......
1496 1549
static int mpegps_read_packet(AVFormatContext *s,
1497 1550
                              AVPacket *pkt)
1498 1551
{
1552
    MpegDemuxContext *m = s->priv_data;
1499 1553
    AVStream *st;
1500
    int len, startcode, i, type, codec_id = 0;
1554
    int len, startcode, i, type, codec_id = 0, es_type;
1501 1555
    int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
1502 1556

  
1503 1557
 redo:
......
1511 1565
        if (st->id == startcode)
1512 1566
            goto found;
1513 1567
    }
1514
    if (startcode >= 0x1e0 && startcode <= 0x1ef) {
1568

  
1569
    es_type = m->psm_es_type[startcode & 0xff];
1570
    if(es_type > 0){
1571
        if(es_type == STREAM_TYPE_VIDEO_MPEG1){
1572
            codec_id = CODEC_ID_MPEG2VIDEO;
1573
            type = CODEC_TYPE_VIDEO;
1574
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){
1575
            codec_id = CODEC_ID_MPEG2VIDEO;
1576
            type = CODEC_TYPE_VIDEO;
1577
        } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||
1578
                  es_type == STREAM_TYPE_AUDIO_MPEG2){
1579
            codec_id = CODEC_ID_MP3;
1580
            type = CODEC_TYPE_AUDIO;
1581
        } else if(es_type == STREAM_TYPE_AUDIO_AAC){
1582
            codec_id = CODEC_ID_AAC;
1583
            type = CODEC_TYPE_AUDIO;
1584
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
1585
            codec_id = CODEC_ID_MPEG4;
1586
            type = CODEC_TYPE_VIDEO;
1587
        } else if(es_type == STREAM_TYPE_VIDEO_H264){
1588
            codec_id = CODEC_ID_H264;
1589
            type = CODEC_TYPE_VIDEO;
1590
        } else if(es_type == STREAM_TYPE_AUDIO_AC3){
1591
            codec_id = CODEC_ID_AC3;
1592
            type = CODEC_TYPE_AUDIO;
1593
        } else {
1594
            goto skip;
1595
        }
1596
    } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
1515 1597
        type = CODEC_TYPE_VIDEO;
1516 1598
        codec_id = CODEC_ID_MPEG2VIDEO;
1517 1599
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {

Also available in: Unified diff