# Cothreads

Cothreads are user-space threads that greatly reduce context switching overhead introduced by regular kernel threads. Cothreads are also used to handle the more complex elements. They differ from other user-space threading libraries in that they are scheduled explictly by GStreamer.

A cothread is created by a `GstBin` whenever an element is found inside the bin that has one or more of the following properties:

- The element is loop-based instead of chain-based

- The element has multiple input pads

- The element has the MULTI_IN flag set

The `GstBin` will create a cothread context for all the elements in the bin so that the elements will interact in cooperative multithreading.

Before proceding to the concept of loop-based elements we will first explain the chain-based elements.

## Chain-based elements

Chain based elements receive a buffer of data and are supposed to handle the data and perform a gst_pad_push.

The basic main function of a chain-based element is like:

    static void
    chain_function (GstPad *pad, GstBuffer *buffer)
    {
      GstBuffer *outbuffer;

      ....
      // process the buffer, create a new outbuffer
      ...

      gst_pad_push (srcpad, outbuffer);
    }

Chain based function are mainly used for elements that have a one to one relation between their input and output behaviour. An example of such an element can be a simple video blur filter. The filter takes a buffer in, performs the blur operation on it and sends out the resulting buffer.

Another element, for example, is a volume filter. The filter takes audio samples as input, performs the volume effect and sends out the resulting buffer.

## Loop-based elements

As opposed to chain-based elements, loop-based elements enter an infinite loop that looks like this:

      GstBuffer *buffer, *outbuffer;

      while (1) {
        buffer = gst_pad_pull (sinkpad);
        ...
        // process buffer, create outbuffer
        while (!done) {
          ....
          // optionally request another buffer
          buffer = gst_pad_pull (sinkpad);
          ....
        }
        ...
        gst_pad_push (srcpad, outbuffer);
      }

The loop-based elements request a buffer whenever they need one.

When the request for a buffer cannot immediatly satisfied, the control will be given to the source element of the loop-based element until it performs a push on its source pad. At that time the control is handed back to the loop-based element, etc... The execution trace can get fairly complex using cothreads when there are multiple input/output pads for the loop-based element. Cothread switches are performed within the call to gst_pad_pull and gst_pad_push; from the perspective of the loop-based element, it just "appears" that gst_pad_push (or _pull) might take a long time to return.

Loop based elements are mainly used for the more complex elements that need a specific amount of data before they can start to produce output. An example of such an element is the MPEG video decoder. The element will pull a buffer, perform some decoding on it and optionally request more buffers to decode, and when a complete video frame has been decoded, a buffer is sent out. For example, any plugin using the bytestream library will need to be loop-based.

There is no problem in putting cothreaded elements into a `GstThread` to create even more complex pipelines with both user and kernel space threads.