diff options
author | Lajos Molnar <molnar@ti.com> | 2010-07-27 20:46:51 +0530 |
---|---|---|
committer | Ricardo Perez Olivares <x0081762@ti.com> | 2010-09-14 19:26:41 -0500 |
commit | dc3b2bd2f439dac6a3205ee67d031a82ce125e1c (patch) | |
tree | 3bc350748c445eea24767decc538362e82b30f44 /drivers/media | |
parent | 978e5839df5b3b52e64e2688ca2217d2c006be31 (diff) |
V4L2 crop support with streaming
Adds the crop support while STREAMON
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Guruswamy Senthilvadivu <svadivu@ti.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/omap/omap_vout.c | 41 | ||||
-rw-r--r-- | drivers/media/video/omap/omap_voutdef.h | 4 |
2 files changed, 27 insertions, 18 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 30f2c13e115d..745a52396e3e 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -48,6 +48,7 @@ #include <plat/vram.h> #include <plat/vrfb.h> #include <plat/display.h> +#include <plat/cpu.h> #include "omap_voutlib.h" #include "omap_voutdef.h" @@ -57,7 +58,6 @@ MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("OMAP Video for Linux Video out driver"); MODULE_LICENSE("GPL"); -#define OMAP_VIDEO3 2 /* Driver Configuration macros */ #define VOUT_NAME "omap_vout" @@ -65,6 +65,7 @@ MODULE_LICENSE("GPL"); enum omap_vout_channels { OMAP_VIDEO1, OMAP_VIDEO2, + OMAP_VIDEO3, }; enum dma_channel_state { @@ -648,7 +649,7 @@ static int v4l2_rot_to_dss_rot(int v4l2_rotation, * start. This offset calculation is mainly required because of * the VRFB 32 pixels alignment with rotation. */ -static int omap_vout_calculate_offset(struct omap_vout_device *vout) +static int omap_vout_calculate_offset(struct omap_vout_device *vout, int idx) { struct omap_overlay *ovl; enum dss_rotation rotation; @@ -659,13 +660,13 @@ static int omap_vout_calculate_offset(struct omap_vout_device *vout) struct omap_dss_device *cur_display; struct v4l2_rect *crop = &vout->crop; struct v4l2_pix_format *pix = &vout->pix; - int *cropped_offset = &vout->cropped_offset; + int *cropped_offset = vout->cropped_offset + idx; int vr_ps = 1, ps = 2; #ifndef CONFIG_ARCH_OMAP4 int temp_ps = 2; int offset = 0; #endif - int *cropped_uv_offset = &vout->cropped_uv_offset; + int *cropped_uv_offset = vout->cropped_uv_offset + idx; int ctop = 0, cleft = 0, line_length = 0; unsigned long addr = 0, uv_addr = 0; @@ -770,12 +771,12 @@ static int omap_vout_calculate_offset(struct omap_vout_device *vout) } #else /* :TODO: change v4l2 to send TSPtr as tiled addresses to DSS2 */ - addr = tiler_get_natural_addr(vout->queued_buf_addr[vout->cur_frm->i]); + addr = tiler_get_natural_addr(vout->queued_buf_addr[idx]); if (OMAP_DSS_COLOR_NV12 == vout->dss_mode) { *cropped_offset = tiler_stride(addr) * crop->top + crop->left; uv_addr = tiler_get_natural_addr( - vout->queued_buf_uv_addr[vout->cur_frm->i]); + vout->queued_buf_uv_addr[idx]); /* :TODO: only allow even crops for NV12 */ *cropped_uv_offset = tiler_stride(uv_addr) * (crop->top >> 1) + (crop->left & ~1); @@ -1871,8 +1872,9 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win); if (!ret) { - /* Video1 plane does not support global alpha */ - if (ovl->id == OMAP_DSS_VIDEO1) + /* Video1 plane does not support global alpha for OMAP 2/3 */ + if ((cpu_is_omap24xx() || cpu_is_omap34xx()) && + ovl->id == OMAP_DSS_VIDEO1) vout->win.global_alpha = 255; else vout->win.global_alpha = f->fmt.win.global_alpha; @@ -1963,7 +1965,11 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) struct omap_overlay *ovl; struct omap_video_timings *timing; - if (vout->streaming) + /* Currently we only allow changing the crop position while + streaming. */ + if (vout->streaming && + (crop->c.height != vout->crop.height || + crop->c.width != vout->crop.width)) return -EBUSY; mutex_lock(&vout->lock); @@ -2220,6 +2226,7 @@ static int vidioc_qbuf(struct file *file, void *fh, { struct omap_vout_device *vout = fh; struct videobuf_queue *q = &vout->vbq; + int ret = 0; if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) || (buffer->index >= vout->buffer_allocated) || @@ -2241,7 +2248,13 @@ static int vidioc_qbuf(struct file *file, void *fh, return -EINVAL; } #endif - return videobuf_qbuf(q, buffer); + ret = videobuf_qbuf(q, buffer); + /* record buffer offset from crop window */ + if (omap_vout_calculate_offset(vout, buffer->index)) { + printk(KERN_ERR "Could not calculate buffer offset\n"); + return -EINVAL; + } + return ret; } static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) @@ -2300,14 +2313,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) vout->first_int = 1; - if (omap_vout_calculate_offset(vout)) { - ret = -EINVAL; - goto streamon_err1; - } addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i] - + vout->cropped_offset; + + vout->cropped_offset[vout->cur_frm->i]; uv_addr = (unsigned long) vout->queued_buf_uv_addr[vout->cur_frm->i] - + vout->cropped_uv_offset; + + vout->cropped_uv_offset[vout->cur_frm->i]; mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_FRAMEDONE | diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h index a9bc59aae16f..d1a5409aaab1 100644 --- a/drivers/media/video/omap/omap_voutdef.h +++ b/drivers/media/video/omap/omap_voutdef.h @@ -146,8 +146,8 @@ struct omap_vout_device { struct videobuf_buffer *cur_frm, *next_frm; struct list_head dma_queue; u8 *queued_buf_addr[VIDEO_MAX_FRAME]; - u32 cropped_offset; - u32 cropped_uv_offset; + u32 cropped_offset[VIDEO_MAX_FRAME]; + u32 cropped_uv_offset[VIDEO_MAX_FRAME]; s32 tv_field1_offset; void *isr_handle; |