123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791 |
- #include <windows.h>
- #include <AtlBase.h>
- #include <streams.h>
- #include <strsafe.h>
- #include <qnetwork.h>
- #include <initguid.h> // declares DEFINE_GUID to declare an EXTERN_C const.
- #include "audioswitch.h"
- CAudioSwitchRenderer::CAudioSwitchRenderer(REFCLSID RenderClass,
- TCHAR *pName,
- LPUNKNOWN pUnk,
- HRESULT *phr) :
- CBaseFilter(pName, pUnk, &m_InterfaceLock, RenderClass),
- m_evComplete(TRUE),
- m_bAbort(FALSE),
- m_pPosition(NULL),
- m_ThreadSignal(TRUE),
- m_bStreaming(FALSE),
- m_bEOS(FALSE),
- m_bEOSDelivered(FALSE),
- m_dwAdvise(0),
- m_pQSink(NULL),
- m_bRepaintStatus(TRUE),
- m_SignalTime(0),
- m_bInReceive(FALSE),
- m_EndOfStreamTimer(0),
- m_inputSelected(0)
- {
- for (int i = 0;i < 16;i++) m_pInputPin[i] = NULL;
- for (int i = 0;i < 16;i++) m_pMediaSample[i] = NULL;
- Ready();
- #ifdef PERF
- m_idBaseStamp = MSR_REGISTER("BaseRenderer: sample time stamp");
- m_idBaseRenderTime = MSR_REGISTER("BaseRenderer: draw time (msec)");
- m_idBaseAccuracy = MSR_REGISTER("BaseRenderer: Accuracy (msec)");
- #endif
- }
- CAudioSwitchRenderer::~CAudioSwitchRenderer()
- {
- ASSERT(m_bStreaming == FALSE);
- ASSERT(m_EndOfStreamTimer == 0);
- StopStreaming();
- ClearPendingSample();
-
- if (m_pPosition)
- {
- delete m_pPosition;
- m_pPosition = NULL;
- }
-
- for (int i = 0;i < 16;i++)
- {
- if (m_pInputPin[i])
- {
- delete m_pInputPin[i];
- m_pInputPin[i] = NULL;
- }
- }
-
- ASSERT(m_pQSink == NULL);
- }
- HRESULT CAudioSwitchRenderer::GetMediaPositionInterface(REFIID riid, void **ppv)
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- if (m_pPosition)
- {
- return m_pPosition->NonDelegatingQueryInterface(riid, ppv);
- }
- HRESULT hr = NOERROR;
-
-
-
-
- m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"),
- CBaseFilter::GetOwner(),
- (HRESULT *) & hr,
- GetPin(m_inputSelected));
- if (m_pPosition == NULL)
- {
- return E_OUTOFMEMORY;
- }
- if (FAILED(hr))
- {
- delete m_pPosition;
- m_pPosition = NULL;
- return E_NOINTERFACE;
- }
- return GetMediaPositionInterface(riid, ppv);
- }
- STDMETHODIMP CAudioSwitchRenderer::NonDelegatingQueryInterface(REFIID riid, void **ppv)
- {
-
- if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking)
- {
- return GetMediaPositionInterface(riid, ppv);
- }
- else
- {
- return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
- }
- }
- HRESULT CAudioSwitchRenderer::SourceThreadCanWait(BOOL bCanWait)
- {
- if (bCanWait == TRUE)
- {
- m_ThreadSignal.Reset();
- }
- else
- {
- m_ThreadSignal.Set();
- }
- return NOERROR;
- }
- #ifdef DEBUG
- void CAudioSwitchRenderer::DisplayRendererState()
- {
- DbgLog((LOG_TIMING, 1, TEXT("\nTimed out in WaitForRenderTime")));
-
- BOOL bSignalled = m_ThreadSignal.Check();
- DbgLog((LOG_TIMING, 1, TEXT("Signal sanity check %d"), bSignalled));
-
- DbgLog((LOG_TIMING, 1, TEXT("Filter state %d"), m_State));
- DbgLog((LOG_TIMING, 1, TEXT("Abort flag %d"), m_bAbort));
- DbgLog((LOG_TIMING, 1, TEXT("Streaming flag %d"), m_bStreaming));
- DbgLog((LOG_TIMING, 1, TEXT("Clock advise link %d"), m_dwAdvise));
- DbgLog((LOG_TIMING, 1, TEXT("Current media sample %x"), m_pMediaSample[m_inputSelected]));
- DbgLog((LOG_TIMING, 1, TEXT("EOS signalled %d"), m_bEOS));
- DbgLog((LOG_TIMING, 1, TEXT("EOS delivered %d"), m_bEOSDelivered));
- DbgLog((LOG_TIMING, 1, TEXT("Repaint status %d"), m_bRepaintStatus));
-
- DbgLog((LOG_TIMING, 1, TEXT("End of stream timer %x"), m_EndOfStreamTimer));
- DbgLog((LOG_TIMING, 1, TEXT("Deliver time %s"), CDisp((LONGLONG)m_SignalTime)));
-
- BOOL bFlushing = m_pInputPin[m_inputSelected]->IsFlushing();
- DbgLog((LOG_TIMING, 1, TEXT("Flushing sanity check %d"), bFlushing));
-
- DbgLog((LOG_TIMING, 1, TEXT("Last run time %s"), CDisp((LONGLONG)m_tStart.m_time)));
-
- if (m_pClock == NULL) return ;
-
- CRefTime CurrentTime, StartTime, EndTime;
- m_pClock->GetTime((REFERENCE_TIME*) &CurrentTime);
- CRefTime Offset = CurrentTime - m_tStart;
-
- DbgLog((LOG_TIMING, 1, TEXT("Clock time %s"), CDisp((LONGLONG)CurrentTime.m_time)));
- DbgLog((LOG_TIMING, 1, TEXT("Time difference %dms"), Offset.Millisecs()));
-
- if (m_pMediaSample[m_inputSelected] == NULL) return ;
- m_pMediaSample[m_inputSelected]->GetTime((REFERENCE_TIME*)&StartTime, (REFERENCE_TIME*)&EndTime);
- DbgLog((LOG_TIMING, 1, TEXT("Next sample stream times (Start %d End %d ms)"),
- StartTime.Millisecs(), EndTime.Millisecs()));
-
- CRefTime Wait = (m_tStart + StartTime) - CurrentTime;
- DbgLog((LOG_TIMING, 1, TEXT("Wait required %d ms"), Wait.Millisecs()));
- }
- #endif
- #define RENDER_TIMEOUT 10000
- HRESULT CAudioSwitchRenderer::WaitForRenderTime()
- {
- HANDLE WaitObjects[] = { m_ThreadSignal, m_RenderEvent };
- DWORD Result = WAIT_TIMEOUT;
-
- OnWaitStart();
- while (Result == WAIT_TIMEOUT)
- {
- Result = WaitForMultipleObjects(2, WaitObjects, FALSE, RENDER_TIMEOUT);
- #ifdef DEBUG
- if (Result == WAIT_TIMEOUT) DisplayRendererState();
- #endif
- }
- OnWaitEnd();
-
- if (Result == WAIT_OBJECT_0)
- {
- return VFW_E_STATE_CHANGED;
- }
- SignalTimerFired();
- return NOERROR;
- }
- void CAudioSwitchRenderer::WaitForReceiveToComplete()
- {
- for (;;)
- {
- if (!m_bInReceive)
- {
- break;
- }
- MSG msg;
-
- PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE);
- Sleep(1);
- }
-
-
-
-
- if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE)
- {
-
- PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
- }
- }
- FILTER_STATE CAudioSwitchRenderer::GetRealState()
- {
- return m_State;
- }
- STDMETHODIMP CAudioSwitchRenderer::GetState(DWORD dwMSecs, FILTER_STATE *State)
- {
- CheckPointer(State, E_POINTER);
- if (WaitDispatchingMessages(m_evComplete, dwMSecs) == WAIT_TIMEOUT)
- {
- *State = m_State;
- return VFW_S_STATE_INTERMEDIATE;
- }
- *State = m_State;
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::CompleteStateChange(FILTER_STATE OldState)
- {
-
- if (m_pInputPin[m_inputSelected]->IsConnected() == FALSE)
- {
- Ready();
- return S_OK;
- }
-
- if (IsEndOfStream() == TRUE)
- {
- Ready();
- return S_OK;
- }
-
- if (HaveCurrentSample() == TRUE)
- {
- if (OldState != State_Stopped)
- {
- Ready();
- return S_OK;
- }
- }
- NotReady();
- return S_FALSE;
- }
- STDMETHODIMP CAudioSwitchRenderer::Stop()
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
-
- if (m_State == State_Stopped)
- {
- return NOERROR;
- }
-
- if (m_pInputPin[m_inputSelected]->IsConnected() == FALSE)
- {
- NOTE("Input pin is not connected");
- m_State = State_Stopped;
- return NOERROR;
- }
- CBaseFilter::Stop();
-
-
-
- if (m_pInputPin[m_inputSelected]->Allocator())
- {
- m_pInputPin[m_inputSelected]->Allocator()->Decommit();
- }
-
- SetRepaintStatus(TRUE);
- StopStreaming();
- SourceThreadCanWait(FALSE);
- ResetEndOfStream();
- CancelNotification();
-
- ASSERT(CancelNotification() == S_FALSE);
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
- ASSERT(m_EndOfStreamTimer == 0);
- Ready();
- WaitForReceiveToComplete();
- m_bAbort = FALSE;
- return NOERROR;
- }
- STDMETHODIMP CAudioSwitchRenderer::Pause()
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- FILTER_STATE OldState = m_State;
- ASSERT(m_pInputPin[m_inputSelected]->IsFlushing() == FALSE);
-
- if (m_State == State_Paused)
- {
- return CompleteStateChange(State_Paused);
- }
-
- if (m_pInputPin[m_inputSelected]->IsConnected() == FALSE)
- {
- NOTE("Input pin is not connected");
- m_State = State_Paused;
- return CompleteStateChange(State_Paused);
- }
-
- HRESULT hr = CBaseFilter::Pause();
- if (FAILED(hr))
- {
- NOTE("Pause failed");
- return hr;
- }
-
- SetRepaintStatus(TRUE);
- StopStreaming();
- SourceThreadCanWait(TRUE);
- CancelNotification();
- ResetEndOfStreamTimer();
-
-
-
- if (m_pInputPin[m_inputSelected]->Allocator())
- {
- m_pInputPin[m_inputSelected]->Allocator()->Commit();
- }
-
- ASSERT(CancelNotification() == S_FALSE);
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
- ASSERT(m_EndOfStreamTimer == 0);
- ASSERT(m_pInputPin[m_inputSelected]->IsFlushing() == FALSE);
-
-
-
-
-
- if (OldState == State_Stopped)
- {
- m_bAbort = FALSE;
- ClearPendingSample();
- }
- return CompleteStateChange(OldState);
- }
- STDMETHODIMP CAudioSwitchRenderer::Run(REFERENCE_TIME StartTime)
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- FILTER_STATE OldState = m_State;
-
- if (m_State == State_Running)
- {
- return NOERROR;
- }
-
- if (m_pInputPin[m_inputSelected]->IsConnected() == FALSE)
- {
- NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this);
- m_State = State_Running;
- return NOERROR;
- }
- Ready();
-
- HRESULT hr = CBaseFilter::Run(StartTime);
- if (FAILED(hr))
- {
- NOTE("Run failed");
- return hr;
- }
-
- ASSERT(m_pInputPin[m_inputSelected]->IsFlushing() == FALSE);
- SourceThreadCanWait(TRUE);
- SetRepaintStatus(FALSE);
-
- ASSERT(CancelNotification() == S_FALSE);
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
- ASSERT(m_EndOfStreamTimer == 0);
- ASSERT(m_pInputPin[m_inputSelected]->IsFlushing() == FALSE);
-
-
-
- if (m_pInputPin[m_inputSelected]->Allocator())
- {
- m_pInputPin[m_inputSelected]->Allocator()->Commit();
- }
-
-
-
-
-
- if (OldState == State_Stopped)
- {
- m_bAbort = FALSE;
- ClearPendingSample();
- }
- return StartStreaming();
- }
- int CAudioSwitchRenderer::GetPinCount()
- {
- return 16;
- }
- CBasePin *CAudioSwitchRenderer::GetPin(int n)
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- HRESULT hr = NOERROR;
- ASSERT(n < 16 && n >= 0);
-
- if (n > 16)
- {
- return NULL;
- }
-
- if (m_pInputPin[n] == NULL)
- {
- WCHAR t[256] = {0};
- StringCchPrintfW(t, 256, L"In%d", n);
- m_pInputPin[n] = new CAudioSwitchRendererInputPin(this, &hr, t);
- }
- return m_pInputPin[n];
- }
- STDMETHODIMP CAudioSwitchRenderer::FindPin(LPCWSTR Id, IPin **ppPin)
- {
- CheckPointer(ppPin, E_POINTER);
- int gotit = 0;
- for (int i = 0;i < 16;i++)
- {
- WCHAR t[256] = {0};
- StringCchPrintfW(t, 256, L"In%d", i);
- if (0 == lstrcmpW(Id, t))
- {
- gotit = 1;
- *ppPin = GetPin(i);
- ASSERT(*ppPin);
- (*ppPin)->AddRef();
- }
- }
- if (!gotit)
- {
- *ppPin = NULL;
- return VFW_E_NOT_FOUND;
- }
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::EndOfStream()
- {
-
- if (m_State == State_Stopped)
- {
- return NOERROR;
- }
-
- m_bEOS = TRUE;
- if (m_pMediaSample[m_inputSelected])
- {
- return NOERROR;
- }
-
-
-
- Ready();
-
-
-
- if (m_bStreaming)
- {
- SendEndOfStream();
- }
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::BeginFlush()
- {
-
- if (m_State == State_Paused)
- {
- NotReady();
- }
- SourceThreadCanWait(FALSE);
- CancelNotification();
- ClearPendingSample();
-
- WaitForReceiveToComplete();
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::EndFlush()
- {
-
- if (m_pPosition) m_pPosition->ResetMediaTime();
-
- ASSERT(CancelNotification() == S_FALSE);
- SourceThreadCanWait(TRUE);
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::CompleteConnect(IPin *pReceivePin)
- {
- SetRepaintStatus(TRUE);
- m_bAbort = FALSE;
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::Active()
- {
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::Inactive()
- {
- if (m_pPosition)
- {
- m_pPosition->ResetMediaTime();
- }
-
-
- ClearPendingSample();
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::SetMediaType(const CMediaType *pmt)
- {
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::BreakConnect()
- {
-
- if (m_pQSink)
- {
- m_pQSink->Release();
- m_pQSink = NULL;
- }
-
- int n = 0;
- for (int i = 0;i < 16;i++)
- {
- if (!m_pInputPin[i] || m_pInputPin[i]->IsConnected() == FALSE) { n++; continue; }
-
- if (m_State != State_Stopped && !m_pInputPin[i]->CanReconnectWhenActive())
- {
- return VFW_E_NOT_STOPPED;
- }
- }
- if (n == 16) return S_FALSE;
- SetRepaintStatus(FALSE);
- ResetEndOfStream();
- ClearPendingSample();
- m_bAbort = FALSE;
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::GetSampleTimes(IMediaSample *pMediaSample,
- REFERENCE_TIME *pStartTime,
- REFERENCE_TIME *pEndTime)
- {
- ASSERT(m_dwAdvise == 0);
- ASSERT(pMediaSample);
-
-
-
- if (SUCCEEDED(pMediaSample->GetTime(pStartTime, pEndTime)))
- {
- if (*pEndTime < *pStartTime)
- {
- return VFW_E_START_TIME_AFTER_END;
- }
- }
- else
- {
-
- return S_OK;
- }
-
-
-
- if (m_pClock == NULL)
- {
- return S_OK;
- }
- return ShouldDrawSampleNow(pMediaSample, pStartTime, pEndTime);
- }
- HRESULT CAudioSwitchRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample,
- REFERENCE_TIME *ptrStart,
- REFERENCE_TIME *ptrEnd)
- {
- return S_FALSE;
- }
- void CAudioSwitchRenderer::SignalTimerFired()
- {
- m_dwAdvise = 0;
- }
- HRESULT CAudioSwitchRenderer::CancelNotification()
- {
- ASSERT(m_dwAdvise == 0 || m_pClock);
- DWORD_PTR dwAdvise = m_dwAdvise;
-
- if (m_dwAdvise)
- {
- m_pClock->Unadvise(m_dwAdvise);
- SignalTimerFired();
- ASSERT(m_dwAdvise == 0);
- }
-
- m_RenderEvent.Reset();
- return (dwAdvise ? S_OK : S_FALSE);
- }
- BOOL CAudioSwitchRenderer::ScheduleSample(IMediaSample *pMediaSample)
- {
- REFERENCE_TIME StartSample, EndSample;
-
- if (pMediaSample == NULL)
- {
- return FALSE;
- }
-
-
-
-
- HRESULT hr = GetSampleTimes(pMediaSample, &StartSample, &EndSample);
- if (FAILED(hr))
- {
- return FALSE;
- }
-
-
-
- if (hr == S_OK)
- {
- EXECUTE_ASSERT(SetEvent((HANDLE) m_RenderEvent));
- return TRUE;
- }
- ASSERT(m_dwAdvise == 0);
- ASSERT(m_pClock);
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
-
-
-
-
- hr = m_pClock->AdviseTime(
- (REFERENCE_TIME) m_tStart,
- StartSample,
- (HEVENT)(HANDLE) m_RenderEvent,
- &m_dwAdvise);
- if (SUCCEEDED(hr))
- {
- return TRUE;
- }
-
-
-
- ASSERT(m_dwAdvise == 0);
- return FALSE;
- }
- HRESULT CAudioSwitchRenderer::Render(IMediaSample *pMediaSample)
- {
-
-
-
- if (pMediaSample == NULL)
- {
- return S_FALSE;
- }
-
-
-
- if (m_bStreaming == FALSE)
- {
- return S_FALSE;
- }
-
- OnRenderStart(pMediaSample);
- DoRenderSample(pMediaSample);
- OnRenderEnd(pMediaSample);
- return NOERROR;
- }
- BOOL CAudioSwitchRenderer::HaveCurrentSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- return (m_pMediaSample[m_inputSelected] == NULL ? FALSE : TRUE);
- }
- IMediaSample *CAudioSwitchRenderer::GetCurrentSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- if (m_pMediaSample[m_inputSelected])
- {
- m_pMediaSample[m_inputSelected]->AddRef();
- }
- return m_pMediaSample[m_inputSelected];
- }
- HRESULT CAudioSwitchRenderer::PrepareReceive(IMediaSample *pMediaSample)
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- m_bInReceive = TRUE;
-
- HRESULT hr = m_pInputPin[m_inputSelected]->CBaseInputPin::Receive(pMediaSample);
- if (hr != NOERROR)
- {
- m_bInReceive = FALSE;
- return E_FAIL;
- }
-
-
-
-
-
-
- if (m_pInputPin[m_inputSelected]->SampleProps()->pMediaType)
- {
- m_pInputPin[m_inputSelected]->SetMediaType((CMediaType *)m_pInputPin[m_inputSelected]->SampleProps()->pMediaType);
- }
- CAutoLock cSampleLock(&m_RendererLock);
- ASSERT(IsActive() == TRUE);
- ASSERT(m_pInputPin[m_inputSelected]->IsFlushing() == FALSE);
- ASSERT(m_pInputPin[m_inputSelected]->IsConnected() == TRUE);
- ASSERT(m_pMediaSample[m_inputSelected] == NULL);
-
-
-
- if (m_pMediaSample[m_inputSelected] || m_bEOS || m_bAbort)
- {
- Ready();
- m_bInReceive = FALSE;
- return E_UNEXPECTED;
- }
-
- if (m_pPosition) m_pPosition->RegisterMediaTime(pMediaSample);
-
- if ((m_bStreaming == TRUE) && (ScheduleSample(pMediaSample) == FALSE))
- {
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
- ASSERT(CancelNotification() == S_FALSE);
- m_bInReceive = FALSE;
- return VFW_E_SAMPLE_REJECTED;
- }
-
- m_SignalTime = m_pInputPin[m_inputSelected]->SampleProps()->tStop;
-
-
-
-
-
- m_pMediaSample[m_inputSelected] = pMediaSample;
- m_pMediaSample[m_inputSelected]->AddRef();
- if (m_bStreaming == FALSE)
- {
- SetRepaintStatus(TRUE);
- }
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::Receive(IMediaSample *pSample)
- {
- ASSERT(pSample);
-
- HRESULT hr = PrepareReceive(pSample);
- ASSERT(m_bInReceive == SUCCEEDED(hr));
- if (FAILED(hr))
- {
- if (hr == VFW_E_SAMPLE_REJECTED)
- {
- return NOERROR;
- }
- return hr;
- }
-
-
- if (m_State == State_Paused)
- {
- PrepareRender();
-
- m_bInReceive = FALSE;
- {
-
- CAutoLock cRendererLock(&m_InterfaceLock);
- if (m_State == State_Stopped)
- return NOERROR;
- m_bInReceive = TRUE;
- }
- Ready();
- }
-
-
-
- hr = WaitForRenderTime();
- if (FAILED(hr))
- {
- m_bInReceive = FALSE;
- return NOERROR;
- }
- PrepareRender();
-
-
-
-
- m_bInReceive = FALSE;
-
- CAutoLock cRendererLock(&m_InterfaceLock);
-
-
- if (m_State == State_Stopped)
- return NOERROR;
- CAutoLock cSampleLock(&m_RendererLock);
-
- Render(m_pMediaSample[m_inputSelected]);
- ClearPendingSample();
- SendEndOfStream();
- CancelNotification();
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::ClearPendingSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- for (int i = 0;i < 16;i++)
- {
- if (m_pMediaSample[i])
- {
- m_pMediaSample[i]->Release();
- m_pMediaSample[i] = NULL;
- }
- }
- return NOERROR;
- }
- void CAudioSwitchRenderer::TimerCallback()
- {
-
-
- CAutoLock cRendererLock(&m_RendererLock);
-
- if (m_EndOfStreamTimer)
- {
- m_EndOfStreamTimer = 0;
- SendEndOfStream();
- }
- }
- #define TIMEOUT_DELIVERYWAIT 50
- #define TIMEOUT_RESOLUTION 10
- HRESULT CAudioSwitchRenderer::SendEndOfStream()
- {
- ASSERT(CritCheckIn(&m_RendererLock));
- if (m_bEOS == FALSE || m_bEOSDelivered || m_EndOfStreamTimer)
- {
- return NOERROR;
- }
-
- if (m_pClock == NULL)
- {
- return NotifyEndOfStream();
- }
-
- REFERENCE_TIME Signal = m_tStart + m_SignalTime;
- REFERENCE_TIME CurrentTime;
- m_pClock->GetTime(&CurrentTime);
- LONG Delay = LONG((Signal - CurrentTime) / 10000);
-
- NOTE1("Delay until end of stream delivery %d", Delay);
- NOTE1("Current %s", (LPCTSTR)CDisp((LONGLONG)CurrentTime));
- NOTE1("Signal %s", (LPCTSTR)CDisp((LONGLONG)Signal));
-
- if (Delay < TIMEOUT_DELIVERYWAIT)
- {
- return NotifyEndOfStream();
- }
-
- m_EndOfStreamTimer = timeSetEvent((UINT) Delay,
- TIMEOUT_RESOLUTION,
- EndOfStreamTimer,
- DWORD_PTR(this),
- TIME_ONESHOT);
- if (m_EndOfStreamTimer == 0)
- {
- return NotifyEndOfStream();
- }
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::NotifyEndOfStream()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- ASSERT(m_bEOS == TRUE);
- ASSERT(m_bEOSDelivered == FALSE);
- ASSERT(m_EndOfStreamTimer == 0);
-
- if (m_bStreaming == FALSE)
- {
- ASSERT(m_EndOfStreamTimer == 0);
- return NOERROR;
- }
-
- m_EndOfStreamTimer = 0;
-
-
-
-
- if (m_pPosition) m_pPosition->EOS();
- m_bEOSDelivered = TRUE;
- NOTE("Sending EC_COMPLETE...");
- return NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this);
- }
- HRESULT CAudioSwitchRenderer::ResetEndOfStream()
- {
- ResetEndOfStreamTimer();
- CAutoLock cRendererLock(&m_RendererLock);
- m_bEOS = FALSE;
- m_bEOSDelivered = FALSE;
- m_SignalTime = 0;
- return NOERROR;
- }
- void CAudioSwitchRenderer::ResetEndOfStreamTimer()
- {
- ASSERT(CritCheckOut(&m_RendererLock));
- if (m_EndOfStreamTimer)
- {
- timeKillEvent(m_EndOfStreamTimer);
- m_EndOfStreamTimer = 0;
- }
- }
- HRESULT CAudioSwitchRenderer::StartStreaming()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- if (m_bStreaming == TRUE)
- {
- return NOERROR;
- }
-
- m_bStreaming = TRUE;
- timeBeginPeriod(1);
- OnStartStreaming();
-
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent, 0));
- ASSERT(CancelNotification() == S_FALSE);
-
- if (m_pMediaSample[m_inputSelected] == NULL)
- {
- return SendEndOfStream();
- }
-
- ASSERT(m_pMediaSample[m_inputSelected]);
- if (!ScheduleSample(m_pMediaSample[m_inputSelected]))
- m_RenderEvent.Set();
- return NOERROR;
- }
- HRESULT CAudioSwitchRenderer::StopStreaming()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- m_bEOSDelivered = FALSE;
- if (m_bStreaming == TRUE)
- {
- m_bStreaming = FALSE;
- OnStopStreaming();
- timeEndPeriod(1);
- }
- return NOERROR;
- }
- void CAudioSwitchRenderer::SetRepaintStatus(BOOL bRepaint)
- {
- CAutoLock cSampleLock(&m_RendererLock);
- m_bRepaintStatus = bRepaint;
- }
- void CAudioSwitchRenderer::SendNotifyWindow(IPin *pPin, HWND hwnd)
- {
- IMediaEventSink *pSink;
-
- HRESULT hr = pPin->QueryInterface(IID_IMediaEventSink, (void **) & pSink);
- if (SUCCEEDED(hr))
- {
- pSink->Notify(EC_NOTIFY_WINDOW, LONG_PTR(hwnd), 0);
- pSink->Release();
- }
- NotifyEvent(EC_NOTIFY_WINDOW, LONG_PTR(hwnd), 0);
- }
- #define RLOG(_x_) DbgLog((LOG_TRACE,1,TEXT(_x_)));
- void CAudioSwitchRenderer::SendRepaint()
- {
- CAutoLock cSampleLock(&m_RendererLock);
- ASSERT(m_pInputPin[m_inputSelected]);
-
-
-
-
-
-
- if (m_bAbort == FALSE)
- {
- if (m_pInputPin[m_inputSelected]->IsConnected() == TRUE)
- {
- if (m_pInputPin[m_inputSelected]->IsFlushing() == FALSE)
- {
- if (IsEndOfStream() == FALSE)
- {
- if (m_bRepaintStatus == TRUE)
- {
- for (int i = 0;i < 16;i++)
- {
- IPin *pPin = (IPin *) m_pInputPin[i];
- if (!pPin) continue;
- NotifyEvent(EC_REPAINT, (LONG_PTR) pPin, 0);
- SetRepaintStatus(FALSE);
- RLOG("Sending repaint");
- }
- }
- }
- }
- }
- }
- }
- BOOL CAudioSwitchRenderer::OnDisplayChange()
- {
-
- CAutoLock cSampleLock(&m_RendererLock);
- int n = 0;
- for (int i = 0;i < 16;i++)
- if (!m_pInputPin[i] || m_pInputPin[i]->IsConnected() == FALSE) n++;
- if (n == 16)
- return FALSE;
- RLOG("Notification of EC_DISPLAY_CHANGE");
-
- for (int i = 0;i < 16;i++)
- if (m_pInputPin[i] && m_pInputPin[i]->IsConnected())
- {
- IPin *pPin = (IPin *) m_pInputPin[i];
- m_pInputPin[i]->AddRef();
- NotifyEvent(EC_DISPLAY_CHANGED, (LONG_PTR) pPin, 0);
- SetAbortSignal(TRUE);
- ClearPendingSample();
- m_pInputPin[i]->Release();
- }
- return TRUE;
- }
- void CAudioSwitchRenderer::OnRenderStart(IMediaSample *pMediaSample)
- {
- #ifdef PERF
- REFERENCE_TIME trStart, trEnd;
- pMediaSample->GetTime(&trStart, &trEnd);
- MSR_INTEGER(m_idBaseStamp, (int)trStart);
- m_pClock->GetTime(&m_trRenderStart);
- MSR_INTEGER(0, (int)m_trRenderStart);
- REFERENCE_TIME trStream;
- trStream = m_trRenderStart - m_tStart;
- MSR_INTEGER(0, (int)trStream);
- const int trLate = (int)(trStream - trStart);
- MSR_INTEGER(m_idBaseAccuracy, trLate / 10000);
- #endif
- }
- void CAudioSwitchRenderer::OnRenderEnd(IMediaSample *pMediaSample)
- {
- #ifdef PERF
- REFERENCE_TIME trNow;
- m_pClock->GetTime(&trNow);
- MSR_INTEGER(0, (int)trNow);
- int t = (int)((trNow - m_trRenderStart) / 10000);
- MSR_INTEGER(m_idBaseRenderTime, t);
- #endif
- }
- void CAudioSwitchRenderer::SetSelectedInput(int n)
- {
- if (m_inputSelected == n) return ;
- if (n > 15 || n < 0) return ;
- ClearPendingSample();
- m_inputSelected = n;
- GetSelectedPin()->NotifyMediaType();
- }
- int CAudioSwitchRenderer::GetSelectedInput()
- {
- return m_inputSelected;
- }
- int CAudioSwitchRenderer::GetConnectedInputsCount()
- {
- int n = 0;
- for (int i = 0;i < 16;i++)
- {
- if (m_pInputPin[i] && m_pInputPin[i]->IsConnected()) n++;
- }
- return n;
- }
- CAudioSwitchRendererInputPin::CAudioSwitchRendererInputPin(CAudioSwitchRenderer *pRenderer,
- HRESULT *phr,
- LPCWSTR pPinName) :
- CBaseInputPin(NAME("Renderer pin"),
- pRenderer,
- &pRenderer->m_InterfaceLock,
- (HRESULT *) phr,
- pPinName)
- {
- m_pRenderer = pRenderer;
- ASSERT(m_pRenderer);
- }
- STDMETHODIMP CAudioSwitchRendererInputPin::EndOfStream()
- {
- HRESULT hr = NOERROR;
- if (m_pRenderer->GetSelectedPin() == this)
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
-
- hr = CheckStreaming();
- if (hr != NOERROR)
- {
- return hr;
- }
-
- hr = m_pRenderer->EndOfStream();
- }
- if (SUCCEEDED(hr))
- {
- hr = CBaseInputPin::EndOfStream();
- }
- return hr;
- }
- STDMETHODIMP CAudioSwitchRendererInputPin::BeginFlush()
- {
- if (m_pRenderer->GetSelectedPin() == this)
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- {
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
- CBaseInputPin::BeginFlush();
- m_pRenderer->BeginFlush();
- }
- return m_pRenderer->ResetEndOfStream();
- }
- else return CBaseInputPin::BeginFlush();
- }
- STDMETHODIMP CAudioSwitchRendererInputPin::EndFlush()
- {
- HRESULT hr = NOERROR;
- if (m_pRenderer->GetSelectedPin() == this)
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
- hr = m_pRenderer->EndFlush();
- }
- if (SUCCEEDED(hr))
- {
- hr = CBaseInputPin::EndFlush();
- }
- return hr;
- }
- STDMETHODIMP CAudioSwitchRendererInputPin::Receive(IMediaSample *pSample)
- {
- if (m_pRenderer->GetSelectedPin() != this)
- return NOERROR;
- return m_pRenderer->Receive(pSample);
- }
- HRESULT CAudioSwitchRendererInputPin::BreakConnect()
- {
- if (m_pRenderer->GetSelectedPin() == this)
- {
- HRESULT hr = m_pRenderer->BreakConnect();
- if (FAILED(hr))
- {
- return hr;
- }
- }
- return CBaseInputPin::BreakConnect();
- }
- HRESULT CAudioSwitchRendererInputPin::CompleteConnect(IPin *pReceivePin)
- {
- if (m_pRenderer->GetSelectedPin() == this)
- {
- HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin);
- if (FAILED(hr))
- {
- return hr;
- }
- }
- return CBaseInputPin::CompleteConnect(pReceivePin);
- }
- STDMETHODIMP CAudioSwitchRendererInputPin::QueryId(LPWSTR *Id)
- {
- CheckPointer(Id, E_POINTER);
- *Id = (LPWSTR)CoTaskMemAlloc(8);
- if (*Id == NULL)
- {
- return E_OUTOFMEMORY;
- }
- StringCbCopyW(*Id, 8, m_pName);
- return NOERROR;
- }
- HRESULT CAudioSwitchRendererInputPin::CheckMediaType(const CMediaType *pmt)
- {
- return m_pRenderer->CheckMediaType(pmt);
- }
- HRESULT CAudioSwitchRendererInputPin::Active()
- {
- return m_pRenderer->Active();
- }
- HRESULT CAudioSwitchRendererInputPin::Inactive()
- {
- return m_pRenderer->Inactive();
- }
- HRESULT CAudioSwitchRendererInputPin::SetMediaType(const CMediaType *pmt)
- {
- HRESULT hr = CBaseInputPin::SetMediaType(pmt);
- if (FAILED(hr))
- {
- return hr;
- }
- m_mt = *pmt;
- if (m_pRenderer->GetSelectedPin() != this)
- return NOERROR;
- return m_pRenderer->SetMediaType(pmt);
- }
- HRESULT CAudioSwitchRendererInputPin::NotifyMediaType()
- {
- if (m_pRenderer->GetSelectedPin() != this)
- return NOERROR;
- return m_pRenderer->SetMediaType(&m_mt);
- }
|