Class SyntheticVideoDecoder

java.lang.Object
limn.video.decode.SyntheticVideoDecoder
All Implemented Interfaces:
VideoDecoder

public final class SyntheticVideoDecoder extends Object implements VideoDecoder
A decoder with nothing to decode: it draws its pictures, so a video is available on any machine, in every layout, under every colour interpretation and at any size, with no file to ship and nothing to go missing. Every sample of every picture is a documented function of its coordinates, which is what makes a rendered frame comparable against arithmetic instead of against a reference image somebody has to eyeball.

The path is a description, not a location. This decoder claims any path whose file name ends in .synth and reads the rest of that name as a SyntheticSpec; it never opens, reads, stats or creates anything. The file need not exist and normally does not.


 Videos.installDecoder(new SyntheticVideoDecoder());
 SyntheticSpec spec = SyntheticSpec.of(640, 360).withPattern(SyntheticPattern.COUNTER);
 try (VideoStreamSource source = Videos.open(spec.path())) {
     // ...
 }
 

Going through Videos rather than calling open(SyntheticSpec) is not ceremony: it is what proves the facade, the install order and a player's ordinary open path with no real decoder installed at all. open(SyntheticSpec) exists for the caller that already holds a spec and would otherwise format a name only to have it parsed straight back.

Stateless and immutable; one instance serves every stream, from any thread.

  • Constructor Details

    • SyntheticVideoDecoder

      public SyntheticVideoDecoder()
  • Method Details

    • name

      public String name()
      Description copied from interface: VideoDecoder
      A short, stable, lower-case identifier used in diagnostics. It appears in the failure raised when nothing accepts an input, which is the only way anyone finds out which decoders existed and in what order they were consulted.

      It carries no meaning and nothing may branch on it; the wrong edit this prevents is a comparison against a literal name somewhere on a control-flow path, which would put a particular decoder's identity into logic that is supposed to be decoder-neutral.

      Deliberately without a default: deriving it from the implementing class produces an unreadable synthetic name for a lambda or an anonymous class, in exactly the message that exists to be readable.

      Specified by:
      name in interface VideoDecoder
      Returns:
      the identifier, never null and never blank
    • supports

      public boolean supports(Path file)
      Description copied from interface: VideoDecoder
      Whether this decoder will attempt file.

      Cheap and honest. It may look at the extension and read the first few bytes; it must not parse a whole container, build an index, touch a network or decode anything, because it runs on the caller's thread, once per installed decoder, every time an input is opened.

      It promises only that this decoder claims the input, not that the input opens, is well-formed, or decodes to the end. It must never throw: a missing, unreadable or surprising input is false, because one bad file that throws here makes the whole probe unusable for every other decoder behind it.

      Deliberately without a default, because both possible defaults are wrong: claiming everything destroys the ordering, and claiming nothing makes a decoder that forgot to override it silently unreachable.

      Specified by:
      supports in interface VideoDecoder
      Returns:
      whether file's name ends with .synth, ignoring case. The filesystem is not touched and the rest of the name is not parsed, so a name that ends correctly and is malformed inside is claimed here and rejected (with a message that says what is wrong with it) by openStream(java.nio.file.Path).
    • openStream

      public VideoStreamSource openStream(Path file)
      Opens the stream described by file's name.
      Specified by:
      openStream in interface VideoDecoder
      Throws:
      IllegalArgumentException - if the name is not a readable SyntheticSpec
      NullPointerException - if file is null
    • open

      public static VideoStreamSource open(SyntheticSpec spec)
      Opens the stream spec describes, without going through a path. The caller owns the source and closes it; its pictures' memory is allocated here, once, and reused for the life of the stream.
      Throws:
      NullPointerException - if spec is null