Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40b8d50a authored by Mike Thomas's avatar Mike Thomas Committed by Greg Kroah-Hartman
Browse files

staging/easycap: Implement interlaced modes and reduced framerates



Interlaced modes are requested by tvtime.  Reduced framerates are
preferred by some userspace programs, e.g. astronomy applications.

Signed-off-by: default avatarMike Thomas <rmthomas@sciolus.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f36bc37a
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -200,7 +200,17 @@
#define  NTSC_M_JP      5
#define  PAL_60         7
#define  PAL_M          9
#define  STANDARD_MANY 10
#define  PAL_BGHIN_SLOW    10
#define  PAL_Nc_SLOW       12
#define  SECAM_SLOW        14
#define  NTSC_N_SLOW       16
#define  NTSC_N_443_SLOW   18
#define  NTSC_M_SLOW       11
#define  NTSC_443_SLOW     13
#define  NTSC_M_JP_SLOW    15
#define  PAL_60_SLOW       17
#define  PAL_M_SLOW        19
#define  STANDARD_MANY 20
/*---------------------------------------------------------------------------*/
/*
 *  ENUMS
@@ -228,7 +238,6 @@ PIXELFORMAT_MANY
enum {
FIELD_NONE,
FIELD_INTERLACED,
FIELD_ALTERNATE,
INTERLACE_MANY
};
#define SETTINGS_MANY	(STANDARD_MANY * \
@@ -333,6 +342,8 @@ bool ntsc;
int fps;
int usec;
int tolerate;
int skip;
int skipped;
int merit[180];

struct timeval timeval0;
@@ -399,7 +410,6 @@ int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */
 */
/*---------------------------------------------------------------------------*/
__u32                   pixelformat;
__u32                   field;
int                     width;
int                     height;
int                     bytesperpixel;
+291 −47
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
 *          peasycap->fps
 *          peasycap->usec
 *          peasycap->tolerate
 *          peasycap->skip
 */
/*---------------------------------------------------------------------------*/
int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
@@ -58,12 +59,20 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) {
	SAM("ERROR: peasycap->pusb_device is NULL\n");
	return -EFAULT;
}
peasycap_standard = &easycap_standard[0];
while (0xFFFF != peasycap_standard->mask) {
	if (std_id == peasycap_standard->v4l2_standard.id)
		break;
	peasycap_standard++;
}
if (0xFFFF == peasycap_standard->mask) {
	peasycap_standard = &easycap_standard[0];
	while (0xFFFF != peasycap_standard->mask) {
		if (std_id & peasycap_standard->v4l2_standard.id)
			break;
		peasycap_standard++;
	}
}
if (0xFFFF == peasycap_standard->mask) {
	SAM("ERROR: 0x%08X=std_id: standard not found\n", \
							(unsigned int)std_id);
@@ -92,10 +101,12 @@ if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
		peasycap_standard->v4l2_standard.frameperiod.numerator;
switch (peasycap->fps) {
case 6:
case 30: {
	peasycap->ntsc = true;
	break;
}
case 5:
case 25: {
	peasycap->ntsc = false;
	break;
@@ -106,9 +117,15 @@ default: {
}
}
JOM(8, "%i frames-per-second\n", peasycap->fps);
if (0x8000 & peasycap_standard->mask) {
	peasycap->skip = 5;
	peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
	peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
} else {
	peasycap->skip = 0;
	peasycap->usec = 1000000 / (2 * peasycap->fps);
	peasycap->tolerate = 1000 * (25 / peasycap->fps);

}
if (peasycap->video_isoc_streaming) {
	resubmit = true;
	kill_video_urbs(peasycap);
@@ -311,7 +328,6 @@ return 0;
 *          peasycap->format_offset
 *          peasycap->inputset[peasycap->input].format_offset
 *          peasycap->pixelformat
 *          peasycap->field
 *          peasycap->height
 *          peasycap->width
 *          peasycap->bytesperpixel
@@ -333,7 +349,7 @@ struct easycap_format *peasycap_format, *peasycap_best_format;
__u16 mask;
struct usb_device *p;
int miss, multiplier, best, k;
char bf[5], *pc;
char bf[5], fo[32], *pc;
__u32 uc;
bool resubmit;

@@ -351,13 +367,62 @@ if ((struct usb_device *)NULL == p) {
	return -EFAULT;
}
pc = &bf[0];
uc = pixelformat;  memcpy((void *)pc, (void *)(&uc), 4);  bf[4] = 0;
mask = easycap_standard[peasycap->standard_offset].mask;
uc = pixelformat;
memcpy((void *)pc, (void *)(&uc), 4);
bf[4] = 0;
mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
SAM("sought:    %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
				width, height, pc, pixelformat, field, mask);
switch (field) {
case V4L2_FIELD_ANY: {
	strcpy(&fo[0], "V4L2_FIELD_ANY ");
	break;
}
case V4L2_FIELD_NONE: {
	strcpy(&fo[0], "V4L2_FIELD_NONE");
	break;
}
case V4L2_FIELD_TOP: {
	strcpy(&fo[0], "V4L2_FIELD_TOP");
	break;
}
case V4L2_FIELD_BOTTOM: {
	strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
	break;
}
case V4L2_FIELD_INTERLACED: {
	strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
	break;
}
case V4L2_FIELD_SEQ_TB: {
	strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
	break;
}
case V4L2_FIELD_SEQ_BT: {
	strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
	break;
}
case V4L2_FIELD_ALTERNATE: {
	strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
	break;
}
case V4L2_FIELD_INTERLACED_TB: {
	strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
	break;
}
case V4L2_FIELD_INTERLACED_BT: {
	strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
	break;
}
default: {
	strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN  ");
	break;
}
}
SAM("sought:    %s\n", &fo[0]);
if (V4L2_FIELD_ANY == field) {
	field = V4L2_FIELD_INTERLACED;
	SAM("prefer:    V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n");
	field = V4L2_FIELD_NONE;
	SAM("prefer:    V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
}
peasycap_best_format = (struct easycap_format *)NULL;
peasycap_format = &easycap_format[0];
@@ -369,7 +434,7 @@ while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
		peasycap_format->v4l2_format.fmt.pix.width,
		peasycap_format->v4l2_format.fmt.pix.height);

	if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
	if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
		(peasycap_format->v4l2_format.fmt.pix.field == field) && \
		(peasycap_format->v4l2_format.fmt.pix.pixelformat == \
							pixelformat) && \
@@ -385,7 +450,7 @@ if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
							width, height, mask);
	peasycap_format = &easycap_format[0];  best = -1;
	while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
		if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
		if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
				 (peasycap_format->v4l2_format.fmt.pix\
						.field == field) && \
				 (peasycap_format->v4l2_format.fmt.pix\
@@ -432,7 +497,6 @@ SAM("actioning: %ix%i %s\n", \
peasycap->height        = peasycap_format->v4l2_format.fmt.pix.height;
peasycap->width         = peasycap_format->v4l2_format.fmt.pix.width;
peasycap->pixelformat   = peasycap_format->v4l2_format.fmt.pix.pixelformat;
peasycap->field         = peasycap_format->v4l2_format.fmt.pix.field;
peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);


@@ -451,11 +515,15 @@ if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {



peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ;
peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
if (0x0100 & peasycap_format->mask)
	peasycap->byteswaporder = true;
else
	peasycap->byteswaporder = false;
if (0x0200 & peasycap_format->mask)
	peasycap->skip = 5;
else
	peasycap->skip = 0;
if (0x0800 & peasycap_format->mask)
	peasycap->decimatepixel = true;
else
@@ -472,24 +540,6 @@ peasycap->videofieldamount = multiplier * peasycap->width * \
					multiplier * peasycap->height;
peasycap->frame_buffer_used = peasycap->bytesperpixel * \
					peasycap->width * peasycap->height;

if (true == peasycap->offerfields) {
	SAM("WARNING: %i=peasycap->field is untested: " \
				"please report problems\n", peasycap->field);


/*
 *    FIXME ---- THIS IS UNTESTED, MAY BE (AND PROBABLY IS) INCORRECT:
 *
 *    peasycap->frame_buffer_used = peasycap->frame_buffer_used / 2;
 *
 *    SO DO NOT RISK IT YET.
 *
 */



}
if (peasycap->video_isoc_streaming) {
	resubmit = true;
	kill_video_urbs(peasycap);
@@ -1386,14 +1436,192 @@ case VIDIOC_ENUM_FMT: {
	break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
 *  THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
 *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUM_FRAMESIZES: {
	JOM(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
	__u32 index;
	struct v4l2_frmsizeenum v4l2_frmsizeenum;

	JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");

	if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \
					sizeof(struct v4l2_frmsizeenum)))
		return -EFAULT;

	index = v4l2_frmsizeenum.index;

	v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;

	if (true == peasycap->ntsc) {
		switch (index) {
		case 0: {
			v4l2_frmsizeenum.discrete.width = 640;
			v4l2_frmsizeenum.discrete.height = 480;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						 discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 1: {
			v4l2_frmsizeenum.discrete.width = 320;
			v4l2_frmsizeenum.discrete.height = 240;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 2: {
			v4l2_frmsizeenum.discrete.width = 720;
			v4l2_frmsizeenum.discrete.height = 480;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 3: {
			v4l2_frmsizeenum.discrete.width = 360;
			v4l2_frmsizeenum.discrete.height = 240;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		default: {
			JOM(8, "%i=index: exhausts framesizes\n", index);
			return -EINVAL;
		}
		}
	} else {
		switch (index) {
		case 0: {
			v4l2_frmsizeenum.discrete.width = 640;
			v4l2_frmsizeenum.discrete.height = 480;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 1: {
			v4l2_frmsizeenum.discrete.width = 320;
			v4l2_frmsizeenum.discrete.height = 240;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 2: {
			v4l2_frmsizeenum.discrete.width = 704;
			v4l2_frmsizeenum.discrete.height = 576;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 3: {
			v4l2_frmsizeenum.discrete.width = 720;
			v4l2_frmsizeenum.discrete.height = 576;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		case 4: {
			v4l2_frmsizeenum.discrete.width = 360;
			v4l2_frmsizeenum.discrete.height = 288;
			JOM(8, "%i=index: %ix%i\n", index, \
					(int)(v4l2_frmsizeenum.\
						discrete.width), \
					(int)(v4l2_frmsizeenum.\
						discrete.height));
			break;
		}
		default: {
			JOM(8, "%i=index: exhausts framesizes\n", index);
			return -EINVAL;
		}
		}
	}
	if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \
					sizeof(struct v4l2_frmsizeenum)))
		return -EFAULT;
	break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
 *  THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
 *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUM_FRAMEINTERVALS: {
	JOM(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
	__u32 index;
	int denominator;
	struct v4l2_frmivalenum v4l2_frmivalenum;

	JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");

	if (peasycap->fps)
		denominator = peasycap->fps;
	else {
		if (true == peasycap->ntsc)
			denominator = 30;
		else
			denominator = 25;
	}

	if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \
					sizeof(struct v4l2_frmivalenum)))
		return -EFAULT;

	index = v4l2_frmivalenum.index;

	v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;

	switch (index) {
	case 0: {
		v4l2_frmivalenum.discrete.numerator = 1;
		v4l2_frmivalenum.discrete.denominator = denominator;
		JOM(8, "%i=index: %i/%i\n", index, \
			(int)(v4l2_frmivalenum.discrete.numerator), \
			(int)(v4l2_frmivalenum.discrete.denominator));
		break;
	}
	case 1: {
		v4l2_frmivalenum.discrete.numerator = 1;
		v4l2_frmivalenum.discrete.denominator = denominator/5;
		JOM(8, "%i=index: %i/%i\n", index, \
			(int)(v4l2_frmivalenum.discrete.numerator), \
			(int)(v4l2_frmivalenum.discrete.denominator));
		break;
	}
	default: {
		JOM(8, "%i=index: exhausts frameintervals\n", index);
		return -EINVAL;
	}
	}
	if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \
					sizeof(struct v4l2_frmivalenum)))
		return -EFAULT;
	break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_FMT: {
	struct v4l2_format v4l2_format;
@@ -1603,6 +1831,10 @@ case VIDIOC_S_STD: {
						sizeof(v4l2_std_id)))
		return -EFAULT;

	JOM(8, "User requests standard: 0x%08X%08X\n", \
		(int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \
		(int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));

	rc = adjust_standard(peasycap, std_id);
	if (0 > rc) {
		JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
@@ -1675,7 +1907,7 @@ case VIDIOC_QUERYBUF: {
	v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
						peasycap->done[index] | \
						peasycap->queued[index];
	v4l2_buffer.field = peasycap->field;
	v4l2_buffer.field = V4L2_FIELD_NONE;
	v4l2_buffer.memory = V4L2_MEMORY_MMAP;
	v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
	v4l2_buffer.length = FRAME_BUFFER_SIZE;
@@ -1762,6 +1994,24 @@ case VIDIOC_DQBUF:
	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;

	if (true == peasycap->offerfields) {
		/*-----------------------------------------------------------*/
		/*
		 *  IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
		 *  V4L2_FIELD_BOTTOM
		*/
		/*-----------------------------------------------------------*/
		if (V4L2_FIELD_TOP == v4l2_buffer.field)
			JOM(8, "user wants V4L2_FIELD_TOP\n");
		else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
			JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
		else if (V4L2_FIELD_ANY == v4l2_buffer.field)
			JOM(8, "user wants V4L2_FIELD_ANY\n");
		else
			JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \
							v4l2_buffer.field);
	}

	if (!peasycap->video_isoc_streaming) {
		JOM(16, "returning -EIO because video urbs not streaming\n");
		return -EIO;
@@ -1811,11 +2061,10 @@ case VIDIOC_DQBUF:
	v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	v4l2_buffer.bytesused = peasycap->frame_buffer_used;
	v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
	v4l2_buffer.field =  peasycap->field;
	if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field)
		v4l2_buffer.field = \
				0x000F & (peasycap->\
				frame_buffer[peasycap->frame_read][0].kount);
	if (true == peasycap->offerfields)
		v4l2_buffer.field = V4L2_FIELD_BOTTOM;
	else
		v4l2_buffer.field = V4L2_FIELD_NONE;
	do_gettimeofday(&timeval);
	timeval2 = timeval;

@@ -1876,10 +2125,6 @@ case VIDIOC_DQBUF:
						sizeof(struct v4l2_buffer)))
		return -EFAULT;

	JOM(8, "..... user is offered frame buffer %i\n", \
							peasycap->frame_read);
	peasycap->frame_lock = 1;

	input = peasycap->frame_buffer[peasycap->frame_read][0].input;
	if (0x08 & input) {
		JOM(8, "user is offered frame buffer %i, input %i\n", \
@@ -1956,7 +2201,6 @@ case VIDIOC_G_PARM: {
	v4l2_streamparm.parm.capture.capability = 0;
	v4l2_streamparm.parm.capture.capturemode = 0;
	v4l2_streamparm.parm.capture.timeperframe.numerator = 1;
	v4l2_streamparm.parm.capture.timeperframe.denominator = 30;

	if (peasycap->fps) {
		v4l2_streamparm.parm.capture.timeperframe.\
+45 −33
Original line number Diff line number Diff line
@@ -471,7 +471,7 @@ if (NULL == peasycap->pusb_device) {
	SAM("ERROR: peasycap->pusb_device is NULL\n");
	return -ENODEV;
}
rc = usb_set_interface(peasycap->pusb_device, \
rc = usb_set_interface(peasycap->pusb_device,
			peasycap->video_interface, \
			peasycap->video_altsetting_off);
if (0 != rc) {
@@ -1103,7 +1103,7 @@ else
int
easycap_dqbuf(struct easycap *peasycap, int mode)
{
int miss, rc;
int ifield, miss, rc;

JOT(8, "\n");

@@ -1111,16 +1111,18 @@ if (NULL == peasycap) {
	SAY("ERROR:  peasycap is NULL\n");
	return -EFAULT;
}
ifield = 0;
JOM(8, "%i=ifield\n", ifield);
/*---------------------------------------------------------------------------*/
/*
 *  WAIT FOR FIELD 0
 *  WAIT FOR FIELD ifield  (0 => TOP, 1 => BOTTOM)
 */
/*---------------------------------------------------------------------------*/
miss = 0;
while ((peasycap->field_read == peasycap->field_fill) || \
				(0 != (0xFF00 & peasycap->field_buffer\
					[peasycap->field_read][0].kount)) || \
				(0 != (0x00FF & peasycap->field_buffer\
				(ifield != (0x00FF & peasycap->field_buffer\
					[peasycap->field_read][0].kount))) {
	if (mode)
		return -EAGAIN;
@@ -1134,7 +1136,7 @@ while ((peasycap->field_read == peasycap->field_fill) || \
			((peasycap->field_read != peasycap->field_fill) && \
				(0 == (0xFF00 & peasycap->field_buffer\
					[peasycap->field_read][0].kount)) && \
				(0 == (0x00FF & peasycap->field_buffer\
				(ifield == (0x00FF & peasycap->field_buffer\
					[peasycap->field_read][0].kount))))))) {
		SAM("aborted by signal\n");
		return -EIO;
@@ -1176,33 +1178,20 @@ JOM(8, "first awakening on wq_video after %i waits\n", miss);
rc = field2frame(peasycap);
if (0 != rc)
	SAM("ERROR: field2frame() returned %i\n", rc);

if (true == peasycap->offerfields) {
	peasycap->frame_read = peasycap->frame_fill;
	(peasycap->frame_fill)++;
	if (peasycap->frame_buffer_many <= peasycap->frame_fill)
		peasycap->frame_fill = 0;

	if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
		peasycap->frame_buffer[peasycap->frame_read][0].kount = \
							V4L2_FIELD_BOTTOM;
	} else {
		peasycap->frame_buffer[peasycap->frame_read][0].kount = \
							V4L2_FIELD_TOP;
	}
JOM(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
JOM(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
}
/*---------------------------------------------------------------------------*/
/*
 *  WAIT FOR FIELD 1
 *  WAIT FOR THE OTHER FIELD
 */
/*---------------------------------------------------------------------------*/
if (ifield)
	ifield = 0;
else
	ifield = 1;
miss = 0;
while ((peasycap->field_read == peasycap->field_fill) || \
				(0 != (0xFF00 & peasycap->field_buffer\
					[peasycap->field_read][0].kount)) || \
				(0 == (0x00FF & peasycap->field_buffer\
				(ifield != (0x00FF & peasycap->field_buffer\
					[peasycap->field_read][0].kount))) {
	if (mode)
		return -EAGAIN;
@@ -1215,8 +1204,9 @@ while ((peasycap->field_read == peasycap->field_fill) || \
			((peasycap->field_read != peasycap->field_fill) && \
				(0 == (0xFF00 & peasycap->field_buffer\
					[peasycap->field_read][0].kount)) && \
				(0 != (0x00FF & peasycap->field_buffer\
					[peasycap->field_read][0].kount))))))) {
				(ifield == (0x00FF & peasycap->field_buffer\
					[peasycap->field_read][0].\
								kount))))))) {
		SAM("aborted by signal\n");
		return -EIO;
	}
@@ -1257,7 +1247,18 @@ JOM(8, "second awakening on wq_video after %i waits\n", miss);
rc = field2frame(peasycap);
if (0 != rc)
	SAM("ERROR: field2frame() returned %i\n", rc);

/*---------------------------------------------------------------------------*/
/*
 *  WASTE THIS FRAME
*/
/*---------------------------------------------------------------------------*/
if (0 != peasycap->skip) {
	peasycap->skipped++;
	if (peasycap->skip != peasycap->skipped)
		return peasycap->skip - peasycap->skipped;
	peasycap->skipped = 0;
}
/*---------------------------------------------------------------------------*/
peasycap->frame_read = peasycap->frame_fill;
peasycap->queued[peasycap->frame_read] = 0;
peasycap->done[peasycap->frame_read]   = V4L2_BUF_FLAG_DONE;
@@ -1289,8 +1290,7 @@ return 0;
 *  odd==false IS TRANSFERRED TO THE FRAME BUFFER.
 *
 *  THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
 *  CHOOSES THE OPTION V4L2_FIELD_ALTERNATE.  NO USERSPACE PROGRAM TESTED
 *  TO DATE HAS DONE THIS.  BUGS ARE LIKELY.
 *  CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
 */
/*---------------------------------------------------------------------------*/
int
@@ -1315,8 +1315,10 @@ if ((struct easycap *)NULL == peasycap) {

badinput = false;

JOM(8, "=====  parity %i, field buffer %i --> frame buffer %i\n", \
JOM(8, "=====  parity %i, input 0x%02X, field buffer %i --> " \
						"frame buffer %i\n", \
			peasycap->field_buffer[peasycap->field_read][0].kount,\
			peasycap->field_buffer[peasycap->field_read][0].input,\
			peasycap->field_read, peasycap->frame_fill);
JOM(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
if (true == peasycap->offerfields)
@@ -1374,7 +1376,7 @@ if (peasycap->field_buffer[kex][0].kount)
else
	odd = false;

if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) {
if ((true == odd) && (false == decimatepixel)) {
	JOM(8, "  initial skipping    %4i          bytes p.%4i\n", \
							w3/multiplier, mad);
	pad += (w3 / multiplier);  rad -= (w3 / multiplier);
@@ -1494,7 +1496,7 @@ while (cz < wz) {
 *  UNLESS IT IS THE LAST LINE OF AN ODD FRAME
 */
/*---------------------------------------------------------------------------*/
		if (((false == odd) || (cz != wz))&&(false == offerfields)) {
		if ((false == odd) || (cz != wz)) {
			over = w3;
			do {
				if (!rad) {
@@ -3162,6 +3164,15 @@ if (purb->status) {
							[peasycap->field_page];
					pfield_buffer->pto = \
							pfield_buffer->pgo;
					pfield_buffer->input = 0x08 | \
						(0x07 & peasycap->input);
					if ((peasycap->field_buffer[peasycap->\
							field_fill][0]).\
								input != \
							pfield_buffer->input)
						(peasycap->field_buffer\
							[peasycap->field_fill]\
							[0]).kount |= 0x1000;
				}

				much = PAGE_SIZE - (int)(pfield_buffer->pto - \
@@ -3441,7 +3452,6 @@ if (0 == bInterfaceNumber) {
			break;
		}
	}

	if (DONGLE_MANY <= dongle_this) {
		SAM("ERROR: too many dongles\n");
		return -ENOMEM;
@@ -3481,6 +3491,8 @@ if (0 == bInterfaceNumber) {

	peasycap->frame_buffer_many = FRAME_BUFFER_MANY;

	peasycap->skip = 0;
	peasycap->skipped = 0;
	peasycap->offerfields = 0;
/*---------------------------------------------------------------------------*/
/*
+230 −38

File changed.

Preview size limit exceeded, changes collapsed.