#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include "CaptureThread.h"
#include "CaptureCmdLine.h"
#include "Capture.h"
#include "CaptureDebug.h"
#include "CaptureError.h"
#include "rgb133v4l2.h"
Enumerations | |
enum | { TOP = 0, LEFT, WIDTH, HEIGHT } |
Functions | |
void | usage (int argc, char *argv[]) |
void | signal_handler (int sig) |
int | TokenizeCropping (psCapture pCapture, char *pCroppingBuffer, unsigned long length) |
int | SetupValues (sCmdLineArgs CmdLineArgs, psCapture pCapture) |
int | main (int argc, char *argv[]) |
Variables | |
int | CaptureStop = 0 |
anonymous enum |
int main | ( | int | argc, | |
char * | argv[] | |||
) |
00252 { 00253 sCmdLineArgs CmdLineArgs; 00254 00255 int ret = 0; 00256 00257 signal(SIGINT, signal_handler); 00258 00259 /* Parse the command line */ 00260 memset(&CmdLineArgs, 0, sizeof(sCmdLineArgs)); 00261 CmdLineArgs.capture_count = -1; /* Set to infinite */ 00262 if(ParseCommandLine(argc, argv, &CmdLineArgs)) 00263 { 00264 usage(argc, argv); 00265 return - CAPERROR_CMDLINE; 00266 } 00267 00268 /* Setup values (or defaults) */ 00269 memset(&Capture, 0, sizeof(sCapture)); 00270 if(SetupValues(CmdLineArgs, &Capture)) 00271 { 00272 CapError("Failed to initilise arguments.\n\n"); 00273 usage(argc, argv); 00274 return - CAPERROR_CMDLINEVALUES; 00275 } 00276 00277 /* Open the capture device control channel */ 00278 if(OpenCaptureDeviceControl(&Capture)) 00279 { 00280 CapError("Failed to open capture device control.\n"); 00281 CloseCaptureDevice(Capture.fd, &Capture); 00282 return -CAPERROR_OPENCONTROLDEVICE; 00283 } 00284 00285 while(!CaptureStop) { 00286 00287 CaptureStop = 1; 00288 00289 /* Open the capture device */ 00290 if(OpenCaptureDevice(CmdLineArgs.device, &Capture, CmdLineArgs.nonblocking)) 00291 { 00292 CapError("Failed to open capture device.\n"); 00293 return -CAPERROR_OPENDEVICE; 00294 } 00295 00296 switch(Capture.ioType) 00297 { 00298 case IO_READ: 00299 /* Initialise read pointers */ 00300 if(InitialiseReadCapture(&Capture, Capture.fmt.fmt.pix.sizeimage)) 00301 { 00302 CapError("Failed to initialise read buffer.\n"); 00303 ret = -CAPERROR_INITCAPTURE; 00304 goto out; 00305 } 00306 break; 00307 case IO_MMAP: 00308 /* Initialise mmap buffers */ 00309 if(InitialiseMmapCapture(&Capture, Capture.fmt.fmt.pix.sizeimage)) 00310 { 00311 CapError("Failed to initialise mmap buffers.\n"); 00312 ret = -CAPERROR_INITCAPTURE; 00313 goto out; 00314 } 00315 break; 00316 case IO_USERPTR: 00317 /* Initialise userptr buffers */ 00318 if(InitialiseUserPtrCapture(&Capture, Capture.fmt.fmt.pix.sizeimage)) 00319 { 00320 CapError("Failed to initialise userptr buffers.\n"); 00321 ret = -CAPERROR_INITCAPTURE; 00322 goto out; 00323 } 00324 break; 00325 default: 00326 CapError("Invalid IO method: %d\n", Capture.ioType); 00327 ret = -CAPERROR_INITCAPTURE; 00328 goto out; 00329 } 00330 00331 /* Set the frame rate */ 00332 InitialiseCapture(&Capture); 00333 00334 /* Start the video capture... 00335 * Happens in a separate thread. 00336 */ 00337 if(StartCapture(&Capture)) 00338 { 00339 CapError("Failed to start video capture.\n"); 00340 ret = -CAPERROR_STARTCAPTURE; 00341 goto out; 00342 } 00343 00344 switch(Capture.ioType) 00345 { 00346 case IO_READ: 00347 /* Initialise read pointers */ 00348 if(UninitialiseReadCapture(&Capture)) 00349 { 00350 CapError("Failed to initialise read buffer.\n"); 00351 ret = -CAPERROR_UNINITCAPTURE; 00352 goto out; 00353 } 00354 break; 00355 case IO_MMAP: 00356 if(UninitialiseMmapCapture(&Capture)) 00357 { 00358 CapError("Failed to uninitialise mmap buffers.\n"); 00359 ret = -CAPERROR_UNINITCAPTURE; 00360 goto out; 00361 } 00362 break; 00363 case IO_USERPTR: 00364 if(UninitialiseUserptrCapture(&Capture)) 00365 { 00366 CapError("Failed to uninitialise userptr buffers.\n"); 00367 ret = -CAPERROR_UNINITCAPTURE; 00368 goto out; 00369 } 00370 break; 00371 default: 00372 CapError("Invalid IO method: %d\n", Capture.ioType); 00373 ret = -CAPERROR_UNINITCAPTURE; 00374 goto out; 00375 } 00376 CloseCaptureDevice(Capture.fd, &Capture); 00377 } 00378 00379 out: 00380 if(ret < 0) 00381 CloseCaptureDevice(Capture.fd, &Capture); 00382 00383 CloseCaptureDeviceControl(Capture.ctrlFd); 00384 00385 return CAPERROR_NOERROR; 00386 }
int SetupValues | ( | sCmdLineArgs | CmdLineArgs, | |
psCapture | pCapture | |||
) |
00135 { 00136 int got_width = 0; 00137 00138 if (CmdLineArgs.capture_count == 0) 00139 pCapture->capture_count = -1; /* -1 is continuous capture */ 00140 else 00141 { 00142 pCapture->capture_count = CmdLineArgs.capture_count; 00143 } 00144 00145 if(CmdLineArgs.output_width[0] == 0) 00146 pCapture->output_width = 640; 00147 else 00148 { 00149 pCapture->output_width = strtol(CmdLineArgs.output_width, 0, 10); 00150 if(pCapture->output_width < 0 || 00151 pCapture->output_width > 4096) 00152 return -1; 00153 got_width = 1; 00154 } 00155 00156 if(CmdLineArgs.output_height[0] == 0) 00157 { 00158 /* If we got a width, use a 4:3 aspect to get the default height */ 00159 if(got_width) 00160 { 00161 pCapture->output_height = (pCapture->output_width * 3) / 4; 00162 } 00163 else 00164 pCapture->output_height = 480; 00165 } 00166 else 00167 { 00168 pCapture->output_height = strtol(CmdLineArgs.output_height, 0, 10); 00169 if(pCapture->output_height < 0 || 00170 pCapture->output_height > 4096) 00171 return -1; 00172 } 00173 00174 if(CmdLineArgs.output_pixfmt[0] == 0) 00175 pCapture->output_pixfmt = V4L2_PIX_FMT_RGB565; 00176 else 00177 { 00178 if((pCapture->output_pixfmt = IsSupportedPixelFormat(CmdLineArgs.output_pixfmt)) == 0) 00179 { 00180 CapError("Invalid pixel format: %s\n", CmdLineArgs.output_pixfmt); 00181 return -1; 00182 } 00183 } 00184 00185 if(CmdLineArgs.output_io[0] == 0) 00186 pCapture->ioType = IO_READ; 00187 else 00188 { 00189 if(!strcmp(CmdLineArgs.output_io, "read")) 00190 pCapture->ioType = IO_READ; 00191 else if(!strcmp(CmdLineArgs.output_io, "mmap")) 00192 pCapture->ioType = IO_MMAP; 00193 else if(!strcmp(CmdLineArgs.output_io, "userptr")) 00194 pCapture->ioType = IO_USERPTR; 00195 else 00196 { 00197 CapError("Invalid IO method: %s\n", CmdLineArgs.output_io); 00198 return -1; 00199 } 00200 } 00201 00202 if(CmdLineArgs.frame_rate[0] == 0) 00203 { 00204 pCapture->fFrameRate = 0.0; 00205 } 00206 else 00207 { 00208 char* endPtr = 0; 00209 pCapture->fFrameRate = strtof(CmdLineArgs.frame_rate, &endPtr); 00210 if((pCapture->fFrameRate == 0.0 && errno != 0) || 00211 endPtr == CmdLineArgs.frame_rate || 00212 endPtr != &CmdLineArgs.frame_rate[strlen(CmdLineArgs.frame_rate)]) 00213 { 00214 CapError("Invalid frame rate: %s\n", CmdLineArgs.frame_rate); 00215 pCapture->fFrameRate = 0.0; 00216 return -1; 00217 } 00218 else if(pCapture->fFrameRate <= 0.0 || 00219 pCapture->fFrameRate > 1000.0) 00220 { 00221 CapError("Invalid frame rate: %.2f\n", pCapture->fFrameRate); 00222 pCapture->fFrameRate = 0.0; 00223 return -1; 00224 } 00225 } 00226 00227 if(CmdLineArgs.cropping[0] != 0) 00228 { 00229 /* Tokenise the cropping string */ 00230 if(TokenizeCropping(pCapture, CmdLineArgs.cropping, strlen(CmdLineArgs.cropping))) 00231 return -1; 00232 } 00233 00234 if(CmdLineArgs.delay[0] == 0) 00235 pCapture->delay = 0; 00236 else 00237 { 00238 pCapture->delay = strtol(CmdLineArgs.delay, 0, 10); 00239 if(pCapture->delay < 0) /* Less than0ms doesn't make sense */ 00240 pCapture->delay = 0; 00241 else if(pCapture->delay > 10000) /* Capped at 10s */ 00242 pCapture->delay = 10000; 00243 } 00244 00245 pCapture->timestamp = CmdLineArgs.timestamp; 00246 pCapture->livestream = CmdLineArgs.livestream; 00247 00248 return 0; 00249 }
void signal_handler | ( | int | sig | ) |
00056 { 00057 signal(sig, SIG_IGN); 00058 00059 /* Tell threads to stop */ 00060 CapDebug("Signal threads to stop...\n"); 00061 CaptureThreadStop = 1; 00062 00063 signal(SIGINT, signal_handler); 00064 }
int TokenizeCropping | ( | psCapture | pCapture, | |
char * | pCroppingBuffer, | |||
unsigned long | length | |||
) |
00074 { 00075 unsigned char value[MAX_LEN]; 00076 int values = TOP; 00077 int i, pos; 00078 00079 BOOL bEnd = 0; 00080 00081 pCapture->CroppingActive = 0; 00082 00083 pos = 0; 00084 while(!bEnd) 00085 { 00086 /* Get a value */ 00087 for(i=0; pos<=length; i++,pos++) 00088 { 00089 if(pCroppingBuffer[pos] == 0) 00090 { 00091 bEnd = 1; 00092 i++; 00093 break; 00094 } 00095 else if(pCroppingBuffer[pos] != ',') 00096 value[i] = pCroppingBuffer[pos]; 00097 else if(pCroppingBuffer[pos] == ',') 00098 { 00099 break; 00100 } 00101 } 00102 value[i] = 0; 00103 00104 switch(values) 00105 { 00106 case TOP: 00107 pCapture->CroppingTop = atoi(value); 00108 values++; 00109 break; 00110 case LEFT: 00111 pCapture->CroppingLeft = atoi(value); 00112 values++; 00113 break; 00114 case WIDTH: 00115 pCapture->CroppingWidth = atoi(value); 00116 values++; 00117 break; 00118 case HEIGHT: 00119 pCapture->CroppingHeight = atoi(value); 00120 values++; 00121 break; 00122 } 00123 pos++; 00124 } 00125 00126 if(values > HEIGHT) 00127 pCapture->CroppingActive = 1; 00128 else 00129 return -1; 00130 00131 return 0; 00132 }
void usage | ( | int | argc, | |
char * | argv[] | |||
) |
00038 { 00039 fprintf(stdout, "\nUsage: %s [OPTIONS]\n", argv[0]); 00040 fprintf(stdout, "Perform a capture from a video4linux capture device.\n\n"); 00041 fprintf(stdout, " -d: Specify video4linux device (default: /dev/video0)\n"); 00042 fprintf(stdout, " -w: Specify output buffer width (default: 640)\n"); 00043 fprintf(stdout, " -h: Specify output buffer height (default: 480)\n"); 00044 fprintf(stdout, " -p: Specify output buffer pixel format (default: RGB565)\n"); 00045 fprintf(stdout, " -i: Specify video4linux capture IO type, \"read/mmap/userptr\" (default: \"read\")\n"); 00046 fprintf(stdout, " -r: Specify frame rate (in Hz, max 2 dp.) (default: input source rate)\n"); 00047 fprintf(stdout, " -c: Specify cropping (format: x,y,width,height) (default: No Cropping Applied)\n"); 00048 fprintf(stdout, " -n: Use non-blocking IO (not supported by Vision driver yet)\n"); 00049 fprintf(stdout, " -t: Print timestamp information (default: off)\n"); 00050 fprintf(stdout, " -l: Use liveStream (default: off)\n"); 00051 fprintf(stdout, " -z: Add delay in ms between dequeuing frames (default: off, no added delay)\n"); 00052 fprintf(stdout, " -j: Specify number of buffers to capture (default: continuous capture)\n"); 00053 }
int CaptureStop = 0 |