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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
/*
* Copyright (C) 2014 The Android Open Source Project
* Copyright@ Samsung Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*!
* \file libscaler-v4l2.h
* \brief source file for Scaler HAL
* \author Cho KyongHo <pullip.cho@samsung.com>
* \date 2014/05/12
*
* <b>Revision History: </b>
* - 2014.05.12 : Cho KyongHo (pullip.cho@samsung.com) \n
* Create
*/
#ifndef _LIBSCALER_V4L2_H_
#define _LIBSCALER_V4L2_H_
#include <fcntl.h>
#include <exynos_scaler.h>
#include "libscaler-common.h"
#define V4L2_CID_EXYNOS_BASE (V4L2_CTRL_CLASS_USER | 0x2000)
#define V4L2_CID_CSC_EQ_MODE (V4L2_CID_EXYNOS_BASE + 100)
#define V4L2_CID_CSC_EQ (V4L2_CID_EXYNOS_BASE + 101)
#define V4L2_CID_CSC_RANGE (V4L2_CID_EXYNOS_BASE + 102)
#define V4L2_CID_CONTENT_PROTECTION (V4L2_CID_EXYNOS_BASE + 201)
#define V4L2_PIX_FMT_NV12N v4l2_fourcc('N', 'N', '1', '2')
#define V4L2_PIX_FMT_NV12NT v4l2_fourcc('T', 'N', '1', '2')
#define V4L2_PIX_FMT_YUV420N v4l2_fourcc('Y', 'N', '1', '2')
#define V4L2_PIX_FMT_NV12N_10B v4l2_fourcc('B', 'N', '1', '2')
#define V4L2_BUF_FLAG_USE_SYNC 0x00008000
class CScalerV4L2 {
public:
enum { SC_MAX_PLANES = SC_NUM_OF_PLANES };
enum { SC_MAX_NODENAME = 14 };
enum { SC_V4L2_FMT_PREMULTI_FLAG = 10 };
enum SC_FRAME_FLAG {
// frame status
SCFF_BUF_FRESH = 0,
// h/w setting
SCFF_CACHEABLE,
SCFF_PREMULTIPLIED,
// v4l2 status
SCFF_REQBUFS,
SCFF_QBUF,
SCFF_STREAMING,
};
enum SC_FLAG {
SCF_RESERVED = 0,
// session status
SCF_ROTATION_FRESH,
SCF_CSC_FRESH,
SCF_DRM_FRESH,
// h/w setting setting
SCF_HFLIP,
SCF_VFLIP,
SCF_DRM,
SCF_ALLOW_DRM,
SCF_CSC_WIDE,
SCF_SRC_BLEND,
SCF_FRAMERATE,
};
struct FrameInfo {
const char *name;
v4l2_buf_type type;
unsigned int width, height;
v4l2_rect crop;
unsigned int color_format;
void *addr[SC_MAX_PLANES];
int fdAcquireFence;
enum v4l2_memory memory;
int out_num_planes;
unsigned long out_plane_size[SC_MAX_PLANES];
unsigned long flags; // enum SC_FRAME_FLAG
};
private:
FrameInfo m_frmSrc;
FrameInfo m_frmDst;
unsigned int m_nRotDegree;
unsigned int m_frameRate;
char m_cszNode[SC_MAX_NODENAME]; // /dev/videoXX
int m_iInstance;
int m_fdValidate;
unsigned int m_filter;
unsigned int m_colorspace;
void Initialize(int instance);
bool ResetDevice(FrameInfo &frm);
inline void SetRotDegree(int rot) {
rot = rot % 360;
if (rot < 0)
rot = 360 + rot;
m_nRotDegree = rot;
SetFlag(m_fStatus, SCF_ROTATION_FRESH);
}
bool DevSetFormat(FrameInfo &frm);
bool ReqBufs(FrameInfo &frm);
bool QBuf(FrameInfo &frm, int *pfdReleaseFence);
bool StreamOn(FrameInfo &frm);
bool DQBuf(FrameInfo &frm);
inline bool SetFormat(FrameInfo &frm, unsigned int width, unsigned int height,
unsigned int v4l2_colorformat) {
frm.color_format = v4l2_colorformat;
frm.width = width;
frm.height = height;
SetFlag(frm.flags, SCFF_BUF_FRESH);
return true;
}
inline bool SetCrop(FrameInfo &frm, unsigned int left, unsigned int top,
unsigned int width, unsigned int height) {
frm.crop.left = left;
frm.crop.top = top;
frm.crop.width = width;
frm.crop.height = height;
SetFlag(frm.flags, SCFF_BUF_FRESH);
return true;
}
inline void SetPremultiplied(FrameInfo &frm, unsigned int premultiplied) {
if (premultiplied)
SetFlag(frm.flags, SCFF_PREMULTIPLIED);
else
ClearFlag(frm.flags, SCFF_PREMULTIPLIED);
}
inline void SetCacheable(FrameInfo &frm, bool __UNUSED__ cacheable) {
SetFlag(frm.flags, SCFF_CACHEABLE);
}
inline void SetAddr(FrameInfo &frm, void *addr[SC_NUM_OF_PLANES], int mem_type, int fence)
{
for (int i = 0; i < SC_MAX_PLANES; i++)
frm.addr[i] = addr[i];
frm.memory = static_cast<v4l2_memory>(mem_type);
frm.fdAcquireFence = fence;
}
bool RunSWScaling();
protected:
unsigned long m_fStatus; // enum SC_FLAG
int m_fdScaler;
inline void SetFlag(unsigned long &flags, unsigned long flag) {
flags |= (1 << flag);
}
inline void ClearFlag(unsigned long &flags, unsigned long flag) {
flags &= ~(1 << flag);
}
inline bool TestFlag(unsigned long &flags, unsigned long flag) {
return (flags & (1 << flag)) != 0;
}
public:
inline bool Valid() { return (m_fdScaler >= 0) && (m_fdScaler == -m_fdValidate); }
CScalerV4L2(int instance, int allow_drm = 0);
virtual ~CScalerV4L2();
bool SetCtrl();
inline bool IsDRMAllowed() { return TestFlag(m_fStatus, SCF_ALLOW_DRM); }
inline int GetScalerID() { return m_iInstance; }
bool Stop();
bool Run(); // Blocking mode
// H/W Control
virtual bool DevSetCtrl();
bool DevSetFormat();
inline bool ReqBufs() {
if (!ReqBufs(m_frmSrc))
return false;
return ReqBufs(m_frmDst);
}
inline bool QBuf(int *pfdSrcReleaseFence = NULL, int *pfdDstReleaseFence = NULL) {
if (!QBuf(m_frmSrc, pfdSrcReleaseFence))
return false;
if (!QBuf(m_frmDst, pfdDstReleaseFence)) {
ClearFlag(m_frmSrc.flags, SCFF_QBUF);
return false;
}
return true;
}
inline bool StreamOn() {
if (!StreamOn(m_frmSrc))
return false;
return StreamOn(m_frmDst);
}
inline bool DQBuf() {
if (!DQBuf(m_frmSrc))
return false;
return DQBuf(m_frmDst);
}
inline bool SetSrcFormat(unsigned int width, unsigned int height,
unsigned int v4l2_colorformat) {
return SetFormat(m_frmSrc, width, height, v4l2_colorformat);
}
inline bool SetDstFormat(unsigned int width, unsigned int height,
unsigned int v4l2_colorformat) {
return SetFormat(m_frmDst, width, height, v4l2_colorformat);
}
inline bool SetSrcCrop(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) {
return SetCrop(m_frmSrc, left, top, width, height);
}
inline bool SetDstCrop(unsigned int left, unsigned int top,
unsigned int width, unsigned int height) {
return SetCrop(m_frmDst, left, top, width, height);
}
inline void SetDRM(bool drm) {
if (drm != TestFlag(m_fStatus, SCF_DRM)) {
if (drm)
SetFlag(m_fStatus, SCF_DRM);
else
ClearFlag(m_fStatus, SCF_DRM);
SetFlag(m_fStatus, SCF_DRM_FRESH);
}
}
inline void SetCSCWide(bool wide) {
if (wide)
SetFlag(m_fStatus, SCF_CSC_WIDE);
else
ClearFlag(m_fStatus, SCF_CSC_WIDE);
SetFlag(m_fStatus, SCF_CSC_FRESH);
}
inline void SetCSCEq(unsigned int v4l2_colorspace) {
if (v4l2_colorspace == V4L2_COLORSPACE_SMPTE170M)
m_colorspace = V4L2_COLORSPACE_DEFAULT;
else
m_colorspace = v4l2_colorspace;
SetFlag(m_fStatus, SCF_CSC_FRESH);
}
inline void SetFilter(unsigned int filter) {
m_filter = filter;
}
inline void SetSrcCacheable(bool cacheable) {
return SetCacheable(m_frmSrc, cacheable);
}
inline void SetDstCacheable(bool cacheable) {
return SetCacheable(m_frmDst, cacheable);
}
inline void SetSrcPremultiplied(bool premultiplied) {
return SetPremultiplied(m_frmSrc, premultiplied);
}
inline void SetDstPremultiplied(bool premultiplied) {
return SetPremultiplied(m_frmDst, premultiplied);
}
// Parameter Extraction
bool SetRotate(int rot, int flip_h, int flip_v);
inline bool SetSrcAddr(void *addr[SC_NUM_OF_PLANES], int mem_type, int fence = -1) {
SetAddr(m_frmSrc, addr, mem_type, fence);
return true;
}
inline bool SetDstAddr(void *addr[SC_NUM_OF_PLANES], int mem_type, int fence = -1) {
SetAddr(m_frmDst, addr, mem_type, fence);
return true;
}
inline void SetFrameRate(int framerate) {
m_frameRate = framerate;
SetFlag(m_fStatus, SCF_FRAMERATE);
}
};
#endif //_LIBSCALER_V4L2_H_
|