diff options
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c')
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 65 |
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); |