          self.args.final_process = _final.replace('-', '_')
  
          self.sort_process()
  
      def launch_aligner(self):
          """ Load the aligner plugin to retrieve landmarks """
          out_queue = queue_manager.get_queue("out")
          kwargs = {"in_queue": queue_manager.get_queue("in"),
                    "out_queue": out_queue}
  
 
</s> remove         out_queue = queue_manager.get_queue("out")
        kwargs = {"in_queue": queue_manager.get_queue("in"),
                  "out_queue": out_queue}

        for plugin in ("fan", "cv2_dnn"):
            aligner = PluginLoader.get_aligner(plugin)(loglevel=self.args.loglevel)
            process = SpawnProcess(aligner.run, **kwargs)
            event = process.event
            process.start()
            # Wait for Aligner to take init
            # The first ever load of the model for FAN has reportedly taken
            # up to 3-4 minutes, hence high timeout.
            event.wait(300)

            if not event.is_set():
                if plugin == "fan":
                    process.join()
                    logger.error("Error initializing FAN. Trying CV2-DNN")
                    continue
                else:
                    raise ValueError("Error inititalizing Aligner")
            if plugin == "cv2_dnn":
                return

            try:
                err = None
                err = out_queue.get(True, 1)
            except QueueEmpty:
                pass
            if not err:
                break
            process.join()
            logger.error("Error initializing FAN. Trying CV2-DNN")
 </s> add         kwargs = dict(in_queue=queue_manager.get_queue("in"),
                      out_queue=queue_manager.get_queue("out"),
                      queue_size=8)
        aligner = PluginLoader.get_aligner("fan")(normalize_method="hist")
        aligner.batchsize = 1
        aligner.initialize(**kwargs)
        aligner.start() </s> remove     def launch_aligner(self):
 </s> add     def _launch_aligner(self): </s> remove         out_queue = queue_manager.get_queue("out")

        d_kwargs = {"in_queue": queue_manager.get_queue("in"),
                    "out_queue": queue_manager.get_queue("align")}
        a_kwargs = {"in_queue": queue_manager.get_queue("align"),
                    "out_queue": out_queue}

        detector = PluginLoader.get_detector("manual")(loglevel=loglevel)
        detect_process = SpawnProcess(detector.run, **d_kwargs)
        d_event = detect_process.event
        detect_process.start()

        plugins = ["fan_amd"] if get_backend() == "amd" else ["fan"]
        plugins.append("cv2_dnn")
        for plugin in plugins:
            aligner = PluginLoader.get_aligner(plugin)(loglevel=loglevel,
                                                       normalize_method="hist")
            align_process = SpawnProcess(aligner.run, **a_kwargs)
            a_event = align_process.event
            align_process.start()

            # Wait for Aligner to initialize
            # The first ever load of the model for FAN has reportedly taken
            # up to 3-4 minutes, hence high timeout.
            a_event.wait(300)
            if not a_event.is_set():
                if plugin.startswith("fan"):
                    align_process.join()
                    logger.error("Error initializing FAN. Trying CV2-DNN")
                    continue
                else:
                    raise ValueError("Error inititalizing Aligner")
            if plugin == "cv2_dnn":
                break

            try:
                err = None
                err = out_queue.get(True, 1)
            except QueueEmpty:
                pass
            if not err:
                break
            align_process.join()
            logger.error("Error initializing FAN. Trying CV2-DNN")

        d_event.wait(10)
        if not d_event.is_set():
            raise ValueError("Error inititalizing Detector")

        self.extractor["detect"] = detector
        self.extractor["align"] = aligner
 </s> add         extractor = Extractor("manual", "fan", multiprocess=True, normalize_method="hist")
        self.queues["in"] = extractor.input_queue
        # Set the batchsizes to 1
        extractor.set_batchsize("detector", 1)
        extractor.set_batchsize("aligner", 1)
        extractor.launch() </s> remove     def init_extractor(self, loglevel):
 </s> add     def init_extractor(self): </s> remove     def launch(self):
        """ Launches the plugins
            This can be called multiple times depending on the phase/whether multiprocessing
            is enabled.

            If multiprocessing:
                launches both plugins, but aligner first so that it's VRAM can be allocated
                prior to giving the remaining to the detector
            If not multiprocessing:
                Launches the relevant plugin for the current phase """
        if self.is_parallel:
            logger.debug("Launching aligner and detector")
            self.launch_aligner()
            self.launch_detector()
        elif self.phase == "detect":
            logger.debug("Launching detector")
            self.launch_detector()
        else:
            logger.debug("Launching aligner")
            self.launch_aligner()
 </s> add     @staticmethod
    def _load_aligner(aligner, configfile, normalize_method):
        """ Set global arguments and load aligner plugin """
        aligner_name = aligner.replace("-", "_").lower()
        logger.debug("Loading Aligner: '%s'", aligner_name)
        aligner = PluginLoader.get_aligner(aligner_name)(configfile=configfile,
                                                         normalize_method=normalize_method)
        return aligner
    @staticmethod
    def launch_aligner():
          self.args.final_process = _final.replace('-', '_')
  
          self.sort_process()
  
    @staticmethod
    def launch_aligner():
          """ Load the aligner plugin to retrieve landmarks """
          out_queue = queue_manager.get_queue("out")
          kwargs = {"in_queue": queue_manager.get_queue("in"),
                    "out_queue": out_queue}
  
keep keep keep keep replace keep keep keep keep keep
 De-Multiprocess Extract (#871)

* requirements.txt: - Pin opencv to 4.1.1 (fixes cv2-dnn error)

* lib.face_detect.DetectedFace: change LandmarksXY to landmarks_xy. Add left, right, top, bottom attributes

* lib.model.session: Session manager for loading models into different graphs (for Nvidia + CPU)

* plugins.extract._base: New parent class for all extract plugins

* plugins.extract.pipeline. Remove MultiProcessing. Dynamically limit batchsize for Nvidia cards. Remove loglevel input

* S3FD + FAN plugins. Standardise to Keras version for all backends

* Standardize all extract plugins to new threaded codebase

* Documentation. Start implementing Numpy style docstrings for Sphinx Documentation

* Remove s3fd_amd. Change convert OTF to expect DetectedFace object

* faces_detect - clean up and documentation

* Remove PoolProcess

* Migrate manual tool to new extract workflow

* Remove AMD specific extractor code from cli and plugins

* Sort tool to new extract workflow

* Remove multiprocessing from project

* Remove multiprocessing queues from QueueManager

* Remove multiprocessing support from logger

* Move face_filter to new extraction pipeline

* Alignments landmarksXY > landmarks_xy and legacy handling

* Intercept get_backend for sphinx doc build

# Add Sphinx documentation 
tools/sort.py