Commit f2d87ed5c3809192d36366452b36905e1c63ff59
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) |