LibVNCServer/LibVNCClient
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
camera.c
Go to the documentation of this file.
1 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <rfb/rfb.h>
44 
45 
46 #define WIDTH 640
47 #define HEIGHT 480
48 #define BPP 4
49 
50 /* 15 frames per second (if we can) */
51 #define PICTURE_TIMEOUT (1.0/15.0)
52 
53 
54 /*
55  * throttle camera updates
56 */
58  static struct timeval now={0,0}, then={0,0};
59  double elapsed, dnow, dthen;
60 
61  gettimeofday(&now,NULL);
62 
63  dnow = now.tv_sec + (now.tv_usec /1000000.0);
64  dthen = then.tv_sec + (then.tv_usec/1000000.0);
65  elapsed = dnow - dthen;
66 
67  if (elapsed > PICTURE_TIMEOUT)
68  memcpy((char *)&then, (char *)&now, sizeof(struct timeval));
69  return elapsed > PICTURE_TIMEOUT;
70 }
71 
72 
73 
74 /*
75  * simulate grabbing a picture from some device
76  */
77 int TakePicture(unsigned char *buffer)
78 {
79  static int last_line=0, fps=0, fcount=0;
80  int line=0;
81  int i,j;
82  struct timeval now;
83 
84  /*
85  * simulate grabbing data from a device by updating the entire framebuffer
86  */
87 
88  for(j=0;j<HEIGHT;++j) {
89  for(i=0;i<WIDTH;++i) {
90  buffer[(j*WIDTH+i)*BPP+0]=(i+j)*128/(WIDTH+HEIGHT); /* red */
91  buffer[(j*WIDTH+i)*BPP+1]=i*128/WIDTH; /* green */
92  buffer[(j*WIDTH+i)*BPP+2]=j*256/HEIGHT; /* blue */
93  }
94  buffer[j*WIDTH*BPP+0]=0xff;
95  buffer[j*WIDTH*BPP+1]=0xff;
96  buffer[j*WIDTH*BPP+2]=0xff;
97  }
98 
99  /*
100  * simulate the passage of time
101  *
102  * draw a simple black line that moves down the screen. The faster the
103  * client, the more updates it will get, the smoother it will look!
104  */
105  gettimeofday(&now,NULL);
106  line = now.tv_usec / (1000000/HEIGHT);
107  if (line>HEIGHT) line=HEIGHT-1;
108  memset(&buffer[(WIDTH * BPP) * line], 0, (WIDTH * BPP));
109 
110  /* frames per second (informational only) */
111  fcount++;
112  if (last_line > line) {
113  fps = fcount;
114  fcount = 0;
115  }
116  last_line = line;
117  fprintf(stderr,"%03d/%03d Picture (%03d fps)\r", line, HEIGHT, fps);
118 
119  /* success! We have a new picture! */
120  return (1==1);
121 }
122 
123 
124 
125 
126 /*
127  * Single-threaded application that interleaves client servicing with taking
128  * pictures from the camera. This way, we do not update the framebuffer
129  * while an encoding is working on it too (banding, and image artifacts).
130  */
131 int main(int argc,char** argv)
132 {
133  long usec;
134 
135  rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
136  if(!server)
137  return 0;
138  server->desktopName = "Live Video Feed Example";
139  server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
140  server->alwaysShared=(1==1);
141 
142  /* Initialize the server */
143  rfbInitServer(server);
144 
145  /* Loop, processing clients and taking pictures */
146  while (rfbIsActive(server)) {
147  if (TimeToTakePicture())
148  if (TakePicture((unsigned char *)server->frameBuffer))
149  rfbMarkRectAsModified(server,0,0,WIDTH,HEIGHT);
150 
151  usec = server->deferUpdateTime*1000;
152  rfbProcessEvents(server,usec);
153  }
154  return(0);
155 }