Experiments have demonstrated that the actual retrieval or transmission bit rate as well as various delays can vary from time to time. To alleviate this problem, a buffer is designed for each resource to absorb rate variations.
We consider that the system consists of multiple producers and consumers with buffers in between to absorb variations in the production and consumption rates. The server (as a producer) produces data by reading it from the disk. This data is consumed by the network (as both consumer and producer) and produced at the client side. The client (as a consumer) in turn consumes this by displaying it on the presentation devices.
A buffer is allocated for each resource in the system. Thus, there is disk buffer at the server end that holds data from the disk before it is transmitted over the network. Similarly, there is a network buffer at the client which stores data before it is consumed. There is a separate network and disk buffer for each stream that is to be presented. Thus, in case that a client displays two streams, there will be two sets of network and disk buffers. A presentation buffer can be optionally designed for keeping decoded data. This additional level of buffering can further adjust the rate variations between encoded and decoded data before presentation.
Since resources are allocated to keep the production and consumption rates constant and buffers absorb transient changes in these rates, the presentation should ideally continue without any hiccups. However, in certain situations, the buffers can {\em overflow or underflow}. This happens when there is always a mismatch between the production and consumption at a buffer. To avoid these problems, the system must be able to dynamically adapt by providing some kind of feedback mechanisms.