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