[Windows Mobile] Capturing video from device camera C# or DirectShow.NET CF Part II

In previous post i explained how to play video or audio on Windows Mobile devices using DirectShow.
I`ve received some emails with request to explain how preview video from device camera.
First of all in Windows Mobile SDK in examples you can find C++ exmaple. I`ve seen examples that suggest  to compile example from SDK to dll and than importing methos from that dll watch camera preview. I did little bit more, i ported whole code to C# so we dont need any dll. So what do we need? we need import 3 api methods, FindFirstDevice, FindClose and GetClientRect

[DllImport("coredll.dll")]
public static extern int GetClientRect(
[In] IntPtr hWnd,
[Out] out Rect lpRect);

[DllImport("coredll.dll")]
public static extern IntPtr FindFirstDevice(
[In] int searchType,
[In] IntPtr searchParam,
[In, Out] ref DEVMGR_DEVICE_INFORMATION pdi);

[DllImport("coredll.dll")]
public static extern int FindClose([In] IntPtr hFindFile);

also we need 6 more Com Interfaces:
IVideoWindow, IBaseFilter, IPersist, IPersistPropertyBag, IPropertyBag, ICaptureGraphBuilder2

[ComVisible(true), ComImport,
Guid("56A868B4-0AD4-11CE-B03A-0020AF0BA770"),
InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IVideoWindow
{
[PreserveSig]
int put_Caption([In] string caption);

[PreserveSig]
int get_Caption([Out] out string caption);

[PreserveSig]
int put_WindowStyle([In] int windowStyle);

[PreserveSig]
int get_WindowStyle([Out] out int windowStyle);

[PreserveSig]
int put_WindowStyleEx([In] int windowStyleEx);

[PreserveSig]
int get_WindowStyleEx(out int windowStyleEx);

[PreserveSig]
int put_AutoShow([In] int autoShow);

[PreserveSig]
int get_AutoShow([Out] out int autoShow);

[PreserveSig]
int put_WindowState([In] int windowState);

[PreserveSig]
int get_WindowState([Out] out int windowState);

[PreserveSig]
int put_BackgroundPalette([In] int backgroundPalette);

[PreserveSig]
int get_BackgroundPalette([Out] out int backgroundPalette);

[PreserveSig]
int put_Visible([In] int visible);

[PreserveSig]
int get_Visible([Out] out int visible);

[PreserveSig]
int put_Left([In] int left);

[PreserveSig]
int get_Left([Out] out int left);

[PreserveSig]
int put_Width([In] int width);

[PreserveSig]
int get_Width([Out] out int width);

[PreserveSig]
int put_Top([In] int top);

[PreserveSig]
int get_Top([Out] out int top);

[PreserveSig]
int put_Height([In] int height);

[PreserveSig]
int get_Height([Out] out int height);

[PreserveSig]
int put_Owner([In] IntPtr owner);

[PreserveSig]
int get_Owner([Out] out IntPtr owner);

[PreserveSig]
int put_MessageDrain([In] IntPtr drain);

[PreserveSig]
int get_MessageDrain([Out] out IntPtr drain);

[PreserveSig]
int get_BorderColor([Out] out int color);

[PreserveSig]
int put_BorderColor([In] int color);

[PreserveSig]
int get_FullScreenMode([Out] out int fullScreenMode);

[PreserveSig]
int put_FullScreenMode([In] int fullScreenMode);

[PreserveSig]
int SetWindowForeground([In] int focus);

[PreserveSig]
int NotifyOwnerMessage(
[In] IntPtr hwnd,
[In] int msg,
[In] IntPtr wParam,
[In] IntPtr lParam);

[PreserveSig]
int SetWindowPosition(
[In] int left,
[In] int top,
[In] int width,
[In] int height);

[PreserveSig]
int GetWindowPosition(
[Out] out int left,
[Out] out int top,
[Out] out int width,
[Out] out int height);

[PreserveSig]
int GetMinIdealImageSize(
[Out] out int width,
[Out] out int height);

[PreserveSig]
int GetMaxIdealImageSize(
[Out] out int width,
[Out] out int height);

[PreserveSig]
int GetRestorePosition(
[Out] out int left,
[Out] out int top,
[Out] out int width,
[Out] out int height);

[PreserveSig]
int HideCursor([In] int hideCursor);

[PreserveSig]
int IsCursorHidden([Out] out int hideCursor);

}

[ComVisible(true), ComImport,
Guid("56A86895-0AD4-11CE-B03A-0020AF0BA770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IBaseFilter
{
[PreserveSig]
int GetClassID([Out] out Guid pClassID);

[PreserveSig]
int Stop();

[PreserveSig]
int Pause();

[PreserveSig]
int Run([In] long tStart);

[PreserveSig]
int GetState(
[In] int dwMilliSecsTimeout,
[Out] out int filtState);

[PreserveSig]
int SetSyncSource([In, MarshalAs(UnmanagedType.Interface)] object pClock);

/// <summary>
///
/// </summary>
[PreserveSig]
int GetSyncSource([Out, MarshalAs(UnmanagedType.Interface)] out object pClock);

[PreserveSig]
int EnumPins([Out, MarshalAs(UnmanagedType.Interface)] out object ppEnum);

[PreserveSig]
int FindPin(
[In, MarshalAs(UnmanagedType.LPWStr)] string Id,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppPin);

[PreserveSig]
int QueryFilterInfo([Out] IntPtr pInfo);

[PreserveSig]
int JoinFilterGraph(
[In, MarshalAs(UnmanagedType.Interface)] object pGraph,
[In, MarshalAs(UnmanagedType.LPWStr)] string pName);

[PreserveSig]
int QueryVendorInfo(
[Out, MarshalAs(UnmanagedType.LPWStr)] out string pVendorInfo);
}

[ComVisible(true), ComImport,
Guid("0000010C-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersist
{
[PreserveSig]
int GetClassID([Out] out Guid pClassID);
}

[ComVisible(true), ComImport,
Guid("37D84F60-42CB-11CE-8135-00AA004BB851"),//Guid("5738E040-B67F-11d0-BD4D-00A0C911CE86"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistPropertyBag : IPersist
{
#region IPersist
[PreserveSig]
new int GetClassID([Out] out Guid pClassID);
#endregion

[PreserveSig]
int InitNew();

[PreserveSig]
int Load(
[In] IPropertyBag pPropBag,
[In, MarshalAs(UnmanagedType.Interface)] object pErrorLog
);

[PreserveSig]
int Save(
IPropertyBag pPropBag,
[In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty,
[In, MarshalAs(UnmanagedType.Bool)] bool fSaveAllProperties
);
}

[ComVisible(true), ComImport,
Guid("55272A00-42CB-11CE-8135-00AA004BB851"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyBag
{
[PreserveSig]
int Read(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
[In, Out, MarshalAs(UnmanagedType.Struct)]    ref    object pVar,
[In] IntPtr pErrorLog);

[PreserveSig]
int Write(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
[In, MarshalAs(UnmanagedType.Struct)] ref object pVar);
}

[ComVisible(true), ComImport,
Guid("93E5A4E0-2D50-11D2-ABFA-00A0C9C6E38D"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICaptureGraphBuilder2
{
[PreserveSig]
int SetFiltergraph([In] IGraphBuilder pfg);

[PreserveSig]
int GetFiltergraph([Out] out IGraphBuilder ppfg);

[PreserveSig]
int SetOutputFileName(
[In] ref Guid pType,
[In, MarshalAs(UnmanagedType.LPWStr)] string lpstrFile,
[Out] out IBaseFilter ppbf,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppSink);

[PreserveSig]
int FindInterface(
[In] ref CGuid pCategory,
[In] ref CGuid pType,
[In] IBaseFilter pbf,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.IUnknown)] out object ppint);

[PreserveSig]
int RenderStream(
[In, MarshalAs(UnmanagedType.LPStruct)] CGuid PinCategory,
[In, MarshalAs(UnmanagedType.LPStruct)] CGuid MediaType,
[In, MarshalAs(UnmanagedType.IUnknown)] object pSource,
[In] IBaseFilter pfCompressor,
[In] IBaseFilter pfRenderer
);

[PreserveSig]
int ControlStream(
[In] ref CGuid pCategory,
[In] ref CGuid pType,
[In] IBaseFilter pFilter,
[In] IntPtr pstart,
[In] IntPtr pstop,
[In] short wStartCookie,
[In] short wStopCookie);

[PreserveSig]
int AllocCapFile(
[In, MarshalAs(UnmanagedType.LPWStr)] string lpstrFile,
[In] long dwlSize);

[PreserveSig]
int CopyCaptureFile(
[In, MarshalAs(UnmanagedType.LPWStr)] string lpwstrOld,
[In, MarshalAs(UnmanagedType.LPWStr)] string lpwstrNew,
[In] int fAllowEscAbort,
[In, MarshalAs(UnmanagedType.Interface)] object pFilter);

[PreserveSig]
int FindPin(
[In] object pSource,
[In] int pindir,
[In] ref CGuid pCategory,
[In] ref CGuid pType,
[In, MarshalAs(UnmanagedType.Bool)] bool fUnconnected,
[In] int num,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppPin);
}

Everything else the same as in SDK example + i made class to hide directshow from cant or not going to understand it :)
Class got 3 public methods:
init() - inits camera and builds graph
release() - stops preview and releases all com objects
run(IntPtr owner) - start preview on control

using System;
using System.Runtime.InteropServices;

namespace DirectShowNETCF
{
public class CCamera
{
private IBaseFilter video = null;
private IBaseFilter renderer = null;
private ICaptureGraphBuilder2 capGraph = null;
private IGraphBuilder graph = null;
private IVideoWindow window = null;
private IMediaControl control = null;

public CCamera()
{
}

~CCamera()
{
release();
}

public bool init()
{
object obj = null;
#region FilterGraph
Guid clsid = CLSID_.FilterGraph;
Guid riid = IID_.IFilterGraph2;
PInvoke.CoCreateInstance(ref clsid, IntPtr.Zero, (uint)CLSCTX_.INPROC_SERVER, ref riid, out obj);
graph = (IGraphBuilder)obj;
if (graph == null)
{
return false;
}
#endregion
obj = null;
#region CaptureGraph
clsid = CLSID_.CaptureGraphBuilder;
riid = IID_.ICaptuGraphBuilder2;
PInvoke.CoCreateInstance(ref clsid, IntPtr.Zero, (uint)CLSCTX_.INPROC_SERVER, ref riid, out obj);
capGraph = (ICaptureGraphBuilder2)obj;
if (capGraph == null)
{
return false;
}
#endregion
obj = null;

int hr = capGraph.SetFiltergraph(graph);
if (hr < 0)
{
return false;
}

if (!getVideoCaptureFilter())
{
return false;
}

hr = graph.AddFilter(video, "Video Capture");
if (hr < 0)
{
return false;
}

if (!getVideoRenderer())
{
return false;
}

hr = graph.AddFilter(renderer, "Video Renderer");
if (hr < 0)
{
return false;
}
hr = capGraph.RenderStream(null, null, video, null, renderer);
if (hr < 0)
{
return false;
}
control = (IMediaControl)graph;
return true;
}

public void release()
{
if (control != null)
{
control.Stop();
}

if (window != null)
{
window.put_Owner(IntPtr.Zero);
window.put_Visible(-1);
}

if (capGraph != null)
{
Marshal.ReleaseComObject(capGraph);
capGraph = null;
}

if (graph != null)
{
Marshal.ReleaseComObject(graph);
graph = null;
control = null;
}

if (video != null)
{
Marshal.ReleaseComObject(video);
video = null;
}

if (renderer != null)
{
Marshal.ReleaseComObject(renderer);
renderer = null;
window = null;
}
}

public bool run(IntPtr owner)
{
if (window != null)
{
Rect rc = new Rect();
PInvoke.GetClientRect(owner, out rc);
window.put_Owner(owner);
window.SetWindowPosition(rc.Left, rc.Top, rc.Right, rc.Bottom);
window.put_WindowStyle(0x40000000 | 0x02000000);
window.put_Visible(0);
}
else
{
return false;
}
return control.Run() >= 0;
}

private bool getVideoCaptureFilter()
{
object obj = null;
Guid clsid = CLSID_.VideoCapture;
Guid riid = IID_.IBaseFilter;
PInvoke.CoCreateInstance(ref clsid, IntPtr.Zero, (uint)CLSCTX_.INPROC_SERVER, ref riid, out obj);
if (obj == null)
{
return false;
}
video = (IBaseFilter)obj;
obj = null;
string name_ = "";
if (!getName(ref name_))
{
return false;
}

IPersistPropertyBag propBag = (IPersistPropertyBag)video;
if (propBag == null)
{
return false;
}

CPropertyBag bag = new CPropertyBag();
object oname = name_;
bag.Write("VCapName", ref oname);
int hr = propBag.Load(bag, null);
if (hr < 0)
{
//System.Windows.Forms.MessageBox.Show("cannot load prop bag");
return false;
}
return true;

}

private bool getVideoRenderer()
{
object obj = null;
Guid clsid = CLSID_.VideoRenderer;
Guid riid = IID_.IBaseFilter;
PInvoke.CoCreateInstance(ref clsid, IntPtr.Zero, (uint)CLSCTX_.INPROC_SERVER, ref riid, out obj);
if (obj == null)
{
return false;
}
renderer = (IBaseFilter)obj;
window = (IVideoWindow)renderer;
return true;
}

private bool getName(ref string name)
{
IntPtr handle = IntPtr.Zero;
IntPtr guid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
Marshal.StructureToPtr(CLSID_.Camera, guid, false);
DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION();
di.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION));
handle = PInvoke.FindFirstDevice(3, guid, ref di);
Marshal.FreeHGlobal(guid);
if ((handle == IntPtr.Zero)||(di.hDevice == IntPtr.Zero))
{
return false;
}

PInvoke.FindClose(handle);
name = di.szLegacyName;
return true;
}
}

public class CPropertyBag : IPropertyBag
{
private object pVar_ = null;

public CPropertyBag()
{
pVar_ = new object();
}

~CPropertyBag()
{
pVar_ = null;
}

public int Read(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
[In, Out, MarshalAs(UnmanagedType.Struct)]    ref    object pVar,
[In] IntPtr pErrorLog)
{
pVar = pVar_;
return 0;
}

public int Write(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
[In, MarshalAs(UnmanagedType.Struct)] ref object pVar)
{
pVar_ = pVar;
return 0;
}
}
}

Last version of DirectShowNETCF

27 Responses to “[Windows Mobile] Capturing video from device camera C# or DirectShow.NET CF Part II”

Pages: [3] 2 1 » Show All

  1. 27
    Abito Says:

    OK, never mind. I just needed a few ideas to begin with the code.
    Anyway, thanks for all your help :)

  2. 26
    admin Says:

    sorry i`m not going to do your work, you can read directshow documentation on msdn or read some directshow books

  3. 25
    Abito Says:

    umm, can you please elaborate using code? thanks

  4. 24
    admin Says:

    connect source filter to encoder and encoder to file writer

  5. 23
    Abito Says:

    How do I save the captured video on the file system?

  6. 22
    admin Says:

    doesnt work what? which exactly class?

  7. 21
    Achiko Says:

    Not works for HTC HD2 :(

Pages: [3] 2 1 » Show All

Leave a Reply