                               "contain information required to correctly generate masks.")
                  logger.error("You can re-extract the face-set by using the Alignments Tool's "
                               "Extract job.")
                  break
              frame_name = metadata["source"]["source_filename"]
              face_index = metadata["source"]["face_index"]
              alignment = self._alignments.get_faces_in_frame(frame_name)
              if not alignment or face_index > len(alignment) - 1:
                  self._counts["skip"] += 1
                  logger.warning("Skipping Face not found in alignments file: '%s'", filename)
                  continue
              alignment = alignment[face_index]
              self._counts["face"] += 1
  
              if self._check_for_missing(frame_name, face_index, alignment):
                  continue
  
              detected_face = self._get_detected_face(alignment)
              if self._update_type == "output":
                  detected_face.image = image
                  self._save(frame_name, face_index, detected_face)
              else:
                  media = ExtractMedia(filename, image, detected_faces=[detected_face])
                  # Hacky overload of ExtractMedia's shape parameter to apply the actual original
                  # frame dimension
                  media._image_shape = (*metadata["source"]["source_frame_dims"], 3)
                  setattr(media, "mask_tool_face_info", metadata["source"])  # TODO formalize
                  queue.put(media)
                  self._counts["update"] += 1
          if self._update_type != "output":
              queue.put("EOF")
  
 
</s> remove     def _input_faces(self, *args):
 </s> add     def _process_face(self,
                      filename: str,
                      image: np.ndarray,
                      metadata: Dict[str, Any]) -> Optional["ExtractMedia"]:
        """ Process a single face when masking from face images

        filename: str
            the filename currently being processed
        image: :class:`numpy.ndarray`
            The current face being processed
        metadata: dict
            The source frame metadata from the PNG header

        Returns
        -------
        :class:`plugins.pipeline.ExtractMedia` or ``None``
            If the update type is 'output' then nothing is returned otherwise the extract media for
            the face is returned
        """
        frame_name = metadata["source"]["source_filename"]
        face_index = metadata["source"]["face_index"]
        alignment = self._alignments.get_faces_in_frame(frame_name)
        if not alignment or face_index > len(alignment) - 1:
            self._counts["skip"] += 1
            logger.warning("Skipping Face not found in alignments file: '%s'", filename)
            return None
        alignment = alignment[face_index]
        self._counts["face"] += 1

        if self._check_for_missing(frame_name, face_index, alignment):
            return None

        detected_face = self._get_detected_face(alignment)
        if self._update_type == "output":
            detected_face.image = image
            self._save(frame_name, face_index, detected_face)
            return None

        media = ExtractMedia(filename, image, detected_faces=[detected_face])
        media.add_frame_metadata(metadata["source"])
        self._counts["update"] += 1
        return media

    def _input_faces(self, *args: Union[tuple, Tuple["EventQueue"]]) -> None: </s> remove                 self._counts["update"] += 1
 </s> add  </s> remove             queue = args[0]
 </s> add             queue = cast("EventQueue", args[0]) </s> remove         sfx += "{}.png".format(arguments.output_type)
 </s> add         sfx += f"{arguments.output_type}.png" </s> remove     def _input_frames(self, *args):
 </s> add     def _input_frames(self, *args: Union[tuple, Tuple["EventQueue"]]) -> None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
                               "contain information required to correctly generate masks.")
                  logger.error("You can re-extract the face-set by using the Alignments Tool's "
                               "Extract job.")
                  break
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
            media = self._process_face(filename, image, metadata)
            if media is not None:
                  queue.put(media)
                  self._counts["update"] += 1
          if self._update_type != "output":
              queue.put("EOF")
  
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Minor updates and fixups
  - Mask Tool - Typing + BiSeNet mask update fix
  - Alignments Tool - Auto search for alignments file 
tools/mask/mask.py