]> Some of my projects - aniplayer.git/commitdiff
Cleaner shutdown
authorAPTX <marek321@gmail.com>
Wed, 23 Feb 2022 12:35:21 +0000 (21:35 +0900)
committerAPTX <marek321@gmail.com>
Wed, 23 Feb 2022 12:37:42 +0000 (21:37 +0900)
Making net owned by the plugin instance is somewhat problematic.

It's only used on the worker thread, which might run when the
instance is deleted.

Also fixes a compile issue that wasn't present on windows/msvc.

featureplugins/feature_annotations/featureannotations.cpp
featureplugins/feature_annotations/featureannotations.h

index 2fc2dafae8533a57e2b3f25df23e91035ee34b1c..d2ecfe90954b4cda5f4a99bad6d30ad9ee869234 100644 (file)
@@ -2,20 +2,21 @@
 
 #include <QImage>
 #include <QLoggingCategory>
+#include <QMetaObject>
+#include <QtConcurrent>
 
-Q_LOGGING_CATEGORY(annotationsCategory, "Annotations")
-Q_LOGGING_CATEGORY(annotationsStatsCategory, "Annotations.stats")
-Q_LOGGING_CATEGORY(annotationsVerboseCategory, "Annotations.verbose")
+#include <stdexcept>
 
 #include <dlib/dnn.h>
 #include <dlib/image_saver/image_saver.h>
 
-#include <QMetaObject>
-#include <QtConcurrent>
-
 // random windows.h defines
 #undef interface
 
+Q_LOGGING_CATEGORY(annotationsCategory, "Annotations")
+Q_LOGGING_CATEGORY(annotationsStatsCategory, "Annotations.stats")
+Q_LOGGING_CATEGORY(annotationsVerboseCategory, "Annotations.verbose")
+
 using namespace std;
 using namespace dlib;
 
@@ -34,32 +35,33 @@ using detection_net_type =
                   rcon5_r<rcon5_r<rcon5_r<downsampler_r<
                       input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
 
-namespace {
-detection_net_type net;
-bool valid = false;
-} // namespace
+struct FeatureAnnoationsInstance::Private
+{
+  detection_net_type net;
+};
 
 FeatureAnnoations::FeatureAnnoations(QObject *parent) : QObject{parent} {
-  try {
-    deserialize("C:/_C/anime_face_recognition/mmod_network.dat") >> net;
-    valid = true;
-  } catch (const std::exception &ex) {
-    qCWarning(annotationsCategory)
-        << "Failed to read neural network. Error:" << ex.what();
-  }
 }
 
 FeaturePluginInstance *
 FeatureAnnoations::createInstance(QObject *instance,
                                   PlayerFeaturePluginInterface *interface) {
-  if (!valid)
-    throw std::exception{"Network failed to initialize"};
   return new FeatureAnnoationsInstance(instance, interface);
 }
 
 FeatureAnnoationsInstance::FeatureAnnoationsInstance(
     QObject *instance, PlayerFeaturePluginInterface *player, QObject *)
-    : FeaturePluginInstance{instance, player} {
+    : FeaturePluginInstance{instance, player},
+      m_private{std::make_unique<Private>()} {
+  try {
+    deserialize("/mnt/windows/_C/anime_face_recognition/"
+                "mmod_network-1000-labeled-adjusted.dat") >>
+        m_private->net;
+  } catch (const std::exception &ex) {
+    qCWarning(annotationsCategory)
+        << "Failed to read neural network. Error:" << ex.what();
+    throw;
+  }
   qCDebug(annotationsCategory) << "Registering with instance" << instance;
 
   connect(&m_watcher, SIGNAL(finished()), this, SLOT(onResultReady()));
@@ -76,10 +78,11 @@ FeatureAnnoationsInstance::FeatureAnnoationsInstance(
   toggleAnnotations();
 }
 
+FeatureAnnoationsInstance::~FeatureAnnoationsInstance() = default;
 
-QList<FeaturePluginInstance::Action> FeatureAnnoationsInstance::featurePluginActions() const
-{
-    return {Action{"Enable annotations", "P", SLOT()}};
+QList<FeaturePluginInstance::Action>
+FeatureAnnoationsInstance::featurePluginActions() const {
+  return {Action{"Enable annotations", "P", SLOT()}};
 }
 
 void FeatureAnnoationsInstance::onFrameChanged(const QImage &image) {
@@ -93,8 +96,9 @@ void FeatureAnnoationsInstance::onFrameChanged(const QImage &image) {
 
   qCDebug(annotationsVerboseCategory) << "Starting annotation detection...";
 
+  auto &prv = *m_private;
   auto future = QtConcurrent::run(
-      [](QImage image) -> PlayerFeaturePluginInterface::AnnotationList {
+      [&prv](QImage image) -> PlayerFeaturePluginInterface::AnnotationList {
         try {
           const int maxHeight{600};
           if (image.size().height() > maxHeight)
@@ -114,7 +118,7 @@ void FeatureAnnoationsInstance::onFrameChanged(const QImage &image) {
 
           // dlib::save_bmp(img, "testimage.bmp");
 
-          auto dets = net(img);
+          auto dets = prv.net(img);
           PlayerFeaturePluginInterface::AnnotationList al;
           for (auto &&d : dets)
             al << PlayerFeaturePluginInterface::Annotation{
index d04c9b9a60b34c80e5f6556cb27fd8a9b675dd8f..d0403b783c9cd51b98742f2031602ca5de3379c8 100644 (file)
@@ -30,7 +30,9 @@ public:
 class FeatureAnnoationsInstance : public QObject, public FeaturePluginInstance {
   Q_OBJECT
 public:
-  FeatureAnnoationsInstance(QObject *instance, PlayerFeaturePluginInterface *, QObject *parent = nullptr);
+  FeatureAnnoationsInstance(QObject *instance, PlayerFeaturePluginInterface *,
+                            QObject *parent = nullptr);
+  ~FeatureAnnoationsInstance() override;
 
   // FeaturePluginInstance interface
   QList<Action> featurePluginActions() const override;
@@ -46,6 +48,8 @@ private:
   void toggleAnnotations();
 
   bool m_enabled = false;
+  struct Private;
+  std::unique_ptr<Private> m_private;
   QTimer m_fpsTimer;
   int m_fpsCounter = 0;
   QFutureWatcher<PlayerFeaturePluginInterface::AnnotationList> m_watcher;