├── .gitignore ├── Makefile ├── Rules.make ├── include ├── ion.h ├── libnxjpeghw.h ├── nx_align.h ├── nx_alloc_mem.h ├── nx_dsp.h ├── nx_fourcc.h ├── nx_video_api.h ├── nx_video_rate_ctrl.h ├── nx_vip.h ├── nxp-v4l2.h └── vpu_types.h ├── kernel-headers ├── linux │ ├── ion.h │ ├── media.h │ ├── nxp_ion.h │ ├── v4l2-mediabus.h │ ├── v4l2-subdev.h │ ├── videodev2.h │ └── videodev2_nxp_media.h ├── mach │ ├── ioc_magic.h │ └── nxp-scaler.h └── media │ └── videobuf2-ion-nxp.h ├── libion ├── Makefile └── ion.c ├── libnxmalloc ├── Makefile └── nx_alloc_mem_ion.c ├── libnxv4l2 ├── Makefile ├── nx_dsp.cpp ├── nx_vip.cpp ├── nxp-v4l2-dev.cpp ├── nxp-v4l2-dev.h ├── nxp-v4l2-media.cpp ├── nxp-v4l2-media.h ├── nxp-v4l2-private.cpp └── nxp-v4l2.cpp ├── libnxvpu ├── Makefile ├── api_osapi.h ├── nx_video_api.c ├── parser_vld.c ├── parser_vld.h └── vpu_drv_ioctl.h ├── nanocam_opencv ├── Makefile ├── nanocam_opencv.cpp ├── yuv2rgb.neon.S └── yuv2rgb.neon.h ├── nanocams ├── .gitignore ├── Makefile ├── NXJpegHWEnc.cpp └── nanocams.cpp └── prebuilt └── libnxvidrc.so /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Don't add files that are generated in specific 3 | # subdirectories here. Add them in the ".gitignore" file 4 | # in that subdirectory instead. 5 | # 6 | # Normal rules 7 | # 8 | 9 | *.rej 10 | *.orig 11 | *~ 12 | *.diff 13 | 14 | # 15 | # Top-level generic files 16 | # 17 | 18 | /out 19 | 20 | # 21 | # Generated files 22 | # 23 | 24 | *.o 25 | *.a 26 | *.lo 27 | *.la 28 | *.log 29 | *.so 30 | .depend 31 | 32 | # cscope files 33 | cscope.* 34 | 35 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------- 2 | # Makefile for building nexell libs and camera demo 3 | # 4 | # Copyright 2016 FriendlyARM (http://www.friendlyarm.com/) 5 | # 6 | 7 | # Do not: 8 | # o use make's built-in rules and variables 9 | # (this increases performance and avoids hard-to-debug behaviour); 10 | # o print "Entering directory ..."; 11 | MAKEFLAGS += 12 | 13 | # ----------------------------------------------------------------------- 14 | # Checking host machine 15 | 16 | ifneq (armv7l,$(shell uname -m)) 17 | CROSS_COMPILE ?= arm-linux- 18 | GCC := $(CROSS_COMPILE)gcc 19 | 20 | # Checking gcc version, it *MUST BE* 4.9.3 for cross compile 21 | GCC_VERSION_A = $(shell $(GCC) -dumpversion) 22 | ifneq (4.9.3,$(GCC_VERSION_A)) 23 | $(warning *** $(GCC) $(GCC_VERSION_A) is *NOT* supported, please) 24 | $(warning *** switch it to "4.9.3" and try again.) 25 | $(error stopping build) 26 | endif 27 | 28 | else 29 | CROSS_COMPILE ?= 30 | endif # End of machine - `armv7l' 31 | 32 | export CROSS_COMPILE 33 | 34 | # ----------------------------------------------------------------------- 35 | 36 | LIBS := libion libnxmalloc libnxv4l2 libnxvpu 37 | APPS := nanocams 38 | 39 | SUBDIRS = $(LIBS) $(APPS) 40 | 41 | PHONY += $(SUBDIRS) 42 | 43 | # ----------------------------------------------------------------------- 44 | PHONY += all 45 | all: $(SUBDIRS) 46 | 47 | 48 | $(SUBDIRS): 49 | @if [ -f $@/Makefile ]; then \ 50 | $(MAKE) -C $@; \ 51 | fi 52 | 53 | libnxmalloc: libion 54 | 55 | libnxvpu: libnxv4l2 56 | 57 | nanocams: $(LIBS) 58 | 59 | 60 | install: $(SUBDIRS) 61 | @for d in $(SUBDIRS); do $(MAKE) -C $${d} $@; done 62 | 63 | clean distclean: 64 | @for d in $(SUBDIRS); do $(MAKE) -C $${d} $@; done 65 | 66 | # ----------------------------------------------------------------------- 67 | 68 | # Declare the contents of the .PHONY variable as phony. We keep that 69 | # information in a variable so we can use it in if_changed and friends. 70 | .PHONY: $(PHONY) install clean distclean 71 | 72 | # End of file 73 | # vim: syntax=make 74 | 75 | -------------------------------------------------------------------------------- /Rules.make: -------------------------------------------------------------------------------- 1 | ######################################################################### 2 | # Embedded Linux Build Enviornment: 3 | # 4 | OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) 5 | BASEDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 6 | 7 | ######################################################################### 8 | # Toolchain 9 | CROSS_COMPILE ?= arm-linux- 10 | CC := $(CROSS_COMPILE)gcc 11 | CXX := $(CROSS_COMPILE)g++ 12 | AR := $(CROSS_COMPILE)ar 13 | AS := $(CROSS_COMPILE)as 14 | LD := $(CROSS_COMPILE)ld 15 | NM := $(CROSS_COMPILE)nm 16 | RANLIB := $(CROSS_COMPILE)ranlib 17 | OBJCOPY := $(CROSS_COMPILE)objcopy 18 | STRIP := $(CROSS_COMPILE)strip 19 | 20 | ######################################################################### 21 | # Library & Header macro 22 | INCLUDE := 23 | 24 | ######################################################################### 25 | # Build Options 26 | OPTS := -O2 -Wall -Wextra \ 27 | -Wcast-align -Wno-unused-parameter -Wshadow -Wwrite-strings \ 28 | -Wcast-qual -fno-strict-aliasing -fstrict-overflow -fsigned-char \ 29 | -fno-omit-frame-pointer -fno-optimize-sibling-calls 30 | COPTS := $(OPTS) 31 | CPPOPTS := $(OPTS) -Wnon-virtual-dtor 32 | 33 | CFLAGS := $(COPTS) 34 | CPPFLAGS := $(CPPOPTS) 35 | AFLAGS := 36 | 37 | ARFLAGS := crv 38 | LDFLAGS := 39 | LIBRARY := 40 | 41 | ######################################################################### 42 | # Generic Rules 43 | %.o: %.c 44 | $(CC) $(CFLAGS) $(INCLUDE) -c -o $@ $< 45 | 46 | %.o: %.s 47 | $(AS) $(AFLAGS) $(INCLUDE) -c -o $@ $< 48 | 49 | %.o: %.cpp 50 | $(CXX) $(CPPFLAGS) $(INCLUDE) -c -o $@ $< 51 | 52 | -------------------------------------------------------------------------------- /include/ion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ion.c 3 | * 4 | * Memory Allocator functions for ion 5 | * 6 | * Copyright 2011 Google, Inc 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #ifndef __SYS_CORE_ION_H 22 | #define __SYS_CORE_ION_H 23 | 24 | #include 25 | 26 | __BEGIN_DECLS 27 | 28 | int ion_open(); 29 | int ion_close(int fd); 30 | int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask, 31 | unsigned int flags, struct ion_handle **handle); 32 | int ion_alloc_fd(int fd, size_t len, size_t align, unsigned int heap_mask, 33 | unsigned int flags, int *handle_fd); 34 | int ion_sync_fd(int fd, int handle_fd); 35 | int ion_free(int fd, struct ion_handle *handle); 36 | int ion_map(int fd, struct ion_handle *handle, size_t length, int prot, 37 | int flags, off_t offset, unsigned char **ptr, int *map_fd); 38 | int ion_share(int fd, struct ion_handle *handle, int *share_fd); 39 | int ion_import(int fd, int share_fd, struct ion_handle **handle); 40 | int ion_get_phys(int fd, int buf_fd, unsigned long *phys); 41 | 42 | __END_DECLS 43 | 44 | #endif /* __SYS_CORE_ION_H */ 45 | -------------------------------------------------------------------------------- /include/libnxjpeghw.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBNXJPEGHW_H 2 | #define _LIBNXJPEGHW_H 3 | 4 | int NX_JpegHWEncoding(void *dstVirt, int dstSize, 5 | int width, int height, unsigned int fourcc, 6 | unsigned int yPhy, unsigned int yVirt, unsigned int yStride, 7 | unsigned int cbPhy, unsigned int cbVirt, unsigned int cbStride, 8 | unsigned int crPhy, unsigned int crVirt, unsigned int crStride, 9 | bool copySOI = true); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /include/nx_align.h: -------------------------------------------------------------------------------- 1 | #ifndef __NEXELL_ALIGN_H__ 2 | #define __NEXELL_ALIGN_H__ 1 3 | 4 | #ifndef ALIGN 5 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 6 | #endif 7 | 8 | #define YUV_STRIDE_ALIGN_FACTOR 64 9 | #define YUV_VSTRIDE_ALIGN_FACTOR 16 10 | 11 | #define YUV_STRIDE(w) ALIGN(w, YUV_STRIDE_ALIGN_FACTOR) 12 | #define YUV_YSTRIDE(w) (ALIGN(w/2, YUV_STRIDE_ALIGN_FACTOR) * 2) 13 | #define YUV_VSTRIDE(h) ALIGN(h, YUV_VSTRIDE_ALIGN_FACTOR) 14 | 15 | #endif /* __NEXELL_ALIGN_H__ */ 16 | -------------------------------------------------------------------------------- /include/nx_alloc_mem.h: -------------------------------------------------------------------------------- 1 | #ifndef __NX_ALLOC_MEM_H__ 2 | #define __NX_ALLOC_MEM_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | //---------------------------------------------------------------------------- 9 | // Enum & Define 10 | enum { 11 | NX_MEM_MAP_LINEAR = 0, // Linear Memory Type 12 | NX_MEM_MAP_TILED = 1, // Tiled Memory Type 13 | }; 14 | 15 | 16 | // 17 | // Nexell Private Memory Type 18 | // 19 | typedef struct 20 | { 21 | void *privateDesc; 22 | int align; 23 | int size; 24 | unsigned int virAddr; 25 | unsigned int phyAddr; 26 | } NX_MEMORY_INFO, *NX_MEMORY_HANDLE; 27 | 28 | 29 | 30 | // 31 | // Nexell Private Video Memory Type 32 | // 33 | typedef struct 34 | { 35 | void *privateDesc[3];// Private Descriptor( for allocator's handle or descriptor ) 36 | int align; // Start Address Align( L/Cb/Cr ) 37 | int memoryMap; // Memory Map Type( Linear or Tiled,. etc, N/A ) 38 | unsigned int fourCC; // Four Charect Code 39 | int imgWidth; // Video Image's Width 40 | int imgHeight; // Video Image's Height 41 | 42 | unsigned int luPhyAddr; 43 | unsigned int luVirAddr; 44 | unsigned int luStride; 45 | 46 | unsigned int cbPhyAddr; 47 | unsigned int cbVirAddr; 48 | unsigned int cbStride; 49 | 50 | unsigned int crPhyAddr; 51 | unsigned int crVirAddr; 52 | unsigned int crStride; 53 | } NX_VID_MEMORY_INFO, *NX_VID_MEMORY_HANDLE; 54 | 55 | 56 | 57 | // Nexell Private Memory Allocator 58 | NX_MEMORY_HANDLE NX_AllocateMemory( int size, int align ); 59 | void NX_FreeMemory( NX_MEMORY_HANDLE handle ); 60 | 61 | 62 | // Video Specific Allocator Wrapper 63 | NX_VID_MEMORY_HANDLE NX_VideoAllocateMemory( int align, int width, int height, int memMap, int fourCC ); 64 | void NX_FreeVideoMemory( NX_VID_MEMORY_HANDLE handle ); 65 | 66 | // For Interlace Camera 3 plane only 67 | NX_VID_MEMORY_HANDLE NX_VideoAllocateMemory2( int align, int width, int height, int memMap, int fourCC ); 68 | 69 | 70 | #ifdef __cplusplus 71 | }; 72 | #endif 73 | 74 | #endif // __NX_ALLOC_MEM_H__ 75 | -------------------------------------------------------------------------------- /include/nx_dsp.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (C) 2013 Nexell Co. All Rights Reserved 4 | // Nexell Co. Proprietary & Confidential 5 | // 6 | // NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE 7 | // AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING 8 | // BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS 9 | // FOR A PARTICULAR PURPOSE. 10 | // 11 | // Module : 12 | // File : 13 | // Description : 14 | // Author : 15 | // Export : 16 | // History : 17 | // 18 | //------------------------------------------------------------------------------ 19 | 20 | #ifndef __NX_DSP_H__ 21 | #define __NX_DSP_H__ 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #define DISPLAY_MAX_BUF_SIZE 2 29 | 30 | //#define DISABLE_PORT_CONFIG 31 | 32 | enum { 33 | DISPLAY_PORT_LCD = 0x00, 34 | DISPLAY_PORT_HDMI = 0x01, 35 | DISPLAY_PORT_TVOUT = 0x02, // S5P6818 Only 36 | }; 37 | 38 | enum { 39 | DISPLAY_MODULE_MLC0 = 0x00, 40 | DISPLAY_MODULE_MLC1 = 0x01, 41 | DISPLAY_MODULE_MLC0_RGB = 0x02, 42 | DISPLAY_MODULE_MLC1_RGB = 0x03, 43 | }; 44 | 45 | typedef struct DSP_IMG_RECT { 46 | int32_t left; 47 | int32_t top; 48 | int32_t right; 49 | int32_t bottom; 50 | } DSP_IMG_RECT; 51 | 52 | typedef struct DISPLAY_INFO { 53 | int32_t port; // port ( DISPLAY_PORT_LCD or DISPLAY_PORT_HDMI ) 54 | int32_t module; // module ( DISPLAY_MODULE_MLC0 or DISPLAY_MODULE_MLC1 ) 55 | 56 | int32_t width; // source width 57 | int32_t height; // source height 58 | int32_t stride; // source image's strid 59 | int32_t fourcc; // source image's format fourcc 60 | int32_t numPlane; // source image's plane number 61 | 62 | DSP_IMG_RECT dspSrcRect; // source image's crop region 63 | DSP_IMG_RECT dspDstRect; // target display rect 64 | } DISPLAY_INFO; 65 | 66 | typedef struct DISPLAY_HANDLE_INFO *DISPLAY_HANDLE; 67 | 68 | #ifdef __cplusplus 69 | extern "C"{ 70 | #endif 71 | 72 | DISPLAY_HANDLE NX_DspInit ( DISPLAY_INFO *pDspInfo ); 73 | void NX_DspClose ( DISPLAY_HANDLE hDisplay ); 74 | int32_t NX_DspStreamControl ( DISPLAY_HANDLE hDisplay, int32_t bEnable ); 75 | 76 | int32_t NX_DspQueueBuffer ( DISPLAY_HANDLE hDisplay, NX_VID_MEMORY_INFO *pVidBuf ); 77 | int32_t NX_DspRgbQueueBuffer ( DISPLAY_HANDLE hDisplay, NX_MEMORY_INFO *pMemInfo ); 78 | int32_t NX_DspDequeueBuffer ( DISPLAY_HANDLE hDisplay ); 79 | 80 | int32_t NX_DspVideoSetSourceFormat ( DISPLAY_HANDLE hDisplay, int32_t width, int32_t height, int32_t stride, int32_t fourcc ); 81 | int32_t NX_DspVideoSetSourceCrop ( DISPLAY_HANDLE hDisplay, DSP_IMG_RECT *pRect ); 82 | int32_t NX_DspVideoSetPosition ( DISPLAY_HANDLE hDisplay, DSP_IMG_RECT *pRect ); 83 | 84 | int32_t NX_DspVideoSetPriority ( int32_t module, int32_t priority ); 85 | int32_t NX_DspVideoGetPriority ( int32_t module, int32_t *priority ); 86 | 87 | int32_t NX_DspSetColorKey ( int32_t module, int32_t colorkey ); 88 | int32_t NX_DspGetColorKey ( int32_t module, int32_t *colorkey ); 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif // __NX_DSP_H__ 94 | -------------------------------------------------------------------------------- /include/nx_fourcc.h: -------------------------------------------------------------------------------- 1 | #ifndef __NX_FOURCC_H__ 2 | #define __NX_FOURCC_H__ 3 | 4 | /*------------------------------------------------------------------------------ 5 | * Macro: FOURCC for video 6 | */ 7 | #ifndef MAKEFOURCC 8 | #define MAKEFOURCC(a,b,c,d) (((unsigned int)a) | (((unsigned int)b)<< 8) | (((unsigned int)c)<<16) | (((unsigned int)d)<<24) ) 9 | #endif 10 | 11 | // Specific Pixel Format FourCC for NX series 12 | #define FOURCC_MVS0 MAKEFOURCC('M', 'V', 'S', '0') // YCbCr 420 : Plarnar Format( Image X, Y, Cb, Cr Aligned x16 Byte ) 13 | #define FOURCC_MVS2 MAKEFOURCC('M', 'V', 'S', '2') // YCbCr 422 : Plarnar Format 14 | #define FOURCC_MVS4 MAKEFOURCC('M', 'V', 'S', '4') // YCbCr 444 : Plaranr Format 15 | #define FOURCC_MVN2 MAKEFOURCC('M', 'V', 'N', '2') // YUV 4:2:2 packed foramt(same as FOURCC_YUYV) 16 | 17 | #define FOURCC_H422 MAKEFOURCC('H', '4', '2', '2') // YCbCr H422 : Plarnar Format (same as FOURCC_MVS2) 18 | #define FOURCC_V422 MAKEFOURCC('V', '4', '2', '2') // YCbCr H422 : Plarnar Format 19 | #define FOURCC_GRAY MAKEFOURCC('G', 'R', 'A', 'Y') // Gray(YCbCr 400) format 20 | 21 | // YUV Packed Format 22 | #define FOURCC_YUY2 MAKEFOURCC('Y', 'U', 'Y', '2') // MPEG1 media format (1D nonseperated 422 format - Y,Cb,Y,Cr) 23 | #define FOURCC_YUYV MAKEFOURCC('Y', 'U', 'Y', 'V') // Duplicated of YUY2(1D nonseperated 422 format - Y,Cb,Y,Cr) */ 24 | #define FOURCC_UYVY MAKEFOURCC('U', 'Y', 'V', 'Y') // YUV 4:2:2 (Y sample at every pixel, U and V sampled at every second pixel horizontally on each line). 25 | // A macropixel contains 2 pixels in 1 u_int32. 26 | // YUV Seperate Format ( Planar Format ) 27 | #define FOURCC_IYUV MAKEFOURCC('I', 'Y', 'U', 'V') // 8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes. 28 | #define FOURCC_YV12 MAKEFOURCC('Y', 'V', '1', '2') // 8 bit Y plane followed by 8 bit 2x2 subsampled V and U planes. 29 | #define FOURCC_NV12 MAKEFOURCC('N', 'V', '1', '2') // 8-bit Y plane followed by an interleaved U/V plane with 2x2 subsampling.(CbCr Order) 30 | #define FOURCC_NV21 MAKEFOURCC('N', 'V', '2', '1') // As NV12 with U(Cb) and V(Cr) reversed in the interleaved plane.(CrCb Order) 31 | 32 | 33 | #endif // __NX_FOURCC_H__ 34 | -------------------------------------------------------------------------------- /include/nx_video_api.h: -------------------------------------------------------------------------------- 1 | // 2 | // Nexel Video En/Decoder API 3 | // 4 | 5 | 6 | #ifndef __NX_VIDEO_API_H__ 7 | #define __NX_VIDEO_API_H__ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX_DEC_FRAME_BUFFERS 30 14 | #define ENC_BITSTREAM_BUFFER (4*1024*1024) 15 | 16 | typedef struct NX_VIDEO_ENC_INFO *NX_VID_ENC_HANDLE; 17 | typedef struct NX_VIDEO_DEC_INFO *NX_VID_DEC_HANDLE; 18 | 19 | 20 | // Video Codec Type ( API Level ) 21 | typedef enum { 22 | // Decoders 23 | NX_AVC_DEC = 0x00, // H.264( AVC ) 24 | NX_VC1_DEC = 0x01, // WMV9 25 | NX_MP2_DEC = 0x02, // Mpeg2 Video 26 | NX_MP4_DEC = 0x03, // Mpeg4 Video 27 | NX_H263_DEC = 0x04, // H.263 28 | NX_DIV3_DEC = 0x05, // Divx 3.11(MS Mpeg4 V3) 29 | NX_RV_DEC = 0x06, // Real Video 30 | NX_THEORA_DEC = 0x07, // Theora 31 | NX_VP8_DEC = 0x08, // VP8 32 | NX_JPEG_DEC = 0x09, // JPEG 33 | NX_HEVC_DEC = 0x0A, // H.265( HEVC ) 34 | 35 | // Encoders 36 | NX_AVC_ENC = 0x10, 37 | NX_MP4_ENC = 0x12, 38 | NX_H263_ENC = 0x13, 39 | NX_JPEG_ENC = 0x20, // JPEG Encoder 40 | } VID_TYPE_E; 41 | 42 | typedef enum{ 43 | VID_ERR_NOT_ALLOC_BUFF = -28, 44 | VID_ERR_NOT_ENOUGH_STREAM = -27, 45 | VID_ERR_NO_DEC_FRAME = -26, 46 | VID_ERR_NEED_MORE_BUF = -25, 47 | VID_ERR_STRM_FULL = -24, // Bitstream Full 48 | VID_ERR_SRAM = -23, // VPU SRAM Configruation Failed 49 | VID_ERR_INST = -22, // VPU Have No Instance Space 50 | VID_ERR_BUSY = -21, // VPU H/W Busy 51 | VID_ERR_TIMEOUT = -20, // VPU Wait Timeout 52 | VID_ERR_MEM_ACCESS = -19, // Memory Access Violation 53 | VID_ERR_NOT_SUPPORT = -7, 54 | VID_ERR_CHG_PARAM = -6, // VPU Not changed 55 | VID_ERR_WRONG_SEQ = -5, // Wrong Sequence 56 | VID_ERR_PARAM = -4, // VPU Invalid Parameter 57 | VID_ERR_RUN = -3, 58 | VID_ERR_INIT = -2, // VPU Not Initialized 59 | VID_ERR_FAIL = -1, // General operation failed 60 | VID_ERR_NONE = 0, 61 | VID_NEED_STREAM = 1, // Need More Stream 62 | } VID_ERROR_E; 63 | 64 | enum{ 65 | PIC_TYPE_I = 0, // Include IDR in h264 66 | PIC_TYPE_P = 1, 67 | PIC_TYPE_B = 2, 68 | PIC_TYPE_VC1_BI = 2, 69 | PIC_TYPE_VC1_B = 3, 70 | PIC_TYPE_D = 3, // D picture in mpeg2, and is only composed of DC codfficients 71 | PIC_TYPE_S = 3, // S picture in mpeg4, and is an acronym of Sprite. and used for GMC 72 | PIC_TYPE_VC1_P_SKIP = 4, 73 | PIC_TYPE_MP4_P_SKIP_NOT_CODED = 4, // Not Coded P Picture at mpeg4 packed mode 74 | PIC_TYPE_SKIP = 5, 75 | PIC_TYPE_IDR = 6, 76 | PIC_TYPE_UNKNOWN = 0xff, 77 | }; 78 | 79 | enum { 80 | DEC_OPT_CHROMA_INTERLEAVE = 0x00000001, 81 | }; 82 | 83 | typedef enum { 84 | VID_CHG_GOP = 1, // GOP 85 | VID_CHG_BITRATE = (1 << 2), // Bit Rate 86 | VID_CHG_FRAMERATE = (1 << 3), // Frame Rate 87 | VID_CHG_INTRARF = (1 << 4), // Intra Refresh 88 | VID_CHG_MAX_QP = (1 << 7), // Maximum quantization parameter 89 | VID_CHG_DISABLE_SKIP = (1 << 8), // Disable skip frame mode 90 | VID_CHG_VBV = (1 << 9), // Reference decoder buffer size in byte 91 | } VID_ENC_CHG_PARAM_E; 92 | 93 | enum { 94 | NONE_FIELD = 0, 95 | FIRST_FIELD = 0, 96 | SECOND_FIELD = 1 97 | }; 98 | 99 | enum { 100 | DECODED_FRAME = 0, 101 | DISPLAY_FRAME = 1 102 | }; 103 | 104 | 105 | // 106 | // Encoder Specific APIs 107 | // 108 | typedef struct tNX_VID_ENC_IN { 109 | NX_VID_MEMORY_HANDLE pImage; // Original captured frame's pointer 110 | uint64_t timeStamp; // Time stamp 111 | int32_t forcedIFrame; // Flag of forced intra frame 112 | int32_t forcedSkipFrame; // Flag of forced skip frame 113 | int32_t quantParam; // User quantization parameter (It is valid only when VBR.) 114 | }NX_VID_ENC_IN; 115 | 116 | typedef struct tNX_VID_ENC_OUT{ 117 | uint8_t *outBuf; // Output buffer's pointer 118 | int32_t bufSize; // OutBuf's size(input) and filled size(output) 119 | int32_t frameType; // Frame type 120 | int32_t width; // Encoded image width 121 | int32_t height; // Encoded image height 122 | NX_VID_MEMORY_INFO ReconImg; // Reconstructed image's pointer 123 | }NX_VID_ENC_OUT; 124 | 125 | typedef struct tNX_VID_ENC_JPEG_PARAM{ 126 | int32_t configFlag; 127 | uint8_t huffVal[4][162]; 128 | uint8_t huffBits[4][256]; 129 | uint8_t qMatTab[4][64]; 130 | uint8_t cInfoTab[4][6]; 131 | }NX_VID_ENC_JPEG_PARAM; 132 | 133 | typedef struct tNX_VID_ENC_INIT_PARAM{ 134 | int32_t width; // Width of image 135 | int32_t height; // Height of image 136 | int32_t gopSize; // Size of key frame interval 137 | int32_t fpsNum; // Frame per second 138 | int32_t fpsDen; 139 | 140 | // Rate Control Parameters (They are valid only when enableRC is TRUE[CBR]) 141 | int32_t enableRC; // En/Disable rate control, 0(Variable Bit Rate mode) or 1(Constant Bit Rate mode) 142 | int32_t RCAlgorithm; // 0 : Chips & Media Rate Control Algorithm, 1 : Nexell Rate Control Algorithm 143 | uint32_t bitrate; // Target bitrate in bits per second 144 | int32_t maximumQp; // Maximum quantization parameter 145 | int32_t disableSkip; // Disable skip frame mode 146 | int32_t RCDelay; // Valid value is 0 ~ 0x7FFF 147 | // 0 does not check reference decoder buffer delay constraint. 148 | uint32_t rcVbvSize; // Reference decoder buffer size in byte 149 | // Default value is 2sec if RCAlgorithm is 1. 150 | // This valid is ignored if RCAlgorithm is 0 & RCDelay is 0. 151 | int32_t gammaFactor; // User gamma factor 152 | // It is valid only when RCAlgorithm is 0. 153 | int32_t RcMode; 154 | 155 | int32_t initialQp; // Initial quantization parameter 156 | // It is computed if enableRC is 1 & RCAlgorithm is 1 and the value is 0. 157 | 158 | int32_t numIntraRefreshMbs; // Intra MB refresh number.(Cyclic Intra Refresh) 159 | int32_t searchRange; // search range of motion estimaiton (0 : 128 x 64, 1 : 64 x 32, 2 : 32 x 16, 3 : 16 x 16) 160 | 161 | // Input Buffer Format 162 | int32_t chromaInterleave; // 0 : disable, 1 : enable 163 | 164 | int32_t rotAngle; 165 | int32_t mirDirection; // 0 : not mir, 1 : horizontal mir, 2 : vertical mir, 3 : horizontal & vertical mir 166 | 167 | // for AVC Encoder 168 | int32_t enableAUDelimiter; // Insert Access Unit Delimiter before NAL unit. 169 | 170 | // for JPEG Specific Parameter 171 | int32_t jpgQuality; // 1~100 172 | }NX_VID_ENC_INIT_PARAM; 173 | 174 | typedef struct tNX_VID_ENC_CHG_PARAM{ 175 | int32_t chgFlg; 176 | int32_t gopSize; // Size of key frame interval 177 | int32_t bitrate; // Target bitrate in bits/second 178 | int32_t fpsNum; // Frame per second 179 | int32_t fpsDen; 180 | int32_t maximumQp; // Maximum quantization parameter 181 | int32_t disableSkip; // Disable skip frame mode 182 | uint32_t rcVbvSize; // Reference decoder buffer size in byte. 183 | // The value shall be set when bitrate is changed in Nexell RC Algorithm. 184 | // Default value is 2sec if RCAlgorithm is 1. (The value is ignored when RCAlgorithm is 0 or enableRC is 0) 185 | 186 | int32_t numIntraRefreshMbs; // Intra MB refresh number.(Cyclic Intra Refresh) 187 | }NX_VID_ENC_CHG_PARAM; 188 | 189 | 190 | // 191 | // Decoder Specific APIs 192 | // 193 | typedef struct tNX_VID_DEC_IN{ 194 | uint8_t *strmBuf; // A compressed stream's pointer 195 | int32_t strmSize; // A compressed stream's size 196 | uint64_t timeStamp; // Time stamp 197 | int32_t eos; 198 | 199 | // for JPEG Decoder 200 | int32_t downScaleWidth; // 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling 201 | int32_t downScaleHeight; // 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling 202 | }NX_VID_DEC_IN; 203 | 204 | typedef struct tNX_VID_DEC_OUT{ 205 | NX_VID_MEMORY_INFO outImg; // Decoded frame's pointer 206 | int32_t outImgIdx; // Display Index 207 | int32_t outDecIdx; // Decode Index 208 | int32_t width; 209 | int32_t height; 210 | int32_t picType[2]; // Picture Type 211 | 212 | uint64_t timeStamp[2]; // Time stamp 213 | uint32_t strmReadPos; // Remained bitstream buffer size 214 | uint32_t strmWritePos; // Remained bitstream buffer size 215 | 216 | int32_t isInterlace; // 0 : progressive, 1 : interlace 217 | int32_t topFieldFirst; // 0 : top field first, 1 : bottom field first 218 | 219 | int32_t outFrmReliable_0_100[2]; // Percentage of MB's are reliable ranging from 0[all damage] to 100 [all clear] 220 | 221 | // for VC1 Decoder 222 | int32_t multiResolution; // 0 : non multi-resulution, 1 : horizontal scale is half, 2 : vertical scale is half, 3 : horizontal & vertical scale is half 223 | 224 | // for VP Decoder 225 | int32_t upSampledWidth; // 0 : No upscaling, other : upscaling width 226 | int32_t upSampledHeight; // 0 : No upscaling, other : upscaling height 227 | }NX_VID_DEC_OUT; 228 | 229 | typedef struct tNX_VID_SEQ_IN{ 230 | uint8_t *seqInfo; // Sequence header's pointer 231 | int32_t seqSize; // Sequence header's size 232 | int32_t width; 233 | int32_t height; 234 | 235 | // for External Buffer ( Optional ) 236 | NX_VID_MEMORY_HANDLE *pMemHandle; // Frame buffer for external buffer mode 237 | int32_t numBuffers; // Number of external frame buffer 238 | 239 | int32_t addNumBuffers; // Add to minimum frame buffer number (total frame buffer number = minimum number + addNumBuffers) 240 | // This value is valid when External Buffer is not used. 241 | int32_t disableOutReorder; // 1 : Decoding Order, 0 : Display Order 242 | 243 | // for MPEG2, MPEG4, Divx3.11 Decoder 244 | int32_t enablePostFilter; // 1 : Deblock filter, 2 : Deringing filter, 3 : Deblock & Deringing filter, 0 : Disable post filter 245 | 246 | // for MPEG2 Decoder 247 | int32_t enableUserData; 248 | 249 | // for JPEG Decoder 250 | int32_t thumbnailMode; // 0 : jpeg mode, 1 : thumbnail mode 251 | }NX_VID_SEQ_IN; 252 | 253 | typedef struct tNX_VID_SEQ_OUT{ 254 | int32_t minBuffers; // Needed minimum number of decoded frames 255 | int32_t numBuffers; 256 | int32_t width; 257 | int32_t height; 258 | int32_t frameBufDelay; 259 | int32_t isInterlace; // 0 : Progressive YUV, 1 : interlaced YUV 260 | 261 | int32_t frameRateNum; // Frame Rate Numerator 262 | int32_t frameRateDen; // Frame Rate Denominator (-1 : no information) 263 | 264 | // for User Data( MPEG2 Decoder Only ) 265 | int32_t userDataNum; 266 | int32_t userDataSize; 267 | int32_t userDataBufFull; 268 | 269 | // for VP8 Decoder 270 | int32_t vp8ScaleWidth; 271 | int32_t vp8ScaleHeight; 272 | 273 | int32_t unsupportedFeature; // Flag to inform the feature is unsupported in NX Codec 274 | 275 | int32_t imgFourCC; // FourCC according to decoded image type (ASCII hexadecimal representation of four characters) 276 | int32_t thumbnailWidth; // Width of thumbnail image 277 | int32_t thumbnailHeight; // Height of thumbnail image 278 | }NX_VID_SEQ_OUT; 279 | 280 | typedef struct tNX_VID_VERSION{ 281 | int32_t iMajor; 282 | int32_t iMinor; 283 | int32_t iPatch; 284 | int32_t iReserved; 285 | } NX_VID_VERSION; 286 | 287 | 288 | 289 | #ifdef __cplusplus 290 | extern "C" { 291 | #endif 292 | 293 | // 294 | // Encoder 295 | // 296 | NX_VID_ENC_HANDLE NX_VidEncOpen( VID_TYPE_E eCodecType, int32_t *piInstanceIdx ); 297 | VID_ERROR_E NX_VidEncClose( NX_VID_ENC_HANDLE hEnc ); 298 | VID_ERROR_E NX_VidEncInit( NX_VID_ENC_HANDLE hEnc, NX_VID_ENC_INIT_PARAM *pstParam ); 299 | VID_ERROR_E NX_VidEncGetSeqInfo( NX_VID_ENC_HANDLE hEnc, uint8_t *pbySeqBuf, int32_t *piSeqBufSize ); 300 | VID_ERROR_E NX_VidEncEncodeFrame( NX_VID_ENC_HANDLE hEnc, NX_VID_ENC_IN *pstEncIn, NX_VID_ENC_OUT *pstEncOut ); 301 | VID_ERROR_E NX_VidEncChangeParameter( NX_VID_ENC_HANDLE hEnc, NX_VID_ENC_CHG_PARAM *pstChgParam ); 302 | 303 | // 304 | // Decoder 305 | // 306 | NX_VID_DEC_HANDLE NX_VidDecOpen( VID_TYPE_E eCodecType, uint32_t uMp4Class, int32_t iOptions, int32_t *piInstanceIdx ); 307 | VID_ERROR_E NX_VidDecClose( NX_VID_DEC_HANDLE hDec ); 308 | VID_ERROR_E NX_VidDecParseVideoCfg(NX_VID_DEC_HANDLE hDec, NX_VID_SEQ_IN *pstSeqIn, NX_VID_SEQ_OUT *pstSeqOut); 309 | VID_ERROR_E NX_VidDecInit(NX_VID_DEC_HANDLE hDec, NX_VID_SEQ_IN *pstSeqIn); 310 | VID_ERROR_E NX_VidDecDecodeFrame( NX_VID_DEC_HANDLE hDec, NX_VID_DEC_IN *pstDecIn, NX_VID_DEC_OUT *pstDecOut ); 311 | VID_ERROR_E NX_VidDecClrDspFlag( NX_VID_DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf, int32_t iFrameIdx ); 312 | VID_ERROR_E NX_VidDecFlush( NX_VID_DEC_HANDLE hDec ); 313 | VID_ERROR_E NX_VidDecGetFrameType( VID_TYPE_E eCodecType, NX_VID_DEC_IN *pstDecIn, int32_t *piFrameType ); 314 | 315 | // 316 | // Jpeg Encoder APIs 317 | // Usage : NX_VidEncOpen() --> NX_VidEncInit() NX_VidEncJpegRunFrame() --> NX_VidEncClose() 318 | // 319 | VID_ERROR_E NX_VidEncJpegGetHeader( NX_VID_ENC_HANDLE hEnc, uint8_t *pbyJpgHeader, int32_t *piHeaderSize ); 320 | VID_ERROR_E NX_VidEncJpegRunFrame( NX_VID_ENC_HANDLE hEnc, NX_VID_MEMORY_HANDLE hInImage, NX_VID_ENC_OUT *pstEncOut ); 321 | 322 | VID_ERROR_E NX_VidGetVersion( NX_VID_VERSION *pstVersion ); 323 | 324 | #ifdef __cplusplus 325 | } 326 | #endif 327 | 328 | #endif // __NX_VPU_API_H__ 329 | -------------------------------------------------------------------------------- /include/nx_video_rate_ctrl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Nexel Video Rate Control API 3 | // 4 | 5 | 6 | #ifndef __NX_VIDEO_RATE_CTRL_H__ 7 | #define __NX_VIDEO_RATE_CTRL_H__ 8 | 9 | #include 10 | 11 | 12 | typedef struct 13 | { 14 | int32_t iMajor; 15 | int32_t iMinor; 16 | int32_t iPatch; 17 | } NX_RC_VERSION; 18 | 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | // 25 | // Video Rate Control API Functions 26 | // 27 | void *NX_VidRateCtrlInit( int32_t iCodecType, NX_VID_ENC_INIT_PARAM *pstPara ); 28 | VID_ERROR_E NX_VidRateCtrlGetFrameQp( void *hRateCtrl, int32_t *piFrmQp, int32_t *piFrmType ); 29 | VID_ERROR_E NX_VidRateCtrlUpdate( void *hRateCtrl, uint32_t uFrmByte ); 30 | VID_ERROR_E NX_VidRateCtrlChangePara( void *hRateCtrl, NX_VID_ENC_CHG_PARAM *pstChgPara ); 31 | VID_ERROR_E NX_VidRateCtrlGetVersion( NX_RC_VERSION *pstVersion ); 32 | 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif // __NX_VIDEO_RATE_CTRL_H__c 39 | -------------------------------------------------------------------------------- /include/nx_vip.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (C) 2013 Nexell Co. All Rights Reserved 4 | // Nexell Co. Proprietary & Confidential 5 | // 6 | // NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE 7 | // AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING 8 | // BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS 9 | // FOR A PARTICULAR PURPOSE. 10 | // 11 | // Module : 12 | // File : 13 | // Description : 14 | // Author : 15 | // Export : 16 | // History : 17 | // 18 | //------------------------------------------------------------------------------ 19 | 20 | #ifndef __NX_VIP_H__ 21 | #define __NX_VIP_H__ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | enum { 31 | VIP_PORT_0 = 0x00, 32 | VIP_PORT_1 = 0x01, 33 | VIP_PORT_2 = 0x02, 34 | VIP_PORT_MIPI = 0x03, 35 | }; 36 | 37 | enum { 38 | VIP_MODE_CLIPPER = 0x00, 39 | VIP_MODE_DECIMATOR = 0x01, 40 | VIP_MODE_CLIP_DEC = 0x02, 41 | VIP_MODE_CLIP_DEC2 = 0x03, 42 | }; 43 | 44 | typedef struct VIP_INFO VIP_INFO; 45 | typedef struct VIP_HANDLE_INFO *VIP_HANDLE; 46 | 47 | struct VIP_INFO { 48 | int32_t port; // video input processor's port number 49 | int32_t mode; // 1 : clipper only, 2 : decimator only, 3 : clipper --> decimator 50 | 51 | int32_t width; // Camera Input Width 52 | int32_t height; // Camera Input Height 53 | 54 | int32_t fpsNum; // Frame per seconds's Numerate value 55 | int32_t fpsDen; // Frame per seconds's Denominate value 56 | 57 | int32_t numPlane; // Input image's plane number 58 | 59 | int32_t cropX; // Cliper x 60 | int32_t cropY; // Cliper y 61 | int32_t cropWidth; // Cliper width 62 | int32_t cropHeight; // Cliper height 63 | 64 | int32_t outWidth; // Decimator width 65 | int32_t outHeight; // Decimator height 66 | }; 67 | 68 | #ifdef __cplusplus 69 | extern "C"{ 70 | #endif 71 | 72 | VIP_HANDLE NX_VipInit ( VIP_INFO *pVipInfo ); 73 | void NX_VipClose ( VIP_HANDLE hVip ); 74 | int32_t NX_VipStreamControl ( VIP_HANDLE hVip, int32_t bEnable ); 75 | 76 | // clipper, decimator, clipper + decimator with memory 77 | int32_t NX_VipQueueBuffer ( VIP_HANDLE hVip, NX_VID_MEMORY_INFO *pMem ); 78 | int32_t NX_VipDequeueBuffer ( VIP_HANDLE hVip, NX_VID_MEMORY_INFO **ppMem, int64_t *pTimeStamp ); 79 | 80 | // clipper with memory + decimator with memory 81 | int32_t NX_VipQueueBuffer2 ( VIP_HANDLE hVip, NX_VID_MEMORY_INFO *pClipMem, NX_VID_MEMORY_INFO *pDeciMem ); 82 | int32_t NX_VipDequeueBuffer2 ( VIP_HANDLE hVip, NX_VID_MEMORY_INFO **ppClipMem, NX_VID_MEMORY_INFO **ppDeciMem, int64_t *pClipTimeStamp, int64_t *pDeciTimeStamp ); 83 | 84 | int32_t NX_VipChangeConfig ( VIP_HANDLE hVip, VIP_INFO *pVipInfo ); 85 | 86 | int32_t NX_VipGetCurrentQueuedCount ( VIP_HANDLE hVip, int32_t *maxSize ); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif // __NX_VIP_H__ 93 | -------------------------------------------------------------------------------- /include/nxp-v4l2.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXP_V4L2_H 2 | #define _NXP_V4L2_H 3 | 4 | #ifdef ANDROID 5 | #include 6 | #else 7 | #include 8 | #include 9 | #endif 10 | 11 | #define MAX_BUFFER_PLANES 3 12 | struct nxp_vid_buffer { 13 | int plane_num; 14 | int fds[MAX_BUFFER_PLANES]; 15 | char *virt[MAX_BUFFER_PLANES]; 16 | unsigned long phys[MAX_BUFFER_PLANES]; 17 | int sizes[MAX_BUFFER_PLANES]; 18 | }; 19 | 20 | /* pixel code */ 21 | #define PIXCODE_YUV422_PACKED V4L2_MBUS_FMT_YUYV8_2X8 22 | #define PIXCODE_YUV420_PLANAR V4L2_MBUS_FMT_YUYV8_1_5X8 23 | #define PIXCODE_YUV422_PLANAR V4L2_MBUS_FMT_YUYV8_1X16 24 | #define PIXCODE_YUV444_PLANAR V4L2_MBUS_FMT_YUV8_1X24 25 | 26 | /* pixel format */ 27 | #define PIXFORMAT_YUV422_PACKED V4L2_PIX_FMT_YUYV 28 | #define PIXFORMAT_YUV420_PLANAR V4L2_PIX_FMT_YUV420M // 3 plane 29 | #define PIXFORMAT_YUV420_YV12 V4L2_PIX_FMT_YUV420 // 1 Plane 30 | #define PIXFORMAT_YUV422_PLANAR V4L2_PIX_FMT_YUV422P 31 | #define PIXFORMAT_YUV444_PLANAR V4L2_PIX_FMT_YUV444 32 | 33 | enum { 34 | YUV422_PACKED = 0, 35 | YUV420_PLANAR, // 3 Plane 36 | YUV420_YV12, // 1 Plane 37 | YUV422_PLANAR, 38 | YUV444_PLANAR, 39 | MAX_PIXFORMAT 40 | }; 41 | 42 | struct PixFormatPixCode { 43 | uint32_t format; 44 | uint32_t code; 45 | }; 46 | 47 | extern struct PixFormatPixCode PixelArray[MAX_PIXFORMAT]; 48 | 49 | #ifndef ANDROID 50 | #ifdef __cplusplus 51 | extern "C" { 52 | #endif 53 | #endif 54 | 55 | /* user control interface */ 56 | typedef enum { 57 | nxp_v4l2_sensor0 = 0, 58 | nxp_v4l2_sensor1 = 1, 59 | nxp_v4l2_mipicsi = 2, 60 | nxp_v4l2_clipper0 = 5, /* include camera sensor, mipicsi */ 61 | nxp_v4l2_clipper1 = 8, 62 | nxp_v4l2_decimator0 = 11, 63 | nxp_v4l2_decimator1 = 14, 64 | nxp_v4l2_scaler = 17, 65 | nxp_v4l2_deinterlacer = 20, 66 | nxp_v4l2_mlc0 = 21, 67 | nxp_v4l2_mlc0_rgb = 23, 68 | nxp_v4l2_mlc0_video = 25, 69 | nxp_v4l2_mlc1 = 26, 70 | nxp_v4l2_mlc1_rgb = 28, 71 | nxp_v4l2_mlc1_video = 30, 72 | nxp_v4l2_resol = 31, 73 | nxp_v4l2_hdmi = 32, 74 | nxp_v4l2_tvout = 33, 75 | nxp_v4l2_id_max, 76 | } nxp_v4l2_id; 77 | 78 | struct V4l2UsageScheme { 79 | bool useClipper0; 80 | bool useDecimator0; 81 | bool useClipper1; 82 | bool useDecimator1; 83 | bool useScaler; 84 | bool useDeinterlacer; 85 | bool useMlc0Rgb; 86 | bool useMlc0Video; 87 | bool useMlc1Rgb; 88 | bool useMlc1Video; 89 | bool useResol; 90 | bool useHdmi; 91 | bool useTvout; 92 | }; 93 | 94 | int v4l2_init(const struct V4l2UsageScheme *scheme); 95 | void v4l2_exit(void); 96 | int v4l2_link(int src_id, int dst_id); 97 | int v4l2_unlink(int src_id, int dst_id); 98 | int v4l2_set_format(int id, int w, int h, int f); 99 | int v4l2_get_format(int id, int *w, int *h, int *f); 100 | int v4l2_set_crop(int id, int l, int t, int w, int h); 101 | int v4l2_set_crop_with_pad(int id, int pad, int l, int t, int w, int h); 102 | int v4l2_get_crop(int id, int *l, int *t, int *w, int *h); 103 | int v4l2_set_ctrl(int id, int ctrl_id, int value); 104 | int v4l2_get_ctrl(int id, int ctrl_id, int *value); 105 | int v4l2_reqbuf(int id, int buf_count); 106 | #ifdef ANDROID 107 | //int v4l2_qbuf(int id, int plane_num, int index0, struct private_handle_t *b0, int index1, struct private_handle_t *b1); 108 | int v4l2_qbuf(int id, int plane_num, int index0, struct private_handle_t const *b0, int index1, struct private_handle_t const *b1, 109 | int *syncfd0 = NULL, int *syncfd1 = NULL); 110 | #endif 111 | int v4l2_qbuf(int id, int plane_num, int index0, struct nxp_vid_buffer *b0, int index1, struct nxp_vid_buffer *b1); 112 | int v4l2_dqbuf(int id, int plane_num, int *index0, int *index1); 113 | int v4l2_streamon(int id); 114 | int v4l2_streamoff(int id); 115 | int v4l2_get_timestamp(int id, long long *timestamp); 116 | int v4l2_set_preset(int id, uint32_t preset); 117 | int v4l2_get_device_fd(int id); 118 | 119 | #ifndef ANDROID 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | #endif 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /include/vpu_types.h: -------------------------------------------------------------------------------- 1 | #ifndef __VPU_TYPES_H__ 2 | #define __VPU_TYPES_H__ 3 | 4 | #include "nx_alloc_mem.h" 5 | 6 | typedef struct 7 | { 8 | int left; 9 | int top; 10 | int right; 11 | int bottom; 12 | } VPU_RECT; 13 | 14 | typedef struct 15 | { 16 | // Input Arguments 17 | int codecStd; 18 | int isEncoder; // Encoder 19 | int mp4Class; // Mpeg4 Class 20 | int chromaInterleave; // CbCr Interleaved 21 | 22 | NX_MEMORY_INFO instanceBuf; 23 | NX_MEMORY_INFO streamBuf; 24 | 25 | // Output Arguments 26 | int instIndex; // Instance Index 27 | } VPU_OPEN_ARG; 28 | 29 | typedef struct 30 | { 31 | // input image size 32 | int srcWidth; // source image's width 33 | int srcHeight; // source image's height 34 | 35 | // Set Stream Buffer Handle 36 | unsigned int strmBufVirAddr; 37 | unsigned int strmBufPhyAddr; 38 | int strmBufSize; 39 | 40 | int frameRateNum; // frame rate 41 | int frameRateDen; 42 | int gopSize; // group of picture size 43 | 44 | // Rate Control 45 | int RCModule; // 0 : VBR, 1 : CnM RC, 2 : NX RC 46 | int bitrate; // Target Bitrate 47 | int disableSkip; // Flag of Skip frame disable 48 | int initialDelay; // This value is valid if RCModule is 1.(MAX 0x7FFF) 49 | // 0 does not check Reference decoder buffer delay constraint. 50 | int vbvBufferSize; // Reference Decoder buffer size in bytes 51 | // This valid is ignored if RCModule is 1 and initialDelay is is 0.(MAX 0x7FFFFFFF) 52 | int gammaFactor; // It is valid when RCModule is 1. 53 | 54 | // Quantization Scale [ H.264/AVC(0~51), MPEG4(1~31) ] 55 | int maxQP; // Max Quantization Scale 56 | int initQP; // This value is Initial QP whne CBR. (Initial QP is computed if initQP is 0.) 57 | // This value is user QP when VBR. 58 | 59 | // Input Buffer Chroma Interleaved 60 | int chromaInterleave; // Input Buffer Chroma Interleaved Format 61 | int refChromaInterleave;// Reference Buffer's Chorma Interleaved Format 62 | 63 | // ME Search Range 64 | int searchRange; // ME_SEARCH_RAGME_[0~3] ( recomand ME_SEARCH_RAGME_2 ) 65 | // 0 : H(-128~127), V(-64~63) 66 | // 1 : H( -64~ 63), V(-32~31) 67 | // 2 : H( -32~ 31), V(-16~15) 68 | // 3 : H( -16~ 15), V(-16~15) 69 | 70 | // Other Options 71 | int intraRefreshMbs; // an Intra MB refresh number. 72 | // It must be less than total MacroBlocks. 73 | 74 | int rotAngle; 75 | int mirDirection; 76 | 77 | // AVC Only 78 | int enableAUDelimiter; // enable/disable Access Unit Delimiter 79 | 80 | // JPEG Specific 81 | int quality; 82 | }VPU_ENC_SEQ_ARG; 83 | 84 | 85 | typedef struct 86 | { 87 | // Reconstruct Buffer 88 | int numFrameBuffer; // Number Of Frame Buffers 89 | NX_VID_MEMORY_INFO frameBuffer[2]; // Frame Buffer Informations 90 | 91 | // Sub Sample A/B Buffer ( 1 sub sample buffer size = Framebuffer size/4 ) 92 | NX_MEMORY_INFO subSampleBuffer[2]; // 93 | 94 | // Data partition Buffer size ( MAX WIDTH * MAX HEIGHT * 3 / 4 ) 95 | NX_MEMORY_INFO dataPartitionBuffer; // Mpeg4 Only 96 | }VPU_ENC_SET_FRAME_ARG; 97 | 98 | 99 | typedef union 100 | { 101 | struct { 102 | unsigned char vosData[512]; 103 | int vosSize; 104 | unsigned char volData[512]; 105 | int volSize; 106 | unsigned char voData[512]; 107 | int voSize; 108 | } mp4Header; 109 | struct { 110 | unsigned char spsData[512]; 111 | int spsSize; 112 | unsigned char ppsData[512]; 113 | int ppsSize; 114 | } avcHeader; 115 | struct { 116 | unsigned char jpegHeader[1024]; 117 | int headerSize; 118 | } jpgHeader; 119 | }VPU_ENC_GET_HEADER_ARG; 120 | 121 | 122 | typedef struct 123 | { 124 | //------------------------------------------------------------------------ 125 | // Input Prameter 126 | NX_VID_MEMORY_INFO inImgBuffer; 127 | // Rate Control Parameters 128 | int changeFlag; 129 | int enableRc; 130 | int forceIPicture; 131 | int quantParam; // User quantization Parameter 132 | int skipPicture; 133 | 134 | // Dynamic Configurable Parameters 135 | 136 | 137 | //------------------------------------------------------------------------ 138 | // Output Parameter 139 | int frameType; // I, P, B, SKIP,.. etc 140 | unsigned char *outStreamAddr; // mmapped virtual address 141 | int outStreamSize; // Stream buffer size 142 | int reconImgIdx; // reconstructed image buffer index 143 | }VPU_ENC_RUN_FRAME_ARG; 144 | 145 | typedef struct 146 | { 147 | int chgFlg; 148 | int gopSize; 149 | int intraQp; 150 | int bitrate; 151 | int frameRateNum; 152 | int frameRateDen; 153 | int intraRefreshMbs; 154 | int sliceMode; 155 | int sliceSizeMode; 156 | int sliceSizeNum; 157 | int hecMode; 158 | } VPU_ENC_CHG_PARA_ARG; 159 | 160 | typedef struct { 161 | int fixedFrameRateFlag; 162 | int timingInfoPresent; 163 | int chromaLocBotField; 164 | int chromaLocTopField; 165 | int chromaLocInfoPresent; 166 | int colorPrimaries; 167 | int colorDescPresent; 168 | int isExtSAR; 169 | int vidFullRange; 170 | int vidFormat; 171 | int vidSigTypePresent; 172 | int vuiParamPresent; 173 | int vuiPicStructPresent; 174 | int vuiPicStruct; 175 | } AvcVuiInfo; 176 | 177 | 178 | // 179 | // Decoder Structures 180 | // 181 | 182 | typedef struct 183 | { 184 | // Input Information 185 | unsigned char *seqData; 186 | int seqDataSize; 187 | int disableOutReorder; 188 | 189 | // General Output Information 190 | int outWidth; 191 | int outHeight; 192 | int frameRateNum; // Frame Rate Numerator 193 | int frameRateDen; // Frame Rate Denominator 194 | unsigned int bitrate; 195 | 196 | int profile; 197 | int level; 198 | int interlace; 199 | int direct8x8Flag; 200 | int constraint_set_flag[4]; 201 | int aspectRateInfo; 202 | 203 | // Frame Buffer Information 204 | int minFrameBufCnt; 205 | int frameBufDelay; 206 | 207 | int enablePostFilter; // 1 : Deblock filter, 0 : Disable post filter 208 | 209 | // Mpeg4 Specific Info 210 | int mp4ShortHeader; 211 | int mp4PartitionEnable; 212 | int mp4ReversibleVlcEnable; 213 | int h263AnnexJEnable; 214 | unsigned int mp4Class; 215 | 216 | // VP8 Specific Info 217 | int vp8HScaleFactor; 218 | int vp8VScaleFactor; 219 | int vp8ScaleWidth; 220 | int vp8ScaleHeight; 221 | 222 | 223 | // H.264(AVC) Specific Info 224 | AvcVuiInfo avcVuiInfo; 225 | int avcIsExtSAR; 226 | int cropLeft; 227 | int cropTop; 228 | int cropRight; 229 | int cropBottom; 230 | int numSliceSize; 231 | int worstSliceSize; 232 | int maxNumRefFrmFlag; 233 | 234 | // VC-1 235 | int vc1Psf; 236 | 237 | // Mpeg2 238 | int mp2LowDelay; 239 | int mp2DispVerSize; 240 | int mp2DispHorSize; 241 | int userDataNum; 242 | int userDataSize; 243 | int userDataBufFull; 244 | int enableUserData; 245 | NX_MEMORY_INFO userDataBuffer; 246 | 247 | }VPU_DEC_SEQ_INIT_ARG; 248 | 249 | 250 | typedef struct 251 | { 252 | // Frame Buffers 253 | int numFrameBuffer; // Number Of Frame Buffers 254 | NX_VID_MEMORY_INFO frameBuffer[30]; // Frame Buffer Informations 255 | 256 | // MV Buffer Address 257 | NX_MEMORY_INFO colMvBuffer; 258 | 259 | // AVC Slice Buffer 260 | NX_MEMORY_INFO sliceBuffer; 261 | 262 | // VPX Codec Specific 263 | NX_MEMORY_INFO pvbSliceBuffer; 264 | 265 | }VPU_DEC_REG_FRAME_ARG; 266 | 267 | // VP8 specific display information 268 | typedef struct { 269 | unsigned int hScaleFactor : 2; 270 | unsigned int vScaleFactor : 2; 271 | unsigned int picWidth : 14; 272 | unsigned int picHeight : 14; 273 | } Vp8ScaleInfo; 274 | 275 | // VP8 specific header information 276 | typedef struct { 277 | unsigned int showFrame : 1; 278 | unsigned int versionNumber : 3; 279 | unsigned int refIdxLast : 8; 280 | unsigned int refIdxAltr : 8; 281 | unsigned int refIdxGold : 8; 282 | } Vp8PicInfo; 283 | 284 | typedef struct 285 | { 286 | // Input Arguments 287 | unsigned char *strmData; 288 | int strmDataSize; 289 | int iFrameSearchEnable; 290 | int skipFrameMode; 291 | int decSkipFrameNum; 292 | int eos; 293 | 294 | // Output Arguments 295 | int outWidth; 296 | int outHeight; 297 | 298 | VPU_RECT outRect; 299 | 300 | int indexFrameDecoded; 301 | int indexFrameDisplay; 302 | 303 | int picType; 304 | int picTypeFirst; 305 | int isInterace; 306 | int picStructure; 307 | int topFieldFirst; 308 | int repeatFirstField; 309 | int progressiveFrame; 310 | int fieldSequence; 311 | int npf; 312 | 313 | int isSuccess; 314 | 315 | int errReason; 316 | int errAddress; 317 | int numOfErrMBs; 318 | int sequenceChanged; 319 | 320 | unsigned int strmReadPos; 321 | unsigned int strmWritePos; 322 | 323 | // AVC Specific Informations 324 | int avcFpaSeiExist; 325 | int avcFpaSeiValue1; 326 | int avcFpaSeiValue2; 327 | 328 | // Output Bitstream Information 329 | unsigned int frameStartPos; 330 | unsigned int frameEndPos; 331 | 332 | // 333 | unsigned int notSufficientPsBuffer; 334 | unsigned int notSufficientSliceBuffer; 335 | 336 | // 337 | unsigned int fRateNumerator; 338 | unsigned int fRateDenominator; 339 | unsigned int aspectRateInfo; // Use vp8ScaleInfo & vp8PicInfo in VP8 340 | 341 | // 342 | unsigned int mp4ModuloTimeBase; 343 | unsigned int mp4TimeIncrement; 344 | 345 | // VP8 Scale Info 346 | Vp8ScaleInfo vp8ScaleInfo; 347 | Vp8PicInfo vp8PicInfo; 348 | 349 | // VC1 Info 350 | int multiRes; 351 | 352 | NX_VID_MEMORY_INFO outFrameBuffer; 353 | 354 | // MPEG2 User Data 355 | int userDataNum; // User Data 356 | int userDataSize; 357 | int userDataBufFull; 358 | int activeFormat; 359 | 360 | int iRet; 361 | 362 | // Jpeg Info 363 | int rstInterval; 364 | int userHuffTable; 365 | 366 | unsigned char *huffBits; 367 | unsigned char *huffPtr; 368 | unsigned int *huffMin; 369 | unsigned int *huffMax; 370 | unsigned char *huffValue; 371 | unsigned char *infoTable; 372 | unsigned char *quantTable; 373 | 374 | int huffAcIdx; 375 | int huffDcIdx; 376 | //int qIdx; 377 | 378 | int busReqNum; 379 | int mcuBlockNum; 380 | int compNum; 381 | int *compInfo; 382 | //int mcuwidth; 383 | //int mcuHeight; 384 | 385 | int width; 386 | int height; 387 | 388 | int pagePtr; 389 | int wordPtr; 390 | int bitPtr; 391 | 392 | int downScaleWidth; // 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling 393 | int downScaleHeight; // 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling 394 | 395 | NX_VID_MEMORY_HANDLE hCurrFrameBuffer; 396 | } VPU_DEC_DEC_FRAME_ARG; 397 | 398 | 399 | typedef struct 400 | { 401 | int indexFrameDisplay; 402 | NX_VID_MEMORY_INFO frameBuffer; 403 | } VPU_DEC_CLR_DSP_FLAG_ARG; 404 | 405 | 406 | ////////////////////////////////////////////////////////////////////////////// 407 | // 408 | // Command Arguments 409 | // 410 | 411 | 412 | // Define Codec Standard 413 | enum { 414 | CODEC_STD_AVC = 0, 415 | CODEC_STD_VC1 = 1, 416 | CODEC_STD_MPEG2 = 2, 417 | CODEC_STD_MPEG4 = 3, 418 | CODEC_STD_H263 = 4, 419 | CODEC_STD_DIV3 = 5, 420 | CODEC_STD_RV = 6, 421 | CODEC_STD_AVS = 7, 422 | CODEC_STD_MJPG = 8, 423 | 424 | CODEC_STD_THO = 9, 425 | CODEC_STD_VP3 = 10, 426 | CODEC_STD_VP8 = 11, 427 | 428 | CODEC_STD_HEVC = 12 429 | }; 430 | 431 | // Search Range 432 | enum { 433 | ME_SEARCH_RAGME_0, // Horizontal( -128 ~ 127 ), Vertical( -64 ~ 64 ) 434 | ME_SEARCH_RAGME_1, // Horizontal( -64 ~ 63 ), Vertical( -32 ~ 32 ) 435 | ME_SEARCH_RAGME_2, // Horizontal( -32 ~ 31 ), Vertical( -16 ~ 15 ) // default 436 | ME_SEARCH_RAGME_3, // Horizontal( -16 ~ 15 ), Vertical( -16 ~ 15 ) 437 | }; 438 | 439 | // Frame Buffer Format for JPEG 440 | enum { 441 | IMG_FORMAT_420 = 0, 442 | IMG_FORMAT_422 = 1, 443 | IMG_FORMAT_224 = 2, 444 | IMG_FORMAT_444 = 3, 445 | IMG_FORMAT_400 = 4 446 | }; 447 | 448 | // JPEG Mirror Direction 449 | enum { 450 | MIRDIR_NONE, 451 | MIRDIR_VER, 452 | MIRDIR_HOR, 453 | MIRDIR_HOR_VER, 454 | }; 455 | 456 | // 457 | // 458 | ////////////////////////////////////////////////////////////////////////////// 459 | 460 | #endif // __VPU_TYPES_H__ 461 | -------------------------------------------------------------------------------- /kernel-headers/linux/ion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * include/linux/ion.h 3 | * 4 | * Copyright (C) 2011 Google, Inc. 5 | * 6 | * This software is licensed under the terms of the GNU General Public 7 | * License version 2, as published by the Free Software Foundation, and 8 | * may be copied, distributed, and modified under those terms. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | */ 16 | 17 | #ifndef _LINUX_ION_H 18 | #define _LINUX_ION_H 19 | 20 | #include 21 | 22 | struct ion_handle; 23 | typedef struct ion_handle* ion_user_handle_t; 24 | 25 | /** 26 | * enum ion_heap_types - list of all possible types of heaps 27 | * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc 28 | * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc 29 | * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved 30 | * carveout heap, allocations are physically 31 | * contiguous 32 | * @ION_HEAP_TYPE_DMA: memory allocated via DMA API 33 | * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask 34 | * is used to identify the heaps, so only 32 35 | * total heap types are supported 36 | */ 37 | enum ion_heap_type { 38 | ION_HEAP_TYPE_SYSTEM, 39 | ION_HEAP_TYPE_SYSTEM_CONTIG, 40 | ION_HEAP_TYPE_CARVEOUT, 41 | ION_HEAP_TYPE_CHUNK, 42 | ION_HEAP_TYPE_DMA, 43 | ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always 44 | are at the end of this enum */ 45 | ION_NUM_HEAPS = 16, 46 | }; 47 | 48 | #define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) 49 | #define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) 50 | #define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) 51 | #define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) 52 | 53 | #define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 54 | 55 | /** 56 | * allocation flags - the lower 16 bits are used by core ion, the upper 16 57 | * bits are reserved for use by the heaps themselves. 58 | */ 59 | #define ION_FLAG_CACHED 1 /* mappings of this buffer should be 60 | cached, ion will do cache 61 | maintenance when the buffer is 62 | mapped for dma */ 63 | #define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created 64 | at mmap time, if this is set 65 | caches must be managed manually */ 66 | 67 | #ifdef __KERNEL__ 68 | struct ion_device; 69 | struct ion_heap; 70 | struct ion_mapper; 71 | struct ion_client; 72 | struct ion_buffer; 73 | 74 | /* This should be removed some day when phys_addr_t's are fully 75 | plumbed in the kernel, and all instances of ion_phys_addr_t should 76 | be converted to phys_addr_t. For the time being many kernel interfaces 77 | do not accept phys_addr_t's that would have to */ 78 | #define ion_phys_addr_t unsigned long 79 | 80 | /** 81 | * struct ion_platform_heap - defines a heap in the given platform 82 | * @type: type of the heap from ion_heap_type enum 83 | * @id: unique identifier for heap. When allocating higher numbers 84 | * will be allocated from first. At allocation these are passed 85 | * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. 86 | * @name: used for debug purposes 87 | * @base: base address of heap in physical memory if applicable 88 | * @size: size of the heap in bytes if applicable 89 | * @align: required alignment in physical memory if applicable 90 | * @priv: private info passed from the board file 91 | * 92 | * Provided by the board file. 93 | */ 94 | struct ion_platform_heap { 95 | enum ion_heap_type type; 96 | unsigned int id; 97 | const char *name; 98 | ion_phys_addr_t base; 99 | size_t size; 100 | ion_phys_addr_t align; 101 | void *priv; 102 | }; 103 | 104 | /** 105 | * struct ion_platform_data - array of platform heaps passed from board file 106 | * @nr: number of structures in the array 107 | * @heaps: array of platform_heap structions 108 | * 109 | * Provided by the board file in the form of platform data to a platform device. 110 | */ 111 | struct ion_platform_data { 112 | int nr; 113 | struct ion_platform_heap *heaps; 114 | }; 115 | 116 | /** 117 | * ion_reserve() - reserve memory for ion heaps if applicable 118 | * @data: platform data specifying starting physical address and 119 | * size 120 | * 121 | * Calls memblock reserve to set aside memory for heaps that are 122 | * located at specific memory addresses or of specfic sizes not 123 | * managed by the kernel 124 | */ 125 | void ion_reserve(struct ion_platform_data *data); 126 | 127 | /** 128 | * ion_client_create() - allocate a client and returns it 129 | * @dev: the global ion device 130 | * @heap_type_mask: mask of heaps this client can allocate from 131 | * @name: used for debugging 132 | */ 133 | struct ion_client *ion_client_create(struct ion_device *dev, 134 | const char *name); 135 | 136 | /** 137 | * ion_client_destroy() - free's a client and all it's handles 138 | * @client: the client 139 | * 140 | * Free the provided client and all it's resources including 141 | * any handles it is holding. 142 | */ 143 | void ion_client_destroy(struct ion_client *client); 144 | 145 | /** 146 | * ion_alloc - allocate ion memory 147 | * @client: the client 148 | * @len: size of the allocation 149 | * @align: requested allocation alignment, lots of hardware blocks 150 | * have alignment requirements of some kind 151 | * @heap_id_mask: mask of heaps to allocate from, if multiple bits are set 152 | * heaps will be tried in order from highest to lowest 153 | * id 154 | * @flags: heap flags, the low 16 bits are consumed by ion, the 155 | * high 16 bits are passed on to the respective heap and 156 | * can be heap custom 157 | * 158 | * Allocate memory in one of the heaps provided in heap mask and return 159 | * an opaque handle to it. 160 | */ 161 | struct ion_handle *ion_alloc(struct ion_client *client, size_t len, 162 | size_t align, unsigned int heap_id_mask, 163 | unsigned int flags); 164 | 165 | /** 166 | * ion_free - free a handle 167 | * @client: the client 168 | * @handle: the handle to free 169 | * 170 | * Free the provided handle. 171 | */ 172 | void ion_free(struct ion_client *client, struct ion_handle *handle); 173 | 174 | /** 175 | * ion_phys - returns the physical address and len of a handle 176 | * @client: the client 177 | * @handle: the handle 178 | * @addr: a pointer to put the address in 179 | * @len: a pointer to put the length in 180 | * 181 | * This function queries the heap for a particular handle to get the 182 | * handle's physical address. It't output is only correct if 183 | * a heap returns physically contiguous memory -- in other cases 184 | * this api should not be implemented -- ion_sg_table should be used 185 | * instead. Returns -EINVAL if the handle is invalid. This has 186 | * no implications on the reference counting of the handle -- 187 | * the returned value may not be valid if the caller is not 188 | * holding a reference. 189 | */ 190 | int ion_phys(struct ion_client *client, struct ion_handle *handle, 191 | ion_phys_addr_t *addr, size_t *len); 192 | 193 | /** 194 | * ion_map_dma - return an sg_table describing a handle 195 | * @client: the client 196 | * @handle: the handle 197 | * 198 | * This function returns the sg_table describing 199 | * a particular ion handle. 200 | */ 201 | struct sg_table *ion_sg_table(struct ion_client *client, 202 | struct ion_handle *handle); 203 | 204 | /** 205 | * ion_map_kernel - create mapping for the given handle 206 | * @client: the client 207 | * @handle: handle to map 208 | * 209 | * Map the given handle into the kernel and return a kernel address that 210 | * can be used to access this address. 211 | */ 212 | void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle); 213 | 214 | /** 215 | * ion_unmap_kernel() - destroy a kernel mapping for a handle 216 | * @client: the client 217 | * @handle: handle to unmap 218 | */ 219 | void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); 220 | 221 | /** 222 | * ion_share_dma_buf() - share buffer as dma-buf 223 | * @client: the client 224 | * @handle: the handle 225 | */ 226 | struct dma_buf *ion_share_dma_buf(struct ion_client *client, 227 | struct ion_handle *handle); 228 | 229 | /** 230 | * ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd 231 | * @client: the client 232 | * @handle: the handle 233 | */ 234 | int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle); 235 | 236 | /** 237 | * ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle 238 | * @client: the client 239 | * @fd: the dma-buf fd 240 | * 241 | * Given an dma-buf fd that was allocated through ion via ion_share_dma_buf, 242 | * import that fd and return a handle representing it. If a dma-buf from 243 | * another exporter is passed in this function will return ERR_PTR(-EINVAL) 244 | */ 245 | struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd); 246 | 247 | #endif /* __KERNEL__ */ 248 | 249 | /** 250 | * DOC: Ion Userspace API 251 | * 252 | * create a client by opening /dev/ion 253 | * most operations handled via following ioctls 254 | * 255 | */ 256 | 257 | /** 258 | * struct ion_allocation_data - metadata passed from userspace for allocations 259 | * @len: size of the allocation 260 | * @align: required alignment of the allocation 261 | * @heap_id_mask: mask of heap ids to allocate from 262 | * @flags: flags passed to heap 263 | * @handle: pointer that will be populated with a cookie to use to 264 | * refer to this allocation 265 | * 266 | * Provided by userspace as an argument to the ioctl 267 | */ 268 | struct ion_allocation_data { 269 | size_t len; 270 | size_t align; 271 | unsigned int heap_id_mask; 272 | unsigned int flags; 273 | struct ion_handle *handle; 274 | }; 275 | 276 | /** 277 | * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair 278 | * @handle: a handle 279 | * @fd: a file descriptor representing that handle 280 | * 281 | * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with 282 | * the handle returned from ion alloc, and the kernel returns the file 283 | * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace 284 | * provides the file descriptor and the kernel returns the handle. 285 | */ 286 | struct ion_fd_data { 287 | struct ion_handle *handle; 288 | int fd; 289 | }; 290 | 291 | /** 292 | * struct ion_handle_data - a handle passed to/from the kernel 293 | * @handle: a handle 294 | */ 295 | struct ion_handle_data { 296 | struct ion_handle *handle; 297 | }; 298 | 299 | /** 300 | * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl 301 | * @cmd: the custom ioctl function to call 302 | * @arg: additional data to pass to the custom ioctl, typically a user 303 | * pointer to a predefined structure 304 | * 305 | * This works just like the regular cmd and arg fields of an ioctl. 306 | */ 307 | struct ion_custom_data { 308 | unsigned int cmd; 309 | unsigned long arg; 310 | }; 311 | 312 | #define ION_IOC_MAGIC 'I' 313 | 314 | /** 315 | * DOC: ION_IOC_ALLOC - allocate memory 316 | * 317 | * Takes an ion_allocation_data struct and returns it with the handle field 318 | * populated with the opaque handle for the allocation. 319 | */ 320 | #define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ 321 | struct ion_allocation_data) 322 | 323 | /** 324 | * DOC: ION_IOC_FREE - free memory 325 | * 326 | * Takes an ion_handle_data struct and frees the handle. 327 | */ 328 | #define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) 329 | 330 | /** 331 | * DOC: ION_IOC_MAP - get a file descriptor to mmap 332 | * 333 | * Takes an ion_fd_data struct with the handle field populated with a valid 334 | * opaque handle. Returns the struct with the fd field set to a file 335 | * descriptor open in the current address space. This file descriptor 336 | * can then be used as an argument to mmap. 337 | */ 338 | #define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) 339 | 340 | /** 341 | * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation 342 | * 343 | * Takes an ion_fd_data struct with the handle field populated with a valid 344 | * opaque handle. Returns the struct with the fd field set to a file 345 | * descriptor open in the current address space. This file descriptor 346 | * can then be passed to another process. The corresponding opaque handle can 347 | * be retrieved via ION_IOC_IMPORT. 348 | */ 349 | #define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) 350 | 351 | /** 352 | * DOC: ION_IOC_IMPORT - imports a shared file descriptor 353 | * 354 | * Takes an ion_fd_data struct with the fd field populated with a valid file 355 | * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle 356 | * filed set to the corresponding opaque handle. 357 | */ 358 | #define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) 359 | 360 | /** 361 | * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory 362 | * 363 | * Deprecated in favor of using the dma_buf api's correctly (syncing 364 | * will happend automatically when the buffer is mapped to a device). 365 | * If necessary should be used after touching a cached buffer from the cpu, 366 | * this will make the buffer in memory coherent. 367 | */ 368 | #define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) 369 | 370 | /** 371 | * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl 372 | * 373 | * Takes the argument of the architecture specific ioctl to call and 374 | * passes appropriate userdata for that ioctl 375 | */ 376 | #define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) 377 | 378 | #endif /* _LINUX_ION_H */ 379 | -------------------------------------------------------------------------------- /kernel-headers/linux/media.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Multimedia device API 3 | * 4 | * Copyright (C) 2010 Nokia Corporation 5 | * 6 | * Contacts: Laurent Pinchart 7 | * Sakari Ailus 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef __LINUX_MEDIA_H 24 | #define __LINUX_MEDIA_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) 31 | 32 | struct media_device_info { 33 | char driver[16]; 34 | char model[32]; 35 | char serial[40]; 36 | char bus_info[32]; 37 | __u32 media_version; 38 | __u32 hw_revision; 39 | __u32 driver_version; 40 | __u32 reserved[31]; 41 | }; 42 | 43 | #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) 44 | 45 | #define MEDIA_ENT_TYPE_SHIFT 16 46 | #define MEDIA_ENT_TYPE_MASK 0x00ff0000 47 | #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff 48 | 49 | #define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) 50 | #define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) 51 | #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) 52 | #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) 53 | #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) 54 | 55 | #define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) 56 | #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) 57 | #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) 58 | #define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) 59 | 60 | #define MEDIA_ENT_FL_DEFAULT (1 << 0) 61 | 62 | struct media_entity_desc { 63 | __u32 id; 64 | char name[32]; 65 | __u32 type; 66 | __u32 revision; 67 | __u32 flags; 68 | __u32 group_id; 69 | __u16 pads; 70 | __u16 links; 71 | 72 | __u32 reserved[4]; 73 | 74 | union { 75 | /* Node specifications */ 76 | struct { 77 | __u32 major; 78 | __u32 minor; 79 | } v4l; 80 | struct { 81 | __u32 major; 82 | __u32 minor; 83 | } fb; 84 | struct { 85 | __u32 card; 86 | __u32 device; 87 | __u32 subdevice; 88 | } alsa; 89 | int dvb; 90 | 91 | /* Sub-device specifications */ 92 | /* Nothing needed yet */ 93 | __u8 raw[184]; 94 | }; 95 | }; 96 | 97 | #define MEDIA_PAD_FL_SINK (1 << 0) 98 | #define MEDIA_PAD_FL_SOURCE (1 << 1) 99 | 100 | struct media_pad_desc { 101 | __u32 entity; /* entity ID */ 102 | __u16 index; /* pad index */ 103 | __u32 flags; /* pad flags */ 104 | __u32 reserved[2]; 105 | }; 106 | 107 | #define MEDIA_LNK_FL_ENABLED (1 << 0) 108 | #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) 109 | #define MEDIA_LNK_FL_DYNAMIC (1 << 2) 110 | 111 | struct media_link_desc { 112 | struct media_pad_desc source; 113 | struct media_pad_desc sink; 114 | __u32 flags; 115 | __u32 reserved[2]; 116 | }; 117 | 118 | struct media_links_enum { 119 | __u32 entity; 120 | /* Should have enough room for pads elements */ 121 | struct media_pad_desc *pads; 122 | /* Should have enough room for links elements */ 123 | struct media_link_desc *links; 124 | __u32 reserved[4]; 125 | }; 126 | 127 | #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) 128 | #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) 129 | #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) 130 | #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) 131 | 132 | #endif /* __LINUX_MEDIA_H */ 133 | -------------------------------------------------------------------------------- /kernel-headers/linux/nxp_ion.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_NXP_ION_H_ 2 | #define _LINUX_NXP_ION_H_ 3 | 4 | #include 5 | 6 | enum { 7 | ION_HEAP_TYPE_NXP_CONTIG = ION_HEAP_TYPE_CUSTOM + 1, 8 | }; 9 | 10 | #define ION_HEAP_NXP_CONTIG_MASK (1 << ION_HEAP_TYPE_NXP_CONTIG) 11 | 12 | /* for private ioctl */ 13 | /* cmd */ 14 | #define NXP_ION_GET_PHY_ADDR 1 15 | #define NXP_ION_SYNC_FROM_DEVICE 2 16 | /* arg */ 17 | struct nxp_ion_physical { 18 | int ion_buffer_fd; /* input */ 19 | unsigned long phys; /* output */ 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /kernel-headers/linux/v4l2-mediabus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Media Bus API header 3 | * 4 | * Copyright (C) 2009, Guennadi Liakhovetski 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 2 as 8 | * published by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef __LINUX_V4L2_MEDIABUS_H 12 | #define __LINUX_V4L2_MEDIABUS_H 13 | 14 | #include 15 | #include 16 | 17 | /* 18 | * These pixel codes uniquely identify data formats on the media bus. Mostly 19 | * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is 20 | * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the 21 | * data format is fixed. Additionally, "2X8" means that one pixel is transferred 22 | * in two 8-bit samples, "BE" or "LE" specify in which order those samples are 23 | * transferred over the bus: "LE" means that the least significant bits are 24 | * transferred first, "BE" means that the most significant bits are transferred 25 | * first, and "PADHI" and "PADLO" define which bits - low or high, in the 26 | * incomplete high byte, are filled with padding bits. 27 | * 28 | * The pixel codes are grouped by type, bus_width, bits per component, samples 29 | * per pixel and order of subsamples. Numerical values are sorted using generic 30 | * numerical sort order (8 thus comes before 10). 31 | * 32 | * As their value can't change when a new pixel code is inserted in the 33 | * enumeration, the pixel codes are explicitly given a numerical value. The next 34 | * free values for each category are listed below, update them when inserting 35 | * new pixel codes. 36 | */ 37 | enum v4l2_mbus_pixelcode { 38 | V4L2_MBUS_FMT_FIXED = 0x0001, 39 | 40 | /* RGB - next is 0x1009 */ 41 | V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001, 42 | V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002, 43 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003, 44 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004, 45 | V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005, 46 | V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006, 47 | V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, 48 | V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, 49 | V4L2_MBUS_FMT_XRGB8888_4X8_LE = 0x1009, 50 | 51 | /* YUV (including grey) - next is 0x2014 */ 52 | V4L2_MBUS_FMT_Y8_1X8 = 0x2001, 53 | V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, 54 | V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, 55 | V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004, 56 | V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005, 57 | V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006, 58 | V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007, 59 | V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008, 60 | V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009, 61 | V4L2_MBUS_FMT_Y10_1X10 = 0x200a, 62 | V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, 63 | V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, 64 | V4L2_MBUS_FMT_Y12_1X12 = 0x2013, 65 | V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, 66 | V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, 67 | V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, 68 | V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, 69 | V4L2_MBUS_FMT_YUV8_1X24 = 0x2014, 70 | V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, 71 | V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, 72 | 73 | /* Bayer - next is 0x3015 */ 74 | V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, 75 | V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013, 76 | V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, 77 | V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014, 78 | V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, 79 | V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, 80 | V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, 81 | V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d, 82 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003, 83 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004, 84 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005, 85 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006, 86 | V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007, 87 | V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e, 88 | V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a, 89 | V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f, 90 | V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008, 91 | V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010, 92 | V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011, 93 | V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012, 94 | 95 | /* JPEG compressed formats - next is 0x4002 */ 96 | V4L2_MBUS_FMT_JPEG_1X8 = 0x4001, 97 | }; 98 | 99 | /** 100 | * struct v4l2_mbus_framefmt - frame format on the media bus 101 | * @width: frame width 102 | * @height: frame height 103 | * @code: data format code (from enum v4l2_mbus_pixelcode) 104 | * @field: used interlacing type (from enum v4l2_field) 105 | * @colorspace: colorspace of the data (from enum v4l2_colorspace) 106 | */ 107 | struct v4l2_mbus_framefmt { 108 | __u32 width; 109 | __u32 height; 110 | __u32 code; 111 | __u32 field; 112 | __u32 colorspace; 113 | __u32 reserved[7]; 114 | }; 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /kernel-headers/linux/v4l2-subdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * V4L2 subdev userspace API 3 | * 4 | * Copyright (C) 2010 Nokia Corporation 5 | * 6 | * Contacts: Laurent Pinchart 7 | * Sakari Ailus 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef __LINUX_V4L2_SUBDEV_H 24 | #define __LINUX_V4L2_SUBDEV_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | /** 31 | * enum v4l2_subdev_format_whence - Media bus format type 32 | * @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only 33 | * @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device 34 | */ 35 | enum v4l2_subdev_format_whence { 36 | V4L2_SUBDEV_FORMAT_TRY = 0, 37 | V4L2_SUBDEV_FORMAT_ACTIVE = 1, 38 | }; 39 | 40 | /** 41 | * struct v4l2_subdev_format - Pad-level media bus format 42 | * @which: format type (from enum v4l2_subdev_format_whence) 43 | * @pad: pad number, as reported by the media API 44 | * @format: media bus format (format code and frame size) 45 | */ 46 | struct v4l2_subdev_format { 47 | __u32 which; 48 | __u32 pad; 49 | struct v4l2_mbus_framefmt format; 50 | __u32 reserved[8]; 51 | }; 52 | 53 | /** 54 | * struct v4l2_subdev_crop - Pad-level crop settings 55 | * @which: format type (from enum v4l2_subdev_format_whence) 56 | * @pad: pad number, as reported by the media API 57 | * @rect: pad crop rectangle boundaries 58 | */ 59 | struct v4l2_subdev_crop { 60 | __u32 which; 61 | __u32 pad; 62 | struct v4l2_rect rect; 63 | __u32 reserved[8]; 64 | }; 65 | 66 | /** 67 | * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration 68 | * @pad: pad number, as reported by the media API 69 | * @index: format index during enumeration 70 | * @code: format code (from enum v4l2_mbus_pixelcode) 71 | */ 72 | struct v4l2_subdev_mbus_code_enum { 73 | __u32 pad; 74 | __u32 index; 75 | __u32 code; 76 | __u32 reserved[9]; 77 | }; 78 | 79 | /** 80 | * struct v4l2_subdev_frame_size_enum - Media bus format enumeration 81 | * @pad: pad number, as reported by the media API 82 | * @index: format index during enumeration 83 | * @code: format code (from enum v4l2_mbus_pixelcode) 84 | */ 85 | struct v4l2_subdev_frame_size_enum { 86 | __u32 index; 87 | __u32 pad; 88 | __u32 code; 89 | __u32 min_width; 90 | __u32 max_width; 91 | __u32 min_height; 92 | __u32 max_height; 93 | __u32 reserved[9]; 94 | }; 95 | 96 | /** 97 | * struct v4l2_subdev_frame_interval - Pad-level frame rate 98 | * @pad: pad number, as reported by the media API 99 | * @interval: frame interval in seconds 100 | */ 101 | struct v4l2_subdev_frame_interval { 102 | __u32 pad; 103 | struct v4l2_fract interval; 104 | __u32 reserved[9]; 105 | }; 106 | 107 | /** 108 | * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration 109 | * @pad: pad number, as reported by the media API 110 | * @index: frame interval index during enumeration 111 | * @code: format code (from enum v4l2_mbus_pixelcode) 112 | * @width: frame width in pixels 113 | * @height: frame height in pixels 114 | * @interval: frame interval in seconds 115 | */ 116 | struct v4l2_subdev_frame_interval_enum { 117 | __u32 index; 118 | __u32 pad; 119 | __u32 code; 120 | __u32 width; 121 | __u32 height; 122 | struct v4l2_fract interval; 123 | __u32 reserved[9]; 124 | }; 125 | 126 | #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) 127 | #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) 128 | #define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ 129 | _IOWR('V', 21, struct v4l2_subdev_frame_interval) 130 | #define VIDIOC_SUBDEV_S_FRAME_INTERVAL \ 131 | _IOWR('V', 22, struct v4l2_subdev_frame_interval) 132 | #define VIDIOC_SUBDEV_ENUM_MBUS_CODE \ 133 | _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) 134 | #define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \ 135 | _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) 136 | #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ 137 | _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) 138 | #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) 139 | #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /kernel-headers/linux/videodev2_nxp_media.h: -------------------------------------------------------------------------------- 1 | #ifndef _VIDEODEV2_NXP_MEDIA_H 2 | #define _VIDEODEV2_NXP_MEDIA_H 3 | 4 | /* 5 | * C O N T R O L S 6 | */ 7 | #define V4L2_CID_NXP_BASE V4L2_CTRL_CLASS_USER 8 | 9 | /* HDMI : 1 ~ 20 */ 10 | #define V4L2_CID_HDMI_HPD_STATUS (V4L2_CID_NXP_BASE + 1) 11 | #define V4L2_CID_HDMI_SET_DVI_MODE (V4L2_CID_NXP_BASE + 2) 12 | #define V4L2_CID_HDMI_GET_DVI_MODE (V4L2_CID_NXP_BASE + 3) 13 | #define V4L2_CID_HDMI_SET_ASPECT_RATIO (V4L2_CID_NXP_BASE + 4) 14 | #define V4L2_CID_HDMI_MAX_AUDIO_CHANNELS (V4L2_CID_NXP_BASE + 5) 15 | #define V4L2_CID_HDMI_ENABLE_HDMI_AUDIO (V4L2_CID_NXP_BASE + 6) 16 | #define V4L2_CID_HDMI_SET_NUM_CHANNELS (V4L2_CID_NXP_BASE + 7) 17 | #define V4L2_CID_HDMI_SET_COLOR_RANGE (V4L2_CID_NXP_BASE + 8) 18 | #define V4L2_CID_HDMI_ON_OFF (V4L2_CID_NXP_BASE + 9) 19 | 20 | /* MLC : 21 ~ 60 */ 21 | /* video : 21 ~ 40 */ 22 | #define V4L2_CID_MLC_VID_PRIORITY (V4L2_CID_NXP_BASE + 21) 23 | #define V4L2_CID_MLC_VID_COLORKEY (V4L2_CID_NXP_BASE + 22) 24 | #define V4L2_CID_MLC_VID_ALPHA (V4L2_CID_NXP_BASE + 23) 25 | #define V4L2_CID_MLC_VID_HFILTER (V4L2_CID_NXP_BASE + 24) 26 | #define V4L2_CID_MLC_VID_VFILTER (V4L2_CID_NXP_BASE + 25) 27 | /* rgb : 41 ~ 60 */ 28 | #define V4L2_CID_MLC_RGB_ALPHA (V4L2_CID_NXP_BASE + 41) 29 | #define V4L2_CID_MLC_RGB_TRANSCOLOR (V4L2_CID_NXP_BASE + 43) 30 | #define V4L2_CID_MLC_RGB_INVERTCOLOR (V4L2_CID_NXP_BASE + 45) 31 | #define V4L2_CID_MLC_RGB_BACKCOLOR (V4L2_CID_NXP_BASE + 47) 32 | #define V4L2_CID_MLC_RGB_INVALIDZONE (V4L2_CID_NXP_BASE + 50) 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /kernel-headers/mach/ioc_magic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2009 3 | * jung hyun kim, Nexell Co, 4 | * 5 | * See file CREDITS for list of people who contributed to this 6 | * project. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation; either version 2 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 | * MA 02111-1307 USA 22 | */ 23 | #ifndef __IOC_MAGIC_H__ 24 | #define __IOC_MAGIC_H__ 25 | 26 | /* IOC MACRO */ 27 | #ifndef _IO 28 | #define TYPE_SHIFT 8 29 | #define _IO(type,nr) ((type<>TYPE_SHIFT) & 0xFF) 31 | #define _IOC_NR(nr) (nr & 0xFF) 32 | #endif 33 | 34 | /* 35 | * _IOC_TYPE = 0x78 : IOC_NX_MAGIC & 0xFF 36 | */ 37 | #define IOC_NX_MAGIC 0x6e78 /* "nx" */ 38 | 39 | #endif /* __IOC_MAGIC_H__ */ 40 | -------------------------------------------------------------------------------- /kernel-headers/mach/nxp-scaler.h: -------------------------------------------------------------------------------- 1 | #ifndef _MACH_NXP_SCALER_H 2 | #define _MACH_NXP_SCALER_H 3 | 4 | #include "ioc_magic.h" 5 | 6 | struct nxp_scaler_ioctl_data { 7 | unsigned long src_phys[3]; 8 | unsigned long src_stride[3]; 9 | unsigned int src_width; 10 | unsigned int src_height; 11 | unsigned int src_code; 12 | unsigned long dst_phys[3]; 13 | unsigned long dst_stride[3]; 14 | unsigned int dst_width; 15 | unsigned int dst_height; 16 | unsigned int dst_code; 17 | }; 18 | 19 | enum { 20 | IOCTL_SCALER_SET_AND_RUN = _IO(IOC_NX_MAGIC, 1), 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /kernel-headers/media/videobuf2-ion-nxp.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEDIA_VIDEOBUF2_ION_NXP_H 2 | #define _MEDIA_VIDEOBUF2_ION_NXP_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* flags to vb2_ion_create_context 11 | * 12 | * bit 0 ~ ION_NUM_HEAPS: ion heap flags 13 | * bit ION_NUM_HEAPS+1 ~ 20: non-ion flags (cached, iommu) 14 | * bit 21 ~ BITS_PER_LONG - 1: ion specific flags 15 | */ 16 | 17 | /* allocate physical continuous memory */ 18 | #define VB2ION_CTX_PHCONTIG ION_HEAP_CARVEOUT_MASK 19 | /* allocate virtual memory */ 20 | #define VB2ION_CTX_VMCONTIG ION_HEAP_SYSTEM_MASK 21 | /* use iommu */ 22 | #define VB2ION_CTX_IOMMU (1 << (ION_NUM_HEAPS + 1)) /* not used */ 23 | /* use noncached memory */ 24 | #define VB2ION_CTX_UNCACHED (1 << (ION_NUM_HEAPS + 2)) 25 | 26 | #define VB2ION_CTX_MASK_ION (~((1 << (BITS_PER_LONG - 12)) - 1) \ 27 | | ((1 << ION_NUM_HEAPS) - 1)) 28 | 29 | /* mask out all non-ion flags */ 30 | #define ion_heapflag(flag) (flag & VB2ION_CTX_MASK_ION) 31 | 32 | struct device; 33 | struct vb2_buffer; 34 | 35 | void *vb2_ion_create_context(struct device *dev, size_t alignment, long flags); 36 | void vb2_ion_destroy_context(void *ctx); 37 | 38 | /* 39 | * data type of the cookie returned by vb2_plane_cookie() 40 | */ 41 | struct vb2_ion_cookie { 42 | dma_addr_t ioaddr; 43 | struct sg_table *sgt; 44 | off_t offset; 45 | }; 46 | 47 | /* 48 | * help functions 49 | */ 50 | int vb2_ion_set_alignement(void *ctx, size_t alignment); 51 | void *vb2_ion_private_vaddr(void *cookie); 52 | void *vb2_ion_private_alloc(void *alloc_ctx, size_t size); 53 | void vb2_ion_private_free(void *cookie); 54 | 55 | /* 56 | * inline functions 57 | */ 58 | static inline int vb2_ion_phys_address(void *cookie, phys_addr_t *phys_addr) 59 | { 60 | struct vb2_ion_cookie *vb2cookie = cookie; 61 | 62 | if (WARN_ON(!phys_addr || IS_ERR_OR_NULL(cookie))) 63 | return -EINVAL; 64 | 65 | if (vb2cookie->sgt->nents == 1) 66 | *phys_addr = sg_phys(vb2cookie->sgt->sgl) + vb2cookie->offset; 67 | else 68 | return -EINVAL; 69 | 70 | return 0; 71 | } 72 | 73 | static inline int vb2_ion_dma_address(void *cookie, dma_addr_t *dma_addr) 74 | { 75 | struct vb2_ion_cookie *vb2cookie = cookie; 76 | 77 | if (WARN_ON(!dma_addr || IS_ERR_OR_NULL(cookie))) 78 | return -EINVAL; 79 | 80 | if (vb2cookie->ioaddr == 0) 81 | return vb2_ion_phys_address(cookie, (phys_addr_t *)dma_addr); 82 | 83 | *dma_addr = vb2cookie->ioaddr; 84 | 85 | return 0; 86 | } 87 | 88 | static inline struct scatterlist *vb2_ion_get_sg(void *cookie, int *nents) 89 | { 90 | struct vb2_ion_cookie *vb2cookie = cookie; 91 | 92 | if (WARN_ON(!nents || IS_ERR_OR_NULL(cookie))) 93 | return NULL; 94 | 95 | *nents = vb2cookie->sgt->nents; 96 | return vb2cookie->sgt->sgl; 97 | } 98 | 99 | extern const struct vb2_mem_ops vb2_ion_memops; 100 | struct ion_device *get_global_ion_device(void); /* drivers/gpu/ion/nexell/nxp-ion.c */ 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /libion/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # Get Linux Build Enviornment: 3 | include ../Rules.make 4 | 5 | DESTDIR ?= ../out 6 | LIB_INSTALL := $(DESTDIR)/lib 7 | 8 | ###################################################################### 9 | # Build options 10 | CFLAGS += -fpic 11 | INCLUDE += -I../include -I../kernel-headers 12 | 13 | ###################################################################### 14 | # Target 15 | COBJS := ion.o 16 | CPPOBJS := 17 | 18 | ION_OBJS := ion.o 19 | ION_LIBNAME := libion 20 | ION_TARGET := $(ION_LIBNAME).a 21 | 22 | ###################################################################### 23 | # Build 24 | OBJS := $(COBJS) $(CPPOBJS) 25 | 26 | all: $(ION_TARGET) 27 | 28 | $(ION_TARGET): $(ION_OBJS) 29 | $(AR) $(ARFLAGS) $(ION_LIBNAME).a $< 30 | 31 | clean: 32 | rm -f *.o *.a *.so .depend 33 | 34 | install: 35 | install -m 755 -d $(LIB_INSTALL) 36 | install -m 644 $(ION_TARGET) $(LIB_INSTALL) 37 | 38 | distclean: clean 39 | rm -f $(LIB_INSTALL)/$(ION_LIBNAME).a 40 | 41 | ###################################################################### 42 | # Dependency 43 | ifeq (.depend,$(wildcard .depend)) 44 | include .depend 45 | else 46 | $(OBJS): depend 47 | endif 48 | 49 | SRCS := $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp) 50 | INCS := $(INCLUDE) 51 | depend dep: 52 | $(CC) -MM $(CFLAGS) $(INCS) $(SRCS) > .depend 53 | 54 | -------------------------------------------------------------------------------- /libion/ion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ion.c 3 | * 4 | * Memory Allocator functions for ion 5 | * 6 | * Copyright 2011 Google, Inc 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | #define LOG_TAG "ion" 21 | 22 | //#include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #ifdef ANDROID 34 | #include 35 | #else 36 | #include "ion.h" 37 | #endif 38 | 39 | #ifndef ANDROID 40 | #define ALOGE(x...) fprintf(stderr, x) 41 | #define ALOGD(x...) fprintf(stdout, x) 42 | #endif 43 | 44 | /* for nxp custom ioctl */ 45 | #define NXP_ION_GET_PHY_ADDR 1 46 | struct nxp_ion_physical { 47 | int ion_buffer_fd; 48 | unsigned long phys; 49 | }; 50 | 51 | int ion_open() 52 | { 53 | int fd = open("/dev/ion", O_RDWR); 54 | if (fd < 0) 55 | ALOGE("open /dev/ion failed!\n"); 56 | return fd; 57 | } 58 | 59 | int ion_close(int fd) 60 | { 61 | return close(fd); 62 | } 63 | 64 | static int ion_ioctl(int fd, int req, void *arg) 65 | { 66 | int ret = ioctl(fd, req, arg); 67 | if (ret < 0) { 68 | ALOGE("ioctl %x failed with code %d: %s\n", req, 69 | ret, strerror(errno)); 70 | return -errno; 71 | } 72 | return ret; 73 | } 74 | 75 | int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask, 76 | unsigned int flags, struct ion_handle **handle) 77 | { 78 | int ret; 79 | struct ion_allocation_data data = { 80 | .len = len, 81 | .align = align, 82 | .heap_id_mask = heap_mask, 83 | .flags = flags, 84 | }; 85 | 86 | ret = ion_ioctl(fd, ION_IOC_ALLOC, &data); 87 | if (ret < 0) 88 | return ret; 89 | *handle = data.handle; 90 | return ret; 91 | } 92 | 93 | int ion_free(int fd, struct ion_handle *handle) 94 | { 95 | struct ion_handle_data data = { 96 | .handle = handle, 97 | }; 98 | return ion_ioctl(fd, ION_IOC_FREE, &data); 99 | } 100 | 101 | int ion_map(int fd, struct ion_handle *handle, size_t length, int prot, 102 | int flags, off_t offset, unsigned char **ptr, int *map_fd) 103 | { 104 | struct ion_fd_data data = { 105 | .handle = handle, 106 | }; 107 | 108 | int ret = ion_ioctl(fd, ION_IOC_MAP, &data); 109 | if (ret < 0) 110 | return ret; 111 | *map_fd = data.fd; 112 | if (*map_fd < 0) { 113 | ALOGE("map ioctl returned negative fd\n"); 114 | return -EINVAL; 115 | } 116 | *ptr = mmap(NULL, length, prot, flags, *map_fd, offset); 117 | if (*ptr == MAP_FAILED) { 118 | ALOGE("mmap failed: %s\n", strerror(errno)); 119 | return -errno; 120 | } 121 | return ret; 122 | } 123 | 124 | int ion_share(int fd, struct ion_handle *handle, int *share_fd) 125 | { 126 | struct ion_fd_data data = { 127 | .handle = handle, 128 | }; 129 | 130 | int ret = ion_ioctl(fd, ION_IOC_SHARE, &data); 131 | if (ret < 0) 132 | return ret; 133 | *share_fd = data.fd; 134 | if (*share_fd < 0) { 135 | ALOGE("share ioctl returned negative fd\n"); 136 | return -EINVAL; 137 | } 138 | return ret; 139 | } 140 | 141 | int ion_alloc_fd(int fd, size_t len, size_t align, unsigned int heap_mask, 142 | unsigned int flags, int *handle_fd) { 143 | struct ion_handle *handle; 144 | int ret; 145 | 146 | ret = ion_alloc(fd, len, align, heap_mask, flags, &handle); 147 | if (ret < 0) 148 | return ret; 149 | ret = ion_share(fd, handle, handle_fd); 150 | ion_free(fd, handle); 151 | return ret; 152 | } 153 | 154 | int ion_import(int fd, int share_fd, struct ion_handle **handle) 155 | { 156 | struct ion_fd_data data = { 157 | .fd = share_fd, 158 | }; 159 | 160 | int ret = ion_ioctl(fd, ION_IOC_IMPORT, &data); 161 | if (ret < 0) 162 | return ret; 163 | *handle = data.handle; 164 | return ret; 165 | } 166 | 167 | int ion_sync_fd(int fd, int handle_fd) 168 | { 169 | struct ion_fd_data data = { 170 | .fd = handle_fd, 171 | }; 172 | return ion_ioctl(fd, ION_IOC_SYNC, &data); 173 | } 174 | 175 | int ion_get_phys(int fd, int buf_fd, unsigned long *phys) 176 | { 177 | int ret; 178 | struct ion_custom_data data; 179 | struct nxp_ion_physical custom_data; 180 | 181 | custom_data.ion_buffer_fd = buf_fd; 182 | data.cmd = NXP_ION_GET_PHY_ADDR; 183 | data.arg = (unsigned long)&custom_data; 184 | 185 | ret = ion_ioctl(fd, ION_IOC_CUSTOM, &data); 186 | if (ret) { 187 | ALOGE("%s error: failed ION_IOC_CUSTOM\n", __func__); 188 | return ret; 189 | } 190 | *phys = custom_data.phys; 191 | return 0; 192 | } 193 | -------------------------------------------------------------------------------- /libnxmalloc/Makefile: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Get Linux Build Enviornment: 3 | include ../Rules.make 4 | 5 | DESTDIR ?= ../out 6 | LIB_INSTALL := $(DESTDIR)/lib 7 | 8 | ###################################################################### 9 | # Build options 10 | INCLUDE += -I../libion -I../include -I../kernel-headers 11 | 12 | LIBRARY += -L../libion 13 | LIBRARY += -lion 14 | 15 | ###################################################################### 16 | # Target 17 | COBJS := 18 | COBJS += nx_alloc_mem_ion.o 19 | CPPOBJS := 20 | 21 | CFLAGS += -Wall -O2 -g -fpic 22 | 23 | LIBNAME := libnxvmem 24 | TARGET := libnxvmem.so 25 | 26 | ###################################################################### 27 | # Build 28 | OBJS := $(COBJS) $(CPPOBJS) 29 | 30 | all: $(TARGET) 31 | 32 | $(TARGET): $(OBJS) 33 | $(AR) $(ARFLAGS) $(LIBNAME).a $^ 34 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $^ $(LIBRARY) 35 | 36 | install: 37 | install -m 755 -d $(LIB_INSTALL) 38 | install -m 644 $(LIBNAME).a $(LIB_INSTALL) 39 | install -m 755 $(TARGET) $(LIB_INSTALL) 40 | 41 | clean: 42 | rm -f *.o *.so *.a .depend 43 | 44 | distclean: clean 45 | rm -f $(LIB_INSTALL)/$(LIBNAME).a 46 | rm -f $(LIB_INSTALL)/$(TARGET) 47 | 48 | 49 | ######################################################################### 50 | # Dependency 51 | ifeq (.depend,$(wildcard .depend)) 52 | include .depend 53 | else 54 | $(OBJS): depend 55 | endif 56 | 57 | SRCS := $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp) $(APPOBJS:.o=.c) 58 | INCS := $(INCLUDE) 59 | depend dep: 60 | $(CC) -MM $(CFLAGS) $(INCS) $(SRCS) > .depend 61 | 62 | -------------------------------------------------------------------------------- /libnxmalloc/nx_alloc_mem_ion.c: -------------------------------------------------------------------------------- 1 | #include // malloc & free 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #ifdef ANDROID 20 | #include 21 | #include 22 | #endif 23 | 24 | //#define EN_MULTIPLE_PLANE 25 | 26 | #define DTAG "[DEBUG|ALLOC] " 27 | #define ETAG "[ERROR|ALLOC] " 28 | 29 | #define DbgMsg(xxx...) do{ \ 30 | printf(DTAG); \ 31 | printf(xxx); \ 32 | }while(0) 33 | #define ErrMsg(xxx...) do{ \ 34 | printf(ETAG); \ 35 | printf("%s (line%d)\n", __FILE__, __LINE__); \ 36 | printf(xxx); \ 37 | }while(0) 38 | 39 | #ifndef ALIGN 40 | #define ALIGN(X,N) ( (X+N-1) & (~(N-1)) ) 41 | #endif 42 | 43 | #define ALIGNED16(X) ALIGN(X,16) 44 | 45 | // Nexell Private Memory Allocator for ION 46 | NX_MEMORY_HANDLE NX_AllocateMemory( int size, int align ) 47 | { 48 | int ret; 49 | int ionFd=-1, ionAllocFdVar=-1; 50 | unsigned long phyAddr; 51 | unsigned long virAddr; 52 | NX_MEMORY_HANDLE handle=NULL; 53 | 54 | handle = malloc(sizeof(NX_MEMORY_INFO)); 55 | if( NULL == handle ) 56 | { 57 | ErrMsg("Memory info allocation failed\n"); 58 | goto Error_Exit; 59 | } 60 | 61 | ionFd = ion_open(); 62 | if( ionFd < 0 ) 63 | { 64 | ErrMsg("ion_open failed\n"); 65 | goto Error_Exit; 66 | } 67 | 68 | // psw0523 for alloc from system 69 | ret = ion_alloc_fd( ionFd, size, align, ION_HEAP_NXP_CONTIG_MASK, 0, &ionAllocFdVar ); 70 | /* ret = ion_alloc_fd( ionFd, size, align, ION_HEAP_SYSTEM_MASK, 0, &ionAllocFdVar ); */ 71 | if( ret<0 ) 72 | { 73 | ErrMsg("ion_alloc_fd failed.(ret=%d)\n", ret); 74 | goto Error_Exit; 75 | } 76 | 77 | ret = ion_get_phys( ionFd, ionAllocFdVar, &phyAddr ); 78 | if( ret<0 ) 79 | { 80 | ErrMsg("ion_get_phys failed.(ret=%d)\n", ret); 81 | goto Error_Exit; 82 | } 83 | 84 | virAddr = (unsigned long)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, ionAllocFdVar, 0); 85 | 86 | if( MAP_FAILED == (void*)virAddr ) 87 | { 88 | ErrMsg("mmap failed.(size=%d, align=%d)\n", size, align); 89 | goto Error_Exit; 90 | } 91 | 92 | memset( (unsigned char*)virAddr, 0x80, size ); 93 | 94 | handle->privateDesc = (void*)ionAllocFdVar; 95 | handle->align = align; 96 | handle->size = size; 97 | handle->virAddr = virAddr; 98 | handle->phyAddr = phyAddr; 99 | close( ionFd ); 100 | return handle; 101 | 102 | Error_Exit: 103 | if( handle ) 104 | { 105 | if( ionFd > 0 ) 106 | { 107 | close( ionFd ); 108 | } 109 | if( ionAllocFdVar > 0 ) 110 | { 111 | close( ionFd ); 112 | } 113 | free(handle); 114 | } 115 | return NULL; 116 | } 117 | 118 | void NX_FreeMemory( NX_MEMORY_HANDLE handle ) 119 | { 120 | if( handle ) 121 | { 122 | if( handle->privateDesc ) 123 | { 124 | munmap( (void*)handle->virAddr, handle->size ); 125 | close( (int)handle->privateDesc ); 126 | } 127 | free( handle ); 128 | } 129 | } 130 | 131 | // Nexell Private Video Specific Allocator for ION 132 | NX_VID_MEMORY_HANDLE NX_VideoAllocateMemory( int align, int width, int height, int memMap, int fourCC ) 133 | { 134 | int lWidth, lHeight; 135 | int cWidth, cHeight; 136 | unsigned int lSize; // Luminance plane size 137 | unsigned int cSize; // Chrominance plane size 138 | NX_VID_MEMORY_HANDLE handle = NULL; 139 | NX_MEMORY_HANDLE luHandle=NULL, cbHandle=NULL, crHandle=NULL; 140 | 141 | handle = (NX_VID_MEMORY_HANDLE)calloc(sizeof(NX_VID_MEMORY_INFO), 1); 142 | if( NULL == handle ) 143 | { 144 | ErrMsg("Memory info allocation failed\n"); 145 | goto Error_Exit; 146 | } 147 | 148 | lWidth = ALIGN(width, 32); 149 | lHeight = ALIGN(height, 16); 150 | lSize = lWidth * lHeight; 151 | switch( fourCC ) 152 | { 153 | case FOURCC_MVS0: 154 | cWidth = ALIGN(width/2, 16); 155 | cHeight = ALIGN(height/2, 16); 156 | // cWidth = lWidth/2; 157 | // cHeight = lHeight/2; 158 | break; 159 | case FOURCC_MVS2: 160 | case FOURCC_H422: 161 | cWidth = ALIGN(width/2, 16); 162 | cHeight = lHeight; 163 | break; 164 | case FOURCC_V422: 165 | cWidth = lWidth; 166 | cHeight = ALIGN(height/2, 16); 167 | break; 168 | case FOURCC_MVS4: 169 | cWidth = lWidth; 170 | cHeight = lHeight; 171 | break; 172 | case FOURCC_NV12: 173 | case FOURCC_NV21: 174 | cWidth = lWidth; 175 | cHeight = lHeight/2; 176 | break; 177 | case FOURCC_GRAY: 178 | cWidth = 0; 179 | cHeight = 0; 180 | break; 181 | default: 182 | ErrMsg("Unknown fourCC type.\n"); 183 | goto Error_Exit; 184 | } 185 | cSize = cWidth * cHeight; 186 | 187 | #ifdef EN_MULTIPLE_PLANE 188 | luHandle = NX_AllocateMemory(lSize, align); 189 | if( NULL == luHandle ) 190 | { 191 | ErrMsg("NX_AllocateMemory failed!!\n"); 192 | goto Error_Exit; 193 | } 194 | 195 | if( cWidth > 0 ) 196 | { 197 | switch(fourCC) 198 | { 199 | case FOURCC_NV12: 200 | case FOURCC_NV21: 201 | cbHandle = NX_AllocateMemory(cSize, align); 202 | if( NULL==cbHandle ) 203 | { 204 | ErrMsg("NX_AllocateMemory failed!!\n"); 205 | goto Error_Exit; 206 | } 207 | break; 208 | default: 209 | cbHandle = NX_AllocateMemory(cSize, align); 210 | crHandle = NX_AllocateMemory(cSize, align); 211 | if( NULL==cbHandle || NULL==crHandle ) 212 | { 213 | ErrMsg("NX_AllocateMemory failed!!\n"); 214 | goto Error_Exit; 215 | } 216 | break; 217 | } 218 | } 219 | handle->privateDesc[0] = luHandle; 220 | handle->privateDesc[1] = cbHandle; 221 | handle->privateDesc[2] = crHandle; 222 | handle->align = align; 223 | handle->memoryMap = memMap; 224 | handle->fourCC = fourCC; 225 | handle->imgWidth = width; 226 | handle->imgHeight = height; 227 | handle->luPhyAddr = luHandle->phyAddr; 228 | handle->luVirAddr = luHandle->virAddr; 229 | handle->luStride = lWidth; 230 | if( cbHandle ) 231 | { 232 | handle->cbPhyAddr = cbHandle->phyAddr; 233 | handle->cbVirAddr = cbHandle->virAddr; 234 | handle->cbStride = cWidth; 235 | } 236 | if( crHandle ) 237 | { 238 | handle->crPhyAddr = crHandle->phyAddr; 239 | handle->crVirAddr = crHandle->virAddr; 240 | handle->crStride = cWidth; 241 | } 242 | #else 243 | luHandle = NX_AllocateMemory(lSize+cSize*2, align); 244 | handle->privateDesc[0] = luHandle; 245 | handle->privateDesc[1] = 0; 246 | handle->privateDesc[2] = 0; 247 | handle->align = align; // Start Address Align 248 | handle->memoryMap = memMap; 249 | handle->fourCC = fourCC; 250 | handle->imgWidth = width; 251 | handle->imgHeight = height; 252 | handle->luPhyAddr = luHandle->phyAddr; 253 | handle->luVirAddr = luHandle->virAddr; 254 | handle->luStride = lWidth; 255 | 256 | handle->cbPhyAddr = luHandle->phyAddr + lSize; 257 | handle->cbVirAddr = luHandle->virAddr + lSize; 258 | handle->cbStride = cWidth; 259 | 260 | if( fourCC == FOURCC_NV12 || fourCC == FOURCC_NV21 ) 261 | { 262 | // Write cb Address & Value 263 | handle->crPhyAddr = handle->cbPhyAddr; 264 | handle->crVirAddr = handle->cbVirAddr; 265 | handle->crStride = cWidth; 266 | } 267 | else 268 | { 269 | handle->crPhyAddr = handle->cbPhyAddr + cSize; 270 | handle->crVirAddr = handle->cbVirAddr + cSize; 271 | handle->crStride = cWidth; 272 | } 273 | #endif 274 | return handle; 275 | 276 | Error_Exit: 277 | if( handle ) 278 | { 279 | if( NULL != luHandle ) NX_FreeMemory( luHandle ); 280 | if( NULL != cbHandle ) NX_FreeMemory( cbHandle ); 281 | if( NULL != crHandle ) NX_FreeMemory( crHandle ); 282 | free(handle); 283 | } 284 | return handle; 285 | } 286 | 287 | // 288 | // For Interlace Camera 289 | // 290 | NX_VID_MEMORY_HANDLE NX_VideoAllocateMemory2( int align, int width, int height, int memMap, int fourCC ) 291 | { 292 | int lWidth, lHeight; 293 | int cWidth, cHeight; 294 | NX_VID_MEMORY_HANDLE handle = NULL; 295 | NX_MEMORY_HANDLE luHandle=NULL, cbHandle=NULL, crHandle=NULL; 296 | 297 | handle = (NX_VID_MEMORY_HANDLE)malloc(sizeof(NX_VID_MEMORY_INFO)); 298 | if( NULL == handle ) 299 | { 300 | ErrMsg("Memory info allocation failed\n"); 301 | goto Error_Exit; 302 | } 303 | 304 | lWidth = ALIGN(width, 64); 305 | lHeight = ALIGN(height, 16); 306 | 307 | switch( fourCC ) 308 | { 309 | case FOURCC_MVS0: 310 | cWidth = ALIGN(lWidth/2, 64); 311 | cHeight = lHeight/2; 312 | break; 313 | case FOURCC_MVS2: 314 | cWidth = lWidth/2; 315 | cHeight = ALIGN(height, 16); 316 | break; 317 | case FOURCC_MVS4: 318 | cWidth = ALIGN(width, 16); 319 | cHeight = ALIGN(height, 16); 320 | break; 321 | default: 322 | ErrMsg("Unknown fourCC type.\n"); 323 | goto Error_Exit; 324 | 325 | } 326 | 327 | luHandle = NX_AllocateMemory(lWidth*lHeight, align); 328 | if( NULL == luHandle ) 329 | { 330 | ErrMsg("NX_AllocateMemory failed!!\n"); 331 | goto Error_Exit; 332 | } 333 | 334 | if( cWidth > 0 ) 335 | { 336 | cbHandle = NX_AllocateMemory(cWidth*cHeight, align); 337 | crHandle = NX_AllocateMemory(cWidth*cHeight, align); 338 | if( NULL==cbHandle || NULL==crHandle ) 339 | { 340 | ErrMsg("NX_AllocateMemory failed!!\n"); 341 | goto Error_Exit; 342 | } 343 | } 344 | 345 | handle->privateDesc[0] = luHandle; 346 | handle->privateDesc[1] = cbHandle; 347 | handle->privateDesc[2] = crHandle; 348 | handle->align = align; 349 | handle->memoryMap = memMap; 350 | handle->fourCC = fourCC; 351 | handle->imgWidth = width; 352 | handle->imgHeight = height; 353 | handle->luPhyAddr = luHandle->phyAddr; 354 | handle->luVirAddr = luHandle->virAddr; 355 | handle->luStride = lWidth; 356 | handle->cbPhyAddr = cbHandle->phyAddr; 357 | handle->cbVirAddr = cbHandle->virAddr; 358 | handle->cbStride = cWidth; 359 | handle->crPhyAddr = crHandle->phyAddr; 360 | handle->crVirAddr = crHandle->virAddr; 361 | handle->crStride = cWidth; 362 | 363 | return handle; 364 | 365 | Error_Exit: 366 | if( handle ) 367 | { 368 | if( NULL != luHandle ) NX_FreeMemory( luHandle ); 369 | if( NULL != cbHandle ) NX_FreeMemory( cbHandle ); 370 | if( NULL != crHandle ) NX_FreeMemory( crHandle ); 371 | free(handle); 372 | } 373 | return handle; 374 | } 375 | 376 | void NX_FreeVideoMemory( NX_VID_MEMORY_HANDLE handle ) 377 | { 378 | if( handle ) 379 | { 380 | if( NULL != handle->privateDesc[0] ) NX_FreeMemory( handle->privateDesc[0] ); 381 | if( NULL != handle->privateDesc[1] ) NX_FreeMemory( handle->privateDesc[1] ); 382 | if( NULL != handle->privateDesc[2] ) NX_FreeMemory( handle->privateDesc[2] ); 383 | free(handle); 384 | } 385 | } 386 | 387 | #ifdef ANDROID 388 | 389 | int NX_PrivateHandleToVideoMemory( struct private_handle_t const *handle, NX_VID_MEMORY_INFO *memInfo ) 390 | { 391 | int ion_fd, ret, vstride; 392 | 393 | vstride = ALIGN(handle->height, 16); 394 | 395 | ion_fd = ion_open(); 396 | ret = ion_get_phys(ion_fd, handle->share_fd, (long unsigned int *)&memInfo->luPhyAddr); 397 | 398 | if( ret <0 || ion_fd < 0 ) 399 | { 400 | return -1; 401 | } 402 | 403 | memset(memInfo, 0, sizeof(NX_VID_MEMORY_INFO)); 404 | memInfo->fourCC = FOURCC_MVS0; 405 | memInfo->imgWidth = handle->width; 406 | memInfo->imgHeight = handle->height; 407 | memInfo->cbPhyAddr = memInfo->luPhyAddr + handle->stride * vstride; 408 | memInfo->crPhyAddr = memInfo->cbPhyAddr + ALIGN((handle->stride>>1),16) * ALIGN((vstride>>1),16); 409 | memInfo->luStride = handle->stride; 410 | memInfo->cbStride = 411 | memInfo->crStride = handle->stride >> 1;; 412 | close( ion_fd ); 413 | return 0; 414 | } 415 | 416 | #endif 417 | -------------------------------------------------------------------------------- /libnxv4l2/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # Get Linux Build Enviornment: 3 | include ../Rules.make 4 | 5 | DESTDIR ?= ../out 6 | LIB_INSTALL := $(DESTDIR)/lib 7 | 8 | ###################################################################### 9 | # Build Options 10 | CFLAGS := -Wall -O2 -g -fpic 11 | CPPFLAGS := -Wall -O2 -g -fpic 12 | INCLUDE += -I. -I../include -I../kernel-headers 13 | LIBRARY += -L. -lnxv4l2 14 | 15 | ###################################################################### 16 | # Target 17 | # nxp-v4l2.cpp : v4l2 original libaray 18 | # nxp-v4l2-media.cpp : v4l2 libaray for media-solution team 19 | COBJS := 20 | CPPOBJS := nxp-v4l2.o nxp-v4l2-media.o nxp-v4l2-dev.o nx_vip.o nx_dsp.o 21 | 22 | NXV4L2_OBJS := nxp-v4l2.o nxp-v4l2-dev.o 23 | NXV4L2_LIBNAME := libv4l2-nexell 24 | NXV4L2_TARGET := $(NXV4L2_LIBNAME).so 25 | 26 | V4L2_OBJS := nxp-v4l2-media.o nxp-v4l2-dev.o 27 | V4L2_LIBNAME := libnxv4l2 28 | V4L2_TARGET := $(V4L2_LIBNAME).so 29 | 30 | VIP_OBJS := nx_vip.o 31 | VIP_LIBNAME := libnxvip 32 | VIP_TARGET := $(VIP_LIBNAME).so 33 | 34 | DSP_OBJS := nx_dsp.o 35 | DSP_LIBNAME := libnxdsp 36 | DSP_TARGET := $(DSP_LIBNAME).so 37 | 38 | ###################################################################### 39 | # Build 40 | OBJS := $(COBJS) $(CPPOBJS) 41 | 42 | all: $(NXV4L2_TARGET) $(V4L2_TARGET) $(VIP_TARGET) $(DSP_TARGET) 43 | 44 | $(NXV4L2_TARGET): $(NXV4L2_OBJS) 45 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $^ 46 | $(AR) $(ARFLAGS) $(NXV4L2_LIBNAME).a $^ 47 | 48 | $(V4L2_TARGET): $(V4L2_OBJS) 49 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $^ 50 | $(AR) $(ARFLAGS) $(V4L2_LIBNAME).a $^ 51 | 52 | $(VIP_TARGET): $(VIP_OBJS) $(V4L2_TARGET) 53 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $(VIP_OBJS) $(LIBRARY) 54 | $(AR) $(ARFLAGS) $(VIP_LIBNAME).a $(VIP_OBJS) 55 | 56 | $(DSP_TARGET): $(DSP_OBJS) $(V4L2_TARGET) 57 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $(DSP_OBJS) $(LIBRARY) 58 | $(AR) $(ARFLAGS) $(DSP_LIBNAME).a $(DSP_OBJS) 59 | 60 | clean: 61 | rm -f *.o *.a *.so *.so.* .depend 62 | 63 | install: 64 | install -m 755 -d $(LIB_INSTALL) 65 | install -m 755 $(NXV4L2_TARGET) $(LIB_INSTALL) 66 | install -m 755 $(V4L2_TARGET) $(LIB_INSTALL) 67 | install -m 755 $(VIP_TARGET) $(LIB_INSTALL) 68 | install -m 755 $(DSP_TARGET) $(LIB_INSTALL) 69 | 70 | distclean: clean 71 | rm -f $(LIB_INSTALL)/$(NXV4L2_TARGET) 72 | rm -f $(LIB_INSTALL)/$(V4L2_TARGET) 73 | rm -f $(LIB_INSTALL)/$(VIP_TARGET) 74 | rm -f $(LIB_INSTALL)/$(DSP_TARGET) 75 | 76 | ######################################################################### 77 | # Dependency 78 | ifeq (.depend,$(wildcard .depend)) 79 | include .depend 80 | else 81 | $(OBJS): depend 82 | endif 83 | 84 | SRCS := $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp) 85 | INCS := $(INCLUDE) 86 | depend dep: 87 | $(CC) -MM $(CFLAGS) $(INCS) $(SRCS) > .depend 88 | 89 | -------------------------------------------------------------------------------- /libnxv4l2/nx_dsp.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (C) 2013 Nexell Co. All Rights Reserved 4 | // Nexell Co. Proprietary & Confidential 5 | // 6 | // NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE 7 | // AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING 8 | // BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS 9 | // FOR A PARTICULAR PURPOSE. 10 | // 11 | // Module : 12 | // File : 13 | // Description : 14 | // Author : 15 | // Export : 16 | // History : 17 | // 18 | //------------------------------------------------------------------------------ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "nx_dsp.h" 36 | 37 | typedef struct DISPLAY_HANDLE_INFO DISPLAY_HANDLE_INFO; 38 | 39 | struct DISPLAY_HANDLE_INFO { 40 | V4L2_PRIVATE_HANDLE hPrivate; 41 | 42 | // Setting values 43 | DISPLAY_INFO displayInfo; 44 | int32_t mlcId; // Internal V4L2 MLC's ID 45 | 46 | // Buffer Control Informations 47 | NX_VID_MEMORY_INFO *videoBuf[DISPLAY_MAX_BUF_SIZE]; 48 | int32_t numPlane; // video memory plane 49 | int32_t numberV4L2ReqBuf; // vidoe buffer size 50 | int32_t lastQueueIdx; 51 | 52 | int32_t streamOnFlag; // on/off flag 53 | pthread_mutex_t hMutex; 54 | }; 55 | 56 | DISPLAY_HANDLE NX_DspInit( DISPLAY_INFO *pDspInfo ) 57 | { 58 | DISPLAY_HANDLE hDisplay = NULL; 59 | V4L2_PRIVATE_HANDLE hPrivate = NULL; 60 | 61 | int32_t result; 62 | int32_t mlcPin, mlcId, format; 63 | 64 | struct V4l2UsageScheme s; 65 | memset(&s, 0, sizeof(s)); 66 | 67 | #ifndef DISABLE_PORT_CONFIG 68 | if( pDspInfo->port == DISPLAY_PORT_HDMI ) { 69 | s.useHdmi = true; 70 | } else if( pDspInfo->port == DISPLAY_PORT_TVOUT ) { 71 | s.useTvout = true; 72 | } 73 | #else 74 | s.useHdmi = false; 75 | printf("s.useHdmi == false\n"); 76 | #endif // DISABLE_PORT_CONFIG 77 | 78 | if( pDspInfo->module == DISPLAY_MODULE_MLC0 ) { 79 | s.useMlc0Video = true; 80 | s.useMlc1Video = false; 81 | s.useMlc0Rgb = false; 82 | s.useMlc1Rgb = false; 83 | 84 | mlcId = nxp_v4l2_mlc0_video; 85 | mlcPin = nxp_v4l2_mlc0; 86 | } 87 | else if( pDspInfo->module == DISPLAY_MODULE_MLC1 ) { 88 | s.useMlc0Video = false; 89 | s.useMlc1Video = true; 90 | s.useMlc0Rgb = false; 91 | s.useMlc1Rgb = false; 92 | 93 | mlcId = nxp_v4l2_mlc1_video; 94 | mlcPin = nxp_v4l2_mlc1; 95 | } 96 | else if( pDspInfo->module == DISPLAY_MODULE_MLC0_RGB ) { 97 | s.useMlc0Video = false; 98 | s.useMlc1Video = false; 99 | s.useMlc0Rgb = true; 100 | s.useMlc1Rgb = false; 101 | 102 | mlcId = nxp_v4l2_mlc0_rgb; 103 | mlcPin = nxp_v4l2_mlc0; 104 | } 105 | else if( pDspInfo->module == DISPLAY_MODULE_MLC1_RGB ) { 106 | s.useMlc0Video = false; 107 | s.useMlc1Video = false; 108 | s.useMlc0Rgb = false; 109 | s.useMlc1Rgb = true; 110 | 111 | mlcId = nxp_v4l2_mlc1_rgb; 112 | mlcPin = nxp_v4l2_mlc1; 113 | } 114 | else { 115 | return NULL; 116 | } 117 | 118 | if( NULL == (hPrivate = v4l2_init(&s)) ) { 119 | printf("%s(): v4l2_init() failed.\n", __FUNCTION__); 120 | return NULL; 121 | } 122 | 123 | v4l2_streamoff( hPrivate, mlcId ); 124 | 125 | #ifndef DISABLE_PORT_CONFIG 126 | if( pDspInfo->port == DISPLAY_PORT_HDMI ) { 127 | result = v4l2_link(hPrivate, mlcPin, nxp_v4l2_hdmi); 128 | if( result < 0 ) { 129 | printf("%s(): v4l2_link() failed.\n", __FUNCTION__); 130 | return NULL; 131 | } 132 | #if 1 133 | result = v4l2_set_preset( hPrivate, nxp_v4l2_hdmi, V4L2_DV_1080P60 ); 134 | if( result < 0 ) { 135 | printf("%s(): v4l2_set_preset() failed!\n", __FUNCTION__); 136 | } 137 | #endif 138 | } 139 | else if( pDspInfo->port == DISPLAY_PORT_TVOUT ) 140 | #endif // DISABLE_PORT_CONFIG 141 | { 142 | result = v4l2_link(hPrivate, mlcPin, nxp_v4l2_tvout); 143 | if( result < 0 ) { 144 | printf("%s(): v4l2_link() failed.\n", __FUNCTION__); 145 | return NULL; 146 | } 147 | } 148 | 149 | // check display plane and set format. 150 | if( pDspInfo->module == DISPLAY_MODULE_MLC0 || pDspInfo->module == DISPLAY_MODULE_MLC1 ) { 151 | if( pDspInfo->numPlane == 1 ) { 152 | result = v4l2_set_format( hPrivate, mlcId, pDspInfo->width, pDspInfo->height, PIXFORMAT_YUV420_YV12 ); 153 | } 154 | else { 155 | result = v4l2_set_format( hPrivate, mlcId, pDspInfo->width, pDspInfo->height, V4L2_PIX_FMT_YUV420M ); 156 | } 157 | } 158 | else { 159 | result = v4l2_set_format( hPrivate, mlcId, pDspInfo->width, pDspInfo->height, V4L2_PIX_FMT_RGB32 ); 160 | } 161 | if( result < 0 ) { 162 | printf("%s(): v4l2_set_format() failed!\n", __FUNCTION__); 163 | return NULL; 164 | } 165 | 166 | // Source Cropping. 167 | result = v4l2_set_crop_with_pad( 168 | hPrivate, mlcId, 2, 169 | pDspInfo->dspSrcRect.left, 170 | pDspInfo->dspSrcRect.top, 171 | pDspInfo->dspSrcRect.right-pDspInfo->dspSrcRect.left, 172 | pDspInfo->dspSrcRect.bottom-pDspInfo->dspSrcRect.top); 173 | if( result < 0 ) { 174 | printf("%s(): v4l2_set_crop() failed!\n", __FUNCTION__); 175 | return NULL; 176 | } 177 | 178 | // Destination Position 179 | result = v4l2_set_crop_with_pad( 180 | hPrivate, mlcId, 0, 181 | pDspInfo->dspDstRect.left, 182 | pDspInfo->dspDstRect.top, 183 | pDspInfo->dspDstRect.right-pDspInfo->dspDstRect.left , 184 | pDspInfo->dspDstRect.bottom-pDspInfo->dspDstRect.top); 185 | if( result < 0 ) { 186 | printf("%s(): v4l2_set_crop() failed!\n", __FUNCTION__); 187 | return NULL; 188 | } 189 | 190 | // Request Buffer. 191 | result = v4l2_reqbuf(hPrivate, mlcId, DISPLAY_MAX_BUF_SIZE); 192 | if( result < 0 ) { 193 | printf("%s(): v4l2_reqbuf() failed!\n", __FUNCTION__); 194 | goto ErrorExit; 195 | } 196 | 197 | // Create Handle. 198 | hDisplay = (DISPLAY_HANDLE)malloc( sizeof(DISPLAY_HANDLE_INFO) ); 199 | memset( hDisplay, 0, sizeof(DISPLAY_HANDLE_INFO) ); 200 | memcpy( &hDisplay->displayInfo, pDspInfo, sizeof(hDisplay->displayInfo) ); 201 | 202 | hDisplay->hPrivate = hPrivate; 203 | hDisplay->numPlane = pDspInfo->numPlane; 204 | hDisplay->streamOnFlag = 0; 205 | hDisplay->numberV4L2ReqBuf = DISPLAY_MAX_BUF_SIZE; 206 | hDisplay->mlcId = mlcId; 207 | 208 | return hDisplay; 209 | 210 | ErrorExit: 211 | if( hPrivate ) v4l2_exit( hPrivate ); 212 | 213 | return NULL; 214 | } 215 | 216 | void NX_DspClose( DISPLAY_HANDLE hDisplay ) 217 | { 218 | if( hDisplay ) 219 | { 220 | if( hDisplay->streamOnFlag ) { 221 | v4l2_streamoff( hDisplay->hPrivate, hDisplay->mlcId ); 222 | hDisplay->streamOnFlag = 0; 223 | } 224 | 225 | if( hDisplay->displayInfo.port == DISPLAY_PORT_HDMI ) { 226 | v4l2_unlink( hDisplay->hPrivate, hDisplay->mlcId, nxp_v4l2_hdmi ); 227 | } 228 | 229 | if( hDisplay->displayInfo.port == DISPLAY_PORT_TVOUT ) { 230 | v4l2_unlink( hDisplay->hPrivate, hDisplay->mlcId, nxp_v4l2_tvout ); 231 | } 232 | 233 | v4l2_exit( hDisplay->hPrivate ); 234 | 235 | if( hDisplay ) free(hDisplay); 236 | } 237 | } 238 | 239 | int32_t NX_DspQueueBuffer( DISPLAY_HANDLE hDisplay, NX_VID_MEMORY_INFO *pVidBuf ) 240 | { 241 | int32_t i; 242 | struct nxp_vid_buffer buf; 243 | NX_MEMORY_INFO *vidMem; 244 | 245 | buf.plane_num = hDisplay->numPlane; 246 | for( i = 0; i < hDisplay->numPlane; i++ ) 247 | { 248 | vidMem = (NX_MEMORY_INFO *)pVidBuf->privateDesc[i]; 249 | buf.fds[i] = (int)vidMem->privateDesc; 250 | buf.virt[i] = (char*)vidMem->virAddr; 251 | buf.phys[i] = (unsigned long)vidMem->phyAddr; 252 | buf.sizes[i] = vidMem->size; 253 | } 254 | 255 | if( v4l2_qbuf(hDisplay->hPrivate, hDisplay->mlcId, hDisplay->numPlane, hDisplay->lastQueueIdx, &buf, -1, NULL) < 0 ) 256 | { 257 | printf("%s(): v4l2_qbuf() failed.\n", __FUNCTION__); 258 | return -1; 259 | } 260 | 261 | hDisplay->lastQueueIdx = (hDisplay->lastQueueIdx + 1) % DISPLAY_MAX_BUF_SIZE; 262 | if( !hDisplay->streamOnFlag ) 263 | { 264 | v4l2_streamon( hDisplay->hPrivate, hDisplay->mlcId ); 265 | hDisplay->streamOnFlag = true; 266 | } 267 | return 0; 268 | } 269 | 270 | int32_t NX_DspRgbQueueBuffer( DISPLAY_HANDLE hDisplay, NX_MEMORY_INFO *pMemInfo ) 271 | { 272 | int32_t i; 273 | struct nxp_vid_buffer buf; 274 | 275 | buf.plane_num = 1; 276 | buf.fds[0] = (int)pMemInfo->privateDesc; 277 | buf.virt[0] = (char*)pMemInfo->virAddr; 278 | buf.phys[0] = (unsigned long)pMemInfo->phyAddr; 279 | buf.sizes[0] = pMemInfo->size; 280 | 281 | if( v4l2_qbuf(hDisplay->hPrivate, hDisplay->mlcId, 1, hDisplay->lastQueueIdx, &buf, -1, NULL) < 0 ) 282 | { 283 | printf("%s(): v4l2_qbuf() failed.\n", __FUNCTION__); 284 | return -1; 285 | } 286 | 287 | hDisplay->lastQueueIdx = (hDisplay->lastQueueIdx + 1) % DISPLAY_MAX_BUF_SIZE; 288 | if( !hDisplay->streamOnFlag ) 289 | { 290 | v4l2_streamon( hDisplay->hPrivate, hDisplay->mlcId ); 291 | hDisplay->streamOnFlag = true; 292 | } 293 | return 0; 294 | } 295 | 296 | int32_t NX_DspDequeueBuffer(DISPLAY_HANDLE hDisplay) 297 | { 298 | int32_t idx; 299 | 300 | if( v4l2_dqbuf(hDisplay->hPrivate, hDisplay->mlcId, hDisplay->numPlane, &idx, NULL) < 0 ) 301 | { 302 | printf("%s(): v4l2_dqbuf() failed.\n", __FUNCTION__); 303 | return -1; 304 | } 305 | return idx; 306 | } 307 | 308 | int32_t NX_DspStreamControl( DISPLAY_HANDLE hDisplay, int32_t bEnable ) 309 | { 310 | printf("%s(): Not implemetation.\n", __FUNCTION__); 311 | return 0; 312 | 313 | if( hDisplay ) 314 | { 315 | if( bEnable ) 316 | { 317 | if( !hDisplay->streamOnFlag ) 318 | { 319 | hDisplay->streamOnFlag = true; 320 | v4l2_streamon(hDisplay->hPrivate, hDisplay->mlcId); 321 | } 322 | } 323 | else 324 | { 325 | if( hDisplay->streamOnFlag ) 326 | { 327 | hDisplay->streamOnFlag = false; 328 | v4l2_streamoff(hDisplay->hPrivate, hDisplay->mlcId); 329 | } 330 | } 331 | } 332 | else 333 | { 334 | return -1; 335 | } 336 | 337 | return 0; 338 | } 339 | 340 | int32_t NX_DspVideoSetSourceFormat( DISPLAY_HANDLE hDisplay, int32_t width, int32_t height, int32_t stride, int32_t fourcc ) 341 | { 342 | DISPLAY_INFO *pDspInfo; 343 | DSP_IMG_RECT *pDstRect; 344 | DSP_IMG_RECT *pSrcRect; 345 | if( !hDisplay || !hDisplay->hPrivate ) 346 | { 347 | return -1; 348 | } 349 | if( width < 1 || height < 1 ) 350 | { 351 | return -1; 352 | } 353 | 354 | pDspInfo = &hDisplay->displayInfo; 355 | 356 | if( ( pDspInfo->width != width ) || 357 | ( pDspInfo->height != height ) || 358 | ( pDspInfo->height != stride ) /*|| 359 | ( pDspInfo->height != forcc ) */) 360 | { 361 | if( hDisplay->streamOnFlag ) 362 | { 363 | if( v4l2_streamoff(hDisplay->hPrivate, hDisplay->mlcId)<0 ) 364 | { 365 | printf("%s:Line(%d) Error : v4l2_streamoff failed.!\n", __FILE__, __LINE__ ); 366 | } 367 | hDisplay->streamOnFlag = false; 368 | } 369 | // Set Format 370 | if( v4l2_set_format(hDisplay->hPrivate, hDisplay->mlcId, stride, height, PIXFORMAT_YUV420_PLANAR) < 0 ) 371 | { 372 | printf("v4l2_set_format() failed!!!\n"); 373 | return -1; 374 | } 375 | // update source image format 376 | pDspInfo->width = width; 377 | pDspInfo->height = height; 378 | pDspInfo->stride = stride; 379 | pDspInfo->fourcc = fourcc; 380 | 381 | pDstRect = &pDspInfo->dspDstRect; 382 | pSrcRect = &pDspInfo->dspSrcRect; 383 | 384 | if( v4l2_set_crop_with_pad(hDisplay->hPrivate, hDisplay->mlcId, 0, pSrcRect->left, pSrcRect->top, pSrcRect->right-pSrcRect->left, pSrcRect->bottom-pSrcRect->top) < 0 ) 385 | { 386 | printf("%s:Line(%d) Error : v4l2_set_crop_with_pad failed(%p,%d,%d,%d,%d,%d,%d)!!!\n", 387 | __FILE__, __LINE__, hDisplay->hPrivate, hDisplay->mlcId, 1, pSrcRect->left, pSrcRect->top, pSrcRect->right-pSrcRect->left, pSrcRect->bottom-pSrcRect->top ); 388 | return -1; 389 | } 390 | } 391 | return 0; 392 | } 393 | 394 | int32_t NX_DspVideoSetSourceCrop( DISPLAY_HANDLE hDisplay, DSP_IMG_RECT *pRect ) 395 | { 396 | DISPLAY_INFO *pDspInfo; 397 | if( !hDisplay || !hDisplay->hPrivate ) 398 | { 399 | return -1; 400 | } 401 | if( (1 > (pRect->right-pRect->left)) || (1 > (pRect->bottom-pRect->top)) ) 402 | { 403 | return -1; 404 | } 405 | 406 | pDspInfo = &hDisplay->displayInfo; 407 | 408 | if( (pDspInfo->dspSrcRect.left != pRect->left ) || 409 | (pDspInfo->dspSrcRect.top != pRect->top ) || 410 | (pDspInfo->dspSrcRect.right != pRect->right ) || 411 | (pDspInfo->dspSrcRect.bottom != pRect->bottom) ) 412 | { 413 | if( 0 > v4l2_set_crop_with_pad(hDisplay->hPrivate, hDisplay->mlcId, 2, pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top) ) 414 | { 415 | printf("%s:Line(%d) Error : v4l2_set_crop_with_pad failed(%p,%d,%d,%d,%d,%d,%d)!!!\n", 416 | __FILE__, __LINE__, hDisplay->hPrivate, hDisplay->mlcId, 2, pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top ); 417 | return -1; 418 | } 419 | 420 | // Update Display Information 421 | pDspInfo->dspSrcRect = *pRect; 422 | } 423 | return 0; 424 | } 425 | 426 | int32_t NX_DspVideoSetPosition( DISPLAY_HANDLE hDisplay, DSP_IMG_RECT *pRect ) 427 | { 428 | DISPLAY_INFO *pDspInfo; 429 | if( !hDisplay || !hDisplay->hPrivate ) 430 | { 431 | return -1; 432 | } 433 | if( (1 > (pRect->right-pRect->left)) || (1 > (pRect->bottom-pRect->top)) ) 434 | { 435 | return -1; 436 | } 437 | 438 | pDspInfo = &hDisplay->displayInfo; 439 | 440 | if( (pDspInfo->dspDstRect.left != pRect->left ) || 441 | (pDspInfo->dspDstRect.top != pRect->top ) || 442 | (pDspInfo->dspDstRect.right != pRect->right ) || 443 | (pDspInfo->dspDstRect.bottom != pRect->bottom) ) 444 | { 445 | if( 0 > v4l2_set_crop_with_pad(hDisplay->hPrivate, hDisplay->mlcId, 0, pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top) ) 446 | { 447 | printf("%s():Line(%d) Error : v4l2_set_crop failed(%p,%d,%d,%d,%d,%d)!!!\n", 448 | __FUNCTION__, __LINE__, hDisplay->hPrivate, hDisplay->mlcId, pRect->left, pRect->top, pRect->right-pRect->left, pRect->bottom-pRect->top ); 449 | return -1; 450 | } 451 | 452 | // Update Display Information 453 | pDspInfo->dspDstRect = *pRect; 454 | } 455 | return 0; 456 | } 457 | 458 | int32_t NX_DspVideoSetPriority( int32_t module, int32_t priority ) 459 | { 460 | V4L2_PRIVATE_HANDLE hPrivate = NULL; 461 | int32_t mlcId, ret = 0; 462 | 463 | struct V4l2UsageScheme s; 464 | memset(&s, 0, sizeof(s)); 465 | 466 | if( module == DISPLAY_MODULE_MLC0 ) { 467 | s.useMlc0Video = true; 468 | mlcId = nxp_v4l2_mlc0_video; 469 | } 470 | else if( module == DISPLAY_MODULE_MLC1 ) { 471 | s.useMlc1Video = true; 472 | mlcId = nxp_v4l2_mlc1_video; 473 | } 474 | else { 475 | return -1; 476 | } 477 | 478 | if( NULL == (hPrivate = v4l2_init(&s)) ) { 479 | printf("%s(): v4l2_init() failed.\n", __FUNCTION__); 480 | ret = -1; 481 | } 482 | 483 | if( 0 > v4l2_set_ctrl( hPrivate, mlcId, V4L2_CID_MLC_VID_PRIORITY, priority ) ) { 484 | printf("%s(): v4l2_set_ctrl() failed.\n", __FUNCTION__); 485 | ret = -1; 486 | } 487 | 488 | if( hPrivate ) v4l2_exit(hPrivate); 489 | return ret; 490 | } 491 | 492 | int32_t NX_DspVideoGetPriority( int32_t module, int32_t *priority ) 493 | { 494 | V4L2_PRIVATE_HANDLE hPrivate = NULL; 495 | int32_t mlcId, ret = 0; 496 | 497 | struct V4l2UsageScheme s; 498 | memset(&s, 0, sizeof(s)); 499 | 500 | if( module == DISPLAY_MODULE_MLC0 ) { 501 | s.useMlc0Video = true; 502 | mlcId = nxp_v4l2_mlc0_video; 503 | } 504 | else if( module == DISPLAY_MODULE_MLC1 ) { 505 | s.useMlc1Video = true; 506 | mlcId = nxp_v4l2_mlc1_video; 507 | } 508 | else { 509 | return -1; 510 | } 511 | 512 | if( NULL == (hPrivate = v4l2_init(&s)) ) { 513 | printf("%s(): v4l2_init() failed.\n", __FUNCTION__); 514 | ret = -1; 515 | } 516 | 517 | if( 0 > v4l2_get_ctrl( hPrivate, mlcId, V4L2_CID_MLC_VID_PRIORITY, priority ) ) { 518 | printf("%s(): v4l2_get_ctrl() failed.\n", __FUNCTION__); 519 | ret = -1; 520 | } 521 | 522 | if( hPrivate ) v4l2_exit(hPrivate); 523 | return ret; 524 | } 525 | 526 | int32_t NX_DspSetColorKey( int32_t module, int32_t colorkey ) 527 | { 528 | V4L2_PRIVATE_HANDLE hPrivate = NULL; 529 | int32_t mlcId, ret = 0; 530 | 531 | struct V4l2UsageScheme s; 532 | memset(&s, 0, sizeof(s)); 533 | 534 | if( module == DISPLAY_MODULE_MLC0 ) { 535 | s.useMlc0Video = true; 536 | mlcId = nxp_v4l2_mlc0_video; 537 | } 538 | else if( module == DISPLAY_MODULE_MLC1 ) { 539 | s.useMlc1Video = true; 540 | mlcId = nxp_v4l2_mlc1_video; 541 | } 542 | else { 543 | return -1; 544 | } 545 | 546 | if( NULL == (hPrivate = v4l2_init(&s)) ) { 547 | printf("%s(): v4l2_init() failed.\n", __FUNCTION__); 548 | ret = -1; 549 | } 550 | 551 | if( 0 > v4l2_set_ctrl( hPrivate, mlcId, V4L2_CID_MLC_VID_COLORKEY, colorkey ) ) { 552 | printf("%s(): v4l2_set_ctrl() failed.\n", __FUNCTION__); 553 | ret = -1; 554 | } 555 | 556 | if( hPrivate ) v4l2_exit(hPrivate); 557 | return ret; 558 | } 559 | 560 | int32_t NX_DspGetColorKey( int32_t module, int32_t *colorkey ) 561 | { 562 | V4L2_PRIVATE_HANDLE hPrivate = NULL; 563 | int32_t mlcId, ret = 0; 564 | 565 | struct V4l2UsageScheme s; 566 | memset(&s, 0, sizeof(s)); 567 | 568 | if( module == DISPLAY_MODULE_MLC0 ) { 569 | s.useMlc0Video = true; 570 | mlcId = nxp_v4l2_mlc0_video; 571 | } 572 | else if( module == DISPLAY_MODULE_MLC1 ) { 573 | s.useMlc1Video = true; 574 | mlcId = nxp_v4l2_mlc1_video; 575 | } 576 | else { 577 | return -1; 578 | } 579 | 580 | if( NULL == (hPrivate = v4l2_init(&s)) ) { 581 | printf("%s(): v4l2_init() failed.\n", __FUNCTION__); 582 | ret = -1; 583 | } 584 | 585 | if( 0 > v4l2_get_ctrl( hPrivate, mlcId, V4L2_CID_MLC_VID_COLORKEY, colorkey ) ) { 586 | printf("%s(): v4l2_get_ctrl() failed.\n", __FUNCTION__); 587 | ret = -1; 588 | } 589 | 590 | if( hPrivate ) v4l2_exit(hPrivate); 591 | return ret; 592 | } -------------------------------------------------------------------------------- /libnxv4l2/nxp-v4l2-dev.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXP_V4L2_DEV_H 2 | #define _NXP_V4L2_DEV_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifdef ANDROID 24 | #include 25 | #endif 26 | 27 | class V4l2Device { 28 | public: 29 | typedef enum { 30 | LINK_INVALID = 0, 31 | LINK_DISCONNECTED, 32 | LINK_CONNECTED, 33 | } LinkStatus; 34 | 35 | public: 36 | V4l2Device() 37 | : FD(-1), 38 | EntityID(-1), 39 | PadNum(0), 40 | LinkNum(0), 41 | Name(NULL), 42 | PadDesc(NULL), 43 | LinkDesc(NULL) 44 | { 45 | } 46 | 47 | virtual ~V4l2Device() { 48 | if (FD >= 0) 49 | close(FD); 50 | if (Name) 51 | delete[] Name; 52 | if (PadDesc) 53 | delete[] PadDesc; 54 | if (LinkDesc) 55 | delete[] LinkDesc; 56 | } 57 | 58 | /* for link */ 59 | virtual LinkStatus checkLink(int myPad, int remoteEntity, int remotePad); 60 | virtual int getSinkPadFor(int remoteEntity, int remotePad = -1); 61 | virtual int getSourcePadFor(int remoteEntity, int remotePad = -1); 62 | 63 | /* pure virtual */ 64 | virtual int setFormat(int w, int h, int format, int index = 0) = 0; 65 | virtual int getFormat(int *w, int *h, int *format, int index = 0) = 0; 66 | virtual int setCrop(int l, int t, int w, int h, int index = 0) = 0; 67 | virtual int getCrop(int *l, int *t, int *w, int *h, int index = 0) = 0; 68 | virtual int reqBuf(int count) = 0; 69 | virtual int qBuf(int planeNum, int index0, int *fds0, int *sizes0, 70 | int index1 = 0, int *fds1 = NULL, int *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) = 0; 71 | virtual int qBuf(int planeNum, int index0, int const *fds0, int const *sizes0, 72 | int index1 = 0, int const *fds1 = NULL, int const *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) = 0; 73 | virtual int dqBuf(int planeNum, int *index0, int *index1 = NULL) = 0; 74 | virtual int streamOn() = 0; 75 | virtual int streamOff() = 0; 76 | virtual long long getTimeStamp() = 0; 77 | virtual int setPreset(uint32_t preset) = 0; 78 | 79 | /* common */ 80 | virtual int setCtrl(int ctrlId, int value); 81 | virtual int getCtrl(int ctrlId, int *value); 82 | 83 | virtual bool activate(); 84 | 85 | virtual bool linkDefault(int srcPad=-1, int sinkPad=-1) = 0; 86 | public: 87 | /* accessors */ 88 | char *getName() { 89 | return Name; 90 | } 91 | int getFD() { 92 | return FD; 93 | } 94 | int getEntityID() { 95 | return EntityID; 96 | } 97 | int getPadNum() { 98 | return PadNum; 99 | } 100 | struct media_pad_desc *getPadDesc() { 101 | return PadDesc; 102 | } 103 | int getLinkNum() { 104 | return LinkNum; 105 | } 106 | struct media_link_desc *getLinkDesc() { 107 | return LinkDesc; 108 | } 109 | 110 | protected: 111 | bool init(char *name, int entityId, int padNum, struct media_pad_desc *pDesc, 112 | int linkNum, struct media_link_desc *lDesc); 113 | 114 | protected: 115 | /* device node name */ 116 | int FD; 117 | int EntityID; 118 | int PadNum; 119 | int LinkNum; 120 | char *Name; 121 | struct media_pad_desc *PadDesc; 122 | struct media_link_desc *LinkDesc; 123 | }; 124 | 125 | class V4l2Subdev : public V4l2Device { 126 | public: 127 | V4l2Subdev(char *name, int entityId, int padNum, struct media_pad_desc *pDesc, 128 | int linkNum, struct media_link_desc *lDesc) { 129 | if (!init(name, entityId, padNum, pDesc, linkNum, lDesc)) 130 | #ifdef ANDROID 131 | return; 132 | #else 133 | throw -EINVAL; 134 | #endif 135 | } 136 | virtual ~V4l2Subdev() { 137 | } 138 | 139 | virtual int setFormat(int w, int h, int format, int index = 0); 140 | virtual int getFormat(int *w, int *h, int *format, int index = 0); 141 | virtual int setCrop(int l, int t, int w, int h, int index = 0); 142 | virtual int getCrop(int *l, int *t, int *w, int *h, int index = 0); 143 | virtual int setPreset(uint32_t preset); 144 | virtual int reqBuf(int count) { 145 | return -EINVAL; 146 | } 147 | virtual int qBuf(int planeNum, int index0, int *fds0, int *sizes0, 148 | int index1 = 0, int *fds1 = NULL, int *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) { 149 | return -EINVAL; 150 | } 151 | virtual int qBuf(int planeNum, int index0, int const *fds0, int const *sizes0, 152 | int index1 = 0, int const *fds1 = NULL, int const *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) { 153 | return -EINVAL; 154 | } 155 | virtual int dqBuf(int planeNum, int *index0, int *index1) { 156 | return -EINVAL; 157 | } 158 | virtual int streamOn() { 159 | return -EINVAL; 160 | } 161 | virtual int streamOff() { 162 | return -EINVAL; 163 | } 164 | virtual long long getTimeStamp() { 165 | return 0; 166 | } 167 | virtual bool linkDefault(int srcPad=-1, int sinkPad=-1) { 168 | return true; 169 | } 170 | }; 171 | 172 | #define NXP_VIDEO_MAX_BUFFER_PLANES 3 173 | class V4l2Video : public V4l2Device { 174 | public: 175 | V4l2Video(char *name, int entityId, int padNum, struct media_pad_desc *pDesc, 176 | int linkNum, struct media_link_desc *lDesc, 177 | bool isM2M, unsigned int bufType, unsigned int memoryType) 178 | : IsM2M(isM2M), 179 | BufType(bufType), 180 | MemoryType(memoryType) 181 | { 182 | if (!init(name, entityId, padNum, pDesc, linkNum, lDesc)) 183 | #ifdef ANDROID 184 | return; 185 | #else 186 | throw -EINVAL; 187 | #endif 188 | if (isM2M) 189 | BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 190 | } 191 | virtual ~V4l2Video() { 192 | } 193 | 194 | virtual int setFormat(int w, int h, int format, int index = 0); 195 | virtual int getFormat(int *w, int *h, int *format, int index = 0); 196 | virtual int setCrop(int l, int t, int w, int h, int index = 0); 197 | virtual int getCrop(int *l, int *t, int *w, int *h, int index = 0); 198 | virtual int reqBuf(int count); 199 | virtual int qBuf(int planeNum, int index0, int *fds0, int *sizes0, 200 | int index1 = 0, int *fds1 = NULL, int *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL); 201 | virtual int qBuf(int planeNum, int index0, int const *fds0, int const *sizes0, 202 | int index1 = 0, int const *fds1 = NULL, int const *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL); 203 | virtual int dqBuf(int planeNum, int *index0, int *index1 = NULL); 204 | virtual int streamOn(); 205 | virtual int streamOff(); 206 | virtual long long getTimeStamp() { 207 | return TimeStamp; 208 | } 209 | virtual bool linkDefault(int srcPad=-1, int sinkPad=-1) { 210 | return true; 211 | } 212 | virtual int setPreset(uint32_t preset) { 213 | return -EINVAL; 214 | } 215 | 216 | private: 217 | bool IsM2M; 218 | /* 219 | * V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 220 | * V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE 221 | */ 222 | unsigned int BufType; 223 | /* 224 | * V4L2_MEMORY_DMABUF 225 | * V4L2_MEMORY_MMAP 226 | * V4L2_MEMORY_USERPTR 227 | */ 228 | unsigned int MemoryType; 229 | 230 | long long TimeStamp; 231 | }; 232 | 233 | class V4l2Composite : public V4l2Device { 234 | public: 235 | typedef enum { 236 | capture, 237 | m2m, 238 | out 239 | } CompositionType; 240 | 241 | V4l2Composite() { 242 | } 243 | V4l2Composite(int mediaFD, V4l2Device *subDev, V4l2Device *videoDev, CompositionType type = capture) 244 | : MediaFD(mediaFD), 245 | SubDev(subDev), 246 | VideoDev(videoDev), 247 | Type(type) 248 | { 249 | } 250 | virtual ~V4l2Composite() { 251 | } 252 | 253 | virtual int setFormat(int w, int h, int format, int index = 0) { 254 | return VideoDev->setFormat(w, h, format); 255 | } 256 | virtual int getFormat(int *w, int *h, int *format, int index = 0) { 257 | return VideoDev->getFormat(w, h, format); 258 | } 259 | virtual int setCrop(int l, int t, int w, int h, int index = 0) { 260 | return VideoDev->setCrop(l, t, w, h, index); 261 | } 262 | virtual int getCrop(int *l, int *t, int *w, int *h, int index = 0) { 263 | return VideoDev->getCrop(l, t, w, h); 264 | } 265 | virtual int setCtrl(int ctrlId, int value) { 266 | return VideoDev->setCtrl(ctrlId, value); 267 | } 268 | virtual int getCtrl(int ctrlId, int *value) { 269 | return VideoDev->getCtrl(ctrlId, value); 270 | } 271 | virtual int reqBuf(int count) { 272 | return VideoDev->reqBuf(count); 273 | } 274 | virtual int qBuf(int planeNum, int index0, int *fds0, int *sizes0, 275 | int index1 = 0, int *fds1 = NULL, int *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) { 276 | return VideoDev->qBuf(planeNum, 277 | index0, fds0, sizes0, index1, fds1, sizes1, syncfd0, syncfd1); 278 | } 279 | virtual int qBuf(int planeNum, int index0, int const *fds0, int const *sizes0, 280 | int index1 = 0, int const *fds1 = NULL, int const *sizes1 = NULL, int *syncfd0 = NULL, int *syncfd1 = NULL) { 281 | return VideoDev->qBuf(planeNum, 282 | index0, fds0, sizes0, index1, fds1, sizes1, syncfd0, syncfd1); 283 | } 284 | virtual int dqBuf(int planeNum, int *index0, int *index1 = NULL) { 285 | return VideoDev->dqBuf(planeNum, index0, index1); 286 | } 287 | virtual int streamOn() { 288 | return VideoDev->streamOn(); 289 | } 290 | virtual int streamOff() { 291 | return VideoDev->streamOff(); 292 | } 293 | 294 | virtual LinkStatus checkLink(int myPad, int remoteEntity, int remotePad) { 295 | return SubDev->checkLink(myPad, remoteEntity, remotePad); 296 | } 297 | 298 | virtual int getSinkPadFor(int remoteEntity, int remotePad = -1) { 299 | return SubDev->getSinkPadFor(remoteEntity, remotePad); 300 | } 301 | 302 | virtual int getSourcePadFor(int remoteEntity, int remotePad = -1) { 303 | return SubDev->getSourcePadFor(remoteEntity, remotePad); 304 | } 305 | 306 | virtual bool activate(); 307 | 308 | virtual long long getTimeStamp() { 309 | return VideoDev->getTimeStamp(); 310 | } 311 | 312 | virtual int setPreset(uint32_t preset) { 313 | return SubDev->setPreset(preset); 314 | } 315 | 316 | virtual bool linkDefault(int srcPad=-1, int sinkPad=-1); 317 | 318 | private: 319 | int MediaFD; 320 | V4l2Device *SubDev; 321 | V4l2Device *VideoDev; 322 | CompositionType Type; 323 | 324 | private: 325 | }; 326 | 327 | #endif 328 | -------------------------------------------------------------------------------- /libnxv4l2/nxp-v4l2-media.cpp: -------------------------------------------------------------------------------- 1 | #include "nxp-v4l2-media.h" 2 | 3 | #ifdef ANDROID 4 | #define LOG_TAG "nxp-v4l2" 5 | #include 6 | #include 7 | #include 8 | #endif 9 | #include "assert.h" 10 | #include "nxp-v4l2-private.cpp" 11 | 12 | /** 13 | * static interface class 14 | */ 15 | static V4l2NexellPrivate *_priv = NULL; 16 | 17 | /** 18 | * format 19 | */ 20 | struct PixFormatPixCode PixelArray[MAX_PIXFORMAT] = { 21 | {PIXFORMAT_YUV422_PACKED, PIXCODE_YUV422_PACKED}, 22 | {PIXFORMAT_YUV420_PLANAR, PIXCODE_YUV420_PLANAR}, // 3 Plane 23 | {PIXFORMAT_YUV420_YV12, PIXCODE_YUV420_PLANAR}, // 1 Plane 24 | {PIXFORMAT_YUV422_PLANAR, PIXCODE_YUV422_PLANAR}, 25 | {PIXFORMAT_YUV444_PLANAR, PIXCODE_YUV444_PLANAR} 26 | }; 27 | 28 | /** 29 | * public api 30 | */ 31 | V4L2_PRIVATE_HANDLE v4l2_init(const struct V4l2UsageScheme *scheme) 32 | { 33 | V4l2NexellPrivate *_priv = NULL; 34 | 35 | if (!_priv) { 36 | _priv = new V4l2NexellPrivate(); 37 | if (!_priv) { 38 | ALOGE("Fatal Error: can't allocate context"); 39 | return _priv; 40 | } 41 | 42 | int ret = _priv->init(scheme); 43 | if (ret < 0) { 44 | ALOGE("Fatal Error: init failed"); 45 | delete _priv; 46 | _priv = NULL; 47 | return _priv; 48 | } 49 | } 50 | return (V4L2_PRIVATE_HANDLE*)_priv; 51 | } 52 | 53 | void v4l2_exit(V4L2_PRIVATE_HANDLE pHandle) 54 | { 55 | if (pHandle) { 56 | delete (V4l2NexellPrivate*)pHandle; 57 | pHandle = NULL; 58 | } 59 | } 60 | 61 | int v4l2_link(V4L2_PRIVATE_HANDLE pHandle, int src_id, int dst_id) 62 | { 63 | assert(pHandle); 64 | return ((V4l2NexellPrivate*)pHandle)->link(src_id, dst_id); 65 | } 66 | 67 | int v4l2_unlink(V4L2_PRIVATE_HANDLE pHandle, int src_id, int dst_id) 68 | { 69 | assert(pHandle); 70 | return ((V4l2NexellPrivate*)pHandle)->unlink(src_id, dst_id); 71 | } 72 | 73 | int v4l2_set_format(V4L2_PRIVATE_HANDLE pHandle, int id, int w, int h, int f) 74 | { 75 | assert(pHandle); 76 | return ((V4l2NexellPrivate*)pHandle)->setFormat(id, w, h, f); 77 | } 78 | 79 | int v4l2_get_format(V4L2_PRIVATE_HANDLE pHandle, int id, int *w, int *h, int *f) 80 | { 81 | assert(pHandle); 82 | return ((V4l2NexellPrivate*)pHandle)->getFormat(id, w, h, f); 83 | } 84 | 85 | int v4l2_set_crop(V4L2_PRIVATE_HANDLE pHandle, int id, int l, int t, int w, int h) 86 | { 87 | assert(pHandle); 88 | return ((V4l2NexellPrivate*)pHandle)->setCrop(id, l, t, w, h); 89 | } 90 | 91 | int v4l2_get_crop(V4L2_PRIVATE_HANDLE pHandle, int id, int *l, int *t, int *w, int *h) 92 | { 93 | assert(pHandle); 94 | return ((V4l2NexellPrivate*)pHandle)->getCrop(id, l, t, w, h); 95 | } 96 | 97 | int v4l2_set_format_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int w, int h, int f) 98 | { 99 | assert(pHandle); 100 | return ((V4l2NexellPrivate*)pHandle)->setFormat(id, w, h, f, pad); 101 | } 102 | 103 | int v4l2_get_format_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int *w, int *h, int *f) 104 | { 105 | assert(pHandle); 106 | return ((V4l2NexellPrivate*)pHandle)->getFormat(id, w, h, f, pad); 107 | } 108 | 109 | int v4l2_set_crop_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int l, int t, int w, int h) 110 | { 111 | assert(pHandle); 112 | return ((V4l2NexellPrivate*)pHandle)->setCrop(id, l, t, w, h, pad); 113 | } 114 | 115 | int v4l2_get_crop_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int *l, int *t, int *w, int *h) 116 | { 117 | assert(pHandle); 118 | return ((V4l2NexellPrivate*)pHandle)->getCrop(id, l, t, w, h, pad); 119 | } 120 | 121 | int v4l2_set_ctrl(V4L2_PRIVATE_HANDLE pHandle, int id, int ctrl_id, int value) 122 | { 123 | assert(pHandle); 124 | return ((V4l2NexellPrivate*)pHandle)->setCtrl(id, ctrl_id, value); 125 | } 126 | 127 | int v4l2_get_ctrl(V4L2_PRIVATE_HANDLE pHandle, int id, int ctrl_id, int *value) 128 | { 129 | assert(pHandle); 130 | return ((V4l2NexellPrivate*)pHandle)->getCtrl(id, ctrl_id, value); 131 | } 132 | 133 | int v4l2_reqbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int buf_count) 134 | { 135 | assert(pHandle); 136 | return ((V4l2NexellPrivate*)pHandle)->reqBuf(id, buf_count); 137 | } 138 | 139 | #ifdef ANDROID 140 | int v4l2_qbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int index0, struct private_handle_t *b0, int index1, struct private_handle_t *b1, 141 | int *syncfd0, int *syncfd1) 142 | { 143 | assert(pHandle); 144 | 145 | if (b1) { 146 | if (plane_num == 1) 147 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0, index1, &b1->share_fd, &b1->size, syncfd1); 148 | else { 149 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 150 | int srcFds1[3] = { b1->share_fd, b1->share_fd1, b1->share_fd2 }; 151 | int sizes0[3]; 152 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 153 | switch (b0->format) { 154 | case HAL_PIXEL_FORMAT_YV12: 155 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 156 | sizes0[2] = sizes0[1]; 157 | break; 158 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 159 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 160 | sizes0[2] = 0; 161 | break; 162 | } 163 | int sizes1[3]; 164 | sizes1[0] = b1->stride * ALIGN(b1->height, 16); 165 | switch (b1->format) { 166 | case HAL_PIXEL_FORMAT_YV12: 167 | sizes1[1] = ALIGN(b1->stride >> 1, 16) * ALIGN(b1->height >> 1, 16); 168 | sizes1[2] = sizes1[1]; 169 | break; 170 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 171 | sizes1[1] = b1->stride * ALIGN(b1->height >> 1, 16); 172 | sizes1[2] = 0; 173 | break; 174 | } 175 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0, index1, srcFds1, sizes1, syncfd1); 176 | } 177 | } else { 178 | if (plane_num == 1) 179 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0); 180 | else { 181 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 182 | int sizes0[3]; 183 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 184 | switch (b0->format) { 185 | case HAL_PIXEL_FORMAT_YV12: 186 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 187 | sizes0[2] = sizes0[1]; 188 | break; 189 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 190 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 191 | sizes0[2] = 0; 192 | break; 193 | } 194 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0); 195 | } 196 | } 197 | } 198 | 199 | int v4l2_qbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int index0, struct private_handle_t const *b0, int index1, struct private_handle_t const *b1, 200 | int *syncfd0, int *syncfd1) 201 | { 202 | assert(pHandle); 203 | 204 | if (b1) { 205 | if (plane_num == 1) 206 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0, index1, &b1->share_fd, &b1->size, syncfd1); 207 | else { 208 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 209 | int srcFds1[3] = { b1->share_fd, b1->share_fd1, b1->share_fd2 }; 210 | int sizes0[3]; 211 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 212 | switch (b0->format) { 213 | case HAL_PIXEL_FORMAT_YV12: 214 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 215 | sizes0[2] = sizes0[1]; 216 | break; 217 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 218 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 219 | sizes0[2] = 0; 220 | break; 221 | } 222 | int sizes1[3]; 223 | sizes1[0] = b1->stride * ALIGN(b1->height, 16); 224 | switch (b1->format) { 225 | case HAL_PIXEL_FORMAT_YV12: 226 | sizes1[1] = ALIGN(b1->stride >> 1, 16) * ALIGN(b1->height >> 1, 16); 227 | sizes1[2] = sizes1[1]; 228 | break; 229 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 230 | sizes1[1] = b1->stride * ALIGN(b1->height >> 1, 16); 231 | sizes1[2] = 0; 232 | break; 233 | } 234 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0, index1, srcFds1, sizes1, syncfd1); 235 | } 236 | } else { 237 | if (plane_num == 1) 238 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0); 239 | else { 240 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 241 | int sizes0[3]; 242 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 243 | switch (b0->format) { 244 | case HAL_PIXEL_FORMAT_YV12: 245 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 246 | sizes0[2] = sizes0[1]; 247 | break; 248 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 249 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 250 | sizes0[2] = 0; 251 | break; 252 | } 253 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0); 254 | } 255 | } 256 | } 257 | #endif 258 | 259 | int v4l2_qbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int index0, struct nxp_vid_buffer *b0, int index1, struct nxp_vid_buffer *b1) 260 | { 261 | assert(pHandle); 262 | 263 | if (b1) 264 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, b0->fds, b0->sizes, NULL, index1, b1->fds, b1->sizes, NULL); 265 | else 266 | return ((V4l2NexellPrivate*)pHandle)->qBuf(id, plane_num, index0, b0->fds, b0->sizes, NULL); 267 | } 268 | 269 | int v4l2_dqbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int *index0, int *index1) 270 | { 271 | assert(pHandle); 272 | 273 | if (index1) 274 | return ((V4l2NexellPrivate*)pHandle)->dqBuf(id, plane_num, index0, index1); 275 | else 276 | return ((V4l2NexellPrivate*)pHandle)->dqBuf(id, plane_num, index0); 277 | } 278 | 279 | int v4l2_streamon(V4L2_PRIVATE_HANDLE pHandle, int id) 280 | { 281 | assert(pHandle); 282 | 283 | return ((V4l2NexellPrivate*)pHandle)->streamOn(id); 284 | } 285 | 286 | int v4l2_streamoff(V4L2_PRIVATE_HANDLE pHandle, int id) 287 | { 288 | assert(pHandle); 289 | 290 | return ((V4l2NexellPrivate*)pHandle)->streamOff(id); 291 | } 292 | 293 | int v4l2_get_timestamp(V4L2_PRIVATE_HANDLE pHandle, int id, long long *timestamp) 294 | { 295 | assert(pHandle); 296 | 297 | return ((V4l2NexellPrivate*)pHandle)->getTimeStamp(id, timestamp); 298 | } 299 | 300 | int v4l2_set_preset(V4L2_PRIVATE_HANDLE pHandle, int id, uint32_t preset) 301 | { 302 | assert(pHandle); 303 | 304 | return ((V4l2NexellPrivate*)pHandle)->setPreset(id, preset); 305 | } 306 | 307 | int v4l2_get_device_fd(V4L2_PRIVATE_HANDLE pHandle, int id) 308 | { 309 | assert(pHandle); 310 | 311 | return ((V4l2NexellPrivate*)pHandle)->getDeviceFD(id); 312 | } 313 | -------------------------------------------------------------------------------- /libnxv4l2/nxp-v4l2-media.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (C) 2013 Nexell Co. All Rights Reserved 4 | // Nexell Co. Proprietary & Confidential 5 | // 6 | // NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE 7 | // AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING 8 | // BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS 9 | // FOR A PARTICULAR PURPOSE. 10 | // 11 | // Module : 12 | // File : 13 | // Description : 14 | // Author : 15 | // Export : 16 | // History : 17 | // 18 | //------------------------------------------------------------------------------ 19 | 20 | #ifndef _NXP_V4L2_H 21 | #define _NXP_V4L2_H 22 | 23 | #ifdef ANDROID 24 | #include 25 | #else 26 | #include 27 | #include 28 | #endif 29 | 30 | #define MAX_BUFFER_PLANES 3 31 | struct nxp_vid_buffer { 32 | int plane_num; 33 | int fds[MAX_BUFFER_PLANES]; 34 | char *virt[MAX_BUFFER_PLANES]; 35 | unsigned long phys[MAX_BUFFER_PLANES]; 36 | int sizes[MAX_BUFFER_PLANES]; 37 | }; 38 | 39 | /* pixel code */ 40 | #define PIXCODE_YUV422_PACKED V4L2_MBUS_FMT_YUYV8_2X8 41 | #define PIXCODE_YUV420_PLANAR V4L2_MBUS_FMT_YUYV8_1_5X8 42 | #define PIXCODE_YUV422_PLANAR V4L2_MBUS_FMT_YUYV8_1X16 43 | #define PIXCODE_YUV444_PLANAR V4L2_MBUS_FMT_YUV8_1X24 44 | 45 | /* pixel format */ 46 | #define PIXFORMAT_YUV422_PACKED V4L2_PIX_FMT_YUYV 47 | #define PIXFORMAT_YUV420_PLANAR V4L2_PIX_FMT_YUV420M // 3 plane 48 | #define PIXFORMAT_YUV420_YV12 V4L2_PIX_FMT_YUV420 // 1 Plane 49 | #define PIXFORMAT_YUV422_PLANAR V4L2_PIX_FMT_YUV422P 50 | #define PIXFORMAT_YUV444_PLANAR V4L2_PIX_FMT_YUV444 51 | 52 | enum { 53 | YUV422_PACKED = 0, 54 | YUV420_PLANAR, // 3 Plane 55 | YUV420_YV12, // 1 Plane 56 | YUV422_PLANAR, 57 | YUV444_PLANAR, 58 | MAX_PIXFORMAT 59 | }; 60 | 61 | struct PixFormatPixCode { 62 | uint32_t format; 63 | uint32_t code; 64 | }; 65 | 66 | extern struct PixFormatPixCode PixelArray[MAX_PIXFORMAT]; 67 | 68 | #ifndef ANDROID 69 | #ifdef __cplusplus 70 | extern "C" { 71 | #endif 72 | #endif 73 | 74 | /* user control interface */ 75 | typedef enum { 76 | nxp_v4l2_sensor0 = 0, 77 | nxp_v4l2_sensor1 = 1, 78 | nxp_v4l2_mipicsi = 2, 79 | nxp_v4l2_clipper0 = 5, /* include camera sensor, mipicsi */ 80 | nxp_v4l2_clipper1 = 8, 81 | nxp_v4l2_decimator0 = 11, 82 | nxp_v4l2_decimator1 = 14, 83 | nxp_v4l2_scaler = 17, 84 | nxp_v4l2_deinterlacer = 20, 85 | nxp_v4l2_mlc0 = 21, 86 | nxp_v4l2_mlc0_rgb = 23, 87 | nxp_v4l2_mlc0_video = 25, 88 | nxp_v4l2_mlc1 = 26, 89 | nxp_v4l2_mlc1_rgb = 28, 90 | nxp_v4l2_mlc1_video = 30, 91 | nxp_v4l2_resol = 31, 92 | nxp_v4l2_hdmi = 32, 93 | nxp_v4l2_tvout = 33, 94 | nxp_v4l2_id_max, 95 | } nxp_v4l2_id; 96 | 97 | struct V4l2UsageScheme { 98 | bool useClipper0; 99 | bool useDecimator0; 100 | bool useClipper1; 101 | bool useDecimator1; 102 | bool useScaler; 103 | bool useDeinterlacer; 104 | bool useMlc0Rgb; 105 | bool useMlc0Video; 106 | bool useMlc1Rgb; 107 | bool useMlc1Video; 108 | bool useResol; 109 | bool useHdmi; 110 | bool useTvout; 111 | }; 112 | 113 | typedef void* V4L2_PRIVATE_HANDLE; 114 | 115 | V4L2_PRIVATE_HANDLE v4l2_init (const struct V4l2UsageScheme *scheme); 116 | void v4l2_exit(V4L2_PRIVATE_HANDLE pHandle); 117 | int v4l2_link(V4L2_PRIVATE_HANDLE pHandle, int src_id, int dst_id); 118 | int v4l2_unlink(V4L2_PRIVATE_HANDLE pHandle, int src_id, int dst_id); 119 | int v4l2_set_format(V4L2_PRIVATE_HANDLE pHandle, int id, int w, int h, int f); 120 | int v4l2_get_format(V4L2_PRIVATE_HANDLE pHandle, int id, int *w, int *h, int *f); 121 | int v4l2_set_crop(V4L2_PRIVATE_HANDLE pHandle, int id, int l, int t, int w, int h); 122 | int v4l2_get_crop(V4L2_PRIVATE_HANDLE pHandle, int id, int *l, int *t, int *w, int *h); 123 | int v4l2_set_format_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int w, int h, int f); 124 | int v4l2_get_format_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int *w, int *h, int *f); 125 | int v4l2_set_crop_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int l, int t, int w, int h); 126 | int v4l2_get_crop_with_pad(V4L2_PRIVATE_HANDLE pHandle, int id, int pad, int *l, int *t, int *w, int *h); 127 | int v4l2_set_ctrl(V4L2_PRIVATE_HANDLE pHandle, int id, int ctrl_id, int value); 128 | int v4l2_get_ctrl(V4L2_PRIVATE_HANDLE pHandle, int id, int ctrl_id, int *value); 129 | int v4l2_reqbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int buf_count); 130 | #ifdef ANDROID 131 | //int v4l2_qbuf(int id, int plane_num, int index0, struct private_handle_t *b0, int index1, struct private_handle_t *b1); 132 | int v4l2_qbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int index0, struct private_handle_t const *b0, int index1, 133 | struct private_handle_t const *b1, int *syncfd0 = NULL, int *syncfd1 = NULL); 134 | #endif 135 | int v4l2_qbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int index0, struct nxp_vid_buffer *b0, int index1, struct nxp_vid_buffer *b1); 136 | int v4l2_dqbuf(V4L2_PRIVATE_HANDLE pHandle, int id, int plane_num, int *index0, int *index1); 137 | int v4l2_streamon(V4L2_PRIVATE_HANDLE pHandle, int id); 138 | int v4l2_streamoff(V4L2_PRIVATE_HANDLE pHandle, int id); 139 | int v4l2_get_timestamp(V4L2_PRIVATE_HANDLE pHandle, int id, long long *timestamp); 140 | int v4l2_set_preset(V4L2_PRIVATE_HANDLE pHandle, int id, uint32_t preset); 141 | int v4l2_get_device_fd(V4L2_PRIVATE_HANDLE pHandle, int id); 142 | #ifndef ANDROID 143 | #ifdef __cplusplus 144 | } 145 | #endif 146 | #endif 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /libnxv4l2/nxp-v4l2.cpp: -------------------------------------------------------------------------------- 1 | #include "nxp-v4l2.h" 2 | 3 | #ifdef ANDROID 4 | #define LOG_TAG "nxp-v4l2" 5 | #include 6 | #include 7 | #include 8 | #endif 9 | 10 | #include "nxp-v4l2-private.cpp" 11 | 12 | /** 13 | * static interface class 14 | */ 15 | static V4l2NexellPrivate *_priv = NULL; 16 | 17 | /** 18 | * format 19 | */ 20 | struct PixFormatPixCode PixelArray[MAX_PIXFORMAT] = { 21 | {PIXFORMAT_YUV422_PACKED, PIXCODE_YUV422_PACKED}, 22 | {PIXFORMAT_YUV420_PLANAR, PIXCODE_YUV420_PLANAR}, // 3 Plane 23 | {PIXFORMAT_YUV420_YV12, PIXCODE_YUV420_PLANAR}, // 1 Plane 24 | {PIXFORMAT_YUV422_PLANAR, PIXCODE_YUV422_PLANAR}, 25 | {PIXFORMAT_YUV444_PLANAR, PIXCODE_YUV444_PLANAR} 26 | }; 27 | 28 | /** 29 | * public api 30 | */ 31 | int v4l2_init(const struct V4l2UsageScheme *scheme) 32 | { 33 | if (!_priv) { 34 | _priv = new V4l2NexellPrivate(); 35 | if (!_priv) { 36 | ALOGE("Fatal Error: can't allocate context"); 37 | return -ENOMEM; 38 | } 39 | 40 | int ret = _priv->init(scheme); 41 | if (ret < 0) { 42 | ALOGE("Fatal Error: init failed"); 43 | delete _priv; 44 | _priv = NULL; 45 | return -EINVAL; 46 | } 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | void v4l2_exit(void) 53 | { 54 | if (_priv) { 55 | delete _priv; 56 | _priv = NULL; 57 | } 58 | } 59 | 60 | int v4l2_link(int src_id, int dst_id) 61 | { 62 | return _priv->link(src_id, dst_id); 63 | } 64 | 65 | int v4l2_unlink(int src_id, int dst_id) 66 | { 67 | return _priv->unlink(src_id, dst_id); 68 | } 69 | 70 | int v4l2_set_format(int id, int w, int h, int f) 71 | { 72 | return _priv->setFormat(id, w, h, f); 73 | } 74 | 75 | int v4l2_get_format(int id, int *w, int *h, int *f) 76 | { 77 | return _priv->getFormat(id, w, h, f); 78 | } 79 | 80 | int v4l2_set_crop(int id, int l, int t, int w, int h) 81 | { 82 | return _priv->setCrop(id, l, t, w, h); 83 | } 84 | 85 | int v4l2_get_crop(int id, int *l, int *t, int *w, int *h) 86 | { 87 | return _priv->getCrop(id, l, t, w, h); 88 | } 89 | 90 | int v4l2_set_format_with_pad(int id, int pad, int w, int h, int f) 91 | { 92 | return _priv->setFormat(id, w, h, f, pad); 93 | } 94 | 95 | int v4l2_get_format_with_pad(int id, int pad, int *w, int *h, int *f) 96 | { 97 | return _priv->getFormat(id, w, h, f, pad); 98 | } 99 | 100 | int v4l2_set_crop_with_pad(int id, int pad, int l, int t, int w, int h) 101 | { 102 | return _priv->setCrop(id, l, t, w, h, pad); 103 | } 104 | 105 | int v4l2_get_crop_with_pad(int id, int pad, int *l, int *t, int *w, int *h) 106 | { 107 | return _priv->getCrop(id, l, t, w, h, pad); 108 | } 109 | 110 | int v4l2_set_ctrl(int id, int ctrl_id, int value) 111 | { 112 | return _priv->setCtrl(id, ctrl_id, value); 113 | } 114 | 115 | int v4l2_get_ctrl(int id, int ctrl_id, int *value) 116 | { 117 | return _priv->getCtrl(id, ctrl_id, value); 118 | } 119 | 120 | int v4l2_reqbuf(int id, int buf_count) 121 | { 122 | return _priv->reqBuf(id, buf_count); 123 | } 124 | 125 | #ifdef ANDROID 126 | int v4l2_qbuf(int id, int plane_num, int index0, struct private_handle_t *b0, int index1, struct private_handle_t *b1, int *syncfd0, int *syncfd1) 127 | { 128 | if (b1) { 129 | if (plane_num == 1) 130 | return _priv->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0, index1, &b1->share_fd, &b1->size, syncfd1); 131 | else { 132 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 133 | int srcFds1[3] = { b1->share_fd, b1->share_fd1, b1->share_fd2 }; 134 | int sizes0[3]; 135 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 136 | switch (b0->format) { 137 | case HAL_PIXEL_FORMAT_YV12: 138 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 139 | sizes0[2] = sizes0[1]; 140 | break; 141 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 142 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 143 | sizes0[2] = 0; 144 | break; 145 | } 146 | int sizes1[3]; 147 | sizes1[0] = b1->stride * ALIGN(b1->height, 16); 148 | switch (b1->format) { 149 | case HAL_PIXEL_FORMAT_YV12: 150 | sizes1[1] = ALIGN(b1->stride >> 1, 16) * ALIGN(b1->height >> 1, 16); 151 | sizes1[2] = sizes1[1]; 152 | break; 153 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 154 | sizes1[1] = b1->stride * ALIGN(b1->height >> 1, 16); 155 | sizes1[2] = 0; 156 | break; 157 | } 158 | return _priv->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0, index1, srcFds1, sizes1, syncfd1); 159 | } 160 | } else { 161 | if (plane_num == 1) 162 | return _priv->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0); 163 | else { 164 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 165 | int sizes0[3]; 166 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 167 | switch (b0->format) { 168 | case HAL_PIXEL_FORMAT_YV12: 169 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 170 | sizes0[2] = sizes0[1]; 171 | break; 172 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 173 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 174 | sizes0[2] = 0; 175 | break; 176 | } 177 | return _priv->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0); 178 | } 179 | } 180 | } 181 | 182 | int v4l2_qbuf(int id, int plane_num, int index0, struct private_handle_t const *b0, int index1, struct private_handle_t const *b1, 183 | int *syncfd0, int *syncfd1) 184 | { 185 | if (b1) { 186 | if (plane_num == 1) 187 | return _priv->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0, index1, &b1->share_fd, &b1->size, syncfd1); 188 | else { 189 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 190 | int srcFds1[3] = { b1->share_fd, b1->share_fd1, b1->share_fd2 }; 191 | int sizes0[3]; 192 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 193 | switch (b0->format) { 194 | case HAL_PIXEL_FORMAT_YV12: 195 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 196 | sizes0[2] = sizes0[1]; 197 | break; 198 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 199 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 200 | sizes0[2] = 0; 201 | break; 202 | } 203 | int sizes1[3]; 204 | sizes1[0] = b1->stride * ALIGN(b1->height, 16); 205 | switch (b1->format) { 206 | case HAL_PIXEL_FORMAT_YV12: 207 | sizes1[1] = ALIGN(b1->stride >> 1, 16) * ALIGN(b1->height >> 1, 16); 208 | sizes1[2] = sizes1[1]; 209 | break; 210 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 211 | sizes1[1] = b1->stride * ALIGN(b1->height >> 1, 16); 212 | sizes1[2] = 0; 213 | break; 214 | } 215 | return _priv->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0, index1, srcFds1, sizes1, syncfd1); 216 | } 217 | } else { 218 | if (plane_num == 1) 219 | return _priv->qBuf(id, plane_num, index0, &b0->share_fd, &b0->size, syncfd0); 220 | else { 221 | int srcFds0[3] = { b0->share_fd, b0->share_fd1, b0->share_fd2 }; 222 | int sizes0[3]; 223 | sizes0[0] = b0->stride * ALIGN(b0->height, 16); 224 | switch (b0->format) { 225 | case HAL_PIXEL_FORMAT_YV12: 226 | sizes0[1] = ALIGN(b0->stride >> 1, 16) * ALIGN(b0->height >> 1, 16); 227 | sizes0[2] = sizes0[1]; 228 | break; 229 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 230 | sizes0[1] = b0->stride * ALIGN(b0->height >> 1, 16); 231 | sizes0[2] = 0; 232 | break; 233 | } 234 | return _priv->qBuf(id, plane_num, index0, srcFds0, sizes0, syncfd0); 235 | } 236 | } 237 | } 238 | #endif 239 | 240 | int v4l2_qbuf(int id, int plane_num, int index0, struct nxp_vid_buffer *b0, int index1, struct nxp_vid_buffer *b1) 241 | { 242 | if (b1) 243 | return _priv->qBuf(id, plane_num, index0, b0->fds, b0->sizes, NULL, index1, b1->fds, b1->sizes, NULL); 244 | else 245 | return _priv->qBuf(id, plane_num, index0, b0->fds, b0->sizes, NULL); 246 | } 247 | 248 | int v4l2_dqbuf(int id, int plane_num, int *index0, int *index1) 249 | { 250 | if (index1) 251 | return _priv->dqBuf(id, plane_num, index0, index1); 252 | else 253 | return _priv->dqBuf(id, plane_num, index0); 254 | } 255 | 256 | int v4l2_streamon(int id) 257 | { 258 | return _priv->streamOn(id); 259 | } 260 | 261 | int v4l2_streamoff(int id) 262 | { 263 | return _priv->streamOff(id); 264 | } 265 | 266 | int v4l2_get_timestamp(int id, long long *timestamp) 267 | { 268 | return _priv->getTimeStamp(id, timestamp); 269 | } 270 | 271 | int v4l2_set_preset(int id, uint32_t preset) 272 | { 273 | return _priv->setPreset(id, preset); 274 | } 275 | 276 | int v4l2_get_device_fd(int id) 277 | { 278 | return _priv->getDeviceFD(id); 279 | } 280 | 281 | -------------------------------------------------------------------------------- /libnxvpu/Makefile: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Get Linux Build Enviornment: 3 | include ../Rules.make 4 | 5 | DESTDIR ?= ../out 6 | LIB_INSTALL := $(DESTDIR)/lib 7 | 8 | ###################################################################### 9 | # Build options 10 | INCLUDE += -I./ -I../include -I../kernel-headers 11 | 12 | LIBRARY += -L../libnxmalloc -lnxvmem 13 | LIBRARY += -L../prebuilt -lnxvidrc 14 | 15 | ifeq ($(HEVC_DEC),y) 16 | CFLAGS += -DHEVC_DEC 17 | INCLUDE += -I../libhevc/common -I../libhevc/decoder 18 | LIBRARY += -lhevcdec 19 | endif 20 | 21 | ###################################################################### 22 | # Target 23 | COBJS := parser_vld.o nx_video_api.o 24 | CPPOBJS := 25 | 26 | CFLAGS += -fPIC 27 | 28 | LDFLAGS += -Wl,-Bsymbolic 29 | 30 | LIBNAME := libnxvpu 31 | TARGET := libnxvpu.so 32 | 33 | ###################################################################### 34 | # Build 35 | OBJS := $(COBJS) $(CPPOBJS) 36 | 37 | all: $(TARGET) 38 | 39 | $(TARGET): $(OBJS) 40 | $(AR) $(ARFLAGS) $(LIBNAME).a $^ 41 | $(CC) $(LDFLAGS) -shared -Wl,-soname,$@ -o $@ $^ $(LIBRARY) 42 | 43 | install: 44 | install -m 755 -d $(LIB_INSTALL) 45 | install -m 755 $(TARGET) $(LIB_INSTALL) 46 | install -m 644 $(LIBNAME).a $(LIB_INSTALL) 47 | 48 | clean: 49 | rm -f *.o *.so *.a .depend 50 | 51 | distclean: clean 52 | rm -f $(LIB_INSTALL)/$(TARGET) 53 | rm -f $(LIB_INSTALL)/$(LIBNAME).a 54 | 55 | 56 | ######################################################################### 57 | # Dependency 58 | ifeq (.depend,$(wildcard .depend)) 59 | include .depend 60 | else 61 | $(OBJS): depend 62 | endif 63 | 64 | SRCS := $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp) $(APPOBJS:.o=.c) 65 | INCS := $(INCLUDE) 66 | depend dep: 67 | $(CC) -MM $(CFLAGS) $(INCS) $(SRCS) > .depend 68 | 69 | -------------------------------------------------------------------------------- /libnxvpu/api_osapi.h: -------------------------------------------------------------------------------- 1 | #ifndef __API_OSAPI_H__ 2 | #define __DRV_OSAPI_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C"{ 6 | #endif 7 | 8 | 9 | ////////////////////////////////////////////////////////////////////////////// 10 | // 11 | // Debug Message 12 | // 13 | 14 | #define EN_DEBUG_MSG 15 | #ifndef NX_DTAG 16 | #define NX_DTAG "" 17 | #endif 18 | 19 | #ifdef ANDROID 20 | #define LOG_TAG NX_DTAG 21 | #endif 22 | 23 | #if defined(__linux) || defined(linux) || defined(ANDROID) || defined(__LINUX__) 24 | #if defined(__KERNEL__) 25 | #include 26 | #define nx_print_msg printk 27 | #define nx_print_err printk 28 | #elif defined(ANDROID) 29 | #include 30 | #define nx_print_msg ALOGD 31 | #define nx_print_err ALOGE 32 | #else 33 | #include 34 | #define nx_print_msg printf 35 | #define nx_print_err printf 36 | #endif // __linux or linux 37 | #else 38 | void nx_print_msg( char fmt,... ); 39 | void nx_print_err( char fmt,... ); 40 | #endif // __linux || linux || ANDROID 41 | 42 | 43 | #ifdef EN_DEBUG_MSG 44 | #ifdef ANDROID 45 | #define NX_DbgMsg( COND, MSG ) do{ if(COND){ nx_print_msg MSG; } }while(0) 46 | #else 47 | #define NX_DbgMsg( COND, MSG ) do{ if(COND){ nx_print_msg(NX_DTAG); nx_print_msg MSG; } }while(0) 48 | #endif 49 | #if 0 50 | #define FUNC_IN() do{ nx_print_msg("%s() In\n", __func__); }while(0) 51 | #define FUNC_OUT() do{ nx_print_msg("%s() Out\n", __func__); }while(0) 52 | #else 53 | #define FUNC_IN() do{}while(0) 54 | #define FUNC_OUT() do{}while(0) 55 | #endif 56 | #else 57 | #define NX_DbgMsg( COND, MSG ) do{}while(0) 58 | #define FUNC_IN() 59 | #define FUNC_OUT() 60 | #endif 61 | 62 | #ifdef ANDROID 63 | #define NX_RelMsg( COND, MSG ) do{ if(COND){ nx_print_msg MSG; } }while(0) 64 | #define NX_ErrMsg( MSG ) nx_print_err MSG 65 | #else 66 | #define NX_RelMsg( COND, MSG ) do{ if(COND){ nx_print_msg(NX_DTAG); nx_print_msg MSG; } }while(0) 67 | #define NX_ErrMsg( MSG ) do \ 68 | { \ 69 | nx_print_err("%s%s(%d) : ", \ 70 | NX_DTAG, __FILE__, __LINE__); \ 71 | nx_print_err MSG; \ 72 | }while(0) 73 | #endif 74 | // 75 | // 76 | // 77 | ////////////////////////////////////////////////////////////////////////////// 78 | 79 | 80 | 81 | #ifdef __cplusplus 82 | }; 83 | #endif 84 | 85 | #endif // __DRV_OSAPI_H__ 86 | 87 | -------------------------------------------------------------------------------- /libnxvpu/parser_vld.c: -------------------------------------------------------------------------------- 1 | #include "parser_vld.h" 2 | 3 | int vld_count_leading_zero(unsigned long dwWord) 4 | { 5 | int iLZ = 0; 6 | 7 | if ( (dwWord >> (32 - 16)) == 0 ) iLZ = 16; 8 | if ( (dwWord >> (32 - 8 - iLZ)) == 0 ) iLZ += 8; 9 | if ( (dwWord >> (32 - 4 - iLZ)) == 0 ) iLZ += 4; 10 | if ( (dwWord >> (32 - 2 - iLZ)) == 0 ) iLZ += 2; 11 | if ( (dwWord >> (32 - 1 - iLZ)) == 0 ) iLZ += 1; 12 | return iLZ; 13 | } 14 | unsigned long vld_show_bits(VLD_STREAM *pstVldStm, int iBits) 15 | { 16 | unsigned long dwUsedBits = pstVldStm->dwUsedBits; 17 | int iBitCnt = 8 - (dwUsedBits & 0x7); 18 | unsigned char *pbyRead = (unsigned char *)pstVldStm->pbyStart + (dwUsedBits>>3); 19 | unsigned long dwRead; 20 | 21 | dwRead = *pbyRead++ << 24; 22 | if ( iBits > iBitCnt ) { 23 | dwRead += *pbyRead++ << 16; 24 | if ( iBits > iBitCnt + 8 ) { 25 | dwRead += *pbyRead++ << 8; 26 | if ( iBits > iBitCnt + 16 ) { 27 | dwRead += *pbyRead++; 28 | } 29 | } 30 | } 31 | 32 | return ( dwRead << (8 - iBitCnt)) >> (32 - iBits); 33 | } 34 | 35 | unsigned long vld_get_bits(VLD_STREAM *pstVldStm, int iBits) 36 | { 37 | unsigned long dwUsedBits = pstVldStm->dwUsedBits; 38 | int iBitCnt = 8 - (dwUsedBits & 0x7); 39 | unsigned char *pbyRead = (unsigned char *)pstVldStm->pbyStart + (dwUsedBits>>3); 40 | unsigned long dwRead; 41 | 42 | pstVldStm->dwUsedBits += iBits; 43 | 44 | dwRead = *pbyRead++ << 24; 45 | if ( iBits > iBitCnt ) { 46 | dwRead += *pbyRead++ << 16; 47 | if ( iBits > iBitCnt + 8 ) { 48 | dwRead += *pbyRead++ << 8; 49 | if ( iBits > iBitCnt + 16 ) { 50 | dwRead += *pbyRead++; 51 | } 52 | } 53 | } 54 | 55 | return ( dwRead << (8 - iBitCnt)) >> (32 - iBits); 56 | } 57 | 58 | void vld_flush_bits(VLD_STREAM *pstVldStm, int iBits) 59 | { 60 | pstVldStm->dwUsedBits += iBits; 61 | } 62 | 63 | unsigned int vld_get_uev(VLD_STREAM *pstVldStm) 64 | { 65 | int iLZ = vld_count_leading_zero(vld_show_bits(pstVldStm, 32)); 66 | vld_flush_bits(pstVldStm, iLZ); 67 | return (vld_get_bits(pstVldStm, iLZ + 1) - 1); 68 | } 69 | 70 | int vld_get_sev(VLD_STREAM *pstVldStm) 71 | { 72 | int iUev; 73 | int iLZ = vld_count_leading_zero(vld_show_bits(pstVldStm, 32)); 74 | vld_flush_bits(pstVldStm, iLZ); 75 | iUev = (vld_get_bits(pstVldStm, iLZ + 1) - 1); 76 | return (iUev & 1 ? -(iUev >> 1) : (iUev >> 1)); 77 | } 78 | -------------------------------------------------------------------------------- /libnxvpu/parser_vld.h: -------------------------------------------------------------------------------- 1 | #ifndef _PARSER_VLD_H_ 2 | #define _PARSER_VLD_H_ 3 | 4 | typedef struct { 5 | unsigned long dwUsedBits; 6 | unsigned char *pbyStart; 7 | unsigned long dwPktSize; 8 | } VLD_STREAM; 9 | 10 | unsigned long vld_show_bits (VLD_STREAM *pstVldStm, int iBits); 11 | unsigned long vld_get_bits (VLD_STREAM *pstVldStm, int iBits); 12 | void vld_flush_bits (VLD_STREAM *pstVldStm, int iBits); 13 | unsigned int vld_get_uev(VLD_STREAM *pstVldStm); 14 | int vld_get_sev(VLD_STREAM *pstVldStm); 15 | 16 | 17 | #endif // #ifndef _PARSER_VLD_H_ 18 | -------------------------------------------------------------------------------- /libnxvpu/vpu_drv_ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __VPU_DRV_IOCTL_H__ 2 | #define __VPU_DRV_IOCTL_H__ 3 | 4 | #include "vpu_types.h" 5 | 6 | #define NX_VPU_DRV_MAGIC 0xC0DE 7 | 8 | enum { 9 | IOCTL_VPU_OPEN_INSTANCE = (NX_VPU_DRV_MAGIC)<<16, // +0 10 | IOCTL_VPU_CLOSE_INSTANCE, // +1 11 | 12 | // Encoder Specific ( MAGIC + 2~6 ) 13 | IOCTL_VPU_ENC_SET_SEQ_PARAM, // +2 14 | IOCTL_VPU_ENC_SET_FRAME_BUF, // +3 15 | IOCTL_VPU_ENC_GET_HEADER, // +4 16 | IOCTL_VPU_ENC_RUN_FRAME, // +5 17 | IOCTL_VPU_ENC_CHG_PARAM, // +6 18 | 19 | // Decoder Specific ( MAGIC + 7~11 ) 20 | IOCTL_VPU_DEC_SET_SEQ_INFO, // +7 21 | IOCTL_VPU_DEC_REG_FRAME_BUF, // +8 22 | IOCTL_VPU_DEC_RUN_FRAME, // +9 23 | IOCTL_VPU_DEC_FLUSH, // +10 24 | IOCTL_VPU_DEC_CLR_DSP_FLAG, // +11 25 | 26 | // Jpeg Specific ( MAGIC + 12 ~ 13 ) 27 | IOCTL_VPU_JPG_GET_HEADER, // +12 28 | IOCTL_VPU_JPG_RUN_FRAME, // +13 29 | }; 30 | 31 | 32 | 33 | #endif // __VPU_DRV_IOCTL_H__ 34 | -------------------------------------------------------------------------------- /nanocam_opencv/Makefile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------- 2 | # Makefile for building Camera Demo 3 | # 4 | # Copyright 2016 FriendlyARM (http://www.friendlyarm.net/) 5 | # 6 | 7 | OPENCVLIB=-lopencv_core -lopencv_highgui -lopencv_imgproc 8 | 9 | ifndef DESTDIR 10 | DESTDIR ?= ../out 11 | endif 12 | 13 | ifneq (armv7l,$(shell uname -m)) 14 | CROSS_COMPILE ?= arm-linux- 15 | else 16 | CROSS_COMPILE ?= 17 | endif 18 | CC = $(CROSS_COMPILE)gcc 19 | CPP = $(CROSS_COMPILE)g++ 20 | INSTALL = install 21 | 22 | 23 | # ----------------------------------------------------------------------- 24 | 25 | CFLAGS += -Wall -O2 -march=armv8-a -mfpu=neon-fp-armv8 -std=c++11 26 | CFLAGS += -I../include -I../kernel-headers 27 | 28 | ifeq ($(USE_STATIC_LIB),y) 29 | LIBS += \ 30 | ../libnxvpu/libnxvpu.a \ 31 | ../libnxv4l2/libv4l2-nexell.a \ 32 | ../libnxmalloc/libnxvmem.a \ 33 | ../libion/libion.a 34 | else 35 | LIBS += -L../libion -lion 36 | LIBS += -L../libnxmalloc -lnxvmem 37 | LIBS += -L../libnxv4l2 -lv4l2-nexell 38 | LIBS += -L../libnxvpu -lnxvpu 39 | endif 40 | LIBS += -L../prebuilt -lnxvidrc -lm $(OPENCVLIB) 41 | 42 | 43 | # ----------------------------------------------------------------------- 44 | 45 | TARGET = nanocam_opencv 46 | 47 | 48 | all: $(TARGET) 49 | 50 | %.o: %.S 51 | $(CPP) $(CFLAGS) -c -o $@ $< 52 | 53 | %.o: %.cpp 54 | $(CPP) $(CFLAGS) -c -o $@ $< 55 | 56 | 57 | nanocam_opencv: nanocam_opencv.o yuv2rgb.neon.o 58 | $(CPP) $(LDFLAGS) $^ -o $@ $(LIBS) -lstdc++ 59 | 60 | install: $(TARGET) 61 | $(INSTALL) -d 755 $(DESTDIR)/bin 62 | $(INSTALL) $^ $(DESTDIR)/bin/ 63 | 64 | clean distclean: 65 | rm -rf *.o $(TARGET) 66 | 67 | 68 | # ----------------------------------------------------------------------- 69 | 70 | .PHONY: $(PHONY) install clean distclean 71 | 72 | # End of file 73 | # vim: syntax=make 74 | 75 | -------------------------------------------------------------------------------- /nanocam_opencv/nanocam_opencv.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd. 3 | * (http://www.friendlyarm.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, you can access it online at 17 | * http://www.gnu.org/licenses/gpl-2.0.html. 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | 41 | #include "opencv2/opencv.hpp" 42 | 43 | #include 44 | #include "yuv2rgb.neon.h" 45 | 46 | #define err(fmt, arg...) \ 47 | fprintf(stderr, "E/%.3d: " fmt, __LINE__, ## arg) 48 | 49 | // -------------------------------------------------------- 50 | #ifndef ALIGN 51 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 52 | #endif 53 | 54 | static inline int get_size(int format, int num, int width, int height) 55 | { 56 | int size; 57 | 58 | width = ALIGN(width, 32); 59 | height = ALIGN(height, 32); 60 | 61 | switch (format) { 62 | case V4L2_PIX_FMT_YUYV: 63 | if (num > 0) return 0; 64 | size = (width * height) * 2; 65 | break; 66 | case V4L2_PIX_FMT_YUV420M: 67 | case V4L2_PIX_FMT_YUV422P: 68 | if (num == 0) 69 | size = width * height; 70 | else 71 | size = (width * height) >> 1; 72 | break; 73 | case V4L2_PIX_FMT_YUV444: 74 | size = width * height; 75 | break; 76 | default: 77 | size = width * height * 2; 78 | break; 79 | } 80 | 81 | return size; 82 | } 83 | 84 | int alloc_buffers(int ion_fd, int count, struct nxp_vid_buffer *bufs, 85 | int width, int height, int format) 86 | { 87 | struct nxp_vid_buffer *vb; 88 | int plane_num; 89 | int i, j; 90 | int ret; 91 | 92 | if (format == V4L2_PIX_FMT_YUYV || format == V4L2_PIX_FMT_RGB565) 93 | plane_num = 1; 94 | else 95 | plane_num = 3; 96 | 97 | int size[plane_num]; 98 | for (j = 0; j < plane_num; j++) 99 | size[j] = get_size(format, j, width, height); 100 | 101 | for (i = 0; i < count; i++) { 102 | vb = &bufs[i]; 103 | vb->plane_num = plane_num; 104 | for (j = 0; j < plane_num; j++) { 105 | ret = ion_alloc_fd(ion_fd, size[j], 0, 106 | ION_HEAP_NXP_CONTIG_MASK, 0, &vb->fds[j]); 107 | if (ret < 0) { 108 | err("failed to ion alloc %d\n", size[j]); 109 | return ret; 110 | } 111 | vb->virt[j] = (char *)mmap(NULL, size[j], 112 | PROT_READ | PROT_WRITE, MAP_SHARED, vb->fds[j], 0); 113 | if (!vb->virt[j]) { 114 | err("failed to mmap\n"); 115 | return -1; 116 | } 117 | ret = ion_get_phys(ion_fd, vb->fds[j], &vb->phys[j]); 118 | if (ret < 0) { 119 | err("failed to get phys\n"); 120 | return ret; 121 | } 122 | vb->sizes[j] = size[j]; 123 | } 124 | } 125 | 126 | return 0; 127 | } 128 | 129 | // -------------------------------------------------------- 130 | #define MAX_BUFFER_COUNT 4 131 | #define FMT_SENDOR V4L2_MBUS_FMT_YUYV8_2X8 132 | 133 | #define __V4L2_S(cmd) \ 134 | do { \ 135 | int ret = cmd; \ 136 | if (ret < 0) { \ 137 | fprintf(stderr, "%.3d: `%s' = %d\n", __LINE__, #cmd, ret); \ 138 | /*return ret;*/ \ 139 | } \ 140 | } while (0) 141 | 142 | /* 143 | * Note: 144 | * - S5P6818: clipper0 + YUV422P 145 | */ 146 | static int init_preview(int width, int height, int format) 147 | { 148 | __V4L2_S(v4l2_set_format(nxp_v4l2_clipper0, width, height, format)); 149 | __V4L2_S(v4l2_set_crop_with_pad(nxp_v4l2_clipper0, 2, 0, 0, width, height)); 150 | 151 | // Set to default format (800x600) at first 152 | if (width != 800) 153 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, 800, 600, FMT_SENDOR)); 154 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, width, height, FMT_SENDOR)); 155 | 156 | __V4L2_S(v4l2_set_ctrl(nxp_v4l2_sensor0, V4L2_CID_EXPOSURE_AUTO, 0)); 157 | 158 | __V4L2_S(v4l2_reqbuf(nxp_v4l2_clipper0, MAX_BUFFER_COUNT)); 159 | return 0; 160 | } 161 | 162 | static int do_preview(struct nxp_vid_buffer *bufs, int width, int height, 163 | int preview_frames, bool grey) 164 | { 165 | struct nxp_vid_buffer *buf; 166 | int i; 167 | 168 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { 169 | buf = &bufs[i]; 170 | v4l2_qbuf(nxp_v4l2_clipper0, buf->plane_num, i, buf, -1, NULL); 171 | } 172 | 173 | __V4L2_S(v4l2_streamon(nxp_v4l2_clipper0)); 174 | 175 | // fill all buffer for display 176 | int index = 0; 177 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { 178 | buf = &bufs[index]; 179 | v4l2_dqbuf(nxp_v4l2_clipper0, buf->plane_num, &index, NULL); 180 | v4l2_qbuf(nxp_v4l2_clipper0, buf->plane_num, index, buf, -1, NULL); 181 | index++; 182 | } 183 | 184 | int cap_index = 0; 185 | int out_index = 0; 186 | cv::namedWindow("preview",1); 187 | 188 | for (i = 0; i < preview_frames; i++) { 189 | buf = &bufs[cap_index]; 190 | v4l2_dqbuf(nxp_v4l2_clipper0, buf->plane_num, &cap_index, NULL); 191 | 192 | ++out_index %= MAX_BUFFER_COUNT; 193 | 194 | cv::Mat out; 195 | if (grey) 196 | { 197 | out = cv::Mat(height, width, CV_8UC1, buf->virt[0], ALIGN(width, 32)); 198 | } 199 | else 200 | { 201 | out = cv::Mat(height, width, CV_8UC4); 202 | yuv422_2_rgb8888_neon((uint8_t *)out.ptr(0), (const uint8_t*)buf->virt[0], (const uint8_t*)buf->virt[1], (const uint8_t*)buf->virt[2], width, height, ALIGN(width, 32), width >> 1, width * 4); 203 | } 204 | cv::imshow("preview", out); 205 | cv::waitKey(1); 206 | 207 | v4l2_qbuf(nxp_v4l2_clipper0, buf->plane_num, cap_index, buf, -1, NULL); 208 | } 209 | 210 | __V4L2_S(v4l2_streamoff(nxp_v4l2_clipper0)); 211 | return 0; 212 | } 213 | 214 | // -------------------------------------------------------- 215 | 216 | /* MLC/video works improperly for YUV420M @800x600,1600x1200 */ 217 | #define FMT_PREVIEW V4L2_PIX_FMT_YUV422P 218 | 219 | // -------------------------------------------------------- 220 | 221 | static void show_usage(char *name) 222 | { 223 | fprintf(stderr, "Usage: %s [OPTION]...\n\n", name); 224 | fprintf(stderr, "Options:\n"); 225 | fprintf(stderr, " -n COUNT show given number of frames then capture\n"); 226 | fprintf(stderr, " -h display this help and exit\n\n"); 227 | fprintf(stderr, "\n"); 228 | fprintf(stderr, "OpenCV Camera demo for S5P6818 board\n"); 229 | } 230 | 231 | int main(int argc, char *argv[]) 232 | { 233 | int width_p = 0, height_p = 0, count_p = 30; 234 | int opt; 235 | bool grey = false; 236 | 237 | while (-1 != (opt = getopt(argc, argv, "n:g:h"))) { 238 | switch (opt) { 239 | case 'n': count_p = atoi(optarg); break; 240 | case 'g': grey = true; break; 241 | case '?': fprintf(stderr, "\n"); 242 | case 'h': show_usage(argv[0]); exit(0); break; 243 | default: 244 | break; 245 | } 246 | } 247 | 248 | // Hardcode what we want 249 | width_p = 800; 250 | height_p = 600; 251 | 252 | int ion_fd = ion_open(); 253 | 254 | if (ion_fd < 0) { 255 | err("failed to ion_open, errno = %d\n", errno); 256 | return -EINVAL; 257 | } 258 | 259 | struct V4l2UsageScheme s; 260 | memset(&s, 0, sizeof(s)); 261 | s.useDecimator0 = false; 262 | s.useClipper0 = true; 263 | s.useMlc0Video = true; 264 | int ret = v4l2_init(&s); 265 | 266 | if (ret < 0) { 267 | err("initialize V4L2 failed, %d\n", ret); 268 | close(ion_fd); 269 | return ret; 270 | } 271 | 272 | struct nxp_vid_buffer bufs[MAX_BUFFER_COUNT]; 273 | ret = alloc_buffers(ion_fd, MAX_BUFFER_COUNT, bufs, 274 | width_p, height_p, FMT_PREVIEW); 275 | 276 | auto baseTime = std::chrono::high_resolution_clock::now(); 277 | if (ret >= 0 && width_p > 0) { 278 | init_preview(width_p, height_p, FMT_PREVIEW); 279 | do_preview(bufs, width_p, height_p, count_p, grey); 280 | } 281 | auto currentTime = std::chrono::high_resolution_clock::now(); 282 | int secondsPassed = (int)std::chrono::duration_cast(currentTime - baseTime).count(); 283 | printf("Took %i seconds to show %i frames. %f FPS.\n", secondsPassed, count_p, (float)count_p/(float)secondsPassed); 284 | 285 | v4l2_exit(); 286 | close(ion_fd); 287 | 288 | return ret; 289 | } 290 | 291 | -------------------------------------------------------------------------------- /nanocam_opencv/yuv2rgb.neon.S: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 ARM Limited. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // 6 | // http://code.google.com/p/chromium/issues/detail?id=71403 7 | // 8 | // 9 | // 10 | #ifdef __ARM_NEON__ 11 | 12 | /* Initial ARM Neon implementation of core YUV2RGB functions. */ 13 | 14 | .text 15 | .align 4 16 | .global yuv420_2_rgb8888_neon 17 | .type yuv420_2_rgb8888_neon, %function 18 | .global yuv422_2_rgb8888_neon 19 | .type yuv422_2_rgb8888_neon, %function 20 | 21 | /* Constants */ 22 | #define coef_y d0 23 | #define coef_v_r d1 24 | #define coef_u_g d2 25 | #define coef_v_g d3 26 | #define coef_u_b d4 27 | /* D5 is spare */ 28 | #define bias_r q3 29 | #define bias_r_lo d6 30 | #define bias_r_hi d7 31 | #define bias_g q4 32 | #define bias_g_lo d8 33 | #define bias_g_hi d9 34 | #define bias_b q5 35 | #define bias_b_lo d10 36 | #define bias_b_hi d11 37 | 38 | /* Input data */ 39 | #define y_even d24 40 | #define y_odd d26 41 | #define u d16 /*overlaps with q8 - b_delta, but safe */ 42 | #define v d17 /*overlaps with q8 - b_delta, but safe */ 43 | 44 | /* Chrominance signal for whole 16x2 block */ 45 | #define r_delta q6 46 | #define g_delta q7 47 | #define b_delta q8 48 | 49 | /* Current group of 8 pixels */ 50 | #define red q9 51 | #define grn q10 52 | #define blu q11 53 | #define y_scale q15 54 | 55 | /* output area, in the right order for interleaved output with VST4 */ 56 | #define blu8_e d24 /* overlaps with y_even, but safe */ 57 | #define red8_e d25 58 | #define blu8_o d26 /* overlaps with y_odd, but safe */ 59 | #define red8_o d27 60 | #define grn8_e d28 61 | #define alp8_e d29 62 | #define grn8_o d30 /* overlaps with q15 - y_scale, but safe */ 63 | #define alp8_o d31 /* overlaps with q15 - y_scale, but safe */ 64 | 65 | /* ARM registers */ 66 | #define rgb_t_ptr r0 67 | #define y_t_ptr r1 68 | #define u_ptr r2 69 | #define v_ptr r3 70 | #define width r4 71 | #define height r5 72 | #define y_pitch r6 73 | #define uv_pitch r7 74 | #define rgb_pitch r8 75 | #define count r9 76 | #define aligned_count sl 77 | #define rgb_b_ptr fp 78 | #define y_b_ptr ip 79 | 80 | /* Constants */ 81 | /* 8-bit constants can be loaded into vectors using VMOV */ 82 | #define C_Y_SCALE 74 /* Y scale , 74 */ 83 | #define C_V_RED 102 /* v -> red coefficient, 102 */ 84 | #define C_U_GREEN 25 /* u -> green , -25 */ 85 | #define C_V_GREEN 52 /* v -> green , -52 */ 86 | #define C_U_BLUE 129 /* u -> blue, +129 */ 87 | 88 | /* Coefficients */ 89 | coefficients: 90 | coeff_bias_r: 91 | .short -14240 /* bias_r = 74 * (-16) + (102 * -128) */ 92 | /* -1,184 + -13,056 */ 93 | coeff_bias_g: 94 | .short 8672 /* bias_g = 74 * (-16) - 25 * (-128) - ( 52 * -128) */ 95 | /* -1,184 - -3200 - -6,656 */ 96 | coeff_bias_b: 97 | .short -17696 /* bias_b = 74 * (-16) + 129 * (-128) */ 98 | /* -1,184 + -16,512 */ 99 | coeff_pad: 100 | .short 0 101 | 102 | yuv420_2_rgb8888_neon: 103 | /* r0 = dst_ptr */ 104 | /* r1 = y_ptr */ 105 | /* r2 = u_ptr */ 106 | /* r3 = v_ptr */ 107 | /* <> = width */ 108 | /* <> = height */ 109 | /* <> = y_pitch */ 110 | /* <> = uv_pitch */ 111 | /* <> = rgb_pitch */ 112 | #ifndef __APPLE__ 113 | .fnstart 114 | #endif 115 | push {r4-r12, lr} /* 10 words */ 116 | vpush {q4-q7} /* 4Q -> 16 words */ 117 | 118 | ldr width, [sp, #26*4] 119 | ldr height, [sp, #27*4] 120 | ldr y_pitch, [sp, #28*4] 121 | ldr uv_pitch, [sp, #29*4] 122 | ldr rgb_pitch, [sp, #30*4] 123 | adr lr, coefficients 124 | 125 | /* We can't cope with a width less than 16. Check for that. */ 126 | cmp width, #16 127 | vpoplt {q4-q7} 128 | poplt {r4-r12, pc} 129 | 130 | /* Load up vectors containing the bias values. */ 131 | vld1.s16 {bias_r_lo[], bias_r_hi[]}, [lr]! 132 | vld1.s16 {bias_g_lo[], bias_g_hi[]}, [lr]! 133 | vld1.s16 {bias_b_lo[], bias_b_hi[]}, [lr]! 134 | 135 | /* Build coefficient vectors containing the same value in each element. */ 136 | vmov.u8 coef_y, #C_Y_SCALE 137 | vmov.u8 coef_v_r, #C_V_RED 138 | vmov.u8 coef_u_g, #C_U_GREEN 139 | vmov.u8 coef_v_g, #C_V_GREEN 140 | vmov.u8 coef_u_b, #C_U_BLUE 141 | 142 | loop_v_420: 143 | add y_b_ptr, y_t_ptr, y_pitch 144 | add rgb_b_ptr, rgb_t_ptr, rgb_pitch 145 | mov aligned_count, width 146 | 147 | /* If width is not an integer multiple of 16, run the 148 | first pass through the loop with the correct number 149 | of pixels to correct the size for the remaining loops. */ 150 | ands count, width, #15 151 | /* If we're already aligned (i.e. count is now 0), set count 152 | to 16 to run the first loop as normal. */ 153 | moveq count, #16 154 | 155 | loop_h_420: 156 | /*****************************/ 157 | /* COMMON CODE FOR BOTH ROWS */ 158 | /*****************************/ 159 | /* Load u and v. */ 160 | vld1.u8 v, [v_ptr] 161 | add v_ptr, count, ASR #1 162 | vld1.u8 u, [u_ptr] 163 | add u_ptr, count, ASR #1 164 | 165 | /* Calculate contribution from chrominance signals. */ 166 | vmull.u8 r_delta, v, coef_v_r 167 | vmull.u8 g_delta, u, coef_u_g 168 | vmlal.u8 g_delta, v, coef_v_g 169 | vmull.u8 b_delta, u, coef_u_b 170 | 171 | /* add bias. */ 172 | vadd.s16 r_delta, r_delta, bias_r 173 | vsub.s16 g_delta, bias_g, g_delta 174 | vadd.s16 b_delta, b_delta, bias_b 175 | 176 | /* Attempt to preload the next set of u and v input data, for 177 | better performance. */ 178 | pld [v_ptr] 179 | pld [u_ptr] 180 | 181 | /***********/ 182 | /* TOP ROW */ 183 | /***********/ 184 | /* Top row: Load 16 pixels of y, even and odd. */ 185 | vld2.u8 {y_even, y_odd}, [y_t_ptr], count 186 | 187 | /* Top row, even: combine luminance and chrominance. */ 188 | vmull.u8 y_scale, y_even, coef_y 189 | vqadd.s16 red, y_scale, r_delta 190 | vqadd.s16 grn, y_scale, g_delta 191 | vqadd.s16 blu, y_scale, b_delta 192 | 193 | /* Top row, even: set up alpha data. */ 194 | vmov.u8 alp8_e, #0xFF 195 | 196 | /* Top row, even: clamp, rescale and clip colour components to 8 bits. */ 197 | vqrshrun.s16 red8_e, red, #6 198 | vqrshrun.s16 grn8_e, grn, #6 199 | vqrshrun.s16 blu8_e, blu, #6 200 | 201 | /* Top row: attempt to preload the next set of Y data, for 202 | better performance. */ 203 | pld [y_t_ptr] 204 | 205 | /* Top row, even: interleave the colour and alpha components 206 | ready for storage. */ 207 | vzip.u8 red8_e, alp8_e 208 | vzip.u8 blu8_e, grn8_e 209 | 210 | /* Top row, odd: combine luminance and chrominance. */ 211 | vmull.u8 y_scale, y_odd, coef_y 212 | vqadd.s16 red, y_scale, r_delta 213 | vqadd.s16 grn, y_scale, g_delta 214 | vqadd.s16 blu, y_scale, b_delta 215 | 216 | /* Top row, odd: set up alpha data. */ 217 | vmov.u8 alp8_o, #0xFF 218 | 219 | /* Top row, odd: clamp, rescale and clip colour components to 8 bits. */ 220 | vqrshrun.s16 red8_o, red, #6 221 | vqrshrun.s16 blu8_o, blu, #6 222 | vqrshrun.s16 grn8_o, grn, #6 223 | 224 | /* Top row, odd: interleave the colour and alpha components 225 | ready for storage. */ 226 | vzip.u8 red8_o, alp8_o 227 | vzip.u8 blu8_o, grn8_o 228 | 229 | /* Top row: Store 16 pixels of ARGB32, interleaving even and 230 | odd. */ 231 | vst4.u16 {blu8_e, red8_e, blu8_o, red8_o}, [rgb_t_ptr] 232 | add rgb_t_ptr, count, LSL #1 233 | vst4.u16 {grn8_e, alp8_e, grn8_o, alp8_o}, [rgb_t_ptr] 234 | add rgb_t_ptr, count, LSL #1 235 | 236 | /**************/ 237 | /* BOTTOM ROW */ 238 | /**************/ 239 | /* Bottom row: Load 16 pixels of y, even and odd. */ 240 | vld2.u8 {y_even, y_odd}, [y_b_ptr], count 241 | 242 | /* Bottom row, even: combine luminance and chrominance. */ 243 | vmull.u8 y_scale, y_even, coef_y 244 | vqadd.s16 red, y_scale, r_delta 245 | vqadd.s16 grn, y_scale, g_delta 246 | vqadd.s16 blu, y_scale, b_delta 247 | 248 | /* Bottom row, even: set up alpha data. */ 249 | vmov.u8 alp8_e, #0xFF 250 | 251 | /* Bottom row, even: clamp, rescale and clip colour components to 8 bits. */ 252 | vqrshrun.s16 red8_e, red, #6 253 | vqrshrun.s16 blu8_e, blu, #6 254 | vqrshrun.s16 grn8_e, grn, #6 255 | 256 | /* Bottom row: attempt to preload the next set of Y data, for 257 | better performance. */ 258 | pld [y_b_ptr] 259 | 260 | /* Bottom row, even: interleave the colour and alpha components 261 | ready for storage. */ 262 | vzip.u8 red8_e, alp8_e 263 | vzip.u8 blu8_e, grn8_e 264 | 265 | /* Bottom row, odd: combine luminance and chrominance. */ 266 | vmull.u8 y_scale, y_odd, coef_y 267 | vqadd.s16 red, y_scale, r_delta 268 | vqadd.s16 grn, y_scale, g_delta 269 | vqadd.s16 blu, y_scale, b_delta 270 | 271 | /* Bottom row, odd: set up alpha data. */ 272 | vmov.u8 alp8_o, #0xFF 273 | 274 | /* Bottom row, odd: clamp, rescale and clip colour components to 8 bits. */ 275 | vqrshrun.s16 red8_o, red, #6 276 | vqrshrun.s16 blu8_o, blu, #6 277 | vqrshrun.s16 grn8_o, grn, #6 278 | 279 | /* Bottom row, odd: Interleave the colour and alpha components 280 | ready for storage. */ 281 | vzip.u8 red8_o, alp8_o 282 | vzip.u8 blu8_o, grn8_o 283 | 284 | /* Have we reached the end of the row yet? */ 285 | subs aligned_count, aligned_count, count 286 | 287 | /* Bottom row: Store 16 pixels of ARGB32, interleaving even and 288 | odd. */ 289 | vst4.u16 {blu8_e, red8_e, blu8_o, red8_o}, [rgb_b_ptr] 290 | add rgb_b_ptr, count, LSL #1 291 | vst4.u16 {grn8_e, alp8_e, grn8_o, alp8_o}, [rgb_b_ptr] 292 | add rgb_b_ptr, count, LSL #1 293 | 294 | /* On the second (and subsequent) passes through this code, 295 | we'll always be working on 16 pixels at once. */ 296 | mov count, #16 297 | bgt loop_h_420 298 | 299 | /* Update pointers for new row of data. */ 300 | sub rgb_t_ptr, width, LSL #2 301 | sub y_t_ptr, width 302 | sub u_ptr, width, ASR #1 303 | sub v_ptr, width, ASR #1 304 | add rgb_t_ptr, rgb_pitch, LSL #1 305 | add y_t_ptr, y_pitch, LSL #1 306 | add u_ptr, uv_pitch 307 | add v_ptr, uv_pitch 308 | 309 | /* Have we reached the bottom row yet? */ 310 | subs height, height, #2 311 | bgt loop_v_420 312 | 313 | vpop {q4-q7} 314 | pop {r4-r12, pc} 315 | #ifndef __APPLE__ 316 | .fnend 317 | #endif 318 | 319 | /* Much the same as the above code, but simplified to work on a single 320 | row at a time. Each U and V value only covers 2 adjacent pixels on 321 | one row, not a 2x2 matrix */ 322 | #define rgb_ptr rgb_t_ptr 323 | #define y_ptr y_t_ptr 324 | 325 | yuv422_2_rgb8888_neon: 326 | /* r0 = dst_ptr */ 327 | /* r1 = y_ptr */ 328 | /* r2 = u_ptr */ 329 | /* r3 = v_ptr */ 330 | /* <> = width */ 331 | /* <> = height */ 332 | /* <> = y_pitch */ 333 | /* <> = uv_pitch */ 334 | /* <> = rgb_pitch */ 335 | #ifndef __APPLE__ 336 | .fnstart 337 | #endif 338 | push {r4-r12, lr} /* 10 words */ 339 | vpush {q4-q7} /* 4Q -> 16 words */ 340 | 341 | ldr width, [sp, #26*4] 342 | ldr height, [sp, #27*4] 343 | ldr y_pitch, [sp, #28*4] 344 | ldr uv_pitch, [sp, #29*4] 345 | ldr rgb_pitch, [sp, #30*4] 346 | adr lr, coefficients 347 | 348 | /* We can't cope with a width less than 16. Check for that. */ 349 | cmp width, #16 350 | vpoplt {q4-q7} 351 | poplt {r4-r12, pc} 352 | 353 | /* Load up vectors containing the bias values. */ 354 | vld1.s16 {bias_r_lo[], bias_r_hi[]}, [lr]! 355 | vld1.s16 {bias_g_lo[], bias_g_hi[]}, [lr]! 356 | vld1.s16 {bias_b_lo[], bias_b_hi[]}, [lr]! 357 | 358 | /* Build coefficient vectors containing the same value in each element. */ 359 | vmov.u8 coef_y, #C_Y_SCALE 360 | vmov.u8 coef_v_r, #C_V_RED 361 | vmov.u8 coef_u_g, #C_U_GREEN 362 | vmov.u8 coef_v_g, #C_V_GREEN 363 | vmov.u8 coef_u_b, #C_U_BLUE 364 | 365 | loop_v_422: 366 | mov aligned_count, width 367 | /* If width is not an integer multiple of 16, run the 368 | first pass through the loop with the correct number 369 | of pixels to correct the size for the remaining loops. */ 370 | ands count, width, #15 371 | /* If we're already aligned (i.e. count is now 0), set count 372 | to 16 to run the first loop as normal. */ 373 | moveq count, #16 374 | 375 | loop_h_422: 376 | /* Load u and v. */ 377 | vld1.u8 v, [v_ptr] 378 | add v_ptr, count, ASR #1 379 | vld1.u8 u, [u_ptr] 380 | add u_ptr, count, ASR #1 381 | 382 | /* Calculate contribution from chrominance signals. */ 383 | vmull.u8 r_delta, v, coef_v_r 384 | vmull.u8 g_delta, u, coef_u_g 385 | vmlal.u8 g_delta, v, coef_v_g 386 | vmull.u8 b_delta, u, coef_u_b 387 | 388 | /* Attempt to preload the next set of u and v input data, for 389 | better performance. */ 390 | pld [v_ptr] 391 | pld [u_ptr] 392 | 393 | /* Load 16 pixels of y, even and odd. */ 394 | vld2.u8 {y_even, y_odd}, [y_ptr], count 395 | 396 | /* Add bias. */ 397 | vadd.s16 r_delta, r_delta, bias_r 398 | vsub.s16 g_delta, bias_g, g_delta 399 | vadd.s16 b_delta, b_delta, bias_b 400 | 401 | /* Even: combine luminance and chrominance. */ 402 | vmull.u8 y_scale, y_even, coef_y 403 | vqadd.s16 red, y_scale, r_delta 404 | vqadd.s16 grn, y_scale, g_delta 405 | vqadd.s16 blu, y_scale, b_delta 406 | 407 | /* Even: set up alpha data. */ 408 | vmov.u8 alp8_e, #0xFF 409 | 410 | /* Attempt to preload the next set of Y data, for better 411 | performance. */ 412 | pld [y_ptr] 413 | 414 | /* Even: clamp, rescale and clip colour components to 8 bits. */ 415 | vqrshrun.s16 red8_e, red, #6 416 | vqrshrun.s16 grn8_e, grn, #6 417 | vqrshrun.s16 blu8_e, blu, #6 418 | 419 | /* Even: Interleave the colour and alpha components 420 | ready for storage. */ 421 | vzip.u8 red8_e, alp8_e 422 | vzip.u8 blu8_e, grn8_e 423 | 424 | /* Odd: combine luminance and chrominance. */ 425 | vmull.u8 y_scale, y_odd, coef_y 426 | vqadd.s16 red, y_scale, r_delta 427 | vqadd.s16 grn, y_scale, g_delta 428 | vqadd.s16 blu, y_scale, b_delta 429 | 430 | /* Odd: set up alpha data. */ 431 | vmov.u8 alp8_o, #0xFF 432 | 433 | /* Odd: clamp, rescale and clip colour components to 8 bits. */ 434 | vqrshrun.s16 red8_o, red, #6 435 | vqrshrun.s16 blu8_o, blu, #6 436 | vqrshrun.s16 grn8_o, grn, #6 437 | 438 | /* Odd: Interleave the colour and alpha components 439 | ready for storage. */ 440 | vzip.u8 red8_o, alp8_o 441 | vzip.u8 blu8_o, grn8_o 442 | 443 | /* Have we reached the end of the row yet? */ 444 | subs aligned_count, aligned_count, count 445 | 446 | /* Store 16 pixels of ARGB32, interleaving even and odd. */ 447 | vst4.u16 {blu8_e, red8_e, blu8_o, red8_o}, [rgb_ptr] 448 | add rgb_ptr, count, LSL #1 449 | vst4.u16 {grn8_e, alp8_e, grn8_o, alp8_o}, [rgb_ptr] 450 | add rgb_ptr, count, LSL #1 451 | 452 | /* On the second (and subsequent) passes through this code, 453 | we'll always be working on 16 pixels at once. */ 454 | mov count, #16 455 | bgt loop_h_422 456 | 457 | /* Update pointers for new row of data. */ 458 | sub rgb_ptr, width, LSL #2 459 | sub y_ptr, width 460 | sub u_ptr, width, ASR #1 461 | sub v_ptr, width, ASR #1 462 | add rgb_ptr, rgb_pitch 463 | add y_ptr, y_pitch 464 | add u_ptr, uv_pitch 465 | add v_ptr, uv_pitch 466 | 467 | /* Have we reached the bottom yet? */ 468 | subs height, height, #1 469 | bgt loop_v_422 470 | 471 | vpop {q4-q7} 472 | pop {r4-r12, pc} 473 | #ifndef __APPLE__ 474 | .fnend 475 | #endif 476 | 477 | #endif /* __ARM_NEON__ */ 478 | -------------------------------------------------------------------------------- /nanocam_opencv/yuv2rgb.neon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | void yuv422_2_rgb8888_neon 6 | ( 7 | uint8_t *dst_ptr, 8 | const uint8_t *y_ptr, 9 | const uint8_t *u_ptr, 10 | const uint8_t *v_ptr, 11 | int width, 12 | int height, 13 | int y_pitch, 14 | int uv_pitch, 15 | int rgb_pitch 16 | ); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /nanocams/.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Generated files 3 | # 4 | 5 | /nanocams 6 | -------------------------------------------------------------------------------- /nanocams/Makefile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------- 2 | # Makefile for building Camera Demo 3 | # 4 | # Copyright 2016 FriendlyARM (http://www.friendlyarm.net/) 5 | # 6 | 7 | ifndef DESTDIR 8 | DESTDIR ?= ../out 9 | endif 10 | 11 | CROSS_COMPILE ?= arm-linux- 12 | CC = $(CROSS_COMPILE)gcc 13 | CPP = $(CROSS_COMPILE)g++ 14 | INSTALL = install 15 | 16 | 17 | # ----------------------------------------------------------------------- 18 | 19 | CFLAGS += -Wall -O2 20 | CFLAGS += -I../include -I../kernel-headers 21 | 22 | ifeq ($(USE_STATIC_LIB),y) 23 | LIBS += \ 24 | ../libnxvpu/libnxvpu.a \ 25 | ../libnxv4l2/libv4l2-nexell.a \ 26 | ../libnxmalloc/libnxvmem.a \ 27 | ../libion/libion.a 28 | else 29 | LIBS += -L../libion -lion 30 | LIBS += -L../libnxmalloc -lnxvmem 31 | LIBS += -L../libnxv4l2 -lv4l2-nexell 32 | LIBS += -L../libnxvpu -lnxvpu 33 | endif 34 | LIBS += -L../prebuilt -lnxvidrc 35 | 36 | 37 | # ----------------------------------------------------------------------- 38 | 39 | TARGET = nanocams 40 | 41 | 42 | all: $(TARGET) 43 | 44 | %.o: %.cpp 45 | $(CPP) $(CFLAGS) -c -o $@ $< 46 | 47 | nanocams: NXJpegHWEnc.o nanocams.o 48 | $(CC) $(LDFLAGS) $^ -o $@ $(LIBS) -lstdc++ 49 | 50 | 51 | install: $(TARGET) 52 | $(INSTALL) -d 755 $(DESTDIR)/bin 53 | $(INSTALL) $^ $(DESTDIR)/bin/ 54 | 55 | clean distclean: 56 | rm -rf *.o $(TARGET) 57 | 58 | 59 | # ----------------------------------------------------------------------- 60 | 61 | .PHONY: $(PHONY) install clean distclean 62 | 63 | # End of file 64 | # vim: syntax=make 65 | 66 | -------------------------------------------------------------------------------- /nanocams/NXJpegHWEnc.cpp: -------------------------------------------------------------------------------- 1 | #define LOG_TAG "NXJpegHW" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #ifndef ALOGE 8 | #define ALOGE printf 9 | #endif 10 | 11 | //#include 12 | 13 | //#include 14 | #include 15 | #include 16 | #include 17 | 18 | //#include "gralloc_priv.h" 19 | 20 | /** 21 | * return jpeg Size 22 | */ 23 | int NX_JpegHWEncoding(void *dstVirt, int dstSize, 24 | int width, int height, unsigned int fourcc, 25 | unsigned int yPhy, unsigned int yVirt, unsigned int yStride, 26 | unsigned int cbPhy, unsigned int cbVirt, unsigned int cbStride, 27 | unsigned int crPhy, unsigned int crVirt, unsigned int crStride, 28 | bool copySOI) 29 | { 30 | NX_VID_ENC_HANDLE hEnc; 31 | NX_VID_ENC_OUT encOut; 32 | NX_VID_MEMORY_INFO memInfo; 33 | NX_VID_ENC_INIT_PARAM encInitParam; 34 | int ret = 0; 35 | 36 | unsigned char *dst = (unsigned char *)dstVirt; 37 | unsigned char *jpegHeader = (unsigned char *)dst; 38 | 39 | memset(&memInfo, 0, sizeof(NX_VID_MEMORY_INFO)); 40 | memInfo.fourCC = fourcc; 41 | memInfo.imgWidth = width; 42 | memInfo.imgHeight = height; 43 | memInfo.luPhyAddr = yPhy; 44 | memInfo.luVirAddr = yVirt; 45 | memInfo.luStride = yStride; 46 | //memInfo.luStride = YUV_STRIDE(width); 47 | memInfo.cbPhyAddr = cbPhy; 48 | memInfo.cbVirAddr = cbVirt; 49 | memInfo.cbStride = cbStride; 50 | //memInfo.cbStride = YUV_STRIDE(width/2); 51 | memInfo.crPhyAddr = crPhy; 52 | memInfo.crVirAddr = crVirt; 53 | memInfo.crStride = crStride; 54 | //memInfo.crStride = YUV_STRIDE(width/2); 55 | 56 | memset( &encInitParam, 0, sizeof(encInitParam) ); 57 | encInitParam.width = width; 58 | encInitParam.height = height; 59 | encInitParam.rotAngle = 0; 60 | encInitParam.mirDirection = 0; 61 | encInitParam.jpgQuality = 100; 62 | 63 | hEnc = NX_VidEncOpen(NX_JPEG_ENC, NULL); 64 | if (NX_VidEncInit(hEnc, &encInitParam) != 0) { 65 | ALOGE("NX_VidEncInit failed!"); 66 | return -EIO; 67 | } 68 | 69 | int size; 70 | NX_VidEncJpegGetHeader(hEnc, jpegHeader, &size); 71 | if (size <= 0) { 72 | ALOGE("Invalid JPEG Header Size %d", size); 73 | return -EINVAL; 74 | } 75 | if (!copySOI) { 76 | memcpy(jpegHeader, jpegHeader + 2, size - 2); 77 | size -= 2; 78 | } 79 | dst += size; 80 | ret = size; 81 | 82 | NX_VidEncJpegRunFrame(hEnc, &memInfo, &encOut); 83 | memcpy(dst, encOut.outBuf, encOut.bufSize); 84 | ret += encOut.bufSize; 85 | 86 | NX_VidEncClose(hEnc); 87 | 88 | return ret; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /nanocams/nanocams.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd. 3 | * (http://www.friendlyarm.com) 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, you can access it online at 17 | * http://www.gnu.org/licenses/gpl-2.0.html. 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | // -------------------------------------------------------- 44 | static int debug = 1; 45 | 46 | #define dbg(level, fmt, arg...) \ 47 | do { \ 48 | if (debug >= (level)) \ 49 | fprintf(stderr, "D/%.3d: " fmt, __LINE__, ## arg); \ 50 | } while (0) 51 | 52 | #define err(fmt, arg...) \ 53 | fprintf(stderr, "E/%.3d: " fmt, __LINE__, ## arg) 54 | 55 | static struct timespec tpstart; 56 | 57 | static void time_start(void) 58 | { 59 | clock_gettime(CLOCK_REALTIME, &tpstart); 60 | } 61 | 62 | static long time_us_delta(void) 63 | { 64 | struct timespec tpend; 65 | clock_gettime(CLOCK_REALTIME, &tpend); 66 | long usec = ((tpend.tv_sec - tpstart.tv_sec) * 1000000 + 67 | (tpend.tv_nsec - tpstart.tv_nsec) / 1000); 68 | tpstart = tpend; 69 | return usec; 70 | } 71 | 72 | // -------------------------------------------------------- 73 | 74 | /* 75 | * See system/core/init/util.c 76 | * Copyright (C) 2008 The Android Open Source Project 77 | */ 78 | static char hardware[32]; 79 | static unsigned revision = 0; 80 | 81 | static void get_hardware_name(char *hardware, unsigned int *revision) 82 | { 83 | const char *cpuinfo = "/proc/cpuinfo"; 84 | char *data = NULL; 85 | size_t len = 0, limit = 1024; 86 | int fd, n; 87 | char *x, *hw, *rev; 88 | 89 | /* Hardware string was provided on kernel command line */ 90 | if (hardware[0]) 91 | return; 92 | 93 | fd = open(cpuinfo, O_RDONLY); 94 | if (fd < 0) return; 95 | 96 | for (;;) { 97 | x = (char *)realloc(data, limit); 98 | if (!x) { 99 | err("Failed to allocate memory to read %s\n", cpuinfo); 100 | goto done; 101 | } 102 | data = x; 103 | 104 | n = read(fd, data + len, limit - len); 105 | if (n < 0) { 106 | err("Failed reading %s: %s (%d)\n", cpuinfo, strerror(errno), errno); 107 | goto done; 108 | } 109 | len += n; 110 | 111 | if (len < limit) 112 | break; 113 | 114 | /* We filled the buffer, so increase size and loop to read more */ 115 | limit *= 2; 116 | } 117 | 118 | data[len] = 0; 119 | hw = strstr(data, "\nHardware"); 120 | rev = strstr(data, "\nRevision"); 121 | 122 | if (hw) { 123 | x = strstr(hw, ": "); 124 | if (x) { 125 | x += 2; 126 | n = 0; 127 | while (*x && *x != '\n') { 128 | if (!isspace(*x)) 129 | hardware[n++] = tolower(*x); 130 | x++; 131 | if (n == 31) break; 132 | } 133 | hardware[n] = 0; 134 | } 135 | } 136 | 137 | if (rev) { 138 | x = strstr(rev, ": "); 139 | if (x) { 140 | *revision = strtoul(x + 2, 0, 16); 141 | } 142 | } 143 | 144 | done: 145 | close(fd); 146 | free(data); 147 | } 148 | 149 | static inline bool cpu_is_s5p4418(void) 150 | { 151 | return !strcmp(hardware, "nanopi2"); 152 | } 153 | 154 | static inline bool cpu_is_s5p6818(void) 155 | { 156 | return !strcmp(hardware, "nanopi3"); 157 | } 158 | 159 | // -------------------------------------------------------- 160 | #ifndef ALIGN 161 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 162 | #endif 163 | 164 | static inline int get_size(int format, int num, int width, int height) 165 | { 166 | int size; 167 | 168 | width = ALIGN(width, 128); 169 | height = ALIGN(height, 128); 170 | 171 | switch (format) { 172 | case V4L2_PIX_FMT_YUYV: 173 | if (num > 0) return 0; 174 | size = (width * height) * 2; 175 | break; 176 | case V4L2_PIX_FMT_YUV420M: 177 | case V4L2_PIX_FMT_YUV422P: 178 | if (num == 0) 179 | size = width * height; 180 | else 181 | size = (width * height) >> 1; 182 | break; 183 | case V4L2_PIX_FMT_YUV444: 184 | size = width * height; 185 | break; 186 | default: 187 | size = width * height * 2; 188 | break; 189 | } 190 | 191 | return size; 192 | } 193 | 194 | int alloc_buffers(int ion_fd, int count, struct nxp_vid_buffer *bufs, 195 | int width, int height, int format) 196 | { 197 | struct nxp_vid_buffer *vb; 198 | int plane_num; 199 | int i, j; 200 | int ret; 201 | 202 | if (format == V4L2_PIX_FMT_YUYV || format == V4L2_PIX_FMT_RGB565) 203 | plane_num = 1; 204 | else 205 | plane_num = 3; 206 | 207 | int size[plane_num]; 208 | for (j = 0; j < plane_num; j++) 209 | size[j] = get_size(format, j, width, height); 210 | 211 | dbg(3, "Alloc buffer: count(%d), plane(%d), format(%x)\n", count, plane_num, format); 212 | for (i = 0; i < count; i++) { 213 | vb = &bufs[i]; 214 | vb->plane_num = plane_num; 215 | dbg(3, "[Buffer %d] --->\n", i); 216 | for (j = 0; j < plane_num; j++) { 217 | ret = ion_alloc_fd(ion_fd, size[j], 0, 218 | ION_HEAP_NXP_CONTIG_MASK, 0, &vb->fds[j]); 219 | if (ret < 0) { 220 | err("failed to ion alloc %d\n", size[j]); 221 | return ret; 222 | } 223 | vb->virt[j] = (char *)mmap(NULL, size[j], 224 | PROT_READ | PROT_WRITE, MAP_SHARED, vb->fds[j], 0); 225 | if (!vb->virt[j]) { 226 | err("failed to mmap\n"); 227 | return -1; 228 | } 229 | ret = ion_get_phys(ion_fd, vb->fds[j], &vb->phys[j]); 230 | if (ret < 0) { 231 | err("failed to get phys\n"); 232 | return ret; 233 | } 234 | vb->sizes[j] = size[j]; 235 | dbg(3, "\tplane %d: fd(%d), size(%d), phys(0x%lx), virt(%p)\n", 236 | j, vb->fds[j], vb->sizes[j], vb->phys[j], vb->virt[j]); 237 | } 238 | } 239 | 240 | return 0; 241 | } 242 | 243 | // -------------------------------------------------------- 244 | #define MAX_BUFFER_COUNT 4 245 | #define FMT_SENDOR V4L2_MBUS_FMT_YUYV8_2X8 246 | 247 | #define __V4L2_S(cmd) \ 248 | do { \ 249 | int ret = cmd; \ 250 | if (ret < 0) { \ 251 | fprintf(stderr, "%.3d: `%s' = %d\n", __LINE__, #cmd, ret); \ 252 | return ret; \ 253 | } \ 254 | } while (0) 255 | 256 | static int init_preview(int width, int height, int format) 257 | { 258 | __V4L2_S(v4l2_set_format(nxp_v4l2_decimator0, width, height, format)); 259 | 260 | __V4L2_S(v4l2_set_crop_with_pad(nxp_v4l2_decimator0, 2, 0, 0, width, height)); 261 | __V4L2_S(v4l2_set_crop(nxp_v4l2_decimator0, 0, 0, width, height)); 262 | 263 | // Set to default format (800x600) at first 264 | if (width != 800) 265 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, 800, 600, FMT_SENDOR)); 266 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, width, height, FMT_SENDOR)); 267 | 268 | __V4L2_S(v4l2_reqbuf(nxp_v4l2_decimator0, MAX_BUFFER_COUNT)); 269 | return 0; 270 | } 271 | 272 | /* 273 | * Note: 274 | * - S5P4418: clipper0 + YUV422P, or decimator0 + YUV420M 275 | * - S5P6818: clipper0 + YUV420M 276 | */ 277 | static int init_capture(int width, int height) 278 | { 279 | int format = V4L2_PIX_FMT_YUV422P; 280 | if (cpu_is_s5p6818()) 281 | format = V4L2_PIX_FMT_YUV420M; 282 | 283 | __V4L2_S(v4l2_set_format(nxp_v4l2_clipper0, width, height, format)); 284 | __V4L2_S(v4l2_set_crop(nxp_v4l2_clipper0, 0, 0, width, height)); 285 | 286 | // Set to default format (800x600) at first 287 | if (width != 800) 288 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, 800, 600, FMT_SENDOR)); 289 | __V4L2_S(v4l2_set_format(nxp_v4l2_sensor0, width, height, FMT_SENDOR)); 290 | 291 | __V4L2_S(v4l2_reqbuf(nxp_v4l2_clipper0, MAX_BUFFER_COUNT)); 292 | return 0; 293 | } 294 | 295 | static int init_display(int width, int height, int format) 296 | { 297 | __V4L2_S(v4l2_set_format(nxp_v4l2_mlc0_video, width, height, format)); 298 | 299 | // Required for S5P6818 300 | __V4L2_S(v4l2_set_crop_with_pad(nxp_v4l2_mlc0_video, 2, 0, 0, width, height)); 301 | 302 | // Adapt to LCD 1024x600 303 | if (width == 1280 && height == 720) { 304 | width = 1024; 305 | height = 720; 306 | } else if (height > 1600) { 307 | width = 640; 308 | height = 480; 309 | } else if (height > 600) { 310 | width = 800; 311 | height = 600; 312 | } 313 | dbg(3, "display crop [%d, %d]\n", width, height); 314 | __V4L2_S(v4l2_set_crop(nxp_v4l2_mlc0_video, 0, 0, width, height)); 315 | 316 | __V4L2_S(v4l2_set_ctrl(nxp_v4l2_mlc0_video, V4L2_CID_MLC_VID_PRIORITY, 0)); 317 | __V4L2_S(v4l2_reqbuf(nxp_v4l2_mlc0_video, MAX_BUFFER_COUNT)); 318 | return 0; 319 | } 320 | 321 | static int save_handle_to_jpeg(struct nxp_vid_buffer *buf, 322 | char *name, int width, int height) 323 | { 324 | int ret = -1; 325 | int align = cpu_is_s5p6818() ? 128 : 16; 326 | int stride = ALIGN(width, align); 327 | 328 | int fd = creat(name, 0644); 329 | if (fd < 0) { 330 | err("failed to create `%s', errno = %d\n", name, errno); 331 | return ret; 332 | } 333 | 334 | int size = buf->sizes[0] + buf->sizes[1] + buf->sizes[2]; 335 | void *dst = malloc(size); 336 | if (!dst) { 337 | err("failed to malloc(%d), errno = %d\n", size, errno); 338 | goto error; 339 | } 340 | 341 | ret = NX_JpegHWEncoding(dst, size, width, height, FOURCC_MVS0, 342 | (unsigned int)buf->phys[0], 0, stride, 343 | (unsigned int)buf->phys[1], 0, stride >> 1, 344 | (unsigned int)buf->phys[2], 0, stride >> 1, true); 345 | if (ret < 0) { 346 | err("failed to encoding JPEG, ret = %d\n", ret); 347 | } else { 348 | ret = write(fd, dst, ret); 349 | if (ret <= 0) 350 | err("failed to write file, errno = %d\n", errno); 351 | } 352 | 353 | free(dst); 354 | error: 355 | close(fd); 356 | return ret; 357 | } 358 | 359 | static int do_preview(struct nxp_vid_buffer *bufs, int width, int height, 360 | int preview_frames) 361 | { 362 | struct nxp_vid_buffer *buf; 363 | int i; 364 | 365 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { 366 | buf = &bufs[i]; 367 | dbg(3, "queue buffer %d\n", i); 368 | v4l2_qbuf(nxp_v4l2_decimator0, buf->plane_num, i, buf, -1, NULL); 369 | } 370 | 371 | __V4L2_S(v4l2_streamon(nxp_v4l2_decimator0)); 372 | 373 | // fill all buffer for display 374 | int index = 0; 375 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { 376 | buf = &bufs[index]; 377 | dbg(2, "load buffer %d (%p)\n", index, buf); 378 | v4l2_dqbuf(nxp_v4l2_decimator0, buf->plane_num, &index, NULL); 379 | v4l2_qbuf(nxp_v4l2_decimator0, buf->plane_num, index, buf, -1, NULL); 380 | index++; 381 | } 382 | 383 | int cap_index = 0; 384 | int out_index = 0; 385 | int out_dq_index = 0; 386 | bool out_started = false; 387 | 388 | dbg(1, "start preview %dx%d (%d frames)\n", width, height, preview_frames); 389 | time_start(); 390 | 391 | for (i = 0; i < preview_frames; i++) { 392 | buf = &bufs[cap_index]; 393 | v4l2_dqbuf(nxp_v4l2_decimator0, buf->plane_num, &cap_index, NULL); 394 | v4l2_qbuf(nxp_v4l2_mlc0_video, buf->plane_num, out_index, buf, -1, NULL); 395 | 396 | dbg(3, "[ %ld ] switch buffer %d\n", time_us_delta(), cap_index); 397 | ++out_index %= MAX_BUFFER_COUNT; 398 | 399 | if (!out_started) { 400 | if (v4l2_streamon(nxp_v4l2_mlc0_video) < 0) 401 | goto __exit; 402 | out_started = true; 403 | } 404 | 405 | v4l2_qbuf(nxp_v4l2_decimator0, buf->plane_num, cap_index, buf, -1, NULL); 406 | if (i >= (MAX_BUFFER_COUNT - 1)) 407 | v4l2_dqbuf(nxp_v4l2_mlc0_video, buf->plane_num, &out_dq_index, NULL); 408 | } 409 | 410 | // stop preview 411 | __V4L2_S(v4l2_streamoff(nxp_v4l2_mlc0_video)); 412 | __exit: 413 | __V4L2_S(v4l2_streamoff(nxp_v4l2_decimator0)); 414 | return 0; 415 | } 416 | 417 | int do_capture(struct nxp_vid_buffer *bufs, int width, int height, 418 | int skip_frames, char *jpeg_file) 419 | { 420 | struct nxp_vid_buffer *buf; 421 | int i; 422 | 423 | dbg(1, "capture image %dx%d --> %s\n", width, height, jpeg_file); 424 | 425 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { 426 | buf = &bufs[i]; 427 | dbg(3, "queue buffer %d\n", i); 428 | v4l2_qbuf(nxp_v4l2_clipper0, buf->plane_num, i, buf, -1, NULL); 429 | } 430 | 431 | __V4L2_S(v4l2_streamon(nxp_v4l2_clipper0)); 432 | 433 | int index = 0; 434 | for (i = 0; i < skip_frames; i++) { 435 | v4l2_dqbuf(nxp_v4l2_clipper0, buf->plane_num, &index, NULL); 436 | buf = &bufs[index]; 437 | v4l2_qbuf(nxp_v4l2_clipper0, buf->plane_num, index, buf, -1, NULL); 438 | dbg(2, "skip buffer %d (%p)\n", index, buf); 439 | } 440 | 441 | __V4L2_S(v4l2_streamoff(nxp_v4l2_clipper0)); 442 | 443 | return save_handle_to_jpeg(buf, jpeg_file, width, height); 444 | } 445 | 446 | // -------------------------------------------------------- 447 | 448 | /* MLC/video works improperly for YUV420M @800x600,1600x1200 */ 449 | #define FMT_PREVIEW V4L2_PIX_FMT_YUV422P 450 | 451 | #ifndef ARRAY_SIZE 452 | #define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0])) 453 | #endif 454 | 455 | /* Supported frame size for sensor - OV5640 */ 456 | static int sensor_frmsize_list[][2] = { 457 | { 640, 480, }, 458 | { 800, 600, }, 459 | { 1280, 720, }, 460 | { 1600, 1200, }, 461 | { 2592, 1944, }, 462 | }; 463 | 464 | static void show_sensor_frmsize(void) 465 | { 466 | fprintf(stderr, "Supported SIZE for preview/capture:\n"); 467 | for (int i = 0; i < ARRAY_SIZE(sensor_frmsize_list); i++) { 468 | fprintf(stderr, " %d - %dx%d\n", i, 469 | sensor_frmsize_list[i][0], sensor_frmsize_list[i][1]); 470 | } 471 | } 472 | 473 | static void get_preview_size(int n, int *width, int *height) 474 | { 475 | if (n < 0 || n > 2) n = 0; 476 | 477 | *width = sensor_frmsize_list[n][0]; 478 | *height = sensor_frmsize_list[n][1]; 479 | } 480 | 481 | static void get_capture_size(int n, int *width, int *height) 482 | { 483 | if (n < 0 || n >= ARRAY_SIZE(sensor_frmsize_list)) 484 | n = ARRAY_SIZE(sensor_frmsize_list) - 1; 485 | 486 | *width = sensor_frmsize_list[n][0]; 487 | *height = sensor_frmsize_list[n][1]; 488 | } 489 | 490 | // -------------------------------------------------------- 491 | 492 | static void show_usage(char *name) 493 | { 494 | fprintf(stderr, "Usage: %s [OPTION]...\n\n", name); 495 | fprintf(stderr, "Options:\n"); 496 | fprintf(stderr, " -p SIZE enable preview in size\n"); 497 | fprintf(stderr, " -c SIZE select capture size\n"); 498 | fprintf(stderr, " -o FILE save JPEG image to file\n"); 499 | fprintf(stderr, " -n COUNT show given number of frames then capture\n"); 500 | fprintf(stderr, " -h display this help and exit\n\n"); 501 | show_sensor_frmsize(); 502 | fprintf(stderr, "\n"); 503 | fprintf(stderr, "Camera demo for S5P4418/S5P6818 boards\n"); 504 | fprintf(stderr, "Copyright (C) FriendlyARM \n"); 505 | } 506 | 507 | int main(int argc, char *argv[]) 508 | { 509 | char *jpeg_file = NULL; 510 | int width_p = 0, height_p = 0, count_p = 30; 511 | int width_c = 0, height_c = 0; 512 | int opt; 513 | 514 | while (-1 != (opt = getopt(argc, argv, "p:c:n:o:d:h"))) { 515 | switch (opt) { 516 | case 'p': get_preview_size(atoi(optarg), &width_p, &height_p); break; 517 | case 'c': get_capture_size(atoi(optarg), &width_c, &height_c); break; 518 | case 'o': jpeg_file = optarg; break; 519 | case 'n': count_p = atoi(optarg); break; 520 | case 'd': debug = atoi(optarg); break; 521 | case '?': fprintf(stderr, "\n"); 522 | case 'h': show_usage(argv[0]); exit(0); break; 523 | default: 524 | break; 525 | } 526 | } 527 | 528 | get_hardware_name(hardware, &revision); 529 | dbg(2, "Board: %s, Rev %04x\n", hardware, revision); 530 | 531 | if (jpeg_file && !width_c) 532 | get_capture_size(-1, &width_c, &height_c); 533 | 534 | if (width_p == 0 && (width_c == 0 || !jpeg_file)) { 535 | dbg(1, "NO preview or capture request. Aborting...\n"); 536 | dbg(1, "try `%s -h' for help\n", argv[0]); 537 | return 1; 538 | } 539 | 540 | int ion_fd = ion_open(); 541 | if (ion_fd < 0) { 542 | err("failed to ion_open, errno = %d\n", errno); 543 | return -EINVAL; 544 | } 545 | 546 | struct V4l2UsageScheme s; 547 | memset(&s, 0, sizeof(s)); 548 | s.useDecimator0 = true; 549 | s.useClipper0 = true; 550 | s.useMlc0Video = true; 551 | 552 | int ret = v4l2_init(&s); 553 | if (ret < 0) { 554 | err("initialize V4L2 failed, %d\n", ret); 555 | close(ion_fd); 556 | return ret; 557 | } 558 | 559 | struct nxp_vid_buffer bufs[MAX_BUFFER_COUNT]; 560 | ret = alloc_buffers(ion_fd, MAX_BUFFER_COUNT, bufs, 561 | (width_c > width_p) ? width_c : width_p, 562 | (height_c > height_p) ? height_c : height_p, FMT_PREVIEW); 563 | if (ret < 0) 564 | goto exit; 565 | 566 | if (width_p > 0) { 567 | init_preview(width_p, height_p, FMT_PREVIEW); 568 | init_display(width_p, height_p, FMT_PREVIEW); 569 | if ((ret = do_preview(bufs, width_p, height_p, count_p))) 570 | goto exit; 571 | } 572 | 573 | if (jpeg_file && !init_capture(width_c, height_c)) { 574 | ret = do_capture(bufs, width_c, height_c, 3, jpeg_file); 575 | } 576 | 577 | exit: 578 | v4l2_exit(); 579 | close(ion_fd); 580 | 581 | return ret; 582 | } 583 | 584 | -------------------------------------------------------------------------------- /prebuilt/libnxvidrc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friendlyarm/nexell_linux_platform/67bed16997c8ca6015987a9d0d03886e332b90cb/prebuilt/libnxvidrc.so --------------------------------------------------------------------------------