Ticket #7759: t7759_repeat_pict_v1.diff

File t7759_repeat_pict_v1.diff, 5.8 KB (added by tralph11@…, 14 years ago)

Full patch including repeat_pict and AV-sync improvements

  • libs/libmythtv/NuppelVideoPlayer.h

     
    804804    bool       decode_extra_audio;
    805805    float      m_stored_audio_stretchfactor;
    806806    bool       audio_paused;
     807    int        repeat_delay;
    807808
    808809    // Audio warping stuff
    809810    bool       usevideotimebase;
     
    815816 
    816817    // Time Code stuff
    817818    int        prevtc;        ///< 32 bit timecode if last VideoFrame shown
     819    int        prevrp;        ///< repeat_pict of last frame
    818820    int        tc_avcheck_framecounter;
    819821    long long  tc_wrap[TCTYPESMAX];
    820822    long long  tc_lastval[TCTYPESMAX];
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    253253      lastsync(false),              m_playing_slower(false),
    254254      m_stored_audio_stretchfactor(1.0),
    255255      audio_paused(false),
     256      repeat_delay(0),
    256257      // Audio warping stuff
    257258      usevideotimebase(false),
    258259      warpfactor(1.0f),             warpfactor_avg(1.0f),
    259260      warplbuff(NULL),              warprbuff(NULL),
    260261      warpbuffsize(0),
    261262      // Time Code stuff
    262       prevtc(0),
     263      prevtc(0),                    prevrp(0),
    263264      tc_avcheck_framecounter(0),   tc_diff_estimate(0),
    264265      savedAudioTimecodeOffset(0),
    265266      // LiveTVChain stuff
     
    23882389
    23892390    avsync_adjustment = 0;
    23902391
     2392    repeat_delay = 0;
     2393
    23912394    if (usevideotimebase)
    23922395    {
    23932396        warpfactor_avg = gContext->GetNumSetting("WarpFactor", 0);
     
    24702473    if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
    24712474        ps = kScan_Progressive;
    24722475
     2476    bool dropframe = false;
    24732477    if (diverge < -MAXDIVERGE)
    24742478    {
     2479        dropframe = true;
    24752480        // If video is way behind of audio, adjust for it...
    24762481        QString dbg = QString("Video is %1 frames behind audio (too slow), ")
    24772482            .arg(-diverge);
     
    25052510
    25062511        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2")
    25072512                .arg(avsync_adjustment).arg(m_double_framerate));
    2508         videosync->WaitForFrame(avsync_adjustment);
     2513        videosync->WaitForFrame(avsync_adjustment + repeat_delay);
    25092514        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
    25102515        if (!resetvideo)
    25112516            videoOutput->Show(ps);
     
    25572562                videoOutput->Show(ps);
    25582563            }
    25592564        }
     2565
     2566        repeat_delay = frame_interval * buffer->repeat_pict * 0.5;
     2567
     2568        if (repeat_delay)
     2569            VERBOSE(VB_TIMESTAMP, QString("A/V repeat_pict, adding %1 repeat "
     2570                    "delay").arg(repeat_delay));
    25602571    }
    25612572    else
    25622573    {
     
    25712582                .arg(warpfactor).arg(warpfactor_avg));
    25722583    }
    25732584
    2574     videosync->AdvanceTrigger();
     2585    if (!dropframe)
     2586        videosync->AdvanceTrigger();
    25752587    avsync_adjustment = 0;
    25762588
    25772589    if (diverge > MAXDIVERGE)
     
    26152627
    26162628            // If the timecode is off by a frame (dropped frame) wait to sync
    26172629            if (delta > (int) frame_interval / 1200 &&
    2618                 delta < (int) frame_interval / 1000 * 3)
     2630                delta < (int) frame_interval / 1000 * 3 &&
     2631                prevrp == 0)
    26192632            {
    26202633                //cerr << "+ ";
    26212634                videosync->AdvanceTrigger();
    26222635                if (m_double_framerate)
    26232636                    videosync->AdvanceTrigger();
    26242637            }
     2638            prevrp = buffer->repeat_pict;
    26252639
    26262640            avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec
    26272641            // prevents major jitter when pts resets during dvd title
  • libs/libmythtv/vsync.cpp

     
    187187/** \fn VideoSync::CalcDelay()
    188188 *  \brief Calculates the delay to the next frame.
    189189 *
    190  *   Regardless of the timing method, if delay is greater than two full
     190 *   Regardless of the timing method, if delay is greater than four full
    191191 *   frames (could be greater than 20 or greater than 200), we don't want
    192192 *   to freeze while waiting for a huge delay. Instead, contine playing
    193193 *   video at half speed and continue to read new audio and video frames
    194194 *   from the file until the sync is 'in the ballpark'.
     195 *   Also prevent the nexttrigger from falling too far in the past in case
     196 *   we are trying to speed up video output faster than possible.
    195197 */
    196198int VideoSync::CalcDelay()
    197199{
     
    205207
    206208    //cout << "delay " << ret_val << endl;
    207209
    208     if (ret_val > m_frame_interval * 2)
     210    if (ret_val > m_frame_interval * 4)
    209211    {
    210212        if (m_interlaced)
    211             ret_val = m_frame_interval; // same as / 2 * 2.
     213            ret_val = (m_frame_interval / 2) * 4;
    212214        else
    213             ret_val = m_frame_interval * 2;
     215            ret_val = m_frame_interval * 4;
    214216
    215217        // set nexttrigger to our new target time
    216218        m_nexttrigger.tv_sec = now.tv_sec;
     
    218220        OffsetTimeval(m_nexttrigger, ret_val);
    219221    }
    220222
     223    if (ret_val < -m_frame_interval)
     224    {
     225        ret_val = -m_frame_interval;
     226
     227        // set nexttrigger to our new target time
     228        m_nexttrigger.tv_sec = now.tv_sec;
     229        m_nexttrigger.tv_usec = now.tv_usec;
     230        OffsetTimeval(m_nexttrigger, ret_val);
     231    }
     232
    221233    return ret_val;
    222234}
    223235
     
    681693        // If late, draw the frame ASAP.  If early, hold the CPU until
    682694        // half as late as the previous frame (fudge).
    683695        m_delay = CalcDelay();
     696        m_fudge = min(m_fudge, m_refresh_interval);
    684697        while (m_delay + m_fudge > 0)
    685698        {
    686699            m_delay = CalcDelay();