rgb_to_yv12_mmx.asm
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:11k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;/**************************************************************************
  2. ; *
  3. ; * XVID MPEG-4 VIDEO CODEC
  4. ; * mmx colorspace conversions
  5. ; *
  6. ; * This program is an implementation of a part of one or more MPEG-4
  7. ; * Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
  8. ; * to use this software module in hardware or software products are
  9. ; * advised that its use may infringe existing patents or copyrights, and
  10. ; * any such use would be at such party's own risk.  The original
  11. ; * developer of this software module and his/her company, and subsequent
  12. ; * editors and their companies, will have no liability for use of this
  13. ; * software or modifications or derivatives thereof.
  14. ; *
  15. ; * This program is free software; you can redistribute it and/or modify
  16. ; * it under the terms of the GNU General Public License as published by
  17. ; * the Free Software Foundation; either version 2 of the License, or
  18. ; * (at your option) any later version.
  19. ; *
  20. ; * This program is distributed in the hope that it will be useful,
  21. ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. ; * GNU General Public License for more details.
  24. ; *
  25. ; * You should have received a copy of the GNU General Public License
  26. ; * along with this program; if not, write to the Free Software
  27. ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28. ; *
  29. ; *************************************************************************/
  30. ;/**************************************************************************
  31. ; *
  32. ; * History:
  33. ; *
  34. ; * 24.11.2001  added cglobal macro (Isibaar)
  35. ; * 23.11.2001 initial version; (c)2001 peter ross <pross@cs.rmit.edu.au>
  36. ; *
  37. ; *************************************************************************/
  38. bits 32
  39. section .data
  40. %macro cglobal 1 
  41. %ifdef PREFIX
  42. global _%1 
  43. %define %1 _%1
  44. %else
  45. global %1
  46. %endif
  47. %endmacro
  48. align 16
  49. ;===========================================================================
  50. ; yuv constants
  51. ;===========================================================================
  52. %define Y_R 0.257
  53. %define Y_G 0.504
  54. %define Y_B 0.098
  55. %define Y_ADD 16
  56. %define U_R 0.148
  57. %define U_G 0.291
  58. %define U_B 0.439
  59. %define U_ADD 128
  60. %define V_R 0.439
  61. %define V_G 0.368
  62. %define V_B 0.071
  63. %define V_ADD 128
  64. ;===========================================================================
  65. ; multiplication matrices
  66. ;===========================================================================
  67. ; %define SCALEBITS 8
  68. y_mul dw 25 ; FIX(Y_B)
  69. dw 129 ; FIX(Y_G)
  70. dw 66 ; FIX(Y_R)
  71. dw 0
  72. u_mul dw 112 ; FIX(U_B)
  73. dw -74 ; FIX(U_G)
  74. dw -38 ; FIX(U_R)
  75. dw 0
  76. v_mul dw -18 ; FIX(V_B)
  77. dw -94 ; FIX(V_G)
  78. dw 112 ; FIX(V_R)
  79. dw 0
  80. section .text
  81. ;===========================================================================
  82. ;
  83. ; void rgb24_to_yv12_mmx(uint8_t * const y_out,
  84. ; uint8_t * const u_out,
  85. ; uint8_t * const v_out,
  86. ; const uint8_t * const src,
  87. ; const uint32_t width,
  88. ; const uint32_t height,
  89. ; const uint32_t stride)
  90. ;
  91. ; always flips
  92. ;
  93. ;===========================================================================
  94. align 16
  95. cglobal rgb24_to_yv12_mmx
  96. rgb24_to_yv12_mmx
  97. push ebx
  98. push ecx
  99. push esi
  100. push edi
  101. push ebp ; STACK BASE = 20
  102. ; global consants
  103. mov eax, [esp + 20 + 28] ; stride
  104. mov ecx, [esp + 20 + 20] ; width
  105. mov ebx, eax
  106. sub ebx, ecx
  107. shr ebx, 1 ; ebx = (stride-width) / 2;
  108. push ebx ; [esp + 20] = uv_dif
  109. ; STACK BASE = 24
  110. add eax, eax
  111. sub eax, ecx ; eax = 2*stride - width
  112. push eax ; [esp + 16] = y_dif
  113. ; STACK BASE = 28
  114. mov ebx, ecx ; 
  115. shr ebx, 1 ;
  116. push ebx ; [esp + 12] = width/2
  117. ; STACK BASE = 32
  118. mov edx, ecx
  119. add ecx, edx
  120. add ecx, edx ; ecx = 3*width   (use 4 for rgb32)
  121. push ecx ; [esp + 8] = width3
  122. ; STACK BASE = 36
  123. mov edx, ecx
  124. add edx, ecx
  125. add edx, ecx ; edx = 3*width3
  126. push edx ; [esp + 4] = src_dif
  127. ; STACK BASE = 40
  128. mov esi, [esp + 40 + 16] ; src
  129. mov ebp, [esp + 40 + 24] ; eax = height
  130. mov eax, ebp
  131. sub eax, 2
  132. mul ecx
  133. add esi, eax ; src += (height-2) * width3
  134. mov edi, [esp + 40 + 4] ; y_out
  135. mov ecx, [esp + 40 + 8] ; u_out
  136. mov edx, [esp + 40 + 12] ; v_out
  137. movq mm7, [y_mul]
  138. shr ebp, 1 ; ebp = height / 2
  139. push ebp ; [esp+0] = tmp
  140. ; STACK BASE = 44
  141. .yloop
  142. mov ebp, [esp + 12] ; ebp = width /2 
  143. .xloop
  144. ; y_out
  145. mov ebx, [esp + 8] ; ebx = width3
  146. pxor mm4, mm4
  147. pxor mm5, mm5
  148. movd mm0, [esi] ; src[0...]
  149. movd mm2, [esi+ebx] ; src[width3...]
  150. punpcklbw mm0, mm4 ; [  |b |g |r ]
  151. punpcklbw mm2, mm5 ; [  |b |g |r ]
  152. movq mm6, mm0 ; = [  |b4|g4|r4]
  153. paddw mm6, mm2 ; +[  |b4|g4|r4]
  154. pmaddwd mm0, mm7 ; *= Y_MUL
  155. pmaddwd mm2, mm7 ; *= Y_MUL
  156. movq mm4, mm0 ; [r]
  157. movq mm5, mm2 ; [r]
  158. psrlq mm4, 32 ; +[g]
  159. psrlq mm5, 32 ; +[g]
  160. paddd mm0, mm4 ; +[b]
  161. paddd mm2, mm5 ; +[b]
  162. pxor mm4, mm4
  163. pxor mm5, mm5
  164. movd mm1, [esi+3] ; src[4...]
  165. movd mm3, [esi+ebx+3] ; src[width3+4...]
  166. punpcklbw mm1, mm4 ; [  |b |g |r ]
  167. punpcklbw mm3, mm5 ; [  |b |g |r ]
  168. paddw mm6, mm1 ; +[  |b4|g4|r4]
  169. paddw mm6, mm3 ; +[  |b4|g4|r4]
  170. pmaddwd mm1, mm7 ; *= Y_MUL
  171. pmaddwd mm3, mm7 ; *= Y_MUL
  172. movq mm4, mm1 ; [r]
  173. movq mm5, mm3 ; [r]
  174. psrlq mm4, 32 ; +[g]
  175. psrlq mm5, 32 ; +[g]
  176. paddd mm1, mm4 ; +[b]
  177. paddd mm3, mm5 ; +[b]
  178. mov ebx, [esp + 44 + 28] ; stride
  179. movd eax, mm0
  180. shr eax, 8
  181. add eax, Y_ADD
  182. mov [edi + ebx], al
  183. movd eax, mm1
  184. shr eax, 8
  185. add eax, Y_ADD
  186. mov [edi + ebx + 1], al
  187. movd eax, mm2
  188. shr eax, 8
  189. add eax, Y_ADD
  190. mov [edi], al
  191. movd eax, mm3
  192. shr eax, 8
  193. add eax, Y_ADD
  194. mov [edi + 1], al
  195. ; u_out, v_out
  196. movq mm0, mm6 ; = [  |b4|g4|r4]
  197. pmaddwd mm6, [v_mul] ; *= V_MUL
  198. pmaddwd mm0, [u_mul] ; *= U_MUL
  199. movq mm1, mm0
  200. movq mm2, mm6
  201. psrlq mm1, 32
  202. psrlq mm2, 32
  203. paddd mm0, mm1
  204. paddd mm2, mm6
  205. movd eax, mm0
  206. shr eax, 10
  207. add eax, U_ADD
  208. mov [ecx], al
  209. movd eax, mm2
  210. shr eax, 10
  211. add eax, V_ADD
  212. mov [edx], al
  213. add esi, 2 * 3 ; (use 4 for rgb32)
  214. add edi, 2
  215. inc ecx
  216. inc edx
  217. dec ebp
  218. jnz near .xloop
  219. sub esi, [esp + 4] ; src  -= src_dif
  220. add edi, [esp + 16] ; y_out += y_dif
  221. add ecx, [esp + 20] ; u_out += uv_dif
  222. add edx, [esp + 20] ; v_out += uv_dif
  223. dec dword [esp+0]
  224. jnz near .yloop
  225. emms
  226. add esp, 24
  227. pop ebp
  228. pop edi
  229. pop esi
  230. pop ecx
  231. pop ebx
  232. ret
  233. ;===========================================================================
  234. ;
  235. ; void rgb32_to_yv12mmx(uint8_t * const y_out,
  236. ; uint8_t * const u_out,
  237. ; uint8_t * const v_out,
  238. ; const uint8_t * const src,
  239. ; const uint32_t width,
  240. ; const uint32_t height,
  241. ; const uint32_t stride)
  242. ;
  243. ; always flips
  244. ;
  245. ;===========================================================================
  246. align 16
  247. cglobal rgb32_to_yv12_mmx
  248. rgb32_to_yv12_mmx
  249. push ebx
  250. push ecx
  251. push esi
  252. push edi
  253. push ebp ; STACK BASE = 20
  254. ; global consants
  255. mov eax, [esp + 20 + 28] ; stride
  256. mov ecx, [esp + 20 + 20] ; width
  257. mov ebx, eax
  258. sub ebx, ecx
  259. shr ebx, 1 ; ebx = (stride-width) / 2;
  260. push ebx ; [esp + 20] = uv_dif
  261. ; STACK BASE = 24
  262. add eax, eax
  263. sub eax, ecx ; eax = 2*stride - width
  264. push eax ; [esp + 16] = y_dif
  265. ; STACK BASE = 28
  266. mov ebx, ecx ; 
  267. shr ebx, 1 ;
  268. push ebx ; [esp + 12] = width/2
  269. ; STACK BASE = 32
  270. mov edx, ecx
  271. shl ecx, 2 ; ecx = 4*width   (use 4 for rgb32)
  272. push ecx ; [esp + 8] = width4
  273. ; STACK BASE = 36
  274. mov edx, ecx
  275. add edx, ecx
  276. add edx, ecx ; edx = 3*width4
  277. push edx ; [esp + 4] = src_dif
  278. ; STACK BASE = 40
  279. mov esi, [esp + 40 + 16] ; src
  280. mov ebp, [esp + 40 + 24] ; eax = height
  281. mov eax, ebp
  282. sub eax, 2
  283. mul ecx
  284. add esi, eax ; src += (height-2) * width4
  285. mov edi, [esp + 40 + 4] ; y_out
  286. mov ecx, [esp + 40 + 8] ; u_out
  287. mov edx, [esp + 40 + 12] ; v_out
  288. movq mm7, [y_mul]
  289. shr ebp, 1 ; ebp = height / 2
  290. push ebp ; [esp+0] = tmp
  291. ; STACK BASE = 44
  292. .yloop
  293. mov ebp, [esp + 12] ; ebp = width /2 
  294. .xloop
  295. ; y_out
  296. mov ebx, [esp + 8] ; ebx = width4
  297. pxor mm4, mm4
  298. movq mm0, [esi] ; src[4...       |0...     ]
  299. movq mm2, [esi+ebx] ; src[width4+4...|width4...]
  300. movq mm1, mm0
  301. movq mm3, mm2
  302. punpcklbw mm0, mm4 ; [  |b |g |r ]
  303. punpcklbw mm2, mm4 ; [  |b |g |r ]
  304. punpckhbw mm1, mm4 ; [  |b |g |r ]
  305. punpckhbw mm3, mm4 ; [  |b |g |r ]
  306. movq mm6, mm0 ; = [  |b4|g4|r4]
  307. paddw mm6, mm2 ; +[  |b4|g4|r4]
  308. pmaddwd mm0, mm7 ; *= Y_MUL
  309. pmaddwd mm2, mm7 ; *= Y_MUL
  310. movq mm4, mm0 ; [r]
  311. movq mm5, mm2 ; [r]
  312. psrlq mm4, 32 ; +[g]
  313. psrlq mm5, 32 ; +[g]
  314. paddd mm0, mm4 ; +[b]
  315. paddd mm2, mm5 ; +[b]
  316. paddw mm6, mm1 ; +[  |b4|g4|r4]
  317. paddw mm6, mm3 ; +[  |b4|g4|r4]
  318. pmaddwd mm1, mm7 ; *= Y_MUL
  319. pmaddwd mm3, mm7 ; *= Y_MUL
  320. movq mm4, mm1 ; [r]
  321. movq mm5, mm3 ; [r]
  322. psrlq mm4, 32 ; +[g]
  323. psrlq mm5, 32 ; +[g]
  324. paddd mm1, mm4 ; +[b]
  325. paddd mm3, mm5 ; +[b]
  326. mov ebx, [esp + 44 + 28] ; stride
  327. movd eax, mm0
  328. shr eax, 8
  329. add eax, Y_ADD
  330. mov [edi + ebx], al
  331. movd eax, mm1
  332. shr eax, 8
  333. add eax, Y_ADD
  334. mov [edi + ebx + 1], al
  335. movd eax, mm2
  336. shr eax, 8
  337. add eax, Y_ADD
  338. mov [edi], al
  339. movd eax, mm3
  340. shr eax, 8
  341. add eax, Y_ADD
  342. mov [edi + 1], al
  343. ; u_out, v_out
  344. movq mm0, mm6 ; = [  |b4|g4|r4]
  345. pmaddwd mm6, [v_mul] ; *= V_MUL
  346. pmaddwd mm0, [u_mul] ; *= U_MUL
  347. movq mm1, mm0
  348. movq mm2, mm6
  349. psrlq mm1, 32
  350. psrlq mm2, 32
  351. paddd mm0, mm1
  352. paddd mm2, mm6
  353. movd eax, mm0
  354. shr eax, 10
  355. add eax, U_ADD
  356. mov [ecx], al
  357. movd eax, mm2
  358. shr eax, 10
  359. add eax, V_ADD
  360. mov [edx], al
  361. add esi, 2 * 4 ; (use 4 for rgb32)
  362. add edi, 2
  363. inc ecx
  364. inc edx
  365. dec ebp
  366. jnz near .xloop
  367. sub esi, [esp + 4] ; src  -= src_dif
  368. add edi, [esp + 16] ; y_out += y_dif
  369. add ecx, [esp + 20] ; u_out += uv_dif
  370. add edx, [esp + 20] ; v_out += uv_dif
  371. dec dword [esp+0]
  372. jnz near .yloop
  373. emms
  374. add esp, 24
  375. pop ebp
  376. pop edi
  377. pop esi
  378. pop ecx
  379. pop ebx
  380. ret