Created
April 26, 2012 19:04
-
-
Save rdp/2502032 to your computer and use it in GitHub Desktop.
rgb32 to i420/yv12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int rgb32_to_i420(int width, int height, const char * src, char * dst) | |
{ | |
unsigned char * dst_y_even; | |
unsigned char * dst_y_odd; | |
unsigned char * dst_u; | |
unsigned char * dst_v; | |
const unsigned char *src_even; | |
const unsigned char *src_odd; | |
int i, j; | |
src_even = (const unsigned char *)src; | |
src_odd = src_even + width * 4; | |
// it's planar | |
dst_y_even = (unsigned char *) dst; | |
dst_y_odd = dst_y_even + width; | |
dst_u = dst_y_even + width * height; | |
dst_v = dst_u + ((width * height) >> 2); | |
// NB this doesn't work perfectly for u and v values of the edges of the video if your video size is not divisible by 2. FWIW. | |
for ( i = 0; i < height / 2; ++i ) | |
{ | |
for ( j = 0; j < width / 2; ++j ) | |
{ | |
short r, g, b; | |
b = *src_even++; | |
g = *src_even++; | |
r = *src_even++; | |
++src_even; | |
*dst_y_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; | |
short sum_r = r, sum_g = g, sum_b = b; | |
b = *src_even++; | |
g = *src_even++; | |
r = *src_even++; | |
++src_even; | |
*dst_y_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; | |
sum_r += r; | |
sum_g += g; | |
sum_b += b; | |
b = *src_odd++; | |
g = *src_odd++; | |
r = *src_odd++; | |
++src_odd; | |
*dst_y_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; | |
sum_r += r; | |
sum_g += g; | |
sum_b += b; | |
b = *src_odd++; | |
g = *src_odd++; | |
r = *src_odd++; | |
++src_odd; | |
*dst_y_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; | |
sum_r += r; | |
sum_g += g; | |
sum_b += b; | |
// compute ave's of this 2x2 bloc for us and v | |
// could use Catmull-Rom interpolation maybe? | |
sum_r += 2; | |
sum_g += 2; | |
sum_b += 2; | |
sum_r /= 4; | |
sum_g /= 4; | |
sum_b /= 4; | |
*dst_u++ = (( sum_r * -38 - sum_g * 74 + sum_b * 112 + 128 ) >> 8 ) + 128; // only one | |
*dst_v++ = (( sum_r * 112 - sum_g * 94 - sum_b * 18 + 128 ) >> 8 ) + 128; // only one | |
} | |
dst_y_even += width; | |
dst_y_odd += width; | |
src_even += width * 4; | |
src_odd += width * 4; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment