2 Copyright 2004-2005 Chris Tallon
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.
25 #include "dssourcefilter.h"
26 #include "dsallocator.h"
30 #include "wwinvideofilter.h"
31 #include "wwinvideoh264filter.h"
33 #include "woptionpane.h"
56 lastaudiomode=MPTYPE_MPEG_AUDIO;
57 //lastaudiomode=MPTYPE_AC3;
59 filtermutex=CreateMutex(NULL,FALSE,NULL);
61 offsetvideonotset=true;
62 offsetaudionotset=true;
69 cur_audio_media_sample=NULL;
70 cur_video_media_sample=NULL;
75 aud_type=Audio::MPEG2_PES;
76 iframemode=false;//We are not in Iframe mode at begining
77 vmrdeinterlacing=2;//Best
78 videofilterselected=-1;
79 videoH264filterselected=-1;
80 OSVERSIONINFO verinfo;
81 verinfo.dwOSVersionInfoSize=sizeof(verinfo);
82 GetVersionEx(&verinfo);
84 if (verinfo.dwMajorVersion>=6) {
87 currentpresenter=VMR9;
89 videoH264dtsfix=false;
90 videompeg2dtsfix=false;
102 CloseHandle(filtermutex);
104 for (i=0;i<videofilterlist.size();i++)
106 if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
107 if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
109 videofilterlist.clear();
111 for (i=0;i<videoH264filterlist.size();i++)
113 if (videoH264filterlist[i].displayname) delete [] videoH264filterlist[i].displayname;
114 if (videoH264filterlist[i].friendlyname) delete [] videoH264filterlist[i].friendlyname;
116 videoH264filterlist.clear();
124 int VideoWin::init(UCHAR tformat)
126 if (initted) return 0;
129 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
131 vd.mode = Fullscreen;
132 initFilterDatabase();
133 initH264FilterDatabase();
135 if (!setFormat(tformat)){ shutdown(); return 0; }
141 int VideoWin::setTVsize(UCHAR ttvsize)
143 pseudotvsize=ttvsize;
147 int VideoWin::setDefaultAspect()
149 return setAspectRatio(Video::ASPECT4X3,parx,pary);
152 int VideoWin::shutdown()
154 if (!initted) return 0;
159 int VideoWin::setFormat(UCHAR tformat)
161 if (!initted) return 0;
162 if ((tformat != PAL) && (tformat != NTSC)) return 0;
178 int VideoWin::setConnection(UCHAR tconnection)
180 if (!initted) return 0;
181 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
182 connection = tconnection;
187 int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
189 if (!initted) return 0;
192 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
193 aspectRatio = taspectRatio;
198 int VideoWin::setMode(UCHAR tmode)
200 if (!initted) return 0;
202 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
204 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
205 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
206 if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
212 int VideoWin::signalOff()
217 int VideoWin::signalOn()
222 int VideoWin::setSource()
224 if (!initted) return 0;
232 if (!initted) return 0;
236 void VideoWin::initFilterDatabase()
238 /* This method should determine all availiable DirectShow Filters */
239 IFilterMapper2* filtmap=NULL;
241 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
242 IID_IFilterMapper2,(void**)&filtmap);
245 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
248 /* Wishlist, what Mediatypes do we want */
249 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
250 IEnumMoniker *myenum;
251 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
252 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
256 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
261 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
263 VideoFilterDesc desc;
264 ZeroMemory(&desc,sizeof(desc));
267 moni->GetDisplayName(0,0,&string);
268 desc.displayname=new char[wcslen(string)+1];
269 wcstombs(desc.displayname,string,wcslen(string)+1);
270 CoTaskMemFree(string);
272 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
276 result = bag->Read(L"FriendlyName",&vari,NULL);
279 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
280 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
288 videofilterlist.push_back(desc);
296 videofilterselected=-1;
307 void VideoWin::initH264FilterDatabase()
309 /* This method should determine all availiable DirectShow Filters */
310 IFilterMapper2* filtmap=NULL;
312 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
313 IID_IFilterMapper2,(void**)&filtmap);
316 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
319 /* Wishlist, what Mediatypes do we want */
320 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
321 IEnumMoniker *myenum;
322 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
323 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
327 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
332 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
334 VideoFilterDesc desc;
335 ZeroMemory(&desc,sizeof(desc));
338 moni->GetDisplayName(0,0,&string);
339 desc.displayname=new char[wcslen(string)+1];
340 wcstombs(desc.displayname,string,wcslen(string)+1);
341 CoTaskMemFree(string);
343 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
347 result = bag->Read(L"FriendlyName",&vari,NULL);
350 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
351 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
359 videoH264filterlist.push_back(desc);
367 videoH264filterselected=-1;
378 bool VideoWin::loadOptionsfromServer(VDR* vdr)
380 char *name=vdr->configLoad("DirectShow","VideoFilter");
384 for (int i = 0;i <videofilterlist.size();i++)
386 if (strcmp(name,videofilterlist[i].displayname)==0)
388 videofilterselected = i;
393 name=vdr->configLoad("DirectShow","VideoH264Filter");
397 for (int i = 0;i <videoH264filterlist.size();i++)
399 if (strcmp(name,videoH264filterlist[i].displayname)==0)
401 videoH264filterselected = i;
406 name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
409 if (STRCASECMP(name,"NoMix")==0) {
411 } else if (STRCASECMP(name,"None")==0) {
413 } else if (STRCASECMP(name,"Best")==0) {
415 } else if (STRCASECMP(name,"Bob")==0) {
417 } else if (STRCASECMP(name,"Weave")==0) {
422 name=vdr->configLoad("DirectShow", "VideoPresenter");
424 if (STRCASECMP(name,"VMR9")==0) {
425 currentpresenter=VMR9;
426 } else if (STRCASECMP(name,"EVR")==0) {
427 currentpresenter=EVR;
430 if (!((OsdWin*)Osd::getInstance())->IsEvrSupported()) {
431 currentpresenter=VMR9;
434 name=vdr->configLoad("DirectShow","videoH264dtsfix");
436 if (STRCASECMP(name,"YES")==0) {
437 videoH264dtsfix=true;
439 videoH264dtsfix=false;
442 name=vdr->configLoad("DirectShow","videompeg2dtsfix");
444 if (STRCASECMP(name,"YES")==0) {
445 videompeg2dtsfix=true;
447 videompeg2dtsfix=false;
451 name=vdr->configLoad("DirectGraphics", "StretchFiltering");
453 if (STRCASECMP(name,"None")==0) {
454 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
455 } else if (STRCASECMP(name,"Point")==0) {
456 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
457 } else if (STRCASECMP(name,"Linear")==0) {
458 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
469 bool VideoWin::handleOptionChanges(Option* option)
471 if( Video::handleOptionChanges(option)) return true;
474 if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
475 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
476 } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
477 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
478 } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
479 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
484 if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0) {
486 } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
488 } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0) {
490 } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0) {
492 } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0) {
497 if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0) {
498 currentpresenter=VMR9;
499 } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0) {
500 currentpresenter=EVR;
504 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
505 videoH264dtsfix=true;
507 videoH264dtsfix=false;
511 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
512 videompeg2dtsfix=true;
514 videompeg2dtsfix=false;
522 bool VideoWin::saveOptionstoServer()
524 if (videofilterselected!=-1) {
525 VDR::getInstance()->configSave("DirectShow",
526 "VideoFilter",videofilterlist[videofilterselected].displayname);
527 VDR::getInstance()->configSave("DirectShow",
528 "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
533 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
534 UINT numChoices, UINT defaultChoice, UINT startInt,
535 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
537 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
539 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
545 DWORD scalingcaps=((OsdWin*)Osd::getInstance())->getFilterCaps();
546 char **scalingopts=new char *[3];
548 scalingopts[i]=new char[strlen("None")+1];
549 strcpy(scalingopts[i],"None");
551 if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0
552 && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
553 scalingopts[i]=new char[strlen("Point")+1];
554 strcpy(scalingopts[i],"Point");
557 if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0
558 && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
559 scalingopts[i]=new char[strlen("Linear")+1];
560 strcpy(scalingopts[i],"Linear");
563 option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
564 options->push_back(option);
565 pane->addOptionLine(option);
566 static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
567 option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
568 options->push_back(option);
569 pane->addOptionLine(option);
571 if (((OsdWin*)Osd::getInstance())->IsEvrSupported())
573 static const char* presenteropts[]={"EVR","VMR9"};
574 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
575 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
577 static const char* presenteropts[]={"VMR9"};
578 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
580 options->push_back(option);
581 pane->addOptionLine(option);
583 static const char* yesnoopts[]={"Yes","No"};
584 option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
585 options->push_back(option);
586 pane->addOptionLine(option);
588 option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
589 options->push_back(option);
590 pane->addOptionLine(option);
599 IBaseFilter *VideoWin::getVideoFilter()
601 IBaseFilter *curfilter= NULL;
602 if (videofilterselected == -1)
605 for (i = 0;i <videofilterlist.size();i++)
608 if (videofilterlist[i].vmr9tested == true)
610 if (videofilterlist[i].vmr9 == true)
612 videofilterselected = i;
622 IMoniker * moni=NULL;
623 IBindCtx *bindctx=NULL;
624 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
625 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
626 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
630 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
632 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
634 IAMDecoderCaps* desccaps=NULL;
635 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
638 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
639 if (caps == DECODER_CAP_SUPPORTED)
641 videofilterlist[i].vmr9tested = true;
642 videofilterlist[i].vmr9 = true;
643 videofilterselected = i;
647 videofilterlist[i].vmr9tested = true;
648 videofilterlist[i].vmr9 = false;
650 curfilter->Release();
661 if (videofilterlist[i].vmr9) break;
664 if (curfilter != NULL)
666 VDR *vdr=VDR::getInstance();
669 vdr->configSave("DirectShow","VideoFilter",
670 videofilterlist[videofilterselected].displayname);
677 IBindCtx *bindctx=NULL;
678 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
679 IMoniker * moni=NULL;
680 LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
681 mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
682 strlen(videofilterlist[videofilterselected].displayname)+1);
684 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
686 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
688 IAMDecoderCaps* desccaps=NULL;
689 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
692 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
693 if (caps == DECODER_CAP_SUPPORTED)
695 videofilterlist[videofilterselected].vmr9tested = true;
696 videofilterlist[videofilterselected].vmr9 = true;
700 videofilterlist[videofilterselected].vmr9tested = true;
701 videofilterlist[videofilterselected].vmr9 = false;
702 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
720 IBaseFilter *VideoWin::getVideoH264Filter()
722 IBaseFilter *curfilter= NULL;
723 if (videoH264filterselected == -1)
726 for (i = 0;i <videoH264filterlist.size();i++)
729 if (videoH264filterlist[i].vmr9tested == true)
731 if (videoH264filterlist[i].vmr9 == true)
733 videoH264filterselected = i;
743 IMoniker * moni=NULL;
744 IBindCtx *bindctx=NULL;
745 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
746 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
747 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
749 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
753 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
755 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
757 IAMDecoderCaps* desccaps=NULL;
758 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
761 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
762 if (caps == DECODER_CAP_SUPPORTED)
764 videoH264filterlist[i].vmr9tested = true;
765 videoH264filterlist[i].vmr9 = true;
766 videoH264filterselected = i;
770 videoH264filterlist[i].vmr9tested = true;
771 videoH264filterlist[i].vmr9 = false;
773 curfilter->Release();
784 if (videoH264filterlist[i].vmr9) break;
787 if (curfilter != NULL)
789 VDR *vdr=VDR::getInstance();
792 vdr->configSave("DirectShow","VideoH264Filter",
793 videoH264filterlist[videoH264filterselected].displayname);
800 IBindCtx *bindctx=NULL;
801 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
802 IMoniker * moni=NULL;
803 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
804 mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
805 strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
807 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
808 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
810 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
812 IAMDecoderCaps* desccaps=NULL;
813 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
816 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
817 if (caps == DECODER_CAP_SUPPORTED)
819 videoH264filterlist[videoH264filterselected].vmr9tested = true;
820 videoH264filterlist[videoH264filterselected].vmr9 = true;
824 videoH264filterlist[videoH264filterselected].vmr9tested = true;
825 videoH264filterlist[videoH264filterselected].vmr9 = false;
826 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
845 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
846 #include "dshelper.h"
853 if (!initted) return 0;
857 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
859 Boxx *box=new WWinVideoFilter();
860 wtb->addTab(tr("Video Filter"), box);
861 box=new WWinVideoH264Filter();
862 wtb->addTab(tr("H264 Filter"), box);
866 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
868 selected=videofilterselected;
869 return &videofilterlist;
872 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
874 selected=videoH264filterselected;
875 return &videoH264filterlist;
878 bool VideoWin::selectVideoFilter(int filter)
880 IBindCtx *bindctx=NULL;
881 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
882 IMoniker * moni=NULL;
883 LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
884 mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
885 strlen(videofilterlist[filter].displayname)+1);
888 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
890 IBaseFilter* curfilter=NULL;
891 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
893 IAMDecoderCaps* desccaps=NULL;
894 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
897 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
898 if (caps == DECODER_CAP_SUPPORTED)
900 videofilterlist[filter].vmr9tested = true;
901 videofilterlist[filter].vmr9 = true;
906 videofilterlist[filter].vmr9tested = true;
907 videofilterlist[filter].vmr9 = false;
912 videofilterlist[filter].vmr9tested = true;
913 videofilterlist[filter].vmr9 = false;
917 curfilter->Release();
926 videofilterselected=filter;
935 bool VideoWin::selectVideoH264Filter(int filter)
937 IBindCtx *bindctx=NULL;
938 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
939 IMoniker * moni=NULL;
940 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
941 mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
942 strlen(videoH264filterlist[filter].displayname)+1);
945 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
947 IBaseFilter* curfilter=NULL;
948 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
950 IAMDecoderCaps* desccaps=NULL;
951 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
954 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
955 if (caps == DECODER_CAP_SUPPORTED)
957 videoH264filterlist[filter].vmr9tested = true;
958 videoH264filterlist[filter].vmr9 = true;
963 videoH264filterlist[filter].vmr9tested = true;
964 videoH264filterlist[filter].vmr9 = false;
969 videoH264filterlist[filter].vmr9tested = true;
970 videoH264filterlist[filter].vmr9 = false;
974 curfilter->Release();
983 videoH264filterselected=filter;
992 int VideoWin::dsInitVideoFilter()
997 //We alloc the vmr9 as next step
998 if (currentpresenter==VMR9)
1000 Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1001 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1002 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1004 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1005 ReleaseMutex(filtermutex);
1009 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1011 ReleaseMutex(filtermutex);
1013 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1016 IVMRFilterConfig9* vmrfilconfig;
1017 if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1019 ReleaseMutex(filtermutex);
1021 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1024 if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1025 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1026 vmrfilconfig->Release();
1027 if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1028 (void**)& dsvmrsurfnotify) != S_OK)
1030 ReleaseMutex(filtermutex);
1032 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1035 allocatorvmr=new DsAllocator();
1036 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1037 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1039 IVMRDeinterlaceControl9* deintctrl;
1040 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1042 ReleaseMutex(filtermutex);
1044 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1048 switch (vmrdeinterlacing)
1050 case 1: //No Deinterlasing
1051 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1054 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1057 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1060 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1063 deintctrl->Release();
1064 /*VMR 9 stuff end */
1066 else if (currentpresenter==EVR)
1068 Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1069 if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1070 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1072 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1073 ReleaseMutex(filtermutex);
1077 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1079 ReleaseMutex(filtermutex);
1081 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1086 IMFGetService *evr_services;
1087 if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1089 ReleaseMutex(filtermutex);
1091 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1095 IMFVideoDisplayControl* mfvideodisplaycontrol;
1096 if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1098 ReleaseMutex(filtermutex);
1100 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1104 evr_services->Release();
1105 mfvideodisplaycontrol->SetVideoWindow(((OsdWin*) Osd::getInstance())->getWindow());
1107 //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1108 //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1110 mfvideodisplaycontrol->Release();
1113 /// if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1115 IMFVideoRenderer *mfvideorenderer;
1116 if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1118 ReleaseMutex(filtermutex);
1120 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1124 allocatorvmr=new DsAllocator();
1125 HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1127 mfvideorenderer->Release();
1128 //How should I do this in EVR?
1129 /* IVMRDeinterlaceControl9* deintctrl;
1130 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1132 ReleaseMutex(filtermutex);
1134 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1138 switch (vmrdeinterlacing)
1140 case 1: //No Deinterlasing
1141 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1144 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1147 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1150 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1153 deintctrl->Release();*/
1156 Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1159 IFilterGraph2*fg2=NULL;
1160 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1162 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1163 ReleaseMutex(filtermutex);
1167 /*#ifndef NEW_DS_MECHANISMENS
1169 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1170 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
1172 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1174 ReleaseMutex(filtermutex);
1180 IBaseFilter*videofilter;
1183 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1184 videofilter=getVideoH264Filter();
1188 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1189 videofilter=getVideoFilter();
1191 if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK)
1193 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1194 ReleaseMutex(filtermutex);
1198 IEnumPins *pinenum=NULL;
1201 mptype_video_detail vid_details;
1202 Demuxer* demux=Demuxer::getInstance();
1203 vid_details.width=demux->getHorizontalSize();
1204 vid_details.height=demux->getVerticalSize();
1208 if (vid_details.width!=0 && vid_details.height!=0)
1210 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1214 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1220 if (vid_details.width!=0 && vid_details.height!=0)
1222 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1226 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1229 if (videofilter->EnumPins(&pinenum) == S_OK)
1233 bool firststep=false;
1235 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1238 if (current->QueryDirection(&dir)==S_OK)
1240 if (dir == PINDIR_INPUT)
1242 if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1252 if (firststep==false)
1254 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1255 videofilter->Release();
1256 ReleaseMutex(filtermutex);
1260 bool secondstep=false;
1262 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1265 if (current->QueryDirection(&dir)==S_OK)
1267 if (dir == PINDIR_OUTPUT)
1270 if (fg2->RenderEx((IPin*)current/*video*/,
1271 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1281 if (secondstep==false)
1283 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1284 videofilter->Release();
1285 ReleaseMutex(filtermutex);
1290 videofilter->Release();
1304 int VideoWin::setAudioStreamType(UCHAR type)
1307 if (!initted) return 0;
1311 int VideoWin::dsplay()
1313 if (!initted) return 0;
1316 //Build filter graph
1318 //So this is the real code, this prevents the feeder from calling noexisting objects!
1319 WaitForSingleObject(filtermutex,INFINITE);
1320 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1321 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
1323 ReleaseMutex(filtermutex);
1327 AddToRot(dsgraphbuilder,&graphidentifier);
1331 if (aud_type==Audio::MP3) {
1332 lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1334 lastaudiomode=MPTYPE_MPEG_AUDIO;
1336 //lastaudiomode=MPTYPE_AC3;
1337 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1339 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
1341 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1342 ReleaseMutex(filtermutex);
1346 sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1347 /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK)
1349 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1350 ReleaseMutex(filtermutex);
1354 if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1356 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1357 ReleaseMutex(filtermutex);
1363 if (dsInitVideoFilter()==0)
1368 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1369 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
1373 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1374 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1376 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1377 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1379 dsbasicaudio->put_Volume(audiovolume);
1383 hresdeb=dsmediacontrol->Run();
1384 iframemode=false;//exit iframe mode
1385 ReleaseMutex(filtermutex);
1389 int VideoWin::EnterIframePlayback()
1391 if (!initted) return 0;
1393 //So this is the real code, this prevents the feeder from calling noexisting objects!
1394 WaitForSingleObject(filtermutex,INFINITE);
1395 iframemode=true;//enter iframe mode
1396 //Build filter graph
1398 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1399 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1400 ReleaseMutex(filtermutex);
1404 AddToRot(dsgraphbuilder,&graphidentifier);
1407 //firstsynched=false;
1408 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1410 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1411 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1412 ReleaseMutex(filtermutex);
1418 dsInitVideoFilter();
1421 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1422 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1426 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1427 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1429 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1430 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1434 dsmediacontrol->Run();
1435 ReleaseMutex(filtermutex);
1440 int VideoWin::dsstop()
1442 if (!initted) return 0;
1450 int VideoWin::stop()
1452 if (!initted) return 0;
1458 int VideoWin::reset()
1460 if (!initted) return 0;
1466 int VideoWin::dsreset()
1468 if (!initted) return 0;
1469 iframemode=false;//exit iframe mode
1475 int VideoWin::dspause()
1477 if (!initted) return 0;
1478 WaitForSingleObject(filtermutex,INFINITE);
1479 if (dsmediacontrol) dsmediacontrol->Pause();
1480 ReleaseMutex(filtermutex);
1484 int VideoWin::pause()
1486 if (!initted) return 0;
1491 int VideoWin::unPause() // FIXME get rid - same as play!!
1492 {//No on windows this is not the same, I don't get rid of!
1493 if (!initted) return 0;
1497 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1498 {//No on windows this is not the same, I don't get rid of!
1499 if (!initted) return 0;
1500 WaitForSingleObject(filtermutex,INFINITE);
1501 if (dsmediacontrol) dsmediacontrol->Run();
1502 ReleaseMutex(filtermutex);
1507 int VideoWin::fastForward()
1509 if (!initted) return 0;
1514 int VideoWin::unFastForward()
1516 if (!initted) return 0;
1521 int VideoWin::attachFrameBuffer()
1523 if (!initted) return 0;
1527 int VideoWin::blank(void)
1529 ((OsdWin*)Osd::getInstance())->Blank();
1533 ULLONG VideoWin::getCurrentTimestamp()
1535 REFERENCE_TIME startoffset;
1536 REFERENCE_TIME ncr_time;
1537 if (iframemode) return 0; //Not in iframe mode!
1538 if (!dsrefclock || !sourcefilter) return 0;
1540 sourcefilter->GetState(10,&state);
1542 if (state==State_Running) dsrefclock->GetTime(&cr_time);
1544 startoffset=sourcefilter->getStartOffset();
1545 if (startoffset==0) return 0;
1546 ncr_time-=startoffset;
1547 ncr_time-=lastreftimeRT;
1548 /* ULLONG result=frameNumberToTimecode(
1549 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1550 long long result=lastreftimePTS;
1551 result+=(ULLONG)(ncr_time/10000LL*90LL);
1552 if (result<0) result=(1LL << 33)-result;
1559 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1561 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1562 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1565 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1567 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1568 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1571 void VideoWin::CleanupDS()
1573 WaitForSingleObject(filtermutex,INFINITE);
1575 if (dsmediacontrol)dsmediacontrol->Stop();
1576 if (cur_audio_media_sample) {
1577 cur_audio_media_sample->Release();
1578 cur_audio_media_sample=NULL;
1580 if (cur_video_media_sample) {
1581 cur_video_media_sample->Release();
1582 cur_video_media_sample=NULL;
1585 dsbasicaudio->Release();
1588 if (dsvmrsurfnotify) {
1589 dsvmrsurfnotify->Release();
1590 dsvmrsurfnotify=NULL;
1593 dsrenderer->Release();
1598 allocatorvmr->Release();
1603 dsrefclock->Release();
1606 if (dsmediafilter) {
1607 dsmediafilter->Release();
1613 if (dsmediacontrol) {
1614 dsmediacontrol->Stop();
1615 dsmediacontrol->Release();
1616 dsmediacontrol=NULL;
1618 if (dsgraphbuilder){
1620 RemoveFromRot(graphidentifier);
1622 dsgraphbuilder->Release();
1623 dsgraphbuilder=NULL;
1625 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1627 ReleaseMutex(filtermutex);
1631 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1634 mediapacket = mplist.front();
1637 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1639 DeliverMediaPacket(mediapacket, buffer, samplepos);
1640 if (*samplepos == mediapacket.length) {
1647 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1648 const UCHAR* buffer,
1652 /*First Check, if we have an audio sample*/
1653 if (!isdsinited()) return 0;
1654 if (packet.type == MPTYPE_VIDEO_H264)
1665 *samplepos+=packet.length;
1666 MILLISLEEP(0); //yet not implemented//bad idea
1667 return packet.length;
1669 /*First Check, if we have an audio sample*/
1673 return 0; //Not in iframe mode!
1675 IMediaSample* ms=NULL;
1676 REFERENCE_TIME reftime1=0;
1677 REFERENCE_TIME reftime2=0;
1680 if (packet.disconti) {
1682 DeliverVideoMediaSample();
1687 /*Inspect PES-Header */
1689 if (*samplepos==0) {//stripheader
1690 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1691 *samplepos+=headerstrip;
1692 if ( packet.synched ) {
1693 DeliverVideoMediaSample();//write out old data
1694 /* if (packet.presentation_time<0) { //Preroll?
1695 *samplepos=packet.length;//if we have not processed at least one
1696 return packet.length;//synched packet ignore it!
1699 reftime1=packet.presentation_time;
1700 reftime2=reftime1+1;
1703 if (!firstsynched) {//
1704 *samplepos=packet.length;//if we have not processed at least one
1705 return packet.length;//synched packet ignore it!
1714 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1716 //MessageBox(0,"da isser","hei",0);
1720 ms_pos=ms->GetActualDataLength();
1721 ms_length=ms->GetSize();
1722 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1723 if ((ms_length-ms_pos)<1 ) {
1724 DeliverVideoMediaSample(); //we are full!
1725 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1727 //MessageBox(0,"da isser","hei",0);
1731 ms_pos=ms->GetActualDataLength();
1732 ms_length=ms->GetSize();
1733 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1735 ms->GetPointer(&ms_buf);
1738 if (ms_pos==0) {//will only be changed on first packet
1739 if (packet.disconti) {
1740 ms->SetDiscontinuity(TRUE);
1742 ms->SetDiscontinuity(FALSE);
1744 if (packet.synched) {
1745 ms->SetSyncPoint(TRUE);
1746 ms->SetTime(&reftime1,&reftime2);
1747 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1748 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1749 //ms->SetTime(NULL,NULL);
1750 ms->SetMediaTime(NULL, NULL);
1751 if (reftime1<0) ms->SetPreroll(TRUE);
1752 else ms->SetPreroll(FALSE);
1753 /*Timecode handling*/
1754 lastreftimeRT=reftime1;
1755 lastreftimePTS=packet.pts;
1760 ms->SetSyncPoint(FALSE);
1761 ms->SetTime(NULL,NULL);
1762 ms->SetMediaTime(NULL, NULL);
1763 ms->SetPreroll(FALSE);
1765 // ms->SetSyncPoint(TRUE);
1771 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1772 ms->SetActualDataLength(haveToCopy+ms_pos);
1774 *samplepos+=haveToCopy;
1776 return haveToCopy+headerstrip;
1780 *samplepos+=packet.length;
1781 MILLISLEEP(0); //yet not implemented//bad idea
1782 return packet.length;
1786 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1788 //WaitForSingleObject(filtermutex,INFINITE);
1790 // ReleaseMutex(filtermutex);
1793 if (cur_audio_media_sample) {
1794 *ms=cur_audio_media_sample;//already open
1797 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1798 // ReleaseMutex(filtermutex);
1800 if (*ms) (*ms)->SetActualDataLength(0);
1801 cur_audio_media_sample=*ms;
1802 //Don't release the mutex before deliver
1806 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1808 //WaitForSingleObject(filtermutex,INFINITE);
1810 // ReleaseMutex(filtermutex);
1813 if (cur_video_media_sample) {
1814 *ms=cur_video_media_sample;//already open
1817 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1818 // ReleaseMutex(filtermutex);
1820 if (*ms) (*ms)->SetActualDataLength(0);
1822 cur_video_media_sample=*ms;
1823 //Don't release the mutex before deliver
1827 int VideoWin::DeliverAudioMediaSample(){
1828 if (cur_audio_media_sample) {
1829 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1830 cur_audio_media_sample=NULL;
1832 //ReleaseMutex(filtermutex);
1836 int VideoWin::DeliverVideoMediaSample(){
1837 if (cur_video_media_sample) {
1838 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1839 cur_video_media_sample=NULL;
1841 //ReleaseMutex(filtermutex);
1845 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1849 startoffset=curreftime;//offset is set for audio
1851 offsetvideonotset=false;
1855 if (offsetvideonotset) {
1856 offsetvideonotset=false;
1859 if ( (curreftime-lastrefvideotime)>10000000LL
1860 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1861 startoffset+=curreftime-lastrefvideotime;
1862 lastrefaudiotime+=curreftime-lastrefvideotime;
1864 offsetaudionotset=true;
1871 lastrefvideotime=curreftime;
1877 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1881 startoffset=curreftime;
1883 offsetaudionotset=false;
1885 if (offsetaudionotset) {
1886 offsetaudionotset=false;
1889 if ( (curreftime-lastrefaudiotime)>10000000LL
1890 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1891 startoffset+=curreftime-lastrefaudiotime;
1892 lastrefvideotime+=curreftime-lastrefaudiotime;
1894 offsetvideonotset=true;
1900 lastrefaudiotime=curreftime;
1904 void VideoWin::ResetTimeOffsets() {
1905 offsetnotset=true; //called from demuxer
1906 offsetvideonotset=true;
1907 offsetaudionotset=true;
1917 void VideoWin::SetAudioVolume(long volume)
1920 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1923 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1925 if (!iframemode) EnterIframePlayback();
1926 if (!isdsinited()) return false;
1929 IMediaSample* ms=NULL;
1930 REFERENCE_TIME reftime1=0;
1931 REFERENCE_TIME reftime2=0;
1932 if (!videoon) return false;
1933 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1939 ms->GetPointer(&ms_buf);
1940 ms_length=ms->GetSize();
1942 /*First Check, if we have an video sample*/
1943 DWORD read_pos = 0, write_pos = 0;
1944 DWORD pattern, packet_length;
1945 DWORD headerstrip=0;
1947 if (length < 4) return false;
1948 //Now we strip the pes header
1949 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1950 while (read_pos + 7 <= length)
1952 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1953 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1959 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1960 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1961 if (read_pos + packet_length > length)
1965 if ( (headerstrip < packet_length) &&
1966 (write_pos+packet_length-headerstrip)>ms_length) {
1968 ms->SetSyncPoint(TRUE);
1969 ms->SetDiscontinuity(TRUE);
1971 } else ms->SetSyncPoint(FALSE);
1972 ms->SetTime(NULL,NULL);
1973 ms->SetMediaTime(NULL, NULL);
1974 ms->SetActualDataLength(write_pos);
1975 DeliverVideoMediaSample();
1977 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1982 ms_length=ms->GetSize();
1983 ms->GetPointer(&ms_buf);
1985 if (packet_length>headerstrip) {
1986 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1987 write_pos += packet_length-headerstrip;
1989 read_pos += packet_length;
1991 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
1992 | (buffer[read_pos+2]);
1997 if (first) {ms->SetSyncPoint(TRUE);
1998 ms->SetDiscontinuity(TRUE);
2000 else ms->SetSyncPoint(FALSE);
2001 ms->SetTime(NULL,NULL);
2002 ms->SetMediaTime(NULL, NULL);
2003 ms->SetActualDataLength(write_pos);
2004 DeliverVideoMediaSample();
2009 // *samplepos+=packet.length;
2010 MILLISLEEP(0); //yet not implemented//bad idea
2015 bool VideoWin::supportsAc3(){
2016 if (sourcefilter != NULL) {
2017 return sourcefilter->supportsAc3();
2023 bool VideoWin::supportsh264()
2025 if (videoH264filterlist.size()>0) return true;
2030 bool VideoWin::changeAType(int type,IMediaSample* ms){
2031 if (sourcefilter!= NULL) {
2033 return sourcefilter->changeAType(type,ms);
2042 int VideoWin::test()
2047 int VideoWin::test2()