Sign in to follow this  
shlomi

Rendering video to texture with DirectShow

Recommended Posts

shlomi    122
Hello, I am trying to use DirectShow and Direct3D to render a video to a texture surface, and then display the texture on a 3D object. Unfortunately I have to use DirectX 8.1. I tried to follow the Texture3D9 sample which is distributed with the DirectShow SDK. The example implements a custom DirectShow filter to capture the video frames and copy it to a texture. For some reason, maybe because compatability issues, attaching the texture causes some wierd memory overiding. Now I am trying to use ISampleGrabber to do the same thing, as described in the following post: Link When I call IMediaControl::Run, after adding a Null Renderer and a SampleGraber filter, the function returns S_FALSE. What can be the cause? Does anybody know easier ways to implement what I need? Can you give me some references or code examples? Please help if you can, this is quite urgent. Thanks a lot, Shlomi Fruchter. [Edited by - shlomi on May 26, 2005 4:05:50 AM]

Share this post


Link to post
Share on other sites
LDenninger    122
After struggling with bugs in my own implementation of my video-texture stuff I switched to the ZVidcap sources ( http://www.mine-control.com/zack/ ).

One thing though - the source on the linked site is out of date and has some problems - I received a much newer & better version when I mailed Zack about it..
I think it's time he puts the new version on his site ;)

Share this post


Link to post
Share on other sites
mrmrcoleman    320
Could you post the code you used when trying out the sample grabber method?

Also a few things you could try in the mean time...

1. Try loading up GraphEdit, attach to your process (make sure you have registered the graph builder with the running object table), and then step through your initialisation code. You should be able to see what is happening in the graph. Compare this to what you think should be happenning and you will find the problem.

2. You say that Run() fails which is very strange; either the graph is already running, or one of the methods in your initialisation has failed. You need to check the return value on every single method you call in your initialisation, the answer will be in there. When you find the dodgy method post it here and then we will be able to offer more help.

3. Don't give up on the Sample Grabber method, it works and it works well!

edit: If it really is urgent you could email the file that you are trying to render to me and I will see if I can send you the correct code back to you to get it working. But it won't be until at least Tuesday so it would probably be faster if you fixed your own code.

Good luck.

Mark Coleman

Share this post


Link to post
Share on other sites
DrGUI    402
Perhaps it would be possible to do some sort of interop from your C++ application to Managed DirectX, as that has a namespace called AudioVideoPlayback, which contains a class called Video which can render to texture!

Share this post


Link to post
Share on other sites
shlomi    122
Thanks for all your replies!

I tried to use GraphEdit to debug the program, and everything seems to be OK (fix me if I'm wrong):
The AVI file is connected to AVI Splitter that is connected with the Sample Grabber and an ACM Wrapper. The Sample Grabber output is connected to a Null Renderer. The ACM Wrapper is connected to a Default DirectSound Device.

I am getting the data to the grabber, but I can't figure out the format. When I'm calling GetConnectedMediaType I can see that the media type is either FORMAT_MPEGVideo or FORMAT_VideoInfo depends on the file I'm trying to play.

How do I convert the data recieved from GetCurrentBuffer to a A8R8G8B8 texture? For example, when I run skiing.avi (a DirectX sample video) which is 128x128, GetCurrentBuffer returns buffer's size of only 2020 bytes. How could that be?

My code:

long video_buffer_size;
HRESULT hr = m_pVideoGrabber->GetCurrentBuffer(&video_buffer_size, NULL);
BYTE* video_buffer = new BYTE[video_buffer_size];
hr = m_pVideoGrabber->GetCurrentBuffer(&video_buffer_size, (long*)video_buffer);

AM_MEDIA_TYPE mt;
hr = m_pVideoGrabber->GetConnectedMediaType(&mt);

// Test format...

VIDEOINFOHEADER *Vih = (VIDEOINFOHEADER*)mt.pbFormat;

// Now what...?

Thanks,
Shlomi Fruchter.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this