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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;/**************************************************************************
  2. ; *
  3. ; * XVID MPEG-4 VIDEO CODEC
  4. ; * mmx yuv planar to yuyv/uyvy
  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. ; * 05.12.2001 initial version; (c)2001 peter ross <pross@cs.rmit.edu.au>
  35. ; *
  36. ; *************************************************************************/
  37. bits 32
  38. section .data
  39. %macro cglobal 1 
  40. %ifdef PREFIX
  41. global _%1 
  42. %define %1 _%1
  43. %else
  44. global %1
  45. %endif
  46. %endmacro
  47. align 16
  48. section .text
  49. ;===========================================================================
  50. ;
  51. ; void yv12_to_uyvy_mmx(
  52. ; uint8_t * dst,
  53. ; int dst_stride,
  54. ; uint8_t * y_src,
  55. ; uint8_t * u_src,
  56. ; uint8_t * v_src,
  57. ; int y_stride,
  58. ; int uv_stride,
  59. ; int width,
  60. ; int height);
  61. ;
  62. ; width must be multiple of 8
  63. ; ~10% faster than plain c
  64. ;
  65. ;===========================================================================
  66. align 16
  67. cglobal yv12_to_yuyv_mmx
  68. yv12_to_yuyv_mmx
  69. push ebx
  70. push ecx
  71. push esi
  72. push edi
  73. push ebp ; STACK BASE = 20
  74. ; global constants
  75. mov ebx, [esp + 20 + 32] ; width
  76. mov eax, [esp + 20 + 8] ; dst_stride
  77. sub eax, ebx ; 
  78. add eax, eax ; eax = 2*(dst_stride - width)
  79. push eax ; [esp + 4] = dst_dif
  80. ; STACK BASE = 24
  81. shr ebx, 3 ; ebx = width / 8
  82. mov edi, [esp + 24 + 4] ; dst
  83. ; --------- flip -------------
  84. mov ebp, [esp + 24 + 36]
  85. test ebp, ebp
  86. jl .flip
  87. mov esi, [esp + 24 + 12] ; y_src
  88. mov ecx, [esp + 24 + 16] ; u_src
  89. mov edx, [esp + 24 + 20] ; v_src
  90. shr ebp, 1 ; y = height / 2
  91. jmp short .yloop
  92. .flip
  93. neg ebp ; height = -height
  94. mov eax, [esp + 24 + 24] ; y_stride
  95. lea edx, [ebp - 1] ; edx = height - 1
  96. mul edx
  97. mov esi, [esp + 24 + 12] ; y_src
  98. add esi, eax ; y_src += (height - 1) * y_stride
  99. shr ebp, 1 ; y = height / 2
  100. mov eax, [esp + 24 + 28] ; uv_stride
  101. lea edx, [ebp - 1] ; edx = height/2 - 1
  102. mul edx
  103. mov ecx, [esp + 24 + 16] ; u_src
  104. mov edx, [esp + 24 + 20] ; v_src
  105. add ecx, eax ; u_src += (height/2 - 1) * uv_stride
  106. add edx, eax ; v_src += (height/2 - 1) * uv_stride
  107. neg dword [esp + 24 + 24] ; y_stride = -y_stride
  108. neg dword [esp + 24 + 28] ; uv_stride = -uv_stride
  109. .yloop
  110. xor eax, eax ; x = 0;
  111. .xloop1
  112. movd mm0, [ecx+4*eax] ; [    |uuuu]
  113. movd mm1, [edx+4*eax] ; [    |vvvv]
  114. movq mm2, [esi+8*eax] ; [yyyy|yyyy]
  115. punpcklbw mm0, mm1 ; [vuvu|vuvu]
  116. movq mm3, mm2
  117. punpcklbw mm2, mm0 ; [vyuy|vyuy]
  118. punpckhbw mm3, mm0 ; [vyuy|vyuy]
  119. movq [edi], mm2
  120. movq [edi+8], mm3
  121. inc eax
  122. add edi, 16
  123. cmp eax, ebx
  124. jb .xloop1
  125. add edi, [esp + 0] ; dst += dst_dif
  126. add esi, [esp + 24 + 24] ; y_src += y_stride
  127. xor eax, eax
  128. .xloop2
  129. movd mm0, [ecx+4*eax] ; [    |uuuu]
  130. movd mm1, [edx+4*eax] ; [    |vvvv]
  131. movq mm2, [esi+8*eax] ; [yyyy|yyyy]
  132. punpcklbw mm0, mm1 ; [vuvu|vuvu]
  133. movq mm3, mm2
  134. punpcklbw mm2, mm0 ; [vyuy|vyuy]
  135. punpckhbw mm3, mm0 ; [vyuy|vyuy]
  136. movq [edi], mm2
  137. movq [edi+8], mm3
  138. inc eax
  139. add edi, 16
  140. cmp eax, ebx
  141. jb .xloop2
  142. add edi, [esp + 0] ; dst += dst_dif
  143. add esi, [esp + 24 + 24] ; y_src += y_stride
  144. add ecx, [esp + 24 + 28] ; u_src += uv_stride
  145. add edx, [esp + 24 + 28] ; v_src += uv_stride
  146. dec ebp ; y--
  147. jnz near .yloop
  148. emms
  149. add esp, 4
  150. pop ebp
  151. pop edi
  152. pop esi
  153. pop ecx
  154. pop ebx
  155. ret
  156. ;===========================================================================
  157. ;
  158. ; void yv12_to_uyvy_mmx(
  159. ; uint8_t * dst,
  160. ; int dst_stride,
  161. ; uint8_t * y_src,
  162. ; uint8_t * u_src,
  163. ; uint8_t * v_src,
  164. ; int y_stride,
  165. ; int uv_stride,
  166. ; int width,
  167. ; int height);
  168. ;
  169. ; width must be multiple of 8
  170. ; ~10% faster than plain c
  171. ;
  172. ;===========================================================================
  173. align 16
  174. cglobal yv12_to_uyvy_mmx
  175. yv12_to_uyvy_mmx
  176. push ebx
  177. push ecx
  178. push esi
  179. push edi
  180. push ebp ; STACK BASE = 20
  181. ; global constants
  182. mov ebx, [esp + 20 + 32] ; width
  183. mov eax, [esp + 20 + 8] ; dst_stride
  184. sub eax, ebx ; 
  185. add eax, eax ; eax = 2*(dst_stride - width)
  186. push eax ; [esp + 4] = dst_dif
  187. ; STACK BASE = 24
  188. shr ebx, 3 ; ebx = width / 8
  189. mov edi, [esp + 24 + 4] ; dst
  190. ; --------- flip -------------
  191. mov ebp, [esp + 24 + 36]
  192. test ebp, ebp
  193. jl .flip
  194. mov esi, [esp + 24 + 12] ; y_src
  195. mov ecx, [esp + 24 + 16] ; u_src
  196. mov edx, [esp + 24 + 20] ; v_src
  197. shr ebp, 1 ; y = height / 2
  198. jmp short .yloop
  199. .flip
  200. neg ebp ; height = -height
  201. mov eax, [esp + 24 + 24] ; y_stride
  202. lea edx, [ebp - 1] ; edx = height - 1
  203. mul edx
  204. mov esi, [esp + 24 + 12] ; y_src
  205. add esi, eax ; y_src += (height - 1) * y_stride
  206. shr ebp, 1 ; y = height / 2
  207. mov eax, [esp + 24 + 28] ; uv_stride
  208. lea edx, [ebp - 1] ; edx = height/2 - 1
  209. mul edx
  210. mov ecx, [esp + 24 + 16] ; u_src
  211. mov edx, [esp + 24 + 20] ; v_src
  212. add ecx, eax ; u_src += (height/2 - 1) * uv_stride
  213. add edx, eax ; v_src += (height/2 - 1) * uv_stride
  214. neg dword [esp + 24 + 24] ; y_stride = -y_stride
  215. neg dword [esp + 24 + 28] ; uv_stride = -uv_stride
  216. .yloop
  217. xor eax, eax ; x = 0;
  218. .xloop1
  219. movd mm0, [ecx+4*eax] ; [    |uuuu]
  220. movd mm1, [edx+4*eax] ; [    |vvvv]
  221. movq mm2, [esi+8*eax] ; [yyyy|yyyy]
  222. punpcklbw mm0, mm1 ; [vuvu|vuvu]
  223. movq mm1, mm0
  224. punpcklbw mm0, mm2 ; [yvyu|yvyu]
  225. punpckhbw mm1, mm2 ; [yvyu|yvyu]
  226. movq [edi], mm0
  227. movq [edi+8], mm1
  228. inc eax
  229. add edi, 16
  230. cmp eax, ebx
  231. jb .xloop1
  232. add edi, [esp + 0] ; dst += dst_dif
  233. add esi, [esp + 24 + 24] ; y_src += y_stride
  234. xor eax, eax
  235. .xloop2
  236. movd mm0, [ecx+4*eax] ; [    |uuuu]
  237. movd mm1, [edx+4*eax] ; [    |vvvv]
  238. movq mm2, [esi+8*eax] ; [yyyy|yyyy]
  239. punpcklbw mm0, mm1 ; [vuvu|vuvu]
  240. movq mm1, mm0
  241. punpcklbw mm0, mm2 ; [yvyu|yvyu]
  242. punpckhbw mm1, mm2 ; [yvyu|yvyu]
  243. movq [edi], mm0
  244. movq [edi+8], mm1
  245. inc eax
  246. add edi, 16
  247. cmp eax, ebx
  248. jb .xloop2
  249. add edi, [esp + 0] ; dst += dst_dif
  250. add esi, [esp + 24 + 24] ; y_src += y_stride
  251. add ecx, [esp + 24 + 28] ; u_src += uv_stride
  252. add edx, [esp + 24 + 28] ; v_src += uv_stride
  253. dec ebp ; y--
  254. jnz near .yloop
  255. emms
  256. add esp, 4
  257. pop ebp
  258. pop edi
  259. pop esi
  260. pop ecx
  261. pop ebx
  262. ret