summaryrefslogtreecommitdiff
path: root/libscaler/libscaler-v4l2.h
diff options
context:
space:
mode:
Diffstat (limited to 'libscaler/libscaler-v4l2.h')
-rw-r--r--libscaler/libscaler-v4l2.h325
1 files changed, 325 insertions, 0 deletions
diff --git a/libscaler/libscaler-v4l2.h b/libscaler/libscaler-v4l2.h
new file mode 100644
index 0000000..98d45e2
--- /dev/null
+++ b/libscaler/libscaler-v4l2.h
@@ -0,0 +1,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_