-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some webcams return green screen #370
Labels
Comments
Here is an idea for a patch. diff --git a/lib/libv4lconvert/jpeg.c b/lib/libv4lconvert/jpeg.c
index 15f8dec7..4f4af582 100644
--- a/lib/libv4lconvert/jpeg.c
+++ b/lib/libv4lconvert/jpeg.c
@@ -238,14 +238,30 @@ static int decode_libjpeg_h_samp2(struct v4lconvert_data *data,
struct jpeg_decompress_struct *cinfo = &data->cinfo;
int y;
unsigned int width = cinfo->image_width;
+ unsigned char *drain_buf;
JSAMPROW y_rows[16], u_rows[8], v_rows[8];
JSAMPARRAY rows[3] = { y_rows, u_rows, v_rows };
+ drain_buf = v4lconvert_alloc_buffer(width,
+ &data->convert_pixfmt_buf,
+ &data->convert_pixfmt_buf_size);
+ if (!drain_buf)
+ return v4lconvert_oom_error(data);
+
while (cinfo->output_scanline < cinfo->image_height) {
- for (y = 0; y < 8 * v_samp; y++) {
+ int last_y = cinfo->image_height - cinfo->output_scanline;
+ int last_uv;
+
+ last_y = last_y < 8 * v_samp ? last_y : 8 * v_samp;
+ last_uv = last_y / v_samp;
+
+ for (y = 0; y < last_y; y++) {
y_rows[y] = ydest;
ydest += width;
}
+ for (; y < 8 * v_samp; y++)
+ y_rows[y] = drain_buf;
+
/*
* For v_samp == 1 were going to get 1 set of uv values per
* line, but we need only 1 set per 2 lines since our output
@@ -253,7 +269,7 @@ static int decode_libjpeg_h_samp2(struct v4lconvert_data *data,
* effectively using the second set for each output line.
*/
if (v_samp == 1) {
- for (y = 0; y < 8; y++) {
+ for (y = 0; y < last_uv; y++) {
u_rows[y] = udest;
v_rows[y] = vdest;
y++;
@@ -262,13 +278,18 @@ static int decode_libjpeg_h_samp2(struct v4lconvert_data *data,
udest += width / 2;
vdest += width / 2;
}
+ for (; y < 8; y++)
+ u_rows[y] = v_rows[y] = drain_buf;
+
} else { /* v_samp == 2 */
- for (y = 0; y < 8; y++) {
+ for (y = 0; y < last_uv; y++) {
u_rows[y] = udest;
v_rows[y] = vdest;
udest += width / 2;
vdest += width / 2;
}
+ for (; y < 8; y++)
+ u_rows[y] = v_rows[y] = drain_buf;
}
y = jpeg_read_raw_data(cinfo, rows, 8 * v_samp);
@@ -390,12 +411,14 @@ int v4lconvert_decode_jpeg_libjpeg(struct v4lconvert_data *data,
}
/* We don't want any padding as that may overflow our dest */
+#if 0
if (width % (8 * h_samp) || height % (8 * v_samp)) {
V4LCONVERT_ERR(
"resolution is not a multiple of dctsize");
errno = EIO;
return -1;
}
+#endif
if (dest_pix_fmt == V4L2_PIX_FMT_YVU420) {
vdest = dest + width * height;
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently, libv4lconvert from libv4l is used for image capture. It simplifies conversion from numerous formats various webcams support to the desired V4L2_PIX_FMT_YUV420. It turned out that some webcams have MJPG as a primary format, with resolution which is not multiple of 8, dct block size (960x540 for example). It turned out that libv4lconvert does not expect such resolution and refuses to work.
I can see two possible solutions. First is to read RGB24 from libv4lconvert, and then convert it back to YUV420. Second is to fix non-8-multiple heights in libv4lconvert.
The text was updated successfully, but these errors were encountered: