1 | Index: 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)
|
---|
201 | Index: 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 | -}
|
---|
336 | Index: 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 */
|
---|