├── .gitattributes ├── .gitignore ├── Linux_UVC_TestAP ├── H264_UVC_TestAP.c ├── Makefile ├── cap_desc.c ├── cap_desc.h ├── cap_desc_parser.c ├── cap_desc_parser.h ├── debug.h ├── h264_xu_ctrls.c ├── h264_xu_ctrls.h ├── nalu.c ├── nalu.h ├── v4l2uvc.c └── v4l2uvc.h ├── Linux_uvc_driver ├── uvc_2.6.36 │ ├── Kconfig │ ├── Makefile_Embedded │ ├── Makefile_PC │ ├── nalu.c │ ├── nalu.h │ ├── uvc_ctrl.c │ ├── uvc_driver.c │ ├── uvc_isight.c │ ├── uvc_queue.c │ ├── uvc_status.c │ ├── uvc_v4l2.c │ ├── uvc_video.c │ └── uvcvideo.h └── uvc_3.3.8 │ ├── Kconfig │ ├── Makefile_Embedded │ ├── Makefile_PC │ ├── nalu.c │ ├── nalu.h │ ├── uvc_ctrl.c │ ├── uvc_debugfs.c │ ├── uvc_driver.c │ ├── uvc_entity.c │ ├── uvc_isight.c │ ├── uvc_queue.c │ ├── uvc_status.c │ ├── uvc_v4l2.c │ ├── uvc_video.c │ └── uvcvideo.h ├── README.md └── Read_me.pdf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/Makefile: -------------------------------------------------------------------------------- 1 | #compiler 2 | #CC = /opt/buildroot-gcc342/bin/mipsel-linux-uclibc-gcc 3 | 4 | #flags 5 | #CFLAGS = -Wall -ansi -g 6 | CFLAGS = -g -I/usr/src/linux-$(shell uname -r)/include 7 | #CFLAGS = -g -I/usr/src/linux-2.6.36.4/include 8 | 9 | #objects 10 | OBJS = H264_UVC_TestAP.o h264_xu_ctrls.o v4l2uvc.o nalu.o cap_desc_parser.o cap_desc.o 11 | 12 | #install path 13 | INSTALL_PATH = ./ 14 | 15 | all: H264_UVC_TestAP 16 | 17 | H264_UVC_TestAP: $(OBJS) 18 | $(CC) $(CFLAGS) $(OBJS) -o $@ -lpthread 19 | 20 | H264_UVC_TestAP.o: H264_UVC_TestAP.c h264_xu_ctrls.h 21 | $(CC) $(CFLAGS) -c -o $@ $< 22 | 23 | H264_xu_ctrls.o: h264_xu_ctrls.c h264_xu_ctrls.h 24 | $(CC) $(CFLAGS) -c -o $@ $< 25 | 26 | clean: 27 | -rm -f *.o *.ko .*.cmd .*.flags *.mod.c 28 | 29 | 30 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/cap_desc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "debug.h" 6 | #include "h264_xu_ctrls.h" 7 | #include "cap_desc.h" 8 | 9 | int GetCapability(int fd, struct CapabiltyBinaryData *pCapData) 10 | { 11 | unsigned int SensorInitTableAddr, CapAddr, CapSize, Section11_addr; 12 | unsigned char *pBuffer; 13 | // get SensorInitTableAddr 14 | pBuffer = malloc(4 * sizeof(unsigned char)); 15 | if(XU_SF_Read(fd, 0x017f, pBuffer,4)<0) 16 | { 17 | TestAp_Printf(TESTAP_DBG_ERR, "%s:read SF error\n",__FUNCTION__); 18 | return -1; 19 | } 20 | SensorInitTableAddr = (pBuffer[0]<<24) | (pBuffer[1]<<16) | (pBuffer[2]<<8) | pBuffer[3]; 21 | TestAp_Printf(TESTAP_DBG_BW, "%s: SensorInitTableAddr = 0x%x\n",__FUNCTION__, SensorInitTableAddr); 22 | free(pBuffer); 23 | 24 | // get CapAddr, CapSize 25 | pBuffer = malloc(25 * sizeof(unsigned char)); // 1 + 2 * (10 + 1) + 2 26 | if(XU_SF_Read(fd, SensorInitTableAddr, pBuffer,25)<0) 27 | { 28 | TestAp_Printf(TESTAP_DBG_ERR, "%s:read SF error\n",__FUNCTION__); 29 | return -1; 30 | } 31 | CapAddr = SensorInitTableAddr + ((pBuffer[21]<<8) | pBuffer[22]); 32 | Section11_addr = SensorInitTableAddr + ((pBuffer[23]<<8) | pBuffer[24]); 33 | CapSize = Section11_addr - CapAddr; 34 | TestAp_Printf(TESTAP_DBG_BW, "%s: CapAddr = 0x%x, CapSize = 0x%x\n",__FUNCTION__, CapAddr, CapSize); 35 | free(pBuffer); 36 | 37 | //get capability 38 | pCapData->pbuf= malloc(CapSize * sizeof(unsigned char)); 39 | pCapData->Lenght= CapSize; 40 | 41 | if(XU_SF_Read(fd, CapAddr, pCapData->pbuf,CapSize)<0) 42 | { 43 | TestAp_Printf(TESTAP_DBG_ERR, "%s:read SF error\n",__FUNCTION__); 44 | return -1; 45 | } 46 | return 0; 47 | } 48 | 49 | int GetInterface(int fd,struct InterfaceDesc *Interface_Desc) 50 | { 51 | int ret, i, j, k; 52 | struct v4l2_fmtdesc fmt; 53 | struct v4l2_frmsizeenum fsize; 54 | struct v4l2_frmivalenum fival; 55 | 56 | memset(Interface_Desc, 0 , sizeof(struct InterfaceDesc)); 57 | 58 | //get format 59 | memset(&fmt, 0, sizeof(fmt)); 60 | fmt.index = 0; 61 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 62 | while ((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt)) == 0) { 63 | Interface_Desc->NumFormat ++; 64 | Interface_Desc->fmt[fmt.index] = fmt.pixelformat; 65 | fmt.index++; 66 | #if 0 67 | TestAp_Printf(TESTAP_DBG_BW,"{ pixelformat = '%c%c%c%c', '%lx', description = '%s' }\n", 68 | fmt.pixelformat & 0xFF, (fmt.pixelformat >> 8) & 0xFF, 69 | (fmt.pixelformat >> 16) & 0xFF, (fmt.pixelformat >> 24) & 0xFF, fmt.pixelformat, 70 | fmt.description); 71 | #endif 72 | } 73 | 74 | //get frame size 75 | memset(&fsize, 0, sizeof(fsize)); 76 | for(i = 0; i < Interface_Desc->NumFormat;i++) 77 | { 78 | fsize.index = 0; 79 | fsize.pixel_format = Interface_Desc->fmt[i]; 80 | while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize)) == 0) 81 | { 82 | if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) 83 | { 84 | Interface_Desc->NumFrame[i]++; 85 | Interface_Desc->frame_info[i][fsize.index].width = fsize.discrete.width; 86 | Interface_Desc->frame_info[i][fsize.index].height= fsize.discrete.height; 87 | } 88 | fsize.index++; 89 | } 90 | } 91 | 92 | //get frame Interval(fps) 93 | memset(&fival, 0, sizeof(fival)); 94 | for(i = 0; i < Interface_Desc->NumFormat;i++) 95 | { 96 | for(j = 0; j < Interface_Desc->NumFrame[i];j++) 97 | { 98 | fival.index = 0; 99 | fival.pixel_format = Interface_Desc->fmt[i]; 100 | fival.width = Interface_Desc->frame_info[i][j].width; 101 | fival.height = Interface_Desc->frame_info[i][j].height; 102 | //Interface_Desc->frame_info[i][j].NumFPS = 0; 103 | while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0) 104 | { 105 | if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) 106 | { 107 | Interface_Desc->frame_info[i][j].NumFPS++; 108 | Interface_Desc->frame_info[i][j].FPS[fival.index] = (unsigned char)fival.discrete.denominator; 109 | } 110 | fival.index ++; 111 | } 112 | } 113 | } 114 | 115 | 116 | #if 0 117 | TestAp_Printf(TESTAP_DBG_BW, "INTERFACE:\n"); 118 | TestAp_Printf(TESTAP_DBG_BW, "format num = %d\n", Interface_Desc->NumFormat); 119 | for(i = 0; i < Interface_Desc->NumFormat;i++) 120 | { 121 | TestAp_Printf(TESTAP_DBG_BW, "\tformat[%d] = %x\n", i, Interface_Desc->fmt[i]); 122 | for(j = 0; j < Interface_Desc->NumFrame[i];j++) 123 | { 124 | TestAp_Printf(TESTAP_DBG_BW, "\t\tframe[%d]: size = %d x %d \n", j, Interface_Desc->frame_info[i][j].width, Interface_Desc->frame_info[i][j].height); 125 | for(k = 0; kframe_info[i][j].NumFPS; k++) 126 | TestAp_Printf(TESTAP_DBG_BW, "\t\t\tfps[%d]: fps = %d\n", k, Interface_Desc->frame_info[i][j].FPS[k]); 127 | 128 | } 129 | 130 | } 131 | #endif 132 | 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/cap_desc.h: -------------------------------------------------------------------------------- 1 | #define MAX_FORMAT 5 2 | #define MAX_FRAME 10 3 | #define MAX_FPS 10 4 | 5 | struct CapabiltyBinaryData{ 6 | unsigned char *pbuf; 7 | int Lenght; 8 | }; 9 | 10 | struct FrameTypeDesc{ 11 | unsigned short width; 12 | unsigned short height; 13 | unsigned char NumFPS; 14 | unsigned char FPS[MAX_FPS]; 15 | }; 16 | 17 | 18 | struct InterfaceDesc{ 19 | unsigned char NumFormat; 20 | unsigned int fmt[MAX_FORMAT]; 21 | unsigned char NumFrame[MAX_FORMAT]; 22 | struct FrameTypeDesc frame_info[MAX_FORMAT][MAX_FRAME]; 23 | }; 24 | 25 | 26 | int GetCapability(int fd, struct CapabiltyBinaryData *pCapData); 27 | int GetInterface(int fd,struct InterfaceDesc *InterfaceDesc); 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/cap_desc_parser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "cap_desc_parser.h" 5 | 6 | //======================================================================= 7 | // start of capability parser 8 | //======================================================================= 9 | 10 | 11 | int ParseMultiStreamConfig(unsigned char *pConfig, struct MultiStreamCfg *Cfg_Desc) 12 | { 13 | int i; 14 | unsigned char *pMultistreamCap; 15 | Cfg_Desc->NumStreams = pConfig[2]; 16 | 17 | //parse multistream capability descriptor 18 | Cfg_Desc->MS_Cap = malloc(Cfg_Desc->NumStreams * sizeof(struct MultiStreamCap)); 19 | pMultistreamCap = pConfig + pConfig[0]; 20 | for(i=0; iNumStreams; i++) 21 | { 22 | memcpy((unsigned char *)&Cfg_Desc->MS_Cap[i], (unsigned char *)pMultistreamCap+2 ,12); 23 | pMultistreamCap += pMultistreamCap[0]; 24 | } 25 | 26 | } 27 | 28 | int ParseCapability(unsigned char *pData, int Length, struct CapabilityDescriptor *Cap_Desc) 29 | { 30 | 31 | int i, j; 32 | int ConfigLength; 33 | unsigned char *pConfigData, *pDemuxerData, *pFrameIntervalData, *pBitrateData; 34 | //check capability header 35 | if(pData[0] != MSC_HEADER_LENGTH || pData[1] != MSC_HEADER) 36 | { 37 | //printf("%s:Not Capability data \n",__FUNCTION__); 38 | return -1; 39 | } 40 | //parse header 41 | Cap_Desc->NumConfigs = pData[4]; 42 | 43 | //parse configuration descriptor 44 | Cap_Desc->Cfg_Desc = malloc(Cap_Desc->NumConfigs * sizeof(struct MultiStreamCfg)); 45 | pConfigData = pData + pData[0]; 46 | ConfigLength = pConfigData[0]; 47 | for(i=0; iNumConfigs; i++) 48 | { 49 | ParseMultiStreamConfig(pConfigData, &Cap_Desc->Cfg_Desc[i]); 50 | pConfigData += (ConfigLength + Cap_Desc->Cfg_Desc[i].NumStreams * pConfigData[ConfigLength]); 51 | 52 | } 53 | 54 | //calculate number of demuxer descriptor 55 | pDemuxerData = pConfigData; 56 | i = 0; 57 | while(pDemuxerData[1]==MSC_DEMUXER) 58 | { 59 | pDemuxerData += pDemuxerData[0]; 60 | i++; 61 | } 62 | Cap_Desc->NumDemuxers = i; 63 | 64 | //parse demuxer descriptor 65 | pDemuxerData = pConfigData; 66 | Cap_Desc->demuxer_Desc = malloc(Cap_Desc->NumDemuxers * sizeof(struct MultiStreamDemuxer)); 67 | for(i = 0; i < Cap_Desc->NumDemuxers; i++) 68 | { 69 | Cap_Desc->demuxer_Desc[i].MSCDemuxIndex = pDemuxerData[2]; 70 | Cap_Desc->demuxer_Desc[i].DemuxID= pDemuxerData[3]; 71 | Cap_Desc->demuxer_Desc[i].Width = (pDemuxerData[4]<<8) | pDemuxerData[5]; 72 | Cap_Desc->demuxer_Desc[i].Height= (pDemuxerData[6]<<8) | pDemuxerData[7]; 73 | pDemuxerData += pDemuxerData[0]; 74 | } 75 | 76 | //calculat number of frameinterval descriptor 77 | pFrameIntervalData = pDemuxerData; 78 | i = 0; 79 | while(pFrameIntervalData[1] == MSC_FRAMEINTERVAL) 80 | { 81 | pFrameIntervalData += pFrameIntervalData[0]; 82 | i++; 83 | } 84 | Cap_Desc->NumFrameIntervals = i; 85 | 86 | //parse frameinterval descriptor 87 | pFrameIntervalData = pDemuxerData; 88 | Cap_Desc->FrameInt_Desc = malloc(Cap_Desc->NumFrameIntervals * sizeof(struct MultiStreamFrameInterval)); 89 | for(i = 0; i < Cap_Desc->NumFrameIntervals; i++) 90 | { 91 | unsigned int FrameInternal, fps; 92 | Cap_Desc->FrameInt_Desc[i].FPSIndex = pFrameIntervalData[2]; 93 | Cap_Desc->FrameInt_Desc[i].FPSCount = pFrameIntervalData[3]; 94 | Cap_Desc->FrameInt_Desc[i].FPS = malloc(Cap_Desc->FrameInt_Desc[i].FPSCount * sizeof(unsigned char)); 95 | for(j = 0; j < Cap_Desc->FrameInt_Desc[i].FPSCount; j++) 96 | { 97 | FrameInternal = (pFrameIntervalData[4+j*4]<<24) | (pFrameIntervalData[4+j*4+1]<<16) + 98 | (pFrameIntervalData[4+j*4+2]<<8) | pFrameIntervalData[4+j*4+3]; 99 | fps = 10000000/FrameInternal; 100 | Cap_Desc->FrameInt_Desc[i].FPS[j] = (unsigned char)fps; 101 | } 102 | pFrameIntervalData += pFrameIntervalData[0]; 103 | } 104 | 105 | //calculate number of bitrate descriptor 106 | pBitrateData = pFrameIntervalData; 107 | i = 0; 108 | while(pBitrateData[1]==MSC_BITRATE) 109 | { 110 | pBitrateData += pBitrateData[0]; 111 | i++; 112 | } 113 | Cap_Desc->NumBitrate = i; 114 | 115 | //parse bitrate descriptor 116 | pBitrateData = pFrameIntervalData; 117 | 118 | Cap_Desc->Bitrate_Desc = malloc(Cap_Desc->NumBitrate*sizeof(struct MultiStreamBitrate)); 119 | for(i = 0; iNumBitrate; i++) 120 | { 121 | memcpy(&Cap_Desc->Bitrate_Desc[i], pBitrateData+2, 2); 122 | pBitrateData += pBitrateData[0]; 123 | } 124 | if((pBitrateData-pData)>Length) 125 | { 126 | printf("%s:data length error \n",__FUNCTION__); 127 | return -1; 128 | } 129 | free(pData); 130 | return 0; 131 | } 132 | 133 | //===================end of capability parser==================================== 134 | 135 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/cap_desc_parser.h: -------------------------------------------------------------------------------- 1 | 2 | //======================================================================= 3 | // start of capability parser defination 4 | //======================================================================= 5 | 6 | struct CapabilityDescriptor{ 7 | unsigned char NumConfigs; 8 | struct MultiStreamCfg *Cfg_Desc; 9 | unsigned char NumDemuxers; 10 | struct MultiStreamDemuxer *demuxer_Desc; 11 | unsigned char NumFrameIntervals; 12 | struct MultiStreamFrameInterval *FrameInt_Desc; 13 | unsigned char NumBitrate; 14 | struct MultiStreamBitrate *Bitrate_Desc; 15 | }; 16 | 17 | struct MultiStreamCfg{ 18 | unsigned char NumStreams; 19 | struct MultiStreamCap *MS_Cap; //capability for each stream 20 | }; 21 | 22 | 23 | struct MultiStreamCap{ 24 | unsigned char UVCInterfaceNum; 25 | unsigned char UVCFormatIndex; 26 | unsigned char UVCFrameIndex; 27 | unsigned char DemuxerIndex; 28 | unsigned char FPSIndex; 29 | unsigned char BRCIndex; 30 | unsigned char OSDIndex; 31 | unsigned char MDIndex; 32 | unsigned char PTZIIndex; 33 | unsigned char FPSGroup; 34 | unsigned char BRCGroup; 35 | unsigned char OSDGroup; 36 | }; 37 | 38 | struct MultiStreamDemuxer{ 39 | unsigned char MSCDemuxIndex; 40 | unsigned char DemuxID; 41 | unsigned short Width; 42 | unsigned short Height; 43 | }; 44 | 45 | struct MultiStreamFrameInterval{ 46 | unsigned char FPSIndex; 47 | unsigned char FPSCount; 48 | unsigned char *FPS; // (10^7) / FrameInterval 49 | }; 50 | 51 | struct MultiStreamBitrate{ 52 | unsigned char BRCIndex; 53 | unsigned char BRCMode; 54 | }; 55 | 56 | enum{ 57 | MSC_HEADER = 0, 58 | MSC_CONFIG, 59 | MSC_CAPABILITY, 60 | MSC_DEMUXER, 61 | MSC_FRAMEINTERVAL, 62 | MSC_BITRATE, 63 | MSC_OSD 64 | }; 65 | 66 | #define MSC_HEADER_LENGTH 5 67 | 68 | int ParseCapability(unsigned char *pCapability, int Length, struct CapabilityDescriptor *Cap_Desc); 69 | 70 | //===================end of capability parser defination==================================== 71 | 72 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/debug.h: -------------------------------------------------------------------------------- 1 | extern int Dbg_Param; 2 | #define TestAp_Printf(flag, msg...) ((Dbg_Param & flag)?printf(msg):flag) 3 | 4 | #define TESTAP_DBG_USAGE (1 << 0) 5 | #define TESTAP_DBG_ERR (1 << 1) 6 | #define TESTAP_DBG_FLOW (1 << 2) 7 | #define TESTAP_DBG_FRAME (1 << 3) 8 | #define TESTAP_DBG_BW (1 << 4) 9 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/h264_xu_ctrls.h: -------------------------------------------------------------------------------- 1 | #ifndef H264_XU_CTRLS_H 2 | #define H264_XU_CTRLS_H 3 | 4 | #include 5 | #include 6 | #if LINUX_VERSION_CODE > KERNEL_VERSION (3, 0, 0) 7 | #include 8 | #endif 9 | 10 | #define CARCAM_PROJECT 0 11 | 12 | /* 13 | * Dynamic controls 14 | */ 15 | //copy from uvcvideo.h 16 | #define UVC_CTRL_DATA_TYPE_RAW 0 17 | #define UVC_CTRL_DATA_TYPE_SIGNED 1 18 | #define UVC_CTRL_DATA_TYPE_UNSIGNED 2 19 | #define UVC_CTRL_DATA_TYPE_BOOLEAN 3 20 | #define UVC_CTRL_DATA_TYPE_ENUM 4 21 | #define UVC_CTRL_DATA_TYPE_BITMASK 5 22 | 23 | /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 24 | 25 | #define V4L2_CID_BASE_EXTCTR_RERVISION 0x0A0c4501 26 | #define V4L2_CID_BASE_RERVISION V4L2_CID_BASE_EXTCTR_RERVISION 27 | #define V4L2_CID_ASIC_RW_RERVISION V4L2_CID_BASE_RERVISION+1 28 | #define V4L2_CID_FLASH_CTRL V4L2_CID_BASE_RERVISION+2 29 | #define V4L2_CID_FRAME_INFO_RERVISION V4L2_CID_BASE_RERVISION+3 30 | #define V4L2_CID_H264_CTRL_RERVISION V4L2_CID_BASE_RERVISION+4 31 | #define V4L2_CID_MJPG_CTRL_RERVISION V4L2_CID_BASE_RERVISION+5 32 | #define V4L2_CID_OSD_CTRL_RERVISION V4L2_CID_BASE_RERVISION+6 33 | #define V4L2_CID_MOTION_DETECTION_RERVISION V4L2_CID_BASE_RERVISION+7 34 | #define V4L2_CID_IMG_SETTING_RERVISION V4L2_CID_BASE_RERVISION+8 35 | #define V4L2_CID_MULTI_STREAM_CTRL_RERVISION V4L2_CID_BASE_RERVISION+9 36 | #define V4L2_CID_GPIO_CTRL_RERVISION V4L2_CID_BASE_RERVISION+10 37 | #define V4L2_CID_DYNAMIC_FPS_CTRL_RERVISION V4L2_CID_BASE_RERVISION+11 38 | #define V4L2_CID_LAST_EXTCTR_RERVISION V4L2_CID_DYNAMIC_FPS_CTRL_RERVISION 39 | 40 | /* ---------------------------------------------------------------------------- */ 41 | 42 | #define UVC_GUID_RERVISION_SYS_HW_CTRL {0x70, 0x33, 0xf0, 0x28, 0x11, 0x63, 0x2e, 0x4a, 0xba, 0x2c, 0x68, 0x90, 0xeb, 0x33, 0x40, 0x16} 43 | #define UVC_GUID_RERVISION_USR_HW_CTRL {0x94, 0x73, 0xDF, 0xDD, 0x3E, 0x97, 0x27, 0x47, 0xBE, 0xD9, 0x04, 0xED, 0x64, 0x26, 0xDC, 0x67} 44 | //#define UVC_GUID_RERVISION_USR_HW_CTRL {0x3F, 0xAE, 0x12, 0x28, 0xD7, 0xBC, 0x11, 0x4E, 0xA3, 0x57, 0x6F, 0x1E, 0xDE, 0xF7, 0xD6, 0x1D} 45 | 46 | #define XU_RERVISION_SYS_ID 0x03 47 | #define XU_RERVISION_USR_ID 0x04 48 | 49 | // ----------------------------- XU Control Selector ------------------------------------ 50 | #define XU_RERVISION_SYS_ASIC_RW 0x01 51 | #define XU_RERVISION_SYS_FLASH_CTRL 0x03 52 | #define XU_RERVISION_SYS_FRAME_INFO 0x06 53 | #define XU_RERVISION_SYS_H264_CTRL 0x07 54 | #define XU_RERVISION_SYS_MJPG_CTRL 0x08 55 | #define XU_RERVISION_SYS_OSD_CTRL 0x09 56 | #define XU_RERVISION_SYS_MOTION_DETECTION 0x0A 57 | #define XU_RERVISION_SYS_IMG_SETTING 0x0B 58 | 59 | #define XU_RERVISION_USR_FRAME_INFO 0x01 60 | #define XU_RERVISION_USR_H264_CTRL 0x02 61 | #define XU_RERVISION_USR_MJPG_CTRL 0x03 62 | #define XU_RERVISION_USR_OSD_CTRL 0x04 63 | #define XU_RERVISION_USR_MOTION_DETECTION 0x05 64 | #define XU_RERVISION_USR_IMG_SETTING 0x06 65 | #define XU_RERVISION_USR_MULTI_STREAM_CTRL 0x07 66 | #define XU_RERVISION_USR_GPIO_CTRL 0x08 67 | #define XU_RERVISION_USR_DYNAMIC_FPS_CTRL 0x09 68 | 69 | // ----------------------------- XU Control Selector ------------------------------------ 70 | //copy from uvcvideo.h 71 | #define UVC_CONTROL_SET_CUR (1 << 0) 72 | #define UVC_CONTROL_GET_CUR (1 << 1) 73 | #define UVC_CONTROL_GET_MIN (1 << 2) 74 | #define UVC_CONTROL_GET_MAX (1 << 3) 75 | #define UVC_CONTROL_GET_RES (1 << 4) 76 | #define UVC_CONTROL_GET_DEF (1 << 5) 77 | /* Control should be saved at suspend and restored at resume. */ 78 | #define UVC_CONTROL_RESTORE (1 << 6) 79 | /* Control can be updated by the camera. */ 80 | #define UVC_CONTROL_AUTO_UPDATE (1 << 7) 81 | 82 | #define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ 83 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ 84 | UVC_CONTROL_GET_DEF) 85 | 86 | struct uvc_xu_control_info { 87 | __u8 entity[16]; 88 | __u8 index; 89 | __u8 selector; 90 | __u16 size; 91 | __u32 flags; 92 | }; 93 | 94 | #if LINUX_VERSION_CODE <= KERNEL_VERSION (3, 0, 0) 95 | struct uvc_xu_control_mapping { 96 | __u32 id; 97 | __u8 name[32]; 98 | __u8 entity[16]; 99 | __u8 selector; 100 | 101 | __u8 size; 102 | __u8 offset; 103 | #if LINUX_VERSION_CODE == KERNEL_VERSION(3,0,0) || LINUX_VERSION_CODE == KERNEL_VERSION(3,0,35) 104 | __u32 v4l2_type; 105 | __u32 data_type; 106 | 107 | struct uvc_menu_info __user *menu_info; 108 | __u32 menu_count; 109 | 110 | __u32 reserved[4]; 111 | #else 112 | enum v4l2_ctrl_type v4l2_type; 113 | __u32 data_type; 114 | #endif 115 | }; 116 | #endif 117 | 118 | struct uvc_xu_control { 119 | __u8 unit; 120 | __u8 selector; 121 | __u16 size; 122 | __u8 *data; 123 | }; 124 | 125 | struct H264Format 126 | { 127 | unsigned short wWidth; 128 | unsigned short wHeight; 129 | int fpsCnt; 130 | unsigned int FrameSize; 131 | unsigned int *FrPay; // FrameInterval[0|1]Payloadsize[2|3] 132 | }; 133 | 134 | struct Cur_H264Format 135 | { 136 | int FmtId; 137 | unsigned short wWidth; 138 | unsigned short wHeight; 139 | int FrameRateId; 140 | unsigned char framerate; 141 | unsigned int FrameSize; 142 | }; 143 | 144 | struct Multistream_Info 145 | { 146 | unsigned char strm_type; 147 | unsigned int format; 148 | }; 149 | 150 | typedef enum{ 151 | CHIP_NONE = -1, 152 | CHIP_RER9420 = 0, 153 | CHIP_RER9421, 154 | CHIP_RER9422 155 | }CHIP_RER942X; 156 | 157 | #if LINUX_VERSION_CODE > KERNEL_VERSION (3, 0, 0) 158 | #define UVC_SET_CUR 0x01 159 | #define UVC_GET_CUR 0x81 160 | #define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) 161 | #define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) 162 | #else 163 | #define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) 164 | #define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) 165 | #define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) 166 | #define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) 167 | #endif 168 | extern unsigned int chip_id; 169 | 170 | int XU_Init_Ctrl(int fd); 171 | int XU_Ctrl_ReadChipID(int fd); 172 | 173 | int H264_GetFormat(int fd); 174 | int H264_CountFormat(unsigned char *Data, int len); 175 | int H264_ParseFormat(unsigned char *Data, int len, struct H264Format *fmt); 176 | int H264_GetFPS(unsigned int FrPay); 177 | 178 | // H.264 XU +++++ 179 | 180 | int XU_Set(int fd, struct uvc_xu_control xctrl); 181 | int XU_Get(int fd, struct uvc_xu_control *xctrl); 182 | 183 | int XU_Set_Cur(int fd, __u8 xu_unit, __u8 xu_selector, __u16 xu_size, __u8 *xu_data); 184 | int XU_Get_Cur(int fd, __u8 xu_unit, __u8 xu_selector, __u16 xu_size, __u8 *xu_data); 185 | 186 | int XU_H264_InitFormat(int fd); 187 | int XU_H264_GetFormatLength(int fd, unsigned short *fwLen); 188 | int XU_H264_GetFormatData(int fd, unsigned char *fwData, unsigned short fwLen); 189 | int XU_H264_SetFormat(int fd, struct Cur_H264Format fmt); 190 | 191 | int XU_H264_Get_QP_Limit(int fd, int *QP_Min, int *QP_Max); 192 | int XU_H264_Get_Mode(int fd, int *Mode); 193 | int XU_H264_Set_Mode(int fd, int Mode); 194 | 195 | int XU_H264_Get_QP(int fd, int *QP_Val); 196 | int XU_H264_Set_QP(int fd, int QP_Val); 197 | 198 | int XU_H264_Get_BitRate(int fd, double *BitRate); 199 | int XU_H264_Set_BitRate(int fd, double BitRate); 200 | 201 | int XU_H264_Set_IFRAME(int fd); 202 | 203 | int XU_H264_Get_SEI(int fd, unsigned char *SEI); 204 | int XU_H264_Set_SEI(int fd, unsigned char SEI); 205 | 206 | int XU_H264_Get_GOP(int fd, unsigned int *GOP); 207 | int XU_H264_Set_GOP(int fd, unsigned int GOP); 208 | 209 | int XU_Asic_Read(int fd, unsigned int Addr, unsigned char *AsicData); 210 | int XU_Asic_Write(int fd, unsigned int Addr, unsigned char AsicData); 211 | 212 | #if(CARCAM_PROJECT == 0) 213 | int XU_Multi_Get_status(int fd, struct Multistream_Info *status); 214 | int XU_Multi_Get_Info(int fd, struct Multistream_Info *Info); 215 | int XU_Multi_Set_Type(int fd, unsigned int format); 216 | 217 | int XU_Multi_Set_Enable(int fd, unsigned char enable); 218 | int XU_Multi_Get_Enable(int fd, unsigned char *enable); 219 | 220 | int XU_Multi_Set_BitRate(int fd, unsigned int StreamID, unsigned int BitRate); 221 | int XU_Multi_Get_BitRate(int fd, unsigned int StreamID, unsigned int *BitRate); 222 | int XU_Multi_Set_QP(int fd, unsigned int StreamID, unsigned int QP_Val); 223 | int XU_Multi_Get_QP(int fd, unsigned int StreamID, unsigned int *QP_val); 224 | int XU_Multi_Set_H264Mode(int fd, unsigned int StreamID, unsigned int Mode); 225 | int XU_Multi_Get_H264Mode(int fd, unsigned int StreamID, unsigned int *Mode); 226 | int XU_Multi_Set_SubStream_FrameRate(int fd, unsigned int sub_fps); 227 | int XU_Multi_Get_SubStream_FrameRate(int fd, unsigned int *sub_fps); 228 | int XU_Multi_Set_SubStream_GOP(int fd, unsigned int sub_gop); 229 | int XU_Multi_Get_SubStream_GOP(int fd, unsigned int *sub_gop); 230 | #endif 231 | 232 | int XU_OSD_Timer_Ctrl(int fd, unsigned char enable); 233 | int XU_OSD_Set_RTC(int fd, unsigned int year, unsigned char month, unsigned char day, unsigned char hour, unsigned char minute, unsigned char second); 234 | int XU_OSD_Get_RTC(int fd, unsigned int *year, unsigned char *month, unsigned char *day, unsigned char *hour, unsigned char *minute, unsigned char *second); 235 | 236 | int XU_OSD_Set_Size(int fd, unsigned char LineSize, unsigned char BlockSize); 237 | int XU_OSD_Get_Size(int fd, unsigned char *LineSize, unsigned char *BlockSize); 238 | 239 | int XU_OSD_Set_Color(int fd, unsigned char FontColor, unsigned char BorderColor); 240 | int XU_OSD_Get_Color(int fd, unsigned char *FontColor, unsigned char *BorderColor); 241 | 242 | int XU_OSD_Set_Enable(int fd, unsigned char Enable_Line, unsigned char Enable_Block); 243 | int XU_OSD_Get_Enable(int fd, unsigned char *Enable_Line, unsigned char *Enable_Block); 244 | 245 | int XU_OSD_Set_AutoScale(int fd, unsigned char Enable_Line, unsigned char Enable_Block); 246 | int XU_OSD_Get_AutoScale(int fd, unsigned char *Enable_Line, unsigned char *Enable_Block); 247 | 248 | int XU_OSD_Set_Start_Position(int fd, unsigned char OSD_Type, unsigned int RowStart, unsigned int ColStart); 249 | int XU_OSD_Get_Start_Position(int fd, unsigned int *LineRowStart, unsigned int *LineColStart, unsigned int *BlockRowStart, unsigned int *BlockColStart); 250 | 251 | #if(CARCAM_PROJECT == 0) 252 | int XU_OSD_Set_Multi_Size(int fd, unsigned char Stream0, unsigned char Stream1, unsigned char Stream2); 253 | int XU_OSD_Get_Multi_Size(int fd, unsigned char *Stream0, unsigned char *Stream1, unsigned char *Stream2); 254 | 255 | int XU_OSD_Set_MS_Start_Position(int fd, unsigned char StreamID, unsigned char RowStart, unsigned char ColStart); 256 | int XU_OSD_Get_MS_Start_Position(int fd, unsigned char *S0_Row, unsigned char *S0_Col, unsigned char *S1_Row, unsigned char *S1_Col, unsigned char *S2_Row, unsigned char *S2_Col); 257 | 258 | int XU_OSD_Set_String(int fd, unsigned char group, char *String); 259 | int XU_OSD_Get_String(int fd, unsigned char group, char *String); 260 | #endif 261 | 262 | int XU_MD_Set_Mode(int fd, unsigned char Enable); 263 | int XU_MD_Get_Mode(int fd, unsigned char *Enable); 264 | 265 | int XU_MD_Set_Threshold(int fd, unsigned int MD_Threshold); 266 | int XU_MD_Get_Threshold(int fd, unsigned int *MD_Threshold); 267 | 268 | int XU_MD_Set_Mask(int fd, unsigned char *Mask); 269 | int XU_MD_Get_Mask(int fd, unsigned char *Mask); 270 | 271 | int XU_MD_Set_RESULT(int fd, unsigned char *Result); 272 | int XU_MD_Get_RESULT(int fd, unsigned char *Result); 273 | 274 | int XU_MJPG_Set_Bitrate(int fd, unsigned int MJPG_Bitrate); 275 | int XU_MJPG_Get_Bitrate(int fd, unsigned int *MJPG_Bitrate); 276 | 277 | int XU_IMG_Set_Mirror(int fd, unsigned char Mirror); 278 | int XU_IMG_Get_Mirror(int fd, unsigned char *Mirror); 279 | 280 | int XU_IMG_Set_Flip(int fd, unsigned char Flip); 281 | int XU_IMG_Get_Flip(int fd, unsigned char *Flip); 282 | 283 | int XU_IMG_Set_Color(int fd, unsigned char Color); 284 | int XU_IMG_Get_Color(int fd, unsigned char *Color); 285 | // H.264 XU ----- 286 | 287 | int XU_GPIO_Ctrl_Set(int fd, unsigned char GPIO_En, unsigned char GPIO_Value); 288 | int XU_GPIO_Ctrl_Get(int fd, unsigned char *GPIO_En, unsigned char *GPIO_OutputValue, unsigned char *GPIO_InputValue); 289 | 290 | int XU_Frame_Drop_En_Set(int fd, unsigned char Stream1_En, unsigned char Stream2_En); 291 | int XU_Frame_Drop_En_Get(int fd, unsigned char *Stream1_En, unsigned char *Stream2_En); 292 | int XU_Frame_Drop_Ctrl_Set(int fd, unsigned char Stream1_fps, unsigned char Stream2_fps); 293 | int XU_Frame_Drop_Ctrl_Get(int fd, unsigned char *Stream1_fps, unsigned char *Stream2_fps); 294 | int XU_SF_Read(int fd, unsigned int Addr, unsigned char* pData,unsigned int Length); 295 | 296 | 297 | #if(CARCAM_PROJECT == 1) 298 | int XU_OSD_Set_CarcamCtrl(int fd, unsigned char SpeedEn, unsigned char CoordinateEn, unsigned char CoordinateCtrl); 299 | int XU_OSD_Get_CarcamCtrl(int fd, unsigned char *SpeedEn, unsigned char *CoordinateEn, unsigned char *CoordinateCtrl); 300 | int XU_OSD_Set_Speed(int fd, unsigned int Speed); 301 | int XU_OSD_Get_Speed(int fd, unsigned int *Speed); 302 | int XU_OSD_Set_Coordinate1(int fd, unsigned char Direction, unsigned char *Vaule); 303 | int XU_OSD_Set_Coordinate2(int fd, unsigned char Direction, unsigned char Vaule1, unsigned long Vaule2, unsigned char Vaule3, unsigned long Vaule4); 304 | int XU_OSD_Get_Coordinate1(int fd, unsigned char *Direction, unsigned char *Vaule); 305 | int XU_OSD_Get_Coordinate2(int fd, unsigned char *Direction, unsigned char *Vaule1, unsigned long *Vaule2, unsigned char *Vaule3, unsigned long *Vaule4); 306 | #endif 307 | 308 | #endif 309 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/nalu.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------// 2 | // H264 NALU c source code // 3 | //----------------------------------------------// 4 | 5 | #include 6 | #include "nalu.h" 7 | 8 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end) 9 | { 10 | unsigned char zero_cnt; 11 | zero_cnt = 0; 12 | 13 | while(1) 14 | { 15 | if(pBuf == pBuf_end) 16 | { 17 | break; 18 | } 19 | if(*pBuf == 0) 20 | { 21 | zero_cnt++; 22 | } 23 | else if((zero_cnt >= 3) && (*pBuf == 1)) 24 | { 25 | zero_cnt = 0; 26 | pBuf++; 27 | break; 28 | } 29 | else 30 | { 31 | zero_cnt = 0; 32 | } 33 | pBuf++; 34 | } 35 | return pBuf; 36 | } 37 | 38 | unsigned int Ue(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 39 | { 40 | unsigned int i=0; 41 | unsigned int nZeroNum = 0; 42 | unsigned long dwRet = 0; 43 | 44 | while((*nStartBit) < (nLen * 8)) 45 | { 46 | if(pBuff[(*nStartBit) / 8] & (0x80 >> ((*nStartBit) % 8))) 47 | break; 48 | 49 | nZeroNum++; 50 | (*nStartBit)++; 51 | } 52 | (*nStartBit) ++; 53 | 54 | for(i=0; i> ((*nStartBit) % 8))) 58 | { 59 | dwRet += 1; 60 | } 61 | (*nStartBit)++; 62 | } 63 | return (1 << nZeroNum) - 1 + dwRet; 64 | } 65 | 66 | int Se(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 67 | { 68 | #if 0 69 | int UeVal=Ue(pBuff,nLen,*nStartBit); 70 | double k=UeVal; 71 | int nValue=ceil(k/2); 72 | 73 | if(UeVal % 2==0) 74 | nValue=-nValue; 75 | 76 | return nValue; 77 | #else 78 | int UeVal=Ue(pBuff,nLen,nStartBit); 79 | int nValue = UeVal / 2; 80 | if( nValue > 0) nValue += UeVal & 0x01; 81 | if(UeVal % 2==0) 82 | nValue=-nValue; 83 | 84 | return nValue; 85 | #endif 86 | } 87 | 88 | unsigned long u(unsigned int BitCount,unsigned char * buf,unsigned int *nStartBit) 89 | { 90 | unsigned long dwRet = 0; 91 | unsigned int i = 0; 92 | 93 | for(i=0; i> ((*nStartBit) % 8))) 97 | { 98 | dwRet += 1; 99 | } 100 | (*nStartBit)++; 101 | } 102 | 103 | return dwRet; 104 | } 105 | 106 | bool h264_decode_seq_parameter_set(unsigned char * buf, unsigned int nLen, int *Width, int *Height) 107 | { 108 | unsigned int StartBit=0; 109 | int forbidden_zero_bit, nal_ref_idc, nal_unit_type; 110 | 111 | forbidden_zero_bit=u(1,buf,&StartBit); 112 | nal_ref_idc=u(2,buf,&StartBit); 113 | nal_unit_type=u(5,buf,&StartBit); 114 | 115 | if(nal_unit_type==7) 116 | { 117 | int profile_idc, constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag, reserved_zero_4bits, level_idc; 118 | int seq_parameter_set_id, log2_max_frame_num_minus4, pic_order_cnt_type; 119 | int num_ref_frames, gaps_in_frame_num_value_allowed_flag, pic_width_in_mbs_minus1, pic_height_in_map_units_minus1, frame_mbs_only_flag; 120 | int direct_8x8_inference_flag, frame_cropping_flag; 121 | int frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, frame_crop_bottom_offset; 122 | 123 | profile_idc=u(8,buf,&StartBit); 124 | constraint_set0_flag=u(1,buf,&StartBit);//(buf[1] & 0x80)>>7; 125 | constraint_set1_flag=u(1,buf,&StartBit);//(buf[1] & 0x40)>>6; 126 | constraint_set2_flag=u(1,buf,&StartBit);//(buf[1] & 0x20)>>5; 127 | constraint_set3_flag=u(1,buf,&StartBit);//(buf[1] & 0x10)>>4; 128 | reserved_zero_4bits=u(4,buf,&StartBit); 129 | level_idc=u(8,buf,&StartBit); 130 | 131 | seq_parameter_set_id=Ue(buf,nLen,&StartBit); 132 | 133 | if((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) 134 | { 135 | int chroma_format_idc, residual_colour_transform_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8, qpprime_y_zero_transform_bypass_flag; 136 | int seq_scaling_matrix_present_flag; 137 | 138 | chroma_format_idc=Ue(buf,nLen,&StartBit); 139 | residual_colour_transform_flag = 0; 140 | 141 | if(chroma_format_idc == 3) 142 | residual_colour_transform_flag=u(1,buf,&StartBit); 143 | 144 | bit_depth_luma_minus8=Ue(buf,nLen,&StartBit); 145 | bit_depth_chroma_minus8=Ue(buf,nLen,&StartBit); 146 | qpprime_y_zero_transform_bypass_flag=u(1,buf,&StartBit); 147 | seq_scaling_matrix_present_flag=u(1,buf,&StartBit); 148 | 149 | if(seq_scaling_matrix_present_flag) 150 | { 151 | int seq_scaling_list_present_flag[8]; 152 | int i=0; 153 | for( i = 0; i < 8; i++ ) 154 | { 155 | seq_scaling_list_present_flag[i]=u(1,buf,&StartBit); 156 | } 157 | } 158 | } 159 | 160 | log2_max_frame_num_minus4=Ue(buf,nLen,&StartBit); 161 | pic_order_cnt_type=Ue(buf,nLen,&StartBit); 162 | 163 | if(pic_order_cnt_type == 0) 164 | { 165 | int log2_max_pic_order_cnt_lsb_minus4=Ue(buf,nLen,&StartBit); 166 | } 167 | else if(pic_order_cnt_type == 1) 168 | { 169 | int delta_pic_order_always_zero_flag=u(1,buf,&StartBit); 170 | int offset_for_non_ref_pic=Se(buf,nLen,&StartBit); 171 | int offset_for_top_to_bottom_field=Se(buf,nLen,&StartBit); 172 | int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,nLen,&StartBit); 173 | #if 0 174 | int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle]; 175 | for(int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 176 | offset_for_ref_frame[i]=Se(buf,nLen,&StartBit); 177 | 178 | delete [] offset_for_ref_frame; 179 | #else 180 | int offset_for_ref_frame = 0; 181 | int i = 0; 182 | for(i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 183 | offset_for_ref_frame =Se(buf,nLen,&StartBit); 184 | #endif 185 | 186 | } 187 | 188 | num_ref_frames=Ue(buf,nLen,&StartBit); 189 | gaps_in_frame_num_value_allowed_flag=u(1,buf,&StartBit); 190 | pic_width_in_mbs_minus1=Ue(buf,nLen,&StartBit); 191 | pic_height_in_map_units_minus1=Ue(buf,nLen,&StartBit); 192 | 193 | frame_mbs_only_flag=u(1,buf,&StartBit); 194 | if(!frame_mbs_only_flag) 195 | { 196 | int mb_adaptive_frame_field_flag; 197 | mb_adaptive_frame_field_flag =u(1,buf,&StartBit); 198 | } 199 | direct_8x8_inference_flag=u(1,buf,&StartBit); 200 | frame_cropping_flag=u(1,buf,&StartBit); 201 | if(frame_cropping_flag == 1) 202 | { 203 | frame_crop_left_offset=Ue(buf,nLen,&StartBit); 204 | frame_crop_right_offset=Ue(buf,nLen,&StartBit); 205 | frame_crop_top_offset=Ue(buf,nLen,&StartBit); 206 | frame_crop_bottom_offset=Ue(buf,nLen,&StartBit); 207 | } 208 | else 209 | { 210 | frame_crop_left_offset=0; 211 | frame_crop_right_offset=0; 212 | frame_crop_top_offset=0; 213 | frame_crop_bottom_offset=0; 214 | } 215 | 216 | *Width=((pic_width_in_mbs_minus1+1)*16)-(frame_crop_left_offset*2)-(frame_crop_right_offset*2); 217 | *Height=((pic_height_in_map_units_minus1+1)*16)-(frame_crop_top_offset*2)-(frame_crop_bottom_offset*2); 218 | 219 | 220 | return true; 221 | } 222 | else 223 | { 224 | return false; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/nalu.h: -------------------------------------------------------------------------------- 1 | #ifndef _NALU_H_ 2 | #define _NALU_H_ 3 | 4 | #include 5 | 6 | //unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned int Buf_len); 7 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end); 8 | 9 | bool h264_decode_seq_parameter_set(unsigned char *buf, unsigned int nLen, int *Width, int *Height); 10 | 11 | #if 0 12 | //! NAL unit structure 13 | typedef struct nalu_sps 14 | { 15 | unsigned char profile_idc; 16 | unsigned constraint_set0_flag:1; 17 | unsigned constraint_set1_flag:1; 18 | unsigned constraint_set2_flag:1; 19 | unsigned constraint_set3_flag:1; 20 | unsigned reserved_zero_4bits:4; 21 | unsigned char level_idc; 22 | unsigned seq_parameter_set_id:1; 23 | unsigned log2_max_frame_num_minus4:5; 24 | } NALU_SPS; 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/v4l2uvc.c: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | # uvccapture: USB UVC Video Class Snapshot Software # 4 | #This package work with the Logitech UVC based webcams with the mjpeg feature # 5 | #. # 6 | # Orginally Copyright (C) 2005 2006 Laurent Pinchart && Michel Xhaard # 7 | # Modifications Copyright (C) 2006 Gabriel A. Devenyi # 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 as published by # 11 | # the Free Software Foundation; either version 2 of the License, or # 12 | # (at your option) any later version. # 13 | # # 14 | # This program is distributed in the hope that it will be useful, # 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 17 | # GNU General Public License for more details. # 18 | # # 19 | # You should have received a copy of the GNU General Public License # 20 | # along with this program; if not, write to the Free Software # 21 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # 22 | # # 23 | *******************************************************************************/ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "v4l2uvc.h" 35 | #include "debug.h" 36 | 37 | static int debug = 0; 38 | 39 | static unsigned char dht_data[DHT_SIZE] = { 40 | 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 41 | 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 42 | 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, 43 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 45 | 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 46 | 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 47 | 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 48 | 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 49 | 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 50 | 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 51 | 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 52 | 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 53 | 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 54 | 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 55 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 56 | 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 57 | 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 58 | 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 59 | 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 60 | 0xfa, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 61 | 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 62 | 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 63 | 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 64 | 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 65 | 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 66 | 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 67 | 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 68 | 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 69 | 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 70 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 71 | 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 72 | 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 73 | 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 74 | 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa 75 | }; 76 | 77 | static int init_v4l2 (struct vdIn *vd); 78 | 79 | int 80 | init_videoIn (struct vdIn *vd, char *device, int width, int height, 81 | int format, int grabmethod) 82 | { 83 | 84 | if (vd == NULL || device == NULL) 85 | return -1; 86 | if (width == 0 || height == 0) 87 | return -1; 88 | if (grabmethod < 0 || grabmethod > 1) 89 | grabmethod = 1; //mmap by default; 90 | vd->videodevice = NULL; 91 | vd->status = NULL; 92 | vd->pictName = NULL; 93 | vd->videodevice = (char *) calloc (1, 16 * sizeof (char)); 94 | vd->status = (char *) calloc (1, 100 * sizeof (char)); 95 | vd->pictName = (char *) calloc (1, 80 * sizeof (char)); 96 | snprintf (vd->videodevice, 12, "%s", device); 97 | vd->toggleAvi = 0; 98 | vd->getPict = 0; 99 | vd->signalquit = 1; 100 | vd->width = width; 101 | vd->height = height; 102 | vd->formatIn = format; 103 | vd->grabmethod = grabmethod; 104 | if (init_v4l2 (vd) < 0) { 105 | TestAp_Printf(TESTAP_DBG_ERR, " Init v4L2 failed !! exit fatal \n"); 106 | goto error;; 107 | } 108 | /* alloc a temp buffer to reconstruct the pict */ 109 | vd->framesizeIn = (vd->width * vd->height << 1); 110 | switch (vd->formatIn) { 111 | case V4L2_PIX_FMT_MJPEG: 112 | vd->tmpbuffer = (unsigned char *) calloc (1, (size_t) vd->framesizeIn); 113 | if (!vd->tmpbuffer) 114 | goto error; 115 | vd->framebuffer = 116 | (unsigned char *) calloc (1, (size_t) vd->width * (vd->height + 8) * 2); 117 | break; 118 | case V4L2_PIX_FMT_YUYV: 119 | vd->framebuffer = (unsigned char *) calloc (1, (size_t) vd->framesizeIn); 120 | break; 121 | default: 122 | TestAp_Printf(TESTAP_DBG_ERR, " should never arrive exit fatal !!\n"); 123 | goto error; 124 | break; 125 | } 126 | if (!vd->framebuffer) 127 | goto error; 128 | return 0; 129 | error: 130 | free (vd->videodevice); 131 | free (vd->status); 132 | free (vd->pictName); 133 | close (vd->fd); 134 | return -1; 135 | } 136 | 137 | static int 138 | init_v4l2 (struct vdIn *vd) 139 | { 140 | int i; 141 | int ret = 0; 142 | 143 | if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1) { 144 | perror ("ERROR opening V4L interface \n"); 145 | exit (1); 146 | } 147 | memset (&vd->cap, 0, sizeof (struct v4l2_capability)); 148 | ret = ioctl (vd->fd, VIDIOC_QUERYCAP, &vd->cap); 149 | if (ret < 0) { 150 | TestAp_Printf(TESTAP_DBG_ERR, "Error opening device %s: unable to query device.\n", 151 | vd->videodevice); 152 | goto fatal; 153 | } 154 | 155 | if ((vd->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { 156 | TestAp_Printf(TESTAP_DBG_ERR, "Error opening device %s: video capture not supported.\n", 157 | vd->videodevice); 158 | goto fatal; 159 | } 160 | if (vd->grabmethod) { 161 | if (!(vd->cap.capabilities & V4L2_CAP_STREAMING)) { 162 | TestAp_Printf(TESTAP_DBG_ERR, "%s does not support streaming i/o\n", 163 | vd->videodevice); 164 | goto fatal; 165 | } 166 | } else { 167 | if (!(vd->cap.capabilities & V4L2_CAP_READWRITE)) { 168 | TestAp_Printf(TESTAP_DBG_ERR, "%s does not support read i/o\n", vd->videodevice); 169 | goto fatal; 170 | } 171 | } 172 | /* set format in */ 173 | memset (&vd->fmt, 0, sizeof (struct v4l2_format)); 174 | vd->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 175 | vd->fmt.fmt.pix.width = vd->width; 176 | vd->fmt.fmt.pix.height = vd->height; 177 | vd->fmt.fmt.pix.pixelformat = vd->formatIn; 178 | vd->fmt.fmt.pix.field = V4L2_FIELD_ANY; 179 | ret = ioctl (vd->fd, VIDIOC_S_FMT, &vd->fmt); 180 | if (ret < 0) { 181 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to set format: %d.\n", errno); 182 | goto fatal; 183 | } 184 | if ((vd->fmt.fmt.pix.width != vd->width) || 185 | (vd->fmt.fmt.pix.height != vd->height)) { 186 | TestAp_Printf(TESTAP_DBG_ERR, " format asked unavailable get width %d height %d \n", 187 | vd->fmt.fmt.pix.width, vd->fmt.fmt.pix.height); 188 | vd->width = vd->fmt.fmt.pix.width; 189 | vd->height = vd->fmt.fmt.pix.height; 190 | /* look the format is not part of the deal ??? */ 191 | //vd->formatIn = vd->fmt.fmt.pix.pixelformat; 192 | } 193 | /* request buffers */ 194 | memset (&vd->rb, 0, sizeof (struct v4l2_requestbuffers)); 195 | vd->rb.count = NB_BUFFER; 196 | vd->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 197 | vd->rb.memory = V4L2_MEMORY_MMAP; 198 | 199 | ret = ioctl (vd->fd, VIDIOC_REQBUFS, &vd->rb); 200 | if (ret < 0) { 201 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to allocate buffers: %d.\n", errno); 202 | goto fatal; 203 | } 204 | /* map the buffers */ 205 | for (i = 0; i < NB_BUFFER; i++) { 206 | memset (&vd->buf, 0, sizeof (struct v4l2_buffer)); 207 | vd->buf.index = i; 208 | vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 209 | vd->buf.memory = V4L2_MEMORY_MMAP; 210 | ret = ioctl (vd->fd, VIDIOC_QUERYBUF, &vd->buf); 211 | if (ret < 0) { 212 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to query buffer (%d).\n", errno); 213 | goto fatal; 214 | } 215 | if (debug) 216 | TestAp_Printf(TESTAP_DBG_FLOW, "length: %u offset: %u\n", vd->buf.length, 217 | vd->buf.m.offset); 218 | vd->mem[i] = mmap (0 /* start anywhere */ , 219 | vd->buf.length, PROT_READ, MAP_SHARED, vd->fd, 220 | vd->buf.m.offset); 221 | if (vd->mem[i] == MAP_FAILED) { 222 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to map buffer (%d)\n", errno); 223 | goto fatal; 224 | } 225 | if (debug) 226 | TestAp_Printf(TESTAP_DBG_FLOW, "Buffer mapped at address %p.\n", vd->mem[i]); 227 | } 228 | /* Queue the buffers. */ 229 | for (i = 0; i < NB_BUFFER; ++i) { 230 | memset (&vd->buf, 0, sizeof (struct v4l2_buffer)); 231 | vd->buf.index = i; 232 | vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 233 | vd->buf.memory = V4L2_MEMORY_MMAP; 234 | ret = ioctl (vd->fd, VIDIOC_QBUF, &vd->buf); 235 | if (ret < 0) { 236 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to queue buffer (%d).\n", errno); 237 | goto fatal;; 238 | } 239 | } 240 | return 0; 241 | fatal: 242 | return -1; 243 | 244 | } 245 | 246 | static int 247 | video_enable (struct vdIn *vd) 248 | { 249 | int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 250 | int ret; 251 | 252 | ret = ioctl (vd->fd, VIDIOC_STREAMON, &type); 253 | if (ret < 0) { 254 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to %s capture: %d.\n", "start", errno); 255 | return ret; 256 | } 257 | vd->isstreaming = 1; 258 | return 0; 259 | } 260 | 261 | static int 262 | video_disable (struct vdIn *vd) 263 | { 264 | int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 265 | int ret; 266 | 267 | ret = ioctl (vd->fd, VIDIOC_STREAMOFF, &type); 268 | if (ret < 0) { 269 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to %s capture: %d.\n", "stop", errno); 270 | return ret; 271 | } 272 | vd->isstreaming = 0; 273 | return 0; 274 | } 275 | 276 | int 277 | uvcGrab (struct vdIn *vd) 278 | { 279 | #define HEADERFRAME1 0xaf 280 | int ret; 281 | 282 | if (!vd->isstreaming) 283 | if (video_enable (vd)) 284 | goto err; 285 | memset (&vd->buf, 0, sizeof (struct v4l2_buffer)); 286 | vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 287 | vd->buf.memory = V4L2_MEMORY_MMAP; 288 | ret = ioctl (vd->fd, VIDIOC_DQBUF, &vd->buf); 289 | if (ret < 0) { 290 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to dequeue buffer (%d).\n", errno); 291 | goto err; 292 | } 293 | switch (vd->formatIn) { 294 | case V4L2_PIX_FMT_MJPEG: 295 | 296 | memcpy (vd->tmpbuffer, vd->mem[vd->buf.index], HEADERFRAME1); 297 | memcpy (vd->tmpbuffer + HEADERFRAME1, dht_data, DHT_SIZE); 298 | memcpy (vd->tmpbuffer + HEADERFRAME1 + DHT_SIZE, 299 | vd->mem[vd->buf.index] + HEADERFRAME1, 300 | (vd->buf.bytesused - HEADERFRAME1)); 301 | if (debug) 302 | TestAp_Printf(TESTAP_DBG_FLOW, "bytes in used %d \n", vd->buf.bytesused); 303 | break; 304 | case V4L2_PIX_FMT_YUYV: 305 | if (vd->buf.bytesused > vd->framesizeIn) 306 | memcpy (vd->framebuffer, vd->mem[vd->buf.index], 307 | (size_t) vd->framesizeIn); 308 | else 309 | memcpy (vd->framebuffer, vd->mem[vd->buf.index], 310 | (size_t) vd->buf.bytesused); 311 | break; 312 | default: 313 | goto err; 314 | break; 315 | } 316 | ret = ioctl (vd->fd, VIDIOC_QBUF, &vd->buf); 317 | if (ret < 0) { 318 | TestAp_Printf(TESTAP_DBG_ERR, "Unable to requeue buffer (%d).\n", errno); 319 | goto err; 320 | } 321 | 322 | return 0; 323 | err: 324 | vd->signalquit = 0; 325 | return -1; 326 | } 327 | 328 | int 329 | close_v4l2 (struct vdIn *vd) 330 | { 331 | int i; 332 | 333 | if (vd->isstreaming) 334 | video_disable (vd); 335 | 336 | /* If the memory maps are not released the device will remain opened even 337 | after a call to close(); */ 338 | for (i = 0; i < NB_BUFFER; i++) { 339 | munmap (vd->mem[i], vd->buf.length); 340 | } 341 | 342 | if (vd->tmpbuffer) 343 | free (vd->tmpbuffer); 344 | vd->tmpbuffer = NULL; 345 | free (vd->framebuffer); 346 | vd->framebuffer = NULL; 347 | free (vd->videodevice); 348 | free (vd->status); 349 | free (vd->pictName); 350 | vd->videodevice = NULL; 351 | vd->status = NULL; 352 | vd->pictName = NULL; 353 | close (vd->fd); 354 | return 0; 355 | } 356 | 357 | /* return >= 0 ok otherwhise -1 */ 358 | static int 359 | isv4l2Control (int fd, int control, struct v4l2_queryctrl *queryctrl) 360 | { 361 | int err = 0; 362 | 363 | queryctrl->id = control; 364 | if ((err = ioctl (fd, VIDIOC_QUERYCTRL, queryctrl)) < 0) { 365 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl querycontrol error %d \n", errno); 366 | } else if (queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) { 367 | TestAp_Printf(TESTAP_DBG_ERR, "control %s disabled \n", (char *) queryctrl->name); 368 | } else if (queryctrl->type & V4L2_CTRL_TYPE_BOOLEAN) { 369 | return 1; 370 | } else if (queryctrl->type & V4L2_CTRL_TYPE_INTEGER) { 371 | return 0; 372 | } else { 373 | TestAp_Printf(TESTAP_DBG_ERR, "contol %s unsupported \n", (char *) queryctrl->name); 374 | } 375 | return -1; 376 | } 377 | 378 | int 379 | v4l2GetControl (int fd, int control) 380 | { 381 | struct v4l2_queryctrl queryctrl; 382 | struct v4l2_control control_s; 383 | int err; 384 | 385 | if (isv4l2Control (fd, control, &queryctrl) < 0) 386 | return -1; 387 | control_s.id = control; 388 | if ((err = ioctl (fd, VIDIOC_G_CTRL, &control_s)) < 0) { 389 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl get control error\n"); 390 | return -1; 391 | } 392 | return control_s.value; 393 | } 394 | 395 | int 396 | v4l2SetControl (int fd, int control, int value) 397 | { 398 | struct v4l2_control control_s; 399 | struct v4l2_queryctrl queryctrl; 400 | int min, max, step, val_def; 401 | int err; 402 | 403 | if (isv4l2Control (fd, control, &queryctrl) < 0) 404 | return -1; 405 | min = queryctrl.minimum; 406 | max = queryctrl.maximum; 407 | step = queryctrl.step; 408 | val_def = queryctrl.default_value; 409 | if ((value >= min) && (value <= max)) { 410 | control_s.id = control; 411 | control_s.value = value; 412 | if ((err = ioctl (fd, VIDIOC_S_CTRL, &control_s)) < 0) { 413 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl set control error\n"); 414 | return -1; 415 | } 416 | } 417 | return 0; 418 | } 419 | 420 | int v4l2UpControl (int fd, int control) 421 | { 422 | struct v4l2_control control_s; 423 | struct v4l2_queryctrl queryctrl; 424 | int min, max, current, step, val_def; 425 | int err; 426 | 427 | if (isv4l2Control (fd, control, &queryctrl) < 0) 428 | return -1; 429 | min = queryctrl.minimum; 430 | max = queryctrl.maximum; 431 | step = queryctrl.step; 432 | val_def = queryctrl.default_value; 433 | current = v4l2GetControl (fd, control); 434 | current += step; 435 | if (current <= max) { 436 | control_s.id = control; 437 | control_s.value = current; 438 | if ((err = ioctl (fd, VIDIOC_S_CTRL, &control_s)) < 0) { 439 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl set control error\n"); 440 | return -1; 441 | } 442 | } 443 | return control_s.value; 444 | } 445 | 446 | int 447 | v4l2DownControl (int fd, int control) 448 | { 449 | struct v4l2_control control_s; 450 | struct v4l2_queryctrl queryctrl; 451 | int min, max, current, step, val_def; 452 | int err; 453 | 454 | if (isv4l2Control (fd, control, &queryctrl) < 0) 455 | return -1; 456 | min = queryctrl.minimum; 457 | max = queryctrl.maximum; 458 | step = queryctrl.step; 459 | val_def = queryctrl.default_value; 460 | current = v4l2GetControl (fd, control); 461 | current -= step; 462 | if (current >= min) { 463 | control_s.id = control; 464 | control_s.value = current; 465 | if ((err = ioctl (fd, VIDIOC_S_CTRL, &control_s)) < 0) { 466 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl set control error\n"); 467 | return -1; 468 | } 469 | } 470 | return control_s.value; 471 | } 472 | 473 | int 474 | v4l2ToggleControl (int fd, int control) 475 | { 476 | struct v4l2_control control_s; 477 | struct v4l2_queryctrl queryctrl; 478 | int current; 479 | int err; 480 | 481 | if (isv4l2Control (fd, control, &queryctrl) != 1) 482 | return -1; 483 | current = v4l2GetControl (fd, control); 484 | control_s.id = control; 485 | control_s.value = !current; 486 | if ((err = ioctl (fd, VIDIOC_S_CTRL, &control_s)) < 0) { 487 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl toggle control error\n"); 488 | return -1; 489 | } 490 | return control_s.value; 491 | } 492 | 493 | int 494 | v4l2ResetControl (int fd, int control) 495 | { 496 | struct v4l2_control control_s; 497 | struct v4l2_queryctrl queryctrl; 498 | int val_def; 499 | int err; 500 | 501 | if (isv4l2Control (fd, control, &queryctrl) < 0) 502 | return -1; 503 | val_def = queryctrl.default_value; 504 | control_s.id = control; 505 | control_s.value = val_def; 506 | if ((err = ioctl (fd, VIDIOC_S_CTRL, &control_s)) < 0) { 507 | TestAp_Printf(TESTAP_DBG_ERR, "ioctl reset control error\n"); 508 | return -1; 509 | } 510 | 511 | return 0; 512 | } 513 | -------------------------------------------------------------------------------- /Linux_UVC_TestAP/v4l2uvc.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | # uvccapture: USB UVC Video Class Snapshot Software # 4 | #This package work with the Logitech UVC based webcams with the mjpeg feature # 5 | # # 6 | # Orginally Copyright (C) 2005 2006 Laurent Pinchart && Michel Xhaard # 7 | # Modifications Copyright (C) 2006 Gabriel A. Devenyi # 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 as published by # 11 | # the Free Software Foundation; either version 2 of the License, or # 12 | # (at your option) any later version. # 13 | # # 14 | # This program is distributed in the hope that it will be useful, # 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 17 | # GNU General Public License for more details. # 18 | # # 19 | # You should have received a copy of the GNU General Public License # 20 | # along with this program; if not, write to the Free Software # 21 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # 22 | # # 23 | *******************************************************************************/ 24 | 25 | #define NB_BUFFER 16 26 | #define DHT_SIZE 420 27 | 28 | #ifndef V4L2_CID_SHARPNESS 29 | #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) 30 | #endif 31 | 32 | struct vdIn { 33 | int fd; 34 | char *videodevice; 35 | char *status; 36 | char *pictName; 37 | struct v4l2_capability cap; 38 | struct v4l2_format fmt; 39 | struct v4l2_buffer buf; 40 | struct v4l2_requestbuffers rb; 41 | void *mem[NB_BUFFER]; 42 | unsigned char *tmpbuffer; 43 | unsigned char *framebuffer; 44 | int isstreaming; 45 | int grabmethod; 46 | int width; 47 | int height; 48 | int formatIn; 49 | int formatOut; 50 | int framesizeIn; 51 | int signalquit; 52 | int toggleAvi; 53 | int getPict; 54 | 55 | }; 56 | 57 | int 58 | init_videoIn (struct vdIn *vd, char *device, int width, int height, 59 | int format, int grabmethod); 60 | int uvcGrab (struct vdIn *vd); 61 | int close_v4l2 (struct vdIn *vd); 62 | 63 | int v4l2GetControl (int fd, int control); 64 | int v4l2SetControl (int fd, int control, int value); 65 | int v4l2UpControl (int fd, int control); 66 | int v4l2DownControl (int fd, int control); 67 | int v4l2ToggleControl (int fd, int control); 68 | int v4l2ResetControl (int fd, int control); 69 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/Kconfig: -------------------------------------------------------------------------------- 1 | config USB_VIDEO_CLASS_H264 2 | tristate "USB Video Class (UVC)" 3 | ---help--- 4 | Support for the RERVISION H264 USB Video Class (UVC). Currently only H264 USB Camera, 5 | such as RER-USB100W04H, are supported. 6 | 7 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/Makefile_Embedded: -------------------------------------------------------------------------------- 1 | uvcvideo_h264-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_debugfs.o uvc_ctrl.o \ 2 | uvc_status.o uvc_isight.o nalu.o 3 | 4 | obj-$(CONFIG_USB_VIDEO_CLASS_H264) += uvcvideo_h264.o 5 | 6 | 7 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/Makefile_PC: -------------------------------------------------------------------------------- 1 | KERNELDIR ?= /lib/modules/`uname -r`/build 2 | PWD := $(shell pwd) 3 | INSTALLDIR ?= ../ 4 | CROSS_COMPILE ?= 5 | CC ?= $(CROSS_COMPILE)gcc 6 | 7 | MODULE_NAME := uvcvideo_h264 8 | RESMAIN_CORE_OBJS := uvc_driver.o 9 | RESMAIN_GLUE_OBJS := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o uvc_status.o uvc_isight.o nalu.o 10 | $(MODULE_NAME)-objs := $(RESMAIN_CORE_OBJS) $(RESMAIN_GLUE_OBJS) 11 | obj-m := uvcvideo_h264.o 12 | 13 | all: 14 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 15 | 16 | install: all 17 | cp *.ko $(INSTALLDIR) 18 | 19 | clean: 20 | rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.markers *.symvers *.order 21 | 22 | .PHONY: 23 | modules modules_install clean 24 | 25 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/nalu.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------// 2 | // H264 NALU c source code // 3 | //----------------------------------------------// 4 | 5 | #include 6 | #include "nalu.h" 7 | 8 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end) 9 | { 10 | unsigned char zero_cnt; 11 | zero_cnt = 0; 12 | 13 | while(1) 14 | { 15 | if(pBuf == pBuf_end) 16 | { 17 | break; 18 | } 19 | if(*pBuf == 0) 20 | { 21 | zero_cnt++; 22 | } 23 | else if((zero_cnt >= 3) && (*pBuf == 1)) 24 | { 25 | zero_cnt = 0; 26 | pBuf++; 27 | break; 28 | } 29 | else 30 | { 31 | zero_cnt = 0; 32 | } 33 | pBuf++; 34 | } 35 | return pBuf; 36 | } 37 | 38 | unsigned int Ue(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 39 | { 40 | unsigned int i=0; 41 | unsigned int nZeroNum = 0; 42 | unsigned long dwRet = 0; 43 | 44 | while((*nStartBit) < (nLen * 8)) 45 | { 46 | if(pBuff[(*nStartBit) / 8] & (0x80 >> ((*nStartBit) % 8))) 47 | break; 48 | 49 | nZeroNum++; 50 | (*nStartBit)++; 51 | } 52 | (*nStartBit) ++; 53 | 54 | for(i=0; i> ((*nStartBit) % 8))) 58 | { 59 | dwRet += 1; 60 | } 61 | (*nStartBit)++; 62 | } 63 | return (1 << nZeroNum) - 1 + dwRet; 64 | } 65 | 66 | int Se(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 67 | { 68 | #if 0 69 | int UeVal=Ue(pBuff,nLen,*nStartBit); 70 | double k=UeVal; 71 | int nValue=ceil(k/2); 72 | 73 | if(UeVal % 2==0) 74 | nValue=-nValue; 75 | 76 | return nValue; 77 | #else 78 | int UeVal=Ue(pBuff,nLen,nStartBit); 79 | int nValue = UeVal / 2; 80 | if( nValue > 0) nValue += UeVal & 0x01; 81 | if(UeVal % 2==0) 82 | nValue=-nValue; 83 | 84 | return nValue; 85 | #endif 86 | } 87 | 88 | unsigned long u(unsigned int BitCount,unsigned char * buf,unsigned int *nStartBit) 89 | { 90 | unsigned long dwRet = 0; 91 | unsigned int i = 0; 92 | 93 | for(i=0; i> ((*nStartBit) % 8))) 97 | { 98 | dwRet += 1; 99 | } 100 | (*nStartBit)++; 101 | } 102 | 103 | return dwRet; 104 | } 105 | 106 | bool h264_decode_seq_parameter_set(unsigned char * buf, unsigned int nLen, int *Width, int *Height) 107 | { 108 | unsigned int StartBit=0; 109 | int forbidden_zero_bit, nal_ref_idc, nal_unit_type; 110 | 111 | forbidden_zero_bit=u(1,buf,&StartBit); 112 | nal_ref_idc=u(2,buf,&StartBit); 113 | nal_unit_type=u(5,buf,&StartBit); 114 | 115 | if(nal_unit_type==7) 116 | { 117 | int profile_idc, constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag, reserved_zero_4bits, level_idc; 118 | int seq_parameter_set_id, log2_max_frame_num_minus4, pic_order_cnt_type; 119 | int num_ref_frames, gaps_in_frame_num_value_allowed_flag, pic_width_in_mbs_minus1, pic_height_in_map_units_minus1; 120 | 121 | profile_idc=u(8,buf,&StartBit); 122 | constraint_set0_flag=u(1,buf,&StartBit);//(buf[1] & 0x80)>>7; 123 | constraint_set1_flag=u(1,buf,&StartBit);//(buf[1] & 0x40)>>6; 124 | constraint_set2_flag=u(1,buf,&StartBit);//(buf[1] & 0x20)>>5; 125 | constraint_set3_flag=u(1,buf,&StartBit);//(buf[1] & 0x10)>>4; 126 | reserved_zero_4bits=u(4,buf,&StartBit); 127 | level_idc=u(8,buf,&StartBit); 128 | 129 | seq_parameter_set_id=Ue(buf,nLen,&StartBit); 130 | 131 | if((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) 132 | { 133 | int chroma_format_idc, residual_colour_transform_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8, qpprime_y_zero_transform_bypass_flag; 134 | int seq_scaling_matrix_present_flag; 135 | 136 | chroma_format_idc=Ue(buf,nLen,&StartBit); 137 | residual_colour_transform_flag = 0; 138 | 139 | if(chroma_format_idc == 3) 140 | residual_colour_transform_flag=u(1,buf,&StartBit); 141 | 142 | bit_depth_luma_minus8=Ue(buf,nLen,&StartBit); 143 | bit_depth_chroma_minus8=Ue(buf,nLen,&StartBit); 144 | qpprime_y_zero_transform_bypass_flag=u(1,buf,&StartBit); 145 | seq_scaling_matrix_present_flag=u(1,buf,&StartBit); 146 | 147 | if(seq_scaling_matrix_present_flag) 148 | { 149 | int seq_scaling_list_present_flag[8]; 150 | int i=0; 151 | for( i = 0; i < 8; i++ ) 152 | { 153 | seq_scaling_list_present_flag[i]=u(1,buf,&StartBit); 154 | } 155 | } 156 | } 157 | 158 | log2_max_frame_num_minus4=Ue(buf,nLen,&StartBit); 159 | pic_order_cnt_type=Ue(buf,nLen,&StartBit); 160 | 161 | if(pic_order_cnt_type == 0) 162 | { 163 | int log2_max_pic_order_cnt_lsb_minus4=Ue(buf,nLen,&StartBit); 164 | } 165 | else if(pic_order_cnt_type == 1) 166 | { 167 | int delta_pic_order_always_zero_flag=u(1,buf,&StartBit); 168 | int offset_for_non_ref_pic=Se(buf,nLen,&StartBit); 169 | int offset_for_top_to_bottom_field=Se(buf,nLen,&StartBit); 170 | int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,nLen,&StartBit); 171 | #if 0 172 | int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle]; 173 | for(int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 174 | offset_for_ref_frame[i]=Se(buf,nLen,&StartBit); 175 | 176 | delete [] offset_for_ref_frame; 177 | #else 178 | int offset_for_ref_frame = 0; 179 | int i = 0; 180 | for(i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 181 | offset_for_ref_frame =Se(buf,nLen,&StartBit); 182 | #endif 183 | 184 | } 185 | 186 | num_ref_frames=Ue(buf,nLen,&StartBit); 187 | gaps_in_frame_num_value_allowed_flag=u(1,buf,&StartBit); 188 | pic_width_in_mbs_minus1=Ue(buf,nLen,&StartBit); 189 | pic_height_in_map_units_minus1=Ue(buf,nLen,&StartBit); 190 | 191 | *Width=(pic_width_in_mbs_minus1+1)*16; 192 | *Height=(pic_height_in_map_units_minus1+1)*16; 193 | 194 | return true; 195 | } 196 | else 197 | { 198 | return false; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/nalu.h: -------------------------------------------------------------------------------- 1 | #ifndef _NALU_H_ 2 | #define _NALU_H_ 3 | 4 | #include 5 | 6 | //unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned int Buf_len); 7 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end); 8 | 9 | bool h264_decode_seq_parameter_set(unsigned char *buf, unsigned int nLen, int *Width, int *Height); 10 | 11 | #if 0 12 | //! NAL unit structure 13 | typedef struct nalu_sps 14 | { 15 | unsigned char profile_idc; 16 | unsigned constraint_set0_flag:1; 17 | unsigned constraint_set1_flag:1; 18 | unsigned constraint_set2_flag:1; 19 | unsigned constraint_set3_flag:1; 20 | unsigned reserved_zero_4bits:4; 21 | unsigned char level_idc; 22 | unsigned seq_parameter_set_id:1; 23 | unsigned log2_max_frame_num_minus4:5; 24 | } NALU_SPS; 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/uvc_isight.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_isight.c -- USB Video Class driver - iSight support 3 | * 4 | * Copyright (C) 2006-2007 5 | * Ivan N. Zlatev 6 | * Copyright (C) 2008-2009 7 | * Laurent Pinchart 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 as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "uvcvideo.h" 21 | 22 | /* Built-in iSight webcams implements most of UVC 1.0 except a 23 | * different packet format. Instead of sending a header at the 24 | * beginning of each isochronous transfer payload, the webcam sends a 25 | * single header per image (on its own in a packet), followed by 26 | * packets containing data only. 27 | * 28 | * Offset Size (bytes) Description 29 | * ------------------------------------------------------------------ 30 | * 0x00 1 Header length 31 | * 0x01 1 Flags (UVC-compliant) 32 | * 0x02 4 Always equal to '11223344' 33 | * 0x06 8 Always equal to 'deadbeefdeadface' 34 | * 0x0e 16 Unknown 35 | * 36 | * The header can be prefixed by an optional, unknown-purpose byte. 37 | */ 38 | 39 | static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, 40 | const __u8 *data, unsigned int len) 41 | { 42 | static const __u8 hdr[] = { 43 | 0x11, 0x22, 0x33, 0x44, 44 | 0xde, 0xad, 0xbe, 0xef, 45 | 0xde, 0xad, 0xfa, 0xce 46 | }; 47 | 48 | unsigned int maxlen, nbytes; 49 | __u8 *mem; 50 | int is_header = 0; 51 | 52 | if (buf == NULL) 53 | return 0; 54 | 55 | if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) || 56 | (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) { 57 | uvc_trace(UVC_TRACE_FRAME, "iSight header found\n"); 58 | is_header = 1; 59 | } 60 | 61 | /* Synchronize to the input stream by waiting for a header packet. */ 62 | if (buf->state != UVC_BUF_STATE_ACTIVE) { 63 | if (!is_header) { 64 | uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of " 65 | "sync).\n"); 66 | return 0; 67 | } 68 | 69 | buf->state = UVC_BUF_STATE_ACTIVE; 70 | } 71 | 72 | /* Mark the buffer as done if we're at the beginning of a new frame. 73 | * 74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection 75 | * as it doesn't make sense to return an empty buffer. 76 | */ 77 | if (is_header && buf->buf.bytesused != 0) { 78 | buf->state = UVC_BUF_STATE_DONE; 79 | return -EAGAIN; 80 | } 81 | 82 | /* Copy the video data to the buffer. Skip header packets, as they 83 | * contain no data. 84 | */ 85 | if (!is_header) { 86 | maxlen = buf->buf.length - buf->buf.bytesused; 87 | mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; 88 | nbytes = min(len, maxlen); 89 | memcpy(mem, data, nbytes); 90 | buf->buf.bytesused += nbytes; 91 | 92 | if (len > maxlen || buf->buf.bytesused == buf->buf.length) { 93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " 94 | "(overflow).\n"); 95 | buf->state = UVC_BUF_STATE_DONE; 96 | } 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, 103 | struct uvc_buffer *buf) 104 | { 105 | int ret, i; 106 | 107 | for (i = 0; i < urb->number_of_packets; ++i) { 108 | if (urb->iso_frame_desc[i].status < 0) { 109 | uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame " 110 | "lost (%d).\n", 111 | urb->iso_frame_desc[i].status); 112 | } 113 | 114 | /* Decode the payload packet. 115 | * uvc_video_decode is entered twice when a frame transition 116 | * has been detected because the end of frame can only be 117 | * reliably detected when the first packet of the new frame 118 | * is processed. The first pass detects the transition and 119 | * closes the previous frame's buffer, the second pass 120 | * processes the data of the first payload of the new frame. 121 | */ 122 | do { 123 | ret = isight_decode(&stream->queue, buf, 124 | urb->transfer_buffer + 125 | urb->iso_frame_desc[i].offset, 126 | urb->iso_frame_desc[i].actual_length); 127 | 128 | if (buf == NULL) 129 | break; 130 | 131 | if (buf->state == UVC_BUF_STATE_DONE || 132 | buf->state == UVC_BUF_STATE_ERROR) 133 | buf = uvc_queue_next_buffer(&stream->queue, 134 | buf); 135 | } while (ret == -EAGAIN); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/uvc_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_queue.c -- USB Video Class driver - Buffers management 3 | * 4 | * Copyright (C) 2005-2009 5 | * Laurent Pinchart (laurent.pinchart@skynet.be) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "uvcvideo.h" 25 | 26 | /* ------------------------------------------------------------------------ 27 | * Video buffers queue management. 28 | * 29 | * Video queues is initialized by uvc_queue_init(). The function performs 30 | * basic initialization of the uvc_video_queue struct and never fails. 31 | * 32 | * Video buffer allocation and freeing are performed by uvc_alloc_buffers and 33 | * uvc_free_buffers respectively. The former acquires the video queue lock, 34 | * while the later must be called with the lock held (so that allocation can 35 | * free previously allocated buffers). Trying to free buffers that are mapped 36 | * to user space will return -EBUSY. 37 | * 38 | * Video buffers are managed using two queues. However, unlike most USB video 39 | * drivers that use an in queue and an out queue, we use a main queue to hold 40 | * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to 41 | * hold empty buffers. This design (copied from video-buf) minimizes locking 42 | * in interrupt, as only one queue is shared between interrupt and user 43 | * contexts. 44 | * 45 | * Use cases 46 | * --------- 47 | * 48 | * Unless stated otherwise, all operations that modify the irq buffers queue 49 | * are protected by the irq spinlock. 50 | * 51 | * 1. The user queues the buffers, starts streaming and dequeues a buffer. 52 | * 53 | * The buffers are added to the main and irq queues. Both operations are 54 | * protected by the queue lock, and the later is protected by the irq 55 | * spinlock as well. 56 | * 57 | * The completion handler fetches a buffer from the irq queue and fills it 58 | * with video data. If no buffer is available (irq queue empty), the handler 59 | * returns immediately. 60 | * 61 | * When the buffer is full, the completion handler removes it from the irq 62 | * queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue. 63 | * At that point, any process waiting on the buffer will be woken up. If a 64 | * process tries to dequeue a buffer after it has been marked done, the 65 | * dequeing will succeed immediately. 66 | * 67 | * 2. Buffers are queued, user is waiting on a buffer and the device gets 68 | * disconnected. 69 | * 70 | * When the device is disconnected, the kernel calls the completion handler 71 | * with an appropriate status code. The handler marks all buffers in the 72 | * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so 73 | * that any process waiting on a buffer gets woken up. 74 | * 75 | * Waking up up the first buffer on the irq list is not enough, as the 76 | * process waiting on the buffer might restart the dequeue operation 77 | * immediately. 78 | * 79 | */ 80 | 81 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type) 82 | { 83 | mutex_init(&queue->mutex); 84 | spin_lock_init(&queue->irqlock); 85 | INIT_LIST_HEAD(&queue->mainqueue); 86 | INIT_LIST_HEAD(&queue->irqqueue); 87 | queue->type = type; 88 | } 89 | 90 | /* 91 | * Allocate the video buffers. 92 | * 93 | * Pages are reserved to make sure they will not be swapped, as they will be 94 | * filled in the URB completion handler. 95 | * 96 | * Buffers will be individually mapped, so they must all be page aligned. 97 | */ 98 | int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, 99 | unsigned int buflength) 100 | { 101 | unsigned int bufsize = PAGE_ALIGN(buflength); 102 | unsigned int i; 103 | void *mem = NULL; 104 | int ret; 105 | 106 | if (nbuffers > UVC_MAX_VIDEO_BUFFERS) 107 | nbuffers = UVC_MAX_VIDEO_BUFFERS; 108 | 109 | mutex_lock(&queue->mutex); 110 | 111 | if ((ret = uvc_free_buffers(queue)) < 0) 112 | goto done; 113 | 114 | /* Bail out if no buffers should be allocated. */ 115 | if (nbuffers == 0) 116 | goto done; 117 | 118 | /* Decrement the number of buffers until allocation succeeds. */ 119 | for (; nbuffers > 0; --nbuffers) { 120 | mem = vmalloc_32(nbuffers * bufsize); 121 | if (mem != NULL) 122 | break; 123 | } 124 | 125 | if (mem == NULL) { 126 | ret = -ENOMEM; 127 | goto done; 128 | } 129 | 130 | for (i = 0; i < nbuffers; ++i) { 131 | memset(&queue->buffer[i], 0, sizeof queue->buffer[i]); 132 | queue->buffer[i].buf.index = i; 133 | queue->buffer[i].buf.m.offset = i * bufsize; 134 | queue->buffer[i].buf.length = buflength; 135 | queue->buffer[i].buf.type = queue->type; 136 | queue->buffer[i].buf.sequence = 0; 137 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; 138 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; 139 | queue->buffer[i].buf.flags = 0; 140 | init_waitqueue_head(&queue->buffer[i].wait); 141 | } 142 | 143 | queue->mem = mem; 144 | queue->count = nbuffers; 145 | queue->buf_size = bufsize; 146 | ret = nbuffers; 147 | 148 | done: 149 | mutex_unlock(&queue->mutex); 150 | return ret; 151 | } 152 | 153 | /* 154 | * Free the video buffers. 155 | * 156 | * This function must be called with the queue lock held. 157 | */ 158 | int uvc_free_buffers(struct uvc_video_queue *queue) 159 | { 160 | unsigned int i; 161 | 162 | for (i = 0; i < queue->count; ++i) { 163 | if (queue->buffer[i].vma_use_count != 0) 164 | return -EBUSY; 165 | } 166 | 167 | if (queue->count) { 168 | #if LINUX_VERSION_CODE>=KERNEL_VERSION(3,0,35) 169 | uvc_queue_cancel(queue, 0); 170 | INIT_LIST_HEAD(&queue->mainqueue); 171 | #endif 172 | vfree(queue->mem); 173 | queue->count = 0; 174 | } 175 | 176 | return 0; 177 | } 178 | 179 | /* 180 | * Check if buffers have been allocated. 181 | */ 182 | int uvc_queue_allocated(struct uvc_video_queue *queue) 183 | { 184 | int allocated; 185 | 186 | mutex_lock(&queue->mutex); 187 | allocated = queue->count != 0; 188 | mutex_unlock(&queue->mutex); 189 | 190 | return allocated; 191 | } 192 | 193 | static void __uvc_query_buffer(struct uvc_buffer *buf, 194 | struct v4l2_buffer *v4l2_buf) 195 | { 196 | memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); 197 | 198 | if (buf->vma_use_count) 199 | v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED; 200 | 201 | switch (buf->state) { 202 | case UVC_BUF_STATE_ERROR: 203 | case UVC_BUF_STATE_DONE: 204 | v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; 205 | break; 206 | case UVC_BUF_STATE_QUEUED: 207 | case UVC_BUF_STATE_ACTIVE: 208 | case UVC_BUF_STATE_READY: 209 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; 210 | break; 211 | case UVC_BUF_STATE_IDLE: 212 | default: 213 | break; 214 | } 215 | } 216 | 217 | int uvc_query_buffer(struct uvc_video_queue *queue, 218 | struct v4l2_buffer *v4l2_buf) 219 | { 220 | int ret = 0; 221 | 222 | mutex_lock(&queue->mutex); 223 | if (v4l2_buf->index >= queue->count) { 224 | ret = -EINVAL; 225 | goto done; 226 | } 227 | 228 | __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); 229 | 230 | done: 231 | mutex_unlock(&queue->mutex); 232 | return ret; 233 | } 234 | 235 | /* 236 | * Queue a video buffer. Attempting to queue a buffer that has already been 237 | * queued will return -EINVAL. 238 | */ 239 | int uvc_queue_buffer(struct uvc_video_queue *queue, 240 | struct v4l2_buffer *v4l2_buf) 241 | { 242 | struct uvc_buffer *buf; 243 | unsigned long flags; 244 | int ret = 0; 245 | 246 | uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); 247 | 248 | if (v4l2_buf->type != queue->type || 249 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { 250 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 251 | "and/or memory (%u).\n", v4l2_buf->type, 252 | v4l2_buf->memory); 253 | return -EINVAL; 254 | } 255 | 256 | mutex_lock(&queue->mutex); 257 | if (v4l2_buf->index >= queue->count) { 258 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); 259 | ret = -EINVAL; 260 | goto done; 261 | } 262 | 263 | buf = &queue->buffer[v4l2_buf->index]; 264 | if (buf->state != UVC_BUF_STATE_IDLE) { 265 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state " 266 | "(%u).\n", buf->state); 267 | ret = -EINVAL; 268 | goto done; 269 | } 270 | 271 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 272 | v4l2_buf->bytesused > buf->buf.length) { 273 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); 274 | ret = -EINVAL; 275 | goto done; 276 | } 277 | 278 | spin_lock_irqsave(&queue->irqlock, flags); 279 | if (queue->flags & UVC_QUEUE_DISCONNECTED) { 280 | spin_unlock_irqrestore(&queue->irqlock, flags); 281 | ret = -ENODEV; 282 | goto done; 283 | } 284 | buf->state = UVC_BUF_STATE_QUEUED; 285 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 286 | buf->buf.bytesused = 0; 287 | else 288 | buf->buf.bytesused = v4l2_buf->bytesused; 289 | 290 | list_add_tail(&buf->stream, &queue->mainqueue); 291 | list_add_tail(&buf->queue, &queue->irqqueue); 292 | spin_unlock_irqrestore(&queue->irqlock, flags); 293 | 294 | done: 295 | mutex_unlock(&queue->mutex); 296 | return ret; 297 | } 298 | 299 | static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) 300 | { 301 | if (nonblocking) { 302 | return (buf->state != UVC_BUF_STATE_QUEUED && 303 | buf->state != UVC_BUF_STATE_ACTIVE && 304 | buf->state != UVC_BUF_STATE_READY) 305 | ? 0 : -EAGAIN; 306 | } 307 | 308 | return wait_event_interruptible(buf->wait, 309 | buf->state != UVC_BUF_STATE_QUEUED && 310 | buf->state != UVC_BUF_STATE_ACTIVE && 311 | buf->state != UVC_BUF_STATE_READY); 312 | } 313 | 314 | /* 315 | * Dequeue a video buffer. If nonblocking is false, block until a buffer is 316 | * available. 317 | */ 318 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, 319 | struct v4l2_buffer *v4l2_buf, int nonblocking) 320 | { 321 | struct uvc_buffer *buf; 322 | int ret = 0; 323 | 324 | if (v4l2_buf->type != queue->type || 325 | v4l2_buf->memory != V4L2_MEMORY_MMAP) { 326 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 327 | "and/or memory (%u).\n", v4l2_buf->type, 328 | v4l2_buf->memory); 329 | return -EINVAL; 330 | } 331 | 332 | mutex_lock(&queue->mutex); 333 | if (list_empty(&queue->mainqueue)) { 334 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n"); 335 | ret = -EINVAL; 336 | goto done; 337 | } 338 | 339 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); 340 | if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0) 341 | goto done; 342 | 343 | uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n", 344 | buf->buf.index, buf->state, buf->buf.bytesused); 345 | 346 | switch (buf->state) { 347 | case UVC_BUF_STATE_ERROR: 348 | uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " 349 | "(transmission error).\n"); 350 | ret = -EIO; 351 | case UVC_BUF_STATE_DONE: 352 | buf->state = UVC_BUF_STATE_IDLE; 353 | break; 354 | 355 | case UVC_BUF_STATE_IDLE: 356 | case UVC_BUF_STATE_QUEUED: 357 | case UVC_BUF_STATE_ACTIVE: 358 | case UVC_BUF_STATE_READY: 359 | default: 360 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " 361 | "(driver bug?).\n", buf->state); 362 | ret = -EINVAL; 363 | goto done; 364 | } 365 | 366 | list_del(&buf->stream); 367 | __uvc_query_buffer(buf, v4l2_buf); 368 | 369 | done: 370 | mutex_unlock(&queue->mutex); 371 | return ret; 372 | } 373 | 374 | /* 375 | * Poll the video queue. 376 | * 377 | * This function implements video queue polling and is intended to be used by 378 | * the device poll handler. 379 | */ 380 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, 381 | poll_table *wait) 382 | { 383 | struct uvc_buffer *buf; 384 | unsigned int mask = 0; 385 | 386 | mutex_lock(&queue->mutex); 387 | if (list_empty(&queue->mainqueue)) { 388 | mask |= POLLERR; 389 | goto done; 390 | } 391 | buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); 392 | 393 | poll_wait(file, &buf->wait, wait); 394 | if (buf->state == UVC_BUF_STATE_DONE || 395 | buf->state == UVC_BUF_STATE_ERROR) { 396 | if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 397 | mask |= POLLIN | POLLRDNORM; 398 | else 399 | mask |= POLLOUT | POLLWRNORM; 400 | } 401 | 402 | done: 403 | mutex_unlock(&queue->mutex); 404 | return mask; 405 | } 406 | 407 | /* 408 | * Enable or disable the video buffers queue. 409 | * 410 | * The queue must be enabled before starting video acquisition and must be 411 | * disabled after stopping it. This ensures that the video buffers queue 412 | * state can be properly initialized before buffers are accessed from the 413 | * interrupt handler. 414 | * 415 | * Enabling the video queue initializes parameters (such as sequence number, 416 | * sync pattern, ...). If the queue is already enabled, return -EBUSY. 417 | * 418 | * Disabling the video queue cancels the queue and removes all buffers from 419 | * the main queue. 420 | * 421 | * This function can't be called from interrupt context. Use 422 | * uvc_queue_cancel() instead. 423 | */ 424 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) 425 | { 426 | unsigned int i; 427 | int ret = 0; 428 | 429 | mutex_lock(&queue->mutex); 430 | if (enable) { 431 | if (uvc_queue_streaming(queue)) { 432 | ret = -EBUSY; 433 | goto done; 434 | } 435 | queue->sequence = 0; 436 | queue->flags |= UVC_QUEUE_STREAMING; 437 | queue->buf_used = 0; 438 | } else { 439 | uvc_queue_cancel(queue, 0); 440 | INIT_LIST_HEAD(&queue->mainqueue); 441 | 442 | for (i = 0; i < queue->count; ++i) 443 | queue->buffer[i].state = UVC_BUF_STATE_IDLE; 444 | 445 | queue->flags &= ~UVC_QUEUE_STREAMING; 446 | } 447 | 448 | done: 449 | mutex_unlock(&queue->mutex); 450 | return ret; 451 | } 452 | 453 | /* 454 | * Cancel the video buffers queue. 455 | * 456 | * Cancelling the queue marks all buffers on the irq queue as erroneous, 457 | * wakes them up and removes them from the queue. 458 | * 459 | * If the disconnect parameter is set, further calls to uvc_queue_buffer will 460 | * fail with -ENODEV. 461 | * 462 | * This function acquires the irq spinlock and can be called from interrupt 463 | * context. 464 | */ 465 | void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) 466 | { 467 | struct uvc_buffer *buf; 468 | unsigned long flags; 469 | 470 | spin_lock_irqsave(&queue->irqlock, flags); 471 | while (!list_empty(&queue->irqqueue)) { 472 | buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, 473 | queue); 474 | list_del(&buf->queue); 475 | buf->state = UVC_BUF_STATE_ERROR; 476 | wake_up(&buf->wait); 477 | } 478 | /* This must be protected by the irqlock spinlock to avoid race 479 | * conditions between uvc_queue_buffer and the disconnection event that 480 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not 481 | * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED 482 | * state outside the queue code. 483 | */ 484 | if (disconnect) 485 | queue->flags |= UVC_QUEUE_DISCONNECTED; 486 | spin_unlock_irqrestore(&queue->irqlock, flags); 487 | } 488 | 489 | struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, 490 | struct uvc_buffer *buf) 491 | { 492 | struct uvc_buffer *nextbuf; 493 | unsigned long flags; 494 | 495 | if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && 496 | buf->buf.length != buf->buf.bytesused) { 497 | buf->state = UVC_BUF_STATE_QUEUED; 498 | buf->buf.bytesused = 0; 499 | return buf; 500 | } 501 | 502 | spin_lock_irqsave(&queue->irqlock, flags); 503 | list_del(&buf->queue); 504 | buf->state = UVC_BUF_STATE_DONE; 505 | if (!list_empty(&queue->irqqueue)) 506 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, 507 | queue); 508 | else 509 | nextbuf = NULL; 510 | spin_unlock_irqrestore(&queue->irqlock, flags); 511 | 512 | buf->buf.sequence = queue->sequence++; 513 | 514 | wake_up(&buf->wait); 515 | return nextbuf; 516 | } 517 | 518 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_2.6.36/uvc_status.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_status.c -- USB Video Class driver - Status endpoint 3 | * 4 | * Copyright (C) 2007-2009 5 | * Laurent Pinchart (laurent.pinchart@skynet.be) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "uvcvideo.h" 19 | 20 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) 21 | #include 22 | #else 23 | #include 24 | #endif 25 | /* -------------------------------------------------------------------------- 26 | * Input device 27 | */ 28 | #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV 29 | static int uvc_input_init(struct uvc_device *dev) 30 | { 31 | struct input_dev *input; 32 | int ret; 33 | 34 | input = input_allocate_device(); 35 | if (input == NULL) 36 | return -ENOMEM; 37 | 38 | usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); 39 | strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); 40 | 41 | input->name = dev->name; 42 | input->phys = dev->input_phys; 43 | usb_to_input_id(dev->udev, &input->id); 44 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) 45 | input->dev.parent = &dev->intf->dev; 46 | #else 47 | input->cdev.dev = &dev->intf->dev; 48 | #endif 49 | 50 | __set_bit(EV_KEY, input->evbit); 51 | __set_bit(KEY_CAMERA, input->keybit); 52 | 53 | if ((ret = input_register_device(input)) < 0) 54 | goto error; 55 | 56 | dev->input = input; 57 | return 0; 58 | 59 | error: 60 | input_free_device(input); 61 | return ret; 62 | } 63 | 64 | static void uvc_input_cleanup(struct uvc_device *dev) 65 | { 66 | if (dev->input) 67 | input_unregister_device(dev->input); 68 | } 69 | 70 | static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, 71 | int value) 72 | { 73 | if (dev->input) { 74 | input_report_key(dev->input, code, value); 75 | input_sync(dev->input); 76 | } 77 | } 78 | 79 | #else 80 | #define uvc_input_init(dev) 81 | #define uvc_input_cleanup(dev) 82 | #define uvc_input_report_key(dev, code, value) 83 | #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ 84 | 85 | /* -------------------------------------------------------------------------- 86 | * Status interrupt endpoint 87 | */ 88 | static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) 89 | { 90 | if (len < 3) { 91 | uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " 92 | "received.\n"); 93 | return; 94 | } 95 | 96 | if (data[2] == 0) { 97 | if (len < 4) 98 | return; 99 | uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", 100 | data[1], data[3] ? "pressed" : "released", len); 101 | uvc_input_report_key(dev, KEY_CAMERA, data[3]); 102 | } else { 103 | uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " 104 | "len %d.\n", data[1], data[2], data[3], len); 105 | } 106 | } 107 | 108 | static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) 109 | { 110 | char *attrs[3] = { "value", "info", "failure" }; 111 | 112 | if (len < 6 || data[2] != 0 || data[4] > 2) { 113 | uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " 114 | "received.\n"); 115 | return; 116 | } 117 | 118 | uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", 119 | data[1], data[3], attrs[data[4]], len); 120 | } 121 | 122 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) 123 | static void uvc_status_complete(struct urb *urb, struct pt_regs *regs) 124 | #else 125 | static void uvc_status_complete(struct urb *urb) 126 | #endif 127 | { 128 | struct uvc_device *dev = urb->context; 129 | int len, ret; 130 | 131 | switch (urb->status) { 132 | case 0: 133 | break; 134 | 135 | case -ENOENT: /* usb_kill_urb() called. */ 136 | case -ECONNRESET: /* usb_unlink_urb() called. */ 137 | case -ESHUTDOWN: /* The endpoint is being disabled. */ 138 | case -EPROTO: /* Device is disconnected (reported by some 139 | * host controller). */ 140 | return; 141 | 142 | default: 143 | uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " 144 | "completion handler.\n", urb->status); 145 | return; 146 | } 147 | 148 | len = urb->actual_length; 149 | if (len > 0) { 150 | switch (dev->status[0] & 0x0f) { 151 | case UVC_STATUS_TYPE_CONTROL: 152 | uvc_event_control(dev, dev->status, len); 153 | break; 154 | 155 | case UVC_STATUS_TYPE_STREAMING: 156 | uvc_event_streaming(dev, dev->status, len); 157 | break; 158 | 159 | default: 160 | uvc_trace(UVC_TRACE_STATUS, "Unknown status event " 161 | "type %u.\n", dev->status[0]); 162 | break; 163 | } 164 | } 165 | 166 | /* Resubmit the URB. */ 167 | urb->interval = dev->int_ep->desc.bInterval; 168 | if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 169 | uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", 170 | ret); 171 | } 172 | } 173 | 174 | int uvc_status_init(struct uvc_device *dev) 175 | { 176 | struct usb_host_endpoint *ep = dev->int_ep; 177 | unsigned int pipe; 178 | int interval; 179 | 180 | if (ep == NULL) 181 | return 0; 182 | 183 | uvc_input_init(dev); 184 | 185 | dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL); 186 | if (dev->status == NULL) 187 | return -ENOMEM; 188 | 189 | dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 190 | if (dev->int_urb == NULL) { 191 | kfree(dev->status); 192 | return -ENOMEM; 193 | } 194 | 195 | pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); 196 | 197 | /* For high-speed interrupt endpoints, the bInterval value is used as 198 | * an exponent of two. Some developers forgot about it. 199 | */ 200 | interval = ep->desc.bInterval; 201 | if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && 202 | (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) 203 | interval = fls(interval) - 1; 204 | 205 | usb_fill_int_urb(dev->int_urb, dev->udev, pipe, 206 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, 207 | dev, interval); 208 | 209 | return 0; 210 | } 211 | 212 | void uvc_status_cleanup(struct uvc_device *dev) 213 | { 214 | usb_kill_urb(dev->int_urb); 215 | usb_free_urb(dev->int_urb); 216 | kfree(dev->status); 217 | uvc_input_cleanup(dev); 218 | } 219 | 220 | int uvc_status_start(struct uvc_device *dev) 221 | { 222 | if (dev->int_urb == NULL) 223 | return 0; 224 | 225 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); 226 | } 227 | 228 | void uvc_status_stop(struct uvc_device *dev) 229 | { 230 | usb_kill_urb(dev->int_urb); 231 | } 232 | 233 | int uvc_status_suspend(struct uvc_device *dev) 234 | { 235 | if (atomic_read(&dev->users)) 236 | usb_kill_urb(dev->int_urb); 237 | 238 | return 0; 239 | } 240 | 241 | int uvc_status_resume(struct uvc_device *dev) 242 | { 243 | if (dev->int_urb == NULL || atomic_read(&dev->users) == 0) 244 | return 0; 245 | 246 | return usb_submit_urb(dev->int_urb, GFP_NOIO); 247 | } 248 | 249 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/Kconfig: -------------------------------------------------------------------------------- 1 | config USB_VIDEO_CLASS_H264 2 | tristate "USB Video Class (UVC)" 3 | select VIDEOBUF2_VMALLOC 4 | ---help--- 5 | Support for the RERVISION H264 USB Video Class (UVC). Currently only H264 USB Camera, 6 | such as RER-USB100W04H, are supported. 7 | 8 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/Makefile_Embedded: -------------------------------------------------------------------------------- 1 | uvcvideo_h264-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_debugfs.o uvc_ctrl.o \ 2 | uvc_status.o uvc_isight.o nalu.o 3 | 4 | obj-$(CONFIG_USB_VIDEO_CLASS_H264) += uvcvideo_h264.o 5 | 6 | 7 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/Makefile_PC: -------------------------------------------------------------------------------- 1 | KERNELDIR ?= /lib/modules/`uname -r`/build 2 | PWD := $(shell pwd) 3 | INSTALLDIR ?= ../ 4 | CROSS_COMPILE ?= 5 | CC ?= $(CROSS_COMPILE)gcc 6 | 7 | MODULE_NAME := uvcvideo_h264 8 | RESMAIN_CORE_OBJS := uvc_driver.o 9 | RESMAIN_GLUE_OBJS := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o uvc_status.o uvc_isight.o nalu.o uvc_debugfs.o uvc_entity.o 10 | $(MODULE_NAME)-objs := $(RESMAIN_CORE_OBJS) $(RESMAIN_GLUE_OBJS) 11 | obj-m := uvcvideo_h264.o 12 | 13 | all: 14 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 15 | 16 | install: all 17 | cp *.ko $(INSTALLDIR) 18 | 19 | clean: 20 | rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.markers *.symvers *.order 21 | 22 | .PHONY: 23 | modules modules_install clean 24 | 25 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/nalu.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------// 2 | // H264 NALU c source code // 3 | //----------------------------------------------// 4 | 5 | #include 6 | #include "nalu.h" 7 | 8 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end) 9 | { 10 | unsigned char zero_cnt; 11 | zero_cnt = 0; 12 | 13 | while(1) 14 | { 15 | if(pBuf == pBuf_end) 16 | { 17 | break; 18 | } 19 | if(*pBuf == 0) 20 | { 21 | zero_cnt++; 22 | } 23 | else if((zero_cnt >= 3) && (*pBuf == 1)) 24 | { 25 | zero_cnt = 0; 26 | pBuf++; 27 | break; 28 | } 29 | else 30 | { 31 | zero_cnt = 0; 32 | } 33 | pBuf++; 34 | } 35 | return pBuf; 36 | } 37 | 38 | unsigned int Ue(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 39 | { 40 | unsigned int i=0; 41 | unsigned int nZeroNum = 0; 42 | unsigned long dwRet = 0; 43 | 44 | while((*nStartBit) < (nLen * 8)) 45 | { 46 | if(pBuff[(*nStartBit) / 8] & (0x80 >> ((*nStartBit) % 8))) 47 | break; 48 | 49 | nZeroNum++; 50 | (*nStartBit)++; 51 | } 52 | (*nStartBit) ++; 53 | 54 | for(i=0; i> ((*nStartBit) % 8))) 58 | { 59 | dwRet += 1; 60 | } 61 | (*nStartBit)++; 62 | } 63 | return (1 << nZeroNum) - 1 + dwRet; 64 | } 65 | 66 | int Se(unsigned char *pBuff, unsigned int nLen, unsigned int *nStartBit) 67 | { 68 | #if 0 69 | int UeVal=Ue(pBuff,nLen,*nStartBit); 70 | double k=UeVal; 71 | int nValue=ceil(k/2); 72 | 73 | if(UeVal % 2==0) 74 | nValue=-nValue; 75 | 76 | return nValue; 77 | #else 78 | int UeVal=Ue(pBuff,nLen,nStartBit); 79 | int nValue = UeVal / 2; 80 | if( nValue > 0) nValue += UeVal & 0x01; 81 | if(UeVal % 2==0) 82 | nValue=-nValue; 83 | 84 | return nValue; 85 | #endif 86 | } 87 | 88 | unsigned long u(unsigned int BitCount,unsigned char * buf,unsigned int *nStartBit) 89 | { 90 | unsigned long dwRet = 0; 91 | unsigned int i = 0; 92 | 93 | for(i=0; i> ((*nStartBit) % 8))) 97 | { 98 | dwRet += 1; 99 | } 100 | (*nStartBit)++; 101 | } 102 | 103 | return dwRet; 104 | } 105 | 106 | bool h264_decode_seq_parameter_set(unsigned char * buf, unsigned int nLen, int *Width, int *Height) 107 | { 108 | unsigned int StartBit=0; 109 | int forbidden_zero_bit, nal_ref_idc, nal_unit_type; 110 | 111 | forbidden_zero_bit=u(1,buf,&StartBit); 112 | nal_ref_idc=u(2,buf,&StartBit); 113 | nal_unit_type=u(5,buf,&StartBit); 114 | 115 | if(nal_unit_type==7) 116 | { 117 | int profile_idc, constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag, reserved_zero_4bits, level_idc; 118 | int seq_parameter_set_id, log2_max_frame_num_minus4, pic_order_cnt_type; 119 | int num_ref_frames, gaps_in_frame_num_value_allowed_flag, pic_width_in_mbs_minus1, pic_height_in_map_units_minus1; 120 | 121 | profile_idc=u(8,buf,&StartBit); 122 | constraint_set0_flag=u(1,buf,&StartBit);//(buf[1] & 0x80)>>7; 123 | constraint_set1_flag=u(1,buf,&StartBit);//(buf[1] & 0x40)>>6; 124 | constraint_set2_flag=u(1,buf,&StartBit);//(buf[1] & 0x20)>>5; 125 | constraint_set3_flag=u(1,buf,&StartBit);//(buf[1] & 0x10)>>4; 126 | reserved_zero_4bits=u(4,buf,&StartBit); 127 | level_idc=u(8,buf,&StartBit); 128 | 129 | seq_parameter_set_id=Ue(buf,nLen,&StartBit); 130 | 131 | if((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) 132 | { 133 | int chroma_format_idc, residual_colour_transform_flag, bit_depth_luma_minus8, bit_depth_chroma_minus8, qpprime_y_zero_transform_bypass_flag; 134 | int seq_scaling_matrix_present_flag; 135 | 136 | chroma_format_idc=Ue(buf,nLen,&StartBit); 137 | residual_colour_transform_flag = 0; 138 | 139 | if(chroma_format_idc == 3) 140 | residual_colour_transform_flag=u(1,buf,&StartBit); 141 | 142 | bit_depth_luma_minus8=Ue(buf,nLen,&StartBit); 143 | bit_depth_chroma_minus8=Ue(buf,nLen,&StartBit); 144 | qpprime_y_zero_transform_bypass_flag=u(1,buf,&StartBit); 145 | seq_scaling_matrix_present_flag=u(1,buf,&StartBit); 146 | 147 | if(seq_scaling_matrix_present_flag) 148 | { 149 | int seq_scaling_list_present_flag[8]; 150 | int i=0; 151 | for( i = 0; i < 8; i++ ) 152 | { 153 | seq_scaling_list_present_flag[i]=u(1,buf,&StartBit); 154 | } 155 | } 156 | } 157 | 158 | log2_max_frame_num_minus4=Ue(buf,nLen,&StartBit); 159 | pic_order_cnt_type=Ue(buf,nLen,&StartBit); 160 | 161 | if(pic_order_cnt_type == 0) 162 | { 163 | int log2_max_pic_order_cnt_lsb_minus4=Ue(buf,nLen,&StartBit); 164 | } 165 | else if(pic_order_cnt_type == 1) 166 | { 167 | int delta_pic_order_always_zero_flag=u(1,buf,&StartBit); 168 | int offset_for_non_ref_pic=Se(buf,nLen,&StartBit); 169 | int offset_for_top_to_bottom_field=Se(buf,nLen,&StartBit); 170 | int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,nLen,&StartBit); 171 | #if 0 172 | int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle]; 173 | for(int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 174 | offset_for_ref_frame[i]=Se(buf,nLen,&StartBit); 175 | 176 | delete [] offset_for_ref_frame; 177 | #else 178 | int offset_for_ref_frame = 0; 179 | int i = 0; 180 | for(i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) 181 | offset_for_ref_frame =Se(buf,nLen,&StartBit); 182 | #endif 183 | 184 | } 185 | 186 | num_ref_frames=Ue(buf,nLen,&StartBit); 187 | gaps_in_frame_num_value_allowed_flag=u(1,buf,&StartBit); 188 | pic_width_in_mbs_minus1=Ue(buf,nLen,&StartBit); 189 | pic_height_in_map_units_minus1=Ue(buf,nLen,&StartBit); 190 | 191 | *Width=(pic_width_in_mbs_minus1+1)*16; 192 | *Height=(pic_height_in_map_units_minus1+1)*16; 193 | 194 | return true; 195 | } 196 | else 197 | { 198 | return false; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/nalu.h: -------------------------------------------------------------------------------- 1 | #ifndef _NALU_H_ 2 | #define _NALU_H_ 3 | 4 | #include 5 | 6 | //unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned int Buf_len); 7 | unsigned char* FindNextH264StartCode(unsigned char *pBuf, unsigned char *pBuf_end); 8 | 9 | bool h264_decode_seq_parameter_set(unsigned char *buf, unsigned int nLen, int *Width, int *Height); 10 | 11 | #if 0 12 | //! NAL unit structure 13 | typedef struct nalu_sps 14 | { 15 | unsigned char profile_idc; 16 | unsigned constraint_set0_flag:1; 17 | unsigned constraint_set1_flag:1; 18 | unsigned constraint_set2_flag:1; 19 | unsigned constraint_set3_flag:1; 20 | unsigned reserved_zero_4bits:4; 21 | unsigned char level_idc; 22 | unsigned seq_parameter_set_id:1; 23 | unsigned log2_max_frame_num_minus4:5; 24 | } NALU_SPS; 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_debugfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_debugfs.c -- USB Video Class driver - Debugging support 3 | * 4 | * Copyright (C) 2011 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "uvcvideo.h" 20 | 21 | /* ----------------------------------------------------------------------------- 22 | * Statistics 23 | */ 24 | 25 | #define UVC_DEBUGFS_BUF_SIZE 1024 26 | 27 | struct uvc_debugfs_buffer { 28 | size_t count; 29 | char data[UVC_DEBUGFS_BUF_SIZE]; 30 | }; 31 | 32 | static int uvc_debugfs_stats_open(struct inode *inode, struct file *file) 33 | { 34 | struct uvc_streaming *stream = inode->i_private; 35 | struct uvc_debugfs_buffer *buf; 36 | 37 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); 38 | if (buf == NULL) 39 | return -ENOMEM; 40 | 41 | buf->count = uvc_video_stats_dump(stream, buf->data, sizeof(buf->data)); 42 | 43 | file->private_data = buf; 44 | return 0; 45 | } 46 | 47 | static ssize_t uvc_debugfs_stats_read(struct file *file, char __user *user_buf, 48 | size_t nbytes, loff_t *ppos) 49 | { 50 | struct uvc_debugfs_buffer *buf = file->private_data; 51 | 52 | return simple_read_from_buffer(user_buf, nbytes, ppos, buf->data, 53 | buf->count); 54 | } 55 | 56 | static int uvc_debugfs_stats_release(struct inode *inode, struct file *file) 57 | { 58 | kfree(file->private_data); 59 | file->private_data = NULL; 60 | 61 | return 0; 62 | } 63 | 64 | static const struct file_operations uvc_debugfs_stats_fops = { 65 | .owner = THIS_MODULE, 66 | .open = uvc_debugfs_stats_open, 67 | .llseek = no_llseek, 68 | .read = uvc_debugfs_stats_read, 69 | .release = uvc_debugfs_stats_release, 70 | }; 71 | 72 | /* ----------------------------------------------------------------------------- 73 | * Global and stream initialization/cleanup 74 | */ 75 | 76 | static struct dentry *uvc_debugfs_root_dir; 77 | 78 | int uvc_debugfs_init_stream(struct uvc_streaming *stream) 79 | { 80 | struct usb_device *udev = stream->dev->udev; 81 | struct dentry *dent; 82 | char dir_name[32]; 83 | 84 | if (uvc_debugfs_root_dir == NULL) 85 | return -ENODEV; 86 | 87 | sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum); 88 | 89 | dent = debugfs_create_dir(dir_name, uvc_debugfs_root_dir); 90 | if (IS_ERR_OR_NULL(dent)) { 91 | uvc_printk(KERN_INFO, "Unable to create debugfs %s " 92 | "directory.\n", dir_name); 93 | return -ENODEV; 94 | } 95 | 96 | stream->debugfs_dir = dent; 97 | 98 | dent = debugfs_create_file("stats", 0444, stream->debugfs_dir, 99 | stream, &uvc_debugfs_stats_fops); 100 | if (IS_ERR_OR_NULL(dent)) { 101 | uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n"); 102 | uvc_debugfs_cleanup_stream(stream); 103 | return -ENODEV; 104 | } 105 | 106 | return 0; 107 | } 108 | 109 | void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream) 110 | { 111 | if (stream->debugfs_dir == NULL) 112 | return; 113 | 114 | debugfs_remove_recursive(stream->debugfs_dir); 115 | stream->debugfs_dir = NULL; 116 | } 117 | 118 | int uvc_debugfs_init(void) 119 | { 120 | struct dentry *dir; 121 | 122 | dir = debugfs_create_dir("uvcvideo", usb_debug_root); 123 | if (IS_ERR_OR_NULL(dir)) { 124 | uvc_printk(KERN_INFO, "Unable to create debugfs directory\n"); 125 | return -ENODATA; 126 | } 127 | 128 | uvc_debugfs_root_dir = dir; 129 | return 0; 130 | } 131 | 132 | void uvc_debugfs_cleanup(void) 133 | { 134 | if (uvc_debugfs_root_dir != NULL) 135 | debugfs_remove_recursive(uvc_debugfs_root_dir); 136 | } 137 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_entity.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_entity.c -- USB Video Class driver 3 | * 4 | * Copyright (C) 2005-2011 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include "uvcvideo.h" 21 | 22 | /* ------------------------------------------------------------------------ 23 | * Video subdevices registration and unregistration 24 | */ 25 | 26 | static int uvc_mc_register_entity(struct uvc_video_chain *chain, 27 | struct uvc_entity *entity) 28 | { 29 | const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; 30 | struct media_entity *sink; 31 | unsigned int i; 32 | int ret; 33 | 34 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) 35 | ? (entity->vdev ? &entity->vdev->entity : NULL) 36 | : &entity->subdev.entity; 37 | if (sink == NULL) 38 | return 0; 39 | 40 | for (i = 0; i < entity->num_pads; ++i) { 41 | struct media_entity *source; 42 | struct uvc_entity *remote; 43 | u8 remote_pad; 44 | 45 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) 46 | continue; 47 | 48 | remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]); 49 | if (remote == NULL) 50 | return -EINVAL; 51 | 52 | source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) 53 | ? (remote->vdev ? &remote->vdev->entity : NULL) 54 | : &remote->subdev.entity; 55 | if (source == NULL) 56 | continue; 57 | 58 | remote_pad = remote->num_pads - 1; 59 | ret = media_entity_create_link(source, remote_pad, 60 | sink, i, flags); 61 | if (ret < 0) 62 | return ret; 63 | } 64 | 65 | if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) 66 | return 0; 67 | 68 | return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); 69 | } 70 | 71 | static struct v4l2_subdev_ops uvc_subdev_ops = { 72 | }; 73 | 74 | void uvc_mc_cleanup_entity(struct uvc_entity *entity) 75 | { 76 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) 77 | media_entity_cleanup(&entity->subdev.entity); 78 | else if (entity->vdev != NULL) 79 | media_entity_cleanup(&entity->vdev->entity); 80 | } 81 | 82 | static int uvc_mc_init_entity(struct uvc_entity *entity) 83 | { 84 | int ret; 85 | 86 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) { 87 | v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops); 88 | strlcpy(entity->subdev.name, entity->name, 89 | sizeof(entity->subdev.name)); 90 | 91 | ret = media_entity_init(&entity->subdev.entity, 92 | entity->num_pads, entity->pads, 0); 93 | } else if (entity->vdev != NULL) { 94 | ret = media_entity_init(&entity->vdev->entity, 95 | entity->num_pads, entity->pads, 0); 96 | } else 97 | ret = 0; 98 | 99 | return ret; 100 | } 101 | 102 | int uvc_mc_register_entities(struct uvc_video_chain *chain) 103 | { 104 | struct uvc_entity *entity; 105 | int ret; 106 | 107 | list_for_each_entry(entity, &chain->entities, chain) { 108 | ret = uvc_mc_init_entity(entity); 109 | if (ret < 0) { 110 | uvc_printk(KERN_INFO, "Failed to initialize entity for " 111 | "entity %u\n", entity->id); 112 | return ret; 113 | } 114 | } 115 | 116 | list_for_each_entry(entity, &chain->entities, chain) { 117 | ret = uvc_mc_register_entity(chain, entity); 118 | if (ret < 0) { 119 | uvc_printk(KERN_INFO, "Failed to register entity for " 120 | "entity %u\n", entity->id); 121 | return ret; 122 | } 123 | } 124 | 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_isight.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_isight.c -- USB Video Class driver - iSight support 3 | * 4 | * Copyright (C) 2006-2007 5 | * Ivan N. Zlatev 6 | * Copyright (C) 2008-2009 7 | * Laurent Pinchart 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 as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "uvcvideo.h" 21 | 22 | /* Built-in iSight webcams implements most of UVC 1.0 except a 23 | * different packet format. Instead of sending a header at the 24 | * beginning of each isochronous transfer payload, the webcam sends a 25 | * single header per image (on its own in a packet), followed by 26 | * packets containing data only. 27 | * 28 | * Offset Size (bytes) Description 29 | * ------------------------------------------------------------------ 30 | * 0x00 1 Header length 31 | * 0x01 1 Flags (UVC-compliant) 32 | * 0x02 4 Always equal to '11223344' 33 | * 0x06 8 Always equal to 'deadbeefdeadface' 34 | * 0x0e 16 Unknown 35 | * 36 | * The header can be prefixed by an optional, unknown-purpose byte. 37 | */ 38 | 39 | static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, 40 | const __u8 *data, unsigned int len) 41 | { 42 | static const __u8 hdr[] = { 43 | 0x11, 0x22, 0x33, 0x44, 44 | 0xde, 0xad, 0xbe, 0xef, 45 | 0xde, 0xad, 0xfa, 0xce 46 | }; 47 | 48 | unsigned int maxlen, nbytes; 49 | __u8 *mem; 50 | int is_header = 0; 51 | 52 | if (buf == NULL) 53 | return 0; 54 | 55 | if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) || 56 | (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) { 57 | uvc_trace(UVC_TRACE_FRAME, "iSight header found\n"); 58 | is_header = 1; 59 | } 60 | 61 | /* Synchronize to the input stream by waiting for a header packet. */ 62 | if (buf->state != UVC_BUF_STATE_ACTIVE) { 63 | if (!is_header) { 64 | uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of " 65 | "sync).\n"); 66 | return 0; 67 | } 68 | 69 | buf->state = UVC_BUF_STATE_ACTIVE; 70 | } 71 | 72 | /* Mark the buffer as done if we're at the beginning of a new frame. 73 | * 74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection 75 | * as it doesn't make sense to return an empty buffer. 76 | */ 77 | if (is_header && buf->bytesused != 0) { 78 | buf->state = UVC_BUF_STATE_DONE; 79 | return -EAGAIN; 80 | } 81 | 82 | /* Copy the video data to the buffer. Skip header packets, as they 83 | * contain no data. 84 | */ 85 | if (!is_header) { 86 | maxlen = buf->length - buf->bytesused; 87 | mem = buf->mem + buf->bytesused; 88 | nbytes = min(len, maxlen); 89 | memcpy(mem, data, nbytes); 90 | buf->bytesused += nbytes; 91 | 92 | if (len > maxlen || buf->bytesused == buf->length) { 93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " 94 | "(overflow).\n"); 95 | buf->state = UVC_BUF_STATE_DONE; 96 | } 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, 103 | struct uvc_buffer *buf) 104 | { 105 | int ret, i; 106 | 107 | for (i = 0; i < urb->number_of_packets; ++i) { 108 | if (urb->iso_frame_desc[i].status < 0) { 109 | uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame " 110 | "lost (%d).\n", 111 | urb->iso_frame_desc[i].status); 112 | } 113 | 114 | /* Decode the payload packet. 115 | * uvc_video_decode is entered twice when a frame transition 116 | * has been detected because the end of frame can only be 117 | * reliably detected when the first packet of the new frame 118 | * is processed. The first pass detects the transition and 119 | * closes the previous frame's buffer, the second pass 120 | * processes the data of the first payload of the new frame. 121 | */ 122 | do { 123 | ret = isight_decode(&stream->queue, buf, 124 | urb->transfer_buffer + 125 | urb->iso_frame_desc[i].offset, 126 | urb->iso_frame_desc[i].actual_length); 127 | 128 | if (buf == NULL) 129 | break; 130 | 131 | if (buf->state == UVC_BUF_STATE_DONE || 132 | buf->state == UVC_BUF_STATE_ERROR) 133 | buf = uvc_queue_next_buffer(&stream->queue, 134 | buf); 135 | } while (ret == -EAGAIN); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_queue.c -- USB Video Class driver - Buffers management 3 | * 4 | * Copyright (C) 2005-2010 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "uvcvideo.h" 26 | 27 | /* ------------------------------------------------------------------------ 28 | * Video buffers queue management. 29 | * 30 | * Video queues is initialized by uvc_queue_init(). The function performs 31 | * basic initialization of the uvc_video_queue struct and never fails. 32 | * 33 | * Video buffers are managed by videobuf2. The driver uses a mutex to protect 34 | * the videobuf2 queue operations by serializing calls to videobuf2 and a 35 | * spinlock to protect the IRQ queue that holds the buffers to be processed by 36 | * the driver. 37 | */ 38 | 39 | /* ----------------------------------------------------------------------------- 40 | * videobuf2 queue operations 41 | */ 42 | 43 | /* ----------------------------------------------------------------------------- 44 | * adding by pae 45 | */ 46 | 47 | static inline struct uvc_streaming * 48 | uvc_queue_to_stream(struct uvc_video_queue *queue) 49 | { 50 | return container_of(queue, struct uvc_streaming, queue); 51 | } 52 | 53 | static inline struct uvc_buffer *uvc_vbuf_to_buffer(struct vb2_v4l2_buffer *buf) 54 | { 55 | return container_of(buf, struct uvc_buffer, buf); 56 | } 57 | /******************************************************************************/ 58 | 59 | static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, 60 | unsigned int *nbuffers, unsigned int *nplanes, 61 | unsigned int sizes[], void *alloc_ctxs[]) 62 | { 63 | struct uvc_video_queue *queue = vb2_get_drv_priv(vq); 64 | struct uvc_streaming *stream = 65 | container_of(queue, struct uvc_streaming, queue); 66 | 67 | if (*nbuffers > UVC_MAX_VIDEO_BUFFERS) 68 | *nbuffers = UVC_MAX_VIDEO_BUFFERS; 69 | 70 | *nplanes = 1; 71 | 72 | sizes[0] = stream->ctrl.dwMaxVideoFrameSize; 73 | 74 | return 0; 75 | } 76 | 77 | /* 78 | static int uvc_buffer_prepare(struct vb2_buffer *vb) 79 | { 80 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 81 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); 82 | 83 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 84 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { 85 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); 86 | return -EINVAL; 87 | } 88 | 89 | if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED)) 90 | return -ENODEV; 91 | 92 | buf->state = UVC_BUF_STATE_QUEUED; 93 | buf->error = 0; 94 | buf->mem = vb2_plane_vaddr(vb, 0); 95 | buf->length = vb2_plane_size(vb, 0); 96 | if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 97 | buf->bytesused = 0; 98 | else 99 | buf->bytesused = vb2_get_plane_payload(vb, 0); 100 | 101 | return 0; 102 | } 103 | */ 104 | 105 | //adding by Pae 106 | 107 | static int uvc_buffer_prepare(struct vb2_buffer *vb) 108 | { 109 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 110 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 111 | struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf); 112 | 113 | if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 114 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { 115 | uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); 116 | return -EINVAL; 117 | } 118 | 119 | if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED)) 120 | return -ENODEV; 121 | 122 | buf->state = UVC_BUF_STATE_QUEUED; 123 | buf->error = 0; 124 | buf->mem = vb2_plane_vaddr(vb, 0); 125 | buf->length = vb2_plane_size(vb, 0); 126 | if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 127 | buf->bytesused = 0; 128 | else 129 | buf->bytesused = vb2_get_plane_payload(vb, 0); 130 | 131 | return 0; 132 | } 133 | 134 | static void uvc_buffer_queue(struct vb2_buffer *vb) 135 | { 136 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 137 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); 138 | unsigned long flags; 139 | 140 | spin_lock_irqsave(&queue->irqlock, flags); 141 | if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) { 142 | list_add_tail(&buf->queue, &queue->irqqueue); 143 | } else { 144 | /* If the device is disconnected return the buffer to userspace 145 | * directly. The next QBUF call will fail with -ENODEV. 146 | */ 147 | buf->state = UVC_BUF_STATE_ERROR; 148 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); 149 | } 150 | 151 | spin_unlock_irqrestore(&queue->irqlock, flags); 152 | } 153 | 154 | /* 155 | static int uvc_buffer_finish(struct vb2_buffer *vb) 156 | { 157 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 158 | struct uvc_streaming *stream = 159 | container_of(queue, struct uvc_streaming, queue); 160 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); 161 | 162 | uvc_video_clock_update(stream, &vb->v4l2_buf, buf); 163 | return 0; 164 | } 165 | 166 | 167 | //adding by Pae 168 | static void uvc_buffer_finish(struct vb2_buffer *vb) 169 | { 170 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 171 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 172 | struct uvc_streaming *stream = uvc_queue_to_stream(queue); 173 | struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); 174 | 175 | if (vb->state == VB2_BUF_STATE_DONE) 176 | uvc_video_clock_update(stream, vbuf, buf); 177 | } 178 | */ 179 | //modify by Pae 180 | static int uvc_buffer_finish(struct vb2_buffer *vb) 181 | { 182 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 183 | struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 184 | struct uvc_streaming *stream = 185 | container_of(queue, struct uvc_streaming, queue); 186 | struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); 187 | 188 | uvc_video_clock_update(stream, vbuf, buf); 189 | return 0; 190 | } 191 | 192 | static struct vb2_ops uvc_queue_qops = { 193 | .queue_setup = uvc_queue_setup, 194 | .buf_prepare = uvc_buffer_prepare, 195 | .buf_queue = uvc_buffer_queue, 196 | .buf_finish = uvc_buffer_finish, 197 | }; 198 | 199 | void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, 200 | int drop_corrupted) 201 | { 202 | queue->queue.type = type; 203 | queue->queue.io_modes = VB2_MMAP; 204 | queue->queue.drv_priv = queue; 205 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); 206 | queue->queue.ops = &uvc_queue_qops; 207 | queue->queue.mem_ops = &vb2_vmalloc_memops; 208 | vb2_queue_init(&queue->queue); 209 | 210 | mutex_init(&queue->mutex); 211 | spin_lock_init(&queue->irqlock); 212 | INIT_LIST_HEAD(&queue->irqqueue); 213 | queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; 214 | } 215 | 216 | /* ----------------------------------------------------------------------------- 217 | * V4L2 queue operations 218 | */ 219 | 220 | int uvc_alloc_buffers(struct uvc_video_queue *queue, 221 | struct v4l2_requestbuffers *rb) 222 | { 223 | int ret; 224 | 225 | mutex_lock(&queue->mutex); 226 | ret = vb2_reqbufs(&queue->queue, rb); 227 | mutex_unlock(&queue->mutex); 228 | 229 | return ret ? ret : rb->count; 230 | } 231 | 232 | void uvc_free_buffers(struct uvc_video_queue *queue) 233 | { 234 | mutex_lock(&queue->mutex); 235 | vb2_queue_release(&queue->queue); 236 | mutex_unlock(&queue->mutex); 237 | } 238 | 239 | int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) 240 | { 241 | int ret; 242 | 243 | mutex_lock(&queue->mutex); 244 | ret = vb2_querybuf(&queue->queue, buf); 245 | mutex_unlock(&queue->mutex); 246 | 247 | return ret; 248 | } 249 | 250 | int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) 251 | { 252 | int ret; 253 | 254 | mutex_lock(&queue->mutex); 255 | ret = vb2_qbuf(&queue->queue, buf); 256 | mutex_unlock(&queue->mutex); 257 | 258 | return ret; 259 | } 260 | 261 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, 262 | int nonblocking) 263 | { 264 | int ret; 265 | 266 | mutex_lock(&queue->mutex); 267 | ret = vb2_dqbuf(&queue->queue, buf, nonblocking); 268 | mutex_unlock(&queue->mutex); 269 | 270 | return ret; 271 | } 272 | 273 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) 274 | { 275 | int ret; 276 | 277 | mutex_lock(&queue->mutex); 278 | ret = vb2_mmap(&queue->queue, vma); 279 | mutex_unlock(&queue->mutex); 280 | 281 | return ret; 282 | } 283 | 284 | unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, 285 | poll_table *wait) 286 | { 287 | unsigned int ret; 288 | 289 | mutex_lock(&queue->mutex); 290 | ret = vb2_poll(&queue->queue, file, wait); 291 | mutex_unlock(&queue->mutex); 292 | 293 | return ret; 294 | } 295 | 296 | /* ----------------------------------------------------------------------------- 297 | * 298 | */ 299 | 300 | /* 301 | * Check if buffers have been allocated. 302 | */ 303 | int uvc_queue_allocated(struct uvc_video_queue *queue) 304 | { 305 | int allocated; 306 | 307 | mutex_lock(&queue->mutex); 308 | allocated = vb2_is_busy(&queue->queue); 309 | mutex_unlock(&queue->mutex); 310 | 311 | return allocated; 312 | } 313 | 314 | #ifndef CONFIG_MMU 315 | /* 316 | * Get unmapped area. 317 | * 318 | * NO-MMU arch need this function to make mmap() work correctly. 319 | */ 320 | unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, 321 | unsigned long pgoff) 322 | { 323 | struct uvc_buffer *buffer; 324 | unsigned int i; 325 | unsigned long ret; 326 | 327 | mutex_lock(&queue->mutex); 328 | for (i = 0; i < queue->count; ++i) { 329 | buffer = &queue->buffer[i]; 330 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff) 331 | break; 332 | } 333 | if (i == queue->count) { 334 | ret = -EINVAL; 335 | goto done; 336 | } 337 | ret = (unsigned long)buf->mem; 338 | done: 339 | mutex_unlock(&queue->mutex); 340 | return ret; 341 | } 342 | #endif 343 | 344 | /* 345 | * Enable or disable the video buffers queue. 346 | * 347 | * The queue must be enabled before starting video acquisition and must be 348 | * disabled after stopping it. This ensures that the video buffers queue 349 | * state can be properly initialized before buffers are accessed from the 350 | * interrupt handler. 351 | * 352 | * Enabling the video queue returns -EBUSY if the queue is already enabled. 353 | * 354 | * Disabling the video queue cancels the queue and removes all buffers from 355 | * the main queue. 356 | * 357 | * This function can't be called from interrupt context. Use 358 | * uvc_queue_cancel() instead. 359 | */ 360 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) 361 | { 362 | unsigned long flags; 363 | int ret; 364 | 365 | mutex_lock(&queue->mutex); 366 | if (enable) { 367 | ret = vb2_streamon(&queue->queue, queue->queue.type); 368 | if (ret < 0) 369 | goto done; 370 | 371 | queue->buf_used = 0; 372 | } else { 373 | ret = vb2_streamoff(&queue->queue, queue->queue.type); 374 | if (ret < 0) 375 | goto done; 376 | 377 | spin_lock_irqsave(&queue->irqlock, flags); 378 | INIT_LIST_HEAD(&queue->irqqueue); 379 | spin_unlock_irqrestore(&queue->irqlock, flags); 380 | } 381 | 382 | done: 383 | mutex_unlock(&queue->mutex); 384 | return ret; 385 | } 386 | 387 | /* 388 | * Cancel the video buffers queue. 389 | * 390 | * Cancelling the queue marks all buffers on the irq queue as erroneous, 391 | * wakes them up and removes them from the queue. 392 | * 393 | * If the disconnect parameter is set, further calls to uvc_queue_buffer will 394 | * fail with -ENODEV. 395 | * 396 | * This function acquires the irq spinlock and can be called from interrupt 397 | * context. 398 | */ 399 | void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) 400 | { 401 | struct uvc_buffer *buf; 402 | unsigned long flags; 403 | 404 | spin_lock_irqsave(&queue->irqlock, flags); 405 | while (!list_empty(&queue->irqqueue)) { 406 | buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, 407 | queue); 408 | list_del(&buf->queue); 409 | buf->state = UVC_BUF_STATE_ERROR; 410 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); 411 | } 412 | /* This must be protected by the irqlock spinlock to avoid race 413 | * conditions between uvc_buffer_queue and the disconnection event that 414 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not 415 | * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED 416 | * state outside the queue code. 417 | */ 418 | if (disconnect) 419 | queue->flags |= UVC_QUEUE_DISCONNECTED; 420 | spin_unlock_irqrestore(&queue->irqlock, flags); 421 | } 422 | 423 | struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, 424 | struct uvc_buffer *buf) 425 | { 426 | struct uvc_buffer *nextbuf; 427 | unsigned long flags; 428 | 429 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { 430 | buf->error = 0; 431 | buf->state = UVC_BUF_STATE_QUEUED; 432 | vb2_set_plane_payload(&buf->buf, 0, 0); 433 | return buf; 434 | } 435 | 436 | spin_lock_irqsave(&queue->irqlock, flags); 437 | list_del(&buf->queue); 438 | if (!list_empty(&queue->irqqueue)) 439 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, 440 | queue); 441 | else 442 | nextbuf = NULL; 443 | spin_unlock_irqrestore(&queue->irqlock, flags); 444 | 445 | buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; 446 | vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); 447 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); 448 | 449 | return nextbuf; 450 | } 451 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_status.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_status.c -- USB Video Class driver - Status endpoint 3 | * 4 | * Copyright (C) 2005-2009 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "uvcvideo.h" 21 | 22 | /* -------------------------------------------------------------------------- 23 | * Input device 24 | */ 25 | #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV 26 | static int uvc_input_init(struct uvc_device *dev) 27 | { 28 | struct input_dev *input; 29 | int ret; 30 | 31 | input = input_allocate_device(); 32 | if (input == NULL) 33 | return -ENOMEM; 34 | 35 | usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); 36 | strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); 37 | 38 | input->name = dev->name; 39 | input->phys = dev->input_phys; 40 | usb_to_input_id(dev->udev, &input->id); 41 | input->dev.parent = &dev->intf->dev; 42 | 43 | __set_bit(EV_KEY, input->evbit); 44 | __set_bit(KEY_CAMERA, input->keybit); 45 | 46 | if ((ret = input_register_device(input)) < 0) 47 | goto error; 48 | 49 | dev->input = input; 50 | return 0; 51 | 52 | error: 53 | input_free_device(input); 54 | return ret; 55 | } 56 | 57 | static void uvc_input_cleanup(struct uvc_device *dev) 58 | { 59 | if (dev->input) 60 | input_unregister_device(dev->input); 61 | } 62 | 63 | static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, 64 | int value) 65 | { 66 | if (dev->input) { 67 | input_report_key(dev->input, code, value); 68 | input_sync(dev->input); 69 | } 70 | } 71 | 72 | #else 73 | #define uvc_input_init(dev) 74 | #define uvc_input_cleanup(dev) 75 | #define uvc_input_report_key(dev, code, value) 76 | #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ 77 | 78 | /* -------------------------------------------------------------------------- 79 | * Status interrupt endpoint 80 | */ 81 | static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) 82 | { 83 | if (len < 3) { 84 | uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " 85 | "received.\n"); 86 | return; 87 | } 88 | 89 | if (data[2] == 0) { 90 | if (len < 4) 91 | return; 92 | uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", 93 | data[1], data[3] ? "pressed" : "released", len); 94 | uvc_input_report_key(dev, KEY_CAMERA, data[3]); 95 | } else { 96 | uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " 97 | "len %d.\n", data[1], data[2], data[3], len); 98 | } 99 | } 100 | 101 | static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) 102 | { 103 | char *attrs[3] = { "value", "info", "failure" }; 104 | 105 | if (len < 6 || data[2] != 0 || data[4] > 2) { 106 | uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " 107 | "received.\n"); 108 | return; 109 | } 110 | 111 | uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", 112 | data[1], data[3], attrs[data[4]], len); 113 | } 114 | 115 | static void uvc_status_complete(struct urb *urb) 116 | { 117 | struct uvc_device *dev = urb->context; 118 | int len, ret; 119 | 120 | switch (urb->status) { 121 | case 0: 122 | break; 123 | 124 | case -ENOENT: /* usb_kill_urb() called. */ 125 | case -ECONNRESET: /* usb_unlink_urb() called. */ 126 | case -ESHUTDOWN: /* The endpoint is being disabled. */ 127 | case -EPROTO: /* Device is disconnected (reported by some 128 | * host controller). */ 129 | return; 130 | 131 | default: 132 | uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " 133 | "completion handler.\n", urb->status); 134 | return; 135 | } 136 | 137 | len = urb->actual_length; 138 | if (len > 0) { 139 | switch (dev->status[0] & 0x0f) { 140 | case UVC_STATUS_TYPE_CONTROL: 141 | uvc_event_control(dev, dev->status, len); 142 | break; 143 | 144 | case UVC_STATUS_TYPE_STREAMING: 145 | uvc_event_streaming(dev, dev->status, len); 146 | break; 147 | 148 | default: 149 | uvc_trace(UVC_TRACE_STATUS, "Unknown status event " 150 | "type %u.\n", dev->status[0]); 151 | break; 152 | } 153 | } 154 | 155 | /* Resubmit the URB. */ 156 | urb->interval = dev->int_ep->desc.bInterval; 157 | if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 158 | uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", 159 | ret); 160 | } 161 | } 162 | 163 | int uvc_status_init(struct uvc_device *dev) 164 | { 165 | struct usb_host_endpoint *ep = dev->int_ep; 166 | unsigned int pipe; 167 | int interval; 168 | 169 | if (ep == NULL) 170 | return 0; 171 | 172 | uvc_input_init(dev); 173 | 174 | dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL); 175 | if (dev->status == NULL) 176 | return -ENOMEM; 177 | 178 | dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 179 | if (dev->int_urb == NULL) { 180 | kfree(dev->status); 181 | return -ENOMEM; 182 | } 183 | 184 | pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); 185 | 186 | /* For high-speed interrupt endpoints, the bInterval value is used as 187 | * an exponent of two. Some developers forgot about it. 188 | */ 189 | interval = ep->desc.bInterval; 190 | if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && 191 | (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) 192 | interval = fls(interval) - 1; 193 | 194 | usb_fill_int_urb(dev->int_urb, dev->udev, pipe, 195 | dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, 196 | dev, interval); 197 | 198 | return 0; 199 | } 200 | 201 | void uvc_status_cleanup(struct uvc_device *dev) 202 | { 203 | usb_kill_urb(dev->int_urb); 204 | usb_free_urb(dev->int_urb); 205 | kfree(dev->status); 206 | uvc_input_cleanup(dev); 207 | } 208 | 209 | int uvc_status_start(struct uvc_device *dev) 210 | { 211 | if (dev->int_urb == NULL) 212 | return 0; 213 | 214 | return usb_submit_urb(dev->int_urb, GFP_KERNEL); 215 | } 216 | 217 | void uvc_status_stop(struct uvc_device *dev) 218 | { 219 | usb_kill_urb(dev->int_urb); 220 | } 221 | 222 | int uvc_status_suspend(struct uvc_device *dev) 223 | { 224 | if (atomic_read(&dev->users)) 225 | usb_kill_urb(dev->int_urb); 226 | 227 | return 0; 228 | } 229 | 230 | int uvc_status_resume(struct uvc_device *dev) 231 | { 232 | if (dev->int_urb == NULL || atomic_read(&dev->users) == 0) 233 | return 0; 234 | 235 | return usb_submit_urb(dev->int_urb, GFP_NOIO); 236 | } 237 | 238 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvc_v4l2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_v4l2.c -- USB Video Class driver - V4L2 API 3 | * 4 | * Copyright (C) 2005-2010 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include "uvcvideo.h" 30 | 31 | /* ------------------------------------------------------------------------ 32 | * UVC ioctls 33 | */ 34 | static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, 35 | struct uvc_xu_control_mapping *xmap) 36 | { 37 | struct uvc_control_mapping *map; 38 | unsigned int size; 39 | int ret; 40 | 41 | map = kzalloc(sizeof *map, GFP_KERNEL); 42 | if (map == NULL) 43 | return -ENOMEM; 44 | 45 | map->id = xmap->id; 46 | memcpy(map->name, xmap->name, sizeof map->name); 47 | memcpy(map->entity, xmap->entity, sizeof map->entity); 48 | map->selector = xmap->selector; 49 | map->size = xmap->size; 50 | map->offset = xmap->offset; 51 | map->v4l2_type = xmap->v4l2_type; 52 | map->data_type = xmap->data_type; 53 | 54 | switch (xmap->v4l2_type) { 55 | case V4L2_CTRL_TYPE_INTEGER: 56 | case V4L2_CTRL_TYPE_BOOLEAN: 57 | case V4L2_CTRL_TYPE_BUTTON: 58 | break; 59 | 60 | case V4L2_CTRL_TYPE_MENU: 61 | /* Prevent excessive memory consumption, as well as integer 62 | * overflows. 63 | */ 64 | if (xmap->menu_count == 0 || 65 | xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { 66 | ret = -EINVAL; 67 | goto done; 68 | } 69 | 70 | size = xmap->menu_count * sizeof(*map->menu_info); 71 | map->menu_info = kmalloc(size, GFP_KERNEL); 72 | if (map->menu_info == NULL) { 73 | ret = -ENOMEM; 74 | goto done; 75 | } 76 | 77 | if (copy_from_user(map->menu_info, xmap->menu_info, size)) { 78 | ret = -EFAULT; 79 | goto done; 80 | } 81 | 82 | map->menu_count = xmap->menu_count; 83 | break; 84 | 85 | default: 86 | uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type " 87 | "%u.\n", xmap->v4l2_type); 88 | ret = -ENOTTY; 89 | goto done; 90 | } 91 | 92 | ret = uvc_ctrl_add_mapping(chain, map); 93 | 94 | done: 95 | kfree(map->menu_info); 96 | kfree(map); 97 | 98 | return ret; 99 | } 100 | 101 | /* ------------------------------------------------------------------------ 102 | * V4L2 interface 103 | */ 104 | 105 | /* 106 | * Find the frame interval closest to the requested frame interval for the 107 | * given frame format and size. This should be done by the device as part of 108 | * the Video Probe and Commit negotiation, but some hardware don't implement 109 | * that feature. 110 | */ 111 | static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) 112 | { 113 | unsigned int i; 114 | 115 | if (frame->bFrameIntervalType) { 116 | __u32 best = -1, dist; 117 | 118 | for (i = 0; i < frame->bFrameIntervalType; ++i) { 119 | dist = interval > frame->dwFrameInterval[i] 120 | ? interval - frame->dwFrameInterval[i] 121 | : frame->dwFrameInterval[i] - interval; 122 | 123 | if (dist > best) 124 | break; 125 | 126 | best = dist; 127 | } 128 | 129 | interval = frame->dwFrameInterval[i-1]; 130 | } else { 131 | const __u32 min = frame->dwFrameInterval[0]; 132 | const __u32 max = frame->dwFrameInterval[1]; 133 | const __u32 step = frame->dwFrameInterval[2]; 134 | 135 | interval = min + (interval - min + step/2) / step * step; 136 | if (interval > max) 137 | interval = max; 138 | } 139 | 140 | return interval; 141 | } 142 | 143 | static int uvc_v4l2_try_format(struct uvc_streaming *stream, 144 | struct v4l2_format *fmt, struct uvc_streaming_control *probe, 145 | struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) 146 | { 147 | struct uvc_format *format = NULL; 148 | struct uvc_frame *frame = NULL; 149 | __u16 rw, rh; 150 | unsigned int d, maxd; 151 | unsigned int i; 152 | __u32 interval; 153 | int ret = 0; 154 | __u8 *fcc; 155 | 156 | if (fmt->type != stream->type) 157 | return -EINVAL; 158 | 159 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; 160 | uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n", 161 | fmt->fmt.pix.pixelformat, 162 | fcc[0], fcc[1], fcc[2], fcc[3], 163 | fmt->fmt.pix.width, fmt->fmt.pix.height); 164 | 165 | /* Check if the hardware supports the requested format. */ 166 | for (i = 0; i < stream->nformats; ++i) { 167 | format = &stream->format[i]; 168 | if (format->fcc == fmt->fmt.pix.pixelformat) 169 | break; 170 | } 171 | 172 | if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { 173 | uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n", 174 | fmt->fmt.pix.pixelformat); 175 | return -EINVAL; 176 | } 177 | 178 | /* Find the closest image size. The distance between image sizes is 179 | * the size in pixels of the non-overlapping regions between the 180 | * requested size and the frame-specified size. 181 | */ 182 | rw = fmt->fmt.pix.width; 183 | rh = fmt->fmt.pix.height; 184 | maxd = (unsigned int)-1; 185 | 186 | for (i = 0; i < format->nframes; ++i) { 187 | __u16 w = format->frame[i].wWidth; 188 | __u16 h = format->frame[i].wHeight; 189 | 190 | d = min(w, rw) * min(h, rh); 191 | d = w*h + rw*rh - 2*d; 192 | if (d < maxd) { 193 | maxd = d; 194 | frame = &format->frame[i]; 195 | } 196 | 197 | if (maxd == 0) 198 | break; 199 | } 200 | 201 | if (frame == NULL) { 202 | uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n", 203 | fmt->fmt.pix.width, fmt->fmt.pix.height); 204 | return -EINVAL; 205 | } 206 | 207 | /* Use the default frame interval. */ 208 | interval = frame->dwDefaultFrameInterval; 209 | uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us " 210 | "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval, 211 | (100000000/interval)%10); 212 | 213 | /* Set the format index, frame index and frame interval. */ 214 | memset(probe, 0, sizeof *probe); 215 | probe->bmHint = 1; /* dwFrameInterval */ 216 | probe->bFormatIndex = format->index; 217 | probe->bFrameIndex = frame->bFrameIndex; 218 | probe->dwFrameInterval = uvc_try_frame_interval(frame, interval); 219 | /* Some webcams stall the probe control set request when the 220 | * dwMaxVideoFrameSize field is set to zero. The UVC specification 221 | * clearly states that the field is read-only from the host, so this 222 | * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by 223 | * the webcam to work around the problem. 224 | * 225 | * The workaround could probably be enabled for all webcams, so the 226 | * quirk can be removed if needed. It's currently useful to detect 227 | * webcam bugs and fix them before they hit the market (providing 228 | * developers test their webcams with the Linux driver as well as with 229 | * the Windows driver). 230 | */ 231 | mutex_lock(&stream->mutex); 232 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) 233 | probe->dwMaxVideoFrameSize = 234 | stream->ctrl.dwMaxVideoFrameSize; 235 | 236 | /* Probe the device. */ 237 | ret = uvc_probe_video(stream, probe); 238 | mutex_unlock(&stream->mutex); 239 | if (ret < 0) 240 | goto done; 241 | 242 | fmt->fmt.pix.width = frame->wWidth; 243 | fmt->fmt.pix.height = frame->wHeight; 244 | fmt->fmt.pix.field = V4L2_FIELD_NONE; 245 | fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; 246 | fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize; 247 | fmt->fmt.pix.colorspace = format->colorspace; 248 | fmt->fmt.pix.priv = 0; 249 | 250 | if (uvc_format != NULL) 251 | *uvc_format = format; 252 | if (uvc_frame != NULL) 253 | *uvc_frame = frame; 254 | 255 | done: 256 | return ret; 257 | } 258 | 259 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, 260 | struct v4l2_format *fmt) 261 | { 262 | struct uvc_format *format; 263 | struct uvc_frame *frame; 264 | int ret = 0; 265 | 266 | if (fmt->type != stream->type) 267 | return -EINVAL; 268 | 269 | mutex_lock(&stream->mutex); 270 | format = stream->cur_format; 271 | frame = stream->cur_frame; 272 | 273 | if (format == NULL || frame == NULL) { 274 | ret = -EINVAL; 275 | goto done; 276 | } 277 | 278 | fmt->fmt.pix.pixelformat = format->fcc; 279 | fmt->fmt.pix.width = frame->wWidth; 280 | fmt->fmt.pix.height = frame->wHeight; 281 | fmt->fmt.pix.field = V4L2_FIELD_NONE; 282 | fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; 283 | fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize; 284 | fmt->fmt.pix.colorspace = format->colorspace; 285 | fmt->fmt.pix.priv = 0; 286 | 287 | done: 288 | mutex_unlock(&stream->mutex); 289 | return ret; 290 | } 291 | 292 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, 293 | struct v4l2_format *fmt) 294 | { 295 | struct uvc_streaming_control probe; 296 | struct uvc_format *format; 297 | struct uvc_frame *frame; 298 | int ret; 299 | 300 | if (fmt->type != stream->type) 301 | return -EINVAL; 302 | 303 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); 304 | if (ret < 0) 305 | return ret; 306 | 307 | mutex_lock(&stream->mutex); 308 | 309 | if (uvc_queue_allocated(&stream->queue)) { 310 | ret = -EBUSY; 311 | goto done; 312 | } 313 | 314 | memcpy(&stream->ctrl, &probe, sizeof probe); 315 | stream->cur_format = format; 316 | stream->cur_frame = frame; 317 | 318 | done: 319 | mutex_unlock(&stream->mutex); 320 | return ret; 321 | } 322 | 323 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, 324 | struct v4l2_streamparm *parm) 325 | { 326 | uint32_t numerator, denominator; 327 | 328 | if (parm->type != stream->type) 329 | return -EINVAL; 330 | 331 | mutex_lock(&stream->mutex); 332 | numerator = stream->ctrl.dwFrameInterval; 333 | mutex_unlock(&stream->mutex); 334 | 335 | denominator = 10000000; 336 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); 337 | 338 | memset(parm, 0, sizeof *parm); 339 | parm->type = stream->type; 340 | 341 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 342 | parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 343 | parm->parm.capture.capturemode = 0; 344 | parm->parm.capture.timeperframe.numerator = numerator; 345 | parm->parm.capture.timeperframe.denominator = denominator; 346 | parm->parm.capture.extendedmode = 0; 347 | parm->parm.capture.readbuffers = 0; 348 | } else { 349 | parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 350 | parm->parm.output.outputmode = 0; 351 | parm->parm.output.timeperframe.numerator = numerator; 352 | parm->parm.output.timeperframe.denominator = denominator; 353 | } 354 | 355 | return 0; 356 | } 357 | 358 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, 359 | struct v4l2_streamparm *parm) 360 | { 361 | struct uvc_streaming_control probe; 362 | struct v4l2_fract timeperframe; 363 | uint32_t interval; 364 | int ret; 365 | 366 | if (parm->type != stream->type) 367 | return -EINVAL; 368 | 369 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 370 | timeperframe = parm->parm.capture.timeperframe; 371 | else 372 | timeperframe = parm->parm.output.timeperframe; 373 | 374 | interval = uvc_fraction_to_interval(timeperframe.numerator, 375 | timeperframe.denominator); 376 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", 377 | timeperframe.numerator, timeperframe.denominator, interval); 378 | 379 | mutex_lock(&stream->mutex); 380 | 381 | if (uvc_queue_streaming(&stream->queue)) { 382 | mutex_unlock(&stream->mutex); 383 | return -EBUSY; 384 | } 385 | 386 | memcpy(&probe, &stream->ctrl, sizeof probe); 387 | probe.dwFrameInterval = 388 | uvc_try_frame_interval(stream->cur_frame, interval); 389 | 390 | /* Probe the device with the new settings. */ 391 | ret = uvc_probe_video(stream, &probe); 392 | if (ret < 0) { 393 | mutex_unlock(&stream->mutex); 394 | return ret; 395 | } 396 | 397 | memcpy(&stream->ctrl, &probe, sizeof probe); 398 | mutex_unlock(&stream->mutex); 399 | 400 | /* Return the actual frame period. */ 401 | timeperframe.numerator = probe.dwFrameInterval; 402 | timeperframe.denominator = 10000000; 403 | uvc_simplify_fraction(&timeperframe.numerator, 404 | &timeperframe.denominator, 8, 333); 405 | 406 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 407 | { 408 | parm->parm.capture.timeperframe = timeperframe; 409 | //transfer dwMaxPayloadTransferSize to AP 410 | parm->parm.capture.reserved[0] = probe.dwMaxPayloadTransferSize; 411 | } 412 | else 413 | parm->parm.output.timeperframe = timeperframe; 414 | 415 | return 0; 416 | } 417 | 418 | /* ------------------------------------------------------------------------ 419 | * Privilege management 420 | */ 421 | 422 | /* 423 | * Privilege management is the multiple-open implementation basis. The current 424 | * implementation is completely transparent for the end-user and doesn't 425 | * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls. 426 | * Those ioctls enable finer control on the device (by making possible for a 427 | * user to request exclusive access to a device), but are not mature yet. 428 | * Switching to the V4L2 priority mechanism might be considered in the future 429 | * if this situation changes. 430 | * 431 | * Each open instance of a UVC device can either be in a privileged or 432 | * unprivileged state. Only a single instance can be in a privileged state at 433 | * a given time. Trying to perform an operation that requires privileges will 434 | * automatically acquire the required privileges if possible, or return -EBUSY 435 | * otherwise. Privileges are dismissed when closing the instance or when 436 | * freeing the video buffers using VIDIOC_REQBUFS. 437 | * 438 | * Operations that require privileges are: 439 | * 440 | * - VIDIOC_S_INPUT 441 | * - VIDIOC_S_PARM 442 | * - VIDIOC_S_FMT 443 | * - VIDIOC_REQBUFS 444 | */ 445 | static int uvc_acquire_privileges(struct uvc_fh *handle) 446 | { 447 | /* Always succeed if the handle is already privileged. */ 448 | if (handle->state == UVC_HANDLE_ACTIVE) 449 | return 0; 450 | 451 | /* Check if the device already has a privileged handle. */ 452 | if (atomic_inc_return(&handle->stream->active) != 1) { 453 | atomic_dec(&handle->stream->active); 454 | return -EBUSY; 455 | } 456 | 457 | handle->state = UVC_HANDLE_ACTIVE; 458 | return 0; 459 | } 460 | 461 | static void uvc_dismiss_privileges(struct uvc_fh *handle) 462 | { 463 | if (handle->state == UVC_HANDLE_ACTIVE) 464 | atomic_dec(&handle->stream->active); 465 | 466 | handle->state = UVC_HANDLE_PASSIVE; 467 | } 468 | 469 | static int uvc_has_privileges(struct uvc_fh *handle) 470 | { 471 | return handle->state == UVC_HANDLE_ACTIVE; 472 | } 473 | 474 | /* ------------------------------------------------------------------------ 475 | * V4L2 file operations 476 | */ 477 | 478 | static int uvc_v4l2_open(struct file *file) 479 | { 480 | struct uvc_streaming *stream; 481 | struct uvc_fh *handle; 482 | int ret = 0; 483 | 484 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); 485 | stream = video_drvdata(file); 486 | 487 | if (stream->dev->state & UVC_DEV_DISCONNECTED) 488 | return -ENODEV; 489 | 490 | ret = usb_autopm_get_interface(stream->dev->intf); 491 | if (ret < 0) 492 | return ret; 493 | 494 | /* Create the device handle. */ 495 | handle = kzalloc(sizeof *handle, GFP_KERNEL); 496 | if (handle == NULL) { 497 | usb_autopm_put_interface(stream->dev->intf); 498 | return -ENOMEM; 499 | } 500 | 501 | if (atomic_inc_return(&stream->dev->users) == 1) { 502 | ret = uvc_status_start(stream->dev); 503 | if (ret < 0) { 504 | usb_autopm_put_interface(stream->dev->intf); 505 | atomic_dec(&stream->dev->users); 506 | kfree(handle); 507 | return ret; 508 | } 509 | } 510 | 511 | handle->chain = stream->chain; 512 | handle->stream = stream; 513 | handle->state = UVC_HANDLE_PASSIVE; 514 | file->private_data = handle; 515 | 516 | return 0; 517 | } 518 | 519 | static int uvc_v4l2_release(struct file *file) 520 | { 521 | struct uvc_fh *handle = file->private_data; 522 | struct uvc_streaming *stream = handle->stream; 523 | 524 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); 525 | 526 | /* Only free resources if this is a privileged handle. */ 527 | if (uvc_has_privileges(handle)) { 528 | uvc_video_enable(stream, 0); 529 | uvc_free_buffers(&stream->queue); 530 | } 531 | 532 | /* Release the file handle. */ 533 | uvc_dismiss_privileges(handle); 534 | kfree(handle); 535 | file->private_data = NULL; 536 | 537 | if (atomic_dec_return(&stream->dev->users) == 0) 538 | uvc_status_stop(stream->dev); 539 | 540 | usb_autopm_put_interface(stream->dev->intf); 541 | return 0; 542 | } 543 | 544 | static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) 545 | { 546 | struct video_device *vdev = video_devdata(file); 547 | struct uvc_fh *handle = file->private_data; 548 | struct uvc_video_chain *chain = handle->chain; 549 | struct uvc_streaming *stream = handle->stream; 550 | long ret = 0; 551 | 552 | switch (cmd) { 553 | /* Query capabilities */ 554 | case VIDIOC_QUERYCAP: 555 | { 556 | struct v4l2_capability *cap = arg; 557 | 558 | memset(cap, 0, sizeof *cap); 559 | strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); 560 | strlcpy(cap->card, vdev->name, sizeof cap->card); 561 | usb_make_path(stream->dev->udev, 562 | cap->bus_info, sizeof(cap->bus_info)); 563 | cap->version = LINUX_VERSION_CODE; 564 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 565 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE 566 | | V4L2_CAP_STREAMING; 567 | else 568 | cap->capabilities = V4L2_CAP_VIDEO_OUTPUT 569 | | V4L2_CAP_STREAMING; 570 | break; 571 | } 572 | 573 | /* Get, Set & Query control */ 574 | case VIDIOC_QUERYCTRL: 575 | return uvc_query_v4l2_ctrl(chain, arg); 576 | 577 | case VIDIOC_G_CTRL: 578 | { 579 | struct v4l2_control *ctrl = arg; 580 | struct v4l2_ext_control xctrl; 581 | 582 | memset(&xctrl, 0, sizeof xctrl); 583 | xctrl.id = ctrl->id; 584 | 585 | ret = uvc_ctrl_begin(chain); 586 | if (ret < 0) 587 | return ret; 588 | 589 | ret = uvc_ctrl_get(chain, &xctrl); 590 | uvc_ctrl_rollback(chain); 591 | if (ret >= 0) 592 | ctrl->value = xctrl.value; 593 | break; 594 | } 595 | 596 | case VIDIOC_S_CTRL: 597 | { 598 | struct v4l2_control *ctrl = arg; 599 | struct v4l2_ext_control xctrl; 600 | 601 | memset(&xctrl, 0, sizeof xctrl); 602 | xctrl.id = ctrl->id; 603 | xctrl.value = ctrl->value; 604 | 605 | ret = uvc_ctrl_begin(chain); 606 | if (ret < 0) 607 | return ret; 608 | 609 | ret = uvc_ctrl_set(chain, &xctrl); 610 | if (ret < 0) { 611 | uvc_ctrl_rollback(chain); 612 | return ret; 613 | } 614 | ret = uvc_ctrl_commit(chain); 615 | if (ret == 0) 616 | ctrl->value = xctrl.value; 617 | break; 618 | } 619 | 620 | case VIDIOC_QUERYMENU: 621 | return uvc_query_v4l2_menu(chain, arg); 622 | 623 | case VIDIOC_G_EXT_CTRLS: 624 | { 625 | struct v4l2_ext_controls *ctrls = arg; 626 | struct v4l2_ext_control *ctrl = ctrls->controls; 627 | unsigned int i; 628 | 629 | ret = uvc_ctrl_begin(chain); 630 | if (ret < 0) 631 | return ret; 632 | 633 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { 634 | ret = uvc_ctrl_get(chain, ctrl); 635 | if (ret < 0) { 636 | uvc_ctrl_rollback(chain); 637 | ctrls->error_idx = i; 638 | return ret; 639 | } 640 | } 641 | ctrls->error_idx = 0; 642 | ret = uvc_ctrl_rollback(chain); 643 | break; 644 | } 645 | 646 | case VIDIOC_S_EXT_CTRLS: 647 | case VIDIOC_TRY_EXT_CTRLS: 648 | { 649 | struct v4l2_ext_controls *ctrls = arg; 650 | struct v4l2_ext_control *ctrl = ctrls->controls; 651 | unsigned int i; 652 | 653 | ret = uvc_ctrl_begin(chain); 654 | if (ret < 0) 655 | return ret; 656 | 657 | for (i = 0; i < ctrls->count; ++ctrl, ++i) { 658 | ret = uvc_ctrl_set(chain, ctrl); 659 | if (ret < 0) { 660 | uvc_ctrl_rollback(chain); 661 | ctrls->error_idx = i; 662 | return ret; 663 | } 664 | } 665 | 666 | ctrls->error_idx = 0; 667 | 668 | if (cmd == VIDIOC_S_EXT_CTRLS) 669 | ret = uvc_ctrl_commit(chain); 670 | else 671 | ret = uvc_ctrl_rollback(chain); 672 | break; 673 | } 674 | 675 | /* Get, Set & Enum input */ 676 | case VIDIOC_ENUMINPUT: 677 | { 678 | const struct uvc_entity *selector = chain->selector; 679 | struct v4l2_input *input = arg; 680 | struct uvc_entity *iterm = NULL; 681 | u32 index = input->index; 682 | int pin = 0; 683 | 684 | if (selector == NULL || 685 | (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 686 | if (index != 0) 687 | return -EINVAL; 688 | list_for_each_entry(iterm, &chain->entities, chain) { 689 | if (UVC_ENTITY_IS_ITERM(iterm)) 690 | break; 691 | } 692 | pin = iterm->id; 693 | } else if (index < selector->bNrInPins) { 694 | pin = selector->baSourceID[index]; 695 | list_for_each_entry(iterm, &chain->entities, chain) { 696 | if (!UVC_ENTITY_IS_ITERM(iterm)) 697 | continue; 698 | if (iterm->id == pin) 699 | break; 700 | } 701 | } 702 | 703 | if (iterm == NULL || iterm->id != pin) 704 | return -EINVAL; 705 | 706 | memset(input, 0, sizeof *input); 707 | input->index = index; 708 | strlcpy(input->name, iterm->name, sizeof input->name); 709 | if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) 710 | input->type = V4L2_INPUT_TYPE_CAMERA; 711 | break; 712 | } 713 | 714 | case VIDIOC_G_INPUT: 715 | { 716 | u8 input; 717 | 718 | if (chain->selector == NULL || 719 | (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 720 | *(int *)arg = 0; 721 | break; 722 | } 723 | 724 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, 725 | chain->selector->id, chain->dev->intfnum, 726 | UVC_SU_INPUT_SELECT_CONTROL, &input, 1); 727 | if (ret < 0) 728 | return ret; 729 | 730 | *(int *)arg = input - 1; 731 | break; 732 | } 733 | 734 | case VIDIOC_S_INPUT: 735 | { 736 | u32 input = *(u32 *)arg + 1; 737 | 738 | if ((ret = uvc_acquire_privileges(handle)) < 0) 739 | return ret; 740 | 741 | if (chain->selector == NULL || 742 | (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 743 | if (input != 1) 744 | return -EINVAL; 745 | break; 746 | } 747 | 748 | if (input == 0 || input > chain->selector->bNrInPins) 749 | return -EINVAL; 750 | 751 | return uvc_query_ctrl(chain->dev, UVC_SET_CUR, 752 | chain->selector->id, chain->dev->intfnum, 753 | UVC_SU_INPUT_SELECT_CONTROL, &input, 1); 754 | } 755 | 756 | /* Try, Get, Set & Enum format */ 757 | case VIDIOC_ENUM_FMT: 758 | { 759 | struct v4l2_fmtdesc *fmt = arg; 760 | struct uvc_format *format; 761 | enum v4l2_buf_type type = fmt->type; 762 | __u32 index = fmt->index; 763 | 764 | if (fmt->type != stream->type || 765 | fmt->index >= stream->nformats) 766 | return -EINVAL; 767 | 768 | memset(fmt, 0, sizeof(*fmt)); 769 | fmt->index = index; 770 | fmt->type = type; 771 | 772 | format = &stream->format[fmt->index]; 773 | fmt->flags = 0; 774 | if (format->flags & UVC_FMT_FLAG_COMPRESSED) 775 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; 776 | strlcpy(fmt->description, format->name, 777 | sizeof fmt->description); 778 | fmt->description[sizeof fmt->description - 1] = 0; 779 | fmt->pixelformat = format->fcc; 780 | break; 781 | } 782 | 783 | case VIDIOC_TRY_FMT: 784 | { 785 | struct uvc_streaming_control probe; 786 | 787 | return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); 788 | } 789 | 790 | case VIDIOC_S_FMT: 791 | if ((ret = uvc_acquire_privileges(handle)) < 0) 792 | return ret; 793 | 794 | return uvc_v4l2_set_format(stream, arg); 795 | 796 | case VIDIOC_G_FMT: 797 | return uvc_v4l2_get_format(stream, arg); 798 | 799 | /* Frame size enumeration */ 800 | case VIDIOC_ENUM_FRAMESIZES: 801 | { 802 | struct v4l2_frmsizeenum *fsize = arg; 803 | struct uvc_format *format = NULL; 804 | struct uvc_frame *frame; 805 | int i; 806 | 807 | /* Look for the given pixel format */ 808 | for (i = 0; i < stream->nformats; i++) { 809 | if (stream->format[i].fcc == 810 | fsize->pixel_format) { 811 | format = &stream->format[i]; 812 | break; 813 | } 814 | } 815 | if (format == NULL) 816 | return -EINVAL; 817 | 818 | if (fsize->index >= format->nframes) 819 | return -EINVAL; 820 | 821 | frame = &format->frame[fsize->index]; 822 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 823 | fsize->discrete.width = frame->wWidth; 824 | fsize->discrete.height = frame->wHeight; 825 | break; 826 | } 827 | 828 | /* Frame interval enumeration */ 829 | case VIDIOC_ENUM_FRAMEINTERVALS: 830 | { 831 | struct v4l2_frmivalenum *fival = arg; 832 | struct uvc_format *format = NULL; 833 | struct uvc_frame *frame = NULL; 834 | int i; 835 | 836 | /* Look for the given pixel format and frame size */ 837 | for (i = 0; i < stream->nformats; i++) { 838 | if (stream->format[i].fcc == 839 | fival->pixel_format) { 840 | format = &stream->format[i]; 841 | break; 842 | } 843 | } 844 | if (format == NULL) 845 | return -EINVAL; 846 | 847 | for (i = 0; i < format->nframes; i++) { 848 | if (format->frame[i].wWidth == fival->width && 849 | format->frame[i].wHeight == fival->height) { 850 | frame = &format->frame[i]; 851 | break; 852 | } 853 | } 854 | if (frame == NULL) 855 | return -EINVAL; 856 | 857 | if (frame->bFrameIntervalType) { 858 | if (fival->index >= frame->bFrameIntervalType) 859 | return -EINVAL; 860 | 861 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 862 | fival->discrete.numerator = 863 | frame->dwFrameInterval[fival->index]; 864 | fival->discrete.denominator = 10000000; 865 | uvc_simplify_fraction(&fival->discrete.numerator, 866 | &fival->discrete.denominator, 8, 333); 867 | } else { 868 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 869 | fival->stepwise.min.numerator = 870 | frame->dwFrameInterval[0]; 871 | fival->stepwise.min.denominator = 10000000; 872 | fival->stepwise.max.numerator = 873 | frame->dwFrameInterval[1]; 874 | fival->stepwise.max.denominator = 10000000; 875 | fival->stepwise.step.numerator = 876 | frame->dwFrameInterval[2]; 877 | fival->stepwise.step.denominator = 10000000; 878 | uvc_simplify_fraction(&fival->stepwise.min.numerator, 879 | &fival->stepwise.min.denominator, 8, 333); 880 | uvc_simplify_fraction(&fival->stepwise.max.numerator, 881 | &fival->stepwise.max.denominator, 8, 333); 882 | uvc_simplify_fraction(&fival->stepwise.step.numerator, 883 | &fival->stepwise.step.denominator, 8, 333); 884 | } 885 | break; 886 | } 887 | 888 | /* Get & Set streaming parameters */ 889 | case VIDIOC_G_PARM: 890 | return uvc_v4l2_get_streamparm(stream, arg); 891 | 892 | case VIDIOC_S_PARM: 893 | if ((ret = uvc_acquire_privileges(handle)) < 0) 894 | return ret; 895 | 896 | return uvc_v4l2_set_streamparm(stream, arg); 897 | 898 | /* Cropping and scaling */ 899 | case VIDIOC_CROPCAP: 900 | { 901 | struct v4l2_cropcap *ccap = arg; 902 | 903 | if (ccap->type != stream->type) 904 | return -EINVAL; 905 | 906 | ccap->bounds.left = 0; 907 | ccap->bounds.top = 0; 908 | 909 | mutex_lock(&stream->mutex); 910 | ccap->bounds.width = stream->cur_frame->wWidth; 911 | ccap->bounds.height = stream->cur_frame->wHeight; 912 | mutex_unlock(&stream->mutex); 913 | 914 | ccap->defrect = ccap->bounds; 915 | 916 | ccap->pixelaspect.numerator = 1; 917 | ccap->pixelaspect.denominator = 1; 918 | break; 919 | } 920 | 921 | case VIDIOC_G_CROP: 922 | case VIDIOC_S_CROP: 923 | return -EINVAL; 924 | 925 | /* Buffers & streaming */ 926 | case VIDIOC_REQBUFS: 927 | if ((ret = uvc_acquire_privileges(handle)) < 0) 928 | return ret; 929 | 930 | mutex_lock(&stream->mutex); 931 | ret = uvc_alloc_buffers(&stream->queue, arg); 932 | mutex_unlock(&stream->mutex); 933 | if (ret < 0) 934 | return ret; 935 | 936 | if (ret == 0) 937 | uvc_dismiss_privileges(handle); 938 | 939 | ret = 0; 940 | break; 941 | 942 | case VIDIOC_QUERYBUF: 943 | { 944 | struct v4l2_buffer *buf = arg; 945 | 946 | if (!uvc_has_privileges(handle)) 947 | return -EBUSY; 948 | 949 | return uvc_query_buffer(&stream->queue, buf); 950 | } 951 | 952 | case VIDIOC_QBUF: 953 | if (!uvc_has_privileges(handle)) 954 | return -EBUSY; 955 | 956 | return uvc_queue_buffer(&stream->queue, arg); 957 | 958 | case VIDIOC_DQBUF: 959 | { 960 | int ret = 0, counter = 4; 961 | bool IsH264_16X16 = 0, IsMJ_MarkerErr = 0; 962 | struct v4l2_buffer *buf = arg; 963 | 964 | if (!uvc_has_privileges(handle)) 965 | return -EBUSY; 966 | ret = uvc_dequeue_buffer(&stream->queue, buf, file->f_flags & O_NONBLOCK); 967 | 968 | 969 | 970 | IsH264_16X16 = stream->cur_format->fcc == V4L2_PIX_FMT_H264 && buf->reserved == 0x00100010; 971 | IsMJ_MarkerErr = stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG && (buf->reserved&0x80000000); 972 | 973 | while(((stream->dev->RER_Chip == CHIP_RER9421)||(stream->dev->RER_Chip == CHIP_RER9422))&& 974 | (IsH264_16X16 || IsMJ_MarkerErr) && counter>0) 975 | { 976 | //remove frame data while checking error 977 | counter --; 978 | uvc_queue_buffer(&stream->queue, buf); 979 | ret = uvc_dequeue_buffer(&stream->queue, arg, 0); //set block mode(0) to wait for data of next buffer 980 | IsH264_16X16 = stream->cur_format->fcc == V4L2_PIX_FMT_H264 && buf->reserved == 0x00100010; 981 | IsMJ_MarkerErr = stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG && (buf->reserved&0x80000000); 982 | } 983 | buf->reserved &= (~0x80000000); //clear marker error bit 984 | return ret; 985 | } 986 | case VIDIOC_STREAMON: 987 | { 988 | int *type = arg; 989 | 990 | if (*type != stream->type) 991 | return -EINVAL; 992 | 993 | if (!uvc_has_privileges(handle)) 994 | return -EBUSY; 995 | 996 | mutex_lock(&stream->mutex); 997 | ret = uvc_video_enable(stream, 1); 998 | mutex_unlock(&stream->mutex); 999 | if (ret < 0) 1000 | return ret; 1001 | break; 1002 | } 1003 | 1004 | case VIDIOC_STREAMOFF: 1005 | { 1006 | int *type = arg; 1007 | 1008 | if (*type != stream->type) 1009 | return -EINVAL; 1010 | 1011 | if (!uvc_has_privileges(handle)) 1012 | return -EBUSY; 1013 | 1014 | return uvc_video_enable(stream, 0); 1015 | } 1016 | 1017 | /* Analog video standards make no sense for digital cameras. */ 1018 | case VIDIOC_ENUMSTD: 1019 | case VIDIOC_QUERYSTD: 1020 | case VIDIOC_G_STD: 1021 | case VIDIOC_S_STD: 1022 | 1023 | case VIDIOC_OVERLAY: 1024 | 1025 | case VIDIOC_ENUMAUDIO: 1026 | case VIDIOC_ENUMAUDOUT: 1027 | 1028 | case VIDIOC_ENUMOUTPUT: 1029 | uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); 1030 | return -EINVAL; 1031 | 1032 | case UVCIOC_CTRL_MAP: 1033 | return uvc_ioctl_ctrl_map(chain, arg); 1034 | 1035 | case UVCIOC_CTRL_QUERY: 1036 | return uvc_xu_ctrl_query(chain, arg); 1037 | 1038 | default: 1039 | uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); 1040 | return -EINVAL; 1041 | } 1042 | 1043 | return ret; 1044 | } 1045 | 1046 | static long uvc_v4l2_ioctl(struct file *file, 1047 | unsigned int cmd, unsigned long arg) 1048 | { 1049 | if (uvc_trace_param & UVC_TRACE_IOCTL) { 1050 | uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl("); 1051 | //v4l_printk_ioctl(cmd); 1052 | printk(")\n"); 1053 | } 1054 | 1055 | return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); 1056 | } 1057 | 1058 | static ssize_t uvc_v4l2_read(struct file *file, char __user *data, 1059 | size_t count, loff_t *ppos) 1060 | { 1061 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n"); 1062 | return -EINVAL; 1063 | } 1064 | 1065 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) 1066 | { 1067 | struct uvc_fh *handle = file->private_data; 1068 | struct uvc_streaming *stream = handle->stream; 1069 | 1070 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); 1071 | 1072 | return uvc_queue_mmap(&stream->queue, vma); 1073 | } 1074 | 1075 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) 1076 | { 1077 | struct uvc_fh *handle = file->private_data; 1078 | struct uvc_streaming *stream = handle->stream; 1079 | 1080 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); 1081 | 1082 | return uvc_queue_poll(&stream->queue, file, wait); 1083 | } 1084 | 1085 | #ifndef CONFIG_MMU 1086 | static unsigned long uvc_v4l2_get_unmapped_area(struct file *file, 1087 | unsigned long addr, unsigned long len, unsigned long pgoff, 1088 | unsigned long flags) 1089 | { 1090 | struct uvc_fh *handle = file->private_data; 1091 | struct uvc_streaming *stream = handle->stream; 1092 | 1093 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n"); 1094 | 1095 | return uvc_queue_get_unmapped_area(&stream->queue, pgoff); 1096 | } 1097 | #endif 1098 | 1099 | const struct v4l2_file_operations uvc_fops = { 1100 | .owner = THIS_MODULE, 1101 | .open = uvc_v4l2_open, 1102 | .release = uvc_v4l2_release, 1103 | .unlocked_ioctl = uvc_v4l2_ioctl, 1104 | .read = uvc_v4l2_read, 1105 | .mmap = uvc_v4l2_mmap, 1106 | .poll = uvc_v4l2_poll, 1107 | #ifndef CONFIG_MMU 1108 | .get_unmapped_area = uvc_v4l2_get_unmapped_area, 1109 | #endif 1110 | }; 1111 | 1112 | -------------------------------------------------------------------------------- /Linux_uvc_driver/uvc_3.3.8/uvcvideo.h: -------------------------------------------------------------------------------- 1 | #ifndef _USB_VIDEO_H_ 2 | #define _USB_VIDEO_H_ 3 | 4 | #ifndef __KERNEL__ 5 | #error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead." 6 | #endif /* __KERNEL__ */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | typedef enum{ 21 | CHIP_NONE = -1, 22 | CHIP_RER9420 = 0, 23 | CHIP_RER9421, 24 | CHIP_RER9422 25 | }CHIP_RER942X; 26 | 27 | /* -------------------------------------------------------------------------- 28 | * UVC constants 29 | */ 30 | 31 | #define UVC_TERM_INPUT 0x0000 32 | #define UVC_TERM_OUTPUT 0x8000 33 | #define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000) 34 | 35 | #define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) 36 | #define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 37 | #define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) 38 | #define UVC_ENTITY_IS_ITERM(entity) \ 39 | (UVC_ENTITY_IS_TERM(entity) && \ 40 | ((entity)->type & 0x8000) == UVC_TERM_INPUT) 41 | #define UVC_ENTITY_IS_OTERM(entity) \ 42 | (UVC_ENTITY_IS_TERM(entity) && \ 43 | ((entity)->type & 0x8000) == UVC_TERM_OUTPUT) 44 | 45 | /* ------------------------------*/ 46 | 47 | 48 | 49 | /* ------------------------------------------------------------------------ 50 | * GUIDs 51 | */ 52 | #define UVC_GUID_UVC_CAMERA \ 53 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} 55 | #define UVC_GUID_UVC_OUTPUT \ 56 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02} 58 | #define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \ 59 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03} 61 | #define UVC_GUID_UVC_PROCESSING \ 62 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01} 64 | #define UVC_GUID_UVC_SELECTOR \ 65 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} 67 | 68 | #define UVC_GUID_FORMAT_MJPEG \ 69 | { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ 70 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 71 | #define UVC_GUID_FORMAT_YUY2 \ 72 | { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 73 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 74 | #define UVC_GUID_FORMAT_YUY2_ISIGHT \ 75 | { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 76 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71} 77 | #define UVC_GUID_FORMAT_NV12 \ 78 | { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 79 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 80 | #define UVC_GUID_FORMAT_YV12 \ 81 | { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 82 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 83 | #define UVC_GUID_FORMAT_I420 \ 84 | { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ 85 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 86 | #define UVC_GUID_FORMAT_UYVY \ 87 | { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \ 88 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 89 | #define UVC_GUID_FORMAT_Y800 \ 90 | { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 91 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 92 | #define UVC_GUID_FORMAT_Y16 \ 93 | { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \ 94 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 95 | #define UVC_GUID_FORMAT_BY8 \ 96 | { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 97 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 98 | #define UVC_GUID_FORMAT_RGBP \ 99 | { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \ 100 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 101 | #define UVC_GUID_FORMAT_M420 \ 102 | { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ 103 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 104 | 105 | #define UVC_GUID_FORMAT_H264 \ 106 | { 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \ 107 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 108 | 109 | /* ------------------------------------------------------------------------ 110 | * Driver specific constants. 111 | */ 112 | 113 | //#define DRIVER_VERSION "1.1.1" 114 | #define DRIVER_VERSION "v1.0.15_H264_v3.3.8" 115 | 116 | /* Number of isochronous URBs. */ 117 | #define UVC_URBS 16 //yiling 118 | /* Maximum number of packets per URB. */ 119 | #define UVC_MAX_PACKETS 32 120 | /* Maximum number of video buffers. */ 121 | #define UVC_MAX_VIDEO_BUFFERS 32 122 | /* Maximum status buffer size in bytes of interrupt URB. */ 123 | #define UVC_MAX_STATUS_SIZE 16 124 | 125 | #define UVC_CTRL_CONTROL_TIMEOUT 300 126 | #define UVC_CTRL_STREAMING_TIMEOUT 5000 127 | 128 | /* Maximum allowed number of control mappings per device */ 129 | #define UVC_MAX_CONTROL_MAPPINGS 1024 130 | #define UVC_MAX_CONTROL_MENU_ENTRIES 32 131 | 132 | /* Devices quirks */ 133 | #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 134 | #define UVC_QUIRK_PROBE_MINMAX 0x00000002 135 | #define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004 136 | #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 137 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 138 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 139 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 140 | #define UVC_QUIRK_PROBE_DEF 0x00000100 141 | #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 142 | 143 | /* Format flags */ 144 | #define UVC_FMT_FLAG_COMPRESSED 0x00000001 145 | #define UVC_FMT_FLAG_STREAM 0x00000002 146 | 147 | #define RERVISION_RER9422_DDR_64M 0x00 148 | #define RERVISION_RER9422_DDR_16M 0x03 149 | /* ------------------------------------------------------------------------ 150 | * Structures. 151 | */ 152 | 153 | struct uvc_device; 154 | 155 | /* TODO: Put the most frequently accessed fields at the beginning of 156 | * structures to maximize cache efficiency. 157 | */ 158 | struct uvc_control_info { 159 | struct list_head mappings; 160 | 161 | __u8 entity[16]; 162 | __u8 index; /* Bit index in bmControls */ 163 | __u8 selector; 164 | 165 | __u16 size; 166 | __u32 flags; 167 | }; 168 | 169 | struct uvc_control_mapping { 170 | struct list_head list; 171 | 172 | struct uvc_control_info *ctrl; 173 | 174 | __u32 id; 175 | __u8 name[32]; 176 | __u8 entity[16]; 177 | __u8 selector; 178 | 179 | __u8 size; 180 | __u8 offset; 181 | enum v4l2_ctrl_type v4l2_type; 182 | __u32 data_type; 183 | 184 | struct uvc_menu_info *menu_info; 185 | __u32 menu_count; 186 | 187 | __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query, 188 | const __u8 *data); 189 | void (*set) (struct uvc_control_mapping *mapping, __s32 value, 190 | __u8 *data); 191 | }; 192 | 193 | struct uvc_control { 194 | struct uvc_entity *entity; 195 | struct uvc_control_info info; 196 | 197 | __u8 index; /* Used to match the uvc_control entry with a 198 | uvc_control_info. */ 199 | __u8 dirty:1, 200 | loaded:1, 201 | modified:1, 202 | cached:1, 203 | initialized:1; 204 | 205 | __u8 *uvc_data; 206 | }; 207 | 208 | struct uvc_format_desc { 209 | char *name; 210 | __u8 guid[16]; 211 | __u32 fcc; 212 | }; 213 | 214 | /* The term 'entity' refers to both UVC units and UVC terminals. 215 | * 216 | * The type field is either the terminal type (wTerminalType in the terminal 217 | * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor). 218 | * As the bDescriptorSubtype field is one byte long, the type value will 219 | * always have a null MSB for units. All terminal types defined by the UVC 220 | * specification have a non-null MSB, so it is safe to use the MSB to 221 | * differentiate between units and terminals as long as the descriptor parsing 222 | * code makes sure terminal types have a non-null MSB. 223 | * 224 | * For terminals, the type's most significant bit stores the terminal 225 | * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should 226 | * always be accessed with the UVC_ENTITY_* macros and never directly. 227 | */ 228 | 229 | struct uvc_entity { 230 | struct list_head list; /* Entity as part of a UVC device. */ 231 | struct list_head chain; /* Entity as part of a video device 232 | * chain. */ 233 | __u8 id; 234 | __u16 type; 235 | char name[64]; 236 | 237 | /* Media controller-related fields. */ 238 | struct video_device *vdev; 239 | struct v4l2_subdev subdev; 240 | unsigned int num_pads; 241 | unsigned int num_links; 242 | struct media_pad *pads; 243 | 244 | union { 245 | struct { 246 | __u16 wObjectiveFocalLengthMin; 247 | __u16 wObjectiveFocalLengthMax; 248 | __u16 wOcularFocalLength; 249 | __u8 bControlSize; 250 | __u8 *bmControls; 251 | } camera; 252 | 253 | struct { 254 | __u8 bControlSize; 255 | __u8 *bmControls; 256 | __u8 bTransportModeSize; 257 | __u8 *bmTransportModes; 258 | } media; 259 | 260 | struct { 261 | } output; 262 | 263 | struct { 264 | __u16 wMaxMultiplier; 265 | __u8 bControlSize; 266 | __u8 *bmControls; 267 | __u8 bmVideoStandards; 268 | } processing; 269 | 270 | struct { 271 | } selector; 272 | 273 | struct { 274 | __u8 guidExtensionCode[16]; 275 | __u8 bNumControls; 276 | __u8 bControlSize; 277 | __u8 *bmControls; 278 | __u8 *bmControlsType; 279 | } extension; 280 | }; 281 | 282 | __u8 bNrInPins; 283 | __u8 *baSourceID; 284 | 285 | unsigned int ncontrols; 286 | struct uvc_control *controls; 287 | }; 288 | 289 | struct uvc_frame { 290 | __u8 bFrameIndex; 291 | __u8 bmCapabilities; 292 | __u16 wWidth; 293 | __u16 wHeight; 294 | __u32 dwMinBitRate; 295 | __u32 dwMaxBitRate; 296 | __u32 dwMaxVideoFrameBufferSize; 297 | __u8 bFrameIntervalType; 298 | __u32 dwDefaultFrameInterval; 299 | __u32 *dwFrameInterval; 300 | }; 301 | 302 | struct uvc_format { 303 | __u8 type; 304 | __u8 index; 305 | __u8 bpp; 306 | __u8 colorspace; 307 | __u32 fcc; 308 | __u32 flags; 309 | 310 | char name[32]; 311 | 312 | unsigned int nframes; 313 | struct uvc_frame *frame; 314 | }; 315 | 316 | struct uvc_streaming_header { 317 | __u8 bNumFormats; 318 | __u8 bEndpointAddress; 319 | __u8 bTerminalLink; 320 | __u8 bControlSize; 321 | __u8 *bmaControls; 322 | /* The following fields are used by input headers only. */ 323 | __u8 bmInfo; 324 | __u8 bStillCaptureMethod; 325 | __u8 bTriggerSupport; 326 | __u8 bTriggerUsage; 327 | }; 328 | 329 | enum uvc_buffer_state { 330 | UVC_BUF_STATE_IDLE = 0, 331 | UVC_BUF_STATE_QUEUED = 1, 332 | UVC_BUF_STATE_ACTIVE = 2, 333 | UVC_BUF_STATE_READY = 3, 334 | UVC_BUF_STATE_DONE = 4, 335 | UVC_BUF_STATE_ERROR = 5, 336 | }; 337 | 338 | //added by Pae 339 | struct uvc_buffer { 340 | struct vb2_v4l2_buffer buf; 341 | struct list_head queue; 342 | enum uvc_buffer_state state; 343 | unsigned int error; 344 | 345 | void *mem; 346 | unsigned int length; 347 | unsigned int bytesused; 348 | 349 | u32 pts; 350 | }; 351 | 352 | #define UVC_QUEUE_DISCONNECTED (1 << 0) 353 | #define UVC_QUEUE_DROP_CORRUPTED (1 << 1) 354 | 355 | struct uvc_video_queue { 356 | struct vb2_queue queue; 357 | struct mutex mutex; /* Protects queue */ 358 | 359 | unsigned int flags; 360 | unsigned int buf_used; 361 | 362 | spinlock_t irqlock; /* Protects irqqueue */ 363 | struct list_head irqqueue; 364 | }; 365 | 366 | struct uvc_video_chain { 367 | struct uvc_device *dev; 368 | struct list_head list; 369 | 370 | struct list_head entities; /* All entities */ 371 | struct uvc_entity *processing; /* Processing unit */ 372 | struct uvc_entity *selector; /* Selector unit */ 373 | 374 | struct mutex ctrl_mutex; /* Protects ctrl.info */ 375 | }; 376 | 377 | struct uvc_stats_frame { 378 | unsigned int size; /* Number of bytes captured */ 379 | unsigned int first_data; /* Index of the first non-empty packet */ 380 | 381 | unsigned int nb_packets; /* Number of packets */ 382 | unsigned int nb_empty; /* Number of empty packets */ 383 | unsigned int nb_invalid; /* Number of packets with an invalid header */ 384 | unsigned int nb_errors; /* Number of packets with the error bit set */ 385 | 386 | unsigned int nb_pts; /* Number of packets with a PTS timestamp */ 387 | unsigned int nb_pts_diffs; /* Number of PTS differences inside a frame */ 388 | unsigned int last_pts_diff; /* Index of the last PTS difference */ 389 | bool has_initial_pts; /* Whether the first non-empty packet has a PTS */ 390 | bool has_early_pts; /* Whether a PTS is present before the first non-empty packet */ 391 | u32 pts; /* PTS of the last packet */ 392 | 393 | unsigned int nb_scr; /* Number of packets with a SCR timestamp */ 394 | unsigned int nb_scr_diffs; /* Number of SCR.STC differences inside a frame */ 395 | u16 scr_sof; /* SCR.SOF of the last packet */ 396 | u32 scr_stc; /* SCR.STC of the last packet */ 397 | }; 398 | 399 | struct uvc_stats_stream { 400 | struct timespec start_ts; /* Stream start timestamp */ 401 | struct timespec stop_ts; /* Stream stop timestamp */ 402 | 403 | unsigned int nb_frames; /* Number of frames */ 404 | 405 | unsigned int nb_packets; /* Number of packets */ 406 | unsigned int nb_empty; /* Number of empty packets */ 407 | unsigned int nb_invalid; /* Number of packets with an invalid header */ 408 | unsigned int nb_errors; /* Number of packets with the error bit set */ 409 | 410 | unsigned int nb_pts_constant; /* Number of frames with constant PTS */ 411 | unsigned int nb_pts_early; /* Number of frames with early PTS */ 412 | unsigned int nb_pts_initial; /* Number of frames with initial PTS */ 413 | 414 | unsigned int nb_scr_count_ok; /* Number of frames with at least one SCR per non empty packet */ 415 | unsigned int nb_scr_diffs_ok; /* Number of frames with varying SCR.STC */ 416 | unsigned int scr_sof_count; /* STC.SOF counter accumulated since stream start */ 417 | unsigned int scr_sof; /* STC.SOF of the last packet */ 418 | unsigned int min_sof; /* Minimum STC.SOF value */ 419 | unsigned int max_sof; /* Maximum STC.SOF value */ 420 | }; 421 | 422 | struct uvc_streaming { 423 | struct list_head list; 424 | struct uvc_device *dev; 425 | struct video_device *vdev; 426 | struct uvc_video_chain *chain; 427 | atomic_t active; 428 | 429 | struct usb_interface *intf; 430 | int intfnum; 431 | __u16 maxpsize; 432 | 433 | struct uvc_streaming_header header; 434 | enum v4l2_buf_type type; 435 | 436 | unsigned int nformats; 437 | struct uvc_format *format; 438 | 439 | struct uvc_streaming_control ctrl; 440 | struct uvc_format *cur_format; 441 | struct uvc_frame *cur_frame; 442 | /* Protect access to ctrl, cur_format, cur_frame and hardware video 443 | * probe control. 444 | */ 445 | struct mutex mutex; 446 | 447 | /* Buffers queue. */ 448 | unsigned int frozen : 1; 449 | struct uvc_video_queue queue; 450 | void (*decode) (struct urb *urb, struct uvc_streaming *video, 451 | struct uvc_buffer *buf); 452 | 453 | /* Context data used by the bulk completion handler. */ 454 | struct { 455 | __u8 header[256]; 456 | unsigned int header_size; 457 | int skip_payload; 458 | __u32 payload_size; 459 | __u32 max_payload_size; 460 | } bulk; 461 | 462 | struct urb *urb[UVC_URBS]; 463 | char *urb_buffer[UVC_URBS]; 464 | dma_addr_t urb_dma[UVC_URBS]; 465 | unsigned int urb_size; 466 | 467 | __u32 sequence; 468 | __u8 last_fid; 469 | 470 | /* debugfs */ 471 | struct dentry *debugfs_dir; 472 | struct { 473 | struct uvc_stats_frame frame; 474 | struct uvc_stats_stream stream; 475 | } stats; 476 | 477 | /* Timestamps support. */ 478 | struct uvc_clock { 479 | struct uvc_clock_sample { 480 | u32 dev_stc; 481 | u16 dev_sof; 482 | struct timespec host_ts; 483 | u16 host_sof; 484 | } *samples; 485 | 486 | unsigned int head; 487 | unsigned int count; 488 | unsigned int size; 489 | 490 | u16 last_sof; 491 | u16 sof_offset; 492 | 493 | spinlock_t lock; 494 | } clock; 495 | }; 496 | 497 | enum uvc_device_state { 498 | UVC_DEV_DISCONNECTED = 1, 499 | }; 500 | 501 | struct uvc_device { 502 | struct usb_device *udev; 503 | struct usb_interface *intf; 504 | unsigned long warnings; 505 | __u32 quirks; 506 | int intfnum; 507 | char name[32]; 508 | 509 | enum uvc_device_state state; 510 | atomic_t users; 511 | atomic_t nmappings; 512 | 513 | /* Video control interface */ 514 | #ifdef CONFIG_MEDIA_CONTROLLER 515 | struct media_device mdev; 516 | #endif 517 | struct v4l2_device vdev; 518 | __u16 uvc_version; 519 | __u32 clock_frequency; 520 | 521 | struct list_head entities; 522 | struct list_head chains; 523 | 524 | /* Video Streaming interfaces */ 525 | struct list_head streams; 526 | atomic_t nstreams; 527 | 528 | /* Status Interrupt Endpoint */ 529 | struct usb_host_endpoint *int_ep; 530 | struct urb *int_urb; 531 | __u8 *status; 532 | struct input_dev *input; 533 | char input_phys[64]; 534 | 535 | unsigned int RER_Chip; 536 | }; 537 | 538 | enum uvc_handle_state { 539 | UVC_HANDLE_PASSIVE = 0, 540 | UVC_HANDLE_ACTIVE = 1, 541 | }; 542 | 543 | struct uvc_fh { 544 | struct uvc_video_chain *chain; 545 | struct uvc_streaming *stream; 546 | enum uvc_handle_state state; 547 | }; 548 | 549 | struct uvc_driver { 550 | struct usb_driver driver; 551 | }; 552 | 553 | /* ------------------------------------------------------------------------ 554 | * Debugging, printing and logging 555 | */ 556 | 557 | #define UVC_TRACE_PROBE (1 << 0) 558 | #define UVC_TRACE_DESCR (1 << 1) 559 | #define UVC_TRACE_CONTROL (1 << 2) 560 | #define UVC_TRACE_FORMAT (1 << 3) 561 | #define UVC_TRACE_CAPTURE (1 << 4) 562 | #define UVC_TRACE_CALLS (1 << 5) 563 | #define UVC_TRACE_IOCTL (1 << 6) 564 | #define UVC_TRACE_FRAME (1 << 7) 565 | #define UVC_TRACE_SUSPEND (1 << 8) 566 | #define UVC_TRACE_STATUS (1 << 9) 567 | #define UVC_TRACE_VIDEO (1 << 10) 568 | #define UVC_TRACE_STATS (1 << 11) 569 | #define UVC_TRACE_CLOCK (1 << 12) 570 | 571 | #define UVC_WARN_MINMAX 0 572 | #define UVC_WARN_PROBE_DEF 1 573 | #define UVC_WARN_XU_GET_RES 2 574 | 575 | extern unsigned int uvc_clock_param; 576 | extern unsigned int uvc_no_drop_param; 577 | extern unsigned int uvc_trace_param; 578 | extern unsigned int uvc_timeout_param; 579 | 580 | 581 | //Debug Trace Start 582 | 583 | #define My_TRACE_FLOW (1 << 0) 584 | #define My_TRACE_FORMAT (1 << 1) 585 | #define My_TRACE_XU (1 << 2) 586 | #define My_TRACE_H264 (1 << 3) 587 | #define My_TRACE_M2TS (1 << 4) 588 | #define My_TRACE_IOCTL (1 << 5) 589 | 590 | extern unsigned int DbgPrint_param; 591 | #define DbgPrint(flag, fmt, args...) \ 592 | do { \ 593 | if (DbgPrint_param & flag) \ 594 | printk(KERN_ALERT "DbgPrint: " fmt, ## args); \ 595 | } while (0) 596 | 597 | //#define DbgPrint(flag, fmt, args...) 598 | //Debug Trace End 599 | 600 | #define uvc_trace(flag, msg...) \ 601 | do { \ 602 | if (uvc_trace_param & flag) \ 603 | printk(KERN_DEBUG "uvcvideo: " msg); \ 604 | } while (0) 605 | 606 | #define uvc_warn_once(dev, warn, msg...) \ 607 | do { \ 608 | if (!test_and_set_bit(warn, &dev->warnings)) \ 609 | printk(KERN_INFO "uvcvideo: " msg); \ 610 | } while (0) 611 | 612 | #define uvc_printk(level, msg...) \ 613 | printk(level "uvcvideo: " msg) 614 | 615 | /* -------------------------------------------------------------------------- 616 | * Internal functions. 617 | */ 618 | 619 | /* Core driver */ 620 | extern struct uvc_driver uvc_driver; 621 | 622 | extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); 623 | 624 | /* Video buffers queue management. */ 625 | extern void uvc_queue_init(struct uvc_video_queue *queue, 626 | enum v4l2_buf_type type, int drop_corrupted); 627 | extern int uvc_alloc_buffers(struct uvc_video_queue *queue, 628 | struct v4l2_requestbuffers *rb); 629 | extern void uvc_free_buffers(struct uvc_video_queue *queue); 630 | extern int uvc_query_buffer(struct uvc_video_queue *queue, 631 | struct v4l2_buffer *v4l2_buf); 632 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, 633 | struct v4l2_buffer *v4l2_buf); 634 | extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, 635 | struct v4l2_buffer *v4l2_buf, int nonblocking); 636 | extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); 637 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); 638 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, 639 | struct uvc_buffer *buf); 640 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, 641 | struct vm_area_struct *vma); 642 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, 643 | struct file *file, poll_table *wait); 644 | #ifndef CONFIG_MMU 645 | extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, 646 | unsigned long pgoff); 647 | #endif 648 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); 649 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) 650 | { 651 | return vb2_is_streaming(&queue->queue); 652 | } 653 | 654 | /* V4L2 interface */ 655 | extern const struct v4l2_file_operations uvc_fops; 656 | 657 | /* Media controller */ 658 | extern int uvc_mc_register_entities(struct uvc_video_chain *chain); 659 | extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); 660 | 661 | /* Video */ 662 | extern int uvc_video_init(struct uvc_streaming *stream); 663 | extern int uvc_video_suspend(struct uvc_streaming *stream); 664 | extern int uvc_video_resume(struct uvc_streaming *stream, int reset); 665 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); 666 | extern int uvc_probe_video(struct uvc_streaming *stream, 667 | struct uvc_streaming_control *probe); 668 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, 669 | __u8 intfnum, __u8 cs, void *data, __u16 size); 670 | void uvc_video_clock_update(struct uvc_streaming *stream, 671 | struct v4l2_buffer *v4l2_buf, 672 | struct uvc_buffer *buf); 673 | 674 | /* Status */ 675 | extern int uvc_status_init(struct uvc_device *dev); 676 | extern void uvc_status_cleanup(struct uvc_device *dev); 677 | extern int uvc_status_start(struct uvc_device *dev); 678 | extern void uvc_status_stop(struct uvc_device *dev); 679 | extern int uvc_status_suspend(struct uvc_device *dev); 680 | extern int uvc_status_resume(struct uvc_device *dev); 681 | 682 | /* Controls */ 683 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, 684 | struct v4l2_queryctrl *v4l2_ctrl); 685 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, 686 | struct v4l2_querymenu *query_menu); 687 | 688 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, 689 | const struct uvc_control_mapping *mapping); 690 | extern int uvc_ctrl_init_device(struct uvc_device *dev); 691 | extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); 692 | extern int uvc_ctrl_resume_device(struct uvc_device *dev); 693 | 694 | extern int uvc_ctrl_begin(struct uvc_video_chain *chain); 695 | extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); 696 | static inline int uvc_ctrl_commit(struct uvc_video_chain *chain) 697 | { 698 | return __uvc_ctrl_commit(chain, 0); 699 | } 700 | static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain) 701 | { 702 | return __uvc_ctrl_commit(chain, 1); 703 | } 704 | 705 | extern int uvc_ctrl_get(struct uvc_video_chain *chain, 706 | struct v4l2_ext_control *xctrl); 707 | extern int uvc_ctrl_set(struct uvc_video_chain *chain, 708 | struct v4l2_ext_control *xctrl); 709 | 710 | extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 711 | struct uvc_xu_control_query *xqry); 712 | 713 | /* Utility functions */ 714 | extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, 715 | unsigned int n_terms, unsigned int threshold); 716 | extern uint32_t uvc_fraction_to_interval(uint32_t numerator, 717 | uint32_t denominator); 718 | extern struct usb_host_endpoint *uvc_find_endpoint( 719 | struct usb_host_interface *alts, __u8 epaddr); 720 | 721 | /* Quirks support */ 722 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, 723 | struct uvc_buffer *buf); 724 | 725 | /* debugfs and statistics */ 726 | int uvc_debugfs_init(void); 727 | void uvc_debugfs_cleanup(void); 728 | int uvc_debugfs_init_stream(struct uvc_streaming *stream); 729 | void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream); 730 | 731 | size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf, 732 | size_t size); 733 | 734 | 735 | extern int uvc_xu_ctrll_ReadChip(struct uvc_device *dev, int *chip); 736 | #endif 737 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ELP_H264_UVC 2 | Official H264 UVC driver for ELP Camera (Downloaded from ELP China) 3 | 4 | This driver has been tested on Debian 8 on Beaglebone Black (Kernel V. linux-4.4.54-ti-r93) 5 | 6 | Installing 7 | - Compiling the uvc_3.3.8 first with Makefile_PC (Inheritated file eg. Makefile) with 8 | > makefile 9 | 10 | - Unload original uvc driver 11 | > sudo rmmod uvcvideo 12 | 13 | - Load new UVC driver module 14 | > sudo insmod ./uvcvideo_h264.ko 15 | 16 | Piping out the raw H264 by H264_UVC_TestAP to stdout eg. FFMPEG 17 | Modifying the H264_UVC_TestAP.c to allows this application piping out, 18 | 19 | - line 129 20 | This function `static int CheckKernelVersion(void)` must bypass by force return true 21 | 22 | - line 682 adding 23 | TestAp_Printf(TESTAP_DBG_USAGE, "-o, --stdout stdout the stream\n"); 24 | 25 | - 26 | -------------------------------------------------------------------------------- /Read_me.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokeap/ELP_H264_UVC/274fb791469b453d7945aa854e94bdd0798cb723/Read_me.pdf --------------------------------------------------------------------------------