Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2009 David Conrad
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include "libavutil/arm/asm.S"
  22.  
  23. const   vp3_idct_constants, align=4
  24. .short 64277, 60547, 54491, 46341, 36410, 25080, 12785
  25. endconst
  26.  
  27. #define xC1S7 d0[0]
  28. #define xC2S6 d0[1]
  29. #define xC3S5 d0[2]
  30. #define xC4S4 d0[3]
  31. #define xC5S3 d1[0]
  32. #define xC6S2 d1[1]
  33. #define xC7S1 d1[2]
  34.  
  35. .macro vp3_loop_filter
  36.     vsubl.u8        q3,  d18, d17
  37.     vsubl.u8        q2,  d16, d19
  38.     vadd.i16        q1,  q3,  q3
  39.     vadd.i16        q2,  q2,  q3
  40.     vadd.i16        q0,  q1,  q2
  41.     vrshr.s16       q0,  q0,  #3
  42.     vmovl.u8        q9,  d18
  43.     vdup.u16        q15, r2
  44.  
  45.     vabs.s16        q1,  q0
  46.     vshr.s16        q0,  q0,  #15
  47.     vqsub.u16       q2,  q15, q1
  48.     vqsub.u16       q3,  q2,  q1
  49.     vsub.i16        q1,  q2,  q3
  50.     veor            q1,  q1,  q0
  51.     vsub.i16        q0,  q1,  q0
  52.  
  53.     vaddw.u8        q2,  q0,  d17
  54.     vsub.i16        q3,  q9,  q0
  55.     vqmovun.s16     d0,  q2
  56.     vqmovun.s16     d1,  q3
  57. .endm
  58.  
  59. function ff_vp3_v_loop_filter_neon, export=1
  60.     sub             ip,  r0,  r1
  61.     sub             r0,  r0,  r1,  lsl #1
  62.     vld1.64         {d16}, [r0,:64], r1
  63.     vld1.64         {d17}, [r0,:64], r1
  64.     vld1.64         {d18}, [r0,:64], r1
  65.     vld1.64         {d19}, [r0,:64], r1
  66.     ldrb            r2,    [r2, #129*4]
  67.  
  68.     vp3_loop_filter
  69.  
  70.     vst1.64         {d0},  [ip,:64], r1
  71.     vst1.64         {d1},  [ip,:64], r1
  72.     bx              lr
  73. endfunc
  74.  
  75. function ff_vp3_h_loop_filter_neon, export=1
  76.     sub             ip,  r0,  #1
  77.     sub             r0,  r0,  #2
  78.     vld1.32         {d16[]},  [r0], r1
  79.     vld1.32         {d17[]},  [r0], r1
  80.     vld1.32         {d18[]},  [r0], r1
  81.     vld1.32         {d19[]},  [r0], r1
  82.     vld1.32         {d16[1]}, [r0], r1
  83.     vld1.32         {d17[1]}, [r0], r1
  84.     vld1.32         {d18[1]}, [r0], r1
  85.     vld1.32         {d19[1]}, [r0], r1
  86.     ldrb            r2,  [r2, #129*4]
  87.  
  88.     vtrn.8          d16, d17
  89.     vtrn.8          d18, d19
  90.     vtrn.16         d16, d18
  91.     vtrn.16         d17, d19
  92.  
  93.     vp3_loop_filter
  94.  
  95.     vtrn.8          d0,  d1
  96.  
  97.     vst1.16         {d0[0]}, [ip], r1
  98.     vst1.16         {d1[0]}, [ip], r1
  99.     vst1.16         {d0[1]}, [ip], r1
  100.     vst1.16         {d1[1]}, [ip], r1
  101.     vst1.16         {d0[2]}, [ip], r1
  102.     vst1.16         {d1[2]}, [ip], r1
  103.     vst1.16         {d0[3]}, [ip], r1
  104.     vst1.16         {d1[3]}, [ip], r1
  105.     bx              lr
  106. endfunc
  107.  
  108.  
  109. function vp3_idct_start_neon
  110.     vpush           {d8-d15}
  111.     vmov.i16        q4,  #0
  112.     vmov.i16        q5,  #0
  113.     movrel          r3,  vp3_idct_constants
  114.     vld1.64         {d0-d1},   [r3,:128]
  115.     vld1.64         {d16-d19}, [r2,:128]
  116.     vst1.64         {q4-q5},   [r2,:128]!
  117.     vld1.64         {d20-d23}, [r2,:128]
  118.     vst1.64         {q4-q5},   [r2,:128]!
  119.     vld1.64         {d24-d27}, [r2,:128]
  120.     vst1.64         {q4-q5},   [r2,:128]!
  121.     vadd.s16        q1,  q8,  q12
  122.     vsub.s16        q8,  q8,  q12
  123.     vld1.64         {d28-d31}, [r2,:128]
  124.     vst1.64         {q4-q5},   [r2,:128]!
  125.  
  126. vp3_idct_core_neon:
  127.     vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
  128.     vmull.s16       q3,  d19, xC1S7
  129.     vmull.s16       q4,  d2,  xC4S4     // ((ip[0] + ip[4]) * C4) << 16
  130.     vmull.s16       q5,  d3,  xC4S4
  131.     vmull.s16       q6,  d16, xC4S4     // ((ip[0] - ip[4]) * C4) << 16
  132.     vmull.s16       q7,  d17, xC4S4
  133.     vshrn.s32       d4,  q2,  #16
  134.     vshrn.s32       d5,  q3,  #16
  135.     vshrn.s32       d6,  q4,  #16
  136.     vshrn.s32       d7,  q5,  #16
  137.     vshrn.s32       d8,  q6,  #16
  138.     vshrn.s32       d9,  q7,  #16
  139.     vadd.s16        q12, q1,  q3        // E = (ip[0] + ip[4]) * C4
  140.     vadd.s16        q8,  q8,  q4        // F = (ip[0] - ip[4]) * C4
  141.     vadd.s16        q1,  q2,  q9        // ip[1] * C1
  142.  
  143.     vmull.s16       q2,  d30, xC1S7     // (ip[7] * C1) << 16
  144.     vmull.s16       q3,  d31, xC1S7
  145.     vmull.s16       q4,  d30, xC7S1     // (ip[7] * C7) << 16
  146.     vmull.s16       q5,  d31, xC7S1
  147.     vmull.s16       q6,  d18, xC7S1     // (ip[1] * C7) << 16
  148.     vmull.s16       q7,  d19, xC7S1
  149.     vshrn.s32       d4,  q2,  #16
  150.     vshrn.s32       d5,  q3,  #16
  151.     vshrn.s32       d6,  q4,  #16       // ip[7] * C7
  152.     vshrn.s32       d7,  q5,  #16
  153.     vshrn.s32       d8,  q6,  #16       // ip[1] * C7
  154.     vshrn.s32       d9,  q7,  #16
  155.     vadd.s16        q2,  q2,  q15       // ip[7] * C1
  156.     vadd.s16        q9,  q1,  q3        // A = ip[1] * C1 + ip[7] * C7
  157.     vsub.s16        q15, q4,  q2        // B = ip[1] * C7 - ip[7] * C1
  158.  
  159.     vmull.s16       q2,  d22, xC5S3     // (ip[3] * C5) << 16
  160.     vmull.s16       q3,  d23, xC5S3
  161.     vmull.s16       q4,  d22, xC3S5     // (ip[3] * C3) << 16
  162.     vmull.s16       q5,  d23, xC3S5
  163.     vmull.s16       q6,  d26, xC5S3     // (ip[5] * C5) << 16
  164.     vmull.s16       q7,  d27, xC5S3
  165.     vshrn.s32       d4,  q2,  #16
  166.     vshrn.s32       d5,  q3,  #16
  167.     vshrn.s32       d6,  q4,  #16
  168.     vshrn.s32       d7,  q5,  #16
  169.     vshrn.s32       d8,  q6,  #16
  170.     vshrn.s32       d9,  q7,  #16
  171.     vadd.s16        q3,  q3,  q11       // ip[3] * C3
  172.     vadd.s16        q4,  q4,  q13       // ip[5] * C5
  173.     vadd.s16        q1,  q2,  q11       // ip[3] * C5
  174.     vadd.s16        q11, q3,  q4        // C = ip[3] * C3 + ip[5] * C5
  175.  
  176.     vmull.s16       q2,  d26, xC3S5     // (ip[5] * C3) << 16
  177.     vmull.s16       q3,  d27, xC3S5
  178.     vmull.s16       q4,  d20, xC2S6     // (ip[2] * C2) << 16
  179.     vmull.s16       q5,  d21, xC2S6
  180.     vmull.s16       q6,  d28, xC6S2     // (ip[6] * C6) << 16
  181.     vmull.s16       q7,  d29, xC6S2
  182.     vshrn.s32       d4,  q2,  #16
  183.     vshrn.s32       d5,  q3,  #16
  184.     vshrn.s32       d6,  q4,  #16
  185.     vshrn.s32       d7,  q5,  #16
  186.     vshrn.s32       d8,  q6,  #16       // ip[6] * C6
  187.     vshrn.s32       d9,  q7,  #16
  188.     vadd.s16        q2,  q2,  q13       // ip[5] * C3
  189.     vadd.s16        q3,  q3,  q10       // ip[2] * C2
  190.     vsub.s16        q13, q2,  q1        // D = ip[5] * C3 - ip[3] * C5
  191.     vsub.s16        q1,  q9,  q11       // (A - C)
  192.     vadd.s16        q11, q9,  q11       // Cd = A + C
  193.     vsub.s16        q9,  q15, q13       // (B - D)
  194.     vadd.s16        q13, q15, q13       // Dd = B + D
  195.     vadd.s16        q15, q3,  q4        // G = ip[2] * C2 + ip[6] * C6
  196.  
  197.     vmull.s16       q2,  d2,  xC4S4     // ((A - C) * C4) << 16
  198.     vmull.s16       q3,  d3,  xC4S4
  199.     vmull.s16       q4,  d28, xC2S6     // (ip[6] * C2) << 16
  200.     vmull.s16       q5,  d29, xC2S6
  201.     vmull.s16       q6,  d20, xC6S2     // (ip[2] * C6) << 16
  202.     vmull.s16       q7,  d21, xC6S2
  203.     vshrn.s32       d4,  q2,  #16
  204.     vshrn.s32       d5,  q3,  #16
  205.     vshrn.s32       d6,  q4,  #16
  206.     vshrn.s32       d7,  q5,  #16
  207.     vshrn.s32       d8,  q6,  #16       // ip[2] * C6
  208.     vmull.s16       q5,  d18, xC4S4     // ((B - D) * C4) << 16
  209.     vmull.s16       q6,  d19, xC4S4
  210.     vshrn.s32       d9,  q7,  #16
  211.     vadd.s16        q3,  q3,  q14       // ip[6] * C2
  212.     vadd.s16        q10, q1,  q2        // Ad = (A - C) * C4
  213.     vsub.s16        q14, q4,  q3        // H = ip[2] * C6 - ip[6] * C2
  214.     bx              lr
  215. endfunc
  216.  
  217. .macro VP3_IDCT_END type
  218. function vp3_idct_end_\type\()_neon
  219. .ifc \type, col
  220.     vdup.16         q0,  r3
  221.     vadd.s16        q12, q12, q0
  222.     vadd.s16        q8,  q8,  q0
  223. .endif
  224.  
  225.     vshrn.s32       d2,  q5,  #16
  226.     vshrn.s32       d3,  q6,  #16
  227.     vadd.s16        q2,  q12, q15       // Gd  = E + G
  228.     vadd.s16        q9,  q1,  q9        // (B - D) * C4
  229.     vsub.s16        q12, q12, q15       // Ed  = E - G
  230.     vsub.s16        q3,  q8,  q10       // Fd  = F - Ad
  231.     vadd.s16        q10, q8,  q10       // Add = F + Ad
  232.     vadd.s16        q4,  q9,  q14       // Hd  = Bd + H
  233.     vsub.s16        q14, q9,  q14       // Bdd = Bd - H
  234.     vadd.s16        q8,  q2,  q11       // [0] = Gd + Cd
  235.     vsub.s16        q15, q2,  q11       // [7] = Gd - Cd
  236.     vadd.s16        q9,  q10, q4        // [1] = Add + Hd
  237.     vsub.s16        q10, q10, q4        // [2] = Add - Hd
  238.     vadd.s16        q11, q12, q13       // [3] = Ed + Dd
  239.     vsub.s16        q12, q12, q13       // [4] = Ed - Dd
  240. .ifc \type, row
  241.     vtrn.16         q8,  q9
  242. .endif
  243.     vadd.s16        q13, q3,  q14       // [5] = Fd + Bdd
  244.     vsub.s16        q14, q3,  q14       // [6] = Fd - Bdd
  245.  
  246. .ifc \type, row
  247.     // 8x8 transpose
  248.     vtrn.16         q10, q11
  249.     vtrn.16         q12, q13
  250.     vtrn.16         q14, q15
  251.     vtrn.32         q8,  q10
  252.     vtrn.32         q9,  q11
  253.     vtrn.32         q12, q14
  254.     vtrn.32         q13, q15
  255.     vswp            d17, d24
  256.     vswp            d19, d26
  257.     vadd.s16        q1,  q8,  q12
  258.     vswp            d21, d28
  259.     vsub.s16        q8,  q8,  q12
  260.     vswp            d23, d30
  261. .endif
  262.     bx              lr
  263. endfunc
  264. .endm
  265.  
  266. VP3_IDCT_END row
  267. VP3_IDCT_END col
  268.  
  269. function ff_vp3_idct_put_neon, export=1
  270.     mov             ip,  lr
  271.     bl              vp3_idct_start_neon
  272.     bl              vp3_idct_end_row_neon
  273.     mov             r3,  #8
  274.     add             r3,  r3,  #2048         // convert signed pixel to unsigned
  275.     bl              vp3_idct_core_neon
  276.     bl              vp3_idct_end_col_neon
  277.     mov             lr,  ip
  278.     vpop            {d8-d15}
  279.  
  280.     vqshrun.s16     d0,  q8,  #4
  281.     vqshrun.s16     d1,  q9,  #4
  282.     vqshrun.s16     d2,  q10, #4
  283.     vqshrun.s16     d3,  q11, #4
  284.     vst1.64         {d0}, [r0,:64], r1
  285.     vqshrun.s16     d4,  q12, #4
  286.     vst1.64         {d1}, [r0,:64], r1
  287.     vqshrun.s16     d5,  q13, #4
  288.     vst1.64         {d2}, [r0,:64], r1
  289.     vqshrun.s16     d6,  q14, #4
  290.     vst1.64         {d3}, [r0,:64], r1
  291.     vqshrun.s16     d7,  q15, #4
  292.     vst1.64         {d4}, [r0,:64], r1
  293.     vst1.64         {d5}, [r0,:64], r1
  294.     vst1.64         {d6}, [r0,:64], r1
  295.     vst1.64         {d7}, [r0,:64], r1
  296.     bx              lr
  297. endfunc
  298.  
  299. function ff_vp3_idct_add_neon, export=1
  300.     mov             ip,  lr
  301.     bl              vp3_idct_start_neon
  302.     bl              vp3_idct_end_row_neon
  303.     mov             r3,  #8
  304.     bl              vp3_idct_core_neon
  305.     bl              vp3_idct_end_col_neon
  306.     mov             lr,  ip
  307.     vpop            {d8-d15}
  308.     mov             r2,  r0
  309.  
  310.     vld1.64         {d0}, [r0,:64], r1
  311.     vshr.s16        q8,  q8,  #4
  312.     vld1.64         {d1}, [r0,:64], r1
  313.     vshr.s16        q9,  q9,  #4
  314.     vld1.64         {d2}, [r0,:64], r1
  315.     vaddw.u8        q8,  q8,  d0
  316.     vld1.64         {d3}, [r0,:64], r1
  317.     vaddw.u8        q9,  q9,  d1
  318.     vld1.64         {d4}, [r0,:64], r1
  319.     vshr.s16        q10, q10, #4
  320.     vld1.64         {d5}, [r0,:64], r1
  321.     vshr.s16        q11, q11, #4
  322.     vld1.64         {d6}, [r0,:64], r1
  323.     vqmovun.s16     d0,  q8
  324.     vld1.64         {d7}, [r0,:64], r1
  325.     vqmovun.s16     d1,  q9
  326.     vaddw.u8        q10, q10, d2
  327.     vaddw.u8        q11, q11, d3
  328.     vshr.s16        q12, q12, #4
  329.     vshr.s16        q13, q13, #4
  330.     vqmovun.s16     d2,  q10
  331.     vqmovun.s16     d3,  q11
  332.     vaddw.u8        q12, q12, d4
  333.     vaddw.u8        q13, q13, d5
  334.     vshr.s16        q14, q14, #4
  335.     vshr.s16        q15, q15, #4
  336.     vst1.64         {d0}, [r2,:64], r1
  337.     vqmovun.s16     d4,  q12
  338.     vst1.64         {d1}, [r2,:64], r1
  339.     vqmovun.s16     d5,  q13
  340.     vst1.64         {d2}, [r2,:64], r1
  341.     vaddw.u8        q14, q14, d6
  342.     vst1.64         {d3}, [r2,:64], r1
  343.     vaddw.u8        q15, q15, d7
  344.     vst1.64         {d4}, [r2,:64], r1
  345.     vqmovun.s16     d6,  q14
  346.     vst1.64         {d5}, [r2,:64], r1
  347.     vqmovun.s16     d7,  q15
  348.     vst1.64         {d6}, [r2,:64], r1
  349.     vst1.64         {d7}, [r2,:64], r1
  350.     bx              lr
  351. endfunc
  352.  
  353. function ff_vp3_idct_dc_add_neon, export=1
  354.     ldrsh           r12, [r2]
  355.     mov             r3,  r0
  356.     add             r12, r12,  #15
  357.     vdup.16         q15, r12
  358.     mov             r12, 0
  359.     strh            r12, [r2]
  360.     vshr.s16        q15, q15, #5
  361.  
  362.     vld1.8          {d0}, [r0,:64], r1
  363.     vld1.8          {d1}, [r0,:64], r1
  364.     vld1.8          {d2}, [r0,:64], r1
  365.     vaddw.u8        q8,  q15, d0
  366.     vld1.8          {d3}, [r0,:64], r1
  367.     vaddw.u8        q9,  q15, d1
  368.     vld1.8          {d4}, [r0,:64], r1
  369.     vaddw.u8        q10, q15, d2
  370.     vld1.8          {d5}, [r0,:64], r1
  371.     vaddw.u8        q11, q15, d3
  372.     vld1.8          {d6}, [r0,:64], r1
  373.     vaddw.u8        q12, q15, d4
  374.     vld1.8          {d7}, [r0,:64], r1
  375.     vaddw.u8        q13, q15, d5
  376.     vqmovun.s16     d0,  q8
  377.     vaddw.u8        q14, q15, d6
  378.     vqmovun.s16     d1,  q9
  379.     vaddw.u8        q15, q15, d7
  380.     vqmovun.s16     d2,  q10
  381.     vst1.8          {d0}, [r3,:64], r1
  382.     vqmovun.s16     d3,  q11
  383.     vst1.8          {d1}, [r3,:64], r1
  384.     vqmovun.s16     d4,  q12
  385.     vst1.8          {d2}, [r3,:64], r1
  386.     vqmovun.s16     d5,  q13
  387.     vst1.8          {d3}, [r3,:64], r1
  388.     vqmovun.s16     d6,  q14
  389.     vst1.8          {d4}, [r3,:64], r1
  390.     vqmovun.s16     d7,  q15
  391.     vst1.8          {d5}, [r3,:64], r1
  392.     vst1.8          {d6}, [r3,:64], r1
  393.     vst1.8          {d7}, [r3,:64], r1
  394.     bx              lr
  395. endfunc
  396.