Ticket #7759: t7759_repeat_pict_v3.diff
File t7759_repeat_pict_v3.diff, 5.8 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.cpp
207 207 lastsync(false), m_playing_slower(false), 208 208 m_stored_audio_stretchfactor(1.0), 209 209 audio_paused(false), 210 repeat_delay(0), 210 211 // Audio warping stuff 211 212 usevideotimebase(false), 212 213 warpfactor(1.0f), warpfactor_avg(1.0f), 213 214 warplbuff(NULL), warprbuff(NULL), 214 215 warpbuffsize(0), 215 216 // Time Code stuff 216 prevtc(0), 217 prevtc(0), prevrp(0), 217 218 tc_avcheck_framecounter(0), tc_diff_estimate(0), 218 219 savedAudioTimecodeOffset(0), 219 220 // LiveTVChain stuff … … 2322 2323 2323 2324 avsync_adjustment = 0; 2324 2325 2326 repeat_delay = 0; 2327 2325 2328 if (usevideotimebase) 2326 2329 { 2327 2330 warpfactor_avg = gContext->GetNumSetting("WarpFactor", 0); … … 2404 2407 if (kScan_Detect == m_scan || kScan_Ignore == m_scan) 2405 2408 ps = kScan_Progressive; 2406 2409 2410 bool dropframe = false; 2407 2411 if (diverge < -MAXDIVERGE) 2408 2412 { 2413 dropframe = true; 2409 2414 // If video is way behind of audio, adjust for it... 2410 2415 QString dbg = QString("Video is %1 frames behind audio (too slow), ") 2411 2416 .arg(-diverge); … … 2439 2444 2440 2445 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2") 2441 2446 .arg(avsync_adjustment).arg(m_double_framerate)); 2442 videosync->WaitForFrame(avsync_adjustment );2447 videosync->WaitForFrame(avsync_adjustment + repeat_delay); 2443 2448 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 2444 2449 if (!resetvideo) 2445 2450 videoOutput->Show(ps); … … 2491 2496 videoOutput->Show(ps); 2492 2497 } 2493 2498 } 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)); 2494 2505 } 2495 2506 else 2496 2507 { … … 2505 2516 .arg(warpfactor).arg(warpfactor_avg)); 2506 2517 } 2507 2518 2508 videosync->AdvanceTrigger(); 2519 if (!dropframe) 2520 videosync->AdvanceTrigger(); 2509 2521 avsync_adjustment = 0; 2510 2522 2511 2523 if (diverge > MAXDIVERGE) … … 2551 2563 2552 2564 // If the timecode is off by a frame (dropped frame) wait to sync 2553 2565 if (delta > (int) frame_interval / 1200 && 2554 delta < (int) frame_interval / 1000 * 3) 2566 delta < (int) frame_interval / 1000 * 3 && 2567 prevrp == 0) 2555 2568 { 2556 2569 //cerr << "+ "; 2557 2570 videosync->AdvanceTrigger(); 2558 2571 if (m_double_framerate) 2559 2572 videosync->AdvanceTrigger(); 2560 2573 } 2574 prevrp = buffer->repeat_pict; 2561 2575 2562 2576 avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec 2563 2577 // prevents major jitter when pts resets during dvd title -
libs/libmythtv/NuppelVideoPlayer.h
790 790 bool decode_extra_audio; 791 791 float m_stored_audio_stretchfactor; 792 792 bool audio_paused; 793 int repeat_delay; 793 794 794 795 // Audio warping stuff 795 796 bool usevideotimebase; … … 801 802 802 803 // Time Code stuff 803 804 int prevtc; ///< 32 bit timecode if last VideoFrame shown 805 int prevrp; ///< repeat_pict of last frame 804 806 int tc_avcheck_framecounter; 805 807 long long tc_wrap[TCTYPESMAX]; 806 808 long long tc_lastval[TCTYPESMAX]; -
libs/libmythtv/vsync.cpp
187 187 /** \fn VideoSync::CalcDelay() 188 188 * \brief Calculates the delay to the next frame. 189 189 * 190 * Regardless of the timing method, if delay is greater than twofull190 * Regardless of the timing method, if delay is greater than four full 191 191 * frames (could be greater than 20 or greater than 200), we don't want 192 192 * to freeze while waiting for a huge delay. Instead, contine playing 193 193 * video at half speed and continue to read new audio and video frames 194 194 * 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. 195 197 */ 196 198 int VideoSync::CalcDelay() 197 199 { … … 205 207 206 208 //cout << "delay " << ret_val << endl; 207 209 208 if (ret_val > m_frame_interval * 2)210 if (ret_val > m_frame_interval * 4) 209 211 { 210 212 if (m_interlaced) 211 ret_val = m_frame_interval; // same as / 2 * 2.213 ret_val = (m_frame_interval / 2) * 4; 212 214 else 213 ret_val = m_frame_interval * 2;215 ret_val = m_frame_interval * 4; 214 216 215 217 // set nexttrigger to our new target time 216 218 m_nexttrigger.tv_sec = now.tv_sec; … … 218 220 OffsetTimeval(m_nexttrigger, ret_val); 219 221 } 220 222 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 221 233 return ret_val; 222 234 } 223 235 … … 681 693 // If late, draw the frame ASAP. If early, hold the CPU until 682 694 // half as late as the previous frame (fudge). 683 695 m_delay = CalcDelay(); 696 m_fudge = min(m_fudge, m_frame_interval); 684 697 while (m_delay + m_fudge > 0) 685 698 { 686 699 m_delay = CalcDelay();