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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
/*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#ifndef OMX_H
#define OMX_H
#include <vdr/thread.h>
#include "tools.h"
extern "C"
{
#include "ilclient.h"
}
class cOmxEvents;
class cOmx : public cThread
{
public:
cOmx();
virtual ~cOmx();
int Init(void);
int DeInit(void);
void SetBufferStallCallback(void (*onBufferStall)(void*), void* data);
void SetEndOfStreamCallback(void (*onEndOfStream)(void*), void* data);
void SetStreamStartCallback(void (*onStreamStart)(void*), void* data);
static OMX_TICKS ToOmxTicks(int64_t val);
static int64_t FromOmxTicks(OMX_TICKS &ticks);
static void PtsToTicks(uint64_t pts, OMX_TICKS &ticks);
static uint64_t TicksToPts(OMX_TICKS &ticks);
int64_t GetSTC(void);
bool IsClockRunning(void);
enum eClockState {
eClockStateRun,
eClockStateStop,
eClockStateWaitForVideo,
eClockStateWaitForAudio,
eClockStateWaitForAudioVideo
};
void StartClock(bool waitForVideo = false, bool waitForAudio = false);
void StopClock(void);
void ResetClock(void);
void SetClockScale(OMX_S32 scale);
bool IsClockFreezed(void) { return m_clockScale == 0; }
unsigned int GetAudioLatency(void);
enum eClockReference {
eClockRefAudio,
eClockRefVideo,
eClockRefNone
};
void SetClockReference(eClockReference clockReference);
void SetClockLatencyTarget(void);
void SetVolume(int vol);
void SetMute(bool mute);
void StopVideo(void);
void StopAudio(void);
void SetVideoErrorConcealment(bool startWithValidFrame);
void SetVideoDecoderExtraBuffers(int extraBuffers);
void FlushAudio(void);
void FlushVideo(bool flushRender = false);
int SetVideoCodec(cVideoCodec::eCodec codec);
int SetupAudioRender(cAudioCodec::eCodec outputFormat,
int channels, cRpiAudioPort::ePort audioPort,
int samplingRate = 0, int frameSize = 0);
void GetVideoFormat(int &width, int &height, int &frameRate,
bool &interlaced);
void SetDisplayMode(bool letterbox, bool noaspect);
void SetDisplayRegion(int x, int y, int width, int height);
OMX_BUFFERHEADERTYPE* GetAudioBuffer(uint64_t pts = 0);
OMX_BUFFERHEADERTYPE* GetVideoBuffer(uint64_t pts = 0);
bool PollVideo(void);
bool EmptyAudioBuffer(OMX_BUFFERHEADERTYPE *buf);
bool EmptyVideoBuffer(OMX_BUFFERHEADERTYPE *buf);
void GetBufferUsage(int &audio, int &video);
private:
virtual void Action(void);
static const char* errStr(int err);
#ifdef DEBUG_BUFFERS
static void DumpBuffer(OMX_BUFFERHEADERTYPE *buf, const char *prefix = "");
#endif
enum eOmxComponent {
eClock = 0,
eVideoDecoder,
eVideoFx,
eVideoScheduler,
eVideoRender,
eAudioRender,
eNumComponents,
eInvalidComponent
};
enum eOmxTunnel {
eVideoDecoderToVideoFx = 0,
eVideoFxToVideoScheduler,
eVideoSchedulerToVideoRender,
eClockToVideoScheduler,
eClockToAudioRender,
eNumTunnels
};
ILCLIENT_T *m_client;
COMPONENT_T *m_comp[cOmx::eNumComponents + 1];
TUNNEL_T m_tun[cOmx::eNumTunnels + 1];
struct VideoFormat
{
int width;
int height;
int frameRate;
bool interlaced;
};
VideoFormat m_videoFormat;
bool m_setAudioStartTime;
bool m_setVideoStartTime;
bool m_setVideoDiscontinuity;
#define BUFFERSTAT_FILTER_SIZE 64
int m_usedAudioBuffers[BUFFERSTAT_FILTER_SIZE];
int m_usedVideoBuffers[BUFFERSTAT_FILTER_SIZE];
OMX_BUFFERHEADERTYPE* m_spareAudioBuffers;
OMX_BUFFERHEADERTYPE* m_spareVideoBuffers;
eClockReference m_clockReference;
OMX_S32 m_clockScale;
cOmxEvents *m_portEvents;
bool m_handlePortEvents;
void (*m_onBufferStall)(void*);
void *m_onBufferStallData;
void (*m_onEndOfStream)(void*);
void *m_onEndOfStreamData;
void (*m_onStreamStart)(void*);
void *m_onStreamStartData;
void HandlePortBufferEmptied(eOmxComponent component);
void HandlePortSettingsChanged(unsigned int portId);
void SetBufferStallThreshold(int delayMs);
bool IsBufferStall(void);
static void OnBufferEmpty(void *instance, COMPONENT_T *comp);
static void OnPortSettingsChanged(void *instance, COMPONENT_T *comp, OMX_U32 data);
static void OnEndOfStream(void *instance, COMPONENT_T *comp, OMX_U32 data);
static void OnError(void *instance, COMPONENT_T *comp, OMX_U32 data);
static void OnConfigChanged(void *instance, COMPONENT_T *comp, OMX_U32 data);
};
#endif
|