diff options
Diffstat (limited to 'rMD-exp/src/recordmydesktop.c')
-rw-r--r-- | rMD-exp/src/recordmydesktop.c | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/rMD-exp/src/recordmydesktop.c b/rMD-exp/src/recordmydesktop.c new file mode 100644 index 0000000..5b7e32b --- /dev/null +++ b/rMD-exp/src/recordmydesktop.c @@ -0,0 +1,259 @@ +/********************************************************************************* +* 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> + + +int main(int argc,char **argv){ + ProgData pdata; + + if(XInitThreads ()==0){ + fprintf(stderr,"Couldn't initialize thread support!\n"); + exit(7); + } + DEFAULT_ARGS(&pdata.args); + if(ParseArgs(argc,argv,&pdata.args)){ + exit(1); + } + if(pdata.args.display!=NULL) + pdata.dpy = XOpenDisplay(pdata.args.display); + else{ + fprintf(stderr,"No display specified for connection!\n"); + exit(8); + } + if (pdata.dpy == NULL) { + fprintf(stderr, "Cannot connect to X server %s\n",pdata.args.display); + exit(9); + } + else{ + EncData enc_data; + pthread_t poll_damage_t, + image_capture_t, + image_encode_t, + sound_capture_t, + sound_encode_t, + flush_to_ogg_t; + XShmSegmentInfo shminfo; + int i; + + QUERY_DISPLAY_SPECS(pdata.dpy,&pdata.specs); + if(pdata.specs.depth!=24){ + fprintf(stderr,"Only 24bpp color depth mode is currently supported.\n"); + exit(10); + } + if(SetBRWindow(pdata.dpy,&pdata.brwin,&pdata.specs,&pdata.args)) + exit(11); + + QueryExtensions(pdata.dpy,&pdata.args,&pdata.damage_event, &pdata.damage_error); + + //init data + + + //these are globals, look for them at the header + frames_total=frames_lost=encoder_busy=capture_busy=0; + + if(!pdata.args.scshot){ + fprintf(stderr,"Initializing...\n"); + MakeMatrices(); + if(pdata.args.have_dummy_cursor){ + pdata.dummy_pointer=MakeDummyPointer(&pdata.specs,16,pdata.args.cursor_color,0,&pdata.npxl); + pdata.dummy_p_size=16; + } + } + if((pdata.args.noshared)||(pdata.args.scshot)) + pdata.datamain=(char *)malloc(pdata.brwin.nbytes); + if(!pdata.args.scshot){ + if(pdata.args.noshared) + pdata.datatemp=(char *)malloc(pdata.brwin.nbytes); + pdata.rect_root[0]=pdata.rect_root[1]=NULL; + pthread_mutex_init(&pdata.list_mutex[0],NULL); + pthread_mutex_init(&pdata.list_mutex[1],NULL); + pthread_mutex_init(&pdata.sound_buffer_mutex,NULL); + pthread_mutex_init(&pdata.libogg_mutex,NULL); + pthread_mutex_init(&pdata.yuv_mutex,NULL); + + pthread_cond_init(&pdata.time_cond,NULL); + pthread_cond_init(&pdata.pause_cond,NULL); + pthread_cond_init(&pdata.image_buffer_ready,NULL); + pthread_cond_init(&pdata.sound_buffer_ready,NULL); + pthread_cond_init(&pdata.sound_data_read,NULL); + pdata.list_selector=Paused=Aborted=pdata.avd=0; + pdata.running=1; + time_cond=&pdata.time_cond; + pause_cond=&pdata.pause_cond; + Running=&pdata.running; + } + if((pdata.args.noshared)||(pdata.args.scshot)){ + pdata.image=XCreateImage(pdata.dpy, pdata.specs.visual, pdata.specs.depth, ZPixmap, 0,pdata.datamain,pdata.brwin.rgeom.width, + pdata.brwin.rgeom.height, 8, 0); + XInitImage(pdata.image); + GetZPixmap(pdata.dpy,pdata.specs.root,pdata.image->data,pdata.brwin.rgeom.x,pdata.brwin.rgeom.y, + pdata.brwin.rgeom.width,pdata.brwin.rgeom.height); + } + if((!pdata.args.noshared)||(!pdata.args.nocondshared)){ + pdata.shimage=XShmCreateImage (pdata.dpy,pdata.specs.visual,pdata.specs.depth,ZPixmap,pdata.datash, + &shminfo, pdata.brwin.rgeom.width,pdata.brwin.rgeom.height); + shminfo.shmid = shmget (IPC_PRIVATE, + pdata.shimage->bytes_per_line * pdata.shimage->height, + IPC_CREAT|0777); + shminfo.shmaddr = pdata.shimage->data = shmat (shminfo.shmid, 0, 0); + shminfo.readOnly = False; + if(!XShmAttach(pdata.dpy,&shminfo)){ + fprintf(stderr,"Failed to attach shared memory to proccess.\n"); + exit(12); + } + XShmGetImage(pdata.dpy,pdata.specs.root,pdata.shimage,pdata.brwin.rgeom.x,pdata.brwin.rgeom.y,AllPlanes); + } + if(pdata.args.scshot){ + if(pdata.args.delay>0){ + fprintf(stderr,"Will sleep for %d seconds now.\n",pdata.args.delay); + sleep(pdata.args.delay); + } + //get a new screenshot + GetZPixmap(pdata.dpy,pdata.specs.root,pdata.image->data,pdata.brwin.rgeom.x,pdata.brwin.rgeom.y, + pdata.brwin.rgeom.width,pdata.brwin.rgeom.height); + ZPixmapToBMP(pdata.image,&pdata.brwin,((!strcmp(pdata.args.filename,"out.ogg"))?"rmdout.bmp":pdata.args.filename),pdata.brwin.nbytes,pdata.args.scale_shot); + fprintf(stderr,"done!\n"); + exit(0); + } + if(!pdata.args.nosound){ + pdata.sound_handle=OpenDev(pdata.args.device,&pdata.args.channels,&pdata.args.frequency,&pdata.periodsize, &pdata.periodtime,&pdata.hard_pause); + if(pdata.sound_handle==NULL){ + fprintf(stderr,"Error while opening/configuring soundcard %s\nTry running with the --no-sound or specify a correct device.\n",pdata.args.device); + exit(3); + } + } + InitEncoder(&pdata,&enc_data); + for(i=0;i<(pdata.enc_data->yuv.y_width*pdata.enc_data->yuv.y_height);i++) + pdata.enc_data->yuv.y[i]=0; + for(i=0;i<(pdata.enc_data->yuv.uv_width*pdata.enc_data->yuv.uv_height);i++){ + pdata.enc_data->yuv.v[i]=pdata.enc_data->yuv.u[i]=127; + } + if((pdata.args.nocondshared)&&(!pdata.args.noshared)){ + if(pdata.args.no_quick_subsample){ + UPDATE_YUV_BUFFER_IM_AVG((&pdata.enc_data->yuv),((unsigned char*)pdata.shimage->data), + (pdata.enc_data->x_offset),(pdata.enc_data->y_offset), + (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height)); + } + else{ + UPDATE_YUV_BUFFER_IM((&pdata.enc_data->yuv),((unsigned char*)pdata.shimage->data), + (pdata.enc_data->x_offset),(pdata.enc_data->y_offset), + (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height)); + } + } + else{ + if(pdata.args.no_quick_subsample){ + UPDATE_YUV_BUFFER_IM_AVG((&pdata.enc_data->yuv),((unsigned char*)pdata.image->data), + (pdata.enc_data->x_offset),(pdata.enc_data->y_offset), + (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height)); + } + else{ + UPDATE_YUV_BUFFER_IM((&pdata.enc_data->yuv),((unsigned char*)pdata.image->data), + (pdata.enc_data->x_offset),(pdata.enc_data->y_offset), + (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height)); + } + } + + pdata.frametime=(1000000)/pdata.args.fps; + + if(pdata.args.delay>0){ + fprintf(stderr,"Will sleep for %d seconds now.\n",pdata.args.delay); + sleep(pdata.args.delay); + } + + /*start threads*/ + if(!pdata.args.full_shots) + pthread_create(&poll_damage_t,NULL,PollDamage,(void *)&pdata); + pthread_create(&image_capture_t,NULL,GetFrame,(void *)&pdata); + pthread_create(&image_encode_t,NULL,EncodeImageBuffer,(void *)&pdata); + if(!pdata.args.nosound){ + pthread_create(&sound_capture_t,NULL,CaptureSound,(void *)&pdata); + pthread_create(&sound_encode_t,NULL,EncodeSoundBuffer,(void *)&pdata); + } + pthread_create(&flush_to_ogg_t,NULL,FlushToOgg,(void *)&pdata); + + + RegisterCallbacks(&pdata.args); + fprintf(stderr,"Capturing!\n"); + + //wait all threads to finish + + pthread_join(image_capture_t,NULL); + fprintf(stderr,"Shutting down."); + pthread_join(image_encode_t,NULL); + fprintf(stderr,"."); + if(!pdata.args.nosound){ + pthread_join(sound_capture_t,NULL); + fprintf(stderr,"."); + pthread_join(sound_encode_t,NULL); + fprintf(stderr,"."); + } + else + fprintf(stderr,".."); + pthread_join(flush_to_ogg_t,NULL); + fprintf(stderr,"."); + if(!pdata.args.full_shots) + pthread_join(poll_damage_t,NULL); + fprintf(stderr,"."); + if((!pdata.args.noshared)||(!pdata.args.nocondshared)){ + XShmDetach (pdata.dpy, &shminfo); +// XDestroyImage (pdata.image); + shmdt (&shminfo.shmaddr); + shmctl (shminfo.shmid, IPC_RMID, 0); + } + fprintf(stderr,"\n"); + XCloseDisplay(pdata.dpy); + if(Aborted){ + if(remove(pdata.args.filename)){ + perror("Error while removing file:\n"); + return 1; + } + else{ + fprintf(stderr,"SIGABRT received,file %s removed\n",pdata.args.filename); + return 0; + } + } + else + fprintf(stderr,"Goodbye!\n"); + } + return 0; +} + + + + + + + + + + + + + + + |