Ticket #7067: mythtv.patch3

File mythtv.patch3, 13.4 KB (added by Davin McCall <davmac@…>, 14 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 */