  
      def set_faces(self, frame):
          """ Pass the current frame faces to faces window """
          faces = self.extracted_faces.get_faces_in_frame(frame)
          landmarks = [{"landmarksXY": face.aligned_landmarks}
                       for face in self.extracted_faces.faces]
          return FacesDisplay(faces, landmarks, self.extracted_faces.size, self.interface)
  
  
  class FrameDisplay():
 
</s> remove             return
        logger.trace("Normalizing face")
        meth = getattr(self, "normalize_{}".format(self.normalize_method.lower()))
        feed_dict["image"] = meth(feed_dict["image"])
        logger.trace("Normalized face")
 </s> add             return faces
        logger.trace("Normalizing faces")
        meth = getattr(self, "_normalize_{}".format(self.normalize_method.lower()))
        faces = [meth(face) for face in faces]
        logger.trace("Normalized faces")
        return faces </s> remove             bounding_box = face["detected_faces"][0]
 </s> add  </s> remove         Pass in a DetectedFace object, Alignments dict or bounding box dict
        (as defined in lib/plugins/extract/detect/_base.py) """
 </s> add         Pass in a DetectedFace object or Alignments dict """ </s> remove         landmarks = faces["landmarks"]
        detected_faces = faces["detected_faces"]
        final_faces = list()

        for idx, face in enumerate(detected_faces):
            detected_face = DetectedFace()
            detected_face.from_bounding_box_dict(face)
            detected_face.landmarksXY = landmarks[idx]
            final_faces.append(detected_face)
 </s> add         final_faces = [face for face in faces["detected_faces"]] </s> remove     def detected_faces(self):
        """ Detect faces from in an image """
        logger.debug("Running Detection. Phase: '%s'", self.phase)
        # If not multiprocessing, intercept the align in queue for
        # detection phase
        out_queue = self.output_queue
        while True:
            try:
                faces = out_queue.get(True, 1)
                if faces == "EOF":
                    break
                if isinstance(faces, dict) and faces.get("exception"):
                    pid = faces["exception"][0]
                    t_back = faces["exception"][1].getvalue()
                    err = "Error in child process {}. {}".format(pid, t_back)
                    raise Exception(err)
            except QueueEmpty:
                continue

            yield faces
        for process in self.processes:
            logger.trace("Joining process: %s", process)
            process.join()
            del process
        if self.final_pass:
            # Cleanup queues
            for q_name in self.queues.keys():
                queue_manager.del_queue(q_name)
            logger.debug("Detection Complete")
        else:
            logger.debug("Switching to align phase")
            self.phase = "align"
 </s> add     def _set_extractor_batchsize(self, vram_required, vram_free):
        """ Sets the batchsize of the used plugins based on their vram and
            vram_per_batch_requirements """
        batch_required = ((self._aligner.vram_per_batch * self._aligner.batchsize) +
                          (self._detector.vram_per_batch * self._detector.batchsize))
        plugin_required = vram_required + batch_required
        if plugin_required <= vram_free:
            logger.verbose("Plugin requirements within threshold: (plugin_required: %sMB, "
                           "vram_free: %sMB)", plugin_required, vram_free)
            return
        # Hacky split across 2 plugins
        available_for_batching = (vram_free - vram_required) // 2
        self._aligner.batchsize = max(1, available_for_batching // self._aligner.vram_per_batch)
        self._detector.batchsize = max(1, available_for_batching // self._detector.vram_per_batch)
        logger.verbose("Reset batchsizes: (aligner: %s, detector: %s)",
                       self._aligner.batchsize, self._detector.batchsize)

    def _join_threads(self):
        """ Join threads for current pass """
        for plugin in self._active_plugins:
            plugin.join()

    def _check_and_raise_error(self):
        """ Check all threads for errors and raise if one occurs """
        for plugin in self._active_plugins:
            if plugin.check_and_raise_error():
                return True
        return False
        landmarks = [{"landmarks_xy": face.aligned_landmarks}
  
      def set_faces(self, frame):
          """ Pass the current frame faces to faces window """
          faces = self.extracted_faces.get_faces_in_frame(frame)
        landmarks = [{"landmarks_xy": face.aligned_landmarks}
                       for face in self.extracted_faces.faces]
          return FacesDisplay(faces, landmarks, self.extracted_faces.size, self.interface)
  
  
  class FrameDisplay():
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/lib_alignments/jobs_manual.py