Ticket #7067: mythtv.patch3

File mythtv.patch3, 13.4 KB (added by Davin McCall <davmac@…>, 16 years ago)

Updated patch, applies to current trunk (23844)/

Line 
1Index: libs/libmythtv/NuppelVideoPlayer.cpp
2===================================================================
3--- libs/libmythtv/NuppelVideoPlayer.cpp (revision 23844)
4+++ libs/libmythtv/NuppelVideoPlayer.cpp (working copy)
5@@ -26,8 +26,6 @@
6 #include <QKeyEvent>
7 #include <QDir>
8
9-#define NEW_AVSYNC
10-
11 // MythTV headers
12 #include "mythconfig.h"
13 #include "mythdbcon.h"
14@@ -957,9 +955,6 @@
15 m_double_framerate = false;
16 m_double_process = false;
17
18- if (videosync)
19- videosync->SetFrameInterval(frame_interval, false);
20-
21 if (osd)
22 osd->SetFrameInterval(frame_interval);
23
24@@ -1036,7 +1031,6 @@
25 if (interlaced && !m_deint_possible)
26 {
27 m_scan = scan;
28- videosync->SetFrameInterval(frame_interval, false);
29 return;
30 }
31
32@@ -1052,9 +1046,7 @@
33 if (videoOutput->NeedsDoubleFramerate())
34 {
35 m_double_framerate = true;
36- videosync->SetFrameInterval(frame_interval, true);
37- // Make sure video sync can double frame rate
38- m_can_double = videosync->UsesFieldInterval();
39+ m_can_double = (frame_interval / 2 > videosync->getRefreshInterval() * 0.995);
40 if (!m_can_double)
41 {
42 VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
43@@ -1071,7 +1063,6 @@
44 {
45 m_double_process = false;
46 m_double_framerate = false;
47- videosync->SetFrameInterval(frame_interval, false);
48 videoOutput->SetDeinterlacingEnabled(false);
49 VERBOSE(VB_PLAYBACK, "Disabled deinterlacing");
50 }
51@@ -2338,11 +2329,11 @@
52 void NuppelVideoPlayer::AVSync(void)
53 {
54 float diverge = 0.0f;
55+ int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;
56 // attempt to reduce fps for standalone PIP
57 if (player_ctx->IsPIP() && framesPlayed % 2)
58 {
59- videosync->WaitForFrame(avsync_adjustment);
60- videosync->AdvanceTrigger();
61+ videosync->WaitForFrame(frameDelay + avsync_adjustment);
62 if (!using_null_videoout)
63 videoOutput->SetFramesPlayed(framesPlayed + 1);
64 return;
65@@ -2354,6 +2345,7 @@
66 VERBOSE(VB_IMPORTANT, LOC_ERR + "AVSync: No video buffer");
67 return;
68 }
69+
70 if (videoOutput->IsErrored())
71 {
72 VERBOSE(VB_IMPORTANT, LOC_ERR + "AVSync: "
73@@ -2376,10 +2368,8 @@
74 if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
75 ps = kScan_Progressive;
76
77- bool dropframe = false;
78 if (diverge < -MAXDIVERGE)
79 {
80- dropframe = true;
81 // If video is way behind of audio, adjust for it...
82 QString dbg = QString("Video is %1 frames behind audio (too slow), ")
83 .arg(-diverge);
84@@ -2413,7 +2403,7 @@
85
86 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2")
87 .arg(avsync_adjustment).arg(m_double_framerate));
88- videosync->WaitForFrame(avsync_adjustment + repeat_delay);
89+ videosync->WaitForFrame(frameDelay + avsync_adjustment + repeat_delay);
90 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
91 if (!resetvideo)
92 videoOutput->Show(ps);
93@@ -2454,12 +2444,7 @@
94 videoOutput->PrepareFrame(buffer, ps);
95
96 // Display the second field
97- videosync->AdvanceTrigger();
98-#ifdef NEW_AVSYNC
99- videosync->WaitForFrame(avsync_adjustment);
100-#else
101- videosync->WaitForFrame(0);
102-#endif
103+ videosync->WaitForFrame(frameDelay + avsync_adjustment);
104 if (!resetvideo)
105 {
106 videoOutput->Show(ps);
107@@ -2474,7 +2459,7 @@
108 }
109 else
110 {
111- videosync->WaitForFrame(0);
112+ videosync->WaitForFrame(frameDelay);
113 }
114
115 if (output_jmeter && output_jmeter->RecordCycleTime())
116@@ -2485,8 +2470,6 @@
117 .arg(warpfactor).arg(warpfactor_avg));
118 }
119
120- if (!dropframe)
121- videosync->AdvanceTrigger();
122 avsync_adjustment = 0;
123
124 if (diverge > MAXDIVERGE)
125@@ -2494,11 +2477,7 @@
126 // If audio is way behind of video, adjust for it...
127 // by cutting the frame rate in half for the length of this frame
128
129-#ifdef NEW_AVSYNC
130 avsync_adjustment = refreshrate;
131-#else
132- avsync_adjustment = frame_interval;
133-#endif
134 lastsync = true;
135 VERBOSE(VB_PLAYBACK, LOC +
136 QString("Video is %1 frames ahead of audio,\n"
137@@ -2530,24 +2509,21 @@
138 prevtc = buffer->timecode;
139 //cerr << delta << " ";
140
141+ avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec
142+ // prevents major jitter when pts resets during dvd title
143+ if (avsync_delay > 2000000 && player_ctx->buffer->isDVD())
144+ avsync_delay = 90000;
145+ avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
146+
147 // If the timecode is off by a frame (dropped frame) wait to sync
148 if (delta > (int) frame_interval / 1200 &&
149 delta < (int) frame_interval / 1000 * 3 &&
150 prevrp == 0)
151 {
152- //cerr << "+ ";
153- videosync->AdvanceTrigger();
154- if (m_double_framerate)
155- videosync->AdvanceTrigger();
156+ // wait an extra frame interval
157+ avsync_adjustment = frame_interval;
158 }
159- prevrp = buffer->repeat_pict;
160
161- avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec
162- // prevents major jitter when pts resets during dvd title
163- if (avsync_delay > 2000000 && player_ctx->buffer->isDVD())
164- avsync_delay = 90000;
165- avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
166-
167 /* If the audio time codes and video diverge, shift
168 the video by one interlaced field (1/2 frame) */
169 if (!lastsync)
170@@ -2911,10 +2887,8 @@
171 // Make sure video sync can do it
172 if (videosync != NULL && m_double_framerate)
173 {
174- videosync->SetFrameInterval(frame_interval, m_double_framerate);
175- m_can_double = videosync->UsesFieldInterval();
176- if (!m_can_double)
177- {
178+ m_can_double = (frame_interval / 2 > videosync->getRefreshInterval() * 0.995);
179+ if (! m_can_double) {
180 VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
181 "framerate (refresh rate too low for bob deint)");
182 FallbackDeint();
183@@ -4216,9 +4190,6 @@
184 (frame_interval>>1) : frame_interval);
185 }
186
187- if (videosync != NULL)
188- videosync->SetFrameInterval(frame_interval, m_double_framerate);
189-
190 VERBOSE(VB_PLAYBACK, LOC + "DoPause() -- setting paused");
191 paused = actuallypaused = true;
192 decoderThreadPaused.wakeAll();
193@@ -4295,7 +4266,6 @@
194
195 m_double_framerate = videoOutput->NeedsDoubleFramerate();
196 m_double_process = videoOutput->IsExtraProcessingRequired();
197- videosync->SetFrameInterval(frame_interval, m_double_framerate);
198 }
199
200 if (osd)
201Index: libs/libmythtv/vsync.cpp
202===================================================================
203--- libs/libmythtv/vsync.cpp (revision 23844)
204+++ libs/libmythtv/vsync.cpp (working copy)
205@@ -126,12 +126,6 @@
206 m_delay(-1)
207 {
208 bzero(&m_nexttrigger, sizeof(m_nexttrigger));
209-
210- int tolerance = m_refresh_interval / 200;
211- if (m_interlaced && m_refresh_interval > ((m_frame_interval/2) + tolerance))
212- m_interlaced = false; // can't display both fields at 2x rate
213-
214- //cout << "Frame interval: " << m_frame_interval << endl;
215 }
216
217 void VideoSync::Start(void)
218@@ -139,21 +133,6 @@
219 gettimeofday(&m_nexttrigger, NULL); // now
220 }
221
222-/** \fn VideoSync::SetFrameInterval(int fr, bool intr)
223- * \brief Change frame interval and interlacing attributes
224- */
225-void VideoSync::SetFrameInterval(int fr, bool intr)
226-{
227- m_frame_interval = fr;
228- m_interlaced = intr;
229- int tolerance = m_refresh_interval / 200;
230- if (m_interlaced && m_refresh_interval > ((m_frame_interval/2) + tolerance))
231- m_interlaced = false; // can't display both fields at 2x rate
232-
233- VERBOSE(VB_PLAYBACK, QString("Set video sync frame interval to %1")
234- .arg(m_frame_interval));
235-}
236-
237 void VideoSync::OffsetTimeval(struct timeval& tv, int offset)
238 {
239 tv.tv_usec += offset;
240@@ -169,21 +148,6 @@
241 }
242 }
243
244-/** \fn VideoSync::UpdateNexttrigger()
245- * \brief Internal method to tells video synchronization method to use
246- * the next frame (or field, if interlaced) for CalcDelay()
247- * and WaitForFrame().
248- */
249-void VideoSync::UpdateNexttrigger()
250-{
251- // Offset by frame interval -- if interlaced, only delay by half
252- // frame interval
253- if (m_interlaced)
254- OffsetTimeval(m_nexttrigger, m_frame_interval/2);
255- else
256- OffsetTimeval(m_nexttrigger, m_frame_interval);
257-}
258-
259 /** \fn VideoSync::CalcDelay()
260 * \brief Calculates the delay to the next frame.
261 *
262@@ -370,12 +334,8 @@
263 //cerr << "Wait " << n << " intervals. Count " << blank.request.sequence;
264 //cerr << " Delay " << m_delay << endl;
265 }
266-}
267
268-void DRMVideoSync::AdvanceTrigger(void)
269-{
270 KeepPhase();
271- UpdateNexttrigger();
272 }
273 #endif /* !_WIN32 */
274
275@@ -539,15 +499,7 @@
276 m_delay = CalcDelay();
277 }
278
279-#endif /* USING_OPENGL_VSYNC */
280-}
281-
282-void OpenGLVideoSync::AdvanceTrigger(void)
283-{
284-#ifdef USING_OPENGL_VSYNC
285-
286 KeepPhase();
287- UpdateNexttrigger();
288 #endif /* USING_OPENGL_VSYNC */
289 }
290 #endif /* !_WIN32 */
291@@ -610,11 +562,6 @@
292 usleep(m_delay);
293 }
294 }
295-
296-void RTCVideoSync::AdvanceTrigger(void)
297-{
298- UpdateNexttrigger();
299-}
300 #endif /* __linux__ */
301
302 #ifdef USING_VDPAU
303@@ -650,11 +597,6 @@
304 vo->SetNextFrameDisplayTimeOffset(m_delay);
305 }
306
307-void VDPAUVideoSync::AdvanceTrigger(void)
308-{
309- UpdateNexttrigger();
310-}
311-
312 #endif
313
314 BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo,
315@@ -705,11 +647,6 @@
316 }
317 }
318
319-void BusyWaitVideoSync::AdvanceTrigger(void)
320-{
321- UpdateNexttrigger();
322-}
323-
324 USleepVideoSync::USleepVideoSync(VideoOutput *vo,
325 int fr, int ri, bool intl) :
326 VideoSync(vo, fr, ri, intl)
327@@ -734,8 +671,3 @@
328 if (m_delay > 0)
329 usleep(m_delay);
330 }
331-
332-void USleepVideoSync::AdvanceTrigger(void)
333-{
334- UpdateNexttrigger();
335-}
336Index: libs/libmythtv/vsync.h
337===================================================================
338--- libs/libmythtv/vsync.h (revision 23844)
339+++ libs/libmythtv/vsync.h (working copy)
340@@ -39,15 +39,9 @@
341 * The factory method BestMethod tries subclasses in roughly quality
342 * order until one succeeds.
343 *
344- * A/V sync methods may supply an additonal delay per frame. Other
345+ * A/V sync methods may supply the nominal delay per frame. Other
346 * than that, video timing is entirely up to these classes. When
347 * WaitForFrame returns, it is time to show the frame.
348- *
349- * There is some basic support for interlaced video timing where the
350- * fields need to be displayed sequentially. Passing true for the
351- * interlaced flags for the constructors, BestMethod, and
352- * SetFrameInterval will cause us to wait for half the specified frame
353- * interval, if the refresh rate is sufficient to do so.
354 */
355 class VideoSync
356 // virtual base class
357@@ -80,17 +74,9 @@
358 */
359 virtual void WaitForFrame(int sync_delay) = 0;
360
361- /// \brief Use the next frame or field for CalcDelay(void)
362- /// and WaitForFrame(int).
363- virtual void AdvanceTrigger(void) = 0;
364+ /// \brief Returns the (minimum) refresh interval of the output device.
365+ int getRefreshInterval(void) const { return m_refresh_interval; }
366
367- void SetFrameInterval(int fi, bool interlaced);
368-
369- /// \brief Returns true AdvanceTrigger(void) advances a field at a time.
370- bool UsesFieldInterval(void) const { return m_interlaced; }
371- /// \brief Returns true AdvanceTrigger(void) advances a frame at a time.
372- bool UsesFrameInterval(void) const { return !m_interlaced; }
373-
374 /** \brief Stops VSync; must be called from main thread.
375 *
376 * Start(void), WaitForFrame(void), and Stop(void) should
377@@ -105,7 +91,6 @@
378 bool interlaced);
379 protected:
380 static void OffsetTimeval(struct timeval& tv, int offset);
381- void UpdateNexttrigger(void);
382 int CalcDelay(void);
383 void KeepPhase(void);
384
385@@ -137,7 +122,6 @@
386 bool TryInit(void);
387 void Start(void);
388 void WaitForFrame(int sync_delay);
389- void AdvanceTrigger(void);
390
391 private:
392 int m_dri_fd;
393@@ -179,7 +163,6 @@
394 bool TryInit(void);
395 void Start(void);
396 void WaitForFrame(int sync_delay);
397- void AdvanceTrigger(void);
398
399 private:
400 OpenGLContext *m_context;
401@@ -208,7 +191,6 @@
402 QString getName(void) const { return QString("RTC"); }
403 bool TryInit(void);
404 void WaitForFrame(int sync_delay);
405- void AdvanceTrigger(void);
406
407 private:
408 int m_rtcfd;
409@@ -229,7 +211,6 @@
410 QString getName(void) const { return QString("VDPAU"); }
411 bool TryInit(void);
412 void WaitForFrame(int sync_delay);
413- void AdvanceTrigger(void);
414
415 private:
416 };
417@@ -257,7 +238,6 @@
418 QString getName(void) const { return QString("USleep with busy wait"); }
419 bool TryInit(void);
420 void WaitForFrame(int sync_delay);
421- void AdvanceTrigger(void);
422
423 private:
424 int m_cheat;
425@@ -285,6 +265,5 @@
426 QString getName(void) const { return QString("USleep"); }
427 bool TryInit(void);
428 void WaitForFrame(int sync_delay);
429- void AdvanceTrigger(void);
430 };
431 #endif /* VSYNC_H_INCLUDED */