]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00220747 V4L2 out: Fix mosaic and flash issue if use VDOA input crop mode
authorWayne Zou <b36644@freescale.com>
Thu, 30 Aug 2012 09:20:06 +0000 (17:20 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:28 +0000 (08:35 +0200)
Fix bug:
A lot of mosaic and flash issue if use VDOA mode when doing video playback
on stream H264_BP13_fc_320x136_29.97_444_AAC_48_130_2_vbr.mp4.

For this special stream, the frame size is 320x144 and the stream includes
input cropping information:320x136. It needs to use 320x144 frame size to
do tiled format conversion instead of 320x128 after alignment.

Signed-off-by: Wayne Zou <b36644@freescale.com>
drivers/media/video/mxc/output/mxc_vout.c

index 367cc5f9acc32a655147f217d0a3977596676da9..388c4b39570f2bc459ec2a64c91ba0098e61e642 100644 (file)
@@ -974,6 +974,7 @@ static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
        int is_1080p_stream;
        size_t size;
        struct ipu_task *ipu_task = &vout->task;
+       struct ipu_crop *icrop = &ipu_task->input.crop;
        struct ipu_task *vdoa_task = &vout->vdoa_task;
        u32 deinterlace = 0;
        u32 in_fmt;
@@ -982,15 +983,23 @@ static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
                deinterlace = 1;
 
        memset(vdoa_task, 0, sizeof(*vdoa_task));
-       memcpy(&vdoa_task->input, &ipu_task->input, sizeof(ipu_task->input));
        vdoa_task->output.format = IPU_PIX_FMT_NV12;
-       vdoa_task->output.width = ipu_task->input.crop.w;
-       vdoa_task->output.height = ipu_task->input.crop.h;
-       vdoa_task->output.crop.w = ipu_task->input.crop.w;
-       vdoa_task->output.crop.h = ipu_task->input.crop.h;
-
-       size = PAGE_ALIGN(ipu_task->input.crop.w *
-                                       ipu_task->input.crop.h *
+       memcpy(&vdoa_task->input, &ipu_task->input,
+                       sizeof(ipu_task->input));
+       if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+               (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+               vdoa_task->input.crop.w =
+                       ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+               vdoa_task->input.crop.h =
+                       ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+       }
+       vdoa_task->output.width = vdoa_task->input.crop.w;
+       vdoa_task->output.height = vdoa_task->input.crop.h;
+       vdoa_task->output.crop.w = vdoa_task->input.crop.w;
+       vdoa_task->output.crop.h = vdoa_task->input.crop.h;
+
+       size = PAGE_ALIGN(vdoa_task->input.crop.w *
+                                       vdoa_task->input.crop.h *
                                        fmt_to_bpp(vdoa_task->output.format)/8);
        if (size > vout->vdoa_work.size) {
                if (vout->vdoa_work.vaddr)
@@ -1030,6 +1039,7 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
        u32 o_height = 0;
        u32 ocrop_h = 0;
        bool tiled_fmt = false;
+       bool tiled_need_pp = false;
 
        vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
        if (vout->vdoa_1080p) {
@@ -1042,10 +1052,17 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
 
        if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
                (IPU_PIX_FMT_TILED_NV12F == input->format)) {
-               crop->w -= crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN;
-               crop->h -= crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN;
-               crop->pos.x -= crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN;
-               crop->pos.y -= crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN;
+               if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+                       (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+                       (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+                       (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+                       v4l2_err(vout->vfd->v4l2_dev,
+                               "ERR: tiled fmt needs 16 pixel align.\n");
+                       return -EINVAL;
+               }
+               if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+                       (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+                       tiled_need_pp = true;
        } else {
                crop->w -= crop->w % 8;
                crop->h -= crop->h % 8;
@@ -1073,7 +1090,8 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
                if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
                        (IPU_PIX_FMT_TILED_NV12F == input->format)) {
                        /* check resize/rotate/flip, or csc task */
-                       if (!((IPU_ROTATE_NONE != output->rotate) ||
+                       if (!(tiled_need_pp ||
+                               (IPU_ROTATE_NONE != output->rotate) ||
                                (input->crop.w != output->crop.w) ||
                                (input->crop.h != output->crop.h) ||
                                (!vout->disp_support_csc &&