PDA

View Full Version : QHttp delaying requests



etru1927
28th April 2008, 12:10
Hi all,

I'm trying to retrieve images from a network camera to display them on a window. I'm sending requests every 50 milliseconds, but I only get 1 FPS or so. The problem seems to be on the Qt side, since 'get' requests are actually sent at that rate (according to signal requestStarted()). Sample output:

Request 1 started (host setup)
Request 1 finished
Request ignored (no image)
Petitioning with id: 2
Request 2 started
Petitioning with id: 3
Petitioning with id: 4
Petitioning with id: 5
Request 2 finished
Reading new frame... (2)
Updating frame on window...
Request 3 started
Request 3 finished, error? 0
Reading new frame... (3)
Updating frame on window...
Request 4 started
Request 4 finished, error? 0
Reading new frame... (4)
Updating frame on window...
Request 5 started
Request 5 finished, error? 0
Reading new frame... (5)
Updating frame on window...

Is this behaviour expected for QHttp? I don't see anything in the documentation saying so, but I'm rather new to Qt. Any ideas?

Thanks!

wysota
28th April 2008, 12:42
Yes, this is expected. QHttp API queues requests and that is clearly mentioned in the docs:

The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished().

etru1927
28th April 2008, 13:12
I've gone over that line at least a dozen times (before your post, and after) and I still don't understand how this behaviour can be inferred from there. I understand that requests are queued and executed asynchronously, but I don't see why one request is not sent until the previous one has finished. Is that what "scheduled" means? If so I guess I'll have to work on my computer science jargon!

If that is the case, what other mechanisms may I use to solve this problem? QTcpSocket?

Thanks again.

wysota
28th April 2008, 13:47
Is that what "scheduled" means?
Yes.


If so I guess I'll have to work on my computer science jargon!
I don't think this is CS jargon :) Scheduling means putting something in sequence (order) and that's exactly what happens here.


If that is the case, what other mechanisms may I use to solve this problem? QTcpSocket?

Depends what you need. QHttp is fine, just use it accordingly. If you really need more than one request processed at the same time, use more than one QHttp object. In general you should connect to signals and process them in your slots. Remember that Qt is event driven, there is no linear flow here, you need to think in terms of events and react to them.

etru1927
28th April 2008, 15:56
I see, I see! That's feasible, but it puts me square into the troubled land of concurrency.

It seems there's too much overhead associated with http calls anyway, so I'm doomed to request the stream and decode it on the fly (which I'd have to do eventually in any case, but I hoped to dodge this one for a while). Thanks for your help. I'll look into the dictionary before asking next time!

stevey
29th April 2008, 01:59
It seems there's too much overhead associated with http calls anyway
That's why many streaming servers use a different underlying protocol, like UDP. There's less handshaking going on, but you can lose data if there's a bottleneck, so if that doesn't matter to you use UDP (if you can).

wysota
29th April 2008, 10:06
Using high-layer protocols like HTTP to transfer each frame separately seems to be an overhead. Using plain tcp or a single http request for all the frames might help a lot. Unfortunately QHttp doesn't pipeline requests, so there will always be a lag between requests.

Scorp2us
29th April 2008, 22:00
thread :----get()--your code or idle loop--------------------done() emitted---------> time
I/O...:.........(request queued)...(bytes start coming in) (done)



Oddly enough, the socket I/O uses callbacks, so it doesn't need a dispatch loop (i.e. exec()) running to work.

If you want it blocking you can use a custom client, or you can use QxtSignalWaiter which you can have wait on the done() signal. If you do this, you will likely have lag, and you'd need more threads so that one request doesn't hold up the rest. You then have to put your images in order because you don't know the order in which they will complete. If you stick with the async stuff, then you can keep it in one thread, but you still have to enforce proper ordering of images.

wysota
29th April 2008, 22:52
"Qt Concurrent" module might be a bit helpful, although I still say to use another approach. HTTP is simply too slow and it's text based so you have to decode the data.