diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-09-21 19:05:45 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 16:33:52 -0400 |
commit | 1f69fd970dfdd9872c83f62864b2557d686948cb (patch) | |
tree | 44222f1582394542bea0881cdc854013b87b598a /drivers/media/video/omap3isp | |
parent | 059dc1d9841f061e5767b95822fb4035ad7559fc (diff) |
[media] omap3isp: preview: Add crop support on the sink pad
The crop rectangle takes the preview engine internal cropping
requirements into account. The smallest allowable margins are 14 columns
and 8 rows when reading from memory, and 18 columns and 8 rows when
processing data on the fly from the CCDC.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/omap3isp')
-rw-r--r-- | drivers/media/video/omap3isp/isppreview.c | 262 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/isppreview.h | 2 |
2 files changed, 198 insertions, 66 deletions
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index d5cce423283c..ccb876fe023f 100644 --- a/drivers/media/video/omap3isp/isppreview.c +++ b/drivers/media/video/omap3isp/isppreview.c | |||
@@ -76,6 +76,42 @@ static struct omap3isp_prev_csc flr_prev_csc = { | |||
76 | 76 | ||
77 | #define DEF_DETECT_CORRECT_VAL 0xe | 77 | #define DEF_DETECT_CORRECT_VAL 0xe |
78 | 78 | ||
79 | /* | ||
80 | * Margins and image size limits. | ||
81 | * | ||
82 | * The preview engine crops several rows and columns internally depending on | ||
83 | * which filters are enabled. To avoid format changes when the filters are | ||
84 | * enabled or disabled (which would prevent them from being turned on or off | ||
85 | * during streaming), the driver assumes all the filters are enabled when | ||
86 | * computing sink crop and source format limits. | ||
87 | * | ||
88 | * If a filter is disabled, additional cropping is automatically added at the | ||
89 | * preview engine input by the driver to avoid overflow at line and frame end. | ||
90 | * This is completely transparent for applications. | ||
91 | * | ||
92 | * Median filter 4 pixels | ||
93 | * Noise filter, | ||
94 | * Faulty pixels correction 4 pixels, 4 lines | ||
95 | * CFA filter 4 pixels, 4 lines in Bayer mode | ||
96 | * 2 lines in other modes | ||
97 | * Color suppression 2 pixels | ||
98 | * or luma enhancement | ||
99 | * ------------------------------------------------------------- | ||
100 | * Maximum total 14 pixels, 8 lines | ||
101 | * | ||
102 | * The color suppression and luma enhancement filters are applied after bayer to | ||
103 | * YUV conversion. They thus can crop one pixel on the left and one pixel on the | ||
104 | * right side of the image without changing the color pattern. When both those | ||
105 | * filters are disabled, the driver must crop the two pixels on the same side of | ||
106 | * the image to avoid changing the bayer pattern. The left margin is thus set to | ||
107 | * 8 pixels and the right margin to 6 pixels. | ||
108 | */ | ||
109 | |||
110 | #define PREV_MARGIN_LEFT 8 | ||
111 | #define PREV_MARGIN_RIGHT 6 | ||
112 | #define PREV_MARGIN_TOP 4 | ||
113 | #define PREV_MARGIN_BOTTOM 4 | ||
114 | |||
79 | #define PREV_MIN_IN_WIDTH 64 | 115 | #define PREV_MIN_IN_WIDTH 64 |
80 | #define PREV_MIN_IN_HEIGHT 8 | 116 | #define PREV_MIN_IN_HEIGHT 8 |
81 | #define PREV_MAX_IN_HEIGHT 16384 | 117 | #define PREV_MAX_IN_HEIGHT 16384 |
@@ -985,52 +1021,36 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average) | |||
985 | * enabled when reporting source pad formats to userspace. If this assumption is | 1021 | * enabled when reporting source pad formats to userspace. If this assumption is |
986 | * not true, rows and columns must be manually cropped at the preview engine | 1022 | * not true, rows and columns must be manually cropped at the preview engine |
987 | * input to avoid overflows at the end of lines and frames. | 1023 | * input to avoid overflows at the end of lines and frames. |
1024 | * | ||
1025 | * See the explanation at the PREV_MARGIN_* definitions for more details. | ||
988 | */ | 1026 | */ |
989 | static void preview_config_input_size(struct isp_prev_device *prev) | 1027 | static void preview_config_input_size(struct isp_prev_device *prev) |
990 | { | 1028 | { |
991 | struct isp_device *isp = to_isp_device(prev); | 1029 | struct isp_device *isp = to_isp_device(prev); |
992 | struct prev_params *params = &prev->params; | 1030 | struct prev_params *params = &prev->params; |
993 | struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK]; | 1031 | unsigned int sph = prev->crop.left; |
994 | unsigned int sph = 0; | 1032 | unsigned int eph = prev->crop.left + prev->crop.width - 1; |
995 | unsigned int eph = format->width - 1; | 1033 | unsigned int slv = prev->crop.top; |
996 | unsigned int slv = 0; | 1034 | unsigned int elv = prev->crop.top + prev->crop.height - 1; |
997 | unsigned int elv = format->height - 1; | 1035 | |
998 | 1036 | if (params->features & PREV_CFA) { | |
999 | if (prev->input == PREVIEW_INPUT_CCDC) { | 1037 | sph -= 2; |
1000 | sph += 2; | 1038 | eph += 2; |
1001 | eph -= 2; | 1039 | slv -= 2; |
1002 | } | 1040 | elv += 2; |
1003 | |||
1004 | /* | ||
1005 | * Median filter 4 pixels | ||
1006 | * Noise filter 4 pixels, 4 lines | ||
1007 | * or faulty pixels correction | ||
1008 | * CFA filter 4 pixels, 4 lines in Bayer mode | ||
1009 | * 2 lines in other modes | ||
1010 | * Color suppression 2 pixels | ||
1011 | * or luma enhancement | ||
1012 | * ------------------------------------------------------------- | ||
1013 | * Maximum total 14 pixels, 8 lines | ||
1014 | */ | ||
1015 | |||
1016 | if (!(params->features & PREV_CFA)) { | ||
1017 | sph += 2; | ||
1018 | eph -= 2; | ||
1019 | slv += 2; | ||
1020 | elv -= 2; | ||
1021 | } | 1041 | } |
1022 | if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) { | 1042 | if (params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER)) { |
1023 | sph += 2; | 1043 | sph -= 2; |
1024 | eph -= 2; | 1044 | eph += 2; |
1025 | slv += 2; | 1045 | slv -= 2; |
1026 | elv -= 2; | 1046 | elv += 2; |
1027 | } | 1047 | } |
1028 | if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) { | 1048 | if (params->features & PREV_HORZ_MEDIAN_FILTER) { |
1029 | sph += 2; | 1049 | sph -= 2; |
1030 | eph -= 2; | 1050 | eph += 2; |
1031 | } | 1051 | } |
1032 | if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE))) | 1052 | if (params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)) |
1033 | sph += 2; | 1053 | sph -= 2; |
1034 | 1054 | ||
1035 | isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, | 1055 | isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, |
1036 | OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO); | 1056 | OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO); |
@@ -1597,6 +1617,16 @@ __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, | |||
1597 | return &prev->formats[pad]; | 1617 | return &prev->formats[pad]; |
1598 | } | 1618 | } |
1599 | 1619 | ||
1620 | static struct v4l2_rect * | ||
1621 | __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, | ||
1622 | enum v4l2_subdev_format_whence which) | ||
1623 | { | ||
1624 | if (which == V4L2_SUBDEV_FORMAT_TRY) | ||
1625 | return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK); | ||
1626 | else | ||
1627 | return &prev->crop; | ||
1628 | } | ||
1629 | |||
1600 | /* previewer format descriptions */ | 1630 | /* previewer format descriptions */ |
1601 | static const unsigned int preview_input_fmts[] = { | 1631 | static const unsigned int preview_input_fmts[] = { |
1602 | V4L2_MBUS_FMT_SGRBG10_1X10, | 1632 | V4L2_MBUS_FMT_SGRBG10_1X10, |
@@ -1611,19 +1641,23 @@ static const unsigned int preview_output_fmts[] = { | |||
1611 | }; | 1641 | }; |
1612 | 1642 | ||
1613 | /* | 1643 | /* |
1614 | * preview_try_format - Handle try format by pad subdev method | 1644 | * preview_try_format - Validate a format |
1615 | * @prev: ISP preview device | 1645 | * @prev: ISP preview engine |
1616 | * @fh : V4L2 subdev file handle | 1646 | * @fh: V4L2 subdev file handle |
1617 | * @pad: pad num | 1647 | * @pad: pad number |
1618 | * @fmt: pointer to v4l2 format structure | 1648 | * @fmt: format to be validated |
1649 | * @which: try/active format selector | ||
1650 | * | ||
1651 | * Validate and adjust the given format for the given pad based on the preview | ||
1652 | * engine limits and the format and crop rectangles on other pads. | ||
1619 | */ | 1653 | */ |
1620 | static void preview_try_format(struct isp_prev_device *prev, | 1654 | static void preview_try_format(struct isp_prev_device *prev, |
1621 | struct v4l2_subdev_fh *fh, unsigned int pad, | 1655 | struct v4l2_subdev_fh *fh, unsigned int pad, |
1622 | struct v4l2_mbus_framefmt *fmt, | 1656 | struct v4l2_mbus_framefmt *fmt, |
1623 | enum v4l2_subdev_format_whence which) | 1657 | enum v4l2_subdev_format_whence which) |
1624 | { | 1658 | { |
1625 | struct v4l2_mbus_framefmt *format; | ||
1626 | enum v4l2_mbus_pixelcode pixelcode; | 1659 | enum v4l2_mbus_pixelcode pixelcode; |
1660 | struct v4l2_rect *crop; | ||
1627 | unsigned int i; | 1661 | unsigned int i; |
1628 | 1662 | ||
1629 | switch (pad) { | 1663 | switch (pad) { |
@@ -1659,15 +1693,8 @@ static void preview_try_format(struct isp_prev_device *prev, | |||
1659 | 1693 | ||
1660 | case PREV_PAD_SOURCE: | 1694 | case PREV_PAD_SOURCE: |
1661 | pixelcode = fmt->code; | 1695 | pixelcode = fmt->code; |
1662 | format = __preview_get_format(prev, fh, PREV_PAD_SINK, which); | 1696 | *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which); |
1663 | memcpy(fmt, format, sizeof(*fmt)); | ||
1664 | 1697 | ||
1665 | /* The preview module output size is configurable through the | ||
1666 | * input interface (horizontal and vertical cropping) and the | ||
1667 | * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In | ||
1668 | * spite of this, hardcode the output size to the biggest | ||
1669 | * possible value for simplicity reasons. | ||
1670 | */ | ||
1671 | switch (pixelcode) { | 1698 | switch (pixelcode) { |
1672 | case V4L2_MBUS_FMT_YUYV8_1X16: | 1699 | case V4L2_MBUS_FMT_YUYV8_1X16: |
1673 | case V4L2_MBUS_FMT_UYVY8_1X16: | 1700 | case V4L2_MBUS_FMT_UYVY8_1X16: |
@@ -1679,20 +1706,14 @@ static void preview_try_format(struct isp_prev_device *prev, | |||
1679 | break; | 1706 | break; |
1680 | } | 1707 | } |
1681 | 1708 | ||
1682 | /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped | 1709 | /* The preview module output size is configurable through the |
1683 | * from the left and right sides when the input source is the | 1710 | * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This |
1684 | * CCDC. This seems not to be needed in practice, investigation | 1711 | * is not supported yet, hardcode the output size to the crop |
1685 | * is required. | 1712 | * rectangle size. |
1686 | */ | ||
1687 | if (prev->input == PREVIEW_INPUT_CCDC) | ||
1688 | fmt->width -= 4; | ||
1689 | |||
1690 | /* Assume that all blocks are enabled and crop pixels and lines | ||
1691 | * accordingly. See preview_config_input_size() for more | ||
1692 | * information. | ||
1693 | */ | 1713 | */ |
1694 | fmt->width -= 14; | 1714 | crop = __preview_get_crop(prev, fh, which); |
1695 | fmt->height -= 8; | 1715 | fmt->width = crop->width; |
1716 | fmt->height = crop->height; | ||
1696 | 1717 | ||
1697 | fmt->colorspace = V4L2_COLORSPACE_JPEG; | 1718 | fmt->colorspace = V4L2_COLORSPACE_JPEG; |
1698 | break; | 1719 | break; |
@@ -1702,6 +1723,49 @@ static void preview_try_format(struct isp_prev_device *prev, | |||
1702 | } | 1723 | } |
1703 | 1724 | ||
1704 | /* | 1725 | /* |
1726 | * preview_try_crop - Validate a crop rectangle | ||
1727 | * @prev: ISP preview engine | ||
1728 | * @sink: format on the sink pad | ||
1729 | * @crop: crop rectangle to be validated | ||
1730 | * | ||
1731 | * The preview engine crops lines and columns for its internal operation, | ||
1732 | * depending on which filters are enabled. Enforce minimum crop margins to | ||
1733 | * handle that transparently for userspace. | ||
1734 | * | ||
1735 | * See the explanation at the PREV_MARGIN_* definitions for more details. | ||
1736 | */ | ||
1737 | static void preview_try_crop(struct isp_prev_device *prev, | ||
1738 | const struct v4l2_mbus_framefmt *sink, | ||
1739 | struct v4l2_rect *crop) | ||
1740 | { | ||
1741 | unsigned int left = PREV_MARGIN_LEFT; | ||
1742 | unsigned int right = sink->width - PREV_MARGIN_RIGHT; | ||
1743 | unsigned int top = PREV_MARGIN_TOP; | ||
1744 | unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM; | ||
1745 | |||
1746 | /* When processing data on-the-fly from the CCDC, at least 2 pixels must | ||
1747 | * be cropped from the left and right sides of the image. As we don't | ||
1748 | * know which filters will be enabled, increase the left and right | ||
1749 | * margins by two. | ||
1750 | */ | ||
1751 | if (prev->input == PREVIEW_INPUT_CCDC) { | ||
1752 | left += 2; | ||
1753 | right -= 2; | ||
1754 | } | ||
1755 | |||
1756 | /* Restrict left/top to even values to keep the Bayer pattern. */ | ||
1757 | crop->left &= ~1; | ||
1758 | crop->top &= ~1; | ||
1759 | |||
1760 | crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH); | ||
1761 | crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT); | ||
1762 | crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH, | ||
1763 | right - crop->left); | ||
1764 | crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT, | ||
1765 | bottom - crop->top); | ||
1766 | } | ||
1767 | |||
1768 | /* | ||
1705 | * preview_enum_mbus_code - Handle pixel format enumeration | 1769 | * preview_enum_mbus_code - Handle pixel format enumeration |
1706 | * @sd : pointer to v4l2 subdev structure | 1770 | * @sd : pointer to v4l2 subdev structure |
1707 | * @fh : V4L2 subdev file handle | 1771 | * @fh : V4L2 subdev file handle |
@@ -1763,6 +1827,60 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, | |||
1763 | } | 1827 | } |
1764 | 1828 | ||
1765 | /* | 1829 | /* |
1830 | * preview_get_crop - Retrieve the crop rectangle on a pad | ||
1831 | * @sd: ISP preview V4L2 subdevice | ||
1832 | * @fh: V4L2 subdev file handle | ||
1833 | * @crop: crop rectangle | ||
1834 | * | ||
1835 | * Return 0 on success or a negative error code otherwise. | ||
1836 | */ | ||
1837 | static int preview_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
1838 | struct v4l2_subdev_crop *crop) | ||
1839 | { | ||
1840 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | ||
1841 | |||
1842 | /* Cropping is only supported on the sink pad. */ | ||
1843 | if (crop->pad != PREV_PAD_SINK) | ||
1844 | return -EINVAL; | ||
1845 | |||
1846 | crop->rect = *__preview_get_crop(prev, fh, crop->which); | ||
1847 | return 0; | ||
1848 | } | ||
1849 | |||
1850 | /* | ||
1851 | * preview_set_crop - Retrieve the crop rectangle on a pad | ||
1852 | * @sd: ISP preview V4L2 subdevice | ||
1853 | * @fh: V4L2 subdev file handle | ||
1854 | * @crop: crop rectangle | ||
1855 | * | ||
1856 | * Return 0 on success or a negative error code otherwise. | ||
1857 | */ | ||
1858 | static int preview_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
1859 | struct v4l2_subdev_crop *crop) | ||
1860 | { | ||
1861 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | ||
1862 | struct v4l2_mbus_framefmt *format; | ||
1863 | |||
1864 | /* Cropping is only supported on the sink pad. */ | ||
1865 | if (crop->pad != PREV_PAD_SINK) | ||
1866 | return -EINVAL; | ||
1867 | |||
1868 | /* The crop rectangle can't be changed while streaming. */ | ||
1869 | if (prev->state != ISP_PIPELINE_STREAM_STOPPED) | ||
1870 | return -EBUSY; | ||
1871 | |||
1872 | format = __preview_get_format(prev, fh, PREV_PAD_SINK, crop->which); | ||
1873 | preview_try_crop(prev, format, &crop->rect); | ||
1874 | *__preview_get_crop(prev, fh, crop->which) = crop->rect; | ||
1875 | |||
1876 | /* Update the source format. */ | ||
1877 | format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, crop->which); | ||
1878 | preview_try_format(prev, fh, PREV_PAD_SOURCE, format, crop->which); | ||
1879 | |||
1880 | return 0; | ||
1881 | } | ||
1882 | |||
1883 | /* | ||
1766 | * preview_get_format - Handle get format by pads subdev method | 1884 | * preview_get_format - Handle get format by pads subdev method |
1767 | * @sd : pointer to v4l2 subdev structure | 1885 | * @sd : pointer to v4l2 subdev structure |
1768 | * @fh : V4L2 subdev file handle | 1886 | * @fh : V4L2 subdev file handle |
@@ -1795,6 +1913,7 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1795 | { | 1913 | { |
1796 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 1914 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
1797 | struct v4l2_mbus_framefmt *format; | 1915 | struct v4l2_mbus_framefmt *format; |
1916 | struct v4l2_rect *crop; | ||
1798 | 1917 | ||
1799 | format = __preview_get_format(prev, fh, fmt->pad, fmt->which); | 1918 | format = __preview_get_format(prev, fh, fmt->pad, fmt->which); |
1800 | if (format == NULL) | 1919 | if (format == NULL) |
@@ -1805,9 +1924,18 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1805 | 1924 | ||
1806 | /* Propagate the format from sink to source */ | 1925 | /* Propagate the format from sink to source */ |
1807 | if (fmt->pad == PREV_PAD_SINK) { | 1926 | if (fmt->pad == PREV_PAD_SINK) { |
1927 | /* Reset the crop rectangle. */ | ||
1928 | crop = __preview_get_crop(prev, fh, fmt->which); | ||
1929 | crop->left = 0; | ||
1930 | crop->top = 0; | ||
1931 | crop->width = fmt->format.width; | ||
1932 | crop->height = fmt->format.height; | ||
1933 | |||
1934 | preview_try_crop(prev, &fmt->format, crop); | ||
1935 | |||
1936 | /* Update the source format. */ | ||
1808 | format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, | 1937 | format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, |
1809 | fmt->which); | 1938 | fmt->which); |
1810 | *format = fmt->format; | ||
1811 | preview_try_format(prev, fh, PREV_PAD_SOURCE, format, | 1939 | preview_try_format(prev, fh, PREV_PAD_SOURCE, format, |
1812 | fmt->which); | 1940 | fmt->which); |
1813 | } | 1941 | } |
@@ -1856,6 +1984,8 @@ static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = { | |||
1856 | .enum_frame_size = preview_enum_frame_size, | 1984 | .enum_frame_size = preview_enum_frame_size, |
1857 | .get_fmt = preview_get_format, | 1985 | .get_fmt = preview_get_format, |
1858 | .set_fmt = preview_set_format, | 1986 | .set_fmt = preview_set_format, |
1987 | .get_crop = preview_get_crop, | ||
1988 | .set_crop = preview_set_crop, | ||
1859 | }; | 1989 | }; |
1860 | 1990 | ||
1861 | /* subdev operations */ | 1991 | /* subdev operations */ |
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h index 272a44a2b9bc..f54e775c2df4 100644 --- a/drivers/media/video/omap3isp/isppreview.h +++ b/drivers/media/video/omap3isp/isppreview.h | |||
@@ -152,6 +152,7 @@ struct isptables_update { | |||
152 | * @subdev: V4L2 subdevice | 152 | * @subdev: V4L2 subdevice |
153 | * @pads: Media entity pads | 153 | * @pads: Media entity pads |
154 | * @formats: Active formats at the subdev pad | 154 | * @formats: Active formats at the subdev pad |
155 | * @crop: Active crop rectangle | ||
155 | * @input: Module currently connected to the input pad | 156 | * @input: Module currently connected to the input pad |
156 | * @output: Bitmask of the active output | 157 | * @output: Bitmask of the active output |
157 | * @video_in: Input video entity | 158 | * @video_in: Input video entity |
@@ -170,6 +171,7 @@ struct isp_prev_device { | |||
170 | struct v4l2_subdev subdev; | 171 | struct v4l2_subdev subdev; |
171 | struct media_pad pads[PREV_PADS_NUM]; | 172 | struct media_pad pads[PREV_PADS_NUM]; |
172 | struct v4l2_mbus_framefmt formats[PREV_PADS_NUM]; | 173 | struct v4l2_mbus_framefmt formats[PREV_PADS_NUM]; |
174 | struct v4l2_rect crop; | ||
173 | 175 | ||
174 | struct v4l2_ctrl_handler ctrls; | 176 | struct v4l2_ctrl_handler ctrls; |
175 | 177 | ||