Esempio n. 1
0
HRESULT MiniPlayer::findPin(IBaseFilter *pFilter, int dir, IPin **pOutPin)
{
	IEnumPins *pEnumPins = NULL;
	IPin *pPin = NULL;
	PIN_INFO pinInfo;
	//FILTER_INFO filterInfo;

	//HRESULT hr = pFilter->QueryFilterInfo(&filterInfo);
	//if(hr == S_OK)
	//{
	//	ctrace(L"%s Pins:\n", filterInfo.achName);
	//}

	HRESULT hr = pFilter->EnumPins(&pEnumPins);
	if(FAILED(hr)) return hr;

	
	while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
	{
		hr = pPin->QueryPinInfo(&pinInfo);
		if(FAILED(hr)) continue;

		if(pinInfo.dir == dir)
		{
			*pOutPin = pPin;
			//ctrace(L"[%s] %s\n", (dir == PINDIR_INPUT)? L"INPUT": L"OUTPUT", pinInfo.achName);
			return S_OK;
		}
	}
	pEnumPins->Release();

	return -1;
}
Esempio n. 2
0
// フィルタから指定メディアのピンを検索する
IPin* DirectShowUtil::GetFilterPin(IBaseFilter *pFilter, const PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType)
{
	IEnumPins *pEnumPins=NULL;
	IPin *pPin;
	IPin *pRetPin=NULL;

	if(pFilter->EnumPins(&pEnumPins)==S_OK ){
		ULONG cFetched;
		while(!pRetPin&&pEnumPins->Next(1,&pPin,&cFetched)==S_OK){
			PIN_INFO stPin;
			if(pPin->QueryPinInfo(&stPin)==S_OK){
				if(stPin.dir==dir){
					if(!pMediaType){
						// 方向さえあっていればOK
						pRetPin=pPin;
						pRetPin->AddRef();
						} else {
						// DirectShowにまかせてピンを検索
						if(pPin->QueryAccept(pMediaType)==S_OK){
							pRetPin=pPin;
							pRetPin->AddRef();
							}
						}
					}
					if(stPin.pFilter) stPin.pFilter->Release();
				}
				pPin->Release();
			}
		pEnumPins->Release();
		}
	return pRetPin;
}
IBaseFilter *DirectShowPlayerService::getConnected(
        IBaseFilter *filter, PIN_DIRECTION direction) const
{
    IBaseFilter *connected = 0;

    IEnumPins *pins = 0;

    if (SUCCEEDED(filter->EnumPins(&pins))) {
        for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
            PIN_DIRECTION dir;
            if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) {
                IPin *peer = 0;
                if (SUCCEEDED(pin->ConnectedTo(&peer))) {
                    PIN_INFO info;

                    if (SUCCEEDED(peer->QueryPinInfo(&info))) {
                        if (connected) {
                            qWarning("DirectShowPlayerService::getConnected: "
                                "Multiple connected filters");
                            connected->Release();
                        }
                        connected = info.pFilter;
                    }
                    peer->Release();
                }
            }
        }
        pins->Release();
    }
    return connected;
}
HRESULT CDShowUtility::GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext)
{
    if (!pFilter || !ppNext)
    {
        return E_POINTER;
    }

    IEnumPins *pEnum = NULL;
    IPin *pPin = 0;
    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }

    while (S_OK == pEnum->Next(1, &pPin, 0))
    {
        // see if this pin matches the specified direction
        PIN_DIRECTION ThisPinDir;
        hr = pPin->QueryDirection(&ThisPinDir);
        if (FAILED(hr))
        {
            // something strange happened 
            hr = E_UNEXPECTED;
            pPin->Release();
            break;
        }

        if (ThisPinDir == Dir)
        {
            // check if the pin is connected to another pin
            IPin *pPinNext = NULL;

            if (SUCCEEDED(hr))
            {
                // get the filter that owns that pin
                PIN_INFO PinInfo;
                hr = pPinNext->QueryPinInfo(&PinInfo);
                pPinNext->Release();
                pEnum->Release();
                if (FAILED(hr) || PinInfo.pFilter == NULL)
                {
                    // Something strange happened 
                    return E_UNEXPECTED;
                }

                // This is the filter we're looking for 
                *ppNext = PinInfo.pFilter;
                return S_OK;
            }
        }

        pPin->Release();
    }
    pEnum->Release();

    return hr;
}
Esempio n. 5
0
HRESULT FindSourceFilter(IFilterGraph* filterGraph,IBaseFilter*& result)
{
	HRESULT hr;
	IEnumFilters *enumFilters;
	hr = filterGraph->EnumFilters(&enumFilters);
	if (FAILED(hr))
	{
		ErrorPrint("Get enum filters error",hr);
		return hr;
	}
	ComReleaser enumFilterReleaser(enumFilters);

	IBaseFilter* filter;
	while (S_OK == enumFilters->Next(1, &filter, NULL))
	{
		ComReleaser filterReleaser(filter);
		IEnumPins *enumPins;
		
		hr = filter->EnumPins(&enumPins);
		if (FAILED(hr))
		{
			ErrorPrint("Get enum pins error",hr);
			return hr;
		}
		ComReleaser enumPinsReleaser(enumPins);

		IPin* pin;
		bool isSourceFilter = true;
		while (S_OK == enumPins->Next(1, &pin, NULL))
		{
			ComReleaser pinReleaser(pin);
			PIN_INFO pinInfo;
			hr = pin->QueryPinInfo(&pinInfo);
			if (FAILED(hr))
			{
				ErrorPrint("Get pin info error",hr);
				continue;
			}
			if (pinInfo.dir == PINDIR_INPUT) //认为没有输入pin的就是source filter,这其实是有些问题的,特别是当捕获(如声卡的音频)的filter有时候有很多输入PIN
			{
				isSourceFilter = false;
				break;
			}
		}

		if (isSourceFilter)
		{
			filter->AddRef(); //存在一个资源管理的释放类,必须增加一个引用,否则会被释放掉
			result = filter;
			return S_OK;
		}
	}

	return E_FAIL;
}
IPin* FindDecoderSubpictureOutputPin(IBaseFilter* pFilter)
{
    IEnumPins* pEnum = NULL;
    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (hr != NOERROR)
        return NULL;

    ULONG ulFound;
    IPin *pPin = NULL;
    hr = E_FAIL;

    while(S_OK == pEnum->Next(1, &pPin, &ulFound))
    {
		PIN_INFO PinInfo;
		//
		// grab this, so we can examine its name field
		//
	    hr = pPin->QueryPinInfo(&PinInfo);
	    if(SUCCEEDED(hr))
		{
			PinInfo.pFilter->Release();
			//
			// check direction
			//
			if (PinInfo.dir == PINDIR_OUTPUT)
			{
				// Make sure its not connected yet and its a video type.
				IPin* dummyPin = NULL;
				hr = pPin->ConnectedTo(&dummyPin);
				SAFE_RELEASE(dummyPin);
				if (hr == VFW_E_NOT_CONNECTED)
				{
					IEnumMediaTypes *mtEnum = NULL;
					pPin->EnumMediaTypes(&mtEnum);
					AM_MEDIA_TYPE *pMT = NULL;
					while (S_OK == mtEnum->Next(1, &pMT, NULL))
					{
						if (pMT->majortype == MEDIATYPE_Video)
						{
							DeleteMediaType(pMT);
							SAFE_RELEASE(mtEnum);
							SAFE_RELEASE(pEnum);
							return pPin;
						}
						DeleteMediaType(pMT);
					}
					SAFE_RELEASE(mtEnum);
				}
			}
		}
        pPin->Release();
    } 
    SAFE_RELEASE(pEnum);
	return NULL;
}
Esempio n. 7
0
// Get the first upstream or downstream filter
HRESULT GetNextFilter(
	IBaseFilter *pFilter, // Pointer to the starting filter
	PIN_DIRECTION Dir,    // Direction to search (upstream or downstream)
	IBaseFilter **ppNext) // Receives a pointer to the next filter.
{
	if (!pFilter || !ppNext) return E_POINTER;

	IEnumPins *pEnum = 0;
	IPin *pPin = 0;
	HRESULT hr = pFilter->EnumPins(&pEnum);
	if (FAILED(hr)) return hr;
	while (S_OK == pEnum->Next(1, &pPin, 0))
	{
		// See if this pin matches the specified direction.
		PIN_DIRECTION ThisPinDir;
		hr = pPin->QueryDirection(&ThisPinDir);
		if (FAILED(hr))
		{
			// Something strange happened.
			hr = E_UNEXPECTED;
			pPin->Release();
			break;
		}
		if (ThisPinDir == Dir)
		{
			// Check if the pin is connected to another pin.
			IPin *pPinNext = 0;
			hr = pPin->ConnectedTo(&pPinNext);
			if (SUCCEEDED(hr))
			{
				// Get the filter that owns that pin.
				PIN_INFO PinInfo;
				hr = pPinNext->QueryPinInfo(&PinInfo);
				pPinNext->Release();
				pPin->Release();
				pEnum->Release();
				if (FAILED(hr) || (PinInfo.pFilter == NULL))
				{
					// Something strange happened.
					return E_UNEXPECTED;
				}
				// This is the filter we're looking for.
				*ppNext = PinInfo.pFilter; // Client must release.
				return S_OK;
			}
		}
		pPin->Release();
	}
	pEnum->Release();
	// Did not find a matching filter.
	return E_FAIL;
}
Esempio n. 8
0
HRESULT CKTVDlg::EnumPinsOnFilter( IBaseFilter *pFilter, PIN_DIRECTION PinDir , int index)
{
    HRESULT r;
    IEnumPins  *pEnum = NULL;
    IPin *pPin = NULL;

    // Verify filter interface
    if (!pFilter)
        return E_NOINTERFACE;

    // Get pin enumerator
    r = pFilter->EnumPins(&pEnum);
    if (FAILED(r))
        return r;

    pEnum->Reset();

    // Enumerate all pins on this filter
    while((r = pEnum->Next(1, &pPin, 0)) == S_OK)
    {
        PIN_DIRECTION PinDirThis;

        r = pPin->QueryDirection(&PinDirThis);
        if (FAILED(r))
        {
            pPin->Release();
            continue;
        }

        // Does the pin's direction match the requested direction?
        if (PinDir == PinDirThis)
        {
            PIN_INFO pininfo={0};

            // Direction matches, so add pin name to listbox
            r = pPin->QueryPinInfo(&pininfo);
            if (SUCCEEDED(r))
            {
                wstring str = pininfo.achName;
                m_captureFilterVec[index].PinVec.push_back(str);
            }

            // The pininfo structure contains a reference to an IBaseFilter,
            // so you must release its reference to prevent resource a leak.
            pininfo.pFilter->Release();
        }
        pPin->Release();
    }
    pEnum->Release();

    return r;
}
Esempio n. 9
0
// Find all the immediate upstream or downstream peers of a filter.
HRESULT GetPeerFilters(
	IBaseFilter *pFilter, // Pointer to the starting filter
	PIN_DIRECTION Dir,    // Direction to search (upstream or downstream)
	CFilterList &FilterList)  // Collect the results in this list.
{
	if (!pFilter) return E_POINTER;

	IEnumPins *pEnum = 0;
	IPin *pPin = 0;
	HRESULT hr = pFilter->EnumPins(&pEnum);
	if (FAILED(hr)) return hr;
	while (S_OK == pEnum->Next(1, &pPin, 0))
	{
		// See if this pin matches the specified direction.
		PIN_DIRECTION ThisPinDir;
		hr = pPin->QueryDirection(&ThisPinDir);
		if (FAILED(hr))
		{
			// Something strange happened.
			hr = E_UNEXPECTED;
			pPin->Release();
			break;
		}
		if (ThisPinDir == Dir)
		{
			// Check if the pin is connected to another pin.
			IPin *pPinNext = 0;
			hr = pPin->ConnectedTo(&pPinNext);
			if (SUCCEEDED(hr))
			{
				// Get the filter that owns that pin.
				PIN_INFO PinInfo;
				hr = pPinNext->QueryPinInfo(&PinInfo);
				pPinNext->Release();
				if (FAILED(hr) || (PinInfo.pFilter == NULL))
				{
					// Something strange happened.
					pPin->Release();
					pEnum->Release();
					return E_UNEXPECTED;
				}
				// Insert the filter into the list.
				AddFilterUnique(FilterList, PinInfo.pFilter);
				PinInfo.pFilter->Release();
			}
		}
		pPin->Release();
	}
	pEnum->Release();
	return S_OK;
}
Esempio n. 10
0
// Tear down everything downstream of a given filter
void __fastcall NukeDownstream(IBaseFilter * pf, IGraphBuilder * pGB)
{
			IPin *pP = 0;
			IPin *pTo = 0;
			ULONG u;
			IEnumPins *pins = NULL;
			PIN_INFO pininfo;

			if (!pf)
				return;

			// Enumerate all filter pins
			HRESULT hr = pf->EnumPins(&pins);
			// Go to beginning of enumeration
			pins->Reset();

			while(hr == NOERROR)
			{
				hr = pins->Next(1, &pP, &u);
				if(hr == S_OK && pP)
				{
					pP->ConnectedTo(&pTo);
					if(pTo)
					{
						hr = pTo->QueryPinInfo(&pininfo);
						if(hr == NOERROR)
						{
							if(pininfo.dir == PINDIR_INPUT)
							{
								NukeDownstream(pininfo.pFilter, pGB);
								pGB->Disconnect(pTo);
								pGB->Disconnect(pP);
								pGB->RemoveFilter(pininfo.pFilter);
							}
							pininfo.pFilter->Release();
							pininfo.pFilter = NULL;
						}
						pTo->Release();
						pTo = NULL;
					}
					pP->Release();
					pP = NULL;
				}
			}
			if(pins)
			{
				pins->Release();
				pins = NULL;
			}
}
Esempio n. 11
0
HRESULT TffdshowDecAudioInputPin::CompleteConnect(IPin* pReceivePin)
{
    HRESULT hr = __super::CompleteConnect(pReceivePin);
    if (FAILED(hr)) {
        return hr;
    }
    m_hNotifyEvent = NULL;

    // Some source filters are not multithreaded, in that case we must not use the blocking mode
    unsigned int numstreams = filter->inpins.getNumConnectedInpins();
    bool noBlock = false;
    for (unsigned int i = 0; i < numstreams; i++) {
        TffdshowDecAudioInputPin *inpin = filter->inpins[i];
        if (noBlock) {
            inpin->m_useBlock = false;
            continue;
        }

        IPin *pPin = NULL;
        inpin->ConnectedTo(&pPin);
        if (!pPin) {
            continue;
        }
        PIN_INFO pinInfo;
        if (SUCCEEDED(pPin->QueryPinInfo(&pinInfo))) {
            CLSID clsid;
            if (pinInfo.pFilter && SUCCEEDED(pinInfo.pFilter->GetClassID(&clsid))) {
                if (clsid == CLSID_AviSplitter || clsid == CLSID_MPC_OggSplitter || clsid == CLSID_MPC_AC3DTSSourceFilter) {
                    DPRINTF(_l("TffdshowDecAudioInputPin::CompleteConnect Use blocking mode on pin %u"), this);
                    m_useBlock = true;
                }
                /* Damm it, Haali is monothreaded (all pins are managed in the same thread), so we cannot use the blocking mode
                   even if another source filter needs it (DTS/AC3 source filter).
                   This is annoying because we can't use Haali with an external AC3/DTS file (albain) */
                else if (clsid == CLSID_HaaliMediaSplitter) {
                    DPRINTF(_l("TffdshowDecAudioInputPin::CompleteConnect Disable all blocking modes, source filter is monothreaded on pin %u"), this);
                    noBlock = true;
                    i = 0;
                }
            }
            SAFE_RELEASE(pPin);
            SAFE_RELEASE(pinInfo.pFilter);
        }
    }



    return S_OK;
}
Esempio n. 12
0
BOOL GetConnectedFilter(IBaseFilter* pFilter, PIN_DIRECTION pinDir, IBaseFilter** ppFilterConnected)
{
	if(!pFilter || !ppFilterConnected)
		return FALSE;

	IEnumPins* pEnumPin = NULL;
	if(FAILED(pFilter->EnumPins(&pEnumPin)))
		return FALSE;

	HRESULT hr = E_FAIL;
	IPin* pPin = NULL;
	while(S_OK == pEnumPin->Next(1,&pPin,NULL))
	{
		PIN_DIRECTION pinDirThis;
		hr = pPin->QueryDirection(&pinDirThis);
		if(FAILED(hr))
		{
			pPin->Release();
			pEnumPin->Release();
			return FALSE;
		}

		if(pinDirThis == pinDir)
		{
			IPin* pPinConnected;
			hr = pPin->ConnectedTo(&pPinConnected);
			if(SUCCEEDED(hr))
			{
				PIN_INFO pinInfo;
				hr = pPinConnected->QueryPinInfo(&pinInfo);
				pPinConnected->Release();
				pPin->Release();
				pEnumPin->Release();
				if(FAILED(hr) || pinInfo.pFilter == NULL)
				{
					return FALSE;
				}
				*ppFilterConnected = pinInfo.pFilter;
				return TRUE;
			}
		}

		pPin->Release();
	}
	
	pEnumPin->Release();

	return FALSE;
}
Esempio n. 13
0
static IPin* ds_get_pin(IBaseFilter* filter, const char* pin_name) {
    com_t<IEnumPins> enum_pins;
    IPin* pin = null;		
    if_failed_return(filter->EnumPins(&enum_pins), null);
    while (enum_pins->Next(1, &pin, 0) == S_OK) {
        PIN_INFO pin_info = {0};
        pin->QueryPinInfo(&pin_info);
        com_release(pin_info.pFilter);
        if (stricmp(pin_name, wcs2str(pin_info.achName)) == 0) {
            return pin;
        }
        com_release(pin);
    }
    return null;
}
Esempio n. 14
0
HRESULT FindConnectedFilter(
    IBaseFilter *pSrc,          // Pointer to the starting filter
    PIN_DIRECTION PinDir,       // Directtion to look (input = upstream, output = downstream)
    IBaseFilter **ppConnected)  // Returns a pointer to the filter that is connected to pSrc
{
	if (!pSrc || !ppConnected) return E_FAIL;

	*ppConnected = NULL;

    IEnumPins *pEnum = 0;
    IPin *pPin = 0;
    HRESULT hr = pSrc->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    while (pEnum->Next(1, &pPin, NULL) == S_OK)
    {
        PIN_DIRECTION ThisPinDir;
        pPin->QueryDirection(&ThisPinDir);
        if (ThisPinDir == PinDir)
        {
            IPin *pTmp = 0;
            hr = pPin->ConnectedTo(&pTmp);
            if (SUCCEEDED(hr) && pTmp)  
            {
				// Return the filter that owns this pin.
				PIN_INFO PinInfo;
				pTmp->QueryPinInfo(&PinInfo);
				pTmp->Release();
				pEnum->Release();
				if (PinInfo.pFilter == NULL)
				{
					// Inconsistent pin state. Something is wrong...
					return E_UNEXPECTED;
				}
				else
				{
					*ppConnected = PinInfo.pFilter;
					return S_OK;
				}
            }
        }
        pPin->Release();
    }
    pEnum->Release();
    return E_FAIL;
}
Esempio n. 15
0
HRESULT GetNextFilter(IBaseFilter* filter, PIN_DIRECTION dir, IBaseFilter*& nextFilter)
{
	IEnumPins *enumPins;
	IPin* pin;
	HRESULT hr;

	hr = filter->EnumPins(&enumPins);
	if(FAILED(hr))
	{
		ErrorPrint("Get enum pins error", hr);
		return hr;
	}
	ComReleaser enumPinsReleaser(enumPins);

	while (enumPins->Next(1, &pin, NULL) == S_OK)
	{
		ComReleaser pinReleaser(pin);
		PIN_DIRECTION thisDir;
		hr = pin->QueryDirection(&thisDir);
		if(FAILED(hr))
		{
			ErrorPrint("Query direction error", hr);
			return hr;
		}
		if(thisDir == dir)
		{
			IPin *nextPin;
			hr = pin->ConnectedTo(&nextPin);
			if(SUCCEEDED(hr))
			{
				ComReleaser nextPinReleaser(nextPin);
				PIN_INFO nextPinInfo;
				hr = nextPin->QueryPinInfo(&nextPinInfo);
				if(SUCCEEDED(hr))
				{
					nextFilter = nextPinInfo.pFilter;
					return S_OK;
				}
				else
				{
					return E_UNEXPECTED;
				}
			}
		}
	}
	return E_FAIL;
}
Esempio n. 16
0
HRESULT MiniPlayer::findPin(IBaseFilter *pFilter, int dir, const GUID &mediaMajorType, IPin **pOutPin)
{
	IEnumPins *pEnumPins = NULL;
	IEnumMediaTypes *pEnumMediaTypes = NULL;
	IPin *pPin = NULL;
	PIN_INFO pinInfo;
	//FILTER_INFO filterInfo;
	AM_MEDIA_TYPE *pMediaType = NULL;

	//HRESULT hr = pFilter->QueryFilterInfo(&filterInfo);
	//if(hr == S_OK)
	//{
	//	ctrace(L"%s Pins:\n", filterInfo.achName);
	//}

	HRESULT hr = pFilter->EnumPins(&pEnumPins);
	if(FAILED(hr)) return hr;

	
	while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
	{
		hr = pPin->QueryPinInfo(&pinInfo);
		if(FAILED(hr)) continue;

		if(pinInfo.dir == dir)
		{
			hr = pPin->EnumMediaTypes(&pEnumMediaTypes);
			if(FAILED(hr))continue;

			while(pEnumMediaTypes->Next(1, &pMediaType, NULL) == S_OK)
			{
				if(pMediaType->majortype == mediaMajorType)
				{
					*pOutPin = pPin;
					return S_OK;
				}
			}
			pEnumMediaTypes->Release();
		}
	}

	pEnumPins->Release();

	return -1;
}
Esempio n. 17
0
// Tear down everything upstream of a given filter
void NukeUpstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) 
{
	if (inGraph && inFilter)
	{
		IEnumPins * pinEnum = 0;
		if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
		{
			pinEnum->Reset();
			IPin * pin = 0;
			ULONG cFetched = 0;
			bool pass = true;
			while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched)))
			{
				if (pin && cFetched)
				{
					IPin * connectedPin = 0;
					pin->ConnectedTo(&connectedPin);
					if(connectedPin) 
					{
						PIN_INFO pininfo;
						if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo)))
						{
							if(pininfo.dir == PINDIR_OUTPUT) 
							{
								NukeUpstream(inGraph, pininfo.pFilter);
								inGraph->Disconnect(connectedPin);
								inGraph->Disconnect(pin);
								inGraph->RemoveFilter(pininfo.pFilter);
							}
							pininfo.pFilter->Release();
						}
						connectedPin->Release();
					}
					pin->Release();
				}
				else
				{
					pass = false;
				}
			}
			pinEnum->Release();
		}
	}
}
Esempio n. 18
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;
}
Esempio n. 19
0
//取设备输出Pin
IPin* CCaptureDevice::GetPin(void)
{
	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 == PINDIR_OUTPUT)
						{
//							pin->AddRef(); //加一引用
							foundPin = pin; //返回PIN
						}
						pinInfo.pFilter->Release();
					}
					pin->Release();
				}
			}
			pinEnum->Release();
		}
	}
//	if (foundPin)
//	{
//		foundPin->Release();
//	}
    return foundPin;
}
Esempio n. 20
0
//-----------------------------------------------------------------------------
// GetPin
// Find the pin of the specified name on the given filter
// This method leaves an outstanding reference on the pin if successful
HRESULT CDSUtils::GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin)
{
	HRESULT hr = S_OK;

	if (pFilter && pName && ppPin)
	{
		CComPtr<IEnumPins> pIEnumPins = NULL;
		hr = pFilter->EnumPins(&pIEnumPins);
		if (SUCCEEDED(hr))
		{
			IPin* pIPin = NULL;
			while (S_OK == pIEnumPins->Next(1, &pIPin, NULL))
			{
				PIN_INFO info = {0};
				hr = pIPin->QueryPinInfo(&info);
				if (SUCCEEDED(hr))
				{
					SAFE_RELEASE(info.pFilter);

					if (0 == wcsncmp(info.achName, pName, wcslen(pName)))
					{
						// matched the pin category
						*ppPin = pIPin;
						break;
					}
				}
				SAFE_RELEASE(pIPin);
			}
		}

		if (NULL == *ppPin)
		{
			// failed to find the named pin
			hr = E_FAIL;
		}
	}
	else
	{
		hr = E_INVALIDARG;
	}

	return hr;
}
Esempio n. 21
0
void MiniPlayer::listAllPins(IBaseFilter *pFilter)
{
	IEnumPins *pEnumPins = NULL;
	IEnumMediaTypes *pEnumMediaTypes = NULL;
	IPin *pPin = NULL;
	PIN_INFO pinInfo;
	FILTER_INFO filterInfo;
	AM_MEDIA_TYPE *pMediaType = NULL;

	HRESULT hr = pFilter->QueryFilterInfo(&filterInfo);
	if(hr == S_OK)
	{
		ctrace(L"%s Pins:\n", filterInfo.achName);
	}

	hr = pFilter->EnumPins(&pEnumPins);
	if(FAILED(hr)) return;

	while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
	{
		hr = pPin->QueryPinInfo(&pinInfo);
		if(FAILED(hr)) continue;

		ctrace(L"\t [%s] %s: ", (pinInfo.dir == PINDIR_INPUT)? L"INPUT": L"OUTPUT", pinInfo.achName);
		hr = pPin->EnumMediaTypes(&pEnumMediaTypes);
		if(FAILED(hr))continue;

		while(pEnumMediaTypes->Next(1, &pMediaType, NULL) == S_OK)
		{
			if(pMediaType->majortype == MEDIATYPE_Video)
				ctrace("Video ");
			if(pMediaType->majortype == MEDIATYPE_Audio)
				ctrace("Audio ");
		}

		ctrace("\n");
		pEnumMediaTypes->Release();
	}

	pEnumPins->Release();
}
int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const
{
    QVarLengthArray<IBaseFilter *, 16> filters;
    source->AddRef();
    filters.append(source);

    int streamTypes = 0;

    while (!filters.isEmpty()) {
        IEnumPins *pins = 0;
        IBaseFilter *filter = filters[filters.size() - 1];
        filters.removeLast();

        if (SUCCEEDED(filter->EnumPins(&pins))) {
            for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
                PIN_DIRECTION direction;
                if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) {
                    AM_MEDIA_TYPE connectionType;
                    if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) {
                        IPin *peer = 0;

                        if (connectionType.majortype == MEDIATYPE_Audio) {
                            streamTypes |= AudioStream;
                        } else if (connectionType.majortype == MEDIATYPE_Video) {
                            streamTypes |= VideoStream;
                        } else if (SUCCEEDED(pin->ConnectedTo(&peer))) {
                            PIN_INFO peerInfo;
                            if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
                                filters.append(peerInfo.pFilter);
                            peer->Release();
                        }
                    } else {
                        streamTypes |= findStreamType(pin);
                    }
                }
            }
        }
        filter->Release();
    }
    return streamTypes;
}
Esempio n. 23
0
void CCaptureDevice::EnumInputList( ENUMINPUTCALLBACK EnumInputCallBack, LPVOID lp )
{
	char pinName[128];
	if (m_pBaseFilter)
	{
		IEnumPins * pinEnum = NULL;
		if ( m_pBaseFilter->EnumPins(&pinEnum) == S_OK )
		{
			pinEnum->Reset();

			BOOL bCancel  = FALSE;
			IPin * pin = NULL;
			ULONG fetchCount = 0;
			while (!bCancel && pinEnum->Next(1, &pin, &fetchCount)==S_OK && fetchCount)
			{
				if (pin)
				{
					PIN_INFO pinInfo;
					if ( pin->QueryPinInfo(&pinInfo)==S_OK )
					{
						pinInfo.pFilter->Release();
						if (pinInfo.dir == PINDIR_INPUT)
						{
							::WideCharToMultiByte(CP_ACP, 0, pinInfo.achName, 
								-1,	pinName, 128, NULL, NULL);
							if( EnumInputCallBack( pinName, pin, lp, bCancel ) != S_OK )
								bCancel = TRUE;
						}
						pin->Release();
						pin = NULL;
					}
				}
				else
				{
					bCancel = FALSE;
				}
			}
			pinEnum->Release();
		}
	}
}
Esempio n. 24
0
CLSID GetConnectedFilterCLSID(CBasePin *pPin)
{
	CLSID clsid = GUID_NULL;

	if (pPin) {
		IPin *pConnectedPin = pPin->GetConnected();

		if (pConnectedPin) {
			PIN_INFO pi;

			if (SUCCEEDED(pConnectedPin->QueryPinInfo(&pi))) {
				if (pi.pFilter) {
					pi.pFilter->GetClassID(&clsid);
					pi.pFilter->Release();
				}
			}
		}
	}

	return clsid;
}
Esempio n. 25
0
HRESULT GetFreePin(IBaseFilter* filter, IPin*& result, PIN_DIRECTION dir)
{
	HRESULT hr = S_OK;
	IEnumPins *enumPins;
	hr = filter->EnumPins(&enumPins);
	if(FAILED(hr))
	{
		ErrorPrint("Enum pins error");
		return hr;
	}
	ComReleaser enumPinsReleaser(enumPins);

	IPin *pin;
	while (S_OK == enumPins->Next(1, &pin, NULL))
	{
		PIN_INFO pinInfo;
		hr = pin->QueryPinInfo(&pinInfo);
		if(FAILED(hr))
		{
			ErrorPrint("Query pin info error");
			pin->Release();
			continue;
		}
		if(pinInfo.dir == dir)
		{
			IPin* connectedPin;
			pin->ConnectedTo(&connectedPin);
			if(connectedPin == NULL)
			{
				result = pin;
				return S_OK;
			}
		}
		pin->Release();

	}

	return E_FAIL;
}
Esempio n. 26
0
    BOOL EnumPins(void)
    {
        IEnumPins *enumpins;
        if (m_pFilter->EnumPins(&enumpins) != S_OK)
            return FALSE;

        enumpins->Reset();

        IPin *pin;
        PIN_INFO pInfo;

        // FIXME: ffdshow has 2 input pins "In" and "In Text"
        // there is not way to check mediatype before connection
        // I think I need a list of pins and then probe for all :(
        while ((m_res = enumpins->Next(1, &pin, NULL)) == S_OK)
        {
            pin->QueryPinInfo(&pInfo);
            /* wprintf(L"Pin: %s - %s\n", pInfo.achName, (pInfo.dir == PINDIR_INPUT) ? L"Input" : L"Output"); */
            if (!m_pInputPin && (pInfo.dir == PINDIR_INPUT))
                m_pInputPin = pin;
            else if (!m_pOutputPin && (pInfo.dir == PINDIR_OUTPUT))
                m_pOutputPin = pin;

            pin->Release();
            m_pFilter->Release();
        }

        enumpins->Release();
        if (!(m_pInputPin && m_pInputPin))
            return FALSE;

        if (m_pInputPin->QueryInterface(IID_IMemInputPin, (LPVOID *) &m_pImp) != S_OK)
            return FALSE;

        return TRUE;
    }
Esempio n. 27
0
HRESULT SetVboxFrequency( JNIEnv *env, DShowCaptureInfo* pCapInfo, ULONG ulFrequency )
{
    HRESULT hr;
    DWORD dwSupported=0;  
    IEnumPins* pEnumPin;
    IPin* pInputPin;
    ULONG ulFetched;
    PIN_INFO infoPin;

	if ( pCapInfo->pBDATuner == NULL )
		return E_FAIL;

	if( ulFrequency == 0 )
	{
		slog( (env,"VOX tuner skips frequency 0\r\n") );
		return S_OK;
	}

    IBaseFilter* pTunerDevice = pCapInfo->pBDATuner; 
    pTunerDevice->EnumPins(&pEnumPin);

    if( SUCCEEDED( hr = pEnumPin->Reset() ) )
    {
		while((hr = pEnumPin->Next( 1, &pInputPin, &ulFetched )) == S_OK)
		{
			pInputPin->QueryPinInfo(&infoPin);
				
			// Release AddRef'd filter, we don't need it
			if( infoPin.pFilter != NULL )
			infoPin.pFilter->Release();

			if(infoPin.dir == PINDIR_INPUT)
			break;
		}

		if(hr != S_OK)
		{
			slog( (env,"Vbox tuner input pin query failed \r\n") );
			return hr;
		}
    }
    else
    {
		slog( (env,"Vbox tuner reset failed \r\n") );
		return E_FAIL;
    }
    
    IKsPropertySet *pKsPropertySet;
    pInputPin->QueryInterface(&pKsPropertySet);
	
    if (!pKsPropertySet)
    {
		slog( (env,"Vbox tuner input pin's QueryInterface failed \r\n") );

		return E_FAIL;
    }
        
    KSPROPERTY_TUNER_MODE_CAPS_S ModeCaps;
    KSPROPERTY_TUNER_FREQUENCY_S Frequency;
    memset(&ModeCaps,0,sizeof(KSPROPERTY_TUNER_MODE_CAPS_S));
    memset(&Frequency,0,sizeof(KSPROPERTY_TUNER_FREQUENCY_S));
    ModeCaps.Mode = AMTUNER_MODE_TV; 

    // Check either the Property is supported or not by the Tuner drivers 

    hr = pKsPropertySet->QuerySupported(PROPSETID_TUNER, 
          KSPROPERTY_TUNER_MODE_CAPS,&dwSupported);
    if(SUCCEEDED(hr) && dwSupported&KSPROPERTY_SUPPORT_GET)
    {
        DWORD cbBytes=0;
        hr = pKsPropertySet->Get(PROPSETID_TUNER,KSPROPERTY_TUNER_MODE_CAPS,
            INSTANCEDATA_OF_PROPERTY_PTR(&ModeCaps),
            INSTANCEDATA_OF_PROPERTY_SIZE(ModeCaps),
            &ModeCaps,
            sizeof(ModeCaps),
            &cbBytes);  
    }
    else
    {
		SAFE_RELEASE(pKsPropertySet);
		slog( (env,"Vbox tuner input pin's not support GET query \r\n") );
        return E_FAIL; 
    }

    Frequency.Frequency=ulFrequency; // in Hz
    if(ModeCaps.Strategy==KS_TUNER_STRATEGY_DRIVER_TUNES)
        Frequency.TuningFlags=KS_TUNER_TUNING_FINE;
    else
        Frequency.TuningFlags=KS_TUNER_TUNING_EXACT;

    // Here the real magic starts
    //if(ulFrequency>=ModeCaps.MinFrequency && ulFrequency<=ModeCaps.MaxFrequency)
    {
        hr = pKsPropertySet->Set(PROPSETID_TUNER,
            KSPROPERTY_TUNER_FREQUENCY,
            INSTANCEDATA_OF_PROPERTY_PTR(&Frequency),
            INSTANCEDATA_OF_PROPERTY_SIZE(Frequency),
            &Frequency,
            sizeof(Frequency));
        if(FAILED(hr))
        {
			slog( (env,"Vbox tuner input pin's set frequency %d failed hr=0x%x\r\n", Frequency.Frequency, hr ) );
			SAFE_RELEASE(pKsPropertySet);
            return E_FAIL; 
        }
    }

  //  else
  //  {
		//slog( (env,"Vbox tuning frequency %d is out of range (%d %d)\r\n", 
		//	          ulFrequency, ModeCaps.MinFrequency, ModeCaps.MaxFrequency ) );
  //      return E_FAIL;
  //  }

	SAFE_RELEASE(pKsPropertySet);
	slog( (env,"Vbox tuner tuning overider frequency %d  successful. \r\n", ulFrequency) );
    return S_OK;
}
HRESULT DirectShowVideoWrapper::ConnectSampleGrabber(void)
{
    HRESULT hr = S_OK;
    TCHAR szErr[MAX_ERROR_TEXT_LEN];
    
    // Register the graph in the Running Object Table (for debug purposes)
    AddGraphToROT(_pGraphBuilder, &dwROT);

    // Create the Sample Grabber which we will use
    // To take each frame for texture generation
    if(_pSampleGrabberFilter == NULL)
    {
        hr = _pSampleGrabberFilter.CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "Could not create SampleGrabberFilter, error: " << szErr << std::endl;
            return hr;
        }
    }

    _pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, reinterpret_cast<void**>(&_pSampleGrabber));

    // We have to set the 24-bit RGB desire here
    // So that the proper conversion filters
    // Are added automatically.
    AM_MEDIA_TYPE desiredType;
    memset(&desiredType, 0, sizeof(desiredType));
    desiredType.majortype = MEDIATYPE_Video;
    //desiredType.subtype = MEDIASUBTYPE_RGB565;
    desiredType.subtype = MEDIASUBTYPE_RGB24;
    //desiredType.subtype = GUID_NULL;
    desiredType.formattype = GUID();
    //desiredType.formattype = FORMAT_VideoInfo;

    _pSampleGrabber->SetMediaType(&desiredType);
    _pSampleGrabber->SetBufferSamples(TRUE);


    // A Null Renderer does not display the video
    // But it allows the Sample Grabber to run
    // And it will keep proper playback timing
    // Unless specified otherwise.
    if(_pVideoRenderer == NULL)
    {
        hr = _pVideoRenderer.CoCreateInstance(CLSID_NullRenderer,   NULL, CLSCTX_INPROC_SERVER);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "Unable to create Null Renderer, error: " << szErr << std::endl;
            return hr;
        }
    }
    
    //Get Input pins to VideoRenderer
    IPin* _VideoRendererIntputPin;
    if (FAILED(hr = _pVideoRenderer->FindPin(L"In", &_VideoRendererIntputPin)))
    {
        AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
        SWARNING << "Could not find VideoRenderer Intput Pin, error: " << szErr << std::endl;
        return hr;
    }

    IBaseFilter* pVidRenderer = NULL;
	hr = FindVideoRenderer(_pGraphBuilder,&pVidRenderer);
    if (FAILED(hr))
    {
        AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
        SWARNING << "error: " << szErr << std::endl;
        return hr;
    }

	if(pVidRenderer)
	{
        SLOG << "Removing default video renderer" << std::endl;
		//get input pin of video renderer
		IPin* ipin;
        hr = GetPin(pVidRenderer, PINDIR_INPUT, 0, &ipin);
		if (FAILED(hr))
		{
			AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
			SWARNING << "Get Vidio Renderer in pin, error: " << szErr << std::endl;
			return hr;
		}
		IPin* opin = NULL;
		//find out who the renderer is connected to and disconnect from them
		hr = ipin->ConnectedTo(&opin);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "error: " << szErr << std::endl;
            return hr;
        }

		//Get the filter of the opin
		PIN_INFO OpinInfo;
		opin->QueryPinInfo(&OpinInfo);
		IBaseFilter* LastFilter(OpinInfo.pFilter);

		FILTER_INFO LastFilterInfo;
		LastFilter->QueryFilterInfo(&LastFilterInfo);
		CLSID LastFilterClassID;
		LastFilter->GetClassID(&LastFilterClassID);
		SLOG << "Last filter name: " << LastFilterInfo.achName 
			<< ", ClassID " << LastFilterClassID.Data1 << "-" << LastFilterClassID.Data2 << "-" << LastFilterClassID.Data3 << "-" << LastFilterClassID.Data4
			 << std::endl;
		LPWSTR *VendorInfo;
		LastFilter->QueryVendorInfo(VendorInfo);
		if(VendorInfo)
		{
			SLOG << "Last filter vendor: " << *VendorInfo << std::endl;
		}
		
		hr = ipin->Disconnect();
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "error: " << szErr << std::endl;
            return hr;
        }
		hr = opin->Disconnect();
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "error: " << szErr << std::endl;
            return hr;
        }

		//SAFE_RELEASE(ipin);

		//remove the default renderer from the graph		
		hr = _pGraphBuilder->RemoveFilter(pVidRenderer);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "error: " << szErr << std::endl;
            return hr;
        }
		//SAFE_RELEASE(pVidRenderer);

		//see if the video renderer was originally connected to 
		//a color space converter
		_pGraphBuilder->FindFilterByName(L"Color Space Converter", &_pCSCFilter);
		if(_pCSCFilter == NULL)
		{
			// Create the Color Space filter
			hr = _pCSCFilter.CoCreateInstance(CLSID_Colour, NULL, CLSCTX_INPROC_SERVER);
			if (FAILED(hr))
			{
				AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				SWARNING << "Could not create Color Space Converter Filter, error: " << szErr << std::endl;
				return hr;
			}

			hr = _pGraphBuilder->AddFilter(_pCSCFilter, L"Color Space Converter");
			if (FAILED(hr))
			{
				AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				SWARNING << "Could not add Color Space Converter Filter, error: " << szErr << std::endl;
				return hr;
			}

			//get the output pin of the last filter
			hr = GetPin(LastFilter, PINDIR_OUTPUT, 0, &opin);
			if (FAILED(hr))
			{
				AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				SWARNING << "Get Last filter out pin, error: " << szErr << std::endl;
				return hr;
			}

			//get the input pin of the Color Space Converter
			hr = GetPin(_pCSCFilter, PINDIR_INPUT, 0, &ipin);
			if (FAILED(hr))
			{
				AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				SWARNING << "Get Color Space Converter In Pin, error: " << szErr << std::endl;
				return hr;
			}

			//connect the filter that was originally connected to the default renderer
			//to the Color Space Converter
			SLOG << "Attaching Color Space Converter Filter. "
				 << opin
				 << " -> " << ipin << std::endl;
			hr = _pGraphBuilder->Connect(opin, ipin);
			if (FAILED(hr))
			{
				AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
				SWARNING << "Could not attach Color Space Converter Filter so it won't be used, error: " << szErr << std::endl;
				//return hr;
			}
			else
			{
				LastFilter = _pCSCFilter;
			}
		}

        hr = _pGraphBuilder->AddFilter(_pSampleGrabberFilter, L"Video Sample Grabber");
        
		//get the input pin of the Sample Grabber
		hr = GetPin(_pSampleGrabberFilter, PINDIR_INPUT, 0, &ipin);
		if (FAILED(hr))
		{
			AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
			SWARNING << "Get Sample Grabber In Pin, error: " << szErr << std::endl;
			return hr;
		}

		//get the output pin of the last filter in the graph
		hr = GetPin(LastFilter, PINDIR_OUTPUT, 0, &opin);
		if (FAILED(hr))
		{
			AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
			SWARNING << "Get Color Space Converter out pin, error: " << szErr << std::endl;
			return hr;
		}

        SLOG << "Attaching video sample grabber filter." << std::endl;
		hr = _pGraphBuilder->Connect(opin, ipin);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "error: " << szErr << std::endl;
            return hr;
        }



		//SAFE_RELEASE(ipin);
		//SAFE_RELEASE(opin);

		//get output pin of sample grabber
		hr = GetPin(_pSampleGrabberFilter, PINDIR_OUTPUT, 0, &opin);
		if (FAILED(hr))
		{
			AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
			SWARNING << "Get Sample Grabber out pin, error: " << szErr << std::endl;
			return hr;
		}
        
		
        SLOG << "Attaching Video Null Renderer." << std::endl;
        hr = _pGraphBuilder->AddFilter(_pVideoRenderer, L"Video Null Renderer");
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "Unable to add Renderer to filter graph, error: " << szErr << std::endl;
            return hr;
        }

		//get input pin of null renderer
		hr = GetPin(_pVideoRenderer, PINDIR_INPUT, 0, &ipin);
		if (FAILED(hr))
		{
			AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
			SWARNING << "Get Null Renderer in pin, error: " << szErr << std::endl;
			return hr;
		}

		//connect them
        SLOG << "Attaching null video renderer." << std::endl;
		hr = _pGraphBuilder->Connect(opin, ipin);
        if (FAILED(hr))
        {
            AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
            SWARNING << "Unable to connect Renderer to sample grabber, error: " << szErr << std::endl;
            return hr;
        }
		//SAFE_RELEASE(ipin);
		//SAFE_RELEASE(opin);
	}

    

    // Just a little trick so that we don't have to know
    // The video resolution when calling this method.
    bool mediaConnected = false;
    AM_MEDIA_TYPE connectedType;
    if (SUCCEEDED(hr = _pSampleGrabber->GetConnectedMediaType(&connectedType)))
    {
        if (connectedType.formattype == FORMAT_VideoInfo)
        {
            VIDEOINFOHEADER* infoHeader = (VIDEOINFOHEADER*)connectedType.pbFormat;
            _VideoWidth = infoHeader->bmiHeader.biWidth;
            _VideoHeight = infoHeader->bmiHeader.biHeight;

            mediaConnected = true;
        }
        else if (connectedType.formattype == FORMAT_VideoInfo2)
        {
            VIDEOINFOHEADER* infoHeader = (VIDEOINFOHEADER*)connectedType.pbFormat;
            _VideoWidth = infoHeader->bmiHeader.biWidth;
            _VideoHeight = infoHeader->bmiHeader.biHeight;

            mediaConnected = true;
        }
        else
        {
            SWARNING << "Unable to get the media type connected to the sample grabber." << std::endl;
        }
        SLOG << "Video Dimensions: " << _VideoWidth << " x " << _VideoHeight << std::endl;
        CoTaskMemFree(connectedType.pbFormat);
    }
    else
    {
        AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
        SWARNING << "Unable to get connected media type, error: " << szErr << std::endl;
        return hr;
    }

    /*if (!mediaConnected)
    {
        uninitVideo();
        return false;
    }*/
    return hr;
}
Esempio n. 29
0
void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel)
{
    if( !pGraph )
    {
        return;
    }

    IEnumFilters *pFilters;

    DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph));

    if (FAILED(pGraph->EnumFilters(&pFilters))) {
	DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!")));
    }

    IBaseFilter *pFilter;
    ULONG	n;
    while (pFilters->Next(1, &pFilter, &n) == S_OK) {
	FILTER_INFO	info;

	if (FAILED(pFilter->QueryFilterInfo(&info))) {
	    DbgLog((LOG_TRACE,dwLevel,TEXT("    Filter [%x]  -- failed QueryFilterInfo"), pFilter));
	} else {
	    QueryFilterInfoReleaseGraph(info);

	    // !!! should QueryVendorInfo here!
	
	    DbgLog((LOG_TRACE,dwLevel,TEXT("    Filter [%x]  '%ls'"), pFilter, info.achName));

	    IEnumPins *pins;

	    if (FAILED(pFilter->EnumPins(&pins))) {
		DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!")));
	    } else {

		IPin *pPin;
		while (pins->Next(1, &pPin, &n) == S_OK) {
		    PIN_INFO	info;

		    if (FAILED(pPin->QueryPinInfo(&info))) {
			DbgLog((LOG_TRACE,dwLevel,TEXT("          Pin [%x]  -- failed QueryPinInfo"), pPin));
		    } else {
			QueryPinInfoReleaseFilter(info);

			IPin *pPinConnected = NULL;

			HRESULT hr = pPin->ConnectedTo(&pPinConnected);

			if (pPinConnected) {
			    DbgLog((LOG_TRACE,dwLevel,TEXT("          Pin [%x]  '%ls' [%sput]")
							   TEXT("  Connected to pin [%x]"),
				    pPin, info.achName,
				    info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"),
				    pPinConnected));

			    pPinConnected->Release();

			    // perhaps we should really dump the type both ways as a sanity
			    // check?
			    if (info.dir == PINDIR_OUTPUT) {
				AM_MEDIA_TYPE mt;

				hr = pPin->ConnectionMediaType(&mt);

				if (SUCCEEDED(hr)) {
				    DisplayType(TEXT("Connection type"), &mt);

				    FreeMediaType(mt);
				}
			    }
			} else {
			    DbgLog((LOG_TRACE,dwLevel,
				    TEXT("          Pin [%x]  '%ls' [%sput]"),
				    pPin, info.achName,
				    info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out")));

			}
		    }

		    pPin->Release();

		}

		pins->Release();
	    }

	}
	
	pFilter->Release();
    }

    pFilters->Release();

}
void DirectShowPlayerService::doRender(QMutexLocker *locker)
{
    m_pendingTasks |= m_executedTasks & (Play | Pause);

    if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
        control->Stop();
        control->Release();
    }

    if (m_pendingTasks & SetAudioOutput) {
        m_graph->AddFilter(m_audioOutput, L"AudioOutput");

        m_pendingTasks ^= SetAudioOutput;
        m_executedTasks |= SetAudioOutput;
    }
    if (m_pendingTasks & SetVideoOutput) {
        m_graph->AddFilter(m_videoOutput, L"VideoOutput");

        m_pendingTasks ^= SetVideoOutput;
        m_executedTasks |= SetVideoOutput;
    }

    IFilterGraph2 *graph = m_graph;
    graph->AddRef();

    QVarLengthArray<IBaseFilter *, 16> filters;
    m_source->AddRef();
    filters.append(m_source);

    bool rendered = false;

    HRESULT renderHr = S_OK;

    while (!filters.isEmpty()) {
        IEnumPins *pins = 0;
        IBaseFilter *filter = filters[filters.size() - 1];
        filters.removeLast();

        if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) {
            int outputs = 0;
            for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
                PIN_DIRECTION direction;
                if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) {
                    ++outputs;

                    IPin *peer = 0;
                    if (pin->ConnectedTo(&peer) == S_OK) {
                        PIN_INFO peerInfo;
                        if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
                            filters.append(peerInfo.pFilter);
                        peer->Release();
                    } else {
                        locker->unlock();
                        HRESULT hr;
                        if (SUCCEEDED(hr = graph->RenderEx(
                                pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, 0))) {
                            rendered = true;
                        } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){
                            renderHr = hr;
                        }
                        locker->relock();
                    }
                }
            }

            pins->Release();

            if (outputs == 0)
                rendered = true;
        }
        filter->Release();
    }

    if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) {
        graph->RemoveFilter(m_audioOutput);

        m_executedTasks &= ~SetAudioOutput;
    }

    if (m_videoOutput && !isConnected(m_videoOutput, PINDIR_INPUT)) {
        graph->RemoveFilter(m_videoOutput);

        m_executedTasks &= ~SetVideoOutput;
    }

    graph->Release();

    if (!(m_pendingTasks & ReleaseFilters)) {
        if (rendered) {
            if (!(m_executedTasks & FinalizeLoad))
                m_pendingTasks |= FinalizeLoad;
        } else {
            m_pendingTasks = 0;

            m_graphStatus = InvalidMedia;

            if (!m_audioOutput && !m_videoOutput) {
                m_error = QMediaPlayer::ResourceError;
                m_errorString = QString();
            } else {
                switch (renderHr) {
                case VFW_E_UNSUPPORTED_AUDIO:
                case VFW_E_UNSUPPORTED_VIDEO:
                case VFW_E_UNSUPPORTED_STREAM:
                    m_error = QMediaPlayer::FormatError;
                    m_errorString = QString();
                    break;
                default:
                    m_error = QMediaPlayer::ResourceError;
                    m_errorString = QString();
                    qWarning("DirectShowPlayerService::doRender: Unresolved error code %x",
                             uint(renderHr));
                }
            }

            QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error)));
        }

        m_executedTasks |= Render;
    }

    m_loop->wake();
}