aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap/omap_voutlib.c
diff options
context:
space:
mode:
authorVaibhav Hiremath <hvaibhav@ti.com>2010-04-11 09:41:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:58:10 -0400
commit5c7ab6348e7b3fcca2b8ee548306c774472971e2 (patch)
tree3d4c1e776b45b3148b73b029d4104b358a5c51c1 /drivers/media/video/omap/omap_voutlib.c
parent0e1de38db83606d802cf2b3e00cf95fc693b8ca2 (diff)
V4L/DVB: V4L2: Add support for OMAP2/3 V4L2 display driver on top of DSS2
Features Supported - 1. Provides V4L2 user interface for the video pipelines of DSS 2. Basic streaming working on LCD, DVI and TV. 3. Works on latest DSS2 library from Tomi 4. Support for various pixel formats like YUV, UYVY, RGB32, RGB24, RGB565 5. Supports Alpha blending. 6. Supports Color keying both source and destination. 7. Supports rotation. 8. Supports cropping. 9. Supports Background color setting. 10. Allocated buffers to only needed size Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl> Reviewed-by: Muralidharan Karicheri <mkaricheri@gmail.com> Signed-off-by: Murailidharan Karicheri <mkaricheri@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/omap/omap_voutlib.c')
-rw-r--r--drivers/media/video/omap/omap_voutlib.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c
new file mode 100644
index 000000000000..b941c761eef9
--- /dev/null
+++ b/drivers/media/video/omap/omap_voutlib.c
@@ -0,0 +1,293 @@
1/*
2 * omap_voutlib.c
3 *
4 * Copyright (C) 2005-2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * Based on the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
13 *
14 * Author: Andy Lowe (source@mvista.com)
15 *
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
18 *
19 */
20
21#include <linux/module.h>
22#include <linux/errno.h>
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/videodev2.h>
26
27#include <plat/cpu.h>
28
29MODULE_AUTHOR("Texas Instruments");
30MODULE_DESCRIPTION("OMAP Video library");
31MODULE_LICENSE("GPL");
32
33/* Return the default overlay cropping rectangle in crop given the image
34 * size in pix and the video display size in fbuf. The default
35 * cropping rectangle is the largest rectangle no larger than the capture size
36 * that will fit on the display. The default cropping rectangle is centered in
37 * the image. All dimensions and offsets are rounded down to even numbers.
38 */
39void omap_vout_default_crop(struct v4l2_pix_format *pix,
40 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop)
41{
42 crop->width = (pix->width < fbuf->fmt.width) ?
43 pix->width : fbuf->fmt.width;
44 crop->height = (pix->height < fbuf->fmt.height) ?
45 pix->height : fbuf->fmt.height;
46 crop->width &= ~1;
47 crop->height &= ~1;
48 crop->left = ((pix->width - crop->width) >> 1) & ~1;
49 crop->top = ((pix->height - crop->height) >> 1) & ~1;
50}
51EXPORT_SYMBOL_GPL(omap_vout_default_crop);
52
53/* Given a new render window in new_win, adjust the window to the
54 * nearest supported configuration. The adjusted window parameters are
55 * returned in new_win.
56 * Returns zero if succesful, or -EINVAL if the requested window is
57 * impossible and cannot reasonably be adjusted.
58 */
59int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
60 struct v4l2_window *new_win)
61{
62 struct v4l2_rect try_win;
63
64 /* make a working copy of the new_win rectangle */
65 try_win = new_win->w;
66
67 /* adjust the preview window so it fits on the display by clipping any
68 * offscreen areas
69 */
70 if (try_win.left < 0) {
71 try_win.width += try_win.left;
72 try_win.left = 0;
73 }
74 if (try_win.top < 0) {
75 try_win.height += try_win.top;
76 try_win.top = 0;
77 }
78 try_win.width = (try_win.width < fbuf->fmt.width) ?
79 try_win.width : fbuf->fmt.width;
80 try_win.height = (try_win.height < fbuf->fmt.height) ?
81 try_win.height : fbuf->fmt.height;
82 if (try_win.left + try_win.width > fbuf->fmt.width)
83 try_win.width = fbuf->fmt.width - try_win.left;
84 if (try_win.top + try_win.height > fbuf->fmt.height)
85 try_win.height = fbuf->fmt.height - try_win.top;
86 try_win.width &= ~1;
87 try_win.height &= ~1;
88
89 if (try_win.width <= 0 || try_win.height <= 0)
90 return -EINVAL;
91
92 /* We now have a valid preview window, so go with it */
93 new_win->w = try_win;
94 new_win->field = V4L2_FIELD_ANY;
95 return 0;
96}
97EXPORT_SYMBOL_GPL(omap_vout_try_window);
98
99/* Given a new render window in new_win, adjust the window to the
100 * nearest supported configuration. The image cropping window in crop
101 * will also be adjusted if necessary. Preference is given to keeping the
102 * the window as close to the requested configuration as possible. If
103 * successful, new_win, vout->win, and crop are updated.
104 * Returns zero if succesful, or -EINVAL if the requested preview window is
105 * impossible and cannot reasonably be adjusted.
106 */
107int omap_vout_new_window(struct v4l2_rect *crop,
108 struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
109 struct v4l2_window *new_win)
110{
111 int err;
112
113 err = omap_vout_try_window(fbuf, new_win);
114 if (err)
115 return err;
116
117 /* update our preview window */
118 win->w = new_win->w;
119 win->field = new_win->field;
120 win->chromakey = new_win->chromakey;
121
122 /* Adjust the cropping window to allow for resizing limitation */
123 if (cpu_is_omap24xx()) {
124 /* For 24xx limit is 8x to 1/2x scaling. */
125 if ((crop->height/win->w.height) >= 2)
126 crop->height = win->w.height * 2;
127
128 if ((crop->width/win->w.width) >= 2)
129 crop->width = win->w.width * 2;
130
131 if (crop->width > 768) {
132 /* The OMAP2420 vertical resizing line buffer is 768
133 * pixels wide. If the cropped image is wider than
134 * 768 pixels then it cannot be vertically resized.
135 */
136 if (crop->height != win->w.height)
137 crop->width = 768;
138 }
139 } else if (cpu_is_omap34xx()) {
140 /* For 34xx limit is 8x to 1/4x scaling. */
141 if ((crop->height/win->w.height) >= 4)
142 crop->height = win->w.height * 4;
143
144 if ((crop->width/win->w.width) >= 4)
145 crop->width = win->w.width * 4;
146 }
147 return 0;
148}
149EXPORT_SYMBOL_GPL(omap_vout_new_window);
150
151/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to
152 * the nearest supported configuration. The image render window in win will
153 * also be adjusted if necessary. The preview window is adjusted such that the
154 * horizontal and vertical rescaling ratios stay constant. If the render
155 * window would fall outside the display boundaries, the cropping rectangle
156 * will also be adjusted to maintain the rescaling ratios. If successful, crop
157 * and win are updated.
158 * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is
159 * impossible and cannot reasonably be adjusted.
160 */
161int omap_vout_new_crop(struct v4l2_pix_format *pix,
162 struct v4l2_rect *crop, struct v4l2_window *win,
163 struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop)
164{
165 struct v4l2_rect try_crop;
166 unsigned long vresize, hresize;
167
168 /* make a working copy of the new_crop rectangle */
169 try_crop = *new_crop;
170
171 /* adjust the cropping rectangle so it fits in the image */
172 if (try_crop.left < 0) {
173 try_crop.width += try_crop.left;
174 try_crop.left = 0;
175 }
176 if (try_crop.top < 0) {
177 try_crop.height += try_crop.top;
178 try_crop.top = 0;
179 }
180 try_crop.width = (try_crop.width < pix->width) ?
181 try_crop.width : pix->width;
182 try_crop.height = (try_crop.height < pix->height) ?
183 try_crop.height : pix->height;
184 if (try_crop.left + try_crop.width > pix->width)
185 try_crop.width = pix->width - try_crop.left;
186 if (try_crop.top + try_crop.height > pix->height)
187 try_crop.height = pix->height - try_crop.top;
188
189 try_crop.width &= ~1;
190 try_crop.height &= ~1;
191
192 if (try_crop.width <= 0 || try_crop.height <= 0)
193 return -EINVAL;
194
195 if (cpu_is_omap24xx()) {
196 if (crop->height != win->w.height) {
197 /* If we're resizing vertically, we can't support a
198 * crop width wider than 768 pixels.
199 */
200 if (try_crop.width > 768)
201 try_crop.width = 768;
202 }
203 }
204 /* vertical resizing */
205 vresize = (1024 * crop->height) / win->w.height;
206 if (cpu_is_omap24xx() && (vresize > 2048))
207 vresize = 2048;
208 else if (cpu_is_omap34xx() && (vresize > 4096))
209 vresize = 4096;
210
211 win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
212 if (win->w.height == 0)
213 win->w.height = 2;
214 if (win->w.height + win->w.top > fbuf->fmt.height) {
215 /* We made the preview window extend below the bottom of the
216 * display, so clip it to the display boundary and resize the
217 * cropping height to maintain the vertical resizing ratio.
218 */
219 win->w.height = (fbuf->fmt.height - win->w.top) & ~1;
220 if (try_crop.height == 0)
221 try_crop.height = 2;
222 }
223 /* horizontal resizing */
224 hresize = (1024 * crop->width) / win->w.width;
225 if (cpu_is_omap24xx() && (hresize > 2048))
226 hresize = 2048;
227 else if (cpu_is_omap34xx() && (hresize > 4096))
228 hresize = 4096;
229
230 win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
231 if (win->w.width == 0)
232 win->w.width = 2;
233 if (win->w.width + win->w.left > fbuf->fmt.width) {
234 /* We made the preview window extend past the right side of the
235 * display, so clip it to the display boundary and resize the
236 * cropping width to maintain the horizontal resizing ratio.
237 */
238 win->w.width = (fbuf->fmt.width - win->w.left) & ~1;
239 if (try_crop.width == 0)
240 try_crop.width = 2;
241 }
242 if (cpu_is_omap24xx()) {
243 if ((try_crop.height/win->w.height) >= 2)
244 try_crop.height = win->w.height * 2;
245
246 if ((try_crop.width/win->w.width) >= 2)
247 try_crop.width = win->w.width * 2;
248
249 if (try_crop.width > 768) {
250 /* The OMAP2420 vertical resizing line buffer is
251 * 768 pixels wide. If the cropped image is wider
252 * than 768 pixels then it cannot be vertically resized.
253 */
254 if (try_crop.height != win->w.height)
255 try_crop.width = 768;
256 }
257 } else if (cpu_is_omap34xx()) {
258 if ((try_crop.height/win->w.height) >= 4)
259 try_crop.height = win->w.height * 4;
260
261 if ((try_crop.width/win->w.width) >= 4)
262 try_crop.width = win->w.width * 4;
263 }
264 /* update our cropping rectangle and we're done */
265 *crop = try_crop;
266 return 0;
267}
268EXPORT_SYMBOL_GPL(omap_vout_new_crop);
269
270/* Given a new format in pix and fbuf, crop and win
271 * structures are initialized to default values. crop
272 * is initialized to the largest window size that will fit on the display. The
273 * crop window is centered in the image. win is initialized to
274 * the same size as crop and is centered on the display.
275 * All sizes and offsets are constrained to be even numbers.
276 */
277void omap_vout_new_format(struct v4l2_pix_format *pix,
278 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
279 struct v4l2_window *win)
280{
281 /* crop defines the preview source window in the image capture
282 * buffer
283 */
284 omap_vout_default_crop(pix, fbuf, crop);
285
286 /* win defines the preview target window on the display */
287 win->w.width = crop->width;
288 win->w.height = crop->height;
289 win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;
290 win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;
291}
292EXPORT_SYMBOL_GPL(omap_vout_new_format);
293