Click here to Skip to main content
15,884,472 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Graph Edit hangs because of this function, when begining to play movies.
What is wrong?
STDMETHODIMP
CEncOutPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    CheckPointer(ppv,E_POINTER);
    ASSERT(ppv);
    *ppv = NULL;
    HRESULT hr = S_OK;
    // See what interface the caller is interested in.
    if(riid == IID_IMediaPosition || riid == IID_IMediaSeeking)
    {
        if(m_pPosition_1)
        {
            if(m_bHoldsSeek == FALSE)
                return E_NOINTERFACE;
            return m_pPosition_1->QueryInterface(riid, ppv);
        }
		if(m_pPosition_2)
        {
            if(m_bHoldsSeek == FALSE)
                return E_NOINTERFACE;
            return m_pPosition_2->QueryInterface(riid, ppv);
        }
    }
    else
    {
        return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
    }
    CAutoLock lock_it(m_pLock);
    ASSERT(m_pPosition_1 == NULL);
	ASSERT(m_pPosition_2 == NULL);
    IUnknown *pMediaPosition = NULL;
    // Try to create a seeking implementation
//    if(InterlockedExchange(&m_pParent->m_lCanSeek, FALSE) == FALSE)
	BOOL local_bool = m_pParent->m_lCanSeek;
	m_pParent->m_lCanSeek = FALSE;
	if(local_bool==FALSE)
        return E_NOINTERFACE;
    // Create implementation of this dynamically as sometimes we may never
    // try and seek. The helper object implements IMediaPosition and also
    // the IMediaSelection control interface and simply takes the calls
    // normally from the downstream filter and passes them upstream
	for(size_t local_counter=0;local_counter<m_pParent->m_pFirstInPins.size();local_counter++)
	{
	    hr = CreatePosPassThru(GetOwner(),
                           FALSE,
                           (IPin *)&m_pParent->m_pFirstInPins[local_counter],
                           &pMediaPosition);
//		hr = m_pParent->m_pFirstInPins[local_counter]->QueryInterface(IID_ISeekingPassThru,(void **)&pMediaPosition);
		if(pMediaPosition == NULL)
		{
//			InterlockedExchange(&m_pParent->m_lCanSeek, TRUE);
			m_pParent->m_lCanSeek = TRUE;
			return E_OUTOFMEMORY;
		}
		if(FAILED(hr))
		{
//			InterlockedExchange(&m_pParent->m_lCanSeek, TRUE);
			m_pParent->m_lCanSeek = TRUE;
	        pMediaPosition->Release();
		    return hr;
		}
		hr = ((ISeekingPassThru*)(pMediaPosition))->Init(FALSE,m_pParent->m_pFirstInPins[local_counter]);
		if(FAILED(hr))
		{
//			InterlockedExchange(&m_pParent->m_lCanSeek, TRUE);
			m_pParent->m_lCanSeek = TRUE;
	        pMediaPosition->Release();
		    return hr;
		}
		if(local_counter==0)
		{
			m_pPosition_1 = pMediaPosition;
		}
		if(local_counter==1)
		{
			m_pPosition_2 = pMediaPosition;
		}
	}
	
	m_bHoldsSeek = TRUE;
    return NonDelegatingQueryInterface(riid, ppv);
} // NonDelegatingQueryInterface
Posted

Here 2 interfaces for each pin must be returned. But we can return only 1 interface. That is the problem. To control seeking on 2 input pins, we must have 2 pairs of interfaces. But we can return only 1. So how can we get information of requiring pin?
 
Share this answer
 
I have modified project BaseClasses so now i can manage 2 pins. May be the desigion is to create 2 output pin (1 for each input pin) to set 1 input - 1 output. Output are same^ stereo picture.
Any ideas?
STDMETHODIMP
CEncOutPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    CheckPointer(ppv,E_POINTER);
    ASSERT(ppv);
    *ppv = NULL;
    HRESULT hr = S_OK;
    // See what interface the caller is interested in.
    if(riid == IID_IMediaPosition || riid == IID_IMediaSeeking)
    {
    }
    else
    {
        return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
    }
    CAutoLock lock_it(m_pLock);
    ASSERT(m_pPosition_1 == NULL);
	ASSERT(m_pPosition_2 == NULL);
    IUnknown *pMediaPosition = NULL;
    // Try to create a seeking implementation
//    if(InterlockedExchange(&m_pParent->m_lCanSeek, FALSE) == FALSE)
	BOOL local_bool = m_pParent->m_lCanSeek;
	m_pParent->m_lCanSeek = FALSE;
	if(local_bool==FALSE)
        return E_NOINTERFACE;
    // Create implementation of this dynamically as sometimes we may never
    // try and seek. The helper object implements IMediaPosition and also
    // the IMediaSelection control interface and simply takes the calls
    // normally from the downstream filter and passes them upstream
	for(size_t local_counter=0;local_counter<m_pParent->m_pFirstInPins.size();local_counter++)
	{
		hr = CreatePosPassThru(GetOwner(),
                           FALSE,
                           (IPin *)&m_pParent->m_pFirstInPins[local_counter],
                           &pMediaPosition);
		if(pMediaPosition == NULL)
		{
//			InterlockedExchange(&m_pParent->m_lCanSeek, TRUE);
			m_pParent->m_lCanSeek = TRUE;
			return E_OUTOFMEMORY;
		}
		if(FAILED(hr))
		{
//			InterlockedExchange(&m_pParent->m_lCanSeek, TRUE);
			m_pParent->m_lCanSeek = TRUE;
	        pMediaPosition->Release();
		    return hr;
		}
		
		m_bHoldsSeek = TRUE;
		if(local_counter==0)
		{
			m_pPosition_1 = pMediaPosition;
			if(m_pPosition_1)
			{
				if(m_bHoldsSeek == FALSE)
					return E_NOINTERFACE;
				return ((CSeekingPassThru*)m_pPosition_1)->NonDelegatingQueryInterface(riid, ppv);
			}
		}
		if(local_counter==1)
		{
			m_pPosition_2 = pMediaPosition;
			if(m_pPosition_2)
		    {
	            if(m_bHoldsSeek == FALSE)
				    return E_NOINTERFACE;
		        return ((CSeekingPassThru*)m_pPosition_2)->NonDelegatingQueryInterface2(riid, ppv);
	        }
		}
	}
	
	return NonDelegatingQueryInterface(riid, ppv);
    
} // NonDelegatingQueryInterface
 
Share this answer
 
I tryed to implement IMediaSeeking in Filter class.
I have implemented interface request, most of functions.
When request of this interface is enabled in my Filter appears ASSERT message when creating Filter.
When request of this interface is disabled Filter hungs on seeking operation.

Why could it be?

STDMETHODIMP CEncStreamsStereoTransformationFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
#ifdef INFORMATION_MESSAGE
    ::MessageBoxW(0,L"STDMETHODIMP CEncStreamsStereoTransformationFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)",L"Information",MB_ICONINFORMATION);
#endif
/*/
    if (riid == IID_IMediaSeeking)
    {
        *ppv = (IMediaSeeking*)this;
        ((IUnknown*)*ppv)->AddRef();
        return S_OK;
    }
/*/
    return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
 
Share this answer
 
v3
In the Filter the vector queue is used

// Struct for queued samples
struct Sample
{
    DWORD dwFlags;
    IMediaSample *pINSSBuffer_1;		//	Кадр от первого входного пина
	IMediaSample *pINSSBuffer_2;		//	Кадр от второго входного пина
	IMediaSample *pOUTSBuffer_1;		//	Кадр от первого выходного пина
//	IMediaSample *pOUTSBuffer_2;		//	Кадр от второго выходного пина
    Sample(DWORD adwFlags, IMediaSample *apINSSBuffer_1, IMediaSample *apINSSBuffer_2,IMediaSample *apOUTSBuffer_1) :
		dwFlags(adwFlags), pINSSBuffer_1(apINSSBuffer_1), pINSSBuffer_2(apINSSBuffer_2), pOUTSBuffer_1(apOUTSBuffer_1) {}
    Sample() {}
};


In comments text is in Russian.
Текст в комментариях на русском языке.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900