Menu

New Windows 7 Stream Buffer Source Interfaces

Andrew
2009-12-29
2012-10-29
  • Andrew

    Andrew - 2009-12-29

    I needed to figure out the new Stream Buffer Engine functionality introduced
    in Windows 7 (), and to that end had to write managed definitions for all the
    new interfaces. I think there are some other new directshow interfaces in win
    7 as well, but hopefully this might help someone else out at some point to
    start with.

    I can provide a simple example app if anyone is interested in seeing these
    interfaces at work in win 7. Much of it is a translation of the samples
    provided in the linked msdn documation.

    Guid's, Enums & Structs:

    public static Guid SBE2_STREAM_DESC_EVENT = new Guid("2313a4ed-bf2d-454f-ad8a-
    d95ba7f91fee");
    public static Guid SBE2_V1_STREAMS_CREATION_EVENT = new
    Guid("000FCF09-97F5-46ac-9769-7A83B35384FB");
    public static Guid SBE2_V2_STREAMS_CREATION_EVENT = new Guid("A72530A3-0344
    -4cab-A2D0-FE937DBDCAB3");

    public enum CrossbarDefaultFlags
    {
    DEF_MODE_PROFILE = 0x0000001,
    DEF_MODE_STREAMS = 0x0000002
    }

    public struct SBE2StreamDesc
    {
    public int Version; //DWORD
    public int StreamId; //SBE2_STREAM_ID
    public int Default; //DWORD
    public int Reserved; //DWORD
    }

    public struct DVRStreamDesc
    {
    public int Version; //DWORD
    public int StreamId; //DWORD
    public bool Default; //BOOL
    public bool Creation; //BOOL
    public int Reserved; //DWORD
    public Guid guidSubMediaType; //GUID
    public Guid guidFormatType; //GUID
    public AMMediaType MediaType; //AM_MEDIA_TYPE
    }

    Interfaces:

    public interface ISBE2GlobalEvent
    {
    //HRESULT GetEvent ( REFGUID idEvt, ULONG param1, ULONG param2, ULONG param3,
    ULONG param4, BOOL pSpanning, DWORD pcb, BYTE *pb);

    int GetEvent( Guid idEvt, int param1, int param2, int param3, int param4, out
    bool pSpanning, ref int pcb, IntPtr pb);
    }

    public interface ISBE2GlobalEvent2 : ISBE2GlobalEvent
    {

    region ISBE2GlobalEvent

    new int GetEvent( Guid idEvt, int param1, int param2, int param3, int param4,
    out bool pSpanning, ref int pcb, IntPtr pb);

    endregion

    //HRESULT GetEventEx ( REFGUID idEvt, ULONG param1, ULONG param2, ULONG
    param3, ULONG param4, BOOL pSpanning, DWORD pcb, BYTE pb, REFERENCE_TIME
    pStreamTime );

    int GetEvent( Guid idEvt, int param1, int param2, int param3, int param4, out
    bool pSpanning, ref int pcb, IntPtr pb, out long pStreamTime);
    }

    public interface ISBE2Crossbar
    {
    //HRESULT EnableDefaultMode ( DWORD DefaultFlags ) ;

    int EnableDefaultMode( int DefaultFlags);

    //HRESULT GetInitialProfile ( ISBE2MediaTypeProfile ** ppProfile ) ;

    int GetInitialProfile( out ISBE2MediaTypeProfile ppProfile);

    //HRESULT SetOutputProfile ( ISBE2MediaTypeProfile * pProfile, DWORD *
    pcOutputPins, IPin ** ppOutputPins ) ;

    int SetOutputProfile(
    ISBE2MediaTypeProfile pProfile,
    out int pcOutputPins,
    IPin ppOutputPins);

    //HRESULT EnumStreams ( ISBE2EnumStream ** ppStreams ) ;

    int EnumStreams( out ISBE2EnumStream ppStreams);
    }

    public interface ISBE2StreamMap
    {
    //HRESULT MapStream ( SBE2_STREAM_ID Stream ) ;

    int MapStream( int Stream);

    //HRESULT UnmapStream ( SBE2_STREAM_ID Stream ) ;

    int UnmapStream( int Stream);

    //HRESULT EnumMappedStreams ( ISBE2EnumStream ** ppStreams ) ;

    int EnumMappedStreams( out ISBE2EnumStream ppStreams);
    }

    public interface ISBE2EnumStream
    {
    //HRESULT Next ( ULONG cRequest, SBE2_STREAM_DESC * pStreamDesc, ULONG *
    pcReceived ) ;

    int Next(
    int cRequest,
    SBE2StreamDesc pStreamDesc,
    out int pcReceived);

    // HRESULT Skip ( ULONG cRecords ) ;

    int Skip( int cRecords);

    //HRESULT Reset () ;

    int Reset();

    //HRESULT Clone ( ISBE2EnumStream ** ppIEnumStream ) ;

    int Clone( out ISBE2EnumStream ppIEnumStream);
    }

    public interface ISBE2MediaTypeProfile
    {
    // HRESULT GetStreamCount ( DWORD * pCount ) ;

    int GetStreamCount( out int pCount);

    //HRESULT GetStream ( DWORD Index, AM_MEDIA_TYPE ** ppMediaType ) ;

    int GetStream( int Index, out AMMediaType ppMediaType);

    //HRESULT AddStream ( AM_MEDIA_TYPE * pMediaType ) ;

    int AddStream( AMMediaType pMediaType);

    //HRESULT DeleteStream ( DWORD Index ) ;

    int DeleteStream( int Index);
    }

    public interface ISBE2FileScan
    {
    //HRESULT RepairFile ( LPCWSTR filename) ;

    int RepairFile( string filename);
    }

    The only method header I'm not totally sure about is
    ISBE2GlobalEvent::GetEvent, where the last parameter is marked as Out but
    expects a pointer. This is similar to methods like
    ISampleGrabber::GetCurrentBuffer where you need to be able to pass null to get
    the required buffer size, but in this case the parameter is marked as Out in
    the unmanaged definition. As far as I can see there is no way to pass null to
    an out parameter from managed code - passing IntPtr.Zero results in an
    E_POINTER return code informing me the pointer is null. This function requires
    null to be passed in order to get the required size returned. I'm happy enough
    with making a best-guess at the required memory allocation, but this might
    become a problem in some situations. I'm not sure if there is a solution to
    this?

    http://msdn.microsoft.com/en-
    us/library/dd758060(VS.85).aspx

     
  • François MAESEELE

    Hi,
    I'm already using these new interfaces to configure a StreamBufferSource. ie I
    wait for global events to map streams manually, because I need to use the
    EVENTID_AudioTypeSpanningEvent which contains audio stream language.
    The GetEvent indeed fails in 32bits with E__INVALIDARG while it works in
    64bits!! I didn't succeed to make it work for now in 32bits OS. If you find a
    solution....

    Also, don't know if you use a StreamBufferSink, but in my application I send
    two audio streams on it, and I noticed that I get these audio streams on the
    StreamBufferSource side in a random order. Moreother, I didn't find a way to
    specify the audio language (iso code) on the StreamBufferSink in order to get
    EVENTID__AudioTypeSpanningEvent event. MCE seems to correctly send it while
    using a DVBT Tuner.

    Also, they are some undocumented interfaces that I couldn't find:
    ISBE2Sink, ISBE2ReadoutConfig

    Regards

     
  • François MAESEELE

    Thanks a lot but I still miss the ISBE2Sink and ISBE2ReadoutConfig interfaces.
    Regarding the GetEvent, the fact is this method has to be called on the same
    thread that created the StreamBufferSink2 filter. Then it works.

     
  • Andrew

    Andrew - 2010-01-03

    @nowinskie - Thanks for the pointer to the cvs, I really should have looked
    there first, certainly would have saved me some time.

    Also, don't know if you use a StreamBufferSink, but in my application I send
    two audio streams on it, and I noticed that I get these audio streams on the
    StreamBufferSource side in a random order.

    I also noticed that when examining the streams available on the SBSource they
    seem to be in an arbitrary order. I think the best was is to follow the
    example in the documentation, to wait for the events to be raised and use the
    streamid in the received structure. I see the problem that you need to have
    set the iso code for the language stream in order to get the audio spanning
    event generated though. Is it possible to generate this event yourself using
    the BroadcastEventService object you create/obtain as described in ?

    Not too sure about the undocumented interfaces, haven't seen reference to them
    anywhere and without headers there's not a lot that can be done.

    I'm not sure I can be of much further help, my need to figure all this out was
    driven by the need to replicate the automatic stream configuration process
    because the default handling is now broken for dv video streams. From the
    documentation you are supposed to still be able to use the SBE as before with
    the automatic handling enabled by default, but this fails to hook a single dv
    video stream up in the SBSource, resulting in a rather horrible crash when you
    render the graph. The only solution I have found is to add support for all
    these new interfaces, turn off the automatic handling and map the streams
    manually as described in the documentation. It seems the default stream
    mapping is somewhat broken for standard use of the SBE as a result of all
    these WTV extensions.

    http://msdn.microsoft.com/en-
    us/library/dd758059(VS.85).aspx

     
  • snarfle

    snarfle - 2010-01-03

    I don't think I've ever heard of ISBE2Sink. It isn't in MS's sdk docs, it
    isn't defined in the PSDK and google turns up no hits. What makes you think it
    even exists?

     
  • François MAESEELE

    @woody3k: Thanks for your input. Let me be clear about the stream ordering. it
    seems that the ordering problem is only on the StreamBufferSink2 filter side,
    because in case of a wtv file with many streams, the order always remain the
    same when reading it. It seems that the streams creation/order has nothing to
    do with the Sink pin creation order. What I miss is how to get information
    about the stream creation on the Sink side ? Or may be I don't need it unless
    I find how MCE send the audio language information from its capture graph when
    a channel has many audio languages.

    @snarfle: This is the reason why I suspect the role of the undocumented
    interface ISBE2Sink (you can find its guid by scanning the filter with
    DsgraphEdit tool from codeproject, or using the MS SDK Tool Ole/Com View
    Tool).

    I Still wonder how MS persist this information in a WTV file as I checked with
    metadata, and there is nothing usable with audio streams.

     
  • François MAESEELE

    Additional note: StreamBufferSink2 reports that it has PropertyPage with one
    page...(so one Guid) but it seems unusable...... Is there a way to get the
    properties of a filter by a generic way ? I mean like a property bag with
    key/value pairs ?

     
  • anton winter

    anton winter - 2010-01-17

    hi woody,

    could i grab a copy of the example application please.

    cheers
    Anton
    e mail antonwintpg.com.au

     

Log in to post a comment.