Пример #1
0
void CBaseMuxerFilter::AddInput()
{
	POSITION pos = m_pInputs.GetHeadPosition();
	while(pos)
	{
		CBasePin* pPin = m_pInputs.GetNext(pos);
		if(!pPin->IsConnected()) return;
	}

	CStringW name;

	name.Format(L"Input %d", m_pInputs.GetCount()+1);

	CBaseMuxerInputPin* pInputPin = NULL;
	if(FAILED(CreateInput(name, &pInputPin)) || !pInputPin) {ASSERT(0); return;}
	CAutoPtr<CBaseMuxerInputPin> pAutoPtrInputPin(pInputPin);

	name.Format(L"~Output %d", m_pRawOutputs.GetCount()+1);

	CBaseMuxerRawOutputPin* pRawOutputPin = NULL;
	if(FAILED(CreateRawOutput(name, &pRawOutputPin)) || !pRawOutputPin) {ASSERT(0); return;}
	CAutoPtr<CBaseMuxerRawOutputPin> pAutoPtrRawOutputPin(pRawOutputPin);

	pInputPin->SetRelatedPin(pRawOutputPin);
	pRawOutputPin->SetRelatedPin(pInputPin);

	m_pInputs.AddTail(pAutoPtrInputPin);
	m_pRawOutputs.AddTail(pAutoPtrRawOutputPin);
}
Пример #2
0
STDMETHODIMP CStreamSwitcherFilter::Info(long lIndex, AM_MEDIA_TYPE** ppmt, DWORD* pdwFlags, LCID* plcid, DWORD* pdwGroup, WCHAR** ppszName, IUnknown** ppObject, IUnknown** ppUnk)
{
	CAutoLock cAutoLock(&m_csPins);

	CBasePin* pPin = GetConnectedInputPin(lIndex);
	if(!pPin) return E_INVALIDARG;

	if(ppmt)
		*ppmt = CreateMediaType(&m_pOutput->CurrentMediaType());

	if(pdwFlags)
		*pdwFlags = (m_pInput == pPin) ? AMSTREAMSELECTINFO_EXCLUSIVE : 0;

	if(plcid)
		*plcid = 0;

	if(pdwGroup)
		*pdwGroup = 0;

	if(ppszName && (*ppszName = (WCHAR*)CoTaskMemAlloc((wcslen(pPin->Name())+1)*sizeof(WCHAR))))
		wcscpy(*ppszName, pPin->Name());

	if(ppObject)
		*ppObject = NULL;

	if(ppUnk)
		*ppUnk = NULL;

	return S_OK;
}
Пример #3
0
///////////////////////////////////////////////////////////
// all inherited virtual functions
///////////////////////////////////////////////////////////
// 1. from CSource
CBasePin *CVCam::GetPin(int n)
{
	vcamLog(50, "CVCam::GetPin, n = %d", n);
	CBasePin *pin = CSource::GetPin(n);
	ASSERT(pin!=NULL);
	if(pin->IsConnected()) {
		vcamLog(50, "  CVCam::GetPin: pin is connected");
	} else {
		vcamLog(50, "  CVCam::GetPin: pin is not connected");
	}
	return pin;
}
Пример #4
0
 // if bSet, only accept settable pins
 SeekingCollection(CBaseFilter* pFilter)
 {
     for (int i = 0; i < pFilter->GetPinCount(); i++)
     {
         CBasePin* pPin = pFilter->GetPin(i);
         PIN_DIRECTION pindir;
         pPin->QueryDirection(&pindir);
         if (pindir == PINDIR_INPUT)
         {
             IMediaSeekingPtr pSeek = pPin->GetConnected();
             if (pSeek != NULL)
             {
                 m_Pins.push_back(pSeek.Detach());
             }
         }
     }
 }
Пример #5
0
HRESULT GetPeer(CStreamSwitcherFilter* pFilter, T** ppT)
{
    *ppT = NULL;

	CBasePin* pPin = pFilter->GetInputPin();
	if(!pPin) return E_NOTIMPL;

    CComPtr<IPin> pConnected;
    if(FAILED(pPin->ConnectedTo(&pConnected))) 
		return E_NOTIMPL;

	if(CComQIPtr<T> pT = pConnected)
	{
		*ppT = pT.Detach();
		return S_OK;
	}

	return E_NOTIMPL;
}
Пример #6
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;
}
DWORD WINAPI PushDataThread(PVOID param)
{
	PushParam* pushParam = (PushParam*)param;
	HANDLE PushSemaphore = pushParam->PushSemaphore;
	HANDLE PushDataMutex = pushParam->PushDataMutex;
	NetReceiveFilter* filter = pushParam->filter;
	std::map<REFERENCE_TIME, IMediaSample*>& SampleList = *pushParam->SampleList;

	delete pushParam;

	REFERENCE_TIME startTime,endTime;
	CRefTime streamTime(LONG(0)),lastStreamTime(LONG(0));

	bool first = true;
	AM_MEDIA_TYPE mediaType;
	IMediaSample* sample ;

	while (SampleList.size() == 0) //等待足够多的数据
	{
		WaitForSingleObject(PushSemaphore,INFINITE);
	}

	CBasePin* pin = filter->GetPin(0);
	pin->ConnectionMediaType(&mediaType);
	IFilterGraph* filterGraph = filter->GetFilterGraph();
	ComReleaser filterGraphReleaser(filterGraph);

	HRESULT hr;
	IMediaControl* mediaControl;
	hr = filterGraph->QueryInterface(IID_IMediaControl, (void**)&mediaControl);
	if(FAILED(hr))
	{
		ErrorPrint("Get media control error", hr);
		return false;
	}
	ComReleaser mediaControlReleaser(mediaControl);

	while (true)
	{
		WaitForSingleObject(PushDataMutex, INFINITE);
		if (filter->getPlayMode() == 0) // 如果只是尽快播放,则不考虑时间戳,而且一次一sample的往下传
		{
			if (SampleList.size() == 0)
			{
				ReleaseMutex(PushDataMutex);
				while (SampleList.size() == 0)
				{
					WaitForSingleObject(PushSemaphore,INFINITE);
				}
				WaitForSingleObject(PushDataMutex, INFINITE);
			}
			sample = SampleList.begin()->second;
		}
		else if (filter->getPlayMode() == 1) //需要考虑时间戳
		{
			NetReceiveFilter::State state = filter->getState();
			if (SampleList.size() == 0)
			{
				g_ReferenceTimeFilter->pauseTime(); //暂停时钟
				ReleaseMutex(PushDataMutex);
				while (SampleList.size() == 0) //等待足够多的数据
				{
					WaitForSingleObject(PushSemaphore,INFINITE);
				}
				WaitForSingleObject(PushDataMutex, INFINITE);
				g_ReferenceTimeFilter->startTime(); //启动时钟

			}

			if (state == NetReceiveFilter::Stopped)
			{
				ReleaseMutex(PushDataMutex);
				Sleep(50);
				continue;
			}

			if(g_ReferenceTimeFilter->isStop())
			{
				ReleaseMutex(PushDataMutex);
				Sleep(50);
				continue;
			}

			sample = SampleList.begin()->second;
			sample->GetTime(&startTime,&endTime);
			filter->StreamTime(streamTime); //得到当前的流时间
			g_ReferenceTimeFilter->GetTime(&startTime);
			g_ReferenceTimeFilter->GetTime(&endTime);

			if (mediaType.majortype == MEDIATYPE_Video)
			{
				int a = 0;
			}
			else
			{
				int b = 0;
			}

			if(state != NetReceiveFilter::Paused) //pause时不修正
			{
				if(startTime - 10000000 > streamTime )
				{
					ReleaseMutex(PushDataMutex);
					Sleep(50);
					continue;
				}
				sample->SetTime(&startTime, &endTime);
			}
			

			if (mediaType.majortype == MEDIATYPE_Video)
			{
				int a = 0;
			}
			else
			{
				int b = 0;
			}

		}
// 		if (mediaType.majortype == MEDIATYPE_Video)
// 		{
// 			std::cout<<"Push video data."<<std::endl;
// 		}
		SampleList.erase(SampleList.begin());
		ReleaseMutex(PushDataMutex);
		if(!filter->PushData(sample))
		{
			ErrorPrint("Push data error");
			sample->Release();
			continue;
		}
		sample->Release();
	}
	return 0;
}
Пример #8
0
STDMETHODIMP
CEnumPins::Next(ULONG cPins,        // place this many pins...
				IPin **ppPins,      // ...in this array
				ULONG *pcFetched)   // actual count passed returned here
{
	CheckPointer(ppPins,E_POINTER);
	ValidateReadWritePtr(ppPins,cPins * sizeof(IPin *));

	ASSERT(ppPins);

	if (pcFetched!=NULL) {
		ValidateWritePtr(pcFetched, sizeof(ULONG));
		*pcFetched = 0;           // default unless we succeed
	}
	// now check that the parameter is valid
	else if (cPins>1) {   // pcFetched == NULL
		return E_INVALIDARG;
	}
	ULONG cFetched = 0;           // increment as we get each one.

	/* Check we are still in sync with the filter */
	if (AreWeOutOfSync() == TRUE) {
		// If we are out of sync, we should refresh the enumerator.
		// This will reset the position and update the other members, but
		// will not clear cache of pins we have already returned.
		Refresh();
	}

	/* Calculate the number of available pins */

	int cRealPins = min(m_PinCount - m_Position, (int) cPins);
	if (cRealPins == 0) {
		return S_FALSE;
	}

	/* Return each pin interface NOTE GetPin returns CBasePin * not addrefed
	so we must QI for the IPin (which increments its reference count)
	If while we are retrieving a pin from the filter an error occurs we
	assume that our internal state is stale with respect to the filter
	(for example someone has deleted a pin) so we
	return VFW_E_ENUM_OUT_OF_SYNC                            */

	while (cRealPins && (m_PinCount - m_Position)) {

		/* Get the next pin object from the filter */

		CBasePin *pPin = m_pFilter->GetPin(m_Position++);
		if (pPin == NULL) {
			// If this happend, and it's not the first time through, then we've got a problem,
			// since we should really go back and release the iPins, which we have previously
			// AddRef'ed.
			ASSERT( cFetched==0 );
			return VFW_E_ENUM_OUT_OF_SYNC;
		}

		/* We only want to return this pin, if it is not in our cache */
		if (0 == m_PinCache.Find(pPin))
		{
			/* From the object get an IPin interface */

			*ppPins = pPin;
			pPin->AddRef();

			cFetched++;
			ppPins++;

			m_PinCache.AddTail(pPin);

			cRealPins--;

		}
	}

	if (pcFetched!=NULL) {
		*pcFetched = cFetched;
	}

	return (cPins==cFetched ? NOERROR : S_FALSE);
}