Dynamic Bandwidth Detection (BWCheck)

This example has moved here:

https://www.wowza.com/docs/how-to-check-bandwidth-from-client-to-server-to-test-uplink-to-be-used-by-a-live-stream-encoder-moduleclientbwcheck

http://www.fluidmd.com/wowza/bwcheck.zip

I will update the link in the other post.

Roger.

I’m working on a new checker that will allow you to do this while a stream is running.

I will post the code here when it is ready.

Roger.

Hi Romano,

As is says on page 1 of this thread, The original bw checker was a port of a similar bit of code originally done for FMS2. They did the same thing with the latency.

Since coding the original, I have tried to make some improvements but the latency thing has always bugged be as well :slight_smile:

The problem is that while wowza is multi threaded, the player only runs in a single thread so all call etc join an event queue and get handled in a fifo fashion.

If the player is running standalone then the queue gets polled every 1 ms and the latency is accurate but if it is running in a browser, this is increased to 15 - 16 ms. This is to do with the active-x or plugin.

The latency reported will be affected by this delay and could be up to 15ms too long. If you run the bw checker locally then the latency should be around 0 - 1ms but it is reported up to 15ms.

This bit of actionscript demonstrates this. First run it in a standalone player and then in the browser. You will need a debug player with flashlog.txt enabled to be able to see the traces.

var time:Date;
var timer:Number = 0;
var lastTime:Number = 0;
function counter() {
	time = new Date();
	trace(String(time.getTime() - lastTime));
	lastTime = time.getTime();
}
timer = setInterval(counter, 1);

The problem is I haven’t found a way to distinguish the difference between the real latency and the delay in the event queue.

Around line 153 in the code, is the first call to the client. This is an empty packet which basically just wakes up the client. I found in testing that the first call always took a long time.

In FirstResult.onResult, the first real packet is sent to the client. This one measures the round trip latency and is what is used to make the latency calculations.

Next, it sends random packets until bwCheckMaxLoops or bwCheckMaxTime is exceeded.

The actual latency figure is used to subtract the calculated latency from the total time so that a more accurate time value can be obtained. That is why it is multiplied by the number of loops.

In order to get accurate figures, you probably need to increase the packet size and reduce the loop count.

Possibly a more accurate way to calculate the latency would be to do it from the client side as the event queue delay is known and could be subtracted from the actual latency value. The reason I haven’t done this is it would require a custom call on the client.

I am not sure if you are, but it is not wise to run the bw checker while the server is sending an actual stream to the client. The reason for this is the the bwchecker packets will end up getting queued on the wire along with the video packets and the results will be wildly inaccurate. If you are targeting flash player 10 then there are features built into the player to detect the bandwidth of the running stream.

Hi Romano,

Have you checked your results using the checker that comes with Wowza? After my last post, I did some other checks and the results I get are normal both in the browser and standalone.

I think it is possible that Adobe have changed the later browser plugins as they now seem to give similar results to the standalone player even though the above test still shows a 15ms polling cycle.

Roger.

I need to measure upload bandwidth to server for setting cam.quality

Is there any method to calculate the actual bandwidth after the stream has started?

Are there any onStreamFlush event (on the server side) that could be extended?

(I know, that I could use the code of BW checker, but it generates an extra traffic with the measurement which is unnecessary if I have a live/working stream.)

Not really.

What is the event/method that I should extend with these calculations?

How could I measure time (to get bytes per sec)?

I have read the IMediaStream and IOPerformanceCounter section in Server API Guide but have no idea.

Take a look at the IOPerformanceCounter interface that is attached the IMediaStream interface.

Through the IOPerformanceCounter you can monitor the bits that travel in and out of the publishing stream. So if you monitor this over time you can calculate the rate.

Charlie

Thanks for the tip, now I can query the actual MessageBytes counters of the publishing stream and I’m able to calculate the actual traffic rate of the publisher.

Actually I want to track of lost traffic, but the getMessagesLossBytes counter gives me always 0. (I reproduced an upload limited situation.)

My server side code is:

public void getStreamStats(IClient client, RequestFunction function, AMFDataList params)
	{
		String streamName = params.getString(PARAM1);
		List streamList = null;
		AMFDataObj streamStatObj = new AMFDataObj();
		IApplicationInstance appInstance = client.getAppInstance();
		MediaStreamMap streams = appInstance.getStreams();
		IMediaStream stream = streams.getStream(streamName);
		IOPerformanceCounter streamStats = stream.getMediaIOPerformance();
		streamStatObj.put("droppedBytes", new AMFDataItem(streamStats.getMessagesLossBytes()));
		streamStatObj.put("outBytes", new AMFDataItem(streamStats.getMessagesInBytes()));
	
		getLogger().debug("getStreamStats for "+streamName+", BytesIn:"+streamStats.getMessagesInBytes()+", BytesOut:"+streamStats.getMessagesOutBytes()+", BytesLoss:"+streamStats.getMessagesLossBytes());
		
		sendResult(client, params, streamStatObj);
	}

My goal is to alert the live publishing client/user if the upload bandwidth limit is exceeded.

since the throttling is happening on the client side

Charlie

So then, anybody has Actionscript code to detect if frame dropes happen by publishing?

hi ,

i am new to Wowza media server…

here live video is coming from client side(flash player using action scripts)

now i want write java code on server side to take that video from client…

please send java code to server side…

and also provide how to compile that one and execute it…

please sir…

thank u.

That trace is coming from netStatusHandler, not onBWCheck:

function netStatusHandler (e:NetStatusEvent):void{
	trace("Level: "+e.info.level+" Code: "+e.info.code);
	if (e.info.code == "NetConnection.Connect.Success") {
		trace("--- connected to: " + nc.uri);	//this.uri
	}
}

“NetConnection.Connect.Success” means it is working.

… also, to get onBWCheck to fire, do this:

var client:Object = new Object();
client.onBWCheck = onBWCheck;
nc.client = client;

That’s what I get too, it’s normal. You can make a new connection every time a new video plays, which is what JW Player does.

Richard

This bandwidth detection, the one in the first post of this thread, measures bandwidth from server to client. There is another version later in this thread that detects bandwidth from client to server. I’m not sure but maybe that one is more consistent.

But I think the reason that bandwidth is calculated server to client is because that is Wowza’s point of view.

Richard

Have you traced the value of detected_bw? Does bandwidthVer have default of “_750”?

Is this up somewhere?

If you’re tester has debug player you can use this method to get trace output from their instance of your player:

http://blog.flexexamples.com/2007/08/26/debugging-flex-applications-with-mmcfg-and-flashlogtxt/

Richard (another one)

richard.lanham@gmail.com

It would be set somewhere above the snip you posted.

But what I was getting at really was whether detect_bw might be null and therefore not meet any of those tests, and so the default value of bandwidthVer is used.

In other words, are you sure the bandwidth checking process has really happened?

Richard

Okay, it’s the example. mostly at least. So you are looking for the trace output of the line below specifically “kbitDown”:

trace("onBWDone: kbitDown:"+kbitDown+" deltaDown:"+deltaDown+" deltaTime:"+deltaTime+" latency:"+latency);

Do you see this trace, and what is it if you do?

There is a server-side to this too, you have to have the right section in the Application.xml at [wowza-install-dir]/conf/video/Application.xml

Also, remember to take out the FLVPlayback Module that is in the original Application.xml. You don’t need that when using the bw check module.

Richard

That looks perfect. Is it solved?

Richard