00001 #include "AsyncFile.h"
00002 #include <errno.h>
00003 #include "Frame.h"
00004 #include "processing/JPEG.h"
00005 #include "processing/DNG.h"
00006 #include "processing/Dump.h"
00007
00008 #include <iostream>
00009 using namespace std;
00010
00011 namespace FCam {
00012 void *launch_async_file_writer_thread_(void *arg) {
00013 AsyncFileWriter *d = (AsyncFileWriter *)arg;
00014 d->run();
00015 d->running = false;
00016 pthread_exit(NULL);
00017 return NULL;
00018 }
00019
00020
00021 AsyncFileWriter::AsyncFileWriter() {
00022 pthread_attr_t attr;
00023 struct sched_param param;
00024
00025 pending = 0;
00026
00027
00028
00029 param.sched_priority = sched_get_priority_min(SCHED_OTHER);
00030
00031 pthread_attr_init(&attr);
00032
00033 running = false;
00034 stop = false;
00035
00036 sem_init(&saveQueueSemaphore, 0, 0);
00037 pthread_mutex_init(&saveQueueMutex, NULL);
00038
00039 if ((errno =
00040 -(pthread_attr_setschedparam(&attr, ¶m) ||
00041 pthread_attr_setschedpolicy(&attr, SCHED_OTHER) ||
00042 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) ||
00043 pthread_create(&thread, &attr, launch_async_file_writer_thread_, this)))) {
00044 perror("Error creating thread");
00045 return;
00046 } else {
00047 running = true;
00048 }
00049 }
00050
00051 AsyncFileWriter::~AsyncFileWriter() {
00052 stop = true;
00053 sem_post(&saveQueueSemaphore);
00054 if (running) {
00055 pthread_join(thread, NULL);
00056 }
00057 }
00058
00059 void AsyncFileWriter::saveDNG(Frame::Ptr f, std::string filename, Lens *lens, Flash *flash) {
00060 pending++;
00061 SaveRequest r;
00062 r.frame = f;
00063 r.filename = filename;
00064 r.fileType = SaveRequest::DNG;
00065 r.quality = 0;
00066 r.lens = lens;
00067 r.flash = flash;
00068
00069 pthread_mutex_lock(&saveQueueMutex);
00070 saveQueue.push(r);
00071 pthread_mutex_unlock(&saveQueueMutex);
00072 sem_post(&saveQueueSemaphore);
00073 }
00074
00075 void AsyncFileWriter::saveJPEG(Frame::Ptr f, std::string filename,
00076 int quality, Lens *lens, Flash *flash) {
00077 pending++;
00078 SaveRequest r;
00079 r.frame = f;
00080 r.filename = filename;
00081 r.quality = quality;
00082 r.fileType = SaveRequest::JPEG;
00083 r.lens = lens;
00084 r.flash = flash;
00085
00086 pthread_mutex_lock(&saveQueueMutex);
00087 saveQueue.push(r);
00088 pthread_mutex_unlock(&saveQueueMutex);
00089 sem_post(&saveQueueSemaphore);
00090 }
00091
00092 void AsyncFileWriter::saveDump(Frame::Ptr f, std::string filename) {
00093 pending++;
00094 SaveRequest r;
00095 r.frame = f;
00096 r.filename = filename;
00097 r.quality = 0;
00098 r.fileType = SaveRequest::Dump;
00099 r.lens = NULL;
00100 r.flash = NULL;
00101
00102 pthread_mutex_lock(&saveQueueMutex);
00103 saveQueue.push(r);
00104 pthread_mutex_unlock(&saveQueueMutex);
00105 sem_post(&saveQueueSemaphore);
00106 }
00107
00108 void AsyncFileWriter::cancel() {
00109 pthread_mutex_lock(&saveQueueMutex);
00110 while (saveQueue.size()) {
00111 saveQueue.pop();
00112 };
00113 pthread_mutex_unlock(&saveQueueMutex);
00114 }
00115
00116 void AsyncFileWriter::run() {
00117 while (!stop) {
00118 sem_wait(&saveQueueSemaphore);
00119 if (stop) return;
00120 SaveRequest r;
00121 pthread_mutex_lock(&saveQueueMutex);
00122 r = saveQueue.front();
00123 saveQueue.pop();
00124 pthread_mutex_unlock(&saveQueueMutex);
00125 switch (r.fileType) {
00126 case SaveRequest::DNG:
00127 FCam::saveDNG(r.frame, r.filename, r.lens, r.flash);
00128 break;
00129 case SaveRequest::JPEG:
00130 FCam::saveJPEG(r.frame, r.filename, r.quality, r.lens, r.flash);
00131 break;
00132 case SaveRequest::Dump:
00133 FCam::saveDump(r.frame, r.filename);
00134 break;
00135 default:
00136 cerr << "Corrupted entry in async file writer save queue." << endl;
00137 }
00138
00139 pending--;
00140 }
00141 }
00142 }
00143