yuv2rgb_mmx.c
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:22k
源码类别:

VC书籍

开发平台:

Visual C++

  1. #include <memory.h> 
  2. #include "portab.h"
  3. #include "yuv2rgb.h"
  4. #define MAXIMUM_Y_WIDTH 800
  5. #define _USE_PREFETCH
  6. static uint64_t mmw_mult_Y    = 0x2568256825682568;
  7. static uint64_t mmw_mult_U_G  = 0xf36ef36ef36ef36e;
  8. static uint64_t mmw_mult_U_B  = 0x40cf40cf40cf40cf;
  9. static uint64_t mmw_mult_V_R  = 0x3343334333433343;
  10. static uint64_t mmw_mult_V_G  = 0xe5e2e5e2e5e2e5e2;
  11. static uint64_t mmb_0x10      = 0x1010101010101010;
  12. static uint64_t mmw_0x0080    = 0x0080008000800080;
  13. static uint64_t mmw_0x00ff    = 0x00ff00ff00ff00ff;
  14. static uint64_t mmw_cut_red   = 0x7c007c007c007c00;
  15. static uint64_t mmw_cut_green = 0x03e003e003e003e0;
  16. static uint64_t mmw_cut_blue  = 0x001f001f001f001f;
  17. void yuv2rgb_32(uint8_t *puc_y, int stride_y, 
  18.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  19.                 uint8_t *puc_out, int width_y, int height_y,
  20. unsigned int _stride_out) {
  21. int y, horiz_count;
  22. int stride_out = width_y * 4;
  23. if (height_y < 0) {
  24. height_y  = -height_y;
  25. puc_y     += (height_y   - 1) * stride_y ;
  26. puc_u     += (height_y/2 - 1) * stride_uv;
  27. puc_v     += (height_y/2 - 1) * stride_uv;
  28. stride_y  = -stride_y;
  29. stride_uv = -stride_uv;
  30. }
  31. horiz_count = -(width_y >> 3);
  32. for (y=0; y<height_y; y++) {
  33. _asm {
  34. push eax
  35. push ebx
  36. push ecx
  37. push edx
  38. push edi
  39. mov eax, puc_out       
  40. mov ebx, puc_y       
  41. mov ecx, puc_u       
  42. mov edx, puc_v
  43. mov edi, horiz_count
  44. horiz_loop:
  45. movd mm2, [ecx]
  46. pxor mm7, mm7
  47. movd mm3, [edx]
  48. punpcklbw mm2, mm7       ; mm2 = __u3__u2__u1__u0
  49. movq mm0, [ebx]          ; mm0 = y7y6y5y4y3y2y1y0  
  50. punpcklbw mm3, mm7       ; mm3 = __v3__v2__v1__v0
  51. movq mm1, mmw_0x00ff     ; mm1 = 00ff00ff00ff00ff 
  52. psubusb mm0, mmb_0x10    ; mm0 -= 16
  53. psubw mm2, mmw_0x0080    ; mm2 -= 128
  54. pand mm1, mm0            ; mm1 = __y6__y4__y2__y0
  55. psubw mm3, mmw_0x0080    ; mm3 -= 128
  56. psllw mm1, 3             ; mm1 *= 8
  57. psrlw mm0, 8             ; mm0 = __y7__y5__y3__y1
  58. psllw mm2, 3             ; mm2 *= 8
  59. pmulhw mm1, mmw_mult_Y   ; mm1 *= luma coeff 
  60. psllw mm0, 3             ; mm0 *= 8
  61. psllw mm3, 3             ; mm3 *= 8
  62. movq mm5, mm3            ; mm5 = mm3 = v
  63. pmulhw mm5, mmw_mult_V_R ; mm5 = red chroma
  64. movq mm4, mm2            ; mm4 = mm2 = u
  65. pmulhw mm0, mmw_mult_Y   ; mm0 *= luma coeff 
  66. movq mm7, mm1            ; even luma part
  67. pmulhw mm2, mmw_mult_U_G ; mm2 *= u green coeff 
  68. paddsw mm7, mm5          ; mm7 = luma + chroma    __r6__r4__r2__r0
  69. pmulhw mm3, mmw_mult_V_G ; mm3 *= v green coeff  
  70. packuswb mm7, mm7        ; mm7 = r6r4r2r0r6r4r2r0
  71. pmulhw mm4, mmw_mult_U_B ; mm4 = blue chroma
  72. paddsw mm5, mm0          ; mm5 = luma + chroma    __r7__r5__r3__r1
  73. packuswb mm5, mm5        ; mm6 = r7r5r3r1r7r5r3r1
  74. paddsw mm2, mm3          ; mm2 = green chroma
  75. movq mm3, mm1            ; mm3 = __y6__y4__y2__y0
  76. movq mm6, mm1            ; mm6 = __y6__y4__y2__y0
  77. paddsw mm3, mm4          ; mm3 = luma + chroma    __b6__b4__b2__b0
  78. paddsw mm6, mm2          ; mm6 = luma + chroma    __g6__g4__g2__g0
  79. punpcklbw mm7, mm5       ; mm7 = r7r6r5r4r3r2r1r0
  80. paddsw mm2, mm0          ; odd luma part plus chroma part    __g7__g5__g3__g1
  81. packuswb mm6, mm6        ; mm2 = g6g4g2g0g6g4g2g0
  82. packuswb mm2, mm2        ; mm2 = g7g5g3g1g7g5g3g1
  83. packuswb mm3, mm3        ; mm3 = b6b4b2b0b6b4b2b0
  84. paddsw mm4, mm0          ; odd luma part plus chroma part    __b7__b5__b3__b1
  85. packuswb mm4, mm4        ; mm4 = b7b5b3b1b7b5b3b1
  86. punpcklbw mm6, mm2       ; mm6 = g7g6g5g4g3g2g1g0
  87. punpcklbw mm3, mm4       ; mm3 = b7b6b5b4b3b2b1b0
  88. /* 32-bit shuffle.... */
  89. pxor mm0, mm0            ; is this needed?
  90. movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0
  91. punpcklbw mm1, mm0       ; mm1 = __g3__g2__g1__g0
  92. movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
  93. punpcklbw mm0, mm7       ; mm0 = r3b3r2b2r1b1r0b0
  94. movq mm2, mm0            ; mm2 = r3b3r2b2r1b1r0b0
  95. punpcklbw mm0, mm1       ; mm0 = __r1g1b1__r0g0b0
  96. punpckhbw mm2, mm1       ; mm2 = __r3g3b3__r2g2b2
  97. movq  [eax], mm0         ; eax[0] = __r1g1b1__r0g0b0
  98. movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0
  99. movq 8[eax], mm2         ; eax[8] = __r3g3b3__r2g2b2
  100. pxor mm0, mm0            ; is this needed?
  101. punpckhbw mm1, mm0       ; mm1 = __g7__g6__g5__g4
  102. movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
  103. punpckhbw mm0, mm7       ; mm0 = r7b7r6b6r5b5r4b4
  104. movq mm2, mm0            ; mm2 = r7b7r6b6r5b5r4b4
  105. punpcklbw mm0, mm1       ; mm0 = __r5g5b5__r4g4b4
  106. punpckhbw mm2, mm1       ; mm2 = __r7g7b7__r6g6b6
  107. add ebx, 8               ; puc_y   += 8;
  108. add ecx, 4               ; puc_u   += 4;
  109. movq 16[eax], mm0        ; eax[16] = __r5g5b5__r4g4b4
  110. add edx, 4               ; puc_v   += 4;
  111. movq 24[eax], mm2        ; eax[24] = __r7g7b7__r6g6b6
  112. add eax, 32              ; puc_out += 32
  113. inc edi
  114. jne horiz_loop
  115. pop edi 
  116. pop edx 
  117. pop ecx
  118. pop ebx 
  119. pop eax
  120. emms
  121. }
  122. puc_y   += stride_y;
  123. if (y%2) {
  124. puc_u   += stride_uv;
  125. puc_v   += stride_uv;
  126. }
  127. puc_out += stride_out;
  128. }
  129. }
  130. void yuv2rgb_24(uint8_t *puc_y, int stride_y, 
  131.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  132.                 uint8_t *puc_out, int width_y, int height_y,
  133. unsigned int _stride_out) {
  134. int y, horiz_count;
  135. uint8_t *puc_out_remembered;
  136. int stride_out = width_y * 3;
  137. if (height_y < 0) {
  138. height_y  = -height_y;
  139. puc_y     += (height_y   - 1) * stride_y ;
  140. puc_u     += (height_y/2 - 1) * stride_uv;
  141. puc_v     += (height_y/2 - 1) * stride_uv;
  142. stride_y  = -stride_y;
  143. stride_uv = -stride_uv;
  144. }
  145. horiz_count = -(width_y >> 3);
  146. for (y=0; y<height_y; y++) {
  147. if (y == height_y-1) {
  148. uint8_t temp_buff[3*MAXIMUM_Y_WIDTH+1];
  149. puc_out_remembered = puc_out;
  150. puc_out = temp_buff; 
  151. }
  152. _asm {
  153. push eax
  154. push ebx
  155. push ecx
  156. push edx
  157. push edi
  158. mov eax, puc_out       
  159. mov ebx, puc_y       
  160. mov ecx, puc_u       
  161. mov edx, puc_v
  162. mov edi, horiz_count
  163. horiz_loop:
  164. movd mm2, [ecx]
  165. pxor mm7, mm7
  166. movd mm3, [edx]
  167. punpcklbw mm2, mm7       ; mm2 = __u3__u2__u1__u0
  168. movq mm0, [ebx]          ; mm0 = y7y6y5y4y3y2y1y0  
  169. punpcklbw mm3, mm7       ; mm3 = __v3__v2__v1__v0
  170. movq mm1, mmw_0x00ff     ; mm1 = 00ff00ff00ff00ff 
  171. psubusb mm0, mmb_0x10    ; mm0 -= 16
  172. psubw mm2, mmw_0x0080    ; mm2 -= 128
  173. pand mm1, mm0            ; mm1 = __y6__y4__y2__y0
  174. psubw mm3, mmw_0x0080    ; mm3 -= 128
  175. psllw mm1, 3             ; mm1 *= 8
  176. psrlw mm0, 8             ; mm0 = __y7__y5__y3__y1
  177. psllw mm2, 3             ; mm2 *= 8
  178. pmulhw mm1, mmw_mult_Y   ; mm1 *= luma coeff 
  179. psllw mm0, 3             ; mm0 *= 8
  180. psllw mm3, 3             ; mm3 *= 8
  181. movq mm5, mm3            ; mm5 = mm3 = v
  182. pmulhw mm5, mmw_mult_V_R ; mm5 = red chroma
  183. movq mm4, mm2            ; mm4 = mm2 = u
  184. pmulhw mm0, mmw_mult_Y   ; mm0 *= luma coeff 
  185. movq mm7, mm1            ; even luma part
  186. pmulhw mm2, mmw_mult_U_G ; mm2 *= u green coeff 
  187. paddsw mm7, mm5          ; mm7 = luma + chroma    __r6__r4__r2__r0
  188. pmulhw mm3, mmw_mult_V_G ; mm3 *= v green coeff  
  189. packuswb mm7, mm7        ; mm7 = r6r4r2r0r6r4r2r0
  190. pmulhw mm4, mmw_mult_U_B ; mm4 = blue chroma
  191. paddsw mm5, mm0          ; mm5 = luma + chroma    __r7__r5__r3__r1
  192. packuswb mm5, mm5        ; mm6 = r7r5r3r1r7r5r3r1
  193. paddsw mm2, mm3          ; mm2 = green chroma
  194. movq mm3, mm1            ; mm3 = __y6__y4__y2__y0
  195. movq mm6, mm1            ; mm6 = __y6__y4__y2__y0
  196. paddsw mm3, mm4          ; mm3 = luma + chroma    __b6__b4__b2__b0
  197. paddsw mm6, mm2          ; mm6 = luma + chroma    __g6__g4__g2__g0
  198. punpcklbw mm7, mm5       ; mm7 = r7r6r5r4r3r2r1r0
  199. paddsw mm2, mm0          ; odd luma part plus chroma part    __g7__g5__g3__g1
  200. packuswb mm6, mm6        ; mm2 = g6g4g2g0g6g4g2g0
  201. packuswb mm2, mm2        ; mm2 = g7g5g3g1g7g5g3g1
  202. packuswb mm3, mm3        ; mm3 = b6b4b2b0b6b4b2b0
  203. paddsw mm4, mm0          ; odd luma part plus chroma part    __b7__b5__b3__b1
  204. packuswb mm4, mm4        ; mm4 = b7b5b3b1b7b5b3b1
  205. punpcklbw mm6, mm2       ; mm6 = g7g6g5g4g3g2g1g0
  206. punpcklbw mm3, mm4       ; mm3 = b7b6b5b4b3b2b1b0
  207. pxor mm0, mm0            ; is this needed?
  208. movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0
  209. punpcklbw mm1, mm0       ; mm1 = __g3__g2__g1__g0
  210. movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
  211. punpcklbw mm0, mm7       ; mm0 = r3b3r2b2r1b1r0b0
  212. movq mm2, mm0            ; mm2 = r3b3r2b2r1b1r0b0
  213. punpcklbw mm0, mm1       ; mm0 = __r1g1b1__r0g0b0
  214. punpckhbw mm2, mm1       ; mm2 = __r3g3b3__r2g2b2
  215. movd   [eax], mm0        ; eax[0] = __r0g0b0
  216. psrlq mm0, 32            ; mm0 = __r1g1b1
  217. movd  3[eax], mm0        ; eax[3] = __r1g1b1
  218. movd  6[eax], mm2        ; eax[6] = __r2g2b2
  219. psrlq mm2, 32            ; mm2 = __r3g3b3
  220. movd  9[eax], mm2        ; eax[9] = __r3g3b3
  221. pxor mm0, mm0            ; is this needed?
  222. movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0
  223. punpckhbw mm1, mm0       ; mm1 = __g7__g6__g5__g4
  224. movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
  225. punpckhbw mm0, mm7       ; mm0 = r7b7r6b6r5b5r4b4
  226. movq mm2, mm0            ; mm2 = r7b7r6b6r5b5r4b4
  227. punpcklbw mm0, mm1       ; mm0 = __r5g5b5__r4g4b4
  228. punpckhbw mm2, mm1       ; mm2 = __r7g7b7__r6g6b6
  229. movd 12[eax], mm0        ; eax[12] = __r4g4b4
  230. psrlq mm0, 32            ; mm0 = __r5g5b5
  231. movd 15[eax], mm0        ; eax[15] = __r5g5b5
  232. add ebx, 8               ; puc_y   += 8;
  233. movd 18[eax], mm2        ; eax[18] = __r6g6b6
  234. psrlq mm2, 32            ; mm2 = __r7g7b7
  235. add ecx, 4               ; puc_u   += 4;
  236. add edx, 4               ; puc_v   += 4;
  237. movd 21[eax], mm2        ; eax[21] = __r7g7b7
  238. add eax, 24              ; puc_out += 24
  239. inc edi
  240. jne horiz_loop
  241. pop edi 
  242. pop edx 
  243. pop ecx
  244. pop ebx 
  245. pop eax
  246. emms
  247. }
  248. if (y == height_y-1) {
  249. int x = 3 * width_y;                  
  250. uint8_t *ps = puc_out;                
  251. uint8_t *pd = puc_out_remembered;    
  252. while (x--) *(pd++) = *(ps++);      
  253. }
  254. puc_y   += stride_y;
  255. if (y%2) {
  256. puc_u   += stride_uv;
  257. puc_v   += stride_uv;
  258. }
  259. puc_out += stride_out; 
  260. }
  261. }
  262. static uint64_t mask_5 = 0xf8f8f8f8f8f8f8f8;
  263. static uint64_t mask_6 = 0xfcfcfcfcfcfcfcfc;
  264. static uint64_t mask_blue = 0x1f1f1f1f1f1f1f1f;
  265. void yuv2rgb_555(uint8_t *puc_y, int stride_y, 
  266.                  uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  267.                  uint8_t *puc_out, int width_y, int height_y,
  268.  unsigned int _stride_out) {
  269. int y, horiz_count;
  270. int stride_out = width_y * 2;
  271. if (height_y < 0) {
  272. height_y  = -height_y;
  273. puc_y     += (height_y   - 1) * stride_y ;
  274. puc_u     += (height_y/2 - 1) * stride_uv;
  275. puc_v     += (height_y/2 - 1) * stride_uv;
  276. stride_y  = -stride_y;
  277. stride_uv = -stride_uv;
  278. }
  279. horiz_count = -(width_y >> 3);
  280. for (y=0; y<height_y; y++) {
  281. _asm {
  282. push eax
  283. push ebx
  284. push ecx
  285. push edx
  286. push edi
  287. mov eax, puc_out       
  288. mov ebx, puc_y       
  289. mov ecx, puc_u       
  290. mov edx, puc_v
  291. mov edi, horiz_count
  292. horiz_loop:
  293. movd mm2, [ecx]  ; mm2 = ________u3u2u1u0
  294. movd mm3, [edx]  ; mm3 = ________v3v2v1v0
  295. movq mm0, [ebx]          ; mm0 = y7y6y5y4y3y2y1y0  
  296. pxor mm7, mm7  ; zero mm7
  297. punpcklbw mm2, mm7       ; mm2 = __u3__u2__u1__u0
  298. punpcklbw mm3, mm7       ; mm3 = __v3__v2__v1__v0
  299. psubw mm2, mmw_0x0080    ; mm2 -= 128
  300. psubw mm3, mmw_0x0080    ; mm3 -= 128
  301. psllw mm2, 3             ; mm2 *= 8
  302. psllw mm3, 3             ; mm3 *= 8
  303. movq mm4, mm2            ; mm4 = mm2 = u
  304. movq mm5, mm3            ; mm5 = mm3 = v
  305. pmulhw mm2, mmw_mult_U_G ; mm2 *= u green coeff 
  306. pmulhw mm3, mmw_mult_V_G ; mm3 *= v green coeff  
  307. pmulhw mm4, mmw_mult_U_B ; mm4 = blue chroma
  308. pmulhw mm5, mmw_mult_V_R ; mm5 = red chroma
  309. paddsw mm2, mm3  ; mm2 = green chroma
  310. psubusb mm0, mmb_0x10    ; mm0 -= 16
  311. movq mm1, mmw_0x00ff     ; mm1 = 00ff00ff00ff00ff 
  312. psrlw mm0, 8             ; mm0 = __y7__y5__y3__y1 luma odd
  313. pand mm1, mm0            ; mm1 = __y6__y4__y2__y0 luma even
  314. psllw mm0, 3             ; mm0 *= 8
  315. psllw mm1, 3             ; mm1 *= 8
  316. pmulhw mm0, mmw_mult_Y   ; mm0 luma odd *= luma coeff 
  317. pmulhw mm1, mmw_mult_Y   ; mm1 luma even *= luma coeff 
  318. movq mm3, mm4  ; copy blue chroma
  319. movq mm6, mm5  ; copy red chroma
  320. movq mm7, mm2  ; copy green chroma
  321. paddsw mm3, mm0  ; mm3 = luma odd + blue chroma
  322. paddsw mm4, mm1  ; mm4 = luma even + blue chroma
  323. paddsw mm6, mm0  ; mm6 = luma odd + red chroma
  324. paddsw mm5, mm1  ; mm5 = luma even + red chroma
  325. paddsw mm7, mm0  ; mm7 = luma odd + green chroma
  326. paddsw mm2, mm1  ; mm2 = luma even + green chroma
  327. packuswb mm3, mm3
  328. packuswb mm4, mm4
  329. packuswb mm6, mm6
  330. packuswb mm5, mm5
  331. packuswb mm7, mm7
  332. packuswb mm2, mm2
  333. punpcklbw mm4, mm3  ; mm4 = b7b6b5b4b3b2b1b0 blue
  334. punpcklbw mm5, mm6  ; mm5 = r7r6r5r4r3r2r1r0 red
  335. punpcklbw mm2, mm7  ; mm2 = g7g6g5g4g3g2g1g0 green
  336. pand mm4, mask_5
  337. pand mm5, mask_5
  338. pand mm2, mask_5
  339. psrlw mm4, 3  ; mm4 = blue shifted
  340. pand mm4, mask_blue  ; mask the blue again
  341. pxor mm7, mm7  ; zero mm7
  342. movq mm1, mm4  ; mm1 = copy blue
  343. movq mm3, mm5  ; mm3 = copy red
  344. movq mm6, mm2  ; mm6 = copy green
  345. punpckhbw mm1, mm7
  346. punpckhbw mm3, mm7
  347. punpckhbw mm6, mm7
  348. psllw mm6, 2  ; shift green
  349. psllw mm3, 7  ; shift red
  350. por mm6, mm3
  351. por mm6, mm1
  352. movq 8[eax], mm6
  353. punpcklbw mm2, mm7  ; mm2 = __g3__g2__g1__g0 already masked
  354. punpcklbw mm5, mm7
  355. punpcklbw mm4, mm7
  356. psllw mm2, 2  ; shift green
  357. psllw mm5, 7  ; shift red
  358. por mm2, mm5
  359. por mm2, mm4
  360. movq [eax], mm2
  361. add ebx, 8               ; puc_y   += 8;
  362. add ecx, 4               ; puc_u   += 4;
  363. add edx, 4               ; puc_v   += 4;
  364. add eax, 16              ; puc_out += 16 // wrote 16 bytes
  365. inc edi
  366. jne horiz_loop
  367. pop edi 
  368. pop edx 
  369. pop ecx
  370. pop ebx 
  371. pop eax
  372. emms
  373. }
  374. puc_y   += stride_y;
  375. if (y%2) {
  376. puc_u   += stride_uv;
  377. puc_v   += stride_uv;
  378. }
  379. puc_out += stride_out;
  380. }
  381. }
  382. /***/
  383. #define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a)
  384. #define _R(y,u,v) (0x2568*(y)          + 0x3343*(u)) /0x2000
  385. #define _G(y,u,v) (0x2568*(y) - 0x0c92*(v) - 0x1a1e*(u)) /0x2000
  386. #define _B(y,u,v) (0x2568*(y) + 0x40cf*(v))      /0x2000
  387. #define _mR 0x7c00
  388. #define _mG 0x03e0
  389. #define _mB 0x001f
  390. #define _Ps565(r,g,b) ( ((r & 0xF8) >> 3) | (((g & 0xF8) << 3)) | (((b & 0xF8) << 8)) )
  391. void yuv2rgb_565(uint8_t *puc_y, int stride_y, 
  392.                 uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  393.                 uint8_t *puc_out, int width_y, int height_y,
  394. unsigned int _stride_out) 
  395. {
  396. int y, horiz_count;
  397. unsigned short * pus_out;
  398. int stride_out = width_y * 2;
  399. if (height_y < 0) {
  400. height_y  = -height_y;
  401. puc_y     += (height_y   - 1) * stride_y ;
  402. puc_u     += (height_y/2 - 1) * stride_uv;
  403. puc_v     += (height_y/2 - 1) * stride_uv;
  404. stride_y  = -stride_y;
  405. stride_uv = -stride_uv;
  406. }
  407. pus_out = (unsigned short *) puc_out;
  408. horiz_count = -(width_y >> 3);
  409. for (y=0; y<height_y; y++) 
  410. {
  411. _asm {
  412. push eax
  413. push ebx
  414. push ecx
  415. push edx
  416. push edi
  417. mov eax, puc_out       
  418. mov ebx, puc_y       
  419. mov ecx, puc_u       
  420. mov edx, puc_v
  421. mov edi, horiz_count
  422. horiz_loop:
  423. movd mm2, [ecx]  ; mm2 = ________u3u2u1u0
  424. movd mm3, [edx]  ; mm3 = ________v3v2v1v0
  425. movq mm0, [ebx]          ; mm0 = y7y6y5y4y3y2y1y0  
  426. pxor mm7, mm7  ; zero mm7
  427. punpcklbw mm2, mm7       ; mm2 = __u3__u2__u1__u0
  428. punpcklbw mm3, mm7       ; mm3 = __v3__v2__v1__v0
  429. psubw mm2, mmw_0x0080    ; mm2 -= 128
  430. psubw mm3, mmw_0x0080    ; mm3 -= 128
  431. psllw mm2, 3             ; mm2 *= 8
  432. psllw mm3, 3             ; mm3 *= 8
  433. movq mm4, mm2            ; mm4 = mm2 = u
  434. movq mm5, mm3            ; mm5 = mm3 = v
  435. pmulhw mm2, mmw_mult_U_G ; mm2 *= u green coeff 
  436. pmulhw mm3, mmw_mult_V_G ; mm3 *= v green coeff  
  437. pmulhw mm4, mmw_mult_U_B ; mm4 = blue chroma
  438. pmulhw mm5, mmw_mult_V_R ; mm5 = red chroma
  439. paddsw mm2, mm3  ; mm2 = green chroma
  440. psubusb mm0, mmb_0x10    ; mm0 -= 16
  441. movq mm1, mmw_0x00ff     ; mm1 = 00ff00ff00ff00ff 
  442. psrlw mm0, 8             ; mm0 = __y7__y5__y3__y1 luma odd
  443. pand mm1, mm0            ; mm1 = __y6__y4__y2__y0 luma even
  444. psllw mm0, 3             ; mm0 *= 8
  445. psllw mm1, 3             ; mm1 *= 8
  446. pmulhw mm0, mmw_mult_Y   ; mm0 luma odd *= luma coeff 
  447. pmulhw mm1, mmw_mult_Y   ; mm1 luma even *= luma coeff 
  448. movq mm3, mm4  ; copy blue chroma
  449. movq mm6, mm5  ; copy red chroma
  450. movq mm7, mm2  ; copy green chroma
  451. paddsw mm3, mm0  ; mm3 = luma odd + blue chroma
  452. paddsw mm4, mm1  ; mm4 = luma even + blue chroma
  453. paddsw mm6, mm0  ; mm6 = luma odd + red chroma
  454. paddsw mm5, mm1  ; mm5 = luma even + red chroma
  455. paddsw mm7, mm0  ; mm7 = luma odd + green chroma
  456. paddsw mm2, mm1  ; mm2 = luma even + green chroma
  457. packuswb mm3, mm3
  458. packuswb mm4, mm4
  459. packuswb mm6, mm6
  460. packuswb mm5, mm5
  461. packuswb mm7, mm7
  462. packuswb mm2, mm2
  463. punpcklbw mm4, mm3  ; mm4 = b7b6b5b4b3b2b1b0 blue
  464. punpcklbw mm5, mm6  ; mm5 = r7r6r5r4r3r2r1r0 red
  465. punpcklbw mm2, mm7  ; mm2 = g7g6g5g4g3g2g1g0 green
  466. pand mm4, mask_5
  467. pand mm5, mask_5
  468. pand mm2, mask_5
  469. psrlw mm4, 3  ; mm4 = red shifted
  470. pand mm4, mask_blue  ; mask the blue again
  471. pxor mm7, mm7  ; zero mm7
  472. movq mm1, mm5  ; mm1 = copy blue
  473. movq mm3, mm4  ; mm3 = copy red
  474. movq mm6, mm2  ; mm6 = copy green
  475. punpckhbw mm1, mm7
  476. punpckhbw mm3, mm7
  477. punpckhbw mm6, mm7
  478. psllw mm6, 3  ; shift green
  479. psllw mm1, 8  ; shift blue
  480. por mm6, mm3
  481. por mm6, mm1
  482. movq 8[eax], mm6
  483. punpcklbw mm2, mm7  ; mm2 = __g3__g2__g1__g0 already masked
  484. punpcklbw mm4, mm7
  485. punpcklbw mm5, mm7
  486. psllw mm2, 3  ; shift green
  487. psllw mm5, 8  ; shift blue
  488. por mm2, mm4
  489. por mm2, mm5
  490. movq [eax], mm2
  491. add ebx, 8               ; puc_y   += 8;
  492. add ecx, 4               ; puc_u   += 4;
  493. add edx, 4               ; puc_v   += 4;
  494. add eax, 16              ; puc_out += 16 // wrote 16 bytes
  495. inc edi
  496. jne horiz_loop
  497. pop edi 
  498. pop edx 
  499. pop ecx
  500. pop ebx 
  501. pop eax
  502. emms
  503. }
  504. /***/
  505. puc_y   += stride_y;
  506. if (y%2) {
  507. puc_u   += stride_uv;
  508. puc_v   += stride_uv;
  509. }
  510. puc_out += stride_out;
  511. }
  512. }
  513. /***/
  514.  
  515. void yuy2_out(uint8_t *puc_y, int stride_y, 
  516.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  517.   uint8_t *puc_out, int width_y, int height_y,
  518. unsigned int stride_out) 
  519. int y;
  520. uint8_t* puc_out2;
  521. unsigned int stride_diff = 4 * stride_out - 2 * width_y; 
  522. if (height_y < 0) {
  523. height_y  = -height_y;
  524. puc_y     += (height_y   - 1) * stride_y ;
  525. puc_u     += (height_y/2 - 1) * stride_uv;
  526. puc_v     += (height_y/2 - 1) * stride_uv;
  527. stride_y  = -stride_y;
  528. stride_uv = -stride_uv;
  529. }
  530. puc_out2 = puc_out + 2 * stride_out;
  531. for (y=height_y/2; y; y--) {
  532. register uint8_t *py, *py2, *pu, *pv;
  533. register int x;
  534. uint32_t tmp;
  535. py = puc_y;
  536. py2 = puc_y + stride_y;
  537. pu = puc_u;
  538. pv = puc_v;
  539. for (x=width_y/2; x; x--) {
  540. tmp = *(py++);
  541. tmp |= *(pu++) << 8;
  542. tmp |= *(py++) << 16;
  543. tmp |= *(pv++) << 24;
  544. *(uint32_t*)puc_out=tmp;
  545. puc_out += 4;
  546. tmp &= 0xFF00FF00;
  547. tmp |= *(py2++);
  548. tmp |= *(py2++) << 16;
  549. *(uint32_t*)puc_out2=tmp;
  550. puc_out2 += 4;
  551. }
  552. puc_y += 2*stride_y;
  553. puc_u += stride_uv;
  554. puc_v += stride_uv;
  555. puc_out += stride_diff;
  556. puc_out2 += stride_diff;
  557. }
  558. }
  559. void uyvy_out(uint8_t *puc_y, int stride_y, 
  560.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  561.   uint8_t *puc_out, int width_y, int height_y,
  562. unsigned int stride_out) 
  563. int y;
  564. uint8_t* puc_out2;
  565. unsigned int stride_diff = 4 * stride_out - 2 * width_y; 
  566. if (height_y < 0) {
  567. height_y  = -height_y;
  568. puc_y     += (height_y   - 1) * stride_y ;
  569. puc_u     += (height_y/2 - 1) * stride_uv;
  570. puc_v     += (height_y/2 - 1) * stride_uv;
  571. stride_y  = -stride_y;
  572. stride_uv = -stride_uv;
  573. }
  574. puc_out2 = puc_out + 2 * stride_out;
  575. for (y=height_y/2; y; y--) {
  576. register uint8_t *py, *py2, *pu, *pv;
  577. register int x;
  578. uint32_t tmp;
  579. py = puc_y;
  580. py2 = puc_y + stride_y;
  581. pu = puc_u;
  582. pv = puc_v;
  583. for (x=width_y/2; x; x--) {
  584. tmp = *(pu++);
  585. tmp |= *(py++) << 8;
  586. tmp |= *(pv++) << 16;
  587. tmp |= *(py++) << 24;
  588. *(uint32_t*)puc_out=tmp;
  589. puc_out += 4;
  590. tmp &= 0x00FF00FF;
  591. tmp |= *(py2++) << 8;
  592. tmp |= *(py2++) << 24;
  593. *(uint32_t*)puc_out2=tmp;
  594. puc_out2 += 4;
  595. }
  596. puc_y += 2*stride_y;
  597. puc_u += stride_uv;
  598. puc_v += stride_uv;
  599. puc_out += stride_diff;
  600. puc_out2 += stride_diff;
  601. }
  602. }
  603. void yuv12_out(uint8_t *puc_y, int stride_y, 
  604.   uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
  605.   uint8_t *puc_out, int width_y, int height_y,
  606. unsigned int stride_out) 
  607. int i;
  608. unsigned char * pauc_out[3];
  609. if (height_y < 0) {
  610. height_y = -height_y;
  611. puc_y     += (height_y   - 1) * stride_y ;
  612. puc_u     += (height_y/2 - 1) * stride_uv;
  613. puc_v     += (height_y/2 - 1) * stride_uv;
  614. stride_y  = -stride_y;
  615. stride_uv = -stride_uv;
  616. }
  617. pauc_out[0] = puc_out;
  618. pauc_out[1] = puc_out + stride_out * height_y;
  619. pauc_out[2] = puc_out + stride_out * height_y * 5 / 4;
  620. for (i=0; i<height_y; i++) {
  621. memcpy(pauc_out[0], puc_y, width_y);
  622. pauc_out[0] += stride_out;
  623. puc_y += stride_y;
  624. }
  625. for (i=0; i<height_y/2; i++) {
  626. memcpy(pauc_out[2], puc_u, width_y/2); 
  627. memcpy(pauc_out[1], puc_v, width_y/2);
  628. pauc_out[1] += stride_out/2;
  629. pauc_out[2] += stride_out/2;
  630. puc_u += stride_uv;
  631. puc_v += stride_uv;
  632. }
  633. }
  634. /***/