summaryrefslogtreecommitdiff
path: root/rMD-exp/src/get_frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'rMD-exp/src/get_frame.c')
-rw-r--r--rMD-exp/src/get_frame.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/rMD-exp/src/get_frame.c b/rMD-exp/src/get_frame.c
new file mode 100644
index 0000000..b1da1fe
--- /dev/null
+++ b/rMD-exp/src/get_frame.c
@@ -0,0 +1,209 @@
+/*********************************************************************************
+* recordMyDesktop *
+**********************************************************************************
+* *
+* Copyright (C) 2006 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 <recordmydesktop.h>
+
+void *GetFrame(void *pdata){
+ int tlist_sel=0;
+ pthread_mutex_t pmut,tmut;
+ uint msk_ret;
+ WGeometry mouse_pos_abs,mouse_pos_rel,mouse_pos_temp;
+ Window root_ret,child_ret;
+ int pixel_total=((ProgData *)pdata)->brwin.rgeom.width*((ProgData *)pdata)->brwin.rgeom.height;
+ XFixesCursorImage *xcim=NULL;
+
+ mouse_pos_abs.x=mouse_pos_temp.x=0;
+ mouse_pos_abs.y=mouse_pos_temp.y=0;
+ mouse_pos_abs.width=mouse_pos_temp.width=((ProgData *)pdata)->dummy_p_size;
+ mouse_pos_abs.height=mouse_pos_temp.height=((ProgData *)pdata)->dummy_p_size;
+ pthread_mutex_init(&pmut,NULL);
+ pthread_mutex_init(&tmut,NULL);
+
+ while(((ProgData *)pdata)->running){
+
+ //if we are left behind we must not wait.
+ //also before actually pausing we must make sure the streams
+ //are synced. sound stops so this should only happen quickly.
+ if(((ProgData *)pdata)->avd>0){
+ pthread_cond_wait(&((ProgData *)pdata)->time_cond,&tmut);
+ if(Paused){
+ pthread_cond_wait(&((ProgData *)pdata)->pause_cond,&pmut);
+ }
+ }
+ capture_busy=1;
+
+ /*pthread_cond_wait(&((ProgData *)pdata)->pause_cond,&((ProgData *)pdata)->pause_cond_mutex);*/
+ //mutexes and lists with changes are useless when full_shots is enabled
+ if(!((ProgData *)pdata)->args.full_shots){
+ tlist_sel=((ProgData *)pdata)->list_selector;
+ ((ProgData *)pdata)->list_selector=((((ProgData *)pdata)->list_selector+1)%2);
+ pthread_mutex_lock(&((ProgData *)pdata)->list_mutex[tlist_sel]);
+ }
+ //here we measure the list and decide which way we will go
+ if(!((ProgData *)pdata)->args.nocondshared){
+ int level=0;
+ RectArea *temp=((ProgData *)pdata)->rect_root[tlist_sel];
+
+ if(temp!=NULL){
+ do{
+ level+=temp->geom.width*temp->geom.height;
+ temp=temp->next;
+ }while(temp!=NULL);
+ level*=100;
+ level/=pixel_total;
+ ((ProgData *)pdata)->args.noshared=(level<((ProgData *)pdata)->args.shared_thres);
+// if(!((ProgData *)pdata)->args.noshared){
+// fprintf(stderr,"shared screenshot with %d\n",level);
+// }
+ }
+ }
+ if(((ProgData *)pdata)->args.xfixes_cursor){
+ //xfixes pointer sequence
+ //update previous_position
+ //(if full_shots is enabled this is skipped since it's pointless)
+ if(!((ProgData *)pdata)->args.full_shots){
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp);
+ if((mouse_pos_temp.x>=0)&&(mouse_pos_temp.y>=0)&&(mouse_pos_temp.width>0)&&(mouse_pos_temp.height>0))
+ RectInsert(&((ProgData *)pdata)->rect_root[tlist_sel],&mouse_pos_temp);
+ }
+ xcim=XFixesGetCursorImage(((ProgData *)pdata)->dpy);
+ mouse_pos_abs.x=xcim->x;
+ mouse_pos_abs.y=xcim->y;
+ mouse_pos_abs.width=xcim->width;
+ mouse_pos_abs.height=xcim->height;
+ }
+ if(((ProgData *)pdata)->args.have_dummy_cursor){
+ //dummy pointer sequence
+ //update previous_position
+ //(if full_shots is enabled this is skipped since it's pointless)
+ if(!((ProgData *)pdata)->args.full_shots){
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp);
+ if((mouse_pos_temp.x>=0)&&(mouse_pos_temp.y>=0)&&(mouse_pos_temp.width>0)&&(mouse_pos_temp.height>0))
+ RectInsert(&((ProgData *)pdata)->rect_root[tlist_sel],&mouse_pos_temp);
+ }
+ //find new one
+ XQueryPointer(((ProgData *)pdata)->dpy,
+ ((ProgData *)pdata)->specs.root,
+ &root_ret,&child_ret,
+ &mouse_pos_abs.x,&mouse_pos_abs.y,
+ &mouse_pos_rel.x,&mouse_pos_rel.y,&msk_ret);
+ }
+ if(!((ProgData *)pdata)->args.noshared)
+ XShmGetImage(((ProgData *)pdata)->dpy,((ProgData *)pdata)->specs.root,((ProgData *)pdata)->shimage,(((ProgData *)pdata)->brwin.rgeom.x),(((ProgData *)pdata)->brwin.rgeom.y),AllPlanes);
+ if(!((ProgData *)pdata)->args.full_shots)
+ UpdateImage(((ProgData *)pdata)->dpy,
+ &((ProgData *)pdata)->enc_data->yuv,
+ &((ProgData *)pdata)->yuv_mutex,
+ &((ProgData *)pdata)->specs,
+ &((ProgData *)pdata)->rect_root[tlist_sel],
+ &((ProgData *)pdata)->brwin,
+ ((ProgData *)pdata)->enc_data,
+ ((((ProgData *)pdata)->args.noshared)?(((ProgData *)pdata)->datatemp):((ProgData *)pdata)->shimage->data),
+ ((ProgData *)pdata)->args.noshared,
+ ((ProgData *)pdata)->args.no_quick_subsample);
+ else{
+ if(((ProgData *)pdata)->args.noshared){
+ GetZPixmap( ((ProgData *)pdata)->dpy,
+ ((ProgData *)pdata)->specs.root,
+ ((ProgData *)pdata)->image->data,
+ ((ProgData *)pdata)->brwin.rgeom.x,
+ ((ProgData *)pdata)->brwin.rgeom.y,
+ ((ProgData *)pdata)->brwin.rgeom.width,
+ ((ProgData *)pdata)->brwin.rgeom.height);
+ pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex);
+ if(((ProgData *)pdata)->args.no_quick_subsample){
+ UPDATE_YUV_BUFFER_IM_AVG((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)((ProgData *)pdata)->image->data),
+ (((ProgData *)pdata)->enc_data->x_offset),(((ProgData *)pdata)->enc_data->y_offset),
+ (((ProgData *)pdata)->brwin.rgeom.width),(((ProgData *)pdata)->brwin.rgeom.height));
+ }
+ else{
+ UPDATE_YUV_BUFFER_IM((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)((ProgData *)pdata)->image->data),
+ (((ProgData *)pdata)->enc_data->x_offset),(((ProgData *)pdata)->enc_data->y_offset),
+ (((ProgData *)pdata)->brwin.rgeom.width),(((ProgData *)pdata)->brwin.rgeom.height));
+ }
+ pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex);
+ }
+ else{
+ pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex);
+ if(((ProgData *)pdata)->args.no_quick_subsample){
+ UPDATE_YUV_BUFFER_IM_AVG((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)((ProgData *)pdata)->shimage->data),
+ (((ProgData *)pdata)->enc_data->x_offset),(((ProgData *)pdata)->enc_data->y_offset),
+ (((ProgData *)pdata)->brwin.rgeom.width),(((ProgData *)pdata)->brwin.rgeom.height));
+ }
+ else{
+ UPDATE_YUV_BUFFER_IM((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)((ProgData *)pdata)->shimage->data),
+ (((ProgData *)pdata)->enc_data->x_offset),(((ProgData *)pdata)->enc_data->y_offset),
+ (((ProgData *)pdata)->brwin.rgeom.width),(((ProgData *)pdata)->brwin.rgeom.height));
+ }
+
+ pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex);
+ }
+ }
+ if(((ProgData *)pdata)->args.xfixes_cursor){
+ //avoid segfaults
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp);
+ //draw the cursor
+ if((mouse_pos_temp.x>=0)&&(mouse_pos_temp.y>=0)&&(mouse_pos_temp.width>0)&&(mouse_pos_temp.height>0)){
+ XFIXES_POINTER_TO_YUV((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)xcim->pixels),
+ (mouse_pos_temp.x-((ProgData *)pdata)->brwin.rgeom.x+((ProgData *)pdata)->enc_data->x_offset),
+ (mouse_pos_temp.y-((ProgData *)pdata)->brwin.rgeom.y+((ProgData *)pdata)->enc_data->y_offset),
+ mouse_pos_temp.width,
+ mouse_pos_temp.height,
+ (xcim->width-mouse_pos_temp.width));
+ }
+ XFree(xcim);
+ xcim=NULL;
+ }
+
+ if(((ProgData *)pdata)->args.have_dummy_cursor){
+ //avoid segfaults
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp);
+ //draw the cursor
+ if((mouse_pos_temp.x>=0)&&(mouse_pos_temp.y>=0)&&(mouse_pos_temp.width>0)&&(mouse_pos_temp.height>0)){
+ DUMMY_POINTER_TO_YUV((&((ProgData *)pdata)->enc_data->yuv),
+ ((ProgData *)pdata)->dummy_pointer,
+ (mouse_pos_temp.x-((ProgData *)pdata)->brwin.rgeom.x+((ProgData *)pdata)->enc_data->x_offset),
+ (mouse_pos_temp.y-((ProgData *)pdata)->brwin.rgeom.y+((ProgData *)pdata)->enc_data->y_offset),
+ mouse_pos_temp.width,
+ mouse_pos_temp.height,
+ ((ProgData *)pdata)->npxl);
+ }
+ }
+ if(!((ProgData *)pdata)->args.full_shots){
+ ClearList(&((ProgData *)pdata)->rect_root[tlist_sel]);
+ pthread_mutex_unlock(&((ProgData *)pdata)->list_mutex[tlist_sel]);
+ }
+ if(encoder_busy){
+ frames_lost++;
+ }
+ pthread_cond_broadcast(&((ProgData *)pdata)->image_buffer_ready);
+ capture_busy=0;
+ }
+ pthread_cond_broadcast(&((ProgData *)pdata)->image_buffer_ready);
+ pthread_exit(&errno);
+}
+
© All Rights Reserved