[xiph-cvs] cvs commit: snatch Snatch libsnatch.c oss.c snatchconvert.c x11.c

Monty xiphmont at xiph.org
Thu Nov 15 20:19:16 PST 2001



xiphmont    01/11/15 20:19:15

  Modified:    .        Snatch libsnatch.c oss.c snatchconvert.c x11.c
  Log:
  Fixes to YUV conversion
  output raw frames in YUV to save disk bandwidth
  capture start fixes to libsnatch

Revision  Changes    Path
1.5       +1 -1      snatch/Snatch

Index: Snatch
===================================================================
RCS file: /usr/local/cvsroot/snatch/Snatch,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Snatch	2001/11/15 08:40:17	1.4
+++ Snatch	2001/11/16 04:19:14	1.5
@@ -15,7 +15,7 @@
     exit 1;
 }
 
-$version="Snatch 20011115";
+$version="Snatch 20011116";
 $configdir=$HOME."/.snatch";
 $configfile=$configdir."/config.txt";
 $historyfile=$configdir."/history.txt";

1.32      +38 -18    snatch/libsnatch.c

Index: libsnatch.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/libsnatch.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- libsnatch.c	2001/11/14 05:13:49	1.31
+++ libsnatch.c	2001/11/16 04:19:14	1.32
@@ -84,6 +84,9 @@
 static int fake_audiop=0;
 static int fake_videop=0;
 
+static int output_audio_p=0;
+static int output_video_p=0;
+
 static void (*QueuedTask)(void);
 
 static int outfile_fd=-1;
@@ -110,21 +113,23 @@
 }
 
 static int gwrite(int fd, void *buf, int n){
-  while(n){
-    int ret=(*libc_write)(fd,buf,n);
-    if(ret<0){
-      if(errno==EAGAIN)
-	ret=0;
-      else{
-	fprintf(stderr,"**ERROR: Write error on capture file!\n"
-		"       : %s\n",strerror(errno));
-	CloseOutputFile(); /* if the error is the 2GB limit on Linux 2.2,
-			      this will result in a new file getting opened */
-	return(ret);
+  if(fd>=0){
+    while(n){
+      int ret=(*libc_write)(fd,buf,n);
+      if(ret<0){
+	if(errno==EAGAIN)
+	  ret=0;
+	else{
+	  fprintf(stderr,"**ERROR: Write error on capture file!\n"
+		  "       : %s\n",strerror(errno));
+	  CloseOutputFile(1); /* if the error is the 2GB limit on Linux 2.2,
+				this will result in a new file getting opened */
+	  return(ret);
+	}
       }
+      buf+=ret;
+      n-=ret;
     }
-    buf+=ret;
-    n-=ret;
   }
   return(0);
 }
@@ -212,7 +217,7 @@
         if(ret==1)
           FakeKeySym(sym,mod,rpplay_window);
       }
-      CloseOutputFile(); /* it will only happen on Robot commands that would
+      CloseOutputFile(0); /* it will only happen on Robot commands that would
                             be starting a new file */
       break;
     case 'E':
@@ -268,10 +273,10 @@
       FakeExposeRPPlay();
       break;
     case 'C':
-      CloseOutputFile();
+      CloseOutputFile(1);
       break;
     case 'I':
-      CloseOutputFile();
+      CloseOutputFile(1);
       snatch_active=0;
       FakeExposeRPPlay();
       break;
@@ -493,11 +498,12 @@
   if(fd==audio_fd){
     audio_fd=-1;
     audio_samplepos=0;
+    audio_channels=0;
     audio_timezero=bigtime(NULL,NULL);
     if(debug)
       fprintf(stderr,
               "    ...: RealPlayer closed audio playback fd %d\n",fd);
-    CloseOutputFile();
+    CloseOutputFile(0);
   }
     
   return(ret);
@@ -548,6 +554,7 @@
     if(count>0 && snatch_active==1){
       
       pthread_mutex_lock(&output_mutex);
+      if(outfile_fd>=0 && !output_audio_p)CloseOutputFile(1);
       if(outfile_fd<0)OpenOutputFile();
       pthread_mutex_unlock(&output_mutex);
       
@@ -627,13 +634,16 @@
       if(debug)fprintf(stderr,"    ...: Capturing to stdout\n");
 
       if(videocount){
+	output_video_p=1;
         if(audio_channels){
+	  output_audio_p=1;
           gwrite(outfile_fd,"SNATCHAV---\n",12);
         }else{
           gwrite(outfile_fd,"SNATCH-V---\n",12);
         }
       }else{
         if(audio_channels){
+	  output_audio_p=1;
           gwrite(outfile_fd,"SNATCHA----\n",12);
         }else{
           gwrite(outfile_fd,"SNATCH-----\n",12);
@@ -690,13 +700,16 @@
         }
         
         if(videocount){
+	  output_video_p=1;
           if(audio_channels){
+	    output_audio_p=1;
             gwrite(outfile_fd,"SNATCHAV---\n",12);
           }else{
             gwrite(outfile_fd,"SNATCH-V---\n",12);
           }
         }else{
           if(audio_channels){
+	    output_audio_p=1;
             gwrite(outfile_fd,"SNATCHA----\n",12);
           }else{
             gwrite(outfile_fd,"SNATCH-----\n",12);
@@ -713,13 +726,16 @@
           if(debug)fprintf(stderr,"    ...: Capturing to file %s\n",outpath);
           
           if(videocount){
+	    output_video_p=1;
             if(audio_channels){
+	      output_audio_p=1;
               gwrite(outfile_fd,"SNATCHAV---\n",12);
             }else{
               gwrite(outfile_fd,"SNATCH-V---\n",12);
             }
           }else{
             if(audio_channels){
+	      output_audio_p=1;
               gwrite(outfile_fd,"SNATCHA----\n",12);
             }else{
               gwrite(outfile_fd,"SNATCH-----\n",12);
@@ -731,7 +747,7 @@
   }
 }
 
-static void CloseOutputFile(){
+static void CloseOutputFile(int preserve){
   pthread_mutex_lock(&output_mutex);
   if(outfile_fd>=0){
     videocount=0;
@@ -739,6 +755,10 @@
     if(outfile_fd!=STDOUT_FILENO)
       close(outfile_fd);
     outfile_fd=-1;
+    if(!preserve){
+      output_audio_p=0;
+      output_video_p=0;
+    }
   }
   pthread_mutex_unlock(&output_mutex);
 }

1.3       +3 -3      snatch/oss.c

Index: oss.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/oss.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- oss.c	2001/11/15 04:09:07	1.2
+++ oss.c	2001/11/16 04:19:14	1.3
@@ -116,7 +116,7 @@
       fprintf(stderr,
               "    ...: Audio output sampling rate set to %dHz.\n",
               audio_rate);
-    CloseOutputFile();
+    CloseOutputFile(0);
     break;
   case SNDCTL_DSP_CHANNELS:
     audio_channels=*(int *)arg;
@@ -124,7 +124,7 @@
       fprintf(stderr,
               "    ...: Audio output set to %d channels.\n",
               audio_channels);
-    CloseOutputFile();
+    CloseOutputFile(0);
     break;
   case SNDCTL_DSP_SETFMT:
     audio_format=oss_fmt_translate(*(int *)arg);
@@ -132,7 +132,7 @@
       fprintf(stderr,
               "    ...: Audio output format set to %s.\n",
               audio_fmts[audio_format]);
-    CloseOutputFile();
+    CloseOutputFile(0);
     break;
   case SNDCTL_DSP_GETOSPACE:
     if(fake_audiop){

1.5       +120 -107  snatch/snatchconvert.c

Index: snatchconvert.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/snatchconvert.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- snatchconvert.c	2001/11/15 19:15:31	1.4
+++ snatchconvert.c	2001/11/16 04:19:14	1.5
@@ -576,62 +576,111 @@
 
 /*********************** video manipulation ***********************/
 
-void rgbscale(char *src,int sw,int sh,
-	      char *dst,int dw,int dh,
+/* planar YUV12 (4:2:0) */
+void yuvscale(unsigned char *src,int sw,int sh,
+	      unsigned char *dst,int dw,int dh,
               int w, int h){
   int x,y;
+  int dxo=(dw-sw)/4,sxo=0;
+  int dyo=(dh-sh)/4,syo=0;
+  
+  /* dirt simple for now. No scaling, just centering */
+  memset(dst,0,dw*dh*3/2);
+  
+  if(dyo<0){
+    syo= -dyo;
+    dyo=0;
+  }
+  if(dxo<0){
+    sxo= -dxo;
+    dxo=0;
+  }
 
-  int xo=(dw-sw)/2;
-  int yo=(dh-sh)/2;
+  for(y=0;y<sh && y<dh;y++){
+    unsigned char *sptr=src+(y+syo*2)*sw+sxo*2;
+    unsigned char *dptr=dst+(y+dyo*2)*dw+dxo*2;
+    for(x=0;x<sw && x<dw;x++)
+      *dptr++=*sptr++;
+  }
 
-  /* dirt simple for now. No scaling, just centering */
-  memset(dst,0,dw*dh*3);
+  src+=sw*sh;
+  dst+=dw*dh;
+  sw/=2;
+  dw/=2;
+  sh/=2;
+  dh/=2;
+
+  for(y=0;y<sh && y<dh;y++){
+    unsigned char *sptr=src+(y+syo)*sw+sxo;
+    unsigned char *dptr=dst+(y+dyo)*dw+dxo;
+    for(x=0;x<sw && x<dw;x++)
+      *dptr++=*sptr++;
+  }
 
-  if(yo>0){
-    if(xo>0){
-      for(y=0;y<sh && y<dh;y++){
-	char *sptr=src+y*sw*3;
-	char *dptr=dst+(y+yo)*dw*3+xo*3;
-	for(x=0;x<sw && x<dw;x++){
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	}
-      }
-    }else{
-      for(y=0;y<sh && y<dh;y++){
-	char *sptr=src+y*sw*3-xo*3;
-	char *dptr=dst+(y+yo)*dw*3;
-	for(x=0;x<sw && x<dw;x++){
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	}
-      }
-    }
-  }else{
-    if(xo>0){
-      for(y=0;y<sh && y<dh;y++){
-	char *sptr=src+(y-yo)*sw*3;
-	char *dptr=dst+y*dw*3+xo*3;
-	for(x=0;x<sw && x<dw;x++){
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	}
-      }
-    }else{
-      for(y=0;y<sh && y<dh;y++){
-	char *sptr=src+(y-yo)*sw*3-xo*3;
-	char *dptr=dst+y*dw*3;
-	for(x=0;x<sw && x<dw;x++){
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	  *dptr++=*sptr++;
-	}
-      }
+  src+=sw*sh;
+  dst+=dw*dh;
+
+  for(y=0;y<sh && y<dh;y++){
+    unsigned char *sptr=src+(y+syo)*sw+sxo;
+    unsigned char *dptr=dst+(y+dyo)*dw+dxo;
+    for(x=0;x<sw && x<dw;x++)
+      *dptr++=*sptr++;
+  }
+
+}
+
+void rgbscale(unsigned char *rgb,int sw,int sh,
+	      unsigned char *dst,int dw,int dh,
+	      unsigned int w, int h){
+  int ih=sh/2*2;
+  int iw=sw/2*2;
+
+  unsigned char *y=alloca(ih*iw*3/2);
+  unsigned char *u=y+ih*iw;
+  unsigned char *v=u+ih*iw/4;
+
+  int every=0,other=sw*3,c4=0,i,j;
+  unsigned char *ye=y,*yo=y+iw;
+
+  for(i=0;i<ih;i+=2){
+    for(j=0;j<iw;j+=2){
+      long yval,uval,vval;
+      
+      yval =   rgb[every]*19595 + rgb[every+1]*38470 + rgb[every+2]*7471;
+      uval = rgb[every+2]*65536 -   rgb[every]*22117 - rgb[every+1]*43419;
+      vval =   rgb[every]*65536 - rgb[every+1]*54878 - rgb[every+2]*10658;
+      *ye++ =yval>>16;
+      every+=3;
+      yval =   rgb[every]*19595 + rgb[every+1]*38470 + rgb[every+2]*7471;
+      uval+= rgb[every+2]*65536 -   rgb[every]*22117 - rgb[every+1]*43419;
+      vval+=   rgb[every]*65536 - rgb[every+1]*54878 - rgb[every+2]*10658;
+      *ye++ =yval>>16;
+      every+=3;
+      
+      yval =   rgb[other]*19595 + rgb[other+1]*38470 + rgb[other+2]*7471;
+      uval = rgb[other+2]*65536 -   rgb[other]*22117 - rgb[other+1]*43419;
+      vval =   rgb[other]*65536 - rgb[other+1]*54878 - rgb[other+2]*10658;
+      *yo++ =yval>>16;
+      other+=3;
+      yval =   rgb[other]*19595 + rgb[other+1]*38470 + rgb[other+2]*7471;
+      uval+= rgb[other+2]*65536 -   rgb[other]*22117 - rgb[other+1]*43419;
+      vval+=   rgb[other]*65536 - rgb[other+1]*54878 - rgb[other+2]*10658;
+      *yo++ =yval>>16;
+      other+=3;
+      
+      u[c4]  =(uval>>19)+128;
+      v[c4++]=(vval>>19)+128;
+      
     }
+    ye+=iw;
+    yo+=iw;
+    every+=sw*3 + sw%2*3;
+    other+=sw*3 + sw%2*3;
+    
   }
+  
+  yuvscale(y,iw,ih,dst,dw,dh,w,h);
+
 }
 
 
@@ -654,7 +703,7 @@
 long long framesmissing=0;
 long long framesdiscarded=0;
       
-static int process_video_frame(char *buffer,FILE *f,int notfakep){
+static int process_video_frame(char *buffer,FILE *f,int notfakep,int yuvp){
   char *s=buffer+6;
   long a=atoi(s),b,w,h,length;
   double t;
@@ -779,20 +828,24 @@
         vidbuf=malloc(vidbuf_size*sizeof(*vidbuf));
         vidbuf_frameno=malloc(vidbuf_size*sizeof(*vidbuf_frameno));
       }
-      if(notfakep)vidbuf[vidbuf_size-1]=malloc(vidbuf_width*vidbuf_height*3);
+      if(notfakep)
+	vidbuf[vidbuf_size-1]=malloc(vidbuf_width*vidbuf_height*3/2);
     }
   }
   vidbuf_frameno[vidbuf_head]=vidbuf_frames;
   vidbuf_frames++;
   
   /* scale image into buffer */
-  if(notfakep)
-    rgbscale(buftemp,w,h,vidbuf[vidbuf_head],vidbuf_width,vidbuf_height,
-	     scale_width,scale_height);
-  
+  if(notfakep){
+    if(yuvp)
+      yuvscale(buftemp,w,h,vidbuf[vidbuf_head],vidbuf_width,vidbuf_height,
+	       scale_width,scale_height);
+    else
+      rgbscale(buftemp,w,h,vidbuf[vidbuf_head],vidbuf_width,vidbuf_height,
+	       scale_width,scale_height);
+  }
   /* finally any needed invasive blanking */
 
-
   vidbuf_head++;
   return(1);
 }
@@ -817,11 +870,17 @@
   }else {
     if(!strncmp(buffer,"VIDEO",5)){
       framesin++;
-      return process_video_frame(buffer, f, wv);
+      return process_video_frame(buffer, f, wv,0);
 
     }else{
-      fprintf(stderr,"Garbage/unknown frame type\n");
-      return(0);
+      if(!strncmp(buffer,"YUV12",5)){
+	framesin++;
+	return process_video_frame(buffer, f, wv,1);
+      }else{
+	
+	fprintf(stderr,"Garbage/unknown frame type\n");
+	return(0);
+      }
     }
   }
 }
@@ -859,55 +918,9 @@
 }
 
 /* YV12 aka 4:2:0 planar */
-void YUVout(unsigned char *rgb,FILE *f){
-  unsigned char *y=alloca(vidbuf_width*vidbuf_height);
-  unsigned char *u=alloca(vidbuf_width*vidbuf_height/4);
-  unsigned char *v=alloca(vidbuf_width*vidbuf_height/4);
-  int every=0,other=vidbuf_width*3,c4=0,i,j;
-  unsigned char *ye=y,*yo=y+vidbuf_width;
-
-  for(i=0;i<vidbuf_height;i+=2){
-    for(j=0;j<vidbuf_width;j+=2){
-      long yval,uval,vval;
-
-      yval= rgb[every]*19595+rgb[every+1]*38470+rgb[every+2]*7471;
-      uval= (rgb[every+2]<<16)-yval;
-      vval= (rgb[every]<<16)-yval;
-      *ye++ =yval>>16;
-      every+=3;
-
-      yval= rgb[every]*19595+rgb[every+1]*38470+rgb[every+2]*7471;
-      uval+= (rgb[every+2]<<16)-yval;
-      vval+= (rgb[every]<<16)-yval;
-      *ye++ =yval>>16;
-      every+=3;
-
-      yval= rgb[other]*19595+rgb[other+1]*38470+rgb[other+2]*7471;
-      uval+= (rgb[other+2]<<16)-yval;
-      vval+= (rgb[other]<<16)-yval;
-      *yo++ =yval>>16;
-      other+=3;
-
-      yval= rgb[other]*19595+rgb[other+1]*38470+rgb[other+2]*7471;
-      uval+= (rgb[other+2]<<16)-yval;
-      vval+= (rgb[other]<<16)-yval;
-      *yo++ =yval>>16;
-      other+=3;
-      
-      u[c4]=(uval>>19)+128;
-      v[c4++]=(vval>>19)+128;
-
-    }
-    ye+=vidbuf_width;
-    yo+=vidbuf_width;
-    every+=vidbuf_width*3;
-    other+=vidbuf_width*3;
-
-  }
+void YUVout(unsigned char *buf,FILE *f){
   fprintf(f,"FRAME\n");
-  fwrite(y,1,vidbuf_width*vidbuf_height,f);
-  fwrite(u,1,vidbuf_width*vidbuf_height/4,f);
-  fwrite(v,1,vidbuf_width*vidbuf_height/4,f);
+  fwrite(buf,1,vidbuf_width*vidbuf_height*3/2,f);
 }
 
 static int synced;

1.24      +153 -114  snatch/x11.c

Index: x11.c
===================================================================
RCS file: /usr/local/cvsroot/snatch/x11.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- x11.c	2001/11/14 06:11:04	1.23
+++ x11.c	2001/11/16 04:19:14	1.24
@@ -54,6 +54,8 @@
 static void queue_task(void (*f)(void));
 static void initialize();
 static int videocount=0;
+static int videotime=0;
+
 static int depthwarningflag;
 
 static void XGetGeometryRoot(unsigned long id,int *root_x,int *root_y){
@@ -386,11 +388,11 @@
   if(id==rpvideo_window){
     if(bitmask & CWHeight){
       video_height=values->height;
-      CloseOutputFile();
+      CloseOutputFile(0);
     }
     if(bitmask & CWWidth){
       video_width=values->width;
-      CloseOutputFile();
+      CloseOutputFile(0);
     }
   }
 
@@ -410,7 +412,7 @@
   if(id==rpvideo_window){
     video_height=height;
     video_width=width;
-    CloseOutputFile();
+    CloseOutputFile(0);
   }
 
   return(ret);
@@ -506,9 +508,129 @@
   return(ret);
 }
 
+/* yes, it's additional CPU load where we don't want any, but the
+   savings in required disk bandwidth is more than worth it (YUV 2:4:0
+   is half the size) */
+
 static char *workbuffer;
 static long worksize;
+void YUVout(XImage *image){
+  pthread_mutex_lock(&output_mutex);
+  if(outfile_fd>=0){
+    char cbuf[80];
+    int i,j,len;	
+
+    long yuv_w=(image->width>>1)<<1; /* must be even for yuv12 */
+    long yuv_h=(image->height>>1)<<1; /* must be even for yuv12 */
+    long yuv_n=yuv_w*yuv_h*3/2;
+
+    long a,b;
+
+    pthread_mutex_unlock(&output_mutex);
+    bigtime(&a,&b);
+    len=sprintf(cbuf,"YUV12 %ld %ld %d %d %ld:",a,b,image->width,
+		image->height,yuv_n);
+	
+    if(worksize<yuv_n){
+      if(worksize==0)
+	workbuffer=malloc(yuv_n);
+      else
+	workbuffer=realloc(workbuffer,yuv_n);
+      worksize=yuv_n;
+    }
+    
+    {
+      unsigned char *y1=workbuffer;
+      unsigned char *y2=workbuffer+yuv_w;
+      unsigned char *u=workbuffer+yuv_w*yuv_h;
+      unsigned char *v=u+yuv_w*yuv_h/4;
+      unsigned char *ptr1=image->data;
+      char *ptr2=image->data+image->bytes_per_line;
+      if(image->byte_order){      
+	
+	for(i=0;i<yuv_h;i+=2){
+	  for(j=0;j<yuv_w;j+=2){
+	    long yval,uval,vval;
+	    
+	    yval  = ptr1[1]*19595 + ptr1[2]*38470 + ptr1[3]*7471;
+	    uval  = ptr1[3]*65536 - ptr1[1]*22117 - ptr1[2]*43419;
+	    vval  = ptr1[1]*65536 - ptr1[2]*54878 - ptr1[3]*10658;
+	    *y1++ = yval>>16;
+
+	    yval  = ptr1[5]*19595 + ptr1[6]*38470 + ptr1[7]*7471;
+	    uval += ptr1[7]*65536 - ptr1[5]*22117 - ptr1[6]*43419;
+	    vval += ptr1[5]*65536 - ptr1[6]*54878 - ptr1[7]*10658;
+	    *y1++ = yval>>16;
+
+	    yval  = ptr2[1]*19595 + ptr2[2]*38470 + ptr2[3]*7471;
+	    uval += ptr2[3]*65536 - ptr2[1]*22117 - ptr2[2]*43419;
+	    vval += ptr2[1]*65536 - ptr2[2]*54878 - ptr2[3]*10658;
+	    *y2++ = yval>>16;
+
+	    yval  = ptr2[5]*19595 + ptr2[6]*38470 + ptr2[7]*7471;
+	    uval += ptr2[7]*65536 - ptr2[5]*22117 - ptr2[6]*43419;
+	    vval += ptr2[5]*65536 - ptr2[6]*54878 - ptr2[7]*10658;
+	    *y2++ = yval>>16;
+	    
+	    *u++  = (uval>>19)+128;
+	    *v++  = (vval>>19)+128;
+	    ptr1+=8;
+	    ptr2+=8;
+	  }
+	  ptr1+=image->bytes_per_line;
+	  ptr2+=image->bytes_per_line;
+	  y1+=yuv_w;
+	  y2+=yuv_w;
+
+	}
+
+      }else{
+
+	for(i=0;i<yuv_h;i+=2){
+	  for(j=0;j<yuv_w;j+=2){
+	    long yval,uval,vval;
+	    
+	    yval  = ptr1[2]*19595 + ptr1[1]*38470 + ptr1[0]*7471;
+	    uval  = ptr1[0]*65536 - ptr1[2]*22117 - ptr1[1]*43419;
+	    vval  = ptr1[2]*65536 - ptr1[1]*54878 - ptr1[0]*10658;
+	    *y1++ = yval>>16;
+
+	    yval  = ptr1[6]*19595 + ptr1[5]*38470 + ptr1[4]*7471;
+	    uval += ptr1[4]*65536 - ptr1[6]*22117 - ptr1[5]*43419;
+	    vval += ptr1[5]*65536 - ptr1[5]*54878 - ptr1[4]*10658;
+	    *y1++ = yval>>16;
+
+	    yval  = ptr2[2]*19595 + ptr2[1]*38470 + ptr2[0]*7471;
+	    uval += ptr2[0]*65536 - ptr2[2]*22117 - ptr2[1]*43419;
+	    vval += ptr2[2]*65536 - ptr2[1]*54878 - ptr2[0]*10658;
+	    *y2++ = yval>>16;
+
+	    yval  = ptr2[6]*19595 + ptr2[5]*38470 + ptr2[4]*7471;
+	    uval += ptr2[4]*65536 - ptr2[6]*22117 - ptr2[5]*43419;
+	    vval += ptr2[5]*65536 - ptr2[5]*54878 - ptr2[4]*10658;
+	    *y2++ = yval>>16;
+	    
+	    *u++  = (uval>>19)+128;
+	    *v++  = (vval>>19)+128;
+	    ptr1+=8;
+	    ptr2+=8;
+	  }
+	  ptr1+=image->bytes_per_line;
+	  ptr2+=image->bytes_per_line;
+	  y1+=yuv_w;
+	  y2+=yuv_w;
 
+	}
+      }
+    }
+    pthread_mutex_lock(&output_mutex);
+    gwrite(outfile_fd,cbuf,len);
+    gwrite(outfile_fd,workbuffer,yuv_n);
+  }
+  pthread_mutex_unlock(&output_mutex);
+}
+
+
 int XPutImage(Display *display,Drawable id,GC gc,XImage *image,
               int src_x,int src_y,
               int x, int y,
@@ -517,64 +639,23 @@
 
   int ret=0;
 
-  if(snatch_active==1 && id==rpvideo_window){
-    videocount++;
+  if(id==rpvideo_window){
+    double t=bigtime(NULL,NULL);
+    if(t-videotime)
+      videocount=1;
+    else
+      videocount++;
+  }
 
+  if(snatch_active==1 && id==rpvideo_window){
     pthread_mutex_lock(&output_mutex);
-    if(outfile_fd<0 && videocount>5)OpenOutputFile();
+    if(outfile_fd>=0 && !output_video_p)CloseOutputFile(1);
+    if(outfile_fd<0 && videocount>4)OpenOutputFile();
     pthread_mutex_unlock(&output_mutex);
     /* only do 24 bit zPixmaps for now */
 
     if(image->format==2 && image->depth>16 && image->depth<=24){
-      if(outfile_fd>=0){
-	char cbuf[80];
-	int bpp=image->bytes_per_line/image->width;
-	long a,b,n=image->width*image->height*3;
-	int i,j,len;
-	
-	bigtime(&a,&b);
-	len=sprintf(cbuf,"VIDEO %ld %ld %d %d %ld:",a,b,image->width,
-		    image->height,n);
-	
-	if(worksize<n){
-	  if(worksize==0)
-	    workbuffer=malloc(n);
-	  else
-	    workbuffer=realloc(workbuffer,n);
-	  worksize=n;
-	}
-	
-	if(image->byte_order){      
-	  char *work=workbuffer;
-	  char *ptr=image->data;
-	  for(i=0;i<image->height;i++){
-	    for(j=0;j<image->width*bpp;){
-	      j++;
-	      *work++=ptr[j++];
-	      *work++=ptr[j++];
-	      *work++=ptr[j++];
-	    }
-	    ptr+=image->bytes_per_line;
-	  }
-	}else{
-	  char *work=workbuffer;
-	  char *ptr=image->data;
-	  for(i=0;i<image->height;i++){
-	    for(j=0;j<image->width*bpp;j+=4){
-	      *work++=ptr[j+2];
-	      *work++=ptr[j+1];
-	      *work++=ptr[j];
-	    }
-	    ptr+=image->bytes_per_line;
-	  }
-	}
-	  	  
-	pthread_mutex_lock(&output_mutex);
-	gwrite(outfile_fd,cbuf,len);
-	gwrite(outfile_fd,workbuffer,n);
-	pthread_mutex_unlock(&output_mutex);
-
-      }
+      YUVout(image);
     }else{
       if(!depthwarningflag)
         fprintf(stderr,"**ERROR: Right now, Snatch only works with 17-24 bit ZPixmap\n"
@@ -745,70 +826,23 @@
                  Bool send_event){
   int ret=0;
 
-  if(!fake_videop)
-    ret=(*xlib_xshmputimage)(display, id, gc, image, src_x, src_y,
-			     dest_x, dest_y, width, height, send_event);
-
-
+  if(id==rpvideo_window){
+    double t=bigtime(NULL,NULL);
+    if(t-videotime>1.)
+      videocount=1;
+    else
+      videocount++;
+  }
+   
   if(snatch_active==1 && id==rpvideo_window){
-    videocount++;
-
     pthread_mutex_lock(&output_mutex);
-    if(outfile_fd<0 && videocount>5)OpenOutputFile();
+    if(outfile_fd>=0 && !output_video_p)CloseOutputFile(1);
+    if(outfile_fd<0 && videocount>4)OpenOutputFile();
     pthread_mutex_unlock(&output_mutex);
 
     /* only do 24 bit zPixmaps for now */
     if(image->format==2 && image->depth>16 && image->depth<=24){
-      if(outfile_fd>=0){
-	char cbuf[80];
-	int bpp=image->bytes_per_line/image->width;
-	long a,b,n=image->width*image->height*3;
-	int i,j,len;
-	
-	bigtime(&a,&b);
-
-	len=sprintf(cbuf,"VIDEO %ld %ld %d %d %ld:",a,b,image->width,
-		    image->height,n);
-	
-	if(worksize<n){
-	  if(worksize==0)
-	    workbuffer=malloc(n);
-	  else
-	    workbuffer=realloc(workbuffer,n);
-	  worksize=n;
-	}
-	
-	if(image->byte_order){      
-	  char *work=workbuffer;
-	  char *ptr=image->data;
-	  for(i=0;i<image->height;i++){
-	    for(j=0;j<image->width*bpp;){
-	      j++;
-	      *work++=ptr[j++];
-	      *work++=ptr[j++];
-	      *work++=ptr[j++];
-	    }
-	    ptr+=image->bytes_per_line;
-	  }
-	}else{
-	  char *work=workbuffer;
-	  char *ptr=image->data;
-	  for(i=0;i<image->height;i++){
-	    for(j=0;j<image->width*bpp;j+=4){
-	      *work++=ptr[j+2];
-	      *work++=ptr[j+1];
-	      *work++=ptr[j];
-	    }
-	    ptr+=image->bytes_per_line;
-	  }
-	}
-
-	pthread_mutex_lock(&output_mutex);
-	gwrite(outfile_fd,cbuf,len);
-	gwrite(outfile_fd,workbuffer,n);
-	pthread_mutex_unlock(&output_mutex);
-
-      }
+      YUVout(image);
     }else{
       if(!depthwarningflag)
         fprintf(stderr,"**ERROR: Right now, Snatch only works with 17-24 bit ZPixmap\n"
@@ -818,12 +852,17 @@
     }
   }
 
+  if(!fake_videop)
+    ret=(*xlib_xshmputimage)(display, id, gc, image, src_x, src_y,
+			     dest_x, dest_y, width, height, send_event);
+
+
   return(ret);
 }
 
 int XCloseDisplay(Display  *d){
   int ret=(*xlib_xclose)(d);
-  CloseOutputFile();
+  CloseOutputFile(0);
   if(debug)fprintf(stderr,"    ...: X display closed; goodbye.\n\n");
   return(ret);
 }

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list