Ticket #529: ogg_seek2.diff

File ogg_seek2.diff, 3.1 KB (added by reimar, 20 years ago)

Another version that should avoid infinite hangs in all cases.

  • libavformat/utils.c

     
    10971097 * @param timestamp new dts expressed in time_base of param ref_st
    10981098 * @param ref_st reference stream giving time_base of param timestamp
    10991099 */
    1100 static void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
     1100void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
    11011101    int i;
    11021102
    11031103    for(i = 0; i < s->nb_streams; i++) {
  • libavformat/ogg2.c

     
    201201        return AVERROR_NOMEM;
    202202
    203203    av_set_pts_info(st, 64, 1, 1000000);
    204     st->start_time = 0;
    205204
    206205    return idx;
    207206}
     
    495494
    496495    ogg->size = size;
    497496    ogg_restore (s, 0);
     497    ogg_save (s);
     498    while (ogg_read_page (s, &i)) {
     499        if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0)
     500            break;
     501    }
     502    if (i == idx) {
     503        s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule);
     504        s->streams[idx]->duration -= s->streams[idx]->start_time;
     505    }
     506    ogg_restore (s, 0);
    498507
    499508    return 0;
    500509}
     
    572581    ogg_t *ogg = s->priv_data;
    573582    ByteIOContext *bc = &s->pb;
    574583    uint64_t min = 0, max = ogg->size;
    575     uint64_t tmin = 0, tmax = st->duration;
     584    uint64_t tmin = st->start_time, tmax = st->start_time + st->duration;
    576585    int64_t pts = AV_NOPTS_VALUE;
    577586
    578587    ogg_save (s);
    579588
    580     while (min <= max){
     589    if ((uint64_t)target_ts < tmin || target_ts < 0)
     590        target_ts = tmin;
     591    while (min <= max && tmin < tmax){
    581592        uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);
    582593        int i = -1;
    583594
     
    599610            break;
    600611
    601612        if (pts > target_ts){
     613            if (max == p && tmax == pts)
     614              // probably our tmin is wrong, causing us to always end up too late in the file
     615              tmin = (target_ts + tmin) / 2;
    602616            max = p;
    603617            tmax = pts;
    604618        }else{
     619            if (min == p && tmin == pts)
     620              // probably our tmax is wrong, causing us to always end up too early in the file
     621              tmax = (target_ts + tmax) / 2;
    605622            min = p;
    606623            tmin = pts;
    607624        }
     
    615632        pts = AV_NOPTS_VALUE;
    616633    }
    617634
    618     return pts;
     635    av_update_cur_dts(s, st, pts);
     636    return 0;
    619637
    620638#if 0
    621639    //later...
  • libavformat/avformat.h

     
    472472int av_add_index_entry(AVStream *st,
    473473                       int64_t pos, int64_t timestamp, int size, int distance, int flags);
    474474int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags);
     475void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
    475476
    476477/* media file output */
    477478int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);