Index: motion/conf.c
===================================================================
--- motion/conf.c	(revision 444)
+++ motion/conf.c	(working copy)
@@ -1623,7 +1623,7 @@
         motion_log(LOG_INFO, 0, "%s: Writing config file to %s", 
                    __FUNCTION__, cnt[thread]->conf_filename);
         
-        conffile = myfopen(cnt[thread]->conf_filename, "w");
+        conffile = myfopen(cnt[thread]->conf_filename, "w", 0);
         
         if (!conffile)
             continue;
@@ -1666,7 +1666,7 @@
         }
 
         fprintf(conffile, "\n");
-        fclose(conffile);
+        myfclose(conffile);
         conffile = NULL;
     }
 }
Index: motion/motion.c
===================================================================
--- motion/motion.c	(revision 444)
+++ motion/motion.c	(working copy)
@@ -381,7 +381,7 @@
     }
 
     if (ptr_logfile) 
-        fclose(ptr_logfile);
+        myfclose(ptr_logfile);
 
 }
 
@@ -2145,16 +2145,16 @@
      * for an enter.
      */
     if (cnt_list[0]->conf.pid_file) {
-        pidf = myfopen(cnt_list[0]->conf.pid_file, "w+");
+        pidf = myfopen(cnt_list[0]->conf.pid_file, "w+", 0);
     
         if (pidf) {
             (void)fprintf(pidf, "%d\n", getpid());
-            fclose(pidf);
+            myfclose(pidf);
         } else {
             motion_log(LOG_ERR, 1, "%s: Exit motion, cannot create process id file (pid file) %s",
                        __FUNCTION__, cnt_list[0]->conf.pid_file);
             if (ptr_logfile) 
-                fclose(ptr_logfile);    
+                myfclose(ptr_logfile);    
             exit(0);    
         }
     }
@@ -2740,6 +2740,13 @@
     return 0;
 }
 
+#define MYBUFCOUNT 32
+struct MyBuffer {
+    FILE* fh;
+    char* buffer;
+    size_t bufsize;
+} buffers[MYBUFCOUNT];
+
 /**
  * myfopen
  *
@@ -2747,17 +2754,25 @@
  *   (which is: path does not exist), the path is created and then things are
  *   tried again. This is faster then trying to create that path over and over
  *   again. If someone removes the path after it was created, myfopen will
- *   recreate the path automatically.
+ *   recreate the path automatically. If the bufsize is set to > 0, we will
+ *   allocate (or re-use) write buffers to use instead of the default ones.
+ *   This gives us much higher throughput in many cases.
  *
  * Parameters:
  *
  *   path - path to the file to open
  *   mode - open mode
+ *   bufsize - size of write buffers, 0 == OS default
  *
  * Returns: the file stream object
  */
-FILE * myfopen(const char *path, const char *mode)
+FILE * myfopen(const char *path, const char *mode, size_t bufsize)
 {
+    static int bufferInit = 0;
+    if (!bufferInit) {
+        bufferInit = 1;
+        memset(buffers, 0x00, sizeof(buffers));
+    }
     /* first, just try to open the file */
     FILE *dummy = fopen(path, mode);
 
@@ -2772,23 +2787,87 @@
 
             /* and retry opening the file */
             dummy = fopen(path, mode);
-            if (dummy)
-                return dummy;
         }
+    }
+ 
+    if (dummy) {
+        if (bufsize > 0) {
+            int i = 0;
+            for (i = 0; i < MYBUFCOUNT; i++) {
+                int first = -1;
+                if (!buffers[i].fh) {
+                    if (first == -1)
+                        first = i;
+                    if (buffers[i].buffer == NULL ||
+                        buffers[i].bufsize >= bufsize ||
+                        (i == (MYBUFCOUNT - 1) && first >= 0)) {
+                        if (buffers[i].buffer == NULL) {
+                            /* We are allocating a new buffer */
+                            buffers[i].fh = dummy;
+                            buffers[i].buffer = mymalloc(bufsize);
+                            buffers[i].bufsize = bufsize;
+                        }
+                        else if (buffers[i].bufsize >= bufsize) {
+                            /* We are using an old buffer */
+                            buffers[i].fh = dummy;
+                        }
+                        else {
+                            /* We are reusing an old buffer, but it is too
+                             * small, realloc it */
+                            i = first;
+                            buffers[i].fh = dummy;
+                            buffers[i].buffer = myrealloc(buffers[i].buffer,
+                                                          bufsize, "myfopen");
+                            buffers[i].bufsize = bufsize;
+                        }
 
+                        if (buffers[i].buffer == NULL) {
+                            /* our allocation failed, so just use the default
+                             * OS buffers */
+                            buffers[i].fh = NULL;
+                            buffers[i].bufsize = 0;
+                        }
+                        else {
+                            setvbuf(buffers[i].fh, buffers[i].buffer,
+                                    _IOFBF, buffers[i].bufsize);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    } else {
         /* two possibilities
-         * 1: there was an other error while trying to open the file for the first time
+         * 1: there was an other error while trying to open the file for the
+         * first time
          * 2: could still not open the file after the path was created
          */
         motion_log(LOG_ERR, 1, "%s: Error opening file %s with mode %s",  
                    __FUNCTION__, path, mode);
-
-        return NULL;
     }
 
     return dummy;
 }
 
+int myfclose(FILE* fh)
+{
+    int i = 0;
+    int rval = fclose(fh);
+    for (i = 0; i < MYBUFCOUNT; i++) {
+        if (buffers[i].fh == fh) {
+            buffers[i].fh = NULL;
+#if 0 /* Don't free the buffers for now, reuse them instead */
+            if (buffers[i].buffer)
+                free(buffers[i].buffer);
+                buffers[i].buffer = NULL;
+                buffers[i].bufsize = 0;
+#endif
+            break;
+        }
+    }
+    return rval;
+}
+
 /**
  * mystrftime
  *
Index: motion/motion.h
===================================================================
--- motion/motion.h	(revision 444)
+++ motion/motion.h	(working copy)
@@ -191,6 +191,8 @@
 #define UPDATE_REF_FRAME  1
 #define RESET_REF_FRAME   2
 
+#define BUFSIZE_1MEG      (1024 * 1024)
+
 /* Forward declaration, used in track.h */
 struct images;
 
@@ -421,7 +423,8 @@
 int http_bindsock(int, int);
 void * mymalloc(size_t);
 void * myrealloc(void *, size_t, const char *);
-FILE * myfopen(const char *, const char *);
+FILE * myfopen(const char *, const char *, size_t);
+int myfclose(FILE *);
 size_t mystrftime(struct context *, char *, size_t, const char *, const struct tm *, const char *, int);
 int create_path(const char *);
 #endif /* _INCLUDE_MOTION_H */
Index: motion/event.c
===================================================================
--- motion/event.c	(revision 444)
+++ motion/event.c	(working copy)
@@ -398,7 +398,7 @@
         snprintf(cnt->extpipefilename, PATH_MAX - 4, "%s/%s", cnt->conf.filepath, stamp);
 
         /* Open a dummy file to check if path is correct */
-        fd_dummy = myfopen(cnt->extpipefilename, "w");
+        fd_dummy = myfopen(cnt->extpipefilename, "w", 0);
 
         /* TODO: trigger some warning instead of only log an error message */
         if (fd_dummy == NULL) {
@@ -414,7 +414,7 @@
 
         }            
         
-        fclose(fd_dummy);        
+        myfclose(fd_dummy);        
         unlink(cnt->extpipefilename);
 
         mystrftime(cnt, stamp, sizeof(stamp), cnt->conf.extpipe, currenttime_tm, cnt->extpipefilename, 0);
Index: motion/ffmpeg.c
===================================================================
--- motion/ffmpeg.c	(revision 444)
+++ motion/ffmpeg.c	(working copy)
@@ -76,7 +76,9 @@
 static int file_open_append(URLContext *h, const char *filename, int flags)
 {
     const char *colon;
-    int access_flags, fd;
+    const char *mode;
+    FILE *fh;
+    size_t bufsize = 0;
 
     /* Skip past the protocol part of filename. */
     colon = strchr(filename, ':');
@@ -86,18 +88,20 @@
     
 
     if (flags & URL_RDWR) {
-        access_flags = O_CREAT | O_APPEND | O_RDWR;
+        mode = "ab+";
+		bufsize = BUFSIZE_1MEG;
     } else if (flags & URL_WRONLY) {
-        access_flags = O_CREAT | O_APPEND | O_WRONLY;
+        mode = "ab";
+		bufsize = BUFSIZE_1MEG;
     } else {
-        access_flags = O_RDONLY;
+        mode = "rb";
     }
 
-    fd = open(filename, access_flags, 0666);
-    if (fd < 0) 
+    fh = myfopen(filename, mode, bufsize);
+    if (fh == NULL)
         return AVERROR(ENOENT);
     
-    h->priv_data = (void *)(size_t)fd;
+    h->priv_data = (void *)fh;
     return 0;
 }
 
@@ -131,49 +135,52 @@
 
 static int file_open(URLContext *h, const char *filename, int flags)
 {
-    int access_flags, fd;
-                              
+    const char *mode;
+    FILE *fh;
+    size_t bufsize = 0;
+
     av_strstart(filename, "file:", &filename);
 
     if (flags & URL_RDWR) {
-        access_flags = O_CREAT | O_TRUNC | O_RDWR;
+        mode = "wb+";
+		bufsize = BUFSIZE_1MEG;
     } else if (flags & URL_WRONLY) {
-        access_flags = O_CREAT | O_TRUNC | O_WRONLY;
+        mode = "wb";
+		bufsize = BUFSIZE_1MEG;
     } else {
-        access_flags = O_RDONLY;
+        mode = "rb";
     }
-#ifdef O_BINARY
-    access_flags |= O_BINARY;
-#endif
-    fd = open(filename, access_flags, 0666);
-    if (fd < 0)
+    fh = myfopen(filename, mode, bufsize);
+    if (fh == NULL)
         return AVERROR(ENOENT);
-    h->priv_data = (void *)(size_t)fd;
+    h->priv_data = (void *)fh;
     return 0;
 }
 
 static int file_read(URLContext *h, unsigned char *buf, int size)
 {
-    int fd = (size_t)h->priv_data;
-    return read(fd, buf, size);
+    FILE *fh = (FILE *)h->priv_data;
+    return fread(buf, 1, size, fh);
 }
          
 static int file_write(URLContext *h, unsigned char *buf, int size)
 {
-    int fd = (size_t)h->priv_data;
-    return write(fd, buf, size);
+    FILE *fh = (FILE *)h->priv_data;
+    return fwrite(buf, 1, size, fh);
 }
 
 static int64_t file_seek(URLContext *h, int64_t pos, int whence)
 {
-    int fd = (size_t)h->priv_data;
-    return lseek(fd, pos, whence);
+    FILE *fh = (FILE *)h->priv_data;
+    if (fseek(fh, pos, whence))
+        return -1;
+    return ftell(fh);
 }
 
 static int file_close(URLContext *h)
 {
-    int fd = (size_t)h->priv_data;
-    return close(fd);
+    FILE *fh = (FILE *)h->priv_data;
+    return myfclose(fh);
 }
 
 URLProtocol file_protocol = {
Index: motion/logger.c
===================================================================
--- motion/logger.c	(revision 444)
+++ motion/logger.c	(working copy)
@@ -33,7 +33,7 @@
  */
 FILE * set_logfile(const char *logfile_name)
 {
-    return logfile = myfopen(logfile_name, "a");
+    return logfile = myfopen(logfile_name, "a", 0);
 }
 
 
Index: motion/picture.c
===================================================================
--- motion/picture.c	(revision 444)
+++ motion/picture.c	(working copy)
@@ -521,7 +521,7 @@
 {
     FILE *picture;
 
-    picture = myfopen(file, "w");
+    picture = myfopen(file, "w", BUFSIZE_1MEG);
     if (!picture) {
         /* Report to syslog - suggest solution if the problem is access rights to target dir */
         if (errno ==  EACCES) {
@@ -540,7 +540,7 @@
     }
 
     put_picture_fd(cnt, picture, image, cnt->conf.quality);
-    fclose(picture);
+    myfclose(picture);
     event(cnt, EVENT_FILECREATE, NULL, file, (void *)(unsigned long)ftype, NULL);
 }
 
@@ -617,7 +617,7 @@
 {
     FILE *picture;
 
-    picture = myfopen(file, "w");
+    picture = myfopen(file, "w", BUFSIZE_1MEG);
     if (!picture) {
         /* Report to syslog - suggest solution if the problem is access rights to target dir */
         if (errno ==  EACCES) {
@@ -643,7 +643,7 @@
         return;
     }
     
-    fclose(picture);
+    myfclose(picture);
 
     motion_log(LOG_ERR, 0, "%s: Creating empty mask %s\nPlease edit this file and "
                "re-run motion to enable mask feature", __FUNCTION__, cnt->conf.mask_file);
