Ticket #7521: avseek_fixes_rev2.diff

File avseek_fixes_rev2.diff, 3.3 KB (added by tralph11@…, 10 years ago)

skip libavf seeking if the target frame is < 1 second away

  • libs/libmythtv/avformatdecoder.h

     
    220220
    221221    bool no_dts_hack;
    222222
     223    bool dorewind;
     224
    223225    bool gopset;
    224226    /// A flag to indicate that we've seen a GOP frame.  Used in junction with seq_count.
    225227    bool seen_gop;
  • libs/libmythtv/avformatdecoder.cpp

     
    570570    if (recordingHasPositionMap || livetv)
    571571        return DecoderBase::DoRewind(desiredFrame, discardFrames);
    572572
     573    dorewind = true;
     574
    573575    // avformat-based seeking
    574576    return DoFastForward(desiredFrame, discardFrames);
    575577}
     
    587589    bool oldrawstate = getrawframes;
    588590    getrawframes = false;
    589591
     592    bool needflush = true;
     593
    590594    AVStream *st = NULL;
    591595    for (uint i = 0; i < ic->nb_streams; i++)
    592596    {
     
    600604    if (!st)
    601605        return false;
    602606
     607    int seekDelta = desiredFrame - framesPlayed;
     608
     609    // avoid using av_frame_seek if we want to advance forward < 1 second
     610    if (seekDelta >= 0 && seekDelta < (int)(fps + 1.0f))
     611    {
     612        SeekReset(framesPlayed, seekDelta, false, true);
     613        GetNVP()->SetFramesPlayed(framesPlayed + 1);
     614        GetNVP()->getVideoOutput()->SetFramesPlayed(framesPlayed + 1);
     615
     616        return true;
     617    }
     618
    603619    int64_t frameseekadjust = 0;
    604620    AVCodecContext *context = st->codec;
    605621
     
    614630    long double diff = (max(desiredFrame - frameseekadjust, 0LL)) * AV_TIME_BASE / fps;
    615631    ts += (long long)diff;
    616632
    617     if (av_seek_frame(ic, -1, ts, AVSEEK_FLAG_BACKWARD) < 0)
     633    bool exactseeks = DecoderBase::getExactSeeks();
     634
     635    int flags = 0;
     636
     637    if (dorewind || exactseeks)
     638        flags |= AVSEEK_FLAG_BACKWARD;
     639
     640    if (av_seek_frame(ic, -1, ts, flags) < 0)
    618641    {
    619642        VERBOSE(VB_IMPORTANT, LOC_ERR
    620643                <<"av_seek_frame(ic, -1, "<<ts<<", 0) -- error");
     
    653676        framesPlayed = lastKey;
    654677        framesRead = lastKey;
    655678
    656         normalframes = desiredFrame - framesPlayed;
     679        normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0;
    657680        normalframes = max(normalframes, 0);
    658681        no_dts_hack = false;
    659682    }
     
    666689        normalframes = 0;
    667690    }
    668691
    669     SeekReset(lastKey, normalframes, discardFrames, discardFrames);
     692    SeekReset(lastKey, normalframes, needflush, discardFrames);
    670693
    671694    if (discardFrames)
    672695    {
     
    674697        GetNVP()->getVideoOutput()->SetFramesPlayed(framesPlayed + 1);
    675698    }
    676699
     700    dorewind = false;
     701
    677702    getrawframes = oldrawstate;
    678703
    679704    return true;
  • libs/libmythtv/decoderbase.h

     
    6262                         int testbufsize = kDecoderProbeBufferSize) = 0;
    6363
    6464    void setExactSeeks(bool exact) { exactseeks = exact; }
     65    bool getExactSeeks(void) { return exactseeks; }
    6566    void setLiveTVMode(bool live) { livetv = live; }
    6667
    6768    // Must be done while player is paused.