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() {
52 DsAllocator::~DsAllocator() {
53 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
54 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
59 void DsAllocator::CleanupSurfaces() {
61 while(fullevrsamples.size()>0)
63 IMFSample *sample=fullevrsamples.front();
67 while(emptyevrsamples.size()>0)
69 IMFSample *sample=emptyevrsamples.front();
70 emptyevrsamples.pop();
74 for (int i=0;i<surfaces.size();i++) {
75 if (surfaces[i]!=NULL) surfaces[i]->Release();
81 HRESULT STDMETHODCALLTYPE DsAllocator::InitializeDevice(DWORD_PTR userid,VMR9AllocationInfo* allocinf,DWORD*numbuf){
82 if (!surfallocnotify) return S_FALSE;
86 surfaces.resize(*numbuf);
87 HRESULT hres= surfallocnotify->AllocateSurfaceHelper(allocinf,numbuf,&surfaces.at(0));
88 vheight=allocinf->dwHeight;
89 vwidth=allocinf->dwWidth;
92 sprintf(buffer,"%d * %d",allocinf->dwWidth,allocinf->dwHeight);
93 MessageBox(0,"hi",buffer,0);*/
97 void DsAllocator::LostDevice(IDirect3DDevice9 *d3ddev, IDirect3D9* d3d) {
98 if (!surfallocnotify) return ;
101 // d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
102 HMONITOR hmon=d3d->GetAdapterMonitor(D3DADAPTER_DEFAULT);
103 surfallocnotify->ChangeD3DDevice(d3ddev,hmon);
108 HRESULT STDMETHODCALLTYPE DsAllocator::TerminateDevice(DWORD_PTR userid){
111 return S_OK; //Do nothing
113 HRESULT STDMETHODCALLTYPE DsAllocator::GetSurface(DWORD_PTR userid,DWORD surfindex,DWORD surfflags, IDirect3DSurface9** surf)
115 if (surfindex>=surfaces.size()) return E_FAIL;
116 if (surf==NULL) return E_POINTER;
119 surfaces[surfindex]->AddRef();
120 *surf=surfaces[surfindex];
124 HRESULT STDMETHODCALLTYPE DsAllocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* allnoty){
126 surfallocnotify=allnoty;
127 IDirect3DDevice9 *d3ddev;
128 //OK lets set the direct3d object from the osd
129 d3ddev=((OsdWin*)Osd::getInstance())->getD3dDev();
130 HMONITOR hmon=((OsdWin*)Osd::getInstance())->getD3d()->GetAdapterMonitor(D3DADAPTER_DEFAULT);
131 HRESULT hres=surfallocnotify->SetD3DDevice(d3ddev,hmon);
137 HRESULT STDMETHODCALLTYPE DsAllocator::StartPresenting(DWORD_PTR userid){
138 //MessageBox(0,"drive me","drive me",0);
139 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
143 HRESULT STDMETHODCALLTYPE DsAllocator::StopPresenting(DWORD_PTR userid){
144 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0);
148 HRESULT STDMETHODCALLTYPE DsAllocator::PresentImage(DWORD_PTR userid,VMR9PresentationInfo* presinf){
149 ((OsdWin*)Osd::getInstance())->RenderDS(presinf->lpSurf); //render and return
154 HRESULT STDMETHODCALLTYPE DsAllocator::QueryInterface(REFIID refiid,void ** obj){
155 if (obj==NULL) return E_POINTER;
157 if (refiid==IID_IVMRSurfaceAllocator9) {
158 *obj=static_cast<IVMRSurfaceAllocator9*>(this);
161 } else if (refiid==IID_IVMRImagePresenter9) {
162 *obj=static_cast<IVMRImagePresenter9*>(this);
165 } else if (refiid==IID_IMFVideoDeviceID) {
166 *obj=static_cast<IMFVideoDeviceID*> (this);
169 } else if (refiid==IID_IMFTopologyServiceLookupClient ) {
170 *obj=static_cast<IMFTopologyServiceLookupClient*> (this);
173 } else if (refiid==IID_IQualProp ) {
174 *obj=static_cast<IQualProp*> (this);
177 } else if (refiid==IID_IMFGetService) {
178 *obj=static_cast<IMFGetService*> (this);
181 } else if (refiid==IID_IDirect3DDeviceManager9) {
182 IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan();
184 return d3dman->QueryInterface(refiid,obj);
188 return E_NOINTERFACE;
191 return E_NOINTERFACE;
196 ULONG STDMETHODCALLTYPE DsAllocator::AddRef(){
197 return InterlockedIncrement(&refcount);
200 ULONG STDMETHODCALLTYPE DsAllocator::Release(){
202 ref=InterlockedDecrement(&refcount);
204 delete this; //Commit suicide
209 HRESULT STDMETHODCALLTYPE DsAllocator::GetDeviceID(IID *pDid)
214 *pDid=__uuidof(IDirect3DDevice9);
218 HRESULT STDMETHODCALLTYPE DsAllocator::InitServicePointers(IMFTopologyServiceLookup *plooky)
220 if (!plooky) return E_POINTER;
223 /* get all interfaces we need*/
226 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_MIXER_SERVICE,
227 __uuidof(IMFTransform),(void**)&mftransform, &dwobjcts);
228 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL,0,MR_VIDEO_RENDER_SERVICE,
229 __uuidof(IMediaEventSink),(void**)&mediasink, &dwobjcts);
230 plooky->LookupService(MF_SERVICE_LOOKUP_GLOBAL, 0, MR_VIDEO_RENDER_SERVICE,
231 __uuidof(IMFClock),(void**)&mfclock,&dwobjcts);
238 HRESULT STDMETHODCALLTYPE DsAllocator::ReleaseServicePointers()
242 /* TODO Set RenderState , sample type etc.*/
244 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,0,0);
246 if (mftransform) mftransform->Release();
249 if (mediasink) mediasink->Release();
252 if (mfclock) mfclock->Release();
254 if (mfmediatype) mfmediatype->Release();
261 HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &iid,LPVOID *obj)
263 if (guid==MR_VIDEO_ACCELERATION_SERVICE)
265 IDirect3DDeviceManager9 *d3dman=((OsdWin*)Osd::getInstance())->getD3dMan();
268 return d3dman->QueryInterface (__uuidof(IDirect3DDeviceManager9), (void**) obj);
272 return E_NOINTERFACE;
276 else if (guid==MR_VIDEO_RENDER_SERVICE)
278 return QueryInterface(iid,obj);
282 return E_NOINTERFACE;
287 void DsAllocator::GetEVRSamples()
289 MFCLOCK_STATE clockstate;
290 if (mfclock) mfclock->GetState(0,&clockstate);
291 //MessageBox(0,"get samples","samples",0);
293 if (mfclock && clockstate==MFCLOCK_STATE_STOPPED && fullevrsamples.size()>0)
299 while (emptyevrsamples.size()>0)
302 MFT_OUTPUT_DATA_BUFFER outdatabuffer;
303 ZeroMemory(&outdatabuffer,sizeof(outdatabuffer));
304 outdatabuffer.pSample=emptyevrsamples.front();
306 LONGLONG starttime,endtime;
313 mfclock->GetCorrelatedTime(0,&starttime,&dummy);
314 if (lastdelframe) CalcJitter( (starttime-lastdelframe)/10000);
315 lastdelframe=starttime;
318 HRESULT hres=mftransform->ProcessOutput(0,1,&outdatabuffer,&status);
321 if (hres==MF_E_TRANSFORM_NEED_MORE_INPUT)
327 mediasink->Notify(EC_COMPLETE,(LONG_PTR) S_OK,0);
332 else if (hres==MF_E_TRANSFORM_STREAM_CHANGE)
334 if (mfmediatype) mfmediatype->Release();
338 else if (hres==MF_E_TRANSFORM_TYPE_NOT_SET)
340 if (mfmediatype) mfmediatype->Release();
342 RenegotiateEVRMediaType();
348 hres=outdatabuffer.pSample->GetSampleTime(&prestime);
349 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Got EVR Sample %lld",prestime);
350 IMFSample *temp=emptyevrsamples.front();
351 emptyevrsamples.pop();
355 fullevrsamples.push(temp);
356 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "got evr sample %d, %d",
357 // emptyevrsamples.size(),fullevrsamples.size());
359 mfclock->GetCorrelatedTime(0,&endtime,&dummy);
360 LONGLONG delay=endtime-starttime;
361 mediasink->Notify( EC_PROCESSING_LATENCY,(LONG_PTR)&delay,0);
369 HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULONG_PTR mess_para)
372 case MFVP_MESSAGE_FLUSH:{
373 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_FLUSH received");
374 FlushEVRSamples(); }break;
375 case MFVP_MESSAGE_INVALIDATEMEDIATYPE: {
376 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_INVALIDATEMEDIATYPE received");
377 if (mfmediatype) mfmediatype->Release();
379 RenegotiateEVRMediaType();}break;
380 case MFVP_MESSAGE_PROCESSINPUTNOTIFY: {
381 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_PROCESSINPUTNOTIFY received");
382 GetEVRSamples(); } break;
383 case MFVP_MESSAGE_BEGINSTREAMING:{
384 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received");
386 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
387 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
390 case MFVP_MESSAGE_ENDSTREAMING: {
391 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received");
392 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
393 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
395 //if (mfmediatype) mfmediatype->Release();
398 case MFVP_MESSAGE_ENDOFSTREAM: {
399 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDOFSTREAM received");
400 MessageBox(0,"endofstream","endofstream",0);
403 case MFVP_MESSAGE_STEP: {
404 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_STEP received");
405 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
406 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause);
407 MessageBox(0,"steppy","steppy",0);
408 FlushEVRSamples(/*LOWORD(mess_para)*/); //Message sending, has to be done after compeletion
410 case MFVP_MESSAGE_CANCELSTEP: {
411 Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_CANCELSTEP received");
415 MessageBox(0,"unhandled","unhandled",0);
420 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG startoffset)
422 //((OsdWin*)Osd::getInstance())->SetEVRTimes(systime,startoffset);
425 if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples();
426 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
427 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
433 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime)
437 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off);
438 ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight);
443 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime)
446 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
447 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause);
451 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime)
453 ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight);
454 ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);
459 HRESULT STDMETHODCALLTYPE DsAllocator::OnClockSetRate(MFTIME systime,float rate)
465 HRESULT STDMETHODCALLTYPE DsAllocator::GetCurrentMediaType(IMFVideoMediaType **mtype)
466 { MessageBox(0,"mediatype","mediatype",0);
467 if (mtype==NULL) return E_POINTER;
469 if (mfmediatype==NULL)
473 return MF_E_NOT_INITIALIZED;
475 HRESULT hres=mfmediatype->QueryInterface(IID_IMFVideoMediaType,(void**)mtype);
480 void DsAllocator::RenegotiateEVRMediaType()
483 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Cannot renegotiate without transform!");
491 IMFMediaType *mixtype=NULL;
493 if (hres=mftransform->GetOutputAvailableType(0,index++,&mixtype)!=S_OK)
495 Log::getInstance()->log("DsAllocator", Log::DEBUG , "No more types availiable from EVR %d !",hres);
501 mixtype->IsCompressedFormat(&compressed);
508 mixtype->GetUINT32(MF_MT_INTERLACE_MODE,&helper);
509 if (helper!=MFVideoInterlace_Progressive) {
510 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type interlaced!");
515 mixtype->GetMajorType(&temp);
516 if (temp!=MEDIATYPE_Video) {
517 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type no video!");
521 if(mftransform->SetOutputType(0,mixtype,MFT_SET_TYPE_TEST_ONLY)!=S_OK)
523 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Skip media type test failed!");
532 if (mfmediatype) mfmediatype->Release();
536 AllocateEVRSurfaces();
539 hres=mftransform->SetOutputType(0,mixtype,0);
546 if (mfmediatype) mfmediatype->Release();
554 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Output type set! %d",hres);
556 if (!gotcha) Log::getInstance()->log("DsAllocator", Log::DEBUG , "No suitable output type!");
562 void DsAllocator::AllocateEVRSurfaces()
565 LARGE_INTEGER temp64;
566 mfmediatype->GetUINT64(MF_MT_FRAME_SIZE, (UINT64*)&temp64);
567 vwidth=temp64.HighPart;
568 vheight=temp64.LowPart;
570 subtype.Data1=D3DFMT_X8R8G8B8;
571 mfmediatype->GetGUID(MF_MT_SUBTYPE,&subtype);
572 D3DFORMAT format=(D3DFORMAT)subtype.Data1;
573 Log::getInstance()->log("DsAllocator", Log::DEBUG , "Surfaceformat is %d, width %d, height %d",format,vwidth,vheight);
574 format=D3DFMT_X8R8G8B8;
578 OsdWin* osdwin=(OsdWin*)Osd::getInstance();
579 LPDIRECT3DDEVICE9 d3ddev=osdwin->getD3dDev();
580 osdwin->BeginPainting();
582 for (int i=0;i<10;i++)
585 LPDIRECT3DSURFACE9 surfy;
587 hres=d3ddev->CreateRenderTarget(vwidth,vheight,format,
588 D3DMULTISAMPLE_NONE,0,FALSE,&surfy,NULL);
598 osdwin->EndPainting();
602 for (int i=0;i<surfaces.size();i++) {
603 if (surfaces[i]!=NULL)
605 IMFSample *sample=NULL;
606 ptrMFCreateVideoSampleFromSurface(surfaces[i],&sample);
607 if (sample) emptyevrsamples.push(sample);
614 void DsAllocator::FlushEVRSamples()
617 while(fullevrsamples.size()>0)
619 IMFSample *sample=fullevrsamples.front();
620 fullevrsamples.pop();
621 emptyevrsamples.push(sample);
627 void DsAllocator::GetNextSurface(LPDIRECT3DSURFACE9* surf,DWORD *waittime)
632 if (fullevrsamples.size()==0) GetEVRSamples();
634 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Enter Get Next Surface");
636 while (fullevrsamples.size()>0)
638 //MessageBox(0,"Got a sample","got a sample",0);
639 IMFSample *sample=fullevrsamples.front();
642 LONGLONG currenttime=0;
644 HRESULT hres=sample->GetSampleTime(&prestime);
647 if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime);
649 LONGLONG delta=prestime-currenttime;
653 if (delta<-10000*20 && false) { //SkipIT
654 LONGLONG latency=-delta;
655 //mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
656 LARGE_INTEGER helper;
657 helper.QuadPart=-delta;
658 Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d prestime %lld",helper.LowPart,helper.HighPart,prestime);
659 CalcSyncOffsets(delta/10000LL);
660 // emptyevrsamples.size(),fullevrsamples.size());
661 fullevrsamples.pop();
662 emptyevrsamples.push(sample);
667 if (delta<10000*20 || !mfclock )
670 IMFMediaBuffer* buffy=NULL;
671 //MessageBox(0,"its showtime","showtimw",0);
672 CalcSyncOffsets(delta/10000LL);
674 hres=sample->GetBufferByIndex(0,&buffy);
675 //LARGE_INTEGER helper;
676 //helper.QuadPart=-delta;
677 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Paint 1 frame %d %d, frames %d prestime %lld",
678 // helper.LowPart,helper.HighPart,fullevrsamples.size(),prestime);
679 if (hres!=S_OK) { //SkipIT
680 fullevrsamples.pop();
681 emptyevrsamples.push(sample);
684 IMFGetService* service;
685 hres=buffy->QueryInterface(IID_IMFGetService,(void**)&service);
687 if (hres!=S_OK) { //SkipIT
688 fullevrsamples.pop();
689 emptyevrsamples.push(sample);
692 LPDIRECT3DSURFACE9 tempsurf;
693 hres=service->GetService(MR_BUFFER_SERVICE,IID_IDirect3DSurface9 ,(void**) &tempsurf);
695 if (hres!=S_OK) { //SkipIT
696 fullevrsamples.pop();
697 emptyevrsamples.push(sample);
703 *waittime=delta/10000-10;
713 void DsAllocator::DiscardSurfaceandgetWait(DWORD *waittime)
715 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait");
717 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "Discard surface and get Wait2");
719 if (fullevrsamples.size()==0) {
724 IMFSample *sample=fullevrsamples.front();
725 fullevrsamples.pop();
726 emptyevrsamples.push(sample);
729 while (fullevrsamples.size()>0)
732 IMFSample *sample=fullevrsamples.front();
735 LONGLONG currenttime=0;
737 HRESULT hres=sample->GetSampleTime(&prestime);
740 mfclock->GetCorrelatedTime(0,¤ttime,&systime);
742 LONGLONG delta=prestime-currenttime;
745 if (delta<-10000*20 ) { //SkipIT
746 LONGLONG latency=-delta;
747 // mediasink->Notify(EC_SAMPLE_LATENCY,(LONG_PTR) &latency,0);
748 //LARGE_INTEGER helper;
749 //helper.QuadPart=-delta;
750 //Log::getInstance()->log("DsAllocator", Log::DEBUG , "skip 1 frame %d %d time %lld",helper.LowPart,helper.HighPart,prestime);
751 CalcSyncOffsets(delta/10000LL);
752 // emptyevrsamples.size(),fullevrsamples.size());
753 fullevrsamples.pop();
754 emptyevrsamples.push(sample);
759 *waittime=min(delta/10000/2-10,1);
766 void DsAllocator::ResetSyncOffsets()
768 for (int i=0;i<n_stats;i++)
784 void DsAllocator::CalcSyncOffsets(int sync)
786 sync_offset[sync_pos]=sync;
787 sync_pos=(sync_pos +1)%n_stats;
790 for (int i=0;i<n_stats;i++)
792 mean_value+=sync_offset[i];
794 mean_value/=(double) n_stats;
796 for (int i=0;i<n_stats;i++)
798 double temp_dev=(mean_value-(double)sync_offset[i]);
799 std_dev+=temp_dev*temp_dev;
801 std_dev/=(double)n_stats;
802 avg_sync_offset=mean_value;
803 dev_sync_offset=sqrt(std_dev);
806 void DsAllocator::CalcJitter(int jitter)
808 jitter_offset[jitter_pos]=jitter;
809 jitter_pos=(jitter_pos +1)%n_stats;
813 for (int i=0;i<n_stats;i++)
815 mean_value+=jitter_offset[i];
817 mean_value/=(double) n_stats;
818 avgfps=1000./mean_value*100.;
820 for (int i=0;i<n_stats;i++)
822 double temp_dev=(mean_value-(double)jitter_offset[i]);
823 std_dev+=temp_dev*temp_dev;
825 std_dev/=(double)n_stats;
826 jitter=sqrt(std_dev);
830 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDrawn(int *val)
836 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgFrameRate(int *val)
842 HRESULT STDMETHODCALLTYPE DsAllocator::get_Jitter(int *val)
848 HRESULT STDMETHODCALLTYPE DsAllocator::get_AvgSyncOffset(int *val)
850 *val=avg_sync_offset;
854 HRESULT STDMETHODCALLTYPE DsAllocator::get_DevSyncOffset(int *val)
856 *val=dev_sync_offset;
859 HRESULT STDMETHODCALLTYPE DsAllocator::get_FramesDroppedInRenderer(int *val)