          self._images = ImagesLoader(self._args.input_dir, fast_count=True)
          self._alignments = Alignments(self._args, True, self._images.is_video)
          self._extractor = extractor
  
          self._existing_count = 0
          self._set_skip_list()
  
          self._post_process = PostProcess(arguments)
          self._threads: List[MultiThread] = []
          self._verify_output = False
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
      def _save_interval(self) -> Optional[int]:
          """ int: The number of frames to be processed between each saving of the alignments file if
 
</s> remove     def _save_interval(self) -> Optional[int]:
        """ int: The number of frames to be processed between each saving of the alignments file if
        it has been provided, otherwise ``None`` """
        if hasattr(self._args, "save_interval"):
            return self._args.save_interval
        return None
 </s> add     def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files) </s> remove         logger.info("Output Directory: %s", self._output_dir)
        self._images = ImagesLoader(self._args.input_dir, fast_count=True)
        self._alignments = Alignments(self._args, True, self._images.is_video)
 </s> add         self._embeddings: List[np.ndarray] = [np.array([]) for _ in self._filter_files]
        self._nembeddings: List[np.ndarray] = [np.array([]) for _ in self._nfilter_files] </s> remove                  extractor: Extractor,
                 arguments: Namespace) -> None:
        logger.debug("Initializing %s: (extractor: %s, args: %s)", self.__class__.__name__,
                     extractor, arguments)
        self._args = arguments
        self._output_dir = None if self._args.skip_saving_faces else get_folder(
            self._args.output_dir)
 </s> add                  threshold: float,
                 filter_files: Optional[Union[str, List[str]]],
                 nfilter_files: Optional[Union[str, List[str]]],
                 extractor: Extractor) -> None:
        logger.debug("Initializing %s: (threshold: %s, filter_files: %s, nfilter_files: %s "
                     "extractor: %s)", self.__class__.__name__, threshold, filter_files,
                     nfilter_files, extractor)
        self._threshold = threshold
        self._filter_files, self._nfilter_files = self._validate_inputs(filter_files,
                                                                        nfilter_files)

        if not self._filter_files and not self._nfilter_files:
            logger.debug("Filter not selected. Exiting %s", self.__class__.__name__)
            return </s> remove         # from lib.queue_manager import queue_manager ; queue_manager.debug_monitor(3)
 </s> add         logger.info("Extracting faces to obtain identity from images")
        logger.debug("Files requiring full extraction: %s",
                     [fname for fname in file_list if fname not in aligned])
        logger.debug("Aligned files requiring identity info: %s", aligned)

        loader = PipelineLoader(file_list, self._extractor, aligned_filenames=aligned)
        loader.launch()

        for phase in range(self._extractor.passes):
            is_final = self._extractor.final_pass
            detected_faces: Dict[str, ExtractMedia] = {}
            self._extractor.launch()
            desc = "Obtaining reference face Identity"
            if self._extractor.passes > 1:
                desc = (f"{desc } pass {phase + 1} of {self._extractor.passes}: "
                        f"{self._extractor.phase_text}")
            for extract_media in tqdm(self._extractor.detected_faces(),
                                      total=len(file_list),
                                      file=sys.stdout,
                                      desc=desc):
                if is_final:
                    self._process_extracted(extract_media)
                else:
                    extract_media.remove_image()
                    # cache extract_media for next run
                    detected_faces[extract_media.filename] = extract_media

            if not is_final:
                logger.debug("Reloading images")
                loader.reload(detected_faces)

        self._extractor.reset_phase_index()

    def _get_embeddings(self) -> None:
        """ Obtain the embeddings for the given filter lists """
        needs_extraction: List[str] = []
        aligned: List[str] = []

        for files, embed in zip((self._filter_files, self._nfilter_files),
                                (self._embeddings, self._nembeddings)):
            for idx, file in enumerate(files):
                identity, is_aligned = self._identity_from_extracted(file)
                if np.any(identity):
                    logger.debug("Obtained identity from png header: '%s'", file)
                    embed[idx] = identity[None, ...]
                    continue

                needs_extraction.append(file)
                if is_aligned:
                    aligned.append(file)

        if needs_extraction:
            self._identity_from_extractor(needs_extraction, aligned)

        if not self._nfilter_files and not self._filter_files:
            logger.error("No faces were detected from your selected identity filter files")
            sys.exit(1)

        logger.debug("Filter: (filenames: %s, shape: %s), nFilter: (filenames: %s, shape: %s)",
                     [os.path.basename(f) for f in self._filter_files],
                     self.embeddings.shape,
                     [os.path.basename(f) for f in self._nfilter_files],
                     self.n_embeddings.shape)


class PipelineLoader():
    """ Handles loading and reloading images into the extraction pipeline.

    Parameters
    ----------
    path: str or list of str
        Full path to a folder of images or a video file or a list of image files
    extractor: :class:`~plugins.extract.pipeline.Extractor`
        The extractor pipeline for obtaining face identity from images
    aligned_filenames: list, optional
        Used for when the loader is used for getting face filter embeddings. List of full path to
        image files that exist in :attr:`path` that are aligned faceswap images
    """
    def __init__(self,
                 path: Union[str, List[str]],
                 extractor: Extractor,
                 aligned_filenames: Optional[List[str]] = None) -> None:
        logger.debug("Initializing %s: (path: %s, extractor: %s, aligned_filenames: %s)",
                     self.__class__.__name__, path, extractor, aligned_filenames)
        self._images = ImagesLoader(path, fast_count=True)
        self._extractor = extractor
        self._threads: List[MultiThread] = []
        self._aligned_filenames = [] if aligned_filenames is None else aligned_filenames
        logger.debug("Initialized %s", self.__class__.__name__)

    @property
    def is_video(self) -> bool:
        """ bool: ``True`` if the input location is a video file, ``False`` if it is a folder of
        images """
        return self._images.is_video

    @property
    def file_list(self) -> List[str]:
        """ list: A full list of files in the source location. If the input is a video
        then this is a list of dummy filenames as corresponding to an alignments file """
        return self._images.file_list

    @property
    def process_count(self) -> int:
        """ int: The number of images or video frames to be processed (IE the total count less
        items that are to be skipped from the :attr:`skip_list`)"""
        return self._images.process_count

    def add_skip_list(self, skip_list: List[int]) -> None:
        """ Add a skip list to the :class:`ImagesLoader`

        Parameters
        ----------
        skip_list: list
            A list of indices corresponding to the frame indices that should be skipped by the
            :func:`load` function.
        """
        self._images.add_skip_list(skip_list)

    def launch(self) -> None:
        """ Launch the image loading pipeline """ </s> remove         skip_list = []
        for idx, filename in enumerate(self._images.file_list):
            if idx % self._skip_num != 0:
                logger.trace("Adding image '%s' to skip list due to "  # type: ignore
                             "extract_every_n = %s", filename, self._skip_num)
                skip_list.append(idx)
            # Items may be in the alignments file if skip-existing[-faces] is selected
            elif os.path.basename(filename) in self._alignments.data:
                self._existing_count += 1
                logger.trace("Removing image: '%s' due to previously existing",  # type: ignore
                             filename)
                skip_list.append(idx)
        if self._existing_count != 0:
            logger.info("Skipping %s frames due to skip_existing/skip_existing_faces.",
                        self._existing_count)
        logger.debug("Adding skip list: %s", skip_list)
        self._images.add_skip_list(skip_list)
 </s> add 
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
          self._images = ImagesLoader(self._args.input_dir, fast_count=True)
          self._alignments = Alignments(self._args, True, self._images.is_video)
          self._extractor = extractor
  
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
        self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold)
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
      def _save_interval(self) -> Optional[int]:
          """ int: The number of frames to be processed between each saving of the alignments file if
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Update Face Filter
  - Remove old face filter
  - plugins.extract.pipeline: Expose plugins directly
  - Change `is_aligned` from plugin level to ExtractMedia level
  - Allow extract pipeline to take faceswap aligned images
  - Add ability for recognition plugins to accept aligned faces as input
  - Add face filter to recognition plugin
  - Move extractor pipeline IO ops to own class 
scripts/extract.py