diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index 2a30cb9..3320553 100644
a
|
b
|
void MythPlayer::SetVideoParams(int width, int height, double fps,
|
816 | 816 | if (ffrew_skip != 0 && ffrew_skip != 1) |
817 | 817 | { |
818 | 818 | UpdateFFRewSkip(); |
819 | | videosync->setFrameInterval(frame_interval); |
820 | 819 | } |
821 | 820 | else |
822 | 821 | { |
… |
… |
void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
|
1890 | 1889 | |
1891 | 1890 | if (avsync_predictor_enabled) |
1892 | 1891 | { |
1893 | | avsync_predictor += frame_interval; |
| 1892 | avsync_predictor += frame_interval + avsync_adjustment + repeat_delay; |
1894 | 1893 | if (avsync_predictor >= refreshrate) |
1895 | 1894 | { |
1896 | 1895 | int refreshperiodsinframe = avsync_predictor/refreshrate; |
… |
… |
void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
|
1956 | 1955 | LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, |
1957 | 1956 | LOC + QString("AVSync waitforframe %1 %2") |
1958 | 1957 | .arg(avsync_adjustment).arg(m_double_framerate)); |
1959 | | vsync_delay_clock = videosync->WaitForFrame |
1960 | | (frameDelay + avsync_adjustment + repeat_delay); |
| 1958 | vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment + repeat_delay); |
1961 | 1959 | } |
1962 | 1960 | else |
1963 | 1961 | { |
… |
… |
void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
|
1994 | 1992 | osdLock.unlock(); |
1995 | 1993 | // Display the second field |
1996 | 1994 | if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP()) |
1997 | | vsync_delay_clock = videosync->WaitForFrame(frameDelay + |
1998 | | avsync_adjustment); |
| 1995 | vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment); |
1999 | 1996 | videoOutput->Show(ps); |
2000 | 1997 | } |
2001 | 1998 | |
… |
… |
void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
|
2008 | 2005 | } |
2009 | 2006 | else |
2010 | 2007 | { |
2011 | | vsync_delay_clock = videosync->WaitForFrame(frameDelay); |
| 2008 | vsync_delay_clock = videosync->WaitForFrame(frameDelay, 0); |
2012 | 2009 | //currentaudiotime = AVSyncGetAudiotime(); |
2013 | 2010 | } |
2014 | 2011 | |
… |
… |
void MythPlayer::VideoStart(void)
|
2450 | 2447 | |
2451 | 2448 | if (player_ctx->IsPIP() && FlagIsSet(kVideoIsNull)) |
2452 | 2449 | { |
2453 | | videosync = new DummyVideoSync(videoOutput, fr_int, 0, false); |
| 2450 | videosync = new DummyVideoSync(videoOutput, 0); |
2454 | 2451 | } |
2455 | 2452 | else if (FlagIsSet(kVideoIsNull)) |
2456 | 2453 | { |
2457 | | videosync = new USleepVideoSync(videoOutput, fr_int, 0, false); |
| 2454 | videosync = new USleepVideoSync(videoOutput, 0); |
2458 | 2455 | } |
2459 | 2456 | else if (videoOutput) |
2460 | 2457 | { |
… |
… |
void MythPlayer::VideoStart(void)
|
2465 | 2462 | |
2466 | 2463 | m_double_process = videoOutput->IsExtraProcessingRequired(); |
2467 | 2464 | |
2468 | | videosync = VideoSync::BestMethod( |
2469 | | videoOutput, (uint)fr_int, (uint)rf_int, m_double_framerate); |
| 2465 | videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int); |
2470 | 2466 | |
2471 | 2467 | // Make sure video sync can do it |
2472 | 2468 | if (videosync != NULL && m_double_framerate) |
… |
… |
void MythPlayer::VideoStart(void)
|
2482 | 2478 | } |
2483 | 2479 | if (!videosync) |
2484 | 2480 | { |
2485 | | videosync = new BusyWaitVideoSync( |
2486 | | videoOutput, fr_int, rf_int, m_double_framerate); |
| 2481 | videosync = new BusyWaitVideoSync(videoOutput, rf_int); |
2487 | 2482 | } |
2488 | 2483 | |
2489 | 2484 | InitAVSync(); |
… |
… |
void MythPlayer::ChangeSpeed(void)
|
3751 | 3746 | normal_speed = next_normal_speed; |
3752 | 3747 | |
3753 | 3748 | bool skip_changed = UpdateFFRewSkip(); |
3754 | | videosync->setFrameInterval(frame_interval); |
3755 | 3749 | |
3756 | 3750 | if (skip_changed && videoOutput) |
3757 | 3751 | { |
diff --git a/mythtv/libs/libmythtv/vsync.cpp b/mythtv/libs/libmythtv/vsync.cpp
index c03e70f..db62191 100644
a
|
b
|
int VideoSync::m_forceskip = 0;
|
59 | 59 | #define TESTVIDEOSYNC(NAME) \ |
60 | 60 | do { if (++m_forceskip > skip) \ |
61 | 61 | { \ |
62 | | trial = new NAME (video_output, frame_interval, \ |
63 | | refresh_interval, halve_frame_interval); \ |
| 62 | trial = new NAME (video_output, refresh_interval); \ |
64 | 63 | if (trial->TryInit()) \ |
65 | 64 | { \ |
66 | 65 | m_forceskip = skip; \ |
… |
… |
int VideoSync::m_forceskip = 0;
|
72 | 71 | |
73 | 72 | #define LOC QString("VSYNC: ") |
74 | 73 | |
75 | | /** \fn VideoSync::BestMethod(VideoOutput*,uint,uint,bool) |
| 74 | /** \fn VideoSync::BestMethod(VideoOutput*,uint) |
76 | 75 | * \brief Returns the most sophisticated video sync method available. |
77 | 76 | */ |
78 | 77 | VideoSync *VideoSync::BestMethod(VideoOutput *video_output, |
79 | | uint frame_interval, uint refresh_interval, |
80 | | bool halve_frame_interval) |
| 78 | uint refresh_interval) |
81 | 79 | { |
82 | 80 | VideoSync *trial = NULL; |
83 | 81 | tryingVideoSync = true; |
… |
… |
VideoSync *VideoSync::BestMethod(VideoOutput *video_output,
|
110 | 108 | return NULL; |
111 | 109 | } |
112 | 110 | |
113 | | /** \fn VideoSync::VideoSync(VideoOutput*,int,int,bool) |
114 | | * \brief Used by BestMethod(VideoOutput*,uint,uint,bool) to initialize |
| 111 | /** \fn VideoSync::VideoSync(VideoOutput*,int) |
| 112 | * \brief Used by BestMethod(VideoOutput*,uint) to initialize |
115 | 113 | * video synchronization method. |
116 | 114 | */ |
117 | | VideoSync::VideoSync(VideoOutput *video_output, |
118 | | int frameint, int refreshint, |
119 | | bool halve_frame_interval) : |
120 | | m_video_output(video_output), m_frame_interval(frameint), |
121 | | m_refresh_interval(refreshint), m_interlaced(halve_frame_interval), |
| 115 | VideoSync::VideoSync(VideoOutput *video_output, int refreshint) : |
| 116 | m_video_output(video_output), m_refresh_interval(refreshint), |
122 | 117 | m_nexttrigger(0), m_delay(-1) |
123 | 118 | { |
124 | 119 | } |
… |
… |
void VideoSync::Start(void)
|
135 | 130 | m_nexttrigger = GetTime(); |
136 | 131 | } |
137 | 132 | |
138 | | /** \fn VideoSync::CalcDelay() |
| 133 | /** \fn VideoSync::CalcDelay(int) |
139 | 134 | * \brief Calculates the delay to the next frame. |
140 | 135 | * |
141 | 136 | * Regardless of the timing method, if delay is greater than four full |
… |
… |
void VideoSync::Start(void)
|
146 | 141 | * Also prevent the nexttrigger from falling too far in the past in case |
147 | 142 | * we are trying to speed up video output faster than possible. |
148 | 143 | */ |
149 | | int VideoSync::CalcDelay() |
| 144 | int VideoSync::CalcDelay(int nominal_frame_interval) |
150 | 145 | { |
151 | 146 | int64_t now = GetTime(); |
152 | 147 | #if 0 |
… |
… |
int VideoSync::CalcDelay()
|
160 | 155 | LOG(VB_GENERAL, LOG_DEBUG, QString("delay %1").arg(ret_val)); |
161 | 156 | #endif |
162 | 157 | |
163 | | if (ret_val > m_frame_interval * 4) |
| 158 | if (ret_val > nominal_frame_interval * 4) |
164 | 159 | { |
165 | | if (m_interlaced) |
166 | | ret_val = (m_frame_interval / 2) * 4; |
167 | | else |
168 | | ret_val = m_frame_interval * 4; |
| 160 | ret_val = nominal_frame_interval * 4; |
169 | 161 | |
170 | 162 | // set nexttrigger to our new target time |
171 | 163 | m_nexttrigger = now + ret_val; |
172 | 164 | } |
173 | 165 | |
174 | | if (ret_val < -m_frame_interval && m_frame_interval >= m_refresh_interval) |
| 166 | if (ret_val < -nominal_frame_interval && nominal_frame_interval >= m_refresh_interval) |
175 | 167 | { |
176 | | ret_val = -m_frame_interval; |
| 168 | ret_val = -nominal_frame_interval; |
177 | 169 | |
178 | 170 | // set nexttrigger to our new target time |
179 | 171 | m_nexttrigger = now + ret_val; |
… |
… |
static int drmWaitVBlank(int fd, drm_wait_vblank_t *vbl)
|
242 | 234 | |
243 | 235 | const char *DRMVideoSync::sm_dri_dev = "/dev/dri/card0"; |
244 | 236 | |
245 | | DRMVideoSync::DRMVideoSync(VideoOutput *vo, int fr, int ri, bool intl) : |
246 | | VideoSync(vo, fr, ri, intl) |
| 237 | DRMVideoSync::DRMVideoSync(VideoOutput *vo, int ri) : |
| 238 | VideoSync(vo, ri) |
247 | 239 | { |
248 | 240 | m_dri_fd = -1; |
249 | 241 | } |
… |
… |
void DRMVideoSync::Start(void)
|
291 | 283 | VideoSync::Start(); |
292 | 284 | } |
293 | 285 | |
294 | | int DRMVideoSync::WaitForFrame(int sync_delay) |
| 286 | int DRMVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay) |
295 | 287 | { |
296 | 288 | // Offset for externally-provided A/V sync delay |
297 | | m_nexttrigger += sync_delay; |
| 289 | m_nexttrigger += nominal_frame_interval + extra_delay; |
298 | 290 | |
299 | | m_delay = CalcDelay(); |
| 291 | m_delay = CalcDelay(nominal_frame_interval); |
300 | 292 | #if 0 |
301 | 293 | LOG(VB_GENERAL, LOG_DEBUG, QString("WaitForFrame at : %1").arg(m_delay)); |
302 | 294 | #endif |
… |
… |
int DRMVideoSync::WaitForFrame(int sync_delay)
|
308 | 300 | blank.request.type = DRM_VBLANK_RELATIVE; |
309 | 301 | blank.request.sequence = 1; |
310 | 302 | drmWaitVBlank(m_dri_fd, &blank); |
311 | | m_delay = CalcDelay(); |
| 303 | m_delay = CalcDelay(nominal_frame_interval); |
312 | 304 | #if 0 |
313 | 305 | LOG(VB_GENERAL, LOG_DEBUG, QString("Delay at sync: %1").arg(m_delay)); |
314 | 306 | #endif |
… |
… |
int DRMVideoSync::WaitForFrame(int sync_delay)
|
323 | 315 | blank.request.type = DRM_VBLANK_RELATIVE; |
324 | 316 | blank.request.sequence = n; |
325 | 317 | drmWaitVBlank(m_dri_fd, &blank); |
326 | | m_delay = CalcDelay(); |
| 318 | m_delay = CalcDelay(nominal_frame_interval); |
327 | 319 | #if 0 |
328 | 320 | LOG(VB_GENERAL, LOG_DEBUG, |
329 | 321 | QString("Wait %1 intervals. Count %2 Delay %3") |
… |
… |
int DRMVideoSync::WaitForFrame(int sync_delay)
|
337 | 329 | |
338 | 330 | #ifdef __linux__ |
339 | 331 | #define RTCRATE 1024 |
340 | | RTCVideoSync::RTCVideoSync(VideoOutput *vo, int fi, int ri, bool intr) : |
341 | | VideoSync(vo, fi, ri, intr) |
| 332 | RTCVideoSync::RTCVideoSync(VideoOutput *vo, int ri) : |
| 333 | VideoSync(vo, ri) |
342 | 334 | { |
343 | 335 | m_rtcfd = -1; |
344 | 336 | } |
… |
… |
bool RTCVideoSync::TryInit(void)
|
377 | 369 | return true; |
378 | 370 | } |
379 | 371 | |
380 | | int RTCVideoSync::WaitForFrame(int sync_delay) |
| 372 | int RTCVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay) |
381 | 373 | { |
382 | | m_nexttrigger += sync_delay; |
| 374 | m_nexttrigger += nominal_frame_interval + extra_delay; |
383 | 375 | |
384 | | m_delay = CalcDelay(); |
| 376 | m_delay = CalcDelay(nominal_frame_interval); |
385 | 377 | |
386 | 378 | unsigned long rtcdata; |
387 | 379 | while (m_delay > 0) |
388 | 380 | { |
389 | 381 | ssize_t val = read(m_rtcfd, &rtcdata, sizeof(rtcdata)); |
390 | | m_delay = CalcDelay(); |
| 382 | m_delay = CalcDelay(nominal_frame_interval); |
391 | 383 | |
392 | 384 | if ((val < 0) && (m_delay > 0)) |
393 | 385 | std::this_thread::sleep_for(std::chrono::microseconds(m_delay)); |
… |
… |
int RTCVideoSync::WaitForFrame(int sync_delay)
|
396 | 388 | } |
397 | 389 | #endif /* __linux__ */ |
398 | 390 | |
399 | | BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo, |
400 | | int fr, int ri, bool intl) : |
401 | | VideoSync(vo, fr, ri, intl) |
| 391 | BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo, int ri) : |
| 392 | VideoSync(vo, ri) |
402 | 393 | { |
403 | 394 | m_cheat = 5000; |
404 | 395 | m_fudge = 0; |
… |
… |
bool BusyWaitVideoSync::TryInit(void)
|
413 | 404 | return true; |
414 | 405 | } |
415 | 406 | |
416 | | int BusyWaitVideoSync::WaitForFrame(int sync_delay) |
| 407 | int BusyWaitVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay) |
417 | 408 | { |
418 | 409 | // Offset for externally-provided A/V sync delay |
419 | | m_nexttrigger += sync_delay; |
| 410 | m_nexttrigger += nominal_frame_interval + extra_delay; |
420 | 411 | |
421 | | m_delay = CalcDelay(); |
| 412 | m_delay = CalcDelay(nominal_frame_interval); |
422 | 413 | |
423 | 414 | if (m_delay > 0) |
424 | 415 | { |
… |
… |
int BusyWaitVideoSync::WaitForFrame(int sync_delay)
|
431 | 422 | |
432 | 423 | // If late, draw the frame ASAP. If early, hold the CPU until |
433 | 424 | // half as late as the previous frame (fudge). |
434 | | m_delay = CalcDelay(); |
435 | | m_fudge = min(m_fudge, m_frame_interval); |
| 425 | m_delay = CalcDelay(nominal_frame_interval); |
| 426 | m_fudge = min(m_fudge, nominal_frame_interval); |
436 | 427 | while (m_delay + m_fudge > 0) |
437 | 428 | { |
438 | | m_delay = CalcDelay(); |
| 429 | m_delay = CalcDelay(nominal_frame_interval); |
439 | 430 | cnt++; |
440 | 431 | } |
441 | 432 | m_fudge = abs(m_delay / 2); |
… |
… |
int BusyWaitVideoSync::WaitForFrame(int sync_delay)
|
445 | 436 | return 0; |
446 | 437 | } |
447 | 438 | |
448 | | USleepVideoSync::USleepVideoSync(VideoOutput *vo, |
449 | | int fr, int ri, bool intl) : |
450 | | VideoSync(vo, fr, ri, intl) |
| 439 | USleepVideoSync::USleepVideoSync(VideoOutput *vo, int ri) : |
| 440 | VideoSync(vo, ri) |
451 | 441 | { |
452 | 442 | } |
453 | 443 | |
… |
… |
bool USleepVideoSync::TryInit(void)
|
460 | 450 | return true; |
461 | 451 | } |
462 | 452 | |
463 | | int USleepVideoSync::WaitForFrame(int sync_delay) |
| 453 | int USleepVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay) |
464 | 454 | { |
465 | 455 | // Offset for externally-provided A/V sync delay |
466 | | m_nexttrigger += sync_delay; |
| 456 | m_nexttrigger += nominal_frame_interval + extra_delay; |
467 | 457 | |
468 | | m_delay = CalcDelay(); |
| 458 | m_delay = CalcDelay(nominal_frame_interval); |
469 | 459 | if (m_delay > 0) |
470 | 460 | std::this_thread::sleep_for(std::chrono::microseconds(m_delay)); |
471 | 461 | return 0; |
diff --git a/mythtv/libs/libmythtv/vsync.h b/mythtv/libs/libmythtv/vsync.h
index 56ab9f9..2e0b79b 100644
a
|
b
|
class VideoSync
|
46 | 46 | // virtual base class |
47 | 47 | { |
48 | 48 | public: |
49 | | VideoSync(VideoOutput*, int fi, int ri, bool intr); |
| 49 | VideoSync(VideoOutput*, int ri); |
50 | 50 | virtual ~VideoSync() {} |
51 | 51 | |
52 | 52 | /// \brief Returns name of instanciated VSync method. |
… |
… |
class VideoSync
|
69 | 69 | * always be called from same thread, to prevent bad |
70 | 70 | * interactions with threads. |
71 | 71 | * |
72 | | * \param sync_delay time until the desired frame or field |
73 | | * \sa CalcDelay(void), KeepPhase(void) |
| 72 | * \param nominal_frame_interval the frame interval normally expected |
| 73 | * \param extra_delay extra time beyond nominal until the desired frame or field |
| 74 | * \sa CalcDelay(int), KeepPhase(void) |
74 | 75 | */ |
75 | | virtual int WaitForFrame(int sync_delay) = 0; |
| 76 | virtual int WaitForFrame(int nominal_frame_interval, int extra_delay) = 0; |
76 | 77 | |
77 | 78 | /// \brief Returns the (minimum) refresh interval of the output device. |
78 | 79 | int getRefreshInterval(void) const { return m_refresh_interval; } |
79 | 80 | /// \brief Sets the refresh interval of the output device. |
80 | 81 | void setRefreshInterval(int ri) { m_refresh_interval = ri; } |
81 | 82 | |
82 | | virtual void setFrameInterval(int fi) { m_frame_interval = fi; }; |
83 | | |
84 | 83 | /** \brief Stops VSync; must be called from main thread. |
85 | 84 | * |
86 | 85 | * Start(void), WaitForFrame(void), and Stop(void) should |
… |
… |
class VideoSync
|
90 | 89 | virtual void Stop(void) {} |
91 | 90 | |
92 | 91 | // documented in vsync.cpp |
93 | | static VideoSync *BestMethod(VideoOutput*, |
94 | | uint frame_interval, uint refresh_interval, |
95 | | bool interlaced); |
| 92 | static VideoSync *BestMethod(VideoOutput *, uint refresh_interval); |
| 93 | |
96 | 94 | protected: |
97 | 95 | int64_t GetTime(void); |
98 | | int CalcDelay(void); |
| 96 | int CalcDelay(int nominal_frame_interval); |
99 | 97 | void KeepPhase(void) MDEPRECATED; |
100 | 98 | |
101 | 99 | VideoOutput *m_video_output; |
102 | | int m_frame_interval; // of video |
103 | 100 | int m_refresh_interval; // of display |
104 | | bool m_interlaced; |
105 | 101 | int64_t m_nexttrigger; |
106 | 102 | int m_delay; |
107 | 103 | |
… |
… |
class VideoSync
|
118 | 114 | class DRMVideoSync : public VideoSync |
119 | 115 | { |
120 | 116 | public: |
121 | | DRMVideoSync(VideoOutput*, |
122 | | int frame_interval, int refresh_interval, bool interlaced); |
| 117 | DRMVideoSync(VideoOutput *, int refresh_interval); |
123 | 118 | ~DRMVideoSync(); |
124 | 119 | |
125 | 120 | QString getName(void) const { return QString("DRM"); } |
126 | 121 | bool TryInit(void); |
127 | 122 | void Start(void); |
128 | | int WaitForFrame(int sync_delay); |
| 123 | int WaitForFrame(int nominal_frame_interval, int extra_delay) override; |
129 | 124 | |
130 | 125 | private: |
131 | 126 | int m_dri_fd; |
… |
… |
class DRMVideoSync : public VideoSync
|
148 | 143 | class RTCVideoSync : public VideoSync |
149 | 144 | { |
150 | 145 | public: |
151 | | RTCVideoSync(VideoOutput*, |
152 | | int frame_interval, int refresh_interval, bool interlaced); |
| 146 | RTCVideoSync(VideoOutput *, int refresh_interval); |
153 | 147 | ~RTCVideoSync(); |
154 | 148 | |
155 | 149 | QString getName(void) const { return QString("RTC"); } |
156 | 150 | bool TryInit(void); |
157 | | int WaitForFrame(int sync_delay); |
| 151 | int WaitForFrame(int nominal_frame_interval, int extra_delay) override; |
158 | 152 | |
159 | 153 | private: |
160 | 154 | int m_rtcfd; |
… |
… |
class RTCVideoSync : public VideoSync
|
174 | 168 | class BusyWaitVideoSync : public VideoSync |
175 | 169 | { |
176 | 170 | public: |
177 | | BusyWaitVideoSync(VideoOutput*, |
178 | | int frame_interval, int refresh_interval, |
179 | | bool interlaced); |
| 171 | BusyWaitVideoSync(VideoOutput *, int refresh_interval); |
180 | 172 | ~BusyWaitVideoSync(); |
181 | 173 | |
182 | 174 | QString getName(void) const { return QString("USleep with busy wait"); } |
183 | 175 | bool TryInit(void); |
184 | | int WaitForFrame(int sync_delay); |
| 176 | int WaitForFrame(int nominal_frame_interval, int extra_delay) override; |
185 | 177 | |
186 | 178 | private: |
187 | 179 | int m_cheat; |
… |
… |
class BusyWaitVideoSync : public VideoSync
|
201 | 193 | class USleepVideoSync : public VideoSync |
202 | 194 | { |
203 | 195 | public: |
204 | | USleepVideoSync(VideoOutput*, |
205 | | int frame_interval, int refresh_interval, |
206 | | bool interlaced); |
| 196 | USleepVideoSync(VideoOutput *, int refresh_interval); |
207 | 197 | ~USleepVideoSync(); |
208 | 198 | |
209 | 199 | QString getName(void) const { return QString("USleep"); } |
210 | 200 | bool TryInit(void); |
211 | | int WaitForFrame(int sync_delay); |
| 201 | int WaitForFrame(int nominal_frame_interval, int extra_delay) override; |
212 | 202 | }; |
213 | 203 | |
214 | 204 | class DummyVideoSync : public VideoSync |
215 | 205 | { |
216 | 206 | public: |
217 | | DummyVideoSync(VideoOutput* vo, int fr, int ri, bool intl) |
218 | | : VideoSync(vo, fr, ri, intl) { } |
| 207 | DummyVideoSync(VideoOutput* vo, int ri) : VideoSync(vo, ri) { } |
219 | 208 | ~DummyVideoSync() { } |
220 | 209 | |
221 | 210 | QString getName(void) const { return QString("Dummy"); } |
222 | 211 | bool TryInit(void) { return true; } |
223 | | int WaitForFrame(int /*sync_delay*/) { return 0; } |
| 212 | int WaitForFrame(int nominal_frame_interval, int extra_delay) override { return 0; } |
224 | 213 | }; |
225 | 214 | #endif /* VSYNC_H_INCLUDED */ |