diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-17 11:12:07 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-17 11:21:51 +0100 |
commit | f9a50de3dcc501e930de6c60983a4feb57121e7e (patch) | |
tree | e2a65ef9a1ce5c15faf8e95e0337e821e2579ac7 /overlay/x11/rgb2yuv.c | |
parent | 7df9caeea1606b4f0272de35f0d7f70eedd5ec30 (diff) |
Introduce intel-gpu-overlay
A realtime display of GPU activity. Note, this is just at the point of
minimum usability...
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'overlay/x11/rgb2yuv.c')
-rw-r--r-- | overlay/x11/rgb2yuv.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/overlay/x11/rgb2yuv.c b/overlay/x11/rgb2yuv.c new file mode 100644 index 00000000..8e0c080e --- /dev/null +++ b/overlay/x11/rgb2yuv.c @@ -0,0 +1,105 @@ +#include <stdint.h> +#include <stdlib.h> + +#include "rgb2yuv.h" + +static int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256]; +static int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256]; +static int RGB2YUV_VG[256], RGB2YUV_VB[256]; + +void rgb2yuv_init(void) +{ + int i; + + for (i = 0; i < 256; i++) + RGB2YUV_YR[i] = 65.481 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_YG[i] = 128.553 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_YB[i] = 24.966 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_UR[i] = 37.797 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_UG[i] = 74.203 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_VG[i] = 93.786 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_VB[i] = 18.214 * (i << 8); + + for (i = 0; i < 256; i++) + RGB2YUV_UBVR[i] = 112 * (i << 8); +} + +int rgb2yuv(cairo_surface_t *surface, XvImage *image, uint8_t *yuv) +{ + uint8_t *data = cairo_image_surface_get_data(surface); + int rgb_stride = cairo_image_surface_get_stride(surface); + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + int y_stride = image->pitches[0]; + int uv_stride = image->pitches[1]; + uint8_t *tmp, *tl, *tr, *bl, *br; + int i, j; + + tmp = malloc(2*width*height); + if (tmp == NULL) + return 0; + + tl = tmp; + bl = tmp + width*height; + + for (i = 0; i < height; i++) { + uint16_t *rgb = (uint16_t *)(data + i * rgb_stride); + for (j = 0; j < width; j++) { + uint8_t r = (rgb[j] >> 11) & 0x1f; + uint8_t g = (rgb[j] >> 5) & 0x3f; + uint8_t b = (rgb[j] >> 0) & 0x1f; + + r = r<<3 | r>>2; + g = g<<2 | g>>4; + b = b<<3 | b>>2; + + yuv[j] = (RGB2YUV_YR[r] + RGB2YUV_YG[g] + RGB2YUV_YB[b] + 1048576) >> 16; + *tl++ = (-RGB2YUV_UR[r] - RGB2YUV_UG[g] + RGB2YUV_UBVR[b] + 8388608) >> 16; + *bl++ = (RGB2YUV_UBVR[r] - RGB2YUV_VG[g] - RGB2YUV_VB[b] + 8388608) >> 16; + } + yuv += y_stride; + } + + tl = tmp; tr = tl + 1; + bl = tl + width; br = bl + 1; + for (i = 0; i < height/2; i ++) { + for (j = 0; j < width/2; j ++) { + yuv[j] = ((int)*tl + *tr + *bl + *br) >> 2; + tl += 2; tr += 2; + bl += 2; br += 2; + } + yuv += uv_stride; + + tl += width; tr += width; + bl += width; br += width; + } + + tl = tmp + width*height; tr = tl + 1; + bl = tl + width; br = bl + 1; + for (i = 0; i < height/2; i++) { + for (j = 0; j < width/2; j++) { + yuv[j] = ((int)*tl + *tr + *bl + *br) >> 2; + tl += 2; tr += 2; + bl += 2; br += 2; + } + yuv += uv_stride; + + tl += width; tr += width; + bl += width; br += width; + } + + free(tmp); + return 1; +} |