Revision a8dd8dc6 libavformat/mpegts.c

View differences:

libavformat/mpegts.c
28 28
#include "avformat.h"
29 29
#include "mpegts.h"
30 30
#include "internal.h"
31
#include "seek.h"
31 32

  
32 33
/* 1.0 second at 24Mbit/s */
33 34
#define MAX_SCAN_PACKETS 32000
......
1521 1522
    return timestamp;
1522 1523
}
1523 1524

  
1524
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
1525
    MpegTSContext *ts = s->priv_data;
1526
    uint8_t buf[TS_PACKET_SIZE];
1525
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags);
1526

  
1527
static int read_seek2(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t target_ts, int64_t max_ts, int flags)
1528
{
1527 1529
    int64_t pos;
1528 1530

  
1529
    if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
1530
        return -1;
1531
    int64_t ts_ret, ts_adj;
1532
    int stream_index_gen_search;
1533
    AVStream *st;
1534
    AVParserState *backup;
1531 1535

  
1532
    pos= url_ftell(s->pb);
1536
    backup = ff_store_parser_state(s);
1533 1537

  
1534
    for(;;) {
1535
        url_fseek(s->pb, pos, SEEK_SET);
1536
        if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
1538
    // detect direction of seeking for search purposes
1539
    flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ? AVSEEK_FLAG_BACKWARD : 0;
1540

  
1541
    if (flags & AVSEEK_FLAG_BYTE) {
1542
        /* use position directly, we will search starting from it */
1543
        pos = target_ts;
1544
    } else {
1545
        /* search for some position with good timestamp match */
1546
        if(stream_index < 0){
1547
            stream_index_gen_search = av_find_default_stream_index(s);
1548
            if (stream_index_gen_search < 0) {
1549
                ff_restore_parser_state(s, backup);
1550
                return -1;
1551
            }
1552

  
1553
            st = s->streams[stream_index_gen_search];
1554
            /* timestamp for default must be expressed in AV_TIME_BASE units */
1555
            ts_adj = av_rescale(target_ts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
1556
        } else {
1557
            ts_adj = target_ts;
1558
            stream_index_gen_search = stream_index;
1559
        }
1560
        pos = av_gen_search(s, stream_index_gen_search, ts_adj,
1561
                            0, INT64_MAX, -1,
1562
                            AV_NOPTS_VALUE,
1563
                            AV_NOPTS_VALUE,
1564
                            flags, &ts_ret, mpegts_get_pcr);
1565
        if (pos < 0) {
1566
            ff_restore_parser_state(s, backup);
1537 1567
            return -1;
1538
//        pid = AV_RB16(buf + 1) & 0x1fff;
1539
        if(buf[1] & 0x40) break;
1540
        pos += ts->raw_packet_size;
1568
        }
1541 1569
    }
1542
    url_fseek(s->pb, pos, SEEK_SET);
1543 1570

  
1571
    /* search for actual matching keyframe/starting position for all streams */
1572
    if (ff_gen_syncpoint_search(s, stream_index, pos, min_ts, target_ts, max_ts, flags) < 0) {
1573
        ff_restore_parser_state(s, backup);
1574
        return -1;
1575
    }
1576

  
1577
    ff_free_parser_state(s, backup);
1544 1578
    return 0;
1545 1579
}
1546 1580

  
1581
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
1582
{
1583
    int ret;
1584
    if (flags & AVSEEK_FLAG_BACKWARD) {
1585
        ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);
1586
        if (ret < 0) {
1587
            // for compatibility reasons, seek to best-fitting timestamp
1588
            ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags & ~AVSEEK_FLAG_BACKWARD);
1589
        }
1590
    } else {
1591
        ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags);
1592
        if (ret < 0) {
1593
            // for compatibility reasons, seek to best-fitting timestamp
1594
            ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
1595
        }
1596
    }
1597
    return ret;
1598
}
1599

  
1547 1600
/**************************************************************/
1548 1601
/* parsing functions - called from other demuxers such as RTP */
1549 1602

  
......
1608 1661
    read_seek,
1609 1662
    mpegts_get_pcr,
1610 1663
    .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
1664
    .read_seek2 = read_seek2,
1611 1665
};
1612 1666

  
1613 1667
AVInputFormat mpegtsraw_demuxer = {
......
1621 1675
    read_seek,
1622 1676
    mpegts_get_pcr,
1623 1677
    .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
1678
    .read_seek2 = read_seek2,
1624 1679
};

Also available in: Unified diff