⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gspca_core.c

📁 Linux下面摄像头最新源代码:支持200多中摄像头
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (minw > spca50x->mode_cam[i].width			    || minh > spca50x->mode_cam[i].height) {				minw = spca50x->mode_cam[i].width;				minh = spca50x->mode_cam[i].height;			}		}	}	spca50x->maxwidth = maxw;	spca50x->maxheight = maxh;	spca50x->minwidth = minw;	spca50x->minheight = minh;	PDEBUG(0, "maxw %d maxh %d minw %d minh %d", maxw, maxh, minw, minh);	return 0;}static intwxh_to_size(int width, int height){	switch (width) {	case 640:		if (height == 480)			return VGA;		break;	case 384:		if (height == 288)			return PAL;		break;	case 352:		if (height == 288)			return SIF;		break;	case 320:		if (height == 240)			return CIF;		break;	case 192:		if (height == 144)			return QPAL;		break;	case 176:		if (height == 144)			return QSIF;		break;	case 160:		if (height == 120)			return QCIF;		break;	}	return -EINVAL;}static intv4l_to_spca5xx(int format){	switch (format) {	case VIDEO_PALETTE_RGB565:		return P_RGB16;	case VIDEO_PALETTE_RGB24:		return P_RGB24;	case VIDEO_PALETTE_RGB32:		return P_RGB32;	case VIDEO_PALETTE_YUV422P:		return P_YUV422;	case VIDEO_PALETTE_YUV420P:		return P_YUV420;	case VIDEO_PALETTE_RAW_JPEG:		return P_RAW;	case VIDEO_PALETTE_JPEG:		return P_JPEG;	default:		return -EINVAL;	}}static inline intspca5xx_setMode(struct usb_spca50x *spca50x, int width, int height, int format){	int i, j;	int formatIn;	int crop = 0, cropx1 = 0, cropx2 = 0, cropy1 = 0, cropy2 = 0, x =	    0, y = 0;/* Avoid changing to already selected mode *//* convert V4l format to our internal format */	PDEBUG(3, "spca5xx set mode asked w %d h %d p %d", width, height,	       format);	if ((formatIn = v4l_to_spca5xx(format)) < 0)		return -EINVAL;	for (i = QCIF; i < TOTMODE; i++) {		if ((spca50x->mode_cam[i].width == width) &&		    (spca50x->mode_cam[i].height == height) &&		    (spca50x->mode_cam[i].t_palette & formatIn)) {			spca50x->width = spca50x->mode_cam[i].width;			spca50x->height = spca50x->mode_cam[i].height;			spca50x->pipe_size = spca50x->mode_cam[i].pipe;			spca50x->mode = spca50x->mode_cam[i].mode;			spca50x->method = spca50x->mode_cam[i].method;			spca50x->format = format;	//palette in use			if (spca50x->method) {				if (spca50x->method == 1) {					for (j = i; j < TOTMODE; j++) {						if (spca50x->mode_cam[j].						    method == 0						    && spca50x->mode_cam[j].						    width) {							spca50x->hdrwidth =							    spca50x->							    mode_cam[j].width;							spca50x->hdrheight =							    spca50x->							    mode_cam[j].height;							spca50x->mode = spca50x->mode_cam[j].mode;	// overwrite by the hardware mode							break;						}					}	// end match hardware mode					if (!spca50x->hdrwidth					    && !spca50x->hdrheight)						return -EINVAL;				}			}/* match found */			break;		}	}			// end match mode/* initialize the hdrwidth and hdrheight for the first init_source *//* precompute the crop x y value for each frame */	if (!spca50x->method) {/* nothing todo hardware found stream */		cropx1 = cropx2 = cropy1 = cropy2 = x = y = 0;		spca50x->hdrwidth = spca50x->width;		spca50x->hdrheight = spca50x->height;	}	if (spca50x->method & 0x01) {/* cropping method */		if (spca50x->hdrwidth > spca50x->width) {			crop = (spca50x->hdrwidth - spca50x->width);			if (spca50x->cameratype == JPEG			    || spca50x->cameratype == JPGH			    || spca50x->cameratype == JPGS				|| spca50x->cameratype == PJPG)				crop = crop >> 4;			cropx1 = crop >> 1;			cropx2 = cropx1 + (crop % 2);		} else {			cropx1 = cropx2 = 0;		}		if (spca50x->hdrheight > spca50x->height) {			crop = (spca50x->hdrheight - spca50x->height);			if (spca50x->cameratype == JPEG)				crop = crop >> 4;			if (spca50x->cameratype == JPGH			    || spca50x->cameratype == JPGS			    || spca50x->cameratype == PJPG)				crop = crop >> 3;			cropy1 = crop >> 1;			cropy2 = cropy1 + (crop % 2);		} else {			cropy1 = cropy2 = 0;		}	}	if (spca50x->method & 0x02) {/* what can put here for div method */	}	if (spca50x->method & 0x04) {/* and here for mult */	}	PDEBUG(2, "Found code %d method %d", spca50x->mode, spca50x->method);	PDEBUG(2, "Soft Win width height %d x %d", spca50x->width,	       spca50x->height);	PDEBUG(2, "Hard Win width height %d x %d", spca50x->hdrwidth,	       spca50x->hdrheight);	for (i = 0; i < SPCA50X_NUMFRAMES; i++) {		spca50x->frame[i].method = spca50x->method;		spca50x->frame[i].cameratype = spca50x->cameratype;		spca50x->frame[i].cropx1 = cropx1;		spca50x->frame[i].cropx2 = cropx2;		spca50x->frame[i].cropy1 = cropy1;		spca50x->frame[i].cropy2 = cropy2;		spca50x->frame[i].x = x;		spca50x->frame[i].y = y;		spca50x->frame[i].hdrwidth = spca50x->hdrwidth;		spca50x->frame[i].hdrheight = spca50x->hdrheight;		spca50x->frame[i].width = spca50x->width;		spca50x->frame[i].height = spca50x->height;		spca50x->frame[i].format = spca50x->format;		spca50x->frame[i].scanlength =		    spca50x->width * spca50x->height * 3 / 2;// ?? assumes 4:2:0 data	}	return 0;}/*********************************************************************** spca50x_mode_init_regs* Function sets up the resolution with checking if it's necessary ***********************************************************************/static intspca5xx_restartMode(struct usb_spca50x *spca50x, int width, int height,		    int format){	int was_streaming;	int r;/* Avoid changing to already selected mode */	if (spca50x->width == width && spca50x->height == height)		return 0;	PDEBUG(1, "Mode changing to %d,%d", width, height);	was_streaming = spca50x->streaming;/* FIXME spca500 bridge is there a way to find an init like Clicksmart310 ? */	if (was_streaming) {		if ((spca50x->bridge != BRIDGE_SPCA500)		    || (spca50x->desc == LogitechClickSmart310))			spca50x_stop_isoc(spca50x);	}	r = spca5xx_setMode(spca50x, width, height, format);	if (r < 0)		goto out;	if (was_streaming) {		if ((spca50x->bridge != BRIDGE_SPCA500)		    || (spca50x->desc == LogitechClickSmart310)) {			r = gspca_init_transfert(spca50x);		} else {			spca50x->funct.start(spca50x);		}	}      out:	return r;}#if 0/************************************************************************ SPCA50X data transfer, IRQ handler***********************************************************************/static struct spca50x_frame *spca50x_next_frame(struct usb_spca50x		   *spca50x, unsigned char *cdata){	int iFrameNext;	struct spca50x_frame *frame = NULL;	PDEBUG(2, "Frame %d State %d", spca50x->curframe,	       spca50x->frame[spca50x->curframe].grabstate);	if (spca50x->frame[spca50x->curframe].grabstate == FRAME_ERROR) {		PDEBUG(2, "Frame %d errdrop", spca50x->curframe);		frame = &spca50x->frame[spca50x->curframe];		goto dropframe;	}/* Cycle through the frame buffer looking for a free frame to overwrite */	iFrameNext = (spca50x->curframe + 1) % SPCA50X_NUMFRAMES;	while (frame == NULL && iFrameNext != (spca50x->curframe)) {		if (spca50x->frame[iFrameNext].grabstate == FRAME_READY ||		    spca50x->frame[iFrameNext].grabstate == FRAME_UNUSED ||		    spca50x->frame[iFrameNext].grabstate == FRAME_ERROR) {			spca50x->curframe = iFrameNext;			frame = &spca50x->frame[iFrameNext];			break;		} else {			iFrameNext = (iFrameNext + 1) % SPCA50X_NUMFRAMES;		}	}	if (frame == NULL) {		PDEBUG(3, "Can't find a free frame to grab into...using next. "		       "This is caused by the application not reading fast enough.");		spca50x->curframe = (spca50x->curframe + 1) % SPCA50X_NUMFRAMES;		frame = &spca50x->frame[spca50x->curframe];	}dropframe:	frame->grabstate = FRAME_GRABBING;	if (spca50x->pictsetting.change) {		memcpy(&frame->pictsetting, &spca50x->pictsetting,		       sizeof (struct pictparam));/* reset flag change */		spca50x->pictsetting.change = 0;		PDEBUG(2, "Picture setting change Pass to decoding   ");	}/* Reset some per-frame variables */	frame->highwater = frame->data;	frame->scanstate = STATE_LINES;	frame->scanlength = 0;	frame->last_packet = -1;	frame->totlength = 0;	spca50x->packet = 0;out:	return frame;}#endif/************************************************************************ SPCA50X data transfer, IRQ handler***********************************************************************/static struct spca50x_frame *spca50x_next_frame(struct usb_spca50x		   *spca50x, unsigned char *cdata){	struct spca50x_frame *frame = NULL;	PDEBUG(2, "Frame %d State %d", spca50x->curframe,	       spca50x->frame[spca50x->curframe].grabstate);	if (spca50x->frame[spca50x->curframe].grabstate != FRAME_ERROR) 		spca50x->curframe = (spca50x->curframe + 1) % SPCA50X_NUMFRAMES;		frame = &spca50x->frame[spca50x->curframe];	if (spca50x->pictsetting.change) {		memcpy(&frame->pictsetting, &spca50x->pictsetting,		       sizeof (struct pictparam));/* reset flag change */		spca50x->pictsetting.change = 0;		PDEBUG(2, "Picture setting change Pass to decoding   ");	}/* Reset some per-frame variables */	frame->grabstate = FRAME_GRABBING;	frame->scanstate = STATE_LINES;	frame->highwater = frame->data;	frame->scanlength = 0;	frame->last_packet = -1;	frame->totlength = 0;	spca50x->packet = 0;	return frame;}/* Tasklet function to decode */voidoutpict_do_tasklet(unsigned long ptr){	int err;	struct spca50x_frame *taskletframe = (struct spca50x_frame *) ptr;	taskletframe->scanlength = taskletframe->highwater - taskletframe->data;	PDEBUG(2,	       "Tasklet ask spcadecoder hdrwidth %d hdrheight %d method %d ",	       taskletframe->hdrwidth, taskletframe->hdrheight,	       taskletframe->method);	if ((err = spca50x_outpicture(taskletframe)) < 0) {		PDEBUG(2, "frame decoder failed (%d)", err);		taskletframe->grabstate = FRAME_ERROR;	} else {		taskletframe->grabstate = FRAME_DONE;		PDEBUG(2, "Decode framestate return %d",		       taskletframe->grabstate);	}	if (waitqueue_active(&taskletframe->wq))		wake_up_interruptible(&taskletframe->wq);	atomic_set(&taskletframe->spca50x_dev->in_use,0);}/*********************************************************************time Helper function**********************************************************************/static inline unsigned longspca5xx_gettimes(void){	u64 times_now;	times_now = get_jiffies_64();	return jiffies_to_msecs(times_now);}/* ******************************************************************* spca50x_move_data* Function serves for moving data from USB transfer buffers* to internal driver frame buffers.******************************************************************* */static intspca50x_move_data(struct usb_spca50x *spca50x, struct urb *urb){	unsigned char *cdata;	//Pointer to buffer where we do store next packet	unsigned char *pData;	//Pointer to buffer where we do store next packet	int i;	for (i = 0; i < urb->number_of_packets; i++) {		int datalength = urb->iso_frame_desc[i].actual_length;		int st = urb->iso_frame_desc[i].status;		unsigned long ms_times_now;		unsigned long ms_times_before;		struct spca50x_frame *frame;	//Pointer to frame data		int sequenceNumber;		int sof;		int iPix;	//Offset of pixel data in the ISO packet		if (st) {			PDEBUG(0, "ISOC data error: [%d] len=%d, status=%d \n",			       i, datalength, st);			continue;		}		cdata = ((unsigned char *) urb->transfer_buffer) +		    urb->iso_frame_desc[i].offset;/* Check for zero length block or no selected frame buffer */		if (!datalength || spca50x->curframe == -1) {			spca50x->synchro = 0;			continue;		}		PDEBUG(5, "Packet data [%d,%d,%d] Status: %d", datalength, st,		       urb->iso_frame_desc[i].offset, st);		frame = &spca50x->frame[spca50x->curframe];		if (frame->last_packet == -1) {/*initialize a new frame */			sequenceNumber = 0;		} else {			sequenceNumber = frame->last_packet;		}/* check frame start */		if ((sof =		     spca50x->funct.sof_detect(spca50x, frame, cdata, &iPix,					       sequenceNumber,					       &datalength)) < 0)			continue;		sequenceNumber = sof;		PDEBUG(3, "spca50x: Packet seqnum = 0x%02x.  curframe=%2d",		       sequenceNumber, spca50x->curframe);		pData = cdata;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -