/*
 * ultracam_ProcessIsocData()
 *
 * Generic routine to parse the ring queue data. It employs either
 * ultracam_find_header() or ultracam_parse_lines() to do most
 * of work.
 *
 * 02-Nov-2000 First (mostly dummy) version.
 * 06-Nov-2000 Rewrote to dump all data into frame.
 */
static void ultracam_ProcessIsocData(struct uvd *uvd, struct usbvideo_frame *frame)
{
	int n;

	assert(uvd != NULL);
	assert(frame != NULL);

	/* Try to move data from queue into frame buffer */
	n = RingQueue_GetLength(&uvd->dp);
	if (n > 0) {
		int m;
		/* See how much spare we have left */
		m = uvd->max_frame_size - frame->seqRead_Length;
		if (n > m)
			n = m;
		/* Now move that much data into frame buffer */
		RingQueue_Dequeue(
			&uvd->dp,
			frame->data + frame->seqRead_Length,
			m);
		frame->seqRead_Length += m;
	}
	/* See if we filled the frame */
	if (frame->seqRead_Length >= uvd->max_frame_size) {
		frame->frameState = FrameState_Done;
		uvd->curframe = -1;
		uvd->stats.frame_num++;
	}
}
Пример #2
0
static void konicawc_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
{
	struct konicawc *cam = (struct konicawc *)uvd->user_data;
	int maxline = cam->maxline;
	int yplanesz = cam->yplanesz;

	assert(frame != NULL);

	DEBUG(5, "maxline = %d yplanesz = %d", maxline, yplanesz);
	DEBUG(3, "Frame state = %d", frame->scanstate);

	if(frame->scanstate == ScanState_Scanning) {
		int drop = 0;
		int curframe;
		int fdrops = 0;
		DEBUG(3, "Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
		while(RingQueue_GetLength(&uvd->dp) >= 4) {
			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
			    (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
			    (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
				curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
				if(cam->lastframe >= 0) {
					fdrops = (0x80 + curframe - cam->lastframe) & 0x7F;
					fdrops--;
					if(fdrops) {
						dev_info(&uvd->dev->dev,
							 "Dropped %d frames "
							 "(%d -> %d)\n",
							 fdrops,
							 cam->lastframe,
							 curframe);
					}
				}
				cam->lastframe = curframe;
				frame->curline = 0;
				frame->scanstate = ScanState_Lines;
				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
				break;
			}
			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
			drop++;
		}
		if(drop)
			DEBUG(2, "dropped %d bytes looking for new frame", drop);
	}

	if(frame->scanstate == ScanState_Scanning)
		return;

	/* Try to move data from queue into frame buffer
	 * We get data in blocks of 384 bytes made up of:
	 * 256 Y, 64 U, 64 V.
	 * This needs to be written out as a Y plane, a U plane and a V plane.
	 */

	while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) {
		/* Y */
		RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
		/* U */
		RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
		/* V */
		RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
		frame->seqRead_Length += 384;
		frame->curline++;
	}
	/* See if we filled the frame */
	if (frame->curline == maxline) {
		DEBUG(5, "got whole frame");

		frame->frameState = FrameState_Done_Hold;
		frame->curline = 0;
		uvd->curframe = -1;
		uvd->stats.frame_num++;
	}
}