# DRAFT push-pull scheduling

Status

    DRAFT. DEPRECATED by better current implementation.

Observations:

  - The main scheduling mode is chain based scheduling where the source
    element pushes buffers through the pipeline to the sinks. this is
    called the push model

  - In the pull model, some plugin pulls buffers from an upstream peer
    element before consuming and/or pushing them further downstream.

Usages of pull based scheduling:

  - sinks that pull in data, possibly at fixed intervals driven by some
    hardware device (audiocard, videodevice, …).

  - Efficient random access to resources. Especially useful for certain
    types of demuxers.

API for pull-based scheduling:

  - an element that wants to pull data from a peer element needs to call
    the `pull_range()` method. This method requires an offset and a
    size. It is possible to leave the offset and size at -1, indicating
    that any offset or size is acceptable, this of course removes the
    advantages of getrange based scheduling.

Types of pull based scheduling:

  - some sources can do random access (file source, …)

  - some sources can read a random number of bytes but not at a random
    offset. (audio cards, …) Audio cards using a ringbuffer can however
    do random access in the ringbuffer.

  - some sources can do random access in a range of bytes but not in
    another range. (a caching network source).

  - some sources can do a fixed size data and without an offset. (video
    sources, …)

Current scheduling decision:

  - core selects scheduling type starting on sinks by looking at
    existence of loop function on sinkpad and calling
    `_check_pull_range()` on the source pad to activate the pads in
    push/pull mode.

  - element proxies pull mode pad activation to peer pad.

Problems:

  - core makes a tough desicion without knowing anything about the
    element. Some elements are able to deal with a `pull_range()` without
    offset while others need full random access.

Requirements:

  - element should be able to select scheduling method itself based on
    how it can use the peer element `pull_range()`. This includes if the
    peer can operate with or without offset/size. This also means that
    the core does not need to select the scheduling method anymore and
    allows for more efficient scheduling methods adjusted for the
    particular element.

Proposition:

  - pads are activated without the core selecting a method.

  - pads queries scheduling mode of peer pad. This query is rather
    finegrained and allows the element to know if the peer supports
    offsets and sizes in the `get_range()` function. A proposition for the
    query is outlined in draft-query.txt.

  - pad selects scheduling mode and informs the peer pad of this
    decision.

Things to query:

  - pad can do real random access (downstream peer can ask for offset `!= -1`)

  - min offset

  - suggest sequential access

  - max offset

  - align: all offsets should be aligned with this value.

  - pad can give ranges from A to B length (peer can ask for `A ⇐ length ⇐ B`)

  - min length

  - suggested length

  - max length

Use cases:

  - An audio source can provide random access to the samples queued in
    its DMA buffer, it however suggests sequential access method. An
    audio source can provide a random number of samples but prefers
    reading from the hardware using a fixed segment size.

  - A caching network source would suggest sequential access but is
    seekable in the cached region. Applications can query for the
    already downloaded portion and update the GUI, a seek can be done in
    that area.

  - a live video source can only provide buffers sequentialy. It exposes
    offsets as -1. lengths are also -1.