#### Archived

This topic is now archived and is closed to further replies.

# Playing an avi onto a direct3d surface

This topic is 5996 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I want to be able to play an avi file onto a region of my direct3d8 window. I presume the "proper" way of doing this involves DirectShow, but I am finding DirectShow *very* slow. The avi I am trying to play is width=900, height=1200. The fil plays for 10 seconds at 30 frames per second, and is currently encoded with the cinpack compressor (although I can easily change to pretty much any other codec if it will make things simpler/faster). As far as I can tell the only DirectShow example program that also uses Diret3d8 is the one that plays the skiing avi onto a texture, and then maps that onto a cylinder. The others all seem to not use direct3d8 (some only create a window, and one uses direct draw in full screen mode). However, I modified the avi-texture sample to play my avi, and to map it onto an single polygon. However, even for just displaying the top 512x512 area of this avi with this technique I was only getting 10-12 fps with my 1.7Ghz P4 + 128MB Geforce4. With directx7 I used to be able to play avi''s really fast using the windows streaming services, but these require an IDirectDrawSurface (note, no number on the end) to render to, and I dont seem to be able to QueryInterface() that kind on surface from anything in Direct3d8. Sorry for the long post, my questions are these: - Has anyone got a non-sdk example of using DirectShow to render an avi to a direct3d8 window? - Is there a way to get an IDirectDrawSurface from Direct3d8 anywhere so I can continue using my old code? - Any better ideas for playing a movie quickly in direct3d8? I dont need to play it onto a texture, I just want to play it to a specified rectangle on the screen. Thanks for any advice, Alan

##### Share on other sites
foo bar?

Sorry, I''m not assuming your ignorance. Those probably just cover DirectDraw, but they might have |something| you haven''t considered before. If not, sorry for wasting your time.

Peace,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//

##### Share on other sites
quote:
Original post by AlanKemp
The avi I am trying to play is width=900, height=1200

Have you tried playing an AVI that is not so insanely big?

##### Share on other sites
Hehe! 900x1200 is pretty big!

~~~~
Kami no Itte ga ore ni zettai naru!

##### Share on other sites
quote:
Original post by Michalson
Have you tried playing an AVI that is not so insanely big?

Its worse than you can possibly imagine...

The huge avi is just the backdrop for a trade-show display. On top of that there is 3d graphics, scrolling text etc etc.

ZealousElixir: Yep, I have already seen those. The DirectShow one is just plain win32 (no direct3d), and the other uses DirectDraw (no number) and DirectDrawSurface (again no number), so unless someone knows a way of extracting either of those from direct3d8...

No one has any hints or tips then?

Alan

##### Share on other sites
Basically you have to copy the data to a texture. I use a 32 bit power of 2 texture, since most cards need textures to be power of 2, the 32 bit is so its is easier to copy the 24 bit dib to the texture. Also make sure your avi has keyframes at smallish intervals, otherwise it may chug.

You can either rescale the dib at run time (stretch blit to another dib), or rescale your avi before hand to be a power of 2. Then just draw a quad using this texture before your 3d stuff etc.

I'm doing this and it seems to work quite well. For an 512x256 avi on a gforce ti4600, Athalon 1800mhz, I get 60fps+.

have a look here for the code I used for decoding an avi

http://www.gamedev.net/reference/programming/features/avifile/page5.asp

I just do:-

  // DeltaTime is in seconds, ie 1/60.0f ...lElapsedTime = DeltaTime*1000.0f;lFrameTime += lElapsedTime * lVideoDirection;LPBITMAPINFOHEADER pBmp;GetVideoFrameAtTime(0, lFrameTime, &pBmp);//then in you dx stuff somewhere.. Note this is not the most efficent way of doing it,// the textureLPDIRECT3DTEXTURE8 Surface=YourTexture;if( pBmp ){	D3DLOCKED_RECT rect; 	u16 y,x;	DXCOLOUR *Dst;	LPBITMAPINFO pBmpInfo=(LPBITMAPINFO)pBmp;	u8 *pBmpBits = ((LPBYTE)pBmpInfo) + pBmpInfo->bmiHeader.biSize;				// lock and copy	if( SUCCEEDED(Surface->LockRect( 0, &rect, 0, 0 )) )	{		// copy		for( y=0;y<pBmp->biHeight;y++)		{			Dst = (DXCOLOUR*)((u8*)rect.pBits + (rect.Pitch*y));											for( x=0;x<pBmp->biWidth;x++,pBmpBits+=3)			{				Dst[x].r = pBmpBits[2];				Dst[x].g = pBmpBits[1];				Dst[x].b = pBmpBits[0];				Dst[x].a = 255;			}			}		Surface->UnlockRect(0);	}}	//then draw the rect

Mark Duffill[The Jackal]
Eurocom Entertainment Software

[edited by - mark duffill on July 17, 2002 7:00:33 PM]

##### Share on other sites
(assuming you only need 2D video) play the AVI using a plain ol'' fullscreen directshow window with video overlay.

create your direct3d window OVER the DS window. Set your clear color to match the overlay color. In some cases, the overlay color may be different when the app runs. You may need to account for that.

Render your 3D stuff as usual. The overlay will handle the mixing automagically. BUT, you won''t have any real transparency between the video and 3D objects. You can create cheap transparency with dithered textures. We can discuss that if need be...

##### Share on other sites
i assume it plays fine when using media player.

i have gotten full framerate 720x480 divx encoded avis playing on a texture using dshow. i use a 1024x512 (may have been 1024x1024) texture and i DONT scale the video. instead i use texture coordinates to fit the video properly on the polygons.

i suggest dropping the res of your video. 900x1200 definatly will be difficult to fit on screen and would use tons of resource to read and decode. just transferring that much data over the agp bus is quite difficult and slow. try a lower res (ie drop the actual file, not at runtime).

if you want you could use the the dshow7 interface and lock the surface for the transfer.

there is a problem however, possibly hardware accelration (like overlays and only updating small section of vram instead of the entire frame, hardware yuv decoding) can be the reason you get high framerates. when this accelration is taken away with your render filter, things get slow. 900x1200 is large, drop it to 450x600 and scale using the polygon. it will still be plenty clear. heck, are you ever running at 1600x1200? if not your wasting agp bandwidth sending data to the card that you will just crop anyway (ie down scale).

1. 1
2. 2
Rutin
21
3. 3
A4L
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 44
• ### Forum Statistics

• Total Topics
633742
• Total Posts
3013628
×