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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;/**************************************************************************
  2. ; *
  3. ; * XVID MPEG-4 VIDEO CODEC
  4. ; * mmx yuyv/uyvy to yuv planar
  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. ; * 30.11.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 .data
  49. ;===========================================================================
  50. ; masks for extracting yuv components
  51. ;===========================================================================
  52. ; y     u     y     v     y     u     y     v
  53. mask1 db 0xff, 0,    0xff, 0,    0xff, 0,    0xff, 0
  54. mask2 db 0,    0xff, 0,    0xff, 0,    0xff, 0,    0xff
  55. section .text
  56. ;===========================================================================
  57. ;
  58. ; void yuyv_to_yv12_mmx(uint8_t * const y_out,
  59. ; uint8_t * const u_out,
  60. ; uint8_t * const v_out,
  61. ; const uint8_t * const src,
  62. ; const uint32_t width,
  63. ; const uint32_t height,
  64. ; const uint32_t stride);
  65. ;
  66. ; width must be multiple of 8
  67. ; does not flip
  68. ; ~30% faster than plain c
  69. ;
  70. ;===========================================================================
  71. align 16
  72. cglobal yuyv_to_yv12_mmx
  73. yuyv_to_yv12_mmx
  74. push ebx
  75. push ecx
  76. push esi
  77. push edi
  78. push ebp ; STACK BASE = 20
  79. ; some global consants
  80. mov ecx, [esp + 20 + 20] ; width
  81. mov eax, [esp + 20 + 28] ; stride
  82. sub eax, ecx ; eax = stride - width
  83. mov edx, eax
  84. add edx, [esp + 20 + 28] ; edx = y_dif + stride
  85. push edx ; [esp + 12] = y_dif
  86. shr eax, 1
  87. push eax ; [esp + 8] = uv_dif
  88. shr ecx, 3
  89. push ecx ; [esp + 4] = width/8
  90. sub esp, 4 ; [esp + 0] = tmp_height_counter
  91. ; STACK_BASE = 36
  92. movq mm6, [mask1]
  93. movq mm7, [mask2]
  94. mov edi, [esp + 36 + 4] ; y_out
  95. mov ebx, [esp + 36 + 8] ; u_out
  96. mov edx, [esp + 36 + 12] ; v_out
  97. mov esi, [esp + 36 + 16] ; src
  98. mov eax, [esp + 36 + 20]
  99. mov ebp, [esp + 36 + 24]
  100. mov ecx, [esp + 36 + 28] ; ecx = stride
  101. shr ebp, 1 ; ebp = height /= 2
  102. add eax, eax ; eax = 2 * width
  103. .yloop
  104. mov [esp], ebp
  105. mov ebp, [esp + 4] ; width/8
  106. .xloop
  107. movq mm2, [esi] ; y 1st row
  108. movq mm3, [esi + 8]
  109. movq mm0, mm2
  110. movq mm1, mm3
  111. pand mm2, mm6 ; mask1
  112. pand mm3, mm6 ; mask1
  113. pand mm0, mm7 ; mask2
  114. pand mm1, mm7 ; mask2
  115. packuswb mm2, mm3
  116. psrlq mm0, 8
  117. psrlq mm1, 8
  118. movq [edi], mm2
  119. movq mm4, [esi + eax] ; y 2nd row
  120. movq mm5, [esi + eax + 8]
  121. movq mm2, mm4
  122. movq mm3, mm5
  123. pand mm4, mm6 ; mask1
  124. pand mm5, mm6 ; mask1
  125. pand mm2, mm7 ; mask2
  126. pand mm3, mm7 ; mask2
  127. packuswb mm4, mm5
  128. psrlq mm2, 8
  129. psrlq mm3, 8
  130. movq [edi + ecx], mm4
  131. paddw mm0, mm2 ; uv avg 1st & 2nd
  132. paddw mm1, mm3
  133. psrlw mm0, 1
  134. psrlw mm1, 1
  135. packuswb mm0, mm1
  136. movq mm2, mm0
  137. pand mm0, mm6 ; mask1
  138. pand mm2, mm7 ; mask2
  139. packuswb mm0, mm0
  140. psrlq mm2, 8
  141. movd [ebx], mm0
  142. packuswb mm2, mm2
  143. movd [edx], mm2
  144. add esi, 16
  145. add edi, 8
  146. add ebx, 4
  147. add edx, 4
  148. dec ebp
  149. jnz near .xloop
  150. mov ebp, [esp]
  151. add esi, eax ; += width2
  152. add edi, [esp + 12] ; += y_dif + stride
  153. add ebx, [esp + 8] ; += uv_dif
  154. add edx, [esp + 8] ; += uv_dif
  155. dec ebp
  156. jnz near .yloop
  157. emms
  158. add esp, 16
  159. pop ebp
  160. pop edi
  161. pop esi
  162. pop ecx
  163. pop ebx
  164. ret
  165. ;===========================================================================
  166. ;
  167. ; void uyvy_to_yv12_mmx(uint8_t * const y_out,
  168. ; uint8_t * const u_out,
  169. ; uint8_t * const v_out,
  170. ; const uint8_t * const src,
  171. ; const uint32_t width,
  172. ; const uint32_t height,
  173. ; const uint32_t stride);
  174. ;
  175. ; width must be multiple of 8
  176. ; does not flip
  177. ; ~30% faster than plain c
  178. ;
  179. ;===========================================================================
  180. align 16
  181. cglobal uyvy_to_yv12_mmx
  182. uyvy_to_yv12_mmx
  183. push ebx
  184. push ecx
  185. push esi
  186. push edi
  187. push ebp ; STACK BASE = 20
  188. ; some global consants
  189. mov ecx, [esp + 20 + 20] ; width
  190. mov eax, [esp + 20 + 28] ; stride
  191. sub eax, ecx ; eax = stride - width
  192. mov edx, eax
  193. add edx, [esp + 20 + 28] ; edx = y_dif + stride
  194. push edx ; [esp + 12] = y_dif
  195. shr eax, 1
  196. push eax ; [esp + 8] = uv_dif
  197. shr ecx, 3
  198. push ecx ; [esp + 4] = width/8
  199. sub esp, 4 ; [esp + 0] = tmp_height_counter
  200. ; STACK_BASE = 36
  201. movq mm6, [mask1]
  202. movq mm7, [mask2]
  203. mov edi, [esp + 36 + 4] ; y_out
  204. mov ebx, [esp + 36 + 8] ; u_out
  205. mov edx, [esp + 36 + 12] ; v_out
  206. mov esi, [esp + 36 + 16] ; src
  207. mov eax, [esp + 36 + 20]
  208. mov ebp, [esp + 36 + 24]
  209. mov ecx, [esp + 36 + 28] ; ecx = stride
  210. shr ebp, 1 ; ebp = height /= 2
  211. add eax, eax ; eax = 2 * width
  212. .yloop
  213. mov [esp], ebp
  214. mov ebp, [esp + 4] ; width/8
  215. .xloop
  216. movq mm2, [esi] ; y 1st row
  217. movq mm3, [esi + 8]
  218. movq mm0, mm2
  219. movq mm1, mm3
  220. pand mm2, mm7 ; mask2
  221. pand mm3, mm7 ; mask2
  222. psrlq mm2, 8
  223. psrlq mm3, 8
  224. pand mm0, mm6 ; mask1
  225. pand mm1, mm6 ; mask1
  226. packuswb mm2, mm3
  227. movq [edi], mm2
  228. movq mm4, [esi + eax] ; y 2nd row
  229. movq mm5, [esi + eax + 8]
  230. movq mm2, mm4
  231. movq mm3, mm5
  232. pand mm4, mm7 ; mask2
  233. pand mm5, mm7 ; mask2
  234. psrlq mm4, 8
  235. psrlq mm5, 8
  236. pand mm2, mm6 ; mask1
  237. pand mm3, mm6 ; mask1
  238. packuswb mm4, mm5
  239. movq [edi + ecx], mm4
  240. paddw mm0, mm2 ; uv avg 1st & 2nd
  241. paddw mm1, mm3
  242. psrlw mm0, 1
  243. psrlw mm1, 1
  244. packuswb mm0, mm1
  245. movq mm2, mm0
  246. pand mm0, mm6 ; mask1
  247. pand mm2, mm7 ; mask2
  248. packuswb mm0, mm0
  249. psrlq mm2, 8
  250. movd [ebx], mm0
  251. packuswb mm2, mm2
  252. movd [edx], mm2
  253. add esi, 16
  254. add edi, 8
  255. add ebx, 4
  256. add edx, 4
  257. dec ebp
  258. jnz near .xloop
  259. mov ebp, [esp]
  260. add esi, eax ; += width2
  261. add edi, [esp + 12] ; += y_dif + stride
  262. add ebx, [esp + 8] ; += uv_dif
  263. add edx, [esp + 8] ; += uv_dif
  264. dec ebp
  265. jnz near .yloop
  266. emms
  267. add esp, 16
  268. pop ebp
  269. pop edi
  270. pop esi
  271. pop ecx
  272. pop ebx
  273. ret