🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.multimedia
3 messages
3 total messages Started by Jonathan Benedicto Fri, 31 Dec 2004 01:04
initializing interfaces
#283
Author: Jonathan Benedicto
Date: Fri, 31 Dec 2004 01:04
8 lines
1308 bytes
I'm trying to create my own custom writer sink in using the Windows Media 
Format SDK.

But I have to override the function AllocateDataUnit in the IWMWriterSink 
interface to provide a pointer to a allocated INSSBuffer. How do I allocate 
a INSSBuffer interface, I've tried IWMWriter's AllocateSample method, but it 
the app just hangs.
-- 
Re: initializing interfaces
#284
Author: Remy Lebeau (TeamB)
Date: Fri, 31 Dec 2004 02:11
162 lines
5333 bytes
"Jonathan Benedicto" <incorrect@no.server> wrote in message
news:41d4a5cc$1@newsgroups.borland.com...

> I have to override the function AllocateDataUnit in the
> IWMWriterSink interface to provide a pointer to a allocated
> INSSBuffer. How do I allocate a INSSBuffer interface

You need to write your own INSSBuffer-derived class.  Then you can
instantiate a new instance of that class when needed, just like you would do
for any other C++ class - via the 'new' operator.  For example:

    class TMyNSSBuffer : public INSSBuffer
    {
    private:
        ULONG fRefCount;
        BYTE* fBuffer;
        DWORD fAllocatedSize;
        DWORD fLength;
    public:
        TMyNSSBuffer(DWORD dwMaxSize);
        ~TMyNSSBuffer();

        ULONG __stdcall AddRef();
        ULONG __stdcall Release();
        HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv);

        HRESULT __stdcall GetBuffer(BYTE** ppdwBuffer);
        HRESULT __stdcall GetBufferAndLength(BYTE** ppdwBuffer, DWORD*
pdwLength);
        HRESULT __stdcall GetLength(DWORD* pdwLength);
        HRESULT __stdcall GetMaxLength(DWORD* pdwLength);
        HRESULT __stdcall SetLength(DWORD dwLength);
    };


    TMyNSSBuffer::TMyNSSBuffer(DWORD dwMaxSize)
        : fRefCount(1), fAllocatedSize(dwMaxSize), fLength(0)
    {
        fBuffer = new BYTE[dwMaxSize];
    }

    TMyNSSBuffer::~TMyNSSBuffer()
    {
        delete[] fBuffer;
    }

    ULONG __stdcall TMyNSSBuffer::AddRef()
    {
        return ++fRefCount;
    }

    ULONG __stdcall TMyNSSBuffer::Release()
    {
        if( --fRefCount == 0 )
        {
            delete this;
            return 0;
        }
        return fRefCount;
    }

    HRESULT __stdcall TMyNSSBuffer::QueryInterface(REFIID riid, LPVOID* ppv)
    {
        if( ppv == NULL )
            return E_POINTER;

        *ppv = NULL;

        if( IsEqualIID(riid, IID_IUnknown) )
            *ppv = (IUnknown*) this;
        else if( IsEqualIID(riid, IID_INSSBuffer) )
            *ppv = (INNSBuffer*) this;

        if( *ppv != NULL )
        {
            AddRef();
            return S_OK;
        }

        return E_NOINTERFACE;
    }

    HRESULT __stdcall TMyNSSBuffer::GetBuffer(BYTE** ppdwBuffer)
    {
        if( ppdwBuffer == NULL )
            return E_POINTER;
        *ppdwBuffer = fBuffer;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetBufferAndLength(BYTE** ppdwBuffer,
DWORD* pdwLength)
    {
        if( (ppdwBuffer == NULL) || (pdwLength == NULL) )
            return E_POINTER;
        *ppdwBuffer = fBuffer;
        *pdwLength = fLength;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetLength(DWORD* pdwLength)
    {
        if( pdwLength == NULL )
            return E_POINTER;
        *pdwLength = fLength;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::GetMaxLength(DWORD* pdwLength)
    {
        if( pdwLength == NULL )
            return E_POINTER;
        *pdwLength = fAllocatedSize;
        return S_OK;
    }

    HRESULT __stdcall TMyNSSBuffer::SetLength(DWORD dwLength)
    {
        if( dwLength > fAllocatedSize )
            return E_INVALIDARG;
        fLength = dwLength;
        return S_OK;
    }


Then your IWMWriterSink can do the following:

    class TMyWMWriterSink : public IWMWriterSink
    {
    public:
        HRESULT __stdcall AllocateDataUnit(DWORD cbDataUnit, INSSBuffer**
ppDataUnit);
        //...
    };

    HRESULT __stdcall TMyWMWriterSink::AllocateDataUnit(DWORD cbDataUnit,
INSSBuffer** ppDataUnit)
    {
        if ( *ppDataUnit == NULL )
            return E_POINTER;

        try
        {
            *ppDataUnit = new TMyNSSBuffer(cbDataUnit);
            return S_OK;
        }
        catch(...) {
            return E_FAIL;
        }
    }

> I've tried IWMWriter's AllocateSample method, but it the app just hangs.

You are deadlocking your code with an endless recursion loop.
IWMWriter::AllocateSample() calls IWMWriterSink::AllocateDataUnit()
internally.  So by having your IWMWriterSink interface call
AllocateSample(), you are calling back into IWMWriterSink over and over
endlessly.


Gambit
Re: initializing interfaces
#285
Author: Jonathan Benedicto
Date: Fri, 31 Dec 2004 03:05
174 lines
5603 bytes
Thank you very much for your help. I really appreciate it.

-- 



"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:41d4b51d$1@newsgroups.borland.com...
>
> "Jonathan Benedicto" <incorrect@no.server> wrote in message
> news:41d4a5cc$1@newsgroups.borland.com...
>
>> I have to override the function AllocateDataUnit in the
>> IWMWriterSink interface to provide a pointer to a allocated
>> INSSBuffer. How do I allocate a INSSBuffer interface
>
> You need to write your own INSSBuffer-derived class.  Then you can
> instantiate a new instance of that class when needed, just like you would 
> do
> for any other C++ class - via the 'new' operator.  For example:
>
>    class TMyNSSBuffer : public INSSBuffer
>    {
>    private:
>        ULONG fRefCount;
>        BYTE* fBuffer;
>        DWORD fAllocatedSize;
>        DWORD fLength;
>    public:
>        TMyNSSBuffer(DWORD dwMaxSize);
>        ~TMyNSSBuffer();
>
>        ULONG __stdcall AddRef();
>        ULONG __stdcall Release();
>        HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv);
>
>        HRESULT __stdcall GetBuffer(BYTE** ppdwBuffer);
>        HRESULT __stdcall GetBufferAndLength(BYTE** ppdwBuffer, DWORD*
> pdwLength);
>        HRESULT __stdcall GetLength(DWORD* pdwLength);
>        HRESULT __stdcall GetMaxLength(DWORD* pdwLength);
>        HRESULT __stdcall SetLength(DWORD dwLength);
>    };
>
>
>    TMyNSSBuffer::TMyNSSBuffer(DWORD dwMaxSize)
>        : fRefCount(1), fAllocatedSize(dwMaxSize), fLength(0)
>    {
>        fBuffer = new BYTE[dwMaxSize];
>    }
>
>    TMyNSSBuffer::~TMyNSSBuffer()
>    {
>        delete[] fBuffer;
>    }
>
>    ULONG __stdcall TMyNSSBuffer::AddRef()
>    {
>        return ++fRefCount;
>    }
>
>    ULONG __stdcall TMyNSSBuffer::Release()
>    {
>        if( --fRefCount == 0 )
>        {
>            delete this;
>            return 0;
>        }
>        return fRefCount;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::QueryInterface(REFIID riid, LPVOID* 
> ppv)
>    {
>        if( ppv == NULL )
>            return E_POINTER;
>
>        *ppv = NULL;
>
>        if( IsEqualIID(riid, IID_IUnknown) )
>            *ppv = (IUnknown*) this;
>        else if( IsEqualIID(riid, IID_INSSBuffer) )
>            *ppv = (INNSBuffer*) this;
>
>        if( *ppv != NULL )
>        {
>            AddRef();
>            return S_OK;
>        }
>
>        return E_NOINTERFACE;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::GetBuffer(BYTE** ppdwBuffer)
>    {
>        if( ppdwBuffer == NULL )
>            return E_POINTER;
>        *ppdwBuffer = fBuffer;
>        return S_OK;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::GetBufferAndLength(BYTE** ppdwBuffer,
> DWORD* pdwLength)
>    {
>        if( (ppdwBuffer == NULL) || (pdwLength == NULL) )
>            return E_POINTER;
>        *ppdwBuffer = fBuffer;
>        *pdwLength = fLength;
>        return S_OK;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::GetLength(DWORD* pdwLength)
>    {
>        if( pdwLength == NULL )
>            return E_POINTER;
>        *pdwLength = fLength;
>        return S_OK;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::GetMaxLength(DWORD* pdwLength)
>    {
>        if( pdwLength == NULL )
>            return E_POINTER;
>        *pdwLength = fAllocatedSize;
>        return S_OK;
>    }
>
>    HRESULT __stdcall TMyNSSBuffer::SetLength(DWORD dwLength)
>    {
>        if( dwLength > fAllocatedSize )
>            return E_INVALIDARG;
>        fLength = dwLength;
>        return S_OK;
>    }
>
>
> Then your IWMWriterSink can do the following:
>
>    class TMyWMWriterSink : public IWMWriterSink
>    {
>    public:
>        HRESULT __stdcall AllocateDataUnit(DWORD cbDataUnit, INSSBuffer**
> ppDataUnit);
>        //...
>    };
>
>    HRESULT __stdcall TMyWMWriterSink::AllocateDataUnit(DWORD cbDataUnit,
> INSSBuffer** ppDataUnit)
>    {
>        if ( *ppDataUnit == NULL )
>            return E_POINTER;
>
>        try
>        {
>            *ppDataUnit = new TMyNSSBuffer(cbDataUnit);
>            return S_OK;
>        }
>        catch(...) {
>            return E_FAIL;
>        }
>    }
>
>> I've tried IWMWriter's AllocateSample method, but it the app just hangs.
>
> You are deadlocking your code with an endless recursion loop.
> IWMWriter::AllocateSample() calls IWMWriterSink::AllocateDataUnit()
> internally.  So by having your IWMWriterSink interface call
> AllocateSample(), you are calling back into IWMWriterSink over and over
> endlessly.
>
>
> Gambit
>
> 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads