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

📄 gspca_core.c

📁 是Linux2.6内核下
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;/* Can we find a frame start */		if (sequenceNumber == 0) {			PDEBUG(3, "spca50x: Found Frame Start!, framenum = %d",			       spca50x->curframe);// Start of frame is implicit end of previous frame// Check for a previous frame and finish it off if one exists			if (frame->scanstate == STATE_LINES) {				if (frame->format != VIDEO_PALETTE_RAW_JPEG) {/* overflow ? */					ms_times_now = spca5xx_gettimes();					if (ms_times_now < spca50x->last_times)						spca50x->last_times = 0;					spin_lock(&spca50x->v4l_lock);					ms_times_before =					    spca50x->last_times +					    spca50x->dtimes;					spin_unlock(&spca50x->v4l_lock);					if (ms_times_now >= ms_times_before) {						PDEBUG(2,						       "Decode frame last %d",						       (int) (ms_times_now -							      spca50x->							      last_times));						spca50x->last_times =						    ms_times_now;/* Decode the frame one at a times or drop*/						if (!atomic_read						    (&spca50x->in_use)) {							atomic_set(&spca50x->								   in_use, 1);							spca50x->							    spca5xx_tasklet.							    data =							    (unsigned long)							    frame;							tasklet_schedule							    (&spca50x->							     spca5xx_tasklet);						} else							frame->grabstate =							    FRAME_ERROR;					} else						frame->grabstate = FRAME_ERROR;				} else {/* RAW DATA stream */					frame->grabstate = FRAME_DONE;					if (waitqueue_active(&frame->wq))						wake_up_interruptible(&frame->								      wq);				}// If someone decided to wait for ANY frame - wake him up 				if (waitqueue_active(&spca50x->wq))					wake_up_interruptible(&spca50x->wq);				frame = spca50x_next_frame(spca50x, cdata);			} else				frame->scanstate = STATE_LINES;		}/* Are we in a frame? */		if (frame == NULL || frame->scanstate != STATE_LINES)			continue;		frame->last_packet = sequenceNumber;		pData = cdata + iPix;	// Skip packet header (1 or 10 bytes)// Consume data		PDEBUG(5, "Processing packet seq  %d,length %d,totlength %d",		       frame->last_packet, datalength, frame->totlength);/* this copy consume input data from the isoc stream */		if ((datalength > 0)) {			memcpy(frame->highwater, pData, datalength);			frame->highwater += datalength;			frame->totlength += datalength;		}	}	return 0;}/****************************************************************************** Buffer management****************************************************************************/static intspca50x_alloc(struct usb_spca50x *spca50x){	int i;	PDEBUG(4, "entered");	down(&spca50x->buf_lock);	if (spca50x->buf_state == BUF_ALLOCATED)		goto out;	spca50x->tmpBuffer = rvmalloc(MAX_FRAME_SIZE);	if (!spca50x->tmpBuffer)		goto error;	spca50x->fbuf = rvmalloc(SPCA50X_NUMFRAMES * MAX_DATA_SIZE);	if (!spca50x->fbuf)		goto error;	for (i = 0; i < SPCA50X_NUMFRAMES; i++) {		spca50x->frame[i].tmpbuffer = spca50x->tmpBuffer;		spca50x->frame[i].decoder = &spca50x->maindecode;	//connect each frame to the main data decoding 		spca50x->frame[i].spca50x_dev = spca50x;	//refind the whole structure 		spca50x->frame[i].grabstate = FRAME_UNUSED;		spca50x->frame[i].scanstate = STATE_SCANNING;		spca50x->frame[i].data = spca50x->fbuf + i * MAX_DATA_SIZE;		spca50x->frame[i].highwater = spca50x->frame[i].data;		memset(&spca50x->frame[i].pictsetting, 0,		       sizeof (struct pictparam));		PDEBUG(4, "frame[%d] @ %p", i, spca50x->frame[i].data);	}	spca50x->buf_state = BUF_ALLOCATED;      out:	up(&spca50x->buf_lock);	PDEBUG(4, "leaving");	return 0;      error:	if (spca50x->fbuf) {		rvfree(spca50x->fbuf, SPCA50X_NUMFRAMES * MAX_DATA_SIZE);		spca50x->fbuf = NULL;	}	if (spca50x->tmpBuffer) {		rvfree(spca50x->tmpBuffer, MAX_FRAME_SIZE);		spca50x->tmpBuffer = NULL;	}	spca50x->buf_state = BUF_NOT_ALLOCATED;	up(&spca50x->buf_lock);	PDEBUG(1, "errored");	return -ENOMEM;}static voidspca5xx_dealloc(struct usb_spca50x *spca50x){	int i;	PDEBUG(2, "entered dealloc");	down(&spca50x->buf_lock);	if (spca50x->fbuf) {		rvfree(spca50x->fbuf, SPCA50X_NUMFRAMES * MAX_DATA_SIZE);		spca50x->fbuf = NULL;		for (i = 0; i < SPCA50X_NUMFRAMES; i++)			spca50x->frame[i].data = NULL;	}	if (spca50x->tmpBuffer) {		rvfree(spca50x->tmpBuffer, MAX_FRAME_SIZE);		spca50x->tmpBuffer = NULL;	}	PDEBUG(2, "buffer memory deallocated");	spca50x->buf_state = BUF_NOT_ALLOCATED;	up(&spca50x->buf_lock);	PDEBUG(2, "leaving dealloc");}/*** Reset the camera and send the correct initialization sequence for the* currently selected source*/static intspca50x_init_source(struct usb_spca50x *spca50x){	int err_code;	if ((err_code = spca50x->funct.initialize(spca50x)) < 0)		return -EINVAL;	spca50x->norme = 0;	spca50x->channel = 0;	spca50x->light_freq = lightfreq;	if ((err_code =	     spca5xx_setMode(spca50x, spca50x->width, spca50x->height,			     VIDEO_PALETTE_RGB24)) < 0)		return -EINVAL;	spca5xx_set_light_freq(spca50x, lightfreq);	return 0;}/****************************************************************************** V4L API****************************************************************************/static inline voidspca5xx_setFrameDecoder(struct usb_spca50x *spca50x){	int i;/* configure the frame detector with default parameters */	memset(&spca50x->pictsetting, 0, sizeof (struct pictparam));	spca50x->pictsetting.change = 0x01;	spca50x->pictsetting.force_rgb = force_rgb;	spca50x->pictsetting.gamma = gamma;	spca50x->pictsetting.OffRed = OffRed;	spca50x->pictsetting.OffBlue = OffBlue;	spca50x->pictsetting.OffGreen = OffGreen;	spca50x->pictsetting.GRed = GRed;	spca50x->pictsetting.GBlue = GBlue;	spca50x->pictsetting.GGreen = GGreen;/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used* (using read() instead). */	for (i = 0; i < SPCA50X_NUMFRAMES; i++) {		spca50x->frame[i].width = spca50x->width;		spca50x->frame[i].height = spca50x->height;		spca50x->frame[i].cameratype = spca50x->cameratype;		spca50x->frame[i].scanlength = spca50x->width * spca50x->height * 3 / 2;	// assumes 4:2:0 data		spca50x->frame[i].depth = 24;/* Note: format reflects format of data as returned to* a process, not as read from camera hardware.* This might be a good idea for dumb programs always* assuming the following settings.*/		spca50x->frame[i].format = VIDEO_PALETTE_RGB24;	}	spca50x->format = VIDEO_PALETTE_RGB24;}static intspca5xx_isjpeg(struct usb_spca50x *spca50x){	if (spca50x->cameratype == JPGH	    || spca50x->cameratype == JPGC	    || spca50x->cameratype == JPGS	    || spca50x->cameratype == JPEG	    || spca50x->cameratype == JPGM 	    || spca50x->cameratype == PJPG	    || spca50x->cameratype == JPGV)		return 1;	return 0;}static voidspca5xx_initDecoder(struct usb_spca50x *spca50x){	if (spca5xx_isjpeg(spca50x))		init_jpeg_decoder(spca50x);	if (spca50x->bridge == BRIDGE_SONIX)		init_sonix_decoder(spca50x);	if (spca50x->bridge == BRIDGE_PAC207)		init_pixart_decoder(spca50x);}static voidspca5xx_chgAuto(struct usb_spca50x *spca50x, __u8 autoval){	spca50x->autoexpo = (int) autoval;	spca50x->funct.set_autobright(spca50x);}static voidspca5xx_chgQtable(struct usb_spca50x *spca50x, __u8 qtable){	int intqtable = (int) qtable;/* one frame maybe corrupted  wait for the result */	if (spca5xx_isjpeg(spca50x) && (spca50x->qindex != intqtable)) {		if (spca50x->cameratype == JPGH) {/* only vimicro ATM */			spca50x->qindex = intqtable;			spca50x->funct.set_quality(spca50x);			init_jpeg_decoder(spca50x);		}	}}static inline voidspca5xx_chgDtimes(struct usb_spca50x *spca50x, __u16 dtimes){	unsigned long flags;	spin_lock_irqsave(&spca50x->v4l_lock, flags);	spca50x->dtimes = (unsigned int) dtimes;	spin_unlock_irqrestore(&spca50x->v4l_lock, flags);}/* Matches the sensor's internal frame rate to the lighting frequency.* Valid frequencies are:* 50 - 50Hz, for European and Asian lighting (default)* 60 - 60Hz, for American lighting*       0 - No Fliker (for outdoore usage)* Returns: 0 for success*/static intspca5xx_set_light_freq(struct usb_spca50x *spca50x, int freq){	int freq_set;	if (freq == 50)		freq_set = freq_50HZ;	else if (freq == 60)		freq_set = freq_60HZ;	else if (freq == 0)		freq_set = NoFliker;	else {		PDEBUG(0, "Invalid light freq (%d Hz)", freq);		return -EINVAL;	}	switch (spca50x->sensor) {	case SENSOR_TAS5130C_VF0250:	case SENSOR_TAS5130CXX:	case SENSOR_PB0330:	case SENSOR_PAS106:	case SENSOR_ICM105A:	case SENSOR_HDCS2020b:	case SENSOR_CS2102:	case SENSOR_OV7660:	case SENSOR_OV7620:	case SENSOR_MC501CB:		break;	default:		PDEBUG(0,		       "Sensor currently not support light frequency banding filters.");		return -EINVAL;	}	if (freq_set == freq_50HZ) {		PDEBUG(1, "Light frequency banding filter set to 50HZ mode");		if (spca50x->mode && spca50x->funct.set_50HZ) {			spca50x->funct.set_50HZ(spca50x);		} else if (spca50x->funct.set_50HZScale) {			spca50x->funct.set_50HZScale(spca50x);		}	} else if (freq_set == freq_60HZ) {		PDEBUG(1, "Light frequency banding filter set to 60HZ mode");		if (spca50x->mode && spca50x->funct.set_60HZ) {			spca50x->funct.set_60HZ(spca50x);		} else if (spca50x->funct.set_60HZScale) {			spca50x->funct.set_60HZScale(spca50x);		}	} else if (freq_set == NoFliker) {		PDEBUG(1,		       "Light frequency banding filter set to NoFliker mode");		if (spca50x->mode && spca50x->funct.set_NoFliker) {			spca50x->funct.set_NoFliker(spca50x);		} else if (spca50x->funct.set_NoFlikerScale) {			spca50x->funct.set_NoFlikerScale(spca50x);		}	}	spca50x->light_freq = freq;	return 0;}static intspca5xx_open(struct inode *inode, struct file *file){	struct video_device *vdev = video_devdata(file);	struct usb_spca50x *spca50x = video_get_drvdata(vdev);	int err;	PDEBUG(2, "opening");	down(&spca50x->lock);/* sanity check disconnect, in use, no memory available */	err = -ENODEV;	if (!spca50x->present)		goto out;	err = -EBUSY;	if (spca50x->user)		goto out;	err = -ENOMEM;	if (spca50x_alloc(spca50x))		goto out;/* initialize sensor and decoding */	err = spca50x_init_source(sp

⌨️ 快捷键说明

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