From 6d7a1f124f38a4358f517437757f6f0c3fe21d8b Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Sun, 19 Jun 2005 20:04:43 +0000
Subject: ImgEncoder now uses the file class for output, through jpeg_mem_dest.

---
 src/file.cc               |  15 ++-
 src/file.h                |   4 +
 src/img_encoder.cc        | 247 ++++++++++++++++++++++++++++++++++------------
 src/img_encoder.h         |  32 +++---
 src/mov_encoder.cc        |  22 +++++
 src/mov_encoder_writer.cc |  74 +++-----------
 src/server.cc             |  95 +-----------------
 src/server_status.cc      |  10 +-
 src/server_status.h       |  10 +-
 9 files changed, 268 insertions(+), 241 deletions(-)

(limited to 'src')

diff --git a/src/file.cc b/src/file.cc
index 2ba20bb..49b9bb5 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.6  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.5  2005/06/19 11:44:14  deva
  * Cleaned up a log of logging.
  * Fixed server queue (shouldn't happen).
@@ -61,19 +64,16 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <stdio.h>
-
 #include <stdlib.h>
 
-
 File::File(char *fn, char* ext, Info *i)
 {
   char path[256];
 
   info = i;
 
-  filename = (char*)malloc(strlen(fn) + 1);
-  extension = (char*)malloc(strlen(ext) + 1);
+  filename = new char[strlen(fn) + 1];
+  extension = new char[strlen(ext) + 1];
 
   strcpy(filename, fn);
   strcpy(extension, ext);
@@ -98,8 +98,8 @@ File::~File()
 {
   close(fd);
 
-  free(filename);
-  free(extension);
+  delete filename;
+  delete extension;
 }
 
 int File::Open()
@@ -179,4 +179,3 @@ int File::createPath(char* path)
   
   return 0;
 }
-
diff --git a/src/file.h b/src/file.h
index 6326528..3faecb5 100644
--- a/src/file.h
+++ b/src/file.h
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.3  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.2  2005/06/13 20:38:19  deva
  * Added some logfile code.
  * Enhanced the file object... now ready to hook into mov_encoder
@@ -46,6 +49,7 @@
 #define __MIAV_FILE_H__
 
 #include "info.h"
+#include <stdio.h>
 
 #include <string.h>
 using namespace std;
diff --git a/src/img_encoder.cc b/src/img_encoder.cc
index c5cc58b..2412520 100644
--- a/src/img_encoder.cc
+++ b/src/img_encoder.cc
@@ -39,6 +39,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.9  2005/05/26 12:48:36  deva
  * *** empty log message ***
  *
@@ -62,91 +65,211 @@
 #include <libdv/dv.h>
 #include <libdv/dv_types.h>
 
-ImgEncoder::ImgEncoder()
+ImgEncoder::ImgEncoder(const char* cpr, Info *i)
 {
+  info = i;
+
+  // Create path and filename
+  char fname[256];
+  string *server_root;
+  char birthmonth[3];
+  char date[32];
+
+  // Get server root
+  server_root = config->readString("server_root");
+
+  // Copy the bytes representing the birth month from the cpr
+  // [dd][mm][yy]-[nn][nn]
+  strncpy(birthmonth, &cpr[2], 2);
+  birthmonth[2] = 0;
+
+  // Create date (today) in [yyyy][mm][dd]
+  struct tm *ltime;
+  time_t t = time(NULL);
+  ltime = localtime(&t);
+  sprintf(date, "%.4d%.2d%.2d", 
+          ltime->tm_year + 1900, 
+          ltime->tm_mon, 
+          ltime->tm_mday);
+
+  sprintf(fname, "%s/%s/%s/%s-%s-", server_root->c_str(), birthmonth, cpr, cpr, date);
+
+  file = new File(fname, "jpg", info);
 }
 
+
 ImgEncoder::~ImgEncoder()
 {
+  delete file;
 }
 
-void ImgEncoder::encode(Frame *dvframe, 
-                        char *filename, 
-                        int quality)
+
+void ImgEncoder::encode(Frame *dvframe, int quality)
 { 
-  // Append suffix..
-  char fname[256];
-  sprintf(fname, "%s.jpg", filename);
-  
   unsigned char rgb[720*576*4];
 
   getRGB(dvframe, rgb);
-  writeJPEGFile(fname, quality, (JSAMPLE*)rgb, 720, 576);
+  writeJPEGFile(quality, (JSAMPLE*)rgb, 720, 576);
 }
-///////////////////////////////////////////////////////////////////////////////////////////
-
-void ImgEncoder::writeJPEGFile(char *filename, 
-                               int quality,
-                               JSAMPLE * image_buffer, // Points to large array of R,G,B-order data 
-                               int image_width,        // Number of columns in image 
-                               int image_height        // Number of rows in image 
-)
+
+#define OUTPUT_BUF_SIZE  4096	/* choose an efficiently ?? size */
+
+/* Expanded data destination object for stdio output */
+typedef struct {
+  struct jpeg_destination_mgr pub; /* public fields */
+
+  JOCTET * outbuff;		/* target buffer */
+  size_t * size;
+} mem_destination_mgr;
+
+typedef mem_destination_mgr * mem_dest_ptr;
+
+/*
+ * Initialize destination --- called by jpeg_start_compress
+ * before any data is actually written.
+ */
+void init_destination (j_compress_ptr cinfo)
 {
-    struct jpeg_compress_struct cinfo;
-    struct jpeg_error_mgr jerr;
-    
-    FILE * outfile;               // target file
-    JSAMPROW row_pointer[1];      // pointer to JSAMPLE row[s] 
-    int row_stride;               // physical row width in image buffer 
-    
-    // Step 1: allocate and initialize JPEG compression object 
-    cinfo.err = jpeg_std_error(&jerr);
-    jpeg_create_compress(&cinfo);
-    
-    // Step 2: specify data destination (eg, a file) 
-    if ((outfile = fopen(filename, "wb")) == NULL) {
-      fprintf(stderr, "can't open %s\n", filename);
-      exit(1);
-    }
-    jpeg_stdio_dest(&cinfo, outfile);
+  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+  *dest->size = 0;
+  dest->pub.next_output_byte = dest->outbuff;
+  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+/*
+ * Terminate destination --- called by jpeg_finish_compress
+ * after all data has been written.  Usually needs to flush buffer.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+void term_destination (j_compress_ptr cinfo)
+{
+  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+
+  /* Write any data remaining in the buffer */
+  if (datacount > 0) {
+    dest->outbuff+=datacount;
+    *dest->size+=datacount;
+  }
+}
+
+/*
+ * Empty the output buffer --- called whenever buffer fills up.
+ *
+ * In typical applications, this should write the entire output buffer
+ * (ignoring the current state of next_output_byte & free_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been dumped.
+ *
+ * In applications that need to be able to suspend compression due to output
+ * overrun, a FALSE return indicates that the buffer cannot be emptied now.
+ * In this situation, the compressor will return to its caller (possibly with
+ * an indication that it has not accepted all the supplied scanlines).  The
+ * application should resume compression after it has made more room in the
+ * output buffer.  Note that there are substantial restrictions on the use of
+ * suspension --- see the documentation.
+ *
+ * When suspending, the compressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_output_byte & free_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point will be regenerated after resumption, so do not
+ * write it out when emptying the buffer externally.
+ */
+boolean empty_output_buffer (j_compress_ptr cinfo)
+{
+  mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+  dest->outbuff+=OUTPUT_BUF_SIZE;
+  *dest->size+=OUTPUT_BUF_SIZE;
+
+  dest->pub.next_output_byte = dest->outbuff;
+  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+
+  return TRUE;
+}
+
+/*
+ * Prepare for output to a memory buffer.
+ . The caller must have already allocated the buffer, and is responsible
+ * for closing it after finishing compression.
+ */
+void jpeg_mem_dest (j_compress_ptr cinfo, char * outbuff, size_t * size)
+{
+  mem_dest_ptr dest;
+
+  /* The destination object is made permanent so that multiple JPEG images
+   * can be written to the same file without re-executing jpeg_stdio_dest.
+   * This makes it dangerous to use this manager and a different destination
+   * manager serially with the same JPEG object, because their private object
+   * sizes may be different.  Caveat programmer.
+   */
+  if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
+    cinfo->dest = (struct jpeg_destination_mgr *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  sizeof(mem_destination_mgr));
+  }
+
+  dest = (mem_dest_ptr) cinfo->dest;
+  dest->pub.init_destination = init_destination;
+  dest->pub.empty_output_buffer = empty_output_buffer;
+  dest->pub.term_destination = term_destination;
+  dest->outbuff = (JOCTET *)outbuff;
+  dest->size = (size_t *)size;
+}
+
+void ImgEncoder::writeJPEGFile(int quality, JSAMPLE * image_buffer, int image_width, int image_height)
+{
+  size_t buffersize = (image_width * image_height * 3) + JPEG_HEADER_PAD;
+  char *jpeg_output_buffer = new char [buffersize];
+  struct jpeg_compress_struct cinfo;
+  struct jpeg_error_mgr jerr;
     
-    // Step 3: set parameters for compression 
-    cinfo.image_width = image_width;      // image width and height, in pixels 
-    cinfo.image_height = image_height;
-    cinfo.input_components = 3;           // # of color components per pixel 
+  JSAMPROW row_pointer[1];      // pointer to JSAMPLE row[s] 
+  int row_stride;               // physical row width in image buffer 
     
-    //typedef enum {
-    //        JCS_UNKNOWN,            // error/unspecified
-    //        JCS_GRAYSCALE,          // monochrome
-    //        JCS_RGB,                // red/green/blue
-    //        JCS_YCbCr,              // Y/Cb/Cr (also known as YUV)
-    //        JCS_CMYK,               // C/M/Y/K
-    //        JCS_YCCK                // Y/Cb/Cr/K
-    //} J_COLOR_SPACE;
+  // Step 1: allocate and initialize JPEG compression object 
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_compress(&cinfo);
     
-    cinfo.in_color_space = JCS_RGB;       // colorspace of input image 
+  // Step 2: specify data destination (eg, a file) 
+  //jpeg_stdio_dest(&cinfo, file->getFP());
+  jpeg_mem_dest(&cinfo, jpeg_output_buffer, &buffersize);
     
-    jpeg_set_defaults(&cinfo);
+  // Step 3: set parameters for compression 
+  cinfo.image_width = image_width;      // image width and height, in pixels 
+  cinfo.image_height = image_height;
+  cinfo.input_components = 3;           // # of color components per pixel 
+ 
+  cinfo.in_color_space = JCS_RGB;       // colorspace of input image 
     
-    jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values
+  jpeg_set_defaults(&cinfo);
     
-    // Step 4: Start compressor 
-    jpeg_start_compress(&cinfo, TRUE);
+  jpeg_set_quality(&cinfo, quality, TRUE); // limit to baseline-JPEG values
     
-    // Step 5: while (scan lines remain to be written) 
-    row_stride = image_width * 3; // JSAMPLEs per row in image_buffer 
+  // Step 4: Start compressor 
+  jpeg_start_compress(&cinfo, TRUE);
     
-    while (cinfo.next_scanline < cinfo.image_height) {
-      row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
-      (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
-    }
+  // Step 5: while (scan lines remain to be written) 
+  row_stride = image_width * 3; // JSAMPLEs per row in image_buffer 
     
-    // Step 6: Finish compression 
-    jpeg_finish_compress(&cinfo);
-    fclose(outfile);
+  while (cinfo.next_scanline < cinfo.image_height) {
+    row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+  }
     
-    // Step 7: release JPEG compression object 
-    jpeg_destroy_compress(&cinfo);
+  // Step 6: Finish compression 
+  jpeg_finish_compress(&cinfo);
+
+  // Step 7: release JPEG compression object 
+  jpeg_destroy_compress(&cinfo);
+
+  info->info("JPEG buffersize: %d", buffersize);
+  file->Write(jpeg_output_buffer, buffersize);
+  delete jpeg_output_buffer;
 }
 
 void ImgEncoder::getRGB(Frame *frame, unsigned char *rgb)
diff --git a/src/img_encoder.h b/src/img_encoder.h
index 4ffec57..eb702b2 100644
--- a/src/img_encoder.h
+++ b/src/img_encoder.h
@@ -38,6 +38,9 @@
 
 /*
  * $Log$
+ * Revision 1.8  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.7  2005/05/07 10:25:34  deva
  *
  * Removed ffmpeg code from img_encoder and corrected decoding errors in mov_encoder
@@ -69,33 +72,26 @@ extern "C" {
 #endif
 }
 
+#include "info.h"
+#include "file.h"
+
 #define VIDEO_BUFFER_SIZE	(1024*1024)	// FIXME: One size fits all...
+#define JPEG_HEADER_PAD 500
 
 class ImgEncoder {
- public:
-  ImgEncoder();
+public:
+  ImgEncoder(const char* cpr, Info *info);
   ~ImgEncoder();
-  void encode(Frame *frame, char* filename, int quality);
-  void writeJPEGFile(char *filename, 
-                     int quality,
+  void encode(Frame *frame, int quality);
+  void writeJPEGFile(int quality,
                      JSAMPLE * image_buffer, // Points to large array of R,G,B-order data 
                      int image_width,        // Number of columns in image 
                      int image_height);      // Number of rows in image 
                      
- private:
+private:
+  File *file;
+  Info *info;
   void getRGB(Frame *frame, unsigned char *rgb);
-  /*
-  // Decoder
-  AVFormatContext *dfc;
-  AVCodecContext *dcc;
-
-  // Encoder
-  AVFormatContext *efc;
-  AVCodecContext *ecc;
-  AVPacket epkt;
-  unsigned char *video_buffer;
-  //  AVPacket pkt;
-  */
 };
 
 #endif /*__RTVIDEOREC_IMGENCODER_H*/
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index b31e1c9..3aa7a49 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -39,6 +39,9 @@
 
 /*
  * $Log$
+ * Revision 1.32  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.31  2005/06/19 11:44:14  deva
  * Cleaned up a log of logging.
  * Fixed server queue (shouldn't happen).
@@ -122,6 +125,9 @@
 
 #include <errno.h>
 
+// For nice
+#include <unistd.h>
+
 #include "miav_config.h"
 
 #include "debug.h"
@@ -385,6 +391,13 @@ void MovEncoder::encode_audio(Frame *dvframe)
 void MovEncoder::thread_main()
 {
   info->info("MovEncoder thread is running.");
+  static volatile int test = 0;
+  int outsize = 0;
+  int insize = 0;
+
+  // Run with slightly lower priority than MovEncoderWriter
+  nice(1);
+
 
   FrameVector *item;
   Frame *in_frame;
@@ -397,6 +410,9 @@ void MovEncoder::thread_main()
     pthread_mutex_lock(input_mutex);
     item = inputqueue->front();
     inputqueue->pop();
+
+    insize = inputqueue->size();
+
     pthread_mutex_unlock(input_mutex);
     // Unlock input mutex
 
@@ -411,12 +427,18 @@ void MovEncoder::thread_main()
         // Lock output mutex
         pthread_mutex_lock(output_mutex);
         outputqueue->push(out_frame);
+
+        outsize = outputqueue->size();
+
         pthread_mutex_unlock(output_mutex);
         // Unlock output mutex
       }
 
       delete item;
 
+      test++;
+      if(test % (25 * 24) == 0) info->info("Input pool size: %d, output pool size: %d", insize, outsize);
+
       // Kick frame writer
       sem_post(output_sem);
 
diff --git a/src/mov_encoder_writer.cc b/src/mov_encoder_writer.cc
index a10d671..1c0fe1b 100644
--- a/src/mov_encoder_writer.cc
+++ b/src/mov_encoder_writer.cc
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.7  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.6  2005/06/16 21:28:57  deva
  * Rewrote thread object
  * Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to
@@ -131,88 +134,43 @@ void MovEncoderWriter::thread_main()
   while(running) {
     sem_wait(sem);
 
+    //    int poolsize;
+
     // Lock output mutex
     pthread_mutex_lock(mutex);
     frame = queue->top();
     if(frame && frame->number == frame_number) queue->pop();
+    //    poolsize = queue->size();
     pthread_mutex_unlock(mutex);
     // Unlock output mutex
 
+    int wrote = 0;
     while(frame && (frame->number == frame_number)) {
+      
       int ret;
 
       ret = file->Write(frame->data, frame->size);
+      frame_number++;
+      wrote ++;
 
       delete frame;
 
-      if(ret == -1) return;
+      if(ret == -1) {
+        info->error("File write returned -1.");
+        return;
+      }
       
-      frame_number++;
-
       // Lock output mutex
       pthread_mutex_lock(mutex);
       frame = queue->top();
       if(frame && frame->number == frame_number) queue->pop();
+      //      poolsize = queue->size();
       pthread_mutex_unlock(mutex);
       // Unlock output mutex
     }
-  }
-
-  info->info("MovEncoderWriter::stop");
-}
-
 
-/*
-void MovEncoderWriter::thread_main()
-{
-  unsigned int howdeep = 0;
-  info->info("MovEncoderWriter::run");
-
-  Frame *frame;
-
-  while(running) {
-    sem_wait(sem);
-    howdeep++;
-
-    // Lock output mutex
-    pthread_mutex_lock(mutex);
-    if(queue->size() == 0) {
-      info->warn("1MovEncoderWriter encountered an empty queue (This shouldn't happen).");
-      // Unlock output mutex
-      pthread_mutex_unlock(mutex);
-      continue;
-    }
-    frame = queue->top();
-    if(frame->number == frame_number) queue->pop();
-    pthread_mutex_unlock(mutex);
-    // Unlock output mutex
-
-    while((frame->number == frame_number) && howdeep) {
-      howdeep--;
-      int ret;
-
-      ret = file->Write(frame->data, frame->size);
-
-      delete frame;
-
-      if(ret == -1) return;
-      
-      frame_number++;
-
-      // Lock output mutex
-      pthread_mutex_lock(mutex);
-      if(queue->size() == 0) {
-        info->warn("2MovEncoderWriter encountered an empty queue (This shouldn't happen).");
-        pthread_mutex_unlock(mutex);
-        continue;
-      }
-      frame = queue->top();
-      if(frame->number == frame_number) queue->pop();
-      pthread_mutex_unlock(mutex);
-      // Unlock output mutex
-    }
+    //    info->info("Wrote %d frames, pool size %d - exp: %d", wrote, poolsize, frame_number);
   }
 
   info->info("MovEncoderWriter::stop");
 }
-*/
diff --git a/src/server.cc b/src/server.cc
index e6a6ff7..35dbb9d 100644
--- a/src/server.cc
+++ b/src/server.cc
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.25  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.24  2005/06/19 11:44:14  deva
  * Cleaned up a log of logging.
  * Fixed server queue (shouldn't happen).
@@ -116,94 +119,6 @@
 
 #include "dv.h"
 
-void saveFrameAsImage(char* cpr, Frame *f)
-{
-  ImgEncoder imgenc;
-  struct tm *ltime;
-  time_t t = time(NULL);
-  FILE *fp;
-  int cnt = 0;
-  char fname[256];
-  char birthmonth[3];
-  char date[9];
-  
-  string *root = config->readString("server_root");
-
-  // Test for server root writeability
-  sprintf(fname, "%s/miavtemp.tmp%d", (char*)root->c_str(), rand());
-  fp = fopen(fname, "w");
-  if(!fp) {
-    int r = rand();
-    fprintf(stderr, "MIaV does not have write access to the server root [%s]\n", root->c_str());
-    fprintf(stderr, "Redirecting output to [/tmp/miav-%d.jpg]\n", r);
-    sprintf(fname, "/tmp/miav-%d", r);
-    imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
-    return;
-  }
-  fclose(fp);
-  unlink(fname);
-
-  // Check for cpr length correctness
-  if(strlen(cpr) != 11) {
-    int r = rand();
-    fprintf(stderr, "Illigal CPR, it must have length 11, it had length %d\n", strlen(cpr));
-    fprintf(stderr, "Redirecting output to [/tmp/miav-%d.jpg]\n", r);
-    sprintf(fname, "/tmp/miav-%d", r);
-    imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
-    return;
-  }
-
-  // Copy the bytes representing the birth month from the cpr
-  // [dd][mm][yy]-[nn][nn]
-  strncpy(birthmonth, &cpr[2], 2);
-  birthmonth[2] = 0;
-
-  // Create folder named birthmonth in server root
-  sprintf(fname, "%s/%s", root->c_str(), birthmonth);
-  if(!mkdir(fname, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH) == -1 && errno != EEXIST) {
-    int r = rand();
-    fprintf(stderr, "Not possible to create subfolder %s\n", fname);
-    fprintf(stderr, "Redirecting output to [/tmp/miav-%d.jpg]\n", r);
-    sprintf(fname, "/tmp/miav-%d", r);
-    imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
-    return;
-  }
-
-  // Create folder named cpr in serverroot/birthmonth
-  sprintf(fname, "%s/%s/%s", root->c_str(), birthmonth, cpr);
-  if(!mkdir(fname, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH) == -1 && errno != EEXIST) {
-    int r = rand();
-    fprintf(stderr, "Not possible to create subfolder %s\n", fname);
-    fprintf(stderr, "Redirecting output to [/tmp/miav-%d.jpg]\n", r);
-    sprintf(fname, "/tmp/miav-%d", r);
-    imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
-    return;
-  }
-
-  // Create date (today) in [yyyy][mm][dd]
-  ltime = localtime(&t);
-  sprintf(date, "%.4d%.2d%.2d", 
-          ltime->tm_year + 1900, 
-          ltime->tm_mon, 
-          ltime->tm_mday);
-
-  // Create filename: [serverroot]/[birthmonth]/[cpr]/[cpr]-[date]-[cnt].mpg
-  sprintf(fname, "%s/%s/%s/%s-%s-%.3d.jpg", root->c_str(), birthmonth, cpr, cpr, date, cnt);
-
-  // test filename-[cnt] for existamce cnt++ until not existing.
-  fp = fopen(fname, "r");
-  while(fp) {
-    fclose(fp);
-    cnt++;
-    sprintf(fname, "%s/%s/%s/%s-%s-%.3d.jpg", root->c_str(), birthmonth, cpr, cpr, date, cnt);
-    fp = fopen(fname, "r");
-  }
-  sprintf(fname, "%s/%s/%s/%s-%s-%.3d", root->c_str(), birthmonth, cpr, cpr, date, cnt);
-
-  fprintf(stderr, "Success - using filename: [%s.jpg]\n", fname); fflush(stderr);
-  imgenc.encode(f, fname, 100); // Quality is between 0...100, where 100 is best.
-}
-
 void newConnection(Socket *socket, Info *info)
 {
   char cpr[256];
@@ -245,11 +160,11 @@ void newConnection(Socket *socket, Info *info)
     
     if(h.header.h_data.snapshot) {
       if(freeze_frame) {
-        saveFrameAsImage(cpr, freeze_frame);
+        ImgEncoder(cpr, info).encode(freeze_frame, 100);
         delete freeze_frame;
         freeze_frame = NULL;
       } else {
-        saveFrameAsImage(cpr, frame);
+        ImgEncoder(cpr, info).encode(frame, 100);
       }
     }
 
diff --git a/src/server_status.cc b/src/server_status.cc
index e65cef2..2b2395c 100644
--- a/src/server_status.cc
+++ b/src/server_status.cc
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.9  2005/06/19 11:44:14  deva
  * Cleaned up a log of logging.
  * Fixed server queue (shouldn't happen).
@@ -76,7 +79,7 @@ ServerStatus::ServerStatus(Info *i)
 
   gettimeofday(&time, NULL);
 
-  frame = 0;
+  interval = 0;
 }
 
 ServerStatus::~ServerStatus()
@@ -95,8 +98,9 @@ void ServerStatus::checkPoint()
 
   gettimeofday(&time, NULL);
 
-  frame++;
-  if(frame % UPD == 0) {
+  interval += frametime[0];
+  if(interval > UPD) {
+    interval = 0;
     double total = 0.0;
     for(int cnt = 0; cnt < BUFFERSIZE; cnt++) {
       total += (double)frametime[cnt];
diff --git a/src/server_status.h b/src/server_status.h
index 58de61c..73b8ecb 100644
--- a/src/server_status.h
+++ b/src/server_status.h
@@ -31,6 +31,9 @@
 
 /*
  * $Log$
+ * Revision 1.5  2005/06/19 20:04:43  deva
+ * ImgEncoder now uses the file class for output, through jpeg_mem_dest.
+ *
  * Revision 1.4  2005/06/19 11:44:14  deva
  * Cleaned up a log of logging.
  * Fixed server queue (shouldn't happen).
@@ -52,8 +55,11 @@
 
 #include <sys/time.h>
 
+// How many steps to do avarage calculation over.
 #define BUFFERSIZE 100
-#define UPD 1500
+
+// Interval in us (microseconds)
+#define UPD 60 * 1000 * 1000 // 1 minute
 
 class ServerStatus {
 public:
@@ -63,7 +69,7 @@ public:
   void checkPoint();
 
 private:
-  int frame;
+  long long interval;
   Info *info;
   unsigned int frametime[BUFFERSIZE];
   struct timeval time; 
-- 
cgit v1.2.3