Revision 0d02cacd libavcodec/dvbsubdec.c

View differences:

libavcodec/dvbsubdec.c
1459 1459
    dvbsub_close_decoder,
1460 1460
    dvbsub_decode,
1461 1461
};
1462

  
1463
/* Parser (mostly) copied from dvdsub.c */
1464

  
1465
#define PARSE_BUF_SIZE  (65536)
1466

  
1467

  
1468
/* parser definition */
1469
typedef struct DVBSubParseContext {
1470
    uint8_t *packet_buf;
1471
    int packet_start;
1472
    int packet_index;
1473
    int in_packet;
1474
} DVBSubParseContext;
1475

  
1476
static int dvbsub_parse_init(AVCodecParserContext *s)
1477
{
1478
    DVBSubParseContext *pc = s->priv_data;
1479
    pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
1480

  
1481
    return 0;
1482
}
1483

  
1484
static int dvbsub_parse(AVCodecParserContext *s,
1485
                        AVCodecContext *avctx,
1486
                        uint8_t **poutbuf, int *poutbuf_size,
1487
                        const uint8_t *buf, int buf_size)
1488
{
1489
    DVBSubParseContext *pc = s->priv_data;
1490
    uint8_t *p, *p_end;
1491
    int len, buf_pos = 0;
1492

  
1493
#ifdef DEBUG
1494
    av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n",
1495
            s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);
1496
#endif
1497

  
1498
#ifdef DEBUG_PACKET_CONTENTS
1499
    int i;
1500

  
1501
    for (i=0; i < buf_size; i++)
1502
    {
1503
        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
1504
        if (i % 16 == 15)
1505
            av_log(avctx, AV_LOG_INFO, "\n");
1506
    }
1507

  
1508
    if (i % 16 != 0)
1509
        av_log(avctx, AV_LOG_INFO, "\n");
1510

  
1511
#endif
1512

  
1513
    *poutbuf = NULL;
1514
    *poutbuf_size = 0;
1515

  
1516
    s->fetch_timestamp = 1;
1517

  
1518
    if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */
1519
    {
1520
        if (pc->packet_index != pc->packet_start)
1521
        {
1522
#ifdef DEBUG
1523
            av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n",
1524
                pc->packet_index - pc->packet_start);
1525
#endif
1526
        }
1527

  
1528
        pc->packet_start = 0;
1529
        pc->packet_index = 0;
1530

  
1531
        if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {
1532
#ifdef DEBUG
1533
            av_log(avctx, AV_LOG_INFO, "Bad packet header\n");
1534
#endif
1535
            return -1;
1536
        }
1537

  
1538
        buf_pos = 2;
1539

  
1540
        pc->in_packet = 1;
1541
    } else {
1542
        if (pc->packet_start != 0)
1543
        {
1544
            if (pc->packet_index != pc->packet_start)
1545
            {
1546
                memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,
1547
                            pc->packet_index - pc->packet_start);
1548

  
1549
                pc->packet_index -= pc->packet_start;
1550
                pc->packet_start = 0;
1551
            } else {
1552
                pc->packet_start = 0;
1553
                pc->packet_index = 0;
1554
            }
1555
        }
1556
    }
1557

  
1558
    if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)
1559
        return -1;
1560

  
1561
/* if not currently in a packet, discard data */
1562
    if (pc->in_packet == 0)
1563
        return buf_size;
1564

  
1565
    memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);
1566
    pc->packet_index += buf_size - buf_pos;
1567

  
1568
    p = pc->packet_buf;
1569
    p_end = pc->packet_buf + pc->packet_index;
1570

  
1571
    while (p < p_end)
1572
    {
1573
        if (*p == 0x0f)
1574
        {
1575
            if (p + 6 <= p_end)
1576
            {
1577
                len = AV_RB16(p + 4);
1578

  
1579
                if (p + len + 6 <= p_end)
1580
                {
1581
                    *poutbuf_size += len + 6;
1582

  
1583
                    p += len + 6;
1584
                } else
1585
                    break;
1586
            } else
1587
                break;
1588
        } else if (*p == 0xff) {
1589
            if (p + 1 < p_end)
1590
            {
1591
#ifdef DEBUG
1592
                av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
1593
#endif
1594
            }
1595
            pc->packet_index = p - pc->packet_buf;
1596
            pc->in_packet = 0;
1597
            break;
1598
        } else {
1599
            av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");
1600

  
1601
            pc->packet_index = p - pc->packet_buf;
1602
            pc->in_packet = 0;
1603
            break;
1604
        }
1605
    }
1606

  
1607
    if (*poutbuf_size > 0)
1608
    {
1609
        *poutbuf = pc->packet_buf;
1610
        pc->packet_start = *poutbuf_size;
1611
    }
1612

  
1613
    if (s->last_pts == AV_NOPTS_VALUE)
1614
        s->last_pts = s->pts;
1615

  
1616
    return buf_size;
1617
}
1618

  
1619
static void dvbsub_parse_close(AVCodecParserContext *s)
1620
{
1621
    DVBSubParseContext *pc = s->priv_data;
1622
    av_freep(&pc->packet_buf);
1623
}
1624

  
1625
AVCodecParser dvbsub_parser = {
1626
    { CODEC_ID_DVB_SUBTITLE },
1627
    sizeof(DVBSubParseContext),
1628
    dvbsub_parse_init,
1629
    dvbsub_parse,
1630
    dvbsub_parse_close,
1631
};

Also available in: Unified diff