swscale_template.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:85k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*
  2.     Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. */
  15. #undef MOVNTQ
  16. #undef PAVGB
  17. #undef PREFETCH
  18. #undef PREFETCHW
  19. #undef EMMS
  20. #undef SFENCE
  21. #ifdef HAVE_3DNOW
  22. /* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */
  23. #define EMMS     "femms"
  24. #else
  25. #define EMMS     "emms"
  26. #endif
  27. #ifdef HAVE_3DNOW
  28. #define PREFETCH  "prefetch"
  29. #define PREFETCHW "prefetchw"
  30. #elif defined ( HAVE_MMX2 )
  31. #define PREFETCH "prefetchnta"
  32. #define PREFETCHW "prefetcht0"
  33. #else
  34. #define PREFETCH "/nop"
  35. #define PREFETCHW "/nop"
  36. #endif
  37. #ifdef HAVE_MMX2
  38. #define SFENCE "sfence"
  39. #else
  40. #define SFENCE "/nop"
  41. #endif
  42. #ifdef HAVE_MMX2
  43. #define PAVGB(a,b) "pavgb " #a ", " #b " nt"
  44. #elif defined (HAVE_3DNOW)
  45. #define PAVGB(a,b) "pavgusb " #a ", " #b " nt"
  46. #endif
  47. #ifdef HAVE_MMX2
  48. #define MOVNTQ(a,b) "movntq " #a ", " #b " nt"
  49. #else
  50. #define MOVNTQ(a,b) "movq " #a ", " #b " nt"
  51. #endif
  52. #ifdef HAVE_ALTIVEC
  53. #include "swscale_altivec_template.c"
  54. #endif
  55. #define YSCALEYUV2YV12X(x, offset) 
  56. "xorl %%eax, %%eax nt"
  57. "movq "VROUNDER_OFFSET"(%0), %%mm3nt"
  58. "movq %%mm3, %%mm4 nt"
  59. "leal " offset "(%0), %%edx nt"
  60. "movl (%%edx), %%esi nt"
  61. ".balign 16 nt" /* FIXME Unroll? */
  62. "1: nt"
  63. "movq 8(%%edx), %%mm0 nt" /* filterCoeff */
  64. "movq " #x "(%%esi, %%eax, 2), %%mm2 nt" /* srcData */
  65. "movq 8+" #x "(%%esi, %%eax, 2), %%mm5 nt" /* srcData */
  66. "addl $16, %%edx nt"
  67. "movl (%%edx), %%esi nt"
  68. "testl %%esi, %%esi nt"
  69. "pmulhw %%mm0, %%mm2 nt"
  70. "pmulhw %%mm0, %%mm5 nt"
  71. "paddw %%mm2, %%mm3 nt"
  72. "paddw %%mm5, %%mm4 nt"
  73. " jnz 1b nt"
  74. "psraw $3, %%mm3 nt"
  75. "psraw $3, %%mm4 nt"
  76. "packuswb %%mm4, %%mm3 nt"
  77. MOVNTQ(%%mm3, (%1, %%eax))
  78. "addl $8, %%eax nt"
  79. "cmpl %2, %%eax nt"
  80. "movq "VROUNDER_OFFSET"(%0), %%mm3nt"
  81. "movq %%mm3, %%mm4 nt"
  82. "leal " offset "(%0), %%edx nt"
  83. "movl (%%edx), %%esi nt"
  84. "jb 1b nt"
  85. #define YSCALEYUV2YV121 
  86. "movl %2, %%eax nt"
  87. ".balign 16 nt" /* FIXME Unroll? */
  88. "1: nt"
  89. "movq (%0, %%eax, 2), %%mm0 nt"
  90. "movq 8(%0, %%eax, 2), %%mm1 nt"
  91. "psraw $7, %%mm0 nt"
  92. "psraw $7, %%mm1 nt"
  93. "packuswb %%mm1, %%mm0 nt"
  94. MOVNTQ(%%mm0, (%1, %%eax))
  95. "addl $8, %%eax nt"
  96. "jnc 1b nt"
  97. /*
  98. :: "m" (-lumFilterSize), "m" (-chrFilterSize),
  99.    "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),
  100.    "r" (dest), "m" (dstW),
  101.    "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)
  102. : "%eax", "%ebx", "%ecx", "%edx", "%esi"
  103. */
  104. #define YSCALEYUV2PACKEDX 
  105. "xorl %%eax, %%eax nt"
  106. ".balign 16 nt"
  107. "nop nt"
  108. "1: nt"
  109. "leal "CHR_MMX_FILTER_OFFSET"(%0), %%edx nt"
  110. "movl (%%edx), %%esi nt"
  111. "movq "VROUNDER_OFFSET"(%0), %%mm3nt"
  112. "movq %%mm3, %%mm4 nt"
  113. ".balign 16 nt"
  114. "2: nt"
  115. "movq 8(%%edx), %%mm0 nt" /* filterCoeff */
  116. "movq (%%esi, %%eax), %%mm2 nt" /* UsrcData */
  117. "movq 4096(%%esi, %%eax), %%mm5 nt" /* VsrcData */
  118. "addl $16, %%edx nt"
  119. "movl (%%edx), %%esi nt"
  120. "pmulhw %%mm0, %%mm2 nt"
  121. "pmulhw %%mm0, %%mm5 nt"
  122. "paddw %%mm2, %%mm3 nt"
  123. "paddw %%mm5, %%mm4 nt"
  124. "testl %%esi, %%esi nt"
  125. " jnz 2b nt"
  126. "leal "LUM_MMX_FILTER_OFFSET"(%0), %%edx nt"
  127. "movl (%%edx), %%esi nt"
  128. "movq "VROUNDER_OFFSET"(%0), %%mm1nt"
  129. "movq %%mm1, %%mm7 nt"
  130. ".balign 16 nt"
  131. "2: nt"
  132. "movq 8(%%edx), %%mm0 nt" /* filterCoeff */
  133. "movq (%%esi, %%eax, 2), %%mm2 nt" /* Y1srcData */
  134. "movq 8(%%esi, %%eax, 2), %%mm5 nt" /* Y2srcData */
  135. "addl $16, %%edx nt"
  136. "movl (%%edx), %%esi nt"
  137. "pmulhw %%mm0, %%mm2 nt"
  138. "pmulhw %%mm0, %%mm5 nt"
  139. "paddw %%mm2, %%mm1 nt"
  140. "paddw %%mm5, %%mm7 nt"
  141. "testl %%esi, %%esi nt"
  142. " jnz 2b nt"
  143. #define YSCALEYUV2RGBX 
  144. YSCALEYUV2PACKEDX
  145. "psubw "U_OFFSET"(%0), %%mm3 nt" /* (U-128)8*/
  146. "psubw "V_OFFSET"(%0), %%mm4 nt" /* (V-128)8*/
  147. "movq %%mm3, %%mm2 nt" /* (U-128)8*/
  148. "movq %%mm4, %%mm5 nt" /* (V-128)8*/
  149. "pmulhw "UG_COEFF"(%0), %%mm3 nt"
  150. "pmulhw "VG_COEFF"(%0), %%mm4 nt"
  151. /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */
  152. "pmulhw "UB_COEFF"(%0), %%mm2 nt"
  153. "pmulhw "VR_COEFF"(%0), %%mm5 nt"
  154. "psubw "Y_OFFSET"(%0), %%mm1 nt" /* 8(Y-16)*/
  155. "psubw "Y_OFFSET"(%0), %%mm7 nt" /* 8(Y-16)*/
  156. "pmulhw "Y_COEFF"(%0), %%mm1 nt"
  157. "pmulhw "Y_COEFF"(%0), %%mm7 nt"
  158. /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */
  159. "paddw %%mm3, %%mm4 nt"
  160. "movq %%mm2, %%mm0 nt"
  161. "movq %%mm5, %%mm6 nt"
  162. "movq %%mm4, %%mm3 nt"
  163. "punpcklwd %%mm2, %%mm2 nt"
  164. "punpcklwd %%mm5, %%mm5 nt"
  165. "punpcklwd %%mm4, %%mm4 nt"
  166. "paddw %%mm1, %%mm2 nt"
  167. "paddw %%mm1, %%mm5 nt"
  168. "paddw %%mm1, %%mm4 nt"
  169. "punpckhwd %%mm0, %%mm0 nt"
  170. "punpckhwd %%mm6, %%mm6 nt"
  171. "punpckhwd %%mm3, %%mm3 nt"
  172. "paddw %%mm7, %%mm0 nt"
  173. "paddw %%mm7, %%mm6 nt"
  174. "paddw %%mm7, %%mm3 nt"
  175. /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */
  176. "packuswb %%mm0, %%mm2 nt"
  177. "packuswb %%mm6, %%mm5 nt"
  178. "packuswb %%mm3, %%mm4 nt"
  179. "pxor %%mm7, %%mm7 nt"
  180. #if 0
  181. #define FULL_YSCALEYUV2RGB 
  182. "pxor %%mm7, %%mm7 nt"
  183. "movd %6, %%mm6 nt" /*yalpha1*/
  184. "punpcklwd %%mm6, %%mm6 nt"
  185. "punpcklwd %%mm6, %%mm6 nt"
  186. "movd %7, %%mm5 nt" /*uvalpha1*/
  187. "punpcklwd %%mm5, %%mm5 nt"
  188. "punpcklwd %%mm5, %%mm5 nt"
  189. "xorl %%eax, %%eax nt"
  190. ".balign 16 nt"
  191. "1: nt"
  192. "movq (%0, %%eax, 2), %%mm0 nt" /*buf0[eax]*/
  193. "movq (%1, %%eax, 2), %%mm1 nt" /*buf1[eax]*/
  194. "movq (%2, %%eax,2), %%mm2 nt" /* uvbuf0[eax]*/
  195. "movq (%3, %%eax,2), %%mm3 nt" /* uvbuf1[eax]*/
  196. "psubw %%mm1, %%mm0 nt" /* buf0[eax] - buf1[eax]*/
  197. "psubw %%mm3, %%mm2 nt" /* uvbuf0[eax] - uvbuf1[eax]*/
  198. "pmulhw %%mm6, %%mm0 nt" /* (buf0[eax] - buf1[eax])yalpha1>>16*/
  199. "pmulhw %%mm5, %%mm2 nt" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/
  200. "psraw $4, %%mm1 nt" /* buf0[eax] - buf1[eax] >>4*/
  201. "movq 4096(%2, %%eax,2), %%mm4 nt" /* uvbuf0[eax+2048]*/
  202. "psraw $4, %%mm3 nt" /* uvbuf0[eax] - uvbuf1[eax] >>4*/
  203. "paddw %%mm0, %%mm1 nt" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/
  204. "movq 4096(%3, %%eax,2), %%mm0 nt" /* uvbuf1[eax+2048]*/
  205. "paddw %%mm2, %%mm3 nt" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/
  206. "psubw %%mm0, %%mm4 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/
  207. "psubw "MANGLE(w80)", %%mm1 nt" /* 8(Y-16)*/
  208. "psubw "MANGLE(w400)", %%mm3 nt" /* 8(U-128)*/
  209. "pmulhw "MANGLE(yCoeff)", %%mm1 nt"
  210. "pmulhw %%mm5, %%mm4 nt" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/
  211. "movq %%mm3, %%mm2 nt" /* (U-128)8*/
  212. "pmulhw "MANGLE(ubCoeff)", %%mm3nt"
  213. "psraw $4, %%mm0 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/
  214. "pmulhw "MANGLE(ugCoeff)", %%mm2nt"
  215. "paddw %%mm4, %%mm0 nt" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/
  216. "psubw "MANGLE(w400)", %%mm0 nt" /* (V-128)8*/
  217. "movq %%mm0, %%mm4 nt" /* (V-128)8*/
  218. "pmulhw "MANGLE(vrCoeff)", %%mm0nt"
  219. "pmulhw "MANGLE(vgCoeff)", %%mm4nt"
  220. "paddw %%mm1, %%mm3 nt" /* B*/
  221. "paddw %%mm1, %%mm0 nt" /* R*/
  222. "packuswb %%mm3, %%mm3 nt"
  223. "packuswb %%mm0, %%mm0 nt"
  224. "paddw %%mm4, %%mm2 nt"
  225. "paddw %%mm2, %%mm1 nt" /* G*/
  226. "packuswb %%mm1, %%mm1 nt"
  227. #endif
  228. #define YSCALEYUV2PACKED(index, c) 
  229. "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0nt"
  230. "movq "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm1nt"
  231. "psraw $3, %%mm0 nt"
  232. "psraw $3, %%mm1 nt"
  233. "movq %%mm0, "CHR_MMX_FILTER_OFFSET"+8("#c")nt"
  234. "movq %%mm1, "LUM_MMX_FILTER_OFFSET"+8("#c")nt"
  235. "xorl "#index", "#index" nt"
  236. ".balign 16 nt"
  237. "1: nt"
  238. "movq (%2, "#index"), %%mm2 nt" /* uvbuf0[eax]*/
  239. "movq (%3, "#index"), %%mm3 nt" /* uvbuf1[eax]*/
  240. "movq 4096(%2, "#index"), %%mm5 nt" /* uvbuf0[eax+2048]*/
  241. "movq 4096(%3, "#index"), %%mm4 nt" /* uvbuf1[eax+2048]*/
  242. "psubw %%mm3, %%mm2 nt" /* uvbuf0[eax] - uvbuf1[eax]*/
  243. "psubw %%mm4, %%mm5 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/
  244. "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0nt"
  245. "pmulhw %%mm0, %%mm2 nt" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/
  246. "pmulhw %%mm0, %%mm5 nt" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/
  247. "psraw $7, %%mm3 nt" /* uvbuf0[eax] - uvbuf1[eax] >>4*/
  248. "psraw $7, %%mm4 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/
  249. "paddw %%mm2, %%mm3 nt" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/
  250. "paddw %%mm5, %%mm4 nt" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/
  251. "movq (%0, "#index", 2), %%mm0 nt" /*buf0[eax]*/
  252. "movq (%1, "#index", 2), %%mm1 nt" /*buf1[eax]*/
  253. "movq 8(%0, "#index", 2), %%mm6 nt" /*buf0[eax]*/
  254. "movq 8(%1, "#index", 2), %%mm7 nt" /*buf1[eax]*/
  255. "psubw %%mm1, %%mm0 nt" /* buf0[eax] - buf1[eax]*/
  256. "psubw %%mm7, %%mm6 nt" /* buf0[eax] - buf1[eax]*/
  257. "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm0nt" /* (buf0[eax] - buf1[eax])yalpha1>>16*/
  258. "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm6nt" /* (buf0[eax] - buf1[eax])yalpha1>>16*/
  259. "psraw $7, %%mm1 nt" /* buf0[eax] - buf1[eax] >>4*/
  260. "psraw $7, %%mm7 nt" /* buf0[eax] - buf1[eax] >>4*/
  261. "paddw %%mm0, %%mm1 nt" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/
  262. "paddw %%mm6, %%mm7 nt" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/
  263.                 
  264. #define YSCALEYUV2RGB(index, c) 
  265. "xorl "#index", "#index" nt"
  266. ".balign 16 nt"
  267. "1: nt"
  268. "movq (%2, "#index"), %%mm2 nt" /* uvbuf0[eax]*/
  269. "movq (%3, "#index"), %%mm3 nt" /* uvbuf1[eax]*/
  270. "movq 4096(%2, "#index"), %%mm5nt" /* uvbuf0[eax+2048]*/
  271. "movq 4096(%3, "#index"), %%mm4nt" /* uvbuf1[eax+2048]*/
  272. "psubw %%mm3, %%mm2 nt" /* uvbuf0[eax] - uvbuf1[eax]*/
  273. "psubw %%mm4, %%mm5 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/
  274. "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0nt"
  275. "pmulhw %%mm0, %%mm2 nt" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/
  276. "pmulhw %%mm0, %%mm5 nt" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/
  277. "psraw $4, %%mm3 nt" /* uvbuf0[eax] - uvbuf1[eax] >>4*/
  278. "psraw $4, %%mm4 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/
  279. "paddw %%mm2, %%mm3 nt" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/
  280. "paddw %%mm5, %%mm4 nt" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/
  281. "psubw "U_OFFSET"("#c"), %%mm3 nt" /* (U-128)8*/
  282. "psubw "V_OFFSET"("#c"), %%mm4 nt" /* (V-128)8*/
  283. "movq %%mm3, %%mm2 nt" /* (U-128)8*/
  284. "movq %%mm4, %%mm5 nt" /* (V-128)8*/
  285. "pmulhw "UG_COEFF"("#c"), %%mm3nt"
  286. "pmulhw "VG_COEFF"("#c"), %%mm4nt"
  287. /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */
  288. "movq (%0, "#index", 2), %%mm0 nt" /*buf0[eax]*/
  289. "movq (%1, "#index", 2), %%mm1 nt" /*buf1[eax]*/
  290. "movq 8(%0, "#index", 2), %%mm6nt" /*buf0[eax]*/
  291. "movq 8(%1, "#index", 2), %%mm7nt" /*buf1[eax]*/
  292. "psubw %%mm1, %%mm0 nt" /* buf0[eax] - buf1[eax]*/
  293. "psubw %%mm7, %%mm6 nt" /* buf0[eax] - buf1[eax]*/
  294. "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm0nt" /* (buf0[eax] - buf1[eax])yalpha1>>16*/
  295. "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm6nt" /* (buf0[eax] - buf1[eax])yalpha1>>16*/
  296. "psraw $4, %%mm1 nt" /* buf0[eax] - buf1[eax] >>4*/
  297. "psraw $4, %%mm7 nt" /* buf0[eax] - buf1[eax] >>4*/
  298. "paddw %%mm0, %%mm1 nt" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/
  299. "paddw %%mm6, %%mm7 nt" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/
  300. "pmulhw "UB_COEFF"("#c"), %%mm2nt"
  301. "pmulhw "VR_COEFF"("#c"), %%mm5nt"
  302. "psubw "Y_OFFSET"("#c"), %%mm1 nt" /* 8(Y-16)*/
  303. "psubw "Y_OFFSET"("#c"), %%mm7 nt" /* 8(Y-16)*/
  304. "pmulhw "Y_COEFF"("#c"), %%mm1 nt"
  305. "pmulhw "Y_COEFF"("#c"), %%mm7 nt"
  306. /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */
  307. "paddw %%mm3, %%mm4 nt"
  308. "movq %%mm2, %%mm0 nt"
  309. "movq %%mm5, %%mm6 nt"
  310. "movq %%mm4, %%mm3 nt"
  311. "punpcklwd %%mm2, %%mm2 nt"
  312. "punpcklwd %%mm5, %%mm5 nt"
  313. "punpcklwd %%mm4, %%mm4 nt"
  314. "paddw %%mm1, %%mm2 nt"
  315. "paddw %%mm1, %%mm5 nt"
  316. "paddw %%mm1, %%mm4 nt"
  317. "punpckhwd %%mm0, %%mm0 nt"
  318. "punpckhwd %%mm6, %%mm6 nt"
  319. "punpckhwd %%mm3, %%mm3 nt"
  320. "paddw %%mm7, %%mm0 nt"
  321. "paddw %%mm7, %%mm6 nt"
  322. "paddw %%mm7, %%mm3 nt"
  323. /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */
  324. "packuswb %%mm0, %%mm2 nt"
  325. "packuswb %%mm6, %%mm5 nt"
  326. "packuswb %%mm3, %%mm4 nt"
  327. "pxor %%mm7, %%mm7 nt"
  328.                 
  329. #define YSCALEYUV2PACKED1(index, c) 
  330. "xorl "#index", "#index" nt"
  331. ".balign 16 nt"
  332. "1: nt"
  333. "movq (%2, "#index"), %%mm3 nt" /* uvbuf0[eax]*/
  334. "movq 4096(%2, "#index"), %%mm4 nt" /* uvbuf0[eax+2048]*/
  335. "psraw $7, %%mm3 nt" 
  336. "psraw $7, %%mm4 nt" 
  337. "movq (%0, "#index", 2), %%mm1 nt" /*buf0[eax]*/
  338. "movq 8(%0, "#index", 2), %%mm7 nt" /*buf0[eax]*/
  339. "psraw $7, %%mm1 nt" 
  340. "psraw $7, %%mm7 nt" 
  341.                 
  342. #define YSCALEYUV2RGB1(index, c) 
  343. "xorl "#index", "#index" nt"
  344. ".balign 16 nt"
  345. "1: nt"
  346. "movq (%2, "#index"), %%mm3 nt" /* uvbuf0[eax]*/
  347. "movq 4096(%2, "#index"), %%mm4 nt" /* uvbuf0[eax+2048]*/
  348. "psraw $4, %%mm3 nt" /* uvbuf0[eax] - uvbuf1[eax] >>4*/
  349. "psraw $4, %%mm4 nt" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/
  350. "psubw "U_OFFSET"("#c"), %%mm3 nt" /* (U-128)8*/
  351. "psubw "V_OFFSET"("#c"), %%mm4 nt" /* (V-128)8*/
  352. "movq %%mm3, %%mm2 nt" /* (U-128)8*/
  353. "movq %%mm4, %%mm5 nt" /* (V-128)8*/
  354. "pmulhw "UG_COEFF"("#c"), %%mm3nt"
  355. "pmulhw "VG_COEFF"("#c"), %%mm4nt"
  356. /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */
  357. "movq (%0, "#index", 2), %%mm1 nt" /*buf0[eax]*/
  358. "movq 8(%0, "#index", 2), %%mm7 nt" /*buf0[eax]*/
  359. "psraw $4, %%mm1 nt" /* buf0[eax] - buf1[eax] >>4*/
  360. "psraw $4, %%mm7 nt" /* buf0[eax] - buf1[eax] >>4*/
  361. "pmulhw "UB_COEFF"("#c"), %%mm2nt"
  362. "pmulhw "VR_COEFF"("#c"), %%mm5nt"
  363. "psubw "Y_OFFSET"("#c"), %%mm1 nt" /* 8(Y-16)*/
  364. "psubw "Y_OFFSET"("#c"), %%mm7 nt" /* 8(Y-16)*/
  365. "pmulhw "Y_COEFF"("#c"), %%mm1 nt"
  366. "pmulhw "Y_COEFF"("#c"), %%mm7 nt"
  367. /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */
  368. "paddw %%mm3, %%mm4 nt"
  369. "movq %%mm2, %%mm0 nt"
  370. "movq %%mm5, %%mm6 nt"
  371. "movq %%mm4, %%mm3 nt"
  372. "punpcklwd %%mm2, %%mm2 nt"
  373. "punpcklwd %%mm5, %%mm5 nt"
  374. "punpcklwd %%mm4, %%mm4 nt"
  375. "paddw %%mm1, %%mm2 nt"
  376. "paddw %%mm1, %%mm5 nt"
  377. "paddw %%mm1, %%mm4 nt"
  378. "punpckhwd %%mm0, %%mm0 nt"
  379. "punpckhwd %%mm6, %%mm6 nt"
  380. "punpckhwd %%mm3, %%mm3 nt"
  381. "paddw %%mm7, %%mm0 nt"
  382. "paddw %%mm7, %%mm6 nt"
  383. "paddw %%mm7, %%mm3 nt"
  384. /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */
  385. "packuswb %%mm0, %%mm2 nt"
  386. "packuswb %%mm6, %%mm5 nt"
  387. "packuswb %%mm3, %%mm4 nt"
  388. "pxor %%mm7, %%mm7 nt"
  389. #define YSCALEYUV2PACKED1b(index, c) 
  390. "xorl "#index", "#index" nt"
  391. ".balign 16 nt"
  392. "1: nt"
  393. "movq (%2, "#index"), %%mm2 nt" /* uvbuf0[eax]*/
  394. "movq (%3, "#index"), %%mm3 nt" /* uvbuf1[eax]*/
  395. "movq 4096(%2, "#index"), %%mm5 nt" /* uvbuf0[eax+2048]*/
  396. "movq 4096(%3, "#index"), %%mm4 nt" /* uvbuf1[eax+2048]*/
  397. "paddw %%mm2, %%mm3 nt" /* uvbuf0[eax] + uvbuf1[eax]*/
  398. "paddw %%mm5, %%mm4 nt" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/
  399. "psrlw $8, %%mm3 nt" 
  400. "psrlw $8, %%mm4 nt" 
  401. "movq (%0, "#index", 2), %%mm1 nt" /*buf0[eax]*/
  402. "movq 8(%0, "#index", 2), %%mm7 nt" /*buf0[eax]*/
  403. "psraw $7, %%mm1 nt" 
  404. "psraw $7, %%mm7 nt" 
  405.                 
  406. // do vertical chrominance interpolation
  407. #define YSCALEYUV2RGB1b(index, c) 
  408. "xorl "#index", "#index" nt"
  409. ".balign 16 nt"
  410. "1: nt"
  411. "movq (%2, "#index"), %%mm2 nt" /* uvbuf0[eax]*/
  412. "movq (%3, "#index"), %%mm3 nt" /* uvbuf1[eax]*/
  413. "movq 4096(%2, "#index"), %%mm5 nt" /* uvbuf0[eax+2048]*/
  414. "movq 4096(%3, "#index"), %%mm4 nt" /* uvbuf1[eax+2048]*/
  415. "paddw %%mm2, %%mm3 nt" /* uvbuf0[eax] + uvbuf1[eax]*/
  416. "paddw %%mm5, %%mm4 nt" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/
  417. "psrlw $5, %%mm3 nt" /*FIXME might overflow*/
  418. "psrlw $5, %%mm4 nt" /*FIXME might overflow*/
  419. "psubw "U_OFFSET"("#c"), %%mm3 nt" /* (U-128)8*/
  420. "psubw "V_OFFSET"("#c"), %%mm4 nt" /* (V-128)8*/
  421. "movq %%mm3, %%mm2 nt" /* (U-128)8*/
  422. "movq %%mm4, %%mm5 nt" /* (V-128)8*/
  423. "pmulhw "UG_COEFF"("#c"), %%mm3nt"
  424. "pmulhw "VG_COEFF"("#c"), %%mm4nt"
  425. /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */
  426. "movq (%0, "#index", 2), %%mm1 nt" /*buf0[eax]*/
  427. "movq 8(%0, "#index", 2), %%mm7 nt" /*buf0[eax]*/
  428. "psraw $4, %%mm1 nt" /* buf0[eax] - buf1[eax] >>4*/
  429. "psraw $4, %%mm7 nt" /* buf0[eax] - buf1[eax] >>4*/
  430. "pmulhw "UB_COEFF"("#c"), %%mm2nt"
  431. "pmulhw "VR_COEFF"("#c"), %%mm5nt"
  432. "psubw "Y_OFFSET"("#c"), %%mm1 nt" /* 8(Y-16)*/
  433. "psubw "Y_OFFSET"("#c"), %%mm7 nt" /* 8(Y-16)*/
  434. "pmulhw "Y_COEFF"("#c"), %%mm1 nt"
  435. "pmulhw "Y_COEFF"("#c"), %%mm7 nt"
  436. /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */
  437. "paddw %%mm3, %%mm4 nt"
  438. "movq %%mm2, %%mm0 nt"
  439. "movq %%mm5, %%mm6 nt"
  440. "movq %%mm4, %%mm3 nt"
  441. "punpcklwd %%mm2, %%mm2 nt"
  442. "punpcklwd %%mm5, %%mm5 nt"
  443. "punpcklwd %%mm4, %%mm4 nt"
  444. "paddw %%mm1, %%mm2 nt"
  445. "paddw %%mm1, %%mm5 nt"
  446. "paddw %%mm1, %%mm4 nt"
  447. "punpckhwd %%mm0, %%mm0 nt"
  448. "punpckhwd %%mm6, %%mm6 nt"
  449. "punpckhwd %%mm3, %%mm3 nt"
  450. "paddw %%mm7, %%mm0 nt"
  451. "paddw %%mm7, %%mm6 nt"
  452. "paddw %%mm7, %%mm3 nt"
  453. /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */
  454. "packuswb %%mm0, %%mm2 nt"
  455. "packuswb %%mm6, %%mm5 nt"
  456. "packuswb %%mm3, %%mm4 nt"
  457. "pxor %%mm7, %%mm7 nt"
  458. #define WRITEBGR32(dst, dstw, index) 
  459. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  460. "movq %%mm2, %%mm1 nt" /* B */
  461. "movq %%mm5, %%mm6 nt" /* R */
  462. "punpcklbw %%mm4, %%mm2 nt" /* GBGBGBGB 0 */
  463. "punpcklbw %%mm7, %%mm5 nt" /* 0R0R0R0R 0 */
  464. "punpckhbw %%mm4, %%mm1 nt" /* GBGBGBGB 2 */
  465. "punpckhbw %%mm7, %%mm6 nt" /* 0R0R0R0R 2 */
  466. "movq %%mm2, %%mm0 nt" /* GBGBGBGB 0 */
  467. "movq %%mm1, %%mm3 nt" /* GBGBGBGB 2 */
  468. "punpcklwd %%mm5, %%mm0 nt" /* 0RGB0RGB 0 */
  469. "punpckhwd %%mm5, %%mm2 nt" /* 0RGB0RGB 1 */
  470. "punpcklwd %%mm6, %%mm1 nt" /* 0RGB0RGB 2 */
  471. "punpckhwd %%mm6, %%mm3 nt" /* 0RGB0RGB 3 */
  472. MOVNTQ(%%mm0, (dst, index, 4))
  473. MOVNTQ(%%mm2, 8(dst, index, 4))
  474. MOVNTQ(%%mm1, 16(dst, index, 4))
  475. MOVNTQ(%%mm3, 24(dst, index, 4))
  476. "addl $8, "#index" nt"
  477. "cmpl "#dstw", "#index" nt"
  478. " jb 1b nt"
  479. #define WRITEBGR16(dst, dstw, index) 
  480. "pand "MANGLE(bF8)", %%mm2 nt" /* B */
  481. "pand "MANGLE(bFC)", %%mm4 nt" /* G */
  482. "pand "MANGLE(bF8)", %%mm5 nt" /* R */
  483. "psrlq $3, %%mm2 nt"
  484. "movq %%mm2, %%mm1 nt"
  485. "movq %%mm4, %%mm3 nt"
  486. "punpcklbw %%mm7, %%mm3 nt"
  487. "punpcklbw %%mm5, %%mm2 nt"
  488. "punpckhbw %%mm7, %%mm4 nt"
  489. "punpckhbw %%mm5, %%mm1 nt"
  490. "psllq $3, %%mm3 nt"
  491. "psllq $3, %%mm4 nt"
  492. "por %%mm3, %%mm2 nt"
  493. "por %%mm4, %%mm1 nt"
  494. MOVNTQ(%%mm2, (dst, index, 2))
  495. MOVNTQ(%%mm1, 8(dst, index, 2))
  496. "addl $8, "#index" nt"
  497. "cmpl "#dstw", "#index" nt"
  498. " jb 1b nt"
  499. #define WRITEBGR15(dst, dstw, index) 
  500. "pand "MANGLE(bF8)", %%mm2 nt" /* B */
  501. "pand "MANGLE(bF8)", %%mm4 nt" /* G */
  502. "pand "MANGLE(bF8)", %%mm5 nt" /* R */
  503. "psrlq $3, %%mm2 nt"
  504. "psrlq $1, %%mm5 nt"
  505. "movq %%mm2, %%mm1 nt"
  506. "movq %%mm4, %%mm3 nt"
  507. "punpcklbw %%mm7, %%mm3 nt"
  508. "punpcklbw %%mm5, %%mm2 nt"
  509. "punpckhbw %%mm7, %%mm4 nt"
  510. "punpckhbw %%mm5, %%mm1 nt"
  511. "psllq $2, %%mm3 nt"
  512. "psllq $2, %%mm4 nt"
  513. "por %%mm3, %%mm2 nt"
  514. "por %%mm4, %%mm1 nt"
  515. MOVNTQ(%%mm2, (dst, index, 2))
  516. MOVNTQ(%%mm1, 8(dst, index, 2))
  517. "addl $8, "#index" nt"
  518. "cmpl "#dstw", "#index" nt"
  519. " jb 1b nt"
  520. #define WRITEBGR24OLD(dst, dstw, index) 
  521. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  522. "movq %%mm2, %%mm1 nt" /* B */
  523. "movq %%mm5, %%mm6 nt" /* R */
  524. "punpcklbw %%mm4, %%mm2 nt" /* GBGBGBGB 0 */
  525. "punpcklbw %%mm7, %%mm5 nt" /* 0R0R0R0R 0 */
  526. "punpckhbw %%mm4, %%mm1 nt" /* GBGBGBGB 2 */
  527. "punpckhbw %%mm7, %%mm6 nt" /* 0R0R0R0R 2 */
  528. "movq %%mm2, %%mm0 nt" /* GBGBGBGB 0 */
  529. "movq %%mm1, %%mm3 nt" /* GBGBGBGB 2 */
  530. "punpcklwd %%mm5, %%mm0 nt" /* 0RGB0RGB 0 */
  531. "punpckhwd %%mm5, %%mm2 nt" /* 0RGB0RGB 1 */
  532. "punpcklwd %%mm6, %%mm1 nt" /* 0RGB0RGB 2 */
  533. "punpckhwd %%mm6, %%mm3 nt" /* 0RGB0RGB 3 */
  534. "movq %%mm0, %%mm4 nt" /* 0RGB0RGB 0 */
  535. "psrlq $8, %%mm0 nt" /* 00RGB0RG 0 */
  536. "pand "MANGLE(bm00000111)", %%mm4nt" /* 00000RGB 0 */
  537. "pand "MANGLE(bm11111000)", %%mm0nt" /* 00RGB000 0.5 */
  538. "por %%mm4, %%mm0 nt" /* 00RGBRGB 0 */
  539. "movq %%mm2, %%mm4 nt" /* 0RGB0RGB 1 */
  540. "psllq $48, %%mm2 nt" /* GB000000 1 */
  541. "por %%mm2, %%mm0 nt" /* GBRGBRGB 0 */
  542. "movq %%mm4, %%mm2 nt" /* 0RGB0RGB 1 */
  543. "psrld $16, %%mm4 nt" /* 000R000R 1 */
  544. "psrlq $24, %%mm2 nt" /* 0000RGB0 1.5 */
  545. "por %%mm4, %%mm2 nt" /* 000RRGBR 1 */
  546. "pand "MANGLE(bm00001111)", %%mm2nt" /* 0000RGBR 1 */
  547. "movq %%mm1, %%mm4 nt" /* 0RGB0RGB 2 */
  548. "psrlq $8, %%mm1 nt" /* 00RGB0RG 2 */
  549. "pand "MANGLE(bm00000111)", %%mm4nt" /* 00000RGB 2 */
  550. "pand "MANGLE(bm11111000)", %%mm1nt" /* 00RGB000 2.5 */
  551. "por %%mm4, %%mm1 nt" /* 00RGBRGB 2 */
  552. "movq %%mm1, %%mm4 nt" /* 00RGBRGB 2 */
  553. "psllq $32, %%mm1 nt" /* BRGB0000 2 */
  554. "por %%mm1, %%mm2 nt" /* BRGBRGBR 1 */
  555. "psrlq $32, %%mm4 nt" /* 000000RG 2.5 */
  556. "movq %%mm3, %%mm5 nt" /* 0RGB0RGB 3 */
  557. "psrlq $8, %%mm3 nt" /* 00RGB0RG 3 */
  558. "pand "MANGLE(bm00000111)", %%mm5nt" /* 00000RGB 3 */
  559. "pand "MANGLE(bm11111000)", %%mm3nt" /* 00RGB000 3.5 */
  560. "por %%mm5, %%mm3 nt" /* 00RGBRGB 3 */
  561. "psllq $16, %%mm3 nt" /* RGBRGB00 3 */
  562. "por %%mm4, %%mm3 nt" /* RGBRGBRG 2.5 */
  563. MOVNTQ(%%mm0, (dst))
  564. MOVNTQ(%%mm2, 8(dst))
  565. MOVNTQ(%%mm3, 16(dst))
  566. "addl $24, "#dst" nt"
  567. "addl $8, "#index" nt"
  568. "cmpl "#dstw", "#index" nt"
  569. " jb 1b nt"
  570. #define WRITEBGR24MMX(dst, dstw, index) 
  571. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  572. "movq %%mm2, %%mm1 nt" /* B */
  573. "movq %%mm5, %%mm6 nt" /* R */
  574. "punpcklbw %%mm4, %%mm2 nt" /* GBGBGBGB 0 */
  575. "punpcklbw %%mm7, %%mm5 nt" /* 0R0R0R0R 0 */
  576. "punpckhbw %%mm4, %%mm1 nt" /* GBGBGBGB 2 */
  577. "punpckhbw %%mm7, %%mm6 nt" /* 0R0R0R0R 2 */
  578. "movq %%mm2, %%mm0 nt" /* GBGBGBGB 0 */
  579. "movq %%mm1, %%mm3 nt" /* GBGBGBGB 2 */
  580. "punpcklwd %%mm5, %%mm0 nt" /* 0RGB0RGB 0 */
  581. "punpckhwd %%mm5, %%mm2 nt" /* 0RGB0RGB 1 */
  582. "punpcklwd %%mm6, %%mm1 nt" /* 0RGB0RGB 2 */
  583. "punpckhwd %%mm6, %%mm3 nt" /* 0RGB0RGB 3 */
  584. "movq %%mm0, %%mm4 nt" /* 0RGB0RGB 0 */
  585. "movq %%mm2, %%mm6 nt" /* 0RGB0RGB 1 */
  586. "movq %%mm1, %%mm5 nt" /* 0RGB0RGB 2 */
  587. "movq %%mm3, %%mm7 nt" /* 0RGB0RGB 3 */
  588. "psllq $40, %%mm0 nt" /* RGB00000 0 */
  589. "psllq $40, %%mm2 nt" /* RGB00000 1 */
  590. "psllq $40, %%mm1 nt" /* RGB00000 2 */
  591. "psllq $40, %%mm3 nt" /* RGB00000 3 */
  592. "punpckhdq %%mm4, %%mm0 nt" /* 0RGBRGB0 0 */
  593. "punpckhdq %%mm6, %%mm2 nt" /* 0RGBRGB0 1 */
  594. "punpckhdq %%mm5, %%mm1 nt" /* 0RGBRGB0 2 */
  595. "punpckhdq %%mm7, %%mm3 nt" /* 0RGBRGB0 3 */
  596. "psrlq $8, %%mm0 nt" /* 00RGBRGB 0 */
  597. "movq %%mm2, %%mm6 nt" /* 0RGBRGB0 1 */
  598. "psllq $40, %%mm2 nt" /* GB000000 1 */
  599. "por %%mm2, %%mm0 nt" /* GBRGBRGB 0 */
  600. MOVNTQ(%%mm0, (dst))
  601. "psrlq $24, %%mm6 nt" /* 0000RGBR 1 */
  602. "movq %%mm1, %%mm5 nt" /* 0RGBRGB0 2 */
  603. "psllq $24, %%mm1 nt" /* BRGB0000 2 */
  604. "por %%mm1, %%mm6 nt" /* BRGBRGBR 1 */
  605. MOVNTQ(%%mm6, 8(dst))
  606. "psrlq $40, %%mm5 nt" /* 000000RG 2 */
  607. "psllq $8, %%mm3 nt" /* RGBRGB00 3 */
  608. "por %%mm3, %%mm5 nt" /* RGBRGBRG 2 */
  609. MOVNTQ(%%mm5, 16(dst))
  610. "addl $24, "#dst" nt"
  611. "addl $8, "#index" nt"
  612. "cmpl "#dstw", "#index" nt"
  613. " jb 1b nt"
  614. #define WRITEBGR24MMX2(dst, dstw, index) 
  615. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  616. "movq "MANGLE(M24A)", %%mm0 nt"
  617. "movq "MANGLE(M24C)", %%mm7 nt"
  618. "pshufw $0x50, %%mm2, %%mm1 nt" /* B3 B2 B3 B2  B1 B0 B1 B0 */
  619. "pshufw $0x50, %%mm4, %%mm3 nt" /* G3 G2 G3 G2  G1 G0 G1 G0 */
  620. "pshufw $0x00, %%mm5, %%mm6 nt" /* R1 R0 R1 R0  R1 R0 R1 R0 */
  621. "pand %%mm0, %%mm1 nt" /*    B2        B1       B0 */
  622. "pand %%mm0, %%mm3 nt" /*    G2        G1       G0 */
  623. "pand %%mm7, %%mm6 nt" /*       R1        R0       */
  624. "psllq $8, %%mm3 nt" /* G2        G1       G0    */
  625. "por %%mm1, %%mm6 nt"
  626. "por %%mm3, %%mm6 nt"
  627. MOVNTQ(%%mm6, (dst))
  628. "psrlq $8, %%mm4 nt" /* 00 G7 G6 G5  G4 G3 G2 G1 */
  629. "pshufw $0xA5, %%mm2, %%mm1 nt" /* B5 B4 B5 B4  B3 B2 B3 B2 */
  630. "pshufw $0x55, %%mm4, %%mm3 nt" /* G4 G3 G4 G3  G4 G3 G4 G3 */
  631. "pshufw $0xA5, %%mm5, %%mm6 nt" /* R5 R4 R5 R4  R3 R2 R3 R2 */
  632. "pand "MANGLE(M24B)", %%mm1 nt" /* B5       B4        B3    */
  633. "pand %%mm7, %%mm3 nt" /*       G4        G3       */
  634. "pand %%mm0, %%mm6 nt" /*    R4        R3       R2 */
  635. "por %%mm1, %%mm3 nt" /* B5    G4 B4     G3 B3    */
  636. "por %%mm3, %%mm6 nt"
  637. MOVNTQ(%%mm6, 8(dst))
  638. "pshufw $0xFF, %%mm2, %%mm1 nt" /* B7 B6 B7 B6  B7 B6 B6 B7 */
  639. "pshufw $0xFA, %%mm4, %%mm3 nt" /* 00 G7 00 G7  G6 G5 G6 G5 */
  640. "pshufw $0xFA, %%mm5, %%mm6 nt" /* R7 R6 R7 R6  R5 R4 R5 R4 */
  641. "pand %%mm7, %%mm1 nt" /*       B7        B6       */
  642. "pand %%mm0, %%mm3 nt" /*    G7        G6       G5 */
  643. "pand "MANGLE(M24B)", %%mm6 nt" /* R7       R6        R5    */
  644. "por %%mm1, %%mm3 nt"
  645. "por %%mm3, %%mm6 nt"
  646. MOVNTQ(%%mm6, 16(dst))
  647. "addl $24, "#dst" nt"
  648. "addl $8, "#index" nt"
  649. "cmpl "#dstw", "#index" nt"
  650. " jb 1b nt"
  651. #ifdef HAVE_MMX2
  652. #undef WRITEBGR24
  653. #define WRITEBGR24 WRITEBGR24MMX2
  654. #else
  655. #undef WRITEBGR24
  656. #define WRITEBGR24 WRITEBGR24MMX
  657. #endif
  658. #define WRITEYUY2(dst, dstw, index) 
  659. "packuswb %%mm3, %%mm3 nt"
  660. "packuswb %%mm4, %%mm4 nt"
  661. "packuswb %%mm7, %%mm1 nt"
  662. "punpcklbw %%mm4, %%mm3 nt"
  663. "movq %%mm1, %%mm7 nt"
  664. "punpcklbw %%mm3, %%mm1 nt"
  665. "punpckhbw %%mm3, %%mm7 nt"
  666. MOVNTQ(%%mm1, (dst, index, 2))
  667. MOVNTQ(%%mm7, 8(dst, index, 2))
  668. "addl $8, "#index" nt"
  669. "cmpl "#dstw", "#index" nt"
  670. " jb 1b nt"
  671. static inline void RENAME(yuv2yuvX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
  672.     int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
  673.     uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
  674. {
  675. #ifdef HAVE_MMX
  676. if(uDest != NULL)
  677. {
  678. asm volatile(
  679. YSCALEYUV2YV12X(0, CHR_MMX_FILTER_OFFSET)
  680. :: "r" (&c->redDither),
  681. "r" (uDest), "m" (chrDstW)
  682. : "%eax", "%edx", "%esi"
  683. );
  684. asm volatile(
  685. YSCALEYUV2YV12X(4096, CHR_MMX_FILTER_OFFSET)
  686. :: "r" (&c->redDither),
  687. "r" (vDest), "m" (chrDstW)
  688. : "%eax", "%edx", "%esi"
  689. );
  690. }
  691. asm volatile(
  692. YSCALEYUV2YV12X(0, LUM_MMX_FILTER_OFFSET)
  693. :: "r" (&c->redDither),
  694.    "r" (dest), "m" (dstW)
  695. : "%eax", "%edx", "%esi"
  696. );
  697. #else
  698. #ifdef HAVE_ALTIVEC
  699. yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,
  700.       chrFilter, chrSrc, chrFilterSize,
  701.       dest, uDest, vDest, dstW, chrDstW);
  702. #else //HAVE_ALTIVEC
  703. yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
  704.     chrFilter, chrSrc, chrFilterSize,
  705.     dest, uDest, vDest, dstW, chrDstW);
  706. #endif //!HAVE_ALTIVEC
  707. #endif
  708. }
  709. static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc,
  710.     uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
  711. {
  712. #ifdef HAVE_MMX
  713. if(uDest != NULL)
  714. {
  715. asm volatile(
  716. YSCALEYUV2YV121
  717. :: "r" (chrSrc + chrDstW), "r" (uDest + chrDstW),
  718. "g" (-chrDstW)
  719. : "%eax"
  720. );
  721. asm volatile(
  722. YSCALEYUV2YV121
  723. :: "r" (chrSrc + 2048 + chrDstW), "r" (vDest + chrDstW),
  724. "g" (-chrDstW)
  725. : "%eax"
  726. );
  727. }
  728. asm volatile(
  729. YSCALEYUV2YV121
  730. :: "r" (lumSrc + dstW), "r" (dest + dstW),
  731. "g" (-dstW)
  732. : "%eax"
  733. );
  734. #else
  735. int i;
  736. for(i=0; i<dstW; i++)
  737. {
  738. int val= lumSrc[i]>>7;
  739. if(val&256){
  740. if(val<0) val=0;
  741. else      val=255;
  742. }
  743. dest[i]= val;
  744. }
  745. if(uDest != NULL)
  746. for(i=0; i<chrDstW; i++)
  747. {
  748. int u=chrSrc[i]>>7;
  749. int v=chrSrc[i + 2048]>>7;
  750. if((u|v)&256){
  751. if(u<0)         u=0;
  752. else if (u>255) u=255;
  753. if(v<0)         v=0;
  754. else if (v>255) v=255;
  755. }
  756. uDest[i]= u;
  757. vDest[i]= v;
  758. }
  759. #endif
  760. }
  761. /**
  762.  * vertical scale YV12 to RGB
  763.  */
  764. static inline void RENAME(yuv2packedX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
  765.     int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
  766.     uint8_t *dest, int dstW, int dstY)
  767. {
  768. int dummy=0;
  769. switch(c->dstFormat)
  770. {
  771. #ifdef HAVE_MMX
  772. case IMGFMT_BGR32:
  773. {
  774. asm volatile(
  775. YSCALEYUV2RGBX
  776. WRITEBGR32(%4, %5, %%eax)
  777. :: "r" (&c->redDither), 
  778.    "m" (dummy), "m" (dummy), "m" (dummy),
  779.    "r" (dest), "m" (dstW)
  780. : "%eax", "%edx", "%esi"
  781. );
  782. }
  783. break;
  784. case IMGFMT_BGR24:
  785. {
  786. asm volatile(
  787. YSCALEYUV2RGBX
  788. "leal (%%eax, %%eax, 2), %%ebx nt" //FIXME optimize
  789. "addl %4, %%ebx nt"
  790. WRITEBGR24(%%ebx, %5, %%eax)
  791. :: "r" (&c->redDither), 
  792.    "m" (dummy), "m" (dummy), "m" (dummy),
  793.    "r" (dest), "m" (dstW)
  794. : "%eax", "%ebx", "%edx", "%esi" //FIXME ebx
  795. );
  796. }
  797. break;
  798. case IMGFMT_BGR15:
  799. {
  800. asm volatile(
  801. YSCALEYUV2RGBX
  802. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  803. #ifdef DITHER1XBPP
  804. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  805. "paddusb "MANGLE(g5Dither)", %%mm4nt"
  806. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  807. #endif
  808. WRITEBGR15(%4, %5, %%eax)
  809. :: "r" (&c->redDither), 
  810.    "m" (dummy), "m" (dummy), "m" (dummy),
  811.    "r" (dest), "m" (dstW)
  812. : "%eax", "%edx", "%esi"
  813. );
  814. }
  815. break;
  816. case IMGFMT_BGR16:
  817. {
  818. asm volatile(
  819. YSCALEYUV2RGBX
  820. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  821. #ifdef DITHER1XBPP
  822. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  823. "paddusb "MANGLE(g6Dither)", %%mm4nt"
  824. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  825. #endif
  826. WRITEBGR16(%4, %5, %%eax)
  827. :: "r" (&c->redDither), 
  828.    "m" (dummy), "m" (dummy), "m" (dummy),
  829.    "r" (dest), "m" (dstW)
  830. : "%eax", "%edx", "%esi"
  831. );
  832. }
  833. break;
  834. case IMGFMT_YUY2:
  835. {
  836. asm volatile(
  837. YSCALEYUV2PACKEDX
  838. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  839. "psraw $3, %%mm3 nt"
  840. "psraw $3, %%mm4 nt"
  841. "psraw $3, %%mm1 nt"
  842. "psraw $3, %%mm7 nt"
  843. WRITEYUY2(%4, %5, %%eax)
  844. :: "r" (&c->redDither), 
  845.    "m" (dummy), "m" (dummy), "m" (dummy),
  846.    "r" (dest), "m" (dstW)
  847. : "%eax", "%edx", "%esi"
  848. );
  849. }
  850. break;
  851. #endif
  852. default:
  853. #ifdef HAVE_ALTIVEC
  854. altivec_yuv2packedX (c, lumFilter, lumSrc, lumFilterSize,
  855.     chrFilter, chrSrc, chrFilterSize,
  856.     dest, dstW, dstY);
  857. #else
  858. yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,
  859.     chrFilter, chrSrc, chrFilterSize,
  860.     dest, dstW, dstY);
  861. #endif
  862. break;
  863. }
  864. }
  865. /**
  866.  * vertical bilinear scale YV12 to RGB
  867.  */
  868. static inline void RENAME(yuv2packed2)(SwsContext *c, uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1,
  869.     uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
  870. {
  871. int yalpha1=yalpha^4095;
  872. int uvalpha1=uvalpha^4095;
  873. int i;
  874. #if 0 //isn't used
  875. if(flags&SWS_FULL_CHR_H_INT)
  876. {
  877. switch(dstFormat)
  878. {
  879. #ifdef HAVE_MMX
  880. case IMGFMT_BGR32:
  881. asm volatile(
  882. FULL_YSCALEYUV2RGB
  883. "punpcklbw %%mm1, %%mm3 nt" // BGBGBGBG
  884. "punpcklbw %%mm7, %%mm0 nt" // R0R0R0R0
  885. "movq %%mm3, %%mm1 nt"
  886. "punpcklwd %%mm0, %%mm3 nt" // BGR0BGR0
  887. "punpckhwd %%mm0, %%mm1 nt" // BGR0BGR0
  888. MOVNTQ(%%mm3, (%4, %%eax, 4))
  889. MOVNTQ(%%mm1, 8(%4, %%eax, 4))
  890. "addl $4, %%eax nt"
  891. "cmpl %5, %%eax nt"
  892. " jb 1b nt"
  893. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),
  894. "m" (yalpha1), "m" (uvalpha1)
  895. : "%eax"
  896. );
  897. break;
  898. case IMGFMT_BGR24:
  899. asm volatile(
  900. FULL_YSCALEYUV2RGB
  901. // lsb ... msb
  902. "punpcklbw %%mm1, %%mm3 nt" // BGBGBGBG
  903. "punpcklbw %%mm7, %%mm0 nt" // R0R0R0R0
  904. "movq %%mm3, %%mm1 nt"
  905. "punpcklwd %%mm0, %%mm3 nt" // BGR0BGR0
  906. "punpckhwd %%mm0, %%mm1 nt" // BGR0BGR0
  907. "movq %%mm3, %%mm2 nt" // BGR0BGR0
  908. "psrlq $8, %%mm3 nt" // GR0BGR00
  909. "pand "MANGLE(bm00000111)", %%mm2nt" // BGR00000
  910. "pand "MANGLE(bm11111000)", %%mm3nt" // 000BGR00
  911. "por %%mm2, %%mm3 nt" // BGRBGR00
  912. "movq %%mm1, %%mm2 nt"
  913. "psllq $48, %%mm1 nt" // 000000BG
  914. "por %%mm1, %%mm3 nt" // BGRBGRBG
  915. "movq %%mm2, %%mm1 nt" // BGR0BGR0
  916. "psrld $16, %%mm2 nt" // R000R000
  917. "psrlq $24, %%mm1 nt" // 0BGR0000
  918. "por %%mm2, %%mm1 nt" // RBGRR000
  919. "movl %4, %%ebx nt"
  920. "addl %%eax, %%ebx nt"
  921. #ifdef HAVE_MMX2
  922. //FIXME Alignment
  923. "movntq %%mm3, (%%ebx, %%eax, 2)nt"
  924. "movntq %%mm1, 8(%%ebx, %%eax, 2)nt"
  925. #else
  926. "movd %%mm3, (%%ebx, %%eax, 2) nt"
  927. "psrlq $32, %%mm3 nt"
  928. "movd %%mm3, 4(%%ebx, %%eax, 2) nt"
  929. "movd %%mm1, 8(%%ebx, %%eax, 2) nt"
  930. #endif
  931. "addl $4, %%eax nt"
  932. "cmpl %5, %%eax nt"
  933. " jb 1b nt"
  934. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest), "m" (dstW),
  935. "m" (yalpha1), "m" (uvalpha1)
  936. : "%eax", "%ebx"
  937. );
  938. break;
  939. case IMGFMT_BGR15:
  940. asm volatile(
  941. FULL_YSCALEYUV2RGB
  942. #ifdef DITHER1XBPP
  943. "paddusb "MANGLE(g5Dither)", %%mm1nt"
  944. "paddusb "MANGLE(r5Dither)", %%mm0nt"
  945. "paddusb "MANGLE(b5Dither)", %%mm3nt"
  946. #endif
  947. "punpcklbw %%mm7, %%mm1 nt" // 0G0G0G0G
  948. "punpcklbw %%mm7, %%mm3 nt" // 0B0B0B0B
  949. "punpcklbw %%mm7, %%mm0 nt" // 0R0R0R0R
  950. "psrlw $3, %%mm3 nt"
  951. "psllw $2, %%mm1 nt"
  952. "psllw $7, %%mm0 nt"
  953. "pand "MANGLE(g15Mask)", %%mm1 nt"
  954. "pand "MANGLE(r15Mask)", %%mm0 nt"
  955. "por %%mm3, %%mm1 nt"
  956. "por %%mm1, %%mm0 nt"
  957. MOVNTQ(%%mm0, (%4, %%eax, 2))
  958. "addl $4, %%eax nt"
  959. "cmpl %5, %%eax nt"
  960. " jb 1b nt"
  961. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),
  962. "m" (yalpha1), "m" (uvalpha1)
  963. : "%eax"
  964. );
  965. break;
  966. case IMGFMT_BGR16:
  967. asm volatile(
  968. FULL_YSCALEYUV2RGB
  969. #ifdef DITHER1XBPP
  970. "paddusb "MANGLE(g6Dither)", %%mm1nt"
  971. "paddusb "MANGLE(r5Dither)", %%mm0nt"
  972. "paddusb "MANGLE(b5Dither)", %%mm3nt"
  973. #endif
  974. "punpcklbw %%mm7, %%mm1 nt" // 0G0G0G0G
  975. "punpcklbw %%mm7, %%mm3 nt" // 0B0B0B0B
  976. "punpcklbw %%mm7, %%mm0 nt" // 0R0R0R0R
  977. "psrlw $3, %%mm3 nt"
  978. "psllw $3, %%mm1 nt"
  979. "psllw $8, %%mm0 nt"
  980. "pand "MANGLE(g16Mask)", %%mm1 nt"
  981. "pand "MANGLE(r16Mask)", %%mm0 nt"
  982. "por %%mm3, %%mm1 nt"
  983. "por %%mm1, %%mm0 nt"
  984. MOVNTQ(%%mm0, (%4, %%eax, 2))
  985. "addl $4, %%eax nt"
  986. "cmpl %5, %%eax nt"
  987. " jb 1b nt"
  988. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),
  989. "m" (yalpha1), "m" (uvalpha1)
  990. : "%eax"
  991. );
  992. break;
  993. #endif
  994. case IMGFMT_RGB32:
  995. #ifndef HAVE_MMX
  996. case IMGFMT_BGR32:
  997. #endif
  998. if(dstFormat==IMGFMT_BGR32)
  999. {
  1000. int i;
  1001. #ifdef WORDS_BIGENDIAN
  1002. dest++;
  1003. #endif
  1004. for(i=0;i<dstW;i++){
  1005. // vertical linear interpolation && yuv2rgb in a single step:
  1006. int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
  1007. int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
  1008. int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
  1009. dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];
  1010. dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];
  1011. dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];
  1012. dest+= 4;
  1013. }
  1014. }
  1015. else if(dstFormat==IMGFMT_BGR24)
  1016. {
  1017. int i;
  1018. for(i=0;i<dstW;i++){
  1019. // vertical linear interpolation && yuv2rgb in a single step:
  1020. int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
  1021. int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
  1022. int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
  1023. dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];
  1024. dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];
  1025. dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];
  1026. dest+= 3;
  1027. }
  1028. }
  1029. else if(dstFormat==IMGFMT_BGR16)
  1030. {
  1031. int i;
  1032. for(i=0;i<dstW;i++){
  1033. // vertical linear interpolation && yuv2rgb in a single step:
  1034. int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
  1035. int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
  1036. int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
  1037. ((uint16_t*)dest)[i] =
  1038. clip_table16b[(Y + yuvtab_40cf[U]) >>13] |
  1039. clip_table16g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |
  1040. clip_table16r[(Y + yuvtab_3343[V]) >>13];
  1041. }
  1042. }
  1043. else if(dstFormat==IMGFMT_BGR15)
  1044. {
  1045. int i;
  1046. for(i=0;i<dstW;i++){
  1047. // vertical linear interpolation && yuv2rgb in a single step:
  1048. int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
  1049. int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
  1050. int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
  1051. ((uint16_t*)dest)[i] =
  1052. clip_table15b[(Y + yuvtab_40cf[U]) >>13] |
  1053. clip_table15g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |
  1054. clip_table15r[(Y + yuvtab_3343[V]) >>13];
  1055. }
  1056. }
  1057. }//FULL_UV_IPOL
  1058. else
  1059. {
  1060. #endif // if 0
  1061. #ifdef HAVE_MMX
  1062. switch(c->dstFormat)
  1063. {
  1064. //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
  1065. case IMGFMT_BGR32:
  1066. asm volatile(
  1067. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1068. "movl %4, %%esp nt"
  1069. YSCALEYUV2RGB(%%eax, %5)
  1070. WRITEBGR32(%%esp, 8280(%5), %%eax)
  1071. "movl "ESP_OFFSET"(%5), %%esp nt"
  1072. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1073. "r" (&c->redDither)
  1074. : "%eax"
  1075. );
  1076. return;
  1077. case IMGFMT_BGR24:
  1078. asm volatile(
  1079. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1080. "movl %4, %%esp nt"
  1081. YSCALEYUV2RGB(%%eax, %5)
  1082. WRITEBGR24(%%esp, 8280(%5), %%eax)
  1083. "movl "ESP_OFFSET"(%5), %%esp nt"
  1084. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1085. "r" (&c->redDither)
  1086. : "%eax"
  1087. );
  1088. return;
  1089. case IMGFMT_BGR15:
  1090. asm volatile(
  1091. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1092. "movl %4, %%esp nt"
  1093. YSCALEYUV2RGB(%%eax, %5)
  1094. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1095. #ifdef DITHER1XBPP
  1096. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1097. "paddusb "MANGLE(g5Dither)", %%mm4nt"
  1098. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1099. #endif
  1100. WRITEBGR15(%%esp, 8280(%5), %%eax)
  1101. "movl "ESP_OFFSET"(%5), %%esp nt"
  1102. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1103. "r" (&c->redDither)
  1104. : "%eax"
  1105. );
  1106. return;
  1107. case IMGFMT_BGR16:
  1108. asm volatile(
  1109. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1110. "movl %4, %%esp nt"
  1111. YSCALEYUV2RGB(%%eax, %5)
  1112. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1113. #ifdef DITHER1XBPP
  1114. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1115. "paddusb "MANGLE(g6Dither)", %%mm4nt"
  1116. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1117. #endif
  1118. WRITEBGR16(%%esp, 8280(%5), %%eax)
  1119. "movl "ESP_OFFSET"(%5), %%esp nt"
  1120. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1121. "r" (&c->redDither)
  1122. : "%eax"
  1123. );
  1124. return;
  1125. case IMGFMT_YUY2:
  1126. asm volatile(
  1127. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1128. "movl %4, %%esp nt"
  1129. YSCALEYUV2PACKED(%%eax, %5)
  1130. WRITEYUY2(%%esp, 8280(%5), %%eax)
  1131. "movl "ESP_OFFSET"(%5), %%esp nt"
  1132. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1133. "r" (&c->redDither)
  1134. : "%eax"
  1135. );
  1136. return;
  1137. default: break;
  1138. }
  1139. #endif //HAVE_MMX
  1140. YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C)
  1141. }
  1142. /**
  1143.  * YV12 to RGB without scaling or interpolating
  1144.  */
  1145. static inline void RENAME(yuv2packed1)(SwsContext *c, uint16_t *buf0, uint16_t *uvbuf0, uint16_t *uvbuf1,
  1146.     uint8_t *dest, int dstW, int uvalpha, int dstFormat, int flags, int y)
  1147. {
  1148. const int yalpha1=0;
  1149. int i;
  1150. uint16_t *buf1= buf0; //FIXME needed for the rgb1/bgr1
  1151. const int yalpha= 4096; //FIXME ...
  1152. if(flags&SWS_FULL_CHR_H_INT)
  1153. {
  1154. RENAME(yuv2packed2)(c, buf0, buf0, uvbuf0, uvbuf1, dest, dstW, 0, uvalpha, y);
  1155. return;
  1156. }
  1157. #ifdef HAVE_MMX
  1158. if( uvalpha < 2048 ) // note this is not correct (shifts chrominance by 0.5 pixels) but its a bit faster
  1159. {
  1160. switch(dstFormat)
  1161. {
  1162. case IMGFMT_BGR32:
  1163. asm volatile(
  1164. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1165. "movl %4, %%esp nt"
  1166. YSCALEYUV2RGB1(%%eax, %5)
  1167. WRITEBGR32(%%esp, 8280(%5), %%eax)
  1168. "movl "ESP_OFFSET"(%5), %%esp nt"
  1169. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1170. "r" (&c->redDither)
  1171. : "%eax"
  1172. );
  1173. return;
  1174. case IMGFMT_BGR24:
  1175. asm volatile(
  1176. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1177. "movl %4, %%esp nt"
  1178. YSCALEYUV2RGB1(%%eax, %5)
  1179. WRITEBGR24(%%esp, 8280(%5), %%eax)
  1180. "movl "ESP_OFFSET"(%5), %%esp nt"
  1181. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1182. "r" (&c->redDither)
  1183. : "%eax"
  1184. );
  1185. return;
  1186. case IMGFMT_BGR15:
  1187. asm volatile(
  1188. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1189. "movl %4, %%esp nt"
  1190. YSCALEYUV2RGB1(%%eax, %5)
  1191. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1192. #ifdef DITHER1XBPP
  1193. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1194. "paddusb "MANGLE(g5Dither)", %%mm4nt"
  1195. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1196. #endif
  1197. WRITEBGR15(%%esp, 8280(%5), %%eax)
  1198. "movl "ESP_OFFSET"(%5), %%esp nt"
  1199. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1200. "r" (&c->redDither)
  1201. : "%eax"
  1202. );
  1203. return;
  1204. case IMGFMT_BGR16:
  1205. asm volatile(
  1206. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1207. "movl %4, %%esp nt"
  1208. YSCALEYUV2RGB1(%%eax, %5)
  1209. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1210. #ifdef DITHER1XBPP
  1211. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1212. "paddusb "MANGLE(g6Dither)", %%mm4nt"
  1213. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1214. #endif
  1215. WRITEBGR16(%%esp, 8280(%5), %%eax)
  1216. "movl "ESP_OFFSET"(%5), %%esp nt"
  1217. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1218. "r" (&c->redDither)
  1219. : "%eax"
  1220. );
  1221. return;
  1222. case IMGFMT_YUY2:
  1223. asm volatile(
  1224. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1225. "movl %4, %%esp nt"
  1226. YSCALEYUV2PACKED1(%%eax, %5)
  1227. WRITEYUY2(%%esp, 8280(%5), %%eax)
  1228. "movl "ESP_OFFSET"(%5), %%esp nt"
  1229. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1230. "r" (&c->redDither)
  1231. : "%eax"
  1232. );
  1233. return;
  1234. }
  1235. }
  1236. else
  1237. {
  1238. switch(dstFormat)
  1239. {
  1240. case IMGFMT_BGR32:
  1241. asm volatile(
  1242. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1243. "movl %4, %%esp nt"
  1244. YSCALEYUV2RGB1b(%%eax, %5)
  1245. WRITEBGR32(%%esp, 8280(%5), %%eax)
  1246. "movl "ESP_OFFSET"(%5), %%esp nt"
  1247. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1248. "r" (&c->redDither)
  1249. : "%eax"
  1250. );
  1251. return;
  1252. case IMGFMT_BGR24:
  1253. asm volatile(
  1254. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1255. "movl %4, %%esp nt"
  1256. YSCALEYUV2RGB1b(%%eax, %5)
  1257. WRITEBGR24(%%esp, 8280(%5), %%eax)
  1258. "movl "ESP_OFFSET"(%5), %%esp nt"
  1259. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1260. "r" (&c->redDither)
  1261. : "%eax"
  1262. );
  1263. return;
  1264. case IMGFMT_BGR15:
  1265. asm volatile(
  1266. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1267. "movl %4, %%esp nt"
  1268. YSCALEYUV2RGB1b(%%eax, %5)
  1269. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1270. #ifdef DITHER1XBPP
  1271. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1272. "paddusb "MANGLE(g5Dither)", %%mm4nt"
  1273. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1274. #endif
  1275. WRITEBGR15(%%esp, 8280(%5), %%eax)
  1276. "movl "ESP_OFFSET"(%5), %%esp nt"
  1277. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1278. "r" (&c->redDither)
  1279. : "%eax"
  1280. );
  1281. return;
  1282. case IMGFMT_BGR16:
  1283. asm volatile(
  1284. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1285. "movl %4, %%esp nt"
  1286. YSCALEYUV2RGB1b(%%eax, %5)
  1287. /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
  1288. #ifdef DITHER1XBPP
  1289. "paddusb "MANGLE(b5Dither)", %%mm2nt"
  1290. "paddusb "MANGLE(g6Dither)", %%mm4nt"
  1291. "paddusb "MANGLE(r5Dither)", %%mm5nt"
  1292. #endif
  1293. WRITEBGR16(%%esp, 8280(%5), %%eax)
  1294. "movl "ESP_OFFSET"(%5), %%esp nt"
  1295. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1296. "r" (&c->redDither)
  1297. : "%eax"
  1298. );
  1299. return;
  1300. case IMGFMT_YUY2:
  1301. asm volatile(
  1302. "movl %%esp, "ESP_OFFSET"(%5) nt"
  1303. "movl %4, %%esp nt"
  1304. YSCALEYUV2PACKED1b(%%eax, %5)
  1305. WRITEYUY2(%%esp, 8280(%5), %%eax)
  1306. "movl "ESP_OFFSET"(%5), %%esp nt"
  1307. :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest),
  1308. "r" (&c->redDither)
  1309. : "%eax"
  1310. );
  1311. return;
  1312. }
  1313. }
  1314. #endif
  1315. if( uvalpha < 2048 )
  1316. {
  1317. YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C)
  1318. }else{
  1319. YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C)
  1320. }
  1321. }
  1322. //FIXME yuy2* can read upto 7 samples to much
  1323. static inline void RENAME(yuy2ToY)(uint8_t *dst, uint8_t *src, int width)
  1324. {
  1325. #ifdef HAVE_MMX
  1326. asm volatile(
  1327. "movq "MANGLE(bm01010101)", %%mm2nt"
  1328. "movl %0, %%eax nt"
  1329. "1: nt"
  1330. "movq (%1, %%eax,2), %%mm0 nt"
  1331. "movq 8(%1, %%eax,2), %%mm1 nt"
  1332. "pand %%mm2, %%mm0 nt"
  1333. "pand %%mm2, %%mm1 nt"
  1334. "packuswb %%mm1, %%mm0 nt"
  1335. "movq %%mm0, (%2, %%eax) nt"
  1336. "addl $8, %%eax nt"
  1337. " js 1b nt"
  1338. : : "g" (-width), "r" (src+width*2), "r" (dst+width)
  1339. : "%eax"
  1340. );
  1341. #else
  1342. int i;
  1343. for(i=0; i<width; i++)
  1344. dst[i]= src[2*i];
  1345. #endif
  1346. }
  1347. static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1348. {
  1349. #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
  1350. asm volatile(
  1351. "movq "MANGLE(bm01010101)", %%mm4nt"
  1352. "movl %0, %%eax nt"
  1353. "1: nt"
  1354. "movq (%1, %%eax,4), %%mm0 nt"
  1355. "movq 8(%1, %%eax,4), %%mm1 nt"
  1356. "movq (%2, %%eax,4), %%mm2 nt"
  1357. "movq 8(%2, %%eax,4), %%mm3 nt"
  1358. PAVGB(%%mm2, %%mm0)
  1359. PAVGB(%%mm3, %%mm1)
  1360. "psrlw $8, %%mm0 nt"
  1361. "psrlw $8, %%mm1 nt"
  1362. "packuswb %%mm1, %%mm0 nt"
  1363. "movq %%mm0, %%mm1 nt"
  1364. "psrlw $8, %%mm0 nt"
  1365. "pand %%mm4, %%mm1 nt"
  1366. "packuswb %%mm0, %%mm0 nt"
  1367. "packuswb %%mm1, %%mm1 nt"
  1368. "movd %%mm0, (%4, %%eax) nt"
  1369. "movd %%mm1, (%3, %%eax) nt"
  1370. "addl $4, %%eax nt"
  1371. " js 1b nt"
  1372. : : "g" (-width), "r" (src1+width*4), "r" (src2+width*4), "r" (dstU+width), "r" (dstV+width)
  1373. : "%eax"
  1374. );
  1375. #else
  1376. int i;
  1377. for(i=0; i<width; i++)
  1378. {
  1379. dstU[i]= (src1[4*i + 1] + src2[4*i + 1])>>1;
  1380. dstV[i]= (src1[4*i + 3] + src2[4*i + 3])>>1;
  1381. }
  1382. #endif
  1383. }
  1384. //this is allmost identical to the previous, end exists only cuz yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses
  1385. static inline void RENAME(uyvyToY)(uint8_t *dst, uint8_t *src, int width)
  1386. {
  1387. #ifdef HAVE_MMX
  1388. asm volatile(
  1389. "movl %0, %%eax nt"
  1390. "1: nt"
  1391. "movq (%1, %%eax,2), %%mm0 nt"
  1392. "movq 8(%1, %%eax,2), %%mm1 nt"
  1393. "psrlw $8, %%mm0 nt"
  1394. "psrlw $8, %%mm1 nt"
  1395. "packuswb %%mm1, %%mm0 nt"
  1396. "movq %%mm0, (%2, %%eax) nt"
  1397. "addl $8, %%eax nt"
  1398. " js 1b nt"
  1399. : : "g" (-width), "r" (src+width*2), "r" (dst+width)
  1400. : "%eax"
  1401. );
  1402. #else
  1403. int i;
  1404. for(i=0; i<width; i++)
  1405. dst[i]= src[2*i+1];
  1406. #endif
  1407. }
  1408. static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1409. {
  1410. #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
  1411. asm volatile(
  1412. "movq "MANGLE(bm01010101)", %%mm4nt"
  1413. "movl %0, %%eax nt"
  1414. "1: nt"
  1415. "movq (%1, %%eax,4), %%mm0 nt"
  1416. "movq 8(%1, %%eax,4), %%mm1 nt"
  1417. "movq (%2, %%eax,4), %%mm2 nt"
  1418. "movq 8(%2, %%eax,4), %%mm3 nt"
  1419. PAVGB(%%mm2, %%mm0)
  1420. PAVGB(%%mm3, %%mm1)
  1421. "pand %%mm4, %%mm0 nt"
  1422. "pand %%mm4, %%mm1 nt"
  1423. "packuswb %%mm1, %%mm0 nt"
  1424. "movq %%mm0, %%mm1 nt"
  1425. "psrlw $8, %%mm0 nt"
  1426. "pand %%mm4, %%mm1 nt"
  1427. "packuswb %%mm0, %%mm0 nt"
  1428. "packuswb %%mm1, %%mm1 nt"
  1429. "movd %%mm0, (%4, %%eax) nt"
  1430. "movd %%mm1, (%3, %%eax) nt"
  1431. "addl $4, %%eax nt"
  1432. " js 1b nt"
  1433. : : "g" (-width), "r" (src1+width*4), "r" (src2+width*4), "r" (dstU+width), "r" (dstV+width)
  1434. : "%eax"
  1435. );
  1436. #else
  1437. int i;
  1438. for(i=0; i<width; i++)
  1439. {
  1440. dstU[i]= (src1[4*i + 0] + src2[4*i + 0])>>1;
  1441. dstV[i]= (src1[4*i + 2] + src2[4*i + 2])>>1;
  1442. }
  1443. #endif
  1444. }
  1445. static inline void RENAME(bgr32ToY)(uint8_t *dst, uint8_t *src, int width)
  1446. {
  1447. #ifdef HAVE_MMXFIXME
  1448. #else
  1449. int i;
  1450. for(i=0; i<width; i++)
  1451. {
  1452. int b=  ((uint32_t*)src)[i]&0xFF;
  1453. int g= (((uint32_t*)src)[i]>>8)&0xFF;
  1454. int r= (((uint32_t*)src)[i]>>16)&0xFF;
  1455. dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
  1456. }
  1457. #endif
  1458. }
  1459. static inline void RENAME(bgr32ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1460. {
  1461. #ifdef HAVE_MMXFIXME
  1462. #else
  1463. int i;
  1464. for(i=0; i<width; i++)
  1465. {
  1466. const int a= ((uint32_t*)src1)[2*i+0];
  1467. const int e= ((uint32_t*)src1)[2*i+1];
  1468. const int c= ((uint32_t*)src2)[2*i+0];
  1469. const int d= ((uint32_t*)src2)[2*i+1];
  1470. const int l= (a&0xFF00FF) + (e&0xFF00FF) + (c&0xFF00FF) + (d&0xFF00FF);
  1471. const int h= (a&0x00FF00) + (e&0x00FF00) + (c&0x00FF00) + (d&0x00FF00);
  1472.   const int b=  l&0x3FF;
  1473. const int g=  h>>8;
  1474. const int r=  l>>16;
  1475. dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1476. dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1477. }
  1478. #endif
  1479. }
  1480. static inline void RENAME(bgr24ToY)(uint8_t *dst, uint8_t *src, int width)
  1481. {
  1482. #ifdef HAVE_MMX
  1483. asm volatile(
  1484. "movl %2, %%eax nt"
  1485. "movq "MANGLE(bgr2YCoeff)", %%mm6 nt"
  1486. "movq "MANGLE(w1111)", %%mm5 nt"
  1487. "pxor %%mm7, %%mm7 nt"
  1488. "leal (%%eax, %%eax, 2), %%ebx nt"
  1489. ".balign 16 nt"
  1490. "1: nt"
  1491. PREFETCH" 64(%0, %%ebx) nt"
  1492. "movd (%0, %%ebx), %%mm0 nt"
  1493. "movd 3(%0, %%ebx), %%mm1 nt"
  1494. "punpcklbw %%mm7, %%mm0 nt"
  1495. "punpcklbw %%mm7, %%mm1 nt"
  1496. "movd 6(%0, %%ebx), %%mm2 nt"
  1497. "movd 9(%0, %%ebx), %%mm3 nt"
  1498. "punpcklbw %%mm7, %%mm2 nt"
  1499. "punpcklbw %%mm7, %%mm3 nt"
  1500. "pmaddwd %%mm6, %%mm0 nt"
  1501. "pmaddwd %%mm6, %%mm1 nt"
  1502. "pmaddwd %%mm6, %%mm2 nt"
  1503. "pmaddwd %%mm6, %%mm3 nt"
  1504. #ifndef FAST_BGR2YV12
  1505. "psrad $8, %%mm0 nt"
  1506. "psrad $8, %%mm1 nt"
  1507. "psrad $8, %%mm2 nt"
  1508. "psrad $8, %%mm3 nt"
  1509. #endif
  1510. "packssdw %%mm1, %%mm0 nt"
  1511. "packssdw %%mm3, %%mm2 nt"
  1512. "pmaddwd %%mm5, %%mm0 nt"
  1513. "pmaddwd %%mm5, %%mm2 nt"
  1514. "packssdw %%mm2, %%mm0 nt"
  1515. "psraw $7, %%mm0 nt"
  1516. "movd 12(%0, %%ebx), %%mm4 nt"
  1517. "movd 15(%0, %%ebx), %%mm1 nt"
  1518. "punpcklbw %%mm7, %%mm4 nt"
  1519. "punpcklbw %%mm7, %%mm1 nt"
  1520. "movd 18(%0, %%ebx), %%mm2 nt"
  1521. "movd 21(%0, %%ebx), %%mm3 nt"
  1522. "punpcklbw %%mm7, %%mm2 nt"
  1523. "punpcklbw %%mm7, %%mm3 nt"
  1524. "pmaddwd %%mm6, %%mm4 nt"
  1525. "pmaddwd %%mm6, %%mm1 nt"
  1526. "pmaddwd %%mm6, %%mm2 nt"
  1527. "pmaddwd %%mm6, %%mm3 nt"
  1528. #ifndef FAST_BGR2YV12
  1529. "psrad $8, %%mm4 nt"
  1530. "psrad $8, %%mm1 nt"
  1531. "psrad $8, %%mm2 nt"
  1532. "psrad $8, %%mm3 nt"
  1533. #endif
  1534. "packssdw %%mm1, %%mm4 nt"
  1535. "packssdw %%mm3, %%mm2 nt"
  1536. "pmaddwd %%mm5, %%mm4 nt"
  1537. "pmaddwd %%mm5, %%mm2 nt"
  1538. "addl $24, %%ebx nt"
  1539. "packssdw %%mm2, %%mm4 nt"
  1540. "psraw $7, %%mm4 nt"
  1541. "packuswb %%mm4, %%mm0 nt"
  1542. "paddusb "MANGLE(bgr2YOffset)", %%mm0 nt"
  1543. "movq %%mm0, (%1, %%eax) nt"
  1544. "addl $8, %%eax nt"
  1545. " js 1b nt"
  1546. : : "r" (src+width*3), "r" (dst+width), "g" (-width)
  1547. : "%eax", "%ebx"
  1548. );
  1549. #else
  1550. int i;
  1551. for(i=0; i<width; i++)
  1552. {
  1553. int b= src[i*3+0];
  1554. int g= src[i*3+1];
  1555. int r= src[i*3+2];
  1556. dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
  1557. }
  1558. #endif
  1559. }
  1560. static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1561. {
  1562. #ifdef HAVE_MMX
  1563. asm volatile(
  1564. "movl %4, %%eax nt"
  1565. "movq "MANGLE(w1111)", %%mm5 nt"
  1566. "movq "MANGLE(bgr2UCoeff)", %%mm6 nt"
  1567. "pxor %%mm7, %%mm7 nt"
  1568. "leal (%%eax, %%eax, 2), %%ebx nt"
  1569. "addl %%ebx, %%ebx nt"
  1570. ".balign 16 nt"
  1571. "1: nt"
  1572. PREFETCH" 64(%0, %%ebx) nt"
  1573. PREFETCH" 64(%1, %%ebx) nt"
  1574. #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
  1575. "movq (%0, %%ebx), %%mm0 nt"
  1576. "movq (%1, %%ebx), %%mm1 nt"
  1577. "movq 6(%0, %%ebx), %%mm2 nt"
  1578. "movq 6(%1, %%ebx), %%mm3 nt"
  1579. PAVGB(%%mm1, %%mm0)
  1580. PAVGB(%%mm3, %%mm2)
  1581. "movq %%mm0, %%mm1 nt"
  1582. "movq %%mm2, %%mm3 nt"
  1583. "psrlq $24, %%mm0 nt"
  1584. "psrlq $24, %%mm2 nt"
  1585. PAVGB(%%mm1, %%mm0)
  1586. PAVGB(%%mm3, %%mm2)
  1587. "punpcklbw %%mm7, %%mm0 nt"
  1588. "punpcklbw %%mm7, %%mm2 nt"
  1589. #else
  1590. "movd (%0, %%ebx), %%mm0 nt"
  1591. "movd (%1, %%ebx), %%mm1 nt"
  1592. "movd 3(%0, %%ebx), %%mm2 nt"
  1593. "movd 3(%1, %%ebx), %%mm3 nt"
  1594. "punpcklbw %%mm7, %%mm0 nt"
  1595. "punpcklbw %%mm7, %%mm1 nt"
  1596. "punpcklbw %%mm7, %%mm2 nt"
  1597. "punpcklbw %%mm7, %%mm3 nt"
  1598. "paddw %%mm1, %%mm0 nt"
  1599. "paddw %%mm3, %%mm2 nt"
  1600. "paddw %%mm2, %%mm0 nt"
  1601. "movd 6(%0, %%ebx), %%mm4 nt"
  1602. "movd 6(%1, %%ebx), %%mm1 nt"
  1603. "movd 9(%0, %%ebx), %%mm2 nt"
  1604. "movd 9(%1, %%ebx), %%mm3 nt"
  1605. "punpcklbw %%mm7, %%mm4 nt"
  1606. "punpcklbw %%mm7, %%mm1 nt"
  1607. "punpcklbw %%mm7, %%mm2 nt"
  1608. "punpcklbw %%mm7, %%mm3 nt"
  1609. "paddw %%mm1, %%mm4 nt"
  1610. "paddw %%mm3, %%mm2 nt"
  1611. "paddw %%mm4, %%mm2 nt"
  1612. "psrlw $2, %%mm0 nt"
  1613. "psrlw $2, %%mm2 nt"
  1614. #endif
  1615. "movq "MANGLE(bgr2VCoeff)", %%mm1 nt"
  1616. "movq "MANGLE(bgr2VCoeff)", %%mm3 nt"
  1617. "pmaddwd %%mm0, %%mm1 nt"
  1618. "pmaddwd %%mm2, %%mm3 nt"
  1619. "pmaddwd %%mm6, %%mm0 nt"
  1620. "pmaddwd %%mm6, %%mm2 nt"
  1621. #ifndef FAST_BGR2YV12
  1622. "psrad $8, %%mm0 nt"
  1623. "psrad $8, %%mm1 nt"
  1624. "psrad $8, %%mm2 nt"
  1625. "psrad $8, %%mm3 nt"
  1626. #endif
  1627. "packssdw %%mm2, %%mm0 nt"
  1628. "packssdw %%mm3, %%mm1 nt"
  1629. "pmaddwd %%mm5, %%mm0 nt"
  1630. "pmaddwd %%mm5, %%mm1 nt"
  1631. "packssdw %%mm1, %%mm0 nt" // V1 V0 U1 U0
  1632. "psraw $7, %%mm0 nt"
  1633. #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
  1634. "movq 12(%0, %%ebx), %%mm4 nt"
  1635. "movq 12(%1, %%ebx), %%mm1 nt"
  1636. "movq 18(%0, %%ebx), %%mm2 nt"
  1637. "movq 18(%1, %%ebx), %%mm3 nt"
  1638. PAVGB(%%mm1, %%mm4)
  1639. PAVGB(%%mm3, %%mm2)
  1640. "movq %%mm4, %%mm1 nt"
  1641. "movq %%mm2, %%mm3 nt"
  1642. "psrlq $24, %%mm4 nt"
  1643. "psrlq $24, %%mm2 nt"
  1644. PAVGB(%%mm1, %%mm4)
  1645. PAVGB(%%mm3, %%mm2)
  1646. "punpcklbw %%mm7, %%mm4 nt"
  1647. "punpcklbw %%mm7, %%mm2 nt"
  1648. #else
  1649. "movd 12(%0, %%ebx), %%mm4 nt"
  1650. "movd 12(%1, %%ebx), %%mm1 nt"
  1651. "movd 15(%0, %%ebx), %%mm2 nt"
  1652. "movd 15(%1, %%ebx), %%mm3 nt"
  1653. "punpcklbw %%mm7, %%mm4 nt"
  1654. "punpcklbw %%mm7, %%mm1 nt"
  1655. "punpcklbw %%mm7, %%mm2 nt"
  1656. "punpcklbw %%mm7, %%mm3 nt"
  1657. "paddw %%mm1, %%mm4 nt"
  1658. "paddw %%mm3, %%mm2 nt"
  1659. "paddw %%mm2, %%mm4 nt"
  1660. "movd 18(%0, %%ebx), %%mm5 nt"
  1661. "movd 18(%1, %%ebx), %%mm1 nt"
  1662. "movd 21(%0, %%ebx), %%mm2 nt"
  1663. "movd 21(%1, %%ebx), %%mm3 nt"
  1664. "punpcklbw %%mm7, %%mm5 nt"
  1665. "punpcklbw %%mm7, %%mm1 nt"
  1666. "punpcklbw %%mm7, %%mm2 nt"
  1667. "punpcklbw %%mm7, %%mm3 nt"
  1668. "paddw %%mm1, %%mm5 nt"
  1669. "paddw %%mm3, %%mm2 nt"
  1670. "paddw %%mm5, %%mm2 nt"
  1671. "movq "MANGLE(w1111)", %%mm5 nt"
  1672. "psrlw $2, %%mm4 nt"
  1673. "psrlw $2, %%mm2 nt"
  1674. #endif
  1675. "movq "MANGLE(bgr2VCoeff)", %%mm1 nt"
  1676. "movq "MANGLE(bgr2VCoeff)", %%mm3 nt"
  1677. "pmaddwd %%mm4, %%mm1 nt"
  1678. "pmaddwd %%mm2, %%mm3 nt"
  1679. "pmaddwd %%mm6, %%mm4 nt"
  1680. "pmaddwd %%mm6, %%mm2 nt"
  1681. #ifndef FAST_BGR2YV12
  1682. "psrad $8, %%mm4 nt"
  1683. "psrad $8, %%mm1 nt"
  1684. "psrad $8, %%mm2 nt"
  1685. "psrad $8, %%mm3 nt"
  1686. #endif
  1687. "packssdw %%mm2, %%mm4 nt"
  1688. "packssdw %%mm3, %%mm1 nt"
  1689. "pmaddwd %%mm5, %%mm4 nt"
  1690. "pmaddwd %%mm5, %%mm1 nt"
  1691. "addl $24, %%ebx nt"
  1692. "packssdw %%mm1, %%mm4 nt" // V3 V2 U3 U2
  1693. "psraw $7, %%mm4 nt"
  1694. "movq %%mm0, %%mm1 nt"
  1695. "punpckldq %%mm4, %%mm0 nt"
  1696. "punpckhdq %%mm4, %%mm1 nt"
  1697. "packsswb %%mm1, %%mm0 nt"
  1698. "paddb "MANGLE(bgr2UVOffset)", %%mm0 nt"
  1699. "movd %%mm0, (%2, %%eax) nt"
  1700. "punpckhdq %%mm0, %%mm0 nt"
  1701. "movd %%mm0, (%3, %%eax) nt"
  1702. "addl $4, %%eax nt"
  1703. " js 1b nt"
  1704. : : "r" (src1+width*6), "r" (src2+width*6), "r" (dstU+width), "r" (dstV+width), "g" (-width)
  1705. : "%eax", "%ebx"
  1706. );
  1707. #else
  1708. int i;
  1709. for(i=0; i<width; i++)
  1710. {
  1711. int b= src1[6*i + 0] + src1[6*i + 3] + src2[6*i + 0] + src2[6*i + 3];
  1712. int g= src1[6*i + 1] + src1[6*i + 4] + src2[6*i + 1] + src2[6*i + 4];
  1713. int r= src1[6*i + 2] + src1[6*i + 5] + src2[6*i + 2] + src2[6*i + 5];
  1714. dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1715. dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1716. }
  1717. #endif
  1718. }
  1719. static inline void RENAME(bgr16ToY)(uint8_t *dst, uint8_t *src, int width)
  1720. {
  1721. int i;
  1722. for(i=0; i<width; i++)
  1723. {
  1724. int d= ((uint16_t*)src)[i];
  1725. int b= d&0x1F;
  1726. int g= (d>>5)&0x3F;
  1727. int r= (d>>11)&0x1F;
  1728. dst[i]= ((2*RY*r + GY*g + 2*BY*b)>>(RGB2YUV_SHIFT-2)) + 16;
  1729. }
  1730. }
  1731. static inline void RENAME(bgr16ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1732. {
  1733. int i;
  1734. for(i=0; i<width; i++)
  1735. {
  1736. int d0= ((uint32_t*)src1)[i];
  1737. int d1= ((uint32_t*)src2)[i];
  1738. int dl= (d0&0x07E0F81F) + (d1&0x07E0F81F);
  1739. int dh= ((d0>>5)&0x07C0F83F) + ((d1>>5)&0x07C0F83F);
  1740. int dh2= (dh>>11) + (dh<<21);
  1741. int d= dh2 + dl;
  1742. int b= d&0x7F;
  1743. int r= (d>>11)&0x7F;
  1744. int g= d>>21;
  1745. dstU[i]= ((2*RU*r + GU*g + 2*BU*b)>>(RGB2YUV_SHIFT+2-2)) + 128;
  1746. dstV[i]= ((2*RV*r + GV*g + 2*BV*b)>>(RGB2YUV_SHIFT+2-2)) + 128;
  1747. }
  1748. }
  1749. static inline void RENAME(bgr15ToY)(uint8_t *dst, uint8_t *src, int width)
  1750. {
  1751. int i;
  1752. for(i=0; i<width; i++)
  1753. {
  1754. int d= ((uint16_t*)src)[i];
  1755. int b= d&0x1F;
  1756. int g= (d>>5)&0x1F;
  1757. int r= (d>>10)&0x1F;
  1758. dst[i]= ((RY*r + GY*g + BY*b)>>(RGB2YUV_SHIFT-3)) + 16;
  1759. }
  1760. }
  1761. static inline void RENAME(bgr15ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1762. {
  1763. int i;
  1764. for(i=0; i<width; i++)
  1765. {
  1766. int d0= ((uint32_t*)src1)[i];
  1767. int d1= ((uint32_t*)src2)[i];
  1768. int dl= (d0&0x03E07C1F) + (d1&0x03E07C1F);
  1769. int dh= ((d0>>5)&0x03E0F81F) + ((d1>>5)&0x03E0F81F);
  1770. int dh2= (dh>>11) + (dh<<21);
  1771. int d= dh2 + dl;
  1772. int b= d&0x7F;
  1773. int r= (d>>10)&0x7F;
  1774. int g= d>>21;
  1775. dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2-3)) + 128;
  1776. dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2-3)) + 128;
  1777. }
  1778. }
  1779. static inline void RENAME(rgb32ToY)(uint8_t *dst, uint8_t *src, int width)
  1780. {
  1781. int i;
  1782. for(i=0; i<width; i++)
  1783. {
  1784. int r=  ((uint32_t*)src)[i]&0xFF;
  1785. int g= (((uint32_t*)src)[i]>>8)&0xFF;
  1786. int b= (((uint32_t*)src)[i]>>16)&0xFF;
  1787. dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
  1788. }
  1789. }
  1790. static inline void RENAME(rgb32ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1791. {
  1792. int i;
  1793. for(i=0; i<width; i++)
  1794. {
  1795. const int a= ((uint32_t*)src1)[2*i+0];
  1796. const int e= ((uint32_t*)src1)[2*i+1];
  1797. const int c= ((uint32_t*)src2)[2*i+0];
  1798. const int d= ((uint32_t*)src2)[2*i+1];
  1799. const int l= (a&0xFF00FF) + (e&0xFF00FF) + (c&0xFF00FF) + (d&0xFF00FF);
  1800. const int h= (a&0x00FF00) + (e&0x00FF00) + (c&0x00FF00) + (d&0x00FF00);
  1801.   const int r=  l&0x3FF;
  1802. const int g=  h>>8;
  1803. const int b=  l>>16;
  1804. dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1805. dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1806. }
  1807. }
  1808. static inline void RENAME(rgb24ToY)(uint8_t *dst, uint8_t *src, int width)
  1809. {
  1810. int i;
  1811. for(i=0; i<width; i++)
  1812. {
  1813. int r= src[i*3+0];
  1814. int g= src[i*3+1];
  1815. int b= src[i*3+2];
  1816. dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
  1817. }
  1818. }
  1819. static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
  1820. {
  1821. int i;
  1822. for(i=0; i<width; i++)
  1823. {
  1824. int r= src1[6*i + 0] + src1[6*i + 3] + src2[6*i + 0] + src2[6*i + 3];
  1825. int g= src1[6*i + 1] + src1[6*i + 4] + src2[6*i + 1] + src2[6*i + 4];
  1826. int b= src1[6*i + 2] + src1[6*i + 5] + src2[6*i + 2] + src2[6*i + 5];
  1827. dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1828. dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
  1829. }
  1830. }
  1831. // Bilinear / Bicubic scaling
  1832. static inline void RENAME(hScale)(int16_t *dst, int dstW, uint8_t *src, int srcW, int xInc,
  1833.   int16_t *filter, int16_t *filterPos, int filterSize)
  1834. {
  1835. #ifdef HAVE_MMX
  1836. assert(filterSize % 4 == 0 && filterSize>0);
  1837. if(filterSize==4) // allways true for upscaling, sometimes for down too
  1838. {
  1839. int counter= -2*dstW;
  1840. filter-= counter*2;
  1841. filterPos-= counter/2;
  1842. dst-= counter/2;
  1843. asm volatile(
  1844. "pxor %%mm7, %%mm7 nt"
  1845. "movq "MANGLE(w02)", %%mm6 nt"
  1846. "pushl %%ebp nt" // we use 7 regs here ...
  1847. "movl %%eax, %%ebp nt"
  1848. ".balign 16 nt"
  1849. "1: nt"
  1850. "movzwl (%2, %%ebp), %%eax nt"
  1851. "movzwl 2(%2, %%ebp), %%ebx nt"
  1852. "movq (%1, %%ebp, 4), %%mm1 nt"
  1853. "movq 8(%1, %%ebp, 4), %%mm3 nt"
  1854. "movd (%3, %%eax), %%mm0 nt"
  1855. "movd (%3, %%ebx), %%mm2 nt"
  1856. "punpcklbw %%mm7, %%mm0 nt"
  1857. "punpcklbw %%mm7, %%mm2 nt"
  1858. "pmaddwd %%mm1, %%mm0 nt"
  1859. "pmaddwd %%mm2, %%mm3 nt"
  1860. "psrad $8, %%mm0 nt"
  1861. "psrad $8, %%mm3 nt"
  1862. "packssdw %%mm3, %%mm0 nt"
  1863. "pmaddwd %%mm6, %%mm0 nt"
  1864. "packssdw %%mm0, %%mm0 nt"
  1865. "movd %%mm0, (%4, %%ebp) nt"
  1866. "addl $4, %%ebp nt"
  1867. " jnc 1b nt"
  1868. "popl %%ebp nt"
  1869. : "+a" (counter)
  1870. : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
  1871. : "%ebx"
  1872. );
  1873. }
  1874. else if(filterSize==8)
  1875. {
  1876. int counter= -2*dstW;
  1877. filter-= counter*4;
  1878. filterPos-= counter/2;
  1879. dst-= counter/2;
  1880. asm volatile(
  1881. "pxor %%mm7, %%mm7 nt"
  1882. "movq "MANGLE(w02)", %%mm6 nt"
  1883. "pushl %%ebp nt" // we use 7 regs here ...
  1884. "movl %%eax, %%ebp nt"
  1885. ".balign 16 nt"
  1886. "1: nt"
  1887. "movzwl (%2, %%ebp), %%eax nt"
  1888. "movzwl 2(%2, %%ebp), %%ebx nt"
  1889. "movq (%1, %%ebp, 8), %%mm1 nt"
  1890. "movq 16(%1, %%ebp, 8), %%mm3 nt"
  1891. "movd (%3, %%eax), %%mm0 nt"
  1892. "movd (%3, %%ebx), %%mm2 nt"
  1893. "punpcklbw %%mm7, %%mm0 nt"
  1894. "punpcklbw %%mm7, %%mm2 nt"
  1895. "pmaddwd %%mm1, %%mm0 nt"
  1896. "pmaddwd %%mm2, %%mm3 nt"
  1897. "movq 8(%1, %%ebp, 8), %%mm1 nt"
  1898. "movq 24(%1, %%ebp, 8), %%mm5 nt"
  1899. "movd 4(%3, %%eax), %%mm4 nt"
  1900. "movd 4(%3, %%ebx), %%mm2 nt"
  1901. "punpcklbw %%mm7, %%mm4 nt"
  1902. "punpcklbw %%mm7, %%mm2 nt"
  1903. "pmaddwd %%mm1, %%mm4 nt"
  1904. "pmaddwd %%mm2, %%mm5 nt"
  1905. "paddd %%mm4, %%mm0 nt"
  1906. "paddd %%mm5, %%mm3 nt"
  1907. "psrad $8, %%mm0 nt"
  1908. "psrad $8, %%mm3 nt"
  1909. "packssdw %%mm3, %%mm0 nt"
  1910. "pmaddwd %%mm6, %%mm0 nt"
  1911. "packssdw %%mm0, %%mm0 nt"
  1912. "movd %%mm0, (%4, %%ebp) nt"
  1913. "addl $4, %%ebp nt"
  1914. " jnc 1b nt"
  1915. "popl %%ebp nt"
  1916. : "+a" (counter)
  1917. : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
  1918. : "%ebx"
  1919. );
  1920. }
  1921. else
  1922. {
  1923. int counter= -2*dstW;
  1924. // filter-= counter*filterSize/2;
  1925. filterPos-= counter/2;
  1926. dst-= counter/2;
  1927. asm volatile(
  1928. "pxor %%mm7, %%mm7 nt"
  1929. "movq "MANGLE(w02)", %%mm6 nt"
  1930. ".balign 16 nt"
  1931. "1: nt"
  1932. "movl %2, %%ecx nt"
  1933. "movzwl (%%ecx, %0), %%eax nt"
  1934. "movzwl 2(%%ecx, %0), %%ebx nt"
  1935. "movl %5, %%ecx nt"
  1936. "pxor %%mm4, %%mm4 nt"
  1937. "pxor %%mm5, %%mm5 nt"
  1938. "2: nt"
  1939. "movq (%1), %%mm1 nt"
  1940. "movq (%1, %6), %%mm3 nt"
  1941. "movd (%%ecx, %%eax), %%mm0 nt"
  1942. "movd (%%ecx, %%ebx), %%mm2 nt"
  1943. "punpcklbw %%mm7, %%mm0 nt"
  1944. "punpcklbw %%mm7, %%mm2 nt"
  1945. "pmaddwd %%mm1, %%mm0 nt"
  1946. "pmaddwd %%mm2, %%mm3 nt"
  1947. "paddd %%mm3, %%mm5 nt"
  1948. "paddd %%mm0, %%mm4 nt"
  1949. "addl $8, %1 nt"
  1950. "addl $4, %%ecx nt"
  1951. "cmpl %4, %%ecx nt"
  1952. " jb 2b nt"
  1953. "addl %6, %1 nt"
  1954. "psrad $8, %%mm4 nt"
  1955. "psrad $8, %%mm5 nt"
  1956. "packssdw %%mm5, %%mm4 nt"
  1957. "pmaddwd %%mm6, %%mm4 nt"
  1958. "packssdw %%mm4, %%mm4 nt"
  1959. "movl %3, %%eax nt"
  1960. "movd %%mm4, (%%eax, %0) nt"
  1961. "addl $4, %0 nt"
  1962. " jnc 1b nt"
  1963. : "+r" (counter), "+r" (filter)
  1964. : "m" (filterPos), "m" (dst), "m"(src+filterSize),
  1965.   "m" (src), "r" (filterSize*2)
  1966. : "%ebx", "%eax", "%ecx"
  1967. );
  1968. }
  1969. #else
  1970. #ifdef HAVE_ALTIVEC
  1971. hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);
  1972. #else
  1973. int i;
  1974. for(i=0; i<dstW; i++)
  1975. {
  1976. int j;
  1977. int srcPos= filterPos[i];
  1978. int val=0;
  1979. // printf("filterPos: %dn", filterPos[i]);
  1980. for(j=0; j<filterSize; j++)
  1981. {
  1982. // printf("filter: %d, src: %dn", filter[i], src[srcPos + j]);
  1983. val += ((int)src[srcPos + j])*filter[filterSize*i + j];
  1984. }
  1985. // filter += hFilterSize;
  1986. dst[i] = MIN(MAX(0, val>>7), (1<<15)-1); // the cubic equation does overflow ...
  1987. // dst[i] = val>>7;
  1988. }
  1989. #endif
  1990. #endif
  1991. }
  1992.       // *** horizontal scale Y line to temp buffer
  1993. static inline void RENAME(hyscale)(uint16_t *dst, int dstWidth, uint8_t *src, int srcW, int xInc,
  1994.    int flags, int canMMX2BeUsed, int16_t *hLumFilter,
  1995.    int16_t *hLumFilterPos, int hLumFilterSize, void *funnyYCode, 
  1996.    int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,
  1997.    int32_t *mmx2FilterPos)
  1998. {
  1999.     if(srcFormat==IMGFMT_YUY2)
  2000.     {
  2001. RENAME(yuy2ToY)(formatConvBuffer, src, srcW);
  2002. src= formatConvBuffer;
  2003.     }
  2004.     else if(srcFormat==IMGFMT_UYVY)
  2005.     {
  2006. RENAME(uyvyToY)(formatConvBuffer, src, srcW);
  2007. src= formatConvBuffer;
  2008.     }
  2009.     else if(srcFormat==IMGFMT_BGR32)
  2010.     {
  2011. RENAME(bgr32ToY)(formatConvBuffer, src, srcW);
  2012. src= formatConvBuffer;
  2013.     }
  2014.     else if(srcFormat==IMGFMT_BGR24)
  2015.     {
  2016. RENAME(bgr24ToY)(formatConvBuffer, src, srcW);
  2017. src= formatConvBuffer;
  2018.     }
  2019.     else if(srcFormat==IMGFMT_BGR16)
  2020.     {
  2021. RENAME(bgr16ToY)(formatConvBuffer, src, srcW);
  2022. src= formatConvBuffer;
  2023.     }
  2024.     else if(srcFormat==IMGFMT_BGR15)
  2025.     {
  2026. RENAME(bgr15ToY)(formatConvBuffer, src, srcW);
  2027. src= formatConvBuffer;
  2028.     }
  2029.     else if(srcFormat==IMGFMT_RGB32)
  2030.     {
  2031. RENAME(rgb32ToY)(formatConvBuffer, src, srcW);
  2032. src= formatConvBuffer;
  2033.     }
  2034.     else if(srcFormat==IMGFMT_RGB24)
  2035.     {
  2036. RENAME(rgb24ToY)(formatConvBuffer, src, srcW);
  2037. src= formatConvBuffer;
  2038.     }
  2039. #ifdef HAVE_MMX
  2040. // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one)
  2041.     if(!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))
  2042. #else
  2043.     if(!(flags&SWS_FAST_BILINEAR))
  2044. #endif
  2045.     {
  2046.      RENAME(hScale)(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
  2047.     }
  2048.     else // Fast Bilinear upscale / crap downscale
  2049.     {
  2050. #ifdef ARCH_X86
  2051. #ifdef HAVE_MMX2
  2052. int i;
  2053. if(canMMX2BeUsed)
  2054. {
  2055. asm volatile(
  2056. "pxor %%mm7, %%mm7 nt"
  2057. "movl %0, %%ecx nt"
  2058. "movl %1, %%edi nt"
  2059. "movl %2, %%edx nt"
  2060. "movl %3, %%ebx nt"
  2061. "xorl %%eax, %%eax nt" // i
  2062. PREFETCH" (%%ecx) nt"
  2063. PREFETCH" 32(%%ecx) nt"
  2064. PREFETCH" 64(%%ecx) nt"
  2065. #define FUNNY_Y_CODE 
  2066. "movl (%%ebx), %%esi nt"
  2067. "call *%4 nt"
  2068. "addl (%%ebx, %%eax), %%ecx nt"
  2069. "addl %%eax, %%edi nt"
  2070. "xorl %%eax, %%eax nt"
  2071. FUNNY_Y_CODE
  2072. FUNNY_Y_CODE
  2073. FUNNY_Y_CODE
  2074. FUNNY_Y_CODE
  2075. FUNNY_Y_CODE
  2076. FUNNY_Y_CODE
  2077. FUNNY_Y_CODE
  2078. FUNNY_Y_CODE
  2079. :: "m" (src), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),
  2080. "m" (funnyYCode)
  2081. : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
  2082. );
  2083. for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;
  2084. }
  2085. else
  2086. {
  2087. #endif
  2088. //NO MMX just normal asm ...
  2089. asm volatile(
  2090. "xorl %%eax, %%eax nt" // i
  2091. "xorl %%ebx, %%ebx nt" // xx
  2092. "xorl %%ecx, %%ecx nt" // 2*xalpha
  2093. ".balign 16 nt"
  2094. "1: nt"
  2095. "movzbl  (%0, %%ebx), %%edi nt" //src[xx]
  2096. "movzbl 1(%0, %%ebx), %%esi nt" //src[xx+1]
  2097. "subl %%edi, %%esi nt" //src[xx+1] - src[xx]
  2098. "imull %%ecx, %%esi nt" //(src[xx+1] - src[xx])*2*xalpha
  2099. "shll $16, %%edi nt"
  2100. "addl %%edi, %%esi nt" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
  2101. "movl %1, %%edi nt"
  2102. "shrl $9, %%esi nt"
  2103. "movw %%si, (%%edi, %%eax, 2) nt"
  2104. "addw %4, %%cx nt" //2*xalpha += xInc&0xFF
  2105. "adcl %3, %%ebx nt" //xx+= xInc>>8 + carry
  2106. "movzbl (%0, %%ebx), %%edi nt" //src[xx]
  2107. "movzbl 1(%0, %%ebx), %%esi nt" //src[xx+1]
  2108. "subl %%edi, %%esi nt" //src[xx+1] - src[xx]
  2109. "imull %%ecx, %%esi nt" //(src[xx+1] - src[xx])*2*xalpha
  2110. "shll $16, %%edi nt"
  2111. "addl %%edi, %%esi nt" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
  2112. "movl %1, %%edi nt"
  2113. "shrl $9, %%esi nt"
  2114. "movw %%si, 2(%%edi, %%eax, 2) nt"
  2115. "addw %4, %%cx nt" //2*xalpha += xInc&0xFF
  2116. "adcl %3, %%ebx nt" //xx+= xInc>>8 + carry
  2117. "addl $2, %%eax nt"
  2118. "cmpl %2, %%eax nt"
  2119. " jb 1b nt"
  2120. :: "r" (src), "m" (dst), "m" (dstWidth), "m" (xInc>>16), "m" (xInc&0xFFFF)
  2121. : "%eax", "%ebx", "%ecx", "%edi", "%esi"
  2122. );
  2123. #ifdef HAVE_MMX2
  2124. } //if MMX2 can't be used
  2125. #endif
  2126. #else
  2127. int i;
  2128. unsigned int xpos=0;
  2129. for(i=0;i<dstWidth;i++)
  2130. {
  2131. register unsigned int xx=xpos>>16;
  2132. register unsigned int xalpha=(xpos&0xFFFF)>>9;
  2133. dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
  2134. xpos+=xInc;
  2135. }
  2136. #endif
  2137.     }
  2138. }
  2139. inline static void RENAME(hcscale)(uint16_t *dst, int dstWidth, uint8_t *src1, uint8_t *src2,
  2140.    int srcW, int xInc, int flags, int canMMX2BeUsed, int16_t *hChrFilter,
  2141.    int16_t *hChrFilterPos, int hChrFilterSize, void *funnyUVCode,
  2142.    int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,
  2143.    int32_t *mmx2FilterPos)
  2144. {
  2145.     if(srcFormat==IMGFMT_YUY2)
  2146.     {
  2147. RENAME(yuy2ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2148. src1= formatConvBuffer;
  2149. src2= formatConvBuffer+2048;
  2150.     }
  2151.     else if(srcFormat==IMGFMT_UYVY)
  2152.     {
  2153. RENAME(uyvyToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2154. src1= formatConvBuffer;
  2155. src2= formatConvBuffer+2048;
  2156.     }
  2157.     else if(srcFormat==IMGFMT_BGR32)
  2158.     {
  2159. RENAME(bgr32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2160. src1= formatConvBuffer;
  2161. src2= formatConvBuffer+2048;
  2162.     }
  2163.     else if(srcFormat==IMGFMT_BGR24)
  2164.     {
  2165. RENAME(bgr24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2166. src1= formatConvBuffer;
  2167. src2= formatConvBuffer+2048;
  2168.     }
  2169.     else if(srcFormat==IMGFMT_BGR16)
  2170.     {
  2171. RENAME(bgr16ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2172. src1= formatConvBuffer;
  2173. src2= formatConvBuffer+2048;
  2174.     }
  2175.     else if(srcFormat==IMGFMT_BGR15)
  2176.     {
  2177. RENAME(bgr15ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2178. src1= formatConvBuffer;
  2179. src2= formatConvBuffer+2048;
  2180.     }
  2181.     else if(srcFormat==IMGFMT_RGB32)
  2182.     {
  2183. RENAME(rgb32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2184. src1= formatConvBuffer;
  2185. src2= formatConvBuffer+2048;
  2186.     }
  2187.     else if(srcFormat==IMGFMT_RGB24)
  2188.     {
  2189. RENAME(rgb24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
  2190. src1= formatConvBuffer;
  2191. src2= formatConvBuffer+2048;
  2192.     }
  2193.     else if(isGray(srcFormat))
  2194.     {
  2195.      return;
  2196.     }
  2197. #ifdef HAVE_MMX
  2198. // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one)
  2199.     if(!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))
  2200. #else
  2201.     if(!(flags&SWS_FAST_BILINEAR))
  2202. #endif
  2203.     {
  2204.      RENAME(hScale)(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
  2205.      RENAME(hScale)(dst+2048, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
  2206.     }
  2207.     else // Fast Bilinear upscale / crap downscale
  2208.     {
  2209. #ifdef ARCH_X86
  2210. #ifdef HAVE_MMX2
  2211. int i;
  2212. if(canMMX2BeUsed)
  2213. {
  2214. asm volatile(
  2215. "pxor %%mm7, %%mm7 nt"
  2216. "movl %0, %%ecx nt"
  2217. "movl %1, %%edi nt"
  2218. "movl %2, %%edx nt"
  2219. "movl %3, %%ebx nt"
  2220. "xorl %%eax, %%eax nt" // i
  2221. PREFETCH" (%%ecx) nt"
  2222. PREFETCH" 32(%%ecx) nt"
  2223. PREFETCH" 64(%%ecx) nt"
  2224. #define FUNNY_UV_CODE 
  2225. "movl (%%ebx), %%esi nt"
  2226. "call *%4 nt"
  2227. "addl (%%ebx, %%eax), %%ecx nt"
  2228. "addl %%eax, %%edi nt"
  2229. "xorl %%eax, %%eax nt"
  2230. FUNNY_UV_CODE
  2231. FUNNY_UV_CODE
  2232. FUNNY_UV_CODE
  2233. FUNNY_UV_CODE
  2234. "xorl %%eax, %%eax nt" // i
  2235. "movl %5, %%ecx nt" // src
  2236. "movl %1, %%edi nt" // buf1
  2237. "addl $4096, %%edi nt"
  2238. PREFETCH" (%%ecx) nt"
  2239. PREFETCH" 32(%%ecx) nt"
  2240. PREFETCH" 64(%%ecx) nt"
  2241. FUNNY_UV_CODE
  2242. FUNNY_UV_CODE
  2243. FUNNY_UV_CODE
  2244. FUNNY_UV_CODE
  2245. :: "m" (src1), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),
  2246. "m" (funnyUVCode), "m" (src2)
  2247. : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
  2248. );
  2249. for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
  2250. {
  2251. // printf("%d %d %dn", dstWidth, i, srcW);
  2252. dst[i] = src1[srcW-1]*128;
  2253. dst[i+2048] = src2[srcW-1]*128;
  2254. }
  2255. }
  2256. else
  2257. {
  2258. #endif
  2259. asm volatile(
  2260. "xorl %%eax, %%eax nt" // i
  2261. "xorl %%ebx, %%ebx nt" // xx
  2262. "xorl %%ecx, %%ecx nt" // 2*xalpha
  2263. ".balign 16 nt"
  2264. "1: nt"
  2265. "movl %0, %%esi nt"
  2266. "movzbl  (%%esi, %%ebx), %%edi nt" //src[xx]
  2267. "movzbl 1(%%esi, %%ebx), %%esi nt" //src[xx+1]
  2268. "subl %%edi, %%esi nt" //src[xx+1] - src[xx]
  2269. "imull %%ecx, %%esi nt" //(src[xx+1] - src[xx])*2*xalpha
  2270. "shll $16, %%edi nt"
  2271. "addl %%edi, %%esi nt" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
  2272. "movl %1, %%edi nt"
  2273. "shrl $9, %%esi nt"
  2274. "movw %%si, (%%edi, %%eax, 2) nt"
  2275. "movzbl  (%5, %%ebx), %%edi nt" //src[xx]
  2276. "movzbl 1(%5, %%ebx), %%esi nt" //src[xx+1]
  2277. "subl %%edi, %%esi nt" //src[xx+1] - src[xx]
  2278. "imull %%ecx, %%esi nt" //(src[xx+1] - src[xx])*2*xalpha
  2279. "shll $16, %%edi nt"
  2280. "addl %%edi, %%esi nt" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
  2281. "movl %1, %%edi nt"
  2282. "shrl $9, %%esi nt"
  2283. "movw %%si, 4096(%%edi, %%eax, 2)nt"
  2284. "addw %4, %%cx nt" //2*xalpha += xInc&0xFF
  2285. "adcl %3, %%ebx nt" //xx+= xInc>>8 + carry
  2286. "addl $1, %%eax nt"
  2287. "cmpl %2, %%eax nt"
  2288. " jb 1b nt"
  2289. :: "m" (src1), "m" (dst), "m" (dstWidth), "m" (xInc>>16), "m" (xInc&0xFFFF),
  2290. "r" (src2)
  2291. : "%eax", "%ebx", "%ecx", "%edi", "%esi"
  2292. );
  2293. #ifdef HAVE_MMX2
  2294. } //if MMX2 can't be used
  2295. #endif
  2296. #else
  2297. int i;
  2298. unsigned int xpos=0;
  2299. for(i=0;i<dstWidth;i++)
  2300. {
  2301. register unsigned int xx=xpos>>16;
  2302. register unsigned int xalpha=(xpos&0xFFFF)>>9;
  2303. dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
  2304. dst[i+2048]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
  2305. /* slower
  2306.   dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha;
  2307.   dst[i+2048]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha;
  2308. */
  2309. xpos+=xInc;
  2310. }
  2311. #endif
  2312.    }
  2313. }
  2314. static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
  2315.              int srcSliceH, uint8_t* dst[], int dstStride[]){
  2316. /* load a few things into local vars to make the code more readable? and faster */
  2317. const int srcW= c->srcW;
  2318. const int dstW= c->dstW;
  2319. const int dstH= c->dstH;
  2320. const int chrDstW= c->chrDstW;
  2321. const int chrSrcW= c->chrSrcW;
  2322. const int lumXInc= c->lumXInc;
  2323. const int chrXInc= c->chrXInc;
  2324. const int dstFormat= c->dstFormat;
  2325. const int srcFormat= c->srcFormat;
  2326. const int flags= c->flags;
  2327. const int canMMX2BeUsed= c->canMMX2BeUsed;
  2328. int16_t *vLumFilterPos= c->vLumFilterPos;
  2329. int16_t *vChrFilterPos= c->vChrFilterPos;
  2330. int16_t *hLumFilterPos= c->hLumFilterPos;
  2331. int16_t *hChrFilterPos= c->hChrFilterPos;
  2332. int16_t *vLumFilter= c->vLumFilter;
  2333. int16_t *vChrFilter= c->vChrFilter;
  2334. int16_t *hLumFilter= c->hLumFilter;
  2335. int16_t *hChrFilter= c->hChrFilter;
  2336. int32_t *lumMmxFilter= c->lumMmxFilter;
  2337. int32_t *chrMmxFilter= c->chrMmxFilter;
  2338. const int vLumFilterSize= c->vLumFilterSize;
  2339. const int vChrFilterSize= c->vChrFilterSize;
  2340. const int hLumFilterSize= c->hLumFilterSize;
  2341. const int hChrFilterSize= c->hChrFilterSize;
  2342. int16_t **lumPixBuf= c->lumPixBuf;
  2343. int16_t **chrPixBuf= c->chrPixBuf;
  2344. const int vLumBufSize= c->vLumBufSize;
  2345. const int vChrBufSize= c->vChrBufSize;
  2346. uint8_t *funnyYCode= c->funnyYCode;
  2347. uint8_t *funnyUVCode= c->funnyUVCode;
  2348. uint8_t *formatConvBuffer= c->formatConvBuffer;
  2349. const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
  2350. const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
  2351. int lastDstY;
  2352. /* vars whch will change and which we need to storw back in the context */
  2353. int dstY= c->dstY;
  2354. int lumBufIndex= c->lumBufIndex;
  2355. int chrBufIndex= c->chrBufIndex;
  2356. int lastInLumBuf= c->lastInLumBuf;
  2357. int lastInChrBuf= c->lastInChrBuf;
  2358. if(isPacked(c->srcFormat)){
  2359. src[0]=
  2360. src[1]=
  2361. src[2]= src[0];
  2362. srcStride[0]=
  2363. srcStride[1]=
  2364. srcStride[2]= srcStride[0];
  2365. }
  2366. srcStride[1]<<= c->vChrDrop;
  2367. srcStride[2]<<= c->vChrDrop;
  2368. // printf("swscale %X %X %X -> %X %X %Xn", (int)src[0], (int)src[1], (int)src[2],
  2369. // (int)dst[0], (int)dst[1], (int)dst[2]);
  2370. #if 0 //self test FIXME move to a vfilter or something
  2371. {
  2372. static volatile int i=0;
  2373. i++;
  2374. if(srcFormat==IMGFMT_YV12 && i==1 && srcSliceH>= c->srcH)
  2375. selfTest(src, srcStride, c->srcW, c->srcH);
  2376. i--;
  2377. }
  2378. #endif
  2379. //printf("sws Strides:%d %d %d -> %d %d %dn", srcStride[0],srcStride[1],srcStride[2],
  2380. //dstStride[0],dstStride[1],dstStride[2]);
  2381. if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0)
  2382. {
  2383. static int firstTime=1; //FIXME move this into the context perhaps
  2384. if(flags & SWS_PRINT_INFO && firstTime)
  2385. {
  2386. MSG_WARN("SwScaler: Warning: dstStride is not aligned!n"
  2387. "SwScaler:          ->cannot do aligned memory acesses anymoren");
  2388. firstTime=0;
  2389. }
  2390. }
  2391. /* Note the user might start scaling the picture in the middle so this will not get executed
  2392.    this is not really intended but works currently, so ppl might do it */
  2393. if(srcSliceY ==0){
  2394. lumBufIndex=0;
  2395. chrBufIndex=0;
  2396. dstY=0;
  2397. lastInLumBuf= -1;
  2398. lastInChrBuf= -1;
  2399. }
  2400. lastDstY= dstY;
  2401. for(;dstY < dstH; dstY++){
  2402. unsigned char *dest =dst[0]+dstStride[0]*dstY;
  2403. const int chrDstY= dstY>>c->chrDstVSubSample;
  2404. unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
  2405. unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
  2406. const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
  2407. const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
  2408. const int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
  2409. const int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
  2410. //printf("dstY:%d dstH:%d firstLumSrcY:%d lastInLumBuf:%d vLumBufSize: %d vChrBufSize: %d slice: %d %d vLumFilterSize: %d firstChrSrcY: %d vChrFilterSize: %d c->chrSrcVSubSample: %dn",
  2411. // dstY, dstH, firstLumSrcY, lastInLumBuf, vLumBufSize, vChrBufSize, srcSliceY, srcSliceH, vLumFilterSize, firstChrSrcY, vChrFilterSize,  c->chrSrcVSubSample);
  2412. //handle holes (FAST_BILINEAR & weird filters)
  2413. if(firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
  2414. if(firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
  2415. //printf("%d %d %dn", firstChrSrcY, lastInChrBuf, vChrBufSize);
  2416. ASSERT(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1)
  2417. ASSERT(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1)
  2418. // Do we have enough lines in this slice to output the dstY line
  2419. if(lastLumSrcY < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample))
  2420. {
  2421. //Do horizontal scaling
  2422. while(lastInLumBuf < lastLumSrcY)
  2423. {
  2424. uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
  2425. lumBufIndex++;
  2426. // printf("%d %d %d %dn", lumBufIndex, vLumBufSize, lastInLumBuf,  lastLumSrcY);
  2427. ASSERT(lumBufIndex < 2*vLumBufSize)
  2428. ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH)
  2429. ASSERT(lastInLumBuf + 1 - srcSliceY >= 0)
  2430. // printf("%d %dn", lumBufIndex, vLumBufSize);
  2431. RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc,
  2432. flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize,
  2433. funnyYCode, c->srcFormat, formatConvBuffer, 
  2434. c->lumMmx2Filter, c->lumMmx2FilterPos);
  2435. lastInLumBuf++;
  2436. }
  2437. while(lastInChrBuf < lastChrSrcY)
  2438. {
  2439. uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
  2440. uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
  2441. chrBufIndex++;
  2442. ASSERT(chrBufIndex < 2*vChrBufSize)
  2443. ASSERT(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH))
  2444. ASSERT(lastInChrBuf + 1 - chrSrcSliceY >= 0)
  2445. //FIXME replace parameters through context struct (some at least)
  2446. if(!(isGray(srcFormat) || isGray(dstFormat)))
  2447. RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc,
  2448. flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize,
  2449. funnyUVCode, c->srcFormat, formatConvBuffer, 
  2450. c->chrMmx2Filter, c->chrMmx2FilterPos);
  2451. lastInChrBuf++;
  2452. }
  2453. //wrap buf index around to stay inside the ring buffer
  2454. if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize;
  2455. if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize;
  2456. }
  2457. else // not enough lines left in this slice -> load the rest in the buffer
  2458. {
  2459. /* printf("%d %d Last:%d %d LastInBuf:%d %d Index:%d %d Y:%d FSize: %d %d BSize: %d %dn",
  2460. firstChrSrcY,firstLumSrcY,lastChrSrcY,lastLumSrcY,
  2461. lastInChrBuf,lastInLumBuf,chrBufIndex,lumBufIndex,dstY,vChrFilterSize,vLumFilterSize,
  2462. vChrBufSize, vLumBufSize);*/
  2463. //Do horizontal scaling
  2464. while(lastInLumBuf+1 < srcSliceY + srcSliceH)
  2465. {
  2466. uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
  2467. lumBufIndex++;
  2468. ASSERT(lumBufIndex < 2*vLumBufSize)
  2469. ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH)
  2470. ASSERT(lastInLumBuf + 1 - srcSliceY >= 0)
  2471. RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc,
  2472. flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize,
  2473. funnyYCode, c->srcFormat, formatConvBuffer, 
  2474. c->lumMmx2Filter, c->lumMmx2FilterPos);
  2475. lastInLumBuf++;
  2476. }
  2477. while(lastInChrBuf+1 < (chrSrcSliceY + chrSrcSliceH))
  2478. {
  2479. uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
  2480. uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
  2481. chrBufIndex++;
  2482. ASSERT(chrBufIndex < 2*vChrBufSize)
  2483. ASSERT(lastInChrBuf + 1 - chrSrcSliceY < chrSrcSliceH)
  2484. ASSERT(lastInChrBuf + 1 - chrSrcSliceY >= 0)
  2485. if(!(isGray(srcFormat) || isGray(dstFormat)))
  2486. RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc,
  2487. flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize,
  2488. funnyUVCode, c->srcFormat, formatConvBuffer, 
  2489. c->chrMmx2Filter, c->chrMmx2FilterPos);
  2490. lastInChrBuf++;
  2491. }
  2492. //wrap buf index around to stay inside the ring buffer
  2493. if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize;
  2494. if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize;
  2495. break; //we can't output a dstY line so let's try with the next slice
  2496. }
  2497. #ifdef HAVE_MMX
  2498. b5Dither= dither8[dstY&1];
  2499. g6Dither= dither4[dstY&1];
  2500. g5Dither= dither8[dstY&1];
  2501. r5Dither= dither8[(dstY+1)&1];
  2502. #endif
  2503.     if(dstY < dstH-2)
  2504.     {
  2505. int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
  2506. int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
  2507. #ifdef HAVE_MMX
  2508. int i;
  2509. for(i=0; i<vLumFilterSize; i++)
  2510. {
  2511. lumMmxFilter[4*i+0]= (int32_t)lumSrcPtr[i];
  2512. lumMmxFilter[4*i+2]= 
  2513. lumMmxFilter[4*i+3]= 
  2514. ((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001;
  2515. }
  2516. for(i=0; i<vChrFilterSize; i++)
  2517. {
  2518. chrMmxFilter[4*i+0]= (int32_t)chrSrcPtr[i];
  2519. chrMmxFilter[4*i+2]= 
  2520. chrMmxFilter[4*i+3]= 
  2521. ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;
  2522. }
  2523. #endif
  2524. if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like
  2525. {
  2526. const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
  2527. if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
  2528. if(vLumFilterSize == 1 && vChrFilterSize == 1) // Unscaled YV12
  2529. {
  2530. int16_t *lumBuf = lumPixBuf[0];
  2531. int16_t *chrBuf= chrPixBuf[0];
  2532. RENAME(yuv2yuv1)(lumBuf, chrBuf, dest, uDest, vDest, dstW, chrDstW);
  2533. }
  2534. else //General YV12
  2535. {
  2536. RENAME(yuv2yuvX)(c,
  2537. vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
  2538. vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
  2539. dest, uDest, vDest, dstW, chrDstW);
  2540. }
  2541. }
  2542. else
  2543. {
  2544. ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
  2545. ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
  2546. if(vLumFilterSize == 1 && vChrFilterSize == 2) //Unscaled RGB
  2547. {
  2548. int chrAlpha= vChrFilter[2*dstY+1];
  2549. RENAME(yuv2packed1)(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1),
  2550.  dest, dstW, chrAlpha, dstFormat, flags, dstY);
  2551. }
  2552. else if(vLumFilterSize == 2 && vChrFilterSize == 2) //BiLinear Upscale RGB
  2553. {
  2554. int lumAlpha= vLumFilter[2*dstY+1];
  2555. int chrAlpha= vChrFilter[2*dstY+1];
  2556. RENAME(yuv2packed2)(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1),
  2557.  dest, dstW, lumAlpha, chrAlpha, dstY);
  2558. }
  2559. else //General RGB
  2560. {
  2561. RENAME(yuv2packedX)(c,
  2562. vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
  2563. vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
  2564. dest, dstW, dstY);
  2565. }
  2566. }
  2567.             }
  2568.     else // hmm looks like we can't use MMX here without overwriting this array's tail
  2569.     {
  2570. int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
  2571. int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
  2572. if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12
  2573. {
  2574. const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
  2575. if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
  2576. yuv2yuvXinC(
  2577. vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
  2578. vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
  2579. dest, uDest, vDest, dstW, chrDstW);
  2580. }
  2581. else
  2582. {
  2583. ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
  2584. ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
  2585. yuv2packedXinC(c, 
  2586. vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
  2587. vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
  2588. dest, dstW, dstY);
  2589. }
  2590.     }
  2591. }
  2592. #ifdef HAVE_MMX
  2593. __asm __volatile(SFENCE:::"memory");
  2594. __asm __volatile(EMMS:::"memory");
  2595. #endif
  2596. /* store changed local vars back in the context */
  2597. c->dstY= dstY;
  2598. c->lumBufIndex= lumBufIndex;
  2599. c->chrBufIndex= chrBufIndex;
  2600. c->lastInLumBuf= lastInLumBuf;
  2601. c->lastInChrBuf= lastInChrBuf;
  2602. return dstY - lastDstY;
  2603. }