Ticket #189: mythtv_timestretch7c.patch

File mythtv_timestretch7c.patch, 9.0 KB (added by Mark Spieth, 15 years ago)

simpler algo for live stretch factor revert

  • libs/libmythtv/NuppelVideoPlayer.h

     
    7474    void SetAudioSampleRate(int rate) { audio_samplerate = rate; }
    7575
    7676    void SetAudioStretchFactor(float factor) { audio_stretchfactor = factor; }
     77    float GetAudioStretchFactor() { return audio_stretchfactor; }
    7778
    7879    void Pause(bool waitvideo = true);
    7980    bool Play(float speed = 1.0, bool normal = true,
     
    8182    bool GetPause(void);
    8283    int GetFFRewSkip(void) { return ffrew_skip; }
    8384    bool AtNormalSpeed(void) { return next_normal_speed; }
     85    float GetNextPlaySpeed() { return next_play_speed; }
    8486
    8587    bool FastForward(float seconds);
    8688    bool Rewind(float seconds);
     
    212214
    213215    long long CalcMaxFFTime(long long ff);
    214216
     217    long long GetLiveTotalFrames();
     218    bool IsLiveAndNearEnd(long long framesRemaining);
     219
    215220    bool IsErrored() { return errored; }
    216221    bool InitVideo(void);
    217222    VideoFrame* GetRawVideoFrame(long long frameNumber = -1);
     
    389394    int totalLength;
    390395    long long totalFrames;
    391396
     397    long long liveTotalFrames;
    392398    OSD *osd;
    393399
    394400    bool using_null_videoout;
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    148148    next_play_speed = 1.0;
    149149    next_normal_speed = true;
    150150    videobuf_retries = 0;
     151    liveTotalFrames = -1;
    151152
    152153    using_null_videoout = disableaudio = false;
    153154
     
    309312    decoder_lock.lock();
    310313    next_play_speed = speed;
    311314    next_normal_speed = normal;
    312     if (normal)
    313         audio_stretchfactor = speed;
    314315    decoder_lock.unlock();
    315316
    316317    return true;
     
    911912            stop = framesPlayed <= keyframedist;
    912913        }
    913914        if (stop)
    914             Play(audio_stretchfactor, true, true);
     915            Play((ffrew_skip > 0)?1.0:audio_stretchfactor, true, true);
    915916    }
     917    else if ((audio_stretchfactor>1.0) && (IsLiveAndNearEnd((int)(video_frame_rate*2))))
     918    {
     919        Play(1.0, true, true);
     920    }
    916921
    917922    return true;
    918923}
     
    24672544    }
    24682545#endif
    24692546
     2547    liveTotalFrames = -1;   // force refetch of endframe, but only once for live only
    24702548    if (normal_speed && audioOutput)
    24712549    {
    2472         audioOutput->SetStretchFactor(play_speed);
     2550        audio_stretchfactor = play_speed;
     2551        audioOutput->SetStretchFactor(audio_stretchfactor);
    24732552#ifdef USING_DIRECTX
    24742553        audioOutput->Reset();
    24752554#endif
    24762555    }
    24772556
    24782557    //cout << "setting unpaused" << endl << endl;
    24792558    paused = actuallypaused = false;
     
    25312615
    25322616    if (livetv || (watchingrecording && nvr_enc && nvr_enc->IsValidRecorder()))
    25332617    {
    2534         long long behind = nvr_enc->GetFramesWritten() - framesPlayed;
     2618        long long behind = GetLiveTotalFrames() - framesPlayed;
    25352619        if (behind < maxtime) // if we're close, do nothing
    25362620            ret = 0;
    25372621        else if (behind - ff <= maxtime)
     
    25552639    return ret;
    25562640}
    25572641
     2642long long NuppelVideoPlayer::GetLiveTotalFrames()
     2643{
     2644    liveTotalFrames = nvr_enc->GetFramesWritten();
     2645    //liveTotalFramesRecordedPos = GetDecoder()->GetFramesRead();
     2646    return liveTotalFrames;
     2647}
     2648
     2649bool NuppelVideoPlayer::IsLiveAndNearEnd(long long nearEndFrameMargin)
     2650{
     2651    bool rv = false;
     2652    if (livetv || (watchingrecording && nvr_enc && nvr_enc->IsValidRecorder()))
     2653    {
     2654        // low DB access method
     2655        long long liveTotalFramesRecordedPos = GetDecoder()->GetFramesRead();
     2656        long long estFramesToEnd = liveTotalFrames - liveTotalFramesRecordedPos;
     2657        nearEndFrameMargin = (long long)(nearEndFrameMargin * audio_stretchfactor);
     2658        if (estFramesToEnd < nearEndFrameMargin)
     2659        {
     2660            // last known pos is updated as it was exceeded
     2661            GetLiveTotalFrames();
     2662            estFramesToEnd = liveTotalFrames - liveTotalFramesRecordedPos;
     2663        }
     2664        if (estFramesToEnd < nearEndFrameMargin)
     2665        {
     2666            rv = true;
     2667        }
     2668#if 0
     2669        int loopcount=0;
     2670        long long rem;
     2671        long long rem1=-1;
     2672        long long framesRead = GetDecoder()->GetFramesRead();
     2673        long long localLiveTotalFrames=liveTotalFrames;
     2674        long long localLiveTotalFramesRecordedPos = liveTotalFramesRecordedPos;
     2675        if (localLiveTotalFrames < 0)
     2676            loopcount++;
     2677        do
     2678        {
     2679            if (localLiveTotalFrames < 0)
     2680            {
     2681                localLiveTotalFrames = GetLiveTotalFrames();
     2682                localLiveTotalFramesRecordedPos = liveTotalFramesRecordedPos;
     2683                framesRead = GetDecoder()->GetFramesRead();
     2684            }
     2685            rem = localLiveTotalFrames - framesRead +
     2686                    (long long)((framesRead-localLiveTotalFramesRecordedPos)/play_speed);
     2687            if ((rem1>=0) && (rem > (rem1+3)))
     2688            {
     2689                // skipping so is getting near end
     2690                rv = true;
     2691                break;
     2692            }
     2693            rv = (rem < framesRemaining);
     2694            if (!rv)
     2695                break;
     2696            localLiveTotalFrames = -1;   // force refetch of endframe, but only once
     2697            loopcount++;
     2698            rem1 = rem;
     2699        } while (loopcount<2);
     2700#endif
     2701#if 0
     2702        VERBOSE(VB_PLAYBACK, QString("tot %1 fp %2 rem %3 ltfrp %4 lc %5")
     2703                .arg(framesRead + (long long)((framesRead-localLiveTotalFramesRecordedPos)/play_speed))
     2704                .arg(framesRead)
     2705                .arg(rem)
     2706                .arg(localLiveTotalFramesRecordedPos)
     2707                .arg(loopcount)
     2708               );
     2709#endif
     2710    }
     2711    return rv;
     2712}
     2713
    25582714bool NuppelVideoPlayer::DoFastForward(void)
    25592715{
    25602716    long long number = fftime - 1;
     
    25972753    if ((livetv) ||
    25982754        (watchingrecording && nvr_enc && nvr_enc->IsValidRecorder()))
    25992755    {
    2600         if (nvr_enc->GetFramesWritten() < (framesPlayed + frames))
     2756        if (GetLiveTotalFrames() < (framesPlayed + frames))
    26012757            return 1;
    26022758    }
    26032759    else if ((totalFrames) && (totalFrames < (framesPlayed + frames)))
     
    37383894        (watchingrecording && nvr_enc &&
    37393895         nvr_enc->IsValidRecorder()))
    37403896    {
    3741         spos = 1000.0 * framesPlayed / nvr_enc->GetFramesWritten();
     3897        spos = 1000.0 * framesPlayed / GetLiveTotalFrames();
    37423898    }
    37433899    else if (totalFrames)
    37443900    {
     
    37533909    if (!nvr_enc)
    37543910        return 0;
    37553911
    3756     long long written = nvr_enc->GetFramesWritten();
     3912    long long written = GetLiveTotalFrames();
    37573913    long long played = framesPlayed;
    37583914
    37593915    if (played > written)
     
    37763932              ((float)ringBuffer->GetFileSize() - ringBuffer->GetSmudgeSize());
    37773933        ret *= 1000.0;
    37783934
    3779         long long written = nvr_enc->GetFramesWritten();
     3935        long long written = GetLiveTotalFrames();
    37803936        long long played = framesPlayed;
    37813937
    37823938        if (played > written)
     
    38433999    int playbackLen;
    38444000    if (watchingrecording && nvr_enc && nvr_enc->IsValidRecorder())
    38454001        playbackLen =
    3846             (int)(((float)nvr_enc->GetFramesWritten() / video_frame_rate));
     4002            (int)(((float)GetLiveTotalFrames() / video_frame_rate));
    38474003    else
    38484004        playbackLen = totalLength;
    38494005
  • libs/libmythtv/tv_play.cpp

     
    13401340        }
    13411341
    13421342        if ((doing_ff_rew || speed_index) &&
    1343             activenvp->AtNormalSpeed())
     1343            activenvp && activenvp->AtNormalSpeed())
    13441344        {
    13451345            speed_index = 0;
    13461346            doing_ff_rew = 0;
    13471347            ff_rew_index = kInitFFRWSpeed;
    1348             UpdatePosOSD(0.0, tr("Play"));
     1348            UpdatePosOSD(0.0, PlayMesg());
    13491349        }
    13501350
     1351        if (activenvp && (activenvp->GetNextPlaySpeed() != normal_speed) &&
     1352            activenvp->AtNormalSpeed())
     1353        {
     1354            normal_speed = 1.0;     // got changed in nvp due to close to end of file
     1355            UpdatePosOSD(0.0, PlayMesg());
     1356        }
     1357
    13511358        if (++updatecheck >= 20)
    13521359        {
    13531360            OSDSet *oset;
     
    25012508    {
    25022509        case  2: speed = 3.0;      mesg = QString(tr("Speed 3X"));    break;
    25032510        case  1: speed = 2.0;      mesg = QString(tr("Speed 2X"));    break;
    2504         case  0: speed = 1.0;      mesg = QString(tr("Play"));        break;
     2511        case  0: speed = 1.0;      mesg = PlayMesg();                 break;
    25052512        case -1: speed = 1.0 / 3;  mesg = QString(tr("Speed 1/3X"));  break;
    25062513        case -2: speed = 1.0 / 8;  mesg = QString(tr("Speed 1/8X"));  break;
    25072514        case -3: speed = 1.0 / 16; mesg = QString(tr("Speed 1/16X")); break;
     
    25092516        default: speed_index = old_speed; return; break;
    25102517    }
    25112518
    2512     if (!activenvp->Play(speed, (speed == 1.0)))
     2519    if (!activenvp->Play((speed_index==0)?normal_speed:speed, speed_index==0))
    25132520    {
    25142521        speed_index = old_speed;
    25152522        return;