arm_colorconv.S
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:9k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * ARM assembly optimized color format conversion functions
  3.  * (YV12 -> YUY2, YV12 -> some custom YUV420 format used by
  4.  * Epson graphics chip in Nokia N800)
  5.  *
  6.  * Copyright (C) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net>
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public License
  10.  * version 2.1 as published by the Free Software Foundation.
  11.  *
  12.  * This library is distributed in the hope that it will be useful, but
  13.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20.  * 02110-1301 USA
  21.  */
  22.         .text
  23. /*******************************************************/
  24.         .align
  25.         .global yv12_to_yuy2_line_arm
  26.         .func yv12_to_yuy2_line_arm
  27. yv12_to_yuy2_line_arm:
  28. #define DST     r0
  29. #define SRC_Y   r1
  30. #define SRC_U   r2
  31. #define SRC_V   r3
  32. #define WIDTH   ip
  33.         ldr     ip, [sp], #0
  34.         stmfd   sp!, {r4-r8, r10, lr}
  35. #define TMP1    r8
  36. #define TMP2    r10
  37. #define TMP3    lr
  38.         bic     WIDTH, #1
  39.         subs    WIDTH, #8
  40.         blt     2f
  41. 1:
  42.         ldrb    r4, [SRC_Y], #1
  43.         ldrb    TMP1, [SRC_U], #1
  44.         ldrb    TMP2, [SRC_Y], #1
  45.         ldrb    TMP3, [SRC_V], #1
  46.         add     r4, r4, TMP1, lsl #8
  47.         add     r4, r4, TMP2, lsl #16
  48.         add     r4, r4, TMP3, lsl #24
  49.         ldrb    r5, [SRC_Y], #1
  50.         ldrb    TMP1, [SRC_U], #1
  51.         ldrb    TMP2, [SRC_Y], #1
  52.         ldrb    TMP3, [SRC_V], #1
  53.         add     r5, r5, TMP1, lsl #8
  54.         add     r5, r5, TMP2, lsl #16
  55.         add     r5, r5, TMP3, lsl #24
  56.         ldrb    r6, [SRC_Y], #1
  57.         ldrb    TMP1, [SRC_U], #1
  58.         ldrb    TMP2, [SRC_Y], #1
  59.         ldrb    TMP3, [SRC_V], #1
  60.         add     r6, r6, TMP1, lsl #8
  61.         add     r6, r6, TMP2, lsl #16
  62.         add     r6, r6, TMP3, lsl #24
  63.         ldrb    r7, [SRC_Y], #1
  64.         ldrb    TMP1, [SRC_U], #1
  65.         ldrb    TMP2, [SRC_Y], #1
  66.         ldrb    TMP3, [SRC_V], #1
  67.         add     r7, r7, TMP1, lsl #8
  68.         add     r7, r7, TMP2, lsl #16
  69.         add     r7, r7, TMP3, lsl #24
  70.         stmia   DST!, {r4-r7}
  71.         subs    WIDTH, WIDTH, #8
  72.         bge     1b
  73. 2:
  74.         adds    WIDTH, WIDTH, #8
  75.         ble     4f
  76. 3:
  77.         ldrb    r4, [SRC_Y], #1
  78.         ldrb    TMP1, [SRC_U], #1
  79.         ldrb    TMP2, [SRC_Y], #1
  80.         ldrb    TMP3, [SRC_V], #1
  81.         add     r4, r4, TMP1, lsl #8
  82.         add     r4, r4, TMP2, lsl #16
  83.         add     r4, r4, TMP3, lsl #24
  84.         str     r4, [DST], #4
  85.         subs    WIDTH, WIDTH, #2
  86.         bgt     3b
  87. 4:
  88.         ldmfd  sp!, {r4-r8, r10, pc}
  89. #undef  DST
  90. #undef  SRC_Y
  91. #undef  SRC_U
  92. #undef  SRC_V
  93. #undef  WIDTH
  94. #undef  TMP1
  95. #undef  TMP2
  96. #undef  TMP3
  97.         .endfunc
  98. /*******************************************************/
  99. #define DST     r0
  100. #define SRC_Y   r1
  101. #define SRC_U   r2
  102. #define WIDTH   r3
  103. #define TMP1    r10
  104. #define TMP2    r11
  105. #define TMP3    lr
  106. .macro YUV420_function_template function_name, USE_PLD, USE_ARMV6
  107.         .align
  108.         .global function_name
  109.         .func function_name
  110. function_name:
  111. /* Read information about 4 pixels, convert them to YUV420 and store into 6 bytes using 16-bit writes */
  112. .macro  CONVERT_4_PIXELS_MACROBLOCK
  113.         ldrb    r4, [SRC_Y], #1
  114.         ldrb    TMP1, [SRC_U], #1
  115.         ldrb    r5, [SRC_U], #1
  116.         ldrb    TMP2, [SRC_Y], #1
  117.         ldrb    r6, [SRC_Y, #1]
  118.         ldrb    TMP3, [SRC_Y], #2
  119.         add     r4, r4, TMP1, lsl #8
  120.         add     r5, r5, TMP2, lsl #8
  121.         add     r6, r6, TMP3, lsl #8
  122.         strh    r4, [DST], #2
  123.         strh    r5, [DST], #2
  124.         strh    r6, [DST], #2
  125. .endm
  126. .if USE_ARMV6
  127. .macro  CONVERT_8_PIXELS_MACROBLOCK_1 DST_REG1, DST_REG2, FLAG1, FLAG2, PLD_FLAG
  128. .if FLAG1 == 0
  129.         ldrb    DST_REG1, [SRC_U], #1
  130.         ldrh    TMP1, [SRC_Y], #2
  131.         ldrb    TMP2, [SRC_U], #1
  132. .endif
  133. .if FLAG2 == 1
  134.         ldrh    DST_REG2, [SRC_Y], #2
  135. .endif
  136. .if PLD_FLAG == 1
  137.         pld     [SRC_Y, #48]
  138. .endif
  139.         add     DST_REG1, DST_REG1, TMP1, lsl #8
  140.         add     DST_REG1, DST_REG1, TMP2, lsl #24
  141. .if FLAG2 == 1
  142.         ldrb    TMP1, [SRC_U], #1
  143.         ldrb    TMP2, [SRC_Y], #1
  144. .endif
  145.         rev16   DST_REG1, DST_REG1
  146. .endm
  147. .macro  CONVERT_8_PIXELS_MACROBLOCK_2 DST_REG1, DST_REG2, FLAG1, FLAG2, DUMMY1
  148. .if FLAG1 == 0
  149.         ldrh    DST_REG1, [SRC_Y], #2
  150.         ldrb    TMP1, [SRC_U], #1
  151.         ldrb    TMP2, [SRC_Y], #1
  152. .endif
  153. .if FLAG2 == 1
  154.         ldrb    DST_REG2, [SRC_Y], #1
  155. .endif
  156.         add     DST_REG1, DST_REG1, TMP1, lsl #16
  157.         add     DST_REG1, DST_REG1, TMP2, lsl #24
  158. .if FLAG2 == 1
  159.         ldrb    TMP1, [SRC_U], #1
  160.         ldrh    TMP2, [SRC_Y], #2
  161. .endif
  162.         rev16   DST_REG1, DST_REG1
  163. .endm
  164. .macro  CONVERT_8_PIXELS_MACROBLOCK_3 DST_REG1, DST_REG2, FLAG1, FLAG2, DUMMY1
  165. .if FLAG1 == 0
  166.         ldrb    DST_REG1, [SRC_Y], #1
  167.         ldrb    TMP1, [SRC_U], #1
  168.         ldrh    TMP2, [SRC_Y], #2
  169. .endif
  170. .if FLAG2 == 1
  171.         ldrb    DST_REG2, [SRC_U], #1
  172. .endif
  173.         add     DST_REG1, DST_REG1, TMP1, lsl #8
  174.         add     DST_REG1, DST_REG1, TMP2, lsl #16
  175. .if FLAG2 == 1
  176.         ldrh    TMP1, [SRC_Y], #2
  177.         ldrb    TMP2, [SRC_U], #1
  178. .endif
  179.         rev16   DST_REG1, DST_REG1
  180. .endm
  181. .else
  182. /* Prepare the first 32-bit output value for 8 pixels macroblock */
  183. .macro  CONVERT_8_PIXELS_MACROBLOCK_1 DST_REG, DUMMY1, DUMMY2, DUMMY3, PLD_FLAG
  184.         ldrb    DST_REG, [SRC_Y], #1
  185.         ldrb    TMP1, [SRC_U], #1
  186.         ldrb    TMP2, [SRC_U], #1
  187.         ldrb    TMP3, [SRC_Y], #1
  188. .if USE_PLD && (PLD_FLAG == 1)
  189.         pld     [SRC_Y, #48]
  190. .endif
  191.         add     DST_REG, DST_REG, TMP1, lsl #8
  192.         add     DST_REG, DST_REG, TMP2, lsl #16
  193.         add     DST_REG, DST_REG, TMP3, lsl #24
  194. .endm
  195. /* Prepare the second 32-bit output value for 8 pixels macroblock */
  196. .macro  CONVERT_8_PIXELS_MACROBLOCK_2 DST_REG, DUMMY1, DUMMY2, DUMMY3, DUMMY4
  197.         ldrb    DST_REG, [SRC_Y, #1]
  198.         ldrb    TMP1, [SRC_Y], #2
  199.         ldrb    TMP2, [SRC_Y], #1
  200.         ldrb    TMP3, [SRC_U], #1
  201.         add     DST_REG, DST_REG, TMP1, lsl #8
  202.         add     DST_REG, DST_REG, TMP2, lsl #16
  203.         add     DST_REG, DST_REG, TMP3, lsl #24
  204. .endm
  205. /* Prepare the third 32-bit output value for 8 pixels macroblock */
  206. .macro  CONVERT_8_PIXELS_MACROBLOCK_3 DST_REG, DUMMY1, DUMMY2, DUMMY3, DUMMY4
  207.         ldrb    DST_REG, [SRC_U], #1
  208.         ldrb    TMP1, [SRC_Y], #1
  209.         ldrb    TMP2, [SRC_Y, #1]
  210.         ldrb    TMP3, [SRC_Y], #2
  211.         add     DST_REG, DST_REG, TMP1, lsl #8
  212.         add     DST_REG, DST_REG, TMP2, lsl #16
  213.         add     DST_REG, DST_REG, TMP3, lsl #24
  214. .endm
  215. .endif
  216. .if USE_PLD
  217.         pld     [SRC_Y]
  218. .endif
  219.         stmfd   sp!, {r4-r8, r10-r11, lr}
  220.         /* Destination buffer should be at least 16-bit aligned, image width should be multiple of 4 */
  221.         bic     DST, #1
  222.         bic     WIDTH, #3
  223.         /* Ensure 32-bit alignment of the destination buffer */
  224.         tst     DST, #2
  225.         beq     1f
  226.         subs    WIDTH, #4
  227.         blt     6f
  228.         CONVERT_4_PIXELS_MACROBLOCK
  229. 1:
  230.         subs    WIDTH, #32
  231.         blt     3f
  232. 2:      /* Convert 32 pixels per loop iteration */
  233.         CONVERT_8_PIXELS_MACROBLOCK_1 r4, r6, 0, 1, 1 /* Also do cache preload for SRC_Y */
  234.         CONVERT_8_PIXELS_MACROBLOCK_2 r6, r7, 1, 1, 0
  235.         CONVERT_8_PIXELS_MACROBLOCK_3 r7, r8, 1, 1, 0
  236.         CONVERT_8_PIXELS_MACROBLOCK_1 r8, r5, 1, 1, 0
  237.         stmia   DST!, {r4, r6, r7, r8}
  238.         subs    WIDTH, #32
  239.         CONVERT_8_PIXELS_MACROBLOCK_2 r5, r6, 1, 1, 0
  240.         CONVERT_8_PIXELS_MACROBLOCK_3 r6, r7, 1, 1, 0
  241.         CONVERT_8_PIXELS_MACROBLOCK_1 r7, r8, 1, 1, 0
  242.         CONVERT_8_PIXELS_MACROBLOCK_2 r8, r4, 1, 1, 0
  243.         stmia   DST!, {r5, r6, r7, r8}
  244. .if USE_PLD
  245.          /* Do cache preload for SRC_U */
  246.         pld     [SRC_U, #48]
  247. .endif
  248.         CONVERT_8_PIXELS_MACROBLOCK_3 r4, r6, 1, 1, 0
  249.         CONVERT_8_PIXELS_MACROBLOCK_1 r6, r7, 1, 1, 0
  250.         CONVERT_8_PIXELS_MACROBLOCK_2 r7, r8, 1, 1, 0
  251.         CONVERT_8_PIXELS_MACROBLOCK_3 r8, r4, 1, 0, 0
  252.         stmia   DST!, {r4, r6, r7, r8}
  253.         bge     2b
  254. 3:
  255.         adds    WIDTH, WIDTH, #32
  256.         ble     6f
  257.         subs    WIDTH, WIDTH, #8
  258.         blt     5f
  259. 4:      /* Convert remaining pixels processing them 8 per iteration */
  260.         CONVERT_8_PIXELS_MACROBLOCK_1 r4, r5, 0, 1, 0
  261.         CONVERT_8_PIXELS_MACROBLOCK_2 r5, r6, 1, 1, 0
  262.         CONVERT_8_PIXELS_MACROBLOCK_3 r6, r7, 1, 0, 0
  263.         stmia   DST!, {r4-r6}
  264.         subs    WIDTH, WIDTH, #8
  265.         bge     4b
  266. 5:      /* Convert the last 4 pixels if needed */
  267.         adds    WIDTH, WIDTH, #8
  268.         ble     6f
  269.         CONVERT_4_PIXELS_MACROBLOCK
  270.         subs    WIDTH, #4
  271.         bgt     4b
  272. 6:      /* Restore all registers and return */
  273.         ldmfd  sp!, {r4-r8, r10-r11, pc}
  274. .purgem CONVERT_4_PIXELS_MACROBLOCK
  275. .purgem CONVERT_8_PIXELS_MACROBLOCK_1
  276. .purgem CONVERT_8_PIXELS_MACROBLOCK_2
  277. .purgem CONVERT_8_PIXELS_MACROBLOCK_3
  278. #undef  DST
  279. #undef  SRC_Y
  280. #undef  SRC_U
  281. #undef  WIDTH
  282. #undef  TMP1
  283. #undef  TMP2
  284. #undef  TMP3
  285.         .endfunc
  286. .endm
  287. YUV420_function_template yv12_to_yuv420_line_arm,   0, 0
  288. YUV420_function_template yv12_to_yuv420_line_armv5, 1, 0
  289. YUV420_function_template yv12_to_yuv420_line_armv6, 1, 1