Skip to content

Commit

Permalink
libv4l: add gamma correction to video processing
Browse files Browse the repository at this point in the history
From: Hans de Goede <hdegoede@redhat.com>

add gamma correction to the video processing, and enable it by default
(correct for a display gamma of 1.5) for pac207 based cams.

Priority: normal

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  • Loading branch information
jwrdegoede authored and philips committed Sep 15, 2009
1 parent dc8ce61 commit be008c1
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 9 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -16,6 +16,7 @@ libv4l-0.5.98
* Add software auto gain / exposure
* The V4L2_ENABLE_ENUM_FMT_EMULATION v4l2_fd_open flag is obsolete, libv4l2
now *always* reports emulated formats through the ENUM_FMT ioctl
* Add software gamma correction

libv4l-0.5.97
-------------
Expand Down
3 changes: 0 additions & 3 deletions TODO
Expand Up @@ -12,7 +12,4 @@
-make updating of parameters happen based on time elapsed rather then
frames


-add gamma correction video processing

-get standardized CID for AUTOGAIN_TARGET upstream and switch to that
3 changes: 2 additions & 1 deletion libv4lconvert/Makefile
Expand Up @@ -16,7 +16,8 @@ CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o sn9c20x.o pac207.o \
mr97310a.o flip.o crop.o jidctflt.o spca561-decompress.o \
rgbyuv.o spca501.o sq905c.o bayer.o hm12.o \
control/libv4lcontrol.o processing/libv4lprocessing.o \
processing/whitebalance.o processing/autogain.o
processing/whitebalance.o processing/autogain.o \
processing/gamma.o
TARGETS = $(CONVERT_LIB) libv4lconvert.pc
INCLUDES = ../include/libv4lconvert.h

Expand Down
4 changes: 4 additions & 0 deletions libv4lconvert/control/libv4lcontrol-priv.h
Expand Up @@ -26,13 +26,16 @@

#define V4LCONTROL_SUPPORTS_NEXT_CTRL 0x01

struct v4lcontrol_flags_info;

struct v4lcontrol_data {
int fd; /* Device fd */
int flags; /* Flags for this device */
int priv_flags; /* Internal use only flags */
int controls; /* Which controls to use for this device */
unsigned int *shm_values; /* shared memory control value store */
unsigned int old_values[V4LCONTROL_COUNT]; /* for controls_changed() */
const struct v4lcontrol_flags_info *flags_info;
};

struct v4lcontrol_flags_info {
Expand All @@ -45,6 +48,7 @@ struct v4lcontrol_flags_info {
const char *manufacturer;
const char *product; */
int flags;
int default_gamma;
};

#endif
28 changes: 23 additions & 5 deletions libv4lconvert/control/libv4lcontrol.c
Expand Up @@ -63,16 +63,16 @@ static const struct v4lcontrol_flags_info v4lcontrol_flags[] = {
{ 0x0471, 0x032d, 0, NULL, NULL, V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
/* Genius E-M 112 (also want whitebalance by default) */
{ 0x093a, 0x2476, 0, NULL, NULL,
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB },
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED|V4LCONTROL_WANTS_WB, 1500 },
/* Asus N50Vn laptop */
{ 0x04f2, 0xb106, 0, "ASUSTeK Computer Inc. ", "N50Vn ",
V4LCONTROL_HFLIPPED|V4LCONTROL_VFLIPPED },
/* Second: devices which should use some software processing by default */
/* Pac207 based devices */
{ 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB },
{ 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB },
{ 0x145f, 0x013a, 0, NULL, NULL, V4LCONTROL_WANTS_WB },
{ 0x2001, 0xf115, 0, NULL, NULL, V4LCONTROL_WANTS_WB },
{ 0x041e, 0x4028, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 },
{ 0x093a, 0x2460, 0x1f, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 },
{ 0x145f, 0x013a, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 },
{ 0x2001, 0xf115, 0, NULL, NULL, V4LCONTROL_WANTS_WB, 1500 },
/* Pac7302 based devices */
{ 0x093a, 0x2620, 0x0f, NULL, NULL,
V4LCONTROL_ROTATED_90_JPEG|V4LCONTROL_WANTS_WB },
Expand Down Expand Up @@ -198,6 +198,7 @@ static void v4lcontrol_init_flags(struct v4lcontrol_data *data)
(v4lcontrol_flags[i].dmi_board_name == NULL ||
!strcmp(v4lcontrol_flags[i].dmi_board_name, dmi_board_name))) {
data->flags |= v4lcontrol_flags[i].flags;
data->flags_info = &v4lcontrol_flags[i];
break;
}
}
Expand Down Expand Up @@ -283,6 +284,9 @@ struct v4lcontrol_data *v4lcontrol_create(int fd, int always_needs_conversion)

if (data->flags & V4LCONTROL_WANTS_WB)
data->shm_values[V4LCONTROL_WHITEBALANCE] = 1;

if (data->flags_info && data->flags_info->default_gamma)
data->shm_values[V4LCONTROL_GAMMA] = data->flags_info->default_gamma;
}

return data;
Expand Down Expand Up @@ -331,6 +335,16 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = {
.default_value = 0,
.flags = 0
},
{
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gamma (software)",
.minimum = 500, /* == 0.5 */
.maximum = 3000, /* == 3.0 */
.step = 1,
.default_value = 1000, /* == 1.0 */
.flags = 0
},
{}, /* Dummy place holder for V4LCONTROL_AUTO_ENABLE_COUNT */
{
.id = V4L2_CID_AUTOGAIN,
Expand Down Expand Up @@ -363,6 +377,10 @@ static void v4lcontrol_copy_queryctrl(struct v4lcontrol_data *data,
if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE &&
(data->flags & V4LCONTROL_WANTS_WB))
ctrl->default_value = 1;

if (ctrl->id == V4L2_CID_GAMMA && data->flags_info &&
data->flags_info->default_gamma)
ctrl->default_value = data->flags_info->default_gamma;
}

int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg)
Expand Down
1 change: 1 addition & 0 deletions libv4lconvert/control/libv4lcontrol.h
Expand Up @@ -37,6 +37,7 @@ enum {
V4LCONTROL_WHITEBALANCE,
V4LCONTROL_HFLIP,
V4LCONTROL_VFLIP,
V4LCONTROL_GAMMA,
/* All fake controls above here are auto enabled when not present in hw */
V4LCONTROL_AUTO_ENABLE_COUNT,
V4LCONTROL_AUTOGAIN,
Expand Down
55 changes: 55 additions & 0 deletions libv4lconvert/processing/gamma.c
@@ -0,0 +1,55 @@
/*
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <math.h>
#include "libv4lprocessing.h"
#include "libv4lprocessing-priv.h"

#define CLIP(color) (unsigned char)(((color)>0xff)?0xff:(((color)<0)?0:(color)))

static int gamma_active(struct v4lprocessing_data *data) {
return v4lcontrol_get_ctrl(data->control, V4LCONTROL_GAMMA) != 1000;
}

static int gamma_calculate_lookup_tables(
struct v4lprocessing_data *data,
unsigned char *buf, const struct v4l2_format *fmt)
{
int i, x, gamma;

gamma = v4lcontrol_get_ctrl(data->control, V4LCONTROL_GAMMA);

if (gamma != data->last_gamma) {
for (i = 0; i < 256; i++) {
x = powf(i / 255.0, 1000.0 / gamma) * 255;
data->gamma_table[i] = CLIP(x);
}
data->last_gamma = gamma;
}

for (i = 0; i < 256; i++) {
data->comp1[i] = data->gamma_table[data->comp1[i]];
data->green[i] = data->gamma_table[data->green[i]];
data->comp2[i] = data->gamma_table[data->comp2[i]];
}

return 1;
}

struct v4lprocessing_filter gamma_filter = {
gamma_active, gamma_calculate_lookup_tables };
4 changes: 4 additions & 0 deletions libv4lconvert/processing/libv4lprocessing-priv.h
Expand Up @@ -39,6 +39,9 @@ struct v4lprocessing_data {
unsigned char comp1[256];
unsigned char green[256];
unsigned char comp2[256];
/* Filter private data for filters which need it */
int last_gamma;
unsigned char gamma_table[256];
};

struct v4lprocessing_filter {
Expand All @@ -51,5 +54,6 @@ struct v4lprocessing_filter {

extern struct v4lprocessing_filter whitebalance_filter;
extern struct v4lprocessing_filter autogain_filter;
extern struct v4lprocessing_filter gamma_filter;

#endif
1 change: 1 addition & 0 deletions libv4lconvert/processing/libv4lprocessing.c
Expand Up @@ -31,6 +31,7 @@
static struct v4lprocessing_filter *filters[] = {
&whitebalance_filter,
&autogain_filter,
&gamma_filter,
};

struct v4lprocessing_data *v4lprocessing_create(int fd, struct v4lcontrol_data* control)
Expand Down

0 comments on commit be008c1

Please sign in to comment.