sig
  type plane =
      (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
  type format = Yuv_422_p | Yuv_444_p | Yuv_420_p
  type video_type =
      CUSTOM
    | QSIF
    | QCIF
    | SIF
    | CIF
    | SIF_4
    | CIF_4
    | SD480I_60
    | SD576I_50
    | HD720P_60
    | HD720P_50
    | HD1080I_60
    | HD1080I_50
    | HD1080P_60
    | HD1080P_50
    | DC2K_24
    | DC4K_24
  type chroma = Chroma_422 | Chroma_444 | Chroma_420
  type colour_primaries = HDTV | SDTV_525 | SDTV_625 | CINEMA
  type colour_matrix = HDTV | SDTV | REVERSIBLE
  type transfer_function = TV_GAMMA | EXTENDED_GAMMUT | LINEAR | DCI_GAMMA
  type signal_range =
      RANGE_CUSTOM
    | RANGE_8BIT_FULL
    | RANGE_8BIT_VIDEO
    | RANGE_10BIT_VIDEO
    | RANGE_12BIT_VIDEO
  type video_format = {
    video_type : Schroedinger.video_type;
    width : int;
    height : int;
    chroma_format : Schroedinger.chroma;
    interlaced : bool;
    top_field_first : bool;
    frame_rate_numerator : int;
    frame_rate_denominator : int;
    aspect_ratio_numerator : int;
    aspect_ratio_denominator : int;
    clean_width : int;
    clean_height : int;
    left_offset : int;
    top_offset : int;
    luma_offset : int;
    luma_excursion : int;
    chroma_offset : int;
    chroma_excursion : int;
    colour_primaries : Schroedinger.colour_primaries;
    colour_matrix : Schroedinger.colour_matrix;
    transfer_function : Schroedinger.transfer_function;
    interlaced_coding : bool;
    signal_range : Schroedinger.signal_range;
  }
  val get_default_video_format :
    Schroedinger.video_type -> Schroedinger.video_format
  type frame = {
    planes : (Schroedinger.plane * int) array;
    frame_width : int;
    frame_height : int;
    format : Schroedinger.format;
  }
  val frames_of_granulepos : interlaced:bool -> Int64.t -> Int64.t
  module Encoder :
    sig
      type t
      val create : Schroedinger.video_format -> Schroedinger.Encoder.t
      val get_video_format :
        Schroedinger.Encoder.t -> Schroedinger.video_format
      val encode_header : Schroedinger.Encoder.t -> Ogg.Stream.t -> unit
      val encode_frame :
        Schroedinger.Encoder.t -> Schroedinger.frame -> Ogg.Stream.t -> unit
      val encoded_of_granulepos :
        Int64.t -> Schroedinger.Encoder.t -> Int64.t
      val eos : Schroedinger.Encoder.t -> Ogg.Stream.t -> unit
      type rate_control =
          Constant_noise_threshold
        | Constant_bitrate
        | Low_delay
        | Lossless
        | Constant_lambda
        | Constant_error
      type gop_structure =
          Adaptive
        | Intra_only
        | Backref
        | Chained_backref
        | Biref
        | Chained_biref
      type perceptual_weighting = None | Ccir959 | Moo | Manos_sakrison
      type filtering =
          None
        | Center_weighted_median
        | Gaussian
        | Add_noise
        | Adaptive_gaussian
      type wavelet =
          Desl_dubuc_9_7
        | Le_gall_5_3
        | Desl_dubuc_13_7
        | Haar_0
        | Haar_1
        | Fidelity
        | Daub_9_7
      type block_size = Automatic | Small | Medium | Large
      type block_overlap = Automatic | None | Partial | Full
      type settings = {
        rate_control : Schroedinger.Encoder.rate_control;
        bitrate : int;
        max_bitrate : int;
        min_bitrate : int;
        buffer_size : int;
        buffer_level : int;
        noise_threshold : float;
        gop_structure : Schroedinger.Encoder.gop_structure;
        queue_depth : int;
        perceptual_weighting : Schroedinger.Encoder.perceptual_weighting;
        perceptual_distance : float;
        filtering : Schroedinger.Encoder.filtering;
        filter_value : float;
        profile : int;
        level : int;
        au_distance : int;
        enable_psnr : bool;
        enable_ssim : bool;
        ref_distance : int;
        transform_depth : int;
        intra_wavelet : Schroedinger.Encoder.wavelet;
        inter_wavelet : Schroedinger.Encoder.wavelet;
        mv_precision : int;
        motion_block_size : Schroedinger.Encoder.block_size;
        motion_block_overlap : Schroedinger.Encoder.block_overlap;
        interlaced_coding : bool;
        enable_internal_testing : bool;
        enable_noarith : bool;
        enable_md5 : bool;
        enable_fullscan_estimation : bool;
        enable_hierarchical_estimation : bool;
        enable_zero_estimation : bool;
        enable_phasecorr_estimation : bool;
        enable_bigblock_estimation : bool;
        horiz_slices : int;
        vert_slices : int;
        magic_dc_metric_offset : float;
        magic_subband0_lambda_scale : float;
        magic_chroma_lambda_scale : float;
        magic_nonref_lambda_scale : float;
        magic_allocation_scale : float;
        magic_keyframe_weight : float;
        magic_scene_change_threshold : float;
        magic_inter_p_weight : float;
        magic_inter_b_weight : float;
        magic_mc_bailout_limit : float;
        magic_bailout_weight : float;
        magic_error_power : float;
        magic_mc_lambda : float;
        magic_subgroup_length : float;
        magic_lambda : float;
      }
      val get_settings :
        Schroedinger.Encoder.t -> Schroedinger.Encoder.settings
      val set_settings :
        Schroedinger.Encoder.t -> Schroedinger.Encoder.settings -> unit
    end
  module Decoder :
    sig
      exception Invalid_header
      exception Skipped_frame
      exception Error
      type t
      val create :
        Ogg.Stream.packet -> Ogg.Stream.packet -> Schroedinger.Decoder.t
      val check : Ogg.Stream.packet -> bool
      val get_video_format :
        Schroedinger.Decoder.t -> Schroedinger.video_format
      val get_picture_number : Schroedinger.Decoder.t -> int
      val decode_frame :
        Schroedinger.Decoder.t -> Ogg.Stream.t -> Schroedinger.frame
    end
  module Skeleton :
    sig
      val fisbone :
        ?start_granule:Int64.t ->
        ?headers:(string * string) list ->
        serialno:Nativeint.t ->
        format:Schroedinger.video_format -> unit -> Ogg.Stream.packet
    end
end