Ticket #7759: t7759_repeat_pict_v3.diff

File t7759_repeat_pict_v3.diff, 5.8 KB (added by taylor.ralph@…, 2 years ago)

final update (trunk 23210)

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    207207      lastsync(false),              m_playing_slower(false), 
    208208      m_stored_audio_stretchfactor(1.0), 
    209209      audio_paused(false), 
     210      repeat_delay(0), 
    210211      // Audio warping stuff 
    211212      usevideotimebase(false), 
    212213      warpfactor(1.0f),             warpfactor_avg(1.0f), 
    213214      warplbuff(NULL),              warprbuff(NULL), 
    214215      warpbuffsize(0), 
    215216      // Time Code stuff 
    216       prevtc(0), 
     217      prevtc(0),                    prevrp(0), 
    217218      tc_avcheck_framecounter(0),   tc_diff_estimate(0), 
    218219      savedAudioTimecodeOffset(0), 
    219220      // LiveTVChain stuff 
     
    23222323 
    23232324    avsync_adjustment = 0; 
    23242325 
     2326    repeat_delay = 0; 
     2327 
    23252328    if (usevideotimebase) 
    23262329    { 
    23272330        warpfactor_avg = gContext->GetNumSetting("WarpFactor", 0); 
     
    24042407    if (kScan_Detect == m_scan || kScan_Ignore == m_scan) 
    24052408        ps = kScan_Progressive; 
    24062409 
     2410    bool dropframe = false; 
    24072411    if (diverge < -MAXDIVERGE) 
    24082412    { 
     2413        dropframe = true; 
    24092414        // If video is way behind of audio, adjust for it... 
    24102415        QString dbg = QString("Video is %1 frames behind audio (too slow), ") 
    24112416            .arg(-diverge); 
     
    24392444 
    24402445        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2") 
    24412446                .arg(avsync_adjustment).arg(m_double_framerate)); 
    2442         videosync->WaitForFrame(avsync_adjustment); 
     2447        videosync->WaitForFrame(avsync_adjustment + repeat_delay); 
    24432448        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 
    24442449        if (!resetvideo) 
    24452450            videoOutput->Show(ps); 
     
    24912496                videoOutput->Show(ps); 
    24922497            } 
    24932498        } 
     2499 
     2500        repeat_delay = frame_interval * buffer->repeat_pict * 0.5; 
     2501 
     2502        if (repeat_delay) 
     2503            VERBOSE(VB_TIMESTAMP, QString("A/V repeat_pict, adding %1 repeat " 
     2504                    "delay").arg(repeat_delay)); 
    24942505    } 
    24952506    else 
    24962507    { 
     
    25052516                .arg(warpfactor).arg(warpfactor_avg)); 
    25062517    } 
    25072518 
    2508     videosync->AdvanceTrigger(); 
     2519    if (!dropframe) 
     2520        videosync->AdvanceTrigger(); 
    25092521    avsync_adjustment = 0; 
    25102522 
    25112523    if (diverge > MAXDIVERGE) 
     
    25512563 
    25522564            // If the timecode is off by a frame (dropped frame) wait to sync 
    25532565            if (delta > (int) frame_interval / 1200 && 
    2554                 delta < (int) frame_interval / 1000 * 3) 
     2566                delta < (int) frame_interval / 1000 * 3 && 
     2567                prevrp == 0) 
    25552568            { 
    25562569                //cerr << "+ "; 
    25572570                videosync->AdvanceTrigger(); 
    25582571                if (m_double_framerate) 
    25592572                    videosync->AdvanceTrigger(); 
    25602573            } 
     2574            prevrp = buffer->repeat_pict; 
    25612575 
    25622576            avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec 
    25632577            // prevents major jitter when pts resets during dvd title 
  • libs/libmythtv/NuppelVideoPlayer.h

     
    790790    bool       decode_extra_audio; 
    791791    float      m_stored_audio_stretchfactor; 
    792792    bool       audio_paused; 
     793    int        repeat_delay; 
    793794 
    794795    // Audio warping stuff 
    795796    bool       usevideotimebase; 
     
    801802  
    802803    // Time Code stuff 
    803804    int        prevtc;        ///< 32 bit timecode if last VideoFrame shown 
     805    int        prevrp;        ///< repeat_pict of last frame 
    804806    int        tc_avcheck_framecounter; 
    805807    long long  tc_wrap[TCTYPESMAX]; 
    806808    long long  tc_lastval[TCTYPESMAX]; 
  • 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_frame_interval); 
    684697        while (m_delay + m_fudge > 0) 
    685698        { 
    686699            m_delay = CalcDelay();