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 29 class SharedBuffer
30 30 {
31 31 public:
32   - SharedBuffer(int _maxItems = 200) : maxItems(_maxItems) {}
  32 + SharedBuffer(int _maxItems = 200000) : maxItems(_maxItems) {}
33 33 virtual ~SharedBuffer() {}
34 34  
35 35 virtual void addItem(FrameData * input)=0;
... ... @@ -49,7 +49,7 @@ protected:
49 49 class SingleBuffer : public SharedBuffer
50 50 {
51 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 54 void stoppedInput()
55 55 {
... ... @@ -119,40 +119,61 @@ private:
119 119 class DataSource
120 120 {
121 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 162 virtual void close() = 0;
127   - virtual bool open(Template & input) = 0;
  163 + virtual bool open(Template & output) = 0;
128 164 virtual bool isOpen() = 0;
  165 +
  166 + virtual bool getNext(FrameData & input) = 0;
  167 +
  168 +protected:
  169 + SingleBuffer allFrames;
129 170 };
130 171  
131 172 // Read a video frame by frame using cv::VideoCapture
132 173 class VideoDataSource : public DataSource
133 174 {
134 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 178 bool open(Template &input)
158 179 {
... ... @@ -167,6 +188,24 @@ public:
167 188 void close() { video.release(); }
168 189  
169 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 209 cv::VideoCapture video;
171 210 Template basis;
172 211 int next_idx;
... ... @@ -177,21 +216,9 @@ private:
177 216 class TemplateDataSource : public DataSource
178 217 {
179 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 224 bool open(Template &input)
... ... @@ -211,6 +238,20 @@ public:
211 238 }
212 239  
213 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 255 Template basis;
215 256 int current_idx;
216 257 int next_sequence;
... ... @@ -232,12 +273,6 @@ public:
232 273 close();
233 274 }
234 275  
235   - FrameData * getNext()
236   - {
237   - if (!isOpen()) return NULL;
238   - return actualSource->getNext();
239   - }
240   -
241 276 void close()
242 277 {
243 278 if (actualSource) {
... ... @@ -253,13 +288,13 @@ public:
253 288 bool open_res = false;
254 289 // Input has no matrices? Its probably a video that hasn't been loaded yet
255 290 if (input.empty()) {
256   - actualSource = new VideoDataSource();
  291 + actualSource = new VideoDataSource(0);
257 292 open_res = actualSource->open(input);
258 293 qDebug("created video resource status %d", open_res);
259 294 }
260 295 else {
261 296 // create frame dealer
262   - actualSource = new TemplateDataSource();
  297 + actualSource = new TemplateDataSource(0);
263 298 open_res = actualSource->open(input);
264 299 }
265 300 if (!isOpen()) {
... ... @@ -274,6 +309,11 @@ public:
274 309  
275 310 protected:
276 311 DataSource * actualSource;
  312 + bool getNext(FrameData & output)
  313 + {
  314 + return actualSource->getNext(output);
  315 + }
  316 +
277 317 };
278 318  
279 319 class ProcessingStage : public QRunnable
... ... @@ -347,7 +387,8 @@ public:
347 387 {
348 388 forever
349 389 {
350   - FrameData * aFrame = dataSource.getNext();
  390 + //FrameData * aFrame = dataSource.getNext();
  391 + FrameData * aFrame = dataSource.getFrame();
351 392 if (aFrame == NULL)
352 393 break;
353 394 outputBuffer->addItem(aFrame);
... ... @@ -367,6 +408,7 @@ public:
367 408 private:
368 409 TemplateList collectedOutput;
369 410 public:
  411 + DataSource * data;
370 412 void run()
371 413 {
372 414 forever
... ... @@ -377,7 +419,8 @@ public:
377 419 break;
378 420 // Just put the item on collectedOutput
379 421 collectedOutput.append(frame->data);
380   - delete frame;
  422 + // Return the frame to the input frame buffer
  423 + data->returnFrame(frame);
381 424 }
382 425 this->markStop();
383 426 }
... ... @@ -505,6 +548,7 @@ public:
505 548 }
506 549  
507 550 collectionStage.inputBuffer = sharedBuffers.last();
  551 + collectionStage.data = &readStage.dataSource;
508 552 collectionStage.stage_id = next_stage_id;
509 553 }
510 554  
... ...