Commit f2d87ed5c3809192d36366452b36905e1c63ff59

Authored by Charles Otto
1 parent a8340241

Proper support for usign the same Stream transform more than once

Showing 1 changed file with 65 additions and 4 deletions
openbr/plugins/stream.cpp
@@ -162,6 +162,7 @@ public: @@ -162,6 +162,7 @@ public:
162 { 162 {
163 final_frame = -1; 163 final_frame = -1;
164 last_issued = -2; 164 last_issued = -2;
  165 + last_received = -3;
165 for (int i=0; i < maxFrames;i++) 166 for (int i=0; i < maxFrames;i++)
166 { 167 {
167 allFrames.addItem(new FrameData()); 168 allFrames.addItem(new FrameData());
@@ -194,30 +195,43 @@ public: @@ -194,30 +195,43 @@ public:
194 // The datasource broke. 195 // The datasource broke.
195 if (!res) { 196 if (!res) {
196 allFrames.addItem(aFrame); 197 allFrames.addItem(aFrame);
197 - QMutexLocker lock(&last_frame_update);  
198 198
  199 + QMutexLocker lock(&last_frame_update);
  200 + // Did we already receive the last frame?
199 final_frame = last_issued; 201 final_frame = last_issued;
200 - if (final_frame == last_received) 202 +
  203 + // We got the last frame before the data source broke,
  204 + // better pulse lastReturned
  205 + if (final_frame == last_received) {
201 lastReturned.wakeAll(); 206 lastReturned.wakeAll();
  207 + }
202 else if (final_frame < last_received) 208 else if (final_frame < last_received)
203 std::cout << "Bad last frame " << final_frame << " but received " << last_received << std::endl; 209 std::cout << "Bad last frame " << final_frame << " but received " << last_received << std::endl;
  210 +
204 return NULL; 211 return NULL;
205 } 212 }
206 last_issued = aFrame->sequenceNumber; 213 last_issued = aFrame->sequenceNumber;
207 return aFrame; 214 return aFrame;
208 } 215 }
209 216
  217 + // Returns true if the frame returned was the last
  218 + // frame issued, false otherwise
210 bool returnFrame(FrameData * inputFrame) 219 bool returnFrame(FrameData * inputFrame)
211 { 220 {
212 allFrames.addItem(inputFrame); 221 allFrames.addItem(inputFrame);
213 222
  223 + bool rval = false;
  224 +
214 QMutexLocker lock(&last_frame_update); 225 QMutexLocker lock(&last_frame_update);
215 last_received = inputFrame->sequenceNumber; 226 last_received = inputFrame->sequenceNumber;
  227 +
216 if (inputFrame->sequenceNumber == final_frame) { 228 if (inputFrame->sequenceNumber == final_frame) {
  229 + // We just received the last frame, better pulse
217 lastReturned.wakeAll(); 230 lastReturned.wakeAll();
  231 + rval = true;
218 } 232 }
219 233
220 - return this->final_frame != -1; 234 + return rval;
221 } 235 }
222 236
223 void waitLast() 237 void waitLast()
@@ -252,6 +266,7 @@ public: @@ -252,6 +266,7 @@ public:
252 { 266 {
253 final_frame = -1; 267 final_frame = -1;
254 last_issued = -2; 268 last_issued = -2;
  269 + last_received = -3;
255 270
256 next_idx = 0; 271 next_idx = 0;
257 basis = input; 272 basis = input;
@@ -312,6 +327,7 @@ public: @@ -312,6 +327,7 @@ public:
312 next_sequence = 0; 327 next_sequence = 0;
313 final_frame = -1; 328 final_frame = -1;
314 last_issued = -2; 329 last_issued = -2;
  330 + last_received = -3;
315 331
316 data_ok = current_idx < basis.size(); 332 data_ok = current_idx < basis.size();
317 return data_ok; 333 return data_ok;
@@ -380,6 +396,7 @@ public: @@ -380,6 +396,7 @@ public:
380 bool open_res = false; 396 bool open_res = false;
381 final_frame = -1; 397 final_frame = -1;
382 last_issued = -2; 398 last_issued = -2;
  399 + last_received = -3;
383 400
384 // Input has no matrices? Its probably a video that hasn't been loaded yet 401 // Input has no matrices? Its probably a video that hasn't been loaded yet
385 if (input.empty()) { 402 if (input.empty()) {
@@ -439,6 +456,8 @@ public: @@ -439,6 +456,8 @@ public:
439 456
440 int stage_id; 457 int stage_id;
441 458
  459 + virtual void reset()=0;
  460 +
442 protected: 461 protected:
443 int thread_count; 462 int thread_count;
444 463
@@ -490,6 +509,11 @@ public: @@ -490,6 +509,11 @@ public:
490 (void) input; 509 (void) input;
491 return true; 510 return true;
492 } 511 }
  512 +
  513 + void reset()
  514 + {
  515 + // nothing to do.
  516 + }
493 }; 517 };
494 518
495 519
@@ -512,6 +536,14 @@ public: @@ -512,6 +536,14 @@ public:
512 delete inputBuffer; 536 delete inputBuffer;
513 } 537 }
514 538
  539 + void reset()
  540 + {
  541 + QWriteLocker writeLock(&statusLock);
  542 + currentStatus = STOPPING;
  543 + next_target = 0;
  544 + }
  545 +
  546 +
515 int next_target; 547 int next_target;
516 enum Status 548 enum Status
517 { 549 {
@@ -631,8 +663,11 @@ public: @@ -631,8 +663,11 @@ public:
631 // Calledfrom a different thread than run. 663 // Calledfrom a different thread than run.
632 bool tryAcquireNextStage(FrameData *& input) 664 bool tryAcquireNextStage(FrameData *& input)
633 { 665 {
634 - dataSource.returnFrame(input); 666 + bool was_last = dataSource.returnFrame(input);
635 input = NULL; 667 input = NULL;
  668 + if (was_last) {
  669 + return false;
  670 + }
636 671
637 if (!dataSource.isOpen()) 672 if (!dataSource.isOpen())
638 return false; 673 return false;
@@ -673,6 +708,12 @@ public: @@ -673,6 +708,12 @@ public:
673 private: 708 private:
674 TemplateList collectedOutput; 709 TemplateList collectedOutput;
675 public: 710 public:
  711 + void reset()
  712 + {
  713 + collectedOutput.clear();
  714 + SingleThreadStage::reset();
  715 + }
  716 +
676 FrameData * run(FrameData * input, bool & should_continue) 717 FrameData * run(FrameData * input, bool & should_continue)
677 { 718 {
678 if (input == NULL) { 719 if (input == NULL) {
@@ -767,8 +808,28 @@ public: @@ -767,8 +808,28 @@ public:
767 readStage->dataSource.waitLast(); 808 readStage->dataSource.waitLast();
768 QThreadPool::globalInstance()->reserveThread(); 809 QThreadPool::globalInstance()->reserveThread();
769 810
  811 + TemplateList final_output;
  812 +
  813 + // Push finalize through the stages
  814 + for (int i=0; i < this->transforms.size(); i++)
  815 + {
  816 + TemplateList output_set;
  817 + transforms[i]->finalize(output_set);
  818 +
  819 + for (int j=i+1; j < transforms.size();j++)
  820 + {
  821 + transforms[j]->projectUpdate(output_set);
  822 + }
  823 + final_output.append(output_set);
  824 + }
  825 +
770 // dst is set to all output received by the final stage 826 // dst is set to all output received by the final stage
771 dst = collectionStage->getOutput(); 827 dst = collectionStage->getOutput();
  828 + dst.append(final_output);
  829 +
  830 + foreach(ProcessingStage * stage, processingStages) {
  831 + stage->reset();
  832 + }
772 } 833 }
773 834
774 virtual void finalize(TemplateList & output) 835 virtual void finalize(TemplateList & output)