2 Copyright 2004-2005 Chris Tallon, Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
23 #include "windowsosd.h"
24 #include "dsallocator.h"
33 typedef HRESULT (__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);
35 extern FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface;
38 DsAllocator::DsAllocator() {
47 start_get_evr_samples=false;
54 DsAllocator::~DsAllocator() {
55 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
56 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
61 void DsAllocator::CleanupSurfaces() {
63 while(fullevrsamples.size()>0)
65 IMFSample *sample=fullevrsamples.front();
69 while(emptyevrsamples.size()>0)
71 IMFSample *sample=emptyevrsamples.front();
72 emptyevrsamples.pop();
76 for (int i=0;i<surfaces.size();i++) {
77 if (surfaces[i]!=NULL) surfaces[i]->Release();
80 start_get_evr_samples=false;
84 HRESULT STDMETHODCALLTYPE DsAllocator::InitializeDevice(DWORD_PTR userid,VMR9AllocationInfo* allocinf,DWORD*numbuf){
85 if (!surfallocnotify) return S_FALSE;
89 surfaces.resize(*numbuf);
90 HRESULT hres= surfallocnotify->AllocateSurfaceHelper(allocinf,numbuf,&surfaces.at(0));
91 vheight=allocinf->dwHeight;
92 vwidth=allocinf->dwWidth;
93 start_get_evr_samples=false;
96 sprintf(buffer,"%d * %d",allocinf->dwWidth,allocinf->dwHeight);
97 MessageBox(0,"hi",buffer,0);*/
101 void DsAllocator::LostDevice(IDirect3DDevice9 *d3ddev, IDirect3D9* d3d) {
102 if (!surfallocnotify) return ;
105 // d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
106 HMONITOR hmon=d3d->GetAdapterMonitor(D3DADAPTER_DEFAULT);
107 surfallocnotify->ChangeD3DDevice(d3ddev,hmon);
112 HRESULT STDMETHODCALLTYPE DsAllocator::TerminateDevice(DWORD_PTR userid){
115 return S_OK; //Do nothing
117 HRESULT STDMETHODCALLTYPE DsAllocator::GetSurface(DWORD_PTR userid,DWORD surfindex,DWORD surfflags, IDirect3DSurface9** surf)
119 if (surfindex>=surfaces.size()) return E_FAIL;
120 if (surf==NULL) return E_POINTER;
123 surfaces[surfindex]->AddRef();
124 *surf=surfaces[surfindex];
128 HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* allnoty){
130 surfallocnotify=allnoty;
131 IDirect3DDevice9 *d3ddev;
132 //OK lets set the direct3d object from the osd
133 d3ddev=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dDev();
134 HMONITOR hmon=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT);
135 HRESULT hres=surfallocnotify->SetD3DDevice(d3ddev,hmon);
141 HRESULT STDMETHODCALLTYPE DsAllocator::StartPresenting(DWORD_PTR userid){
142 //MessageBox(0,"drive me","drive me",0);
143 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
144 start_get_evr_samples=false;
148 HRESULT STDMETHODCALLTYPE DsAllocator::StopPresenting(DWORD_PTR userid){
149 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL,0,0);
150 start_get_evr_samples=false;
154 HRESULT STDMETHODCALLTYPE DsAllocator::PresentImage(DWORD_PTR userid,VMR9PresentationInfo* presinf){
155 dynamic_cast<WindowsOsd*>(Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return
160 HRESULT STDMETHODCALLTYPE DsAllocator::QueryInterface(REFIID refiid,void ** obj){
161 if (obj==NULL) return E_POINTER;
163 if (refiid==IID_IVMRSurfaceAllocator9) {
164 *obj=static_cast<IVMRSurfaceAllocator9*>(this);
167 } else if (refiid==IID_IVMRImagePresenter9) {
168 *obj=static_cast<IVMRImagePresenter9*>(this);
171 } else if (refiid==IID_IMFVideoDeviceID) {
172 *obj=static_cast<IMFVideoDeviceID*> (this);
175 } else if (refiid==IID_IMFTopologyServiceLookupClient ) {
176 *obj=static_cast<IMFTopologyServiceLookupClient*> (this);
179 } else if (refiid==IID_IQualProp ) {
180 *obj=static_cast<IQualProp*> (this);
183 } else if (refiid==IID_IMFGetService) {
184 *obj=static_cast<IMFGetService*> (this);
187 } else if (refiid==IID_IDirect3DDeviceManager9) {
188 IDirect3DDeviceManager9 *d3dman=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dMan();
190 return d3dman->QueryInterface(refiid,obj);
194 return E_NOINTERFACE;
197 return E_NOINTERFACE;
202 ULONG STDMETHODCALLTYPE DsAllocator::AddRef(){
203 return InterlockedIncrement(&refcount);
206 ULONG STDMETHODCALLTYPE DsAllocator::Release(){
208 ref=InterlockedDecrement(&refcount);
210 delete this; //Commit suicide
215 HRESULT STDMETHODCALLTYPE DsAllocator::GetDeviceID(IID *pDid)
220 *pDid=__uuidof(IDirect3DDevice9);
224 HRESULT STDMETHODCALLTYPE DsAllocator::InitServicePointers(IMFTopologyServiceLookup *plooky)
226 if (!plooky) return E_POINTER;
229 /* get all interfaces we need*/
232 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_MIXER_SERVICE,
233 __uuidof(IMFTransform),(void**)&mftransform, &dwobjcts);
234 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_RENDER_SERVICE,
235 __uuidof(IMediaEventSink),(void**)&mediasink, &dwobjcts);
236 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
237 __uuidof(IMFClock),(void**)&mfclock,&dwobjcts);
244 HRESULT STDMETHODCALLTYPE DsAllocator::ReleaseServicePointers()
248 /* TODO Set RenderState , sample type etc.*/
250 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, 0, 0);
252 if (mftransform) mftransform->Release();
255 if (mediasink) mediasink->Release();
258 if (mfclock) mfclock->Release();
260 if (mfmediatype) mfmediatype->Release();
267 HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &iid,LPVOID *obj)
269 if (guid==MR_VIDEO_ACCELERATION_SERVICE)
271 IDirect3DDeviceManager9 *d3dman=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dMan();
274 return d3dman->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) obj);
278 return E_NOINTERFACE;
282 else if (guid==MR_VIDEO_RENDER_SERVICE)
284 return QueryInterface(iid,obj);
288 return E_NOINTERFACE;
293 void DsAllocator::GetEVRSamples()
296 MFCLOCK_STATE clockstate;
297 if (mfclock) mfclock->GetState(0,&clockstate);
298 //MessageBox(0,"get samples","samples",0);
300 if (mfclock && clockstate==MFCLOCK_STATE_STOPPED && fullevrsamples.size()>0)
306 while (emptyevrsamples.size()>0)
309 MFT_OUTPUT_DATA_BUFFER outdatabuffer;
310 ZeroMemory(&outdatabuffer,sizeof(outdatabuffer));
311 outdatabuffer.pSample=emptyevrsamples.front();
313 LONGLONG starttime,endtime;
320 mfclock->GetCorrelatedTime(0,&starttime,&dummy);
321 if (lastdelframe) CalcJitter( (starttime-lastdelframe)/10000);
322 lastdelframe=starttime;
325 HRESULT hres=mftransform->ProcessOutput(0,1,&outdatabuffer,&status);
328 if (hres==MF_E_TRANSFORM_NEED_MORE_INPUT)
334 mediasink->Notify(EC_COMPLETE,(LONG_PTR) S_OK,0);
339 else if (hres==MF_E_TRANSFORM_STREAM_CHANGE)
341 if (mfmediatype) mfmediatype->Release();
345 else if (hres==MF_E_TRANSFORM_TYPE_NOT_SET)
347 if (mfmediatype) mfmediatype->Release();
349 RenegotiateEVRMediaType();
355 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
356 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Got EVR Sample %lld",prestime);
357 IMFSample *temp=emptyevrsamples.front();
358 emptyevrsamples.pop();
362 fullevrsamples.push(temp);
363 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "got evr sample %d, %d",
364 // emptyevrsamples.size(),fullevrsamples.size());
366 mfclock->GetCorrelatedTime(0,&endtime,&dummy);
367 LONGLONG delay=endtime-starttime;
368 mediasink->Notify( EC_PROCESSING_LATENCY,(LONG_PTR)&delay,0);
370 //Check if presentation is soon
372 LONGLONG currenttime=0;
373 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
376 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
378 LONGLONG delta=prestime-currenttime;
380 break; //break if presentation is soon
391 HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULONG_PTR mess_para)
394 case MFVP_MESSAGE_FLUSH:{
395 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_FLUSH received");
397 start_get_evr_samples=false;
399 case MFVP_MESSAGE_INVALIDATEMEDIATYPE: {
400 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_INVALIDATEMEDIATYPE received");
401 if (mfmediatype) mfmediatype->Release();
403 start_get_evr_samples=false;
404 RenegotiateEVRMediaType();}break;
405 case MFVP_MESSAGE_PROCESSINPUTNOTIFY: {
406 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_PROCESSINPUTNOTIFY received");
407 if (!start_get_evr_samples) GetEVRSamples();
408 start_get_evr_samples=true;
410 case MFVP_MESSAGE_BEGINSTREAMING:{
411 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received");
413 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
414 //((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);//No need to do this causes misbehaviout
417 case MFVP_MESSAGE_ENDSTREAMING: {
418 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received");
419 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
420 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
421 start_get_evr_samples=false;
423 //if (mfmediatype) mfmediatype->Release();
426 case MFVP_MESSAGE_ENDOFSTREAM: {
427 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDOFSTREAM received");
428 //MessageBox(0,"endofstream","endofstream",0);
430 start_get_evr_samples=false;
432 case MFVP_MESSAGE_STEP: {
433 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_STEP received");
434 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
435 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause);
436 //MessageBox(0,"steppy","steppy",0);
437 FlushEVRSamples(/*LOWORD(mess_para)*/); //Message sending, has to be done after compeletion
439 case MFVP_MESSAGE_CANCELSTEP: {
440 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_CANCELSTEP received");
444 MessageBox(0,"unhandled","unhandled",0);
449 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG startoffset)
451 //((OsdWin*)Osd::getInstance())->SetEVRTimes(systime,startoffset);
454 if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples();
455 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
456 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart");
457 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started);
463 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime)
467 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
469 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop");
470 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
475 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime)
478 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
480 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause");
481 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause);
485 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime)
487 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
489 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart");
490 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started);
495 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockSetRate(MFTIME systime,float rate)
501 HRESULT STDMETHODCALLTYPE DsAllocator::GetCurrentMediaType(IMFVideoMediaType **mtype)
502 {// MessageBox(0,"mediatype","mediatype",0);
503 if (mtype==NULL) return E_POINTER;
505 if (mfmediatype==NULL)
509 return MF_E_NOT_INITIALIZED;
511 HRESULT hres=mfmediatype->QueryInterface(IID_IMFVideoMediaType,(void**)mtype);
516 void DsAllocator::RenegotiateEVRMediaType()
519 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Cannot renegotiate without transform!");
527 IMFMediaType *mixtype=NULL;
529 if (hres=mftransform->GetOutputAvailableType(0,index++,&mixtype)!=S_OK)
531 Log::getInstance()->log("DsAllocator", Log::DEBUG , "No more types availiable from EVR %d !",hres);
537 mixtype->IsCompressedFormat(&compressed);
544 mixtype->GetUINT32(MF_MT_INTERLACE_MODE,&helper);
545 if (helper!=MFVideoInterlace_Progressive) {
546 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type interlaced!");
551 mixtype->GetMajorType(&temp);
552 if (temp!=MEDIATYPE_Video) {
553 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type no video!");
557 if(mftransform->SetOutputType(0,mixtype,MFT_SET_TYPE_TEST_ONLY)!=S_OK)
559 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type test failed!");
568 if (mfmediatype) mfmediatype->Release();
572 AllocateEVRSurfaces();
575 hres=mftransform->SetOutputType(0,mixtype,0);
582 if (mfmediatype) mfmediatype->Release();
590 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Output type set! %d",hres);
592 if (!gotcha) Log::getInstance()->log("DsAllocator", Log::DEBUG , "No suitable output type!");
598 void DsAllocator::AllocateEVRSurfaces()
601 LARGE_INTEGER temp64;
602 mfmediatype->GetUINT64(MF_MT_FRAME_SIZE, (UINT64*)&temp64);
603 vwidth=temp64.HighPart;
604 vheight=temp64.LowPart;
606 subtype.Data1=D3DFMT_X8R8G8B8;
607 mfmediatype->GetGUID(MF_MT_SUBTYPE,&subtype);
608 D3DFORMAT format=(D3DFORMAT)subtype.Data1;
609 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Surfaceformat is %d, width %d, height %d",format,vwidth,vheight);
610 format=D3DFMT_X8R8G8B8;
614 WindowsOsd* osdwin = dynamic_cast<WindowsOsd*>(Osd::getInstance());
615 LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev();
616 osdwin->BeginPainting();
618 for (int i=0;i<10;i++)
621 LPDIRECT3DSURFACE9 surfy;
623 hres=d3ddev->CreateRenderTarget(vwidth,vheight,format,
624 D3DMULTISAMPLE_NONE,0,FALSE,&surfy,NULL);
634 osdwin->EndPainting();
638 for (int i=0;i<surfaces.size();i++) {
639 if (surfaces[i]!=NULL)
641 IMFSample *sample=NULL;
642 ptrMFCreateVideoSampleFromSurface(surfaces[i],&sample);
643 if (sample) emptyevrsamples.push(sample);
650 void DsAllocator::FlushEVRSamples()
653 while(fullevrsamples.size()>0)
655 IMFSample *sample=fullevrsamples.front();
656 fullevrsamples.pop();
657 emptyevrsamples.push(sample);
663 void DsAllocator::GetNextSurface(LPDIRECT3DSURFACE9* surf,DWORD *waittime)
669 if (fullevrsamples.size()==0) {
671 if (start_get_evr_samples) GetEVRSamples();
673 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Enter Get Next Surface");
675 while (fullevrsamples.size()>0)
677 //MessageBox(0,"Got a sample","got a sample",0);
678 IMFSample *sample=fullevrsamples.front();
681 LONGLONG currenttime=0;
683 HRESULT hres=sample->GetSampleTime(&prestime);
686 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
688 LONGLONG delta=prestime-currenttime;
692 if (delta<-10000*20 && false) { //SkipIT
693 LONGLONG latency=-delta;
694 //mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
695 LARGE_INTEGER helper;
696 helper.QuadPart=-delta;
697 Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d prestime %lld",helper.LowPart,helper.HighPart,prestime);
698 CalcSyncOffsets(delta/10000LL);
699 // emptyevrsamples.size(),fullevrsamples.size());
700 fullevrsamples.pop();
701 emptyevrsamples.push(sample);
706 if (delta<10000*20 || !mfclock )
709 IMFMediaBuffer* buffy=NULL;
710 //MessageBox(0,"its showtime","showtimw",0);
711 CalcSyncOffsets(delta/10000LL);
713 hres=sample->GetBufferByIndex(0,&buffy);
714 //LARGE_INTEGER helper;
715 //helper.QuadPart=-delta;
716 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Paint 1 frame %d %d, frames %d prestime %lld",
717 // helper.LowPart,helper.HighPart,fullevrsamples.size(),prestime);
718 if (hres!=S_OK) { //SkipIT
719 fullevrsamples.pop();
720 emptyevrsamples.push(sample);
723 IMFGetService* service;
724 hres=buffy->QueryInterface(IID_IMFGetService,(void**)&service);
726 if (hres!=S_OK) { //SkipIT
727 fullevrsamples.pop();
728 emptyevrsamples.push(sample);
731 LPDIRECT3DSURFACE9 tempsurf;
732 hres=service->GetService(MR_BUFFER_SERVICE,IID_IDirect3DSurface9 ,(void**) &tempsurf);
734 if (hres!=S_OK) { //SkipIT
735 fullevrsamples.pop();
736 emptyevrsamples.push(sample);
742 *waittime=delta/10000-10;
752 void DsAllocator::DiscardSurfaceandgetWait(DWORD *waittime)
754 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait");
755 if (start_get_evr_samples) GetEVRSamples();
756 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait2");
758 if (fullevrsamples.size()==0) {
763 IMFSample *sample=fullevrsamples.front();
764 fullevrsamples.pop();
765 emptyevrsamples.push(sample);
768 while (fullevrsamples.size()>0)
771 IMFSample *sample=fullevrsamples.front();
774 LONGLONG currenttime=0;
776 HRESULT hres=sample->GetSampleTime(&prestime);
779 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
781 LONGLONG delta=prestime-currenttime;
784 if (delta<-10000*20 ) { //SkipIT
785 LONGLONG latency=-delta;
786 // mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
787 //LARGE_INTEGER helper;
788 //helper.QuadPart=-delta;
789 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d time %lld",helper.LowPart,helper.HighPart,prestime);
790 CalcSyncOffsets(delta/10000LL);
791 // emptyevrsamples.size(),fullevrsamples.size());
792 fullevrsamples.pop();
793 emptyevrsamples.push(sample);
798 *waittime=min(delta/10000/2-10,1);
805 void DsAllocator::ResetSyncOffsets()
807 for (int i=0;i<n_stats;i++)
823 void DsAllocator::CalcSyncOffsets(int sync)
825 sync_offset[sync_pos]=sync;
826 sync_pos=(sync_pos +1)%n_stats;
829 for (int i=0;i<n_stats;i++)
831 mean_value+=sync_offset[i];
833 mean_value/=(double) n_stats;
835 for (int i=0;i<n_stats;i++)
837 double temp_dev=(mean_value-(double)sync_offset[i]);
838 std_dev+=temp_dev*temp_dev;
840 std_dev/=(double)n_stats;
841 avg_sync_offset=mean_value;
842 dev_sync_offset=sqrt(std_dev);
845 void DsAllocator::CalcJitter(int jitter)
847 jitter_offset[jitter_pos]=jitter;
848 jitter_pos=(jitter_pos +1)%n_stats;
852 for (int i=0;i<n_stats;i++)
854 mean_value+=jitter_offset[i];
856 mean_value/=(double) n_stats;
857 avgfps=1000./mean_value*100.;
859 for (int i=0;i<n_stats;i++)
861 double temp_dev=(mean_value-(double)jitter_offset[i]);
862 std_dev+=temp_dev*temp_dev;
864 std_dev/=(double)n_stats;
865 jitter=sqrt(std_dev);
869 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDrawn(int *val)
875 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgFrameRate(int *val)
881 HRESULT STDMETHODCALLTYPE DsAllocator::get_Jitter(int *val)
887 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgSyncOffset(int *val)
889 *val=avg_sync_offset;
893 HRESULT STDMETHODCALLTYPE DsAllocator::get_DevSyncOffset(int *val)
895 *val=dev_sync_offset;
898 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDroppedInRenderer(int *val)