mirror of
https://github.com/Motion-Project/motion.git
synced 2026-02-02 19:11:26 -05:00
Update time methods and types
This commit is contained in:
70
src/event.c
70
src/event.c
@@ -76,7 +76,7 @@ static const char *eventToString(motion_event e)
|
||||
static void exec_command(struct ctx_cam *cam, char *command, char *filename, int filetype)
|
||||
{
|
||||
char stamp[PATH_MAX];
|
||||
mystrftime(cam, stamp, sizeof(stamp), command, &cam->current_image->timestamp_tv, filename, filetype);
|
||||
mystrftime(cam, stamp, sizeof(stamp), command, &cam->current_image->imgts, filename, filetype);
|
||||
|
||||
if (!fork()) {
|
||||
int i;
|
||||
@@ -106,7 +106,7 @@ static void exec_command(struct ctx_cam *cam, char *command, char *filename, int
|
||||
|
||||
static void event_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)cam;
|
||||
(void)evnt;
|
||||
@@ -121,7 +121,7 @@ static void event_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_beep(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -143,7 +143,7 @@ static void event_beep(struct ctx_cam *cam, motion_event evnt
|
||||
*/
|
||||
static void on_picture_save_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int filetype = (unsigned long)ftype;
|
||||
|
||||
@@ -160,7 +160,7 @@ static void on_picture_save_command(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void on_motion_detected_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -291,7 +291,7 @@ static void do_sql_query(char *sqlquery, struct ctx_cam *cam, int save_id)
|
||||
|
||||
static void event_sqlfirstmotion(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
char sqlquery[PATH_MAX];
|
||||
|
||||
@@ -307,7 +307,7 @@ static void event_sqlfirstmotion(struct ctx_cam *cam, motion_event evnt
|
||||
}
|
||||
|
||||
mystrftime(cam, sqlquery, sizeof(sqlquery), cam->conf.sql_query_start,
|
||||
&cam->current_image->timestamp_tv, NULL, 0);
|
||||
&cam->current_image->imgts, NULL, 0);
|
||||
|
||||
do_sql_query(sqlquery, cam, 1);
|
||||
|
||||
@@ -315,7 +315,7 @@ static void event_sqlfirstmotion(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_sqlnewfile(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int sqltype = (unsigned long)ftype;
|
||||
char sqlquery[PATH_MAX];
|
||||
@@ -335,7 +335,7 @@ static void event_sqlnewfile(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_sqlfileclose(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int sqltype = (unsigned long)ftype;
|
||||
char sqlquery[PATH_MAX];
|
||||
@@ -355,7 +355,7 @@ static void event_sqlfileclose(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void on_area_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -369,7 +369,7 @@ static void on_area_command(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void on_event_start_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -383,7 +383,7 @@ static void on_event_start_command(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void on_event_end_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -397,7 +397,7 @@ static void on_event_end_command(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_stream_put(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int subsize;
|
||||
|
||||
@@ -499,7 +499,7 @@ static void event_stream_put(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_vlp_putpipe(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)fname;
|
||||
@@ -525,7 +525,7 @@ const char *imageext(struct ctx_cam *cam) {
|
||||
|
||||
static void event_image_detect(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
char fullfilename[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
@@ -565,7 +565,7 @@ static void event_image_detect(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_imagem_detect(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
struct config *conf = &cam->conf;
|
||||
char fullfilenamem[PATH_MAX];
|
||||
@@ -606,7 +606,7 @@ static void event_imagem_detect(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_image_snapshot(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
char fullfilename[PATH_MAX];
|
||||
char filename[PATH_MAX];
|
||||
@@ -680,7 +680,7 @@ static void event_image_snapshot(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_image_preview(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int use_imagepath;
|
||||
const char *imagepath;
|
||||
@@ -756,7 +756,7 @@ static void event_image_preview(struct ctx_cam *cam, motion_event evnt
|
||||
else
|
||||
imagepath = (char *)DEF_IMAGEPATH;
|
||||
|
||||
mystrftime(cam, filename, sizeof(filename), imagepath, &cam->imgs.preview_image.timestamp_tv, NULL, 0);
|
||||
mystrftime(cam, filename, sizeof(filename), imagepath, &cam->imgs.preview_image.imgts, NULL, 0);
|
||||
snprintf(previewname, PATH_MAX, "%.*s/%.*s.%s"
|
||||
, (int)(PATH_MAX-2-strlen(filename)-strlen(imageext(cam)))
|
||||
, cam->conf.target_dir
|
||||
@@ -779,7 +779,7 @@ static void event_image_preview(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_camera_lost(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -793,7 +793,7 @@ static void event_camera_lost(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_camera_found(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -807,7 +807,7 @@ static void event_camera_found(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void on_movie_end_command(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int filetype = (unsigned long) ftype;
|
||||
|
||||
@@ -821,7 +821,7 @@ static void on_movie_end_command(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_extpipe_end(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -842,7 +842,7 @@ static void event_extpipe_end(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_create_extpipe(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int retcd;
|
||||
char stamp[PATH_MAX] = "";
|
||||
@@ -923,7 +923,7 @@ static void event_create_extpipe(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_extpipe_put(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int passthrough;
|
||||
|
||||
@@ -956,7 +956,7 @@ static void event_extpipe_put(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_new_video(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -976,7 +976,7 @@ static void event_new_video(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
char stamp[PATH_MAX];
|
||||
const char *moviepath;
|
||||
@@ -1098,7 +1098,7 @@ static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
cam->movie_output->filename = cam->newfilename;
|
||||
cam->movie_output->quality = cam->conf.movie_quality;
|
||||
cam->movie_output->start_time.tv_sec = ts1->tv_sec;
|
||||
cam->movie_output->start_time.tv_usec = ts1->tv_usec;
|
||||
cam->movie_output->start_time.tv_nsec = ts1->tv_nsec;
|
||||
cam->movie_output->last_pts = -1;
|
||||
cam->movie_output->base_pts = 0;
|
||||
cam->movie_output->gop_cnt = 0;
|
||||
@@ -1134,7 +1134,7 @@ static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
cam->movie_output_motion->filename = cam->motionfilename;
|
||||
cam->movie_output_motion->quality = cam->conf.movie_quality;
|
||||
cam->movie_output_motion->start_time.tv_sec = ts1->tv_sec;
|
||||
cam->movie_output_motion->start_time.tv_usec = ts1->tv_usec;
|
||||
cam->movie_output_motion->start_time.tv_nsec = ts1->tv_nsec;
|
||||
cam->movie_output_motion->last_pts = -1;
|
||||
cam->movie_output_motion->base_pts = 0;
|
||||
cam->movie_output_motion->gop_cnt = 0;
|
||||
@@ -1162,7 +1162,7 @@ static void event_movie_newfile(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_movie_timelapse(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
int retcd;
|
||||
int passthrough;
|
||||
@@ -1209,7 +1209,7 @@ static void event_movie_timelapse(struct ctx_cam *cam, motion_event evnt
|
||||
cam->movie_timelapse->filename = cam->timelapsefilename;
|
||||
cam->movie_timelapse->quality = cam->conf.movie_quality;
|
||||
cam->movie_timelapse->start_time.tv_sec = ts1->tv_sec;
|
||||
cam->movie_timelapse->start_time.tv_usec = ts1->tv_usec;
|
||||
cam->movie_timelapse->start_time.tv_nsec = ts1->tv_nsec;
|
||||
cam->movie_timelapse->last_pts = -1;
|
||||
cam->movie_timelapse->base_pts = 0;
|
||||
cam->movie_timelapse->test_mode = FALSE;
|
||||
@@ -1259,7 +1259,7 @@ static void event_movie_timelapse(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_movie_put(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)fname;
|
||||
@@ -1279,7 +1279,7 @@ static void event_movie_put(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_movie_closefile(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -1304,7 +1304,7 @@ static void event_movie_closefile(struct ctx_cam *cam, motion_event evnt
|
||||
|
||||
static void event_movie_timelapseend(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
|
||||
(void)evnt;
|
||||
(void)img_data;
|
||||
@@ -1467,7 +1467,7 @@ struct event_handlers event_handlers[] = {
|
||||
*/
|
||||
void event(struct ctx_cam *cam, motion_event evnt
|
||||
,struct image_data *img_data, char *fname
|
||||
,void *ftype, struct timeval *ts1) {
|
||||
,void *ftype, struct timespec *ts1) {
|
||||
int i=-1;
|
||||
|
||||
while (event_handlers[++i].handler) {
|
||||
|
||||
@@ -36,9 +36,9 @@ typedef enum {
|
||||
} motion_event;
|
||||
|
||||
typedef void(* event_handler)(struct ctx_cam *cam, motion_event, struct image_data *,
|
||||
char *, void *, struct timeval *);
|
||||
char *, void *, struct timespec *);
|
||||
|
||||
void event(struct ctx_cam *cam, motion_event, struct image_data *img_data, char *, void *, struct timeval *);
|
||||
void event(struct ctx_cam *cam, motion_event, struct image_data *img_data, char *, void *, struct timespec *);
|
||||
const char * imageext(struct ctx_cam *cam);
|
||||
|
||||
#endif /* _INCLUDE_EVENT_H_ */
|
||||
|
||||
@@ -422,11 +422,11 @@ static GLOBAL(int) _jpeg_mem_size(j_compress_ptr cinfo)
|
||||
*/
|
||||
static void put_jpeg_exif(j_compress_ptr cinfo,
|
||||
const struct ctx_cam *cam,
|
||||
const struct timeval *tv1,
|
||||
const struct timespec *ts1,
|
||||
const struct coord *box)
|
||||
{
|
||||
unsigned char *exif = NULL;
|
||||
unsigned exif_len = prepare_exif(&exif, cam, tv1, box);
|
||||
unsigned exif_len = prepare_exif(&exif, cam, ts1, box);
|
||||
|
||||
if(exif_len > 0) {
|
||||
/* EXIF data lives in a JPEG APP1 marker */
|
||||
@@ -549,7 +549,7 @@ int jpgutl_decode_jpeg (unsigned char *jpeg_data_in, int jpeg_data_len,
|
||||
|
||||
int jpgutl_put_yuv420p(unsigned char *dest_image, int image_size,
|
||||
unsigned char *input_image, int width, int height, int quality,
|
||||
struct ctx_cam *cam, struct timeval *tv1, struct coord *box)
|
||||
struct ctx_cam *cam, struct timespec *ts1, struct coord *box)
|
||||
|
||||
{
|
||||
int i, j, jpeg_image_size;
|
||||
@@ -606,7 +606,7 @@ int jpgutl_put_yuv420p(unsigned char *dest_image, int image_size,
|
||||
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
put_jpeg_exif(&cinfo, cam, tv1, box);
|
||||
put_jpeg_exif(&cinfo, cam, ts1, box);
|
||||
|
||||
/* If the image is not a multiple of 16, this overruns the buffers
|
||||
* we'll just pad those last bytes with zeros
|
||||
@@ -638,7 +638,7 @@ int jpgutl_put_yuv420p(unsigned char *dest_image, int image_size,
|
||||
|
||||
int jpgutl_put_grey(unsigned char *dest_image, int image_size,
|
||||
unsigned char *input_image, int width, int height, int quality,
|
||||
struct ctx_cam *cam, struct timeval *tv1, struct coord *box)
|
||||
struct ctx_cam *cam, struct timespec *ts1, struct coord *box)
|
||||
{
|
||||
int y, dest_image_size;
|
||||
JSAMPROW row_ptr[1];
|
||||
@@ -674,7 +674,7 @@ int jpgutl_put_grey(unsigned char *dest_image, int image_size,
|
||||
|
||||
jpeg_start_compress (&cjpeg, TRUE);
|
||||
|
||||
put_jpeg_exif(&cjpeg, cam, tv1, box);
|
||||
put_jpeg_exif(&cjpeg, cam, ts1, box);
|
||||
|
||||
row_ptr[0] = input_image;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
int jpgutl_decode_jpeg (unsigned char *jpeg_data_in, int jpeg_data_len,
|
||||
unsigned int width, unsigned int height, unsigned char *volatile img_out);
|
||||
|
||||
int jpgutl_put_yuv420p(unsigned char *, int image, unsigned char *, int, int, int, struct ctx_cam *cam, struct timeval *, struct coord *);
|
||||
int jpgutl_put_grey(unsigned char *, int image, unsigned char *, int, int, int, struct ctx_cam *cam, struct timeval *, struct coord *);
|
||||
int jpgutl_put_yuv420p(unsigned char *, int image, unsigned char *, int, int, int, struct ctx_cam *cam, struct timespec *, struct coord *);
|
||||
int jpgutl_put_grey(unsigned char *, int image, unsigned char *, int, int, int, struct ctx_cam *cam, struct timespec *, struct coord *);
|
||||
|
||||
#endif
|
||||
|
||||
265
src/motion.c
265
src/motion.c
@@ -569,39 +569,26 @@ static void motion_detected(struct ctx_cam *cam, int dev, struct image_data *img
|
||||
|
||||
/* Do things only if we have got minimum_motion_frames */
|
||||
if (img->flags & IMAGE_TRIGGER) {
|
||||
/* Take action if this is a new event and we have a trigger image */
|
||||
if (cam->event_nr != cam->prev_event) {
|
||||
/*
|
||||
* Reset prev_event number to current event and save event time
|
||||
* in both time_t and struct tm format.
|
||||
*/
|
||||
|
||||
cam->prev_event = cam->event_nr;
|
||||
cam->eventtime = img->timestamp_tv.tv_sec;
|
||||
localtime_r(&cam->eventtime, cam->eventtime_tm);
|
||||
cam->eventtime = img->imgts.tv_sec;
|
||||
|
||||
/*
|
||||
* Since this is a new event we create the event_text_string used for
|
||||
* the %C conversion specifier. We may already need it for
|
||||
* on_motion_detected_commend so it must be done now.
|
||||
*/
|
||||
mystrftime(cam, cam->text_event_string, sizeof(cam->text_event_string),
|
||||
cam->conf.text_event, &img->timestamp_tv, NULL, 0);
|
||||
cam->conf.text_event, &img->imgts, NULL, 0);
|
||||
|
||||
/* EVENT_FIRSTMOTION triggers on_event_start_command and event_movie_newfile */
|
||||
event(cam, EVENT_FIRSTMOTION, img, NULL, NULL,
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].timestamp_tv);
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].imgts);
|
||||
|
||||
MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Motion detected - starting event %d"),
|
||||
cam->event_nr);
|
||||
|
||||
/* always save first motion frame as preview-shot, may be changed to an other one later */
|
||||
if (cam->new_img & (NEWIMG_FIRST | NEWIMG_BEST | NEWIMG_CENTER))
|
||||
image_save_as_preview(cam, img);
|
||||
|
||||
}
|
||||
|
||||
/* EVENT_MOTION triggers event_beep and on_motion_detected_command */
|
||||
event(cam, EVENT_MOTION, NULL, NULL, NULL, &img->timestamp_tv);
|
||||
event(cam, EVENT_MOTION, NULL, NULL, NULL, &img->imgts);
|
||||
}
|
||||
|
||||
/* Limit framerate */
|
||||
@@ -613,14 +600,14 @@ static void motion_detected(struct ctx_cam *cam, int dev, struct image_data *img
|
||||
* We also disable this in setup_mode.
|
||||
*/
|
||||
if (conf->stream_motion && !conf->setup_mode && img->shot != 1)
|
||||
event(cam, EVENT_STREAM, img, NULL, NULL, &img->timestamp_tv);
|
||||
event(cam, EVENT_STREAM, img, NULL, NULL, &img->imgts);
|
||||
|
||||
/*
|
||||
* Save motion jpeg, if configured
|
||||
* Output the image_out (motion) picture.
|
||||
*/
|
||||
if (conf->picture_output_motion)
|
||||
event(cam, EVENT_IMAGEM_DETECTED, NULL, NULL, NULL, &img->timestamp_tv);
|
||||
event(cam, EVENT_IMAGEM_DETECTED, NULL, NULL, NULL, &img->imgts);
|
||||
}
|
||||
|
||||
/* if track enabled and auto track on */
|
||||
@@ -677,7 +664,7 @@ static void process_image_ring(struct ctx_cam *cam, unsigned int max_images)
|
||||
t = "Other";
|
||||
|
||||
mystrftime(cam, tmp, sizeof(tmp), "%H%M%S-%q",
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].timestamp_tv, NULL, 0);
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].imgts, NULL, 0);
|
||||
draw_text(cam->imgs.image_ring[cam->imgs.image_ring_out].image_norm,
|
||||
cam->imgs.width, cam->imgs.height, 10, 20, tmp, cam->text_scale);
|
||||
draw_text(cam->imgs.image_ring[cam->imgs.image_ring_out].image_norm,
|
||||
@@ -687,7 +674,7 @@ static void process_image_ring(struct ctx_cam *cam, unsigned int max_images)
|
||||
/* Output the picture to jpegs and ffmpeg */
|
||||
event(cam, EVENT_IMAGE_DETECTED,
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out], NULL, NULL,
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].timestamp_tv);
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].imgts);
|
||||
|
||||
|
||||
/*
|
||||
@@ -722,7 +709,7 @@ static void process_image_ring(struct ctx_cam *cam, unsigned int max_images)
|
||||
/* Add a filler frame into encoder */
|
||||
event(cam, EVENT_MOVIE_PUT,
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out], NULL, NULL,
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].timestamp_tv);
|
||||
&cam->imgs.image_ring[cam->imgs.image_ring_out].imgts);
|
||||
|
||||
cam->movie_last_shot++;
|
||||
}
|
||||
@@ -1250,18 +1237,15 @@ static void dbse_sqlmask_update(struct ctx_cam *cam){
|
||||
static int motion_init(struct ctx_cam *cam)
|
||||
{
|
||||
FILE *picture;
|
||||
int indx, retcd;
|
||||
int retcd;
|
||||
|
||||
util_threadname_set("ml",cam->threadnr,cam->conf.camera_name);
|
||||
|
||||
/* Store thread number in TLS. */
|
||||
pthread_setspecific(tls_key_threadnr, (void *)((unsigned long)cam->threadnr));
|
||||
|
||||
cam->currenttime_tm = mymalloc(sizeof(struct tm));
|
||||
cam->eventtime_tm = mymalloc(sizeof(struct tm));
|
||||
/* Init frame time */
|
||||
cam->currenttime = time(NULL);
|
||||
localtime_r(&cam->currenttime, cam->currenttime_tm);
|
||||
clock_gettime(CLOCK_REALTIME, &cam->frame_last_ts);
|
||||
clock_gettime(CLOCK_REALTIME, &cam->frame_curr_ts);
|
||||
|
||||
cam->smartmask_speed = 0;
|
||||
|
||||
@@ -1544,19 +1528,6 @@ static int motion_init(struct ctx_cam *cam)
|
||||
|
||||
cam->frame_delay = cam->required_frame_time;
|
||||
|
||||
/*
|
||||
* Reserve enough space for a 10 second timing history buffer. Note that,
|
||||
* if there is any problem on the allocation, mymalloc does not return.
|
||||
*/
|
||||
cam->rolling_average_data = NULL;
|
||||
cam->rolling_average_limit = 10 * cam->conf.framerate;
|
||||
cam->rolling_average_data = mymalloc(sizeof(cam->rolling_average_data) * cam->rolling_average_limit);
|
||||
|
||||
/* Preset history buffer with expected frame rate */
|
||||
for (indx = 0; indx < cam->rolling_average_limit; indx++)
|
||||
cam->rolling_average_data[indx] = cam->required_frame_time;
|
||||
|
||||
|
||||
cam->track_posx = 0;
|
||||
cam->track_posy = 0;
|
||||
if (cam->track.type)
|
||||
@@ -1710,17 +1681,6 @@ static void motion_cleanup(struct ctx_cam *cam) {
|
||||
cam->mpipe = -1;
|
||||
}
|
||||
|
||||
if (cam->rolling_average_data != NULL) free(cam->rolling_average_data);
|
||||
|
||||
|
||||
/* Cleanup the current time structure */
|
||||
free(cam->currenttime_tm);
|
||||
cam->currenttime_tm = NULL;
|
||||
|
||||
/* Cleanup the event time structure */
|
||||
free(cam->eventtime_tm);
|
||||
cam->eventtime_tm = NULL;
|
||||
|
||||
dbse_deinit(cam);
|
||||
|
||||
}
|
||||
@@ -1818,7 +1778,7 @@ static void mlp_areadetect(struct ctx_cam *cam){
|
||||
cam->current_image->location.x < cam->area_maxx[z] &&
|
||||
cam->current_image->location.y > cam->area_miny[z] &&
|
||||
cam->current_image->location.y < cam->area_maxy[z]) {
|
||||
event(cam, EVENT_AREA_DETECTED, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_AREA_DETECTED, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
cam->areadetect_eventnbr = cam->event_nr; /* Fire script only once per event */
|
||||
MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO
|
||||
,_("Motion in area %d detected."), z + 1);
|
||||
@@ -1833,19 +1793,14 @@ static void mlp_areadetect(struct ctx_cam *cam){
|
||||
static void mlp_prepare(struct ctx_cam *cam){
|
||||
|
||||
int frame_buffer_size;
|
||||
struct timeval tv1;
|
||||
|
||||
/***** MOTION LOOP - PREPARE FOR NEW FRAME SECTION *****/
|
||||
cam->watchdog = WATCHDOG_TMO;
|
||||
|
||||
/* Get current time and preserver last time for frame interval calc. */
|
||||
|
||||
/* This may be better at the end of the loop or moving the part in
|
||||
* the end doing elapsed time calc in here
|
||||
*/
|
||||
cam->timebefore = cam->timenow;
|
||||
gettimeofday(&tv1, NULL);
|
||||
cam->timenow = tv1.tv_usec + 1000000L * tv1.tv_sec;
|
||||
|
||||
cam->frame_last_ts.tv_sec = cam->frame_curr_ts.tv_sec;
|
||||
cam->frame_last_ts.tv_nsec = cam->frame_curr_ts.tv_nsec;
|
||||
clock_gettime(CLOCK_REALTIME, &cam->frame_curr_ts);
|
||||
|
||||
/*
|
||||
* Calculate detection rate limit. Above 5fps we limit the detection
|
||||
@@ -1858,42 +1813,23 @@ static void mlp_prepare(struct ctx_cam *cam){
|
||||
cam->process_thisframe = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we don't have sanity checks done when options are set,
|
||||
* this sanity check must go in the main loop :(, before pre_captures
|
||||
* are attempted.
|
||||
*/
|
||||
if (cam->conf.minimum_motion_frames < 1)
|
||||
cam->conf.minimum_motion_frames = 1;
|
||||
|
||||
if (cam->conf.pre_capture < 0)
|
||||
cam->conf.pre_capture = 0;
|
||||
|
||||
/*
|
||||
* Check if our buffer is still the right size
|
||||
* If pre_capture or minimum_motion_frames has been changed
|
||||
* via the http remote control we need to re-size the ring buffer
|
||||
*/
|
||||
frame_buffer_size = cam->conf.pre_capture + cam->conf.minimum_motion_frames;
|
||||
|
||||
if (cam->imgs.image_ring_size != frame_buffer_size)
|
||||
image_ring_resize(cam, frame_buffer_size);
|
||||
|
||||
/* Get time for current frame */
|
||||
cam->currenttime = time(NULL);
|
||||
|
||||
/*
|
||||
* localtime returns static data and is not threadsafe
|
||||
* so we use localtime_r which is reentrant and threadsafe
|
||||
*/
|
||||
localtime_r(&cam->currenttime, cam->currenttime_tm);
|
||||
|
||||
/*
|
||||
* If we have started on a new second we reset the shots variable
|
||||
* lastrate is updated to be the number of the last frame. last rate
|
||||
* is used as the ffmpeg framerate when motion is detected.
|
||||
*/
|
||||
if (cam->lastframetime != cam->currenttime) {
|
||||
if (cam->frame_last_ts.tv_sec != cam->frame_curr_ts.tv_sec) {
|
||||
cam->lastrate = cam->shots + 1;
|
||||
cam->shots = -1;
|
||||
cam->lastframetime = cam->currenttime;
|
||||
@@ -1955,7 +1891,7 @@ static void mlp_resetimages(struct ctx_cam *cam){
|
||||
} else if (cam->current_image && old_image) {
|
||||
/* not processing this frame: save some important values for next image */
|
||||
cam->current_image->diffs = old_image->diffs;
|
||||
cam->current_image->timestamp_tv = old_image->timestamp_tv;
|
||||
cam->current_image->imgts = old_image->imgts;
|
||||
cam->current_image->shot = old_image->shot;
|
||||
cam->current_image->cent_dist = old_image->cent_dist;
|
||||
cam->current_image->flags = old_image->flags & (~IMAGE_SAVED);
|
||||
@@ -1963,8 +1899,7 @@ static void mlp_resetimages(struct ctx_cam *cam){
|
||||
cam->current_image->total_labels = old_image->total_labels;
|
||||
}
|
||||
|
||||
/* Store time with pre_captured image */
|
||||
gettimeofday(&cam->current_image->timestamp_tv, NULL);
|
||||
clock_gettime(CLOCK_REALTIME, &cam->current_image->imgts);
|
||||
|
||||
/* Store shot number with pre_captured image */
|
||||
cam->current_image->shot = cam->shots;
|
||||
@@ -2037,7 +1972,7 @@ static int mlp_capture(struct ctx_cam *cam){
|
||||
const char *tmpin;
|
||||
char tmpout[80];
|
||||
int vid_return_code = 0; /* Return code used when calling vid_next */
|
||||
struct timeval tv1;
|
||||
struct timespec ts1;
|
||||
|
||||
/***** MOTION LOOP - IMAGE CAPTURE SECTION *****/
|
||||
/*
|
||||
@@ -2077,16 +2012,6 @@ static int mlp_capture(struct ctx_cam *cam){
|
||||
|
||||
memcpy(cam->imgs.image_vprvcy.image_norm, cam->current_image->image_norm, cam->imgs.size_norm);
|
||||
|
||||
/*
|
||||
* If the camera is a netcam we let the camera decide the pace.
|
||||
* Otherwise we will keep on adding duplicate frames.
|
||||
* By resetting the timer the framerate becomes maximum the rate
|
||||
* of the Netcam.
|
||||
*/
|
||||
if (cam->conf.netcam_url) {
|
||||
gettimeofday(&tv1, NULL);
|
||||
cam->timenow = tv1.tv_usec + 1000000L * tv1.tv_sec;
|
||||
}
|
||||
// FATAL ERROR - leave the thread by breaking out of the main loop
|
||||
} else if (vid_return_code < 0) {
|
||||
/* Fatal error - Close video device */
|
||||
@@ -2159,10 +2084,10 @@ static int mlp_capture(struct ctx_cam *cam){
|
||||
else
|
||||
tmpin = "UNABLE TO OPEN VIDEO DEVICE\\nSINCE %Y-%m-%d %T";
|
||||
|
||||
tv1.tv_sec=cam->connectionlosttime;
|
||||
tv1.tv_usec = 0;
|
||||
ts1.tv_sec=cam->connectionlosttime;
|
||||
ts1.tv_nsec = 0;
|
||||
memset(cam->current_image->image_norm, 0x80, cam->imgs.size_norm);
|
||||
mystrftime(cam, tmpout, sizeof(tmpout), tmpin, &tv1, NULL, 0);
|
||||
mystrftime(cam, tmpout, sizeof(tmpout), tmpin, &ts1, NULL, 0);
|
||||
draw_text(cam->current_image->image_norm, cam->imgs.width, cam->imgs.height,
|
||||
10, 20 * cam->text_scale, tmpout, cam->text_scale);
|
||||
|
||||
@@ -2171,7 +2096,7 @@ static int mlp_capture(struct ctx_cam *cam){
|
||||
MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO
|
||||
,_("Video signal lost - Adding grey image"));
|
||||
// Event for lost video signal can be called from here
|
||||
event(cam, EVENT_CAMERA_LOST, NULL, NULL, NULL, &tv1);
|
||||
event(cam, EVENT_CAMERA_LOST, NULL, NULL, NULL, &ts1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2441,7 +2366,7 @@ static void mlp_overlay(struct ctx_cam *cam){
|
||||
/* Add text in lower left corner of the pictures */
|
||||
if (cam->conf.text_left) {
|
||||
mystrftime(cam, tmp, sizeof(tmp), cam->conf.text_left,
|
||||
&cam->current_image->timestamp_tv, NULL, 0);
|
||||
&cam->current_image->imgts, NULL, 0);
|
||||
draw_text(cam->current_image->image_norm, cam->imgs.width, cam->imgs.height,
|
||||
10, cam->imgs.height - (10 * cam->text_scale), tmp, cam->text_scale);
|
||||
}
|
||||
@@ -2449,7 +2374,7 @@ static void mlp_overlay(struct ctx_cam *cam){
|
||||
/* Add text in lower right corner of the pictures */
|
||||
if (cam->conf.text_right) {
|
||||
mystrftime(cam, tmp, sizeof(tmp), cam->conf.text_right,
|
||||
&cam->current_image->timestamp_tv, NULL, 0);
|
||||
&cam->current_image->imgts, NULL, 0);
|
||||
draw_text(cam->current_image->image_norm, cam->imgs.width, cam->imgs.height,
|
||||
cam->imgs.width - 10, cam->imgs.height - (10 * cam->text_scale),
|
||||
tmp, cam->text_scale);
|
||||
@@ -2485,7 +2410,7 @@ static void mlp_actions(struct ctx_cam *cam){
|
||||
* get a pause in the movie.
|
||||
*/
|
||||
if ( (cam->detecting_motion == 0) && (cam->movie_output != NULL) )
|
||||
movie_reset_movie_start_time(cam->movie_output, &cam->current_image->timestamp_tv);
|
||||
movie_reset_movie_start_time(cam->movie_output, &cam->current_image->imgts);
|
||||
cam->detecting_motion = 1;
|
||||
if (cam->conf.post_capture > 0) {
|
||||
/* Setup the postcap counter */
|
||||
@@ -2528,7 +2453,7 @@ static void mlp_actions(struct ctx_cam *cam){
|
||||
* get a pause in the movie.
|
||||
*/
|
||||
if ( (cam->detecting_motion == 0) && (cam->movie_output != NULL) )
|
||||
movie_reset_movie_start_time(cam->movie_output, &cam->current_image->timestamp_tv);
|
||||
movie_reset_movie_start_time(cam->movie_output, &cam->current_image->imgts);
|
||||
|
||||
cam->detecting_motion = 1;
|
||||
|
||||
@@ -2567,7 +2492,7 @@ static void mlp_actions(struct ctx_cam *cam){
|
||||
|
||||
/* Update last frame saved time, so we can end event after gap time */
|
||||
if (cam->current_image->flags & IMAGE_SAVE)
|
||||
cam->lasttime = cam->current_image->timestamp_tv.tv_sec;
|
||||
cam->lasttime = cam->current_image->imgts.tv_sec;
|
||||
|
||||
|
||||
mlp_areadetect(cam);
|
||||
@@ -2593,11 +2518,11 @@ static void mlp_actions(struct ctx_cam *cam){
|
||||
|
||||
/* Save preview_shot here at the end of event */
|
||||
if (cam->imgs.preview_image.diffs) {
|
||||
event(cam, EVENT_IMAGE_PREVIEW, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_IMAGE_PREVIEW, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
cam->imgs.preview_image.diffs = 0;
|
||||
}
|
||||
|
||||
event(cam, EVENT_ENDMOTION, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_ENDMOTION, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
|
||||
/*
|
||||
* If tracking is enabled we center our camera so it does not
|
||||
@@ -2683,9 +2608,10 @@ static void mlp_snapshot(struct ctx_cam *cam){
|
||||
cam->time_current_frame = cam->currenttime;
|
||||
|
||||
if ((cam->conf.snapshot_interval > 0 && cam->shots == 0 &&
|
||||
cam->time_current_frame % cam->conf.snapshot_interval <= cam->time_last_frame % cam->conf.snapshot_interval) ||
|
||||
cam->frame_curr_ts.tv_sec % cam->conf.snapshot_interval <=
|
||||
cam->frame_last_ts.tv_sec % cam->conf.snapshot_interval) ||
|
||||
cam->snapshot) {
|
||||
event(cam, EVENT_IMAGE_SNAPSHOT, cam->current_image, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_IMAGE_SNAPSHOT, cam->current_image, NULL, NULL, &cam->current_image->imgts);
|
||||
cam->snapshot = 0;
|
||||
}
|
||||
|
||||
@@ -2696,7 +2622,7 @@ static void mlp_timelapse(struct ctx_cam *cam){
|
||||
struct tm timestamp_tm;
|
||||
|
||||
if (cam->conf.timelapse_interval) {
|
||||
localtime_r(&cam->current_image->timestamp_tv.tv_sec, ×tamp_tm);
|
||||
localtime_r(&cam->current_image->imgts.tv_sec, ×tamp_tm);
|
||||
|
||||
/*
|
||||
* Check to see if we should start a new timelapse file. We start one when
|
||||
@@ -2704,7 +2630,7 @@ static void mlp_timelapse(struct ctx_cam *cam){
|
||||
* to prevent the timelapse file from getting reset multiple times during the minute.
|
||||
*/
|
||||
if (timestamp_tm.tm_min == 0 &&
|
||||
(cam->time_current_frame % 60 < cam->time_last_frame % 60) &&
|
||||
(cam->frame_curr_ts.tv_sec % 60 < cam->frame_last_ts.tv_sec % 60) &&
|
||||
cam->shots == 0) {
|
||||
|
||||
if (strcasecmp(cam->conf.timelapse_mode, "manual") == 0) {
|
||||
@@ -2713,27 +2639,27 @@ static void mlp_timelapse(struct ctx_cam *cam){
|
||||
/* If we are daily, raise timelapseend event at midnight */
|
||||
} else if (strcasecmp(cam->conf.timelapse_mode, "daily") == 0) {
|
||||
if (timestamp_tm.tm_hour == 0)
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
|
||||
/* handle the hourly case */
|
||||
} else if (strcasecmp(cam->conf.timelapse_mode, "hourly") == 0) {
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
|
||||
/* If we are weekly-sunday, raise timelapseend event at midnight on sunday */
|
||||
} else if (strcasecmp(cam->conf.timelapse_mode, "weekly-sunday") == 0) {
|
||||
if (timestamp_tm.tm_wday == 0 &&
|
||||
timestamp_tm.tm_hour == 0)
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
/* If we are weekly-monday, raise timelapseend event at midnight on monday */
|
||||
} else if (strcasecmp(cam->conf.timelapse_mode, "weekly-monday") == 0) {
|
||||
if (timestamp_tm.tm_wday == 1 &&
|
||||
timestamp_tm.tm_hour == 0)
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
/* If we are monthly, raise timelapseend event at midnight on first day of month */
|
||||
} else if (strcasecmp(cam->conf.timelapse_mode, "monthly") == 0) {
|
||||
if (timestamp_tm.tm_mday == 1 &&
|
||||
timestamp_tm.tm_hour == 0)
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
/* If invalid we report in syslog once and continue in manual mode */
|
||||
} else {
|
||||
MOTION_LOG(ERR, TYPE_ALL, NO_ERRNO
|
||||
@@ -2744,22 +2670,20 @@ static void mlp_timelapse(struct ctx_cam *cam){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If ffmpeg timelapse is enabled and time since epoch MOD movie_timelaps = 0
|
||||
* add a timelapse frame to the timelapse movie.
|
||||
*/
|
||||
if (cam->shots == 0 && cam->time_current_frame % cam->conf.timelapse_interval <=
|
||||
cam->time_last_frame % cam->conf.timelapse_interval) {
|
||||
event(cam, EVENT_TIMELAPSE, cam->current_image, NULL, NULL,
|
||||
&cam->current_image->timestamp_tv);
|
||||
if (cam->shots == 0 &&
|
||||
cam->frame_curr_ts.tv_sec % cam->conf.timelapse_interval <=
|
||||
cam->frame_last_ts.tv_sec % cam->conf.timelapse_interval) {
|
||||
event(cam, EVENT_TIMELAPSE, cam->current_image, NULL
|
||||
, NULL, &cam->current_image->imgts);
|
||||
}
|
||||
|
||||
} else if (cam->movie_timelapse) {
|
||||
/*
|
||||
* If timelapse movie is in progress but conf.timelapse_interval is zero then close timelapse file
|
||||
* This is an important feature that allows manual roll-over of timelapse file using the http
|
||||
* remote control via a cron job.
|
||||
*/
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_TIMELAPSEEND, NULL, NULL, NULL, &cam->current_image->imgts);
|
||||
}
|
||||
|
||||
cam->time_last_frame = cam->time_current_frame;
|
||||
@@ -2780,18 +2704,18 @@ static void mlp_loopback(struct ctx_cam *cam){
|
||||
*/
|
||||
if (cam->conf.setup_mode) {
|
||||
|
||||
event(cam, EVENT_IMAGE, &cam->imgs.img_motion, NULL, &cam->pipe, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_STREAM, &cam->imgs.img_motion, NULL, NULL, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_IMAGE, &cam->imgs.img_motion, NULL, &cam->pipe, &cam->current_image->imgts);
|
||||
event(cam, EVENT_STREAM, &cam->imgs.img_motion, NULL, NULL, &cam->current_image->imgts);
|
||||
} else {
|
||||
event(cam, EVENT_IMAGE, cam->current_image, NULL,
|
||||
&cam->pipe, &cam->current_image->timestamp_tv);
|
||||
&cam->pipe, &cam->current_image->imgts);
|
||||
|
||||
if (!cam->conf.stream_motion || cam->shots == 1)
|
||||
event(cam, EVENT_STREAM, cam->current_image, NULL, NULL,
|
||||
&cam->current_image->timestamp_tv);
|
||||
&cam->current_image->imgts);
|
||||
}
|
||||
|
||||
event(cam, EVENT_IMAGEM, &cam->imgs.img_motion, NULL, &cam->mpipe, &cam->current_image->timestamp_tv);
|
||||
event(cam, EVENT_IMAGEM, &cam->imgs.img_motion, NULL, &cam->mpipe, &cam->current_image->imgts);
|
||||
|
||||
}
|
||||
|
||||
@@ -2871,59 +2795,40 @@ static void mlp_parmsupdate(struct ctx_cam *cam){
|
||||
static void mlp_frametiming(struct ctx_cam *cam){
|
||||
|
||||
int indx;
|
||||
struct timeval tv2;
|
||||
unsigned long int elapsedtime; //TODO: Need to evaluate logic for needing this.
|
||||
long int delay_time_nsec;
|
||||
struct timespec ts2;
|
||||
int64_t avgtime;
|
||||
|
||||
/***** MOTION LOOP - FRAMERATE TIMING AND SLEEPING SECTION *****/
|
||||
/*
|
||||
* Work out expected frame rate based on config setting which may
|
||||
* have changed from http-control
|
||||
*/
|
||||
if (cam->conf.framerate)
|
||||
cam->required_frame_time = 1000000L / cam->conf.framerate;
|
||||
else
|
||||
cam->required_frame_time = 0;
|
||||
/* Shuffle the last wait times*/
|
||||
for (indx=0; indx<AVGCNT-1; indx++){
|
||||
cam->frame_wait[indx]=cam->frame_wait[indx+1];
|
||||
}
|
||||
|
||||
/* Get latest time to calculate time taken to process video data */
|
||||
gettimeofday(&tv2, NULL);
|
||||
elapsedtime = (tv2.tv_usec + 1000000L * tv2.tv_sec) - cam->timenow;
|
||||
if (cam->conf.framerate) {
|
||||
cam->frame_wait[AVGCNT-1] = 1000000L / cam->conf.framerate;
|
||||
} else {
|
||||
cam->frame_wait[AVGCNT-1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update history buffer but ignore first pass as timebefore
|
||||
* variable will be inaccurate
|
||||
*/
|
||||
if (cam->passflag)
|
||||
cam->rolling_average_data[cam->rolling_frame] = cam->timenow - cam->timebefore;
|
||||
else
|
||||
cam->passflag = 1;
|
||||
clock_gettime(CLOCK_REALTIME, &ts2);
|
||||
|
||||
cam->rolling_frame++;
|
||||
if (cam->rolling_frame >= cam->rolling_average_limit)
|
||||
cam->rolling_frame = 0;
|
||||
cam->frame_wait[AVGCNT-1] = cam->frame_wait[AVGCNT-1] -
|
||||
(1000000L * (ts2.tv_sec - cam->frame_curr_ts.tv_sec)) -
|
||||
((ts2.tv_nsec - cam->frame_curr_ts.tv_nsec)/1000);
|
||||
|
||||
/* Calculate 10 second average and use deviation in delay calculation */
|
||||
cam->rolling_average = 0L;
|
||||
avgtime = 0;
|
||||
for (indx=0; indx<AVGCNT; indx++){
|
||||
avgtime = avgtime + cam->frame_wait[indx];
|
||||
}
|
||||
avgtime = (avgtime/AVGCNT);
|
||||
|
||||
for (indx = 0; indx < cam->rolling_average_limit; indx++)
|
||||
cam->rolling_average += cam->rolling_average_data[indx];
|
||||
|
||||
cam->rolling_average /= cam->rolling_average_limit;
|
||||
cam->frame_delay = cam->required_frame_time - elapsedtime - (cam->rolling_average - cam->required_frame_time);
|
||||
|
||||
if (cam->frame_delay > 0) {
|
||||
/* Apply delay to meet frame time */
|
||||
if (cam->frame_delay > cam->required_frame_time)
|
||||
cam->frame_delay = cam->required_frame_time;
|
||||
|
||||
/* Delay time in nanoseconds for SLEEP */
|
||||
delay_time_nsec = cam->frame_delay * 1000;
|
||||
|
||||
if (delay_time_nsec > 999999999)
|
||||
delay_time_nsec = 999999999;
|
||||
|
||||
/* SLEEP as defined in motion.h A safe sleep using nanosleep */
|
||||
SLEEP(0, delay_time_nsec);
|
||||
if (avgtime > 0) {
|
||||
avgtime = avgtime * 1000;
|
||||
/* If over 1 second, just do one*/
|
||||
if (avgtime > 999999999) {
|
||||
SLEEP(1, 0);
|
||||
} else {
|
||||
SLEEP(0, avgtime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3923,7 +3828,7 @@ static void mystrftime_long (const struct ctx_cam *cam,
|
||||
* Returns: number of bytes written to the string s
|
||||
*/
|
||||
size_t mystrftime(const struct ctx_cam *cam, char *s, size_t max, const char *userformat,
|
||||
const struct timeval *tv1, const char *filename, int sqltype)
|
||||
const struct timespec *ts1, const char *filename, int sqltype)
|
||||
{
|
||||
char formatstring[PATH_MAX] = "";
|
||||
char tempstring[PATH_MAX] = "";
|
||||
@@ -3932,7 +3837,7 @@ size_t mystrftime(const struct ctx_cam *cam, char *s, size_t max, const char *us
|
||||
int width;
|
||||
struct tm timestamp_tm;
|
||||
|
||||
localtime_r(&tv1->tv_sec, ×tamp_tm);
|
||||
localtime_r(&ts1->tv_sec, ×tamp_tm);
|
||||
|
||||
format = formatstring;
|
||||
|
||||
|
||||
23
src/motion.h
23
src/motion.h
@@ -83,10 +83,10 @@ int nls_enabled;
|
||||
* If a signal such as SIG_CHLD interrupts the sleep we just continue sleeping
|
||||
*/
|
||||
#define SLEEP(seconds, nanoseconds) { \
|
||||
struct timespec tv; \
|
||||
tv.tv_sec = (seconds); \
|
||||
tv.tv_nsec = (nanoseconds); \
|
||||
while (nanosleep(&tv, &tv) == -1); \
|
||||
struct timespec ts1; \
|
||||
ts1.tv_sec = (seconds); \
|
||||
ts1.tv_nsec = (nanoseconds); \
|
||||
while (nanosleep(&ts1, &ts1) == -1); \
|
||||
}
|
||||
|
||||
#define DEF_PALETTE 17
|
||||
@@ -172,7 +172,7 @@ int nls_enabled;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define AVGCNT 30
|
||||
|
||||
/*
|
||||
* Structure to hold images information
|
||||
@@ -227,7 +227,7 @@ struct image_data {
|
||||
int diffs;
|
||||
int64_t idnbr_norm;
|
||||
int64_t idnbr_high;
|
||||
struct timeval timestamp_tv;
|
||||
struct timespec imgts;
|
||||
int shot; /* Sub second timestamp count */
|
||||
|
||||
/*
|
||||
@@ -422,8 +422,9 @@ struct ctx_cam {
|
||||
int postcap; /* downcounter, frames left to to send post event */
|
||||
int shots;
|
||||
unsigned int detecting_motion;
|
||||
struct tm *currenttime_tm;
|
||||
struct tm *eventtime_tm;
|
||||
long frame_wait[AVGCNT]; /* Last wait times through motion loop*/
|
||||
struct timespec frame_curr_ts;
|
||||
struct timespec frame_last_ts;
|
||||
|
||||
time_t currenttime;
|
||||
time_t lasttime;
|
||||
@@ -483,10 +484,6 @@ struct ctx_cam {
|
||||
|
||||
long int required_frame_time, frame_delay;
|
||||
|
||||
long int rolling_average_limit;
|
||||
long int *rolling_average_data;
|
||||
unsigned long int rolling_average;
|
||||
|
||||
int olddiffs; //only need this in here for a printf later...do we need that printf?
|
||||
int smartmask_ratio;
|
||||
int smartmask_count;
|
||||
@@ -527,7 +524,7 @@ void * mymalloc(size_t);
|
||||
void * myrealloc(void *, size_t, const char *);
|
||||
FILE * myfopen(const char *, const char *);
|
||||
int myfclose(FILE *);
|
||||
size_t mystrftime(const struct ctx_cam *, char *, size_t, const char *, const struct timeval *, const char *, int);
|
||||
size_t mystrftime(const struct ctx_cam *, char *, size_t, const char *, const struct timespec *, const char *, int);
|
||||
int create_path(const char *);
|
||||
|
||||
void util_threadname_set(const char *abbr, int threadnbr, const char *threadname);
|
||||
|
||||
30
src/movie.c
30
src/movie.c
@@ -523,7 +523,7 @@ static int movie_encode_video(struct ctx_movie *movie){
|
||||
|
||||
}
|
||||
|
||||
static int movie_set_pts(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
static int movie_set_pts(struct ctx_movie *movie, const struct timespec *ts1){
|
||||
|
||||
int64_t pts_interval;
|
||||
|
||||
@@ -531,10 +531,10 @@ static int movie_set_pts(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
movie->last_pts++;
|
||||
movie->picture->pts = movie->last_pts;
|
||||
} else {
|
||||
pts_interval = ((1000000L * (tv1->tv_sec - movie->start_time.tv_sec)) + tv1->tv_usec - movie->start_time.tv_usec);
|
||||
pts_interval = ((1000000L * (ts1->tv_sec - movie->start_time.tv_sec)) + (ts1->tv_nsec/1000) - (movie->start_time.tv_nsec/1000));
|
||||
if (pts_interval < 0){
|
||||
/* This can occur when we have pre-capture frames. Reset start time of video. */
|
||||
movie_reset_movie_start_time(movie, tv1);
|
||||
movie_reset_movie_start_time(movie, ts1);
|
||||
pts_interval = 0;
|
||||
}
|
||||
if (movie->last_pts < 0) {
|
||||
@@ -562,7 +562,7 @@ static int movie_set_pts(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int movie_set_pktpts(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
static int movie_set_pktpts(struct ctx_movie *movie, const struct timespec *ts1){
|
||||
|
||||
int64_t pts_interval;
|
||||
|
||||
@@ -570,10 +570,10 @@ static int movie_set_pktpts(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
movie->last_pts++;
|
||||
movie->pkt.pts = movie->last_pts;
|
||||
} else {
|
||||
pts_interval = ((1000000L * (tv1->tv_sec - movie->start_time.tv_sec)) + tv1->tv_usec - movie->start_time.tv_usec);
|
||||
pts_interval = ((1000000L * (ts1->tv_sec - movie->start_time.tv_sec)) + (ts1->tv_nsec/1000) - (movie->start_time.tv_nsec/1000));
|
||||
if (pts_interval < 0){
|
||||
/* This can occur when we have pre-capture frames. Reset start time of video. */
|
||||
movie_reset_movie_start_time(movie, tv1);
|
||||
movie_reset_movie_start_time(movie, ts1);
|
||||
pts_interval = 0;
|
||||
}
|
||||
movie->pkt.pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},movie->video_st->time_base) + movie->base_pts;
|
||||
@@ -1098,14 +1098,14 @@ static int movie_flush_codec(struct ctx_movie *movie){
|
||||
|
||||
}
|
||||
|
||||
static int movie_put_frame(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
static int movie_put_frame(struct ctx_movie *movie, const struct timespec *ts1){
|
||||
int retcd;
|
||||
|
||||
av_init_packet(&movie->pkt);
|
||||
movie->pkt.data = NULL;
|
||||
movie->pkt.size = 0;
|
||||
|
||||
retcd = movie_set_pts(movie, tv1);
|
||||
retcd = movie_set_pts(movie, ts1);
|
||||
if (retcd < 0) {
|
||||
//If there is an error, it has already been reported.
|
||||
my_packet_unref(movie->pkt);
|
||||
@@ -1168,7 +1168,7 @@ static void movie_passthru_write(struct ctx_movie *movie, int indx){
|
||||
return;
|
||||
}
|
||||
|
||||
retcd = movie_set_pktpts(movie, &movie->netcam_data->pktarray[indx].timestamp_tv);
|
||||
retcd = movie_set_pktpts(movie, &movie->netcam_data->pktarray[indx].timestamp_ts);
|
||||
if (retcd < 0) {
|
||||
my_packet_unref(movie->pkt);
|
||||
return;
|
||||
@@ -1548,7 +1548,7 @@ void movie_close(struct ctx_movie *movie){
|
||||
}
|
||||
|
||||
|
||||
int movie_put_image(struct ctx_movie *movie, struct image_data *img_data, const struct timeval *tv1){
|
||||
int movie_put_image(struct ctx_movie *movie, struct image_data *img_data, const struct timespec *ts1){
|
||||
|
||||
int retcd = 0;
|
||||
int cnt = 0;
|
||||
@@ -1582,9 +1582,9 @@ int movie_put_image(struct ctx_movie *movie, struct image_data *img_data, const
|
||||
* never want a frame buffered so we keep sending back the
|
||||
* the same pic until it flushes or fails in a different way
|
||||
*/
|
||||
retcd = movie_put_frame(movie, tv1);
|
||||
retcd = movie_put_frame(movie, ts1);
|
||||
while ((retcd == -2) && (movie->tlapse != TIMELAPSE_NONE)) {
|
||||
retcd = movie_put_frame(movie, tv1);
|
||||
retcd = movie_put_frame(movie, ts1);
|
||||
cnt++;
|
||||
if (cnt > 50){
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
|
||||
@@ -1603,13 +1603,13 @@ int movie_put_image(struct ctx_movie *movie, struct image_data *img_data, const
|
||||
|
||||
}
|
||||
|
||||
void movie_reset_movie_start_time(struct ctx_movie *movie, const struct timeval *tv1){
|
||||
void movie_reset_movie_start_time(struct ctx_movie *movie, const struct timespec *ts1){
|
||||
int64_t one_frame_interval = av_rescale_q(1,(AVRational){1, movie->fps},movie->video_st->time_base);
|
||||
if (one_frame_interval <= 0)
|
||||
one_frame_interval = 1;
|
||||
movie->base_pts = movie->last_pts + one_frame_interval;
|
||||
|
||||
movie->start_time.tv_sec = tv1->tv_sec;
|
||||
movie->start_time.tv_usec = tv1->tv_usec;
|
||||
movie->start_time.tv_sec = ts1->tv_sec;
|
||||
movie->start_time.tv_nsec = ts1->tv_nsec;
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ struct ctx_movie {
|
||||
int64_t base_pts;
|
||||
int test_mode;
|
||||
int gop_cnt;
|
||||
struct timeval start_time;
|
||||
struct timespec start_time;
|
||||
int high_resolution;
|
||||
int motion_images;
|
||||
int passthrough;
|
||||
@@ -84,8 +84,8 @@ void movie_global_deinit(void);
|
||||
void movie_avcodec_log(void *, int, const char *, va_list);
|
||||
|
||||
int movie_open(struct ctx_movie *ffmpeg);
|
||||
int movie_put_image(struct ctx_movie *ffmpeg, struct image_data *img_data, const struct timeval *tv1);
|
||||
int movie_put_image(struct ctx_movie *ffmpeg, struct image_data *img_data, const struct timespec *tv1);
|
||||
void movie_close(struct ctx_movie *ffmpeg);
|
||||
void movie_reset_movie_start_time(struct ctx_movie *ffmpeg, const struct timeval *tv1);
|
||||
void movie_reset_movie_start_time(struct ctx_movie *ffmpeg, const struct timespec *tv1);
|
||||
|
||||
#endif /* _INCLUDE_MOVIE_H_ */
|
||||
|
||||
57
src/netcam.c
57
src/netcam.c
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <regex.h>
|
||||
#include <time.h>
|
||||
#include "rotate.h" /* already includes motion.h */
|
||||
#include "netcam.h"
|
||||
#include "video_v4l2.h" /* Needed to validate palette for v4l2 via netcam */
|
||||
@@ -414,8 +415,8 @@ static void netcam_pktarray_add(struct ctx_netcam *netcam){
|
||||
netcam->pktarray[indx_next].iskey = FALSE;
|
||||
}
|
||||
netcam->pktarray[indx_next].iswritten = FALSE;
|
||||
netcam->pktarray[indx_next].timestamp_tv.tv_sec = netcam->img_recv->image_time.tv_sec;
|
||||
netcam->pktarray[indx_next].timestamp_tv.tv_usec = netcam->img_recv->image_time.tv_usec;
|
||||
netcam->pktarray[indx_next].timestamp_ts.tv_sec = netcam->img_recv->image_time.tv_sec;
|
||||
netcam->pktarray[indx_next].timestamp_ts.tv_nsec = netcam->img_recv->image_time.tv_nsec;
|
||||
netcam->pktarray_index = indx_next;
|
||||
pthread_mutex_unlock(&netcam->mutex_pktarray);
|
||||
|
||||
@@ -662,9 +663,7 @@ static int netcam_interrupt(void *ctx){
|
||||
if (netcam->status == NETCAM_CONNECTED) {
|
||||
return FALSE;
|
||||
} else if (netcam->status == NETCAM_READINGIMAGE) {
|
||||
if (gettimeofday(&netcam->interruptcurrenttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptcurrenttime);
|
||||
if ((netcam->interruptcurrenttime.tv_sec - netcam->interruptstarttime.tv_sec ) > netcam->interruptduration){
|
||||
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
|
||||
,_("%s: Camera reading (%s) timed out")
|
||||
@@ -680,9 +679,7 @@ static int netcam_interrupt(void *ctx){
|
||||
* netcam_connect function will use the same start time. Otherwise we
|
||||
* would need to reset the time before each call to a ffmpeg function.
|
||||
*/
|
||||
if (gettimeofday(&netcam->interruptcurrenttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptcurrenttime);
|
||||
if ((netcam->interruptcurrenttime.tv_sec - netcam->interruptstarttime.tv_sec ) > netcam->interruptduration){
|
||||
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
|
||||
,_("%s: Camera (%s) timed out")
|
||||
@@ -797,9 +794,7 @@ static int netcam_read_image(struct ctx_netcam *netcam){
|
||||
netcam->packet_recv.size = 0;
|
||||
|
||||
netcam->interrupted=FALSE;
|
||||
if (gettimeofday(&netcam->interruptstarttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptstarttime);
|
||||
netcam->interruptduration = 10;
|
||||
|
||||
netcam->status = NETCAM_READINGIMAGE;
|
||||
@@ -843,10 +838,7 @@ static int netcam_read_image(struct ctx_netcam *netcam){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (gettimeofday(&netcam->img_recv->image_time, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->img_recv->image_time);
|
||||
/* Skip status change on our first image to keep the "next" function waiting
|
||||
* until the handler thread gets going
|
||||
*/
|
||||
@@ -1197,12 +1189,9 @@ static void netcam_set_parms (struct ctx_cam *cam, struct ctx_netcam *netcam ) {
|
||||
|
||||
snprintf(netcam->threadname, 15, "%s",_("Unknown"));
|
||||
|
||||
if (gettimeofday(&netcam->interruptstarttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
if (gettimeofday(&netcam->interruptcurrenttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptstarttime);
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptcurrenttime);
|
||||
|
||||
/* If this is the norm and we have a highres, then disable passthru on the norm */
|
||||
if ((!netcam->high_resolution) &&
|
||||
(cam->conf.netcam_highres)) {
|
||||
@@ -1213,12 +1202,8 @@ static void netcam_set_parms (struct ctx_cam *cam, struct ctx_netcam *netcam ) {
|
||||
netcam->interruptduration = 5;
|
||||
netcam->interrupted = FALSE;
|
||||
|
||||
if (gettimeofday(&netcam->frame_curr_tm, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
if (gettimeofday(&netcam->frame_prev_tm, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->frame_curr_tm);
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->frame_prev_tm);
|
||||
|
||||
netcam_set_path(cam, netcam);
|
||||
|
||||
@@ -1331,9 +1316,7 @@ static int netcam_open_context(struct ctx_netcam *netcam){
|
||||
netcam->format_context->interrupt_callback.opaque = netcam;
|
||||
netcam->interrupted = FALSE;
|
||||
|
||||
if (gettimeofday(&netcam->interruptstarttime, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->interruptstarttime);
|
||||
|
||||
netcam->interruptduration = 20;
|
||||
|
||||
@@ -1544,13 +1527,11 @@ static void netcam_handler_wait(struct ctx_netcam *netcam){
|
||||
usec_maxrate = (1000000L / (framerate + 3));
|
||||
}
|
||||
|
||||
if (gettimeofday(&netcam->frame_curr_tm, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->frame_curr_tm);
|
||||
|
||||
usec_delay = usec_maxrate -
|
||||
((netcam->frame_curr_tm.tv_sec - netcam->frame_prev_tm.tv_sec) * 1000000L) -
|
||||
(netcam->frame_curr_tm.tv_usec - netcam->frame_prev_tm.tv_usec);
|
||||
((netcam->frame_curr_tm.tv_nsec - netcam->frame_prev_tm.tv_nsec)/1000);
|
||||
if ((usec_delay > 0) && (usec_delay < 1000000L)){
|
||||
SLEEP(0, usec_delay * 1000);
|
||||
}
|
||||
@@ -1609,15 +1590,11 @@ static void *netcam_handler(void *arg){
|
||||
|
||||
while (!netcam->finish) {
|
||||
if (!netcam->format_context) { /* We must have disconnected. Try to reconnect */
|
||||
if (gettimeofday(&netcam->frame_prev_tm, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->frame_prev_tm);
|
||||
netcam_handler_reconnect(netcam);
|
||||
continue;
|
||||
} else { /* We think we are connected...*/
|
||||
if (gettimeofday(&netcam->frame_prev_tm, NULL) < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, SHOW_ERRNO, "gettimeofday");
|
||||
}
|
||||
clock_gettime(CLOCK_REALTIME, &netcam->frame_prev_tm);
|
||||
if (netcam_read_image(netcam) < 0) {
|
||||
if (!netcam->finish) { /* Nope. We are not or got bad image. Reconnect*/
|
||||
netcam_handler_reconnect(netcam);
|
||||
|
||||
14
src/netcam.h
14
src/netcam.h
@@ -42,7 +42,7 @@ typedef struct netcam_image_buff {
|
||||
int content_length;
|
||||
size_t size; /* total allocated size */
|
||||
size_t used; /* bytes already used */
|
||||
struct timeval image_time; /* time this image was received */
|
||||
struct timespec image_time; /* time this image was received */
|
||||
} netcam_buff;
|
||||
typedef netcam_buff *netcam_buff_ptr;
|
||||
|
||||
@@ -58,7 +58,7 @@ struct packet_item{
|
||||
int64_t idnbr;
|
||||
int iskey;
|
||||
int iswritten;
|
||||
struct timeval timestamp_tv;
|
||||
struct timespec timestamp_ts;
|
||||
};
|
||||
|
||||
struct ctx_netcam {
|
||||
@@ -79,8 +79,8 @@ struct ctx_netcam {
|
||||
int video_stream_index; /* Stream index associated with video from camera */
|
||||
|
||||
enum NETCAM_STATUS status; /* Status of whether the camera is connecting, closed, etc*/
|
||||
struct timeval interruptstarttime; /* The time set before calling the av functions */
|
||||
struct timeval interruptcurrenttime; /* Time during the interrupt to determine duration since start*/
|
||||
struct timespec interruptstarttime; /* The time set before calling the av functions */
|
||||
struct timespec interruptcurrenttime; /* Time during the interrupt to determine duration since start*/
|
||||
int interruptduration; /* Seconds permitted before triggering a interrupt */
|
||||
|
||||
netcam_buff_ptr img_recv; /* The image buffer that is currently being processed */
|
||||
@@ -105,9 +105,9 @@ struct ctx_netcam {
|
||||
int reconnect_count; /* Count of the times reconnection is tried*/
|
||||
int src_fps; /* The fps provided from source*/
|
||||
|
||||
struct timeval frame_prev_tm; /* The time set before calling the av functions */
|
||||
struct timeval frame_curr_tm; /* Time during the interrupt to determine duration since start*/
|
||||
struct config *conf; /* Pointer to conf parms of parent cam*/
|
||||
struct timespec frame_prev_tm; /* The time set before calling the av functions */
|
||||
struct timespec frame_curr_tm; /* Time during the interrupt to determine duration since start*/
|
||||
struct config *conf; /* Pointer to conf parms of parent cam*/
|
||||
|
||||
char threadname[16]; /* The thread name*/
|
||||
int threadnbr; /* The thread number */
|
||||
|
||||
@@ -162,7 +162,7 @@ static void put_subjectarea(struct tiff_writing *into, const struct coord *box)
|
||||
*/
|
||||
unsigned prepare_exif(unsigned char **exif,
|
||||
const struct ctx_cam *cam,
|
||||
const struct timeval *tv_in1,
|
||||
const struct timespec *ts_in1,
|
||||
const struct coord *box)
|
||||
{
|
||||
/* description, datetime, and subtime are the values that are actually
|
||||
@@ -172,15 +172,15 @@ unsigned prepare_exif(unsigned char **exif,
|
||||
char datetime_buf[22];
|
||||
char tmpbuf[45];
|
||||
struct tm timestamp_tm;
|
||||
struct timeval tv1;
|
||||
struct timespec ts1;
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
if (tv_in1 != NULL) {
|
||||
tv1.tv_sec = tv_in1->tv_sec;
|
||||
tv1.tv_usec = tv_in1->tv_usec;
|
||||
clock_gettime(CLOCK_REALTIME, &ts1);
|
||||
if (ts_in1 != NULL) {
|
||||
ts1.tv_sec = ts_in1->tv_sec;
|
||||
ts1.tv_nsec = ts_in1->tv_nsec;
|
||||
}
|
||||
|
||||
localtime_r(&tv1.tv_sec, ×tamp_tm);
|
||||
localtime_r(&ts1.tv_sec, ×tamp_tm);
|
||||
/* Exif requires this exact format */
|
||||
/* The compiler is twitchy on truncating formats and the exif is twitchy
|
||||
* on the length of the whole string. So we do it in two steps of printing
|
||||
@@ -203,7 +203,7 @@ unsigned prepare_exif(unsigned char **exif,
|
||||
|
||||
if (cam->conf.picture_exif) {
|
||||
description = malloc(PATH_MAX);
|
||||
mystrftime(cam, description, PATH_MAX-1, cam->conf.picture_exif, &tv1, NULL, 0);
|
||||
mystrftime(cam, description, PATH_MAX-1, cam->conf.picture_exif, &ts1, NULL, 0);
|
||||
} else {
|
||||
description = NULL;
|
||||
}
|
||||
@@ -353,11 +353,11 @@ unsigned prepare_exif(unsigned char **exif,
|
||||
*/
|
||||
static void put_webp_exif(WebPMux* webp_mux,
|
||||
const struct ctx_cam *cam,
|
||||
const struct timeval *tv1,
|
||||
const struct timespec *ts1,
|
||||
const struct coord *box)
|
||||
{
|
||||
unsigned char *exif = NULL;
|
||||
unsigned exif_len = prepare_exif(&exif, cam, tv1, box);
|
||||
unsigned exif_len = prepare_exif(&exif, cam, ts1, box);
|
||||
|
||||
if(exif_len > 0) {
|
||||
WebPData webp_exif;
|
||||
@@ -395,7 +395,7 @@ static void put_webp_exif(WebPMux* webp_mux,
|
||||
*/
|
||||
static void put_webp_yuv420p_file(FILE *fp,
|
||||
unsigned char *image, int width, int height,
|
||||
int quality, struct ctx_cam *cam, struct timeval *tv1, struct coord *box)
|
||||
int quality, struct ctx_cam *cam, struct timespec *ts1, struct coord *box)
|
||||
{
|
||||
/* Create a config present and check for compatible library version */
|
||||
WebPConfig webp_config;
|
||||
@@ -441,7 +441,7 @@ static void put_webp_yuv420p_file(FILE *fp,
|
||||
|
||||
/* Create a mux from the prepared image data */
|
||||
WebPMux* webp_mux = WebPMuxCreate(&webp_bitstream, 1);
|
||||
put_webp_exif(webp_mux, cam, tv1, box);
|
||||
put_webp_exif(webp_mux, cam, ts1, box);
|
||||
|
||||
/* Add Exif data to the webp image data */
|
||||
WebPData webp_output;
|
||||
@@ -489,13 +489,13 @@ static void put_webp_yuv420p_file(FILE *fp,
|
||||
static void put_jpeg_yuv420p_file(FILE *fp,
|
||||
unsigned char *image, int width, int height,
|
||||
int quality,
|
||||
struct ctx_cam *cam, struct timeval *tv1, struct coord *box)
|
||||
struct ctx_cam *cam, struct timespec *ts1, struct coord *box)
|
||||
{
|
||||
int sz = 0;
|
||||
int image_size = cam->imgs.size_norm;
|
||||
unsigned char *buf = mymalloc(image_size);
|
||||
|
||||
sz = jpgutl_put_yuv420p(buf, image_size, image, width, height, quality, cam ,tv1, box);
|
||||
sz = jpgutl_put_yuv420p(buf, image_size, image, width, height, quality, cam ,ts1, box);
|
||||
fwrite(buf, sz, 1, fp);
|
||||
|
||||
free(buf);
|
||||
@@ -518,14 +518,14 @@ static void put_jpeg_yuv420p_file(FILE *fp,
|
||||
* Returns nothing
|
||||
*/
|
||||
static void put_jpeg_grey_file(FILE *picture, unsigned char *image, int width, int height,
|
||||
int quality, struct ctx_cam *cam, struct timeval *tv1, struct coord *box)
|
||||
int quality, struct ctx_cam *cam, struct timespec *ts1, struct coord *box)
|
||||
|
||||
{
|
||||
int sz = 0;
|
||||
int image_size = cam->imgs.size_norm;
|
||||
unsigned char *buf = mymalloc(image_size);
|
||||
|
||||
sz = jpgutl_put_grey(buf, image_size, image, width, height, quality, cam ,tv1, box);
|
||||
sz = jpgutl_put_grey(buf, image_size, image, width, height, quality, cam ,ts1, box);
|
||||
fwrite(buf, sz, 1, picture);
|
||||
|
||||
free(buf);
|
||||
@@ -754,20 +754,15 @@ void overlay_largest_label(struct ctx_cam *cam, unsigned char *out)
|
||||
int put_picture_memory(struct ctx_cam *cam, unsigned char* dest_image, int image_size, unsigned char *image,
|
||||
int quality, int width, int height)
|
||||
{
|
||||
struct timeval tv1;
|
||||
|
||||
/*
|
||||
* Reset the time for the current image since it is not reliable
|
||||
* for putting images to memory.
|
||||
*/
|
||||
gettimeofday(&tv1, NULL);
|
||||
struct timespec ts1;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts1);
|
||||
if (!cam->conf.stream_grey){
|
||||
return jpgutl_put_yuv420p(dest_image, image_size, image,
|
||||
width, height, quality, cam ,&tv1,NULL);
|
||||
width, height, quality, cam ,&ts1, NULL);
|
||||
} else {
|
||||
return jpgutl_put_grey(dest_image, image_size, image,
|
||||
width, height, quality, cam,&tv1,NULL);
|
||||
width, height, quality, cam,&ts1, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -795,12 +790,12 @@ static void put_picture_fd(struct ctx_cam *cam, FILE *picture, unsigned char *im
|
||||
if (dummy == 1){
|
||||
#ifdef HAVE_WEBP
|
||||
if (cam->imgs.picture_type == IMAGE_TYPE_WEBP)
|
||||
put_webp_yuv420p_file(picture, image, width, height, quality, cam, &(cam->current_image->timestamp_tv), &(cam->current_image->location));
|
||||
put_webp_yuv420p_file(picture, image, width, height, quality, cam, &(cam->current_image->imgts), &(cam->current_image->location));
|
||||
#endif /* HAVE_WEBP */
|
||||
if (cam->imgs.picture_type == IMAGE_TYPE_JPEG)
|
||||
put_jpeg_yuv420p_file(picture, image, width, height, quality, cam, &(cam->current_image->timestamp_tv), &(cam->current_image->location));
|
||||
put_jpeg_yuv420p_file(picture, image, width, height, quality, cam, &(cam->current_image->imgts), &(cam->current_image->location));
|
||||
} else {
|
||||
put_jpeg_grey_file(picture, image, width, height, quality, cam, &(cam->current_image->timestamp_tv), &(cam->current_image->location));
|
||||
put_jpeg_grey_file(picture, image, width, height, quality, cam, &(cam->current_image->imgts), &(cam->current_image->location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
void preview_save(struct ctx_cam *cam);
|
||||
void pic_scale_img(int width_src, int height_src, unsigned char *img_src, unsigned char *img_dst);
|
||||
|
||||
unsigned prepare_exif(unsigned char **, const struct ctx_cam *cam, const struct timeval *, const struct coord *);
|
||||
unsigned prepare_exif(unsigned char **, const struct ctx_cam *cam, const struct timespec *, const struct coord *);
|
||||
|
||||
#endif /* _INCLUDE_PICTURE_H_ */
|
||||
|
||||
@@ -1312,7 +1312,7 @@ static unsigned int generic_move(struct ctx_cam *cam, enum track_action action,
|
||||
cam->track_posx += cent->x;
|
||||
cam->track_posy += cent->y;
|
||||
|
||||
mystrftime(cam, fmtcmd, sizeof(fmtcmd), cam->track.generic_move, &cam->current_image->timestamp_tv, NULL, 0);
|
||||
mystrftime(cam, fmtcmd, sizeof(fmtcmd), cam->track.generic_move, &cam->current_image->imgts, NULL, 0);
|
||||
|
||||
if (!fork()) {
|
||||
int i;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
size_t resp_used; /* The amount of the response page used */
|
||||
uint64_t stream_pos; /* Stream position of sent image */
|
||||
int stream_fps; /* Stream rate per second */
|
||||
struct timeval time_last; /* Keep track of processing time for stream thread*/
|
||||
struct timespec time_last; /* Keep track of processing time for stream thread*/
|
||||
int mhd_first; /* Boolean for whether it is the first connection*/
|
||||
|
||||
struct MHD_Connection *connection; /* The MHD connection value from the client */
|
||||
|
||||
@@ -35,15 +35,15 @@ static void webu_stream_mjpeg_delay(struct webui_ctx *webui) {
|
||||
*/
|
||||
|
||||
long stream_rate;
|
||||
struct timeval time_curr;
|
||||
struct timespec time_curr;
|
||||
long stream_delay;
|
||||
|
||||
gettimeofday(&time_curr, NULL);
|
||||
clock_gettime(CLOCK_REALTIME, &time_curr);
|
||||
|
||||
/* The stream rate MUST be less than 1000000000 otherwise undefined behaviour
|
||||
* will occur with the SLEEP function.
|
||||
*/
|
||||
stream_delay = ((time_curr.tv_usec - webui->time_last.tv_usec)*1000) +
|
||||
stream_delay = ((time_curr.tv_nsec - webui->time_last.tv_nsec)) +
|
||||
((time_curr.tv_sec - webui->time_last.tv_sec)*1000000000);
|
||||
if (stream_delay < 0) stream_delay = 0;
|
||||
if (stream_delay > 1000000000 ) stream_delay = 1000000000;
|
||||
@@ -56,7 +56,7 @@ static void webu_stream_mjpeg_delay(struct webui_ctx *webui) {
|
||||
SLEEP(1,0);
|
||||
}
|
||||
}
|
||||
gettimeofday(&webui->time_last, NULL);
|
||||
clock_gettime(CLOCK_REALTIME, &webui->time_last);
|
||||
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ int webu_stream_mjpeg(struct webui_ctx *webui) {
|
||||
|
||||
webu_stream_mjpeg_checkbuffers(webui);
|
||||
|
||||
gettimeofday(&webui->time_last, NULL);
|
||||
clock_gettime(CLOCK_REALTIME, &webui->time_last);
|
||||
|
||||
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024
|
||||
,&webu_stream_mjpeg_response, webui, NULL);
|
||||
|
||||
Reference in New Issue
Block a user