1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#pragma once
/*
* Copyright (C) 2005-2008 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "system.h" // for HAS_XRANDR, and Win32 types
#include "Thread.h"
#include "utils/CriticalSection.h"
//TODO: get rid of #ifdef hell, abstract implementations in separate classes
#if defined(HAS_GLX) && defined(HAS_XRANDR)
#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#elif defined(_WIN32) && defined(HAS_DX)
#include <d3d9.h>
#include "D3DResource.h"
class CD3DCallback : public ID3DResource
{
public:
void Reset();
void OnDestroyDevice();
void OnCreateDevice();
void Aquire();
void Release();
bool IsValid();
private:
bool m_devicevalid;
bool m_deviceused;
CCriticalSection m_critsection;
CEvent m_createevent;
CEvent m_releaseevent;
};
#endif
class CVideoReferenceClock : public CThread
{
public:
CVideoReferenceClock();
int64_t GetTime();
int64_t GetFrequency();
void SetSpeed(double Speed);
double GetSpeed();
int GetRefreshRate();
int64_t Wait(int64_t Target);
bool WaitStarted(int MSecs);
bool GetClockInfo(int& MissedVblanks, double& ClockSpeed, int& RefreshRate);
#if defined(__APPLE__)
void VblankHandler(int64_t nowtime, double fps);
#endif
private:
void Process();
bool UpdateRefreshrate(bool Forced = false);
void SendVblankSignal();
void UpdateClock(int NrVBlanks, bool CheckMissed);
int64_t TimeOfNextVblank();
int64_t m_CurrTime; //the current time of the clock when using vblank as clock source
int64_t m_AdjustedFrequency; //the frequency of the clock set by dvdplayer
int64_t m_ClockOffset; //the difference between the vblank clock and systemclock, set when vblank clock is stopped
int64_t m_LastRefreshTime; //last time we updated the refreshrate
int64_t m_SystemFrequency; //frequency of the systemclock
bool m_UseVblank; //set to true when vblank is used as clock source
int64_t m_RefreshRate; //current refreshrate
int m_PrevRefreshRate; //previous refreshrate, used for log printing and getting refreshrate from nvidia-settings
int m_MissedVblanks; //number of clock updates missed by the vblank clock
int m_TotalMissedVblanks;//total number of clock updates missed, used by codec information screen
int64_t m_VblankTime; //last time the clock was updated when using vblank as clock
CEvent m_Started; //set when the vblank clock is started
CEvent m_VblankEvent; //set when a vblank happens
CCriticalSection m_CritSection;
#if defined(HAS_GLX) && defined(HAS_XRANDR)
bool SetupGLX();
void RunGLX();
void CleanupGLX();
bool ParseNvSettings(int& RefreshRate);
int GetRandRRate();
int (*m_glXWaitVideoSyncSGI) (int, int, unsigned int*);
int (*m_glXGetVideoSyncSGI) (unsigned int*);
Display* m_Dpy;
XVisualInfo *m_vInfo;
Window m_Window;
GLXContext m_Context;
int m_RREventBase;
bool m_UseNvSettings;
#elif defined(_WIN32) && defined(HAS_DX)
bool SetupD3D();
double MeasureRefreshrate(int MSecs);
void RunD3D();
void CleanupD3D();
LPDIRECT3DDEVICE9 m_D3dDev;
CD3DCallback m_D3dCallback;
unsigned int m_Width;
unsigned int m_Height;
#elif defined(__APPLE__)
bool SetupCocoa();
void RunCocoa();
void CleanupCocoa();
int64_t m_LastVBlankTime; //timestamp of the last vblank, used for calculating how many vblanks happened
//not the same as m_VblankTime
#endif
};
extern CVideoReferenceClock g_VideoReferenceClock;
|