          to_process = self.process_item_count()
          size = self.args.size if hasattr(self.args, "size") else 256
          exception = False
  
          for phase in range(self.extractor.passes):
              if exception:
                  break
              is_final = self.extractor.final_pass
              detected_faces = dict()
              self.extractor.launch()
 
</s> remove             is_final = self.extractor.final_pass
 </s> add             is_final = self._extractor.final_pass </s> remove     def save_faces(self):
        """ Save the generated faces """
        logger.debug("Save Faces: Start")
        while True:
            if self.save_queue.shutdown.is_set():
                logger.debug("Save Queue: Stop signal received. Terminating")
                break
            item = self.save_queue.get()
            logger.trace(item)
            if item == "EOF":
                break
            filename, face = item

            logger.trace("Saving face: '%s'", filename)
            try:
                with open(filename, "wb") as out_file:
                    out_file.write(face)
            except Exception as err:  # pylint: disable=broad-except
                logger.error("Failed to save image '%s'. Original Error: %s", filename, err)
                continue
        logger.debug("Save Faces: Complete")

    def process_item_count(self):
        """ Return the number of items to be processedd """
        processed = sum(os.path.basename(frame) in self.alignments.data.keys()
                        for frame in self.images.input_images)
        logger.debug("Items already processed: %s", processed)

        if processed != 0 and self.args.skip_existing:
            logger.info("Skipping previously extracted frames: %s", processed)
        if processed != 0 and self.args.skip_faces:
            logger.info("Skipping frames with detected faces: %s", processed)

        to_process = (self.images.images_found - processed) // self.skip_num
        logger.debug("Items to be Processed: %s", to_process)
        if to_process == 0:
            logger.error("No frames to process. Exiting")
            queue_manager.terminate_queues()
            exit(0)
        return to_process

    def run_extraction(self):
        """ Run Face Detection """
        to_process = self.process_item_count()
        size = self.args.size if hasattr(self.args, "size") else 256
 </s> add     def _run_extraction(self):
        """ The main Faceswap Extraction process

        Receives items from :class:`plugins.extract.Pipeline.Extractor` and either saves out the
        faces and data (if on the final pass) or reprocesses data through the pipeline for serial
        processing.
        """
        size = self._args.size if hasattr(self._args, "size") else 256
        saver = ImagesSaver(self._output_dir, as_bytes=True) </s> remove             self.extractor.launch()
            self.check_thread_error()
 </s> add             self._extractor.launch()
            self._check_thread_error() </s> remove                                                       self.extractor.passes,
                                                      self.extractor.phase.title())
            status_bar = tqdm(self.extractor.detected_faces(),
                              total=to_process,
 </s> add                                                       self._extractor.passes,
                                                      self._extractor.phase.title())
            status_bar = tqdm(self._extractor.detected_faces(),
                              total=self._images.process_count, </s> remove                 self.check_thread_error()
 </s> add                 self._check_thread_error()
        for phase in range(self._extractor.passes):
          to_process = self.process_item_count()
          size = self.args.size if hasattr(self.args, "size") else 256
          exception = False
  
        for phase in range(self._extractor.passes):
              if exception:
                  break
              is_final = self.extractor.final_pass
              detected_faces = dict()
              self.extractor.launch()
keep keep keep keep replace keep keep keep keep keep
 scripts.extract - code optimizations

Limit queue sizes to reduce RAM usage
Rename lib.image.BackgroundIO to ImageIO
Create separate ImagesLoader and ImagesSaver classes
Load/Save images from centralized lib.image.ImageIO
scripts.extract documentation 
scripts/extract.py