PDA

View Full Version : How to detect frozen frame in the dynamic texture?



Jan Z
05-18-2006, 01:02 PM
The application is receiving video streams in the form of dynamic textures.
One of the goals is to detect when the provided image is not changing (it is static).
The detection process has to be efficient because the video streams are big and refreshed with high frequency, and the GPU is also used for different tasks.
Anybody has any brilliant idea how to do it using GPU?
Any help will be appreciated.

Jan

CatAtWork
05-18-2006, 03:09 PM
Difference shader using last and current frames as the texture inputs -> rendered to an FBO with GenerateMipmap. Then ReadPixels on the smallest mip level to see if anything is non-zero?

AlexN
05-18-2006, 03:49 PM
Perhaps you could use the difference shader, but place the difference into the output alpha and use alpha test + occlusion query to check the number of pixels with a difference greater than 0.

Rodrix
05-18-2006, 07:57 PM
I don't know about GPU ideas,
but I can tell you about some statistics concepts that could help.

You could use some statistics in your ReadPixels, and read not all the pixels of your image, but only a sample. In this way, since the the refresh rate is of very high frequency, you can assure a high probability of determining that the stream is static with a relatively small number of points.

You could also calculate this % of probability of success given the number of pixels to check, and the time interval to determine the static stream (aka use the frequency refresh rate).

Good luck!
Rodrix

Jan Z
05-19-2006, 08:24 AM
All of the advices are very helpful.
Probably I will come up with a hybrid solution using your advices.
Thank you very much.
I have another question:
I will be using newest NVIDA 7800 based cards and no power of two textures.
Will the hardware accelerate creation of the mipmaps?

Jan

sqrt[-1]
05-19-2006, 10:30 AM
Another variation on what CatAtWork said, load the new scene in texture 0, old scene in texture 1.
Enable alpha testing then do something like this in a shader:

vec3 diff = (tex0 - tex1);
result.a = Dot(diff,diff) * 100000.0;

And when you render, run an occlusion query to count the number of fragments that got rendered. (if 0, the image was identical)

Jan Z
05-19-2006, 11:54 AM
The texture refresh speed is about 16ms and the size of the texture is really big. I do not have a lot of time to do the processing. I am using NVIDA 7800 cards.
Is the occlusion query done using hardware acceleration?
Is it fast?

Thank you for all the help.

Jan

sqrt[-1]
05-19-2006, 05:40 PM
Occlusion queriesare done using hardware acceleration.

Its hould be fast, but before querying the result, if you have other OpenGL work to do it is best to wait.

Eg.
Setup query and render

.... Do other OpenGL calls here...

Get the query result.

If you get the result straight away, you will force OpenGL to wait on that readback command, stalling the pipeline.

yooyo
05-20-2006, 04:24 AM
If I understand correclty, you have video stream and you copy frames to texture and later do something with this texture. Do you have readback too?

Note that uploading texture to GPU memory could be more expensive than running "difference shader". You will save you GPU clocks by NOT uplading frame to texture. This mean... difference test should be run on CPU.

One of suggestions for this task is to check differences between lines in prev and current frame. You'll got final array of differences and find line with max difference. If this value goes over trashold value you need to refresh GL texture.

Even more... in most cases frames will be different, so you can run test only on couple lines and if you detect difference refresh texture.