diff options
Diffstat (limited to 'recordmydesktop/src')
-rw-r--r-- | recordmydesktop/src/Makefile.am | 2 | ||||
-rw-r--r-- | recordmydesktop/src/get_frame.c | 1 | ||||
-rw-r--r-- | recordmydesktop/src/initialize_data.c | 28 | ||||
-rw-r--r-- | recordmydesktop/src/update_image.c | 1 | ||||
-rw-r--r-- | recordmydesktop/src/yuv_utils.c | 55 | ||||
-rw-r--r-- | recordmydesktop/src/yuv_utils.h | 356 |
6 files changed, 416 insertions, 27 deletions
diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am index e1633ca..fff50e8 100644 --- a/recordmydesktop/src/Makefile.am +++ b/recordmydesktop/src/Makefile.am @@ -37,6 +37,8 @@ recordmydesktop_SOURCES = \ skeleton.c \ specsfile.c \ update_image.c \ + yuv_utils.c \ + yuv_utils.h \ wm_check.c diff --git a/recordmydesktop/src/get_frame.c b/recordmydesktop/src/get_frame.c index 1a5d445..39bbb36 100644 --- a/recordmydesktop/src/get_frame.c +++ b/recordmydesktop/src/get_frame.c @@ -27,6 +27,7 @@ #include "recordmydesktop.h" #include "rectinsert.h" +#include "yuv_utils.h" #define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,wgeom){\ diff --git a/recordmydesktop/src/initialize_data.c b/recordmydesktop/src/initialize_data.c index 1e206ae..acc2668 100644 --- a/recordmydesktop/src/initialize_data.c +++ b/recordmydesktop/src/initialize_data.c @@ -24,8 +24,8 @@ * For further information contact me at johnvarouhakis@gmail.com * ******************************************************************************/ - #include "recordmydesktop.h" +#include "yuv_utils.h" #ifdef HAVE_LIBASOUND @@ -44,32 +44,6 @@ static void FixBufferSize(u_int32_t *buffsize) { (int)buffsize_ret,(int)*buffsize); } -/** -* Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values. -*/ -static void MakeMatrices () { - int i; - - for (i = 0; i < 256; i++) - Yr[i] = (2104.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Yg[i] = (4130.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Yb[i] = (802.0 * i) / 8192.0; - - for (i = 0; i < 256; i++) - Ur[i] = 37.8 - (1204.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Ug[i] = 74.2 - (2384.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - UbVr[i] = (3598.0 * i) / 8192.0 ; - - for (i = 0; i < 256; i++) - Vg[i] = 93.8 - (3013.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Vb[i] = 18.2 - (585.0 * i) / 8192.0 + 8.0; -} - int InitializeData(ProgData *pdata, EncData *enc_data, CacheData *cache_data){ diff --git a/recordmydesktop/src/update_image.c b/recordmydesktop/src/update_image.c index bccd544..7a09920 100644 --- a/recordmydesktop/src/update_image.c +++ b/recordmydesktop/src/update_image.c @@ -26,6 +26,7 @@ #include "recordmydesktop.h" +#include "yuv_utils.h" void UpdateImage(Display * dpy, diff --git a/recordmydesktop/src/yuv_utils.c b/recordmydesktop/src/yuv_utils.c new file mode 100644 index 0000000..e80c5e2 --- /dev/null +++ b/recordmydesktop/src/yuv_utils.c @@ -0,0 +1,55 @@ +/****************************************************************************** +* recordMyDesktop * +******************************************************************************* +* * +* Copyright (C) 2006,2007,2008 John Varouhakis * +* * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* * +* * +* For further information contact me at johnvarouhakis@gmail.com * +******************************************************************************/ + +#include "yuv_utils.h" + +// Keep these global (for performance reasons I assume). +unsigned char Yr[256], Yg[256], Yb[256], + Ur[256], Ug[256], UbVr[256], + Vg[256], Vb[256]; + +void MakeMatrices (void) { + int i; + + for (i = 0; i < 256; i++) + Yr[i] = (2104.0 * i) / 8192.0 + 8.0; + for (i = 0; i < 256; i++) + Yg[i] = (4130.0 * i) / 8192.0 + 8.0; + for (i = 0; i < 256; i++) + Yb[i] = (802.0 * i) / 8192.0; + + for (i = 0; i < 256; i++) + Ur[i] = 37.8 - (1204.0 * i) / 8192.0 + 8.0; + for (i = 0; i < 256; i++) + Ug[i] = 74.2 - (2384.0 * i) / 8192.0 + 8.0; + for (i = 0; i < 256; i++) + UbVr[i] = (3598.0 * i) / 8192.0 ; + + for (i = 0; i < 256; i++) + Vg[i] = 93.8 - (3013.0 * i) / 8192.0 + 8.0; + for (i = 0; i < 256; i++) + Vb[i] = 18.2 - (585.0 * i) / 8192.0 + 8.0; +} diff --git a/recordmydesktop/src/yuv_utils.h b/recordmydesktop/src/yuv_utils.h new file mode 100644 index 0000000..14809ff --- /dev/null +++ b/recordmydesktop/src/yuv_utils.h @@ -0,0 +1,356 @@ +/****************************************************************************** +* recordMyDesktop * +******************************************************************************* +* * +* Copyright (C) 2006,2007,2008 John Varouhakis * +* * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* * +* * +* For further information contact me at johnvarouhakis@gmail.com * +******************************************************************************/ + +#ifndef YUV_UTILS_H +#define YUV_UTILS_H 1 + + +// The macros work directly on this data (for performance reasons I +// suppose) so we keep this global +extern unsigned char Yr[256], Yg[256], Yb[256], + Ur[256], Ug[256], UbVr[256], + Vg[256], Vb[256]; + + +#define POINT_IN_BLOCK(xv,yv,widthv,blocksize) ((yv/blocksize)*\ + (widthv/blocksize)+\ + (xv/blocksize)) + +#define UPDATE_Y_PLANE(data,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ + *_yr=Yr,*_yg=Yg,*_yb=Yb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data;\ + for(k=0;k<height_tm;k++){\ + for(i=0;i<width_tm;i++){\ + t_val=*datapi;\ + *yuv_y=_yr[__RVALUE_##__bit_depth__(t_val)] +\ + _yg[__GVALUE_##__bit_depth__(t_val)] +\ + _yb[__BVALUE_##__bit_depth__(t_val)] ;\ + datapi++;\ + yuv_y++;\ + }\ + yuv_y+=yuv->y_width-width_tm;\ + }\ +} + +#define UPDATE_Y_PLANE_DBUF(data,\ + data_back,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ + *_yr=Yr,*_yg=Yg,*_yb=Yb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data,\ + *datapi_back=(u_int##__bit_depth__##_t *)data_back;\ + for(k=0;k<height_tm;k++){\ + for(i=0;i<width_tm;i++){\ + if(*datapi!=*datapi_back){\ + t_val=*datapi;\ + *yuv_y=_yr[__RVALUE_##__bit_depth__(t_val)] +\ + _yg[__GVALUE_##__bit_depth__(t_val)] +\ + _yb[__BVALUE_##__bit_depth__(t_val)] ;\ + yblocks[POINT_IN_BLOCK(i,k,width_tm,Y_UNIT_WIDTH)]=1;\ + }\ + datapi++;\ + datapi_back++;\ + yuv_y++;\ + }\ + yuv_y+=yuv->y_width-width_tm;\ + }\ +} + +#define UPDATE_A_UV_PIXEL(yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + if(__sampling_type==__PXL_AVERAGE){\ + CALC_TVAL_AVG_##__bit_depth__(t_val,datapi,datapi_next)\ + }\ + else\ + t_val=*datapi;\ + *yuv_u=\ + _ur[__RVALUE_##__bit_depth__(t_val)] +\ + _ug[__GVALUE_##__bit_depth__(t_val)] +\ + _ubvr[__BVALUE_##__bit_depth__(t_val)];\ + *yuv_v=\ + _ubvr[__RVALUE_##__bit_depth__(t_val)] +\ + _vg[__GVALUE_##__bit_depth__(t_val)] +\ + _vb[__BVALUE_##__bit_depth__(t_val)];\ + + +#define UPDATE_UV_PLANES(data,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __sampling_type,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *_ur=Ur,*_ug=Ug,*_ubvr=UbVr,\ + *_vg=Vg,*_vb=Vb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data,\ + *datapi_next=NULL;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next=datapi+width_tm;\ + }\ + for(k=0;k<height_tm;k+=2){\ + for(i=0;i<width_tm;i+=2){\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + datapi+=2;\ + if(__sampling_type==__PXL_AVERAGE)\ + datapi_next+=2;\ + yuv_u++;\ + yuv_v++;\ + }\ + yuv_u+=(yuv->y_width-width_tm)/2;\ + yuv_v+=(yuv->y_width-width_tm)/2;\ + datapi+=width_tm;\ + if(__sampling_type==__PXL_AVERAGE)\ + datapi_next+=width_tm;\ + }\ +} + +#define UPDATE_UV_PLANES_DBUF( data,\ + data_back,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __sampling_type,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *_ur=Ur,*_ug=Ug,*_ubvr=UbVr,\ + *_vg=Vg,*_vb=Vb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data,\ + *datapi_next=NULL,\ + *datapi_back=(u_int##__bit_depth__##_t *)data_back,\ + *datapi_back_next=NULL;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next=datapi+width_tm;\ + datapi_back_next=datapi_back+width_tm;\ + for(k=0;k<height_tm;k+=2){\ + for(i=0;i<width_tm;i+=2){\ + if(( (*datapi!=*datapi_back) ||\ + (*(datapi+1)!=*(datapi_back+1)) ||\ + (*datapi_next!=*datapi_back_next) ||\ + (*(datapi_next+1)!=*(datapi_back_next+1)))){\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + ublocks[POINT_IN_BLOCK(i,k,width_tm,Y_UNIT_WIDTH)]=1;\ + vblocks[POINT_IN_BLOCK(i,k,width_tm,Y_UNIT_WIDTH)]=1;\ + }\ + datapi+=2;\ + datapi_back+=2;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=2;\ + datapi_back_next+=2;\ + }\ + yuv_u++;\ + yuv_v++;\ + }\ + yuv_u+=(yuv->y_width-width_tm)/2;\ + yuv_v+=(yuv->y_width-width_tm)/2;\ + datapi+=width_tm;\ + datapi_back+=width_tm;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=width_tm;\ + datapi_back_next+=width_tm;\ + }\ + }\ + }\ + else{\ + for(k=0;k<height_tm;k+=2){\ + for(i=0;i<width_tm;i+=2){\ + if ((*datapi!=*datapi_back)){\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + ublocks[POINT_IN_BLOCK(i,k,width_tm,Y_UNIT_WIDTH)]=1;\ + vblocks[POINT_IN_BLOCK(i,k,width_tm,Y_UNIT_WIDTH)]=1;\ + }\ + datapi+=2;\ + datapi_back+=2;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=2;\ + datapi_back_next+=2;\ + }\ + yuv_u++;\ + yuv_v++;\ + }\ + yuv_u+=(yuv->y_width-width_tm)/2;\ + yuv_v+=(yuv->y_width-width_tm)/2;\ + datapi+=width_tm;\ + datapi_back+=width_tm;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=width_tm;\ + datapi_back_next+=width_tm;\ + }\ + }\ + }\ +} + +#define UPDATE_YUV_BUFFER(yuv,\ + data,\ + data_back,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + __sampling_type,\ + __color_depth){\ + if(data_back==NULL){\ + if((__color_depth==24)||(__color_depth==32)){\ + UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,32)\ + UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,32)\ + }\ + else if(__color_depth==16){\ + UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,16)\ + UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,16)\ + }\ + }\ + else{\ + if((__color_depth==24)||(__color_depth==32)){\ + UPDATE_Y_PLANE_DBUF(data,data_back,x_tm,y_tm,\ + height_tm,width_tm,yuv,32)\ + UPDATE_UV_PLANES_DBUF(data,data_back,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,32)\ + }\ + else if(__color_depth==16){\ + UPDATE_Y_PLANE_DBUF(data,data_back,x_tm,y_tm,\ + height_tm,width_tm,yuv,16)\ + UPDATE_UV_PLANES_DBUF(data,data_back,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,16)\ + }\ + }\ +} + +#define DUMMY_POINTER_TO_YUV(yuv,\ + data_tm,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + x_offset,\ + y_offset,\ + no_pixel){\ + int i,k,j=0;\ + int x_2=x_tm/2,y_2=y_tm/2,y_width_2=(yuv)->y_width/2;\ + for(k=y_offset;k<y_offset+height_tm;k++){\ + for(i=x_offset;i<x_offset+width_tm;i++){\ + j=k*16+i;\ + if(data_tm[(j*4)]!=(no_pixel)){\ + (yuv)->y[x_tm+(i-x_offset)+((k-y_offset)+y_tm)*(yuv)->y_width]=\ + Yr[data_tm[(j*4)+__RBYTE]] +\ + Yg[data_tm[(j*4)+__GBYTE]] +\ + Yb[data_tm[(j*4)+__BBYTE]];\ + if((k%2)&&(i%2)){\ + yuv->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\ + Ur[data_tm[(k*width_tm+i)*4+__RBYTE]] +\ + Ug[data_tm[(k*width_tm+i)*4+__GBYTE]] +\ + UbVr[data_tm[(k*width_tm+i)*4+__BBYTE]];\ + yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\ + UbVr[data_tm[(k*width_tm+i)*4+__RBYTE]] +\ + Vg[data_tm[(k*width_tm+i)*4+__GBYTE]] +\ + Vb[data_tm[(k*width_tm+i)*4+__BBYTE]] ;\ + }\ + }\ + }\ + }\ +} + +#define MARK_BACK_BUFFER_C( data,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + buffer_width,\ + __bit_depth__){\ + int k,i;\ + register u_int##__bit_depth__##_t\ + *datapi=\ + ((u_int##__bit_depth__##_t *)data)+y_tm*buffer_width+x_tm;\ + for(k=0;k<height_tm;k++){\ + for(i=0;i<width_tm;i++){\ + *datapi+=1;\ + datapi++;\ + }\ + datapi+=buffer_width-width_tm;\ + }\ +} + + +/** +* Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values. +*/ +void MakeMatrices(void); + + +#endif |