[Windows Mobile] Capturing Raw Frames or SampleGrabber and DirectShow.NETCF
What is SampleGrabber? this is filter (as a rule Transform or TransInPlace) that goes after filter which samples we are going to grab.
Why do we need SampleGrabber?
1. In windows mobile this is the fastest way to still images, more than that we still uncompressed images (so we dont loose time for encoding/decoding)
2. We can use SampleGrabber to draw text or images on received stream
3. We grab images to memory.
I Think this is enough to say that sample grabber is useful.
The problem is that windows already have sample grabber and we dont need to make any extra moves to use it, but Windows Mobile knows nothing about sample grabber
On www.codeproject.com you can find some articles that explain how to implement SampleGrabber. But there tons limits and problems in every case, so i decided to implement my own.
The main question was “Is it possible to implement SampleGrabber that not need to registered?”. I meant that if i programming on C++ i can use unit (class) that contain samplegrabber code, i if i programming on any other language i can use this unit compiled to dll. Yes its possible (!!!!) we dont need resvrCE and anything else, just unit or dll
I was going to use developed SampleGrabber for barcode reader, but samples that i receive were too blurred to be recognized even by human (may be this is my cam dieing? O,o). anyway that was reason i decided to stop work on it, so here is what i got for this time:
DirectShowNETCF.Native.dll that contain SampleGrabber. How to use it?
[DllImport("DirectShowNETCF.Native.dll")]
private static extern IntPtr GetBaseFilter();
this is method returns IntPtr that equal to IBaseFilter*
how to get IBaseFilter?
IntPtr grabber_ = GetBaseFilter(); IBaseFilter grabber = (IBaseFilter)Marshal.GetTypedObjectForIUnknown(grabber_, typeof(IBaseFilter));
To grab raw frame you have to call
1. getSize(out long size)
2. alloc memory (use DirectShowNETCF.PInvoke.LocalAlloc(0×40, size))
3. call getFrame(IntPtr pBuff)
[ComVisible(true), ComImport,
Guid("2B21644A-D405-4E27-A51C-A4812bE0CE4C"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IGetFrame
{
[PreserveSig]
int getFrame(IntPtr pBuff);
[PreserveSig]
int getSize([Out] out long size);
}
//example of grabbing frame
public IntPtr grabFrame(ref long bufSize)
{
IntPtr res_ = IntPtr.Zero;
long size = 0;
frmGrabber.getSize(out size);
bufSize = size;
res_ = PInvoke.LocalAlloc(0x40, (int)size);
frmGrabber.getFrame(res_);
return res_;
}
last version of DirectShowNETCF you can download here
Filed under: Programming
November 17th, 2009 at 12:34 pm
Is there any way to draw images on the stream and make them interactable?
November 13th, 2009 at 9:58 am
Mine is HTC 2125 and WM 5.0
November 12th, 2009 at 9:28 pm
strange, what OS and what Device you got this problem on?
November 12th, 2009 at 2:21 pm
I’m getting ConnectGrabberError_2 on init(), when using DirectShowNETCF.Camera.AMCameraEx.AMCameraEx or DirectShowNETCF.Camera.AMCamera.AMCamera. But DirectShowNETCF.Camera.Camera works fine.
Any ideas?
November 11th, 2009 at 9:29 pm
ConnectGrabberError_2 means that there something wrong when we trying to connect samplegrabber and video renderer. What exactly class example you got this message on?
November 11th, 2009 at 4:18 pm
Hi,
Thanks for sharing such a good info with us.
I get an error msg that says “Cannot init camera! Result: ConnectGrabberError_2″ when i click start button on device.
Why do you think that I get this error message ?
Thanks in advance.
Yasin
September 18th, 2009 at 10:23 am
Hi,
Can you put a source code example to use the samplegrabber with a custom filter graph like MPEG1?
Thanx.
September 14th, 2009 at 5:10 pm
i dont know when and how you call this method, so its dificult to help you…
September 14th, 2009 at 4:47 pm
Hi , I have problem when running grabFrame(ref size) method, nullreference exception . Please help??
September 7th, 2009 at 11:19 am
I declared private static IntPtr grabber_ = new intPtr(); and private IBaseFilter grabber = null;
in the init() method, i used the above code > IntPtr grabber_ = GetBaseFilter();
IBaseFilter grabber = (IBaseFilter)Marshal.GetTypedObjectForIUnknown(grabber_, typeof(IBaseFilter)); the rest of the code is same as the sample above.
but i kept getting nullargument exception, when i checked the intrptr, it has a value = intptr.zero. any ideas? thank you very much.