                  raise
              if output == "" and self.process.poll() is not None:
                  break
              if output:
                  if ((self.command == "train" and self.capture_loss(output)) or
                          (self.command == "effmpeg" and self.capture_ffmpeg(output)) or
                          (self.command not in ("train", "effmpeg") and self.capture_tqdm(output))):
                      continue
                  if self.command == "train" and self.wrapper.tk_vars.is_training.get():
                      if "[saved models]" in output.strip().lower():
                          logger.debug("Trigger GUI Training update")
                          logger.trace("tk_vars: %s",
                                       {itm: var.get()
                                        for itm, var in self.wrapper.tk_vars.__dict__.items()})
                          if not Session.is_training:
                              # Don't initialize session until after the first save as state
                              # file must exist first
                              logger.debug("Initializing curret training session")
                              Session.initialize_session(
                                  self._session_info["model_folder"],
                                  self._session_info["model_name"],
                                  is_training=True)
                          self.wrapper.tk_vars.update_preview.set(True)
                          self.wrapper.tk_vars.refresh_graph.set(True)
                      if "[preview updated]" in output.strip().lower():
                          self.wrapper.tk_vars.update_preview.set(True)
                          continue
                  print(output.rstrip())
          returncode = self.process.poll()
          message = self.set_final_status(returncode)
          self.wrapper.terminate(message)
          logger.debug("Terminated stdout reader. returncode: %s", returncode)
 
</s> remove     def read_stdout(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
 </s> add     def _process_progress_stdout(self, output: str) -> bool:
        """ Process stdout for any faceswap processes that update the status/progress bar(s)

        Parameters
        ----------
        output: str
            The output line read from stdout

        Returns
        -------
        bool
            ``True`` if all actions have been completed on the output line otherwise ``False``
        """
        if self.command == "train" and self.capture_loss(output):
            return True

        if self.command == "effmpeg" and self.capture_ffmpeg(output):
            return True

        if self.command not in ("train", "effmpeg") and self.capture_tqdm(output):
            return True

        return False

    def _process_training_stdout(self, output: str) -> None:
        """ Process any triggers that are required to update the GUI when Faceswap is running a
        training session.

        Parameters
        ----------
        output: str
            The output line read from stdout
        """
        if self.command != "train" or not self.wrapper.tk_vars.is_training.get():
            return

        if "[saved models]" not in output.strip().lower():
            return

        logger.debug("Trigger GUI Training update")
        logger.trace("tk_vars: %s", {itm: var.get()  # type:ignore
                                     for itm, var in self.wrapper.tk_vars.__dict__.items()})
        if not Session.is_training:
            # Don't initialize session until after the first save as state file must exist first
            logger.debug("Initializing curret training session")
            Session.initialize_session(self._session_info["model_folder"],
                                       self._session_info["model_name"],
                                       is_training=True)
        self.wrapper.tk_vars.refresh_graph.set(True)

    def read_stdout(self) -> None:
        """ Read stdout from the subprocess. """ </s> remove     def previewoutput(self) -> Tuple[Image.Image, ImageTk.PhotoImage]:
        """ Tuple: First item in the tuple is the extract or convert preview image
        (:class:`PIL.Image`), the second item is the image in a format that tkinter can display
        (:class:`PIL.ImageTK.PhotoImage`).
 </s> add     def buffer(self) -> PreviewBuffer:
        """ :class:`~lib.training.PreviewBuffer` The preview buffer for the training preview
        image. """
        return self._buffer

    def load(self) -> bool:
        """ Load the latest training preview image(s) from disk and add to :attr:`buffer` """
        logger.trace("Loading Training preview images")  # type:ignore
        image_files = _get_previews(self._cache_path)
        filename = next((fname for fname in image_files
                         if os.path.basename(fname) == TRAININGPREVIEW), "")
        if not filename:
            logger.trace("No preview to display")  # type:ignore
            return False
        try:
            modified = os.path.getmtime(filename)
            if modified <= self._modified:
                logger.trace("preview '%s' not updated. Current timestamp: %s, "  # type:ignore
                             "existing timestamp: %s", filename, modified, self._modified)
                return False

            logger.debug("Loading preview: '%s'", filename)
            img = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
            self._modified = modified
            self._buffer.add_image(os.path.basename(filename), img)
            self._error_count = 0
        except ValueError:
            # This is probably an error reading the file whilst it's being saved so ignore it
            # for now and only pick up if there have been multiple consecutive fails
            logger.warning("Unable to display preview: (image: '%s', attempt: %s)",
                           img, self._error_count)
            if self._error_count < 10:
                self._error_count += 1
            else:
                logger.error("Error reading the preview file for '%s'", filename)
            return False </s> remove         size = 256 if self.command == "convert" else 128
        get_images().load_latest_preview(thumbnail_size=int(size * get_config().scaling_factor),
                                         frame_dims=(self.winfo_width(), self.winfo_height()))
        self.display_item = get_images().previewoutput
 </s> add         size = int(256 if self.command == "convert" else 128 * get_config().scaling_factor)
        if not self._preview.load_latest_preview(thumbnail_size=size,
                                                 frame_dims=(self.winfo_width(),
                                                             self.winfo_height())):
            logger.trace("Preview not updated")  # type:ignore
            return
        logger.debug("Preview loaded")
        self.display_item = True
                self._process_training_stdout(output)
                  raise
              if output == "" and self.process.poll() is not None:
                  break
              if output:
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                self._process_training_stdout(output)
                  print(output.rstrip())
          returncode = self.process.poll()
          message = self.set_final_status(returncode)
          self.wrapper.terminate(message)
          logger.debug("Terminated stdout reader. returncode: %s", returncode)
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
 GUI - Preview updates
  - Training preview. Embed preview pop-out window
  - Bugfix - convert/extract previews 
lib/gui/wrapper.py