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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;/******************************************************************************
  2. ; *                                                                            *
  3. ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *
  4. ; *                                                                            *
  5. ; *  XviD is an implementation of a part of one or more MPEG-4 Video tools     *
  6. ; *  as specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  7. ; *  software module in hardware or software products are advised that its     *
  8. ; *  use may infringe existing patents or copyrights, and any such use         *
  9. ; *  would be at such party's own risk.  The original developer of this        *
  10. ; *  software module and his/her company, and subsequent editors and their     *
  11. ; *  companies, will have no liability for use of this software or             *
  12. ; *  modifications or derivatives thereof.                                     *
  13. ; *                                                                            *
  14. ; *  XviD is free software; you can redistribute it and/or modify it           *
  15. ; *  under the terms of the GNU General Public License as published by         *
  16. ; *  the Free Software Foundation; either version 2 of the License, or         *
  17. ; *  (at your option) any later version.                                       *
  18. ; *                                                                            *
  19. ; *  XviD is distributed in the hope that it will be useful, but               *
  20. ; *  WITHOUT ANY WARRANTY; without even the implied warranty of                *
  21. ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
  22. ; *  GNU General Public License for more details.                              *
  23. ; *                                                                            *
  24. ; *  You should have received a copy of the GNU General Public License         *
  25. ; *  along with this program; if not, write to the Free Software               *
  26. ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *
  27. ; *                                                                            *
  28. ; ******************************************************************************/
  29. ;
  30. ;/******************************************************************************
  31. ; *                                                                            *
  32. ; *  yuv_to_rgb32.asm, MMX optimized color conversion                          *
  33. ; *                                                                            *
  34. ; *  Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org>,                 *
  35. ; *                                                                            *
  36. ; *  For more information visit the XviD homepage: http://www.xvid.org         *
  37. ; *                                                                            *
  38. ; ******************************************************************************/
  39. ;
  40. ;/******************************************************************************
  41. ; *                                                                            *
  42. ; *  Revision history:                                                         *
  43. ; *                                                                            *
  44. ; *  13.12.2001 initial version  (Isibaar)                                     *
  45. ; *                                                                            *
  46. ; ******************************************************************************/
  47. ; //NOTE: In contrary to the c implementation this code does the conversion
  48. ;   using direct calculations. Input data width must be a multiple of 8
  49. ;         and height must be even.
  50. ;   This implementation is less precise than the c version but is
  51. ;         more than twice as fast :-)
  52. bits 32
  53. %macro cglobal 1 
  54. %ifdef PREFIX
  55. global _%1 
  56. %define %1 _%1
  57. %else
  58. global %1
  59. %endif
  60. %endmacro
  61. %define SCALEBITS 6
  62. ALIGN 16
  63. section .data
  64. TEMP_Y1 dd 0,0
  65. TEMP_Y2 dd 0,0
  66. TEMP_G1 dd 0,0
  67. TEMP_G2 dd 0,0
  68. TEMP_B1 dd 0,0
  69. TEMP_B2 dd 0,0
  70. y_dif dd 0
  71. dst_dif dd 0
  72. uv_dif dd 0
  73. height dd 0
  74. width_8 dd 0
  75. height_2 dd 0
  76. Y_SUB dw  16,  16,  16,  16
  77. U_SUB dw 128, 128, 128, 128
  78. V_SUB dw 128, 128, 128, 128
  79. Y_MUL dw  74,  74,  74,  74
  80. UG_MUL dw  25,  25,  25,  25
  81. VG_MUL dw  52,  52,  52,  52
  82. UB_MUL dw 129, 129, 129, 129
  83. VR_MUL dw 102, 102, 102, 102
  84. section .text
  85. ;void yv12_to_rgb32_mmx(uint8_t *dst, int dst_stride,
  86. ; uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, 
  87. ; int y_stride, int uv_stride,
  88. ; int width, int height)
  89. cglobal yv12_to_rgb32_mmx
  90. yv12_to_rgb32_mmx:
  91. push ebx
  92. push esi
  93. push edi
  94. push ebp
  95. mov eax, [esp + 52] ; height -> eax
  96. cmp eax, 0x00
  97. jge near dont_flip ; flip?
  98. neg eax ; neg height
  99. mov [height], eax
  100. mov esi, [esp + 48] ; width -> esi
  101. mov ebp, [esp + 40] ; y_stride -> ebp
  102. mov ebx, ebp
  103. shl ebx, 1 ; 2 * y_stride -> ebx
  104. neg ebx
  105. sub ebx, esi ; y_dif -> eax
  106. mov [y_dif], ebx
  107. sub eax, 1 ; height - 1 -> eax
  108. mul ebp ; (height - 1) * y_stride -> ebp
  109. mov ecx, eax
  110. mov eax, [esp + 28] ; y_src -> eax
  111. add eax, ecx ; y_src -> eax
  112. mov ebx, eax
  113. sub ebx, ebp ; y_src2 -> ebx
  114. mov ecx, [esp + 24] ; dst_stride -> ecx
  115. mov edx, ecx
  116. shl edx, 3
  117. mov ecx, edx ; 8 * dst_stride -> ecx
  118. shl esi, 2
  119. sub ecx, esi ; 8 * dst_stride - 4 * width -> ecx
  120. mov [dst_dif], ecx
  121. mov esi, [esp + 20] ; dst -> esi
  122. mov edi, esi
  123. shr edx, 1
  124. add edi, edx ; dst2 -> edi
  125. mov ebp, [esp + 48] ; width -> ebp
  126. mov ecx, ebp ; width -> ecx
  127. shr ecx, 1
  128. shr ebp, 3 ; width / 8 -> ebp
  129. mov [width_8], ebp
  130. mov ebp, [esp + 44] ; uv_stride -> ebp
  131. mov edx, ebp
  132. neg edx
  133. sub edx, ecx
  134. mov [uv_dif], edx
  135. mov edx, ebp
  136. mov ebp, eax
  137. mov eax, [height] ; height -> eax
  138. shr eax, 1 ; height / 2 -> eax
  139. mov ecx, [esp + 32] ; u_src -> ecx
  140. sub eax, 1
  141. mul edx
  142. add ecx, eax
  143. mov edx, [esp + 36] ; v_src -> edx
  144. add edx, eax
  145. mov eax, ebp
  146. mov ebp, [height] ; height -> ebp
  147. shr ebp, 1 ; height / 2 -> ebp
  148. pxor mm7, mm7
  149. jmp y_loop
  150. dont_flip:
  151. mov esi, [esp + 48] ; width -> esi
  152. mov ebp, [esp + 40] ; y_stride -> ebp
  153. mov ebx, ebp
  154. shl ebx, 1 ; 2 * y_stride -> ebx
  155. sub ebx, esi ; y_dif -> ebx
  156. mov [y_dif], ebx
  157. mov eax, [esp + 28] ; y_src -> eax
  158. mov ebx, eax
  159. add ebx, ebp ; y_src2 -> ebp
  160. mov ecx, [esp + 24] ; dst_stride -> ecx
  161. shl ecx, 3
  162. mov edx, ecx ; 8 * dst_stride -> edx
  163. shl esi, 2
  164. sub ecx, esi ; 8 * dst_stride - 4 * width -> ecx
  165. mov [dst_dif], ecx
  166. mov esi, [esp + 20] ; dst -> esi
  167. mov edi, esi
  168. shr edx, 1
  169. add edi, edx ; dst2 -> edi
  170. mov ebp, [esp + 48] ; width -> ebp
  171. mov ecx, ebp ; width -> ecx
  172. shr ecx, 1
  173. shr ebp, 3 ; width / 8 -> ebp
  174. mov [width_8], ebp
  175. mov ebp, [esp + 44] ; uv_stride -> ebp
  176. sub ebp, ecx
  177. mov [uv_dif], ebp
  178. mov ecx, [esp + 32] ; u_src -> ecx
  179. mov edx, [esp + 36] ; v_src -> edx
  180. mov ebp, [esp + 52] ; height -> ebp
  181. shr ebp, 1 ; height / 2 -> ebp
  182. pxor mm7, mm7
  183. y_loop:
  184. mov [height_2], ebp
  185. mov ebp, [width_8]
  186. x_loop:
  187. movd mm2, [ecx]
  188. movd mm3, [edx]
  189. punpcklbw mm2, mm7 ; u3u2u1u0 -> mm2
  190. punpcklbw mm3, mm7 ; v3v2v1v0 -> mm3
  191. psubsw mm2, [U_SUB] ; U - 128
  192. psubsw mm3, [V_SUB] ; V - 128
  193. movq mm4, mm2
  194. movq mm5, mm3
  195. pmullw mm2, [UG_MUL]
  196. pmullw mm3, [VG_MUL]
  197. movq mm6, mm2 ; u3u2u1u0 -> mm6
  198. punpckhwd mm2, mm2 ; u3u3u2u2 -> mm2
  199. punpcklwd mm6, mm6 ; u1u1u0u0 -> mm6
  200. pmullw mm4, [UB_MUL] ; B_ADD -> mm4
  201. movq mm0, mm3
  202. punpckhwd mm3, mm3 ; v3v3v2v2 -> mm2
  203. punpcklwd mm0, mm0 ; v1v1v0v0 -> mm6
  204. paddsw mm2, mm3
  205. paddsw mm6, mm0
  206. pmullw mm5, [VR_MUL] ; R_ADD -> mm5
  207. movq mm0, [eax] ; y7y6y5y4y3y2y1y0 -> mm0
  208. movq mm1, mm0
  209. punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
  210. punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
  211. psubsw mm0, [Y_SUB] ; Y - Y_SUB
  212. psubsw mm1, [Y_SUB] ; Y - Y_SUB
  213. pmullw mm1, [Y_MUL] 
  214. pmullw mm0, [Y_MUL]
  215. movq [TEMP_Y2], mm1 ; y7y6y5y4 -> mm3
  216. movq [TEMP_Y1], mm0 ; y3y2y1y0 -> mm7
  217. psubsw mm1, mm2 ; g7g6g5g4 -> mm1
  218. psubsw mm0, mm6 ; g3g2g1g0 -> mm0
  219. psraw mm1, SCALEBITS
  220. psraw mm0, SCALEBITS
  221. packuswb mm0, mm1 ;g7g6g5g4g3g2g1g0 -> mm0
  222. movq [TEMP_G1], mm0
  223. movq mm0, [ebx] ; y7y6y5y4y3y2y1y0 -> mm0
  224. movq mm1, mm0
  225. punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
  226. punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
  227. psubsw mm0, [Y_SUB] ; Y - Y_SUB
  228. psubsw mm1, [Y_SUB] ; Y - Y_SUB
  229. pmullw mm1, [Y_MUL] 
  230. pmullw mm0, [Y_MUL]
  231. movq mm3, mm1
  232. psubsw mm1, mm2 ; g7g6g5g4 -> mm1
  233. movq mm2, mm0
  234. psubsw mm0, mm6 ; g3g2g1g0 -> mm0
  235. psraw mm1, SCALEBITS
  236. psraw mm0, SCALEBITS
  237. packuswb mm0, mm1 ; g7g6g5g4g3g2g1g0 -> mm0
  238. movq [TEMP_G2], mm0
  239. movq mm0, mm4
  240. punpckhwd mm4, mm4 ; u3u3u2u2 -> mm2
  241. punpcklwd mm0, mm0 ; u1u1u0u0 -> mm6
  242. movq mm1, mm3 ; y7y6y5y4 -> mm1
  243. paddsw mm3, mm4 ; b7b6b5b4 -> mm3
  244. movq mm7, mm2 ; y3y2y1y0 -> mm7
  245. paddsw mm2, mm0 ; b3b2b1b0 -> mm2
  246. psraw mm3, SCALEBITS
  247. psraw mm2, SCALEBITS
  248. packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
  249. movq [TEMP_B2], mm2
  250. movq mm3, [TEMP_Y2]
  251. movq mm2, [TEMP_Y1]
  252. movq mm6, mm3 ; TEMP_Y2 -> mm6
  253. paddsw mm3, mm4 ; b7b6b5b4 -> mm3
  254. movq mm4, mm2 ; TEMP_Y1 -> mm4
  255. paddsw mm2, mm0 ; b3b2b1b0 -> mm2
  256. psraw mm3, SCALEBITS
  257. psraw mm2, SCALEBITS
  258. packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
  259. movq [TEMP_B1], mm2
  260. movq mm0, mm5
  261. punpckhwd mm5, mm5 ; v3v3v2v2 -> mm5
  262. punpcklwd mm0, mm0 ; v1v1v0v0 -> mm0
  263. paddsw mm1, mm5 ; r7r6r5r4 -> mm1
  264. paddsw mm7, mm0 ; r3r2r1r0 -> mm7
  265. psraw mm1, SCALEBITS
  266. psraw mm7, SCALEBITS
  267. packuswb mm7, mm1 ; r7r6r5r4r3r2r1r0 -> mm7 (TEMP_R2)
  268. paddsw mm6, mm5 ; r7r6r5r4 -> mm6
  269. paddsw mm4, mm0 ; r3r2r1r0 -> mm4
  270. psraw mm6, SCALEBITS
  271. psraw mm4, SCALEBITS
  272. packuswb mm4, mm6 ; r7r6r5r4r3r2r1r0 -> mm4 (TEMP_R1)
  273. movq mm0, [TEMP_B1]
  274. movq mm1, [TEMP_G1]
  275. movq mm6, mm7
  276. movq mm2, mm0
  277. punpcklbw mm2, mm4 ; r3b3r2b2r1b1r0b0 -> mm2
  278. punpckhbw mm0, mm4 ; r7b7r6b6r5b5r4b4 -> mm0
  279. pxor mm7, mm7
  280. movq mm3, mm1
  281. punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
  282. punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
  283. movq mm4, mm2
  284. punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
  285. punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
  286. movq mm5, mm0
  287. punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
  288. punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
  289. movq [esi], mm2
  290. movq [esi + 8], mm4
  291. movq [esi + 16], mm0
  292. movq [esi + 24], mm5
  293. movq mm0, [TEMP_B2]
  294. movq mm1, [TEMP_G2]
  295. movq mm2, mm0
  296. punpcklbw mm2, mm6 ; r3b3r2b2r1b1r0b0 -> mm2
  297. punpckhbw mm0, mm6 ; r7b7r6b6r5b5r4b4 -> mm0
  298. movq mm3, mm1 
  299. punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
  300. punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
  301. movq mm4, mm2
  302. punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
  303. punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
  304. movq mm5, mm0
  305. punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
  306. punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
  307. movq [edi], mm2
  308. movq [edi + 8], mm4
  309. movq [edi + 16], mm0
  310. movq [edi + 24], mm5
  311. add esi, 32
  312. add edi, 32
  313. add eax, 8
  314. add ebx, 8
  315. add ecx, 4
  316. add edx, 4
  317. dec ebp
  318. jnz near x_loop
  319. add esi, [dst_dif]
  320. add edi, [dst_dif]
  321. add eax, [y_dif]
  322. add ebx, [y_dif]
  323. add ecx, [uv_dif]
  324. add edx, [uv_dif]
  325. mov ebp, [height_2]
  326. dec ebp
  327. jnz near y_loop
  328. emms
  329. pop ebp
  330. pop edi
  331. pop esi
  332. pop ebx
  333. ret