I'm using DirectX.Capture to preview video from a webcam inside of a panel. The reason why I use DirectX.Capture is obvious -> it's very simple and provides all I need in my application. But now I would like to see the preview stream from DirectX.Capture in more than one panels/windows at once, and that's not possible by instancing more Capture objects with same video input devices. Can anyone help me with this? I'm new to this forum and maybe there is allready some thread about this that I didn't see, I so pls forward me there... Thanx
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In meantime, i've looked at the DirectShow.NET libraty. So if it's not possible to do with DirectX.Capture , i'll do it with DirectShow.NET. Can anyone tell me how?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've allready come up with one sollution -> capturing video to bitmap (as it is shown in poor's man web cam program DxWebCam sample client/server app) and then i can put the bitmap in more panels (e.c. Picturebox...) . But i feel that it is not programmaticly best way how to do more preview windows, so thanx for the posts and i look at the Infinite Tee filter. As I metnioned, I'm new to this kind of topic so I don't understand what is a GMF bridge, can u please tell me more about it?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
'GMFPreview demonstrates how to keep showing the preview stream from a video capture device while starting and stopping capture into different files'.
Each graph can have its own Ivideowindow interface to accomplish your task and the preview window on the source graph wont blip as you start and stop the capture graph.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Iv'e spent last two days searching for an InfTee filter sample, I've read almost all msdn documentation about graphs and filters, pins and allocators and aaaaallll kind of stuff in DirectShow, but only sample I found was written in C++ in Windows SDK and that's a 'little' more complicated than one would expect, so I'm begging for some example. I mean this should be a simple thing to add an InfTee filter and connect it to any commnig input pins/preview windows. Or maybe it's not. I don't know
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Some time ago I wrote such code to get Teletext properly working on VMR9. Something went wrong always and currently once in a while. I am not using that code anymore and I removed the code partly already. I am using a completely different method now, to get Teletext working with VMR. Which pieces of code you found, you do not understand?
The part of code that is still there uses the Smart tee filter. For the Infinite tee filter (clsid_inftee) the code may probably exactly the same. The code adds the filter and with help of renderstream the filters are connected. I think I wrote also a function that looks for a suitable connection without using renderstream. Such function can be written yourself. Look at the filter removal code in DirectX.Capture to get an idea how you can do that.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Allright , I got my InfTee filter and everything seems to work allright, but:
Every time, I initialize new window to preview the capture stream, I do it this way:
try
{
int hr = 0;
// stops media stream if running
this.Stop();
// initializing new video Renderer
videoRenderer = new VideoRenderer() as IBaseFilter;
// adding that render to filter
hr = graphBuilder.AddFilter(videoRenderer, "Video Renderer");
DsError.ThrowExceptionForHR(hr);
// connect renderer to the tee filter (which is of course connected to capture source filter)
hr = captureGraphBuilder.RenderStream(null, MediaType.Video, infTee, null, videoRenderer);
DsError.ThrowExceptionForHR(hr);
object videoWin = null;
// find IVideoWindow vidow, which will be put into preview window control(panel) to show preview
hr = captureGraphBuilder.FindInterface(null, MediaType.Video, videoRenderer, typeof(IVideoWindow).GUID, out videoWin);
DsError.ThrowExceptionForHR(hr);
if (videoWin != null)
{
// than set notify window
hr = mediaEventEx.SetNotifyWindow(window.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
// window is the new control parent of preview window, so I'm passing the IVideoWindow object
// to that parent control to be able to control it (show/hide, resize,...)
window.VideoWindow = videoWin as IVideoWindow;
}
}
finally
{
// releasing renderer resources, 'cause I dont need it anymore
if (videoRenderer != null)
Marshal.ReleaseComObject(videoRenderer); videoRenderer = null;
}
si this is my initialization. Every time I want to show/hide preview in one of my preview panels, I call
// (inside of preview panel)
VideoWindow.put_Visible(OABool.True/False);
And here the problem occurs. Every time when I call this method to show preview in any of my preview windows, and all my preview windows are in hidden state, all of them become visible. I looks to me as the IVideoWindow interface, that I get by captureGraphBuilder.FindInterface() , is allways the same COM object or a least they're somehow connected. There are also some other small show/hide issues when displaying more windows...
Probobly it is bad way to always initialize new VideoRenderer and find IVideoWindow in it...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Next funny thing is that when the windows are in same form, and the form is moved, one of them (the first one initialized) is perfectly steady (in it's owner control) and the other one is kind of catching up the movement, allways a few pixels behinds it's owner control postion. It's gotta be something with message handling , but I dont't understand it, because all messages are passed also to IVideoWindow child :
if (this.VideoWindow != null)
this.VideoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32());
and messages of type WM_GRAPHNOTIFY are passed to all panels(capture windows) that contain IVideoWindow.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm using DirectX.Capture to preview video from a webcam inside of a panel. The reason why I use DirectX.Capture is obvious -> it's very simple and provides all I need in my application. But now I would like to see the preview stream from DirectX.Capture in more than one panels/windows at once, and that's not possible by instancing more Capture objects with same video input devices. Can anyone help me with this? I'm new to this forum and maybe there is allready some thread about this that I didn't see, I so pls forward me there... Thanx
In meantime, i've looked at the DirectShow.NET libraty. So if it's not possible to do with DirectX.Capture , i'll do it with DirectShow.NET. Can anyone tell me how?
Nothing wrong with using DirectX.Capture. I have used a version of this myself (one that I updated to work with our library).
Outputting to more than one window panel is do-able. If they are all in the same application. Going cross application is going to be a lot tougher.
However, you'll need to make some mods down in the depths of Capture. In particular, read about the Infinite Tee filter: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directshow/htm/infinitepinteefilter.asp
Can u help me out with some code examples with that infitite tee filter?
C'mon. What's the big challenge here? You add the filter to the graph, you connect the pins. We have a number of samples that show how to do this.
Have you played with this in GraphEdt?
The GMF bridge is a good option. Run your preview window off the source graph, and capture window on the sink graph.
I've allready come up with one sollution -> capturing video to bitmap (as it is shown in poor's man web cam program DxWebCam sample client/server app) and then i can put the bitmap in more panels (e.c. Picturebox...) . But i feel that it is not programmaticly best way how to do more preview windows, so thanx for the posts and i look at the Infinite Tee filter. As I metnioned, I'm new to this kind of topic so I don't understand what is a GMF bridge, can u please tell me more about it?
http://www.gdcl.co.uk/gmfbridge/index.htm
'GMFPreview demonstrates how to keep showing the preview stream from a video capture device while starting and stopping capture into different files'.
Each graph can have its own Ivideowindow interface to accomplish your task and the preview window on the source graph wont blip as you start and stop the capture graph.
Iv'e spent last two days searching for an InfTee filter sample, I've read almost all msdn documentation about graphs and filters, pins and allocators and aaaaallll kind of stuff in DirectShow, but only sample I found was written in C++ in Windows SDK and that's a 'little' more complicated than one would expect, so I'm begging for some example. I mean this should be a simple thing to add an InfTee filter and connect it to any commnig input pins/preview windows. Or maybe it's not. I don't know
ok, i've looked everywhere but here for samples and that was I mistake :) . I havent played with graph edit yet...
Some time ago I wrote such code to get Teletext properly working on VMR9. Something went wrong always and currently once in a while. I am not using that code anymore and I removed the code partly already. I am using a completely different method now, to get Teletext working with VMR. Which pieces of code you found, you do not understand?
The part of code that is still there uses the Smart tee filter. For the Infinite tee filter (clsid_inftee) the code may probably exactly the same. The code adds the filter and with help of renderstream the filters are connected. I think I wrote also a function that looks for a suitable connection without using renderstream. Such function can be written yourself. Look at the filter removal code in DirectX.Capture to get an idea how you can do that.
Also look here: http://sourceforge.net/forum/forum.php?thread_id=1502288&forum_id=460697
The infinite tee filter is added/used in this code also.
Allright , I got my InfTee filter and everything seems to work allright, but:
Every time, I initialize new window to preview the capture stream, I do it this way:
try
{
int hr = 0;
}
finally
{
// releasing renderer resources, 'cause I dont need it anymore
if (videoRenderer != null)
Marshal.ReleaseComObject(videoRenderer); videoRenderer = null;
}
si this is my initialization. Every time I want to show/hide preview in one of my preview panels, I call
// (inside of preview panel)
VideoWindow.put_Visible(OABool.True/False);
And here the problem occurs. Every time when I call this method to show preview in any of my preview windows, and all my preview windows are in hidden state, all of them become visible. I looks to me as the IVideoWindow interface, that I get by captureGraphBuilder.FindInterface() , is allways the same COM object or a least they're somehow connected. There are also some other small show/hide issues when displaying more windows...
Probobly it is bad way to always initialize new VideoRenderer and find IVideoWindow in it...
And one more thing. If there is only one preview window, and I stop preview like :
IVideoWindow.put_Visible(OABool.False);
Last frame of the preview stays still drawn on the panel, even if I call
Invalidate(true);
on the preview control (owner of IVideoWindow). How can it be erased, when there is no handle to IVideoWindow window?
Next funny thing is that when the windows are in same form, and the form is moved, one of them (the first one initialized) is perfectly steady (in it's owner control) and the other one is kind of catching up the movement, allways a few pixels behinds it's owner control postion. It's gotta be something with message handling , but I dont't understand it, because all messages are passed also to IVideoWindow child :
if (this.VideoWindow != null)
this.VideoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32());
and messages of type WM_GRAPHNOTIFY are passed to all panels(capture windows) that contain IVideoWindow.
All my problems solved, at least for now ;) Thanx anyway
By the time I read your first messages, it appears you have already solved everything!