Ticket #5628: NuppelVideoPlayer.cpp.diff
File NuppelVideoPlayer.cpp.diff, 6.4 KB (added by , 16 years ago) |
---|
-
NuppelVideoPlayer.cpp
173 173 rewindtime(0), m_recusage(inUseID), 174 174 // Input Video Attributes 175 175 video_disp_dim(0,0), video_dim(0,0), 176 video_frame_rate(2 9.97f), video_aspect(4.0f / 3.0f),176 video_frame_rate(25.00f), video_aspect(4.0f / 3.0f), 177 177 forced_video_aspect(-1), 178 178 m_scan(kScan_Interlaced), m_scan_locked(false), 179 179 m_scan_tracker(0), … … 238 238 decoder_lock(true), 239 239 next_play_speed(1.0f), next_normal_speed(true), 240 240 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), 242 242 // Audio and video synchronization stuff 243 243 videosync(NULL), delay(0), 244 244 vsynctol(30/4), avsync_delay(0), 245 245 avsync_adjustment(0), avsync_avg(0), 246 246 avsync_oldavg(0), refreshrate(0), 247 lastsync(false),m_playing_slower(false),247 m_playing_slower(false), 248 248 m_stored_audio_stretchfactor(1.0), 249 249 audio_paused(false), 250 250 // Audio warping stuff … … 263 263 hidedvdbutton(true), need_change_dvd_track(0), 264 264 dvd_stillframe_showing(false), 265 265 // Debugging variables 266 output_jmeter(NULL) 266 output_jmeter(NULL), 267 isFixingDiverge(false) 267 268 { 268 269 vbimode = VBIMode::Parse(gContext->GetSetting("VbiFormat")); 269 270 … … 2208 2209 #define WARPAVLEN (video_frame_rate * 600) 2209 2210 /** How much we allow the warp to deviate from 1.0 (normal speed). */ 2210 2211 #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 2213 2216 /** A/V divergence above this amount is clipped to avoid a bad stream 2214 2217 * causing large playback glitches. */ 2215 #define DIVERGELIMIT 30.0f2218 #define DIVERGELIMIT 500.0f 2216 2219 2217 2220 float NuppelVideoPlayer::WarpFactor(void) 2218 2221 { … … 2224 2227 2225 2228 // Number of frames the audio is out by 2226 2229 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 } 2227 2239 // Number of frames divergence is changing by per frame 2228 2240 rate = (float)(avsync_avg - avsync_oldavg) / (float)frame_interval; 2229 2241 avsync_oldavg = avsync_avg; … … 2304 2316 void NuppelVideoPlayer::AVSync(void) 2305 2317 { 2306 2318 float diverge = 0.0f; 2319 float maxdiverge = 0.0f; 2307 2320 2308 2321 VideoFrame *buffer = videoOutput->GetLastShownFrame(); 2309 2322 if (!buffer) … … 2323 2336 if (normal_speed) 2324 2337 { 2325 2338 diverge = WarpFactor(); 2326 // If we are WAY out of sync, we can't really adjust this much2327 // so just adjust by DIVERGELIMIT and hope lip-sync remains.2328 diverge = max(diverge, -DIVERGELIMIT);2329 diverge = min(diverge, +DIVERGELIMIT);2330 2339 } 2331 2340 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 2332 2358 FrameScanType ps = m_scan; 2333 2359 if (kScan_Detect == m_scan || kScan_Ignore == m_scan) 2334 2360 ps = kScan_Progressive; 2335 2361 2336 if (diverge < - MAXDIVERGE)2362 if (diverge < -maxdiverge) 2337 2363 { 2338 2364 // If video is way behind of audio, adjust for it... 2339 2365 QString dbg = QString("Video is %1 frames behind audio (too slow), ") 2340 2366 .arg(-diverge); 2341 2367 2342 // Reset A/V Sync2343 lastsync = true;2344 2345 2368 if (buffer && !using_null_videoout && 2346 2369 (videoOutput->hasMCAcceleration() || 2347 2370 videoOutput->hasIDCTAcceleration() || … … 2428 2451 videosync->AdvanceTrigger(); 2429 2452 avsync_adjustment = 0; 2430 2453 2431 if (diverge > MAXDIVERGE)2454 if (diverge > maxdiverge) 2432 2455 { 2433 2456 // If audio is way behind of video, adjust for it... 2434 2457 // by cutting the frame rate in half for the length of this frame 2435 2458 2436 2459 avsync_adjustment = frame_interval; 2437 lastsync = true;2438 2460 VERBOSE(VB_PLAYBACK, LOC + 2439 2461 QString("Video is %1 frames ahead of audio,\n" 2440 2462 "\t\t\tdoubling video frame interval to slow down.").arg(diverge)); … … 2477 2499 // prevents major jitter when pts resets during dvd title 2478 2500 if (avsync_delay > 2000000 && ringBuffer->isDVD()) 2479 2501 avsync_delay = 90000; 2502 if (avsync_avg = 0) 2503 avsync_avg = avsync_delay; 2480 2504 avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4; 2481 if (!usevideotimebase)2482 {2483 /* If the audio time codes and video diverge, shift2484 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 else2500 lastsync = false;2501 }2502 2505 } 2503 2506 else 2504 2507 { … … 2780 2783 avsync_avg = 0; 2781 2784 avsync_oldavg = 0; 2782 2785 refreshrate = 0; 2783 lastsync = false;2784 2786 2785 2787 usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0); 2786 2788