Ticket #5628: NuppelVideoPlayer.cpp.diff

File NuppelVideoPlayer.cpp.diff, 6.4 KB (added by anonymous, 16 years ago)
  • NuppelVideoPlayer.cpp

     
    173173      rewindtime(0),                m_recusage(inUseID),
    174174      // Input Video Attributes
    175175      video_disp_dim(0,0), video_dim(0,0),
    176       video_frame_rate(29.97f), video_aspect(4.0f / 3.0f),
     176      video_frame_rate(25.00f), video_aspect(4.0f / 3.0f),
    177177      forced_video_aspect(-1),
    178178      m_scan(kScan_Interlaced),     m_scan_locked(false),
    179179      m_scan_tracker(0),
     
    238238      decoder_lock(true),
    239239      next_play_speed(1.0f),        next_normal_speed(true),
    240240      play_speed(1.0f),             normal_speed(true),
    241       frame_interval((int)(1000000.0f / 30)), ffrew_skip(1),
     241      frame_interval((int)(1000000.0f / 25)), ffrew_skip(1),
    242242      // Audio and video synchronization stuff
    243243      videosync(NULL),              delay(0),
    244244      vsynctol(30/4),               avsync_delay(0),
    245245      avsync_adjustment(0),         avsync_avg(0),
    246246      avsync_oldavg(0),             refreshrate(0),
    247       lastsync(false),              m_playing_slower(false),
     247      m_playing_slower(false),
    248248      m_stored_audio_stretchfactor(1.0),
    249249      audio_paused(false),
    250250      // Audio warping stuff
     
    263263      hidedvdbutton(true), need_change_dvd_track(0),
    264264      dvd_stillframe_showing(false),
    265265      // Debugging variables
    266       output_jmeter(NULL)
     266      output_jmeter(NULL),
     267      isFixingDiverge(false)
    267268{
    268269    vbimode = VBIMode::Parse(gContext->GetSetting("VbiFormat"));
    269270
     
    22082209#define WARPAVLEN (video_frame_rate * 600)
    22092210/** How much we allow the warp to deviate from 1.0 (normal speed). */
    22102211#define WARPCLIP    0.1f
    2211 /** Number of frames of A/V divergence allowed adjustments are made. */
    2212 #define MAXDIVERGE  3.0f
     2212/** Number of frames of A/V divergence allowed before adjustments are made. */
     2213#define MAXDIVERGE  0.5f
     2214/** Number of frames of A/V divergence when adjustment stops. */
     2215#define MAXDIVERGELOW  0.05f
    22132216/** A/V divergence above this amount is clipped to avoid a bad stream
    22142217 *  causing large playback glitches. */
    2215 #define DIVERGELIMIT 30.0f
     2218#define DIVERGELIMIT 500.0f
    22162219
    22172220float NuppelVideoPlayer::WarpFactor(void)
    22182221{
     
    22242227
    22252228    // Number of frames the audio is out by
    22262229    divergence = (float)avsync_avg / (float)frame_interval;
     2230
     2231    // When skipping audio is reset to 0 causing massive
     2232    // divergence.  If divergence is greater than DIVERGELIMIT
     2233    // then ignore the divergence.  It will eventually correct
     2234    // itself
     2235    if ((divergence > DIVERGELIMIT) || (divergence < -DIVERGELIMIT)) {
     2236        divergence = 0;
     2237        return divergence;
     2238    }
    22272239    // Number of frames divergence is changing by per frame
    22282240    rate = (float)(avsync_avg - avsync_oldavg) / (float)frame_interval;
    22292241    avsync_oldavg = avsync_avg;
     
    23042316void NuppelVideoPlayer::AVSync(void)
    23052317{
    23062318    float diverge = 0.0f;
     2319    float maxdiverge = 0.0f;
    23072320
    23082321    VideoFrame *buffer = videoOutput->GetLastShownFrame();
    23092322    if (!buffer)
     
    23232336    if (normal_speed)
    23242337    {
    23252338        diverge = WarpFactor();
    2326         // If we are WAY out of sync, we can't really adjust this much
    2327         // so just adjust by DIVERGELIMIT and hope lip-sync remains.
    2328         diverge = max(diverge, -DIVERGELIMIT);
    2329         diverge = min(diverge, +DIVERGELIMIT);
    23302339    }
    23312340
     2341    // If we are outside MAXDIVERGE then activate correction
     2342    // Keep correcting until MAXDIVERGELOW is reached
     2343    // If A/V diverge is drifting this allows a longer
     2344    // time between corrections (and thus less jitter on screen)
     2345    //
     2346    if ((diverge < -MAXDIVERGE) || (diverge > MAXDIVERGE)) {
     2347        isFixingDiverge=true;
     2348    } else if (((diverge > -MAXDIVERGELOW) && (diverge <= 0)) || ((diverge < MAXDIVERGELOW) && (diverge >= 0))) {
     2349        isFixingDiverge=false;
     2350    }
     2351   
     2352    if (isFixingDiverge) {
     2353        maxdiverge=MAXDIVERGELOW;
     2354    } else {
     2355        maxdiverge=MAXDIVERGE;
     2356    }
     2357   
    23322358    FrameScanType ps = m_scan;
    23332359    if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
    23342360        ps = kScan_Progressive;
    23352361
    2336     if (diverge < -MAXDIVERGE)
     2362    if (diverge < -maxdiverge)
    23372363    {
    23382364        // If video is way behind of audio, adjust for it...
    23392365        QString dbg = QString("Video is %1 frames behind audio (too slow), ")
    23402366            .arg(-diverge);
    23412367
    2342         // Reset A/V Sync
    2343         lastsync = true;
    2344  
    23452368        if (buffer && !using_null_videoout &&
    23462369            (videoOutput->hasMCAcceleration()   ||
    23472370             videoOutput->hasIDCTAcceleration() ||
     
    24282451    videosync->AdvanceTrigger();
    24292452    avsync_adjustment = 0;
    24302453
    2431     if (diverge > MAXDIVERGE)
     2454    if (diverge > maxdiverge)
    24322455    {
    24332456        // If audio is way behind of video, adjust for it...
    24342457        // by cutting the frame rate in half for the length of this frame
    24352458
    24362459        avsync_adjustment = frame_interval;
    2437         lastsync = true;
    24382460        VERBOSE(VB_PLAYBACK, LOC +
    24392461                QString("Video is %1 frames ahead of audio,\n"
    24402462                        "\t\t\tdoubling video frame interval to slow down.").arg(diverge));
     
    24772499            // prevents major jitter when pts resets during dvd title
    24782500            if (avsync_delay > 2000000 && ringBuffer->isDVD())
    24792501                avsync_delay = 90000;
     2502            if (avsync_avg = 0)
     2503                avsync_avg = avsync_delay;
    24802504            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
    2481             if (!usevideotimebase)
    2482             {
    2483                 /* If the audio time codes and video diverge, shift
    2484                    the video by one interlaced field (1/2 frame) */
    2485 
    2486                 if (!lastsync)
    2487                 {
    2488                     if (avsync_avg > frame_interval * 3 / 2)
    2489                     {
    2490                         avsync_adjustment = refreshrate;
    2491                         lastsync = true;
    2492                     }
    2493                     else if (avsync_avg < 0 - frame_interval * 3 / 2)
    2494                     {
    2495                         avsync_adjustment = -refreshrate;
    2496                         lastsync = true;
    2497                     }
    2498                 }
    2499                 else
    2500                     lastsync = false;
    2501             }
    25022505        }
    25032506        else
    25042507        {
     
    27802783    avsync_avg = 0;
    27812784    avsync_oldavg = 0;
    27822785    refreshrate = 0;
    2783     lastsync = false;
    27842786
    27852787    usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0);
    27862788