View Source Membrane.TimestampQueue (Membrane Timestamp Queue v0.2.0)

Implementation of a queue, that accepts:

  • Membrane buffers
  • events
  • stream formats
  • end of streams from various pads. Items in queue are sorted according to their timestamps.

Moreover, Membrane.TimestampQueue is able to manage demand of pads, based on the amount of buffers from each pad currently stored in the queue.

Summary

Types

Value passed to :pause_demand_boundary option in new/1.

t()

A queue, that accepts buffers, stream formats and events from various pads and sorts them based on their timestamps.

Functions

Pops all items in the proper order and closes the queue.

Returns true, if the pad has been registered in the queue or item from it has been pushed to the queue and moreover, end of stream of this pad hasn't been popped from the queue.

Returns list of all pads, that

Pops items from the queue while they are available.

Works like pop_available_items/1, but the returned items are arranged in chunks of duration chunk_duration.

Pushes a buffer associated with a specified pad to the queue.

The equivalent of calling push_buffer/2 and then pop_chunked/1.

Pushes end of stream of the specified pad to the queue.

Pushes event associated with a specified pad to the queue.

Pushes stream format associated with a specified pad to the queue.

Registers an input pad in the queue without pushing anything on that pad.

Types

@type chunk() :: [popped_value()]
@type item() ::
  {:stream_format, Membrane.StreamFormat.t()}
  | {:buffer, Membrane.Buffer.t()}
  | {:event, Membrane.Event.t()}
  | :end_of_stream
@type options() :: [
  pause_demand_boundary: pos_integer() | Membrane.Time.t() | :infinity,
  chunk_duration: Membrane.Time.t(),
  synchronization_strategy: :synchronize_on_arrival | :explicit_offsets
]

Options passed to Membrane.TimestampQueue.new/1.

Following options are allowed:

  • :pause_demand_boundary - pause_demand_boundary/0. Defaults to {:buffers, 1000}.
  • :chunk_duration - Membrane.Time.t/0. Specifies how long the fragments returned by Membrane.TimestampQueue.pop_chunked/1 will be approximately. If not set, popping chunks will not be available.
  • :synchronization_strategy - :synchronize_on_arrival or :exact_timestamps (default to :synchronize_on_arrival). Specyfies, how items from different pads will be synchronized with each other. If it is set to:
    • :synchronize_on_arrival - in the moment of the arrival of the first buffer from a specific pad, there will be caluclated timestamp offset for this pad. These offsets will be added to the buffers timestamps, to caluclate from which pad items should be returned in the first order. Every offset will be calculated in such a way that the first buffer from a new pad will be returned as the next item.
    • :explicit_offsets - buffers from various pads will be sorted based on their timestamps and pads offsets. Pads offsets can be set using Membrane.TimestampQueue.register_pad/3 function. If pad offset is not explicitly set before the first buffer from this pad, it will be equal 0.
Link to this type

pause_demand_boundary()

View Source
@type pause_demand_boundary() ::
  {:buffer | :bytes, pos_integer() | :infinity} | {:time, Membrane.Time.t()}

Value passed to :pause_demand_boundary option in new/1.

Specyfies, what amount of buffers associated with a specific pad must be stored in the queue, to pause auto demand.

Is a two-element tuple, which

  • the first element specifies metric, in which boundary is expressed (default to :buffers)
  • the second element is the boundary (default to 1000).
@type popped_value() :: {Membrane.Pad.ref(), item()}
Link to this type

register_pad_options()

View Source
@type register_pad_options() :: [
  timestamp_offset: integer(),
  wait_on_buffers?: boolean()
]

Options passed to Membrane.TimestampQueue.register_pad/3.

Following options are allowed:

  • :wait_on_buffers? - boolean(), default to true. Specyfies, if the queue will wait with returning buffers in pop_* functions, until it receives the first buffer from a pad passed as a second argument to the function.
  • :timestamp_offset - integer. Specyfies, what will be the timestamp offset of a pad passed as a second argument to the function. Allowed only if Membrane.TimestampQueue synchronization strategy is :explicit_offsets.
@opaque t()

A queue, that accepts buffers, stream formats and events from various pads and sorts them based on their timestamps.

Functions

Link to this function

flush_and_close(timestamp_queue)

View Source
@spec flush_and_close(t()) ::
  {[Membrane.Element.Action.resume_auto_demand()], [popped_value()], t()}

Pops all items in the proper order and closes the queue.

After being closed, nothing can be pushed to the queue anymore - a new queue should be created if needed.

The returned value is a suggested actions list, a list of popped buffers and the updated queue.

Suggested actions list contains t:Membrane.Action.resume_auto_demand() for every pad, that had pasued auto demand before the flush.

Link to this function

has_pad?(timestamp_queue, pad_ref)

View Source
@spec has_pad?(t(), Membrane.Pad.ref()) :: boolean()

Returns true, if the pad has been registered in the queue or item from it has been pushed to the queue and moreover, end of stream of this pad hasn't been popped from the queue.

@spec new(options()) :: t()
@spec pads(t()) :: [Membrane.Pad.ref()]

Returns list of all pads, that:

  1. have been ever registered in the queue or item from them has been pushed to the queue
  2. their end of stream hasn't been popped from the queue.
Link to this function

pop_available_items(timestamp_queue)

View Source
@spec pop_available_items(t()) ::
  {[Membrane.Element.Action.resume_auto_demand()], [popped_value()], t()}

Pops items from the queue while they are available.

A buffer b from pad p is available, if all pads different than p

  • either have a buffer in the queue, that is older than b
  • or haven't ever had any buffer on the queue
  • or have end of stream pushed on the queue.

An item other than a buffer is considered available if all newer buffers on the same pad are available.

The returned value is a suggested actions list, a list of popped items and the updated queue.

If the amount of buffers associated with any pad in the queue falls below the pause_demand_boundary, the suggested actions list contains t:Membrane.Action.resume_auto_demand() actions, otherwise it is an empty list.

Link to this function

pop_chunked(timestamp_queue)

View Source
@spec pop_chunked(t()) ::
  {[Membrane.Element.Action.resume_auto_demand()], [chunk()], t()}

Works like pop_available_items/1, but the returned items are arranged in chunks of duration chunk_duration.

chunk_duration must be passed as an option to new/1. The duration of each chunk may not be exactly the chunk_duration, but the average duration will converge to it. With that exception, only full chunks are returned.

See pop_available_items/1 for details.

Link to this function

push_buffer(timestamp_queue, pad_ref, buffer)

View Source

Pushes a buffer associated with a specified pad to the queue.

Returns a suggested actions list and the updated queue.

If the amount of buffers associated with the specified pad in the queue just exceded pause_demand_boundary, the suggested actions list contains t:Membrane.Action.pause_auto_demand() action, otherwise it is equal an empty list.

Buffers pushed to the queue must have a non-nil dts or pts.

Link to this function

push_buffer_and_pop_available_items(timestamp_queue, pad_ref, buffer)

View Source

The equivalent of calling push_buffer/2 and then pop_available_items/1.

Link to this function

push_buffer_and_pop_chunked(timestamp_queue, pad_ref, buffer)

View Source

The equivalent of calling push_buffer/2 and then pop_chunked/1.

Link to this function

push_end_of_stream(timestamp_queue, pad_ref)

View Source
@spec push_end_of_stream(t(), Membrane.Pad.ref()) :: t()

Pushes end of stream of the specified pad to the queue.

Returns the updated queue.

Link to this function

push_event(timestamp_queue, pad_ref, event)

View Source
@spec push_event(t(), Membrane.Pad.ref(), Membrane.Event.t()) :: t()

Pushes event associated with a specified pad to the queue.

Returns the updated queue.

Link to this function

push_stream_format(timestamp_queue, pad_ref, stream_format)

View Source
@spec push_stream_format(t(), Membrane.Pad.ref(), Membrane.StreamFormat.t()) :: t()

Pushes stream format associated with a specified pad to the queue.

Returns the updated queue.

Link to this function

register_pad(timestamp_queue, pad_ref, opts \\ [])

View Source
@spec register_pad(t(), Membrane.Pad.ref(), register_pad_options()) :: t()

Registers an input pad in the queue without pushing anything on that pad.

Once a pad is registered with option wait_on_buffers?: true (default), the pop_available_items/3 function won't return any buffers until a buffer or end_of_stream is available on the registered pad.

Pushing a buffer on an unregistered pad automatically registers it.