📄 event.c
字号:
if (cnt->conf.mpegpath) mpegpath = cnt->conf.mpegpath; else mpegpath = DEF_MPEGPATH; mystrftime(cnt, stamp, sizeof(stamp), mpegpath, currenttime_tm, NULL, 0); /* motion mpegs get the same name as normal mpegs plus an appended 'm' */ /* PATH_MAX - 4 to allow for .mpg to be appended without overflow */ snprintf(cnt->motionfilename, PATH_MAX - 4, "%s/%sm", cnt->conf.filepath, stamp); snprintf(cnt->newfilename, PATH_MAX - 4, "%s/%s", cnt->conf.filepath, stamp); if (cnt->conf.ffmpeg_cap_new) { if (cnt->imgs.type==VIDEO_PALETTE_GREY) { convbuf=mymalloc((width*height)/2); y=img; u=convbuf; v=convbuf+(width*height)/4; grey2yuv420p(u, v, width, height); } else { convbuf=NULL; y=img; u=img+width*height; v=u+(width*height)/4; } if (cnt->conf.low_cpu) fps=cnt->conf.frame_limit; else fps=cnt->lastrate; if (fps>30) fps=30; if (fps<2) fps=2; if ( (cnt->ffmpeg_new = ffmpeg_open((char *)cnt->conf.ffmpeg_video_codec, cnt->newfilename, y, u, v, cnt->imgs.width, cnt->imgs.height, fps, cnt->conf.ffmpeg_bps, cnt->conf.ffmpeg_vbr)) == NULL) { motion_log(LOG_ERR, 1, "ffopen_open error creating (new) file [%s]",cnt->newfilename); cnt->finish=1; return; } ((struct ffmpeg *)cnt->ffmpeg_new)->udata=convbuf; event(cnt, EVENT_FILECREATE, NULL, cnt->newfilename, (void *)FTYPE_MPEG, NULL); } if (cnt->conf.ffmpeg_cap_motion) { if (cnt->imgs.type==VIDEO_PALETTE_GREY) { convbuf=mymalloc((width*height)/2); y=cnt->imgs.out; u=convbuf; v=convbuf+(width*height)/4; grey2yuv420p(u, v, width, height); } else { y=cnt->imgs.out; u=cnt->imgs.out+width*height; v=u+(width*height)/4; convbuf=NULL; } if (cnt->conf.low_cpu) fps=cnt->conf.frame_limit; else fps=cnt->lastrate; if (fps>30) fps=30; if (fps<2) fps=2; if ( (cnt->ffmpeg_motion = ffmpeg_open((char *)cnt->conf.ffmpeg_video_codec, cnt->motionfilename, y, u, v, cnt->imgs.width, cnt->imgs.height, fps, cnt->conf.ffmpeg_bps, cnt->conf.ffmpeg_vbr)) == NULL){ motion_log(LOG_ERR, 1, "ffopen_open error creating (motion) file [%s]", cnt->motionfilename); cnt->finish=1; return; } cnt->ffmpeg_motion->udata=convbuf; event(cnt, EVENT_FILECREATE, NULL, cnt->motionfilename, (void *)FTYPE_MPEG_MOTION, NULL); }}static void event_ffmpeg_timelapse(struct context *cnt, int type ATTRIBUTE_UNUSED, unsigned char *img, char *dummy1 ATTRIBUTE_UNUSED, void *dummy2 ATTRIBUTE_UNUSED, struct tm *currenttime_tm){ int width = cnt->imgs.width; int height = cnt->imgs.height; unsigned char *convbuf, *y, *u, *v; if (!cnt->ffmpeg_timelapse) { char tmp[PATH_MAX]; const char *timepath; /* conf.timepath would normally be defined but if someone deleted it by control interface it is better to revert to the default than fail */ if (cnt->conf.timepath) timepath = cnt->conf.timepath; else timepath = DEF_TIMEPATH; mystrftime(cnt, tmp, sizeof(tmp), timepath, currenttime_tm, NULL, 0); /* PATH_MAX - 4 to allow for .mpg to be appended without overflow */ snprintf(cnt->timelapsefilename, PATH_MAX - 4, "%s/%s", cnt->conf.filepath, tmp); if (cnt->imgs.type == VIDEO_PALETTE_GREY) { convbuf = mymalloc((width*height)/2); y = img; u = convbuf; v = convbuf+(width*height)/4; grey2yuv420p(u, v, width, height); } else { convbuf = NULL; y = img; u = img+width*height; v = u+(width*height)/4; } if ( (cnt->ffmpeg_timelapse = ffmpeg_open((char *)TIMELAPSE_CODEC, cnt->timelapsefilename, y, u, v, cnt->imgs.width, cnt->imgs.height, 24, cnt->conf.ffmpeg_bps, cnt->conf.ffmpeg_vbr)) == NULL) { motion_log(LOG_ERR, 1, "ffopen_open error creating (timelapse) file [%s]", cnt->timelapsefilename); cnt->finish=1; return; } cnt->ffmpeg_timelapse->udata = convbuf; event(cnt, EVENT_FILECREATE, NULL, cnt->timelapsefilename, (void *)FTYPE_MPEG_TIMELAPSE, NULL); } y = img; if (cnt->imgs.type == VIDEO_PALETTE_GREY) u = cnt->ffmpeg_timelapse->udata; else u = img+width*height; v = u+(width*height)/4; ffmpeg_put_other_image(cnt->ffmpeg_timelapse, y, u, v); }static void event_ffmpeg_put(struct context *cnt, int type ATTRIBUTE_UNUSED, unsigned char *img, char *dummy1 ATTRIBUTE_UNUSED, void *dummy2 ATTRIBUTE_UNUSED, struct tm *tm ATTRIBUTE_UNUSED){ if (cnt->ffmpeg_new) { int width=cnt->imgs.width; int height=cnt->imgs.height; unsigned char *y = img; unsigned char *u, *v; if (cnt->imgs.type == VIDEO_PALETTE_GREY) u = cnt->ffmpeg_timelapse->udata; else u = y + (width * height); v = u + (width * height) / 4; ffmpeg_put_other_image(cnt->ffmpeg_new, y, u, v); } if (cnt->ffmpeg_motion) { ffmpeg_put_image(cnt->ffmpeg_motion); }}static void event_ffmpeg_closefile(struct context *cnt, int type ATTRIBUTE_UNUSED, unsigned char *dummy1 ATTRIBUTE_UNUSED, char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED, struct tm *tm ATTRIBUTE_UNUSED){ if (cnt->ffmpeg_new) { if (cnt->ffmpeg_new->udata) free(cnt->ffmpeg_new->udata); ffmpeg_close(cnt->ffmpeg_new); cnt->ffmpeg_new=NULL; event(cnt, EVENT_FILECLOSE, NULL, cnt->newfilename, (void *)FTYPE_MPEG, NULL); } if (cnt->ffmpeg_motion) { if (cnt->ffmpeg_motion->udata) free(cnt->ffmpeg_motion->udata); ffmpeg_close(cnt->ffmpeg_motion); cnt->ffmpeg_motion=NULL; event(cnt, EVENT_FILECLOSE, NULL, cnt->motionfilename, (void *)FTYPE_MPEG_MOTION, NULL); }}static void event_ffmpeg_timelapseend(struct context *cnt, int type ATTRIBUTE_UNUSED, unsigned char *dummy1 ATTRIBUTE_UNUSED, char *dummy2 ATTRIBUTE_UNUSED, void *dummy3 ATTRIBUTE_UNUSED, struct tm *tm ATTRIBUTE_UNUSED){ if (cnt->ffmpeg_timelapse) { if (cnt->ffmpeg_timelapse->udata) free(cnt->ffmpeg_timelapse->udata); ffmpeg_close(cnt->ffmpeg_timelapse); cnt->ffmpeg_timelapse=NULL; event(cnt, EVENT_FILECLOSE, NULL, cnt->timelapsefilename, (void *)FTYPE_MPEG_TIMELAPSE, NULL); }}#endif /* HAVE_FFMPEG *//* * Starting point for all events */struct event_handlers { int type; event_handler handler;};struct event_handlers event_handlers[] = {#if defined(HAVE_MYSQL) || defined(HAVE_PGSQL) { EVENT_FILECREATE, event_sqlnewfile },#endif { EVENT_FILECREATE, on_picture_save_command }, { EVENT_FILECREATE, event_newfile }, { EVENT_MOTION, event_beep }, { EVENT_MOTION, on_motion_detected_command }, { EVENT_FIRSTMOTION, on_event_start_command }, { EVENT_ENDMOTION, on_event_end_command }, { EVENT_IMAGE_DETECTED, event_image_detect }, { EVENT_IMAGE_SNAPSHOT, event_image_snapshot },#ifndef WITHOUT_V4L#if (!defined(BSD)) { EVENT_IMAGE | EVENT_IMAGEM, event_vid_putpipe },#endif /* BSD */#endif /* WITHOUT_V4L */ { EVENT_WEBCAM, event_webcam_put },#ifdef HAVE_FFMPEG { EVENT_FIRSTMOTION, event_ffmpeg_newfile }, { EVENT_IMAGE_DETECTED, event_ffmpeg_put }, { EVENT_ENDMOTION, event_ffmpeg_closefile }, { EVENT_TIMELAPSE, event_ffmpeg_timelapse }, { EVENT_TIMELAPSEEND, event_ffmpeg_timelapseend }, { EVENT_FILECLOSE, on_movie_end_command },#endif /* HAVE_FFMPEG */ { EVENT_STOP, event_stop_webcam }, {0, NULL}};/* The event functions are defined with the following parameters: * - Type as defined in event.h (EVENT_...) * - The global context struct cnt * - image - A pointer to unsigned char as used for images * - filename - A pointer to typically a string for a file path * - eventdata - A void pointer that can be cast to anything. E.g. FTYPE_... * - tm - A tm struct that carries a full time structure * The split between unsigned images and signed filenames was introduced in 3.2.2 * as a code reading friendly solution to avoid a stream of compiler warnings in gcc 4.0. */void event(struct context *cnt, int type, unsigned char *image, char *filename, void *eventdata, struct tm *tm){ int i=-1; while (event_handlers[++i].handler) { if (type & event_handlers[i].type) event_handlers[i].handler(cnt, type, image, filename, eventdata, tm); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -