code: def test_framecatcher():
      class FakeGenerator:
          def __init__(self, nframebytes):
              self._f = BytesIO()
              self._n = nframebytes
              self._lock = threading.RLock()
              self._bb = b""
  
          def write_and_rewind(self, bb):
              with self._lock:
                  t = self._f.tell()
                  self._f.write(bb)
                  self._f.seek(t)
  
          def __next__(self):
              while True:
                  time.sleep(0.001)
                  with self._lock:
                      if self._f.closed:
                          raise StopIteration()
                      self._bb += self._f.read(self._n)
                  if len(self._bb) >= self._n:
                      bb = self._bb[: self._n]
                      self._bb = self._bb[self._n :]
                      return bb
  
          def close(self):
              with self._lock:
                  self._f.close()
  
      # Test our class
      N = 100
      file = FakeGenerator(N)
      file.write_and_rewind(b"v" * N)
      assert file.__next__() == b"v" * N
  
      file = FakeGenerator(N)
      T = imageio.plugins.ffmpeg.FrameCatcher(
          file
      )  # the file looks like a generator
  
      # Init None
      time.sleep(0.1)
      assert T._frame is None  # get_frame() would stall
  
      # Read frame
      file.write_and_rewind(b"x" * (N - 20))
      time.sleep(0.2)  # Let it read a part
      assert T._frame is None  # get_frame() would stall
      file.write_and_rewind(b"x" * 20)
      time.sleep(0.2)  # Let it read the rest
      frame, is_new = T.get_frame()
      assert frame == b"x" * N
      assert (
          is_new
      ), "is_new should be True the first time a frame is retrieved"
  
      # Read frame that has not been updated
      frame, is_new = T.get_frame()
      assert (
          frame == b"x" * N
      ), "frame content should be the same as before"
      assert (
          not is_new
      ), "is_new should be False if the frame has already been retrieved"
  
      # Read frame when we pass plenty of data
      file.write_and_rewind(b"y" * N * 3)
      time.sleep(0.2)
      frame, is_new = T.get_frame()
      assert frame == b"y" * N
      assert (
          is_new
      ), "is_new should be True again if the frame has been updated"
  
      # Close
      file.close()
  
imports: import gc
  import os
  import platform
  import sys
  import threading
  import time
  import warnings
  from io import BytesIO
  from pathlib import Path
  import imageio.plugins
  import imageio.v2
  import imageio.v3
  import numpy
  import pytest
  from imageio import core
  from imageio.core import IS_PYPY
  from conftest import deprecated_test
label_desc: Use image node_id 18 for calling a global function with example usage: test_framecatcher() and returns: bb