Tag: webcam
fswebcam flock & src_open Patch
8. Juni 2013 21:08

Ein Patch für fswebcam.
Es wird unter Verwendung von flock() verhindert, dass noch nicht vollständig auf Platte geschriebene Bilder auf der Webseite angezeigt werden. flock() muss ebenfalls im jeweiligen Script verwendet werden, welches die Bilddatei ausliefert (PHP, CGI etc.).
Zusätzlich wird die Webcam nur noch einmal geöffnet, sollte fswebcam im loop Modus betrieben werden.

                    December 2012 tuxwave.net
Sebastian Kricner

Implement file locking with flock() syscall.
This is to prevent delivery of broken images for live webcams.
This also needs a flock() LOCK_SH call in the script (PHP, CGI etc.) which delivers
the webcam image.

Additionally open the webcam only once when using the loop mode of fswebcam.

diff -rupN fswebcam-20110717.orig//fswebcam.c fswebcam-20110717/fswebcam.c
--- fswebcam-20110717.orig//fswebcam.c	2011-07-17 14:27:16.000000000 +0200
+++ fswebcam-20110717/fswebcam.c	2013-02-25 18:08:03.302774107 +0100
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/file.h>
 #include <sys/stat.h>
 #include "fswebcam.h"
 #include "log.h"
@@ -482,8 +483,15 @@ int fswc_output(fswebcam_config_t *confi
 	fswc_draw_overlay(config, config->overlay, im);
 	
 	/* Write to a file if a filename was given, otherwise stdout. */
-	if(strncmp(name, "-", 2)) f = fopen(filename, "wb");
-	else f = stdout;
+	if(strncmp(name, "-", 2))
+	{
+		f = fopen(filename, "wb");
+		flock(fileno(f), LOCK_EX);
+	}
+	else
+	{
+		f = stdout;
+	}
 	
 	if(!f)
 	{
@@ -506,7 +514,12 @@ int fswc_output(fswebcam_config_t *confi
 		break;
 	}
 	
-	if(f != stdout) fclose(f);
+	if(f != stdout)
+	{
+		fflush(f);
+		flock(fileno(f), LOCK_UN);
+		fclose(f);
+	}
 	
 	gdImageDestroy(im);
 	
@@ -557,29 +570,41 @@ int fswc_grab(fswebcam_config_t *config)
 	avgbmp_t *abitmap, *pbitmap;
 	gdImage *image, *original;
 	uint8_t modified;
-	src_t src;
+
+	static src_t src;
+    static uint8_t src_assigned = 0;
 	
 	/* Record the start time. */
 	config->start = time(NULL);
 	
 	/* Set source options... */
-	memset(&src, 0, sizeof(src));
-	src.input      = config->input;
-	src.tuner      = config->tuner;
-	src.frequency  = config->frequency;
-	src.delay      = config->delay;
-	src.timeout    = 10; /* seconds */
-	src.use_read   = config->use_read;
-	src.list       = config->list;
-	src.palette    = config->palette;
-	src.width      = config->width;
-	src.height     = config->height;
-	src.fps        = config->fps;
-	src.option     = config->option;
-	
-	HEAD("--- Opening %s...", config->device);
-	
-	if(src_open(&src, config->device) == -1) return(-1);
+    if(!src_assigned)
+    {
+        memset(&src, 0, sizeof(src));
+        src.input      = config->input;
+        src.tuner      = config->tuner;
+        src.frequency  = config->frequency;
+        src.delay      = config->delay;
+        src.timeout    = 10; /* seconds */
+        src.use_read   = config->use_read;
+        src.list       = config->list;
+        src.palette    = config->palette;
+        src.width      = config->width;
+        src.height     = config->height;
+        src.fps        = config->fps;
+        src.option     = config->option;
+    }
+	
+	
+    if(!src_assigned)
+    {
+        HEAD("--- Opening %s...", config->device);
+        if(src_open(&src, config->device) == -1)
+        {
+            return(-1);
+        }
+        src_assigned = 1;
+    }
 	
 	/* The source may have adjusted the width and height we passed
 	 * to it. Update the main config to match. */
@@ -684,7 +709,10 @@ int fswc_grab(fswebcam_config_t *config)
 	}
 	
 	/* We are now finished with the capture card. */
-	src_close(&src);
+    if(!config->loop || !frame)
+    {
+        src_close(&src);
+    }
 	
 	/* Fail if no frames where captured. */
 	if(!frame)

                    
        
Download