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: Mike Thomas <rmthomas@sciolus.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
f36bc37a48
Коммит
40b8d50ac9
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
case VIDIOC_ENUM_FRAMEINTERVALS: {
|
||||
JOM(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
|
||||
}
|
||||
} 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: {
|
||||
__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.\
|
||||
|
|
|
@ -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;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
|
|
@ -33,11 +33,15 @@
|
|||
* THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
|
||||
* 0 => 25 fps
|
||||
* 1 => 30 fps
|
||||
*
|
||||
* THE MOST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
|
||||
* 0 => full framerate
|
||||
* 1 => 20% framerate
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct easycap_standard easycap_standard[] = {
|
||||
{
|
||||
.mask = 0x000F & PAL_BGHIN ,
|
||||
.mask = 0x00FF & PAL_BGHIN ,
|
||||
.v4l2_standard = {
|
||||
.index = PAL_BGHIN,
|
||||
.id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
|
||||
|
@ -50,7 +54,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & NTSC_N_443 ,
|
||||
.mask = 0x00FF & NTSC_N_443 ,
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_N_443,
|
||||
.id = V4L2_STD_UNKNOWN,
|
||||
|
@ -62,7 +66,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & PAL_Nc ,
|
||||
.mask = 0x00FF & PAL_Nc ,
|
||||
.v4l2_standard = {
|
||||
.index = PAL_Nc,
|
||||
.id = V4L2_STD_PAL_Nc,
|
||||
|
@ -74,7 +78,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & NTSC_N ,
|
||||
.mask = 0x00FF & NTSC_N ,
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_N,
|
||||
.id = V4L2_STD_UNKNOWN,
|
||||
|
@ -86,7 +90,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & SECAM ,
|
||||
.mask = 0x00FF & SECAM ,
|
||||
.v4l2_standard = {
|
||||
.index = SECAM,
|
||||
.id = V4L2_STD_SECAM,
|
||||
|
@ -98,7 +102,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & NTSC_M ,
|
||||
.mask = 0x00FF & NTSC_M ,
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_M,
|
||||
.id = V4L2_STD_NTSC_M,
|
||||
|
@ -110,7 +114,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & NTSC_M_JP ,
|
||||
.mask = 0x00FF & NTSC_M_JP ,
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_M_JP,
|
||||
.id = V4L2_STD_NTSC_M_JP,
|
||||
|
@ -122,7 +126,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & PAL_60 ,
|
||||
.mask = 0x00FF & PAL_60 ,
|
||||
.v4l2_standard = {
|
||||
.index = PAL_60,
|
||||
.id = V4L2_STD_PAL_60,
|
||||
|
@ -134,7 +138,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & NTSC_443 ,
|
||||
.mask = 0x00FF & NTSC_443 ,
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_443,
|
||||
.id = V4L2_STD_NTSC_443,
|
||||
|
@ -146,7 +150,7 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x000F & PAL_M ,
|
||||
.mask = 0x00FF & PAL_M ,
|
||||
.v4l2_standard = {
|
||||
.index = PAL_M,
|
||||
.id = V4L2_STD_PAL_M,
|
||||
|
@ -158,6 +162,128 @@ const struct easycap_standard easycap_standard[] = {
|
|||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = PAL_BGHIN_SLOW,
|
||||
.id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
|
||||
V4L2_STD_PAL_I | V4L2_STD_PAL_N | \
|
||||
(((v4l2_std_id)0x01) << 32)),
|
||||
.name = "PAL_BGHIN_SLOW",
|
||||
.frameperiod = {1, 5},
|
||||
.framelines = 625,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_N_443_SLOW,
|
||||
.id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)),
|
||||
.name = "NTSC_N_443_SLOW",
|
||||
.frameperiod = {1, 5},
|
||||
.framelines = 480,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & PAL_Nc_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = PAL_Nc_SLOW,
|
||||
.id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "PAL_Nc_SLOW",
|
||||
.frameperiod = {1, 5},
|
||||
.framelines = 625,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & NTSC_N_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_N_SLOW,
|
||||
.id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)),
|
||||
.name = "NTSC_N_SLOW",
|
||||
.frameperiod = {1, 5},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & SECAM_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = SECAM_SLOW,
|
||||
.id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "SECAM_SLOW",
|
||||
.frameperiod = {1, 5},
|
||||
.framelines = 625,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & NTSC_M_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_M_SLOW,
|
||||
.id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "NTSC_M_SLOW",
|
||||
.frameperiod = {1, 6},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_M_JP_SLOW,
|
||||
.id = (V4L2_STD_NTSC_M_JP | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "NTSC_M_JP_SLOW",
|
||||
.frameperiod = {1, 6},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & PAL_60_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = PAL_60_SLOW,
|
||||
.id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "PAL_60_SLOW",
|
||||
.frameperiod = {1, 6},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & NTSC_443_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = NTSC_443_SLOW,
|
||||
.id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "NTSC_443_SLOW",
|
||||
.frameperiod = {1, 6},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0x8000 | (0x00FF & PAL_M_SLOW),
|
||||
.v4l2_standard = {
|
||||
.index = PAL_M_SLOW,
|
||||
.id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)),
|
||||
.name = "PAL_M_SLOW",
|
||||
.frameperiod = {1, 6},
|
||||
.framelines = 525,
|
||||
.reserved = {0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
{
|
||||
.mask = 0xFFFF
|
||||
}
|
||||
};
|
||||
|
@ -165,15 +291,16 @@ const struct easycap_standard easycap_standard[] = {
|
|||
/*
|
||||
* THE 16-BIT easycap_format.mask HAS MEANING:
|
||||
* (least significant) BIT 0: 0 => PAL, 25 FPS; 1 => NTSC, 30 FPS
|
||||
* BITS 1-3: RESERVED FOR DIFFERENTIATING STANDARDS
|
||||
* BITS 4-7: NUMBER OF BYTES PER PIXEL
|
||||
* BITS 2-4: RESERVED FOR DIFFERENTIATING STANDARDS
|
||||
* BITS 5-7: NUMBER OF BYTES PER PIXEL
|
||||
* BIT 8: 0 => NATIVE BYTE ORDER; 1 => SWAPPED
|
||||
* BITS 9-10: RESERVED FOR OTHER BYTE PERMUTATIONS
|
||||
* BIT 11: 0 => UNDECIMATED; 1 => DECIMATED
|
||||
* BIT 12: 0 => OFFER FRAMES; 1 => OFFER FIELDS
|
||||
* (most significant) BITS 13-15: RESERVED FOR OTHER FIELD ORDER OPTIONS
|
||||
* BIT 13: 0 => FULL FRAMERATE; 1 => REDUCED
|
||||
* (most significant) BITS 14-15: RESERVED FOR OTHER FIELD/FRAME OPTIONS
|
||||
* IT FOLLOWS THAT:
|
||||
* bytesperpixel IS ((0x00F0 & easycap_format.mask) >> 4)
|
||||
* bytesperpixel IS ((0x00E0 & easycap_format.mask) >> 5)
|
||||
* byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask))
|
||||
*
|
||||
* decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask))
|
||||
|
@ -197,65 +324,135 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) {
|
|||
mask1 = 0x0000;
|
||||
switch (i) {
|
||||
case PAL_BGHIN: {
|
||||
mask1 = PAL_BGHIN;
|
||||
mask1 = 0x1F & PAL_BGHIN;
|
||||
strcpy(&name1[0], "PAL_BGHIN");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case SECAM: {
|
||||
mask1 = SECAM;
|
||||
mask1 = 0x1F & SECAM;
|
||||
strcpy(&name1[0], "SECAM");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_Nc: {
|
||||
mask1 = PAL_Nc;
|
||||
mask1 = 0x1F & PAL_Nc;
|
||||
strcpy(&name1[0], "PAL_Nc");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_60: {
|
||||
mask1 = PAL_60;
|
||||
mask1 = 0x1F & PAL_60;
|
||||
strcpy(&name1[0], "PAL_60");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_M: {
|
||||
mask1 = PAL_M;
|
||||
mask1 = 0x1F & PAL_M;
|
||||
strcpy(&name1[0], "PAL_M");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case NTSC_M: {
|
||||
mask1 = NTSC_M;
|
||||
mask1 = 0x1F & NTSC_M;
|
||||
strcpy(&name1[0], "NTSC_M");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_443: {
|
||||
mask1 = NTSC_443;
|
||||
mask1 = 0x1F & NTSC_443;
|
||||
strcpy(&name1[0], "NTSC_443");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_M_JP: {
|
||||
mask1 = NTSC_M_JP;
|
||||
mask1 = 0x1F & NTSC_M_JP;
|
||||
strcpy(&name1[0], "NTSC_M_JP");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_N: {
|
||||
mask1 = NTSC_M;
|
||||
mask1 = 0x1F & NTSC_M;
|
||||
strcpy(&name1[0], "NTSC_N");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_N_443: {
|
||||
mask1 = NTSC_N_443;
|
||||
mask1 = 0x1F & NTSC_N_443;
|
||||
strcpy(&name1[0], "NTSC_N_443");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case PAL_BGHIN_SLOW: {
|
||||
mask1 = 0x001F & PAL_BGHIN_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "PAL_BGHIN_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case SECAM_SLOW: {
|
||||
mask1 = 0x001F & SECAM_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "SECAM_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_Nc_SLOW: {
|
||||
mask1 = 0x001F & PAL_Nc_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "PAL_Nc_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_60_SLOW: {
|
||||
mask1 = 0x001F & PAL_60_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "PAL_60_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case PAL_M_SLOW: {
|
||||
mask1 = 0x001F & PAL_M_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "PAL_M_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
|
||||
break;
|
||||
}
|
||||
case NTSC_M_SLOW: {
|
||||
mask1 = 0x001F & NTSC_M_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "NTSC_M_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_443_SLOW: {
|
||||
mask1 = 0x001F & NTSC_443_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "NTSC_443_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_M_JP_SLOW: {
|
||||
mask1 = 0x001F & NTSC_M_JP_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "NTSC_M_JP_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_N_SLOW: {
|
||||
mask1 = 0x001F & NTSC_N_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "NTSC_N_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
case NTSC_N_443_SLOW: {
|
||||
mask1 = 0x001F & NTSC_N_443_SLOW;
|
||||
mask1 |= 0x0200;
|
||||
strcpy(&name1[0], "NTSC_N_443_SLOW");
|
||||
colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -311,39 +508,39 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) {
|
|||
case FMT_UYVY: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY));
|
||||
pixelformat = V4L2_PIX_FMT_UYVY;
|
||||
mask3 |= (0x02 << 4);
|
||||
mask3 |= (0x02 << 5);
|
||||
break;
|
||||
}
|
||||
case FMT_YUY2: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2));
|
||||
pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
mask3 |= (0x02 << 4);
|
||||
mask3 |= (0x02 << 5);
|
||||
mask3 |= 0x0100;
|
||||
break;
|
||||
}
|
||||
case FMT_RGB24: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24));
|
||||
pixelformat = V4L2_PIX_FMT_RGB24;
|
||||
mask3 |= (0x03 << 4);
|
||||
mask3 |= (0x03 << 5);
|
||||
break;
|
||||
}
|
||||
case FMT_RGB32: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32));
|
||||
pixelformat = V4L2_PIX_FMT_RGB32;
|
||||
mask3 |= (0x04 << 4);
|
||||
mask3 |= (0x04 << 5);
|
||||
break;
|
||||
}
|
||||
case FMT_BGR24: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24));
|
||||
pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
mask3 |= (0x03 << 4);
|
||||
mask3 |= (0x03 << 5);
|
||||
mask3 |= 0x0100;
|
||||
break;
|
||||
}
|
||||
case FMT_BGR32: {
|
||||
strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32));
|
||||
pixelformat = V4L2_PIX_FMT_BGR32;
|
||||
mask3 |= (0x04 << 4);
|
||||
mask3 |= (0x04 << 5);
|
||||
mask3 |= 0x0100;
|
||||
break;
|
||||
}
|
||||
|
@ -363,13 +560,8 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) {
|
|||
}
|
||||
case FIELD_INTERLACED: {
|
||||
strcpy(&name4[0], "-i");
|
||||
field = V4L2_FIELD_INTERLACED;
|
||||
break;
|
||||
}
|
||||
case FIELD_ALTERNATE: {
|
||||
strcpy(&name4[0], "-a");
|
||||
mask4 |= 0x1000;
|
||||
field = V4L2_FIELD_ALTERNATE;
|
||||
field = V4L2_FIELD_INTERLACED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Загрузка…
Ссылка в новой задаче