summaryrefslogtreecommitdiffstats
path: root/exynos/multimedia/utils/csc/exynos4
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-05-20 12:00:36 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-05-20 12:00:36 +0200
commit62f02ba4f4b7b561aa15408ebd9951600bdd71aa (patch)
treeac05dc645945a58edbc26e96df1a78ac16f27706 /exynos/multimedia/utils/csc/exynos4
parente54debb12ecdf92d12acab00a261c0c5a6ef1d64 (diff)
downloadandroid_hardware_samsung-62f02ba4f4b7b561aa15408ebd9951600bdd71aa.tar.gz
android_hardware_samsung-62f02ba4f4b7b561aa15408ebd9951600bdd71aa.tar.bz2
android_hardware_samsung-62f02ba4f4b7b561aa15408ebd9951600bdd71aa.zip
exynos: reorganized and updated from insignal
Changes needed on exynos4210 devices: libcsc -> libseccscapi libswconverter -> remove TARGET_HAL_PATH := hardware/samsung/exynos4/hal TARGET_OMX_PATH := hardware/samsung/exynos/multimedia/openmax $(call inherit-product, hardware/samsung/exynos4210.mk) Change-Id: Ic59ef95b85ef37b3f38fb36cf6a364a5414685ee
Diffstat (limited to 'exynos/multimedia/utils/csc/exynos4')
-rw-r--r--exynos/multimedia/utils/csc/exynos4/Android.mk42
-rw-r--r--exynos/multimedia/utils/csc/exynos4/color_space_convertor.c1732
-rw-r--r--exynos/multimedia/utils/csc/exynos4/color_space_convertor.h414
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp134
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_fimc.h106
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s120
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s492
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s563
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s701
-rw-r--r--exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_deinterleave_crop_neon.s786
10 files changed, 5090 insertions, 0 deletions
diff --git a/exynos/multimedia/utils/csc/exynos4/Android.mk b/exynos/multimedia/utils/csc/exynos4/Android.mk
new file mode 100644
index 0000000..e7ed4e2
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/Android.mk
@@ -0,0 +1,42 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := libsecmm
+LOCAL_COPY_HEADERS := \
+ color_space_convertor.h \
+ csc_fimc.h
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ color_space_convertor.c \
+ csc_linear_to_tiled_crop_neon.s \
+ csc_linear_to_tiled_interleave_crop_neon.s \
+ csc_tiled_to_linear_crop_neon.s \
+ csc_tiled_to_linear_deinterleave_crop_neon.s \
+ csc_interleave_memcpy_neon.s \
+ csc_fimc.cpp
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/$(TARGET_OMX_PATH)/include/khronos \
+ $(TOP)/$(TARGET_OMX_PATH)/include/sec \
+ $(TOP)/$(TARGET_HAL_PATH)/include \
+ $(TOP)/$(TARGET_HAL_PATH)/libhwconverter
+
+ifeq ($(BOARD_USE_SAMSUNG_COLORFORMAT), true)
+LOCAL_CFLAGS += -DUSE_SAMSUNG_COLORFORMAT
+endif
+
+LOCAL_MODULE := libseccscapi
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES := liblog libfimc libhwconverter
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c
new file mode 100644
index 0000000..7a4c559
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.c
@@ -0,0 +1,1732 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file color_space_convertor.c
+ *
+ * @brief SEC_OMX specific define
+ *
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ *
+ * @version 1.0
+ *
+ * @history
+ * 2011.7.01 : Create
+ */
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "color_space_convertor.h"
+
+/*
+ * Get tiled address of position(x,y)
+ *
+ * @param x_size
+ * width of tiled[in]
+ *
+ * @param y_size
+ * height of tiled[in]
+ *
+ * @param x_pos
+ * x position of tield[in]
+ *
+ * @param src_size
+ * y position of tield[in]
+ *
+ * @return
+ * address of tiled data
+ */
+static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+ int pixel_x_m1, pixel_y_m1;
+ int roundup_x, roundup_y;
+ int linear_addr0, linear_addr1, bank_addr ;
+ int x_addr;
+ int trans_addr;
+
+ pixel_x_m1 = x_size -1;
+ pixel_y_m1 = y_size -1;
+
+ roundup_x = ((pixel_x_m1 >> 7) + 1);
+ roundup_y = ((pixel_x_m1 >> 6) + 1);
+
+ x_addr = x_pos >> 2;
+
+ if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
+ (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
+ linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ } else {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ }
+
+ linear_addr0 = linear_addr0 << 2;
+ trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
+
+ return trans_addr;
+}
+
+/*
+ * De-interleaves src to dest1, dest2
+ *
+ * @param dest1
+ * Address of de-interleaved data[out]
+ *
+ * @param dest2
+ * Address of de-interleaved data[out]
+ *
+ * @param src
+ * Address of interleaved data[in]
+ *
+ * @param src_size
+ * Size of interleaved data[in]
+ */
+static void csc_deinterleave_memcpy(
+ unsigned char *dest1,
+ unsigned char *dest2,
+ unsigned char *src,
+ unsigned int src_size)
+{
+ unsigned int i = 0;
+ for(i=0; i<src_size/2; i++) {
+ dest1[i] = src[i*2];
+ dest2[i] = src[i*2+1];
+ }
+}
+
+/*
+ * Interleaves src1, src2 to dest
+ *
+ * @param dest
+ * Address of interleaved data[out]
+ *
+ * @param src1
+ * Address of de-interleaved data[in]
+ *
+ * @param src2
+ * Address of de-interleaved data[in]
+ *
+ * @param src_size
+ * Size of de-interleaved data[in]
+ */
+static void csc_interleave_memcpy(
+ unsigned char *dest,
+ unsigned char *src1,
+ unsigned char *src2,
+ unsigned int src_size)
+{
+ unsigned int i = 0;
+ for(i=0; i<src_size; i++) {
+ dest[i * 2] = src1[i];
+ dest[i * 2 + 1] = src2[i];
+ }
+}
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ * Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+static void csc_tiled_to_linear_crop(
+ unsigned char *yuv420_dest,
+ unsigned char *nv12t_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom)
+{
+ unsigned int i, j;
+ unsigned int tiled_offset = 0, tiled_offset1 = 0;
+ unsigned int linear_offset = 0;
+ unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
+
+ temp3 = yuv420_width-right;
+ temp1 = temp3-left;
+ /* real width is greater than or equal 256 */
+ if (temp1 >= 256) {
+ for (i=top; i<yuv420_height-buttom; i=i+1) {
+ j = left;
+ temp3 = (j>>8)<<8;
+ temp3 = temp3>>6;
+ temp4 = i>>5;
+ if (temp4 & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = temp4-1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset+2;
+ temp1 = (temp3>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 8;
+ } else {
+ temp2 = ((yuv420_height+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = temp3+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = temp3+temp1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset+temp4*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*6;
+ temp4 = 8;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = temp4*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 4;
+ }
+ }
+
+ temp1 = i&0x1F;
+ tiled_offset = tiled_offset+64*(temp1);
+ tiled_offset1 = tiled_offset1+64*(temp1);
+ temp2 = yuv420_width-left-right;
+ linear_offset = temp2*(i-top);
+ temp3 = ((j+256)>>8)<<8;
+ temp3 = temp3-j;
+ temp1 = left&0x3F;
+ if (temp3 > 192) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
+ temp2 = ((left+63)>>6)<<6;
+ temp3 = ((yuv420_width-right)>>6)<<6;
+ if (temp2 == temp3) {
+ temp2 = yuv420_width-right-(64-temp1);
+ }
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+256-temp1;
+ } else if (temp3 > 128) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+192-temp1;
+ } else if (temp3 > 64) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+128-temp1;
+ } else if (temp3 > 0) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
+ linear_offset = linear_offset+64-temp1;
+ }
+
+ tiled_offset = tiled_offset+temp4*2048;
+ j = (left>>8)<<8;
+ j = j + 256;
+ temp2 = yuv420_width-right-256;
+ for (; j<=temp2; j=j+256) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+ tiled_offset = tiled_offset+temp4*2048;
+ memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+256;
+ }
+
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ temp2 = yuv420_width-right-j;
+ if (temp2 > 192) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
+ } else if (temp2 > 128) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
+ } else if (temp2 > 64) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
+ } else {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ }
+ }
+ } else if (temp1 >= 64) {
+ for (i=top; i<(yuv420_height-buttom); i=i+1) {
+ j = left;
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp2 = ((j+64)>>6)<<6;
+ temp2 = temp2-j;
+ linear_offset = temp1*(i-top);
+ temp4 = j&0x3;
+ tiled_offset = tiled_offset+temp4;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ linear_offset = linear_offset+temp2;
+ j = j+temp2;
+ if ((j+64) <= temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ linear_offset = linear_offset+64;
+ j = j+64;
+ }
+ if ((j+64) <= temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ linear_offset = linear_offset+64;
+ j = j+64;
+ }
+ if (j < temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp2 = temp3-j;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ }
+ }
+ } else {
+ for (i=top; i<(yuv420_height-buttom); i=i+1) {
+ linear_offset = temp1*(i-top);
+ for (j=left; j<(yuv420_width-right); j=j+2) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp4 = j&0x3;
+ tiled_offset = tiled_offset+temp4;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
+ linear_offset = linear_offset+2;
+ }
+ }
+ }
+}
+
+/*
+ * Converts and Deinterleaves tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. UV of NV12T to UV of YUV420P
+ *
+ * @param yuv420_u_dest
+ * U plane address of YUV420P[out]
+ *
+ * @param yuv420_v_dest
+ * V plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_uv_height
+ * Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+static void csc_tiled_to_linear_deinterleave_crop(
+ unsigned char *yuv420_u_dest,
+ unsigned char *yuv420_v_dest,
+ unsigned char *nv12t_uv_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_uv_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom)
+{
+ unsigned int i, j;
+ unsigned int tiled_offset = 0, tiled_offset1 = 0;
+ unsigned int linear_offset = 0;
+ unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
+
+ temp3 = yuv420_width-right;
+ temp1 = temp3-left;
+ /* real width is greater than or equal 256 */
+ if (temp1 >= 256) {
+ for (i=top; i<yuv420_uv_height-buttom; i=i+1) {
+ j = left;
+ temp3 = (j>>8)<<8;
+ temp3 = temp3>>6;
+ temp4 = i>>5;
+ if (temp4 & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = temp4-1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset+2;
+ temp1 = (temp3>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 8;
+ } else {
+ temp2 = ((yuv420_uv_height+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = temp3+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = temp3+temp1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset+temp4*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*6;
+ temp4 = 8;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = temp4*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 4;
+ }
+ }
+
+ temp1 = i&0x1F;
+ tiled_offset = tiled_offset+64*(temp1);
+ tiled_offset1 = tiled_offset1+64*(temp1);
+ temp2 = yuv420_width-left-right;
+ linear_offset = temp2*(i-top)/2;
+ temp3 = ((j+256)>>8)<<8;
+ temp3 = temp3-j;
+ temp1 = left&0x3F;
+ if (temp3 > 192) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, yuv420_v_dest+linear_offset, nv12t_uv_src+tiled_offset+temp1, 64-temp1);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
+ yuv420_v_dest+linear_offset+(32-temp1/2),
+ nv12t_uv_src+tiled_offset+2048, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
+ yuv420_v_dest+linear_offset+(64-temp1/2),
+ nv12t_uv_src+tiled_offset1, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(96-temp1/2),
+ yuv420_v_dest+linear_offset+(96-temp1/2),
+ nv12t_uv_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+128-temp1/2;
+ } else if (temp3 > 128) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset+2048+temp1, 64-temp1);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
+ yuv420_v_dest+linear_offset+(32-temp1/2),
+ nv12t_uv_src+tiled_offset1, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
+ yuv420_v_dest+linear_offset+(64-temp1/2),
+ nv12t_uv_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+96-temp1/2;
+ } else if (temp3 > 64) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset1+temp1, 64-temp1);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
+ yuv420_v_dest+linear_offset+(32-temp1/2),
+ nv12t_uv_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+64-temp1/2;
+ } else if (temp3 > 0) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset1+2048+temp1, 64-temp1);
+ linear_offset = linear_offset+32-temp1/2;
+ }
+
+ tiled_offset = tiled_offset+temp4*2048;
+ j = (left>>8)<<8;
+ j = j + 256;
+ temp2 = yuv420_width-right-256;
+ for (; j<=temp2; j=j+256) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
+ yuv420_v_dest+linear_offset+32,
+ nv12t_uv_src+tiled_offset+2048, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
+ yuv420_v_dest+linear_offset+64,
+ nv12t_uv_src+tiled_offset1, 64);
+ tiled_offset = tiled_offset+temp4*2048;
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
+ yuv420_v_dest+linear_offset+96,
+ nv12t_uv_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+128;
+ }
+
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ temp2 = yuv420_width-right-j;
+ if (temp2 > 192) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
+ yuv420_v_dest+linear_offset+32,
+ nv12t_uv_src+tiled_offset+2048, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
+ yuv420_v_dest+linear_offset+64,
+ nv12t_uv_src+tiled_offset1, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
+ yuv420_v_dest+linear_offset+96,
+ nv12t_uv_src+tiled_offset1+2048, temp2-192);
+ } else if (temp2 > 128) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
+ yuv420_v_dest+linear_offset+32,
+ nv12t_uv_src+tiled_offset+2048, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
+ yuv420_v_dest+linear_offset+64,
+ nv12t_uv_src+tiled_offset1, temp2-128);
+ } else if (temp2 > 64) {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
+ yuv420_v_dest+linear_offset+32,
+ nv12t_uv_src+tiled_offset+2048, temp2-64);
+ } else {
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, temp2);
+ }
+ }
+ } else if (temp1 >= 64) {
+ for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
+ j = left;
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
+ temp2 = ((j+64)>>6)<<6;
+ temp2 = temp2-j;
+ temp3 = yuv420_width-right;
+ temp4 = temp3-left;
+ linear_offset = temp4*(i-top)/2;
+ temp4 = j&0x3;
+ tiled_offset = tiled_offset+temp4;
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, temp2);
+ linear_offset = linear_offset+temp2/2;
+ j = j+temp2;
+ if ((j+64) <= temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ linear_offset = linear_offset+32;
+ j = j+64;
+ }
+ if ((j+64) <= temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 64);
+ linear_offset = linear_offset+32;
+ j = j+64;
+ }
+ if (j < temp3) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
+ temp1 = temp3-j;
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, temp1);
+ }
+ }
+ } else {
+ for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
+ temp3 = yuv420_width-right;
+ temp4 = temp3-left;
+ linear_offset = temp4*(i-top)/2;
+ for (j=left; j<(yuv420_width-right); j=j+2) {
+ tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
+ temp3 = j&0x3;
+ tiled_offset = tiled_offset+temp3;
+ csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
+ yuv420_v_dest+linear_offset,
+ nv12t_uv_src+tiled_offset, 2);
+ linear_offset = linear_offset+1;
+ }
+ }
+ }
+}
+
+/*
+ * Converts linear data to tiled
+ * Crops left, top, right, buttom
+ * 1. Y of YUV420P to Y of NV12T
+ * 2. Y of YUV420S to Y of NV12T
+ * 3. UV of YUV420S to UV of NV12T
+ *
+ * @param nv12t_dest
+ * Y or UV plane address of NV12T[out]
+ *
+ * @param yuv420_src
+ * Y or UV plane address of YUV420P(S)[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+static void csc_linear_to_tiled_crop(
+ unsigned char *nv12t_dest,
+ unsigned char *yuv420_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom)
+{
+ unsigned int i, j;
+ unsigned int tiled_x_index = 0, tiled_y_index = 0;
+ unsigned int aligned_x_size = 0, aligned_y_size = 0;
+ unsigned int tiled_offset = 0;
+ unsigned int temp1 = 0, temp2 = 0;
+
+ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
+ aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
+
+ for (i=0; i<aligned_y_size; i=i+32) {
+ for (j=0; j<aligned_x_size; j=j+64) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+
+ memcpy(nv12t_dest+tiled_offset, yuv420_src+left+j+yuv420_width*(i+top), 64);
+ memcpy(nv12t_dest+tiled_offset+64*1, yuv420_src+left+j+yuv420_width*(i+top+1), 64);
+ memcpy(nv12t_dest+tiled_offset+64*2, yuv420_src+left+j+yuv420_width*(i+top+2), 64);
+ memcpy(nv12t_dest+tiled_offset+64*3, yuv420_src+left+j+yuv420_width*(i+top+3), 64);
+ memcpy(nv12t_dest+tiled_offset+64*4, yuv420_src+left+j+yuv420_width*(i+top+4), 64);
+ memcpy(nv12t_dest+tiled_offset+64*5, yuv420_src+left+j+yuv420_width*(i+top+5), 64);
+ memcpy(nv12t_dest+tiled_offset+64*6, yuv420_src+left+j+yuv420_width*(i+top+6), 64);
+ memcpy(nv12t_dest+tiled_offset+64*7, yuv420_src+left+j+yuv420_width*(i+top+7), 64);
+ memcpy(nv12t_dest+tiled_offset+64*8, yuv420_src+left+j+yuv420_width*(i+top+8), 64);
+ memcpy(nv12t_dest+tiled_offset+64*9, yuv420_src+left+j+yuv420_width*(i+top+9), 64);
+ memcpy(nv12t_dest+tiled_offset+64*10, yuv420_src+left+j+yuv420_width*(i+top+10), 64);
+ memcpy(nv12t_dest+tiled_offset+64*11, yuv420_src+left+j+yuv420_width*(i+top+11), 64);
+ memcpy(nv12t_dest+tiled_offset+64*12, yuv420_src+left+j+yuv420_width*(i+top+12), 64);
+ memcpy(nv12t_dest+tiled_offset+64*13, yuv420_src+left+j+yuv420_width*(i+top+13), 64);
+ memcpy(nv12t_dest+tiled_offset+64*14, yuv420_src+left+j+yuv420_width*(i+top+14), 64);
+ memcpy(nv12t_dest+tiled_offset+64*15, yuv420_src+left+j+yuv420_width*(i+top+15), 64);
+ memcpy(nv12t_dest+tiled_offset+64*16, yuv420_src+left+j+yuv420_width*(i+top+16), 64);
+ memcpy(nv12t_dest+tiled_offset+64*17, yuv420_src+left+j+yuv420_width*(i+top+17), 64);
+ memcpy(nv12t_dest+tiled_offset+64*18, yuv420_src+left+j+yuv420_width*(i+top+18), 64);
+ memcpy(nv12t_dest+tiled_offset+64*19, yuv420_src+left+j+yuv420_width*(i+top+19), 64);
+ memcpy(nv12t_dest+tiled_offset+64*20, yuv420_src+left+j+yuv420_width*(i+top+20), 64);
+ memcpy(nv12t_dest+tiled_offset+64*21, yuv420_src+left+j+yuv420_width*(i+top+21), 64);
+ memcpy(nv12t_dest+tiled_offset+64*22, yuv420_src+left+j+yuv420_width*(i+top+22), 64);
+ memcpy(nv12t_dest+tiled_offset+64*23, yuv420_src+left+j+yuv420_width*(i+top+23), 64);
+ memcpy(nv12t_dest+tiled_offset+64*24, yuv420_src+left+j+yuv420_width*(i+top+24), 64);
+ memcpy(nv12t_dest+tiled_offset+64*25, yuv420_src+left+j+yuv420_width*(i+top+25), 64);
+ memcpy(nv12t_dest+tiled_offset+64*26, yuv420_src+left+j+yuv420_width*(i+top+26), 64);
+ memcpy(nv12t_dest+tiled_offset+64*27, yuv420_src+left+j+yuv420_width*(i+top+27), 64);
+ memcpy(nv12t_dest+tiled_offset+64*28, yuv420_src+left+j+yuv420_width*(i+top+28), 64);
+ memcpy(nv12t_dest+tiled_offset+64*29, yuv420_src+left+j+yuv420_width*(i+top+29), 64);
+ memcpy(nv12t_dest+tiled_offset+64*30, yuv420_src+left+j+yuv420_width*(i+top+30), 64);
+ memcpy(nv12t_dest+tiled_offset+64*31, yuv420_src+left+j+yuv420_width*(i+top+31), 64);
+ }
+ }
+
+ for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+2) {
+ for (j=0; j<aligned_x_size; j=j+64) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+
+ temp1 = i&0x1F;
+ memcpy(nv12t_dest+tiled_offset+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 64);
+ memcpy(nv12t_dest+tiled_offset+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 64);
+ }
+ }
+
+ for (i=0; i<(yuv420_height-top-buttom); i=i+2) {
+ for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+
+ temp1 = i&0x1F;
+ temp2 = j&0x3F;
+ memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 2);
+ memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 2);
+ }
+ }
+
+}
+
+/*
+ * Converts and Interleaves linear to tiled
+ * Crops left, top, right, buttom
+ * 1. UV of YUV420P to UV of NV12T
+ *
+ * @param nv12t_uv_dest
+ * UV plane address of NV12T[out]
+ *
+ * @param yuv420p_u_src
+ * U plane address of YUV420P[in]
+ *
+ * @param yuv420p_v_src
+ * V plane address of YUV420P[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_uv_height
+ * Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+static void csc_linear_to_tiled_interleave_crop(
+ unsigned char *nv12t_uv_dest,
+ unsigned char *yuv420_u_src,
+ unsigned char *yuv420_v_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom)
+{
+ unsigned int i, j;
+ unsigned int tiled_x_index = 0, tiled_y_index = 0;
+ unsigned int aligned_x_size = 0, aligned_y_size = 0;
+ unsigned int tiled_offset = 0;
+ unsigned int temp1 = 0, temp2 = 0;
+
+ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
+ aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
+
+ for (i=0; i<aligned_y_size; i=i+32) {
+ for (j=0; j<aligned_x_size; j=j+64) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*1,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+1),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+1), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*2,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+2),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+2), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*3,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+3),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+3), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*4,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+4),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+4), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*5,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+5),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+5), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*6,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+6),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+6), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*7,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+7),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+7), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*8,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+8),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+8), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*9,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+9),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+9), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*10,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+10),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+10), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*11,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+11),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+11), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*12,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+12),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+12), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*13,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+13),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+13), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*14,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+14),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+14), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*15,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+15),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+15), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*16,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+16),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+16), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*17,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+17),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+17), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*18,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+18),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+18), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*19,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+19),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+19), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*20,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+20),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+20), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*21,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+21),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+21), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*22,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+22),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+22), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*23,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+23),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+23), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*24,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+24),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+24), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*25,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+25),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+25), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*26,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+26),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+26), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*27,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+27),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+27), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*28,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+28),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+28), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*29,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+29),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+29), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*30,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+30),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+30), 32);
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*31,
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+31),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+31), 32);
+
+ }
+ }
+
+ for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+1) {
+ for (j=0; j<aligned_x_size; j=j+64) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+ temp1 = i&0x1F;
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1),
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
+ }
+ }
+
+ for (i=0; i<(yuv420_height-top-buttom); i=i+1) {
+ for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
+ tiled_offset = 0;
+ tiled_x_index = j>>6;
+ tiled_y_index = i>>5;
+ if (tiled_y_index & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = tiled_y_index-1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset+2;
+ temp1 = (tiled_x_index>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ } else {
+ temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
+ if ((i+32)<temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = tiled_x_index+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = tiled_x_index+temp1;
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
+ tiled_offset = tiled_y_index*(temp1>>6);
+ tiled_offset = tiled_offset+tiled_x_index;
+ tiled_offset = tiled_offset<<11;
+ }
+ }
+ temp1 = i&0x1F;
+ temp2 = j&0x3F;
+ csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1),
+ yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
+ yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 1);
+ }
+ }
+
+}
+
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ * Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+void csc_tiled_to_linear_crop_neon(
+ unsigned char *yuv420_dest,
+ unsigned char *nv12t_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom);
+
+/*
+ * Converts and Deinterleaves tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. UV of NV12T to UV of YUV420P
+ *
+ * @param yuv420_u_dest
+ * U plane address of YUV420P[out]
+ *
+ * @param yuv420_v_dest
+ * V plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_uv_height
+ * Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+void csc_tiled_to_linear_deinterleave_crop_neon(
+ unsigned char *yuv420_u_dest,
+ unsigned char *yuv420_v_dest,
+ unsigned char *nv12t_uv_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_uv_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom);
+
+/*
+ * Converts linear data to tiled
+ * Crops left, top, right, buttom
+ * 1. Y of YUV420P to Y of NV12T
+ * 2. Y of YUV420S to Y of NV12T
+ * 3. UV of YUV420S to UV of NV12T
+ *
+ * @param nv12t_dest
+ * Y or UV plane address of NV12T[out]
+ *
+ * @param yuv420_src
+ * Y or UV plane address of YUV420P(S)[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+void csc_linear_to_tiled_crop_neon(
+ unsigned char *nv12t_dest,
+ unsigned char *yuv420_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom);
+
+/*
+ * Converts and Interleaves linear to tiled
+ * Crops left, top, right, buttom
+ * 1. UV of YUV420P to UV of NV12T
+ *
+ * @param nv12t_uv_dest
+ * UV plane address of NV12T[out]
+ *
+ * @param yuv420p_u_src
+ * U plane address of YUV420P[in]
+ *
+ * @param yuv420p_v_src
+ * V plane address of YUV420P[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_uv_height
+ * Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+void csc_linear_to_tiled_interleave_crop_neon(
+ unsigned char *nv12t_uv_dest,
+ unsigned char *yuv420_u_src,
+ unsigned char *yuv420_v_src,
+ unsigned int yuv420_width,
+ unsigned int yuv420_height,
+ unsigned int left,
+ unsigned int top,
+ unsigned int right,
+ unsigned int buttom);
+
+/*
+ * Converts tiled data to linear.
+ * 1. y of nv12t to y of yuv420p
+ * 2. y of nv12t to y of yuv420s
+ *
+ * @param dst
+ * y address of yuv420[out]
+ *
+ * @param src
+ * y address of nv12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_tiled_to_linear_y(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts tiled data to linear
+ * 1. uv of nv12t to y of yuv420s
+ *
+ * @param dst
+ * uv address of yuv420s[out]
+ *
+ * @param src
+ * uv address of nv12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420s[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420s[in]
+ *
+ */
+void csc_tiled_to_linear_uv(
+ unsigned char *uv_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_crop(uv_dst, uv_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts tiled data to linear
+ * 1. uv of nt12t to uv of yuv420p
+ *
+ * @param u_dst
+ * u address of yuv420p[out]
+ *
+ * @param v_dst
+ * v address of yuv420p[out]
+ *
+ * @param uv_src
+ * uv address of nt12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420p[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420p[in]
+ */
+void csc_tiled_to_linear_uv_deinterleave(
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_deinterleave_crop(u_dst, v_dst, uv_src, width, height,
+ 0, 0, 0, 0);
+}
+
+/*
+ * Converts linear data to tiled
+ * 1. y of yuv420 to y of nv12t
+ *
+ * @param dst
+ * y address of nv12t[out]
+ *
+ * @param src
+ * y address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_linear_to_tiled_y(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_linear_to_tiled_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts and interleaves linear data to tiled
+ * 1. uv of nv12t to uv of yuv420
+ *
+ * @param dst
+ * uv address of nv12t[out]
+ *
+ * @param src
+ * u address of yuv420[in]
+ *
+ * @param src
+ * v address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ *
+ */
+void csc_linear_to_tiled_uv(
+ unsigned char *uv_dst,
+ unsigned char *u_src,
+ unsigned char *v_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_linear_to_tiled_interleave_crop(uv_dst, u_src, v_src, width, height,
+ 0, 0, 0, 0);
+}
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ *
+ * @param dst
+ * Y address of YUV420[out]
+ *
+ * @param src
+ * Y address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: real height of YUV420[in]
+ *
+ */
+void csc_tiled_to_linear_y_neon(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * 1. UV of NV12T to Y of YUV420S
+ *
+ * @param u_dst
+ * UV plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * (real height)/2 of YUV420[in]
+ */
+void csc_tiled_to_linear_uv_neon(
+ unsigned char *uv_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_crop_neon(uv_dst, uv_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * Deinterleave src to u_dst, v_dst
+ * 1. UV of NV12T to Y of YUV420P
+ *
+ * @param u_dst
+ * U plane address of YUV420P[out]
+ *
+ * @param v_dst
+ * V plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * (real height)/2 of YUV420[in]
+ */
+void csc_tiled_to_linear_uv_deinterleave_neon(
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_tiled_to_linear_deinterleave_crop_neon(u_dst, v_dst, uv_src, width, height,
+ 0, 0, 0, 0);
+}
+
+/*
+ * Converts linear data to tiled
+ * 1. y of yuv420 to y of nv12t
+ *
+ * @param dst
+ * y address of nv12t[out]
+ *
+ * @param src
+ * y address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_linear_to_tiled_y_neon(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_linear_to_tiled_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts and interleaves linear data to tiled
+ * 1. uv of nv12t to uv of yuv420
+ *
+ * @param dst
+ * uv address of nv12t[out]
+ *
+ * @param src
+ * u address of yuv420[in]
+ *
+ * @param src
+ * v address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ *
+ */
+void csc_linear_to_tiled_uv_neon(
+ unsigned char *uv_dst,
+ unsigned char *u_src,
+ unsigned char *v_src,
+ unsigned int width,
+ unsigned int height)
+{
+ csc_linear_to_tiled_interleave_crop_neon(uv_dst, u_src, v_src,
+ width, height, 0, 0, 0, 0);
+}
+
+/*
+ * Converts RGB565 to YUV420P
+ *
+ * @param y_dst
+ * Y plane address of YUV420P[out]
+ *
+ * @param u_dst
+ * U plane address of YUV420P[out]
+ *
+ * @param v_dst
+ * V plane address of YUV420P[out]
+ *
+ * @param rgb_src
+ * Address of RGB565[in]
+ *
+ * @param width
+ * Width of RGB565[in]
+ *
+ * @param height
+ * Height of RGB565[in]
+ */
+void csc_RGB565_to_YUV420P(
+ unsigned char *y_dst,
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int i, j;
+ unsigned int tmp;
+
+ unsigned int R, G, B;
+ unsigned int Y, U, V;
+
+ unsigned int offset1 = width * height;
+ unsigned int offset2 = width/2 * height/2;
+
+ unsigned short int *pSrc = (unsigned short int *)rgb_src;
+
+ unsigned char *pDstY = (unsigned char *)y_dst;
+ unsigned char *pDstU = (unsigned char *)u_dst;
+ unsigned char *pDstV = (unsigned char *)v_dst;
+
+ unsigned int yIndex = 0;
+ unsigned int uIndex = 0;
+ unsigned int vIndex = 0;
+
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ tmp = pSrc[j * width + i];
+
+ R = (tmp & 0x0000F800) >> 8;
+ G = (tmp & 0x000007E0) >> 3;
+ B = (tmp & 0x0000001F);
+ B = B << 3;
+
+ Y = ((66 * R) + (129 * G) + (25 * B) + 128);
+ Y = Y >> 8;
+ Y += 16;
+
+ pDstY[yIndex++] = (unsigned char)Y;
+
+ if ((j % 2) == 0 && (i % 2) == 0) {
+ U = ((-38 * R) - (74 * G) + (112 * B) + 128);
+ U = U >> 8;
+ U += 128;
+ V = ((112 * R) - (94 * G) - (18 * B) + 128);
+ V = V >> 8;
+ V += 128;
+
+ pDstU[uIndex++] = (unsigned char)U;
+ pDstV[vIndex++] = (unsigned char)V;
+ }
+ }
+ }
+}
+
+/*
+ * Converts RGB565 to YUV420SP
+ *
+ * @param y_dst
+ * Y plane address of YUV420SP[out]
+ *
+ * @param uv_dst
+ * UV plane address of YUV420SP[out]
+ *
+ * @param rgb_src
+ * Address of RGB565[in]
+ *
+ * @param width
+ * Width of RGB565[in]
+ *
+ * @param height
+ * Height of RGB565[in]
+ */
+void csc_RGB565_to_YUV420SP(
+ unsigned char *y_dst,
+ unsigned char *uv_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int i, j;
+ unsigned int tmp;
+
+ unsigned int R, G, B;
+ unsigned int Y, U, V;
+
+ unsigned int offset = width * height;
+
+ unsigned short int *pSrc = (unsigned short int *)rgb_src;
+
+ unsigned char *pDstY = (unsigned char *)y_dst;
+ unsigned char *pDstUV = (unsigned char *)uv_dst;
+
+ unsigned int yIndex = 0;
+ unsigned int uvIndex = 0;
+
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ tmp = pSrc[j * width + i];
+
+ R = (tmp & 0x0000F800) >> 11;
+ R = R * 8;
+ G = (tmp & 0x000007E0) >> 5;
+ G = G * 4;
+ B = (tmp & 0x0000001F);
+ B = B * 8;
+
+ Y = ((66 * R) + (129 * G) + (25 * B) + 128);
+ Y = Y >> 8;
+ Y += 16;
+
+ pDstY[yIndex++] = (unsigned char)Y;
+
+ if ((j % 2) == 0 && (i % 2) == 0) {
+ U = ((-38 * R) - (74 * G) + (112 * B) + 128);
+ U = U >> 8;
+ U += 128;
+ V = ((112 * R) - (94 * G) - (18 * B) + 128);
+ V = V >> 8;
+ V += 128;
+
+ pDstUV[uvIndex++] = (unsigned char)U;
+ pDstUV[uvIndex++] = (unsigned char)V;
+ }
+ }
+ }
+}
+
+void csc_ARGB8888_to_YUV420SP(
+ unsigned char *y_dst,
+ unsigned char *uv_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int i, j;
+ unsigned int tmp;
+
+ unsigned int R, G, B;
+ unsigned int Y, U, V;
+
+ unsigned int offset = width * height;
+
+ unsigned int *pSrc = (unsigned int *)rgb_src;
+
+ unsigned char *pDstY = (unsigned char *)y_dst;
+ unsigned char *pDstUV = (unsigned char *)uv_dst;
+
+ unsigned int yIndex = 0;
+ unsigned int uvIndex = 0;
+
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ tmp = pSrc[j * width + i];
+
+ R = (tmp & 0x00FF0000) >> 16;
+ G = (tmp & 0x0000FF00) >> 8;
+ B = (tmp & 0x000000FF);
+
+ Y = ((66 * R) + (129 * G) + (25 * B) + 128);
+ Y = Y >> 8;
+ Y += 16;
+
+ pDstY[yIndex++] = (unsigned char)Y;
+
+ if ((j % 2) == 0 && (i % 2) == 0) {
+ U = ((-38 * R) - (74 * G) + (112 * B) + 128);
+ U = U >> 8;
+ U += 128;
+ V = ((112 * R) - (94 * G) - (18 * B) + 128);
+ V = V >> 8;
+ V += 128;
+
+ pDstUV[uvIndex++] = (unsigned char)U;
+ pDstUV[uvIndex++] = (unsigned char)V;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h
new file mode 100644
index 0000000..92c0a6d
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/color_space_convertor.h
@@ -0,0 +1,414 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file color_space_convertor.h
+ * @brief SEC_OMX specific define. It support MFC 5.x tiled.
+ * NV12T(tiled) layout:
+ * Each element is not pixel. It is 64x32 pixel block.
+ * uv pixel block is interleaved as u v u v u v ...
+ * y1 y2 y7 y8 y9 y10 y15 y16
+ * y3 y4 y5 y6 y11 y12 y13 y14
+ * y17 y18 y23 y24 y25 y26 y31 y32
+ * y19 y20 y21 y22 y27 y28 y29 y30
+ * uv1 uv2 uv7 uv8 uv9 uv10 uv15 uv16
+ * uv3 uv4 uv5 uv6 uv11 uv12 uv13 uv14
+ * YUV420Planar(linear) layout:
+ * Each element is not pixel. It is 64x32 pixel block.
+ * y1 y2 y3 y4 y5 y6 y7 y8
+ * y9 y10 y11 y12 y13 y14 y15 y16
+ * y17 y18 y19 y20 y21 y22 y23 y24
+ * y25 y26 y27 y28 y29 y30 y31 y32
+ * u1 u2 u3 u4 u5 u6 u7 u8
+ * v1 v2 v3 v4 v5 v6 v7 v8
+ * YUV420Semiplanar(linear) layout:
+ * Each element is not pixel. It is 64x32 pixel block.
+ * uv pixel block is interleaved as u v u v u v ...
+ * y1 y2 y3 y4 y5 y6 y7 y8
+ * y9 y10 y11 y12 y13 y14 y15 y16
+ * y17 y18 y19 y20 y21 y22 y23 y24
+ * y25 y26 y27 y28 y29 y30 y31 y32
+ * uv1 uv2 uv3 uv4 uv5 uv6 uv7 uv8
+ * uv9 uv10 uv11 uv12 uv13 uv14 uv15 uv16
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2011.07.01 : Create
+ * 2011.12.01 : Added csc functions
+ */
+
+#ifndef COLOR_SPACE_CONVERTOR_H_
+#define COLOR_SPACE_CONVERTOR_H_
+
+/*--------------------------------------------------------------------------------*/
+/* Format Conversion API */
+/*--------------------------------------------------------------------------------*/
+/*
+ * Interleaves src1, src2 to dest
+ *
+ * @param dest
+ * Address of interleaved data[out]
+ *
+ * @param src1
+ * Address of de-interleaved data[in]
+ *
+ * @param src2
+ * Address of de-interleaved data[in]
+ *
+ * @param src_size
+ * Size of de-interleaved data[in]
+ */
+/*
+void csc_interleave_memcpy(
+ unsigned char *dest,
+ unsigned char *src1,
+ unsigned char *src2,
+ unsigned int src_size);
+*/
+/* C Code */
+/*
+ * Converts tiled data to linear
+ * 1. y of nv12t to y of yuv420p
+ * 2. y of nv12t to y of yuv420s
+ *
+ * @param dst
+ * y address of yuv420[out]
+ *
+ * @param src
+ * y address of nv12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_tiled_to_linear_y(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts tiled data to linear
+ * 1. uv of nv12t to y of yuv420s
+ *
+ * @param dst
+ * uv address of yuv420s[out]
+ *
+ * @param src
+ * uv address of nv12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420s[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420s[in]
+ *
+ */
+void csc_tiled_to_linear_uv(
+ unsigned char *uv_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts tiled data to linear
+ * 1. uv of nt12t to uv of yuv420p
+ *
+ * @param u_dst
+ * u address of yuv420p[out]
+ *
+ * @param v_dst
+ * v address of yuv420p[out]
+ *
+ * @param uv_src
+ * uv address of nt12t[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420p[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420p[in]
+ */
+void csc_tiled_to_linear_uv_deinterleave(
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts linear data to tiled
+ * 1. y of yuv420 to y of nv12t
+ *
+ * @param dst
+ * y address of nv12t[out]
+ *
+ * @param src
+ * y address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_linear_to_tiled_y(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts and interleaves linear data to tiled
+ * 1. uv of nv12t to uv of yuv420
+ *
+ * @param dst
+ * uv address of nv12t[out]
+ *
+ * @param src
+ * u address of yuv420[in]
+ *
+ * @param src
+ * v address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ *
+ */
+void csc_linear_to_tiled_uv(
+ unsigned char *uv_dst,
+ unsigned char *u_src,
+ unsigned char *v_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ *
+ * @param dst
+ * Y address of YUV420[out]
+ *
+ * @param src
+ * Y address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: real height of YUV420[in]
+ *
+ */
+void csc_tiled_to_linear_y_neon(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * 1. UV of NV12T to Y of YUV420S
+ *
+ * @param u_dst
+ * UV plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * (real height)/2 of YUV420[in]
+ */
+void csc_tiled_to_linear_uv_neon(
+ unsigned char *uv_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts tiled data to linear for mfc 6.x
+ * Deinterleave src to u_dst, v_dst
+ * 1. UV of NV12T to Y of YUV420P
+ *
+ * @param u_dst
+ * U plane address of YUV420P[out]
+ *
+ * @param v_dst
+ * V plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * real width of YUV420[in]
+ *
+ * @param yuv420_height
+ * (real height)/2 of YUV420[in]
+ */
+void csc_tiled_to_linear_uv_deinterleave_neon(
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *uv_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts linear data to tiled
+ * 1. y of yuv420 to y of nv12t
+ *
+ * @param dst
+ * y address of nv12t[out]
+ *
+ * @param src
+ * y address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ * it should be even
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ * it should be even.
+ *
+ */
+void csc_linear_to_tiled_y_neon(
+ unsigned char *y_dst,
+ unsigned char *y_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts and interleaves linear data to tiled
+ * 1. uv of nv12t to uv of yuv420
+ *
+ * @param dst
+ * uv address of nv12t[out]
+ *
+ * @param src
+ * u address of yuv420[in]
+ *
+ * @param src
+ * v address of yuv420[in]
+ *
+ * @param yuv420_width
+ * real width of yuv420[in]
+ *
+ * @param yuv420_height
+ * real height of yuv420[in]
+ *
+ */
+void csc_linear_to_tiled_uv_neon(
+ unsigned char *uv_dst,
+ unsigned char *u_src,
+ unsigned char *v_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts RGB565 to YUV420P
+ *
+ * @param y_dst
+ * Y plane address of YUV420P[out]
+ *
+ * @param u_dst
+ * U plane address of YUV420P[out]
+ *
+ * @param v_dst
+ * V plane address of YUV420P[out]
+ *
+ * @param rgb_src
+ * Address of RGB565[in]
+ *
+ * @param width
+ * Width of RGB565[in]
+ *
+ * @param height
+ * Height of RGB565[in]
+ */
+void csc_RGB565_to_YUV420P(
+ unsigned char *y_dst,
+ unsigned char *u_dst,
+ unsigned char *v_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts RGB565 to YUV420S
+ *
+ * @param y_dst
+ * Y plane address of YUV420S[out]
+ *
+ * @param uv_dst
+ * UV plane address of YUV420S[out]
+ *
+ * @param rgb_src
+ * Address of RGB565[in]
+ *
+ * @param width
+ * Width of RGB565[in]
+ *
+ * @param height
+ * Height of RGB565[in]
+ */
+void csc_RGB565_to_YUV420SP(
+ unsigned char *y_dst,
+ unsigned char *uv_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height);
+
+/*
+ * Converts ARGB888 to YUV420SP
+ *
+ * @param y_dst
+ * Y plane address of YUV420SP[out]
+ *
+ * @param uv_dst
+ * UV plane address of YUV420SP[out]
+ *
+ * @param rgb_src
+ * Address of ARGB888[in]
+ *
+ * @param width
+ * Width of ARGB888[in]
+ *
+ * @param height
+ * Height of ARGB888[in]
+ */
+void csc_ARGB8888_to_YUV420SP(
+ unsigned char *y_dst,
+ unsigned char *uv_dst,
+ unsigned char *rgb_src,
+ unsigned int width,
+ unsigned int height);
+
+#endif /*COLOR_SPACE_CONVERTOR_H_*/
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp b/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp
new file mode 100644
index 0000000..7c458b2
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_fimc.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_fimc.cpp
+ *
+ * @brief csc_fimc use fimc1 to color space convertion
+ *
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ *
+ * @version 1.0
+ *
+ * @history
+ * 2011.11.01 : Create
+ */
+
+#include <utils/Log.h>
+#include <dlfcn.h>
+
+#include "SEC_OMX_Def.h"
+#include "csc_fimc.h"
+#include "HardwareConverter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * create and open fimc handle
+ *
+ * @return
+ * fimc handle
+ */
+void *csc_fimc_open()
+{
+ HardwareConverter *hw_converter = NULL;
+
+ hw_converter = new HardwareConverter;
+ if (hw_converter->bHWconvert_flag == 0) {
+ delete hw_converter;
+ hw_converter = NULL;
+ LOGE("%s LINE = %d HardwareConverter failed", __func__, __LINE__);
+ }
+
+ return (void *)hw_converter;
+}
+
+/*
+ * close and destroy fimc handle
+ *
+ * @param handle
+ * fimc handle[in]
+ *
+ * @return
+ * pass or fail
+ */
+CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle)
+{
+ HardwareConverter *hw_converter = (HardwareConverter *)handle;
+
+ if (hw_converter != NULL)
+ delete hw_converter;
+
+ return CSC_FIMC_RET_OK;
+}
+
+/*
+ * convert color space nv12t to omxformat
+ *
+ * @param handle
+ * fimc handle[in]
+ *
+ * @param dst_addr
+ * y,u,v address of dst_addr[out]
+ *
+ * @param src_addr
+ * y,uv address of src_addr.Format is nv12t[in]
+ *
+ * @param width
+ * width of dst image[in]
+ *
+ * @param height
+ * height of dst image[in]
+ *
+ * @param omxformat
+ * omxformat of dst image[in]
+ *
+ * @return
+ * pass or fail
+ */
+CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t(
+ void *handle,
+ void **dst_addr,
+ void **src_addr,
+ unsigned int width,
+ unsigned int height,
+ OMX_COLOR_FORMATTYPE omxformat)
+{
+ CSC_FIMC_ERROR_CODE ret = CSC_FIMC_RET_OK;
+ HardwareConverter *hw_converter = (HardwareConverter *)handle;
+
+ if (hw_converter == NULL) {
+ ret = CSC_FIMC_RET_FAIL;
+ goto EXIT;
+ }
+
+ hw_converter->convert(
+ (void *)src_addr, (void *)dst_addr,
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12TPhysicalAddress,
+ width, height, omxformat);
+
+ ret = CSC_FIMC_RET_OK;
+
+EXIT:
+
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_fimc.h b/exynos/multimedia/utils/csc/exynos4/csc_fimc.h
new file mode 100644
index 0000000..3ae24ac
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_fimc.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_fimc.h
+ *
+ * @brief csc_fimc use fimc1 to color space convertion
+ *
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ *
+ * @version 1.0
+ *
+ * @history
+ * 2011.11.01 : Create
+ */
+
+#ifndef CSC_FIMC_H
+
+#define CSC_FIMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <OMX_Video.h>
+
+/*--------------------------------------------------------------------------------*/
+/* Structure and Type */
+/*--------------------------------------------------------------------------------*/
+typedef enum {
+ CSC_FIMC_RET_OK = 0,
+ CSC_FIMC_RET_FAIL = -1
+} CSC_FIMC_ERROR_CODE;
+
+/*--------------------------------------------------------------------------------*/
+/* CSC FIMC APIs */
+/*--------------------------------------------------------------------------------*/
+/*
+ * create and open fimc handle
+ *
+ * @return
+ * fimc handle
+ */
+void *csc_fimc_open();
+
+/*
+ * close and destroy fimc handle
+ *
+ * @param handle
+ * fimc handle[in]
+ *
+ * @return
+ * error code
+ */
+CSC_FIMC_ERROR_CODE csc_fimc_close(void *handle);
+
+/*
+ * convert color space nv12t to omxformat
+ *
+ * @param handle
+ * fimc handle[in]
+ *
+ * @param dst_addr
+ * y,u,v address of dst_addr[out]
+ *
+ * @param src_addr
+ * y,uv address of src_addr.Format is nv12t[in]
+ *
+ * @param width
+ * width of dst image[in]
+ *
+ * @param height
+ * height of dst image[in]
+ *
+ * @param omxformat
+ * omxformat of dst image[in]
+ *
+ * @return
+ * error code
+ */
+CSC_FIMC_ERROR_CODE csc_fimc_convert_nv12t(
+ void *handle,
+ void **dst_addr,
+ void **src_addr,
+ unsigned int width,
+ unsigned int height,
+ OMX_COLOR_FORMATTYPE omxformat);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s
new file mode 100644
index 0000000..3d2b41f
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_interleave_memcpy_neon.s
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_linear_to_tiled_crop_neon.s
+ * @brief SEC_OMX specific define
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2012.01.04 : Create
+ */
+
+/*
+ * Interleave src1, src2 to dst
+ *
+ * @param dest
+ * dst address[out]
+ *
+ * @param src1
+ * src1 address[in]
+ *
+ * @param src2
+ * src2 address[in]
+ *
+ * @param src_size
+ * src_size or src1
+ */
+
+ .arch armv7-a
+ .text
+ .global csc_interleave_memcpy_neon
+ .type csc_interleave_memcpy_neon, %function
+csc_interleave_memcpy_neon:
+ .fnstart
+
+ @r0 dest
+ @r1 src1
+ @r2 src2
+ @r3 src_size
+ @r4
+ @r5
+ @r6
+ @r7
+ @r8 temp1
+ @r9 temp2
+ @r10 dest_addr
+ @r11 src1_addr
+ @r12 src2_addr
+ @r14 i
+
+ stmfd sp!, {r8-r12,r14} @ backup registers
+
+ mov r10, r0
+ mov r11, r1
+ mov r12, r2
+ mov r14, r3
+
+ cmp r14, #128
+ blt LESS_THAN_128
+
+LOOP_128:
+ vld1.8 {q0}, [r11]!
+ vld1.8 {q2}, [r11]!
+ vld1.8 {q4}, [r11]!
+ vld1.8 {q6}, [r11]!
+ vld1.8 {q8}, [r11]!
+ vld1.8 {q10}, [r11]!
+ vld1.8 {q12}, [r11]!
+ vld1.8 {q14}, [r11]!
+ vld1.8 {q1}, [r12]!
+ vld1.8 {q3}, [r12]!
+ vld1.8 {q5}, [r12]!
+ vld1.8 {q7}, [r12]!
+ vld1.8 {q9}, [r12]!
+ vld1.8 {q11}, [r12]!
+ vld1.8 {q13}, [r12]!
+ vld1.8 {q15}, [r12]!
+
+ vst2.8 {q0, q1}, [r10]!
+ vst2.8 {q2, q3}, [r10]!
+ vst2.8 {q4, q5}, [r10]!
+ vst2.8 {q6, q7}, [r10]!
+ vst2.8 {q8, q9}, [r10]!
+ vst2.8 {q10, q11}, [r10]!
+ vst2.8 {q12, q13}, [r10]!
+ vst2.8 {q14, q15}, [r10]!
+
+ sub r14, #128
+ cmp r14, #128
+ bgt LOOP_128
+
+LESS_THAN_128:
+ cmp r14, #0
+ beq RESTORE_REG
+
+LOOP_1:
+ ldrb r8, [r11], #1
+ ldrb r9, [r12], #1
+ strb r8, [r10], #1
+ strb r9, [r10], #1
+ subs r14, #1
+ bne LOOP_1
+
+RESTORE_REG:
+ ldmfd sp!, {r8-r12,r15} @ restore registers
+ .fnend
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s
new file mode 100644
index 0000000..745d495
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_crop_neon.s
@@ -0,0 +1,492 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_linear_to_tiled_crop_neon.s
+ * @brief SEC_OMX specific define
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2011.8.04 : Create
+ */
+
+/*
+ * Converts linear data to tiled
+ * Crops left, top, right, buttom
+ * 1. Y of YUV420P to Y of NV12T
+ * 2. Y of YUV420S to Y of NV12T
+ * 3. UV of YUV420S to UV of NV12T
+ *
+ * @param nv12t_dest
+ * Y or UV plane address of NV12T[out]
+ *
+ * @param yuv420_src
+ * Y or UV plane address of YUV420P(S)[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left. It should be even.
+ *
+ * @param top
+ * Crop size of top. It should be even.
+ *
+ * @param right
+ * Crop size of right. It should be even.
+ *
+ * @param buttom
+ * Crop size of buttom. It should be even.
+ */
+
+ .arch armv7-a
+ .text
+ .global csc_linear_to_tiled_crop_neon
+ .type csc_linear_to_tiled_crop_neon, %function
+csc_linear_to_tiled_crop_neon:
+ .fnstart
+
+ @r0 tiled_dest
+ @r1 linear_src
+ @r2 yuv420_width
+ @r3 yuv420_height
+ @r4 j
+ @r5 i
+ @r6 nn(tiled_addr)
+ @r7 mm(linear_addr)
+ @r8 aligned_x_size
+ @r9 aligned_y_size
+ @r10 temp1
+ @r11 temp2
+ @r12 temp3
+ @r14 temp4
+
+ stmfd sp!, {r4-r12,r14} @ backup registers
+
+ ldr r11, [sp, #44] @ top
+ ldr r14, [sp, #52] @ buttom
+ ldr r10, [sp, #40] @ left
+ ldr r12, [sp, #48] @ right
+
+ sub r9, r3, r11 @ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5
+ sub r9, r9, r14
+ bic r9, r9, #0x1F
+
+ sub r8, r2, r10 @ aligned_x_size = ((yuv420_width-left-right)>>6)<<6
+ sub r8, r8, r12
+ bic r8, r8, #0x3F
+
+ mov r5, #0 @ i = 0
+LOOP_ALIGNED_Y_SIZE:
+
+ mov r4, #0 @ j = 0
+LOOP_ALIGNED_X_SIZE:
+
+ bl GET_TILED_OFFSET
+
+ ldr r10, [sp, #44] @ r10 = top
+ ldr r14, [sp, #40] @ r14 = left
+ add r10, r5, r10 @ temp1 = linear_x_size*(i+top)
+ mul r10, r2, r10
+ add r7, r1, r4 @ linear_addr = linear_src+j
+ add r7, r7, r10 @ linear_addr = linear_addr+temp1
+ add r7, r7, r14 @ linear_addr = linear_addr+left
+ sub r10, r2, #32
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*1, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*2, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*3, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ add r6, r0, r6 @ tiled_addr = tiled_dest+tiled_addr
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*1}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*2}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*3}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*4, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*5, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*6, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*7, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*4}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*5}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*6}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*7}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*8, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*9, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*10, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*11, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*8}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*9}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*10}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*11}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*12, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*13, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*14, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*15, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*12}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*13}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*14}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*15}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*16, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*17, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*18, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*19, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*16}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*17}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*18}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*19}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*20, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*21, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*22, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*23, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*20}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*21}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*22}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*23}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*24, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*25, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*26, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*27, 64}
+ pld [r7, r2]
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*24}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*25}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*26}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*27}
+ vst1.8 {q14, q15}, [r6]!
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src+linear_x_size*28, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*29, 64}
+ pld [r7, r2]
+ vld1.8 {q6, q7}, [r7], r10
+ pld [r7, r2]
+ vld1.8 {q8, q9}, [r7]! @ load {linear_src+linear_x_size*30, 64}
+ pld [r7, r2]
+ vld1.8 {q10, q11}, [r7], r10
+ vld1.8 {q12, q13}, [r7]! @ load {linear_src+linear_x_size*31, 64}
+ vld1.8 {q14, q15}, [r7], r10
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr+64*28}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*29}
+ vst1.8 {q6, q7}, [r6]!
+ vst1.8 {q8, q9}, [r6]! @ store {tiled_addr+64*30}
+ vst1.8 {q10, q11}, [r6]!
+ vst1.8 {q12, q13}, [r6]! @ store {tiled_addr+64*31}
+ vst1.8 {q14, q15}, [r6]!
+
+ add r4, r4, #64 @ j = j+64
+ cmp r4, r8 @ j<aligned_x_size
+ blt LOOP_ALIGNED_X_SIZE
+
+ add r5, r5, #32 @ i = i+32
+ cmp r5, r9 @ i<aligned_y_size
+ blt LOOP_ALIGNED_Y_SIZE
+
+ ldr r10, [sp, #44] @ r10 = top
+ ldr r11, [sp, #52] @ r11 = buttom
+ sub r10, r3, r10
+ sub r10, r10, r11
+ cmp r5, r10 @ i == (yuv420_height-top-buttom)
+ beq LOOP_LINEAR_Y_SIZE_2_START
+
+LOOP_LINEAR_Y_SIZE_1:
+
+ mov r4, #0 @ j = 0
+LOOP_ALIGNED_X_SIZE_1:
+
+ bl GET_TILED_OFFSET
+
+ ldr r10, [sp, #44] @ r10 = top
+ ldr r14, [sp, #40] @ r14 = left
+ add r10, r5, r10 @ temp1 = yuv420_width*(i+top)
+ mul r10, r2, r10
+ add r7, r1, r4 @ linear_addr = linear_src+j
+ add r7, r7, r10 @ linear_addr = linear_addr+temp1
+ add r7, r7, r14 @ linear_addr = linear_addr+left
+ sub r10, r2, #32 @ temp1 = yuv420_width-32
+
+ pld [r7, r2]
+ vld1.8 {q0, q1}, [r7]! @ load {linear_src, 64}
+ pld [r7, r2]
+ vld1.8 {q2, q3}, [r7], r10
+ vld1.8 {q4, q5}, [r7]! @ load {linear_src+linear_x_size*1, 64}
+ vld1.8 {q6, q7}, [r7]
+ add r6, r0, r6 @ tiled_addr = tiled_dest+tiled_addr
+ and r10, r5, #0x1F @ temp1 = i&0x1F
+ mov r10, r10, lsl #6 @ temp1 = 64*temp1
+ add r6, r6, r10 @ tiled_addr = tiled_addr+temp1
+ vst1.8 {q0, q1}, [r6]! @ store {tiled_addr}
+ vst1.8 {q2, q3}, [r6]!
+ vst1.8 {q4, q5}, [r6]! @ store {tiled_addr+64*1}
+ vst1.8 {q6, q7}, [r6]!
+
+ add r4, r4, #64 @ j = j+64
+ cmp r4, r8 @ j<aligned_x_size
+ blt LOOP_ALIGNED_X_SIZE_1
+
+ add r5, r5, #2 @ i = i+2
+ ldr r10, [sp, #44] @ r10 = top
+ ldr r14, [sp, #52] @ r14 = buttom
+ sub r10, r3, r10
+ sub r10, r10, r14
+ cmp r5, r10 @ i<yuv420_height-top-buttom
+ blt LOOP_LINEAR_Y_SIZE_1
+
+LOOP_LINEAR_Y_SIZE_2_START:
+ ldr r10, [sp, #40] @ r10 = left
+ ldr r11, [sp, #48] @ r11 = right
+ sub r10, r2, r10
+ sub r10, r10, r11
+ cmp r8, r10 @ aligned_x_size == (yuv420_width-left-right)
+ beq RESTORE_REG
+
+ mov r5, #0 @ i = 0
+LOOP_LINEAR_Y_SIZE_2:
+
+ mov r4, r8 @ j = aligned_x_size
+LOOP_LINEAR_X_SIZE_2:
+
+ bl GET_TILED_OFFSET
+
+ ldr r10, [sp, #44] @ r14 = top
+ ldr r14, [sp, #40] @ r10 = left
+ add r10, r5, r10
+ mul r10, r2, r10 @ temp1 = linear_x_size*(i+top)
+ add r7, r1, r4 @ linear_addr = linear_src+j
+ add r7, r7, r10 @ linear_addr = linear_addr+temp1
+ add r7, r7, r14 @ linear_addr = linear_addr+left
+
+ add r6, r0, r6 @ tiled_addr = tiled_dest+tiled_addr
+ and r11, r5, #0x1F @ temp2 = i&0x1F
+ mov r11, r11, lsl #6 @ temp2 = 64*temp2
+ add r6, r6, r11 @ tiled_addr = tiled_addr+temp2
+ and r11, r4, #0x3F @ temp2 = j&0x3F
+ add r6, r6, r11 @ tiled_addr = tiled_addr+temp2
+
+ ldrh r10, [r7], r2
+ ldrh r11, [r7]
+ strh r10, [r6], #64
+ strh r11, [r6]
+
+ ldr r12, [sp, #40] @ r12 = left
+ ldr r14, [sp, #48] @ r14 = right
+ add r4, r4, #2 @ j = j+2
+ sub r12, r2, r12
+ sub r12, r12, r14
+ cmp r4, r12 @ j<(yuv420_width-left-right)
+ blt LOOP_LINEAR_X_SIZE_2
+
+ ldr r12, [sp, #44] @ r12 = top
+ ldr r14, [sp, #52] @ r14 = buttom
+ add r5, r5, #2 @ i = i+2
+ sub r12, r3, r12
+ sub r12, r12, r14
+ cmp r5, r12 @ i<(yuv420_height-top-buttom)
+ blt LOOP_LINEAR_Y_SIZE_2
+
+RESTORE_REG:
+ ldmfd sp!, {r4-r12,r15} @ restore registers
+
+GET_TILED_OFFSET:
+
+ mov r11, r5, asr #5 @ temp2 = i>>5
+ mov r10, r4, asr #6 @ temp1 = j>>6
+
+ and r12, r11, #0x1 @ if (temp2 & 0x1)
+ cmp r12, #0x1
+ bne GET_TILED_OFFSET_EVEN_FORMULA_1
+
+GET_TILED_OFFSET_ODD_FORMULA:
+ sub r6, r11, #1 @ tiled_addr = temp2-1
+
+ ldr r7, [sp, #40] @ left
+ add r12, r2, #127 @ temp3 = linear_x_size+127
+ sub r12, r12, r7
+ ldr r7, [sp, #48] @ right
+ sub r12, r12, r7
+ bic r12, r12, #0x7F @ temp3 = (temp3 >>7)<<7
+ mov r12, r12, asr #6 @ temp3 = temp3>>6
+ mul r6, r6, r12 @ tiled_addr = tiled_addr*temp3
+ add r6, r6, r10 @ tiled_addr = tiled_addr+temp1
+ add r6, r6, #2 @ tiled_addr = tiled_addr+2
+ bic r12, r10, #0x3 @ temp3 = (temp1>>2)<<2
+ add r6, r6, r12 @ tiled_addr = tiled_addr+temp3
+ mov r6, r6, lsl #11 @ tiled_addr = tiled_addr<<11
+ b GET_TILED_OFFSET_RETURN
+
+GET_TILED_OFFSET_EVEN_FORMULA_1:
+ ldr r7, [sp, #44] @ top
+ add r12, r3, #31 @ temp3 = linear_y_size+31
+ sub r12, r12, r7
+ ldr r7, [sp, #52] @ buttom
+ sub r12, r12, r7
+ bic r12, r12, #0x1F @ temp3 = (temp3>>5)<<5
+ sub r12, r12, #32 @ temp3 = temp3 - 32
+ cmp r5, r12 @ if (i<(temp3-32)) {
+ bge GET_TILED_OFFSET_EVEN_FORMULA_2
+ add r12, r10, #2 @ temp3 = temp1+2
+ bic r12, r12, #3 @ temp3 = (temp3>>2)<<2
+ add r6, r10, r12 @ tiled_addr = temp1+temp3
+ ldr r7, [sp, #40] @ left
+ add r12, r2, #127 @ temp3 = linear_x_size+127
+ sub r12, r12, r7
+ ldr r7, [sp, #48] @ right
+ sub r12, r12, r7
+ bic r12, r12, #0x7F @ temp3 = (temp3>>7)<<7
+ mov r12, r12, asr #6 @ temp3 = temp3>>6
+ mul r11, r11, r12 @ tiled_y_index = tiled_y_index*temp3
+ add r6, r6, r11 @ tiled_addr = tiled_addr+tiled_y_index
+ mov r6, r6, lsl #11 @
+ b GET_TILED_OFFSET_RETURN
+
+GET_TILED_OFFSET_EVEN_FORMULA_2:
+ ldr r7, [sp, #40] @ left
+ add r12, r2, #127 @ temp3 = linear_x_size+127
+ sub r12, r12, r7
+ ldr r7, [sp, #48] @ right
+ sub r12, r12, r7
+ bic r12, r12, #0x7F @ temp3 = (temp3>>7)<<7
+ mov r12, r12, asr #6 @ temp3 = temp3>>6
+ mul r6, r11, r12 @ tiled_addr = temp2*temp3
+ add r6, r6, r10 @ tiled_addr = tiled_addr+temp3
+ mov r6, r6, lsl #11 @ tiled_addr = tiled_addr<<11@
+
+GET_TILED_OFFSET_RETURN:
+ mov pc, lr
+
+ .fnend
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s
new file mode 100644
index 0000000..6a054fa
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_linear_to_tiled_interleave_crop_neon.s
@@ -0,0 +1,563 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_linear_to_tiled_interleave_crop_neon.s
+ * @brief SEC_OMX specific define
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2011.8.04 : Create
+ */
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ * Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left. It should be even.
+ *
+ * @param top
+ * Crop size of top. It should be even.
+ *
+ * @param right
+ * Crop size of right. It should be even.
+ *
+ * @param buttom
+ * Crop size of buttom. It should be even.
+ */
+
+ .arch armv7-a
+ .text
+ .global csc_linear_to_tiled_interleave_crop_neon
+ .type csc_linear_to_tiled_interleave_crop_neon, %function
+csc_linear_to_tiled_interleave_crop_neon:
+ .fnstart
+
+ @r0 tiled_dest
+ @r1 linear_src_u
+ @r2 linear_src_v
+ @r3 yuv420_width
+ @r4 yuv420_height
+ @r5 j
+ @r6 i
+ @r7 tiled_addr
+ @r8 linear_addr
+ @r9 aligned_x_size
+ @r10 aligned_y_size
+ @r11 temp1
+ @r12 temp2
+ @r14 temp3
+
+ stmfd sp!, {r4-r12,r14} @ backup registers
+
+ ldr r4, [sp, #40] @ load linear_y_size to r4
+
+ ldr r10, [sp, #48] @ r10 = top
+ ldr r14, [sp, #56] @ r14 = buttom
+ ldr r11, [sp, #44] @ r11 = left
+ ldr r12, [sp, #52] @ r12 = right
+
+ sub r10, r4, r10 @ aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5
+ sub r10, r10, r14
+ bic r10, r10, #0x1F
+ sub r11, r3, r11 @ aligned_x_size = ((yuv420_width-left-right)>>6)<<6
+ sub r11, r11, r12
+ bic r9, r11, #0x3F
+
+ mov r6, #0 @ i = 0
+LOOP_ALIGNED_Y_SIZE:
+
+ mov r5, #0 @ j = 0
+LOOP_ALIGNED_X_SIZE:
+
+ bl GET_TILED_OFFSET
+
+ ldr r12, [sp, #48] @ r12 = top
+ ldr r8, [sp, #44] @ r8 = left
+
+ mov r11, r3, asr #1 @ temp1 = (yuv420_width/2)*(i+top)
+ add r12, r6, r12
+ mul r11, r11, r12
+ add r11, r11, r5, asr #1 @ temp1 = temp1+j/2
+ add r11, r11, r8, asr #1 @ temp1 = temp1+left/2
+
+ mov r12, r3, asr #1 @ temp2 = yuv420_width/2
+ sub r12, r12, #16 @ temp2 = yuv420_width-16
+
+ add r8, r1, r11 @ linear_addr = linear_src_u+temp1
+ add r11, r2, r11 @ temp1 = linear_src_v+temp1
+ add r7, r0, r7 @ tiled_addr = tiled_dest+tiled_addr
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*1, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*2, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*3, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*1, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*2, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*3, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*1}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*2}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*3}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*4, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*5, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*6, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*7, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*4, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*5, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*6, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*7, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*4}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*5}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*6}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*7}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*8, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*9, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*10, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*11, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*8, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*9, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*10, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*11, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*8}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*9}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*10}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*11}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*12, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*13, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*14, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*15, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*12, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*13, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*14, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*15, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*12}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*13}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*14}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*15}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*16, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*17, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*18, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*19, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*16, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*17, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*18, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*19, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*16}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*17}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*18}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*19}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*20, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*21, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*22, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*23, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*20, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*21, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*22, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*23, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*20}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*21}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*22}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*23}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*24, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*25, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*26, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*27, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*24, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*25, 32}
+ vld1.8 {q7}, [r11], r12
+ pld [r8]
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*26, 32}
+ vld1.8 {q11}, [r11], r12
+ pld [r8, r3, asr #1]
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*27, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*24}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*25}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*26}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*27}
+ vst2.8 {q14, q15}, [r7]!
+
+ pld [r8, r3]
+ vld1.8 {q0}, [r8]! @ load {linear_src_u+(linear_x_size/2)*28, 32}
+ vld1.8 {q2}, [r8], r12
+ pld [r8, r3]
+ vld1.8 {q4}, [r8]! @ load {linear_src_u+(linear_x_size/2)*29, 32}
+ vld1.8 {q6}, [r8], r12
+ pld [r11]
+ vld1.8 {q8}, [r8]! @ load {linear_src_u+(linear_x_size/2)*30, 32}
+ vld1.8 {q10}, [r8], r12
+ pld [r11, r3, asr #1]
+ vld1.8 {q12}, [r8]! @ load {linear_src_u+(linear_x_size/2)*31, 32}
+ vld1.8 {q14}, [r8], r12
+ pld [r11, r3]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v+(linear_x_size/2)*28, 32}
+ vld1.8 {q3}, [r11], r12
+ pld [r11, r3]
+ vld1.8 {q5}, [r11]! @ load {linear_src_v+(linear_x_size/2)*29, 32}
+ vld1.8 {q7}, [r11], r12
+ vld1.8 {q9}, [r11]! @ load {linear_src_v+(linear_x_size/2)*30, 32}
+ vld1.8 {q11}, [r11], r12
+ vld1.8 {q13}, [r11]! @ load {linear_src_v+(linear_x_size/2)*31, 32}
+ vld1.8 {q15}, [r11], r12
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr+64*28}
+ vst2.8 {q2, q3}, [r7]!
+ vst2.8 {q4, q5}, [r7]! @ store {tiled_addr+64*29}
+ vst2.8 {q6, q7}, [r7]!
+ vst2.8 {q8, q9}, [r7]! @ store {tiled_addr+64*30}
+ vst2.8 {q10, q11}, [r7]!
+ vst2.8 {q12, q13}, [r7]! @ store {tiled_addr+64*31}
+ vst2.8 {q14, q15}, [r7]!
+
+ add r5, r5, #64 @ j = j+64
+ cmp r5, r9 @ j<aligned_x_size
+ blt LOOP_ALIGNED_X_SIZE
+
+ add r6, r6, #32 @ i = i+32
+ cmp r6, r10 @ i<aligned_y_size
+ blt LOOP_ALIGNED_Y_SIZE
+
+ cmp r6, r4
+ beq LOOP_LINEAR_Y_SIZE_2_START
+
+LOOP_LINEAR_Y_SIZE_1:
+
+ mov r5, #0 @ j = 0
+LOOP_ALIGNED_X_SIZE_1:
+
+ bl GET_TILED_OFFSET
+
+ ldr r12, [sp, #48] @ r12 = top
+ ldr r8, [sp, #44] @ r8 = left
+
+ mov r11, r3, asr #1 @ temp1 = (yuv420_width/2)*(i+top)
+ add r12, r6, r12
+ mul r11, r11, r12
+ add r11, r11, r5, asr #1 @ temp1 = temp1+j/2
+ add r11, r11, r8, asr #1 @ temp1 = temp1+left/2
+
+ add r8, r1, r11 @ linear_addr = linear_src_u+temp1
+ add r11, r2, r11 @ temp1 = linear_src_v+temp1
+ add r7, r0, r7 @ tiled_addr = tiled_dest+tiled_addr
+ and r14, r6, #0x1F @ temp3 = i&0x1F@
+ mov r14, r14, lsl #6 @ temp3 = temp3*64
+ add r7, r7, r14 @ tiled_addr = tiled_addr+temp3
+
+ vld1.8 {q0}, [r8]! @ load {linear_src_u, 32}
+ vld1.8 {q2}, [r8]
+ vld1.8 {q1}, [r11]! @ load {linear_src_v, 32}
+ vld1.8 {q3}, [r11]
+ vst2.8 {q0, q1}, [r7]! @ store {tiled_addr}
+ vst2.8 {q2, q3}, [r7]!
+
+ add r5, r5, #64 @ j = j+64
+ cmp r5, r9 @ j<aligned_x_size
+ blt LOOP_ALIGNED_X_SIZE_1
+
+ ldr r12, [sp, #48] @ r12 = top
+ ldr r8, [sp, #56] @ r8 = buttom
+ add r6, r6, #1 @ i = i+1
+ sub r12, r4, r12
+ sub r12, r12, r8
+ cmp r6, r12 @ i<(yuv420_height-top-buttom)
+ blt LOOP_LINEAR_Y_SIZE_1
+
+LOOP_LINEAR_Y_SIZE_2_START:
+ cmp r5, r3
+ beq RESTORE_REG
+
+ mov r6, #0 @ i = 0
+LOOP_LINEAR_Y_SIZE_2:
+
+ mov r5, r9 @ j = aligned_x_size
+LOOP_LINEAR_X_SIZE_2:
+
+ bl GET_TILED_OFFSET
+
+ ldr r12, [sp, #48] @ r12 = top
+ ldr r8, [sp, #44] @ r8 = left
+
+ mov r11, r3, asr #1 @ temp1 = (yuv420_width/2)*(i+top)
+ add r12, r6, r12
+ mul r11, r11, r12
+ add r11, r11, r5, asr #1 @ temp1 = temp1+j/2
+ add r11, r11, r8, asr #1 @ temp1 = temp1+left/2
+
+ mov r12, r3, asr #1 @ temp2 = linear_x_size/2
+ sub r12, r12, #1 @ temp2 = linear_x_size-1
+
+ add r8, r1, r11 @ linear_addr = linear_src_u+temp1
+ add r11, r2, r11 @ temp1 = linear_src_v+temp1
+ add r7, r0, r7 @ tiled_addr = tiled_dest+tiled_addr
+ and r14, r6, #0x1F @ temp3 = i&0x1F@
+ mov r14, r14, lsl #6 @ temp3 = temp3*64
+ add r7, r7, r14 @ tiled_addr = tiled_addr+temp3
+ and r14, r5, #0x3F @ temp3 = j&0x3F
+ add r7, r7, r14 @ tiled_addr = tiled_addr+temp3
+
+ ldrb r10, [r8], #1
+ ldrb r14, [r11], #1
+ mov r14, r14, lsl #8
+ orr r10, r10, r14
+ strh r10, [r7], #2
+
+ ldr r12, [sp, #44] @ r12 = left
+ ldr r8, [sp, #52] @ r8 = right
+ add r5, r5, #2 @ j = j+2
+ sub r12, r3, r12
+ sub r12, r12, r8
+ cmp r5, r12 @ j<(yuv420_width-left-right)
+ blt LOOP_LINEAR_X_SIZE_2
+
+ ldr r12, [sp, #48] @ r12 = top
+ ldr r8, [sp, #56] @ r8 = buttom
+ add r6, r6, #1 @ i = i+1
+ sub r12, r4, r12
+ sub r12, r12, r8
+ cmp r6, r12 @ i<(yuv420_height-top-buttom)
+ blt LOOP_LINEAR_Y_SIZE_2
+
+RESTORE_REG:
+ ldmfd sp!, {r4-r12,r15} @ restore registers
+
+GET_TILED_OFFSET:
+ stmfd sp!, {r14}
+
+ mov r12, r6, asr #5 @ temp2 = i>>5
+ mov r11, r5, asr #6 @ temp1 = j>>6
+
+ and r14, r12, #0x1 @ if (temp2 & 0x1)
+ cmp r14, #0x1
+ bne GET_TILED_OFFSET_EVEN_FORMULA_1
+
+GET_TILED_OFFSET_ODD_FORMULA:
+
+ ldr r7, [sp, #48] @ r7 = left , (r14 was pushed to stack)
+ ldr r8, [sp, #56] @ r8 = right , (r14 was pushed to stack)
+ sub r14, r3, r7
+ sub r14, r14, r8
+ add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7
+ bic r14, r14, #0x7F @ temp3 = (temp3 >>7)<<7
+ mov r14, r14, asr #6 @ temp3 = temp3>>6
+ sub r7, r12, #1 @ tiled_addr = temp2-1
+ mul r7, r7, r14 @ tiled_addr = tiled_addr*temp3
+ add r7, r7, r11 @ tiled_addr = tiled_addr+temp1
+ add r7, r7, #2 @ tiled_addr = tiled_addr+2
+ bic r14, r11, #0x3 @ temp3 = (temp1>>2)<<2
+ add r7, r7, r14 @ tiled_addr = tiled_addr+temp3
+ mov r7, r7, lsl #11 @ tiled_addr = tiled_addr<<11
+ b GET_TILED_OFFSET_RETURN
+
+GET_TILED_OFFSET_EVEN_FORMULA_1:
+ ldr r7, [sp, #52] @ r7 = top, (r14 was pushed to stack)
+ ldr r8, [sp, #60] @ r8 = buttom, (r14 was pushed to stack)
+ sub r14, r4, r7
+ sub r14, r14, r8
+ add r14, r14, #31 @ temp3 = (((yuv420_height-top-buttom)+31)>>5)<<5
+ bic r14, r14, #0x1F @ temp3 = (temp3>>5)<<5
+ sub r14, r14, #32 @ temp3 = temp3 - 32
+ cmp r6, r14 @ if (i<(temp3-32)) {
+ bge GET_TILED_OFFSET_EVEN_FORMULA_2
+ add r14, r11, #2 @ temp3 = temp1+2
+ bic r14, r14, #3 @ temp3 = (temp3>>2)<<2
+ add r7, r11, r14 @ tiled_addr = temp1+temp3
+ ldr r8, [sp, #48] @ r8 = left, (r14 was pushed to stack)
+ sub r14, r3, r8
+ ldr r8, [sp, #56] @ r8 = right, (r14 was pushed to stack)
+ sub r14, r14, r8
+ add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7
+ bic r14, r14, #0x7F @ temp3 = (temp3>>7)<<7
+ mov r14, r14, asr #6 @ temp3 = temp3>>6
+ mul r12, r12, r14 @ tiled_y_index = tiled_y_index*temp3
+ add r7, r7, r12 @ tiled_addr = tiled_addr+tiled_y_index
+ mov r7, r7, lsl #11 @
+ b GET_TILED_OFFSET_RETURN
+
+GET_TILED_OFFSET_EVEN_FORMULA_2:
+ ldr r8, [sp, #48] @ r8 = left, (r14 was pushed to stack)
+ sub r14, r3, r8
+ ldr r8, [sp, #56] @ r8 = right, (r14 was pushed to stack)
+ sub r14, r14, r8
+ add r14, r14, #127 @ temp3 = (((yuv420_width-left-right)+127)>>7)<<7
+ bic r14, r14, #0x7F @ temp3 = (temp3>>7)<<7
+ mov r14, r14, asr #6 @ temp3 = temp3>>6
+ mul r7, r12, r14 @ tiled_addr = temp2*temp3
+ add r7, r7, r11 @ tiled_addr = tiled_addr+temp3
+ mov r7, r7, lsl #11 @ tiled_addr = tiled_addr<<11@
+
+GET_TILED_OFFSET_RETURN:
+ ldmfd sp!, {r15} @ restore registers
+
+ .fnend
+
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s
new file mode 100644
index 0000000..da86ac6
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_crop_neon.s
@@ -0,0 +1,701 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_tiled_to_linear_crop_neon.s
+ * @brief SEC_OMX specific define
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2011.8.04 : Create
+ */
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ * Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left. It should be even.
+ *
+ * @param top
+ * Crop size of top. It should be even.
+ *
+ * @param right
+ * Crop size of right. It should be even.
+ *
+ * @param buttom
+ * Crop size of buttom. It should be even.
+ */
+
+ .arch armv7-a
+ .text
+ .global csc_tiled_to_linear_crop_neon
+ .type csc_tiled_to_linear_crop_neon, %function
+csc_tiled_to_linear_crop_neon:
+ .fnstart
+
+ @r0 yuv420_dest
+ @r1 nv12t_src
+ @r2 yuv420_width
+ @r3 yuv420_height
+ @r4
+ @r5 i
+ @r6 j
+ @r7 tiled_offset
+ @r8 tiled_offset1
+ @r9 linear_offset
+ @r10 temp1
+ @r11 temp2
+ @r12 temp3
+ @r14 temp4
+
+ stmfd sp!, {r4-r12,r14} @ backup registers
+
+ ldr r12, [sp, #48] @ r12 = right
+ ldr r10, [sp, #40] @ r10 = left
+ sub r12, r2, r12 @ temp3 = yuv420_width-right@
+ sub r10, r12, r10 @ temp1 = temp3-left@
+ cmp r10, #256 @ if (temp1 >= 256)
+ blt LOOP_HEIGHT_64_START
+
+ ldr r5, [sp, #44] @ i = top
+LOOP_HEIGHT_256:
+ ldr r6, [sp, #40] @ j = left
+ mov r14, r5, asr #5 @ temp4 = i>>5
+ bic r12, r6, #0xFF @ temp3 = (j>>8)<<8
+ mov r12, r12, asr #6 @ temp3 = temp3>>6
+ and r11, r14, #0x1 @ if (temp4 & 0x1)
+ cmp r11, #0x1
+ bne LOOP_HEIGHT_256_GET_TILED_EVEN
+LOOP_HEIGHT_256_GET_TILED_ODD:
+ sub r7, r14, #1 @ tiled_offset = temp4-1
+ add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = tiled_offset*(temp1>>6)
+ mul r7, r7, r10
+ add r7, r7, r12 @ tiled_offset = tiled_offset+temp3
+ add r7, r7, #2 @ tiled_offset = tiled_offset+2
+ bic r10, r12, #0x3 @ temp1 = (temp3>>2)<<2
+ add r7, r7, r10 @ tiled_offset = tiled_offset+temp1
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2
+ mov r14, #8
+ b LOOP_HEIGHT_256_GET_TILED_END
+
+LOOP_HEIGHT_256_GET_TILED_EVEN:
+ add r11, r3, #31 @ temp2 = ((yuv420_height+31)>>5)<<5
+ bic r11, r11, #0x1F
+ add r10, r5, #32 @ if ((i+32)<temp2)
+ cmp r10, r11
+ bge LOOP_HEIGHT_256_GET_TILED_EVEN1
+ add r10, r12, #2 @ temp1 = temp3+2
+ bic r10, r10, #0x3 @ temp1 = (temp1>>2)<<2
+ add r7, r12, r10 @ tiled_offset = temp3+temp1@
+ add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = tiled_offset+temp4*(temp1>>6)
+ mla r7, r14, r10, r7
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #12288 @ tiled_offset1 = tiled_offset+2048*6
+ mov r14, #8
+ b LOOP_HEIGHT_256_GET_TILED_END
+
+LOOP_HEIGHT_256_GET_TILED_EVEN1:
+ add r10, r2, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = temp4*(temp1>>6)
+ mul r7, r14, r10
+ add r7, r7, r12 @ tiled_offset = tiled_offset+temp3
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2
+ mov r14, #4
+
+LOOP_HEIGHT_256_GET_TILED_END:
+
+ ldr r12, [sp, #48] @ right
+ ldr r9, [sp, #44] @ top
+ and r10, r5, #0x1F @ temp1 = i&0x1F
+ add r7, r7, r10, lsl #6 @ tiled_offset = tiled_offset+64*(temp1)
+ add r8, r8, r10, lsl #6 @ tiled_offset1 = tiled_offset1+64*(temp1)
+ sub r11, r2, r6 @ temp2 = yuv420_width-left(==j)-right
+ sub r11, r11, r12
+ sub r9, r5, r9 @ linear_offset = temp2*(i-top)@
+ mul r9, r11, r9
+ add r12, r6, #256 @ temp3 = ((j+256)>>8)<<8@
+ bic r12, r12, #0xFF
+ sub r12, r12, r6 @ temp3 = temp3-j@
+ and r10, r6, #0x3F @ temp1 = left(==j)&0x3F
+
+ cmp r12, #192 @ if (temp3 > 192)
+ ble LOOP_HEIGHT_256_LEFT_192
+ add r11, r1, r7 @ r11 = nv12t_src+tiled_offset+temp1
+ add r11, r11, r10
+ pld [r11]
+ add r12, r1, r7 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r11, #32]
+ add r12, r12, #2048
+ pld [r12]
+ cmp r10, #0
+ pld [r12, #32]
+ stmnefd sp!, {r9-r12, r14} @ backup registers
+ rsbne r10, r10, #64
+ blne MEMCOPY_UNDER_64
+ ldmnefd sp!, {r9-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_256_64
+ vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ vld1.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64}
+ vst1.8 {q2, q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_256_64:
+ add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1
+ pld [r11]
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r11, #32]
+ vld1.8 {q6, q7}, [r12]
+ add r12, r11, #2048 @ r12 = nv12t_src+tiled_offset1+2048
+ pld [r12]
+ vld1.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1, 64}
+ pld [r12, #32]
+ vld1.8 {q10, q11}, [r11]
+ vld1.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset1+2048, 64}
+ vld1.8 {q14, q15}, [r12]
+
+ sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1
+ add r12, r9, #64
+ add r11, r11, r12
+
+ vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64}
+ vst1.8 {q6, q7}, [r11]!
+ vst1.8 {q8, q9}, [r11]! @ store {yuv420_dest+linear_offset+128-temp1, 64}
+ vst1.8 {q10, q11}, [r11]!
+ vst1.8 {q12, q13}, [r11]! @ store {yuv420_dest+linear_offset+192-temp1, 64}
+ vst1.8 {q14, q15}, [r11]!
+
+ add r9, r9, #256
+ sub r9, r9, r10
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_192:
+ cmp r12, #128 @ if (temp3 > 128)
+ ble LOOP_HEIGHT_256_LEFT_128
+ add r11, r1, r7 @ r11 = nv12t_src+tiled_offset+2048+temp1
+ add r11, r11, r10
+ add r11, r11, #2048
+ pld [r11]
+ add r12, r1, r8 @ r12 = nv12t_src+tiled_offset1
+ pld [r11, #32]
+ cmp r10, #0
+ pld [r12]
+ stmnefd sp!, {r9-r12, r14} @ backup registers
+ pld [r12, #32]
+ rsbne r10, r10, #64
+ blne MEMCOPY_UNDER_64
+ ldmnefd sp!, {r9-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_192_64
+ vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+2048+temp1, 64}
+ vld1.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64}
+ vst1.8 {q2, q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_192_64:
+ add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+2048
+ add r11, r11, #2048
+ pld [r11]
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64}
+ pld [r11, #32]
+ vld1.8 {q6, q7}, [r12]
+ vld1.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1+2048, 64}
+ vld1.8 {q10, q11}, [r11]
+
+ sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1
+ add r12, r9, #64
+ add r11, r11, r12
+
+ vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64}
+ vst1.8 {q6, q7}, [r11]!
+ vst1.8 {q8, q9}, [r11]! @ store {yuv420_dest+linear_offset+128-temp1, 64}
+ vst1.8 {q10, q11}, [r11]!
+
+ add r9, r9, #192
+ sub r9, r9, r10
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_128:
+ cmp r12, #64 @ if (temp3 > 64)
+ ble LOOP_HEIGHT_256_LEFT_64
+ add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+temp1
+ add r11, r11, r10
+ pld [r11]
+ add r12, r1, r8 @ r12 = nv12t_src+tiled_offset1
+ add r12, r12, #2048
+ pld [r11, #32]
+ cmp r10, #0
+ pld [r12]
+ stmnefd sp!, {r9-r12, r14} @ backup registers
+ pld [r12, #32]
+ rsbne r10, r10, #64
+ blne MEMCOPY_UNDER_64
+ ldmnefd sp!, {r9-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_128_64
+ vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64}
+ vld1.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64}
+ vst1.8 {q2, q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_128_64:
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64}
+ vld1.8 {q6, q7}, [r12]
+
+ sub r11, r0, r10 @ r11 = yuv420_dest+linear_offset+64-temp1
+ add r12, r9, #64
+ add r11, r11, r12
+
+ vst1.8 {q4, q5}, [r11]! @ store {yuv420_dest+linear_offset+64-temp1, 64}
+ vst1.8 {q6, q7}, [r11]!
+
+ add r9, r9, #128
+ sub r9, r9, r10
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_64:
+ add r11, r1, r8 @ r11 = nv12t_src+tiled_offset1+2048+temp1
+ add r11, r11, #2048
+ add r11, r11, r10
+ cmp r10, #0
+ pld [r11]
+ stmnefd sp!, {r9-r12, r14} @ backup registers
+ pld [r11, #32]
+ rsbne r10, r10, #64
+ blne MEMCOPY_UNDER_64
+ ldmnefd sp!, {r9-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_64_64
+ vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64}
+ vld1.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64}
+ vst1.8 {q2, q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_64_64:
+ add r9, r9, #64
+ sub r9, r9, r10
+
+LOOP_HEIGHT_256_LEFT_END:
+
+ ldr r12, [sp, #48] @ right
+ add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048
+ add r10, r1, r7 @ r10 = nv12t_src+tiled_offset
+ pld [r10]
+ bic r6, r6, #0xFF @ j = (left>>8)<<8
+ pld [r10, #32]
+ add r6, r6, #256 @ j = j + 256
+ sub r11, r2, r12 @ temp2 = yuv420_width-right-256
+ sub r11, r11, #256
+ cmp r6, r11
+ bgt LOOP_HEIGHT_256_WIDTH_END
+
+LOOP_HEIGHT_256_WIDTH:
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r12]
+ vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset, 64}
+ pld [r12, #32]
+ vld1.8 {q2, q3}, [r10]
+
+ add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048
+ add r10, r1, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r10]
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r10, #32]
+ vld1.8 {q6, q7}, [r12]
+
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r12]
+ vld1.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r12, #32]
+ vld1.8 {q10, q11}, [r10]
+
+ add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048
+ add r10, r1, r7
+ pld [r10]
+ vld1.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r10, #32]
+ vld1.8 {q14, q15}, [r12]
+
+ add r12, r0, r9 @ r12 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r12]!
+ vst1.8 {q2, q3}, [r12]!
+ vst1.8 {q4, q5}, [r12]!
+ vst1.8 {q6, q7}, [r12]!
+ vst1.8 {q8, q9}, [r12]!
+ vst1.8 {q10, q11}, [r12]!
+ vst1.8 {q12, q13}, [r12]!
+ vst1.8 {q14, q15}, [r12]!
+ add r9, r9, #256 @ linear_offset = linear_offset+256
+
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+
+ add r6, r6, #256 @ j=j+256
+ cmp r6, r11 @ j<=temp2
+ ble LOOP_HEIGHT_256_WIDTH
+
+LOOP_HEIGHT_256_WIDTH_END:
+
+ add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048
+ ldr r14, [sp, #48] @ right
+ sub r11, r2, r6 @ temp2 = yuv420_width-right-j
+ sub r11, r11, r14
+ cmp r11, #0
+ beq LOOP_HEIGHT_256_RIGHT_END
+ cmp r11, #192
+ ble LOOP_HEIGHT_256_RIGHT_192
+ add r12, r10, #2048
+ pld [r12]
+ vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r12, #32]
+ vld1.8 {q2, q3}, [r10]
+
+ add r10, r1, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r10]
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048}
+ pld [r10, #32]
+ vld1.8 {q6, q7}, [r12]
+
+ add r14, r10, #2048 @ r10 = nv12t_src+tiled_offset1+2048
+ pld [r14]
+ vld1.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset1}
+ pld [r14, #32]
+ vld1.8 {q10, q11}, [r10]
+
+ add r12, r0, r9 @ r12 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r12]!
+ vst1.8 {q2, q3}, [r12]!
+ vst1.8 {q4, q5}, [r12]!
+ vst1.8 {q6, q7}, [r12]!
+ vst1.8 {q8, q9}, [r12]!
+ vst1.8 {q10, q11}, [r12]!
+ add r9, r9, #192 @ linear_offset = linear_offset+192
+
+ stmfd sp!, {r9-r12, r14} @ backup registers
+ sub r10, r11, #192
+ mov r11, r14
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_192:
+ cmp r11, #128
+ ble LOOP_HEIGHT_256_RIGHT_128
+ add r12, r10, #2048
+ pld [r12]
+ vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r12, #32]
+ vld1.8 {q2, q3}, [r10]
+
+ add r14, r1, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r14]
+ vld1.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048}
+ pld [r14, #32]
+ vld1.8 {q6, q7}, [r12]
+
+ add r12, r0, r9 @ r12 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r12]!
+ vst1.8 {q2, q3}, [r12]!
+ vst1.8 {q4, q5}, [r12]!
+ vst1.8 {q6, q7}, [r12]!
+ add r9, r9, #128 @ linear_offset = linear_offset+128
+
+ stmfd sp!, {r9-r12, r14} @ backup registers
+ sub r10, r11, #128
+ mov r11, r14
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_128:
+ cmp r11, #64
+ ble LOOP_HEIGHT_256_RIGHT_64
+ add r14, r10, #2048
+ pld [r14]
+ vld1.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r14, #32]
+ vld1.8 {q2, q3}, [r10]
+
+ add r12, r0, r9 @ r12 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r12]!
+ vst1.8 {q2, q3}, [r12]!
+ add r9, r9, #64 @ linear_offset = linear_offset+64
+
+ stmfd sp!, {r9-r12, r14} @ backup registers
+ sub r10, r11, #64
+ mov r11, r14
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_64:
+ stmfd sp!, {r9-r12, r14} @ backup registers
+ mov r14, r11
+ mov r11, r10
+ mov r10, r14
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12, r14} @ restore registers
+
+LOOP_HEIGHT_256_RIGHT_END:
+
+ ldr r14, [sp, #52] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r3, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_256
+ b RESTORE_REG
+
+LOOP_HEIGHT_64_START:
+ cmp r10, #64 @ if (temp1 >= 64)
+ blt LOOP_HEIGHT_2_START
+
+ ldr r5, [sp, #44] @ i = top
+LOOP_HEIGHT_64:
+ ldr r6, [sp, #40] @ j = left
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ ldr r9, [sp, #44] @ linear_offset = top
+ add r11, r6, #64 @ temp2 = ((j+64)>>6)<<6
+ bic r11, r11, #0x3F
+ sub r11, r11, r6 @ temp2 = temp2-j
+ sub r9, r5, r9 @ linear_offset = temp1*(i-top)
+ mul r9, r9, r10
+ and r14, r6, #0x3 @ temp4 = j&0x3
+ add r7, r7, r14 @ tiled_offset = tiled_offset+temp4
+ stmfd sp!, {r9-r12} @ backup parameters
+ mov r10, r11
+ add r11, r1, r7
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12} @ restore parameters
+ add r9, r9, r11 @ linear_offset = linear_offset+temp2
+ add r6, r6, r11 @ j = j+temp2@
+
+ add r14, r6, #64
+ cmp r14, r12
+ bgt LOOP_HEIGHT_64_1
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ add r7, r1, r7
+ vld1.8 {q0, q1}, [r7]!
+ vld1.8 {q2, q3}, [r7]
+ add r7, r0, r9
+ vst1.8 {q0, q1}, [r7]!
+ vst1.8 {q2, q3}, [r7]
+ add r9, r9, #64
+ add r6, r6, #64
+
+LOOP_HEIGHT_64_1:
+ add r14, r6, #64
+ cmp r14, r12
+ bgt LOOP_HEIGHT_64_2
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ add r7, r1, r7
+ vld1.8 {q0, q1}, [r7]!
+ vld1.8 {q2, q3}, [r7]
+ add r7, r0, r9
+ vst1.8 {q0, q1}, [r7]!
+ vst1.8 {q2, q3}, [r7]
+ add r9, r9, #64
+ add r6, r6, #64
+
+LOOP_HEIGHT_64_2:
+ cmp r6, r12
+ bge LOOP_HEIGHT_64_3
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ sub r11, r12, r6
+ stmfd sp!, {r9-r12} @ backup parameters
+ mov r10, r11
+ add r11, r1, r7
+ bl MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12} @ restore parameters
+
+LOOP_HEIGHT_64_3:
+
+ ldr r14, [sp, #52] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r3, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_64
+ b RESTORE_REG
+
+LOOP_HEIGHT_2_START:
+
+ ldr r5, [sp, #44] @ i = top
+LOOP_HEIGHT_2:
+
+ ldr r6, [sp, #40] @ j = left
+ ldr r9, [sp, #44] @ linear_offset = top
+ add r11, r6, #64 @ temp2 = ((j+64)>>6)<<6
+ bic r11, r11, #0x3F
+ sub r11, r11, r6 @ temp2 = temp2-j
+ sub r9, r5, r9 @ linear_offset = temp1*(i-top)
+ mul r9, r10, r9
+ add r9, r0, r9 @ linear_offset = linear_dst+linear_offset
+LOOP_HEIGHT_2_WIDTH:
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+
+ and r14, r6, #0x3 @ temp4 = j&0x3@
+ add r7, r7, r14 @ tiled_offset = tiled_offset+temp4@
+ add r7, r1, r7
+
+ ldrh r14, [r7]
+ strh r14, [r9], #2
+
+ ldr r14, [sp, #48] @ right
+ add r6, r6, #2 @ j=j+2
+ sub r14, r2, r14 @ j<yuv420_width-right
+ cmp r6, r14
+ blt LOOP_HEIGHT_2_WIDTH
+
+ ldr r14, [sp, #52] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r3, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_2
+
+RESTORE_REG:
+ ldmfd sp!, {r4-r12,r15} @ restore registers
+
+MEMCOPY_UNDER_64: @ count=r10, src=r11
+ cmp r10, #32
+ add r9, r0, r9 @ r9 = yuv420_dest+linear_offset
+ blt MEMCOPY_UNDER_32
+ vld1.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ sub r10, r10, #32
+ cmp r10, #0
+ vst1.8 {q0, q1}, [r9]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ beq MEMCOPY_UNDER_END
+MEMCOPY_UNDER_32:
+ cmp r10, #16
+ blt MEMCOPY_UNDER_16
+ vld1.8 {q0}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ sub r10, r10, #16
+ cmp r10, #0
+ vst1.8 {q0}, [r9]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ beq MEMCOPY_UNDER_END
+MEMCOPY_UNDER_16:
+ ldrb r12, [r11], #1
+ strb r12, [r9], #1
+ subs r10, r10, #1
+ bne MEMCOPY_UNDER_16
+
+MEMCOPY_UNDER_END:
+ and r10, r6, #0x3F @ temp1 = left(==j)&0x3F
+ cmp r10, #0
+ mov pc, lr
+
+tile_4x2_read_asm:
+LFB0:
+ add ip, r3, #32
+ sub r0, r0, #1
+ cmp r1, ip
+ cmple r3, r1
+ mov ip, r2, asr #2
+ mov r0, r0, asr #7
+ stmfd sp!, {r4, r5, lr}
+LCFI0:
+ add r0, r0, #1
+ bge L2
+ sub r1, r1, #1
+ tst r1, #32
+ bne L2
+ tst r3, #32
+ bne L2
+ mov r4, r2, asr #7
+ and r1, r3, #31
+ eor r4, r4, r3, asr #5
+ ubfx r3, r3, #6, #8
+ tst r4, #1
+ ubfx r4, r2, #8, #6
+ and ip, ip, #15
+ mov r2, r2, asr #6
+ mla r3, r0, r3, r4
+ orr r1, ip, r1, asl #4
+ b L9
+L2:
+ mov r2, ip, asr #5
+ and r4, r3, #31
+ eor r1, r2, r3, asr #5
+ and r5, r2, #127
+ ubfx r3, r3, #6, #8
+ tst r1, #1
+ and r1, ip, #15
+ mov r2, ip, asr #4
+ mla r3, r0, r3, r5
+ orr r1, r1, r4, asl #4
+L9:
+ andne r2, r2, #1
+ andeq r2, r2, #1
+ orrne r2, r2, #2
+ mov r1, r1, asl #2
+ orr r3, r1, r3, asl #13
+ orr r0, r3, r2, asl #11
+ ldmfd sp!, {r4, r5, pc}
+LFE0:
+ .fnend
+
diff --git a/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_deinterleave_crop_neon.s b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_deinterleave_crop_neon.s
new file mode 100644
index 0000000..45a749d
--- /dev/null
+++ b/exynos/multimedia/utils/csc/exynos4/csc_tiled_to_linear_deinterleave_crop_neon.s
@@ -0,0 +1,786 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @file csc_tiled_to_linear_deinterleave_crop_neon.s
+ * @brief SEC_OMX specific define
+ * @author ShinWon Lee (shinwon.lee@samsung.com)
+ * @version 1.0
+ * @history
+ * 2011.8.04 : Create
+ */
+
+/*
+ * Converts and Deinterleaves tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. UV of NV12T to UV of YUV420P
+ *
+ * @param yuv420_u_dest
+ * U plane address of YUV420P[out]
+ *
+ * @param yuv420_v_dest
+ * V plane address of YUV420P[out]
+ *
+ * @param nv12t_src
+ * UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_uv_height
+ * Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left. It should be even.
+ *
+ * @param top
+ * Crop size of top. It should be even.
+ *
+ * @param right
+ * Crop size of right. It should be even.
+ *
+ * @param buttom
+ * Crop size of buttom. It should be even.
+ */
+
+ .arch armv7-a
+ .text
+ .global csc_tiled_to_linear_deinterleave_crop_neon
+ .type csc_tiled_to_linear_deinterleave_crop_neon, %function
+csc_tiled_to_linear_deinterleave_crop_neon:
+ .fnstart
+
+ @r0 yuv420_u_dest
+ @r1 yuv420_v_dest
+ @r2 nv12t_src
+ @r3 yuv420_width
+ @r4 yuv420_height
+ @r5 i
+ @r6 j
+ @r7 tiled_offset
+ @r8 tiled_offset1
+ @r9 linear_offset
+ @r10 temp1
+ @r11 temp2
+ @r12 temp3
+ @r14 temp4
+
+ stmfd sp!, {r4-r12,r14} @ backup registers
+
+ ldr r4, [sp, #40] @ r4 = yuv420_height
+
+ ldr r12, [sp, #52] @ r12 = right
+ ldr r10, [sp, #44] @ r10 = left
+ sub r12, r3, r12 @ temp3 = yuv420_width-right@
+ sub r10, r12, r10 @ temp1 = temp3-left@
+ cmp r10, #256 @ if (temp1 >= 256)
+ blt LOOP_HEIGHT_64_START
+
+ ldr r5, [sp, #48] @ top
+LOOP_HEIGHT_256:
+ ldr r6, [sp, #44] @ j = left
+ mov r14, r5, asr #5 @ temp4 = i>>5
+ bic r12, r6, #0xFF @ temp3 = (j>>8)<<8
+ mov r12, r12, asr #6 @ temp3 = temp3>>6
+ and r11, r14, #0x1 @ if (temp4 & 0x1)
+ cmp r11, #0x1
+ bne LOOP_HEIGHT_256_GET_TILED_EVEN
+LOOP_HEIGHT_256_GET_TILED_ODD:
+ sub r7, r14, #1 @ tiled_offset = temp4-1
+ add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = tiled_offset*(temp1>>6)
+ mul r7, r7, r10
+ add r7, r7, r12 @ tiled_offset = tiled_offset+temp3
+ add r7, r7, #2 @ tiled_offset = tiled_offset+2
+ bic r10, r12, #0x3 @ temp1 = (temp3>>2)<<2
+ add r7, r7, r10 @ tiled_offset = tiled_offset+temp1
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2
+ mov r14, #8
+ b LOOP_HEIGHT_256_GET_TILED_END
+
+LOOP_HEIGHT_256_GET_TILED_EVEN:
+ add r11, r4, #31 @ temp2 = ((yuv420_height+31)>>5)<<5
+ bic r11, r11, #0x1F
+ add r10, r5, #32 @ if ((i+32)<temp2)
+ cmp r10, r11
+ bge LOOP_HEIGHT_256_GET_TILED_EVEN1
+ add r10, r12, #2 @ temp1 = temp3+2
+ bic r10, r10, #0x3 @ temp1 = (temp1>>2)<<2
+ add r7, r12, r10 @ tiled_offset = temp3+temp1@
+ add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = tiled_offset+temp4*(temp1>>6)
+ mla r7, r14, r10, r7
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #12288 @ tiled_offset1 = tiled_offset+2048*6
+ mov r14, #8
+ b LOOP_HEIGHT_256_GET_TILED_END
+
+LOOP_HEIGHT_256_GET_TILED_EVEN1:
+ add r10, r3, #127 @ temp1 = ((yuv420_width+127)>>7)<<7
+ bic r10, r10, #0x7F
+ mov r10, r10, asr #6 @ tiled_offset = temp4*(temp1>>6)
+ mul r7, r14, r10
+ add r7, r7, r12 @ tiled_offset = tiled_offset+temp3
+ mov r7, r7, lsl #11 @ tiled_offset = tiled_offset<<11
+ add r8, r7, #4096 @ tiled_offset1 = tiled_offset+2048*2
+ mov r14, #4
+
+LOOP_HEIGHT_256_GET_TILED_END:
+
+ ldr r12, [sp, #52] @ right
+ ldr r9, [sp, #48] @ top
+ and r10, r5, #0x1F @ temp1 = i&0x1F
+ add r7, r7, r10, lsl #6 @ tiled_offset = tiled_offset+64*(temp1)
+ add r8, r8, r10, lsl #6 @ tiled_offset1 = tiled_offset1+64*(temp1)
+ sub r11, r3, r6 @ temp2 = yuv420_width-left(==j)-right
+ sub r11, r11, r12
+ sub r9, r5, r9 @ linear_offset = temp2*(i-top)/2@
+ mul r9, r11, r9
+ mov r9, r9, asr #1
+ add r12, r6, #256 @ temp3 = ((j+256)>>8)<<8@
+ bic r12, r12, #0xFF
+ sub r12, r12, r6 @ temp3 = temp3-j@
+ and r10, r6, #0x3F @ temp1 = left(==j)&0x3F
+
+ cmp r12, #192 @ if (temp3 > 192)
+ ble LOOP_HEIGHT_256_LEFT_192
+ add r11, r2, r7 @ r11 = nv12t_src+tiled_offset+temp1
+ add r11, r11, r10
+ pld [r11]
+ add r12, r2, r7 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r11, #32]
+ add r12, r12, #2048
+ pld [r12]
+ cmp r10, #0
+ pld [r12, #32]
+ stmnefd sp!, {r8-r12, r14} @ backup registers
+ rsbne r10, r10, #64
+ blne INTERLEAVED_MEMCOPY_UNDER_64
+ ldmnefd sp!, {r8-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_256_64
+ vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ vld2.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r11]!
+ vst1.8 {q2}, [r11]!
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r11]!
+ vst1.8 {q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_256_64:
+ add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1
+ pld [r11]
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r11, #32]
+ vld2.8 {q6, q7}, [r12]
+ add r12, r11, #2048 @ r12 = nv12t_src+tiled_offset1+2048
+ pld [r12]
+ vld2.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1, 64}
+ pld [r12, #32]
+ vld2.8 {q10, q11}, [r11]
+ vld2.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset1+2048, 64}
+ vld2.8 {q14, q15}, [r12]
+
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q4}, [r11]!
+ vst1.8 {q6}, [r11]!
+ vst1.8 {q8}, [r11]!
+ vst1.8 {q10}, [r11]!
+ vst1.8 {q12}, [r11]!
+ vst1.8 {q14}, [r11]!
+
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q5}, [r11]!
+ vst1.8 {q7}, [r11]!
+ vst1.8 {q9}, [r11]!
+ vst1.8 {q11}, [r11]!
+ vst1.8 {q13}, [r11]!
+ vst1.8 {q15}, [r11]!
+
+ add r9, r9, #128
+ sub r9, r9, r10, asr #1
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_192:
+ cmp r12, #128 @ if (temp3 > 128)
+ ble LOOP_HEIGHT_256_LEFT_128
+ add r11, r2, r7 @ r11 = nv12t_src+tiled_offset+2048+temp1
+ add r11, r11, r10
+ add r11, r11, #2048
+ pld [r11]
+ add r12, r2, r8 @ r12 = nv12t_src+tiled_offset1
+ pld [r11, #32]
+ cmp r10, #0
+ pld [r12]
+ stmnefd sp!, {r8-r12, r14} @ backup registers
+ pld [r12, #32]
+ rsbne r10, r10, #64
+ blne INTERLEAVED_MEMCOPY_UNDER_64
+ ldmnefd sp!, {r8-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_192_64
+ vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+2048+temp1, 64}
+ vld2.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r11]!
+ vst1.8 {q2}, [r11]!
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r11]!
+ vst1.8 {q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_192_64:
+ add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+2048
+ add r11, r11, #2048
+ pld [r11]
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64}
+ pld [r11, #32]
+ vld2.8 {q6, q7}, [r12]
+ vld2.8 {q8, q9}, [r11]! @ load {nv12t_src+tiled_offset1+2048, 64}
+ vld2.8 {q10, q11}, [r11]
+
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q4}, [r11]!
+ vst1.8 {q6}, [r11]!
+ vst1.8 {q8}, [r11]!
+ vst1.8 {q10}, [r11]!
+
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q5}, [r11]!
+ vst1.8 {q7}, [r11]!
+ vst1.8 {q9}, [r11]!
+ vst1.8 {q11}, [r11]!
+
+ add r9, r9, #96
+ sub r9, r9, r10, asr #1
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_128:
+ cmp r12, #64 @ if (temp3 > 64)
+ ble LOOP_HEIGHT_256_LEFT_64
+ add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+temp1
+ add r11, r11, r10
+ pld [r11]
+ add r12, r2, r8 @ r12 = nv12t_src+tiled_offset1
+ add r12, r12, #2048
+ pld [r11, #32]
+ cmp r10, #0
+ pld [r12]
+ stmnefd sp!, {r8-r12, r14} @ backup registers
+ pld [r12, #32]
+ rsbne r10, r10, #64
+ blne INTERLEAVED_MEMCOPY_UNDER_64
+ ldmnefd sp!, {r8-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_128_64
+ vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64}
+ vld2.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r11]!
+ vst1.8 {q2}, [r11]!
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r11]!
+ vst1.8 {q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_128_64:
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset1, 64}
+ vld2.8 {q6, q7}, [r12]
+
+ add r11, r0, r9 @ r11 = yuv420_u_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q4}, [r11]!
+ vst1.8 {q6}, [r11]!
+
+ add r11, r1, r9 @ r11 = yuv420_v_dest+linear_offset+32-temp1/2
+ add r11, r11, #32
+ sub r11, r11, r10, asr #1
+ vst1.8 {q5}, [r11]!
+ vst1.8 {q7}, [r11]!
+
+ add r9, r9, #64
+ sub r9, r9, r10, asr #1
+ b LOOP_HEIGHT_256_LEFT_END
+
+LOOP_HEIGHT_256_LEFT_64:
+ add r11, r2, r8 @ r11 = nv12t_src+tiled_offset1+2048+temp1
+ add r11, r11, #2048
+ add r11, r11, r10
+ cmp r10, #0
+ pld [r11]
+ stmnefd sp!, {r8-r12, r14} @ backup registers
+ pld [r11, #32]
+ rsbne r10, r10, #64
+ blne INTERLEAVED_MEMCOPY_UNDER_64
+ ldmnefd sp!, {r8-r12, r14} @ restore registers
+ bne LOOP_HEIGHT_256_LEFT_64_64
+ vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset1+temp1, 64}
+ vld2.8 {q2, q3}, [r11]
+ add r11, r0, r9 @ r11 = yuv420_dest+linear_offset
+ vst1.8 {q0, q1}, [r11]! @ store {yuv420_dest+linear_offset, 64}
+ vst1.8 {q2, q3}, [r11]!
+LOOP_HEIGHT_256_LEFT_64_64:
+ add r9, r9, #32
+ sub r9, r9, r10, asr #1
+
+LOOP_HEIGHT_256_LEFT_END:
+
+ ldr r12, [sp, #52] @ right
+ add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048
+ add r10, r2, r7 @ r10 = nv12t_src+tiled_offset
+ pld [r10]
+ bic r6, r6, #0xFF @ j = (left>>8)<<8
+ pld [r10, #32]
+ add r6, r6, #256 @ j = j + 256
+ sub r11, r3, r12 @ temp2 = yuv420_width-right-256
+ sub r11, r11, #256
+ cmp r6, r11
+ bgt LOOP_HEIGHT_256_WIDTH_END
+
+LOOP_HEIGHT_256_WIDTH:
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r12]
+ vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset, 64}
+ pld [r12, #32]
+ vld2.8 {q2, q3}, [r10]
+
+ add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048
+ add r10, r2, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r10]
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r10, #32]
+ vld2.8 {q6, q7}, [r12]
+
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+ pld [r12]
+ vld2.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r12, #32]
+ vld2.8 {q10, q11}, [r10]
+
+ add r7, r7, r14, lsl #11 @ tiled_offset = tiled_offset+temp4*2048
+ add r10, r2, r7
+ pld [r10]
+ vld2.8 {q12, q13}, [r12]! @ load {nv12t_src+tiled_offset+2048, 64}
+ pld [r10, #32]
+ vld2.8 {q14, q15}, [r12]
+
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r12]!
+ vst1.8 {q2}, [r12]!
+ vst1.8 {q4}, [r12]!
+ vst1.8 {q6}, [r12]!
+ vst1.8 {q8}, [r12]!
+ vst1.8 {q10}, [r12]!
+ vst1.8 {q12}, [r12]!
+ vst1.8 {q14}, [r12]!
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r12]!
+ vst1.8 {q3}, [r12]!
+ vst1.8 {q5}, [r12]!
+ vst1.8 {q7}, [r12]!
+ vst1.8 {q9}, [r12]!
+ vst1.8 {q11}, [r12]!
+ vst1.8 {q13}, [r12]!
+ vst1.8 {q15}, [r12]!
+ add r9, r9, #128 @ linear_offset = linear_offset+128
+
+ add r12, r10, #2048 @ r12 = nv12t_src+tiled_offset+2048
+
+ add r6, r6, #256 @ j=j+256
+ cmp r6, r11 @ j<=temp2
+ ble LOOP_HEIGHT_256_WIDTH
+
+LOOP_HEIGHT_256_WIDTH_END:
+
+ add r8, r8, r14, lsl #11 @ tiled_offset1 = tiled_offset1+temp4*2048
+ ldr r14, [sp, #52] @ right
+ sub r11, r3, r6 @ temp2 = yuv420_width-right-j
+ sub r11, r11, r14
+ cmp r11, #0
+ beq LOOP_HEIGHT_256_RIGHT_END
+ cmp r11, #192
+ ble LOOP_HEIGHT_256_RIGHT_192
+ add r12, r10, #2048
+ pld [r12]
+ vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r12, #32]
+ vld2.8 {q2, q3}, [r10]
+
+ add r10, r2, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r10]
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048}
+ pld [r10, #32]
+ vld2.8 {q6, q7}, [r12]
+
+ add r14, r10, #2048 @ r10 = nv12t_src+tiled_offset1+2048
+ pld [r14]
+ vld2.8 {q8, q9}, [r10]! @ load {nv12t_src+tiled_offset1}
+ pld [r14, #32]
+ vld2.8 {q10, q11}, [r10]
+
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r12]!
+ vst1.8 {q2}, [r12]!
+ vst1.8 {q4}, [r12]!
+ vst1.8 {q6}, [r12]!
+ vst1.8 {q8}, [r12]!
+ vst1.8 {q10}, [r12]!
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r12]!
+ vst1.8 {q3}, [r12]!
+ vst1.8 {q5}, [r12]!
+ vst1.8 {q7}, [r12]!
+ vst1.8 {q9}, [r12]!
+ vst1.8 {q11}, [r12]!
+ add r9, r9, #96 @ linear_offset = linear_offset+96
+
+ stmfd sp!, {r8-r12, r14} @ backup registers
+ sub r10, r11, #192
+ mov r11, r14
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r8-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_192:
+ cmp r11, #128
+ ble LOOP_HEIGHT_256_RIGHT_128
+ add r12, r10, #2048
+ pld [r12]
+ vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r12, #32]
+ vld2.8 {q2, q3}, [r10]
+
+ add r14, r2, r8 @ r10 = nv12t_src+tiled_offset1
+ pld [r14]
+ vld2.8 {q4, q5}, [r12]! @ load {nv12t_src+tiled_offset+2048}
+ pld [r14, #32]
+ vld2.8 {q6, q7}, [r12]
+
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r12]!
+ vst1.8 {q2}, [r12]!
+ vst1.8 {q4}, [r12]!
+ vst1.8 {q6}, [r12]!
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r12]!
+ vst1.8 {q3}, [r12]!
+ vst1.8 {q5}, [r12]!
+ vst1.8 {q7}, [r12]!
+ add r9, r9, #64 @ linear_offset = linear_offset+64
+
+ stmfd sp!, {r8-r12, r14} @ backup registers
+ sub r10, r11, #128
+ mov r11, r14
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r8-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_128:
+ cmp r11, #64
+ ble LOOP_HEIGHT_256_RIGHT_64
+ add r14, r10, #2048
+ pld [r14]
+ vld2.8 {q0, q1}, [r10]! @ load {nv12t_src+tiled_offset}
+ pld [r14, #32]
+ vld2.8 {q2, q3}, [r10]
+
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r12]!
+ vst1.8 {q2}, [r12]!
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r12]!
+ vst1.8 {q3}, [r12]!
+ add r9, r9, #32 @ linear_offset = linear_offset+32
+
+ stmfd sp!, {r8-r12, r14} @ backup registers
+ sub r10, r11, #64
+ mov r11, r14
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r8-r12, r14} @ restore registers
+ b LOOP_HEIGHT_256_RIGHT_END
+
+LOOP_HEIGHT_256_RIGHT_64:
+ stmfd sp!, {r8-r12, r14} @ backup registers
+ mov r14, r11
+ mov r11, r10
+ mov r10, r14
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r8-r12, r14} @ restore registers
+
+LOOP_HEIGHT_256_RIGHT_END:
+
+ ldr r14, [sp, #56] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r4, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_256
+ b RESTORE_REG
+
+LOOP_HEIGHT_64_START:
+ cmp r10, #64 @ if (temp1 >= 64)
+ blt LOOP_HEIGHT_2_START
+
+ ldr r5, [sp, #48] @ i = top
+LOOP_HEIGHT_64:
+ ldr r6, [sp, #44] @ j = left
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r3
+ mov r1, r4
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ ldr r9, [sp, #48] @ linear_offset = top
+ ldr r12, [sp, #52] @ r12 = right
+ add r11, r6, #64 @ temp2 = ((j+64)>>6)<<6
+ bic r11, r11, #0x3F
+ sub r11, r11, r6 @ temp2 = temp2-j
+ sub r12, r3, r12 @ temp3 = yuv420_width-right
+ sub r14, r12, r6 @ temp4 = temp3-left
+ sub r9, r5, r9 @ linear_offset = temp4*(i-top)/2
+ mul r9, r9, r14
+ mov r9, r9, asr #1
+ and r14, r6, #0x3 @ temp4 = j&0x3
+ add r7, r7, r14 @ tiled_offset = tiled_offset+temp4
+ stmfd sp!, {r9-r12} @ backup parameters
+ mov r10, r11
+ add r11, r2, r7
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12} @ restore parameters
+ add r9, r9, r11, asr #1 @ linear_offset = linear_offset+temp2/2
+ add r6, r6, r11 @ j = j+temp2@
+
+ add r14, r6, #64
+ cmp r14, r12
+ bgt LOOP_HEIGHT_64_1
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r3
+ mov r1, r4
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ add r7, r2, r7
+ vld2.8 {q0, q1}, [r7]!
+ vld2.8 {q2, q3}, [r7]
+ add r7, r0, r9
+ vst1.8 {q0}, [r7]!
+ vst1.8 {q2}, [r7]
+ add r7, r1, r9
+ vst1.8 {q1}, [r7]!
+ vst1.8 {q3}, [r7]
+ add r9, r9, #32
+ add r6, r6, #64
+
+LOOP_HEIGHT_64_1:
+ add r14, r6, #64
+ cmp r14, r12
+ bgt LOOP_HEIGHT_64_2
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r3
+ mov r1, r4
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ add r7, r2, r7
+ vld2.8 {q0, q1}, [r7]!
+ vld2.8 {q2, q3}, [r7]
+ add r7, r0, r9
+ vst1.8 {q0}, [r7]!
+ vst1.8 {q2}, [r7]
+ add r7, r1, r9
+ vst1.8 {q1}, [r7]!
+ vst1.8 {q3}, [r7]
+ add r9, r9, #32
+ add r6, r6, #64
+
+LOOP_HEIGHT_64_2:
+ cmp r6, r12
+ bge LOOP_HEIGHT_64_3
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r3
+ mov r1, r4
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+ sub r11, r12, r6
+ stmfd sp!, {r9-r12} @ backup parameters
+ mov r10, r11
+ add r11, r2, r7
+ bl INTERLEAVED_MEMCOPY_UNDER_64
+ ldmfd sp!, {r9-r12} @ restore parameters
+
+LOOP_HEIGHT_64_3:
+
+ ldr r14, [sp, #56] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r4, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_64
+ b RESTORE_REG
+
+LOOP_HEIGHT_2_START:
+
+ ldr r5, [sp, #48] @ i = top
+LOOP_HEIGHT_2:
+
+ ldr r12, [sp, #52] @ linear_offset = right
+ ldr r6, [sp, #44] @ j = left
+ ldr r9, [sp, #48] @ linear_offset = top
+
+ sub r12, r3, r12 @ temp3 = yuv420_width-right
+ sub r14, r12, r6 @ temp4 = temp3-left@
+ sub r9, r5, r9 @ r9 = i-top
+ mul r9, r14, r9 @ temp4*(i-top)
+ mov r9, r9, lsr #1 @ linear_offset = temp4*(i-top)/2
+ add r11, r0, r9
+ add r12, r1, r9
+LOOP_HEIGHT_2_WIDTH:
+ stmfd sp!, {r0-r3, r12} @ backup parameters
+ mov r0, r2
+ mov r1, r3
+ mov r2, r6
+ mov r3, r5
+ bl tile_4x2_read_asm
+ mov r7, r0
+ ldmfd sp!, {r0-r3, r12} @ restore parameters
+
+ and r14, r6, #0x3 @ temp4 = j&0x3@
+ add r7, r7, r14 @ tiled_offset = tiled_offset+temp4@
+ add r7, r2, r7
+
+ ldrh r14, [r7]
+ strb r14, [r11], #1
+ mov r14, r14, lsr #8
+ strb r14, [r12], #1
+
+ ldr r14, [sp, #52] @ right
+ add r6, r6, #2 @ j=j+2
+ sub r14, r3, r14 @ j<yuv420_width-right
+ cmp r6, r14
+ blt LOOP_HEIGHT_2_WIDTH
+
+ ldr r14, [sp, #56] @ buttom
+ add r5, r5, #1 @ i=i+1
+ sub r14, r4, r14 @ i<yuv420_height-buttom
+ cmp r5, r14
+ blt LOOP_HEIGHT_2
+
+RESTORE_REG:
+ ldmfd sp!, {r4-r12,r15} @ restore registers
+
+INTERLEAVED_MEMCOPY_UNDER_64: @ count=r10, src=r11
+ cmp r10, #32
+ blt INTERLEAVED_MEMCOPY_UNDER_32
+ vld2.8 {q0, q1}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ sub r10, r10, #32
+ cmp r10, #0
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {q0}, [r12] @ load {nv12t_src+tiled_offset+temp1, 64}
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {q1}, [r12] @ load {nv12t_src+tiled_offset+temp1, 64}
+ add r9, r9, #16
+ beq INTERLEAVED_MEMCOPY_UNDER_END
+INTERLEAVED_MEMCOPY_UNDER_32:
+ cmp r10, #16
+ blt INTERLEAVED_MEMCOPY_UNDER_16
+ vld2.8 {q0}, [r11]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ sub r10, r10, #16
+ cmp r10, #0
+ add r12, r0, r9 @ r12 = yuv420_u_dest+linear_offset
+ vst1.8 {d0}, [r12]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ add r12, r1, r9 @ r12 = yuv420_v_dest+linear_offset
+ vst1.8 {d1}, [r12]! @ load {nv12t_src+tiled_offset+temp1, 64}
+ add r9, r9, #8
+ beq INTERLEAVED_MEMCOPY_UNDER_END
+INTERLEAVED_MEMCOPY_UNDER_16:
+ ldrh r12, [r11], #2
+ add r8, r0, r9 @ r8 = yuv420_u_dest+linear_offset
+ strb r12, [r8]
+ add r8, r1, r9 @ r8 = yuv420_v_dest+linear_offset
+ mov r12, r12, lsr #8
+ strb r12, [r8]
+ subs r10, r10, #2
+ add r9, r9, #1
+ bne INTERLEAVED_MEMCOPY_UNDER_16
+
+INTERLEAVED_MEMCOPY_UNDER_END:
+ and r10, r6, #0x3F @ temp1 = left(==j)&0x3F
+ cmp r10, #0
+ mov pc, lr
+
+tile_4x2_read_asm:
+LFB0:
+ add ip, r3, #32
+ sub r0, r0, #1
+ cmp r1, ip
+ cmple r3, r1
+ mov ip, r2, asr #2
+ mov r0, r0, asr #7
+ stmfd sp!, {r4, r5, lr}
+LCFI0:
+ add r0, r0, #1
+ bge L2
+ sub r1, r1, #1
+ tst r1, #32
+ bne L2
+ tst r3, #32
+ bne L2
+ mov r4, r2, asr #7
+ and r1, r3, #31
+ eor r4, r4, r3, asr #5
+ ubfx r3, r3, #6, #8
+ tst r4, #1
+ ubfx r4, r2, #8, #6
+ and ip, ip, #15
+ mov r2, r2, asr #6
+ mla r3, r0, r3, r4
+ orr r1, ip, r1, asl #4
+ b L9
+L2:
+ mov r2, ip, asr #5
+ and r4, r3, #31
+ eor r1, r2, r3, asr #5
+ and r5, r2, #127
+ ubfx r3, r3, #6, #8
+ tst r1, #1
+ and r1, ip, #15
+ mov r2, ip, asr #4
+ mla r3, r0, r3, r5
+ orr r1, r1, r4, asl #4
+L9:
+ andne r2, r2, #1
+ andeq r2, r2, #1
+ orrne r2, r2, #2
+ mov r1, r1, asl #2
+ orr r3, r1, r3, asl #13
+ orr r0, r3, r2, asl #11
+ ldmfd sp!, {r4, r5, pc}
+LFE0:
+ .fnend
+