Exemplo n.º 1
0
PinPtr CaptureDShow::findUnconnectedPin(IBaseFilter *pFilter,
                                        PIN_DIRECTION PinDir) const
{
    IEnumPins *pEnum = NULL;

    if (FAILED(pFilter->EnumPins(&pEnum)))
        return PinPtr();

    PinPtr matchedPin;
    IPin *pPin = NULL;

    while (pEnum->Next(1, &pPin, NULL) == S_OK) {
        PIN_DIRECTION pinDir;

        if (FAILED(pPin->QueryDirection(&pinDir))
            || pinDir != PinDir)
            continue;

        bool ok;
        bool connected = this->isPinConnected(pPin, &ok);

        if (!ok || connected)
            continue;

        matchedPin = PinPtr(pPin, this->deletePin);
        pPin->AddRef();

        break;
    }

    pEnum->Release();

    return matchedPin;
}
Exemplo n.º 2
0
STDMETHODIMP CapturePin::ConnectedTo(IPin **pPin)
{
	PrintFunc(L"CapturePin::ConnectedTo");

	if (!connectedPin)
		return VFW_E_NOT_CONNECTED;

	IPin *pin = connectedPin;
	pin->AddRef();
	*pPin = pin;
	return S_OK;
}
Exemplo n.º 3
0
void DisplayView::OnDumpStream()
{
    if (!current_pin) return ;

    // now create an instance of this filter
    CComPtr<IBaseFilter>	instance;
    HRESULT					hr;

    hr = CoCreateInstance(DSUtil::CLSID_Dump, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&instance);
    if (FAILED(hr)) {
        // try our internal Dump Filter as an alternative
        CMonoDump	*dump = new CMonoDump(NULL, &hr);
        hr = dump->NonDelegatingQueryInterface(IID_IBaseFilter, (void**)&instance);
    }

    if (SUCCEEDED(hr)) {

        // now check for a few interfaces
        int ret = ConfigureInsertedFilter(instance);
        if (ret < 0) {
            instance = NULL;
        }

        if (instance) {

            IPin		*outpin = current_pin->pin;
            outpin->AddRef();

            // add the filter to graph
            hr = graph.AddFilter(instance, _T("Dump"));
            if (FAILED(hr)) {
                // display error message
            } else {
                // connect the pin to the renderer
                hr = DSUtil::ConnectPin(graph.gb, outpin, instance);

                graph.RefreshFilters();
                graph.SmartPlacement();
                graph.Dirty();
                Invalidate();
            }

            outpin->Release();
        }
    }
    instance = NULL;
    current_pin = NULL;
}
Exemplo n.º 4
0
void DisplayView::OnFileWriterStream()
{
    if (!current_pin) return ;

    // now create an instance of this filter
    CComPtr<IBaseFilter>	instance;
    HRESULT					hr;

    hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&instance);
    if (FAILED(hr)) {
        return ;
    }

    if (SUCCEEDED(hr)) {

        // now check for a few interfaces
        int ret = ConfigureInsertedFilter(instance);
        if (ret < 0) {
            instance = NULL;
        }

        if (instance) {

            IPin		*outpin = current_pin->pin;
            outpin->AddRef();

            // add the filter to graph
            hr = graph.AddFilter(instance, _T("File Writer"));
            if (FAILED(hr)) {
                // display error message
            } else {
                // connect the pin to the renderer
                hr = DSUtil::ConnectPin(graph.gb, outpin, instance);

                graph.RefreshFilters();
                graph.SmartPlacement();
                graph.Dirty();
                Invalidate();
            }

            outpin->Release();
        }
    }
    instance = NULL;
    current_pin = NULL;
}
Exemplo n.º 5
0
// IEnumPins
STDMETHODIMP CaptureEnumPins::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched)
{
    UINT nFetched = 0;

    if(curPin == 0 && cPins > 0)
    {
        IPin *pPin = filter->GetCapturePin();
        *ppPins = pPin;
        pPin->AddRef();
        nFetched = 1;
        curPin++;
    }

    if(pcFetched) *pcFetched = nFetched;

    return (nFetched == cPins) ? S_OK : S_FALSE;
}
Exemplo n.º 6
0
//取设备输出Pin
IPin* CGraphBuilder::GetPin(PIN_DIRECTION PinDirection)
{
	IPin * foundPin = NULL;

	if( m_pBaseFilter )
	{
		//创建枚举
		IEnumPins * pinEnum = NULL;
		if ( m_pBaseFilter->EnumPins(&pinEnum)==S_OK )
		{
			//复位
			pinEnum->Reset();

			//循环每个PIN
			ULONG fetchCount = 0;
			IPin * pin = NULL;
			while ( !foundPin && S_OK==(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount )
			{
				if (pin)
				{
					//得到PIN信息
					PIN_INFO pinInfo;
					if ( S_OK==pin->QueryPinInfo(&pinInfo) )
					{
						//检测是否是输出PIN
						if (pinInfo.dir == PinDirection)
						{
							pin->AddRef(); //加一引用
							foundPin = pin; //返回PIN
						}
						pinInfo.pFilter->Release();
					}
					pin->Release();
				}
			}
			pinEnum->Release();
		}
	}
	if (foundPin)
	{
		foundPin->Release();
	}
    return foundPin;
}
Exemplo n.º 7
0
/* IEnumPins */
STDMETHODIMP SampleCaptureEnumPins::Next( ULONG cPins, IPin ** ppPins,
                                    ULONG * pcFetched )
{
#ifdef DEBUG_DSHOW_L1
    ATLTRACE(  "SampleCaptureEnumPins::Next" );
#endif

    unsigned int i_fetched = 0;

    if( i_position < 1 && cPins > 0 )
    {
        IPin *pPin = p_filter->CustomGetPin();
        *ppPins = pPin;
        pPin->AddRef();
        i_fetched = 1;
        i_position++;
    }

    if( pcFetched ) *pcFetched = i_fetched;

    return (i_fetched == cPins) ? S_OK : S_FALSE;
};
Exemplo n.º 8
0
/* Return an AddRef()'d pointer to the connected pin if there is one */
STDMETHODIMP
CBasePin::ConnectedTo(
					  IPin **ppPin
					  )
{
	CheckPointer(ppPin,E_POINTER);
	ValidateReadWritePtr(ppPin,sizeof(IPin *));
	//
	//  It's pointless to lock here.
	//  The caller should ensure integrity.
	//

	IPin *pPin = m_Connected;
	*ppPin = pPin;
	if (pPin != NULL) {
		pPin->AddRef();
		return S_OK;
	} else {
		ASSERT(*ppPin == NULL);
		return VFW_E_NOT_CONNECTED;
	}
}
Exemplo n.º 9
0
void gui::dx::audio_playerX::initialize_speedup_filter() {
	if (speedup_filter_available_valid && !speedup_filter_available) {
		// We don't seem to have the filter. Too bad.
		return;
	}
	// Either the filter exists or we haven't tried yet. Let's try to create
	// it and remember whether it worked.
	IBaseFilter *pNewFilter = NULL;

	HRESULT res;
	res = CoCreateInstance(CLSID_TPBVupp69, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void**)&pNewFilter);

	if (res != S_OK) {
		traceX("dx_audio_player: Speedup filter not available, error 0x%x", res);
		speedup_filter_available = false;
		speedup_filter_available_valid = true;
		return;
	}
	res = m_graph_builder->AddFilter(pNewFilter, NULL);
	if (res != S_OK) {
		traceX("dx_audio_player: AddFilter(Speedup filter): error 0x%x", res);
		pNewFilter->Release();
		return;
	}
	speedup_filter_available = true;
	speedup_filter_available_valid = true;
	//	AM_DBG lib::debugX("dx_audio_player: added speedup filter to graph");

	// Next step: find out where we want to add the filter to the graph.
	// We iterate over the filter graph, then for each item in the graph
	// we iterate over the connected output pins util we find one we like.
	IPin *pOutputPin = NULL;
	IPin *pInputPin = NULL;
	IEnumFilters *pEnumFilters = NULL;
	res = m_graph_builder->EnumFilters(&pEnumFilters);
	if (res != S_OK) {
		traceX("dx_audio_filter: EnumFilters: error 0x%x", res);
		return;
	}

	IBaseFilter *pCurFilter;
	while (pOutputPin == NULL && (res=pEnumFilters->Next(1, &pCurFilter, NULL)) == S_OK) {
		AM_DBG {
			FILTER_INFO info;
			LPWSTR vendorInfo;
			res = pCurFilter->QueryFilterInfo(&info);
			if (res != S_OK) info.achName[0] = 0;
			res = pCurFilter->QueryVendorInfo(&vendorInfo);
			if (res != S_OK) vendorInfo = L"";
			//ambulant::lib::textptr tInfo(info.achName);
			//ambulant::lib::textptr tVendorInfo(vendorInfo);
			//lib::debugX("dx_audio_filter: filter found: '%s' vendor '%s'", tInfo.c_str(), tVendorInfo.c_str());
		}
		IEnumPins *pEnumPins;
		res = pCurFilter->EnumPins(&pEnumPins);
		IPin *pCurPin;
		while (pOutputPin == NULL && (res=pEnumPins->Next(1, &pCurPin, NULL)) == S_OK) {
			AM_MEDIA_TYPE mediaType;
			PIN_DIRECTION curPinDir;
			res = pCurPin->QueryDirection(&curPinDir);
			HRESULT res2 = pCurPin->ConnectionMediaType(&mediaType);
			if (res == S_OK && 
				res2 == S_OK && 
				curPinDir == PINDIR_OUTPUT &&
				mediaType.majortype == MEDIATYPE_Audio&& 
				mediaType.subtype == MEDIASUBTYPE_PCM){
					pOutputPin = pCurPin;
					res = pOutputPin->ConnectedTo(&pInputPin);
					if (res != S_OK) {
						// This output pin was the correct type, but not connected.
						// So it cannot be the one we're looking for.
						pOutputPin = pInputPin = NULL;
					} else {
						// Found it!
						pOutputPin->AddRef();
						pInputPin->AddRef();
					}
				}
				if (res2 == S_OK) {
					if (mediaType.cbFormat != 0) {
						CoTaskMemFree((PVOID)mediaType.pbFormat);
					}
				}
				pCurPin->Release();
		}
		if (res != S_FALSE && res != S_OK) 
			traceX("dx_audio_filter: enumerating pins: error 0x%x", res);
		pEnumPins->Release();
		pCurFilter->Release();
	}
	if (res != S_FALSE && res != S_OK)
		traceX("dx_audio_filter: enumerating filters: error 0x%x", res);

	pEnumFilters->Release();
	// We have the correct pins now.
	if (pOutputPin) {
		traceX("dx_audio_filter: found the right pins!");
	} else {
		traceX("dx_audio_filter: could not find a good pin");
		pOutputPin->Release();
		pInputPin->Release();
		return;
	}
	// Now we need to find the pins on our speedup filter.
	IPin *pFilterInputPin = NULL;
	IPin *pFilterOutputPin = NULL;
	IEnumPins *pEnumPins;
	res = pNewFilter->EnumPins(&pEnumPins);
	IPin *pCurPin;
	while (res=pEnumPins->Next(1, &pCurPin, NULL) == S_OK) {
		PIN_DIRECTION pinDir;
		res = pCurPin->QueryDirection(&pinDir);
		//assert(res == S_OK);
		if (pinDir == PINDIR_INPUT) {
			if (pFilterInputPin) {
				traceX("dx_audio_filter: multiple input pins on filter");
				goto bad;
			}
			pFilterInputPin = pCurPin;
			pFilterInputPin->AddRef();
		} else {
			if (pFilterOutputPin) {
				traceX("dx_audio_filter: multiple output pins on filter");
				goto bad;
			}
			pFilterOutputPin = pCurPin;
			pFilterOutputPin->AddRef();
		}
	}
	if (!pFilterInputPin) {
		traceX("dx_audio_filter: no input pin on filter");
		goto bad;
	}
	if (!pFilterOutputPin) {
		traceX("dx_audio_filter: no output pin on filter");
		goto bad;
	}
	// We have everything. Sever the old connection and insert the filter.
	res = m_graph_builder->Disconnect(pOutputPin);
	if (res) {
		traceX("dx_audio_filter: Severing old connection: error 0x%x", res);
		goto bad;
	}
	res = m_graph_builder->Disconnect(pInputPin);
	if (res) {
		traceX("dx_audio_filter: Severing old connection: error 0x%x", res);
		goto bad;
	}
	res = m_graph_builder->Connect(pOutputPin, pFilterInputPin);
	if (res) {
		traceX("dx_audio_filter: Creating filter input connection: error 0x%x", res);
		goto bad;
	}
	res = m_graph_builder->Connect(pFilterOutputPin, pInputPin);
	if (res) {
		traceX("dx_audio_filter: Creating filter output connection: error 0x%x", res);
		goto bad;
	}
	// Finally remember the interface to set speedup/slowdown, and register ourselves
	// in the global pool (so Amis can change our speed).
	res = pNewFilter->QueryInterface(IID_IVuppInterface, (void**) &m_audio_speedup);
	if (res != S_OK) {
		traceX("dx_audio_filter: filter does not provide IVuppInterface");
		goto bad;
	}
	set_rate(s_current_playback_rate);

bad:
	if (pOutputPin) pOutputPin->Release();
	if (pInputPin) pInputPin->Release();
	if (pFilterOutputPin) pFilterOutputPin->Release();
	if (pFilterInputPin) pFilterInputPin->Release();
	return;

}
HRESULT CFLVConverter::AssembeAudioBranch(const CParameters & param, IPin* pSrc, IPin* pDest)
{
HRESULT hr=S_OK;
IPin* pEndPin = NULL;
AM_MEDIA_TYPE mtSrc;
AM_MEDIA_TYPE *pmtWrp    = NULL;
WE_WAVEFORMATEX* pwfxSrc = NULL;
WE_WAVEFORMATEX* pwfxWrp = NULL;
ULONG ulFetched = 0;
	if(!pSrc || !pDest)
		return E_POINTER;

	m_wfx.wFormatTag      = WAVE_FORMAT_MPEGLAYER3;
	m_wfx.nChannels       = 1;
	m_wfx.nSamplesPerSec  = 11025;
	m_wfx.wBitsPerSample  = 0;
	m_wfx.nBlockAlign     = 1;
	m_wfx.nAvgBytesPerSec = 2500;
	m_wfx.cbSize          = MPEGLAYER3_WFX_EXTRA_BYTES;
	MPEGLAYER3WAVEFORMAT* pMp3Format = (MPEGLAYER3WAVEFORMAT*) &m_wfx;
	pMp3Format->wID             = MPEGLAYER3_ID_MPEG;
	pMp3Format->fdwFlags        = MPEGLAYER3_FLAG_PADDING_ON;//MPEGLAYER3_FLAG_PADDING_OFF;
	pMp3Format->nBlockSize      = 132;
	pMp3Format->nFramesPerBlock = 1;
	pMp3Format->nCodecDelay     = 1393;

	CComPtr<IMediaSeeking> cpMediaSeeking;
	hr = pSrc->QueryInterface(IID_IMediaSeeking, (void **)&cpMediaSeeking);
	if(SUCCEEDED(hr))
	{
		hr = cpMediaSeeking->SetTimeFormat(&TIME_FORMAT_SAMPLE);
		if(SUCCEEDED(hr))
		{
			cpMediaSeeking->GetDuration(&m_llAudioSamplesCount);
		}
	}

	pEndPin = pSrc;
	pEndPin->AddRef();

	CComPtr<IBaseFilter> cpAudioSkipFilter;
	hr = CreateAndInsertFilter(pGB, CLSID_CAudioSkipper, &cpAudioSkipFilter, L"AudioSkipper");
	if(SUCCEEDED(hr))
	{

		hr = JoinFilterToChain(pGB, cpAudioSkipFilter, &pEndPin);

		CComPtr<IAudioSkip> cpAudioSkip;
		hr = cpAudioSkipFilter->QueryInterface(IID_IAudioSkip, (void**) &cpAudioSkip);
		if(SUCCEEDED(hr))
		{
			cpAudioSkip->SetSamplesCount(m_llVideoFramesCount, m_llAudioSamplesCount);
			cpAudioSkip->SetIntervals((void*)param.GetAllDeletedInterval(), (void*)param.GetAudioDeletedInterval());
		}
	}
	if(FAILED(hr))
	{
		SAFE_RELEASE(pEndPin);
		return hr;
	}
	hr = pSrc->ConnectionMediaType(&mtSrc);
	if(SUCCEEDED(hr))
	{
		pwfxSrc = (WE_WAVEFORMATEX*) mtSrc.pbFormat;
		if((pwfxSrc->wFormatTag!=m_wfx.wFormatTag) || (pwfxSrc->nSamplesPerSec!=m_wfx.nSamplesPerSec))
		{
			CComPtr<IBaseFilter> cpAcmWrapper = NULL;
			hr = CoCreateInstance(CLSID_ACMWrapper, NULL, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID *)&cpAcmWrapper);
			if(SUCCEEDED(hr))
			{
				hr = JoinFilterToChain(pGB, cpAcmWrapper, L"ACM Wrapper", &pEndPin);
				if(SUCCEEDED(hr))
				{
					CComPtr<IAMStreamConfig> cpAudioStreamConfig;
					hr = pEndPin->QueryInterface(IID_IAMStreamConfig,(void **)&cpAudioStreamConfig);
					if(SUCCEEDED(hr))
					{
						hr = cpAudioStreamConfig->GetFormat(&pmtWrp);
						if(SUCCEEDED(hr))
						{
							pwfxWrp = (WE_WAVEFORMATEX*) pmtWrp->pbFormat;
							if(WAVE_FORMAT_PCM!=m_wfx.wFormatTag)
							{
								WAVEFORMATEX wfxSrs;
								wfxSrs.nChannels  = m_wfx.nChannels;
								wfxSrs.wFormatTag = WAVE_FORMAT_PCM;
								MMRESULT mmr = acmFormatSuggest(NULL, &m_wfx, &wfxSrs, sizeof(wfxSrs),ACM_FORMATSUGGESTF_NCHANNELS| ACM_FORMATSUGGESTF_WFORMATTAG);
								if(MMSYSERR_NOERROR==mmr)
								{
									pwfxWrp->nChannels       = wfxSrs.nChannels;
									pwfxWrp->nSamplesPerSec  = wfxSrs.nSamplesPerSec;
									pwfxWrp->nAvgBytesPerSec = wfxSrs.nAvgBytesPerSec;
									pwfxWrp->nBlockAlign     = wfxSrs.nBlockAlign;
									pwfxWrp->wBitsPerSample  = wfxSrs.wBitsPerSample;
								}
							}
							else
							{
								pwfxWrp->nChannels       = m_wfx.nChannels;
								pwfxWrp->nSamplesPerSec  = m_wfx.nSamplesPerSec;
								pwfxWrp->nAvgBytesPerSec = m_wfx.nAvgBytesPerSec;
								pwfxWrp->nBlockAlign     = m_wfx.nBlockAlign;
								pwfxWrp->wBitsPerSample  = m_wfx.wBitsPerSample;
							}
							hr = cpAudioStreamConfig->SetFormat(pmtWrp);
							DeleteMediaType(pmtWrp);
						}
					}
				}
			}

			if(WAVE_FORMAT_PCM!=m_wfx.wFormatTag)
			{
				CComPtr<IBaseFilter> cpAComp;
				hr = CreateAudioCompressor(&m_wfx, &cpAComp);
				if(S_OK==hr)
				{
					hr = JoinFilterToChain(pGB, cpAComp, L"Audio compressor", &pEndPin); 
					if(SUCCEEDED(hr))
					{
						CComPtr<IBaseFilter> cpTimeRemover;
						hr = CoCreateInstance(CLSID_CTimeRemover, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&cpTimeRemover);
						if(SUCCEEDED(hr))
						{	//this filter needs as workaround for 0x80040228 error code generated by some
							//audio compressors:
							hr = JoinFilterToChain(pGB, cpTimeRemover, L"TimeStamp remover", &pEndPin); 
						}
					}
				}
			}
		}
	}
	hr = pGB->Connect(pDest, pEndPin);
	FreeMediaType(mtSrc);
	SAFE_RELEASE(pEndPin);
	return hr;
}