1 /* 2 * netcam.h 3 * 4 * Include file for handling network cameras. 5 * 6 * This code was inspired by the original netcam.c module 7 * written by Jeroen Vreeken and enhanced by several Motion 8 * project contributors, particularly Angel Carpintero and 9 * Christopher Price. 10 * 11 * Copyright 2005, William M. Brack 12 * This software is distributed under the GNU Public license 13 * Version 2. See also the file 'COPYING'. 14 */ 15 #ifndef _INCLUDE_NETCAM_H 16 #define _INCLUDE_NETCAM_H 17 18 /* This is a workaround regarding these defines. The config.h file defines 19 * HAVE_STDLIB_H as 1 whereas the jpeglib.h just defines it without a value. 20 * this causes massive warnings/error on mis-matched definitions. We do not 21 * control either of these so we have to suffer through this workaround hack 22 */ 23 #if (HAVE_STDLIB_H == 1) 24 #undef HAVE_STDLIB_H 25 #define HAVE_STDLIB_H_ORIG 1 26 #endif 27 28 #include <jpeglib.h> 29 30 #ifdef HAVE_STDLIB_H 31 #ifdef HAVE_STDLIB_H_ORIG 32 #undef HAVE_STDLIB_H 33 #undef HAVE_STDLIB_H_ORIG 34 #define HAVE_STDLIB_H 1 35 #else 36 #undef HAVE_STDLIB_H 37 #endif 38 #endif 39 40 41 #include <setjmp.h> 42 #include <sys/socket.h> 43 #include <sys/types.h> 44 #include <regex.h> 45 46 /** 47 * ATTRIBUTE_UNUSED: 48 * 49 * Macro used to signal to GCC unused function parameters 50 */ 51 #ifdef __GNUC__ 52 #ifdef HAVE_ANSIDECL_H 53 #include <ansidecl.h> 54 #endif 55 #ifndef ATTRIBUTE_UNUSED 56 #define ATTRIBUTE_UNUSED __attribute__((unused)) 57 #endif 58 #else 59 #define ATTRIBUTE_UNUSED 60 #endif 61 62 /* netcam_wget.h needs to have netcam_context_ptr */ 63 typedef struct netcam_context *netcam_context_ptr; 64 65 #include "netcam_wget.h" /* needed for struct rbuf */ 66 67 #define NETCAM_BUFFSIZE 4096 /* Initial size reserved for a JPEG 68 image. If expansion is required, 69 this value is also used for the 70 amount to increase. */ 71 72 /* 73 * Error return codes for netcam routines. The values are "bit 74 * significant". All error returns will return bit 1 set to indicate 75 * these are "netcam errors"; additional bits set will give more detail 76 * as to what kind of error it was. 77 * Bit 0 is reserved for V4L type errors. 78 * 79 */ 80 #define NETCAM_GENERAL_ERROR 0x02 /* binary 000010 */ 81 #define NETCAM_NOTHING_NEW_ERROR 0x06 /* binary 000110 */ 82 #define NETCAM_JPEG_CONV_ERROR 0x0a /* binary 001010 */ 83 #define NETCAM_RESTART_ERROR 0x12 /* binary 010010 */ 84 #define NETCAM_FATAL_ERROR -2 85 86 #define NCS_UNSUPPORTED 0 /* streaming is not supported */ 87 #define NCS_MULTIPART 1 /* streaming is done via multipart */ 88 #define NCS_BLOCK 2 /* streaming is done via MJPG-block */ 89 90 /* 91 * struct url_t is used when parsing the user-supplied URL, as well as 92 * when attempting to connect to the netcam. 93 */ 94 struct url_t { 95 char *service; 96 char *userpass; 97 char *host; 98 int port; 99 char *path; 100 }; 101 102 /* 103 * We use a special "triple-buffer" technique. There are 104 * three separate buffers (latest, receiving and jpegbuf) 105 * which are each described using a struct netcam_image_buff 106 */ 107 typedef struct netcam_image_buff { 108 char *ptr; 109 int content_length; 110 size_t size; /* total allocated size */ 111 size_t used; /* bytes already used */ 112 struct timeval image_time; /* time this image was received */ 113 } netcam_buff; 114 typedef netcam_buff *netcam_buff_ptr; 115 116 extern struct netcam_caps { /* netcam capabilities: */ 117 unsigned char streaming; /* See the NCS_* defines */ 118 unsigned char content_length; /* 0 - unsupported */ 119 } caps; 120 121 122 /* 123 * struct netcam_context contains all the structures and other data 124 * for an individual netcam. 125 */ 126 typedef struct netcam_context { 127 struct context *cnt; /* pointer to parent motion 128 context structure */ 129 130 int finish; /* flag to break the camera- 131 handling thread out of it's 132 infinite loop in emergency */ 133 134 int threadnr; /* motion's thread number for 135 the camera-handling thread 136 (if required). Used for 137 error reporting */ 138 139 pthread_t thread_id; /* thread i.d. for a camera-handling thread (if required). */ 140 141 pthread_mutex_t mutex; /* mutex used with conditional waits */ 142 143 pthread_cond_t exiting; /* signal for exiting thread */ 144 145 pthread_cond_t cap_cond; /* pthread condition structure to 146 initiate next capture request (used 147 only with non-streaming cameras */ 148 149 pthread_cond_t pic_ready; /* pthread condition structure used 150 for synchronisation between the 151 camera handler and the motion main 152 loop, showing new frame is ready */ 153 154 int start_capture; /* besides our signalling condition, 155 we also keep a flag to assure the 156 camera-handler will always start 157 a new cycle as soon as possible, 158 even if it's not currently waiting 159 on the condition. */ 160 161 char *connect_host; /* the host to connect to (may be 162 either the camera host, or 163 possibly a proxy) */ 164 165 int connect_port; /* usually will be 80, but can be 166 specified as something else by 167 the user */ 168 169 int connect_http_10; /* set to TRUE if HTTP 1.0 connection 170 (netcam_keepalive off) */ 171 172 int connect_http_11; /* set to TRUE if HTTP 1.1 connection 173 (netcam_keepalive on) */ 174 175 int connect_keepalive; /* set to TRUE if connection maintained after 176 a request, otherwise FALSE to close down 177 the socket each time (netcam_keealive force) */ 178 179 int keepalive_thisconn; /* set to TRUE if cam has sent 'Keep-Alive' in this connection */ 180 181 int keepalive_timeup; /* set to TRUE if it is time to close netcam's socket, 182 and then re-open it with Keep-Alive set again. 183 Even Keep-Alive netcams need a close/open sometimes. */ 184 185 char *connect_request; /* contains the complete string 186 required for connection to the 187 camera */ 188 189 int sock; /* fd for the camera's socket. 190 Note that this value is also 191 present within the struct 192 rbuf *response. */ 193 194 struct timeval timeout; /* The current timeout setting for 195 the socket. */ 196 197 struct rbuf *response; /* this structure (defined in the 198 netcam_wget module) contains 199 the context for an HTTP 200 connection. Note that this 201 structure includes a large 202 buffer for the HTTP data */ 203 204 struct ftp_context *ftp; /* this structure contains the context for FTP connection */ 205 struct file_context *file; /* this structure contains the context for FILE connection */ 206 207 int (*get_image)(netcam_context_ptr); 208 /* Function to fetch the image from 209 the netcam. It is initialised in 210 netcam_setup depending upon whether 211 the picture source is from an http 212 server or from an ftp server */ 213 214 215 struct netcam_caps caps; /* Type of camera */ 216 char *boundary; /* 'boundary' string when used to separate mjpeg images */ 217 size_t boundary_length; /* string length of the boundary string */ 218 219 netcam_buff_ptr latest; /* This buffer contains the latest frame received from the camera */ 220 netcam_buff_ptr receiving; /* This buffer is used for receiving data from the camera */ 221 netcam_buff_ptr jpegbuf; /* This buffer is used for jpeg decompression */ 222 223 int imgcnt; /* count for # of received jpegs */ 224 int imgcnt_last; /* remember last count to check if a new image arrived */ 225 int warning_count; /* simple count of number of warnings since last good frame was received */ 226 int error_count; /* simple count of number of errors since last good frame was received */ 227 228 unsigned int width; /* info for decompression */ 229 unsigned int height; 230 231 int JFIF_marker; /* Debug to know if JFIF was present or not */ 232 unsigned int netcam_tolerant_check; /* For network cameras with buggy firmwares */ 233 234 struct timeval last_image; /* time the most recent image was received */ 235 float av_frame_time; /* "running average" of time between successive frames (microseconds) */ 236 237 struct jpeg_error_mgr jerr; 238 jmp_buf setjmp_buffer; 239 240 int jpeg_error; /* flag to show error or warning occurred during decompression*/ 241 242 int handler_finished; 243 244 } netcam_context; 245 246 /* 247 * Declare prototypes for our external entry points 248 */ 249 /* Within netcam_jpeg.c */ 250 int netcam_proc_jpeg (struct netcam_context *, struct image_data *img_data); 251 void netcam_fix_jpeg_header(struct netcam_context *); 252 void netcam_get_dimensions (struct netcam_context *); 253 /* Within netcam.c */ 254 int netcam_start (struct context *); 255 int netcam_next(struct context *cnt, struct image_data *img_data); 256 void netcam_cleanup (struct netcam_context *, int); 257 ssize_t netcam_recv(netcam_context_ptr, void *, size_t); 258 void netcam_url_parse(struct url_t *parse_url, const char *text_url); 259 void netcam_url_free(struct url_t *parse_url); 260 261 /** 262 * Publish new image 263 * 264 * Moves the image in 'receiving' into 'latest' and updates last frame time 265 */ 266 void netcam_image_read_complete(netcam_context_ptr netcam); 267 268 /** 269 * This routine checks whether there is enough room in a buffer to copy 270 * some additional data. If there is not enough room, it will re-allocate 271 * the buffer and adjust it's size. 272 * 273 * Parameters: 274 * buff Pointer to a netcam_image_buffer structure. 275 * numbytes The number of bytes to be copied. 276 * 277 * Returns: Nothing 278 */ 279 void netcam_check_buffsize(netcam_buff_ptr buff, size_t numbytes); 280 281 #endif 282