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, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "windowsosd.h"
25 #include "dsallocator.h"
34 typedef HRESULT (__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);
36 extern FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface;
39 DsAllocator::DsAllocator() {
48 start_get_evr_samples=false;
55 DsAllocator::~DsAllocator() {
56 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
57 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
62 void DsAllocator::CleanupSurfaces() {
64 while(fullevrsamples.size()>0)
66 IMFSample *sample=fullevrsamples.front();
70 while(emptyevrsamples.size()>0)
72 IMFSample *sample=emptyevrsamples.front();
73 emptyevrsamples.pop();
77 for (int i=0;i<surfaces.size();i++) {
78 if (surfaces[i]!=NULL) surfaces[i]->Release();
81 start_get_evr_samples=false;
85 HRESULT STDMETHODCALLTYPE DsAllocator::InitializeDevice(DWORD_PTR userid,VMR9AllocationInfo* allocinf,DWORD*numbuf){
86 if (!surfallocnotify) return S_FALSE;
90 surfaces.resize(*numbuf);
91 HRESULT hres= surfallocnotify->AllocateSurfaceHelper(allocinf,numbuf,&surfaces.at(0));
92 vheight=allocinf->dwHeight;
93 vwidth=allocinf->dwWidth;
94 start_get_evr_samples=false;
97 sprintf(buffer,"%d * %d",allocinf->dwWidth,allocinf->dwHeight);
98 MessageBox(0,"hi",buffer,0);*/
102 void DsAllocator::LostDevice(IDirect3DDevice9 *d3ddev, IDirect3D9* d3d) {
103 if (!surfallocnotify) return ;
106 // d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
107 HMONITOR hmon=d3d->GetAdapterMonitor(D3DADAPTER_DEFAULT);
108 surfallocnotify->ChangeD3DDevice(d3ddev,hmon);
113 HRESULT STDMETHODCALLTYPE DsAllocator::TerminateDevice(DWORD_PTR userid){
116 return S_OK; //Do nothing
118 HRESULT STDMETHODCALLTYPE DsAllocator::GetSurface(DWORD_PTR userid,DWORD surfindex,DWORD surfflags, IDirect3DSurface9** surf)
120 if (surfindex>=surfaces.size()) return E_FAIL;
121 if (surf==NULL) return E_POINTER;
124 surfaces[surfindex]->AddRef();
125 *surf=surfaces[surfindex];
129 HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* allnoty){
131 surfallocnotify=allnoty;
132 IDirect3DDevice9 *d3ddev;
133 //OK lets set the direct3d object from the osd
134 d3ddev=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dDev();
135 HMONITOR hmon=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT);
136 HRESULT hres=surfallocnotify->SetD3DDevice(d3ddev,hmon);
142 HRESULT STDMETHODCALLTYPE DsAllocator::StartPresenting(DWORD_PTR userid){
143 //MessageBox(0,"drive me","drive me",0);
144 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
145 start_get_evr_samples=false;
149 HRESULT STDMETHODCALLTYPE DsAllocator::StopPresenting(DWORD_PTR userid){
150 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL,0,0);
151 start_get_evr_samples=false;
155 HRESULT STDMETHODCALLTYPE DsAllocator::PresentImage(DWORD_PTR userid,VMR9PresentationInfo* presinf){
156 dynamic_cast<WindowsOsd*>(Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return
161 HRESULT STDMETHODCALLTYPE DsAllocator::QueryInterface(REFIID refiid,void ** obj){
162 if (obj==NULL) return E_POINTER;
164 if (refiid==IID_IVMRSurfaceAllocator9) {
165 *obj=static_cast<IVMRSurfaceAllocator9*>(this);
168 } else if (refiid==IID_IVMRImagePresenter9) {
169 *obj=static_cast<IVMRImagePresenter9*>(this);
172 } else if (refiid==IID_IMFVideoDeviceID) {
173 *obj=static_cast<IMFVideoDeviceID*> (this);
176 } else if (refiid==IID_IMFTopologyServiceLookupClient ) {
177 *obj=static_cast<IMFTopologyServiceLookupClient*> (this);
180 } else if (refiid==IID_IQualProp ) {
181 *obj=static_cast<IQualProp*> (this);
184 } else if (refiid==IID_IMFGetService) {
185 *obj=static_cast<IMFGetService*> (this);
188 } else if (refiid==IID_IDirect3DDeviceManager9) {
189 IDirect3DDeviceManager9 *d3dman=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dMan();
191 return d3dman->QueryInterface(refiid,obj);
195 return E_NOINTERFACE;
198 return E_NOINTERFACE;
203 ULONG STDMETHODCALLTYPE DsAllocator::AddRef(){
204 return InterlockedIncrement(&refcount);
207 ULONG STDMETHODCALLTYPE DsAllocator::Release(){
209 ref=InterlockedDecrement(&refcount);
211 delete this; //Commit suicide
216 HRESULT STDMETHODCALLTYPE DsAllocator::GetDeviceID(IID *pDid)
221 *pDid=__uuidof(IDirect3DDevice9);
225 HRESULT STDMETHODCALLTYPE DsAllocator::InitServicePointers(IMFTopologyServiceLookup *plooky)
227 if (!plooky) return E_POINTER;
230 /* get all interfaces we need*/
233 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_MIXER_SERVICE,
234 __uuidof(IMFTransform),(void**)&mftransform, &dwobjcts);
235 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_RENDER_SERVICE,
236 __uuidof(IMediaEventSink),(void**)&mediasink, &dwobjcts);
237 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
238 __uuidof(IMFClock),(void**)&mfclock,&dwobjcts);
245 HRESULT STDMETHODCALLTYPE DsAllocator::ReleaseServicePointers()
249 /* TODO Set RenderState , sample type etc.*/
251 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, 0, 0);
253 if (mftransform) mftransform->Release();
256 if (mediasink) mediasink->Release();
259 if (mfclock) mfclock->Release();
261 if (mfmediatype) mfmediatype->Release();
268 HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &iid,LPVOID *obj)
270 if (guid==MR_VIDEO_ACCELERATION_SERVICE)
272 IDirect3DDeviceManager9 *d3dman=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getD3dMan();
275 return d3dman->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) obj);
279 return E_NOINTERFACE;
283 else if (guid==MR_VIDEO_RENDER_SERVICE)
285 return QueryInterface(iid,obj);
289 return E_NOINTERFACE;
294 void DsAllocator::GetEVRSamples()
297 MFCLOCK_STATE clockstate;
298 if (mfclock) mfclock->GetState(0,&clockstate);
299 //MessageBox(0,"get samples","samples",0);
301 if (mfclock && clockstate==MFCLOCK_STATE_STOPPED && fullevrsamples.size()>0)
307 while (emptyevrsamples.size()>0)
310 MFT_OUTPUT_DATA_BUFFER outdatabuffer;
311 ZeroMemory(&outdatabuffer,sizeof(outdatabuffer));
312 outdatabuffer.pSample=emptyevrsamples.front();
314 LONGLONG starttime,endtime;
321 mfclock->GetCorrelatedTime(0,&starttime,&dummy);
322 if (lastdelframe) CalcJitter( (starttime-lastdelframe)/10000);
323 lastdelframe=starttime;
326 HRESULT hres=mftransform->ProcessOutput(0,1,&outdatabuffer,&status);
329 if (hres==MF_E_TRANSFORM_NEED_MORE_INPUT)
335 mediasink->Notify(EC_COMPLETE,(LONG_PTR) S_OK,0);
340 else if (hres==MF_E_TRANSFORM_STREAM_CHANGE)
342 if (mfmediatype) mfmediatype->Release();
346 else if (hres==MF_E_TRANSFORM_TYPE_NOT_SET)
348 if (mfmediatype) mfmediatype->Release();
350 RenegotiateEVRMediaType();
356 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
357 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Got EVR Sample %lld",prestime);
358 IMFSample *temp=emptyevrsamples.front();
359 emptyevrsamples.pop();
363 fullevrsamples.push(temp);
364 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "got evr sample %d, %d",
365 // emptyevrsamples.size(),fullevrsamples.size());
367 mfclock->GetCorrelatedTime(0,&endtime,&dummy);
368 LONGLONG delay=endtime-starttime;
369 mediasink->Notify( EC_PROCESSING_LATENCY,(LONG_PTR)&delay,0);
371 //Check if presentation is soon
373 LONGLONG currenttime=0;
374 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
377 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
379 LONGLONG delta=prestime-currenttime;
381 break; //break if presentation is soon
392 HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULONG_PTR mess_para)
395 case MFVP_MESSAGE_FLUSH:{
396 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_FLUSH received");
398 start_get_evr_samples=false;
400 case MFVP_MESSAGE_INVALIDATEMEDIATYPE: {
401 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_INVALIDATEMEDIATYPE received");
402 if (mfmediatype) mfmediatype->Release();
404 start_get_evr_samples=false;
405 RenegotiateEVRMediaType();}break;
406 case MFVP_MESSAGE_PROCESSINPUTNOTIFY: {
407 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_PROCESSINPUTNOTIFY received");
408 if (!start_get_evr_samples) GetEVRSamples();
409 start_get_evr_samples=true;
411 case MFVP_MESSAGE_BEGINSTREAMING:{
412 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received");
414 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
415 //((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);//No need to do this causes misbehaviout
418 case MFVP_MESSAGE_ENDSTREAMING: {
419 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received");
420 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
421 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
422 start_get_evr_samples=false;
424 //if (mfmediatype) mfmediatype->Release();
427 case MFVP_MESSAGE_ENDOFSTREAM: {
428 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDOFSTREAM received");
429 //MessageBox(0,"endofstream","endofstream",0);
431 start_get_evr_samples=false;
433 case MFVP_MESSAGE_STEP: {
434 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_STEP received");
435 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
436 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause);
437 //MessageBox(0,"steppy","steppy",0);
438 FlushEVRSamples(/*LOWORD(mess_para)*/); //Message sending, has to be done after compeletion
440 case MFVP_MESSAGE_CANCELSTEP: {
441 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_CANCELSTEP received");
445 MessageBox(0,"unhandled","unhandled",0);
450 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG startoffset)
452 //((OsdWin*)Osd::getInstance())->SetEVRTimes(systime,startoffset);
455 if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples();
456 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
457 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart");
458 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started);
464 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime)
468 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_off);
470 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop");
471 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(NULL, vwidth, vheight);
476 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime)
479 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
481 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause");
482 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_pause);
486 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime)
488 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setExternalDriving(this, vwidth, vheight);
490 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart");
491 dynamic_cast<WindowsOsd*>(Osd::getInstance())->SetEVRStatus(WindowsOsd::EVR_pres_started);
496 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockSetRate(MFTIME systime,float rate)
502 HRESULT STDMETHODCALLTYPE DsAllocator::GetCurrentMediaType(IMFVideoMediaType **mtype)
503 {// MessageBox(0,"mediatype","mediatype",0);
504 if (mtype==NULL) return E_POINTER;
506 if (mfmediatype==NULL)
510 return MF_E_NOT_INITIALIZED;
512 HRESULT hres=mfmediatype->QueryInterface(IID_IMFVideoMediaType,(void**)mtype);
517 void DsAllocator::RenegotiateEVRMediaType()
520 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Cannot renegotiate without transform!");
528 IMFMediaType *mixtype=NULL;
530 if (hres=mftransform->GetOutputAvailableType(0,index++,&mixtype)!=S_OK)
532 Log::getInstance()->log("DsAllocator", Log::DEBUG , "No more types availiable from EVR %d !",hres);
538 mixtype->IsCompressedFormat(&compressed);
545 mixtype->GetUINT32(MF_MT_INTERLACE_MODE,&helper);
546 if (helper!=MFVideoInterlace_Progressive) {
547 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type interlaced!");
552 mixtype->GetMajorType(&temp);
553 if (temp!=MEDIATYPE_Video) {
554 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type no video!");
558 if(mftransform->SetOutputType(0,mixtype,MFT_SET_TYPE_TEST_ONLY)!=S_OK)
560 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type test failed!");
569 if (mfmediatype) mfmediatype->Release();
573 AllocateEVRSurfaces();
576 hres=mftransform->SetOutputType(0,mixtype,0);
583 if (mfmediatype) mfmediatype->Release();
591 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Output type set! %d",hres);
593 if (!gotcha) Log::getInstance()->log("DsAllocator", Log::DEBUG , "No suitable output type!");
599 void DsAllocator::AllocateEVRSurfaces()
602 LARGE_INTEGER temp64;
603 mfmediatype->GetUINT64(MF_MT_FRAME_SIZE, (UINT64*)&temp64);
604 vwidth=temp64.HighPart;
605 vheight=temp64.LowPart;
607 subtype.Data1=D3DFMT_X8R8G8B8;
608 mfmediatype->GetGUID(MF_MT_SUBTYPE,&subtype);
609 D3DFORMAT format=(D3DFORMAT)subtype.Data1;
610 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Surfaceformat is %d, width %d, height %d",format,vwidth,vheight);
611 format=D3DFMT_X8R8G8B8;
615 WindowsOsd* osdwin = dynamic_cast<WindowsOsd*>(Osd::getInstance());
616 LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev();
617 osdwin->BeginPainting();
619 for (int i=0;i<10;i++)
622 LPDIRECT3DSURFACE9 surfy;
624 hres=d3ddev->CreateRenderTarget(vwidth,vheight,format,
625 D3DMULTISAMPLE_NONE,0,FALSE,&surfy,NULL);
635 osdwin->EndPainting();
639 for (int i=0;i<surfaces.size();i++) {
640 if (surfaces[i]!=NULL)
642 IMFSample *sample=NULL;
643 ptrMFCreateVideoSampleFromSurface(surfaces[i],&sample);
644 if (sample) emptyevrsamples.push(sample);
651 void DsAllocator::FlushEVRSamples()
654 while(fullevrsamples.size()>0)
656 IMFSample *sample=fullevrsamples.front();
657 fullevrsamples.pop();
658 emptyevrsamples.push(sample);
664 void DsAllocator::GetNextSurface(LPDIRECT3DSURFACE9* surf,DWORD *waittime)
670 if (fullevrsamples.size()==0) {
672 if (start_get_evr_samples) GetEVRSamples();
674 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Enter Get Next Surface");
676 while (fullevrsamples.size()>0)
678 //MessageBox(0,"Got a sample","got a sample",0);
679 IMFSample *sample=fullevrsamples.front();
682 LONGLONG currenttime=0;
684 HRESULT hres=sample->GetSampleTime(&prestime);
687 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
689 LONGLONG delta=prestime-currenttime;
693 if (delta<-10000*20 && false) { //SkipIT
694 LONGLONG latency=-delta;
695 //mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
696 LARGE_INTEGER helper;
697 helper.QuadPart=-delta;
698 Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d prestime %lld",helper.LowPart,helper.HighPart,prestime);
699 CalcSyncOffsets(delta/10000LL);
700 // emptyevrsamples.size(),fullevrsamples.size());
701 fullevrsamples.pop();
702 emptyevrsamples.push(sample);
707 if (delta<10000*20 || !mfclock )
710 IMFMediaBuffer* buffy=NULL;
711 //MessageBox(0,"its showtime","showtimw",0);
712 CalcSyncOffsets(delta/10000LL);
714 hres=sample->GetBufferByIndex(0,&buffy);
715 //LARGE_INTEGER helper;
716 //helper.QuadPart=-delta;
717 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Paint 1 frame %d %d, frames %d prestime %lld",
718 // helper.LowPart,helper.HighPart,fullevrsamples.size(),prestime);
719 if (hres!=S_OK) { //SkipIT
720 fullevrsamples.pop();
721 emptyevrsamples.push(sample);
724 IMFGetService* service;
725 hres=buffy->QueryInterface(IID_IMFGetService,(void**)&service);
727 if (hres!=S_OK) { //SkipIT
728 fullevrsamples.pop();
729 emptyevrsamples.push(sample);
732 LPDIRECT3DSURFACE9 tempsurf;
733 hres=service->GetService(MR_BUFFER_SERVICE,IID_IDirect3DSurface9 ,(void**) &tempsurf);
735 if (hres!=S_OK) { //SkipIT
736 fullevrsamples.pop();
737 emptyevrsamples.push(sample);
743 *waittime=delta/10000-10;
753 void DsAllocator::DiscardSurfaceandgetWait(DWORD *waittime)
755 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait");
756 if (start_get_evr_samples) GetEVRSamples();
757 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait2");
759 if (fullevrsamples.size()==0) {
764 IMFSample *sample=fullevrsamples.front();
765 fullevrsamples.pop();
766 emptyevrsamples.push(sample);
769 while (fullevrsamples.size()>0)
772 IMFSample *sample=fullevrsamples.front();
775 LONGLONG currenttime=0;
777 HRESULT hres=sample->GetSampleTime(&prestime);
780 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
782 LONGLONG delta=prestime-currenttime;
785 if (delta<-10000*20 ) { //SkipIT
786 LONGLONG latency=-delta;
787 // mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
788 //LARGE_INTEGER helper;
789 //helper.QuadPart=-delta;
790 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d time %lld",helper.LowPart,helper.HighPart,prestime);
791 CalcSyncOffsets(delta/10000LL);
792 // emptyevrsamples.size(),fullevrsamples.size());
793 fullevrsamples.pop();
794 emptyevrsamples.push(sample);
799 *waittime=min(delta/10000/2-10,1);
806 void DsAllocator::ResetSyncOffsets()
808 for (int i=0;i<n_stats;i++)
824 void DsAllocator::CalcSyncOffsets(int sync)
826 sync_offset[sync_pos]=sync;
827 sync_pos=(sync_pos +1)%n_stats;
830 for (int i=0;i<n_stats;i++)
832 mean_value+=sync_offset[i];
834 mean_value/=(double) n_stats;
836 for (int i=0;i<n_stats;i++)
838 double temp_dev=(mean_value-(double)sync_offset[i]);
839 std_dev+=temp_dev*temp_dev;
841 std_dev/=(double)n_stats;
842 avg_sync_offset=mean_value;
843 dev_sync_offset=sqrt(std_dev);
846 void DsAllocator::CalcJitter(int jitter)
848 jitter_offset[jitter_pos]=jitter;
849 jitter_pos=(jitter_pos +1)%n_stats;
853 for (int i=0;i<n_stats;i++)
855 mean_value+=jitter_offset[i];
857 mean_value/=(double) n_stats;
858 avgfps=1000./mean_value*100.;
860 for (int i=0;i<n_stats;i++)
862 double temp_dev=(mean_value-(double)jitter_offset[i]);
863 std_dev+=temp_dev*temp_dev;
865 std_dev/=(double)n_stats;
866 jitter=sqrt(std_dev);
870 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDrawn(int *val)
876 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgFrameRate(int *val)
882 HRESULT STDMETHODCALLTYPE DsAllocator::get_Jitter(int *val)
888 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgSyncOffset(int *val)
890 *val=avg_sync_offset;
894 HRESULT STDMETHODCALLTYPE DsAllocator::get_DevSyncOffset(int *val)
896 *val=dev_sync_offset;
899 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDroppedInRenderer(int *val)