Skip to content

Instantly share code, notes, and snippets.

@rdp
Created April 26, 2012 19:04
Show Gist options
  • Save rdp/2502032 to your computer and use it in GitHub Desktop.
Save rdp/2502032 to your computer and use it in GitHub Desktop.
rgb32 to i420/yv12
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