• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/AsyncFile.cpp

00001 #include <errno.h>
00002 #include <iostream>
00003 
00004 #include "FCam/AsyncFile.h"
00005 #include "FCam/Frame.h"
00006 #include "FCam/processing/JPEG.h"
00007 #include "FCam/processing/DNG.h"
00008 #include "FCam/processing/Dump.h"
00009 
00010 #include "Debug.h"
00011 
00012 using namespace std;
00013 
00014 namespace FCam {
00015     void *launch_async_file_writer_thread_(void *arg) {
00016         AsyncFileWriter *d = (AsyncFileWriter *)arg;
00017         d->run();    
00018         d->running = false;    
00019         pthread_exit(NULL);
00020         return NULL;
00021     }
00022 
00023 
00024     AsyncFileWriter::AsyncFileWriter() {
00025         pthread_attr_t attr;
00026         struct sched_param param;
00027 
00028         pending = 0;
00029         
00030         // make the thread
00031         
00032         param.sched_priority = sched_get_priority_min(SCHED_OTHER);
00033         
00034         pthread_attr_init(&attr);
00035 
00036         running = false;
00037         stop = false;
00038 
00039 #ifdef FCAM_PLATFORM_OSX
00040         // unnamed semaphores not supported on OSX
00041         char semName[256];
00042         // Create a unique semaphore name for this TSQueue using its pointer value
00043         snprintf(semName, 256, "FCam::AsyncFile::sem::%llx", (long long unsigned)this);
00044         saveQueueSemaphore = sem_open(semName, O_CREAT, 666, 0);
00045 #else
00046         saveQueueSemaphore = new sem_t;
00047         sem_init(saveQueueSemaphore, 0, 0);
00048 #endif
00049         pthread_mutex_init(&saveQueueMutex, NULL);
00050 
00051         if ((errno =
00052              -(pthread_attr_setschedparam(&attr, &param) ||
00053                pthread_attr_setschedpolicy(&attr, SCHED_OTHER) ||
00054                pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) ||
00055                pthread_create(&thread, &attr, launch_async_file_writer_thread_, this)))) {
00056             error(Event::InternalError, "Error creating async file writer thread");
00057             return;
00058         } else {
00059             running = true;
00060         }        
00061     }
00062 
00063     AsyncFileWriter::~AsyncFileWriter() {
00064         stop = true;
00065         sem_post(saveQueueSemaphore);
00066         if (running) {
00067             pthread_join(thread, NULL);
00068         }
00069 #ifdef FCAM_PLATFORM_OSX
00070         sem_close(saveQueueSemaphore);
00071         char semName[256];
00072         // Recreate the unique semaphore name for this AsyncFileWriter using its pointer value
00073         snprintf(semName, 256, "FCam::AsyncFile::sem::%llx", (long long unsigned)this);
00074         sem_unlink(semName);
00075 #else
00076         sem_destroy(saveQueueSemaphore);
00077         delete saveQueueSemaphore;
00078 #endif
00079 
00080     }
00081 
00082     void AsyncFileWriter::saveDNG(Frame f, std::string filename) {
00083         pending++;
00084         SaveRequest r;
00085         r.frame = f;
00086         r.filename = filename;
00087         r.fileType = SaveRequest::DNGFrame;
00088         r.quality = 0; // meaningless for DNG
00089 
00090         pthread_mutex_lock(&saveQueueMutex);
00091         saveQueue.push(r);
00092         pthread_mutex_unlock(&saveQueueMutex);
00093         sem_post(saveQueueSemaphore);
00094     }
00095 
00096     void AsyncFileWriter::saveJPEG(Frame f, std::string filename, int quality) {
00097         pending++;
00098         SaveRequest r;
00099         r.frame = f;
00100         r.filename = filename;
00101         r.quality = quality;
00102         r.fileType = SaveRequest::JPEGFrame;
00103 
00104         pthread_mutex_lock(&saveQueueMutex);
00105         saveQueue.push(r);
00106         pthread_mutex_unlock(&saveQueueMutex);
00107         sem_post(saveQueueSemaphore);
00108     }
00109 
00110     void AsyncFileWriter::saveJPEG(Image im, std::string filename, int quality) {
00111         pending++;
00112         SaveRequest r;
00113         r.image = im;
00114         r.filename = filename;
00115         r.quality = quality;
00116         r.fileType = SaveRequest::JPEGImage;
00117 
00118         pthread_mutex_lock(&saveQueueMutex);
00119         saveQueue.push(r);
00120         pthread_mutex_unlock(&saveQueueMutex);
00121         sem_post(saveQueueSemaphore);
00122     }
00123 
00124     void AsyncFileWriter::saveDump(Frame f, std::string filename) {
00125         pending++;
00126         SaveRequest r;
00127         r.frame = f;
00128         r.filename = filename;
00129         r.quality = 0;
00130         r.fileType = SaveRequest::DumpFrame;
00131 
00132         pthread_mutex_lock(&saveQueueMutex);
00133         saveQueue.push(r);
00134         pthread_mutex_unlock(&saveQueueMutex);
00135         sem_post(saveQueueSemaphore);
00136     }
00137 
00138     void AsyncFileWriter::saveDump(Image im, std::string filename) {
00139         pending++;
00140         SaveRequest r;
00141         r.image = im;
00142         r.filename = filename;
00143         r.quality = 0;
00144         r.fileType = SaveRequest::DumpImage;
00145 
00146         pthread_mutex_lock(&saveQueueMutex);
00147         saveQueue.push(r);
00148         pthread_mutex_unlock(&saveQueueMutex);
00149         sem_post(saveQueueSemaphore);
00150     }
00151 
00152     void AsyncFileWriter::cancel() {
00153         pthread_mutex_lock(&saveQueueMutex);
00154         while (saveQueue.size()) {
00155             saveQueue.pop();
00156         };
00157         pthread_mutex_unlock(&saveQueueMutex);
00158     }
00159 
00160     void AsyncFileWriter::run() {
00161         while (!stop) {
00162             sem_wait(saveQueueSemaphore);
00163             if (stop) return;
00164             SaveRequest r;
00165             pthread_mutex_lock(&saveQueueMutex);
00166             r = saveQueue.front();
00167             saveQueue.pop();
00168             pthread_mutex_unlock(&saveQueueMutex);            
00169             switch (r.fileType) {
00170             case SaveRequest::DNGFrame:                    
00171                 FCam::saveDNG(r.frame, r.filename);
00172                 break;
00173             case SaveRequest::JPEGFrame:
00174                 FCam::saveJPEG(r.frame, r.filename, r.quality);
00175                 break;
00176             case SaveRequest::JPEGImage:
00177                 FCam::saveJPEG(r.image, r.filename, r.quality);
00178                 break;
00179             case SaveRequest::DumpFrame:
00180                 FCam::saveDump(r.frame, r.filename);
00181                 break;
00182             case SaveRequest::DumpImage:
00183                 FCam::saveDump(r.image, r.filename);
00184                 break;
00185             default:
00186                 cerr << "Corrupted entry in async file writer save queue." << endl;
00187             }
00188 
00189             pending--;
00190         }
00191     }
00192 }
00193     

Generated on Mon Aug 16 2010 14:25:45 for FCam by  doxygen 1.7.1