Ticket #7759: t7759_repeat_pict_v2.diff
File t7759_repeat_pict_v2.diff, 5.8 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.h
804 804 bool decode_extra_audio; 805 805 float m_stored_audio_stretchfactor; 806 806 bool audio_paused; 807 int repeat_delay; 807 808 808 809 // Audio warping stuff 809 810 bool usevideotimebase; … … 815 816 816 817 // Time Code stuff 817 818 int prevtc; ///< 32 bit timecode if last VideoFrame shown 819 int prevrp; ///< repeat_pict of last frame 818 820 int tc_avcheck_framecounter; 819 821 long long tc_wrap[TCTYPESMAX]; 820 822 long long tc_lastval[TCTYPESMAX]; -
libs/libmythtv/NuppelVideoPlayer.cpp
253 253 lastsync(false), m_playing_slower(false), 254 254 m_stored_audio_stretchfactor(1.0), 255 255 audio_paused(false), 256 repeat_delay(0), 256 257 // Audio warping stuff 257 258 usevideotimebase(false), 258 259 warpfactor(1.0f), warpfactor_avg(1.0f), 259 260 warplbuff(NULL), warprbuff(NULL), 260 261 warpbuffsize(0), 261 262 // Time Code stuff 262 prevtc(0), 263 prevtc(0), prevrp(0), 263 264 tc_avcheck_framecounter(0), tc_diff_estimate(0), 264 265 savedAudioTimecodeOffset(0), 265 266 // LiveTVChain stuff … … 2388 2389 2389 2390 avsync_adjustment = 0; 2390 2391 2392 repeat_delay = 0; 2393 2391 2394 if (usevideotimebase) 2392 2395 { 2393 2396 warpfactor_avg = gContext->GetNumSetting("WarpFactor", 0); … … 2470 2473 if (kScan_Detect == m_scan || kScan_Ignore == m_scan) 2471 2474 ps = kScan_Progressive; 2472 2475 2476 bool dropframe = false; 2473 2477 if (diverge < -MAXDIVERGE) 2474 2478 { 2479 dropframe = true; 2475 2480 // If video is way behind of audio, adjust for it... 2476 2481 QString dbg = QString("Video is %1 frames behind audio (too slow), ") 2477 2482 .arg(-diverge); … … 2505 2510 2506 2511 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2") 2507 2512 .arg(avsync_adjustment).arg(m_double_framerate)); 2508 videosync->WaitForFrame(avsync_adjustment );2513 videosync->WaitForFrame(avsync_adjustment + repeat_delay); 2509 2514 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 2510 2515 if (!resetvideo) 2511 2516 videoOutput->Show(ps); … … 2557 2562 videoOutput->Show(ps); 2558 2563 } 2559 2564 } 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)); 2560 2571 } 2561 2572 else 2562 2573 { … … 2571 2582 .arg(warpfactor).arg(warpfactor_avg)); 2572 2583 } 2573 2584 2574 videosync->AdvanceTrigger(); 2585 if (!dropframe) 2586 videosync->AdvanceTrigger(); 2575 2587 avsync_adjustment = 0; 2576 2588 2577 2589 if (diverge > MAXDIVERGE) … … 2615 2627 2616 2628 // If the timecode is off by a frame (dropped frame) wait to sync 2617 2629 if (delta > (int) frame_interval / 1200 && 2618 delta < (int) frame_interval / 1000 * 3) 2630 delta < (int) frame_interval / 1000 * 3 && 2631 prevrp == 0) 2619 2632 { 2620 2633 //cerr << "+ "; 2621 2634 videosync->AdvanceTrigger(); 2622 2635 if (m_double_framerate) 2623 2636 videosync->AdvanceTrigger(); 2624 2637 } 2638 prevrp = buffer->repeat_pict; 2625 2639 2626 2640 avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec 2627 2641 // prevents major jitter when pts resets during dvd title -
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();