Beispiel #1
0
STDMETHODIMP CStreamSwitcherFilter::Count(DWORD* pcStreams)
{
    if (!pcStreams) {
        return E_POINTER;
    }

    CAutoLock cAutoLock(&m_csPins);

    *pcStreams = 0;
    POSITION pos = m_pInputs.GetHeadPosition();
    while (pos) {
        CStreamSwitcherInputPin* pInputPin = m_pInputs.GetNext(pos);

        if (pInputPin->IsConnected()) {
            if (CComPtr<IAMStreamSelect> pSSF = pInputPin->GetStreamSelectionFilter()) {
                DWORD cStreams = 0;
                HRESULT hr = pSSF->Count(&cStreams);
                if (SUCCEEDED(hr)) {
                    for (int i = 0; i < (int)cStreams; i++) {
                        AM_MEDIA_TYPE* pmt = nullptr;
                        hr = pSSF->Info(i, &pmt, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
                        if (SUCCEEDED(hr) && pmt && pmt->majortype == MEDIATYPE_Audio) {
                            (*pcStreams)++;
                        }
                        DeleteMediaType(pmt);
                    }
                }
            } else {
                (*pcStreams)++;
            }
        }
    }

    return S_OK;
}
Beispiel #2
0
HRESULT CStreamSwitcherOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
{
    CStreamSwitcherInputPin* pIn = (static_cast<CStreamSwitcherFilter*>(m_pFilter))->GetInputPin();
    if (!pIn || !pIn->IsConnected()) {
        return E_UNEXPECTED;
    }

    CComPtr<IEnumMediaTypes> pEM;
    if (FAILED(pIn->GetConnected()->EnumMediaTypes(&pEM))) {
        return VFW_S_NO_MORE_ITEMS;
    }

    if (iPosition > 0 && FAILED(pEM->Skip(iPosition))) {
        return VFW_S_NO_MORE_ITEMS;
    }

    AM_MEDIA_TYPE* tmp = nullptr;
    if (S_OK != pEM->Next(1, &tmp, nullptr) || !tmp) {
        return VFW_S_NO_MORE_ITEMS;
    }

    CopyMediaType(pmt, tmp);
    DeleteMediaType(tmp);
    /*
        if (iPosition < 0) return E_INVALIDARG;
        if (iPosition > 0) return VFW_S_NO_MORE_ITEMS;

        CopyMediaType(pmt, &pIn->CurrentMediaType());
    */
    return S_OK;
}
Beispiel #3
0
void CStreamSwitcherFilter::SelectInput(CStreamSwitcherInputPin* pInput)
{
    // make sure no input thinks it is active
    m_pInput = nullptr;

    // release blocked GetBuffer in our own allocator & block all Receive
    POSITION pos = m_pInputs.GetHeadPosition();
    while (pos) {
        CStreamSwitcherInputPin* pPin = m_pInputs.GetNext(pos);
        pPin->Block(false);
        // a few Receive calls can arrive here, but since m_pInput == nullptr neighter of them gets delivered
        pPin->Block(true);
    }

    // this will let waiting GetBuffer() calls go on inside our Receive()
    if (m_pOutput) {
        m_pOutput->DeliverBeginFlush();
        m_pOutput->DeliverEndFlush();
    }

    if (!pInput) {
        return;
    }

    // set new input
    m_pInput = pInput;

    // let it go
    m_pInput->Block(false);
}
Beispiel #4
0
HRESULT CStreamSwitcherOutputPin::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
{
    CStreamSwitcherInputPin* pIn = (static_cast<CStreamSwitcherFilter*>(m_pFilter))->GetInputPin();
    if (!pIn || !pIn->IsConnected()) {
        return E_UNEXPECTED;
    }

    CComPtr<IMemAllocator> pAllocatorIn;
    pIn->GetAllocator(&pAllocatorIn);
    if (!pAllocatorIn) {
        return E_UNEXPECTED;
    }

    HRESULT hr;
    if (FAILED(hr = pAllocatorIn->GetProperties(pProperties))) {
        return hr;
    }

    if (pProperties->cBuffers < 8 && pIn->CurrentMediaType().majortype == MEDIATYPE_Audio) {
        pProperties->cBuffers = 8;
    }

    ALLOCATOR_PROPERTIES Actual;
    if (FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) {
        return hr;
    }

    return (pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
            ? E_FAIL
            : NOERROR);
}
Beispiel #5
0
STDMETHODIMP CStreamSwitcherOutputPin::Notify(IBaseFilter* pSender, Quality q)
{
    CStreamSwitcherInputPin* pIn = (static_cast<CStreamSwitcherFilter*>(m_pFilter))->GetInputPin();
    if (!pIn || !pIn->IsConnected()) {
        return VFW_E_NOT_CONNECTED;
    }
    return pIn->PassNotify(q);
}
Beispiel #6
0
STDMETHODIMP CStreamSwitcherFilter::Enable(long lIndex, DWORD dwFlags)
{
    if (dwFlags != AMSTREAMSELECTENABLE_ENABLE) {
        return E_NOTIMPL;
    }

    PauseGraph;

    bool bFound = false;
    int i = 0;
    CStreamSwitcherInputPin* pNewInputPin = nullptr;
    POSITION pos = m_pInputs.GetHeadPosition();
    while (pos && !bFound) {
        pNewInputPin = m_pInputs.GetNext(pos);

        if (pNewInputPin->IsConnected()) {
            if (CComPtr<IAMStreamSelect> pSSF = pNewInputPin->GetStreamSelectionFilter()) {
                DWORD cStreams = 0;
                HRESULT hr = pSSF->Count(&cStreams);
                if (SUCCEEDED(hr)) {
                    for (i = 0; i < (int)cStreams; i++) {
                        AM_MEDIA_TYPE* pmt = nullptr;
                        hr = pSSF->Info(i, &pmt, nullptr, nullptr, NULL, nullptr, nullptr, nullptr);
                        if (SUCCEEDED(hr) && pmt && pmt->majortype == MEDIATYPE_Audio) {
                            if (lIndex == 0) {
                                bFound = true;
                                DeleteMediaType(pmt);
                                break;
                            } else {
                                lIndex--;
                            }
                        }
                        DeleteMediaType(pmt);
                    }
                }
            } else if (lIndex == 0) {
                bFound = true;
            } else {
                lIndex--;
            }
        }
    }

    if (!bFound) {
        return E_INVALIDARG;
    }

    SelectInput(pNewInputPin);

    if (CComPtr<IAMStreamSelect> pSSF = pNewInputPin->GetStreamSelectionFilter()) {
        pSSF->Enable(i, dwFlags);
    }

    ResumeGraph;

    return S_OK;
}
HRESULT CStreamSwitcherOutputPin::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
{
	CStreamSwitcherInputPin* pIn = ((CStreamSwitcherFilter*)m_pFilter)->GetInputPin();
	if(!pIn || !pIn->IsConnected()) {
		SVP_LogMsg5(L"DecideBufferSize	if(!pIn || !pIn->IsConnected()) {");
		return E_UNEXPECTED;
	}

	CComPtr<IMemAllocator> pAllocatorIn;
	pIn->GetAllocator(&pAllocatorIn);
	if(!pAllocatorIn){
		SVP_LogMsg5(L"DecideBufferSize pIn->GetAllocator(&pAllocatorIn);");
		return E_UNEXPECTED;
	}

	HRESULT hr;
	if(FAILED(hr = pAllocatorIn->GetProperties(pProperties))) {
		SVP_LogMsg5(L"DecideBufferSize	if(FAILED(hr = pAllocatorIn->GetProperties(pProperties))) {");
		return hr;
	}

	if( pIn->CurrentMediaType().majortype == MEDIATYPE_Audio){
		if(pProperties->cBuffers < 8)
			pProperties->cBuffers = 8;

		WAVEFORMATEX* wfe = (WAVEFORMATEX*)pIn->CurrentMediaType().pbFormat;
		pProperties->cbBuffer = (long) ((__int64) pProperties->cbBuffer * 8 / min( wfe->nChannels ,8 ) * 
			96000 / min( wfe->nSamplesPerSec, 96000));

	}

	
	
	

	ALLOCATOR_PROPERTIES Actual;
	if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) {
		SVP_LogMsg5(L"DecideBufferSize 	if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) {");
		return hr;
	}

	hr = (pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
		? E_FAIL
		: NOERROR);
	SVP_LogMsg5(L"DecideBufferSize  %d %d %d %d %x",pProperties->cBuffers  ,Actual.cBuffers  , pProperties->cbBuffer , Actual.cbBuffer , hr );
	return hr;
}
Beispiel #8
0
CStreamSwitcherInputPin* CStreamSwitcherFilter::GetConnectedInputPin(int n)
{
    if (n >= 0) {
        POSITION pos = m_pInputs.GetHeadPosition();
        while (pos) {
            CStreamSwitcherInputPin* pPin = m_pInputs.GetNext(pos);
            if (pPin->IsConnected()) {
                if (n == 0) {
                    return pPin;
                }
                n--;
            }
        }
    }

    return nullptr;
}
Beispiel #9
0
HRESULT CStreamSwitcherOutputPin::QueryAcceptUpstream(const AM_MEDIA_TYPE* pmt)
{
    HRESULT hr = S_FALSE;

    CStreamSwitcherInputPin* pIn = (static_cast<CStreamSwitcherFilter*>(m_pFilter))->GetInputPin();

    if (pIn && pIn->IsConnected() && (pIn->IsUsingOwnAllocator() || pIn->CurrentMediaType() == *pmt)) {
        if (CComQIPtr<IPin> pPinTo = pIn->GetConnected()) {
            if (S_OK != (hr = pPinTo->QueryAccept(pmt))) {
                return VFW_E_TYPE_NOT_ACCEPTED;
            }
        } else {
            return E_FAIL;
        }
    }

    return hr;
}
Beispiel #10
0
HRESULT CStreamSwitcherOutputPin::CompleteConnect(IPin* pReceivePin)
{
    m_pPinConnection = CComQIPtr<IPinConnection>(pReceivePin);
    HRESULT hr = __super::CompleteConnect(pReceivePin);

    CStreamSwitcherInputPin* pIn = (static_cast<CStreamSwitcherFilter*>(m_pFilter))->GetInputPin();
    CMediaType mt;
    if (SUCCEEDED(hr) && pIn && pIn->IsConnected()
            && SUCCEEDED(pIn->GetConnected()->ConnectionMediaType(&mt)) && m_mt != mt) {
        if (pIn->GetConnected()->QueryAccept(&m_mt) == S_OK) {
            hr = m_pFilter->ReconnectPin(pIn->GetConnected(), &m_mt);
        } else {
            hr = VFW_E_TYPE_NOT_ACCEPTED;
        }
    }

    return hr;
}
Beispiel #11
0
// pdwGroup value is set to:
//  - 0 if the track isn't controlled by any underlying IAMStreamSelect interface
//  - 1 if the track is controlled by an underlying IAMStreamSelect interface and is not selected at that level
//  - 2 if the track is controlled by an underlying IAMStreamSelect interface and is selected at that level
STDMETHODIMP CStreamSwitcherFilter::Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk)
{
    CAutoLock cAutoLock(&m_csPins);

    IUnknown* pObject = nullptr;
    bool bFound = false;
    POSITION pos = m_pInputs.GetHeadPosition();
    while (pos && !bFound) {
        CStreamSwitcherInputPin* pInputPin = m_pInputs.GetNext(pos);

        if (pInputPin->IsConnected()) {
            if (CComPtr<IAMStreamSelect> pSSF = pInputPin->GetStreamSelectionFilter()) {
                DWORD cStreams = 0;
                HRESULT hr = pSSF->Count(&cStreams);
                if (SUCCEEDED(hr)) {
                    for (int i = 0; i < (int)cStreams; i++) {
                        AM_MEDIA_TYPE* pmt = nullptr;
                        DWORD dwFlags;
                        LPWSTR pszName = nullptr;
                        hr = pSSF->Info(i, &pmt, &dwFlags, plcid, NULL, &pszName, nullptr, nullptr);
                        if (SUCCEEDED(hr) && pmt && pmt->majortype == MEDIATYPE_Audio) {
                            if (lIndex == 0) {
                                bFound = true;
                                pObject = pSSF;

                                if (ppmt) {
                                    *ppmt = pmt;
                                } else {
                                    DeleteMediaType(pmt);
                                }

                                if (pdwFlags) {
                                    *pdwFlags = (m_pInput == pInputPin) ? dwFlags : 0;
                                }

                                if (pdwGroup) {
                                    *pdwGroup = (dwFlags & (AMSTREAMSELECTINFO_ENABLED | AMSTREAMSELECTINFO_EXCLUSIVE)) ? 2 : 1;
                                }

                                if (ppszName) {
                                    *ppszName = pszName;
                                } else {
                                    CoTaskMemFree(pszName);
                                }

                                break;
                            } else {
                                lIndex--;
                            }
                        }
                        DeleteMediaType(pmt);
                        CoTaskMemFree(pszName);
                    }
                }
            } else if (lIndex == 0) {
                bFound = true;

                if (ppmt) {
                    *ppmt = CreateMediaType(&m_pOutput->CurrentMediaType());
                }

                if (pdwFlags) {
                    *pdwFlags = (m_pInput == pInputPin) ? AMSTREAMSELECTINFO_EXCLUSIVE : 0;
                }

                if (plcid) {
                    *plcid = 0;
                }

                if (pdwGroup) {
                    *pdwGroup = 0;
                }

                if (ppszName) {
                    *ppszName = (WCHAR*)CoTaskMemAlloc((wcslen(pInputPin->Name()) + 1) * sizeof(WCHAR));
                    if (*ppszName) {
                        wcscpy_s(*ppszName, wcslen(pInputPin->Name()) + 1, pInputPin->Name());
                    }
                }
            } else {
                lIndex--;
            }
        }
    }

    if (!bFound) {
        return E_INVALIDARG;
    }

    if (ppObject) {
        *ppObject = pObject;
        if (pObject) {
            pObject->AddRef();
        }
    }

    if (ppUnk) {
        *ppUnk = nullptr;
    }

    return S_OK;
}