Ticket #7521: t7521_avseek_fixes_rev3.diff

File t7521_avseek_fixes_rev3.diff, 3.1 KB (added by taylor.ralph@…, 10 years ago)

final update (trunk 23210)

  • libs/libmythtv/decoderbase.h

     
    9191                         int testbufsize = kDecoderProbeBufferSize) = 0;
    9292
    9393    void setExactSeeks(bool exact) { exactseeks = exact; }
     94    bool getExactSeeks(void) { return exactseeks; }
    9495    void setLiveTVMode(bool live) { livetv = live; }
    9596
    9697    // Must be done while player is paused.
  • libs/libmythtv/avformatdecoder.cpp

     
    589589    if (recordingHasPositionMap || livetv)
    590590        return DecoderBase::DoRewind(desiredFrame, discardFrames);
    591591
     592    dorewind = true;
     593
    592594    // avformat-based seeking
    593595    return DoFastForward(desiredFrame, discardFrames);
    594596}
     
    619621    if (!st)
    620622        return false;
    621623
     624    int seekDelta = desiredFrame - framesPlayed;
     625
     626    // avoid using av_frame_seek if we want to advance forward < 1 second
     627    if (seekDelta >= 0 && seekDelta < (int)(fps + 1.0f) && !dorewind)
     628    {
     629        SeekReset(framesPlayed, seekDelta, false, true);
     630        GetNVP()->SetFramesPlayed(framesPlayed + 1);
     631        GetNVP()->getVideoOutput()->SetFramesPlayed(framesPlayed + 1);
     632
     633        return true;
     634    }
     635
    622636    int64_t frameseekadjust = 0;
    623637    AVCodecContext *context = st->codec;
    624638
     
    633647    long double diff = (max(desiredFrame - frameseekadjust, 0LL)) * AV_TIME_BASE / fps;
    634648    ts += (long long)diff;
    635649
    636     if (av_seek_frame(ic, -1, ts, AVSEEK_FLAG_BACKWARD) < 0)
     650    bool exactseeks = DecoderBase::getExactSeeks();
     651
     652    int flags = 0;
     653    if (dorewind || exactseeks)
     654        flags |= AVSEEK_FLAG_BACKWARD;
     655
     656    if (av_seek_frame(ic, -1, ts, flags) < 0)
    637657    {
    638658        VERBOSE(VB_IMPORTANT, LOC_ERR
    639659                <<"av_seek_frame(ic, -1, "<<ts<<", 0) -- error");
     
    672692        framesPlayed = lastKey;
    673693        framesRead = lastKey;
    674694
    675         normalframes = desiredFrame - framesPlayed;
     695        normalframes = (exactseeks) ? desiredFrame - framesPlayed : 0;
    676696        normalframes = max(normalframes, 0);
    677697        no_dts_hack = false;
    678698    }
     
    685705        normalframes = 0;
    686706    }
    687707
    688     SeekReset(lastKey, normalframes, discardFrames, discardFrames);
     708    SeekReset(lastKey, normalframes, true, discardFrames);
    689709
    690710    if (discardFrames)
    691711    {
     
    693713        GetNVP()->getVideoOutput()->SetFramesPlayed(framesPlayed + 1);
    694714    }
    695715
     716    dorewind = false;
     717
    696718    getrawframes = oldrawstate;
    697719
    698720    return true;
  • libs/libmythtv/avformatdecoder.h

     
    220220    bool drawband;
    221221
    222222    bool no_dts_hack;
     223    bool dorewind;
    223224
    224225    bool gopset;
    225226    /// A flag to indicate that we've seen a GOP frame.  Used in junction with seq_count.