Fix for issue: 3437071 Crash during rendering mode change for specific video size

Change-Id: I358c7cc24a7f8c71b953cf5179902fa20fbd727c
diff --git a/libvideoeditor/lvpp/VideoEditorTools.cpp b/libvideoeditor/lvpp/VideoEditorTools.cpp
index 3c3a7b8..c9ee2f6 100755
--- a/libvideoeditor/lvpp/VideoEditorTools.cpp
+++ b/libvideoeditor/lvpp/VideoEditorTools.cpp
@@ -1610,7 +1610,7 @@
                                                                 M4VIFI_ImagePlane *pPlaneIn,

                                                                 M4VIFI_ImagePlane *pPlaneOut)

 {

-    M4VIFI_UInt8    *pu8_data_in, *pu8_data_out;

+    M4VIFI_UInt8    *pu8_data_in, *pu8_data_out, *pu8dum;

     M4VIFI_UInt32   u32_plane;

     M4VIFI_UInt32   u32_width_in, u32_width_out, u32_height_in, u32_height_out;

     M4VIFI_UInt32   u32_stride_in, u32_stride_out;

@@ -1623,19 +1623,29 @@
     M4VIFI_UInt8    *pu8_src_top;

     M4VIFI_UInt8    *pu8_src_bottom;

 

-    if ( (pPlaneIn[0].u_height == pPlaneOut[0].u_height) && (pPlaneIn[0].u_width == pPlaneOut[0].u_width))

+    M4VIFI_UInt8    u8Wflag = 0;

+    M4VIFI_UInt8    u8Hflag = 0;

+    M4VIFI_UInt32   loop = 0;

+

+

+    /*

+     If input width is equal to output width and input height equal to

+     output height then M4VIFI_YUV420toYUV420 is called.

+    */

+    if ((pPlaneIn[0].u_height == pPlaneOut[0].u_height) &&

+              (pPlaneIn[0].u_width == pPlaneOut[0].u_width))

     {

         return M4VIFI_YUV420toYUV420(pUserData, pPlaneIn, pPlaneOut);

     }

 

     /* Check for the YUV width and height are even */

-    if( (IS_EVEN(pPlaneIn[0].u_height) == FALSE)    ||

+    if ((IS_EVEN(pPlaneIn[0].u_height) == FALSE)    ||

         (IS_EVEN(pPlaneOut[0].u_height) == FALSE))

     {

         return M4VIFI_ILLEGAL_FRAME_HEIGHT;

     }

 

-    if( (IS_EVEN(pPlaneIn[0].u_width) == FALSE) ||

+    if ((IS_EVEN(pPlaneIn[0].u_width) == FALSE) ||

         (IS_EVEN(pPlaneOut[0].u_width) == FALSE))

     {

         return M4VIFI_ILLEGAL_FRAME_WIDTH;

@@ -1659,6 +1669,16 @@
         u32_width_out   = pPlaneOut[u32_plane].u_width;

         u32_height_out  = pPlaneOut[u32_plane].u_height;

 

+        /*

+        For the case , width_out = width_in , set the flag to avoid

+        accessing one column beyond the input width.In this case the last

+        column is replicated for processing

+        */

+        if (u32_width_out == u32_width_in) {

+            u32_width_out = u32_width_out-1;

+            u8Wflag = 1;

+        }

+

         /* Compute horizontal ratio between src and destination width.*/

         if (u32_width_out >= u32_width_in)

         {

@@ -1669,6 +1689,16 @@
             u32_x_inc   = (u32_width_in * MAX_SHORT) / (u32_width_out);

         }

 

+        /*

+        For the case , height_out = height_in , set the flag to avoid

+        accessing one row beyond the input height.In this case the last

+        row is replicated for processing

+        */

+        if (u32_height_out == u32_height_in) {

+            u32_height_out = u32_height_out-1;

+            u8Hflag = 1;

+        }

+

         /* Compute vertical ratio between src and destination height.*/

         if (u32_height_out >= u32_height_in)

         {

@@ -1681,14 +1711,15 @@
 

         /*

         Calculate initial accumulator value : u32_y_accum_start.

-        u32_y_accum_start is coded on 15 bits, and represents a value between 0 and 0.5

+        u32_y_accum_start is coded on 15 bits, and represents a value

+        between 0 and 0.5

         */

         if (u32_y_inc >= MAX_SHORT)

         {

-            /*

-                Keep the fractionnal part, assimung that integer  part is coded

-                on the 16 high bits and the fractionnal on the 15 low bits

-            */

+        /*

+        Keep the fractionnal part, assimung that integer  part is coded

+        on the 16 high bits and the fractional on the 15 low bits

+        */

             u32_y_accum = u32_y_inc & 0xffff;

 

             if (!u32_y_accum)

@@ -1705,8 +1736,9 @@
 

 

         /*

-            Calculate initial accumulator value : u32_x_accum_start.

-            u32_x_accum_start is coded on 15 bits, and represents a value between 0 and 0.5

+        Calculate initial accumulator value : u32_x_accum_start.

+        u32_x_accum_start is coded on 15 bits, and represents a value

+        between 0 and 0.5

         */

         if (u32_x_inc >= MAX_SHORT)

         {

@@ -1727,12 +1759,14 @@
         u32_height = u32_height_out;

 

         /*

-        Bilinear interpolation linearly interpolates along each row, and then uses that

-        result in a linear interpolation donw each column. Each estimated pixel in the

-        output image is a weighted combination of its four neighbours according to the formula:

-        F(p',q')=f(p,q)R(-a)R(b)+f(p,q-1)R(-a)R(b-1)+f(p+1,q)R(1-a)R(b)+f(p+&,q+1)R(1-a)R(b-1)

-        with  R(x) = / x+1  -1 =< x =< 0 \ 1-x  0 =< x =< 1 and a (resp. b)weighting coefficient

-        is the distance from the nearest neighbor in the p (resp. q) direction

+        Bilinear interpolation linearly interpolates along each row, and

+        then uses that result in a linear interpolation donw each column.

+        Each estimated pixel in the output image is a weighted combination

+        of its four neighbours according to the formula:

+        F(p',q')=f(p,q)R(-a)R(b)+f(p,q-1)R(-a)R(b-1)+f(p+1,q)R(1-a)R(b)+

+        f(p+&,q+1)R(1-a)R(b-1) with  R(x) = / x+1  -1 =< x =< 0 \ 1-x

+        0 =< x =< 1 and a (resp. b)weighting coefficient is the distance

+        from the nearest neighbor in the p (resp. q) direction

         */

 

         do { /* Scan all the row */

@@ -1762,6 +1796,16 @@
                 u32_x_accum += u32_x_inc;

             } while(--u32_width);

 

+            /*

+               This u8Wflag flag gets in to effect if input and output

+               width is same, and height may be different. So previous

+               pixel is replicated here

+            */

+            if (u8Wflag) {

+                *pu8_data_out = (M4VIFI_UInt8)u32_temp_value;

+            }

+

+            pu8dum = (pu8_data_out-u32_width_out);

             pu8_data_out = pu8_data_out + u32_stride_out - u32_width_out;

 

             /* Update vertical accumulator */

@@ -1771,6 +1815,17 @@
                 u32_y_accum &= 0xffff;

             }

         } while(--u32_height);

+

+        /*

+        This u8Hflag flag gets in to effect if input and output height

+        is same, and width may be different. So previous pixel row is

+        replicated here

+        */

+        if (u8Hflag) {

+            for(loop =0; loop < (u32_width_out+u8Wflag); loop++) {

+                *pu8_data_out++ = (M4VIFI_UInt8)*pu8dum++;

+            }

+        }

     }

 

     return M4VIFI_OK;