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

流媒体/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_rgb24.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_rgb24_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_rgb24_mmx
  90. yv12_to_rgb24_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
  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. add ecx, edx
  117. shl edx, 2
  118. add ecx, edx ; 6 * dst_stride -> ecx
  119. mov edx, ecx
  120. sub ecx, esi
  121. shl esi, 1
  122. sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx
  123. mov [dst_dif], ecx
  124. mov esi, [esp + 20] ; dst -> esi
  125. mov edi, esi
  126. shr edx, 1
  127. add edi, edx ; dst2 -> edi
  128. mov ebp, [esp + 48] ; width -> ebp
  129. mov ecx, ebp ; width -> ecx
  130. shr ecx, 1
  131. shr ebp, 3 ; width / 8 -> ebp
  132. mov [width_8], ebp
  133. mov ebp, [esp + 44] ; uv_stride -> ebp
  134. mov edx, ebp
  135. neg edx
  136. sub edx, ecx
  137. mov [uv_dif], edx
  138. mov edx, ebp
  139. mov ebp, eax
  140. mov eax, [height] ; height -> eax
  141. shr eax, 1 ; height / 2 -> eax
  142. mov ecx, [esp + 32] ; u_src -> ecx
  143. sub eax, 1
  144. mul edx
  145. add ecx, eax
  146. mov edx, [esp + 36] ; v_src -> edx
  147. add edx, eax
  148. mov eax, ebp
  149. mov ebp, [height] ; height -> ebp
  150. shr ebp, 1 ; height / 2 -> ebp
  151. pxor mm7, mm7 ; clear mm7
  152. jmp y_loop
  153. dont_flip:
  154. mov esi, [esp + 48] ; width -> esi
  155. mov ebp, [esp + 40] ; y_stride -> ebp
  156. mov ebx, ebp
  157. shl ebx, 1 ; 2 * y_stride -> ebx
  158. sub ebx, esi ; y_dif -> ebx
  159. mov [y_dif], ebx
  160. mov eax, [esp + 28] ; y_src -> eax
  161. mov ebx, eax
  162. add ebx, ebp ; y_src2 -> ebp
  163. mov ecx, [esp + 24] ; dst_stride -> ecx
  164. mov edx, ecx
  165. add ecx, edx
  166. shl edx, 2
  167. add ecx, edx ; 6 * dst_stride -> ecx
  168. mov edx, ecx
  169. sub ecx, esi
  170. shl esi, 1
  171. sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx
  172. mov [dst_dif], ecx
  173. mov esi, [esp + 20] ; dst -> esi
  174. mov edi, esi
  175. shr edx, 1
  176. add edi, edx ; dst2 -> edi
  177. mov ebp, [esp + 48] ; width -> ebp
  178. mov ecx, ebp ; width -> ecx
  179. shr ecx, 1
  180. shr ebp, 3 ; width / 8 -> ebp
  181. mov [width_8], ebp
  182. mov ebp, [esp + 44] ; uv_stride -> ebp
  183. sub ebp, ecx
  184. mov [uv_dif], ebp
  185. mov ecx, [esp + 32] ; u_src -> ecx
  186. mov edx, [esp + 36] ; v_src -> edx
  187. mov ebp, [esp + 52] ; height -> ebp
  188. shr ebp, 1 ; height / 2 -> ebp
  189. pxor mm7, mm7
  190. y_loop:
  191. mov [height_2], ebp
  192. mov ebp, [width_8]
  193. x_loop:
  194. movd mm2, [ecx]
  195. movd mm3, [edx]
  196. punpcklbw mm2, mm7 ; u3u2u1u0 -> mm2
  197. punpcklbw mm3, mm7 ; v3v2v1v0 -> mm3
  198. psubsw mm2, [U_SUB] ; U - 128
  199. psubsw mm3, [V_SUB] ; V - 128
  200. movq mm4, mm2
  201. movq mm5, mm3
  202. pmullw mm2, [UG_MUL]
  203. pmullw mm3, [VG_MUL]
  204. movq mm6, mm2 ; u3u2u1u0 -> mm6
  205. punpckhwd mm2, mm2 ; u3u3u2u2 -> mm2
  206. punpcklwd mm6, mm6 ; u1u1u0u0 -> mm6
  207. pmullw mm4, [UB_MUL] ; B_ADD -> mm4
  208. movq mm0, mm3
  209. punpckhwd mm3, mm3 ; v3v3v2v2 -> mm2
  210. punpcklwd mm0, mm0 ; v1v1v0v0 -> mm6
  211. paddsw mm2, mm3
  212. paddsw mm6, mm0
  213. pmullw mm5, [VR_MUL] ; R_ADD -> mm5
  214. movq mm0, [eax] ; y7y6y5y4y3y2y1y0 -> mm0
  215. movq mm1, mm0
  216. punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
  217. punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
  218. psubsw mm0, [Y_SUB] ; Y - Y_SUB
  219. psubsw mm1, [Y_SUB] ; Y - Y_SUB
  220. pmullw mm1, [Y_MUL] 
  221. pmullw mm0, [Y_MUL]
  222. movq [TEMP_Y2], mm1 ; y7y6y5y4 -> mm3
  223. movq [TEMP_Y1], mm0 ; y3y2y1y0 -> mm7
  224. psubsw mm1, mm2 ; g7g6g5g4 -> mm1
  225. psubsw mm0, mm6 ; g3g2g1g0 -> mm0
  226. psraw mm1, SCALEBITS
  227. psraw mm0, SCALEBITS
  228. packuswb mm0, mm1 ;g7g6g5g4g3g2g1g0 -> mm0
  229. movq [TEMP_G1], mm0
  230. movq mm0, [ebx] ; y7y6y5y4y3y2y1y0 -> mm0
  231. movq mm1, mm0
  232. punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1
  233. punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0
  234. psubsw mm0, [Y_SUB] ; Y - Y_SUB
  235. psubsw mm1, [Y_SUB] ; Y - Y_SUB
  236. pmullw mm1, [Y_MUL] 
  237. pmullw mm0, [Y_MUL]
  238. movq mm3, mm1
  239. psubsw mm1, mm2 ; g7g6g5g4 -> mm1
  240. movq mm2, mm0
  241. psubsw mm0, mm6 ; g3g2g1g0 -> mm0
  242. psraw mm1, SCALEBITS
  243. psraw mm0, SCALEBITS
  244. packuswb mm0, mm1 ; g7g6g5g4g3g2g1g0 -> mm0
  245. movq [TEMP_G2], mm0
  246. movq mm0, mm4
  247. punpckhwd mm4, mm4 ; u3u3u2u2 -> mm2
  248. punpcklwd mm0, mm0 ; u1u1u0u0 -> mm6
  249. movq mm1, mm3 ; y7y6y5y4 -> mm1
  250. paddsw mm3, mm4 ; b7b6b5b4 -> mm3
  251. movq mm7, mm2 ; y3y2y1y0 -> mm7
  252. paddsw mm2, mm0 ; b3b2b1b0 -> mm2
  253. psraw mm3, SCALEBITS
  254. psraw mm2, SCALEBITS
  255. packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
  256. movq [TEMP_B2], mm2
  257. movq mm3, [TEMP_Y2]
  258. movq mm2, [TEMP_Y1]
  259. movq mm6, mm3 ; TEMP_Y2 -> mm6
  260. paddsw mm3, mm4 ; b7b6b5b4 -> mm3
  261. movq mm4, mm2 ; TEMP_Y1 -> mm4
  262. paddsw mm2, mm0 ; b3b2b1b0 -> mm2
  263. psraw mm3, SCALEBITS
  264. psraw mm2, SCALEBITS
  265. packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2
  266. movq [TEMP_B1], mm2
  267. movq mm0, mm5
  268. punpckhwd mm5, mm5 ; v3v3v2v2 -> mm5
  269. punpcklwd mm0, mm0 ; v1v1v0v0 -> mm0
  270. paddsw mm1, mm5 ; r7r6r5r4 -> mm1
  271. paddsw mm7, mm0 ; r3r2r1r0 -> mm7
  272. psraw mm1, SCALEBITS
  273. psraw mm7, SCALEBITS
  274. packuswb mm7, mm1 ; r7r6r5r4r3r2r1r0 -> mm7 (TEMP_R2)
  275. paddsw mm6, mm5 ; r7r6r5r4 -> mm6
  276. paddsw mm4, mm0 ; r3r2r1r0 -> mm4
  277. psraw mm6, SCALEBITS
  278. psraw mm4, SCALEBITS
  279. packuswb mm4, mm6 ; r7r6r5r4r3r2r1r0 -> mm4 (TEMP_R1)
  280. movq mm0, [TEMP_B1]
  281. movq mm1, [TEMP_G1]
  282. movq mm6, mm7
  283. movq mm2, mm0
  284. punpcklbw mm2, mm4 ; r3b3r2b2r1b1r0b0 -> mm2
  285. punpckhbw mm0, mm4 ; r7b7r6b6r5b5r4b4 -> mm0
  286. pxor mm7, mm7
  287. movq mm3, mm1
  288. punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
  289. punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
  290. movq mm4, mm2
  291. punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
  292. punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
  293. movq mm5, mm0
  294. punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
  295. punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
  296. movd [esi], mm2
  297. psrlq mm2, 32
  298. movd [esi + 3], mm2
  299. movd [esi + 6], mm4
  300. psrlq mm4, 32
  301. movd [esi + 9], mm4
  302. movd [esi + 12], mm0
  303. psrlq mm0, 32
  304. movd [esi + 15], mm0
  305. movd [esi + 18], mm5
  306. psrlq mm5, 32
  307. movd [esi + 21], mm5
  308. movq mm0, [TEMP_B2]
  309. movq mm1, [TEMP_G2]
  310. movq mm2, mm0
  311. punpcklbw mm2, mm6 ; r3b3r2b2r1b1r0b0 -> mm2
  312. punpckhbw mm0, mm6 ; r7b7r6b6r5b5r4b4 -> mm0
  313. movq mm3, mm1 
  314. punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1
  315. punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3
  316. movq mm4, mm2
  317. punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2
  318. punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4
  319. movq mm5, mm0
  320. punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0
  321. punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5
  322. movd [edi], mm2
  323. psrlq mm2, 32
  324. movd [edi + 3], mm2
  325. movd [edi + 6], mm4
  326. psrlq mm4, 32
  327. movd [edi + 9], mm4
  328. movd [edi + 12], mm0
  329. psrlq mm0, 32
  330. movd [edi + 15], mm0
  331. movd [edi + 18], mm5
  332. psrlq mm5, 32
  333. movd [edi + 21], mm5
  334. add esi, 24
  335. add edi, 24
  336. add eax, 8
  337. add ebx, 8
  338. add ecx, 4
  339. add edx, 4
  340. dec ebp
  341. jnz near x_loop
  342. add esi, [dst_dif]
  343. add edi, [dst_dif]
  344. add eax, [y_dif]
  345. add ebx, [y_dif]
  346. add ecx, [uv_dif]
  347. add edx, [uv_dif]
  348. mov ebp, [height_2]
  349. dec ebp
  350. jnz near y_loop
  351. emms
  352. pop ebp
  353. pop edi
  354. pop esi
  355. pop ebx
  356. ret