mv_machine_learning: code refactoring to getOutput function
authorInki Dae <inki.dae@samsung.com>
Fri, 11 Aug 2023 06:00:46 +0000 (15:00 +0900)
committerKwanghoon Son <k.son@samsung.com>
Mon, 4 Sep 2023 04:57:02 +0000 (13:57 +0900)
[Issue type] : code refactoring

Do code refactoring to getOutput function of the concrete class,
ObjectDetection, by extracting some portion of existing getOutput function code
and moving it to a new interface function, getOutputCache.

With original version of the getOutput function, it handled the specific case
that one more get-result API are called, which in turn, it made the getOutput
function to be complicated.

Therefore, this patch drops the specific case from the getOutput function
by introducing getOutputCache interface which always returns internal
result object, _current_result instead of calling the result member function
of each concrete class which decodes raw output tensor data after the completion
of the inference.

Change-Id: I4aacb8fc55be3f63a983182b919291dcb927b0c9
Signed-off-by: Inki Dae <inki.dae@samsung.com>
25 files changed:
mv_machine_learning/common/include/itask.h
mv_machine_learning/face_recognition/include/face_recognition_adapter.h
mv_machine_learning/face_recognition/include/facenet_adapter.h
mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp
mv_machine_learning/face_recognition/src/facenet_adapter.cpp
mv_machine_learning/image_classification/include/image_classification_adapter.h
mv_machine_learning/image_classification/src/image_classification_adapter.cpp
mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h
mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h
mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp
mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp
mv_machine_learning/object_detection/include/face_detection_adapter.h
mv_machine_learning/object_detection/include/iobject_detection.h
mv_machine_learning/object_detection/include/object_detection.h
mv_machine_learning/object_detection/include/object_detection_adapter.h
mv_machine_learning/object_detection/include/object_detection_external.h
mv_machine_learning/object_detection/include/object_detection_type.h
mv_machine_learning/object_detection/src/face_detection_adapter.cpp
mv_machine_learning/object_detection/src/mv_face_detection.cpp
mv_machine_learning/object_detection/src/mv_object_detection.cpp
mv_machine_learning/object_detection/src/object_detection.cpp
mv_machine_learning/object_detection/src/object_detection_adapter.cpp
mv_machine_learning/object_detection/src/object_detection_external.cpp
mv_machine_learning/object_detection_3d/include/object_detection_3d_adapter.h
mv_machine_learning/object_detection_3d/src/object_detection_3d_adapter.cpp

index bfad5a915468436a58b23cf01a866b2ae666353c..99723b62ceaf9ee6e0f03d9842268ef2d0e1b04e 100644 (file)
@@ -39,6 +39,7 @@ public:
        virtual void perform() = 0;
        virtual void performAsync(T &t) = 0;
        virtual V &getOutput() = 0;
+       virtual V &getOutputCache() = 0;
 };
 } // namespace
 } // namespace
index b6acf6328f223af488384ccc30ad094fb296e748..69c2854e0babcf2f1a9f8758d15554084b62fba4 100644 (file)
@@ -56,6 +56,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index 17e1b261a9aede2f3d25eab26ad6270bacb19278..94cb4cd58e99be313cf49b6900fcd8dbff213a3e 100644 (file)
@@ -50,6 +50,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index a6126ef5b2c75e98aa90692b27b9ccd79a9fde1c..5464c66ea6ce9f3aab9ee1b2ddc9db48a689f01b 100644 (file)
@@ -153,6 +153,11 @@ template<typename T, typename V> V &FaceRecognitionAdapter<T, V>::getOutput()
        return _face_recognition->result();
 }
 
+template<typename T, typename V> V &FaceRecognitionAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class FaceRecognitionAdapter<FaceRecognitionInput, FaceRecognitionResult>;
 }
 }
\ No newline at end of file
index 7f16ba5f6ec3655ad0f1db8c8f906c0408bfa884..82de240b42b0d2e47573c16cd26d7f2119788d1a 100644 (file)
@@ -94,6 +94,11 @@ template<typename T, typename V> V &FacenetAdapter<T, V>::getOutput()
        return _facenet->result();
 }
 
+template<typename T, typename V> V &FacenetAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class FacenetAdapter<FacenetInput, FacenetOutput>;
 }
 }
\ No newline at end of file
index 45e493d831c9537d29677cb3d0dfa239dab7c948..0066c8e8cb1d905367feda5167ffb917cdece0e2 100644 (file)
@@ -50,6 +50,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index 4c59dd3c5ee3bb39e8f1faef567b1db9c0143680..852eb54d8221e2bf04646770c3b158414996615f 100644 (file)
@@ -112,6 +112,11 @@ template<typename T, typename V> V &ImageClassificationAdapter<T, V>::getOutput(
        return _image_classification->result();
 }
 
+template<typename T, typename V> V &ImageClassificationAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class ImageClassificationAdapter<ImageClassificationInput, ImageClassificationResult>;
 }
 }
\ No newline at end of file
index 1ea521dbe275f24fe0e186e70358cd1d69ecce5e..82f8e1c05d8832af4ba252c5674cced22fca5133 100644 (file)
@@ -56,6 +56,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index f2b7f53c38a31fefe81dee9f5e290cb48de33105..b9659f119ca7007e70f5e5ec318dd51b8e86bf56 100644 (file)
@@ -56,6 +56,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index 9fb19e0e17ff35a857ef5623c9a0290149cdba4e..90a235e32c5e099f5e884c6c19dd34d0e6d1e7a4 100644 (file)
@@ -148,6 +148,11 @@ template<typename T, typename V> V &FacialLandmarkAdapter<T, V>::getOutput()
        return _landmark_detection->result();
 }
 
+template<typename T, typename V> V &FacialLandmarkAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class FacialLandmarkAdapter<LandmarkDetectionInput, LandmarkDetectionResult>;
 }
 }
\ No newline at end of file
index 5fb6c3132e0fd5d8e9a89964435fdb1239a5802f..f7b38d7ee1d94715a3e1af26d7ccf26af7d105e9 100644 (file)
@@ -148,6 +148,11 @@ template<typename T, typename V> V &PoseLandmarkAdapter<T, V>::getOutput()
        return _landmark_detection->result();
 }
 
+template<typename T, typename V> V &PoseLandmarkAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class PoseLandmarkAdapter<LandmarkDetectionInput, LandmarkDetectionResult>;
 }
 }
\ No newline at end of file
index 50e32d16aa82e8ce2edbc841ee16aac7e8ca0c57..b6f427dc82bcef055e452b88e39aee645bf23e44 100644 (file)
@@ -56,6 +56,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index ccc735c38763e5549f171dc9adda31fbe5aaa6b4..c1c3c6b5fab296d8b0133ee006607c4caa3a831c 100644 (file)
@@ -42,6 +42,7 @@ public:
        virtual void perform(mv_source_h &mv_src) = 0;
        virtual void performAsync(ObjectDetectionInput &input) = 0;
        virtual ObjectDetectionResult &getOutput() = 0;
+       virtual ObjectDetectionResult &getOutputCache() = 0;
 };
 
 } // machine_learning
index 64ca00f6507889b56116c1f54e182c4d697e6313..70866322bf0990898485f76374beba85d2615aa0 100644 (file)
@@ -53,7 +53,6 @@ private:
        void loadLabel();
        void getEngineList();
        void getDeviceList(const char *engine_type);
-       void updateResult(ObjectDetectionResult &result);
        template<typename T>
        void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
        template<typename T> void pushToInput(ObjectDetectionQueue<T> &input);
@@ -105,6 +104,7 @@ public:
        void perform(mv_source_h &mv_src) override;
        void performAsync(ObjectDetectionInput &input) override;
        ObjectDetectionResult &getOutput() override;
+       ObjectDetectionResult &getOutputCache() override;
 };
 
 } // machine_learning
index 1650726dc3ab9c6fa7b6f554cd407daa77f295b5..41be841b7543d026116a0b643584b559f5e88336 100644 (file)
@@ -59,6 +59,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index 3768be76c77627d8227d17130bac871b8707f2b3..9034af77ce7cbc13d7b7f42c22d406c6602cb3ba 100644 (file)
@@ -54,6 +54,7 @@ public:
        void perform(mv_source_h &mv_src) override;
        void performAsync(ObjectDetectionInput &input) override;
        ObjectDetectionResult &getOutput() override;
+       ObjectDetectionResult &getOutputCache() override;
 };
 
 } // machine_learning
index bbd1fd5f82afe89c7e190803913e29d715b875d2..8c04c4b59ed6c7df5f4f0c1cf2ea12cef19d29e3 100644 (file)
@@ -47,7 +47,6 @@ template<typename T> struct ObjectDetectionQueue {
  * @details Contains object detection result.
  */
 struct ObjectDetectionResult {
-       bool is_valid {};
        unsigned int number_of_objects {};
        std::vector<unsigned int> indices;
        std::vector<std::string> names;
index 239a6d6e559c594a2b7fe9aa0df2cdf882db2cc2..1e1473da492231916ee17a3a970a03427ef6449e 100644 (file)
@@ -141,6 +141,11 @@ template<typename T, typename V> V &FaceDetectionAdapter<T, V>::getOutput()
        return _object_detection->getOutput();
 }
 
+template<typename T, typename V> V &FaceDetectionAdapter<T, V>::getOutputCache()
+{
+       return _object_detection->getOutputCache();
+}
+
 template class FaceDetectionAdapter<ObjectDetectionInput, ObjectDetectionResult>;
 }
 }
\ No newline at end of file
index 98509786598bc0f8a55e408611048121cedaa9fd..5521b1c364f46623bf5b8bfa6c117789bfb7d4a7 100644 (file)
@@ -417,7 +417,7 @@ int mv_face_detection_get_label(mv_face_detection_h handle, const unsigned int i
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
 
-               ObjectDetectionResult &result = task->getOutput();
+               ObjectDetectionResult &result = task->getOutputCache();
 
                if (result.number_of_objects <= index)
                        throw InvalidParameter("Invalid index range.");
index a22245daad84d374d5c4e250b33d3a260f01b704..c84f20dae26cfe8d100c3b0a5d2526401c5bdac6 100644 (file)
@@ -415,7 +415,7 @@ int mv_object_detection_get_label(mv_object_detection_h handle, const unsigned i
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               ObjectDetectionResult &result = task->getOutput();
+               ObjectDetectionResult &result = task->getOutputCache();
 
                if (result.number_of_objects <= index)
                        throw InvalidParameter("Invalid index range.");
index 2ebf37353345e6653739b983ad602bb82a04ebd8..14681fd84a111ab4da3ac1ccf4ce319abda8688f 100644 (file)
@@ -368,7 +368,6 @@ template<typename T> void inferenceThreadLoop(ObjectDetection *object)
                object->inference<T>(input.inputs);
 
                ObjectDetectionResult &result = object->result();
-               result.is_valid = false;
 
                object->pushToOutput(result);
 
@@ -412,30 +411,23 @@ void ObjectDetection::performAsync(ObjectDetectionInput &input)
        }
 }
 
-void ObjectDetection::updateResult(ObjectDetectionResult &result)
-{
-       _current_result = result;
-       _current_result.is_valid = true;
-}
-
 ObjectDetectionResult &ObjectDetection::getOutput()
 {
        if (_thread_handle) {
-               // There may be two or more Native APIs which utilize getOutput() function.
-               // Therefore, the current result should be kept until a new inference request is made for result consistency.
-               if (_current_result.is_valid)
-                       return _current_result;
-
                if (isOutputQueueEmpty())
-                       throw InvalidOperation("Output queue is empty.");
-
-               ObjectDetectionResult result = popFromOutput();
-               updateResult(result);
+                       throw InvalidOperation("No inference result.");
 
-               return _current_result;
+               _current_result = popFromOutput();
+       } else {
+               _current_result = result();
        }
 
-       return result();
+       return _current_result;
+}
+
+ObjectDetectionResult &ObjectDetection::getOutputCache()
+{
+       return _current_result;
 }
 
 void ObjectDetection::getOutputNames(vector<string> &names)
@@ -491,6 +483,7 @@ ObjectDetectionResult ObjectDetection::popFromOutput()
 {
        lock_guard<mutex> lock(_outgoing_queue_mutex);
        ObjectDetectionResult output = _outgoing_queue.front();
+
        _outgoing_queue.pop();
 
        return output;
index 4cc86b7aa4943dece3cae551185df68728c92949..eb80a63b96ba0fd802eb900ddaf31456c646d082 100644 (file)
@@ -169,6 +169,11 @@ template<typename T, typename V> V &ObjectDetectionAdapter<T, V>::getOutput()
        return _object_detection->getOutput();
 }
 
+template<typename T, typename V> V &ObjectDetectionAdapter<T, V>::getOutputCache()
+{
+       return _object_detection->getOutputCache();
+}
+
 template<typename T, typename V> void ObjectDetectionAdapter<T, V>::performAsync(T &t)
 {
        _object_detection->performAsync(t);
index f23041292cf09bb23689bee3a59e548a2fd31347..08ef64707cf6b9d40b24020bb28381f810e3a4d9 100644 (file)
@@ -135,7 +135,14 @@ void ObjectDetectionExternal::performAsync(ObjectDetectionInput &input)
 
 ObjectDetectionResult &ObjectDetectionExternal::getOutput()
 {
-       return _object_detection_plugin->getOutput();
+       _current_result = _object_detection_plugin->getOutput();
+
+       return _current_result;
+}
+
+ObjectDetectionResult &ObjectDetectionExternal::getOutputCache()
+{
+       return _current_result;
 }
 
 }
index 542dc85717ab61ed22cda4d421b005f8a416ce68..192dca824f9e8edc88150f42086ad6cbe87f4b28 100644 (file)
@@ -56,6 +56,7 @@ public:
        void perform() override;
        void performAsync(T &t) override;
        V &getOutput() override;
+       V &getOutputCache() override;
 };
 
 } // machine_learning
index b72274f033e14e9a036831f21259a7b450f40387..4c0ca5c1e2df18c68edce7d81ec6da2f121bf208 100644 (file)
@@ -134,6 +134,11 @@ template<typename T, typename V> V &ObjectDetection3dAdapter<T, V>::getOutput()
        return _object_detection_3d->result();
 }
 
+template<typename T, typename V> V &ObjectDetection3dAdapter<T, V>::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
 template class ObjectDetection3dAdapter<ObjectDetection3dInput, ObjectDetection3dResult>;
 }
 }
\ No newline at end of file