Module Avfilter.Utils

An audio converter built on a private filter graph: it re-frames audio to a fixed frame size and, optionally, converts it to another sample rate, channel layout and sample format.

type audio_converter

A converter. It owns a launched graph made of an audio buffer source, a resampling filter when output parameters were given, and an audio buffer sink.

type audio_params = {
  1. sample_rate : int;
  2. channel_layout : Avutil.Channel_layout.t;
  3. sample_format : Avutil.Sample_format.t;
}

The parameters of an audio stream. sample_rate is in Hz.

val init_audio_converter : ?out_params:audio_params -> ?out_frame_size:int -> in_time_base:Avutil.rational -> in_params:audio_params -> unit -> audio_converter

Creates a converter and launches its graph.

  • parameter out_params

    The parameters of the frames delivered. By default they are the ones of the input and no resampling filter is used.

  • parameter out_frame_size

    When given, every frame delivered has exactly that many samples per channel, except the last one after a flush. By default the frames have the sizes the graph produces.

  • parameter in_time_base

    The time base of the timestamps of the input frames.

  • parameter in_params

    The parameters of the input frames.

  • raises Avutil.Error

    with `Filter_not_found when out_params is given and FFmpeg lacks its aresample filter; with `Failure _ when out_frame_size is below 1; with the FFmpeg error of the step that failed otherwise.

val time_base : audio_converter -> Avutil.rational

The time base of the timestamps of the frames the converter delivers, read once when the converter is created.

val convert_audio : audio_converter -> (Avutil.audio Avutil.frame -> unit) -> [ `Frame of Avutil.audio Avutil.frame | `Flush ] -> unit

convert_audio converter callback input pushes a frame, or the end of the stream with `Flush, and calls callback on every frame that becomes available, in order.

It first delivers the frames the converter already has ready, then pushes input, then delivers until the converter has no frame ready. A call that delivers no frame is normal. After `Flush every remaining frame is delivered, and a later `Frame _ raises Error `Eof.

callback runs on the caller's thread, between native calls, and may use the converter. An exception it raises propagates unchanged; the frames not yet delivered stay in the converter and the next convert_audio delivers them first.

The pushed frame is unchanged and stays usable. Pushing and pulling release the OCaml runtime lock.

type filter_spec = string * args list

A filter to attach: its name and its arguments.

val filter_of_transform : Avutil.Display_matrix.transform -> filter_spec

The filter that performs one step of Avutil.Display_matrix.transforms: transpose, hflip, vflip or rotate.

val filter_of_cropping : Avutil.cropping -> filter_spec option

The crop filter that discards the borders, None when there is nothing to discard.

type display_layout = {
  1. width : int;
  2. height : int;
  3. pixel_aspect : Avutil.rational option;
  4. filters : filter_spec list;
}

The picture a display chain produces: its size, its pixel aspect ratio, and the filters that produce it.

type undecided = [
  1. | `Invalid_cropping of Avutil.cropping
  2. | `Odd_rotation of float
]

What the bindings do not decide in the caller's place:

  • `Invalid_cropping: the cropping is negative or leaves no picture;
  • `Odd_rotation a: the display matrix turns the picture by a degrees clockwise, which is not a quarter turn, so the size of the result is a choice.
val display_layout : ?cropping:Avutil.cropping -> ?display_matrix:Avutil.Display_matrix.t -> ?pixel_aspect:Avutil.rational -> width:int -> height:int -> unit -> [ `Layout of display_layout | `Undecided of undecided ]

display_layout ?cropping ?display_matrix ?pixel_aspect ~width ~height () is the layout of a widthxheight picture once shown upright and cropped. filters is the chain that does it, in the order to link them: filter_of_cropping, then filter_of_transform on each step the display matrix asks for. cropping is the container's, found in the stream parameters: Avcodec.Packet_side_data.cropping (Avcodec.params_side_data params). A quarter turn swaps the width and the height and inverts the pixel aspect ratio. It is `Undecided where there is no single right answer; the caller then decides, for instance from filter_of_transform.

type undecided_frame = [
  1. | undecided
  2. | `Hardware_frame
]

What convert_display does not decide: undecided, and a frame in a hardware pixel format, which no software filter can transform.

val video_buffer_args : time_base:Avutil.rational -> Avutil.Video.frame_format -> args list

The arguments of a buffer source that takes frames of the given format, with timestamps in time_base: the size, the pixel format, and the pixel aspect, colour space and colour range when the format has them.

type video_chain = {
  1. chain_source : [ `Video ] input;
  2. chain_sink : [ `Video ] output;
}

A launched graph that runs video frames through filters, one after the other: chain_source takes the frames and the end of the stream, chain_sink delivers them.

val video_chain : time_base:Avutil.rational -> Avutil.Video.frame_format -> filter_spec list -> video_chain

video_chain ~time_base format filters is the chain of filters, in order, for frames of format with timestamps in time_base.

  • raises Avutil.Error

    with `Filter_not_found when a filter is unknown, and with FFmpeg's error when the graph cannot be built.

type display_converter

A converter that delivers decoded video frames upright and cropped. It reads the display matrix of each frame and runs the filters of display_layout on a private graph, rebuilt when the matrix or the Avutil.Video.frame_format of the frames changes. Two threads must not use one at the same time.

val init_display_converter : ?cropping:Avutil.cropping -> ?on_undecided:(undecided_frame -> filter_spec list option) -> ?ignore:Avutil.Video.frame_property list -> time_base:Avutil.rational -> unit -> display_converter

init_display_converter ?cropping ?on_undecided ~time_base () is a converter for frames whose timestamps are in time_base. cropping is as in display_layout.

on_undecided is asked what to do with the frames the converter cannot decide for, once per run of frames with the same question. Some filters is a decision: the frames go through those filters and lose their display matrix. None is no decision: the frames are delivered untouched, display matrix included, for something downstream to act on. By default it logs a warning through Avutil.Log.log and answers None. Filters that cannot be built are no decision either: the converter logs a warning and delivers the frames untouched.

ignore lists the properties of the frame format whose change does not rebuild the graph, as in Avutil.Video.same_frame_format.

val convert_display : display_converter -> (Avutil.video Avutil.frame -> unit) -> [ `Frame of Avutil.video Avutil.frame | `Flush ] -> unit

convert_display converter callback input pushes a frame, or the end of the stream, and calls callback on every frame that becomes available, in order.

A delivered frame has no display matrix and keeps the timestamp it came with. A frame with nothing to apply goes through no filter: it is the pushed frame itself when that one has no display matrix, a frame sharing its data otherwise. A frame nothing is decided for (see init_display_converter) is the pushed frame itself, display matrix included. The pushed frame is unchanged and stays usable.

After `Flush every remaining frame is delivered and the converter can be used again. An exception raised by callback propagates unchanged.

  • raises Avutil.Error

    when building the graph, pushing or pulling fails.