Commit 46985ff5538ba29ff04f2b9298a49da1a483c4f3

Authored by Charles Otto
1 parent e9a774f1

Buffer management via scarcity

Rather than putting limits on the number of items in the buffers of individual
processing stages of a stream, put a limit on the total number of frames
actively being processed by the stream.
Showing 1 changed file with 95 additions and 51 deletions
sdk/plugins/stream.cpp
@@ -29,7 +29,7 @@ public: @@ -29,7 +29,7 @@ public:
29 class SharedBuffer 29 class SharedBuffer
30 { 30 {
31 public: 31 public:
32 - SharedBuffer(int _maxItems = 200) : maxItems(_maxItems) {} 32 + SharedBuffer(int _maxItems = 200000) : maxItems(_maxItems) {}
33 virtual ~SharedBuffer() {} 33 virtual ~SharedBuffer() {}
34 34
35 virtual void addItem(FrameData * input)=0; 35 virtual void addItem(FrameData * input)=0;
@@ -49,7 +49,7 @@ protected: @@ -49,7 +49,7 @@ protected:
49 class SingleBuffer : public SharedBuffer 49 class SingleBuffer : public SharedBuffer
50 { 50 {
51 public: 51 public:
52 - SingleBuffer(unsigned _maxItems = 20) : SharedBuffer(_maxItems) { no_input = false; } 52 + SingleBuffer(unsigned _maxItems = 20000) : SharedBuffer(_maxItems) { no_input = false; }
53 53
54 void stoppedInput() 54 void stoppedInput()
55 { 55 {
@@ -119,40 +119,61 @@ private: @@ -119,40 +119,61 @@ private:
119 class DataSource 119 class DataSource
120 { 120 {
121 public: 121 public:
122 - DataSource() {}  
123 - virtual ~DataSource() {} 122 + DataSource(int maxFrames=100)
  123 + {
  124 + for (int i=0; i < maxFrames;i++)
  125 + {
  126 + allFrames.addItem(new FrameData());
  127 + }
  128 + allFrames.startInput();
  129 + }
  130 +
  131 + virtual ~DataSource()
  132 + {
  133 + allFrames.stoppedInput();
  134 + while (true)
  135 + {
  136 + FrameData * frame = allFrames.getItem();
  137 + if (frame == NULL)
  138 + break;
  139 + delete frame;
  140 + }
  141 + }
  142 +
  143 + FrameData * getFrame()
  144 + {
  145 + FrameData * aFrame = allFrames.getItem();
  146 + aFrame->data.clear();
  147 + aFrame->sequenceNumber = -1;
  148 +
  149 + bool res = getNext(*aFrame);
  150 + if (!res) {
  151 + allFrames.addItem(aFrame);
  152 + return NULL;
  153 + }
  154 + return aFrame;
  155 + }
  156 +
  157 + void returnFrame(FrameData * inputFrame)
  158 + {
  159 + allFrames.addItem(inputFrame);
  160 + }
124 161
125 - virtual FrameData * getNext() = 0;  
126 virtual void close() = 0; 162 virtual void close() = 0;
127 - virtual bool open(Template & input) = 0; 163 + virtual bool open(Template & output) = 0;
128 virtual bool isOpen() = 0; 164 virtual bool isOpen() = 0;
  165 +
  166 + virtual bool getNext(FrameData & input) = 0;
  167 +
  168 +protected:
  169 + SingleBuffer allFrames;
129 }; 170 };
130 171
131 // Read a video frame by frame using cv::VideoCapture 172 // Read a video frame by frame using cv::VideoCapture
132 class VideoDataSource : public DataSource 173 class VideoDataSource : public DataSource
133 { 174 {
134 public: 175 public:
135 - VideoDataSource() {}  
136 -  
137 - FrameData * getNext()  
138 - {  
139 - if (!isOpen())  
140 - return NULL;  
141 -  
142 - FrameData * output = new FrameData();  
143 - output->data.append(Template(basis.file));  
144 - output->data.last().append(cv::Mat());  
145 -  
146 - output->sequenceNumber = next_idx;  
147 - next_idx++;  
148 -  
149 - bool res = video.read(output->data.last().last());  
150 - if (!res) {  
151 - delete output;  
152 - return NULL;  
153 - }  
154 - return output;  
155 - } 176 + VideoDataSource(int maxFrames) : DataSource(maxFrames) {}
156 177
157 bool open(Template &input) 178 bool open(Template &input)
158 { 179 {
@@ -167,6 +188,24 @@ public: @@ -167,6 +188,24 @@ public:
167 void close() { video.release(); } 188 void close() { video.release(); }
168 189
169 private: 190 private:
  191 + bool getNext(FrameData & output)
  192 + {
  193 + if (!isOpen())
  194 + return false;
  195 +
  196 + output.data.append(Template(basis.file));
  197 + output.data.last().append(cv::Mat());
  198 +
  199 + output.sequenceNumber = next_idx;
  200 + next_idx++;
  201 +
  202 + bool res = video.read(output.data.last().last());
  203 + if (!res) {
  204 + return false;
  205 + }
  206 + return true;
  207 + }
  208 +
170 cv::VideoCapture video; 209 cv::VideoCapture video;
171 Template basis; 210 Template basis;
172 int next_idx; 211 int next_idx;
@@ -177,21 +216,9 @@ private: @@ -177,21 +216,9 @@ private:
177 class TemplateDataSource : public DataSource 216 class TemplateDataSource : public DataSource
178 { 217 {
179 public: 218 public:
180 - TemplateDataSource() { current_idx = INT_MAX; }  
181 -  
182 - FrameData * getNext() 219 + TemplateDataSource(int maxFrames) : DataSource(maxFrames)
183 { 220 {
184 - if (!isOpen())  
185 - return NULL;  
186 -  
187 - FrameData * output = new FrameData();  
188 - output->data.append(basis[current_idx]);  
189 - current_idx++;  
190 -  
191 - output->sequenceNumber = next_sequence;  
192 - next_sequence++;  
193 -  
194 - return output; 221 + current_idx = INT_MAX;
195 } 222 }
196 223
197 bool open(Template &input) 224 bool open(Template &input)
@@ -211,6 +238,20 @@ public: @@ -211,6 +238,20 @@ public:
211 } 238 }
212 239
213 private: 240 private:
  241 + bool getNext(FrameData & output)
  242 + {
  243 + if (!isOpen())
  244 + return false;
  245 +
  246 + output.data.append(basis[current_idx]);
  247 + current_idx++;
  248 +
  249 + output.sequenceNumber = next_sequence;
  250 + next_sequence++;
  251 +
  252 + return true;
  253 + }
  254 +
214 Template basis; 255 Template basis;
215 int current_idx; 256 int current_idx;
216 int next_sequence; 257 int next_sequence;
@@ -232,12 +273,6 @@ public: @@ -232,12 +273,6 @@ public:
232 close(); 273 close();
233 } 274 }
234 275
235 - FrameData * getNext()  
236 - {  
237 - if (!isOpen()) return NULL;  
238 - return actualSource->getNext();  
239 - }  
240 -  
241 void close() 276 void close()
242 { 277 {
243 if (actualSource) { 278 if (actualSource) {
@@ -253,13 +288,13 @@ public: @@ -253,13 +288,13 @@ public:
253 bool open_res = false; 288 bool open_res = false;
254 // Input has no matrices? Its probably a video that hasn't been loaded yet 289 // Input has no matrices? Its probably a video that hasn't been loaded yet
255 if (input.empty()) { 290 if (input.empty()) {
256 - actualSource = new VideoDataSource(); 291 + actualSource = new VideoDataSource(0);
257 open_res = actualSource->open(input); 292 open_res = actualSource->open(input);
258 qDebug("created video resource status %d", open_res); 293 qDebug("created video resource status %d", open_res);
259 } 294 }
260 else { 295 else {
261 // create frame dealer 296 // create frame dealer
262 - actualSource = new TemplateDataSource(); 297 + actualSource = new TemplateDataSource(0);
263 open_res = actualSource->open(input); 298 open_res = actualSource->open(input);
264 } 299 }
265 if (!isOpen()) { 300 if (!isOpen()) {
@@ -274,6 +309,11 @@ public: @@ -274,6 +309,11 @@ public:
274 309
275 protected: 310 protected:
276 DataSource * actualSource; 311 DataSource * actualSource;
  312 + bool getNext(FrameData & output)
  313 + {
  314 + return actualSource->getNext(output);
  315 + }
  316 +
277 }; 317 };
278 318
279 class ProcessingStage : public QRunnable 319 class ProcessingStage : public QRunnable
@@ -347,7 +387,8 @@ public: @@ -347,7 +387,8 @@ public:
347 { 387 {
348 forever 388 forever
349 { 389 {
350 - FrameData * aFrame = dataSource.getNext(); 390 + //FrameData * aFrame = dataSource.getNext();
  391 + FrameData * aFrame = dataSource.getFrame();
351 if (aFrame == NULL) 392 if (aFrame == NULL)
352 break; 393 break;
353 outputBuffer->addItem(aFrame); 394 outputBuffer->addItem(aFrame);
@@ -367,6 +408,7 @@ public: @@ -367,6 +408,7 @@ public:
367 private: 408 private:
368 TemplateList collectedOutput; 409 TemplateList collectedOutput;
369 public: 410 public:
  411 + DataSource * data;
370 void run() 412 void run()
371 { 413 {
372 forever 414 forever
@@ -377,7 +419,8 @@ public: @@ -377,7 +419,8 @@ public:
377 break; 419 break;
378 // Just put the item on collectedOutput 420 // Just put the item on collectedOutput
379 collectedOutput.append(frame->data); 421 collectedOutput.append(frame->data);
380 - delete frame; 422 + // Return the frame to the input frame buffer
  423 + data->returnFrame(frame);
381 } 424 }
382 this->markStop(); 425 this->markStop();
383 } 426 }
@@ -505,6 +548,7 @@ public: @@ -505,6 +548,7 @@ public:
505 } 548 }
506 549
507 collectionStage.inputBuffer = sharedBuffers.last(); 550 collectionStage.inputBuffer = sharedBuffers.last();
  551 + collectionStage.data = &readStage.dataSource;
508 collectionStage.stage_id = next_stage_id; 552 collectionStage.stage_id = next_stage_id;
509 } 553 }
510 554