summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
diff options
context:
space:
mode:
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c')
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
index a175973ef..94539e376 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
@@ -47,15 +47,15 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
{ V4L2_PIX_FMT_YUYV, 0 },
{ V4L2_PIX_FMT_YVYU, 0 },
{ V4L2_PIX_FMT_UYVY, 0 },
- { V4L2_PIX_FMT_SN9C20X_I420, 0 },
- { V4L2_PIX_FMT_SBGGR8, 0 },
- { V4L2_PIX_FMT_SGBRG8, 0 },
- { V4L2_PIX_FMT_SGRBG8, 0 },
- { V4L2_PIX_FMT_SRGGB8, 0 },
- { V4L2_PIX_FMT_SPCA501, 0 },
- { V4L2_PIX_FMT_SPCA505, 0 },
- { V4L2_PIX_FMT_SPCA508, 0 },
- { V4L2_PIX_FMT_HM12, 0 },
+ { V4L2_PIX_FMT_SN9C20X_I420, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SBGGR8, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SGBRG8, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SGRBG8, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SRGGB8, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SPCA501, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SPCA505, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_SPCA508, V4LCONVERT_NEEDS_CONVERSION },
+ { V4L2_PIX_FMT_HM12, V4LCONVERT_NEEDS_CONVERSION },
{ V4L2_PIX_FMT_MJPEG, V4LCONVERT_COMPRESSED },
{ V4L2_PIX_FMT_JPEG, V4LCONVERT_COMPRESSED },
{ V4L2_PIX_FMT_SPCA561, V4LCONVERT_COMPRESSED },
@@ -88,6 +88,10 @@ struct v4lconvert_data *v4lconvert_create(int fd)
int i, j;
struct v4lconvert_data *data = calloc(1, sizeof(struct v4lconvert_data));
struct v4l2_capability cap;
+ /* This keeps tracks of devices which have only formats for which apps
+ most likely will need conversion and we can thus safely add software
+ processing controls without a performance impact. */
+ int always_needs_conversion = 1;
if (!data)
return NULL;
@@ -107,8 +111,13 @@ struct v4lconvert_data *v4lconvert_create(int fd)
if (fmt.pixelformat == supported_src_pixfmts[j].fmt) {
data->supported_src_formats |= 1 << j;
v4lconvert_get_framesizes(data, fmt.pixelformat, j);
+ if (!supported_src_pixfmts[j].flags)
+ always_needs_conversion = 0;
break;
}
+
+ if (j == ARRAY_SIZE(supported_src_pixfmts))
+ always_needs_conversion = 0;
}
data->no_formats = i;
@@ -121,7 +130,7 @@ struct v4lconvert_data *v4lconvert_create(int fd)
data->flags |= V4LCONVERT_IS_SN9C20X;
}
- data->control = v4lcontrol_create(fd);
+ data->control = v4lcontrol_create(fd, always_needs_conversion);
if (!data->control) {
free(data);
return NULL;
@@ -854,7 +863,8 @@ int v4lconvert_convert(struct v4lconvert_data *data,
const struct v4l2_format *dest_fmt, /* in */
unsigned char *src, int src_size, unsigned char *dest, int dest_size)
{
- int res, dest_needed, temp_needed, processing, convert = 0, crop = 0;
+ int res, dest_needed, temp_needed, processing, convert = 0;
+ int rotate90, vflip, hflip, crop;
unsigned char *convert1_dest = dest;
unsigned char *convert2_src = src, *convert2_dest = dest;
unsigned char *rotate90_src = src, *rotate90_dest = dest;
@@ -864,14 +874,15 @@ int v4lconvert_convert(struct v4lconvert_data *data,
struct v4l2_format my_dest_fmt = *dest_fmt;
processing = v4lprocessing_pre_processing(data->processing);
+ rotate90 = data->control_flags & V4LCONTROL_ROTATED_90_JPEG;
+ hflip = v4lcontrol_get_ctrl(data->control, V4LCONTROL_HFLIP);
+ vflip = v4lcontrol_get_ctrl(data->control, V4LCONTROL_VFLIP);
+ crop = my_dest_fmt.fmt.pix.width != my_src_fmt.fmt.pix.width ||
+ my_dest_fmt.fmt.pix.height != my_src_fmt.fmt.pix.height;
if (/* If no conversion/processing is needed */
- (src_fmt->fmt.pix.width == dest_fmt->fmt.pix.width &&
- src_fmt->fmt.pix.height == dest_fmt->fmt.pix.height &&
- src_fmt->fmt.pix.pixelformat == dest_fmt->fmt.pix.pixelformat &&
- !processing &&
- !(data->control_flags & (V4LCONTROL_ROTATED_90_JPEG |
- V4LCONTROL_VFLIPPED | V4LCONTROL_HFLIPPED))) ||
+ (src_fmt->fmt.pix.pixelformat == dest_fmt->fmt.pix.pixelformat &&
+ !processing && !rotate90 && !hflip && !vflip && !crop) ||
/* or if we should do processing/rotating/flipping but the app tries to
use the native cam format, we just return an unprocessed frame copy */
!v4lconvert_supported_dst_format(dest_fmt->fmt.pix.pixelformat)) {
@@ -923,10 +934,6 @@ int v4lconvert_convert(struct v4lconvert_data *data,
else if (my_dest_fmt.fmt.pix.pixelformat != my_src_fmt.fmt.pix.pixelformat)
convert = 1;
- if (my_dest_fmt.fmt.pix.width != my_src_fmt.fmt.pix.width ||
- my_dest_fmt.fmt.pix.height != my_src_fmt.fmt.pix.height)
- crop = 1;
-
/* convert_pixfmt (only if convert == 2) -> processing -> convert_pixfmt ->
rotate -> flip -> crop, all steps are optional */
if (convert == 2) {
@@ -939,8 +946,7 @@ int v4lconvert_convert(struct v4lconvert_data *data,
convert2_src = convert1_dest;
}
- if (convert && ((data->control_flags & (V4LCONTROL_ROTATED_90_JPEG |
- V4LCONTROL_VFLIPPED | V4LCONTROL_HFLIPPED)) || crop)) {
+ if (convert && (rotate90 || hflip || vflip || crop)) {
convert2_dest = v4lconvert_alloc_buffer(data, temp_needed,
&data->convert2_buf, &data->convert2_buf_size);
if (!convert2_dest)
@@ -949,9 +955,7 @@ int v4lconvert_convert(struct v4lconvert_data *data,
rotate90_src = flip_src = crop_src = convert2_dest;
}
- if ((data->control_flags & V4LCONTROL_ROTATED_90_JPEG) &&
- ((data->control_flags & (V4LCONTROL_VFLIPPED | V4LCONTROL_HFLIPPED)) ||
- crop)) {
+ if (rotate90 && (hflip || vflip || crop)) {
rotate90_dest = v4lconvert_alloc_buffer(data, temp_needed,
&data->rotate90_buf, &data->rotate90_buf_size);
if (!rotate90_dest)
@@ -960,8 +964,7 @@ int v4lconvert_convert(struct v4lconvert_data *data,
flip_src = crop_src = rotate90_dest;
}
- if ((data->control_flags & (V4LCONTROL_VFLIPPED | V4LCONTROL_HFLIPPED)) &&
- crop) {
+ if ((vflip || hflip) && crop) {
flip_dest = v4lconvert_alloc_buffer(data, temp_needed, &data->flip_buf,
&data->flip_buf_size);
if (!flip_dest)
@@ -1001,11 +1004,11 @@ int v4lconvert_convert(struct v4lconvert_data *data,
if (processing)
v4lprocessing_processing(data->processing, rotate90_src, &my_src_fmt);
- if (data->control_flags & V4LCONTROL_ROTATED_90_JPEG)
+ if (rotate90)
v4lconvert_rotate90(rotate90_src, rotate90_dest, &my_src_fmt);
- if (data->control_flags & (V4LCONTROL_VFLIPPED | V4LCONTROL_HFLIPPED))
- v4lconvert_flip(flip_src, flip_dest, &my_src_fmt, data->control_flags);
+ if (hflip || vflip)
+ v4lconvert_flip(flip_src, flip_dest, &my_src_fmt, hflip, vflip);
if (crop)
v4lconvert_crop(crop_src, dest, &my_src_fmt, &my_dest_fmt);