Class Y4mDecoder

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

public final class Y4mDecoder extends Object implements VideoDecoder
Reads YUV4MPEG2: a text header, then a FRAME line and raw planes per picture, with no compression and no container. What every encoder and every codec test harness reads and writes, which makes it the format a picture can be got into this toolkit in without a codec existing yet.

Reads every layout this toolkit has: C420, C420jpeg, C420paldv and C420mpeg2, which differ only in chroma siting and are one layout here, C444, and their 10-bit forms C420p10 and C444p10, whose samples are little-endian 16-bit words. A stream with no C tag is 8-bit 4:2:0 by the format's own convention. C422, the 12- and 16-bit variants and the monochrome tags are refused when the stream is opened, with a message that names the tag and what is readable instead.

Colour. YUV4MPEG2 signals neither a matrix nor a range, so a stream reports VideoColor.unspecified(), which decodes as BT.709 studio range, and says so, rather than claiming a stream stated something it did not. The one exception is FFmpeg's XCOLORRANGE extension, which some writers do emit and which is honoured when present. Content that is something else (standard-definition BT.601 material is the common case) is opened by a decoder built with Y4mDecoder(VideoColor), whose interpretation wins over anything in the header.

Immutable and stateless; one instance serves every file, from any thread.

  • Field Details

    • EXTENSION

      public static final String EXTENSION
      What the format's own file extension is; a file so named is claimed without being opened.
      See Also:
  • Constructor Details

    • Y4mDecoder

      public Y4mDecoder()
      A decoder that reports what the header implies: VideoColor.unspecified(), normally.
    • Y4mDecoder

      public Y4mDecoder(VideoColor color)
      A decoder that reports color for every stream it opens, whatever the header says.

      This is not a preference, it is the caller asserting knowledge the container cannot hold: a Y4M file of standard-definition content is BT.601 and nothing in it says so, and decoding it as BT.709 shifts every colour that is not grey. Install one of these ahead of the plain decoder for a directory of such files.

      Parameters:
      color - the interpretation every stream reports; null for what the header implies
  • 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 is named .y4m, or begins with the YUV4MPEG2 signature. Never throws: a missing, unreadable or surprising input is simply not claimed, because one bad file that threw here would break the probe for every decoder behind this one.
    • openStream

      public VideoStreamSource openStream(Path file)
      Opens file and reads its header, so every metadata accessor answers before the first picture is decoded.
      Specified by:
      openStream in interface VideoDecoder
      Throws:
      UnsupportedOperationException - if the stream's C tag names a layout this toolkit has no PixelFormat for
      IllegalStateException - if the header is missing, malformed, or gives a size outside [1..PixelFormat.MAX_DIMENSION]
      UncheckedIOException - if the file cannot be read
      NullPointerException - if file is null