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

流媒体/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_yuv.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. ; *  24.11.2001 initial version  (Isibaar)                                     *
  45. ; *                                                                            *
  46. ; ******************************************************************************/
  47. BITS 32
  48. %macro cglobal 1 
  49. %ifdef PREFIX
  50. global _%1 
  51. %define %1 _%1
  52. %else
  53. global %1
  54. %endif
  55. %endmacro
  56. SECTION .data
  57. remainder dw 0
  58. SECTION .text
  59. ALIGN 64
  60. ; Attention: This code assumes that width is a multiple of 16
  61. ; This function probably also runs on PentiumII class cpu's
  62. ;;void yuv_to_yv12_xmm(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src,
  63. ;;    int width, int height, int stride);
  64. cglobal yuv_to_yv12_xmm
  65. yuv_to_yv12_xmm:
  66.     push ebx
  67.     push esi
  68.     push edi
  69. push ebp
  70.     mov eax, [esp + 40] ; height -> eax
  71.     mov ebx, [esp + 44] ; stride -> ebx
  72.     mov esi, [esp + 32]  ; src -> esi 
  73.     mov edi, [esp + 20]  ; y_out -> edi 
  74.     mov ecx, [esp + 36]  ; width -> ecx
  75.     sub ebx, ecx ; stride - width -> ebx
  76. mov edx, ecx
  77. mov ebp, ecx
  78. shr edx, 6
  79. mov ecx, edx ; 64 bytes copied per iteration
  80. shl edx, 6
  81. sub ebp, edx ; remainder -> ebp
  82. shr ebp, 4 ; 16 bytes per iteration
  83. add ebp, 1
  84. mov [remainder], ebp
  85. mov edx, ecx
  86. .y_inner_loop:
  87. prefetchnta [esi + 64] ; non temporal prefetch 
  88.     prefetchnta [esi + 96] 
  89.     movq mm1, [esi] ; read from src 
  90.     movq mm2, [esi + 8] 
  91.     movq mm3, [esi + 16] 
  92.     movq mm4, [esi + 24] 
  93.     movq mm5, [esi + 32] 
  94.     movq mm6, [esi + 40] 
  95.     movq mm7, [esi + 48] 
  96.     movq mm0, [esi + 56] 
  97.     movntq [edi], mm1 ; write to y_out 
  98.     movntq [edi + 8], mm2 
  99.     movntq [edi + 16], mm3 
  100.     movntq [edi + 24], mm4 
  101.     movntq [edi + 32], mm5 
  102.     movntq [edi + 40], mm6 
  103.     movntq [edi + 48], mm7 
  104.     movntq [edi + 56], mm0 
  105.     add esi, 64
  106.     add edi, 64 
  107.     dec ecx
  108.     jnz .y_inner_loop    
  109. dec ebp
  110. jz .y_outer_loop
  111. .y_remainder_loop:
  112.     movq mm1, [esi] ; read from src 
  113.     movq mm2, [esi + 8] 
  114.     movntq [edi], mm1 ; write to y_out 
  115.     movntq [edi + 8], mm2 
  116.     add esi, 16
  117.     add edi, 16 
  118. dec ebp
  119. jnz .y_remainder_loop
  120. .y_outer_loop:
  121. mov ebp, [remainder]
  122.     mov ecx, edx
  123.     add edi, ebx
  124.     
  125.     dec eax
  126. jnz near .y_inner_loop
  127.     mov eax, [esp + 40] ; height -> eax
  128.     mov ebx, [esp + 44] ; stride -> ebx
  129.     mov ecx, [esp + 36]   ; width -> ecx
  130.     mov edi, [esp + 24]  ; u_out -> edi 
  131. shr ecx, 1 ; width / 2 -> ecx
  132. shr ebx, 1 ; stride / 2 -> ebx
  133. shr eax, 1 ; height / 2 -> eax
  134.     sub ebx, ecx ; stride / 2 - width / 2 -> ebx
  135. mov edx, ecx
  136. mov ebp, ecx
  137. shr edx, 6
  138. mov ecx, edx ; 64 bytes copied per iteration
  139. shl edx, 6
  140. sub ebp, edx ; remainder -> ebp
  141. shr ebp, 3 ; 8 bytes per iteration
  142. add ebp, 1
  143. mov [remainder], ebp
  144. mov edx, ecx
  145. .u_inner_loop:
  146. prefetchnta [esi + 64] ; non temporal prefetch 
  147.     prefetchnta [esi + 96] 
  148.     movq mm1, [esi] ; read from src 
  149.     movq mm2, [esi + 8] 
  150.     movq mm3, [esi + 16] 
  151.     movq mm4, [esi + 24] 
  152.     movq mm5, [esi + 32] 
  153.     movq mm6, [esi + 40] 
  154.     movq mm7, [esi + 48] 
  155.     movq mm0, [esi + 56] 
  156.     movntq [edi], mm1 ; write to u_out 
  157.     movntq [edi + 8], mm2 
  158.     movntq [edi + 16], mm3 
  159.     movntq [edi + 24], mm4 
  160.     movntq [edi + 32], mm5 
  161.     movntq [edi + 40], mm6 
  162.     movntq [edi + 48], mm7 
  163.     movntq [edi + 56], mm0 
  164.     add esi, 64
  165.     add edi, 64 
  166.     dec ecx
  167.     jnz .u_inner_loop    
  168. dec ebp
  169. jz .u_outer_loop
  170. .u_remainder_loop:
  171.     movq mm1, [esi] ; read from src 
  172.     movntq [edi], mm1 ; write to y_out 
  173.     add esi, 8
  174.     add edi, 8 
  175. dec ebp
  176. jnz .u_remainder_loop
  177. .u_outer_loop:
  178. mov ebp, [remainder]
  179.     mov ecx, edx
  180.     add edi, ebx
  181.     
  182.     dec eax
  183. jnz .u_inner_loop
  184.     mov eax, [esp + 40] ; height -> eax
  185.     mov ecx, [esp + 36]  ; width -> ecx
  186.     mov edi, [esp + 28]  ; v_out -> edi 
  187. shr ecx, 1 ; width / 2 -> ecx
  188. shr eax, 1 ; height / 2 -> eax
  189. mov edx, ecx
  190. mov ebp, ecx
  191. shr edx, 6
  192. mov ecx, edx ; 64 bytes copied per iteration
  193. shl edx, 6
  194. sub ebp, edx ; remainder -> ebp
  195. shr ebp, 3 ; 8 bytes per iteration
  196. add ebp, 1
  197. mov [remainder], ebp
  198. mov edx, ecx
  199. .v_inner_loop:
  200. prefetchnta [esi + 64] ; non temporal prefetch 
  201.     prefetchnta [esi + 96] 
  202.     movq mm1, [esi] ; read from src 
  203.     movq mm2, [esi + 8] 
  204.     movq mm3, [esi + 16] 
  205.     movq mm4, [esi + 24] 
  206.     movq mm5, [esi + 32] 
  207.     movq mm6, [esi + 40] 
  208.     movq mm7, [esi + 48] 
  209.     movq mm0, [esi + 56] 
  210.     movntq [edi], mm1 ; write to u_out 
  211.     movntq [edi + 8], mm2 
  212.     movntq [edi + 16], mm3 
  213.     movntq [edi + 24], mm4 
  214.     movntq [edi + 32], mm5 
  215.     movntq [edi + 40], mm6 
  216.     movntq [edi + 48], mm7 
  217.     movntq [edi + 56], mm0 
  218.     add esi, 64
  219.     add edi, 64 
  220.     dec ecx
  221.     jnz .v_inner_loop    
  222. dec ebp
  223. jz .v_outer_loop
  224. .v_remainder_loop:
  225.     movq mm1, [esi] ; read from src 
  226.     movntq [edi], mm1 ; write to y_out 
  227.     add esi, 8
  228.     add edi, 8 
  229. dec ebp
  230. jnz .v_remainder_loop
  231. .v_outer_loop:
  232. mov ebp, [remainder]
  233.     mov ecx, edx
  234.     add edi, ebx
  235.     
  236.     dec eax
  237. jnz .v_inner_loop
  238. pop ebp
  239.     pop edi
  240.     pop esi
  241.     pop ebx
  242.     
  243.     emms
  244.     ret
  245. ; Attention: This code assumes that width is a multiple of 16
  246. ;;void yuv_to_yv12_mmx(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src,
  247. ;;    int width, int height, int stride);
  248. cglobal yuv_to_yv12_mmx
  249. yuv_to_yv12_mmx:
  250.     push ebx
  251.     push esi
  252.     push edi
  253. push ebp
  254.     mov eax, [esp + 40] ; height -> eax
  255.     mov ebx, [esp + 44] ; stride -> ebx
  256.     mov esi, [esp + 32]  ; src -> esi 
  257.     mov edi, [esp + 20]  ; y_out -> edi 
  258.     mov ecx, [esp + 36]  ; width -> ecx
  259.     sub ebx, ecx ; stride - width -> ebx
  260. mov edx, ecx
  261. mov ebp, ecx
  262. shr edx, 6
  263. mov ecx, edx ; 64 bytes copied per iteration
  264. shl edx, 6
  265. sub ebp, edx ; remainder -> ebp
  266. shr ebp, 4 ; 16 bytes per iteration
  267. add ebp, 1
  268. mov [remainder], ebp
  269. mov edx, ecx
  270. .y_inner_loop:
  271.     movq mm1, [esi] ; read from src 
  272.     movq mm2, [esi + 8] 
  273.     movq mm3, [esi + 16] 
  274.     movq mm4, [esi + 24] 
  275.     movq mm5, [esi + 32] 
  276.     movq mm6, [esi + 40] 
  277.     movq mm7, [esi + 48] 
  278.     movq mm0, [esi + 56] 
  279.     movq [edi], mm1 ; write to y_out 
  280.     movq [edi + 8], mm2 
  281.     movq [edi + 16], mm3 
  282.     movq [edi + 24], mm4 
  283.     movq [edi + 32], mm5 
  284.     movq [edi + 40], mm6 
  285.     movq [edi + 48], mm7 
  286.     movq [edi + 56], mm0 
  287.     add esi, 64
  288.     add edi, 64 
  289.     dec ecx
  290.     jnz .y_inner_loop    
  291. dec ebp
  292. jz .y_outer_loop
  293. .y_remainder_loop:
  294.     movq mm1, [esi] ; read from src 
  295.     movq mm2, [esi + 8] 
  296.     movq [edi], mm1 ; write to y_out 
  297.     movq [edi + 8], mm2 
  298.     add esi, 16
  299.     add edi, 16 
  300. dec ebp
  301. jnz .y_remainder_loop
  302. .y_outer_loop:
  303. mov ebp, [remainder]
  304.     mov ecx, edx
  305.     add edi, ebx
  306.     
  307.     dec eax
  308. jnz near .y_inner_loop
  309.     mov eax, [esp + 40] ; height -> eax
  310.     mov ebx, [esp + 44] ; stride -> ebx
  311.     mov ecx, [esp + 36]   ; width -> ecx
  312.     mov edi, [esp + 24]  ; u_out -> edi 
  313. shr ecx, 1 ; width / 2 -> ecx
  314. shr ebx, 1 ; stride / 2 -> ebx
  315. shr eax, 1 ; height / 2 -> eax
  316.     sub ebx, ecx ; stride / 2 - width / 2 -> ebx
  317. mov edx, ecx
  318. mov ebp, ecx
  319. shr edx, 6
  320. mov ecx, edx ; 64 bytes copied per iteration
  321. shl edx, 6
  322. sub ebp, edx ; remainder -> ebp
  323. shr ebp, 3 ; 8 bytes per iteration
  324. add ebp, 1
  325. mov [remainder], ebp
  326. mov edx, ecx
  327. .u_inner_loop:
  328.     movq mm1, [esi] ; read from src 
  329.     movq mm2, [esi + 8] 
  330.     movq mm3, [esi + 16] 
  331.     movq mm4, [esi + 24] 
  332.     movq mm5, [esi + 32] 
  333.     movq mm6, [esi + 40] 
  334.     movq mm7, [esi + 48] 
  335.     movq mm0, [esi + 56] 
  336.     movq [edi], mm1 ; write to u_out 
  337.     movq [edi + 8], mm2 
  338.     movq [edi + 16], mm3 
  339.     movq [edi + 24], mm4 
  340.     movq [edi + 32], mm5 
  341.     movq [edi + 40], mm6 
  342.     movq [edi + 48], mm7 
  343.     movq [edi + 56], mm0 
  344.     add esi, 64
  345.     add edi, 64 
  346.     dec ecx
  347.     jnz .u_inner_loop    
  348. dec ebp
  349. jz .u_outer_loop
  350. .u_remainder_loop:
  351.     movq mm1, [esi] ; read from src 
  352.     movq [edi], mm1 ; write to y_out 
  353.     add esi, 8
  354.     add edi, 8 
  355. dec ebp
  356. jnz .u_remainder_loop
  357. .u_outer_loop:
  358. mov ebp, [remainder]
  359.     mov ecx, edx
  360.     add edi, ebx
  361.     
  362.     dec eax
  363. jnz .u_inner_loop
  364.     mov eax, [esp + 40] ; height -> eax
  365.     mov ecx, [esp + 36]  ; width -> ecx
  366.     mov edi, [esp + 28]  ; v_out -> edi 
  367. shr ecx, 1 ; width / 2 -> ecx
  368. shr eax, 1 ; height / 2 -> eax
  369. mov edx, ecx
  370. mov ebp, ecx
  371. shr edx, 6
  372. mov ecx, edx ; 64 bytes copied per iteration
  373. shl edx, 6
  374. sub ebp, edx ; remainder -> ebp
  375. shr ebp, 3 ; 8 bytes per iteration
  376. add ebp, 1
  377. mov [remainder], ebp
  378. mov edx, ecx
  379. .v_inner_loop:
  380.     movq mm1, [esi] ; read from src 
  381.     movq mm2, [esi + 8] 
  382.     movq mm3, [esi + 16] 
  383.     movq mm4, [esi + 24] 
  384.     movq mm5, [esi + 32] 
  385.     movq mm6, [esi + 40] 
  386.     movq mm7, [esi + 48] 
  387.     movq mm0, [esi + 56] 
  388.     movq [edi], mm1 ; write to u_out 
  389.     movq [edi + 8], mm2 
  390.     movq [edi + 16], mm3 
  391.     movq [edi + 24], mm4 
  392.     movq [edi + 32], mm5 
  393.     movq [edi + 40], mm6 
  394.     movq [edi + 48], mm7 
  395.     movq [edi + 56], mm0 
  396.     add esi, 64
  397.     add edi, 64 
  398.     dec ecx
  399.     jnz .v_inner_loop    
  400. dec ebp
  401. jz .v_outer_loop
  402. .v_remainder_loop:
  403.     movq mm1, [esi] ; read from src 
  404.     movq [edi], mm1 ; write to y_out 
  405.     add esi, 8
  406.     add edi, 8 
  407. dec ebp
  408. jnz .v_remainder_loop
  409. .v_outer_loop:
  410. mov ebp, [remainder]
  411.     mov ecx, edx
  412.     add edi, ebx
  413.     
  414.     dec eax
  415. jnz .v_inner_loop
  416. pop ebp
  417.     pop edi
  418.     pop esi
  419.     pop ebx
  420.     
  421.     emms
  422.     ret