rk29-ipp:give a solution of the problem that down scaling is unsupported in some...
authorchenli <chenli@rock-chips.com>
Thu, 29 Sep 2011 09:27:45 +0000 (17:27 +0800)
committerchenli <chenli@rock-chips.com>
Thu, 29 Sep 2011 09:48:02 +0000 (17:48 +0800)
When fmt is YUV,ensure pre_scale_output_w and pre_scale_output_h are even and src image's width and height may be clipped.

drivers/staging/rk29/ipp/rk29-ipp.c

index 63d0936dcdddcdad1ab5c2924a7bd67b17c7a759..5537824910be69ba433db8c5d48420060a2dad24 100755 (executable)
@@ -262,7 +262,7 @@ int ipp_check_param(const struct rk29_ipp_req *req)
 \r
        if(req->src0.fmt == IPP_Y_CBCR_H2V2)\r
        {\r
-               if (unlikely((req->src0.w&0x1 != 0) || (req->src0.h&0x1 != 0) || (req->dst0.w&0x1 != 0)) || (req->dst0.h&0x1 != 0)) {\r
+               if (unlikely(((req->src0.w&0x1) != 0) || ((req->src0.h&0x1) != 0) || ((req->dst0.w&0x1) != 0)) || ((req->dst0.h&0x1) != 0)) {\r
                                printk("YUV420 src or dst resolution is invalid! \n");\r
                                return  -EINVAL;\r
                        }\r
@@ -317,6 +317,8 @@ int ipp_blit(const struct rk29_ipp_req *req)
        uint32_t dst0_YrgbMst=0,dst0_CbrMst=0;\r
        uint32_t ret = 0;\r
        uint32_t deinterlace_config = 0;\r
+       uint32_t src0_w = req->src0.w;\r
+       uint32_t src0_h = req->src0.h;\r
        \r
        //printk("ipp_blit\n");\r
        if (drvdata == NULL) {                  /* ddl@rock-chips.com : check driver is normal or not */\r
@@ -554,7 +556,7 @@ int ipp_blit(const struct rk29_ipp_req *req)
        {\r
                ipp_write(req->src0.CbrMst, IPP_SRC0_CBR_MST);\r
        }\r
-       ipp_write(req->src0.h<<16|req->src0.w, IPP_SRC_IMG_INFO);\r
+       //ipp_write(req->src0.h<<16|req->src0.w, IPP_SRC_IMG_INFO);\r
        ipp_write((ipp_read(IPP_CONFIG)&(~0x7))|req->src0.fmt, IPP_CONFIG);\r
 \r
        /* Configure destination image */\r
@@ -584,7 +586,6 @@ int ipp_blit(const struct rk29_ipp_req *req)
        {\r
                if(((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate)))\r
                {\r
-\r
                        if((req->src0.w>req->dst0.h))\r
                        {\r
                                pre_scale_w = (uint32_t)( req->src0.w/req->dst0.h);//floor\r
@@ -606,7 +607,6 @@ int ipp_blit(const struct rk29_ipp_req *req)
                }\r
                else//0 180 x ,y\r
                {\r
-\r
                        if((req->src0.w>req->dst0.w))\r
                        {\r
                                pre_scale_w = (uint32_t)( req->src0.w/req->dst0.w);//floor\r
@@ -670,6 +670,21 @@ int ipp_blit(const struct rk29_ipp_req *req)
                {\r
                        pre_scale_output_h = req->src0.h/pre_scale_h;\r
                }\r
+\r
+               //when fmt is YUV,make sure pre_scale_output_w and pre_scale_output_h are even\r
+               if(IS_YCRCB(req->src0.fmt))\r
+               {\r
+                       if((pre_scale_output_w & 0x1) != 0)\r
+                       {\r
+                               pre_scale_output_w -=1;\r
+                               src0_w = pre_scale_output_w * pre_scale_w;\r
+                       }\r
+                       if((pre_scale_output_h & 0x1) != 0)\r
+                       {\r
+                               pre_scale_output_h -=1;\r
+                               src0_h = pre_scale_output_h * pre_scale_h;\r
+                       }\r
+               }\r
                        \r
                ipp_write((ipp_read(IPP_CONFIG)&0xffffffef)|PRE_SCALE, IPP_CONFIG);             //enable pre_scale\r
                ipp_write((pre_scale_h-1)<<3|(pre_scale_w-1),IPP_PRE_SCL_PARA);\r
@@ -683,6 +698,8 @@ int ipp_blit(const struct rk29_ipp_req *req)
                ipp_write((req->src0.h<<16)|req->src0.w, IPP_PRE_IMG_INFO);\r
        }\r
 \r
+       ipp_write(src0_h<<16|src0_w, IPP_SRC_IMG_INFO);\r
+       \r
        /*Configure Post_scale*/\r
        if((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate))\r
        {\r