mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-02 09:51:11 +00:00
Faster RGB to YUV conversion
Original commit message from CVS: Faster RGB to YUV conversion
This commit is contained in:
parent
5d8ebbc9f5
commit
c7669b9434
1 changed files with 42 additions and 112 deletions
|
@ -12,139 +12,69 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#define RGB2YUV_SHIFT 8
|
#define Y_FROM_RGB(r,g,b) ((9798 * (r) + 19235 * (g) + 3736 * (b)) >> 15)
|
||||||
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
|
#define U_FROM_BY(b,y) ((16122 * ((b) - (y))) >> 15) + 128;
|
||||||
#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
|
#define V_FROM_RY(r,y) ((25203 * ((r) - (y))) >> 15) + 128;
|
||||||
#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))
|
|
||||||
|
|
||||||
/**
|
static void
|
||||||
*
|
gst_colorspace_rgb32_to_yuv (unsigned char *src,
|
||||||
* height should be a multiple of 2 and width should be a multiple of 2 (if this is a
|
unsigned char *ydst,
|
||||||
* problem for anyone then tell me, and ill fix it)
|
unsigned char *udst,
|
||||||
* chrominance data is only taken from every secound line others are ignored FIXME write HQ version
|
unsigned char *vdst,
|
||||||
*/
|
guint width, guint height)
|
||||||
void
|
|
||||||
gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height)
|
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
const int chrom_width = width >> 1;
|
const int chrom_width = width >> 1;
|
||||||
const int chrom_size = (width * height) >> 2;
|
int Y;
|
||||||
|
int b, g, r;
|
||||||
|
|
||||||
unsigned char *ydst = dest;
|
for (y = height; y; y -= 2) {
|
||||||
unsigned char *udst = ydst + (width * height);
|
|
||||||
unsigned char *vdst = udst + chrom_size;
|
|
||||||
|
|
||||||
for (y = 0; y < height; y += 2) {
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < chrom_width; i++) {
|
for (i = chrom_width; i; i--) {
|
||||||
unsigned int b = src[8 * i + 0];
|
b = *src++;
|
||||||
unsigned int g = src[8 * i + 1];
|
g = *src++;
|
||||||
unsigned int r = src[8 * i + 2];
|
r = *src++;
|
||||||
|
src++;
|
||||||
|
|
||||||
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
Y = Y_FROM_RGB (r,g,b);
|
||||||
unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
|
|
||||||
unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
|
|
||||||
|
|
||||||
udst[i] = U;
|
*ydst++ = Y;
|
||||||
vdst[i] = V;
|
*udst++ = U_FROM_BY (b,Y);
|
||||||
ydst[2 * i] = Y;
|
*vdst++ = V_FROM_RY (r,Y);
|
||||||
|
|
||||||
b = src[8 * i + 4];
|
b = *src++;
|
||||||
g = src[8 * i + 5];
|
g = *src++;
|
||||||
r = src[8 * i + 6];
|
r = *src++; src++;
|
||||||
|
|
||||||
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
*ydst++ = Y_FROM_RGB (r,g,b);
|
||||||
ydst[2 * i + 1] = Y;
|
|
||||||
}
|
}
|
||||||
ydst += width;
|
|
||||||
src += (width * 4);
|
|
||||||
|
|
||||||
for (i = 0; i < chrom_width; i++) {
|
for (i = width; i; i--) {
|
||||||
unsigned int b = src[8 * i + 0];
|
b = *src++;
|
||||||
unsigned int g = src[8 * i + 1];
|
g = *src++;
|
||||||
unsigned int r = src[8 * i + 2];
|
r = *src++; src++;
|
||||||
|
*ydst++ = Y_FROM_RGB (r,g,b);
|
||||||
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
|
|
||||||
ydst[2 * i] = Y;
|
|
||||||
|
|
||||||
b = src[8 * i + 4];
|
|
||||||
g = src[8 * i + 5];
|
|
||||||
r = src[8 * i + 6];
|
|
||||||
|
|
||||||
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
ydst[2 * i + 1] = Y;
|
|
||||||
}
|
}
|
||||||
udst += chrom_width;
|
|
||||||
vdst += chrom_width;
|
|
||||||
ydst += width;
|
|
||||||
src += (width * 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height)
|
||||||
|
{
|
||||||
|
unsigned char *ydst = dest;
|
||||||
|
unsigned char *udst = ydst + (width * height);
|
||||||
|
unsigned char *vdst = udst + ((width * height) >> 2);
|
||||||
|
|
||||||
|
gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height)
|
gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height)
|
||||||
{
|
{
|
||||||
int y;
|
|
||||||
const int chrom_width = width >> 1;
|
|
||||||
const int chrom_size = (width * height) >> 2;
|
|
||||||
|
|
||||||
unsigned char *ydst = dest;
|
unsigned char *ydst = dest;
|
||||||
unsigned char *vdst = ydst + (width * height);
|
unsigned char *vdst = ydst + (width * height);
|
||||||
unsigned char *udst = vdst + chrom_size;
|
unsigned char *udst = vdst + ((width * height) >> 2);
|
||||||
|
|
||||||
for (y = 0; y < height; y += 2) {
|
gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height);
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < chrom_width; i++) {
|
|
||||||
unsigned int b = src[8 * i + 0];
|
|
||||||
unsigned int g = src[8 * i + 1];
|
|
||||||
unsigned int r = src[8 * i + 2];
|
|
||||||
|
|
||||||
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
|
|
||||||
unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
|
|
||||||
|
|
||||||
udst[i] = U;
|
|
||||||
vdst[i] = V;
|
|
||||||
ydst[2 * i] = Y;
|
|
||||||
|
|
||||||
b = src[8 * i + 4];
|
|
||||||
g = src[8 * i + 5];
|
|
||||||
r = src[8 * i + 6];
|
|
||||||
|
|
||||||
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
ydst[2 * i + 1] = Y;
|
|
||||||
}
|
|
||||||
ydst += width;
|
|
||||||
src += (width * 4);
|
|
||||||
|
|
||||||
for (i = 0; i < chrom_width; i++) {
|
|
||||||
unsigned int b = src[8 * i + 0];
|
|
||||||
unsigned int g = src[8 * i + 1];
|
|
||||||
unsigned int r = src[8 * i + 2];
|
|
||||||
|
|
||||||
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
|
|
||||||
ydst[2 * i] = Y;
|
|
||||||
|
|
||||||
b = src[8 * i + 4];
|
|
||||||
g = src[8 * i + 5];
|
|
||||||
r = src[8 * i + 6];
|
|
||||||
|
|
||||||
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
|
|
||||||
ydst[2 * i + 1] = Y;
|
|
||||||
}
|
|
||||||
udst += chrom_width;
|
|
||||||
vdst += chrom_width;
|
|
||||||
ydst += width;
|
|
||||||
src += (width * 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue