              self.writer = self.get_writer()
          self.cache_frame(filename, image)
          self.save_from_cache()
  
      def set_dimensions(self, frame_dims):
          """ Set the dimensions based on a given frame frame. This protects against different
              sized images coming in and ensure all images go out at the same size for writers
              that require it and mapped to a macro block size 16"""
          logger.debug("input dimensions: %s", frame_dims)
          self.output_dimensions = "{}:{}".format(
              int(ceil(frame_dims[1] / 16) * 16),
              int(ceil(frame_dims[0] / 16) * 16))
          logger.debug("Set dimensions: %s", self.output_dimensions)
 
</s> remove         self.output_dimensions = "{}:{}".format(
            int(ceil(frame_dims[1] / 16) * 16),
            int(ceil(frame_dims[0] / 16) * 16))
        logger.debug("Set dimensions: %s", self.output_dimensions)

    def save_from_cache(self):
        """ Save all the frames that are ready to be output from cache """
        while self.frame_order:
            if self.frame_order[0] not in self.cache:
 </s> add         self._output_dimensions = (f"{int(ceil(frame_dims[1] / 16) * 16)}:"
                                   f"{int(ceil(frame_dims[0] / 16) * 16)}")
        logger.debug("Set dimensions: %s", self._output_dimensions)

    def _save_from_cache(self) -> None:
        """ Writes any consecutive frames to the video container that are ready to be output
        from the cache. """
        while self._frame_order:
            if self._frame_order[0] not in self.cache: </s> remove         self.save_from_cache()
 </s> add         self._save_from_cache() </s> remove         if not self.output_dimensions:
            logger.info("Outputting to: '%s'", self.video_file)
            self.set_dimensions(image.shape[:2])
            self.writer = self.get_writer()
 </s> add         if not self._output_dimensions:
            self._set_dimensions(image.shape[:2])
            self._writer = self._get_writer() </s> remove     def cache_frame(self, filename, image):
        """ Add the incoming frame to the cache """
 </s> add     def cache_frame(self, filename, image) -> None:
        """ Add the incoming converted frame to the cache ready for writing out.

        Used for ffmpeg and gif writers to ensure that the frames are written out in the correct
        order.

        Parameters
        ----------
        filename: str
            The filename of the incoming frame, where the frame index can be extracted from
        image: class:`numpy.ndarray`
            The converted frame corresponding to the given filename
        """ </s> remove         self.source_video = source_video
        self.frame_ranges = frame_ranges
        self.frame_order = self.set_frame_order(total_count)
        self.output_dimensions = None  # Fix dims of 1st frame in case of different sized images
        self.writer = None  # Need to know dimensions of first frame, so set writer then

    @property
    def video_file(self):
        """ Return full path to video output """
        filename = os.path.basename(self.source_video)
        filename = os.path.splitext(filename)[0]
        filename = "{}_converted.{}".format(filename, self.config["container"])
        retval = os.path.join(self.output_folder, filename)
        logger.debug(retval)
        return retval
 </s> add         self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
    def _set_dimensions(self, frame_dims) -> None:
        """ Set the attribute :attr:`_output_dimensions` based on the first frame received.
        This protects against different sized images coming in and ensures all images are written
        to ffmpeg at the same size. Dimensions are mapped to a macro block size 16. """
              self.writer = self.get_writer()
          self.cache_frame(filename, image)
          self.save_from_cache()
  
    def _set_dimensions(self, frame_dims) -> None:
        """ Set the attribute :attr:`_output_dimensions` based on the first frame received.
        This protects against different sized images coming in and ensures all images are written
        to ffmpeg at the same size. Dimensions are mapped to a macro block size 16. """
    def _set_dimensions(self, frame_dims) -> None:
        """ Set the attribute :attr:`_output_dimensions` based on the first frame received.
        This protects against different sized images coming in and ensures all images are written
        to ffmpeg at the same size. Dimensions are mapped to a macro block size 16. """
    def _set_dimensions(self, frame_dims) -> None:
        """ Set the attribute :attr:`_output_dimensions` based on the first frame received.
        This protects against different sized images coming in and ensures all images are written
        to ffmpeg at the same size. Dimensions are mapped to a macro block size 16. """
    def _set_dimensions(self, frame_dims) -> None:
        """ Set the attribute :attr:`_output_dimensions` based on the first frame received.
        This protects against different sized images coming in and ensures all images are written
        to ffmpeg at the same size. Dimensions are mapped to a macro block size 16. """
          logger.debug("input dimensions: %s", frame_dims)
          self.output_dimensions = "{}:{}".format(
              int(ceil(frame_dims[1] / 16) * 16),
              int(ceil(frame_dims[0] / 16) * 16))
          logger.debug("Set dimensions: %s", self.output_dimensions)
keep keep keep keep replace replace replace replace keep keep keep keep keep
 ffmpeg writer: Create new filename if output pre-exists 
plugins/convert/writer/ffmpeg.py