Optimization...

Started by
7 comments, last by mrmrcoleman 20 years, 2 months ago
Hello there. I have written some code to copy from a video sample onto and Direct3DTexture9 surface. It is, however, fairly slow and I thought that maybe you guys could give me a hand in speeding it up a little as I dont know all that much about optimization. The code looks like this:

HRESULT TextureRenderer::DoRenderSample( IMediaSample * pSample )
{
	// Set-up variables

	DWORD Width, Height; // Both the sample and the texture are the same size

	long SampleStride, TextureStride;
	BYTE *SampleTop, *TextureTop;
	BYTE *SampleBits;
	RGBQUAD *TextureBits;

	// This is all used for the sample ***********

	// Get a pointer to the DIB data

	pSample->GetPointer(&SampleBits);
	GetVideoInfoParameters(pVIH,
							SampleBits,
							&Width,
							&Height,
							&SampleStride,
							&SampleTop,
							false);

	// Get the information for the texture object

	D3DSURFACE_DESC SurfaceDescriptor;
	AnimationTexture->GetLevelDesc(0, &SurfaceDescriptor);
	
	// These are probably not necessary as the values are already filled above

	Height = SurfaceDescriptor.Height;
	Width = SurfaceDescriptor.Width;
		
	// Lock the texture object

	D3DLOCKED_RECT LockedRect;
	if(AnimationTexture)
	{
		if(FAILED(AnimationTexture->LockRect(0, &LockedRect, NULL, D3DLOCK_DISCARD)))
		{
			MessageBox(0, TEXT("Could not lock texture surface"), TEXT("Error"), 0);
			return false;
		}
	}
	else
	{
		MessageBox(0, TEXT("Texture invalid"), TEXT("Error"), 0);
	}

	// Get the pitch of the texture object

	TextureStride = (LONG)LockedRect.Pitch;

	// Cast the texture bits to an array of RGBQUAD''s (32bpp)

	TextureBits = static_cast<RGBQUAD *>(LockedRect.pBits);

	// Set TextureTop to point to the first element

	TextureTop = (BYTE*)TextureBits;

	// Loop through the two arrays copying each pixel

	for(DWORD y = 0;y < Height;y++)
	{
		// Set pointers to the first elements in each row

		RGBQUAD* TextureRow = (RGBQUAD*)TextureTop;
		RGBQUAD* SampleRow = (RGBQUAD*)SampleTop;
		
		// Loop across the row

		for(DWORD x = 0;x < Width;x++)
		{
			// Assign the RGBQUAD

			TextureRow[x].rgbBlue = SampleRow[x].rgbBlue;
			TextureRow[x].rgbGreen = SampleRow[x].rgbGreen;
			TextureRow[x].rgbRed = SampleRow[x].rgbRed;
			TextureRow[x].rgbReserved = SampleRow[x].rgbReserved;
		}
		TextureTop += TextureStride;
		SampleTop += SampleStride;
	}
This function is called every frame. I already know that it would be a good idea to move some of the variables out of the function but what I think could really help is to the make the loop faster. All is basically does is loop through the sample copying each pixel onto the texture. Each pixel is 32bit and is represented by the RGBQUAD (GDI) for ease of use. If anybody could help that would be greatly appreciated. Mark Coleman P.S. Please dont flame my code too much I know it is pretty bad!
Advertisement
Its hard to optimize that.. I have a similar implementation (actually the DPlay/DXSDK Tex9 sample) and even with 512x512 textures its fast (260K looped iterations of simply copying data).

are you noticing that it''s slow, or just looking for optimizing pointers for reference?
Superdeveloper, I am noticing that it is actually rendering ''slowly'', it is really jumpy.

One thing I thought it might be is that I am rendering a 15mb uncompressed AVI. Would this slow the application down so much?

Mark Coleman
Id say yes, get this, i have a great program called imageforge and it allows you to create gifs, avis, ect, and well i tried to make an avi, worked great... i saved it uncompressed thinking that was non standard, it was about 5 seconds long, it ended up being 30 mb, after STANDARD compression, it was down to 600 kb, and with DivX it was down to 300 so if you consider it, the bandwidth is probably so affected that it gets like that (just my two cents)
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
SuperDeveloper, I have managed to fix it

It was a problem with my FPS code rather than the Direct Show code, I think the FPS was too high so Direct Show was missing lots of frames.

Ademan555 - I think you have a point, but for just one file bandwidth isnt really a problem. However, I will be using up to 10 animations on screen at once so I may well run into trouble. That program you used to compress your AVI, does it maintain the file as an AVI? Also does it maintain the format of the AVI? If so then I would be very aprreciative if you could tell me where I could get it from. I may do some tests to see if it works with my application.

Thanks.

Mark Coleman

[edited by - mrmrcoleman on February 19, 2004 9:13:51 PM]
Yes, it retains the AVI extension, and because its microsoft''s standard compression, i assume it would be compatible, and heres a link (its free to try, i think 20 to buy (i hate it all my favorite old shareware programs are becomming free to try $X to buy ) crimsonland, imageforge, bleh) oh and heres a link

Wow, found a freeware version YAY, anyways it may not support AVI''s so u may want to at least download the non cripple-ware trial...

hope it helps
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
I''m no expert on video files and all but I know that DirectShow''s VMR9 can give you a video image directly as a D3D texture. This is what the ATI Video Shader app uses. Maybe you could look into using that?

neneboricua
When asking these questions, always ask yourself: "where is the bottleneck"?

Then find out. Don''t guess -- measure! Get a profiler. Something like VTune, or Quantify, or CodeAnalyst. It will tell you.

Also, when asking yourself whether your computer can do 10 AVIs, look at the data rate of your AVI. If each AVI is 1 MB/s in data rate, then you''d need to be able to sustain 10 MB/s from your hard disk to play back 10 streams; this is while seeking between the 10 streams.
enum Bool { True, False, FileNotFound };
Although you solved the problem already, i just see one optimization:

Since the color depths are the same (32bit), use memcpy on one row, don''t copy the pixel data byte by byte. Don''t do that if the color depths are different!!

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement