It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Webcam control with WPF or how to create high framerate player with DirectShow by using InteropBitmap in WPF application

Did you ever see, that MediaElement “eats” about 30% of CPU while playing movie in WPF? Did you thought, that you  can display live camera capture in WPF with 60 fps full screen (I have really high resolution 1920×1200) and 2% of  CPU? You did not? Let’s see how it can be done. Today we’ll create simple WebCam player control that can show you live video capturing with high frame rate. In order to do it, we’ll use DirectShow, WPF and make them work together.

  image

You, probably do not believe me. Let’s start. In order to build this application, we need to make DirectDraw working in C# managed code. We can use DirectShow.NET, but this time we’ll do it manually. Why? because I love to do things manually. So let’s understand what we need? Actually, not very much: one Sample Grabber (ISampleGrabber) and one Device input filter(IBaseFilter). Both we should connvert with Graph Builder (IGraphBuilder) and point to some grabber implementation (ISampleGrabberCB). Also, we do not want DirectShow to render video for use, thus we’ll send it’s default Video Window (IVideoWindow) to null with no AutoShow and then run the controller (IMediaControl). Do you tired enough to lost me? Let’s see the code. One Filter graph with one Device Filter and one Sample grabber.

graph = Activator.CreateInstance(Type.GetTypeFromCLSID(FilterGraph)) as IGraphBuilder;
sourceObject = FilterInfo.CreateFilter(deviceMoniker);

grabber = Activator.CreateInstance(Type.GetTypeFromCLSID(SampleGrabber)) as ISampleGrabber;
grabberObject = grabber as IBaseFilter;

graph.AddFilter(sourceObject, "source");
graph.AddFilter(grabberObject, "grabber");

Set media type for our grabber

using (AMMediaType mediaType = new AMMediaType())
                {
                    mediaType.MajorType = MediaTypes.Video;
                    mediaType.SubType = MediaSubTypes.RGB32;
                    grabber.SetMediaType(mediaType);

And then connect device filter to out pin and grabber to in pin. Then get capabilities of video received (thiss stuff come from your web camera manufacturer)

if (graph.Connect(sourceObject.GetPin(PinDirection.Output, 0), grabberObject.GetPin(PinDirection.Input, 0)) >= 0)
                    {
                        if (grabber.GetConnectedMediaType(mediaType) == 0)
                        {
                            VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));
                            capGrabber.Width = header.BmiHeader.Width;
                            capGrabber.Height = header.BmiHeader.Height;
                        }
                    }

Out pin to grabber without buffering and callback to grabber object (this one will get all images from our source).

graph.Render(grabberObject.GetPin(PinDirection.Output, 0));
grabber.SetBufferSamples(false);
grabber.SetOneShot(false);
grabber.SetCallback(capGrabber, 1);

Dump output window

IVideoWindow wnd = (IVideoWindow)graph;
wnd.put_AutoShow(false);
wnd = null;

And run the controller

control = (IMediaControl)graph;
control.Run();

We done. Now our video is captured and can be accessed from BufferCB method of ISampleGrabberCB. Next step is to do WPF related stuff

First of all, we’ll use InteropBitmap. This one will provide us with real performance bust. So, one our DirectShow graph is ready and we know result image capabilities, we can create memory section and map it in order to provide ISampleGrabberCB with place to put images. This will be always the same pointer, so all we have to do is to .Invalidate interop image.

if (capGrabber.Width != default(int) && capGrabber.Height != default(int))
                {

                    uint pcount = (uint)(capGrabber.Width * capGrabber.Height * PixelFormats.Bgr32.BitsPerPixel / 8);
                    section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0×04, 0, pcount, null);
                    map = MapViewOfFile(section, 0xF001F, 0, 0, pcount);
                    BitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(section, capGrabber.Width, capGrabber.Height, PixelFormats.Bgr32,
                        capGrabber.Width * PixelFormats.Bgr32.BitsPerPixel / 8, 0) as InteropBitmap;
                    capGrabber.Map = map;
                    if (OnNewBitmapReady != null)
                        OnNewBitmapReady(this, null);
                }

Now in capGrabber (ISampleGrabberCB) we’ll copy buffer, comes from our webcam to the mapped location for WPF usage

public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
        {
            if (Map != IntPtr.Zero)
            {
                CopyMemory(Map, buffer, bufferLen);
                OnNewFrameArrived();
            }
            return 0;
        }

All we have to do is to call InteropBitmap.Invalidate() each frame to reread the image bytes from the mapped section.

if (BitmapSource != null)
                    {
                        BitmapSource.Invalidate();

How do display all this stuff? Simple – subclass from Image and set it’s Source property with the interop bitmap.

public class CapPlayer : Image,IDisposable
    {

void _device_OnNewBitmapReady(object sender, EventArgs e)
        {
            this.Source = _device.BitmapSource;
        }

Now, the usage from XAML is really simple

<l:CapPlayer x:Name="player"/>

We done :) As always, download full source code for this article

…and be good people and don’t tell anymore, that WPF performance in terms of imaging is sucks :)

P.S. small ‘r’ if you have more, then one WebCam connected. Inside CapDevice class there is member, public static FilterInfo[] DeviceMonikes, that provides you with all DirectShow devices installed. So, the only thing you should do in order to change the device is to set deviceMoniker = DeviceMonikes[0].MonikerString; with the moniker of your device. This sample works with first one.

Be Sociable, Share!

59 Responses to “Webcam control with WPF or how to create high framerate player with DirectShow by using InteropBitmap in WPF application”

  1. Rich Says:

    Very impressive.  +1 for changing the resolution.  I’ve been searching for a solution and could not find any that I understand.

  2. Geert van Horrik Says:

    I have extended your CapPlayer class a little bit by adding 2 properties:

    1) Rotation

    2) CurrentBitmap

    You can find a blog entry about it here:

    blog.catenalogic.com/…/Retrieving-snapshots-from-a-webcam.aspx

  3. Rodrigo Says:

    I’m starting in WPF. There is some method in the classes of this project that capture one frame of the CapPlayer control to put in one image control, for example?

  4. Matt Says:

    How would you specify the resolution you want the camera to produce?  Sorry about the newbie question.

  5. Ivan Says:

    What about webcam options? Is it possible to change them?

  6. Webcam Control with WPF « Roman’s Blog Says:

    Pingback from  Webcam Control with WPF  &laquo; Roman&#8217;s Blog

  7. C.S. Finch Says:

    Hi, I noticed someone posted  a question about the video being upside down, and I must admit I have the same problem, however, I fixed it with an easy fix.

    2 options.

    First option is you can go into Expression Blend 2.0, and just rotate the video player 180 degrees.

    if you don’t have Expression Blend 2.0 you can do the following

    replace the following <1:CapPlayer x:Name="player"/>

    with the following code

           <l:CapPlayer x:Name="player" RenderTransformOrigin="0.5,0.5">

            <l:CapPlayer.RenderTransform>

            <TransformGroup>

            <ScaleTransform ScaleX="1" ScaleY="1"/>

            <SkewTransform AngleX="0" AngleY="0"/>

            <RotateTransform Angle="180.294"/>

            <TranslateTransform X="0" Y="0"/>

            </TransformGroup>

            </l:CapPlayer.RenderTransform>

           </l:CapPlayer>

    Hope it helped.

  8. Brandon Says:

    How do you stop the feed of the images? I called the Stop() method located _device.Stop() and made a public method to access. When I call this it will stop but it takes a crazy long time and is very random, does it not dispose properly?

  9. Mike Says:

    Wow, excellent article/code, thanks!

    I’m trying to get this to work with an IP Camera (Linksys WVC54GC) but can’t figure out how to get the FilterInfo for the ip camera (device enum won’t work since it’s not directly connected to my pc).  I can get IFilterInfo for the ip cam by going through FilgraphManager instead, but connect fails when I try to use this filter.  Any ideas on how I can get this to work with an IP Camera?  Any help would be greatly appreciated.

    Thanks!

    Mike.

  10. Ted Says:

    Excellent article Tamir!

    I was playing around with it using a firewire-video as source, and it worked just fine (except for beeing flipped upside down, but that was easily corrected with a a scale transform), BUT I have a question though, is there any route I could take to add de-interlacing of the video as well? Do you know? Thanks!

    Cheers!

    -Ted

  11. Tamir Khason Says:

    cindex, I do not understand and cannot repro the problem. It looks like a problem with your webcam software or drivers

  12. cindex Says:

    Please, answer my problem.

    T.T

    Inspite of "player.Dispose();"

    webcam is not released.

    Because of that, new window do not load webcam.

    Help,me

  13. cindex Says:

    …hmm

    Lamp turned off when debugging stop, not when application is closed.

  14. cindex Says:

    Web cam video window is opened by "showdialog()"

  15. cindex Says:

    Thank you  for your answer,Tamir Khason.

    But, I do not understand yours.

    Inspite fo "player.Dispose();"

    My webcam`s lamp is not turned off.(my webcam`lame turned on when it run)

    Because of that, probably new window is non shown webcam video.

    It`s lamp is turned off when application is closed.

  16. Futile » links for 2009-01-06 Says:

    [...] Webcam control with WPF how to create high framerate player with DirectShow by using InteropBitmap in WPF application (tags: c# wpf webcam development) Share and Enjoy: [...]

  17. colby Says:

    Anybody got something like this in vb.net? I already have the whole app written in vb, i was just needing a webcam control and i would be golden…

  18. Pablo Says:

    This solution works for me but i have a big problem: this is “eating” more than 30 of CPU. Why could it be possible?
    Sorry for my english

  19. Anatoly Says:

    How to increase resolution of video? I ve got hd web cam and got only 160/120 resolution?

    With greetings, Anatoly

  20. Juan Jose Says:

    Good! It works fine! Thank you.

  21. Gatzo Says:

    Great job!
    How can I change the Webcam resolution?

    ————————————
    Rich Says:
    January 1st, 2009 at 12:45 am

    Very impressive. +1 for changing the resolution. I’ve been searching for a solution and could not find any that I understand.
    ————————————

  22. Skippy Says:

    Trying to use this to limit the video to just one of the channels (say… Red-only, don’t show the blue or green, so I have just the red part of the image…).

    I’m guessing that it’ll be a tweak in the capGrabber_PropertyChanged function of CapDevice.cs. Because that’s where the BitmapSource is built from memory.

    Or am I on completely the wrong track?

    -Scott

  23. maltub@gmail.com Says:

    why the picture is

  24. Ben Says:

    Hi there, I have tried this sample but the box just comes up black. The webcam is connected via USB and I can get it working with a DirectShow control for WinForms, but really need it in WPF without just wrapping up the WinForms control. Any ideas why this would be black? I have checked that it is setting to the correct device. Please help!

  25. Andrew Says:

    I have used the CapPlayer – it’s great. But I didn’t found how to change the resolution. My webcam supports 1024×768 but CapPlayer allowed me to play only 320×240.

    How to change resolution?

  26. J. Mason Says:

    Great component, Does anyone have any idea on how to save the stream to disk???

  27. Gaylord Stonehouse Says:

    Netten Weblog hast du da. Bin gerade eben

  28. behdad Says:

    hi
    how to setting differant frame rate in webcam or changing frame rate to (15-30)fps

  29. ssaifriend Says:

    I don’t access here:
    http://schemas.sharpsoft.net/xaml

    Access Fail. Help;;

  30. Abdul Sami Says:

    Can some one assist me in measuring the latency between start (source) and end (rendering the video) process of the filters involved?

  31. Peter Says:

    Thanks, you know so much more about it then I do.

    The while (!stopSignal.WaitOne(0, true)) { Thread.Sleep(10); } loop in CapDevice.captureImage could be replaced by a single call to stopSignal.WaitOne();

    Then you won’t get a ThreadAbortException either when CapDevice.Stop calls worker.Abort().

    I don’t think calling worker.Abort (unconditionally) is necessary.
    This call also prevents execution of control.StopWhenReady();

    My 2nd, much less important, remark is that I would keep the variables graph, grabber, sourceObject, grabberObject, control, map and section of CapDevice should all local to the captureImage function.

  32. Federico Says:

    Hello.
    Can anybody send me more information about:
    - Config Image Resolution
    - Use Zoom
    Thanks.

  33. edwin Says:

    Hi, I’ve been testing and I still see 12%CPU usage. Which is a lot higher than 2%. I would like to know why this is so much higher than with your example? Any thoughts?
    Ps.
    I’m looking to implement IP cameras on a WPF control. Why: WPF gives a lot of new features which would take forever to program in winform.
    Ps2.
    Process explorer indicates that ksproxy.ax is using 10% CPU.

  34. Holy Says:

    For the problem of cindex (the camera lamp is not turned off when window is closed), I solved by replacing the code (thanks Peter) code of stop routine in capdevice.cs

    I know for cindex it’s too late but can be helpful to someone.

    HTH,
    Holy

    public void Stop()
    {
    if (IsRunning)
    {
    stopSignal.Set();
    try
    {
    worker.Abort();

    }
    catch (ThreadAbortException) { }
    finally
    {
    if (worker != null)
    {
    //worker.Join();
    Release();
    }
    }

    }
    }

  35. maven Says:

    Hi,
    Can this hook up to Kinect Camera?

  36. Ivan Says:

    How I can fix in C# code problem: the video being upside down?

  37. Tosin Says:

    in case this can help someone.
    On the problem of the camera not being disposed properly, the problem is that the worker thread
    is not properly receiving the stop signal I tried Holy’s post and it did not work for me. What worked for me if by replacing the thread abort logic in Runworker() // Wait for the stop signal
    while (!_stopSignal.WaitOne(10, true))
    {
    Thread.Sleep(10);
    }

    with while (!_stopSignal.WaitOne(10, true))
    {
    //Thread.Sleep(10);
    }
    This way it waits for the stop signal at least 10mil secs before aborting. I hope this helps

  38. Ivan Says:

    Anybody, know answer to next question:
    How I can fix in C# code problem: the video being upside down?

  39. Free graphics, 3d, code snippets, PHP, HTML, JavaScript and more! Says:

    You actually make it seem so easy together with your presentation however I to find this topic to be really something that I feel I’d never understand. It seems too complex and extremely huge for me. I am looking ahead in your next submit, I?ll try to get the dangle of it!

  40. Dominic Mertz Says:

    some really excellent info , Gladiolus I found this.

  41. John Roach Says:

    Hi,
    I know it has been a long time since you have posted this post. I found the article very helpful with my own project which I had some performance issues.

    I just have one question… I am using a c920 Logitech camera. I have noticed that some programs such as skype allow HD Video play (1080p) however when I use the code you have provided

    capGrabber.Width = header.BmiHeader.Width;
    capGrabber.Height = header.BmiHeader.Height;

    gives me at best a 640×480 image… and not 1080p at all….

    Why is this so?
    Does skype send a secret command to the webcam so it can work with bigger images?

    Thank you for your time and help in advance.

  42. memorias ddr Says:

    We are a gaggle of volunteers and starting a brand new scheme in our community. Your web site offered us with helpful info to paintings on. You have performed a formidable job and our entire community can be grateful to you.

  43. rg Says:

    your code works really nice. But wen i try to call through another window. The first time it works but the second time the windows goes black and doesn’t show anything at all. Can u plz help me out in this?
    thank you

  44. salomon Says:

    Great Code! Have been using WPFMedia kit which had many troubles!

    I’ve developed the solution to adapt other frame provider then capture.
    I solved problems which might interest other developers:

    1. Problem: Got black screen, though when saving some of the buffers to bitmap file were correct.

    Solution: passing unique name parameter for “CreateFileMapping” method. I used Guid.NewGuid().ToString() for that last parameter.
    The problem cause is that the frame provider might use file mapping as well with no unique id, which cause a collision.
    This technique might be used by any driver writer!

    2. Problem: Using 24 bits RGB format frames causes cycles of memory increase untill 1 GB and than memory release at once.
    Solution: use only 32 bits. Somehow WPF likes it.
    It would be very interesting to know why?

  45. Natalia Says:

    Is it possible to change video brightness, contrast, sharpness…?

    Also, how to save the captured video to harddisk?

  46. Computer Keyboard not working help Says:

    Right here is the right web site for everyone who would like to find out
    about this topic. You realize a whole lot its almost hard to argue with you (not that I really
    would want to…HaHa). You certainly put a new spin on a subject that has been discussed for
    ages. Excellent stuff, just wonderful!

  47. Alexander Muylaert Says:

    Hi

    As for the upside down photos. I think flipping it while rendering is a bit silly.

    I found a clue here
    http://stackoverflow.com/questions/13894177/image-top-down-from-web-camera/15586584#15586584

    I optimized the answer a bit for performance.

    thanks for the good explanation

  48. virendra Says:

    How can can save image through CapPlayer .
    please assis me

    Regards,
    Virendra

  49. likwidacja myszy Gdańsk Says:

    I was curious if you ever considered changing
    the layout of your blog? Its very well written; I love what youve got to say.
    But maybe you could a little more in the way of content so people could connect with it
    better. Youve got an awful lot of text for only having
    1 or 2 pictures. Maybe you could space it out better?

  50. dipwater Says:

    It’s really very good!Continue with it.

  51. free shemale cams Says:

    I am curious to find out what blog platform you’re utilizing?
    I’m experiencing some small security issues with my latest site and I would like
    to find something more secure. Do you have any suggestions?

  52. Salomon online Says:

    Hey! Someone in my Facebook group shared this site with us so I came to take a look.
    I’m definitely loving the information. I’m book-marking
    and will be tweeting this to my followers! Fantastic blog and terrific design and style.

  53. Huy Says:

    I have laptop with configuration:
    OS: windows 7 32bit
    CPU: core 2 duo P7450, 2,13GHz
    RAM: 3GB
    I test your examples and getting results is:
    AvCapWPF.vhosst.exe CPU use 15%-24% and Ram is 26MB-30Mb
    How only 2% CPU just like you?

  54. infinity cheerleading shoes Says:

    Thanks for the auspicious writeup. It in truth was once a leisure
    account it. Glance complex to far introduced agreeable from you!
    However, how can we communicate?

  55. family fitness Says:

    My developer is trying to convince me to move to .net from PHP.
    I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress on a variety of
    websites for about a year and am anxious about switching to another platform.

    I have heard good things about blogengine.net. Is there a way I can import all my wordpress posts into it?
    Any help would be greatly appreciated!

  56. varsity Says:

    Hello! Would you mind if I share your blog with my twitter group?
    There’s a lot of people that I think would really enjoy your content.

    Please let me know. Cheers

  57. tips on playing pool Says:

    Hey very nice blog!

    My blog post: tips on playing pool

  58. play pool free online Says:

    Hey terrific blog! Does running a blog such as this require
    a large amount of work? I have very little understanding of programming
    however I had been hoping to start my own blog soon. Anyways, should you have any suggestions or techniques
    for new blog owners please share. I understand this is off topic however I just had
    to ask. Appreciate it!

    Stop by my weblog … play pool free online

  59. Symantec Norton Promo Says:

    Sweet blog! I found it while surfing around on Yahoo News.
    Do you have any suggestions on how to get listed in Yahoo
    News? I’ve been trying for a while but I never seem to get there!
    Appreciate it

Leave a Reply

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project