Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285705
b: refs/heads/master
c: 795e6eb
h: refs/heads/master
i:
  285703: 2a2fb85
v: v3
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Jan 6, 2012
1 parent c09481b commit c6386d2
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 223 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a08d2c727153dc6cea1d5d54a43fd7d69c1467c3
refs/heads/master: 795e6eb3262d3b7247ce450835eea6df6571d103
10 changes: 0 additions & 10 deletions trunk/Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -460,16 +460,6 @@ Who: Jean Delvare <khali@linux-fr.org>

----------------------------

What: Software emulation of arbritary resolutions in the pwc driver
When: 3.3
Why: The pwc driver claims to support any resolution between 160x120
and 640x480, but emulates this by simply drawing a black border
around the image. Userspace can draw its own black border if it
really wants one.
Who: Hans de Goede <hdegoede@redhat.com>

----------------------------

What: For VIDIOC_S_FREQUENCY the type field must match the device node's type.
If not, return -EINVAL.
When: 3.2
Expand Down
69 changes: 13 additions & 56 deletions trunk/drivers/media/video/pwc/pwc-ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
#include "pwc-nala.h"
};

static void pwc_set_image_buffer_size(struct pwc_device *pdev);

/****************************************************************************/

static int _send_control_msg(struct pwc_device *pdev,
Expand Down Expand Up @@ -221,8 +219,9 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
/* Set various parameters */
pdev->vframes = frames;
pdev->valternate = pEntry->alternate;
pdev->image = pwc_image_sizes[size];
pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->frame_size = (pdev->width * pdev->height * 3) / 2;
if (pEntry->compressed) {
if (pdev->release < 5) { /* 4 fold compression */
pdev->vbandlength = 528;
Expand Down Expand Up @@ -282,12 +281,13 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
/* Set various parameters */
pdev->vframes = frames;
pdev->valternate = pChoose->alternate;
pdev->image = pwc_image_sizes[size];
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->vbandlength = pChoose->bandlength;
if (pChoose->bandlength > 0)
pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
pdev->frame_size = (pChoose->bandlength * pdev->height) / 4;
else
pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
return 0;
}

Expand Down Expand Up @@ -339,37 +339,25 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
/* All set and go */
pdev->vframes = frames;
pdev->valternate = pChoose->alternate;
pdev->image = pwc_image_sizes[size];
pdev->width = pwc_image_sizes[size][0];
pdev->height = pwc_image_sizes[size][1];
pdev->vbandlength = pChoose->bandlength;
if (pdev->vbandlength > 0)
pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
pdev->frame_size = (pdev->vbandlength * pdev->height) / 4;
else
pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vbandlength=%d\n",
pdev->frame_size, pdev->vframes, size, pdev->vbandlength);
return 0;
}



/**
@pdev: device structure
@width: viewport width
@height: viewport height
@frame: framerate, in fps
@compression: preferred compression ratio
*/
int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
int frames, int compression)
{
int ret, size;

PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
size = pwc_decode_size(pdev, width, height);
if (size < 0) {
PWC_DEBUG_MODULE("Could not find suitable size.\n");
return -ERANGE;
}
size = pwc_get_size(pdev, width, height);
PWC_TRACE("decode_size = %d.\n", size);

if (DEVICE_USE_CODEC1(pdev->type)) {
Expand All @@ -385,12 +373,9 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
return ret;
}
pdev->view.x = width;
pdev->view.y = height;
pdev->vcompression = compression;
pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
pwc_set_image_buffer_size(pdev);
PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height);
return 0;
}

Expand Down Expand Up @@ -447,34 +432,6 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i
return ret;
}

static void pwc_set_image_buffer_size(struct pwc_device *pdev)
{
int factor = 0;

/* for V4L2_PIX_FMT_YUV420 */
switch (pdev->pixfmt) {
case V4L2_PIX_FMT_YUV420:
factor = 6;
break;
case V4L2_PIX_FMT_PWC1:
case V4L2_PIX_FMT_PWC2:
factor = 6; /* can be uncompressed YUV420P */
break;
}

/* Set sizes in bytes */
pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
pdev->view.size = pdev->view.x * pdev->view.y * factor / 4;

/* Align offset, or you'll get some very weird results in
YUV420 mode... x must be multiple of 4 (to get the Y's in
place), and y even (or you'll mixup U & V). This is less of a
problem for YUV420P.
*/
pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
}

int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
{
int ret;
Expand Down
29 changes: 10 additions & 19 deletions trunk/drivers/media/video/pwc/pwc-dec23.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,18 +656,14 @@ static void DecompressBand23(struct pwc_dec23_private *pdec,
*
* Uncompress a pwc23 buffer.
*
* pwc.view: size of the image wanted
* pwc.image: size of the image returned by the camera
* pwc.offset: (x,y) to displayer image in the view
*
* src: raw data
* dst: image output
*/
void pwc_dec23_decompress(const struct pwc_device *pwc,
const void *src,
void *dst)
{
int bandlines_left, stride, bytes_per_block;
int bandlines_left, bytes_per_block;
struct pwc_dec23_private *pdec = pwc->decompress_data;

/* YUV420P image format */
Expand All @@ -678,28 +674,23 @@ void pwc_dec23_decompress(const struct pwc_device *pwc,

mutex_lock(&pdec->lock);

bandlines_left = pwc->image.y / 4;
bytes_per_block = pwc->view.x * 4;
plane_size = pwc->view.x * pwc->view.y;

/* offset in Y plane */
stride = pwc->view.x * pwc->offset.y;
pout_planar_y = dst + stride + pwc->offset.x;
bandlines_left = pwc->height / 4;
bytes_per_block = pwc->width * 4;
plane_size = pwc->height * pwc->width;

/* offsets in U/V planes */
stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
pout_planar_u = dst + plane_size + stride;
pout_planar_v = dst + plane_size + plane_size / 4 + stride;
pout_planar_y = dst;
pout_planar_u = dst + plane_size;
pout_planar_v = dst + plane_size + plane_size / 4;

while (bandlines_left--) {
DecompressBand23(pwc->decompress_data,
src,
pout_planar_y, pout_planar_u, pout_planar_v,
pwc->image.x, pwc->view.x);
pwc->width, pwc->width);
src += pwc->vbandlength;
pout_planar_y += bytes_per_block;
pout_planar_u += pwc->view.x;
pout_planar_v += pwc->view.x;
pout_planar_u += pwc->width;
pout_planar_v += pwc->width;
}
mutex_unlock(&pdec->lock);
}
10 changes: 6 additions & 4 deletions trunk/drivers/media/video/pwc/pwc-if.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
unsigned int sizes[], void *alloc_ctxs[])
{
struct pwc_device *pdev = vb2_get_drv_priv(vq);
int size;

if (*nbuffers < MIN_FRAMES)
*nbuffers = MIN_FRAMES;
Expand All @@ -664,7 +665,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,

*nplanes = 1;

sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
pwc_image_sizes[size][1] * 3 / 2);

return 0;
}
Expand Down Expand Up @@ -742,7 +745,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
pwc_camera_power(pdev, 1);
if (pdev->power_save) {
/* Restore video mode */
pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y,
pwc_set_video_mode(pdev, pdev->width, pdev->height,
pdev->vframes, pdev->vcompression);
}
pwc_set_leds(pdev, led_on, led_off);
Expand Down Expand Up @@ -1056,7 +1059,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
}
pdev->type = type_id;
pdev->vframes = default_fps;
strcpy(pdev->serial, serial_number);
pdev->features = features;
pwc_construct(pdev); /* set min/max sizes correct */

Expand Down Expand Up @@ -1119,7 +1121,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
pwc_set_leds(pdev, 0, 0);

/* Setup intial videomode */
rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y,
rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
pdev->vframes, pdev->vcompression);
if (rc)
goto err_free_mem;
Expand Down
87 changes: 26 additions & 61 deletions trunk/drivers/media/video/pwc/pwc-misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,67 +27,47 @@

#include "pwc.h"

const struct pwc_coord pwc_image_sizes[PSZ_MAX] =
const int pwc_image_sizes[PSZ_MAX][2] =
{
{ 128, 96, 0 }, /* sqcif */
{ 160, 120, 0 }, /* qsif */
{ 176, 144, 0 }, /* qcif */
{ 320, 240, 0 }, /* sif */
{ 352, 288, 0 }, /* cif */
{ 640, 480, 0 }, /* vga */
{ 128, 96 }, /* sqcif */
{ 160, 120 }, /* qsif */
{ 176, 144 }, /* qcif */
{ 320, 240 }, /* sif */
{ 352, 288 }, /* cif */
{ 640, 480 }, /* vga */
};

/* x,y -> PSZ_ */
int pwc_decode_size(struct pwc_device *pdev, int width, int height)
int pwc_get_size(struct pwc_device *pdev, int width, int height)
{
int i, find;

/* Make sure we don't go beyond our max size.
NB: we have different limits for RAW and normal modes. In case
you don't have the decompressor loaded or use RAW mode,
the maximum viewable size is smaller.
*/
if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
{
if (width > pdev->abs_max.x || height > pdev->abs_max.y)
{
PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
return -1;
}
}
else
{
if (width > pdev->view_max.x || height > pdev->view_max.y)
{
PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n");
return -1;
}
}
int i;

/* Find the largest size supported by the camera that fits into the
requested size.
*/
find = -1;
requested size. */
for (i = PSZ_MAX - 1; i >= 0; i--) {
if (!(pdev->image_mask & (1 << i)))
continue;

if (pwc_image_sizes[i][0] <= width &&
pwc_image_sizes[i][1] <= height)
return i;
}

/* No mode found, return the smallest mode we have */
for (i = 0; i < PSZ_MAX; i++) {
if (pdev->image_mask & (1 << i)) {
if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
find = i;
}
if (pdev->image_mask & (1 << i))
return i;
}
return find;

/* Never reached there always is atleast one supported mode */
return 0;
}

/* initialize variables depending on type and decompressor*/
/* initialize variables depending on type and decompressor */
void pwc_construct(struct pwc_device *pdev)
{
if (DEVICE_USE_CODEC1(pdev->type)) {

pdev->view_min.x = 128;
pdev->view_min.y = 96;
pdev->view_max.x = 352;
pdev->view_max.y = 288;
pdev->abs_max.x = 352;
pdev->abs_max.y = 288;
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
pdev->vcinterface = 2;
pdev->vendpoint = 4;
Expand All @@ -96,34 +76,19 @@ void pwc_construct(struct pwc_device *pdev)

} else if (DEVICE_USE_CODEC3(pdev->type)) {

pdev->view_min.x = 160;
pdev->view_min.y = 120;
pdev->view_max.x = 640;
pdev->view_max.y = 480;
pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
pdev->abs_max.x = 640;
pdev->abs_max.y = 480;
pdev->vcinterface = 3;
pdev->vendpoint = 5;
pdev->frame_header_size = TOUCAM_HEADER_SIZE;
pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;

} else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {

pdev->view_min.x = 128;
pdev->view_min.y = 96;
/* Anthill bug #38: PWC always reports max size, even without PWCX */
pdev->view_max.x = 640;
pdev->view_max.y = 480;
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
pdev->abs_max.x = 640;
pdev->abs_max.y = 480;
pdev->vcinterface = 3;
pdev->vendpoint = 4;
pdev->frame_header_size = 0;
pdev->frame_trailer_size = 0;
}
pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
}
Loading

0 comments on commit c6386d2

Please sign in to comment.