Link to home
Start Free TrialLog in
Avatar of WxW
WxW

asked on

Direct Show- based Video Conference

I am trying a simple video conference app currently with VFW , which successfully initializes , compresses, sends and receives video.

I want to try it a bit with DirectShow. To capture the data I would connect:

1)Video Capture Filter + Video Compression Manager Filter
and then render the output pin. I see it in an ActiveMovie window, but i don't want only to see it, i also want to capture X pics per second (depending on the frame rate) to memory. Which filter should I connect and where ?

2) Assume I get the image and send it over the internet. The receiver should display this one, but there is no capture device. How can I specify e.g. to get the image and play it in a ActiveMovie window from the memory and not from a capture device ? Currently I do this still with VFW, which means I get the image bytes but i cannot decompress and show it with DirectShow, so I am calling the ICManager and display it as a bitmap.

Thank you,
Michael
Avatar of mxjijo
mxjijo


>> 1)Video Capture Filter + Video Compression Manager Filter and then render the output pin.
      As you might know,  once you render the pin, you get the video, so you should not do it at the capture side.

I suggest you to take a look at the Directshow filter samples that comes with DirectX SDK.
Especially
[DxSdkHome]\Samples\C++\DirectShow\Filters\DSNetwork

That has a sender side and a receiver side filter code.
Please not that you *don't have to* use DirectX at the sender side.
If you are able to retrieve data from yout video capture device directly, that is good enough at the sender side.
The client side you need Dx and DSNetwork sample has pretty much everything to keep you going.

Avatar of WxW

ASKER

I don't have a problem to capture the video. The trouble is in the receiver side. Once i capture the data with ISampleGrabber and send him the bytes, how will he display them ?

How should I decompress the bytes and show them as a bitmap ?

Regards.
Avatar of WxW

ASKER

If I am about to use AVI Decompressor to decompress the bytes, how do I set the source for these bytes ?

Regards.

I haven't worked in the "data compression" part of it but...

If you take a look at DSNetwork sample I mentioned above, it is a network multi-cast receiver filter.
I guess you are using UDP. With very minor changes you can make "DSNetwork" sample to receive data
thru a UDP port and make it avilable for the DirectShow applications thru an "MPEG Program Stream" out put pin.
Once you have that -as you might know-  any DirectShow may load this filter and connect the out put pin to
suitable MPEG Demux filters.

Back to your requirement, The additional thing that you would need to add into the "DSNetwork" filter is the
decompression. You must be knowing how to decompress the data. So you can call that decompression function
once you receive the data form the UDP socket before you make the data available to the out put pin.

In short your modified DSNetwork would look something like this

[UDP Stream] --- >  Stage 1 (socket recv) --> Stage 2 (Decompress data) --> Stage 3 (Copy data to the output pin buffer)

And the connected filter graph would look like

                                              |----> [Audio decoder] --> [Audio renderer] --> Speaker
[DSNetwork] --> [MPEG DMux] |
                                              |----->[Video Decoder] --> [Video renderer] --> Video Window

                                               





Avatar of WxW

ASKER

The problem is that , in order to decompress the data, I need the AVI Decompressor filter. That means that I have to copy the data from the output pin buffer to the AVI decompressor, and then render, so I must send compressed bytes to the filter i would create.

I will try, (I haven't made any filter yet in the past) and tell you.

Yes, if you are using AVI Decompress or, you have to connect AVI Decompress or filter right after your DSNetwork filter.
So the diagram would look like...


                                                                       |----> [Audio decoder] --> [Audio renderer] --> Speaker
[DSNetwork] --> [AVI Decomp]--> [MPEG DMux] |
                                                                       |----->[Video Decoder] --> [Video renderer] --> Video Window

>> I will try, (I haven't made any filter yet in the past) and tell you.
    Honestly filters programming is irritating at the beginning, but once you get a hang of it, its not that bad :)
The most painful part is debugging. It took a week for me to fig out why
my filter wasn't rendering the video - I was trying to play MPEG1 instead of MPEG 2 :)

good luck anyway.. :)

Avatar of WxW

ASKER

I made the filter.

The sender is

WDM Capture Device -> Compressor -> ISampleGrabber -> Null Rendered
I get the bytes from ISampleGrabber and send them to receiver

Receiver is:

My Filter (that gets input from the udp socket) -> AVI Decompressor -> Renderer.

The bytes got are the same ISampleGrabber sends, and currently, the image i see in the renderer is a bit scrumbled, i would say 40-45 degrees rotated.

Is there a chance that ISampleGrabber modifies the bytes and i get modified bytes and thats why the renderer displays weird results:

Pic is at http://www.turboirc.com/weird.jpg 

You could test this by rendering it at the serder side itself.
Instead of sending it, pass it to a video render.
It won't take more than 5 minutes to set it up with Graphedit tool.

I haven't used samplegrabber filter, but I know it is used for in-line editing of the data.
Is there a special reason why you use it ? Are you modifying the data at the sender side ? - that could be a reason .
Just wondering why couldn't you send the data directly after the Compressor ?
Avatar of WxW

ASKER

How do I get the data to send them if I do not use ISampleGrabber ?

I thought you have the compressed data in hand.
Why don't you take the out put data of compressor, packetize it and send it right away using socket ?
Avatar of WxW

ASKER

Yea thats what I ask.
I want to get the compressed bytes. Thats why I used ISampleGrabber. Can I connect to the output pin of the compressor and get the data in another way ? (without making a new filter myself)

At the sender side, you don't have to use the filters (unless you are doing some image editing or so)
If you can capture data from the driver directly, I would say that would be the best.
The reason being filters -even though they make our lives a lot easier- add substantial overhead to the CPU.
If you have noticed, there are so many levels of function calls involved and most of them are virtual functions.
So, if you have a performance oriented design at the sender side, consider getting rid of filters.

good luck.

May be you are right, ISampleGrabber may be an easy way to grab the data.
I'll let you know if I find a way around to avoid ISampleGrabber.

So, I guess you pass a callback function to ISampleGrabber and the application sends the data over the socket.
I was thinking the filter itself was sending it.
 
ASKER CERTIFIED SOLUTION
Avatar of mxjijo
mxjijo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of WxW

ASKER

Your help is really appreciated.
I will keep working on DirectShow and notify you on the results.
Thanks a lot.

Michael
good luck:)