You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

542 lines
18KB

  1. /*
  2. * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/arm/asm.S"
  21. #include "neon.S"
  22. /* H.264 loop filter */
  23. .macro h264_loop_filter_start
  24. ldr r12, [sp]
  25. tst r2, r2
  26. ldr r12, [r12]
  27. it ne
  28. tstne r3, r3
  29. vmov.32 d24[0], r12
  30. and r12, r12, r12, lsl #16
  31. it eq
  32. bxeq lr
  33. ands r12, r12, r12, lsl #8
  34. it lt
  35. bxlt lr
  36. .endm
  37. .macro h264_loop_filter_luma
  38. vdup.8 q11, r2 @ alpha
  39. vmovl.u8 q12, d24
  40. vabd.u8 q6, q8, q0 @ abs(p0 - q0)
  41. vmovl.u16 q12, d24
  42. vabd.u8 q14, q9, q8 @ abs(p1 - p0)
  43. vsli.16 q12, q12, #8
  44. vabd.u8 q15, q1, q0 @ abs(q1 - q0)
  45. vsli.32 q12, q12, #16
  46. vclt.u8 q6, q6, q11 @ < alpha
  47. vdup.8 q11, r3 @ beta
  48. vclt.s8 q7, q12, #0
  49. vclt.u8 q14, q14, q11 @ < beta
  50. vclt.u8 q15, q15, q11 @ < beta
  51. vbic q6, q6, q7
  52. vabd.u8 q4, q10, q8 @ abs(p2 - p0)
  53. vand q6, q6, q14
  54. vabd.u8 q5, q2, q0 @ abs(q2 - q0)
  55. vclt.u8 q4, q4, q11 @ < beta
  56. vand q6, q6, q15
  57. vclt.u8 q5, q5, q11 @ < beta
  58. vand q4, q4, q6
  59. vand q5, q5, q6
  60. vand q12, q12, q6
  61. vrhadd.u8 q14, q8, q0
  62. vsub.i8 q6, q12, q4
  63. vqadd.u8 q7, q9, q12
  64. vhadd.u8 q10, q10, q14
  65. vsub.i8 q6, q6, q5
  66. vhadd.u8 q14, q2, q14
  67. vmin.u8 q7, q7, q10
  68. vqsub.u8 q11, q9, q12
  69. vqadd.u8 q2, q1, q12
  70. vmax.u8 q7, q7, q11
  71. vqsub.u8 q11, q1, q12
  72. vmin.u8 q14, q2, q14
  73. vmovl.u8 q2, d0
  74. vmax.u8 q14, q14, q11
  75. vmovl.u8 q10, d1
  76. vsubw.u8 q2, q2, d16
  77. vsubw.u8 q10, q10, d17
  78. vshl.i16 q2, q2, #2
  79. vshl.i16 q10, q10, #2
  80. vaddw.u8 q2, q2, d18
  81. vaddw.u8 q10, q10, d19
  82. vsubw.u8 q2, q2, d2
  83. vsubw.u8 q10, q10, d3
  84. vrshrn.i16 d4, q2, #3
  85. vrshrn.i16 d5, q10, #3
  86. vbsl q4, q7, q9
  87. vbsl q5, q14, q1
  88. vneg.s8 q7, q6
  89. vmovl.u8 q14, d16
  90. vmin.s8 q2, q2, q6
  91. vmovl.u8 q6, d17
  92. vmax.s8 q2, q2, q7
  93. vmovl.u8 q11, d0
  94. vmovl.u8 q12, d1
  95. vaddw.s8 q14, q14, d4
  96. vaddw.s8 q6, q6, d5
  97. vsubw.s8 q11, q11, d4
  98. vsubw.s8 q12, q12, d5
  99. vqmovun.s16 d16, q14
  100. vqmovun.s16 d17, q6
  101. vqmovun.s16 d0, q11
  102. vqmovun.s16 d1, q12
  103. .endm
  104. function ff_h264_v_loop_filter_luma_neon, export=1
  105. h264_loop_filter_start
  106. vld1.8 {d0, d1}, [r0,:128], r1
  107. vld1.8 {d2, d3}, [r0,:128], r1
  108. vld1.8 {d4, d5}, [r0,:128], r1
  109. sub r0, r0, r1, lsl #2
  110. sub r0, r0, r1, lsl #1
  111. vld1.8 {d20,d21}, [r0,:128], r1
  112. vld1.8 {d18,d19}, [r0,:128], r1
  113. vld1.8 {d16,d17}, [r0,:128], r1
  114. vpush {d8-d15}
  115. h264_loop_filter_luma
  116. sub r0, r0, r1, lsl #1
  117. vst1.8 {d8, d9}, [r0,:128], r1
  118. vst1.8 {d16,d17}, [r0,:128], r1
  119. vst1.8 {d0, d1}, [r0,:128], r1
  120. vst1.8 {d10,d11}, [r0,:128]
  121. vpop {d8-d15}
  122. bx lr
  123. endfunc
  124. function ff_h264_h_loop_filter_luma_neon, export=1
  125. h264_loop_filter_start
  126. sub r0, r0, #4
  127. vld1.8 {d6}, [r0], r1
  128. vld1.8 {d20}, [r0], r1
  129. vld1.8 {d18}, [r0], r1
  130. vld1.8 {d16}, [r0], r1
  131. vld1.8 {d0}, [r0], r1
  132. vld1.8 {d2}, [r0], r1
  133. vld1.8 {d4}, [r0], r1
  134. vld1.8 {d26}, [r0], r1
  135. vld1.8 {d7}, [r0], r1
  136. vld1.8 {d21}, [r0], r1
  137. vld1.8 {d19}, [r0], r1
  138. vld1.8 {d17}, [r0], r1
  139. vld1.8 {d1}, [r0], r1
  140. vld1.8 {d3}, [r0], r1
  141. vld1.8 {d5}, [r0], r1
  142. vld1.8 {d27}, [r0], r1
  143. transpose_8x8 q3, q10, q9, q8, q0, q1, q2, q13
  144. vpush {d8-d15}
  145. h264_loop_filter_luma
  146. transpose_4x4 q4, q8, q0, q5
  147. sub r0, r0, r1, lsl #4
  148. add r0, r0, #2
  149. vst1.32 {d8[0]}, [r0], r1
  150. vst1.32 {d16[0]}, [r0], r1
  151. vst1.32 {d0[0]}, [r0], r1
  152. vst1.32 {d10[0]}, [r0], r1
  153. vst1.32 {d8[1]}, [r0], r1
  154. vst1.32 {d16[1]}, [r0], r1
  155. vst1.32 {d0[1]}, [r0], r1
  156. vst1.32 {d10[1]}, [r0], r1
  157. vst1.32 {d9[0]}, [r0], r1
  158. vst1.32 {d17[0]}, [r0], r1
  159. vst1.32 {d1[0]}, [r0], r1
  160. vst1.32 {d11[0]}, [r0], r1
  161. vst1.32 {d9[1]}, [r0], r1
  162. vst1.32 {d17[1]}, [r0], r1
  163. vst1.32 {d1[1]}, [r0], r1
  164. vst1.32 {d11[1]}, [r0], r1
  165. vpop {d8-d15}
  166. bx lr
  167. endfunc
  168. .macro h264_loop_filter_chroma
  169. vdup.8 d22, r2 @ alpha
  170. vmovl.u8 q12, d24
  171. vabd.u8 d26, d16, d0 @ abs(p0 - q0)
  172. vmovl.u8 q2, d0
  173. vabd.u8 d28, d18, d16 @ abs(p1 - p0)
  174. vsubw.u8 q2, q2, d16
  175. vsli.16 d24, d24, #8
  176. vshl.i16 q2, q2, #2
  177. vabd.u8 d30, d2, d0 @ abs(q1 - q0)
  178. vaddw.u8 q2, q2, d18
  179. vclt.u8 d26, d26, d22 @ < alpha
  180. vsubw.u8 q2, q2, d2
  181. vdup.8 d22, r3 @ beta
  182. vrshrn.i16 d4, q2, #3
  183. vclt.u8 d28, d28, d22 @ < beta
  184. vclt.u8 d30, d30, d22 @ < beta
  185. vmin.s8 d4, d4, d24
  186. vneg.s8 d25, d24
  187. vand d26, d26, d28
  188. vmax.s8 d4, d4, d25
  189. vand d26, d26, d30
  190. vmovl.u8 q11, d0
  191. vand d4, d4, d26
  192. vmovl.u8 q14, d16
  193. vaddw.s8 q14, q14, d4
  194. vsubw.s8 q11, q11, d4
  195. vqmovun.s16 d16, q14
  196. vqmovun.s16 d0, q11
  197. .endm
  198. function ff_h264_v_loop_filter_chroma_neon, export=1
  199. h264_loop_filter_start
  200. sub r0, r0, r1, lsl #1
  201. vld1.8 {d18}, [r0,:64], r1
  202. vld1.8 {d16}, [r0,:64], r1
  203. vld1.8 {d0}, [r0,:64], r1
  204. vld1.8 {d2}, [r0,:64]
  205. h264_loop_filter_chroma
  206. sub r0, r0, r1, lsl #1
  207. vst1.8 {d16}, [r0,:64], r1
  208. vst1.8 {d0}, [r0,:64], r1
  209. bx lr
  210. endfunc
  211. function ff_h264_h_loop_filter_chroma_neon, export=1
  212. h264_loop_filter_start
  213. sub r0, r0, #2
  214. vld1.32 {d18[0]}, [r0], r1
  215. vld1.32 {d16[0]}, [r0], r1
  216. vld1.32 {d0[0]}, [r0], r1
  217. vld1.32 {d2[0]}, [r0], r1
  218. vld1.32 {d18[1]}, [r0], r1
  219. vld1.32 {d16[1]}, [r0], r1
  220. vld1.32 {d0[1]}, [r0], r1
  221. vld1.32 {d2[1]}, [r0], r1
  222. vtrn.16 d18, d0
  223. vtrn.16 d16, d2
  224. vtrn.8 d18, d16
  225. vtrn.8 d0, d2
  226. h264_loop_filter_chroma
  227. vtrn.16 d18, d0
  228. vtrn.16 d16, d2
  229. vtrn.8 d18, d16
  230. vtrn.8 d0, d2
  231. sub r0, r0, r1, lsl #3
  232. vst1.32 {d18[0]}, [r0], r1
  233. vst1.32 {d16[0]}, [r0], r1
  234. vst1.32 {d0[0]}, [r0], r1
  235. vst1.32 {d2[0]}, [r0], r1
  236. vst1.32 {d18[1]}, [r0], r1
  237. vst1.32 {d16[1]}, [r0], r1
  238. vst1.32 {d0[1]}, [r0], r1
  239. vst1.32 {d2[1]}, [r0], r1
  240. bx lr
  241. endfunc
  242. @ Biweighted prediction
  243. .macro biweight_16 macs, macd
  244. vdup.8 d0, r4
  245. vdup.8 d1, r5
  246. vmov q2, q8
  247. vmov q3, q8
  248. 1: subs r3, r3, #2
  249. vld1.8 {d20-d21},[r0,:128], r2
  250. \macd q2, d0, d20
  251. pld [r0]
  252. \macd q3, d0, d21
  253. vld1.8 {d22-d23},[r1,:128], r2
  254. \macs q2, d1, d22
  255. pld [r1]
  256. \macs q3, d1, d23
  257. vmov q12, q8
  258. vld1.8 {d28-d29},[r0,:128], r2
  259. vmov q13, q8
  260. \macd q12, d0, d28
  261. pld [r0]
  262. \macd q13, d0, d29
  263. vld1.8 {d30-d31},[r1,:128], r2
  264. \macs q12, d1, d30
  265. pld [r1]
  266. \macs q13, d1, d31
  267. vshl.s16 q2, q2, q9
  268. vshl.s16 q3, q3, q9
  269. vqmovun.s16 d4, q2
  270. vqmovun.s16 d5, q3
  271. vshl.s16 q12, q12, q9
  272. vshl.s16 q13, q13, q9
  273. vqmovun.s16 d24, q12
  274. vqmovun.s16 d25, q13
  275. vmov q3, q8
  276. vst1.8 {d4- d5}, [r6,:128], r2
  277. vmov q2, q8
  278. vst1.8 {d24-d25},[r6,:128], r2
  279. bne 1b
  280. pop {r4-r6, pc}
  281. .endm
  282. .macro biweight_8 macs, macd
  283. vdup.8 d0, r4
  284. vdup.8 d1, r5
  285. vmov q1, q8
  286. vmov q10, q8
  287. 1: subs r3, r3, #2
  288. vld1.8 {d4},[r0,:64], r2
  289. \macd q1, d0, d4
  290. pld [r0]
  291. vld1.8 {d5},[r1,:64], r2
  292. \macs q1, d1, d5
  293. pld [r1]
  294. vld1.8 {d6},[r0,:64], r2
  295. \macd q10, d0, d6
  296. pld [r0]
  297. vld1.8 {d7},[r1,:64], r2
  298. \macs q10, d1, d7
  299. pld [r1]
  300. vshl.s16 q1, q1, q9
  301. vqmovun.s16 d2, q1
  302. vshl.s16 q10, q10, q9
  303. vqmovun.s16 d4, q10
  304. vmov q10, q8
  305. vst1.8 {d2},[r6,:64], r2
  306. vmov q1, q8
  307. vst1.8 {d4},[r6,:64], r2
  308. bne 1b
  309. pop {r4-r6, pc}
  310. .endm
  311. .macro biweight_4 macs, macd
  312. vdup.8 d0, r4
  313. vdup.8 d1, r5
  314. vmov q1, q8
  315. vmov q10, q8
  316. 1: subs r3, r3, #4
  317. vld1.32 {d4[0]},[r0,:32], r2
  318. vld1.32 {d4[1]},[r0,:32], r2
  319. \macd q1, d0, d4
  320. pld [r0]
  321. vld1.32 {d5[0]},[r1,:32], r2
  322. vld1.32 {d5[1]},[r1,:32], r2
  323. \macs q1, d1, d5
  324. pld [r1]
  325. blt 2f
  326. vld1.32 {d6[0]},[r0,:32], r2
  327. vld1.32 {d6[1]},[r0,:32], r2
  328. \macd q10, d0, d6
  329. pld [r0]
  330. vld1.32 {d7[0]},[r1,:32], r2
  331. vld1.32 {d7[1]},[r1,:32], r2
  332. \macs q10, d1, d7
  333. pld [r1]
  334. vshl.s16 q1, q1, q9
  335. vqmovun.s16 d2, q1
  336. vshl.s16 q10, q10, q9
  337. vqmovun.s16 d4, q10
  338. vmov q10, q8
  339. vst1.32 {d2[0]},[r6,:32], r2
  340. vst1.32 {d2[1]},[r6,:32], r2
  341. vmov q1, q8
  342. vst1.32 {d4[0]},[r6,:32], r2
  343. vst1.32 {d4[1]},[r6,:32], r2
  344. bne 1b
  345. pop {r4-r6, pc}
  346. 2: vshl.s16 q1, q1, q9
  347. vqmovun.s16 d2, q1
  348. vst1.32 {d2[0]},[r6,:32], r2
  349. vst1.32 {d2[1]},[r6,:32], r2
  350. pop {r4-r6, pc}
  351. .endm
  352. .macro biweight_func w
  353. function ff_biweight_h264_pixels_\w\()_neon, export=1
  354. push {r4-r6, lr}
  355. ldr r12, [sp, #16]
  356. add r4, sp, #20
  357. ldm r4, {r4-r6}
  358. lsr lr, r4, #31
  359. add r6, r6, #1
  360. eors lr, lr, r5, lsr #30
  361. orr r6, r6, #1
  362. vdup.16 q9, r12
  363. lsl r6, r6, r12
  364. vmvn q9, q9
  365. vdup.16 q8, r6
  366. mov r6, r0
  367. beq 10f
  368. subs lr, lr, #1
  369. beq 20f
  370. subs lr, lr, #1
  371. beq 30f
  372. b 40f
  373. 10: biweight_\w vmlal.u8, vmlal.u8
  374. 20: rsb r4, r4, #0
  375. biweight_\w vmlal.u8, vmlsl.u8
  376. 30: rsb r4, r4, #0
  377. rsb r5, r5, #0
  378. biweight_\w vmlsl.u8, vmlsl.u8
  379. 40: rsb r5, r5, #0
  380. biweight_\w vmlsl.u8, vmlal.u8
  381. endfunc
  382. .endm
  383. biweight_func 16
  384. biweight_func 8
  385. biweight_func 4
  386. @ Weighted prediction
  387. .macro weight_16 add
  388. vdup.8 d0, r12
  389. 1: subs r2, r2, #2
  390. vld1.8 {d20-d21},[r0,:128], r1
  391. vmull.u8 q2, d0, d20
  392. pld [r0]
  393. vmull.u8 q3, d0, d21
  394. vld1.8 {d28-d29},[r0,:128], r1
  395. vmull.u8 q12, d0, d28
  396. pld [r0]
  397. vmull.u8 q13, d0, d29
  398. \add q2, q8, q2
  399. vrshl.s16 q2, q2, q9
  400. \add q3, q8, q3
  401. vrshl.s16 q3, q3, q9
  402. vqmovun.s16 d4, q2
  403. vqmovun.s16 d5, q3
  404. \add q12, q8, q12
  405. vrshl.s16 q12, q12, q9
  406. \add q13, q8, q13
  407. vrshl.s16 q13, q13, q9
  408. vqmovun.s16 d24, q12
  409. vqmovun.s16 d25, q13
  410. vst1.8 {d4- d5}, [r4,:128], r1
  411. vst1.8 {d24-d25},[r4,:128], r1
  412. bne 1b
  413. pop {r4, pc}
  414. .endm
  415. .macro weight_8 add
  416. vdup.8 d0, r12
  417. 1: subs r2, r2, #2
  418. vld1.8 {d4},[r0,:64], r1
  419. vmull.u8 q1, d0, d4
  420. pld [r0]
  421. vld1.8 {d6},[r0,:64], r1
  422. vmull.u8 q10, d0, d6
  423. \add q1, q8, q1
  424. pld [r0]
  425. vrshl.s16 q1, q1, q9
  426. vqmovun.s16 d2, q1
  427. \add q10, q8, q10
  428. vrshl.s16 q10, q10, q9
  429. vqmovun.s16 d4, q10
  430. vst1.8 {d2},[r4,:64], r1
  431. vst1.8 {d4},[r4,:64], r1
  432. bne 1b
  433. pop {r4, pc}
  434. .endm
  435. .macro weight_4 add
  436. vdup.8 d0, r12
  437. vmov q1, q8
  438. vmov q10, q8
  439. 1: subs r2, r2, #4
  440. vld1.32 {d4[0]},[r0,:32], r1
  441. vld1.32 {d4[1]},[r0,:32], r1
  442. vmull.u8 q1, d0, d4
  443. pld [r0]
  444. blt 2f
  445. vld1.32 {d6[0]},[r0,:32], r1
  446. vld1.32 {d6[1]},[r0,:32], r1
  447. vmull.u8 q10, d0, d6
  448. pld [r0]
  449. \add q1, q8, q1
  450. vrshl.s16 q1, q1, q9
  451. vqmovun.s16 d2, q1
  452. \add q10, q8, q10
  453. vrshl.s16 q10, q10, q9
  454. vqmovun.s16 d4, q10
  455. vmov q10, q8
  456. vst1.32 {d2[0]},[r4,:32], r1
  457. vst1.32 {d2[1]},[r4,:32], r1
  458. vmov q1, q8
  459. vst1.32 {d4[0]},[r4,:32], r1
  460. vst1.32 {d4[1]},[r4,:32], r1
  461. bne 1b
  462. pop {r4, pc}
  463. 2: \add q1, q8, q1
  464. vrshl.s16 q1, q1, q9
  465. vqmovun.s16 d2, q1
  466. vst1.32 {d2[0]},[r4,:32], r1
  467. vst1.32 {d2[1]},[r4,:32], r1
  468. pop {r4, pc}
  469. .endm
  470. .macro weight_func w
  471. function ff_weight_h264_pixels_\w\()_neon, export=1
  472. push {r4, lr}
  473. ldr r12, [sp, #8]
  474. ldr r4, [sp, #12]
  475. cmp r3, #1
  476. lsl r4, r4, r3
  477. vdup.16 q8, r4
  478. mov r4, r0
  479. ble 20f
  480. rsb lr, r3, #1
  481. vdup.16 q9, lr
  482. cmp r12, #0
  483. blt 10f
  484. weight_\w vhadd.s16
  485. 10: rsb r12, r12, #0
  486. weight_\w vhsub.s16
  487. 20: rsb lr, r3, #0
  488. vdup.16 q9, lr
  489. cmp r12, #0
  490. blt 10f
  491. weight_\w vadd.s16
  492. 10: rsb r12, r12, #0
  493. weight_\w vsub.s16
  494. endfunc
  495. .endm
  496. weight_func 16
  497. weight_func 8
  498. weight_func 4