326 lines
9.0 KiB
C++
326 lines
9.0 KiB
C++
/*
|
|
* 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_
|