• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1138
  • Last Modified:

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
0
WxW
Asked:
WxW
  • 9
  • 7
1 Solution
 
mxjijoCommented:

>> 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.

0
 
WxWAuthor Commented:
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.
0
 
WxWAuthor Commented:
If I am about to use AVI Decompressor to decompress the bytes, how do I set the source for these bytes ?

Regards.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
mxjijoCommented:

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

                                               





0
 
WxWAuthor Commented:
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.
0
 
mxjijoCommented:

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.. :)

0
 
WxWAuthor Commented:
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 
0
 
mxjijoCommented:

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 ?
0
 
WxWAuthor Commented:
How do I get the data to send them if I do not use ISampleGrabber ?
0
 
mxjijoCommented:

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 ?
0
 
WxWAuthor Commented:
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)
0
 
mxjijoCommented:

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.
0
 
mxjijoCommented:

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.
 
0
 
mxjijoCommented:

I think the way to read from an output pin is via its IAsyncReader interface.
Output pins generally expose this interface. I don't have a sample to point you to, but
I found these links

http://www.gdcl.co.uk/q_and_a.htm#IAsyncReader

Also take a look at directX SDK help topic under

DirectShow->UsingDirectShow->WritingDirectShowFilters->DadaFlowForFilterDevelopers

I think the idea is, for an application to receive data from an output pin of a filter, the application has to create
and input pin, connect that pin to the output pin of the target filter and call IAsyncReader::Request or IAsyncReader::SyncRead.

This is the same mechanism filters use at the input side. The pin doesn't have to be the part of a filter it could be owned by your
application as well. It is not very hard to instantiate and connect an input pin. However, if you think it complicates your stuff, you should go with Sample grabber.
0
 
WxWAuthor Commented:
Your help is really appreciated.
I will keep working on DirectShow and notify you on the results.
Thanks a lot.

Michael
0
 
mxjijoCommented:
good luck:)
0

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 9
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now