123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862 |
- #include <pjmedia-videodev/config.h>
- #if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0
- #include <streams.h> // DirectShow base class definitions
- #include <mmsystem.h> // Needed for definition of timeGetTime
- #include <limits.h> // Standard data type limit definitions
- #include <measure.h> // Used for time critical log functions
- #pragma warning(disable:4355)
- int inline TimeDiff(REFERENCE_TIME rt)
- {
- if (rt < - (50 * UNITS)) {
- return -(50 * UNITS);
- } else
- if (rt > 50 * UNITS) {
- return 50 * UNITS;
- } else return (int)rt;
- }
- CBaseRenderer::CBaseRenderer(REFCLSID RenderClass,
- __in_opt LPCTSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- __inout HRESULT *phr) :
- CBaseFilter(pName,pUnk,&m_InterfaceLock,RenderClass),
- m_evComplete(TRUE, phr),
- m_RenderEvent(FALSE, phr),
- m_bAbort(FALSE),
- m_pPosition(NULL),
- m_ThreadSignal(TRUE, phr),
- m_bStreaming(FALSE),
- m_bEOS(FALSE),
- m_bEOSDelivered(FALSE),
- m_pMediaSample(NULL),
- m_dwAdvise(0),
- m_pQSink(NULL),
- m_pInputPin(NULL),
- m_bRepaintStatus(TRUE),
- m_SignalTime(0),
- m_bInReceive(FALSE),
- m_EndOfStreamTimer(0)
- {
- if (SUCCEEDED(*phr)) {
- Ready();
- #ifdef PERF
- m_idBaseStamp = MSR_REGISTER(TEXT("BaseRenderer: sample time stamp"));
- m_idBaseRenderTime = MSR_REGISTER(TEXT("BaseRenderer: draw time (msec)"));
- m_idBaseAccuracy = MSR_REGISTER(TEXT("BaseRenderer: Accuracy (msec)"));
- #endif
- }
- }
- CBaseRenderer::~CBaseRenderer()
- {
- ASSERT(m_bStreaming == FALSE);
- ASSERT(m_EndOfStreamTimer == 0);
- StopStreaming();
- ClearPendingSample();
-
- if (m_pPosition) {
- delete m_pPosition;
- m_pPosition = NULL;
- }
-
- if (m_pInputPin) {
- delete m_pInputPin;
- m_pInputPin = NULL;
- }
-
- ASSERT(m_pQSink == NULL);
- }
- HRESULT CBaseRenderer::GetMediaPositionInterface(REFIID riid, __deref_out void **ppv)
- {
- CAutoLock cObjectCreationLock(&m_ObjectCreationLock);
- if (m_pPosition) {
- return m_pPosition->NonDelegatingQueryInterface(riid,ppv);
- }
- CBasePin *pPin = GetPin(0);
- if (NULL == pPin) {
- return E_OUTOFMEMORY;
- }
- HRESULT hr = NOERROR;
-
-
-
-
- m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"),
- CBaseFilter::GetOwner(),
- (HRESULT *) &hr,
- pPin);
- if (m_pPosition == NULL) {
- return E_OUTOFMEMORY;
- }
- if (FAILED(hr)) {
- delete m_pPosition;
- m_pPosition = NULL;
- return E_NOINTERFACE;
- }
- return GetMediaPositionInterface(riid,ppv);
- }
- STDMETHODIMP CBaseRenderer::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
- {
-
- if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {
- return GetMediaPositionInterface(riid,ppv);
- } else {
- return CBaseFilter::NonDelegatingQueryInterface(riid,ppv);
- }
- }
- HRESULT CBaseRenderer::SourceThreadCanWait(BOOL bCanWait)
- {
- if (bCanWait == TRUE) {
- m_ThreadSignal.Reset();
- } else {
- m_ThreadSignal.Set();
- }
- return NOERROR;
- }
- #ifdef DEBUG
- void CBaseRenderer::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));
- 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->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 == NULL) return;
- m_pMediaSample->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 CBaseRenderer::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 CBaseRenderer::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 CBaseRenderer::GetRealState() {
- return m_State;
- }
- STDMETHODIMP CBaseRenderer::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 CBaseRenderer::CompleteStateChange(FILTER_STATE OldState)
- {
-
- if (m_pInputPin->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 CBaseRenderer::Stop()
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
-
- if (m_State == State_Stopped) {
- return NOERROR;
- }
-
- if (m_pInputPin->IsConnected() == FALSE) {
- NOTE("Input pin is not connected");
- m_State = State_Stopped;
- return NOERROR;
- }
- CBaseFilter::Stop();
-
-
-
- if (m_pInputPin->Allocator()) {
- m_pInputPin->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 CBaseRenderer::Pause()
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- FILTER_STATE OldState = m_State;
- ASSERT(m_pInputPin->IsFlushing() == FALSE);
-
- if (m_State == State_Paused) {
- return CompleteStateChange(State_Paused);
- }
-
- if (m_pInputPin->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->Allocator()) {
- m_pInputPin->Allocator()->Commit();
- }
-
- ASSERT(CancelNotification() == S_FALSE);
- ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));
- ASSERT(m_EndOfStreamTimer == 0);
- ASSERT(m_pInputPin->IsFlushing() == FALSE);
-
-
-
-
-
- if (OldState == State_Stopped) {
- m_bAbort = FALSE;
- ClearPendingSample();
- }
- return CompleteStateChange(OldState);
- }
- STDMETHODIMP CBaseRenderer::Run(REFERENCE_TIME StartTime)
- {
- CAutoLock cRendererLock(&m_InterfaceLock);
- FILTER_STATE OldState = m_State;
-
- if (m_State == State_Running) {
- return NOERROR;
- }
-
- if (m_pInputPin->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->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->IsFlushing() == FALSE);
-
-
-
- if (m_pInputPin->Allocator()) {
- m_pInputPin->Allocator()->Commit();
- }
-
-
-
-
-
- if (OldState == State_Stopped) {
- m_bAbort = FALSE;
- ClearPendingSample();
- }
- return StartStreaming();
- }
- int CBaseRenderer::GetPinCount()
- {
- if (m_pInputPin == NULL) {
-
- (void)GetPin(0);
- }
- return m_pInputPin != NULL ? 1 : 0;
- }
- CBasePin *CBaseRenderer::GetPin(int n)
- {
- CAutoLock cObjectCreationLock(&m_ObjectCreationLock);
-
- ASSERT(n == 0);
- if (n != 0) {
- return NULL;
- }
-
- if (m_pInputPin == NULL) {
-
-
-
- HRESULT hr = NOERROR;
- m_pInputPin = new CRendererInputPin(this,&hr,L"In");
- if (NULL == m_pInputPin) {
- return NULL;
- }
- if (FAILED(hr)) {
- delete m_pInputPin;
- m_pInputPin = NULL;
- return NULL;
- }
- }
- return m_pInputPin;
- }
- STDMETHODIMP CBaseRenderer::FindPin(LPCWSTR Id, __deref_out IPin **ppPin)
- {
- CheckPointer(ppPin,E_POINTER);
- if (0==lstrcmpW(Id,L"In")) {
- *ppPin = GetPin(0);
- if (*ppPin) {
- (*ppPin)->AddRef();
- } else {
- return E_OUTOFMEMORY;
- }
- } else {
- *ppPin = NULL;
- return VFW_E_NOT_FOUND;
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::EndOfStream()
- {
-
- if (m_State == State_Stopped) {
- return NOERROR;
- }
-
- m_bEOS = TRUE;
- if (m_pMediaSample) {
- return NOERROR;
- }
-
-
-
- Ready();
-
-
-
- if (m_bStreaming) {
- SendEndOfStream();
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::BeginFlush()
- {
-
- if (m_State == State_Paused) {
- NotReady();
- }
- SourceThreadCanWait(FALSE);
- CancelNotification();
- ClearPendingSample();
-
- WaitForReceiveToComplete();
- return NOERROR;
- }
- HRESULT CBaseRenderer::EndFlush()
- {
-
- if (m_pPosition) m_pPosition->ResetMediaTime();
-
- ASSERT(CancelNotification() == S_FALSE);
- SourceThreadCanWait(TRUE);
- return NOERROR;
- }
- HRESULT CBaseRenderer::CompleteConnect(IPin *pReceivePin)
- {
-
-
- ASSERT(CritCheckIn(&m_InterfaceLock));
- m_bAbort = FALSE;
- if (State_Running == GetRealState()) {
- HRESULT hr = StartStreaming();
- if (FAILED(hr)) {
- return hr;
- }
- SetRepaintStatus(FALSE);
- } else {
- SetRepaintStatus(TRUE);
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::Active()
- {
- return NOERROR;
- }
- HRESULT CBaseRenderer::Inactive()
- {
- if (m_pPosition) {
- m_pPosition->ResetMediaTime();
- }
-
-
- ClearPendingSample();
- return NOERROR;
- }
- HRESULT CBaseRenderer::SetMediaType(const CMediaType *pmt)
- {
- return NOERROR;
- }
- HRESULT CBaseRenderer::BreakConnect()
- {
-
- if (m_pQSink) {
- m_pQSink->Release();
- m_pQSink = NULL;
- }
-
- if (m_pInputPin->IsConnected() == FALSE) {
- return S_FALSE;
- }
-
- if (m_State != State_Stopped && !m_pInputPin->CanReconnectWhenActive()) {
- return VFW_E_NOT_STOPPED;
- }
- SetRepaintStatus(FALSE);
- ResetEndOfStream();
- ClearPendingSample();
- m_bAbort = FALSE;
- if (State_Running == m_State) {
- StopStreaming();
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::GetSampleTimes(IMediaSample *pMediaSample,
- __out REFERENCE_TIME *pStartTime,
- __out 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 CBaseRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample,
- __out REFERENCE_TIME *ptrStart,
- __out REFERENCE_TIME *ptrEnd)
- {
- return S_FALSE;
- }
- void CBaseRenderer::SignalTimerFired()
- {
- m_dwAdvise = 0;
- }
- HRESULT CBaseRenderer::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 CBaseRenderer::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 CBaseRenderer::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 CBaseRenderer::HaveCurrentSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- return (m_pMediaSample == NULL ? FALSE : TRUE);
- }
- IMediaSample *CBaseRenderer::GetCurrentSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- if (m_pMediaSample) {
- m_pMediaSample->AddRef();
- }
- return m_pMediaSample;
- }
- HRESULT CBaseRenderer::PrepareReceive(IMediaSample *pMediaSample)
- {
- CAutoLock cInterfaceLock(&m_InterfaceLock);
- m_bInReceive = TRUE;
-
-
-
-
- HRESULT hr = m_pInputPin->CBaseInputPin::Receive(pMediaSample);
- if (hr != NOERROR) {
- m_bInReceive = FALSE;
- return E_FAIL;
- }
-
-
-
-
-
-
- if (m_pInputPin->SampleProps()->pMediaType) {
- hr = m_pInputPin->SetMediaType(
- (CMediaType *)m_pInputPin->SampleProps()->pMediaType);
- if (FAILED(hr)) {
- m_bInReceive = FALSE;
- return hr;
- }
- }
- CAutoLock cSampleLock(&m_RendererLock);
- ASSERT(IsActive() == TRUE);
- ASSERT(m_pInputPin->IsFlushing() == FALSE);
- ASSERT(m_pInputPin->IsConnected() == TRUE);
- ASSERT(m_pMediaSample == NULL);
-
-
-
- if (m_pMediaSample || 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->SampleProps()->tStop;
-
-
-
-
-
- m_pMediaSample = pMediaSample;
- m_pMediaSample->AddRef();
- if (m_bStreaming == FALSE) {
- SetRepaintStatus(TRUE);
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::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;
- CAutoLock cSampleLock(&m_RendererLock);
- OnReceiveFirstSample(pSample);
- }
- 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);
- ClearPendingSample();
- SendEndOfStream();
- CancelNotification();
- return NOERROR;
- }
- HRESULT CBaseRenderer::ClearPendingSample()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- if (m_pMediaSample) {
- m_pMediaSample->Release();
- m_pMediaSample = NULL;
- }
- return NOERROR;
- }
- void CALLBACK EndOfStreamTimer(UINT uID,
- UINT uMsg,
- DWORD_PTR dwUser,
- DWORD_PTR dw1,
- DWORD_PTR dw2)
- {
- CBaseRenderer *pRenderer = (CBaseRenderer *) dwUser;
- NOTE1("EndOfStreamTimer called (%d)",uID);
- pRenderer->TimerCallback();
- }
- void CBaseRenderer::TimerCallback()
- {
-
-
- CAutoLock cRendererLock(&m_RendererLock);
-
- if (m_EndOfStreamTimer) {
- m_EndOfStreamTimer = 0;
- SendEndOfStream();
- }
- }
- #define TIMEOUT_DELIVERYWAIT 50
- #define TIMEOUT_RESOLUTION 10
- HRESULT CBaseRenderer::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 = CompatibleTimeSetEvent((UINT) Delay,
- TIMEOUT_RESOLUTION,
- EndOfStreamTimer,
- DWORD_PTR(this),
- TIME_ONESHOT);
- if (m_EndOfStreamTimer == 0) {
- return NotifyEndOfStream();
- }
- return NOERROR;
- }
- HRESULT CBaseRenderer::NotifyEndOfStream()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- 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 CBaseRenderer::ResetEndOfStream()
- {
- ResetEndOfStreamTimer();
- CAutoLock cRendererLock(&m_RendererLock);
- m_bEOS = FALSE;
- m_bEOSDelivered = FALSE;
- m_SignalTime = 0;
- return NOERROR;
- }
- void CBaseRenderer::ResetEndOfStreamTimer()
- {
- ASSERT(CritCheckOut(&m_RendererLock));
- if (m_EndOfStreamTimer) {
- timeKillEvent(m_EndOfStreamTimer);
- m_EndOfStreamTimer = 0;
- }
- }
- HRESULT CBaseRenderer::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 == NULL) {
- return SendEndOfStream();
- }
-
- ASSERT(m_pMediaSample);
- if (!ScheduleSample(m_pMediaSample))
- m_RenderEvent.Set();
- return NOERROR;
- }
- HRESULT CBaseRenderer::StopStreaming()
- {
- CAutoLock cRendererLock(&m_RendererLock);
- m_bEOSDelivered = FALSE;
- if (m_bStreaming == TRUE) {
- m_bStreaming = FALSE;
- OnStopStreaming();
- timeEndPeriod(1);
- }
- return NOERROR;
- }
- void CBaseRenderer::SetRepaintStatus(BOOL bRepaint)
- {
- CAutoLock cSampleLock(&m_RendererLock);
- m_bRepaintStatus = bRepaint;
- }
- void CBaseRenderer::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 CBaseRenderer::SendRepaint()
- {
- CAutoLock cSampleLock(&m_RendererLock);
- ASSERT(m_pInputPin);
-
-
-
-
-
-
- if (m_bAbort == FALSE) {
- if (m_pInputPin->IsConnected() == TRUE) {
- if (m_pInputPin->IsFlushing() == FALSE) {
- if (IsEndOfStream() == FALSE) {
- if (m_bRepaintStatus == TRUE) {
- IPin *pPin = (IPin *) m_pInputPin;
- NotifyEvent(EC_REPAINT,(LONG_PTR) pPin,0);
- SetRepaintStatus(FALSE);
- RLOG("Sending repaint");
- }
- }
- }
- }
- }
- }
- BOOL CBaseRenderer::OnDisplayChange()
- {
-
- CAutoLock cSampleLock(&m_RendererLock);
- if (m_pInputPin->IsConnected() == FALSE) {
- return FALSE;
- }
- RLOG("Notification of EC_DISPLAY_CHANGE");
-
- IPin *pPin = (IPin *) m_pInputPin;
- m_pInputPin->AddRef();
- NotifyEvent(EC_DISPLAY_CHANGED,(LONG_PTR) pPin,0);
- SetAbortSignal(TRUE);
- ClearPendingSample();
- m_pInputPin->Release();
- return TRUE;
- }
- void CBaseRenderer::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 CBaseRenderer::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
- }
- CRendererInputPin::CRendererInputPin(__inout CBaseRenderer *pRenderer,
- __inout HRESULT *phr,
- __in_opt LPCWSTR pPinName) :
- CBaseInputPin(NAME("Renderer pin"),
- pRenderer,
- &pRenderer->m_InterfaceLock,
- (HRESULT *) phr,
- pPinName)
- {
- m_pRenderer = pRenderer;
- ASSERT(m_pRenderer);
- }
- STDMETHODIMP CRendererInputPin::EndOfStream()
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
-
- HRESULT hr = CheckStreaming();
- if (hr != NOERROR) {
- return hr;
- }
-
- hr = m_pRenderer->EndOfStream();
- if (SUCCEEDED(hr)) {
- hr = CBaseInputPin::EndOfStream();
- }
- return hr;
- }
- STDMETHODIMP CRendererInputPin::BeginFlush()
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- {
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
- CBaseInputPin::BeginFlush();
- m_pRenderer->BeginFlush();
- }
- return m_pRenderer->ResetEndOfStream();
- }
- STDMETHODIMP CRendererInputPin::EndFlush()
- {
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
- CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);
- HRESULT hr = m_pRenderer->EndFlush();
- if (SUCCEEDED(hr)) {
- hr = CBaseInputPin::EndFlush();
- }
- return hr;
- }
- STDMETHODIMP CRendererInputPin::Receive(IMediaSample *pSample)
- {
- HRESULT hr = m_pRenderer->Receive(pSample);
- if (FAILED(hr)) {
-
-
- ASSERT(CritCheckOut(&m_pRenderer->m_RendererLock));
- {
-
-
-
- CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);
-
-
-
-
- if (!IsStopped() && !IsFlushing() && !m_pRenderer->m_bAbort && !m_bRunTimeError) {
-
-
-
- m_pRenderer->NotifyEvent(EC_ERRORABORT,hr,0);
- {
- CAutoLock alRendererLock(&m_pRenderer->m_RendererLock);
- if (m_pRenderer->IsStreaming() && !m_pRenderer->IsEndOfStreamDelivered()) {
- m_pRenderer->NotifyEndOfStream();
- }
- }
-
- m_bRunTimeError = TRUE;
- }
- }
- }
- return hr;
- }
- HRESULT CRendererInputPin::BreakConnect()
- {
- HRESULT hr = m_pRenderer->BreakConnect();
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseInputPin::BreakConnect();
- }
- HRESULT CRendererInputPin::CompleteConnect(IPin *pReceivePin)
- {
- HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin);
- if (FAILED(hr)) {
- return hr;
- }
- return CBaseInputPin::CompleteConnect(pReceivePin);
- }
- STDMETHODIMP CRendererInputPin::QueryId(__deref_out LPWSTR *Id)
- {
- CheckPointer(Id,E_POINTER);
- const WCHAR szIn[] = L"In";
- *Id = (LPWSTR)CoTaskMemAlloc(sizeof(szIn));
- if (*Id == NULL) {
- return E_OUTOFMEMORY;
- }
- CopyMemory(*Id, szIn, sizeof(szIn));
- return NOERROR;
- }
- HRESULT CRendererInputPin::CheckMediaType(const CMediaType *pmt)
- {
- return m_pRenderer->CheckMediaType(pmt);
- }
- HRESULT CRendererInputPin::Active()
- {
- return m_pRenderer->Active();
- }
- HRESULT CRendererInputPin::Inactive()
- {
-
-
- ASSERT(CritCheckIn(&m_pRenderer->m_InterfaceLock));
- m_bRunTimeError = FALSE;
- return m_pRenderer->Inactive();
- }
- HRESULT CRendererInputPin::SetMediaType(const CMediaType *pmt)
- {
- HRESULT hr = CBaseInputPin::SetMediaType(pmt);
- if (FAILED(hr)) {
- return hr;
- }
- return m_pRenderer->SetMediaType(pmt);
- }
- const TCHAR AMQUALITY[] = TEXT("ActiveMovie");
- const TCHAR DRAWLATEFRAMES[] = TEXT("DrawLateFrames");
- CBaseVideoRenderer::CBaseVideoRenderer(
- REFCLSID RenderClass,
- __in_opt LPCTSTR pName,
- __inout_opt LPUNKNOWN pUnk,
- __inout HRESULT *phr) :
- CBaseRenderer(RenderClass,pName,pUnk,phr),
- m_cFramesDropped(0),
- m_cFramesDrawn(0),
- m_bSupplierHandlingQuality(FALSE)
- {
- ResetStreamingTimes();
- #ifdef PERF
- m_idTimeStamp = MSR_REGISTER(TEXT("Frame time stamp"));
- m_idEarliness = MSR_REGISTER(TEXT("Earliness fudge"));
- m_idTarget = MSR_REGISTER(TEXT("Target (mSec)"));
- m_idSchLateTime = MSR_REGISTER(TEXT("mSec late when scheduled"));
- m_idDecision = MSR_REGISTER(TEXT("Scheduler decision code"));
- m_idQualityRate = MSR_REGISTER(TEXT("Quality rate sent"));
- m_idQualityTime = MSR_REGISTER(TEXT("Quality time sent"));
- m_idWaitReal = MSR_REGISTER(TEXT("Render wait"));
-
- m_idFrameAccuracy = MSR_REGISTER(TEXT("Frame accuracy (msecs)"));
- m_bDrawLateFrames = GetProfileInt(AMQUALITY, DRAWLATEFRAMES, FALSE);
-
- m_idRenderAvg = MSR_REGISTER(TEXT("Render draw time Avg"));
- m_idFrameAvg = MSR_REGISTER(TEXT("FrameAvg"));
- m_idWaitAvg = MSR_REGISTER(TEXT("WaitAvg"));
- m_idDuration = MSR_REGISTER(TEXT("Duration"));
- m_idThrottle = MSR_REGISTER(TEXT("Audio-video throttle wait"));
-
- #endif
- }
- CBaseVideoRenderer::~CBaseVideoRenderer()
- {
- ASSERT(m_dwAdvise == 0);
- }
- HRESULT CBaseVideoRenderer::ResetStreamingTimes()
- {
- m_trLastDraw = -1000;
- m_tStreamingStart = timeGetTime();
- m_trRenderAvg = 0;
- m_trFrameAvg = -1;
- m_trDuration = 0;
- m_trRenderLast = 0;
- m_trWaitAvg = 0;
- m_tRenderStart = 0;
- m_cFramesDrawn = 0;
- m_cFramesDropped = 0;
- m_iTotAcc = 0;
- m_iSumSqAcc = 0;
- m_iSumSqFrameTime = 0;
- m_trFrame = 0;
- m_trLate = 0;
- m_iSumFrameTime = 0;
- m_nNormal = 0;
- m_trEarliness = 0;
- m_trTarget = -300000;
- m_trThrottle = 0;
- m_trRememberStampForPerf = 0;
- #ifdef PERF
- m_trRememberFrameForPerf = 0;
- #endif
- return NOERROR;
- }
- HRESULT CBaseVideoRenderer::OnStartStreaming()
- {
- ResetStreamingTimes();
- return NOERROR;
- }
- HRESULT CBaseVideoRenderer::OnStopStreaming()
- {
- m_tStreamingStart = timeGetTime()-m_tStreamingStart;
- return NOERROR;
- }
- void CBaseVideoRenderer::OnWaitStart()
- {
- MSR_START(m_idWaitReal);
- }
- void CBaseVideoRenderer::OnWaitEnd()
- {
- #ifdef PERF
- MSR_STOP(m_idWaitReal);
-
-
- REFERENCE_TIME trRealStream;
- #if 0
- m_pClock->GetTime(&trRealStream);
- #else
-
-
-
- REFERENCE_TIME tr = timeGetTime()*10000;
- trRealStream = tr + m_llTimeOffset;
- #endif
- trRealStream -= m_tStart;
- if (m_trRememberStampForPerf==0) {
-
-
-
-
- PreparePerformanceData(0, 0);
- } else {
- int trLate = (int)(trRealStream - m_trRememberStampForPerf);
- int trFrame = (int)(tr - m_trRememberFrameForPerf);
- PreparePerformanceData(trLate, trFrame);
- }
- m_trRememberFrameForPerf = tr;
- #endif
- }
- void CBaseVideoRenderer::PreparePerformanceData(int trLate, int trFrame)
- {
- m_trLate = trLate;
- m_trFrame = trFrame;
- }
- void CBaseVideoRenderer::RecordFrameLateness(int trLate, int trFrame)
- {
-
- int tLate = trLate/10000;
-
-
-
-
- MSR_INTEGER( m_idFrameAccuracy, tLate );
-
-
-
- if (tLate>1000 || tLate<-1000) {
- if (m_cFramesDrawn<=1) {
- tLate = 0;
- } else if (tLate>0) {
- tLate = 1000;
- } else {
- tLate = -1000;
- }
- }
-
-
- if (m_cFramesDrawn>1) {
- m_iTotAcc += tLate;
- m_iSumSqAcc += (tLate*tLate);
- }
-
-
- if (m_cFramesDrawn>2) {
- int tFrame = trFrame/10000;
-
-
-
- if (tFrame>1000||tFrame<0) tFrame = 1000;
- m_iSumSqFrameTime += tFrame*tFrame;
- ASSERT(m_iSumSqFrameTime>=0);
- m_iSumFrameTime += tFrame;
- }
- ++m_cFramesDrawn;
- }
- void CBaseVideoRenderer::ThrottleWait()
- {
- if (m_trThrottle>0) {
- int iThrottle = m_trThrottle/10000;
- MSR_INTEGER( m_idThrottle, iThrottle);
- DbgLog((LOG_TRACE, 0, TEXT("Throttle %d ms"), iThrottle));
- Sleep(iThrottle);
- } else {
- Sleep(0);
- }
- }
- void CBaseVideoRenderer::OnDirectRender(IMediaSample *pMediaSample)
- {
- m_trRenderAvg = 0;
- m_trRenderLast = 5000000;
-
-
-
- RecordFrameLateness(m_trLate, m_trFrame);
- ThrottleWait();
- }
- void CBaseVideoRenderer::OnRenderStart(IMediaSample *pMediaSample)
- {
- RecordFrameLateness(m_trLate, m_trFrame);
- m_tRenderStart = timeGetTime();
- }
- void CBaseVideoRenderer::OnRenderEnd(IMediaSample *pMediaSample)
- {
-
-
-
- int tr = (timeGetTime() - m_tRenderStart)*10000;
- if (tr < m_trRenderAvg*2 || tr < 2 * m_trRenderLast) {
-
- m_trRenderAvg = (tr + (AVGPERIOD-1)*m_trRenderAvg)/AVGPERIOD;
- }
- m_trRenderLast = tr;
- ThrottleWait();
- }
- STDMETHODIMP CBaseVideoRenderer::SetSink( IQualityControl * piqc)
- {
- m_pQSink = piqc;
- return NOERROR;
- }
- STDMETHODIMP CBaseVideoRenderer::Notify( IBaseFilter * pSelf, Quality q)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (q.Proportion>=1000) { m_trThrottle = 0; }
- else {
-
-
- m_trThrottle = -330000 + (388880000/(q.Proportion+167));
- }
- return NOERROR;
- }
- HRESULT CBaseVideoRenderer::SendQuality(REFERENCE_TIME trLate,
- REFERENCE_TIME trRealStream)
- {
- Quality q;
- HRESULT hr;
-
-
-
-
-
-
-
-
-
-
-
- q.TimeStamp = (REFERENCE_TIME)trRealStream;
- if (m_trFrameAvg<0) {
- q.Type = Famine;
- }
-
- else if (m_trFrameAvg > 2*m_trRenderAvg) {
- q.Type = Famine;
- } else {
- q.Type = Flood;
- }
- q.Proportion = 1000;
- if (m_trFrameAvg<0) {
-
- }
- else if ( trLate> 0 ) {
-
-
-
- q.Proportion = 1000 - (int)((trLate)/(UNITS/1000));
- if (q.Proportion<500) {
- q.Proportion = 500;
- } else {
- }
- } else if ( m_trWaitAvg>20000
- && trLate<-20000
- ){
-
- if (m_trWaitAvg>=m_trFrameAvg) {
-
-
-
-
- q.Proportion = 2000;
- } else {
- if (m_trFrameAvg+20000 > m_trWaitAvg) {
- q.Proportion
- = 1000 * (m_trFrameAvg / (m_trFrameAvg + 20000 - m_trWaitAvg));
- } else {
-
-
-
-
- q.Proportion = 2000;
- }
- }
- if (q.Proportion>2000) {
- q.Proportion = 2000;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- q.Late = trLate + m_trRenderAvg/2;
-
- MSR_INTEGER(m_idQualityRate, q.Proportion);
- MSR_INTEGER( m_idQualityTime, (int)q.Late / 10000 );
-
- if (m_pQSink==NULL) {
-
-
-
- IQualityControl *pQC = NULL;
- IPin *pOutputPin = m_pInputPin->GetConnected();
- ASSERT(pOutputPin != NULL);
-
- hr = pOutputPin->QueryInterface(IID_IQualityControl,(void**) &pQC);
- if (SUCCEEDED(hr)) {
- m_pQSink = pQC;
- }
- }
- if (m_pQSink) {
- return m_pQSink->Notify(this,q);
- }
- return S_FALSE;
- }
- HRESULT CBaseVideoRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample,
- __inout REFERENCE_TIME *ptrStart,
- __inout REFERENCE_TIME *ptrEnd)
- {
-
- ASSERT(m_pClock);
- MSR_INTEGER(m_idTimeStamp, (int)((*ptrStart)>>32));
- MSR_INTEGER(m_idTimeStamp, (int)(*ptrStart));
-
-
-
-
-
- if (*ptrStart>=80000) {
- *ptrStart -= 80000;
- *ptrEnd -= 80000;
- }
-
-
- m_trRememberStampForPerf = *ptrStart;
-
- REFERENCE_TIME trRealStream;
- m_pClock->GetTime(&trRealStream);
- #ifdef PERF
-
-
-
-
- m_llTimeOffset = trRealStream-timeGetTime()*10000;
- #endif
- trRealStream -= m_tStart;
-
-
-
-
-
-
-
- const int trTrueLate = TimeDiff(trRealStream - *ptrStart);
- const int trLate = trTrueLate;
- MSR_INTEGER(m_idSchLateTime, trTrueLate/10000);
-
- HRESULT hr = SendQuality(trLate, trRealStream);
-
- m_bSupplierHandlingQuality = (hr==S_OK);
-
- const int trDuration = (int)(*ptrEnd - *ptrStart);
- {
-
-
-
-
-
- int t = m_trDuration/32;
- if ( trDuration > m_trDuration+t
- || trDuration < m_trDuration-t
- ) {
-
-
-
- m_trFrameAvg = trDuration;
- m_trDuration = trDuration;
- }
- }
- MSR_INTEGER(m_idEarliness, m_trEarliness/10000);
- MSR_INTEGER(m_idRenderAvg, m_trRenderAvg/10000);
- MSR_INTEGER(m_idFrameAvg, m_trFrameAvg/10000);
- MSR_INTEGER(m_idWaitAvg, m_trWaitAvg/10000);
- MSR_INTEGER(m_idDuration, trDuration/10000);
- #ifdef PERF
- if (S_OK==pMediaSample->IsDiscontinuity()) {
- MSR_INTEGER(m_idDecision, 9000);
- }
- #endif
-
-
-
-
-
- BOOL bJustDroppedFrame
- = ( m_bSupplierHandlingQuality
-
-
- && (S_OK == pMediaSample->IsDiscontinuity())
- )
- || (m_nNormal==-1);
-
- if (trLate>0) {
- m_trEarliness = 0;
- } else if ( (trLate>=m_trEarliness) || bJustDroppedFrame) {
- m_trEarliness = trLate;
- } else {
- m_trEarliness = m_trEarliness - m_trEarliness/8;
- }
-
-
- int trWaitAvg;
- {
-
-
- int trL = trLate<0 ? -trLate : 0;
- trWaitAvg = (trL + m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD;
- }
- int trFrame;
- {
- REFERENCE_TIME tr = trRealStream - m_trLastDraw;
- if (tr>10000000) {
- tr = 10000000;
- }
- trFrame = int(tr);
- }
-
- if (
-
-
- (3*m_trRenderAvg <= m_trFrameAvg)
-
-
-
- || ( m_bSupplierHandlingQuality
- ? (trLate <= trDuration*4)
- : (trLate+trLate < trDuration)
- )
-
-
- || (m_trWaitAvg > 80000)
-
-
-
- || ((trRealStream - m_trLastDraw) > UNITS)
- ) {
- HRESULT Result;
-
-
-
-
-
- BOOL bPlayASAP = FALSE;
-
-
- if ( bJustDroppedFrame) {
- bPlayASAP = TRUE;
- MSR_INTEGER(m_idDecision, 9001);
- }
-
-
-
- else if ( (m_trFrameAvg > trDuration + trDuration/16)
-
-
-
- && (trLate > - trDuration*10)
- ){
- bPlayASAP = TRUE;
- MSR_INTEGER(m_idDecision, 9002);
- }
- #if 0
-
- else if ( (trLate + trDuration > 0)
- && (m_trWaitAvg<=20000)
- ) {
- bPlayASAP = TRUE;
- MSR_INTEGER(m_idDecision, 9003);
- }
- #endif
-
-
-
-
- if (trLate<-9000000) {
- bPlayASAP = FALSE;
- }
- if (bPlayASAP) {
- m_nNormal = 0;
- MSR_INTEGER(m_idDecision, 0);
-
-
-
-
-
- m_trWaitAvg = (m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD;
-
- m_trFrameAvg = (trFrame + m_trFrameAvg*(AVGPERIOD-1))/AVGPERIOD;
- #ifndef PERF
-
-
-
-
-
-
- PreparePerformanceData(trTrueLate, trFrame);
- #endif
- m_trLastDraw = trRealStream;
- if (m_trEarliness > trLate) {
- m_trEarliness = trLate;
- }
- Result = S_OK;
- } else {
- ++m_nNormal;
-
-
-
-
-
-
- m_trFrameAvg = trDuration;
- MSR_INTEGER(m_idDecision, 1);
-
- {
- int trE = m_trEarliness;
- if (trE < -m_trFrameAvg) {
- trE = -m_trFrameAvg;
- }
- *ptrStart += trE;
- }
- int Delay = -trTrueLate;
- Result = Delay<=0 ? S_OK : S_FALSE;
- m_trWaitAvg = trWaitAvg;
-
- if (Result==S_FALSE) {
- trFrame = TimeDiff(*ptrStart-m_trLastDraw);
- m_trLastDraw = *ptrStart;
- } else {
-
- m_trLastDraw = trRealStream;
- }
- #ifndef PERF
- int iAccuracy;
- if (Delay>0) {
-
- iAccuracy = TimeDiff(*ptrStart-m_trRememberStampForPerf);
- } else {
-
- iAccuracy = trTrueLate;
- }
- PreparePerformanceData(iAccuracy, trFrame);
- #endif
- }
- return Result;
- }
-
-
-
- m_trWaitAvg = trWaitAvg;
- #ifdef PERF
-
- if (m_bDrawLateFrames) {
- return S_OK;
- }
- #endif
-
-
-
- MSR_INTEGER(m_idDecision, 2);
- m_nNormal = -1;
- return E_FAIL;
- }
- BOOL CBaseVideoRenderer::ScheduleSample(IMediaSample *pMediaSample)
- {
-
- BOOL bDrawImage = CBaseRenderer::ScheduleSample(pMediaSample);
- if (bDrawImage == FALSE) {
- ++m_cFramesDropped;
- return FALSE;
- }
-
-
- return TRUE;
- }
- STDMETHODIMP CBaseVideoRenderer::get_FramesDroppedInRenderer(__out int *pcFramesDropped)
- {
- CheckPointer(pcFramesDropped,E_POINTER);
- CAutoLock cVideoLock(&m_InterfaceLock);
- *pcFramesDropped = m_cFramesDropped;
- return NOERROR;
- }
- STDMETHODIMP CBaseVideoRenderer::get_FramesDrawn( int *pcFramesDrawn)
- {
- CheckPointer(pcFramesDrawn,E_POINTER);
- CAutoLock cVideoLock(&m_InterfaceLock);
- *pcFramesDrawn = m_cFramesDrawn;
- return NOERROR;
- }
- STDMETHODIMP CBaseVideoRenderer::get_AvgFrameRate( int *piAvgFrameRate)
- {
- CheckPointer(piAvgFrameRate,E_POINTER);
- CAutoLock cVideoLock(&m_InterfaceLock);
- int t;
- if (m_bStreaming) {
- t = timeGetTime()-m_tStreamingStart;
- } else {
- t = m_tStreamingStart;
- }
- if (t<=0) {
- *piAvgFrameRate = 0;
- ASSERT(m_cFramesDrawn == 0);
- } else {
-
- *piAvgFrameRate = MulDiv(100000, m_cFramesDrawn, t);
- }
- return NOERROR;
- }
- STDMETHODIMP CBaseVideoRenderer::get_AvgSyncOffset(__out int *piAvg)
- {
- CheckPointer(piAvg,E_POINTER);
- CAutoLock cVideoLock(&m_InterfaceLock);
- if (NULL==m_pClock) {
- *piAvg = 0;
- return NOERROR;
- }
-
-
- if (m_cFramesDrawn<=1) {
- *piAvg = 0;
- } else {
- *piAvg = (int)(m_iTotAcc / (m_cFramesDrawn-1));
- }
- return NOERROR;
- }
- int isqrt(int x)
- {
- int s = 1;
-
- if (x > 0x40000000) {
- s = 0x8000;
- } else {
- while (s*s<x) {
- s = 2*s;
- }
-
- if (x==0) {
- s= 0;
-
- } else {
- s = (s*s+x)/(2*s);
- if (s>=0) s = (s*s+x)/(2*s);
- if (s>=0) s = (s*s+x)/(2*s);
- }
- }
- return s;
- }
- HRESULT CBaseVideoRenderer::GetStdDev(
- int nSamples,
- __out int *piResult,
- LONGLONG llSumSq,
- LONGLONG iTot
- )
- {
- CheckPointer(piResult,E_POINTER);
- CAutoLock cVideoLock(&m_InterfaceLock);
- if (NULL==m_pClock) {
- *piResult = 0;
- return NOERROR;
- }
-
-
-
-
- if (nSamples<=1) {
- *piResult = 0;
- } else {
- LONGLONG x;
-
-
-
- x = llSumSq - llMulDiv(iTot, iTot, nSamples, 0);
- x = x / (nSamples-1);
- ASSERT(x>=0);
- *piResult = isqrt((LONG)x);
- }
- return NOERROR;
- }
- STDMETHODIMP CBaseVideoRenderer::get_DevSyncOffset(__out int *piDev)
- {
-
-
- return GetStdDev(m_cFramesDrawn - 1,
- piDev,
- m_iSumSqAcc,
- m_iTotAcc);
- }
- STDMETHODIMP CBaseVideoRenderer::get_Jitter(__out int *piJitter)
- {
-
-
-
- return GetStdDev(m_cFramesDrawn - 2,
- piJitter,
- m_iSumSqFrameTime,
- m_iSumFrameTime);
- }
- STDMETHODIMP
- CBaseVideoRenderer::NonDelegatingQueryInterface(REFIID riid,__deref_out VOID **ppv)
- {
-
- if (riid == IID_IQualProp) {
- return GetInterface( (IQualProp *)this, ppv);
- } else if (riid == IID_IQualityControl) {
- return GetInterface( (IQualityControl *)this, ppv);
- }
- return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
- }
- STDMETHODIMP
- CBaseVideoRenderer::JoinFilterGraph(__inout_opt IFilterGraph *pGraph, __in_opt LPCWSTR pName)
- {
-
-
-
- if (!pGraph && m_pGraph) {
-
-
- IBaseFilter* pFilter = this;
- NotifyEvent(EC_WINDOW_DESTROYED, (LPARAM) pFilter, 0);
- }
- return CBaseFilter::JoinFilterGraph(pGraph, pName);
- }
- #pragma warning(disable: 4514)
- #endif
|