Webcam capture

Sep 15, 2011 at 11:28 AM

Hi guys,
I'm using the WPF MediaKit from codeplex to show a webcam in my application, so far so good. But I want to capture an image from the webcam as well. I'm using the EnableSampleGrabbing property and I've hooked into the NewVideoSample event.


But the event never fires! I've downloaded the sourcecode and debuged all the way down to the ISampleGrabberCB.SampleCB method and it is never triggered. I suspect that this method should be triggered by the DirectShowLib dll that the MediaKit uses. I've also downloaded the latest version of this DLL.
Has anyone done this with success ?


I'm using VS2010, .net 4.0 on Windows7 64bit.

Sep 20, 2011 at 12:25 PM

Yeah, I had to face the same issue.

In my case the webcam streams in YUY2, whereas the Subtype Format forced in WPF Media Kit is RGB24.

I've managed to get it to work with: grpBuilder.RenderStream(PinCategory.Capture, MediaType.Video, this.capDev, null, (IBaseFilter)smpGrabber).
Without it, the grabber was not connected, and I don't understand how it was working anyway.
Further down I have: hr = grpBuilder.RenderStream(PinCategory.Preview, MediaType.Video, this.capDev, null, Renderer);

It works. But I am not completely satisfied by the solution: I don't have a great experience in DirectShow, and I'd like to know what jmorril, or some other guru, thinks about it.

Cheers,

Gianluca.

Sep 21, 2011 at 12:41 PM

Thanks for the Help,

 

I've done a bit of research after I read your response and it does work (current build) with most webcams. The initial webcam was a Freetalk webcam from skype shop and it has hw acceleration of H.264 encoding.. or something like that. 

With a normal Microsoft or Logitec webcam, it worked!

Oct 13, 2011 at 2:12 PM
gianluca_c wrote:

Yeah, I had to face the same issue.

In my case the webcam streams in YUY2, whereas the Subtype Format forced in WPF Media Kit is RGB24.

I've managed to get it to work with: grpBuilder.RenderStream(PinCategory.Capture, MediaType.Video, this.capDev, null, (IBaseFilter)smpGrabber).
Without it, the grabber was not connected, and I don't understand how it was working anyway.
Further down I have: hr = grpBuilder.RenderStream(PinCategory.Preview, MediaType.Video, this.capDev, null, Renderer);

It works. But I am not completely satisfied by the solution: I don't have a great experience in DirectShow, and I'd like to know what jmorril, or some other guru, thinks about it.

Cheers,

Gianluca.


Can you elaborate what does "hr = grpBuilder.RenderStream(PinCategory.Preview, MediaType.Video, this.capDev, null, Renderer);" mean? Because I am quit confused with these and DirectShow.

Thanks in advance.

Jul 23, 2012 at 1:18 AM

I'm having a similar issue trying to grab using a YUY2 stream.  Did anyone come up with a good solution to this issue?

Thanks!

Jun 5, 2013 at 8:17 PM
grpBuilder.RenderStream(PinCategory.Capture, MediaType.Video, this.capDev, null, (IBaseFilter)smpGrabber

where did you put this code? i don't have any reference to grpBuilder anywhere in the solution.
Jun 5, 2013 at 8:34 PM
Been banging my head against a wall for about 2 days trying to figure this one out, pretty much to the point where I'm going to have to abandon WPFMediaKit if I can't get an answer soon. It's really too bad because it works flawlessly when I'm using a RBG24 camera but when I switch to an RBG10 camera I run into this scenario where the event never fires. Any help would be greatly appreciated.
May 9, 2014 at 9:10 PM
Edited May 9, 2014 at 9:14 PM
Hi, I had the same problem. Turned out that my camera was not able to stream in rgb (only yuv2 and some other format).
In my case SampleGrabber could not connect to output pin of camera, because format mismatch (SampleGrabber wants RGB24). My modification detects if there is YUV2 format on output pin and add sample grabber before renderer and DirectShow automatically adds colour space conversion block.

I have modified (made three little changes) the code in VideoCapturePlayer.cs file so:

LINE 78:
private string m_fileName;
BECOMES:
private string m_fileName;

        private Guid outPinMediaType = Guid.Empty;
LINE ~370:
hr = graphBuilder.RenderStream(PinCategory.Preview,
                                               MediaType.Video,
                                               m_captureDevice,
                                               null,
                                               m_renderer);
BECOMES:
IBaseFilter f = null;
                if(EnableSampleGrabbing && outPinMediaType.Equals(MediaSubType.YUY2)) f = (IBaseFilter)m_sampleGrabber;

                hr = graphBuilder.RenderStream(PinCategory.Preview,
                                               MediaType.Video,
                                               m_captureDevice,
                                               f,
                                               m_renderer); 
LINE ~465:
media.subType = mediaSubType;
            }
BECOMES:
media.subType = mediaSubType;
            }

            outPinMediaType = media.subType;
NOTE that line
if(EnableSampleGrabbing && outPinMediaType.Equals(MediaSubType.YUY2)) 
can by changed to
if(EnableSampleGrabbing && !outPinMediaType.Equals(MediaSubType.RGB24))
then this operation is done also for other than YUV2 format.


You can also skip modification 1 and 3 and always add sample grabber in the middle of renderer and camera just modify the line ~370 so:
hr = graphBuilder.RenderStream(PinCategory.Preview,
                                               MediaType.Video,
                                               m_captureDevice,
                                               null,
                                               m_renderer);
BECOMES:
hr = graphBuilder.RenderStream(PinCategory.Preview,
                                               MediaType.Video,
                                               m_captureDevice,
                                               EnableSampleGrabbing  ? (IBaseFilter)m_sampleGrabber : null ,
                                               m_renderer);
this change will always auto match output camera pin to sample grabber input (which is forced rgb24).

Anyway thanks for great library, it saved me a lot of time since I wanted to write my own camera capture DS wrapper
Jan 13, 2015 at 9:54 PM
pc25, you're brilliant! That fix worked. My onboard webcam for my Lenovo thinkpad was working just fine, but the cheap USB webcam I was also testing with wasn't firing the event. Thanks very much for the code snippet.