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 "dsallocator.h"
32 typedef HRESULT (__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);
34 extern FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface;
37 DsAllocator::DsAllocator() {
46 start_get_evr_samples=false;
53 DsAllocator::~DsAllocator() {
54 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
55 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
60 void DsAllocator::CleanupSurfaces() {
62 while(fullevrsamples.size()>0)
64 IMFSample *sample=fullevrsamples.front();
68 while(emptyevrsamples.size()>0)
70 IMFSample *sample=emptyevrsamples.front();
71 emptyevrsamples.pop();
75 for (int i=0;i<surfaces.size();i++) {
76 if (surfaces[i]!=NULL) surfaces[i]->Release();
79 start_get_evr_samples=false;
83 HRESULT STDMETHODCALLTYPE DsAllocator::InitializeDevice(DWORD_PTR userid,VMR9AllocationInfo* allocinf,DWORD*numbuf){
84 if (!surfallocnotify) return S_FALSE;
88 surfaces.resize(*numbuf);
89 HRESULT hres= surfallocnotify->AllocateSurfaceHelper(allocinf,numbuf,&surfaces.at(0));
90 vheight=allocinf->dwHeight;
91 vwidth=allocinf->dwWidth;
92 start_get_evr_samples=false;
95 sprintf(buffer,"%d * %d",allocinf->dwWidth,allocinf->dwHeight);
96 MessageBox(0,"hi",buffer,0);*/
100 void DsAllocator::LostDevice(IDirect3DDevice9 *d3ddev, IDirect3D9* d3d) {
101 if (!surfallocnotify) return ;
104 // d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
105 HMONITOR hmon=d3d->GetAdapterMonitor(D3DADAPTER_DEFAULT);
106 surfallocnotify->ChangeD3DDevice(d3ddev,hmon);
111 HRESULT STDMETHODCALLTYPE DsAllocator::TerminateDevice(DWORD_PTR userid){
114 return S_OK; //Do nothing
116 HRESULT STDMETHODCALLTYPE DsAllocator::GetSurface(DWORD_PTR userid,DWORD surfindex,DWORD surfflags, IDirect3DSurface9** surf)
118 if (surfindex>=surfaces.size()) return E_FAIL;
119 if (surf==NULL) return E_POINTER;
122 surfaces[surfindex]->AddRef();
123 *surf=surfaces[surfindex];
127 HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* allnoty){
129 surfallocnotify=allnoty;
130 IDirect3DDevice9 *d3ddev;
131 //OK lets set the direct3d object from the osd
132 d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
133 HMONITOR hmon=((OsdWin*)Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT);
134 HRESULT hres=surfallocnotify->SetD3DDevice(d3ddev,hmon);
140 HRESULT STDMETHODCALLTYPE DsAllocator::StartPresenting(DWORD_PTR userid){
141 //MessageBox(0,"drive me","drive me",0);
142 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
143 start_get_evr_samples=false;
147 HRESULT STDMETHODCALLTYPE DsAllocator::StopPresenting(DWORD_PTR userid){
148 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0);
149 start_get_evr_samples=false;
153 HRESULT STDMETHODCALLTYPE DsAllocator::PresentImage(DWORD_PTR userid,VMR9PresentationInfo* presinf){
154 ((OsdWin*)Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return
159 HRESULT STDMETHODCALLTYPE DsAllocator::QueryInterface(REFIID refiid,void ** obj){
160 if (obj==NULL) return E_POINTER;
162 if (refiid==IID_IVMRSurfaceAllocator9) {
163 *obj=static_cast<IVMRSurfaceAllocator9*>(this);
166 } else if (refiid==IID_IVMRImagePresenter9) {
167 *obj=static_cast<IVMRImagePresenter9*>(this);
170 } else if (refiid==IID_IMFVideoDeviceID) {
171 *obj=static_cast<IMFVideoDeviceID*> (this);
174 } else if (refiid==IID_IMFTopologyServiceLookupClient ) {
175 *obj=static_cast<IMFTopologyServiceLookupClient*> (this);
178 } else if (refiid==IID_IQualProp ) {
179 *obj=static_cast<IQualProp*> (this);
182 } else if (refiid==IID_IMFGetService) {
183 *obj=static_cast<IMFGetService*> (this);
186 } else if (refiid==IID_IDirect3DDeviceManager9) {
187 IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan();
189 return d3dman->QueryInterface(refiid,obj);
193 return E_NOINTERFACE;
196 return E_NOINTERFACE;
201 ULONG STDMETHODCALLTYPE DsAllocator::AddRef(){
202 return InterlockedIncrement(&refcount);
205 ULONG STDMETHODCALLTYPE DsAllocator::Release(){
207 ref=InterlockedDecrement(&refcount);
209 delete this; //Commit suicide
214 HRESULT STDMETHODCALLTYPE DsAllocator::GetDeviceID(IID *pDid)
219 *pDid=__uuidof(IDirect3DDevice9);
223 HRESULT STDMETHODCALLTYPE DsAllocator::InitServicePointers(IMFTopologyServiceLookup *plooky)
225 if (!plooky) return E_POINTER;
228 /* get all interfaces we need*/
231 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_MIXER_SERVICE,
232 __uuidof(IMFTransform),(void**)&mftransform, &dwobjcts);
233 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_RENDER_SERVICE,
234 __uuidof(IMediaEventSink),(void**)&mediasink, &dwobjcts);
235 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
236 __uuidof(IMFClock),(void**)&mfclock,&dwobjcts);
243 HRESULT STDMETHODCALLTYPE DsAllocator::ReleaseServicePointers()
247 /* TODO Set RenderState , sample type etc.*/
249 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0);
251 if (mftransform) mftransform->Release();
254 if (mediasink) mediasink->Release();
257 if (mfclock) mfclock->Release();
259 if (mfmediatype) mfmediatype->Release();
266 HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &iid,LPVOID *obj)
268 if (guid==MR_VIDEO_ACCELERATION_SERVICE)
270 IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan();
273 return d3dman->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) obj);
277 return E_NOINTERFACE;
281 else if (guid==MR_VIDEO_RENDER_SERVICE)
283 return QueryInterface(iid,obj);
287 return E_NOINTERFACE;
292 void DsAllocator::GetEVRSamples()
295 MFCLOCK_STATE clockstate;
296 if (mfclock) mfclock->GetState(0,&clockstate);
297 //MessageBox(0,"get samples","samples",0);
299 if (mfclock && clockstate==MFCLOCK_STATE_STOPPED && fullevrsamples.size()>0)
305 while (emptyevrsamples.size()>0)
308 MFT_OUTPUT_DATA_BUFFER outdatabuffer;
309 ZeroMemory(&outdatabuffer,sizeof(outdatabuffer));
310 outdatabuffer.pSample=emptyevrsamples.front();
312 LONGLONG starttime,endtime;
319 mfclock->GetCorrelatedTime(0,&starttime,&dummy);
320 if (lastdelframe) CalcJitter( (starttime-lastdelframe)/10000);
321 lastdelframe=starttime;
324 HRESULT hres=mftransform->ProcessOutput(0,1,&outdatabuffer,&status);
327 if (hres==MF_E_TRANSFORM_NEED_MORE_INPUT)
333 mediasink->Notify(EC_COMPLETE,(LONG_PTR) S_OK,0);
338 else if (hres==MF_E_TRANSFORM_STREAM_CHANGE)
340 if (mfmediatype) mfmediatype->Release();
344 else if (hres==MF_E_TRANSFORM_TYPE_NOT_SET)
346 if (mfmediatype) mfmediatype->Release();
348 RenegotiateEVRMediaType();
354 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
355 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Got EVR Sample %lld",prestime);
356 IMFSample *temp=emptyevrsamples.front();
357 emptyevrsamples.pop();
361 fullevrsamples.push(temp);
362 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "got evr sample %d, %d",
363 // emptyevrsamples.size(),fullevrsamples.size());
365 mfclock->GetCorrelatedTime(0,&endtime,&dummy);
366 LONGLONG delay=endtime-starttime;
367 mediasink->Notify( EC_PROCESSING_LATENCY,(LONG_PTR)&delay,0);
369 //Check if presentation is soon
371 LONGLONG currenttime=0;
372 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
375 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
377 LONGLONG delta=prestime-currenttime;
379 break; //break if presentation is soon
390 HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULONG_PTR mess_para)
393 case MFVP_MESSAGE_FLUSH:{
394 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_FLUSH received");
396 start_get_evr_samples=false;
398 case MFVP_MESSAGE_INVALIDATEMEDIATYPE: {
399 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_INVALIDATEMEDIATYPE received");
400 if (mfmediatype) mfmediatype->Release();
402 start_get_evr_samples=false;
403 RenegotiateEVRMediaType();}break;
404 case MFVP_MESSAGE_PROCESSINPUTNOTIFY: {
405 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_PROCESSINPUTNOTIFY received");
406 if (!start_get_evr_samples) GetEVRSamples();
407 start_get_evr_samples=true;
409 case MFVP_MESSAGE_BEGINSTREAMING:{
410 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received");
412 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
413 //((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);//No need to do this causes misbehaviout
416 case MFVP_MESSAGE_ENDSTREAMING: {
417 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received");
418 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
419 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
420 start_get_evr_samples=false;
422 //if (mfmediatype) mfmediatype->Release();
425 case MFVP_MESSAGE_ENDOFSTREAM: {
426 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDOFSTREAM received");
427 MessageBox(0,"endofstream","endofstream",0);
429 start_get_evr_samples=false;
431 case MFVP_MESSAGE_STEP: {
432 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_STEP received");
433 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
434 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause);
435 MessageBox(0,"steppy","steppy",0);
436 FlushEVRSamples(/*LOWORD(mess_para)*/); //Message sending, has to be done after compeletion
438 case MFVP_MESSAGE_CANCELSTEP: {
439 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_CANCELSTEP received");
443 MessageBox(0,"unhandled","unhandled",0);
448 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG startoffset)
450 //((OsdWin*)Osd::getInstance())->SetEVRTimes(systime,startoffset);
453 if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples();
454 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
455 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart");
456 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
462 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime)
466 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
468 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop");
469 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
474 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime)
477 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
479 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause");
480 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause);
484 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime)
486 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
488 Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart");
489 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
494 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockSetRate(MFTIME systime,float rate)
500 HRESULT STDMETHODCALLTYPE DsAllocator::GetCurrentMediaType(IMFVideoMediaType **mtype)
501 { MessageBox(0,"mediatype","mediatype",0);
502 if (mtype==NULL) return E_POINTER;
504 if (mfmediatype==NULL)
508 return MF_E_NOT_INITIALIZED;
510 HRESULT hres=mfmediatype->QueryInterface(IID_IMFVideoMediaType,(void**)mtype);
515 void DsAllocator::RenegotiateEVRMediaType()
518 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Cannot renegotiate without transform!");
526 IMFMediaType *mixtype=NULL;
528 if (hres=mftransform->GetOutputAvailableType(0,index++,&mixtype)!=S_OK)
530 Log::getInstance()->log("DsAllocator", Log::DEBUG , "No more types availiable from EVR %d !",hres);
536 mixtype->IsCompressedFormat(&compressed);
543 mixtype->GetUINT32(MF_MT_INTERLACE_MODE,&helper);
544 if (helper!=MFVideoInterlace_Progressive) {
545 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type interlaced!");
550 mixtype->GetMajorType(&temp);
551 if (temp!=MEDIATYPE_Video) {
552 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type no video!");
556 if(mftransform->SetOutputType(0,mixtype,MFT_SET_TYPE_TEST_ONLY)!=S_OK)
558 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type test failed!");
567 if (mfmediatype) mfmediatype->Release();
571 AllocateEVRSurfaces();
574 hres=mftransform->SetOutputType(0,mixtype,0);
581 if (mfmediatype) mfmediatype->Release();
589 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Output type set! %d",hres);
591 if (!gotcha) Log::getInstance()->log("DsAllocator", Log::DEBUG , "No suitable output type!");
597 void DsAllocator::AllocateEVRSurfaces()
600 LARGE_INTEGER temp64;
601 mfmediatype->GetUINT64(MF_MT_FRAME_SIZE, (UINT64*)&temp64);
602 vwidth=temp64.HighPart;
603 vheight=temp64.LowPart;
605 subtype.Data1=D3DFMT_X8R8G8B8;
606 mfmediatype->GetGUID(MF_MT_SUBTYPE,&subtype);
607 D3DFORMAT format=(D3DFORMAT)subtype.Data1;
608 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Surfaceformat is %d, width %d, height %d",format,vwidth,vheight);
609 format=D3DFMT_X8R8G8B8;
613 OsdWin* osdwin=(OsdWin*)Osd::getInstance();
614 LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev();
615 osdwin->BeginPainting();
617 for (int i=0;i<10;i++)
620 LPDIRECT3DSURFACE9 surfy;
622 hres=d3ddev->CreateRenderTarget(vwidth,vheight,format,
623 D3DMULTISAMPLE_NONE,0,FALSE,&surfy,NULL);
633 osdwin->EndPainting();
637 for (int i=0;i<surfaces.size();i++) {
638 if (surfaces[i]!=NULL)
640 IMFSample *sample=NULL;
641 ptrMFCreateVideoSampleFromSurface(surfaces[i],&sample);
642 if (sample) emptyevrsamples.push(sample);
649 void DsAllocator::FlushEVRSamples()
652 while(fullevrsamples.size()>0)
654 IMFSample *sample=fullevrsamples.front();
655 fullevrsamples.pop();
656 emptyevrsamples.push(sample);
662 void DsAllocator::GetNextSurface(LPDIRECT3DSURFACE9* surf,DWORD *waittime)
668 if (fullevrsamples.size()==0) {
670 if (start_get_evr_samples) GetEVRSamples();
672 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Enter Get Next Surface");
674 while (fullevrsamples.size()>0)
676 //MessageBox(0,"Got a sample","got a sample",0);
677 IMFSample *sample=fullevrsamples.front();
680 LONGLONG currenttime=0;
682 HRESULT hres=sample->GetSampleTime(&prestime);
685 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
687 LONGLONG delta=prestime-currenttime;
691 if (delta<-10000*20 && false) { //SkipIT
692 LONGLONG latency=-delta;
693 //mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
694 LARGE_INTEGER helper;
695 helper.QuadPart=-delta;
696 Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d prestime %lld",helper.LowPart,helper.HighPart,prestime);
697 CalcSyncOffsets(delta/10000LL);
698 // emptyevrsamples.size(),fullevrsamples.size());
699 fullevrsamples.pop();
700 emptyevrsamples.push(sample);
705 if (delta<10000*20 || !mfclock )
708 IMFMediaBuffer* buffy=NULL;
709 //MessageBox(0,"its showtime","showtimw",0);
710 CalcSyncOffsets(delta/10000LL);
712 hres=sample->GetBufferByIndex(0,&buffy);
713 //LARGE_INTEGER helper;
714 //helper.QuadPart=-delta;
715 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Paint 1 frame %d %d, frames %d prestime %lld",
716 // helper.LowPart,helper.HighPart,fullevrsamples.size(),prestime);
717 if (hres!=S_OK) { //SkipIT
718 fullevrsamples.pop();
719 emptyevrsamples.push(sample);
722 IMFGetService* service;
723 hres=buffy->QueryInterface(IID_IMFGetService,(void**)&service);
725 if (hres!=S_OK) { //SkipIT
726 fullevrsamples.pop();
727 emptyevrsamples.push(sample);
730 LPDIRECT3DSURFACE9 tempsurf;
731 hres=service->GetService(MR_BUFFER_SERVICE,IID_IDirect3DSurface9 ,(void**) &tempsurf);
733 if (hres!=S_OK) { //SkipIT
734 fullevrsamples.pop();
735 emptyevrsamples.push(sample);
741 *waittime=delta/10000-10;
751 void DsAllocator::DiscardSurfaceandgetWait(DWORD *waittime)
753 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait");
754 if (start_get_evr_samples) GetEVRSamples();
755 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait2");
757 if (fullevrsamples.size()==0) {
762 IMFSample *sample=fullevrsamples.front();
763 fullevrsamples.pop();
764 emptyevrsamples.push(sample);
767 while (fullevrsamples.size()>0)
770 IMFSample *sample=fullevrsamples.front();
773 LONGLONG currenttime=0;
775 HRESULT hres=sample->GetSampleTime(&prestime);
778 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
780 LONGLONG delta=prestime-currenttime;
783 if (delta<-10000*20 ) { //SkipIT
784 LONGLONG latency=-delta;
785 // mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
786 //LARGE_INTEGER helper;
787 //helper.QuadPart=-delta;
788 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d time %lld",helper.LowPart,helper.HighPart,prestime);
789 CalcSyncOffsets(delta/10000LL);
790 // emptyevrsamples.size(),fullevrsamples.size());
791 fullevrsamples.pop();
792 emptyevrsamples.push(sample);
797 *waittime=min(delta/10000/2-10,1);
804 void DsAllocator::ResetSyncOffsets()
806 for (int i=0;i<n_stats;i++)
822 void DsAllocator::CalcSyncOffsets(int sync)
824 sync_offset[sync_pos]=sync;
825 sync_pos=(sync_pos +1)%n_stats;
828 for (int i=0;i<n_stats;i++)
830 mean_value+=sync_offset[i];
832 mean_value/=(double) n_stats;
834 for (int i=0;i<n_stats;i++)
836 double temp_dev=(mean_value-(double)sync_offset[i]);
837 std_dev+=temp_dev*temp_dev;
839 std_dev/=(double)n_stats;
840 avg_sync_offset=mean_value;
841 dev_sync_offset=sqrt(std_dev);
844 void DsAllocator::CalcJitter(int jitter)
846 jitter_offset[jitter_pos]=jitter;
847 jitter_pos=(jitter_pos +1)%n_stats;
851 for (int i=0;i<n_stats;i++)
853 mean_value+=jitter_offset[i];
855 mean_value/=(double) n_stats;
856 avgfps=1000./mean_value*100.;
858 for (int i=0;i<n_stats;i++)
860 double temp_dev=(mean_value-(double)jitter_offset[i]);
861 std_dev+=temp_dev*temp_dev;
863 std_dev/=(double)n_stats;
864 jitter=sqrt(std_dev);
868 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDrawn(int *val)
874 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgFrameRate(int *val)
880 HRESULT STDMETHODCALLTYPE DsAllocator::get_Jitter(int *val)
886 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgSyncOffset(int *val)
888 *val=avg_sync_offset;
892 HRESULT STDMETHODCALLTYPE DsAllocator::get_DevSyncOffset(int *val)
894 *val=dev_sync_offset;
897 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDroppedInRenderer(int *val)