# 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
-*/
+ */
#ifndef __LIBV4LPROCESSING_PRIV_H
#define __LIBV4LPROCESSING_PRIV_H
#include "../control/libv4lcontrol.h"
#include "../libv4lsyscall-priv.h"
-#define V4L2PROCESSING_UPDATE_RATE 10
+#define V4L2PROCESSING_UPDATE_RATE 10
struct v4lprocessing_data {
- struct v4lcontrol_data *control;
- int fd;
- int do_process;
- int controls_changed;
- /* True if any of the lookup tables does not contain
- linear 0-255 */
- int lookup_table_active;
- /* Counts the number of processed frames until a
- V4L2PROCESSING_UPDATE_RATE overflow happens */
- int lookup_table_update_counter;
- /* RGB/BGR lookup tables */
- unsigned char comp1[256];
- unsigned char green[256];
- unsigned char comp2[256];
- /* Filter private data for filters which need it */
- /* whitebalance.c data */
- int green_avg;
- int comp1_avg;
- int comp2_avg;
- /* gamma.c data */
- int last_gamma;
- unsigned char gamma_table[256];
- /* autogain.c data */
- int last_gain_correction;
+ struct v4lcontrol_data *control;
+ int fd;
+ int do_process;
+ int controls_changed;
+ /* True if any of the lookup tables does not contain
+ linear 0-255 */
+ int lookup_table_active;
+ /* Counts the number of processed frames until a
+ V4L2PROCESSING_UPDATE_RATE overflow happens */
+ int lookup_table_update_counter;
+ /* RGB/BGR lookup tables */
+ unsigned char comp1[256];
+ unsigned char green[256];
+ unsigned char comp2[256];
+ /* Filter private data for filters which need it */
+ /* whitebalance.c data */
+ int green_avg;
+ int comp1_avg;
+ int comp2_avg;
+ /* gamma.c data */
+ int last_gamma;
+ unsigned char gamma_table[256];
+ /* autogain.c data */
+ int last_gain_correction;
};
struct v4lprocessing_filter {
- /* Returns 1 if the filter is active */
- int (*active)(struct v4lprocessing_data *data);
- /* Returns 1 if any of the lookup tables was changed */
- int (*calculate_lookup_tables)(struct v4lprocessing_data *data,
- unsigned char *buf, const struct v4l2_format *fmt);
+ /* Returns 1 if the filter is active */
+ int (*active)(struct v4lprocessing_data *data);
+ /* Returns 1 if any of the lookup tables was changed */
+ int (*calculate_lookup_tables)(struct v4lprocessing_data *data,
+ unsigned char *buf, const struct v4l2_format *fmt);
};
extern struct v4lprocessing_filter whitebalance_filter;
# 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 <errno.h>
#include <string.h>
#include "../libv4lconvert-priv.h" /* for PIX_FMT defines */
static struct v4lprocessing_filter *filters[] = {
- &whitebalance_filter,
- &autogain_filter,
- &gamma_filter,
+ &whitebalance_filter,
+ &autogain_filter,
+ &gamma_filter,
};
-struct v4lprocessing_data *v4lprocessing_create(int fd, struct v4lcontrol_data* control)
+struct v4lprocessing_data *v4lprocessing_create(int fd, struct v4lcontrol_data *control)
{
- struct v4lprocessing_data *data =
- calloc(1, sizeof(struct v4lprocessing_data));
+ struct v4lprocessing_data *data =
+ calloc(1, sizeof(struct v4lprocessing_data));
- if (!data) {
- fprintf(stderr, "libv4lprocessing: error: out of memory!\n");
- return NULL;
- }
+ if (!data) {
+ fprintf(stderr, "libv4lprocessing: error: out of memory!\n");
+ return NULL;
+ }
- data->fd = fd;
- data->control = control;
+ data->fd = fd;
+ data->control = control;
- return data;
+ return data;
}
void v4lprocessing_destroy(struct v4lprocessing_data *data)
{
- free(data);
+ free(data);
}
int v4lprocessing_pre_processing(struct v4lprocessing_data *data)
{
- int i;
+ int i;
- data->do_process = 0;
- for (i = 0; i < ARRAY_SIZE(filters); i++) {
- if (filters[i]->active(data))
- data->do_process = 1;
- }
+ data->do_process = 0;
+ for (i = 0; i < ARRAY_SIZE(filters); i++) {
+ if (filters[i]->active(data))
+ data->do_process = 1;
+ }
- data->controls_changed |= v4lcontrol_controls_changed(data->control);
+ data->controls_changed |= v4lcontrol_controls_changed(data->control);
- return data->do_process;
+ return data->do_process;
}
static void v4lprocessing_update_lookup_tables(struct v4lprocessing_data *data,
- unsigned char *buf, const struct v4l2_format *fmt)
+ unsigned char *buf, const struct v4l2_format *fmt)
{
- int i;
-
- for (i = 0; i < 256; i++) {
- data->comp1[i] = i;
- data->green[i] = i;
- data->comp2[i] = i;
- }
-
- data->lookup_table_active = 0;
- for (i = 0; i < ARRAY_SIZE(filters); i++) {
- if (filters[i]->active(data)) {
- if (filters[i]->calculate_lookup_tables(data, buf, fmt))
- data->lookup_table_active = 1;
- }
- }
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ data->comp1[i] = i;
+ data->green[i] = i;
+ data->comp2[i] = i;
+ }
+
+ data->lookup_table_active = 0;
+ for (i = 0; i < ARRAY_SIZE(filters); i++) {
+ if (filters[i]->active(data)) {
+ if (filters[i]->calculate_lookup_tables(data, buf, fmt))
+ data->lookup_table_active = 1;
+ }
+ }
}
static void v4lprocessing_do_processing(struct v4lprocessing_data *data,
- unsigned char *buf, const struct v4l2_format *fmt)
+ unsigned char *buf, const struct v4l2_format *fmt)
{
- int x, y;
-
- switch (fmt->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_SGBRG8:
- case V4L2_PIX_FMT_SGRBG8: /* Bayer patterns starting with green */
- for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
- for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
- *buf = data->green[*buf];
- buf++;
- *buf = data->comp1[*buf];
- buf++;
- }
- buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
- for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
- *buf = data->comp2[*buf];
- buf++;
- *buf = data->green[*buf];
- buf++;
+ int x, y;
+
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SGBRG8:
+ case V4L2_PIX_FMT_SGRBG8: /* Bayer patterns starting with green */
+ for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
+ for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
+ *buf = data->green[*buf];
+ buf++;
+ *buf = data->comp1[*buf];
+ buf++;
+ }
+ buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
+ for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
+ *buf = data->comp2[*buf];
+ buf++;
+ *buf = data->green[*buf];
+ buf++;
+ }
+ buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
+ }
+ break;
+
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SRGGB8: /* Bayer patterns *NOT* starting with green */
+ for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
+ for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
+ *buf = data->comp1[*buf];
+ buf++;
+ *buf = data->green[*buf];
+ buf++;
+ }
+ buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
+ for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
+ *buf = data->green[*buf];
+ buf++;
+ *buf = data->comp2[*buf];
+ buf++;
+ }
+ buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
+ }
+ break;
+
+ case V4L2_PIX_FMT_RGB24:
+ case V4L2_PIX_FMT_BGR24:
+ for (y = 0; y < fmt->fmt.pix.height; y++) {
+ for (x = 0; x < fmt->fmt.pix.width; x++) {
+ *buf = data->comp1[*buf];
+ buf++;
+ *buf = data->green[*buf];
+ buf++;
+ *buf = data->comp2[*buf];
+ buf++;
+ }
+ buf += fmt->fmt.pix.bytesperline - 3 * fmt->fmt.pix.width;
+ }
+ break;
}
- buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
- }
- break;
-
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SRGGB8: /* Bayer patterns *NOT* starting with green */
- for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
- for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
- *buf = data->comp1[*buf];
- buf++;
- *buf = data->green[*buf];
- buf++;
- }
- buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
- for (x = 0; x < fmt->fmt.pix.width / 2; x++) {
- *buf = data->green[*buf];
- buf++;
- *buf = data->comp2[*buf];
- buf++;
- }
- buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
- }
- break;
-
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_BGR24:
- for (y = 0; y < fmt->fmt.pix.height; y++) {
- for (x = 0; x < fmt->fmt.pix.width; x++) {
- *buf = data->comp1[*buf];
- buf++;
- *buf = data->green[*buf];
- buf++;
- *buf = data->comp2[*buf];
- buf++;
- }
- buf += fmt->fmt.pix.bytesperline - 3 * fmt->fmt.pix.width;
- }
- break;
- }
}
void v4lprocessing_processing(struct v4lprocessing_data *data,
- unsigned char *buf, const struct v4l2_format *fmt)
+ unsigned char *buf, const struct v4l2_format *fmt)
{
- if (!data->do_process)
- return;
-
- /* Do we support the current pixformat? */
- switch (fmt->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_SGBRG8:
- case V4L2_PIX_FMT_SGRBG8:
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SRGGB8:
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_BGR24:
- break;
- default:
- return; /* Non supported pix format */
- }
-
- if (data->controls_changed ||
- data->lookup_table_update_counter == V4L2PROCESSING_UPDATE_RATE) {
- data->controls_changed = 0;
- data->lookup_table_update_counter = 0;
- /* Do this after resetting lookup_table_update_counter so that filters can
- force the next update to be sooner when they changed camera settings */
- v4lprocessing_update_lookup_tables(data, buf, fmt);
- } else
- data->lookup_table_update_counter++;
-
- if (data->lookup_table_active)
- v4lprocessing_do_processing(data, buf, fmt);
-
- data->do_process = 0;
+ if (!data->do_process)
+ return;
+
+ /* Do we support the current pixformat? */
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SGBRG8:
+ case V4L2_PIX_FMT_SGRBG8:
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SRGGB8:
+ case V4L2_PIX_FMT_RGB24:
+ case V4L2_PIX_FMT_BGR24:
+ break;
+ default:
+ return; /* Non supported pix format */
+ }
+
+ if (data->controls_changed ||
+ data->lookup_table_update_counter == V4L2PROCESSING_UPDATE_RATE) {
+ data->controls_changed = 0;
+ data->lookup_table_update_counter = 0;
+ /* Do this after resetting lookup_table_update_counter so that filters can
+ force the next update to be sooner when they changed camera settings */
+ v4lprocessing_update_lookup_tables(data, buf, fmt);
+ } else
+ data->lookup_table_update_counter++;
+
+ if (data->lookup_table_active)
+ v4lprocessing_do_processing(data, buf, fmt);
+
+ data->do_process = 0;
}