diff -Naur motion-orig/conf.c motion/conf.c --- motion-orig/conf.c 2006-01-07 05:10:02.000000000 +0100 +++ motion/conf.c 2006-01-12 09:47:16.000000000 +0100 @@ -77,6 +77,7 @@ ffmpeg_cap_motion: 0, ffmpeg_bps: DEF_FFMPEG_BPS, ffmpeg_vbr: DEF_FFMPEG_VBR, + ffmpeg_deinterlace: 0, ffmpeg_video_codec: DEF_FFMPEG_CODEC, webcam_port: 0, webcam_quality: 50, diff -Naur motion-orig/webcam.c motion/webcam.c --- motion-orig/webcam.c 2006-01-07 05:10:02.000000000 +0100 +++ motion/webcam.c 2006-01-12 09:45:46.000000000 +0100 @@ -93,6 +93,12 @@ return -1; } +/* Put webcam_tmpbuffer to reuse onto list of unused webcam_tmpbuffers */ +static void webcam_tmpbuffer_unuse(struct webcam *list, struct webcam_buffer *tmpbuffer) +{ + tmpbuffer->next=list->tmpbuffer; + list->tmpbuffer=tmpbuffer; +} /* Webcam flush sends any outstanding data to all connected clients. * It continuously goes through the client list until no data is able @@ -149,11 +155,9 @@ */ if ( (client->filepos >= client->tmpbuffer->size) || (written < 0 && errno!=EAGAIN)) { - /* If no other clients need this buffer, free it */ - if (--client->tmpbuffer->ref <= 0) { - free(client->tmpbuffer->ptr); - free(client->tmpbuffer); - } + /* If no other clients need this buffer, unuse it */ + if (--client->tmpbuffer->ref <= 0) + webcam_tmpbuffer_unuse(list, client->tmpbuffer); /* Mark this client's buffer as empty */ client->tmpbuffer=NULL; @@ -196,18 +200,29 @@ } /* Routine to create a new "tmpbuffer", which is a common - * object used by all clients connected to a single camera + * object used by all clients connected to a single camera. + * Get an unused webcam_tmpbuffer or create a new one */ -static struct webcam_buffer *webcam_tmpbuffer(int size) +static struct webcam_buffer *webcam_tmpbuffer(struct webcam *list, int size) { - struct webcam_buffer *tmpbuffer=mymalloc(sizeof(struct webcam_buffer)); - tmpbuffer->ref=0; - tmpbuffer->ptr=mymalloc(size); - + struct webcam_buffer *tmpbuffer; + + tmpbuffer=list->tmpbuffer; + if (tmpbuffer) { + list->tmpbuffer=tmpbuffer->next; + if (size > tmpbuffer->buffersize) { + tmpbuffer->ptr=myrealloc(tmpbuffer->ptr,size,"webcam_tmpbuffer"); + tmpbuffer->buffersize=size; + } + } else { + tmpbuffer=mymalloc(sizeof(struct webcam_buffer)); + tmpbuffer->ref=0; + tmpbuffer->ptr=mymalloc(size); + tmpbuffer->buffersize=size; + } return tmpbuffer; } - static void webcam_add_client(struct webcam *list, int sc) { struct webcam *new = mymalloc(sizeof(struct webcam)); @@ -223,11 +238,12 @@ memset(new, 0, sizeof(struct webcam)); new->socket=sc; - if ((new->tmpbuffer = webcam_tmpbuffer(sizeof(header))) == NULL) { + if ((new->tmpbuffer = webcam_tmpbuffer(list, sizeof(header))) == NULL) { motion_log(LOG_ERR, 1, "Error creating tmpbuffer in webcam_add_client"); } else { memcpy(new->tmpbuffer->ptr, header, sizeof(header)-1); new->tmpbuffer->size = sizeof(header)-1; + new->tmpbuffer->ref++; } new->prev=list; @@ -259,10 +275,8 @@ } } - if (tmpbuffer->ref<=0) { - free(tmpbuffer->ptr); - free(tmpbuffer); - } + if (tmpbuffer->ref<=0) + webcam_tmpbuffer_unuse(list, tmpbuffer); } @@ -292,6 +306,7 @@ cnt->webcam.socket=http_bindsock(cnt->conf.webcam_port, cnt->conf.webcam_localhost); cnt->webcam.next=NULL; cnt->webcam.prev=NULL; + cnt->webcam.tmpbuffer=NULL; return cnt->webcam.socket; } @@ -302,6 +317,7 @@ { struct webcam *list; struct webcam *next = cnt->webcam.next; + struct webcam_buffer *tmpbuffer; if (cnt->conf.setup_mode) motion_log(-1, 0, "Closing webcam listen socket"); @@ -323,6 +339,13 @@ close(list->socket); free(list); } + tmpbuffer=cnt->webcam.tmpbuffer; + while (tmpbuffer) { + tmpbuffer=cnt->webcam.tmpbuffer->next; + + free(cnt->webcam.tmpbuffer->ptr); + free(cnt->webcam.tmpbuffer); + } } /* webcam_put is the starting point of the webcam loop. It is called from @@ -379,12 +402,12 @@ /* Check if any clients have available buffers */ if (webcam_check_write(&cnt->webcam)) { - /* yes - create a new tmpbuffer for current image. + /* yes - get a tmpbuffer for current image. * Note that this should create a buffer which is *much* larger * than necessary, but it is difficult to estimate the * minimum size actually required. */ - tmpbuffer = webcam_tmpbuffer(cnt->imgs.size); + tmpbuffer = webcam_tmpbuffer(&cnt->webcam, cnt->imgs.size); /* check if allocation went ok */ if (tmpbuffer) { diff -Naur motion-orig/webcam.h motion/webcam.h --- motion-orig/webcam.h 2006-01-07 05:10:02.000000000 +0100 +++ motion/webcam.h 2006-01-12 09:48:14.000000000 +0100 @@ -25,6 +25,8 @@ unsigned char *ptr; int ref; long size; + long buffersize; + struct webcam_buffer *next; }; struct webcam {