-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathWindowsThreadStackCompressor.h
More file actions
254 lines (211 loc) · 9.62 KB
/
WindowsThreadStackCompressor.h
File metadata and controls
254 lines (211 loc) · 9.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*
* File: WindowsThreadStackCompressor.h
* Author: Marc
*
* modifies LinearStackCompressor to use windows threads and mutexes
* * Generates a stack of background removed images on disk; This is the highest level object in the library
* it maintains a set of StaticBackgroundCompressor objects, each of which holds a background image and a set of background removed images
*
*
* compresses images as they are added to the stack with explicit multi-threading
* as long as the average processing time (including writing to disk)
* is less than the average arrival time of images, this will compress images continuously without
* slowing acquisition as every function returns almost immediately
*
*
* below is an example use of WTSC to compress a stack of jpg images
*
* string stub = "\\\\labnas2\\LarvalCO2\\Image Data\\50 mL CO2 in 2 L air\\20101001\\CS3\\CS3_";
* WindowsThreadStackCompressor wtsc;
* wtsc.setThresholds(0, 5, 2, 3);
* wtsc.setIntervals(90, 1);
* wtsc.setOutputFileName("c:\\teststack.mmf");
* wtsc.setFrameRate(5);
* int nframes = 1000;
* wtsc.startThreads();
* wtsc.startRecording(nframes);
* stringstream s;
* for (int j = 0; j < nframes; ++j) {
* s.str("");
* s << stub << j << ".jpg";
* IplImage *im = cvLoadImage(s.str().c_str(), 0);
* assert(im != NULL);
* cout << "loaded image " << j <<"\n";
* BlankMetaData *bmd = new BlankMetaData;
* wtsc.newFrame(im, bmd);
* cvReleaseImage(&im);
* }
* wtsc.stopRecording();
*
* (C) Marc Gershow; licensed under the Creative Commons Attribution Share Alike 3.0 United States License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
* Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
*
*/
#ifndef WINDOWSTHREADSTACKCOMPRESSOR_H
#define WINDOWSTHREADSTACKCOMPRESSOR_H
#ifdef WIN32
#include "LinearStackCompressor.h"
#include "tictoc/tictoc.h"
#include <windows.h>
#include <process.h>
#include <queue>
class WindowsThreadStackCompressor : public LinearStackCompressor {
public:
/* WindowsThreadStackCompressor();
*
* creates a wtsc and initializes it, but does not open a data file or start recording
* also, does not start required threads; user must call startThreads prior to
* calling newFrame
*/
WindowsThreadStackCompressor();
/* virtual ~WindowsThreadStackCompressor();
* finishes recording (compresses & writes any outstanding frames to disk)
* then closes output file (if open), stops threads and frees memory
*
*/
virtual ~WindowsThreadStackCompressor();
/* virtual int checkIfThreadsHaveEnded(int timeout= 2000);
*
* returns 0 if threads have ended
* otherwise returns an integer reflecting which threads are still active
*
*/
virtual int checkIfThreadsAreActive(int timeout = 2000);
/* virtual int endThreads(int timeout= 2000);
*
* ends all compression and writing threads, call only before destruction
*
*/
virtual int endThreads(int timeout= 2000);
/* virtual int startThreads(); //returns -1 on error, 0 on ok
*
* starts compression and writing threads that run in background
*
* may be called at any time after construction, must be called before first newFrame
*/
virtual int startThreads(); //returns -1 on error, 0 on ok
/* virtual void newFrame(const IplImage *im, ImageMetaData *metadata = NULL);
*
* adds an image and any associated metadata to the stack of images to be compressed
*
* a copy of the IplImage is made and stored; the user is free to delete or reuse the image after calling
* the metadata becomes the property and responsibility of the lsc;
* the user should make no further use of the metadata and lsc will free it when appropriate
*
* a note on timing: a few memory allocations, copying the image over, and updating of the background via a comparison
* are all carried out prior to this function returning; the total overhead of these function calls is small
* the function must also acquire one or more mutexes before proceeding; however, the code has been written to minimize the
* amount of time any thread holds on to the mutexes required by next frame
*
* it is up to the user to determine the maximum rate at which frames can be added in the environment in which this code is used
* it has been tested at 5 Hz with 5 MP images without problems on a typical windows machine
*/
virtual void newFrame(const IplImage *im, ImageMetaData *metadata);
/* virtual void finishRecording();
*
* stops recording and waits for all images to be written to disk before proceeding
* does not close output file
*/
virtual void finishRecording();
/* virtual bool nothingLeftToCompressOrWrite();
* returns true if all images have been compressed and written to disk
*/
virtual bool nothingLeftToCompressOrWrite(bool verbose = false);
virtual void goIdle();
/* virtual void goIdle();
* stops recording; adds any queued images to last static background compressor
* then returns (does not wait for threads to finish)
*
*/
/* virtual void openOutputFile ();
* virtual void closeOutputFile ();
*
* opens, closes output files; neither needs to be called explicitly by user, but functionality is provided anyway
*
* writing thread will automatically open the output file as soon as it has stacks to write, so
* user should be sure to set a file name prior to starting recording
* output file is closed automatically on destruction, or on creation of a new output file
*/
virtual void openOutputFile ();
virtual void closeOutputFile ();
/* setNumCompressionThreads (int numThreads)
* sets the maximum number of threads used by the static background compressor
* note: does not change the number of threads used directly by this class,
* which has a separate writing threads and compression threads
*/
virtual inline void setNumCompressionThreads (int numThreads) {
maxCompressionThreads = numThreads;
}
inline TICTOC::tictoc const& NonthreadedTimer () {
return nonthreadedTimer;
}
inline TICTOC::tictoc const& WritingThreadTimer () {
return writingThreadTimer;
}
inline TICTOC::tictoc const& CompressionThreadTimer () {
return compressionThreadTimer;
}
inline TICTOC::tictoc const& InputBufferThreadTimer () {
return inputBufferThreadTimer;
}
/* bool readyForNewFrame();
* returns false if input buffer is over full & frame will be discarded
* returns true if new frame will be added to stack
*
*/
virtual bool readyForNewFrame();
std::string generateTimingReport();
virtual void numStacksWaiting (int &numToCompress, int &numToWrite);
protected:
CRITICAL_SECTION inputBufferCS;
CRITICAL_SECTION activeStackCS;
CRITICAL_SECTION compressingStackCS;
CRITICAL_SECTION imageStacksCS;
CRITICAL_SECTION outfileCS;
CRITICAL_SECTION writingStackCS;
CRITICAL_SECTION compressedStacksCS;
CRITICAL_SECTION stacksToWriteCS;
HANDLE compressionThread;
HANDLE writingThread;
HANDLE inputBufferThread;
int maxCompressionThreads;
bool compressionThreadActive;
bool writingThreadActive;
bool inputBufferThreadActive;
bool stacksLeftToCompress;
bool stacksLeftToWrite;
TICTOC::tictoc nonthreadedTimer;
TICTOC::tictoc compressionThreadTimer;
TICTOC::tictoc writingThreadTimer;
TICTOC::tictoc inputBufferThreadTimer;
int numTimesNewFrameCalled;
int numTimesFramePassedToInputBuffer;
int numTimesFramePassedToStackCompressor;
int numTimesFrameIsCompressed;
int numTimesFrameIsNotRecorded;
unsigned __stdcall compressionThreadFunction();
unsigned __stdcall writingThreadFunction();
unsigned __stdcall inputBufferThreadFunction();
static unsigned __stdcall startCompressionThread(void *ptr);
static unsigned __stdcall startWritingThread(void *ptr);
static unsigned __stdcall startInputBufferThread(void *ptr);
typedef std::pair<IplImage *, ImageMetaData *> InputImT;
std::queue<InputImT> inputBuffer;
virtual bool inputBufferEmpty();
virtual int inputBufferLength();
virtual void createStack();
virtual void addFrameToStack(IplImage **im, ImageMetaData *metadata);
virtual void setCompressionStack();
virtual void setWritingStack();
virtual void mergeCompressedStacks();
virtual void emptyInputBuffer();
private:
WindowsThreadStackCompressor(const WindowsThreadStackCompressor& orig);
void init();
};
#else
#include "LinearStackCompressor.h"
typedef LinearStackCompressor WindowsThreadStackCompressor;
#endif
#endif /* WINDOWSTHREADSTACKCOMPRESSOR_H */