Commit 302e502136c35d51f3b355f3e35c394b6124b82f

Authored by Charles Otto
1 parent 24229280

Explicitly surface the behavior of the end of a stream as a transform

By default, all processed templates are collected, and output at the end
of the call to projectUpdate, but it is now possible to e.g. simply discard all
results, if nothing more needs to be done with the processed templates.
openbr/core/core.cpp
... ... @@ -198,12 +198,10 @@ struct AlgorithmCore
198 198 QScopedPointer<Transform> outputTform(Transform::make(outputDesc, NULL));
199 199 stages.append(outputTform.data());
200 200 stages.append(progressCounter.data());
201   - QScopedPointer<Transform> discard(Transform::make("Discard",NULL));
202   - stages.append(discard.data());
203 201  
204 202 QScopedPointer<Transform> pipeline(br::pipeTransforms(stages));
205 203  
206   - QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery)"));
  204 + QScopedPointer<Transform> stream(br::wrapTransform(pipeline.data(), "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)"));
207 205  
208 206 TemplateList data, output;
209 207 data.append(input);
... ... @@ -486,8 +484,6 @@ struct AlgorithmCore
486 484  
487 485 // The ProgressCounter transform will simply provide a display about the number of rows completed.
488 486 compareOutput.append(progressCounter.data());
489   - QScopedPointer<Transform> discard(Transform::make("Discard",NULL));
490   - compareOutput.append(discard.data());
491 487  
492 488 // With this, we have set up a transform which (optionally) enrolls templates, compares them
493 489 // against a gallery, and outputs them.
... ... @@ -495,7 +491,7 @@ struct AlgorithmCore
495 491  
496 492 // Now, we will give that base transform to a stream, which will incrementally read the row gallery
497 493 // and pass the transforms it reads through the base algorithm.
498   - QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery)"));
  494 + QScopedPointer<Transform> streamWrapper(br::wrapTransform(pipeline, "Stream(readMode=StreamGallery, endPoint=DiscardTemplates)"));
499 495  
500 496 // We set up a template containing the rowGallery we want to compare.
501 497 TemplateList rowGalleryTemplate;
... ...
openbr/plugins/misc.cpp
... ... @@ -278,6 +278,23 @@ class DiscardTransform : public UntrainableMetaTransform
278 278  
279 279 BR_REGISTER(Transform, DiscardTransform)
280 280  
  281 +class DiscardTemplatesTransform : public UntrainableMetaTransform
  282 +{
  283 + Q_OBJECT
  284 +
  285 + void project(const Template &src, Template &dst) const
  286 + {
  287 + (void) src; (void) dst;
  288 + qFatal("Incorrect project called on DiscardTemplatesTransform");
  289 + }
  290 + void project(const TemplateList &src, TemplateList &dst) const
  291 + {
  292 + (void) src;
  293 + dst.clear();
  294 + }
  295 +};
  296 +BR_REGISTER(Transform, DiscardTemplatesTransform)
  297 +
281 298 /*!
282 299 * \ingroup transforms
283 300 * \brief Removes all but the first matrix from the template.
... ...
openbr/plugins/stream.cpp
... ... @@ -1085,6 +1085,32 @@ public:
1085 1085  
1086 1086 };
1087 1087  
  1088 +class CollectOutputTransform : public TimeVaryingTransform
  1089 +{
  1090 + Q_OBJECT
  1091 +public:
  1092 + CollectOutputTransform() : TimeVaryingTransform(false, false) {}
  1093 +
  1094 + TemplateList data;
  1095 +
  1096 + void projectUpdate(const TemplateList &src, TemplateList &dst)
  1097 + {
  1098 + (void) dst;
  1099 + data.append(src);
  1100 + }
  1101 +
  1102 + void finalize(TemplateList & output)
  1103 + {
  1104 + output = data;
  1105 + data.clear();
  1106 + }
  1107 + void train(const TemplateList &data)
  1108 + {
  1109 + (void) data;
  1110 + }
  1111 +};
  1112 +BR_REGISTER(Transform, CollectOutputTransform)
  1113 +
1088 1114 // This stage reads new frames from the data source.
1089 1115 class ReadStage : public SingleThreadStage
1090 1116 {
... ... @@ -1204,11 +1230,12 @@ class DirectStreamTransform : public CompositeTransform
1204 1230 {
1205 1231 Q_OBJECT
1206 1232 public:
1207   -
1208 1233 Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames)
1209 1234 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode)
  1235 + Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true)
1210 1236 BR_PROPERTY(int, activeFrames, 100)
1211 1237 BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto)
  1238 + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput"))
1212 1239  
1213 1240 friend class StreamTransfrom;
1214 1241  
... ... @@ -1349,22 +1376,19 @@ public:
1349 1376 }
1350 1377 final_output.append(output_set);
1351 1378 }
  1379 + endPoint->projectUpdate(final_output);
1352 1380  
1353 1381 // Clear dst, since we set it to src so that the datasource could open it
1354 1382 dst.clear();
1355 1383  
1356 1384 // dst is set to all output received by the final stage, along
1357 1385 // with anything output via the calls to finalize.
1358   - foreach (const TemplateList &list, collector->sets)
1359   - dst.append(list);
1360   -
1361   - collector->sets.clear();
1362   -
1363   - dst.append(final_output);
  1386 + TemplateList output;
  1387 + endPoint->finalize(output);
  1388 + dst.append(output);
1364 1389  
1365 1390 foreach (ProcessingStage *stage, processingStages)
1366 1391 stage->reset();
1367   -
1368 1392 }
1369 1393  
1370 1394  
... ... @@ -1387,7 +1411,7 @@ public:
1387 1411 QMutexLocker poolLock(&poolsAccess);
1388 1412 QHash<QObject *, QThreadPool *>::Iterator it;
1389 1413 if (!pools.contains(this->parent())) {
1390   - it = pools.insert(this->parent(), new QThreadPool(this->parent()));
  1414 + it = pools.insert(this->parent(), new QThreadPool());
1391 1415 it.value()->setMaxThreadCount(Globals->parallelism);
1392 1416 }
1393 1417 else it = pools.find(this->parent());
... ... @@ -1440,7 +1464,7 @@ public:
1440 1464 // We also have the last stage, which just puts the output of the
1441 1465 // previous stages on a template list.
1442 1466 collectionStage = new SingleThreadStage(prev_stage_variance);
1443   - collectionStage->transform = this->collector.data();
  1467 + collectionStage->transform = this->endPoint;
1444 1468  
1445 1469  
1446 1470 processingStages.append(collectionStage);
... ... @@ -1456,11 +1480,6 @@ public:
1456 1480 collectionStage->nextStage = readStage;
1457 1481 }
1458 1482  
1459   - DirectStreamTransform()
1460   - {
1461   - this->collector = QSharedPointer<CollectSets>(new CollectSets());
1462   - }
1463   -
1464 1483 ~DirectStreamTransform()
1465 1484 {
1466 1485 // Delete all the stages
... ... @@ -1476,7 +1495,6 @@ protected:
1476 1495  
1477 1496 ReadStage *readStage;
1478 1497 SingleThreadStage *collectionStage;
1479   - QSharedPointer<CollectSets> collector;
1480 1498  
1481 1499 QList<ProcessingStage *> processingStages;
1482 1500  
... ... @@ -1525,11 +1543,13 @@ public:
1525 1543 {
1526 1544 }
1527 1545  
  1546 + Q_PROPERTY(br::Transform* endPoint READ get_endPoint WRITE set_endPoint RESET reset_endPoint STORED true)
1528 1547 Q_PROPERTY(int activeFrames READ get_activeFrames WRITE set_activeFrames RESET reset_activeFrames)
1529 1548 Q_PROPERTY(br::Idiocy::StreamModes readMode READ get_readMode WRITE set_readMode RESET reset_readMode)
1530 1549  
1531 1550 BR_PROPERTY(int, activeFrames, 100)
1532 1551 BR_PROPERTY(br::Idiocy::StreamModes, readMode, br::Idiocy::Auto)
  1552 + BR_PROPERTY(br::Transform*, endPoint, make("CollectOutput"))
1533 1553  
1534 1554 bool timeVarying() const { return true; }
1535 1555  
... ... @@ -1571,6 +1591,7 @@ public:
1571 1591 basis->transforms.clear();
1572 1592 basis->activeFrames = this->activeFrames;
1573 1593 basis->readMode = this->readMode;
  1594 + basis->endPoint = this->endPoint;
1574 1595  
1575 1596 // We need at least a CompositeTransform * to acess transform's children.
1576 1597 CompositeTransform *downcast = dynamic_cast<CompositeTransform *> (transform);
... ...