Ticket #12004: seek_v2.patch

File seek_v2.patch, 2.3 KB (added by Jim Stichnoth, 7 years ago)
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index e9eaad2..7a4d64a 100644
    a b void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 
    832832    }
    833833
    834834    // Skip all the desired number of skipFrames
    835     for (;skipFrames > 0 && !ateof; skipFrames--)
     835
     836    // Some seeks can be very slow.  The most common example comes
     837    // from HD-PVR recordings, where keyframes are 128 frames apart
     838    // and decoding (even hardware decoding) may not be much faster
     839    // than realtime, causing some exact seeks to take 2-4 seconds.
     840    // If exact seeking is not required, we take some shortcuts.
     841    // First, we impose an absolute maximum time we are willing to
     842    // spend (maxSeekTimeMs) on the forward frame-by-frame skip.
     843    // After that much time has elapsed, we give up and stop the
     844    // frame-by-frame seeking.  Second, after skipping a few frames,
     845    // we predict whether the situation is hopeless, i.e. the total
     846    // skipping would take longer than giveUpPredictionMs, and if so,
     847    // stop skipping right away.
     848    bool exactSeeks = !GetSeekSnap();
     849    const int maxSeekTimeMs = 200;
     850    int profileFrames = 0;
     851    QTime begin;
     852    begin.start();
     853    for (; (skipFrames > 0 && !ateof &&
     854            (exactSeeks || begin.elapsed() < maxSeekTimeMs));
     855         --skipFrames, ++profileFrames)
    836856    {
    837857        GetFrame(kDecodeVideo);
    838858        if (decoded_video_frame)
    void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 
    840860            m_parent->DiscardVideoFrame(decoded_video_frame);
    841861            decoded_video_frame = NULL;
    842862        }
     863        if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
     864        {
     865            const int giveUpPredictionMs = 400;
     866            int remainingTimeMs =
     867                skipFrames * (float)begin.elapsed() / profileFrames;
     868            if (remainingTimeMs > giveUpPredictionMs)
     869            {
     870              LOG(VB_PLAYBACK, LOG_DEBUG,
     871                  QString("Frame-by-frame seeking would take "
     872                          "%1 ms to finish, skipping.").arg(remainingTimeMs));
     873              break;
     874            }
     875        }
    843876    }
    844877
    845878    if (doflush)