Mercurial > mplayer.hg
annotate postproc/rgb2rgb.c @ 2723:22aba8af94af
fixed yv12toyuy2
author | michael |
---|---|
date | Mon, 05 Nov 2001 18:26:49 +0000 |
parents | 4ba64e254042 |
children | c08b7af26782 |
rev | line source |
---|---|
2694 | 1 /* |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
2 * |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
3 * rgb2rgb.c, Software RGB to RGB convertor |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
4 * Written by Nick Kurshev. |
2702 | 5 * palette stuff & yuv stuff by Michael |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
6 */ |
2504 | 7 #include <inttypes.h> |
8 #include "../config.h" | |
9 #include "rgb2rgb.h" | |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
10 #include "../mmx_defs.h" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
11 |
2535 | 12 #ifdef HAVE_MMX |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
13 static const uint64_t mask32 __attribute__((aligned(8))) = 0x00FFFFFF00FFFFFFULL; |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
14 static const uint64_t mask24l __attribute__((aligned(8))) = 0x0000000000FFFFFFULL; |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
15 static const uint64_t mask24h __attribute__((aligned(8))) = 0x0000FFFFFF000000ULL; |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
16 static const uint64_t mask15b __attribute__((aligned(8))) = 0x001F001F001F001FULL; /* 00000000 00011111 xxB */ |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
17 static const uint64_t mask15rg __attribute__((aligned(8))) = 0x7FE07FE07FE07FE0ULL; /* 01111111 11100000 RGx */ |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
18 static const uint64_t mask15s __attribute__((aligned(8))) = 0xFFE0FFE0FFE0FFE0ULL; |
2535 | 19 #endif |
2513 | 20 |
2718 | 21 void rgb24to32(const uint8_t *src,uint8_t *dst,unsigned src_size) |
2504 | 22 { |
2508 | 23 uint8_t *dest = dst; |
2677 | 24 const uint8_t *s = src; |
25 const uint8_t *end; | |
2510 | 26 #ifdef HAVE_MMX |
27 uint8_t *mm_end; | |
28 #endif | |
2504 | 29 end = s + src_size; |
2510 | 30 #ifdef HAVE_MMX |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
31 __asm __volatile(PREFETCH" %0"::"m"(*s):"memory"); |
2516 | 32 mm_end = (uint8_t*)((((unsigned long)end)/(MMREG_SIZE*2))*(MMREG_SIZE*2)); |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
33 __asm __volatile("movq %0, %%mm7"::"m"(mask32):"memory"); |
2516 | 34 if(mm_end == end) mm_end -= MMREG_SIZE*2; |
2510 | 35 while(s < mm_end) |
36 { | |
2511 | 37 __asm __volatile( |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
38 PREFETCH" 32%1\n\t" |
2510 | 39 "movd %1, %%mm0\n\t" |
40 "movd 3%1, %%mm1\n\t" | |
41 "movd 6%1, %%mm2\n\t" | |
42 "movd 9%1, %%mm3\n\t" | |
43 "punpckldq %%mm1, %%mm0\n\t" | |
44 "punpckldq %%mm3, %%mm2\n\t" | |
45 "pand %%mm7, %%mm0\n\t" | |
46 "pand %%mm7, %%mm2\n\t" | |
2511 | 47 MOVNTQ" %%mm0, %0\n\t" |
48 MOVNTQ" %%mm2, 8%0" | |
2510 | 49 :"=m"(*dest) |
50 :"m"(*s) | |
51 :"memory"); | |
52 dest += 16; | |
53 s += 12; | |
54 } | |
2513 | 55 __asm __volatile(SFENCE:::"memory"); |
2511 | 56 __asm __volatile(EMMS:::"memory"); |
2510 | 57 #endif |
2504 | 58 while(s < end) |
59 { | |
2508 | 60 *dest++ = *s++; |
61 *dest++ = *s++; | |
62 *dest++ = *s++; | |
63 *dest++ = 0; | |
2504 | 64 } |
65 } | |
2505 | 66 |
2718 | 67 void rgb32to24(const uint8_t *src,uint8_t *dst,unsigned src_size) |
2505 | 68 { |
69 uint8_t *dest = dst; | |
2677 | 70 const uint8_t *s = src; |
71 const uint8_t *end; | |
2517 | 72 #ifdef HAVE_MMX |
73 uint8_t *mm_end; | |
74 #endif | |
2505 | 75 end = s + src_size; |
2517 | 76 #ifdef HAVE_MMX |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
77 __asm __volatile(PREFETCH" %0"::"m"(*s):"memory"); |
2517 | 78 mm_end = (uint8_t*)((((unsigned long)end)/(MMREG_SIZE*2))*(MMREG_SIZE*2)); |
79 __asm __volatile( | |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
80 "movq %0, %%mm7\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
81 "movq %1, %%mm6" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
82 ::"m"(mask24l),"m"(mask24h):"memory"); |
2517 | 83 if(mm_end == end) mm_end -= MMREG_SIZE*2; |
84 while(s < mm_end) | |
85 { | |
86 __asm __volatile( | |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
87 PREFETCH" 32%1\n\t" |
2517 | 88 "movq %1, %%mm0\n\t" |
89 "movq 8%1, %%mm1\n\t" | |
90 "movq %%mm0, %%mm2\n\t" | |
91 "movq %%mm1, %%mm3\n\t" | |
92 "psrlq $8, %%mm2\n\t" | |
93 "psrlq $8, %%mm3\n\t" | |
94 "pand %%mm7, %%mm0\n\t" | |
95 "pand %%mm7, %%mm1\n\t" | |
96 "pand %%mm6, %%mm2\n\t" | |
97 "pand %%mm6, %%mm3\n\t" | |
98 "por %%mm2, %%mm0\n\t" | |
99 "por %%mm3, %%mm1\n\t" | |
100 MOVNTQ" %%mm0, %0\n\t" | |
101 MOVNTQ" %%mm1, 6%0" | |
102 :"=m"(*dest) | |
103 :"m"(*s) | |
104 :"memory"); | |
105 dest += 12; | |
106 s += 16; | |
107 } | |
108 __asm __volatile(SFENCE:::"memory"); | |
109 __asm __volatile(EMMS:::"memory"); | |
110 #endif | |
2505 | 111 while(s < end) |
112 { | |
113 *dest++ = *s++; | |
114 *dest++ = *s++; | |
115 *dest++ = *s++; | |
116 s++; | |
117 } | |
118 } | |
2506 | 119 |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
120 /* |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
121 Original by Strepto/Astral |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
122 ported to gcc & bugfixed : A'rpi |
2564 | 123 MMX2, 3DNOW optimization by Nick Kurshev |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
124 32bit c version, and and&add trick by Michael Niedermayer |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
125 */ |
2718 | 126 void rgb15to16(const uint8_t *src,uint8_t *dst,unsigned src_size) |
2506 | 127 { |
128 #ifdef HAVE_MMX | |
2677 | 129 register const char* s=src+src_size; |
2506 | 130 register char* d=dst+src_size; |
131 register int offs=-src_size; | |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
132 __asm __volatile(PREFETCH" %0"::"m"(*(s+offs))); |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
133 __asm __volatile( |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
134 "movq %0, %%mm4\n\t" |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
135 ::"m"(mask15s)); |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
136 while(offs<0) |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
137 { |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
138 __asm __volatile( |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
139 PREFETCH" 32%1\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
140 "movq %1, %%mm0\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
141 "movq 8%1, %%mm2\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
142 "movq %%mm0, %%mm1\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
143 "movq %%mm2, %%mm3\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
144 "pand %%mm4, %%mm0\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
145 "pand %%mm4, %%mm2\n\t" |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
146 "paddw %%mm1, %%mm0\n\t" |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
147 "paddw %%mm3, %%mm2\n\t" |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
148 MOVNTQ" %%mm0, %0\n\t" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
149 MOVNTQ" %%mm2, 8%0" |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
150 :"=m"(*(d+offs)) |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
151 :"m"(*(s+offs)) |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
152 ); |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
153 offs+=16; |
2506 | 154 } |
2538
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
155 __asm __volatile(SFENCE:::"memory"); |
71320898b333
Finish mmx2, 3dnow optimiz. 15to16 should be tested. Better fix of can't compile
nick
parents:
2535
diff
changeset
|
156 __asm __volatile(EMMS:::"memory"); |
2506 | 157 #else |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
158 #if 0 |
2677 | 159 const uint16_t *s1=( uint16_t * )src; |
2506 | 160 uint16_t *d1=( uint16_t * )dst; |
161 uint16_t *e=((uint8_t *)s1)+src_size; | |
162 while( s1<e ){ | |
163 register int x=*( s1++ ); | |
164 /* rrrrrggggggbbbbb | |
165 0rrrrrgggggbbbbb | |
166 0111 1111 1110 0000=0x7FE0 | |
167 00000000000001 1111=0x001F */ | |
168 *( d1++ )=( x&0x001F )|( ( x&0x7FE0 )<<1 ); | |
169 } | |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
170 #else |
2718 | 171 const unsigned *s1=( unsigned * )src; |
172 unsigned *d1=( unsigned * )dst; | |
2698
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
173 int i; |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
174 int size= src_size>>2; |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
175 for(i=0; i<size; i++) |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
176 { |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
177 register int x= s1[i]; |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
178 // d1[i] = x + (x&0x7FE07FE0); //faster but need msbit =0 which might not allways be true |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
179 d1[i] = (x&0x7FFF7FFF) + (x&0x7FE07FE0); |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
180 |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
181 } |
22652c028692
faster 15to16 bit rgb (the mmx routine is limited by memory speed so there is no difference ): but the c routine is faster
michael
parents:
2697
diff
changeset
|
182 #endif |
2506 | 183 #endif |
184 } | |
2694 | 185 |
186 /** | |
187 * Pallete is assumed to contain bgr32 | |
188 */ | |
2718 | 189 void palette8torgb32(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette) |
2694 | 190 { |
2718 | 191 unsigned i; |
2702 | 192 for(i=0; i<num_pixels; i++) |
2718 | 193 ((unsigned *)dst)[i] = ((unsigned *)palette)[ src[i] ]; |
2694 | 194 } |
195 | |
2697 | 196 /** |
197 * Pallete is assumed to contain bgr32 | |
198 */ | |
2718 | 199 void palette8torgb24(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette) |
2697 | 200 { |
2718 | 201 unsigned i; |
2697 | 202 /* |
203 writes 1 byte o much and might cause alignment issues on some architectures? | |
2702 | 204 for(i=0; i<num_pixels; i++) |
2718 | 205 ((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ]; |
2697 | 206 */ |
2702 | 207 for(i=0; i<num_pixels; i++) |
2697 | 208 { |
209 //FIXME slow? | |
210 dst[0]= palette[ src[i]*4+0 ]; | |
211 dst[1]= palette[ src[i]*4+1 ]; | |
212 dst[2]= palette[ src[i]*4+2 ]; | |
213 dst+= 3; | |
214 } | |
215 } | |
216 | |
2718 | 217 void rgb32to16(const uint8_t *src, uint8_t *dst, unsigned src_size) |
2694 | 218 { |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
219 unsigned j,i,num_pixels=src_size/4; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
220 uint16_t *d = (uint16_t *)dst; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
221 for(i=0,j=0; j<num_pixels; i+=4,j++) |
2694 | 222 { |
223 const int b= src[i+0]; | |
224 const int g= src[i+1]; | |
225 const int r= src[i+2]; | |
226 | |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
227 d[j]= (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8); |
2694 | 228 } |
229 } | |
230 | |
2718 | 231 void rgb32to15(const uint8_t *src, uint8_t *dst, unsigned src_size) |
2694 | 232 { |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
233 unsigned j,i,num_pixels=src_size/4; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
234 uint16_t *d = (uint16_t *)dst; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
235 for(i=0,j=0; j<num_pixels; i+=4,j++) |
2694 | 236 { |
237 const int b= src[i+0]; | |
238 const int g= src[i+1]; | |
239 const int r= src[i+2]; | |
240 | |
2720 | 241 d[j]= (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7); |
2694 | 242 } |
243 } | |
244 | |
2718 | 245 void rgb24to16(const uint8_t *src, uint8_t *dst, unsigned src_size) |
246 { | |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
247 unsigned j,i,num_pixels=src_size/3; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
248 uint16_t *d = (uint16_t *)dst; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
249 for(i=0,j=0; j<num_pixels; i+=3,j++) |
2718 | 250 { |
251 const int b= src[i+0]; | |
252 const int g= src[i+1]; | |
253 const int r= src[i+2]; | |
254 | |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
255 d[j]= (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8); |
2718 | 256 } |
257 } | |
258 | |
259 void rgb24to15(const uint8_t *src, uint8_t *dst, unsigned src_size) | |
260 { | |
2719
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
261 unsigned j,i,num_pixels=src_size/3; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
262 uint16_t *d = (uint16_t *)dst; |
fafa73d6d80c
Fixed rgb32(24)to16 stuff, rgb32(24)to15 is still broken
nick
parents:
2718
diff
changeset
|
263 for(i=0,j=0; j<num_pixels; i+=3,j++) |
2718 | 264 { |
265 const int b= src[i+0]; | |
266 const int g= src[i+1]; | |
267 const int r= src[i+2]; | |
268 | |
2720 | 269 d[j]= (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7); |
2718 | 270 } |
271 } | |
2694 | 272 |
273 /** | |
274 * Palette is assumed to contain bgr16, see rgb32to16 to convert the palette | |
275 */ | |
2718 | 276 void palette8torgb16(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette) |
2694 | 277 { |
2718 | 278 unsigned i; |
2702 | 279 for(i=0; i<num_pixels; i++) |
2694 | 280 ((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ]; |
281 } | |
282 | |
283 /** | |
284 * Pallete is assumed to contain bgr15, see rgb32to15 to convert the palette | |
285 */ | |
2718 | 286 void palette8torgb15(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette) |
2694 | 287 { |
2718 | 288 unsigned i; |
2702 | 289 for(i=0; i<num_pixels; i++) |
2694 | 290 ((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ]; |
2697 | 291 } |
2702 | 292 /** |
293 * | |
2723 | 294 * width must be a multiple of 16 for the MMX version |
2702 | 295 */ |
2723 | 296 void yv12toyuy2(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, |
297 int width, int height, int lumStride, int chromStride, int dstStride) | |
2701 | 298 { |
2723 | 299 int y; |
300 const int chromWidth= width>>1; | |
301 for(y=0; y<height; y++) | |
302 { | |
2702 | 303 #ifdef HAVE_MMX |
2723 | 304 //FIXME handle 2 lines a once (fewer prefetch, reuse some chrom, but very likely limited by mem anyway) |
305 asm volatile( | |
306 "xorl %%eax, %%eax \n\t" | |
307 "1: \n\t" | |
308 PREFETCH" 32(%1, %%eax, 2) \n\t" | |
309 PREFETCH" 32(%2, %%eax) \n\t" | |
310 PREFETCH" 32(%3, %%eax) \n\t" | |
311 "movq (%2, %%eax), %%mm0 \n\t" // U(0) | |
312 "movq %%mm0, %%mm2 \n\t" // U(0) | |
313 "movq (%3, %%eax), %%mm1 \n\t" // V(0) | |
314 "punpcklbw %%mm1, %%mm0 \n\t" // UVUV UVUV(0) | |
315 "punpckhbw %%mm1, %%mm2 \n\t" // UVUV UVUV(8) | |
316 | |
317 "movq (%1, %%eax,2), %%mm3 \n\t" // Y(0) | |
318 "movq 8(%1, %%eax,2), %%mm5 \n\t" // Y(8) | |
319 "movq %%mm3, %%mm4 \n\t" // Y(0) | |
320 "movq %%mm5, %%mm6 \n\t" // Y(8) | |
321 "punpcklbw %%mm0, %%mm3 \n\t" // YUYV YUYV(0) | |
322 "punpckhbw %%mm0, %%mm4 \n\t" // YUYV YUYV(4) | |
323 "punpcklbw %%mm2, %%mm5 \n\t" // YUYV YUYV(8) | |
324 "punpckhbw %%mm2, %%mm6 \n\t" // YUYV YUYV(12) | |
2702 | 325 |
2723 | 326 MOVNTQ" %%mm3, (%0, %%eax, 4) \n\t" |
327 MOVNTQ" %%mm4, 8(%0, %%eax, 4) \n\t" | |
328 MOVNTQ" %%mm5, 16(%0, %%eax, 4) \n\t" | |
329 MOVNTQ" %%mm6, 24(%0, %%eax, 4) \n\t" | |
2702 | 330 |
2723 | 331 "addl $8, %%eax \n\t" |
332 "cmpl %4, %%eax \n\t" | |
333 " jb 1b \n\t" | |
334 ::"r"(dst), "r"(ysrc), "r"(usrc), "r"(vsrc), "r" (chromWidth) | |
335 : "%eax" | |
336 ); | |
2702 | 337 #else |
2723 | 338 int i; |
339 for(i=0; i<chromWidth; i++) | |
340 { | |
341 dst[4*i+0] = ysrc[2*i+0]; | |
342 dst[4*i+1] = usrc[i]; | |
343 dst[4*i+2] = ysrc[2*i+1]; | |
344 dst[4*i+3] = vsrc[i]; | |
345 } | |
346 #endif | |
347 if(y&1) | |
348 { | |
349 usrc += chromStride; | |
350 vsrc += chromStride; | |
351 } | |
352 ysrc += lumStride; | |
353 dst += dstStride; | |
2701 | 354 } |
2723 | 355 #ifdef HAVE_MMX |
356 asm( EMMS" \n\t" | |
357 SFENCE" \n\t" | |
358 :::"memory"); | |
2702 | 359 #endif |
2701 | 360 } |
361 | |
2718 | 362 void yuy2toyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, unsigned num_pixels) |
2701 | 363 { |
2704 | 364 #ifdef HAVE_MMX |
365 asm volatile( | |
366 "xorl %%eax, %%eax \n\t" | |
367 "pcmpeqw %%mm7, %%mm7 \n\t" | |
368 "psrlw $8, %%mm7 \n\t" // FF,00,FF,00... | |
369 "1: \n\t" | |
370 PREFETCH" 64(%0, %%eax, 4) \n\t" | |
371 "movq (%0, %%eax, 4), %%mm0 \n\t" // YUYV YUYV(0) | |
372 "movq 8(%0, %%eax, 4), %%mm1 \n\t" // YUYV YUYV(4) | |
373 "movq %%mm0, %%mm2 \n\t" // YUYV YUYV(0) | |
374 "movq %%mm1, %%mm3 \n\t" // YUYV YUYV(4) | |
375 "psrlw $8, %%mm0 \n\t" // U0V0 U0V0(0) | |
376 "psrlw $8, %%mm1 \n\t" // U0V0 U0V0(4) | |
377 "pand %%mm7, %%mm2 \n\t" // Y0Y0 Y0Y0(0) | |
378 "pand %%mm7, %%mm3 \n\t" // Y0Y0 Y0Y0(4) | |
379 "packuswb %%mm1, %%mm0 \n\t" // UVUV UVUV(0) | |
380 "packuswb %%mm3, %%mm2 \n\t" // YYYY YYYY(0) | |
381 | |
382 MOVNTQ" %%mm2, (%1, %%eax, 2) \n\t" | |
383 | |
384 "movq 16(%0, %%eax, 4), %%mm1 \n\t" // YUYV YUYV(8) | |
385 "movq 24(%0, %%eax, 4), %%mm2 \n\t" // YUYV YUYV(12) | |
386 "movq %%mm1, %%mm3 \n\t" // YUYV YUYV(8) | |
387 "movq %%mm2, %%mm4 \n\t" // YUYV YUYV(12) | |
388 "psrlw $8, %%mm1 \n\t" // U0V0 U0V0(8) | |
389 "psrlw $8, %%mm2 \n\t" // U0V0 U0V0(12) | |
390 "pand %%mm7, %%mm3 \n\t" // Y0Y0 Y0Y0(8) | |
391 "pand %%mm7, %%mm4 \n\t" // Y0Y0 Y0Y0(12) | |
392 "packuswb %%mm2, %%mm1 \n\t" // UVUV UVUV(8) | |
393 "packuswb %%mm4, %%mm3 \n\t" // YYYY YYYY(8) | |
394 | |
395 MOVNTQ" %%mm3, 8(%1, %%eax, 2) \n\t" | |
396 | |
397 "movq %%mm0, %%mm2 \n\t" // UVUV UVUV(0) | |
398 "movq %%mm1, %%mm3 \n\t" // UVUV UVUV(8) | |
399 "psrlw $8, %%mm0 \n\t" // V0V0 V0V0(0) | |
400 "psrlw $8, %%mm1 \n\t" // V0V0 V0V0(8) | |
401 "pand %%mm7, %%mm2 \n\t" // U0U0 U0U0(0) | |
402 "pand %%mm7, %%mm3 \n\t" // U0U0 U0U0(8) | |
403 "packuswb %%mm1, %%mm0 \n\t" // VVVV VVVV(0) | |
404 "packuswb %%mm3, %%mm2 \n\t" // UUUU UUUU(0) | |
405 | |
406 MOVNTQ" %%mm0, (%3, %%eax) \n\t" | |
407 MOVNTQ" %%mm2, (%2, %%eax) \n\t" | |
408 | |
409 "addl $8, %%eax \n\t" | |
410 "cmpl %4, %%eax \n\t" | |
411 " jb 1b \n\t" | |
412 EMMS" \n\t" | |
413 SFENCE | |
414 ::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "r" (num_pixels>>1) | |
415 : "memory", "%eax" | |
416 ); | |
417 #else | |
2701 | 418 int i; |
2702 | 419 num_pixels>>=1; |
420 for(i=0; i<num_pixels; i++) | |
2701 | 421 { |
422 ydst[2*i+0] = src[4*i+0]; | |
423 udst[i] = src[4*i+1]; | |
424 ydst[2*i+1] = src[4*i+2]; | |
425 vdst[i] = src[4*i+3]; | |
426 } | |
2704 | 427 #endif |
2723 | 428 } |