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;
}
Exemplo n.º 2
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();

}
Exemplo n.º 3
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;

}
Exemplo n.º 4
0
HRESULT FindRenderer(IGraphBuilder *pGB, const GUID *mediatype, IBaseFilter **ppFilter)
{
    HRESULT hr;
    IEnumFilters *pEnum = NULL;
    IBaseFilter *pFilter = NULL;
    IPin *pPin;
    ULONG ulFetched, ulInPins, ulOutPins;
    BOOL bFound=FALSE;

    // Verify graph builder interface
    if (!pGB)
        return E_NOINTERFACE;

    // Verify that a media type was passed
    if (!mediatype)
        return E_POINTER;

    // Clear the filter pointer in case there is no match
    if (ppFilter)
        *ppFilter = NULL;

    // Get filter enumerator
    hr = pGB->EnumFilters(&pEnum);
    if (FAILED(hr))
        return hr;

    pEnum->Reset();

    // Enumerate all filters in the graph
    while(!bFound && (pEnum->Next(1, &pFilter, &ulFetched) == S_OK))
    {
#ifdef DEBUG
        // Read filter name for debugging purposes
        FILTER_INFO FilterInfo;
        TCHAR szName[256];

        hr = pFilter->QueryFilterInfo(&FilterInfo);
        if (SUCCEEDED(hr))
        {
            // Show filter name in debugger
#ifdef UNICODE
            lstrcpy(szName, FilterInfo.achName);
#else
            WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, 256, 0, 0);
#endif
            FilterInfo.pGraph->Release();
        }
#endif

        // Find a filter with one input and no output pins
        hr = CountFilterPins(pFilter, &ulInPins, &ulOutPins);
        if (FAILED(hr))
            break;

        if ((ulInPins == 1) && (ulOutPins == 0))
        {
            // Get the first pin on the filter
            pPin=0;
            pPin = GetInPin(pFilter, 0);

            // Read this pin's major media type
            AM_MEDIA_TYPE type= {0};
            hr = pPin->ConnectionMediaType(&type);
            if (FAILED(hr))
                break;

            // Is this pin's media type the requested type?
            // If so, then this is the renderer for which we are searching.
            // Copy the interface pointer and return.
            if (type.majortype == *mediatype)
            {
                // Found our filter
                *ppFilter = pFilter;
                bFound = TRUE;;
            }
            // This is not the renderer, so release the interface.
            else
                pFilter->Release();

            // Delete memory allocated by ConnectionMediaType()
            FreeMediaType(type);
        }
        else
        {
            // No match, so release the interface
            pFilter->Release();
        }
    }

    pEnum->Release();
    return hr;
}