Wowza Community

Dynamic Bandwidth Detection (BWCheck)

No, I don’t think anyone has had a go at extending the BWChecker to test upload performance.

Charlie

Also, set the ObjectEndoding to AMF0.

Charlie

The getMessagesLossBytes will always be 0 when publishing since the throttling is happening on the client side. Wowza Pro has no idea if packets are being dropped on the server side.

Charlie

I don’t know of any way of getting that information.

Charlie

There shouldn’t be. Maybe Roger will chime in with more info.

Charlie

I think the problem is obvious isn’t it. Your client-side method is:

public function onBWDone(kbitDown:Number, deltaDown:Number, deltaTime:Number, latency:Number):void

It is looking for a version of this method with no parameter.

public function onBWDone():void

Charlie

When I try to use this tool it sits on “testing performance…” indefinitely.

Sorry, I didn’t see the top post since I was linked directly to the second post. I have it working now.

-Aaron

I will have a look at it and put something up later.

Roger.

I did start to look into it and then got swamped with other things. Will take another look at it.

Roger.

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.