コード例 #1
0
ファイル: BaseMuxerInputPin.cpp プロジェクト: AeonAxan/mpc-hc
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;
}
コード例 #2
0
ファイル: StreamSwitcher.cpp プロジェクト: EchoLiao/mpc-hc
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;
}
コード例 #3
0
ファイル: DSMMuxer.cpp プロジェクト: AeonAxan/mpc-hc
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);
            }
        }
    }
}
コード例 #4
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;
}
コード例 #5
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;
}