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;
77 aud_type=Audio::MPEG2_PES;
78 iframemode=false;//We are not in Iframe mode at begining
79 vmrdeinterlacing=2;//Best
80 videofilterselected=-1;
81 videoH264filterselected=-1;
82 OSVERSIONINFO verinfo;
83 verinfo.dwOSVersionInfoSize=sizeof(verinfo);
84 GetVersionEx(&verinfo);
86 if (verinfo.dwMajorVersion>=6) {
89 currentpresenter=VMR9;
91 videoH264dtsfix=false;
92 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
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;
214 int VideoWin::signalOff()
219 int VideoWin::signalOn()
224 int VideoWin::setSource()
226 if (!initted) return 0;
231 int VideoWin::setPosition(int x, int y)
233 if (!initted) return 0;
234 if (mode==QUARTER || mode==EIGHTH) {
243 if (!initted) return 0;
247 void VideoWin::initFilterDatabase()
249 /* This method should determine all availiable DirectShow Filters */
250 IFilterMapper2* filtmap=NULL;
252 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
253 IID_IFilterMapper2,(void**)&filtmap);
256 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
259 /* Wishlist, what Mediatypes do we want */
260 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
261 IEnumMoniker *myenum;
262 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
263 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
267 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
272 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
274 VideoFilterDesc desc;
275 ZeroMemory(&desc,sizeof(desc));
278 moni->GetDisplayName(0,0,&string);
279 desc.displayname=new char[wcslen(string)+1];
280 wcstombs(desc.displayname,string,wcslen(string)+1);
281 CoTaskMemFree(string);
283 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
287 result = bag->Read(L"FriendlyName",&vari,NULL);
290 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
291 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
299 videofilterlist.push_back(desc);
307 videofilterselected=-1;
318 void VideoWin::initH264FilterDatabase()
320 /* This method should determine all availiable DirectShow Filters */
321 IFilterMapper2* filtmap=NULL;
323 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
324 IID_IFilterMapper2,(void**)&filtmap);
327 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
330 /* Wishlist, what Mediatypes do we want */
331 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
332 IEnumMoniker *myenum;
333 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
334 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
338 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
343 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
345 VideoFilterDesc desc;
346 ZeroMemory(&desc,sizeof(desc));
349 moni->GetDisplayName(0,0,&string);
350 desc.displayname=new char[wcslen(string)+1];
351 wcstombs(desc.displayname,string,wcslen(string)+1);
352 CoTaskMemFree(string);
354 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
358 result = bag->Read(L"FriendlyName",&vari,NULL);
361 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
362 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
370 videoH264filterlist.push_back(desc);
378 videoH264filterselected=-1;
389 bool VideoWin::loadOptionsfromServer(VDR* vdr)
391 char *name=vdr->configLoad("DirectShow","VideoFilter");
395 for (int i = 0;i <videofilterlist.size();i++)
397 if (strcmp(name,videofilterlist[i].displayname)==0)
399 videofilterselected = i;
404 name=vdr->configLoad("DirectShow","VideoH264Filter");
408 for (int i = 0;i <videoH264filterlist.size();i++)
410 if (strcmp(name,videoH264filterlist[i].displayname)==0)
412 videoH264filterselected = i;
417 name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
420 if (STRCASECMP(name,"NoMix")==0) {
422 } else if (STRCASECMP(name,"None")==0) {
424 } else if (STRCASECMP(name,"Best")==0) {
426 } else if (STRCASECMP(name,"Bob")==0) {
428 } else if (STRCASECMP(name,"Weave")==0) {
433 name=vdr->configLoad("DirectShow", "VideoPresenter");
435 if (STRCASECMP(name,"VMR9")==0) {
436 currentpresenter=VMR9;
437 } else if (STRCASECMP(name,"EVR")==0) {
438 currentpresenter=EVR;
441 if (!((OsdWin*)Osd::getInstance())->IsEvrSupported()) {
442 currentpresenter=VMR9;
445 name=vdr->configLoad("DirectShow","videoH264dtsfix");
447 if (STRCASECMP(name,"YES")==0) {
448 videoH264dtsfix=true;
450 videoH264dtsfix=false;
453 name=vdr->configLoad("DirectShow","videompeg2dtsfix");
455 if (STRCASECMP(name,"YES")==0) {
456 videompeg2dtsfix=true;
458 videompeg2dtsfix=false;
462 name=vdr->configLoad("DirectGraphics", "StretchFiltering");
464 if (STRCASECMP(name,"None")==0) {
465 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
466 } else if (STRCASECMP(name,"Point")==0) {
467 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
468 } else if (STRCASECMP(name,"Linear")==0) {
469 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
480 bool VideoWin::handleOptionChanges(Option* option)
482 if( Video::handleOptionChanges(option)) return true;
485 if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
486 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
487 } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
488 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
489 } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
490 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
495 if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0) {
497 } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
499 } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0) {
501 } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0) {
503 } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0) {
508 if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0) {
509 currentpresenter=VMR9;
510 } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0) {
511 currentpresenter=EVR;
515 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
516 videoH264dtsfix=true;
518 videoH264dtsfix=false;
522 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
523 videompeg2dtsfix=true;
525 videompeg2dtsfix=false;
533 bool VideoWin::saveOptionstoServer()
535 if (videofilterselected!=-1) {
536 VDR::getInstance()->configSave("DirectShow",
537 "VideoFilter",videofilterlist[videofilterselected].displayname);
538 VDR::getInstance()->configSave("DirectShow",
539 "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
544 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
545 UINT numChoices, UINT defaultChoice, UINT startInt,
546 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
548 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
550 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
556 DWORD scalingcaps=((OsdWin*)Osd::getInstance())->getFilterCaps();
557 char **scalingopts=new char *[3];
559 scalingopts[i]=new char[strlen("None")+1];
560 strcpy(scalingopts[i],"None");
562 if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0
563 && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
564 scalingopts[i]=new char[strlen("Point")+1];
565 strcpy(scalingopts[i],"Point");
568 if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0
569 && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
570 scalingopts[i]=new char[strlen("Linear")+1];
571 strcpy(scalingopts[i],"Linear");
574 option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
575 options->push_back(option);
576 pane->addOptionLine(option);
577 static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
578 option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
579 options->push_back(option);
580 pane->addOptionLine(option);
582 if (((OsdWin*)Osd::getInstance())->IsEvrSupported())
584 static const char* presenteropts[]={"EVR","VMR9"};
585 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
586 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
588 static const char* presenteropts[]={"VMR9"};
589 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
591 options->push_back(option);
592 pane->addOptionLine(option);
594 static const char* yesnoopts[]={"Yes","No"};
595 option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
596 options->push_back(option);
597 pane->addOptionLine(option);
599 option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
600 options->push_back(option);
601 pane->addOptionLine(option);
610 IBaseFilter *VideoWin::getVideoFilter()
612 IBaseFilter *curfilter= NULL;
613 if (videofilterselected == -1)
616 for (i = 0;i <videofilterlist.size();i++)
619 if (videofilterlist[i].vmr9tested == true)
621 if (videofilterlist[i].vmr9 == true)
623 videofilterselected = i;
633 IMoniker * moni=NULL;
634 IBindCtx *bindctx=NULL;
635 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
636 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
637 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
641 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
643 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
645 IAMDecoderCaps* desccaps=NULL;
646 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
649 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
650 if (caps == DECODER_CAP_SUPPORTED)
652 videofilterlist[i].vmr9tested = true;
653 videofilterlist[i].vmr9 = true;
654 videofilterselected = i;
658 videofilterlist[i].vmr9tested = true;
659 videofilterlist[i].vmr9 = false;
661 curfilter->Release();
672 if (videofilterlist[i].vmr9) break;
675 if (curfilter != NULL)
677 VDR *vdr=VDR::getInstance();
680 vdr->configSave("DirectShow","VideoFilter",
681 videofilterlist[videofilterselected].displayname);
688 IBindCtx *bindctx=NULL;
689 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
690 IMoniker * moni=NULL;
691 LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
692 mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
693 strlen(videofilterlist[videofilterselected].displayname)+1);
695 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
697 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
699 IAMDecoderCaps* desccaps=NULL;
700 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
703 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
704 if (caps == DECODER_CAP_SUPPORTED)
706 videofilterlist[videofilterselected].vmr9tested = true;
707 videofilterlist[videofilterselected].vmr9 = true;
711 videofilterlist[videofilterselected].vmr9tested = true;
712 videofilterlist[videofilterselected].vmr9 = false;
713 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
731 IBaseFilter *VideoWin::getVideoH264Filter()
733 IBaseFilter *curfilter= NULL;
734 if (videoH264filterselected == -1)
737 for (i = 0;i <videoH264filterlist.size();i++)
740 if (videoH264filterlist[i].vmr9tested == true)
742 if (videoH264filterlist[i].vmr9 == true)
744 videoH264filterselected = i;
754 IMoniker * moni=NULL;
755 IBindCtx *bindctx=NULL;
756 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
757 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
758 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
760 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
764 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
766 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
768 IAMDecoderCaps* desccaps=NULL;
769 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
772 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
773 if (caps == DECODER_CAP_SUPPORTED)
775 videoH264filterlist[i].vmr9tested = true;
776 videoH264filterlist[i].vmr9 = true;
777 videoH264filterselected = i;
781 videoH264filterlist[i].vmr9tested = true;
782 videoH264filterlist[i].vmr9 = false;
784 curfilter->Release();
795 if (videoH264filterlist[i].vmr9) break;
798 if (curfilter != NULL)
800 VDR *vdr=VDR::getInstance();
803 vdr->configSave("DirectShow","VideoH264Filter",
804 videoH264filterlist[videoH264filterselected].displayname);
811 IBindCtx *bindctx=NULL;
812 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
813 IMoniker * moni=NULL;
814 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
815 mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
816 strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
818 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
819 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
821 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
823 IAMDecoderCaps* desccaps=NULL;
824 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
827 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
828 if (caps == DECODER_CAP_SUPPORTED)
830 videoH264filterlist[videoH264filterselected].vmr9tested = true;
831 videoH264filterlist[videoH264filterselected].vmr9 = true;
835 videoH264filterlist[videoH264filterselected].vmr9tested = true;
836 videoH264filterlist[videoH264filterselected].vmr9 = false;
837 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
856 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
857 #include "dshelper.h"
864 if (!initted) return 0;
868 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
870 Boxx *box=new WWinVideoFilter();
871 wtb->addTab(tr("Video Filter"), box);
872 box=new WWinVideoH264Filter();
873 wtb->addTab(tr("H264 Filter"), box);
877 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
879 selected=videofilterselected;
880 return &videofilterlist;
883 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
885 selected=videoH264filterselected;
886 return &videoH264filterlist;
889 bool VideoWin::selectVideoFilter(int filter)
891 IBindCtx *bindctx=NULL;
892 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
893 IMoniker * moni=NULL;
894 LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
895 mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
896 strlen(videofilterlist[filter].displayname)+1);
899 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
901 IBaseFilter* curfilter=NULL;
902 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
904 IAMDecoderCaps* desccaps=NULL;
905 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
908 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
909 if (caps == DECODER_CAP_SUPPORTED)
911 videofilterlist[filter].vmr9tested = true;
912 videofilterlist[filter].vmr9 = true;
917 videofilterlist[filter].vmr9tested = true;
918 videofilterlist[filter].vmr9 = false;
923 videofilterlist[filter].vmr9tested = true;
924 videofilterlist[filter].vmr9 = false;
928 curfilter->Release();
937 videofilterselected=filter;
946 bool VideoWin::selectVideoH264Filter(int filter)
948 IBindCtx *bindctx=NULL;
949 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
950 IMoniker * moni=NULL;
951 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
952 mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
953 strlen(videoH264filterlist[filter].displayname)+1);
956 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
958 IBaseFilter* curfilter=NULL;
959 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
961 IAMDecoderCaps* desccaps=NULL;
962 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
965 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
966 if (caps == DECODER_CAP_SUPPORTED)
968 videoH264filterlist[filter].vmr9tested = true;
969 videoH264filterlist[filter].vmr9 = true;
974 videoH264filterlist[filter].vmr9tested = true;
975 videoH264filterlist[filter].vmr9 = false;
980 videoH264filterlist[filter].vmr9tested = true;
981 videoH264filterlist[filter].vmr9 = false;
985 curfilter->Release();
994 videoH264filterselected=filter;
1003 int VideoWin::dsInitVideoFilter()
1008 //We alloc the vmr9 as next step
1009 if (currentpresenter==VMR9)
1011 Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1012 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1013 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1015 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1016 ReleaseMutex(filtermutex);
1020 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1022 ReleaseMutex(filtermutex);
1024 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1027 IVMRFilterConfig9* vmrfilconfig;
1028 if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1030 ReleaseMutex(filtermutex);
1032 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1035 if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1036 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1037 vmrfilconfig->Release();
1038 if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1039 (void**)& dsvmrsurfnotify) != S_OK)
1041 ReleaseMutex(filtermutex);
1043 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1046 allocatorvmr=new DsAllocator();
1047 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1048 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1050 IVMRDeinterlaceControl9* deintctrl;
1051 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1053 ReleaseMutex(filtermutex);
1055 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1059 switch (vmrdeinterlacing)
1061 case 1: //No Deinterlasing
1062 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1065 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1068 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1071 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1074 deintctrl->Release();
1075 /*VMR 9 stuff end */
1077 else if (currentpresenter==EVR)
1079 Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1080 if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1081 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1083 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1084 ReleaseMutex(filtermutex);
1088 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1090 ReleaseMutex(filtermutex);
1092 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1097 IMFGetService *evr_services;
1098 if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1100 ReleaseMutex(filtermutex);
1102 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1106 IMFVideoDisplayControl* mfvideodisplaycontrol;
1107 if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1109 ReleaseMutex(filtermutex);
1111 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1115 evr_services->Release();
1116 mfvideodisplaycontrol->SetVideoWindow(((OsdWin*) Osd::getInstance())->getWindow());
1118 //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1119 //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1121 mfvideodisplaycontrol->Release();
1124 /// if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1126 IMFVideoRenderer *mfvideorenderer;
1127 if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1129 ReleaseMutex(filtermutex);
1131 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1135 allocatorvmr=new DsAllocator();
1136 HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1138 mfvideorenderer->Release();
1139 //How should I do this in EVR?
1140 /* IVMRDeinterlaceControl9* deintctrl;
1141 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1143 ReleaseMutex(filtermutex);
1145 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1149 switch (vmrdeinterlacing)
1151 case 1: //No Deinterlasing
1152 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1155 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1158 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1161 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1164 deintctrl->Release();*/
1167 Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1170 IFilterGraph2*fg2=NULL;
1171 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1173 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1174 ReleaseMutex(filtermutex);
1178 /*#ifndef NEW_DS_MECHANISMENS
1180 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1181 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
1183 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1185 ReleaseMutex(filtermutex);
1191 IBaseFilter*videofilter;
1194 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1195 videofilter=getVideoH264Filter();
1199 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1200 videofilter=getVideoFilter();
1202 if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK)
1204 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1205 ReleaseMutex(filtermutex);
1209 IEnumPins *pinenum=NULL;
1212 mptype_video_detail vid_details;
1213 Demuxer* demux=Demuxer::getInstance();
1214 vid_details.width=demux->getHorizontalSize();
1215 vid_details.height=demux->getVerticalSize();
1219 if (vid_details.width!=0 && vid_details.height!=0)
1221 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1225 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1231 if (vid_details.width!=0 && vid_details.height!=0)
1233 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1237 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1240 if (videofilter->EnumPins(&pinenum) == S_OK)
1244 bool firststep=false;
1246 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1249 if (current->QueryDirection(&dir)==S_OK)
1251 if (dir == PINDIR_INPUT)
1253 if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1263 if (firststep==false)
1265 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1266 videofilter->Release();
1267 ReleaseMutex(filtermutex);
1271 bool secondstep=false;
1273 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1276 if (current->QueryDirection(&dir)==S_OK)
1278 if (dir == PINDIR_OUTPUT)
1281 if (fg2->RenderEx((IPin*)current/*video*/,
1282 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1292 if (secondstep==false)
1294 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1295 videofilter->Release();
1296 ReleaseMutex(filtermutex);
1301 videofilter->Release();
1315 int VideoWin::setAudioStreamType(UCHAR type)
1318 if (!initted) return 0;
1322 int VideoWin::dsplay()
1324 if (!initted) return 0;
1327 //Build filter graph
1329 //So this is the real code, this prevents the feeder from calling noexisting objects!
1330 WaitForSingleObject(filtermutex,INFINITE);
1331 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1332 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
1334 ReleaseMutex(filtermutex);
1338 AddToRot(dsgraphbuilder,&graphidentifier);
1342 if (aud_type==Audio::MP3) {
1343 lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1345 lastaudiomode=MPTYPE_MPEG_AUDIO;
1347 //lastaudiomode=MPTYPE_AC3;
1348 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1350 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
1352 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1353 ReleaseMutex(filtermutex);
1357 sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1358 /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK)
1360 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1361 ReleaseMutex(filtermutex);
1365 if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1367 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1368 ReleaseMutex(filtermutex);
1374 if (dsInitVideoFilter()==0)
1379 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1380 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
1384 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1385 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1387 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1388 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1390 dsbasicaudio->put_Volume(audiovolume);
1394 hresdeb=dsmediacontrol->Run();
1395 iframemode=false;//exit iframe mode
1396 ReleaseMutex(filtermutex);
1400 int VideoWin::EnterIframePlayback()
1402 if (!initted) return 0;
1404 //So this is the real code, this prevents the feeder from calling noexisting objects!
1405 WaitForSingleObject(filtermutex,INFINITE);
1406 iframemode=true;//enter iframe mode
1407 //Build filter graph
1409 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1410 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1411 ReleaseMutex(filtermutex);
1415 AddToRot(dsgraphbuilder,&graphidentifier);
1418 //firstsynched=false;
1419 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1421 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1422 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1423 ReleaseMutex(filtermutex);
1429 dsInitVideoFilter();
1432 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1433 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1437 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1438 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1440 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1441 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1445 dsmediacontrol->Run();
1446 ReleaseMutex(filtermutex);
1451 int VideoWin::dsstop()
1453 if (!initted) return 0;
1461 int VideoWin::stop()
1463 if (!initted) return 0;
1469 int VideoWin::reset()
1471 if (!initted) return 0;
1477 int VideoWin::dsreset()
1479 if (!initted) return 0;
1482 iframemode=false;//exit iframe mode
1488 int VideoWin::dspause()
1490 if (!initted) return 0;
1491 WaitForSingleObject(filtermutex,INFINITE);
1492 if (dsmediacontrol) dsmediacontrol->Pause();
1493 ReleaseMutex(filtermutex);
1497 int VideoWin::pause()
1499 if (!initted) return 0;
1504 int VideoWin::unPause() // FIXME get rid - same as play!!
1505 {//No on windows this is not the same, I don't get rid of!
1506 if (!initted) return 0;
1510 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1511 {//No on windows this is not the same, I don't get rid of!
1512 if (!initted) return 0;
1513 WaitForSingleObject(filtermutex,INFINITE);
1514 if (dsmediacontrol) dsmediacontrol->Run();
1515 ReleaseMutex(filtermutex);
1520 int VideoWin::fastForward()
1522 if (!initted) return 0;
1527 int VideoWin::unFastForward()
1529 if (!initted) return 0;
1534 int VideoWin::attachFrameBuffer()
1536 if (!initted) return 0;
1540 int VideoWin::blank(void)
1542 ((OsdWin*)Osd::getInstance())->Blank();
1546 ULLONG VideoWin::getCurrentTimestamp()
1548 REFERENCE_TIME startoffset;
1549 REFERENCE_TIME ncr_time;
1550 if (iframemode) return 0; //Not in iframe mode!
1551 if (!dsrefclock || !sourcefilter) return 0;
1553 sourcefilter->GetState(10,&state);
1555 if (state==State_Running) dsrefclock->GetTime(&cr_time);
1557 startoffset=sourcefilter->getStartOffset();
1558 if (startoffset==0) return 0;
1559 ncr_time-=startoffset;
1560 ncr_time-=lastreftimeRT;
1561 /* ULLONG result=frameNumberToTimecode(
1562 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1563 long long result=lastreftimePTS;
1564 result+=(ULLONG)(ncr_time/10000LL*90LL);
1565 if (result<0) result=(1LL << 33)-result;
1572 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1574 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1575 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1578 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1580 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1581 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1584 void VideoWin::CleanupDS()
1586 WaitForSingleObject(filtermutex,INFINITE);
1588 if (dsmediacontrol)dsmediacontrol->Stop();
1589 if (cur_audio_media_sample) {
1590 cur_audio_media_sample->Release();
1591 cur_audio_media_sample=NULL;
1593 if (cur_video_media_sample) {
1594 cur_video_media_sample->Release();
1595 cur_video_media_sample=NULL;
1598 dsbasicaudio->Release();
1601 if (dsvmrsurfnotify) {
1602 dsvmrsurfnotify->Release();
1603 dsvmrsurfnotify=NULL;
1606 dsrenderer->Release();
1611 allocatorvmr->Release();
1616 dsrefclock->Release();
1619 if (dsmediafilter) {
1620 dsmediafilter->Release();
1626 if (dsmediacontrol) {
1627 dsmediacontrol->Stop();
1628 dsmediacontrol->Release();
1629 dsmediacontrol=NULL;
1631 if (dsgraphbuilder){
1633 RemoveFromRot(graphidentifier);
1635 dsgraphbuilder->Release();
1636 dsgraphbuilder=NULL;
1638 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1640 ReleaseMutex(filtermutex);
1644 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1647 mediapacket = mplist.front();
1650 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1652 DeliverMediaPacket(mediapacket, buffer, samplepos);
1653 if (*samplepos == mediapacket.length) {
1660 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1661 const UCHAR* buffer,
1665 /*First Check, if we have an audio sample*/
1666 if (!isdsinited()) return 0;
1667 if (packet.type == MPTYPE_VIDEO_H264)
1678 *samplepos+=packet.length;
1679 MILLISLEEP(0); //yet not implemented//bad idea
1680 return packet.length;
1682 /*First Check, if we have an audio sample*/
1686 return 0; //Not in iframe mode!
1688 IMediaSample* ms=NULL;
1689 REFERENCE_TIME reftime1=0;
1690 REFERENCE_TIME reftime2=0;
1693 if (packet.disconti) {
1695 DeliverVideoMediaSample();
1700 /*Inspect PES-Header */
1702 if (*samplepos==0) {//stripheader
1703 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1704 *samplepos+=headerstrip;
1705 if ( packet.synched ) {
1706 DeliverVideoMediaSample();//write out old data
1707 /* if (packet.presentation_time<0) { //Preroll?
1708 *samplepos=packet.length;//if we have not processed at least one
1709 return packet.length;//synched packet ignore it!
1712 reftime1=packet.presentation_time;
1713 reftime2=reftime1+1;
1716 if (!firstsynched) {//
1717 *samplepos=packet.length;//if we have not processed at least one
1718 return packet.length;//synched packet ignore it!
1727 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1729 //MessageBox(0,"da isser","hei",0);
1733 ms_pos=ms->GetActualDataLength();
1734 ms_length=ms->GetSize();
1735 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1736 if ((ms_length-ms_pos)<1 ) {
1737 DeliverVideoMediaSample(); //we are full!
1738 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1740 //MessageBox(0,"da isser","hei",0);
1744 ms_pos=ms->GetActualDataLength();
1745 ms_length=ms->GetSize();
1746 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1748 ms->GetPointer(&ms_buf);
1751 if (ms_pos==0) {//will only be changed on first packet
1752 if (packet.disconti) {
1753 ms->SetDiscontinuity(TRUE);
1755 ms->SetDiscontinuity(FALSE);
1757 if (packet.synched) {
1758 ms->SetSyncPoint(TRUE);
1759 ms->SetTime(&reftime1,&reftime2);
1760 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1761 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1762 //ms->SetTime(NULL,NULL);
1763 ms->SetMediaTime(NULL, NULL);
1764 if (reftime1<0) ms->SetPreroll(TRUE);
1765 else ms->SetPreroll(FALSE);
1766 /*Timecode handling*/
1767 lastreftimeRT=reftime1;
1768 lastreftimePTS=packet.pts;
1773 ms->SetSyncPoint(FALSE);
1774 ms->SetTime(NULL,NULL);
1775 ms->SetMediaTime(NULL, NULL);
1776 ms->SetPreroll(FALSE);
1778 // ms->SetSyncPoint(TRUE);
1784 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1785 ms->SetActualDataLength(haveToCopy+ms_pos);
1787 *samplepos+=haveToCopy;
1789 return haveToCopy+headerstrip;
1793 *samplepos+=packet.length;
1794 MILLISLEEP(0); //yet not implemented//bad idea
1795 return packet.length;
1799 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1801 //WaitForSingleObject(filtermutex,INFINITE);
1803 // ReleaseMutex(filtermutex);
1806 if (cur_audio_media_sample) {
1807 *ms=cur_audio_media_sample;//already open
1810 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1811 // ReleaseMutex(filtermutex);
1813 if (*ms) (*ms)->SetActualDataLength(0);
1814 cur_audio_media_sample=*ms;
1815 //Don't release the mutex before deliver
1819 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1821 //WaitForSingleObject(filtermutex,INFINITE);
1823 // ReleaseMutex(filtermutex);
1826 if (cur_video_media_sample) {
1827 *ms=cur_video_media_sample;//already open
1830 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1831 // ReleaseMutex(filtermutex);
1833 if (*ms) (*ms)->SetActualDataLength(0);
1835 cur_video_media_sample=*ms;
1836 //Don't release the mutex before deliver
1840 int VideoWin::DeliverAudioMediaSample(){
1841 if (cur_audio_media_sample) {
1842 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1843 cur_audio_media_sample=NULL;
1845 //ReleaseMutex(filtermutex);
1849 int VideoWin::DeliverVideoMediaSample(){
1850 if (cur_video_media_sample) {
1851 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1852 cur_video_media_sample=NULL;
1854 //ReleaseMutex(filtermutex);
1858 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1862 startoffset=curreftime;//offset is set for audio
1864 offsetvideonotset=false;
1868 if (offsetvideonotset) {
1869 offsetvideonotset=false;
1872 if ( (curreftime-lastrefvideotime)>10000000LL
1873 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1874 startoffset+=curreftime-lastrefvideotime;
1875 lastrefaudiotime+=curreftime-lastrefvideotime;
1877 offsetaudionotset=true;
1884 lastrefvideotime=curreftime;
1890 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1894 startoffset=curreftime;
1896 offsetaudionotset=false;
1898 if (offsetaudionotset) {
1899 offsetaudionotset=false;
1902 if ( (curreftime-lastrefaudiotime)>10000000LL
1903 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1904 startoffset+=curreftime-lastrefaudiotime;
1905 lastrefvideotime+=curreftime-lastrefaudiotime;
1907 offsetvideonotset=true;
1913 lastrefaudiotime=curreftime;
1917 void VideoWin::ResetTimeOffsets() {
1918 offsetnotset=true; //called from demuxer
1919 offsetvideonotset=true;
1920 offsetaudionotset=true;
1930 void VideoWin::SetAudioVolume(long volume)
1933 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1936 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1938 if (!iframemode) EnterIframePlayback();
1939 if (!isdsinited()) return false;
1942 IMediaSample* ms=NULL;
1943 REFERENCE_TIME reftime1=0;
1944 REFERENCE_TIME reftime2=0;
1945 if (!videoon) return false;
1946 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1952 ms->GetPointer(&ms_buf);
1953 ms_length=ms->GetSize();
1955 /*First Check, if we have an video sample*/
1956 DWORD read_pos = 0, write_pos = 0;
1957 DWORD pattern, packet_length;
1958 DWORD headerstrip=0;
1960 if (length < 4) return false;
1961 //Now we strip the pes header
1962 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1963 while (read_pos + 7 <= length)
1965 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1966 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1972 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1973 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1974 if (read_pos + packet_length > length)
1978 if ( (headerstrip < packet_length) &&
1979 (write_pos+packet_length-headerstrip)>ms_length) {
1981 ms->SetSyncPoint(TRUE);
1982 ms->SetDiscontinuity(TRUE);
1984 } else ms->SetSyncPoint(FALSE);
1985 ms->SetTime(NULL,NULL);
1986 ms->SetMediaTime(NULL, NULL);
1987 ms->SetActualDataLength(write_pos);
1988 DeliverVideoMediaSample();
1990 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1995 ms_length=ms->GetSize();
1996 ms->GetPointer(&ms_buf);
1998 if (packet_length>headerstrip) {
1999 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
2000 write_pos += packet_length-headerstrip;
2002 read_pos += packet_length;
2004 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
2005 | (buffer[read_pos+2]);
2010 if (first) {ms->SetSyncPoint(TRUE);
2011 ms->SetDiscontinuity(TRUE);
2013 else ms->SetSyncPoint(FALSE);
2014 ms->SetTime(NULL,NULL);
2015 ms->SetMediaTime(NULL, NULL);
2016 ms->SetActualDataLength(write_pos);
2017 DeliverVideoMediaSample();
2022 // *samplepos+=packet.length;
2023 MILLISLEEP(0); //yet not implemented//bad idea
2028 bool VideoWin::supportsAc3(){
2029 if (sourcefilter != NULL) {
2030 return sourcefilter->supportsAc3();
2036 bool VideoWin::supportsh264()
2038 if (videoH264filterlist.size()>0) return true;
2043 bool VideoWin::changeAType(int type,IMediaSample* ms){
2044 if (sourcefilter!= NULL) {
2046 return sourcefilter->changeAType(type,ms);
2055 int VideoWin::test()
2060 int VideoWin::test2()