From 772716f546da84a6d6d6285a1a18891221c4f364 Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Tue, 24 Jun 2014 23:22:39 -0700 Subject: [PATCH] exynos: Update from ODROID-XU 04212014 BSP Change-Id: Ie4d9feeaae52243b346b6b5057337cd144d38021 --- Android.mk | 3 +- include/ExynosBuffer.h | 176 ++++++++ include/FimgApi.h | 21 + include/csc.h | 61 +++ include/exynos_format.h | 7 +- include/s5p_fimc_v4l2.h | 5 + include/s5p_tvout_v4l2.h | 218 ++++++++++ libcec/Android.mk | 25 ++ libcec/cec.h | 26 ++ libcec/libcec.c | 384 ++++++++++++++++++ libcec/libcec.h | 173 ++++++++ libcsc/Android.mk | 13 + libcsc/csc.c | 338 +++++++++------ libcsc/csc_helper.c | 24 +- libexynosutils/Android.mk | 10 +- libexynosutils/ExynosMutex.cpp | 3 +- ...os5_format_v4l2.c => exynos_format_v4l2.c} | 44 +- libfimg4x/Android.mk | 6 +- libfimg4x/FimgApi.cpp | 139 +++++++ libfimg4x/FimgExynos5.cpp | 8 + libv4l2/exynos_mc.c | 4 +- libv4l2/exynos_subdev.c | 10 +- libv4l2/exynos_v4l2.c | 6 +- 23 files changed, 1550 insertions(+), 154 deletions(-) create mode 100644 include/ExynosBuffer.h mode change 100755 => 100644 include/exynos_format.h create mode 100644 include/s5p_tvout_v4l2.h create mode 100644 libcec/Android.mk create mode 100644 libcec/cec.h create mode 100644 libcec/libcec.c create mode 100644 libcec/libcec.h rename libexynosutils/{exynos5_format_v4l2.c => exynos_format_v4l2.c} (94%) diff --git a/Android.mk b/Android.mk index 9c2d0c3..cb4e67c 100644 --- a/Android.mk +++ b/Android.mk @@ -21,7 +21,8 @@ common_exynos_dirs := \ libcsc \ libv4l2 \ libexynosutils \ - libfimg4x + libfimg4x \ + libcec include $(call all-named-subdir-makefiles,$(common_exynos_dirs)) diff --git a/include/ExynosBuffer.h b/include/ExynosBuffer.h new file mode 100644 index 0000000..e4c03dc --- /dev/null +++ b/include/ExynosBuffer.h @@ -0,0 +1,176 @@ +/* + * 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 ExynosBuffer.h + * \brief header file for ExynosBuffer + * \author Sangwoo, Park(sw5771.park@samsung.com) + * \date 2011/06/02 + * + * Revision History: + * - 2010/06/03 : Sangwoo, Park(sw5771.park@samsung.com) \n + * Initial version + * + * - 2012/03/14 : sangwoo.park(sw5771.park@samsung.com) \n + * Change file, struct name to ExynosXXX. + * + * - 2012/10/08 : sangwoo.park(sw5771.park@samsung.com) \n + * Add BUFFER_PLANE_NUM_DEFAULT, and, Increase Buffer as 4. + * + */ + +#ifndef EXYNOS_BUFFER_H_ +#define EXYNOS_BUFFER_H_ + +#include + +//! Buffer information +/*! + * \ingroup Exynos + */ +struct ExynosBuffer +{ +public: + //! Buffer type + enum BUFFER_TYPE + { + BUFFER_TYPE_BASE = 0, + BUFFER_TYPE_VIRT = 1 << 0, //!< virtual address + BUFFER_TYPE_PHYS = 1 << 1, //!< physical address + BUFFER_TYPE_FD = 1 << 2, //!< fd address + BUFFER_TYPE_RESERVED = 1 << 3, //!< reserved type + BUFFER_TYPE_MAX, + }; + + //! Buffer plane number + enum BUFFER_PLANE_NUM + { + BUFFER_PLANE_NUM_DEFAULT = 4, + }; + + //! Buffer virtual address + union { + char *p; //! single address. + char *extP[BUFFER_PLANE_NUM_DEFAULT]; //! Y Cb Cr. + } virt; + + //! Buffer physical address + union { + unsigned int p; //! single address. + unsigned int extP[BUFFER_PLANE_NUM_DEFAULT]; //! Y Cb Cr. + } phys; + + //! Buffer file descriptors + union { + int fd; //! single address. + int extFd[BUFFER_PLANE_NUM_DEFAULT]; //! Y Cb Cr. + } fd; + + //! Buffer reserved id + union { + int p; //! \n + int extP[BUFFER_PLANE_NUM_DEFAULT]; //! \n + } reserved; + + //! Buffer size + union { + unsigned int s; + unsigned int extS[BUFFER_PLANE_NUM_DEFAULT]; + } size; + +#ifdef __cplusplus + //! Constructor + ExynosBuffer() + { + for (int i = 0; i < BUFFER_PLANE_NUM_DEFAULT; i++) { + virt. extP [i] = NULL; + phys. extP [i] = 0; + fd. extFd[i] = -1; + reserved.extP [i] = 0; + size. extS [i] = 0; + } + } + + //! Constructor + ExynosBuffer(const ExynosBuffer *other) + { + for (int i = 0; i < BUFFER_PLANE_NUM_DEFAULT; i++) { + virt. extP [i] = other->virt.extP[i]; + phys. extP [i] = other->phys.extP[i]; + fd. extFd[i] = other->fd.extFd[i]; + reserved.extP [i] = other->reserved.extP[i]; + size. extS [i] = other->size.extS[i]; + } + } + + //! Operator(=) override + ExynosBuffer& operator =(const ExynosBuffer &other) + { + for (int i = 0; i < BUFFER_PLANE_NUM_DEFAULT; i++) { + virt. extP [i] = other.virt.extP[i]; + phys. extP [i] = other.phys.extP[i]; + fd. extFd[i] = other.fd.extFd[i]; + reserved.extP [i] = other.reserved.extP[i]; + size. extS [i] = other.size.extS[i]; + } + return *this; + } + + //! Operator(==) override + bool operator ==(const ExynosBuffer &other) const + { + bool ret = true; + + for (int i = 0; i < BUFFER_PLANE_NUM_DEFAULT; i++) { + if ( virt. extP [i] != other.virt. extP[i] + || phys. extP [i] != other.phys. extP[i] + || fd. extFd[i] != other.fd. extFd[i] + || reserved.extP [i] != other.reserved.extP[i] + || size. extS [i] != other.size. extS[i]) { + ret = false; + break; + } + } + + return ret; + } + + //! Operator(!=) override + bool operator !=(const ExynosBuffer &other) const + { + // use operator(==) + return !(*this == other); + } + + //! Get Buffer type + static int BUFFER_TYPE(ExynosBuffer *buf) + { + int type = BUFFER_TYPE_BASE; + if (buf->virt.p) + type |= BUFFER_TYPE_VIRT; + if (buf->phys.p) + type |= BUFFER_TYPE_PHYS; + if (buf->fd.fd >= 0) + type |= BUFFER_TYPE_FD; + if (buf->reserved.p) + type |= BUFFER_TYPE_RESERVED; + + return type; + } +#endif +}; + +#endif //EXYNOS_BUFFER_H_ diff --git a/include/FimgApi.h b/include/FimgApi.h index c59193e..26550b8 100644 --- a/include/FimgApi.h +++ b/include/FimgApi.h @@ -97,6 +97,16 @@ struct blit_op_table { const char *str; }; +struct compromise_param { + int clipW; + int clipH; + int src_fmt; + int dst_fmt; + int isScaling; + int isFilter; + int isSrcOver; +}; + extern struct blit_op_table optbl[]; class FimgApi @@ -145,6 +155,17 @@ void destroyFimgApi(FimgApi *ptrFimgApi); extern "C" #endif int stretchFimgApi(struct fimg2d_blit *cmd); + +#ifdef __cplusplus +extern "C" +#endif +int stretchFimgApi_fast(struct fimg2d_blit *cmd, unsigned long temp_addr, int temp_size); + +#ifdef __cplusplus +extern "C" +#endif +int compromiseFimgApi(struct compromise_param *param); + #ifdef __cplusplus extern "C" #endif diff --git a/include/csc.h b/include/csc.h index 6390893..728549d 100644 --- a/include/csc.h +++ b/include/csc.h @@ -60,8 +60,66 @@ typedef enum _CSC_MEMTYPE { CSC_MEMORY_USERPTR, CSC_MEMORY_OVERLAY, CSC_MEMORY_DMABUF, + CSC_MEMORY_MFC, } CSC_MEMTYPE; +typedef enum _CSC_HW_ID { + CSC_HW_GSC0 = 0, + CSC_HW_GSC1, + CSC_HW_GSC2, + CSC_HW_GSC3, + CSC_HW_SC0, + CSC_HW_SC1, + CSC_HW_SC2, + CSC_HW_MAX, +} CSC_HW_ID; + +typedef enum _CSC_PLANE { + CSC_Y_PLANE = 0, + CSC_RGB_PLANE = 0, + CSC_U_PLANE = 1, + CSC_UV_PLANE = 1, + CSC_V_PLANE = 2 +} CSC_PLANE; + +typedef enum _CSC_HW_TYPE { + CSC_HW_TYPE_FIMC = 0, + CSC_HW_TYPE_GSCALER +} CSC_HW_TYPE; + +typedef struct _CSC_FORMAT { + unsigned int width; + unsigned int height; + unsigned int crop_left; + unsigned int crop_top; + unsigned int crop_width; + unsigned int crop_height; + unsigned int color_format; + unsigned int cacheable; + unsigned int mode_drm; +} CSC_FORMAT; + +typedef struct _CSC_BUFFER { + void *planes[CSC_MAX_PLANES]; + int mem_type; +} CSC_BUFFER; + +typedef struct _CSC_HW_PROPERTY { + int fixed_node; + int mode_drm; +} CSC_HW_PROPERTY; + +typedef struct _CSC_HANDLE { + CSC_FORMAT dst_format; + CSC_FORMAT src_format; + CSC_BUFFER dst_buffer; + CSC_BUFFER src_buffer; + CSC_METHOD csc_method; + CSC_HW_TYPE csc_hw_type; + void *csc_hw_handle; + CSC_HW_PROPERTY hw_property; +} CSC_HANDLE; + /* * change hal pixel format to omx pixel format * @@ -393,6 +451,9 @@ CSC_ERRORCODE csc_set_dst_buffer( CSC_ERRORCODE csc_convert( void *handle); +CSC_ERRORCODE csc_convert_with_rotation( + void *handle, int rotation, int flip_horizontal, int flip_vertical); + #ifdef __cplusplus } #endif diff --git a/include/exynos_format.h b/include/exynos_format.h old mode 100755 new mode 100644 index fff96ce..f5836a2 --- a/include/exynos_format.h +++ b/include/exynos_format.h @@ -30,7 +30,7 @@ enum { HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x105, HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x106, HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x107, - HAL_PIXEL_FORMAT_ARGB888 = 0x108, + HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888 = 0x108, // support custom format for zero copy HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x110, HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x111, @@ -45,6 +45,7 @@ enum { HAL_PIXEL_FORMAT_EXYNOS_YV12 = 0x11C, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP = 0x11D, + HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_FULL = 0x11E, HAL_PIXEL_FORMAT_CUSTOM_MAX }; @@ -152,7 +153,7 @@ int V4L2_PIX_2_YUV_INFO( * @return * bpp */ -unsigned int get_yuv_bpp( +int get_yuv_bpp( unsigned int v4l2_pixel_format); /* @@ -164,7 +165,7 @@ unsigned int get_yuv_bpp( * @return * num of plane */ -unsigned int get_yuv_planes( +int get_yuv_planes( unsigned int v4l2_pixel_format); #ifdef __cplusplus diff --git a/include/s5p_fimc_v4l2.h b/include/s5p_fimc_v4l2.h index 52b1b6d..1b46462 100644 --- a/include/s5p_fimc_v4l2.h +++ b/include/s5p_fimc_v4l2.h @@ -60,9 +60,14 @@ * V 4 L 2 F I M C E X T E N S I O N S * */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + /* FOURCC for FIMC specific */ #define V4L2_PIX_FMT_NV12X v4l2_fourcc('N', '1', '2', 'X') #define V4L2_PIX_FMT_NV21X v4l2_fourcc('N', '2', '1', 'X') +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') #define V4L2_PIX_FMT_NV16X v4l2_fourcc('N', '1', '6', 'X') #define V4L2_PIX_FMT_NV61X v4l2_fourcc('N', '6', '1', 'X') diff --git a/include/s5p_tvout_v4l2.h b/include/s5p_tvout_v4l2.h new file mode 100644 index 0000000..cada1fe --- /dev/null +++ b/include/s5p_tvout_v4l2.h @@ -0,0 +1,218 @@ +/* + * 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. + */ + +#ifndef __S5P_TVOUT_H__ +#define __S5P_TVOUT_H__ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************* + * Define + *******************************************/ +/* TVOUT control */ +#define PFX_NODE_FB "/dev/graphics/fb" + +#define PFX_NODE_MEDIADEV "/dev/media" +#define PFX_NODE_SUBDEV "/dev/v4l-subdev" +#define PFX_NODE_VIDEODEV "/dev/video" +#define PFX_ENTITY_SUBDEV_MIXER "s5p-mixer%d" +#define PFX_ENTITY_VIDEODEV_MIXER_GRP "mxr%d_graph%d" +#define PFX_ENTITY_SUBDEV_GSC_OUT "exynos-gsc-sd.%d" +#define PFX_ENTITY_VIDEODEV_GSC_OUT "exynos-gsc.%d.output" + +#define PFX_ENTITY_SUBDEV_FIMD "s5p-fimd%d" +#define PFX_ENTITY_SUBDEV_GSC_CAP "gsc-cap-subdev.%d" +#define PFX_ENTITY_VIDEODEV_GSC_CAP "exynos-gsc.%d.capture" + +/* Sub-Mixer 0 */ +#define TVOUT0_DEV_G0 "/dev/video16" +#define TVOUT0_DEV_G1 "/dev/video17" +/* Sub-Mixer 1 */ +#define TVOUT1_DEV_G0 "/dev/video18" +#define TVOUT1_DEV_G1 "/dev/video19" + +#define MIXER_V_SUBDEV_PAD_SINK (0) +#define MIXER_V_SUBDEV_PAD_SOURCE (3) +#define MIXER_G0_SUBDEV_PAD_SINK (1) +#define MIXER_G0_SUBDEV_PAD_SOURCE (4) +#define MIXER_G1_SUBDEV_PAD_SINK (2) +#define MIXER_G1_SUBDEV_PAD_SOURCE (5) + +#define GSCALER_SUBDEV_PAD_SINK (0) +#define GSCALER_SUBDEV_PAD_SOURCE (1) +#define FIMD_SUBDEV_PAD_SOURCE (0) + +#define HPD_DEV "/dev/HPD" + +/* ------------- Output -----------------*/ +/* type */ +#define V4L2_OUTPUT_TYPE_MSDMA 4 +#define V4L2_OUTPUT_TYPE_COMPOSITE 5 +#define V4L2_OUTPUT_TYPE_SVIDEO 6 +#define V4L2_OUTPUT_TYPE_YPBPR_INERLACED 7 +#define V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE 8 +#define V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE 9 +#define V4L2_OUTPUT_TYPE_DIGITAL 10 +#define V4L2_OUTPUT_TYPE_HDMI V4L2_OUTPUT_TYPE_DIGITAL +#define V4L2_OUTPUT_TYPE_HDMI_RGB 11 +#define V4L2_OUTPUT_TYPE_DVI 12 + +/* ------------- STD -------------------*/ +#define V4L2_STD_PAL_BDGHI\ + (V4L2_STD_PAL_B|V4L2_STD_PAL_D|V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_PAL_I) + +#define V4L2_STD_480P_60_16_9 ((v4l2_std_id)0x04000000) +#define V4L2_STD_480P_60_4_3 ((v4l2_std_id)0x05000000) +#define V4L2_STD_576P_50_16_9 ((v4l2_std_id)0x06000000) +#define V4L2_STD_576P_50_4_3 ((v4l2_std_id)0x07000000) +#define V4L2_STD_720P_60 ((v4l2_std_id)0x08000000) +#define V4L2_STD_720P_50 ((v4l2_std_id)0x09000000) +#define V4L2_STD_1080P_60 ((v4l2_std_id)0x0a000000) +#define V4L2_STD_1080P_50 ((v4l2_std_id)0x0b000000) +#define V4L2_STD_1080I_60 ((v4l2_std_id)0x0c000000) +#define V4L2_STD_1080I_50 ((v4l2_std_id)0x0d000000) +#define V4L2_STD_480P_59 ((v4l2_std_id)0x0e000000) +#define V4L2_STD_720P_59 ((v4l2_std_id)0x0f000000) +#define V4L2_STD_1080I_59 ((v4l2_std_id)0x10000000) +#define V4L2_STD_1080P_59 ((v4l2_std_id)0x11000000) +#define V4L2_STD_1080P_30 ((v4l2_std_id)0x12000000) +#define V4L2_STD_TVOUT_720P_60_SBS_HALF ((v4l2_std_id)0x13000000) +#define V4L2_STD_TVOUT_720P_59_SBS_HALF ((v4l2_std_id)0x14000000) +#define V4L2_STD_TVOUT_720P_50_TB ((v4l2_std_id)0x15000000) +#define V4L2_STD_TVOUT_1080P_24_TB ((v4l2_std_id)0x16000000) +#define V4L2_STD_TVOUT_1080P_23_TB ((v4l2_std_id)0x17000000) +#define V4L2_STD_TVOUT_1080P_60_SBS_HALF ((v4l2_std_id)0x18000000) + +/* ------------- Input ------------------*/ +/* type */ +#define V4L2_INPUT_TYPE_MSDMA 3 +#define V4L2_INPUT_TYPE_FIFO 4 + +/******************************************* + * structures + *******************************************/ + +/* TVOUT */ +struct v4l2_vid_overlay_src { + void *base_y; + void *base_c; + struct v4l2_pix_format pix_fmt; +}; + +struct v4l2_window_s5p_tvout { + __u32 capability; + __u32 flags; + __u32 priority; + struct v4l2_window win; +}; + +struct v4l2_pix_format_s5p_tvout { + void *base_y; + void *base_c; + __u32 src_img_endian; + struct v4l2_pix_format pix_fmt; +}; + +struct vid_overlay_param { + struct v4l2_vid_overlay_src src; + struct v4l2_rect src_crop; + struct v4l2_framebuffer dst; + struct v4l2_window dst_win; +}; + +struct tvout_param { + struct v4l2_pix_format_s5p_tvout tvout_src; + struct v4l2_window_s5p_tvout tvout_rect; + struct v4l2_rect tvout_dst; +}; + +struct overlay_param { + struct v4l2_framebuffer overlay_frame; + struct v4l2_window_s5p_tvout overlay_rect; + struct v4l2_rect overlay_dst; +}; + +/* FB */ +struct s5ptvfb_user_window { + int x; + int y; +}; + +struct s5ptvfb_user_plane_alpha { + int channel; + unsigned char alpha; +}; + +struct s5ptvfb_user_chroma { + int enabled; + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +enum s5ptvfb_ver_scaling_t { + VERTICAL_X1, + VERTICAL_X2, +}; + +enum s5ptvfb_hor_scaling_t { + HORIZONTAL_X1, + HORIZONTAL_X2, +}; + +struct s5ptvfb_user_scaling { + enum s5ptvfb_ver_scaling_t ver; + enum s5ptvfb_hor_scaling_t hor; +}; + +/******************************************* + * custom ioctls + *******************************************/ + +#define VIDIOC_S_BASEADDR _IOR('V', 83, int) + +#define VIDIOC_HDCP_ENABLE _IOWR('V', 100, unsigned int) +#define VIDIOC_HDCP_STATUS _IOR('V', 101, unsigned int) +#define VIDIOC_HDCP_PROT_STATUS _IOR('V', 102, unsigned int) + +#define VIDIOC_INIT_AUDIO _IOR('V', 103, unsigned int) +#define VIDIOC_AV_MUTE _IOR('V', 104, unsigned int) +#define VIDIOC_G_AVMUTE _IOR('V', 105, unsigned int) +#define HPD_GET_STATE _IOR('H', 100, unsigned int) + +#define S5PTVFB_WIN_POSITION _IOW('F', 213, struct s5ptvfb_user_window) +#define S5PTVFB_WIN_SET_PLANE_ALPHA _IOW('F', 214, struct s5ptvfb_user_plane_alpha) +#define S5PTVFB_WIN_SET_CHROMA _IOW('F', 215, struct s5ptvfb_user_chroma) + +#define S5PTVFB_SET_VSYNC_INT _IOW('F', 216, unsigned int) +#define S5PTVFB_WAITFORVSYNC _IO('F', 32) +#define S5PTVFB_WIN_SET_ADDR _IOW('F', 219, unsigned int) +#define S5PTVFB_SET_WIN_ON _IOW('F', 220, unsigned int) +#define S5PTVFB_SET_WIN_OFF _IOW('F', 221, unsigned int) +#define S5PTVFB_SCALING _IOW('F', 222, struct s5ptvfb_user_scaling) + +#ifdef __cplusplus +} +#endif + +#endif /* __S5P_TVOUT_H__ */ diff --git a/libcec/Android.mk b/libcec/Android.mk new file mode 100644 index 0000000..763c204 --- /dev/null +++ b/libcec/Android.mk @@ -0,0 +1,25 @@ +# Copyright (C) 2012 The Android Open Source Project +# +# 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. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SRC_FILES := libcec.c + +LOCAL_MODULE := libcec +include $(BUILD_SHARED_LIBRARY) diff --git a/libcec/cec.h b/libcec/cec.h new file mode 100644 index 0000000..96d4d7f --- /dev/null +++ b/libcec/cec.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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. + */ +#ifndef _LINUX_CEC_H_ +#define _LINUX_CEC_H_ + +#define CEC_IOC_MAGIC 'c' + +/** + * CEC device request code to set logical address. + */ +#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int) + +#endif /* _LINUX_CEC_H_ */ diff --git a/libcec/libcec.c b/libcec/libcec.c new file mode 100644 index 0000000..72c545d --- /dev/null +++ b/libcec/libcec.c @@ -0,0 +1,384 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* drv. header */ +#include "cec.h" + +#include "libcec.h" + +#define CEC_DEBUG 0 + +/** + * @def CEC_DEVICE_NAME + * Defines simbolic name of the CEC device. + */ +#define CEC_DEVICE_NAME "/dev/CEC" + +static struct { + enum CECDeviceType devtype; + unsigned char laddr; +} laddresses[] = { + { CEC_DEVICE_RECODER, 1 }, + { CEC_DEVICE_RECODER, 2 }, + { CEC_DEVICE_TUNER, 3 }, + { CEC_DEVICE_PLAYER, 4 }, + { CEC_DEVICE_AUDIO, 5 }, + { CEC_DEVICE_TUNER, 6 }, + { CEC_DEVICE_TUNER, 7 }, + { CEC_DEVICE_PLAYER, 8 }, + { CEC_DEVICE_RECODER, 9 }, + { CEC_DEVICE_TUNER, 10 }, + { CEC_DEVICE_PLAYER, 11 }, +}; + +static int CECSetLogicalAddr(unsigned int laddr); + +#ifdef CEC_DEBUG +inline static void CECPrintFrame(unsigned char *buffer, unsigned int size); +#endif + +static int fd = -1; + +/** + * Open device driver and assign CEC file descriptor. + * + * @return If success to assign CEC file descriptor, return fd; otherwise, return -1. + */ +int CECOpen() +{ + if (fd != -1) + CECClose(); + + if ((fd = open(CEC_DEVICE_NAME, O_RDWR)) < 0) { + ALOGE("Can't open %s!\n", CEC_DEVICE_NAME); + return -1; + } + + return fd; +} + +/** + * Close CEC file descriptor. + * + * @return If success to close CEC file descriptor, return 1; otherwise, return 0. + */ +int CECClose() +{ + int res = 1; + + if (fd != -1) { + if (close(fd) != 0) { + ALOGE("close() failed!\n"); + res = 0; + } + fd = -1; + } + + return res; +} + +/** + * Allocate logical address. + * + * @param paddr [in] CEC device physical address. + * @param devtype [in] CEC device type. + * + * @return new logical address, or 0 if an error occured. + */ +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype) +{ + unsigned char laddr = CEC_LADDR_UNREGISTERED; + int i = 0; + + if (fd == -1) { + ALOGE("open device first!\n"); + return 0; + } + + if (CECSetLogicalAddr(laddr) < 0) { + ALOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + if (paddr == CEC_NOT_VALID_PHYSICAL_ADDRESS) + return CEC_LADDR_UNREGISTERED; + + /* send "Polling Message" */ + while (i < sizeof(laddresses) / sizeof(laddresses[0])) { + if (laddresses[i].devtype == devtype) { + unsigned char _laddr = laddresses[i].laddr; + unsigned char message = ((_laddr << 4) | _laddr); + if (CECSendMessage(&message, 1) != 1) { + laddr = _laddr; + break; + } + } + i++; + } + + if (laddr == CEC_LADDR_UNREGISTERED) { + ALOGE("All LA addresses in use!!!\n"); + return CEC_LADDR_UNREGISTERED; + } + + if (CECSetLogicalAddr(laddr) < 0) { + ALOGE("CECSetLogicalAddr() failed!\n"); + return 0; + } + + /* broadcast "Report Physical Address" */ + unsigned char buffer[5]; + buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST; + buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS; + buffer[2] = (paddr >> 8) & 0xFF; + buffer[3] = paddr & 0xFF; + buffer[4] = devtype; + + if (CECSendMessage(buffer, 5) != 5) { + ALOGE("CECSendMessage() failed!\n"); + return 0; + } + + return laddr; +} + +/** + * Send CEC message. + * + * @param *buffer [in] pointer to buffer address where message located. + * @param size [in] message size. + * + * @return number of bytes written, or 0 if an error occured. + */ +int CECSendMessage(unsigned char *buffer, int size) +{ + if (fd == -1) { + ALOGE("open device first!\n"); + return 0; + } + + if (size > CEC_MAX_FRAME_SIZE) { + ALOGE("size should not exceed %d\n", CEC_MAX_FRAME_SIZE); + return 0; + } + +#if CEC_DEBUG + ALOGI("CECSendMessage() : "); + CECPrintFrame(buffer, size); +#endif + + return write(fd, buffer, size); +} + +/** + * Receive CEC message. + * + * @param *buffer [in] pointer to buffer address where message will be stored. + * @param size [in] buffer size. + * @param timeout [in] timeout in microseconds. + * + * @return number of bytes received, or 0 if an error occured. + */ +int CECReceiveMessage(unsigned char *buffer, int size, long timeout) +{ + int bytes = 0; + fd_set rfds; + struct timeval tv; + int retval; + + if (fd == -1) { + ALOGE("open device first!\n"); + return 0; + } + + tv.tv_sec = 0; + tv.tv_usec = timeout; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + retval = select(fd + 1, &rfds, NULL, NULL, &tv); + + if (retval == -1) { + return 0; + } else if (retval) { + bytes = read(fd, buffer, size); +#if CEC_DEBUG + ALOGI("CECReceiveMessage() : size(%d)", bytes); + if(bytes > 0) + CECPrintFrame(buffer, bytes); +#endif + } + + return bytes; +} + +/** + * Set CEC logical address. + * + * @return 1 if success, otherwise, return 0. + */ +int CECSetLogicalAddr(unsigned int laddr) +{ + if (ioctl(fd, CEC_IOC_SETLADDR, &laddr)) { + ALOGE("ioctl(CEC_IOC_SETLA) failed!\n"); + return 0; + } + + return 1; +} + +#if CEC_DEBUG +/** + * Print CEC frame. + */ +void CECPrintFrame(unsigned char *buffer, unsigned int size) +{ + if (size > 0) { + int i; + ALOGI("fsize: %d ", size); + ALOGI("frame: "); + for (i = 0; i < size; i++) + ALOGI("0x%02x ", buffer[i]); + + ALOGI("\n"); + } +} +#endif + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param lsrc [in] buffer size. + * + * @return 1 if message should be ignored, otherwise, return 0. + */ +//TODO: not finished +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc) +{ + int retval = 0; + + /* if a message coming from address 15 (unregistered) */ + if (lsrc == CEC_LADDR_UNREGISTERED) { + switch (opcode) { + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + retval = 1; + default: + break; + } + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param size [in] message size. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageSize(unsigned char opcode, int size) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + if (size != 1) + retval = 0; + break; + case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE: + if (size != 2) + retval = 0; + break; + case CEC_OPCODE_PLAY: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + case CEC_OPCODE_ROUTING_INFORMATION: + case CEC_OPCODE_SET_STREAM_PATH: + if (size != 3) + retval = 0; + break; + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_DEVICE_VENDOR_ID: + case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS: + if (size != 4) + retval = 0; + break; + case CEC_OPCODE_ROUTING_CHANGE: + if (size != 5) + retval = 0; + break; + /* CDC - 1.4 */ + case 0xf8: + if (!(size > 5 && size <= 16)) + retval = 0; + break; + default: + break; + } + + return retval; +} + +/** + * Check CEC message. + * + * @param opcode [in] pointer to buffer address where message will be stored. + * @param broadcast [in] broadcast/direct message. + * + * @return 0 if message should be ignored, otherwise, return 1. + */ +//TODO: not finished +int CECCheckMessageMode(unsigned char opcode, int broadcast) +{ + int retval = 1; + + switch (opcode) { + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + case CEC_OPCODE_SET_MENU_LANGUAGE: + case CEC_OPCODE_ACTIVE_SOURCE: + if (!broadcast) + retval = 0; + break; + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + case CEC_OPCODE_DECK_CONTROL: + case CEC_OPCODE_PLAY: + case CEC_OPCODE_FEATURE_ABORT: + case CEC_OPCODE_ABORT: + if (broadcast) + retval = 0; + break; + default: + break; + } + + return retval; +} diff --git a/libcec/libcec.h b/libcec/libcec.h new file mode 100644 index 0000000..9086232 --- /dev/null +++ b/libcec/libcec.h @@ -0,0 +1,173 @@ +/* + * 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. + */ + +#ifndef _LIBCEC_H_ +#define _LIBCEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Maximum CEC frame size */ +#define CEC_MAX_FRAME_SIZE 16 +/* Not valid CEC physical address */ +#define CEC_NOT_VALID_PHYSICAL_ADDRESS 0xFFFF + +/* CEC broadcast address (as destination address) */ +#define CEC_MSG_BROADCAST 0x0F +/* CEC unregistered address (as initiator address) */ +#define CEC_LADDR_UNREGISTERED 0x0F + +/* + * CEC Messages + */ + +/* @name Messages for the One Touch Play Feature */ +#define CEC_OPCODE_ACTIVE_SOURCE 0x82 +#define CEC_OPCODE_IMAGE_VIEW_ON 0x04 +#define CEC_OPCODE_TEXT_VIEW_ON 0x0D + +/* @name Messages for the Routing Control Feature */ +#define CEC_OPCODE_INACTIVE_SOURCE 0x9D +#define CEC_OPCODE_REQUEST_ACTIVE_SOURCE 0x85 +#define CEC_OPCODE_ROUTING_CHANGE 0x80 +#define CEC_OPCODE_ROUTING_INFORMATION 0x81 +#define CEC_OPCODE_SET_STREAM_PATH 0x86 + +/* @name Messages for the Standby Feature */ +#define CEC_OPCODE_STANDBY 0x36 + +/* @name Messages for the One Touch Record Feature */ +#define CEC_OPCODE_RECORD_OFF 0x0B +#define CEC_OPCODE_RECORD_ON 0x09 +#define CEC_OPCODE_RECORD_STATUS 0x0A +#define CEC_OPCODE_RECORD_TV_SCREEN 0x0F + +/* @name Messages for the Timer Programming Feature */ +#define CEC_OPCODE_CLEAR_ANALOGUE_TIMER 0x33 +#define CEC_OPCODE_CLEAR_DIGITAL_TIMER 0x99 +#define CEC_OPCODE_CLEAR_EXTERNAL_TIMER 0xA1 +#define CEC_OPCODE_SET_ANALOGUE_TIMER 0x34 +#define CEC_OPCODE_SET_DIGITAL_TIMER 0x97 +#define CEC_OPCODE_SET_EXTERNAL_TIMER 0xA2 +#define CEC_OPCODE_SET_TIMER_PROGRAM_TITLE 0x67 +#define CEC_OPCODE_TIMER_CLEARED_STATUS 0x43 +#define CEC_OPCODE_TIMER_STATUS 0x35 + +/* @name Messages for the System Information Feature */ +#define CEC_OPCODE_CEC_VERSION 0x9E +#define CEC_OPCODE_GET_CEC_VERSION 0x9F +#define CEC_OPCODE_GIVE_PHYSICAL_ADDRESS 0x83 +#define CEC_OPCODE_GET_MENU_LANGUAGE 0x91 +//#define CEC_OPCODE_POLLING_MESSAGE +#define CEC_OPCODE_REPORT_PHYSICAL_ADDRESS 0x84 +#define CEC_OPCODE_SET_MENU_LANGUAGE 0x32 + +/* @name Messages for the Deck Control Feature */ +#define CEC_OPCODE_DECK_CONTROL 0x42 +#define CEC_OPCODE_DECK_STATUS 0x1B +#define CEC_OPCODE_GIVE_DECK_STATUS 0x1A +#define CEC_OPCODE_PLAY 0x41 + +/* @name Messages for the Tuner Control Feature */ +#define CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS 0x08 +#define CEC_OPCODE_SELECT_ANALOGUE_SERVICE 0x92 +#define CEC_OPCODE_SELECT_DIGITAL_SERVICE 0x93 +#define CEC_OPCODE_TUNER_DEVICE_STATUS 0x07 +#define CEC_OPCODE_TUNER_STEP_DECREMENT 0x06 +#define CEC_OPCODE_TUNER_STEP_INCREMENT 0x05 + +/* @name Messages for the Vendor Specific Commands Feature */ +#define CEC_OPCODE_DEVICE_VENDOR_ID 0x87 +#define CEC_OPCODE_GET_DEVICE_VENDOR_ID 0x8C +#define CEC_OPCODE_VENDOR_COMMAND 0x89 +#define CEC_OPCODE_VENDOR_COMMAND_WITH_ID 0xA0 +#define CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN 0x8A +#define CEC_OPCODE_VENDOR_REMOVE_BUTTON_UP 0x8B + +/* @name Messages for the OSD Display Feature */ +#define CEC_OPCODE_SET_OSD_STRING 0x64 + +/* @name Messages for the Device OSD Transfer Feature */ +#define CEC_OPCODE_GIVE_OSD_NAME 0x46 +#define CEC_OPCODE_SET_OSD_NAME 0x47 + +/* @name Messages for the Device Menu Control Feature */ +#define CEC_OPCODE_MENU_REQUEST 0x8D +#define CEC_OPCODE_MENU_STATUS 0x8E +#define CEC_OPCODE_USER_CONTROL_PRESSED 0x44 +#define CEC_OPCODE_USER_CONTROL_RELEASED 0x45 + +/* @name Messages for the Remote Control Passthrough Feature */ + +/* @name Messages for the Power Status Feature */ +#define CEC_OPCODE_GIVE_DEVICE_POWER_STATUS 0x8F +#define CEC_OPCODE_REPORT_POWER_STATUS 0x90 + +/* @name Messages for General Protocol messages */ +#define CEC_OPCODE_FEATURE_ABORT 0x00 +#define CEC_OPCODE_ABORT 0xFF + +/* @name Messages for the System Audio Control Feature */ +#define CEC_OPCODE_GIVE_AUDIO_STATUS 0x71 +#define CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7D +#define CEC_OPCODE_REPORT_AUDIO_STATUS 0x7A +#define CEC_OPCODE_SET_SYSTEM_AUDIO_MODE 0x72 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST 0x70 +#define CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS 0x7E + +/* @name Messages for the Audio Rate Control Feature */ +#define CEC_OPCODE_SET_AUDIO_RATE 0x9A + +/* @name CEC Operands */ + +/* TODO: not finished */ + +#define CEC_DECK_CONTROL_MODE_STOP 0x03 +#define CEC_PLAY_MODE_PLAY_FORWARD 0x24 + +/* + * @enum CECDeviceType + * Type of CEC device + */ +enum CECDeviceType { + /* TV */ + CEC_DEVICE_TV, + /* Recording Device */ + CEC_DEVICE_RECODER, + /* Tuner */ + CEC_DEVICE_TUNER, + /* Playback Device */ + CEC_DEVICE_PLAYER, + /* Audio System */ + CEC_DEVICE_AUDIO, +}; + +int CECOpen(); +int CECClose(); +int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype); +int CECSendMessage(unsigned char *buffer, int size); +int CECReceiveMessage(unsigned char *buffer, int size, long timeout); + +int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc); +int CECCheckMessageSize(unsigned char opcode, int size); +int CECCheckMessageMode(unsigned char opcode, int broadcast); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBCEC_H_ */ diff --git a/libcsc/Android.mk b/libcsc/Android.mk index 3920b4c..6fcb9e1 100644 --- a/libcsc/Android.mk +++ b/libcsc/Android.mk @@ -72,9 +72,22 @@ LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../include + +ifeq ($(TARGET_BOARD_PLATFORM),exynos3) +LOCAL_CFLAGS += -DENABLE_FIMC +LOCAL_SHARED_LIBRARIES += libexynosfimc +endif +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +LOCAL_CFLAGS += -DENABLE_FIMC +LOCAL_SHARED_LIBRARIES += libexynosfimc +endif ifeq ($(TARGET_BOARD_PLATFORM),exynos5) LOCAL_CFLAGS += -DENABLE_GSCALER LOCAL_SHARED_LIBRARIES += libexynosgscaler +ifeq ($(BOARD_USES_SCALER), true) +LOCAL_CFLAGS += -DENABLE_SCALER +LOCAL_SHARED_LIBRARIES += libexynosscaler +endif endif LOCAL_CFLAGS += -DUSE_ION diff --git a/libcsc/csc.c b/libcsc/csc.c index e494fa0..b2c8396 100644 --- a/libcsc/csc.c +++ b/libcsc/csc.c @@ -46,61 +46,75 @@ #endif #ifdef ENABLE_FIMC -#include "hwconverter_wrapper.h" +#include "exynos_fimc.h" #endif #ifdef ENABLE_GSCALER #include "exynos_gscaler.h" +#ifdef ENABLE_SCALER +#include "exynos_scaler.h" +#endif #endif #define GSCALER_IMG_ALIGN 16 -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) - -typedef enum _CSC_PLANE { - CSC_Y_PLANE = 0, - CSC_RGB_PLANE = 0, - CSC_U_PLANE = 1, - CSC_UV_PLANE = 1, - CSC_V_PLANE = 2 -} CSC_PLANE; - -typedef enum _CSC_HW_TYPE { - CSC_HW_TYPE_FIMC = 0, - CSC_HW_TYPE_GSCALER -} CSC_HW_TYPE; - -typedef struct _CSC_FORMAT { - unsigned int width; - unsigned int height; - unsigned int crop_left; - unsigned int crop_top; - unsigned int crop_width; - unsigned int crop_height; - unsigned int color_format; - unsigned int cacheable; - unsigned int mode_drm; -} CSC_FORMAT; - -typedef struct _CSC_BUFFER { - void *planes[CSC_MAX_PLANES]; - int mem_type; -} CSC_BUFFER; - -typedef struct _CSC_HW_PROPERTY { - int fixed_node; - int mode_drm; -} CSC_HW_PROPERTY; - -typedef struct _CSC_HANDLE { - CSC_FORMAT dst_format; - CSC_FORMAT src_format; - CSC_BUFFER dst_buffer; - CSC_BUFFER src_buffer; - CSC_METHOD csc_method; - CSC_HW_TYPE csc_hw_type; - void *csc_hw_handle; - CSC_HW_PROPERTY hw_property; -} CSC_HANDLE; +#define FIMC_IMG_ALIGN_WIDTH 16 +#define FIMC_IMG_ALIGN_HEIGHT 2 +#define MFC_IMG_ALIGN_WIDTH 16 + +static void copy_mfc_data(CSC_HANDLE *handle) { + int i; + char *pSrc = NULL; + char *pDst = NULL; + + switch (handle->dst_format.color_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_EXYNOS_YV12: + pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE]; + pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE]; + for (i = 0; i < handle->src_format.height; i++) { + memcpy(pDst + (handle->src_format.crop_width * i), + pSrc + (handle->src_format.width * i), + handle->src_format.crop_width); + } + + pSrc = (char *)handle->src_buffer.planes[CSC_U_PLANE]; + pDst = (char *)handle->dst_buffer.planes[CSC_U_PLANE]; + for (i = 0; i < (handle->src_format.height >> 1); i++) { + memcpy(pDst + ((handle->src_format.crop_width >> 1) * i), + pSrc + (ALIGN((handle->src_format.crop_width >> 1), MFC_IMG_ALIGN_WIDTH) * i), + (handle->src_format.crop_width >> 1)); + } + + pSrc = (char *)handle->src_buffer.planes[CSC_V_PLANE]; + pDst = (char *)handle->dst_buffer.planes[CSC_V_PLANE]; + for (i = 0; i < (handle->src_format.height >> 1); i++) { + memcpy(pDst + ((handle->src_format.crop_width >> 1) * i), + pSrc + (ALIGN((handle->src_format.crop_width >> 1), MFC_IMG_ALIGN_WIDTH) * i), + (handle->src_format.crop_width >> 1)); + } + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: + pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE]; + pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE]; + for (i = 0; i < handle->src_format.height; i++) { + memcpy(pDst + (handle->src_format.crop_width * i), + pSrc + (handle->src_format.width * i), + handle->src_format.crop_width); + } + + pSrc = (char *)handle->src_buffer.planes[CSC_UV_PLANE]; + pDst = (char *)handle->dst_buffer.planes[CSC_UV_PLANE]; + for (i = 0; i < (handle->src_format.height >> 1); i++) { + memcpy(pDst + (handle->src_format.crop_width * i), + pSrc + (handle->src_format.width * i), + handle->src_format.crop_width); + } + break; + default: + break; + } +} /* source is RGB888 */ static CSC_ERRORCODE conv_sw_src_argb888( @@ -186,15 +200,20 @@ static CSC_ERRORCODE conv_sw_src_yuv420p( switch (handle->dst_format.color_format) { case HAL_PIXEL_FORMAT_YCbCr_420_P: /* bypass */ - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], - (handle->src_format.width * handle->src_format.height) >> 2); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], - (handle->src_format.width * handle->src_format.height) >> 2); + case HAL_PIXEL_FORMAT_EXYNOS_YV12: + if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) { + copy_mfc_data(handle); + } else { + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE], + (handle->src_format.width * handle->src_format.height) >> 2); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE], + (handle->src_format.width * handle->src_format.height) >> 2); + } ret = CSC_ErrorNone; break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: @@ -235,12 +254,17 @@ static CSC_ERRORCODE conv_sw_src_yuv420sp( ret = CSC_ErrorNone; break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: /* bypass */ - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], - handle->src_format.width * handle->src_format.height); - memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], - (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], - handle->src_format.width * handle->src_format.height >> 1); + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: + if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) { + copy_mfc_data(handle); + } else { + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE], + handle->src_format.width * handle->src_format.height); + memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE], + (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE], + handle->src_format.width * handle->src_format.height >> 1); + } ret = CSC_ErrorNone; break; default: @@ -261,12 +285,14 @@ static CSC_ERRORCODE conv_sw( ret = conv_sw_src_nv12t(handle); break; case HAL_PIXEL_FORMAT_YCbCr_420_P: + case HAL_PIXEL_FORMAT_EXYNOS_YV12: ret = conv_sw_src_yuv420p(handle); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: ret = conv_sw_src_yuv420sp(handle); break; - case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: ret = conv_sw_src_argb888(handle); break; default: @@ -284,34 +310,26 @@ static CSC_ERRORCODE conv_hw( switch (handle->csc_hw_type) { #ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: - { - void *src_addr[3]; - void *dst_addr[3]; - OMX_COLOR_FORMATTYPE src_omx_format; - OMX_COLOR_FORMATTYPE dst_omx_format; - src_addr[0] = handle->src_buffer.planes[CSC_Y_PLANE]; - src_addr[1] = handle->src_buffer.planes[CSC_UV_PLANE]; - dst_addr[0] = handle->dst_buffer.planes[CSC_Y_PLANE]; - dst_addr[1] = handle->dst_buffer.planes[CSC_U_PLANE]; - dst_addr[2] = handle->dst_buffer.planes[CSC_V_PLANE]; - src_omx_format = hal_2_omx_pixel_format(handle->src_format.color_format); - dst_omx_format = hal_2_omx_pixel_format(handle->dst_format.color_format); - csc_hwconverter_convert_nv12t( - handle->csc_hw_handle, - dst_addr, - src_addr, - handle->dst_format.width, - handle->dst_format.height, - dst_omx_format, - src_omx_format); + if (exynos_fimc_convert(handle->csc_hw_handle) != 0) { + ALOGE("%s:: exynos_fimc_convert() fail", __func__); + ret = CSC_Error; + } break; - } #endif #ifdef ENABLE_GSCALER case CSC_HW_TYPE_GSCALER: - if (exynos_gsc_convert(handle->csc_hw_handle) != 0) { - ALOGE("%s:: exynos_gsc_convert() fail", __func__); - ret = CSC_Error; + if (handle->hw_property.fixed_node < CSC_HW_SC0) { + if (exynos_gsc_convert(handle->csc_hw_handle) != 0) { + ALOGE("%s:: exynos_gsc_convert() fail", __func__); + ret = CSC_Error; + } +#ifdef ENABLE_SCALER + } else { + if (exynos_sc_convert(handle->csc_hw_handle) != 0) { + ALOGE("%s:: exynos_sc_convert() fail", __func__); + ret = CSC_Error; + } +#endif } break; #endif @@ -341,16 +359,27 @@ static CSC_ERRORCODE csc_init_hw( switch (csc_handle->csc_hw_type) { #ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: - csc_handle->csc_hw_handle = csc_hwconverter_open(); + if (csc_handle->hw_property.fixed_node >= 0) + csc_handle->csc_hw_handle = exynos_fimc_create_exclusive(csc_handle->hw_property.fixed_node, FIMC_M2M_MODE, 0, 0); + else + csc_handle->csc_hw_handle = exynos_fimc_create(); ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__); break; #endif #ifdef ENABLE_GSCALER case CSC_HW_TYPE_GSCALER: - if (csc_handle->hw_property.fixed_node >= 0) - csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0); - else - csc_handle->csc_hw_handle = exynos_gsc_create(); + if (csc_handle->hw_property.fixed_node >= 0) { + if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) + csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0); +#ifdef ENABLE_SCALER + else if (csc_handle->hw_property.fixed_node < CSC_HW_MAX) + csc_handle->csc_hw_handle = exynos_sc_create(csc_handle->hw_property.fixed_node - CSC_HW_SC0); +#endif + else + csc_handle->csc_hw_handle = NULL; + } else { + csc_handle->csc_hw_handle = exynos_gsc_create(); + } ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__); break; #endif @@ -379,6 +408,7 @@ static CSC_ERRORCODE csc_set_format( { CSC_HANDLE *csc_handle; CSC_ERRORCODE ret = CSC_ErrorNone; + int narrowRgb = 0; if (handle == NULL) return CSC_ErrorNotInit; @@ -386,14 +416,12 @@ static CSC_ERRORCODE csc_set_format( csc_handle = (CSC_HANDLE *)handle; if (csc_handle->csc_method == CSC_METHOD_HW) { switch (csc_handle->csc_hw_type) { +#ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: - break; -#ifdef ENABLE_GSCALER - case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_src_format( + exynos_fimc_set_src_format( csc_handle->csc_hw_handle, - ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->src_format.width, FIMC_IMG_ALIGN_WIDTH), + ALIGN(csc_handle->src_format.height, FIMC_IMG_ALIGN_HEIGHT), csc_handle->src_format.crop_left, csc_handle->src_format.crop_top, csc_handle->src_format.crop_width, @@ -402,10 +430,10 @@ static CSC_ERRORCODE csc_set_format( csc_handle->src_format.cacheable, csc_handle->hw_property.mode_drm); - exynos_gsc_set_dst_format( + exynos_fimc_set_dst_format( csc_handle->csc_hw_handle, - ALIGN(csc_handle->dst_format.width, GSCALER_IMG_ALIGN), - ALIGN(csc_handle->dst_format.height, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->dst_format.width, FIMC_IMG_ALIGN_WIDTH), + ALIGN(csc_handle->dst_format.height, FIMC_IMG_ALIGN_HEIGHT), csc_handle->dst_format.crop_left, csc_handle->dst_format.crop_top, csc_handle->dst_format.crop_width, @@ -415,6 +443,68 @@ static CSC_ERRORCODE csc_set_format( csc_handle->hw_property.mode_drm, 0); break; +#endif +#ifdef ENABLE_GSCALER + case CSC_HW_TYPE_GSCALER: + if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) { + exynos_gsc_set_src_format( + csc_handle->csc_hw_handle, + ALIGN(csc_handle->src_format.width, GSCALER_IMG_ALIGN), + ALIGN(csc_handle->src_format.height, GSCALER_IMG_ALIGN), + csc_handle->src_format.crop_left, + csc_handle->src_format.crop_top, + csc_handle->src_format.crop_width, + csc_handle->src_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), + csc_handle->src_format.cacheable, + csc_handle->hw_property.mode_drm); + + if ((csc_handle->dst_format.color_format == HAL_PIXEL_FORMAT_YCbCr_420_SP) || + (csc_handle->dst_format.color_format == HAL_PIXEL_FORMAT_YCrCb_420_SP) ) + narrowRgb = 1; + + exynos_gsc_set_dst_format( + csc_handle->csc_hw_handle, + csc_handle->dst_format.width, + csc_handle->dst_format.height, + csc_handle->dst_format.crop_left, + csc_handle->dst_format.crop_top, + csc_handle->dst_format.crop_width, + csc_handle->dst_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), + csc_handle->dst_format.cacheable, + csc_handle->hw_property.mode_drm, + narrowRgb); +#ifdef ENABLE_SCALER + } else { + exynos_sc_set_src_format( + csc_handle->csc_hw_handle, + csc_handle->src_format.width, + csc_handle->src_format.height, + csc_handle->src_format.crop_left, + csc_handle->src_format.crop_top, + csc_handle->src_format.crop_width, + csc_handle->src_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format), + csc_handle->src_format.cacheable, + csc_handle->hw_property.mode_drm, + 1); + + exynos_sc_set_dst_format( + csc_handle->csc_hw_handle, + csc_handle->dst_format.width, + csc_handle->dst_format.height, + csc_handle->dst_format.crop_left, + csc_handle->dst_format.crop_top, + csc_handle->dst_format.crop_width, + csc_handle->dst_format.crop_height, + HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format), + csc_handle->dst_format.cacheable, + csc_handle->hw_property.mode_drm, + 1); +#endif + } + break; #endif default: ALOGE("%s:: unsupported csc_hw_type", __func__); @@ -437,12 +527,23 @@ static CSC_ERRORCODE csc_set_buffer( csc_handle = (CSC_HANDLE *)handle; if (csc_handle->csc_method == CSC_METHOD_HW) { switch (csc_handle->csc_hw_type) { +#ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: + exynos_fimc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1); + exynos_fimc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1); break; +#endif #ifdef ENABLE_GSCALER case CSC_HW_TYPE_GSCALER: - exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1); - exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1); + if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) { + exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1); + exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1); +#ifdef ENABLE_SCALER + } else { + exynos_sc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1); + exynos_sc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1); +#endif + } break; #endif default: @@ -484,12 +585,17 @@ CSC_ERRORCODE csc_deinit( switch (csc_handle->csc_hw_type) { #ifdef ENABLE_FIMC case CSC_HW_TYPE_FIMC: - csc_hwconverter_close(csc_handle->csc_hw_handle); + exynos_fimc_destroy(csc_handle->csc_hw_handle); break; #endif #ifdef ENABLE_GSCALER case CSC_HW_TYPE_GSCALER: - exynos_gsc_destroy(csc_handle->csc_hw_handle); + if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) + exynos_gsc_destroy(csc_handle->csc_hw_handle); +#ifdef ENABLE_SCALER + else + exynos_sc_destroy(csc_handle->csc_hw_handle); +#endif break; #endif default: @@ -755,12 +861,8 @@ CSC_ERRORCODE csc_convert( return ret; } -#ifdef USE_CONVERT_WITH_ROTATE CSC_ERRORCODE csc_convert_with_rotation( - void *handle, - int rot, - int flip_horiz, - int flip_vert) + void *handle, int rotation, int flip_horizontal, int flip_vertical) { CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle; CSC_ERRORCODE ret = CSC_ErrorNone; @@ -775,8 +877,17 @@ CSC_ERRORCODE csc_convert_with_rotation( csc_set_format(csc_handle); csc_set_buffer(csc_handle); - exynos_gsc_set_rotation(csc_handle->csc_hw_handle, - rot, flip_horiz, flip_vert); +#ifdef ENABLE_FIMC + exynos_fimc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical); +#endif +#ifdef ENABLE_GSCALER + if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) + exynos_gsc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical); +#ifdef ENABLE_SCALER + else + exynos_sc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical); +#endif +#endif if (csc_handle->csc_method == CSC_METHOD_HW) ret = conv_hw(csc_handle); @@ -785,4 +896,3 @@ CSC_ERRORCODE csc_convert_with_rotation( return ret; } -#endif diff --git a/libcsc/csc_helper.c b/libcsc/csc_helper.c index d08df4c..ce8521b 100644 --- a/libcsc/csc_helper.c +++ b/libcsc/csc_helper.c @@ -19,7 +19,7 @@ #include #include - +#include #include "Exynos_OMX_Def.h" #include "csc.h" @@ -45,9 +45,18 @@ OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format( case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: omx_format = OMX_SEC_COLOR_FormatNV12Tiled; break; - case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: omx_format = OMX_COLOR_Format32bitARGB8888; break; + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: + omx_format = OMX_SEC_COLOR_FormatNV21Linear; + break; + case HAL_PIXEL_FORMAT_EXYNOS_YV12: + omx_format = OMX_SEC_COLOR_FormatYVU420Planar; + break; + case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888: + omx_format = OMX_COLOR_Format32bitBGRA8888; + break; default: omx_format = OMX_COLOR_FormatYUV420Planar; break; @@ -76,7 +85,16 @@ unsigned int omx_2_hal_pixel_format( hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; break; case OMX_COLOR_Format32bitARGB8888: - hal_format = HAL_PIXEL_FORMAT_RGBA_8888; + hal_format = HAL_PIXEL_FORMAT_BGRA_8888; + break; + case OMX_SEC_COLOR_FormatNV21Linear: + hal_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP; + break; + case OMX_SEC_COLOR_FormatYVU420Planar: + hal_format = HAL_PIXEL_FORMAT_EXYNOS_YV12; + break; + case OMX_COLOR_Format32bitBGRA8888: + hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888; break; default: hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P; diff --git a/libexynosutils/Android.mk b/libexynosutils/Android.mk index c95e74b..6858eab 100644 --- a/libexynosutils/Android.mk +++ b/libexynosutils/Android.mk @@ -30,12 +30,18 @@ LOCAL_SRC_FILES := ExynosMutex.cpp \ LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libexynosutils -ifeq ($(TARGET_BOARD_PLATFORM), exynos5) -LOCAL_SRC_FILES += exynos5_format_v4l2.c +LOCAL_SRC_FILES += exynos_format_v4l2.c LOCAL_C_INCLUDES += \ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \ $(LOCAL_PATH)/../include + LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +ifeq ($(TARGET_BOARD_PLATFORM),exynos3) +LOCAL_CFLAGS += -DENABLE_FIMC +endif +ifeq ($(TARGET_BOARD_PLATFORM),exynos4) +LOCAL_CFLAGS += -DENABLE_FIMC endif include $(BUILD_SHARED_LIBRARY) diff --git a/libexynosutils/ExynosMutex.cpp b/libexynosutils/ExynosMutex.cpp index c0020ed..b310b94 100644 --- a/libexynosutils/ExynosMutex.cpp +++ b/libexynosutils/ExynosMutex.cpp @@ -47,6 +47,7 @@ ExynosMutex::ExynosMutex() m_mutex = NULL; m_flagCreate = false; m_type = TYPE_BASE; + memset(m_name, 0, 128); } ExynosMutex::~ExynosMutex() @@ -85,7 +86,7 @@ bool ExynosMutex::create(int type, char* name) } m_type = type; - strcpy(m_name, name); + strncpy(m_name, name, 128 - 1); m_flagCreate = true; diff --git a/libexynosutils/exynos5_format_v4l2.c b/libexynosutils/exynos_format_v4l2.c similarity index 94% rename from libexynosutils/exynos5_format_v4l2.c rename to libexynosutils/exynos_format_v4l2.c index 8c30826..b818010 100644 --- a/libexynosutils/exynos5_format_v4l2.c +++ b/libexynosutils/exynos_format_v4l2.c @@ -41,6 +41,8 @@ #include "exynos_format.h" #include "s5p_fimc_v4l2.h" #include +#include +#include int HAL_PIXEL_FORMAT_2_V4L2_PIX( int hal_pixel_format) @@ -65,14 +67,6 @@ int HAL_PIXEL_FORMAT_2_V4L2_PIX( v4l2_pixel_format = V4L2_PIX_FMT_BGR32; break; - case HAL_PIXEL_FORMAT_RGBA_5551: - v4l2_pixel_format = V4L2_PIX_FMT_RGB555X; - break; - - case HAL_PIXEL_FORMAT_RGBA_4444: - v4l2_pixel_format = V4L2_PIX_FMT_RGB444; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YV12: v4l2_pixel_format = V4L2_PIX_FMT_YVU420M; break; @@ -121,12 +115,20 @@ int HAL_PIXEL_FORMAT_2_V4L2_PIX( break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: - v4l2_pixel_format = V4L2_PIX_FMT_NV12MT_16X16; - break; +#ifdef ENABLE_FIMC + v4l2_pixel_format = V4L2_PIX_FMT_NV12MT; +#else + v4l2_pixel_format = V4L2_PIX_FMT_NV12MT_16X16; +#endif + break; case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: - v4l2_pixel_format = V4L2_PIX_FMT_NV12MT_16X16; - break; +#ifdef ENABLE_FIMC + v4l2_pixel_format = V4L2_PIX_FMT_NV12MT; +#else + v4l2_pixel_format = V4L2_PIX_FMT_NV12MT_16X16; +#endif + break; case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: v4l2_pixel_format = V4L2_PIX_FMT_YVYU; @@ -167,14 +169,6 @@ int V4L2_PIX_2_HAL_PIXEL_FORMAT( hal_pixel_format = HAL_PIXEL_FORMAT_BGRA_8888; break; - case V4L2_PIX_FMT_RGB555X: - hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_5551; - break; - - case V4L2_PIX_FMT_RGB444: - hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_4444; - break; - case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV420M: hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_P; @@ -219,8 +213,8 @@ int V4L2_PIX_2_HAL_PIXEL_FORMAT( case V4L2_PIX_FMT_NV21: hal_pixel_format = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP; break; + case V4L2_PIX_FMT_NV12MT: case V4L2_PIX_FMT_NV12MT_16X16: - hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED; break; @@ -279,8 +273,6 @@ unsigned int FRAME_SIZE( switch (hal_pixel_format) { // 16bpp case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_RGBA_5551: - case HAL_PIXEL_FORMAT_RGBA_4444: frame_size = GET_16BPP_FRAME_SIZE(width, height); break; @@ -400,6 +392,7 @@ int V4L2_PIX_2_YUV_INFO(unsigned int v4l2_pixel_format, unsigned int * bpp, unsi case V4L2_PIX_FMT_NV21X: case V4L2_PIX_FMT_NV12M: case V4L2_PIX_FMT_NV21M: + case V4L2_PIX_FMT_NV12MT: case V4L2_PIX_FMT_NV12MT_16X16: *bpp = 12; *planes = 2; @@ -407,6 +400,7 @@ int V4L2_PIX_2_YUV_INFO(unsigned int v4l2_pixel_format, unsigned int * bpp, unsi case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV420M: case V4L2_PIX_FMT_YVU420M: + case V4L2_PIX_FMT_YVU420: *bpp = 12; *planes = 3; break; @@ -436,7 +430,7 @@ int V4L2_PIX_2_YUV_INFO(unsigned int v4l2_pixel_format, unsigned int * bpp, unsi return 0; } -unsigned int get_yuv_bpp(unsigned int v4l2_pixel_format) +int get_yuv_bpp(unsigned int v4l2_pixel_format) { unsigned int bpp, planes; @@ -446,7 +440,7 @@ unsigned int get_yuv_bpp(unsigned int v4l2_pixel_format) return bpp; } -unsigned int get_yuv_planes(unsigned int v4l2_pixel_format) +int get_yuv_planes(unsigned int v4l2_pixel_format) { unsigned int bpp, planes; diff --git a/libfimg4x/Android.mk b/libfimg4x/Android.mk index 5ec3060..688729a 100644 --- a/libfimg4x/Android.mk +++ b/libfimg4x/Android.mk @@ -17,6 +17,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-insignal + ifeq ($(BOARD_USES_SKIA_FIMGAPI),true) LOCAL_MODULE_TAGS := optional @@ -26,7 +28,9 @@ LOCAL_SRC_FILES:= \ LOCAL_C_INCLUDES += \ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \ - $(LOCAL_PATH)/../include + $(LOCAL_PATH)/../include \ + hardware/samsung_slsi/$(TARGET_SOC)/include \ + hardware/samsung_slsi/$(PLATFORM_DIR)/include LOCAL_ADDITIONAL_DEPENDENCIES := \ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr diff --git a/libfimg4x/FimgApi.cpp b/libfimg4x/FimgApi.cpp index 8cca61c..c0a6d4b 100644 --- a/libfimg4x/FimgApi.cpp +++ b/libfimg4x/FimgApi.cpp @@ -247,6 +247,145 @@ extern "C" int stretchFimgApi(struct fimg2d_blit *cmd) return 0; } +extern "C" int stretchFimgApi_fast(struct fimg2d_blit *cmd, unsigned long tmpbuf_addr, int tmpbuf_size) +{ + if (tmpbuf_addr == 0 || tmpbuf_size <= 0) + return stretchFimgApi(cmd); + + /* scaling & rotation only */ + if (cmd->param.rotate == ORIGIN || cmd->param.scaling.mode == NO_SCALING) + return stretchFimgApi(cmd); + + /* src & dst only */ + if (cmd->src == NULL || cmd->msk != NULL) + return stretchFimgApi(cmd); + + /* a(x)rgb8888 src only */ + if (cmd->src->fmt >= CF_RGB_565) + return stretchFimgApi(cmd); + + FimgApi * fimgApi = createFimgApi(); + + if (fimgApi == NULL) { + PRINT("%s::createFimgApi() fail\n", __func__); + return -1; + } + + bool is_scaledown, sr_w, sr_h; + struct fimg2d_image tmpbuf; + struct fimg2d_blit cmd1st, cmd2nd; + struct fimg2d_param *p; + + /* check is_scaledown */ + p = &cmd->param; + sr_w = p->scaling.src_w - p->scaling.dst_w; + sr_h = p->scaling.src_h - p->scaling.dst_h; + is_scaledown = (sr_w + sr_h > 0) ? true : false; + + if (is_scaledown) { + /* set temp buffer */ + tmpbuf.width = cmd->dst->rect.y2 - cmd->dst->rect.y1; + tmpbuf.height = cmd->dst->rect.x2 - cmd->dst->rect.x1; + tmpbuf.stride = tmpbuf.width * 4; + tmpbuf.order = cmd->src->order; + tmpbuf.fmt = cmd->src->fmt; + tmpbuf.addr.type = cmd->src->addr.type; + tmpbuf.addr.start = tmpbuf_addr; + tmpbuf.plane2.type = ADDR_NONE; + tmpbuf.rect.x1 = 0; + tmpbuf.rect.y1 = 0; + tmpbuf.rect.x2 = tmpbuf.width; + tmpbuf.rect.y2 = tmpbuf.height; + tmpbuf.need_cacheopr = false; + + /* 1st step : copy with scaling down */ + p = &cmd1st.param; + memcpy(p, &cmd->param, sizeof(cmd->param)); + p->rotate = ORIGIN; + p->g_alpha = 0xff; + p->dither = false; + cmd1st.op = BLIT_OP_SRC; + cmd1st.src = cmd->src; + cmd1st.dst = &tmpbuf; + cmd1st.msk = NULL; + cmd1st.tmp = NULL; + cmd1st.sync = BLIT_SYNC; + cmd1st.seq_no = cmd->seq_no; + + /* 2nd step : op with rotation */ + p = &cmd2nd.param; + memcpy(p, &cmd->param, sizeof(cmd->param)); + p->scaling.mode = NO_SCALING; + cmd2nd.op = cmd->op; + cmd2nd.src = &tmpbuf; + cmd2nd.dst = cmd->dst; + cmd2nd.msk = NULL; + cmd2nd.tmp = NULL; + cmd2nd.sync = BLIT_SYNC; + cmd2nd.seq_no = cmd->seq_no; + } else { + /* set temp buffer */ + tmpbuf.width = cmd->src->rect.y2 - cmd->src->rect.y1; + tmpbuf.height = cmd->src->rect.x2 - cmd->src->rect.x1; + tmpbuf.stride = tmpbuf.width * 4; + tmpbuf.order = cmd->src->order; + tmpbuf.fmt = cmd->src->fmt; + tmpbuf.addr.type = cmd->src->addr.type; + tmpbuf.addr.start = tmpbuf_addr; + tmpbuf.plane2.type = ADDR_NONE; + tmpbuf.rect.x1 = 0; + tmpbuf.rect.y1 = 0; + tmpbuf.rect.x2 = tmpbuf.width; + tmpbuf.rect.y2 = tmpbuf.height; + tmpbuf.need_cacheopr = false; + + /* 1st step : copy with rotation */ + p = &cmd1st.param; + memcpy(p, &cmd->param, sizeof(cmd->param)); + p->scaling.mode = NO_SCALING; + p->g_alpha = 0xff; + p->dither = false; + cmd1st.op = BLIT_OP_SRC; + cmd1st.src = cmd->src; + cmd1st.dst = &tmpbuf; + cmd1st.msk = NULL; + cmd1st.tmp = NULL; + cmd1st.sync = BLIT_SYNC; + cmd1st.seq_no = cmd->seq_no; + + /* 2nd step : op with scaling up */ + p = &cmd2nd.param; + memcpy(p, &cmd->param, sizeof(cmd->param)); + p->rotate = ORIGIN; + cmd2nd.op = cmd->op; + cmd2nd.src = &tmpbuf; + cmd2nd.dst = cmd->dst; + cmd2nd.msk = NULL; + cmd2nd.tmp = NULL; + cmd2nd.sync = BLIT_SYNC; + cmd2nd.seq_no = cmd->seq_no; + } + + /* 1st step blit */ + if (fimgApi->Stretch(&cmd1st) == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + return -1; + } + + /* 2nd step blit */ + if (fimgApi->Stretch(&cmd2nd) == false) { + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + return -1; + } + + if (fimgApi != NULL) + destroyFimgApi(fimgApi); + + return 0; +} + extern "C" int SyncFimgApi(void) { FimgApi * fimgApi = createFimgApi(); diff --git a/libfimg4x/FimgExynos5.cpp b/libfimg4x/FimgExynos5.cpp index 4b25edb..be11319 100644 --- a/libfimg4x/FimgExynos5.cpp +++ b/libfimg4x/FimgExynos5.cpp @@ -22,6 +22,7 @@ #include #include "FimgExynos5.h" +#include "sec_g2d_comp.h" namespace android { @@ -296,4 +297,11 @@ extern "C" void destroyFimgApi(FimgApi * ptrFimgApi) // Dont' call DestroyInstance. } +extern "C" bool compromiseFimgApi(struct compromise_param * param) +{ + if ((param->clipW * param->clipH) < comp_value[param->src_fmt][param->dst_fmt][param->isScaling][param->isFilter][param->isSrcOver]) + return false; + return true; +} + }; // namespace android diff --git a/libv4l2/exynos_mc.c b/libv4l2/exynos_mc.c index 759eb51..e6a335a 100644 --- a/libv4l2/exynos_mc.c +++ b/libv4l2/exynos_mc.c @@ -175,7 +175,7 @@ static int __media_get_devname_sysfs(struct media_entity *entity) entity->info.v4l.minor); ret = readlink(sysname, target, sizeof(target)); - if (ret < 0) + if (ret < 0 || ret >= sizeof(target)) return -errno; target[ret] = '\0'; @@ -186,7 +186,7 @@ static int __media_get_devname_sysfs(struct media_entity *entity) snprintf(devname, sizeof(devname), "/tmp/%s", p + 1); ret = mknod(devname, 0666 | S_IFCHR, MKDEV(81, entity->info.v4l.minor)); - strncpy(entity->devname, devname, 32); + strncpy(entity->devname, devname, sizeof(devname) - 1); return 0; } diff --git a/libv4l2/exynos_subdev.c b/libv4l2/exynos_subdev.c index 0f4f3a2..e5552bb 100644 --- a/libv4l2/exynos_subdev.c +++ b/libv4l2/exynos_subdev.c @@ -91,6 +91,10 @@ int exynos_subdev_get_node_num(const char *devname, int oflag, ...) ALOGD("try node: %s, minor: %d", filename, minor); /* open sysfs entry */ snprintf(filename, sizeof(filename), "/sys/class/video4linux/v4l-subdev%d/name", minor); + if (S_ISLNK(s.st_mode)) { + ALOGE("symbolic link detected"); + return -1; + } stream_fd = fopen(filename, "r"); if (stream_fd == NULL) { ALOGE("failed to open sysfs entry for subdev"); @@ -146,6 +150,10 @@ int exynos_subdev_open_devname(const char *devname, int oflag, ...) ALOGD("try node: %s, minor: %d", filename, minor); /* open sysfs entry */ snprintf(filename, sizeof(filename), "/sys/class/video4linux/v4l-subdev%d/name", minor); + if (S_ISLNK(s.st_mode)) { + ALOGE("symbolic link detected"); + return -1; + } stream_fd = fopen(filename, "r"); if (stream_fd == NULL) { ALOGE("failed to open sysfs entry for subdev"); @@ -170,7 +178,7 @@ int exynos_subdev_open_devname(const char *devname, int oflag, ...) } while (found == false); if (found) { - sprintf(filename, "/dev/v4l-subdev%d", minor); + snprintf(filename, sizeof(filename), "/dev/v4l-subdev%d", minor); va_start(ap, oflag); fd = __subdev_open(filename, oflag, ap); va_end(ap); diff --git a/libv4l2/exynos_v4l2.c b/libv4l2/exynos_v4l2.c index b54766d..3d380bd 100644 --- a/libv4l2/exynos_v4l2.c +++ b/libv4l2/exynos_v4l2.c @@ -130,6 +130,10 @@ int exynos_v4l2_open_devname(const char *devname, int oflag, ...) ALOGD("try node: %s, minor: %d", filename, minor); /* open sysfs entry */ snprintf(filename, sizeof(filename), "/sys/class/video4linux/video%d/name", minor); + if (S_ISLNK(s.st_mode)) { + ALOGE("symbolic link detected"); + return -1; + } stream_fd = fopen(filename, "r"); if (stream_fd == NULL) { ALOGE("failed to open sysfs entry for videodev"); @@ -154,7 +158,7 @@ int exynos_v4l2_open_devname(const char *devname, int oflag, ...) } while (found == false); if (found) { - sprintf(filename, "/dev/video%d", minor); + snprintf(filename, sizeof(filename), "/dev/video%d", minor); va_start(ap, oflag); fd = __v4l2_open(filename, oflag, ap); va_end(ap); -- 2.20.1