1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright@ Samsung Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*!
19  * \file      libscaler-v4l2.h
20  * \brief     source file for Scaler HAL
21  * \author    Cho KyongHo <pullip.cho@samsung.com>
22  * \date      2014/05/12
23  *
24  * <b>Revision History: </b>
25  * - 2014.05.12 : Cho KyongHo (pullip.cho@samsung.com) \n
26  *   Create
27  */
28 #ifndef _LIBSCALER_V4L2_H_
29 #define _LIBSCALER_V4L2_H_
30 
31 #include <fcntl.h>
32 
33 #include <exynos_scaler.h>
34 
35 #include "libscaler-common.h"
36 
37 #define V4L2_CID_EXYNOS_BASE            (V4L2_CTRL_CLASS_USER | 0x2000)
38 #define V4L2_CID_CSC_EQ_MODE            (V4L2_CID_EXYNOS_BASE + 100)
39 #define V4L2_CID_CSC_EQ                 (V4L2_CID_EXYNOS_BASE + 101)
40 #define V4L2_CID_CSC_RANGE              (V4L2_CID_EXYNOS_BASE + 102)
41 #define V4L2_CID_CONTENT_PROTECTION     (V4L2_CID_EXYNOS_BASE + 201)
42 
43 #define V4L2_PIX_FMT_NV12N              v4l2_fourcc('N', 'N', '1', '2')
44 #define V4L2_PIX_FMT_NV12NT             v4l2_fourcc('T', 'N', '1', '2')
45 #define V4L2_PIX_FMT_YUV420N            v4l2_fourcc('Y', 'N', '1', '2')
46 #define V4L2_PIX_FMT_NV12N_10B          v4l2_fourcc('B', 'N', '1', '2')
47 
48 #define V4L2_BUF_FLAG_USE_SYNC          0x00008000
49 
50 class CScalerV4L2 {
51 public:
52     enum { SC_MAX_PLANES = SC_NUM_OF_PLANES };
53     enum { SC_MAX_NODENAME = 14 };
54     enum { SC_V4L2_FMT_PREMULTI_FLAG = 10 };
55 
56     enum SC_FRAME_FLAG {
57         // frame status
58         SCFF_BUF_FRESH = 0,
59         // h/w setting
60         SCFF_CACHEABLE,
61         SCFF_PREMULTIPLIED,
62         // v4l2 status
63         SCFF_REQBUFS,
64         SCFF_QBUF,
65         SCFF_STREAMING,
66     };
67 
68     enum SC_FLAG {
69         SCF_RESERVED = 0,
70         // session status
71         SCF_ROTATION_FRESH,
72         SCF_CSC_FRESH,
73         SCF_DRM_FRESH,
74         // h/w setting setting
75         SCF_HFLIP,
76         SCF_VFLIP,
77         SCF_DRM,
78         SCF_ALLOW_DRM,
79         SCF_CSC_WIDE,
80 	SCF_SRC_BLEND,
81 	SCF_FRAMERATE,
82     };
83 
84     struct FrameInfo {
85         const char *name;
86         v4l2_buf_type type;
87         unsigned int width, height;
88         v4l2_rect crop;
89         unsigned int color_format;
90         void *addr[SC_MAX_PLANES];
91         int fdAcquireFence;
92         enum v4l2_memory memory;
93         int out_num_planes;
94         unsigned long out_plane_size[SC_MAX_PLANES];
95         unsigned long flags; // enum SC_FRAME_FLAG
96     };
97 
98 private:
99     FrameInfo m_frmSrc;
100     FrameInfo m_frmDst;
101 
102     unsigned int m_nRotDegree;
103     unsigned int m_frameRate;
104     char m_cszNode[SC_MAX_NODENAME]; // /dev/videoXX
105     int m_iInstance;
106 
107     int m_fdValidate;
108 
109     unsigned int m_filter;
110     unsigned int m_colorspace;
111 
112     void Initialize(int instance);
113     bool ResetDevice(FrameInfo &frm);
114 
SetRotDegree(int rot)115     inline void SetRotDegree(int rot) {
116         rot = rot % 360;
117         if (rot < 0)
118             rot = 360 + rot;
119 
120         m_nRotDegree = rot;
121         SetFlag(m_fStatus, SCF_ROTATION_FRESH);
122     }
123 
124     bool DevSetFormat(FrameInfo &frm);
125     bool ReqBufs(FrameInfo &frm);
126     bool QBuf(FrameInfo &frm, int *pfdReleaseFence);
127     bool StreamOn(FrameInfo &frm);
128     bool DQBuf(FrameInfo &frm);
129 
SetFormat(FrameInfo & frm,unsigned int width,unsigned int height,unsigned int v4l2_colorformat)130     inline bool SetFormat(FrameInfo &frm, unsigned int width, unsigned int height,
131                    unsigned int v4l2_colorformat) {
132         frm.color_format = v4l2_colorformat;
133         frm.width = width;
134         frm.height = height;
135         SetFlag(frm.flags, SCFF_BUF_FRESH);
136         return true;
137     }
138 
SetCrop(FrameInfo & frm,unsigned int left,unsigned int top,unsigned int width,unsigned int height)139     inline bool SetCrop(FrameInfo &frm, unsigned int left, unsigned int top,
140                  unsigned int width, unsigned int height) {
141         frm.crop.left = left;
142         frm.crop.top = top;
143         frm.crop.width = width;
144         frm.crop.height = height;
145         SetFlag(frm.flags, SCFF_BUF_FRESH);
146         return true;
147     }
148 
SetPremultiplied(FrameInfo & frm,unsigned int premultiplied)149     inline void SetPremultiplied(FrameInfo &frm, unsigned int premultiplied) {
150         if (premultiplied)
151             SetFlag(frm.flags, SCFF_PREMULTIPLIED);
152         else
153             ClearFlag(frm.flags, SCFF_PREMULTIPLIED);
154     }
155 
SetCacheable(FrameInfo & frm,bool __UNUSED__ cacheable)156     inline void SetCacheable(FrameInfo &frm, bool __UNUSED__ cacheable) {
157         SetFlag(frm.flags, SCFF_CACHEABLE);
158     }
159 
SetAddr(FrameInfo & frm,void * addr[SC_NUM_OF_PLANES],int mem_type,int fence)160     inline void SetAddr(FrameInfo &frm, void *addr[SC_NUM_OF_PLANES], int mem_type, int fence)
161     {
162         for (int i = 0; i < SC_MAX_PLANES; i++)
163             frm.addr[i] = addr[i];
164 
165         frm.memory = static_cast<v4l2_memory>(mem_type);
166         frm.fdAcquireFence = fence;
167     }
168 
169     bool RunSWScaling();
170 
171 protected:
172     unsigned long m_fStatus; // enum SC_FLAG
173 
174     int m_fdScaler;
175 
SetFlag(unsigned long & flags,unsigned long flag)176     inline void SetFlag(unsigned long &flags, unsigned long flag) {
177         flags |= (1 << flag);
178     }
179 
ClearFlag(unsigned long & flags,unsigned long flag)180     inline void ClearFlag(unsigned long &flags, unsigned long flag) {
181         flags &= ~(1 << flag);
182     }
183 
TestFlag(unsigned long & flags,unsigned long flag)184     inline bool TestFlag(unsigned long &flags, unsigned long flag) {
185         return (flags & (1 << flag)) != 0;
186     }
187 
188 
189 public:
Valid()190     inline bool Valid() { return (m_fdScaler >= 0) && (m_fdScaler == -m_fdValidate); }
191 
192     CScalerV4L2(int instance, int allow_drm = 0);
193     virtual ~CScalerV4L2();
194 
195     bool SetCtrl();
196 
IsDRMAllowed()197     inline bool IsDRMAllowed() { return TestFlag(m_fStatus, SCF_ALLOW_DRM); }
GetScalerID()198     inline int GetScalerID() { return m_iInstance; }
199 
200     bool Stop();
201     bool Run(); // Blocking mode
202 
203     // H/W Control
204     virtual bool DevSetCtrl();
205     bool DevSetFormat();
206 
ReqBufs()207     inline bool ReqBufs() {
208         if (!ReqBufs(m_frmSrc))
209             return false;
210 
211         return ReqBufs(m_frmDst);
212     }
213 
214     inline bool QBuf(int *pfdSrcReleaseFence = NULL, int *pfdDstReleaseFence = NULL) {
215         if (!QBuf(m_frmSrc, pfdSrcReleaseFence))
216             return false;
217 
218         if (!QBuf(m_frmDst, pfdDstReleaseFence)) {
219             ClearFlag(m_frmSrc.flags, SCFF_QBUF);
220             return false;
221         }
222         return true;
223     }
224 
StreamOn()225     inline bool StreamOn() {
226         if (!StreamOn(m_frmSrc))
227             return false;
228 
229         return StreamOn(m_frmDst);
230     }
231 
DQBuf()232     inline bool DQBuf() {
233         if (!DQBuf(m_frmSrc))
234             return false;
235 
236         return DQBuf(m_frmDst);
237     }
238 
SetSrcFormat(unsigned int width,unsigned int height,unsigned int v4l2_colorformat)239     inline bool SetSrcFormat(unsigned int width, unsigned int height,
240                       unsigned int v4l2_colorformat) {
241         return SetFormat(m_frmSrc, width, height, v4l2_colorformat);
242     }
243 
SetDstFormat(unsigned int width,unsigned int height,unsigned int v4l2_colorformat)244     inline bool SetDstFormat(unsigned int width, unsigned int height,
245                       unsigned int v4l2_colorformat) {
246         return SetFormat(m_frmDst, width, height, v4l2_colorformat);
247     }
248 
SetSrcCrop(unsigned int left,unsigned int top,unsigned int width,unsigned int height)249     inline bool SetSrcCrop(unsigned int left, unsigned int top,
250                     unsigned int width, unsigned int height) {
251         return SetCrop(m_frmSrc, left, top, width, height);
252     }
253 
SetDstCrop(unsigned int left,unsigned int top,unsigned int width,unsigned int height)254     inline bool SetDstCrop(unsigned int left, unsigned int top,
255                     unsigned int width, unsigned int height) {
256         return SetCrop(m_frmDst, left, top, width, height);
257     }
258 
SetDRM(bool drm)259     inline void SetDRM(bool drm) {
260         if (drm != TestFlag(m_fStatus, SCF_DRM)) {
261             if (drm)
262                 SetFlag(m_fStatus, SCF_DRM);
263             else
264                 ClearFlag(m_fStatus, SCF_DRM);
265             SetFlag(m_fStatus, SCF_DRM_FRESH);
266         }
267     }
268 
SetCSCWide(bool wide)269     inline void SetCSCWide(bool wide) {
270         if (wide)
271             SetFlag(m_fStatus, SCF_CSC_WIDE);
272         else
273             ClearFlag(m_fStatus, SCF_CSC_WIDE);
274 
275         SetFlag(m_fStatus, SCF_CSC_FRESH);
276     }
277 
SetCSCEq(unsigned int v4l2_colorspace)278     inline void SetCSCEq(unsigned int v4l2_colorspace) {
279         if (v4l2_colorspace == V4L2_COLORSPACE_SMPTE170M)
280             m_colorspace = V4L2_COLORSPACE_DEFAULT;
281         else
282             m_colorspace = v4l2_colorspace;
283         SetFlag(m_fStatus, SCF_CSC_FRESH);
284     }
285 
SetFilter(unsigned int filter)286     inline void SetFilter(unsigned int filter) {
287         m_filter = filter;
288     }
289 
SetSrcCacheable(bool cacheable)290     inline void SetSrcCacheable(bool cacheable) {
291         return SetCacheable(m_frmSrc, cacheable);
292     }
293 
SetDstCacheable(bool cacheable)294     inline void SetDstCacheable(bool cacheable) {
295         return SetCacheable(m_frmDst, cacheable);
296     }
297 
SetSrcPremultiplied(bool premultiplied)298     inline void SetSrcPremultiplied(bool premultiplied) {
299         return SetPremultiplied(m_frmSrc, premultiplied);
300     }
301 
SetDstPremultiplied(bool premultiplied)302     inline void SetDstPremultiplied(bool premultiplied) {
303         return SetPremultiplied(m_frmDst, premultiplied);
304     }
305 
306     // Parameter Extraction
307     bool SetRotate(int rot, int flip_h, int flip_v);
308 
309     inline bool SetSrcAddr(void *addr[SC_NUM_OF_PLANES], int mem_type, int fence = -1) {
310         SetAddr(m_frmSrc, addr, mem_type, fence);
311         return true;
312     }
313 
314     inline bool SetDstAddr(void *addr[SC_NUM_OF_PLANES], int mem_type, int fence = -1) {
315         SetAddr(m_frmDst, addr, mem_type, fence);
316         return true;
317     }
318 
SetFrameRate(int framerate)319     inline void SetFrameRate(int framerate) {
320         m_frameRate = framerate;
321         SetFlag(m_fStatus, SCF_FRAMERATE);
322     }
323 };
324 
325 #endif //_LIBSCALER_V4L2_H_
326