Log in

View Full Version : Is DirectShow faster than VFW for Webcams?


Valiant
3rd June 2003, 15:59
Hi

(VFW = Video For Windows)
(DIB = Device Independent Bitmap)

We were using VFW to get lots of Bitmaps per second from our Webcam to our application (memory) (Video Conferencing application).
But it's slow, maybe our implementation is slow, maybe the VFW wrapper by "Ken Varn" is slow or maybe it's VFW which is the problem.

Now to my question:
Is DirectShow (with WDM Webcam) faster than VFW for this purpose? Is it generally faster?
Could DirectShow be faster but only with an intelligent implementation / FilterGraph / SampleGrabber?

I read about the benefits of DirectShow over the obsolete VFW, but I couldn't find a performance comparison or even a qualitative statement whether VFW or DirectShow / WDM is faster.

I'm re-coding the application to use DirectShow instead of the VFW wrapper.
After learning DirectShow, COM and coding nearly for a week, I've already everything running but the picture grabbing (to be finished today, hopefully).
Now I'm wondering if this DirectShow thing was waste-of-time...

Thanks in advance - Andy

Additional Info if you're interested:
As a student project we're writing a Video Conferencing Client-Server application.
The Server has a preview window just showing the actual stream from the webcam and it captures 10 to 20 frames / second. For each frame it does some lossy (YUV 420, Motion Estimation, DCT+Quantization) and lossless (Huffmann or Lempel-Ziv Coding) compression.
Until now, we used a small VFW wrapper by "Ken Varn".
But this wrapper needs to long to get a DIB and copy it into our memory space (50 - 170 milli seconds).
My first try to get it faster was an additional thread which gets the DIBs asynchronously. But surprisingly this wouldn't help much. Well, actually it's not a surprise, as it still needs these 50-170 ms.
1. We need more FPS than 10-15
2. We need to get them reliable, the range between 50 and 170ms is to big.

Valiant
4th June 2003, 01:40
Hi again

After exactly one week, I have the first DirectShow version of the server completed.

I'm still interested in an experts view on VFW versus DirectShow!!

Bottom line:
DirectShow / WDM is faster than VFI when capturing lots of DIBs from a Webcam into the memory as fast as possible.
How much faster?
It's just a first dirty and slow implementation, but I reach 30-45 FPS with DirectShow (Logitech guarantees 30 FPS) when doing no compression, just RGB -> YUV420 and sending over TCP/IP "Loopback" to the client on the same pc (1.4GHz Celeron).
With the VFW Wrapper I reach 10 FPS.
To capture one single DIB and copy it into my memory space the DirectShow version takes 0-10 ms (average 0 or 10ms), the VFW had 40-170ms (average 50 - 70 ms).

Here comes the but:
The DirectShow Graph with it's VMR9 Renderer consumes about 20% CPU!!
What does that mean? Just for sending uncompressed bitmaps to the client, this DirectShow version is excellent. But if we want to do heavy compression with CPU consuming algorithms as Motion Estimation / DCT / Huffmann, we lose some CPU time to the Filter-Graph.

If anyone else is interested in howto use DirectShow for a similar project:

I use the fallowing COM objects:
IGraphBuilder, ICaptureGraphBuilder2, IBaseFilter for my Logitech Quickcam Pro 4000, IbaseFilter for the VideoMixingRenderer9 (Windowless_Mode) and IBaseFilter for the ISampleGrabber.

The Graph is built by Intelligent Connect with IMediaControl->RenderStream(....,sourceFilter(webcam),grabberFilter,sinkFilter(VMR9));

Currently I've activated the SampleBuffering in the Grabber and get the images by GetCurrentBuffer.
Alternatively I could use the ISampleGrabberCB (Callback) Interface on a little GrabberCallBack class.

Nic
4th June 2003, 16:08
Hmmm, You could try creating a filter in memory (use the nullnull example in the SDK) and just grab the frames in the Transfer function rather than using the samplegrabber... ? And are you rendering the filter to the Null Renderer or do you need it to render to something specific ?

If you using the SampleGrabber in oneshot mode, it might be a tad slower than my suggestion above.

Also in the DX9SDK there is quite an informative and open text by some dev at MS. He describes why the SampleGrabber was a bad idea and what they suggest instead.

May not be much use to you, but I thought id mention it, good luck in your project,

-Nic

Valiant
4th June 2003, 16:27
Thanks Nic.

I guess you refer to the descriptive text to the /Filters/Grabber/ sample. I quoted the paragraph you're refering to.
As you see, the SampleGrabber is a good solution for "Capturing still images from a live video stream" and that's what I'm using it for.

I'm rendering the Stream to a preview "window" (windowless) in the server application, so I need a renderer. I use the VMR-9 as the renderer.

OneShotMode? Doesn't make sense when rendering the live stream at the same time.

I had almost half a week to understand that the SampleGrabber with its ISampleGrabber interface is what I need and that it's so easy to implement.
GetCurrentBuffer in BufferedMode or use a self built class implementing the Callback Interface ISampleGrabberCB.

Well, I didn't know COM objects or anything about DirectX before...

You'd still say I should create my own Filter, basing on a TransInPlace or NullRenderer class?

Thanks - Andy



=======================================
The Sample Grabber
=======================================

The easiest way to get data out of a DirectShow graph, if you’re not going to use
MultiMedia Streaming, is probably to write your own TransInPlace filter, a sub-variety
of a Transform filter. Then connect this filter to the desired stream of data you wish to
monitor, and then run, pause, seek, or otherwise control the graph. The data, as it passes
through the transform filter, can be manipulated however you want. We call this kind of
filter, a “sample grabber”. Microsoft released a limited-functionality sample grabber
with DX8.0. This filter is limited because it doesn’t deal with DV Data or mediatypes
with a format of VideoInfo2. It doesn’t allow the user to receive prerolled samples.
(What’s a preroll sample? See the DX8.1 docs) Its “OneShot” mode also has some problems.

What is a Transform-based Sample Grabber good for?

1. Decoding an entire file into a memory buffer
2. Getting a “Poster Frame” of video from a video file
3. Capturing still images from a live video stream
4. Decoding a video file into a direct-draw buffer (for a game)

Harlequin
4th June 2003, 17:22
You might want to re-configure the linker by removing misc libs I know that loading GDI32.lib into a DirrectShow app or driver can serously slow it down.

Nic
4th June 2003, 17:32
@Valiant:

Oh, I think I misunderstood what you were trying to do then. Your probably doing it the best way that you can.

Ive used the SampleGrabber on a number of projects, and it never performed great for me. But I wasn't trying to do what your doing, so your probably already doing it optimally

As I said, Good Luck :),

-Nic

Valiant
4th June 2003, 18:05
However, do you know if VFW is generally slower than DirectShow or is it here just a bad VFW wrapper?


@Harlequin: Thanks, gonna take a look at it...