source filter dynamic format change
-
Wednesday, December 08, 2010 9:38 AM
I have a direct show source filter that exposes 4 formats. All of them differs by size : 320x240 ... 640x480 all 24 bps. I need to support the following scenario:
* filter is connected using 640x480 format, graph is started and I need to change to 320x240 format.
From what I read regarding dynamic format change I need to do the followings:
* call IPinConnection.DynamicQueryAccept (or IPin.QueryAccept if IPinConnection is not available) with new media type
* if S_OK is returned I need to attach the new media type to the next sample I send.
* if an error is returned I need to force reconnection. I'm doing that using EC_DISPLAY_CHANGED event
My implementation:
I override DoProcessingLoop() as follows:
- if format change needed
- create new media type
- call DynamicQueryAccept or QueryAccept with new media type on connected pin
- if format not accepted call filter->NotifyEvent(EC_DISPLAY_CHANGED, (LONG_PTR)connectedPin, 0);
- call GetDeliveryBuffer()
- call FillBuffer()
- if new format accepted
- call pMediaSample->SetMediaType() with new media type
- if S_OK is retuned change m_mt to new media type
- call Deliver() to deliver media sample
Also it says that in order for this to work negotiated buffer must not change. To support this, on DecideBufferSize() i provide a big enough buffer that will fit the biggest format that I can support.
VIDEOINFOHEADER:
Here I tried more versions:
1. for every media type I provided it's own VIDEOINFOHEADER:
320x240 - rcSource= [0, 0, 320, 240] bmiHeader.biWidth= 320 bmiHeader.biHeigh= 240
............
640x480 - rcSource= [0, 0, 640, 480] bmiHeader.biWidth= 640 bmiHeader.biHeigh= 480
2. all media types have the same biWidth and biHeight:
320x240 - rcSource= [0, 0, 320, 240] bmiHeader.biWidth= 640 bmiHeader.biHeigh= 480
............
640x480 - rcSource= [0, 0, 640, 480] bmiHeader.biWidth= 640 bmiHeader.biHeigh= 480
I tested with: Skype, AmCap, U-stream
My problems are:
with AmCap:
- using first approach for VIDEOINFOHEADER media type is accepted, but the sample size is rendered using the media type negotiated on filter connection. Calling filter->NotifyEvent(EC_DISPLAY_CHANGED, (LONG_PTR)connectedPin, 0) will force a reconnection and the problem is solved
- using second approach for VIDEOINFOHEADER I have two problems:
* necociated media type is always 640x480
* any new media type is not accepted and filter->NotifyEvent(EC_DISPLAY_CHANGED, (LONG_PTR)connectedPin, 0) will not work, because of fixed negociated media type.
with Skype:
- using first approach for VIDEOINFOHEADER media type is accepted, but the sample size is rendered using the media type negotiated on filter connection. Calling filter->NotifyEvent(EC_DISPLAY_CHANGED, (LONG_PTR)connectedPin, 0) will force a reconnection, the new negotiated type is the right one, but skype will still use the old one.
- with second approach skype will always use BITMAPINFOHEADER biWidth and biHeight to render the sample
with u-stream:
- using first approach we have the same behaviour as skype
- using second approach we have same behaviour as AmCap.
I tried working with rcTarget, but seams to be ignored by all three.
I need to have consistent behaviors on all three application. What is wrong with my approach?
Iulian
All Replies
-
Wednesday, December 08, 2010 1:38 PM
I need to have consistent behaviors on all three application. What is wrong with my approach?
Nothing. The applications are simply badly written and do not support a dynamic format change (which are not really required to) or rcSource (which they should).
MVP :: DirectShow / MediaFoundation <http://www.riseoftheants.com/mmx/faq.htm>


