Exemplo n.º 1
0
STDMETHODIMP CStreamSwitcherInputPin::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
    return
        QI(IStreamSwitcherInputPin)
        IsConnected() && GetCLSID(GetFilterFromPin(GetConnected())) == __uuidof(NeroAudioDecoder) && QI(IPinConnection)
        __super::NonDelegatingQueryInterface(riid, ppv);
}
Exemplo n.º 2
0
HRESULT CBaseMuxerInputPin::CompleteConnect(IPin* pReceivePin)
{
    HRESULT hr = __super::CompleteConnect(pReceivePin);
    if (FAILED(hr)) {
        return hr;
    }

    // duration

    m_rtDuration = 0;
    CComQIPtr<IMediaSeeking> pMS;
    if ((pMS = GetFilterFromPin(pReceivePin)) || (pMS = pReceivePin)) {
        pMS->GetDuration(&m_rtDuration);
    }

    // properties

    for (CComPtr<IPin> pPin = pReceivePin; pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin))) {
        if (CComQIPtr<IDSMPropertyBag> pPB = pPin) {
            ULONG cProperties = 0;
            if (SUCCEEDED(pPB->CountProperties(&cProperties)) && cProperties > 0) {
                for (ULONG iProperty = 0; iProperty < cProperties; iProperty++) {
                    PROPBAG2 PropBag;
                    memset(&PropBag, 0, sizeof(PropBag));
                    ULONG cPropertiesReturned = 0;
                    if (FAILED(pPB->GetPropertyInfo(iProperty, 1, &PropBag, &cPropertiesReturned))) {
                        continue;
                    }

                    HRESULT hr2;
                    CComVariant var;
                    if (SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr2)) && SUCCEEDED(hr2)) {
                        SetProperty(PropBag.pstrName, &var);
                    }

                    CoTaskMemFree(PropBag.pstrName);
                }
            }
        }
    }

    (static_cast<CBaseMuxerFilter*>(m_pFilter))->AddInput();

    return S_OK;
}
Exemplo n.º 3
0
HRESULT CStreamSwitcherOutputPin::CheckConnect(IPin* pPin)
{
    CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPin);

    return
        IsAudioWaveRenderer(pBF) || GetCLSID(pBF) == __uuidof(MatrixMixer)
        ? __super::CheckConnect(pPin)
        : E_FAIL;

    //  return CComQIPtr<IPinConnection>(pPin) ? CBaseOutputPin::CheckConnect(pPin) : E_NOINTERFACE;
    //  return CBaseOutputPin::CheckConnect(pPin);
}
Exemplo n.º 4
0
bool CBaseSplitterOutputPin::IsActive()
{
    CComPtr<IPin> pPin = this;
    do {
        CComPtr<IPin> pPinTo;
        CComQIPtr<IStreamSwitcherInputPin> pSSIP;
        if (S_OK == pPin->ConnectedTo(&pPinTo) && (pSSIP = pPinTo) && !pSSIP->IsActive()) {
            return false;
        }
        pPin = GetFirstPin(GetFilterFromPin(pPinTo), PINDIR_OUTPUT);
    } while (pPin);

    return true;
}
Exemplo n.º 5
0
STDMETHODIMP CBaseMuxerFilter::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
{
	FILTER_STATE fs;

	if(SUCCEEDED(GetState(0, &fs)) && fs == State_Stopped)
	{
		POSITION pos = m_pInputs.GetHeadPosition();
		while(pos)
		{
			CBasePin* pPin = m_pInputs.GetNext(pos);
			CComQIPtr<IMediaSeeking> pMS = pPin->GetConnected();
			if(!pMS) pMS = GetFilterFromPin(pPin->GetConnected());
			if(pMS) pMS->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
		}

		return S_OK;
	}

	return VFW_E_WRONG_STATE;
}
Exemplo n.º 6
0
	BeginEnumPins(pBFParent, pEP, pPin)
	{
		CComPtr<IPin> pPinTo;
		CComPtr<IBaseFilter> pBF;
		if(S_OK != m_pGB->IsPinDirection(pPin, PINDIR_OUTPUT)
			|| FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
			|| !(pBF = GetFilterFromPin(pPinTo)))
			continue;

		CTreeItem* t = NULL;

		if(pBF == m_pMux)
		{
			t = DNew CTreeItemPin(pPin, m_tree, hTIParent);
		}
		else
		{
			t = DNew CTreeItemFilter(pBF, m_tree, hTIParent);
			AddFilter(*t, pBF);
		}
	}
Exemplo n.º 7
0
void CBaseSplitterOutputPin::MakeISCRHappy()
{
    CComPtr<IPin> pPinTo = this, pTmp;
    while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
        pTmp = nullptr;

        CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);

        if (GetCLSID(pBF) == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) { // ISCR
            CAutoPtr<Packet> p(DEBUG_NEW Packet());
            p->TrackNumber = DWORD_ERROR;
            p->rtStart = -1;
            p->rtStop = 0;
            p->bSyncPoint = FALSE;
            p->SetData(" ", 2);
            QueuePacket(p);
            break;
        }

        pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
    }
}
Exemplo n.º 8
0
DWORD CBaseSplitterOutputPin::ThreadProc()
{
    SetThreadName(DWORD(-1), "CBaseSplitterOutputPin");
    m_hrDeliver = S_OK;
    m_fFlushing = m_fFlushed = false;
    m_eEndFlush.Set();

    // fix for Microsoft DTV-DVD Video Decoder - video freeze after STOP/PLAY
    bool iHaaliRenderConnect = false;
    CComPtr<IPin> pPinTo = this, pTmp;
    while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) {
        pTmp = nullptr;
        CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo);
        if (GetCLSID(pBF) == CLSID_DXR) { // Haali Renderer
            iHaaliRenderConnect = true;
            break;
        }
        pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT);
    }
    if (IsConnected() && !iHaaliRenderConnect) {
        GetConnected()->BeginFlush();
        GetConnected()->EndFlush();
    }

    for (;;) {
        Sleep(1);

        DWORD cmd;
        if (CheckRequest(&cmd)) {
            m_hThread = nullptr;
            cmd = GetRequest();
            Reply(S_OK);
            ASSERT(cmd == CMD_EXIT);
            return 0;
        }

        int cnt = 0;
        do {
            CAutoPtr<Packet> p;

            {
                CAutoLock cAutoLock(&m_queue);
                if ((cnt = m_queue.GetCount()) > 0) {
                    p = m_queue.Remove();
                }
            }

            if (S_OK == m_hrDeliver && cnt > 0) {
                ASSERT(!m_fFlushing);

                m_fFlushed = false;

                // flushing can still start here, to release a blocked deliver call

                HRESULT hr = p
                             ? DeliverPacket(p)
                             : DeliverEndOfStream();

                m_eEndFlush.Wait(); // .. so we have to wait until it is done

                if (hr != S_OK && !m_fFlushed) { // and only report the error in m_hrDeliver if we didn't flush the stream
                    // CAutoLock cAutoLock(&m_csQueueLock);
                    m_hrDeliver = hr;
                    break;
                }
            }
        } while (--cnt > 0);
    }
}
Exemplo n.º 9
0
HRESULT CStreamSwitcherInputPin::CompleteConnect(IPin* pReceivePin)
{
    HRESULT hr = __super::CompleteConnect(pReceivePin);
    if (FAILED(hr)) {
        return hr;
    }

    (static_cast<CStreamSwitcherFilter*>(m_pFilter))->CompleteConnect(PINDIR_INPUT, this, pReceivePin);

    m_fCanBlock = false;
    bool fForkedSomewhere = false;

    CStringW fileName;
    CStringW pinName;

    IPin* pPin = (IPin*)this;
    IBaseFilter* pBF = (IBaseFilter*)m_pFilter;

    pPin = GetUpStreamPin(pBF, pPin);
    if (pPin) {
        pBF = GetFilterFromPin(pPin);
    }
    while (pPin && pBF) {
        if (IsSplitter(pBF)) {
            pinName = GetPinName(pPin);
        }

        CLSID clsid = GetCLSID(pBF);
        if (clsid == CLSID_AviSplitter || clsid == CLSID_OggSplitter) {
            m_fCanBlock = true;
        }

        int nIn, nOut, nInC, nOutC;
        CountPins(pBF, nIn, nOut, nInC, nOutC);
        fForkedSomewhere = fForkedSomewhere || nIn > 1 || nOut > 1;

        DWORD cStreams = 0;
        if (CComQIPtr<IAMStreamSelect> pSSF = pBF) {
            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) {
                        m_pSSF = pSSF;
                        DeleteMediaType(pmt);
                        break;
                    }
                    DeleteMediaType(pmt);
                }
            }
        }

        if (CComQIPtr<IFileSourceFilter> pFSF = pBF) {
            WCHAR* pszName = nullptr;
            AM_MEDIA_TYPE mt;
            if (SUCCEEDED(pFSF->GetCurFile(&pszName, &mt)) && pszName) {
                fileName = pszName;
                CoTaskMemFree(pszName);

                fileName.Replace('\\', '/');
                CStringW fn = fileName.Mid(fileName.ReverseFind('/') + 1);
                if (!fn.IsEmpty()) {
                    fileName = fn;
                }

                // Haali & LAVFSplitter return only one "Audio" pin name, cause CMainFrame::OnInitMenuPopup lookup find the wrong popmenu,
                // add space at the end to prevent this, internal filter never return "Audio" only.
                if (!pinName.IsEmpty()) {
                    fileName = pinName + L" ";
                }

                WCHAR* pName = DEBUG_NEW WCHAR[fileName.GetLength() + 1];
                if (pName) {
                    wcscpy_s(pName, fileName.GetLength() + 1, fileName);
                    if (m_pName) {
                        delete [] m_pName;
                    }
                    m_pName = pName;
                    if (cStreams == 1) { // Simple external track, no need to use the info from IAMStreamSelect
                        m_pSSF.Release();
                    }
                }
            }

            break;
        }

        pPin = GetFirstPin(pBF);

        pPin = GetUpStreamPin(pBF, pPin);
        if (pPin) {
            pBF = GetFilterFromPin(pPin);
        }
    }

    if (!fForkedSomewhere) {
        m_fCanBlock = true;
    }

    m_hNotifyEvent = nullptr;

    return S_OK;
}
Exemplo n.º 10
0
HRESULT CStreamSwitcherInputPin::CompleteConnect(IPin* pReceivePin)
{
	HRESULT hr = __super::CompleteConnect(pReceivePin);
	if(FAILED(hr)) return hr;

    ((CStreamSwitcherFilter*)m_pFilter)->CompleteConnect(PINDIR_INPUT, this, pReceivePin);

	m_fCanBlock = false;
	bool fForkedSomewhere = false;

	CStringW fileName;
	CStringW pinName;

    IPin* pPin = (IPin*)this;
	IBaseFilter* pBF = (IBaseFilter*)m_pFilter;

	while((pPin = GetUpStreamPin(pBF, pPin)) && (pBF = GetFilterFromPin(pPin)))
	{
		if(IsSplitter(pBF))
		{
			pinName = GetPinName(pPin);
		}

		CLSID clsid = GetCLSID(pBF);
		if(clsid == CLSID_AviSplitter || clsid == CLSID_OggSplitter)
			m_fCanBlock = true;

		int nIn, nOut, nInC, nOutC;
		CountPins(pBF, nIn, nOut, nInC, nOutC);
		fForkedSomewhere = fForkedSomewhere || nIn > 1 || nOut > 1;

		if(CComQIPtr<IFileSourceFilter> pFSF = pBF)
		{
			WCHAR* pszName = NULL;
			AM_MEDIA_TYPE mt;
			if(SUCCEEDED(pFSF->GetCurFile(&pszName, &mt)) && pszName)
			{
				fileName = pszName;
				CoTaskMemFree(pszName);

				fileName.Replace('\\', '/');
				CStringW fn = fileName.Mid(fileName.ReverseFind('/')+1);
				if(!fn.IsEmpty()) fileName = fn;

				if(!pinName.IsEmpty()) fileName += L" / " + pinName;

				WCHAR* pName = new WCHAR[fileName.GetLength()+1];
				if(pName)
				{
					wcscpy(pName, fileName);
					if(m_pName) delete [] m_pName;
					m_pName = pName;
				}
			}

			break;
		}

		pPin = GetFirstPin(pBF);
	}

	if(!fForkedSomewhere)
		m_fCanBlock = true;

	m_hNotifyEvent = NULL;

	return S_OK;
}
Exemplo n.º 11
0
DWORD CStreamDriveThruFilter::ThreadProc()
{
	while(1)
	{
		DWORD cmd = GetRequest();

		switch(cmd)
		{
		default:
		case CMD_EXIT: 
			Reply(S_OK);
			return 0;
		case CMD_STOP:
			Reply(S_OK);
			break;
		case CMD_PAUSE:
			Reply(S_OK);
			break;
		case CMD_RUN:
			Reply(S_OK);

			do
			{
				CComPtr<IAsyncReader> pAsyncReader;
				CComPtr<IStream> pStream;

				if(!m_pInput || !m_pInput->IsConnected() || FAILED(m_pInput->GetAsyncReader(&pAsyncReader))
				|| !m_pOutput || !m_pOutput->IsConnected() || FAILED(m_pOutput->GetStream(&pStream)))
					break;

				LARGE_INTEGER li = {0};
				ULARGE_INTEGER uli = {0};

				if(FAILED(pStream->Seek(li, STREAM_SEEK_SET, NULL))
				|| FAILED(pStream->SetSize(uli)))
					break;

				if(CComQIPtr<IFileSinkFilter2> pFSF = GetFilterFromPin(m_pOutput->GetConnected()))
				{
					pFSF->SetMode(AM_FILE_OVERWRITE);

					LPOLESTR pfn;
					if(SUCCEEDED(pFSF->GetCurFile(&pfn, NULL)))
					{
						pFSF->SetFileName(pfn, NULL);
						CoTaskMemFree(pfn);
					}
				}

				m_position = 0;
				BYTE buff[PACKETSIZE];

				do
				{
					while(!CheckRequest(&cmd))
					{
						CAutoLock csAutoLock(&m_csLock);

						LONGLONG total = 0, available = 0;
						if(FAILED(pAsyncReader->Length(&total, &available)) || m_position >= total)
						{
							cmd = CMD_STOP;
							break;
						}

						LONG size = (LONG)min(PACKETSIZE, total - m_position);
						if(FAILED(pAsyncReader->SyncRead(m_position, size, buff)))
						{
							cmd = CMD_STOP;
							break;
						}

						ULONG written = 0;
						if(FAILED(pStream->Write(buff, (ULONG)size, &written)) || (ULONG)size != written)
						{
							cmd = CMD_STOP;
							break;
						}

						m_position += size;
					}

					if(cmd == CMD_PAUSE)
					{
						Reply(S_OK); // reply to CMD_PAUSE

						while(!CheckRequest(&cmd))
							Sleep(50);

						Reply(S_OK); // reply to something
					}
				}
				while(cmd == CMD_RUN);

				uli.QuadPart = m_position;
				pStream->SetSize(uli);

				if(CComPtr<IPin> pPin = m_pOutput->GetConnected())
					pPin->EndOfStream();
			}
			while(false);

			break;
		}
	}

	return 0;
}
Exemplo n.º 12
0
void CDSMMuxerFilter::MuxHeader(IBitStream* pBS)
{
    CString muxer;
    muxer.Format(_T("DSM Muxer (%s)"), CString(__TIMESTAMP__));

    SetProperty(L"MUXR", CStringW(muxer));
    SetProperty(L"DATE", CStringW(CTime::GetCurrentTime().FormatGmt(_T("%Y-%m-%d %H:%M:%S"))));

    MuxFileInfo(pBS);

    POSITION pos = m_pPins.GetHeadPosition();
    while (pos) {
        CBaseMuxerInputPin* pPin = m_pPins.GetNext(pos);
        const CMediaType& mt = pPin->CurrentMediaType();

        ASSERT((mt.lSampleSize >> 30) == 0); // you don't need >1GB samples, do you?

        MuxPacketHeader(pBS, DSMP_MEDIATYPE, 5 + sizeof(GUID) * 3 + mt.FormatLength());
        pBS->BitWrite(pPin->GetID(), 8);
        pBS->ByteWrite(&mt.majortype, sizeof(mt.majortype));
        pBS->ByteWrite(&mt.subtype, sizeof(mt.subtype));
        pBS->BitWrite(mt.bFixedSizeSamples, 1);
        pBS->BitWrite(mt.bTemporalCompression, 1);
        pBS->BitWrite(mt.lSampleSize, 30);
        pBS->ByteWrite(&mt.formattype, sizeof(mt.formattype));
        pBS->ByteWrite(mt.Format(), mt.FormatLength());

        MuxStreamInfo(pBS, pPin);
    }

    // resources & chapters

    CInterfaceList<IDSMResourceBag> pRBs;
    pRBs.AddTail(this);

    CComQIPtr<IDSMChapterBag> pCB = (IUnknown*)(INonDelegatingUnknown*)this;

    pos = m_pPins.GetHeadPosition();
    while (pos) {
        for (CComPtr<IPin> pPin = m_pPins.GetNext(pos)->GetConnected(); pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin))) {
            if (m_fAutoRes) {
                CComQIPtr<IDSMResourceBag> pPB = GetFilterFromPin(pPin);
                if (pPB && !pRBs.Find(pPB)) {
                    pRBs.AddTail(pPB);
                }
            }

            if (m_fAutoChap) {
                if (!pCB || pCB->ChapGetCount() == 0) {
                    pCB = GetFilterFromPin(pPin);
                }
            }
        }
    }

    // resources

    pos = pRBs.GetHeadPosition();
    while (pos) {
        IDSMResourceBag* pRB = pRBs.GetNext(pos);

        for (DWORD i = 0, j = pRB->ResGetCount(); i < j; i++) {
            CComBSTR name, desc, mime;
            BYTE* pData = NULL;
            DWORD len = 0;
            if (SUCCEEDED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL))) {
                CStringA utf8_name = UTF16To8(name);
                CStringA utf8_desc = UTF16To8(desc);
                CStringA utf8_mime = UTF16To8(mime);

                MuxPacketHeader(pBS, DSMP_RESOURCE,
                                1 +
                                utf8_name.GetLength() + 1 +
                                utf8_desc.GetLength() + 1 +
                                utf8_mime.GetLength() + 1 +
                                len);

                pBS->BitWrite(0, 2);
                pBS->BitWrite(0, 6); // reserved
                pBS->ByteWrite(utf8_name, utf8_name.GetLength() + 1);
                pBS->ByteWrite(utf8_desc, utf8_desc.GetLength() + 1);
                pBS->ByteWrite(utf8_mime, utf8_mime.GetLength() + 1);
                pBS->ByteWrite(pData, len);

                CoTaskMemFree(pData);
            }
        }
    }

    // chapters

    if (pCB) {
        CAtlList<CDSMChapter> chapters;
        REFERENCE_TIME rtPrev = 0;
        int len = 0;

        pCB->ChapSort();

        for (DWORD i = 0; i < pCB->ChapGetCount(); i++) {
            CDSMChapter c;
            CComBSTR name;
            if (SUCCEEDED(pCB->ChapGet(i, &c.rt, &name))) {
                REFERENCE_TIME rtDiff = c.rt - rtPrev;
                rtPrev = c.rt;
                c.rt = rtDiff;
                c.name = name;
                len += 1 + GetByteLength(myabs(c.rt)) + UTF16To8(c.name).GetLength() + 1;
                chapters.AddTail(c);
            }
        }

        if (chapters.GetCount()) {
            MuxPacketHeader(pBS, DSMP_CHAPTERS, len);

            pos = chapters.GetHeadPosition();
            while (pos) {
                CDSMChapter& c = chapters.GetNext(pos);
                CStringA name = UTF16To8(c.name);
                int irt = GetByteLength(myabs(c.rt));
                pBS->BitWrite(c.rt < 0, 1);
                pBS->BitWrite(irt, 3);
                pBS->BitWrite(0, 4);
                pBS->BitWrite(myabs(c.rt), irt << 3);
                pBS->ByteWrite((LPCSTR)name, name.GetLength() + 1);
            }
        }
    }
}
Exemplo n.º 13
0
HRESULT CStreamSwitcherInputPin::CompleteConnect(IPin* pReceivePin)
{
	HRESULT hr = __super::CompleteConnect(pReceivePin);
	if (FAILED(hr)) {
		return hr;
	}

	(static_cast<CStreamSwitcherFilter*>(m_pFilter))->CompleteConnect(PINDIR_INPUT, this, pReceivePin);

	m_fCanBlock = false;
	bool fForkedSomewhere = false;

	CStringW fileName;
	CStringW pinName;

	IPin* pPin = (IPin*)this;
	IBaseFilter* pBF = (IBaseFilter*)m_pFilter;

	pPin = GetUpStreamPin(pBF, pPin);
	if (pPin) {
		pBF = GetFilterFromPin(pPin);
	}
	while (pPin && pBF) {
		if (IsSplitter(pBF)) {
			pinName = GetPinName(pPin);
		}

		CLSID clsid = GetCLSID(pBF);
		if (clsid == CLSID_AviSplitter || clsid == CLSID_OggSplitter) {
			m_fCanBlock = true;
		}

		int nIn, nOut, nInC, nOutC;
		CountPins(pBF, nIn, nOut, nInC, nOutC);
		fForkedSomewhere = fForkedSomewhere || nIn > 1 || nOut > 1;

		if (CComQIPtr<IFileSourceFilter> pFSF = pBF) {
			WCHAR* pszName = NULL;
			AM_MEDIA_TYPE mt;
			if (SUCCEEDED(pFSF->GetCurFile(&pszName, &mt)) && pszName) {
				fileName = pszName;
				CoTaskMemFree(pszName);

				fileName.Replace('\\', '/');
				CStringW fn = fileName.Mid(fileName.ReverseFind('/')+1);
				if (!fn.IsEmpty()) {
					fileName = fn;
				}

				// Haali & LAVFSplitter return only one "Audio" pin name, cause CMainFrame::OnInitMenuPopup lookup find the wrong popmenu,
				// add space at the end to prevent this, internal filter never return "Audio" only.
				if (!pinName.IsEmpty()) {
					fileName = pinName + L" ";
				}

				WCHAR* pName = DNew WCHAR[fileName.GetLength()+1];
				if (pName) {
					wcscpy_s(pName, fileName.GetLength() + 1, fileName);
					if (m_pName) {
						delete [] m_pName;
					}
					m_pName = pName;
				}
			}

			break;
		}

		pPin = GetFirstPin(pBF);

		pPin = GetUpStreamPin(pBF, pPin);
		if (pPin) {
			pBF = GetFilterFromPin(pPin);
		}
	}

	if (!fForkedSomewhere) {
		m_fCanBlock = true;
	}

	m_hNotifyEvent = NULL;

	return S_OK;
}