A Dynamic Buffering strategy

In this TechNote I’m going to talk about the buffering of a FMS (or FCS) stream and about the implementation of a dynamic buffering scheme for recorded streams.

How FMS buffering works

Subscribing a pre-recorded FMS stream, it’s possible to define a subscribing buffer with the method netStream.setBufferTime(N). The buffer behaviour is indeed very simple and similar to that of other media streaming servers. The FlashPlayer receives the stream and archives it until the buffer is full, at that moment, the stream starts to play and the Flash Player tries to keep the buffer full to its nominal lenght. If the bandwidth is insufficient, the buffer slowly decreses; when the buffer is empty, the playing is stopped until the buffer reaches again the desired lenght. The picture below illustratse the buffer behaviour related to an ipotetic profile of available client-server bandwidth.

The first profile illustrates an ipotetic client-server bandwidth normalized on the required stream bandwidth. The second profile reports the buffering lenght normalized to a required value (es: 4 sec). At the beginning, the buffer starts to fill linearly because the playing is not yet started and the bandwidth is constant. In time T1 the buffer is full, the stream start to play and the buffer is keeped full by a bandwidth greater than the required (Available bandwidth > 100% of the required by stream). In T2 the available bandwidth becames insufficient and the buffer starts to empty. In T3 the buffer is definitely empty, the stream is paused and therefore the buffer restart to fill almost linearly because of the almost costant bandwidth (notice that the refill time is more than doubled because of the halved bandwidth). Reached the full state, the stream exits from pause and the buffer lenght is the result of the buffer flushing (dued to the playing) and the buffer filling (dued to the available bandwidth). In time T5 the available bandwidth reach the 100% minimum required value and the buffer becames to fill again up to the full status (T6).

We have seen that with this standard, static buffering method, if bandwidth decreases under the required value, the buffer may be insufficient to compensate the bandwidth void and one or more rebuffering may be necessary to get over. Obviously with a bigger and deeper buffer, this could not happen.

We must indeed choose a buffer depth thinking that:

1. to prevent rebuffering, the buffer must be deep. A deeper buffer can compensate a longer time lapse with insufficient bandwidth.

2. a buffer to much deep means an higher buffering time and probably a worst viewer experience.

Why then not to use a dynamic buffer instead of a static one ?

The rise of the dynamic buffering

Using the onStatus event of our netStream object, we are able to recognise when the buffer is full or empty. So, we can set a starting buffer lenght and then, reached the buffer full status, we can set it to an higher value to exploit the bandwidth eventually in excess. If the buffer goes empty, we can lower the buffer lenght again to the starting value. The code is quite simple:

// Init

startBL=2; mainBL=15;
in_ns.onStatus = Status;

function Status(infoObject:Object) {
if (infoObject[“code”]==”NetStream.Buffer.Full”){in_ns.setBufferTime(mainBL);};
if (infoObject[“code”]==”NetStream.Buffer.Empty”){in_ns.setBufferTime(startBL);};
};Let’s take a look at the dynamic buffer behaviour:

Compared to the previous behaviour, when the Starting Buffer (SB) is full, the buffer lenght is enlarged to exploit the amount of bandwidth beyond the required. Until the time T2, when available bandwidth decreases under the 100%, the buffer continues to fill. With this “supply” of video, the lack of bandwidth between time T2 and T3 is handled without video interruptions. At time T3 bandwidth returns over the 100% and the buffer grows again.

The dynamic buffer can guarantee short starting time (using a low startBL) and at the same time an arbritarily high resilience to bandwidth fluctuation. Dynamic buffering is more usefull when average bandwidth is higher than the required (a very common scenario). When average bandwidth is equal to the required, it is still usefull but starting buffer must be deep since the beginning with less advantages.

If the video is often seeked, may be usefull to set a mainBL not too high.

Dynamic buffering in progressive downloaded video is useless, because the download is inherently dynamic, infact while the buffer fills, the whole flv is cached by the player, even beyond the buffer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s