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"
28 #include "windowsosd.h"
29 #include "osdwinvector.h"
31 #include "wwinvideofilter.h"
32 #include "wwinvideoh264filter.h"
34 #include "woptionpane.h"
57 lastaudiomode=MPTYPE_MPEG_AUDIO;
58 //lastaudiomode=MPTYPE_AC3;
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);
85 #pragma warning(disable : 4996)
87 GetVersionEx(&verinfo);
89 if (verinfo.dwMajorVersion>=6) {
92 currentpresenter=VMR9;
94 videoH264dtsfix=false;
95 videompeg2dtsfix=false;
103 VideoWin::~VideoWin()
107 for (i=0;i<videofilterlist.size();i++)
109 if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
110 if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
112 videofilterlist.clear();
114 for (i=0;i<videoH264filterlist.size();i++)
116 if (videoH264filterlist[i].displayname) delete [] videoH264filterlist[i].displayname;
117 if (videoH264filterlist[i].friendlyname) delete [] videoH264filterlist[i].friendlyname;
119 videoH264filterlist.clear();
127 int VideoWin::init(UCHAR tformat)
129 if (initted) return 0;
132 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
134 vd.mode = Fullscreen;
135 initFilterDatabase();
136 initH264FilterDatabase();
138 if (!setFormat(tformat)){ shutdown(); return 0; }
144 int VideoWin::setTVsize(UCHAR ttvsize)
146 pseudotvsize=ttvsize;
150 int VideoWin::setDefaultAspect()
152 Osd *osd = Osd::getInstance();
153 if (dynamic_cast<OsdWinVector*>(osd)) {
154 return setAspectRatio(Video::ASPECT16X9, parx, pary);
157 return setAspectRatio(Video::ASPECT4X3, parx, pary);
161 int VideoWin::shutdown()
163 if (!initted) return 0;
168 int VideoWin::setFormat(UCHAR tformat)
170 if (!initted) return 0;
171 if ((tformat != PAL) && (tformat != NTSC)) return 0;
187 int VideoWin::setConnection(UCHAR tconnection)
189 if (!initted) return 0;
190 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
191 connection = tconnection;
196 int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
198 if (!initted) return 0;
201 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
202 aspectRatio = taspectRatio;
207 int VideoWin::setMode(UCHAR tmode)
209 if (!initted) return 0;
211 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
213 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
214 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
215 if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
221 int VideoWin::signalOff()
226 int VideoWin::signalOn()
231 int VideoWin::setSource()
233 if (!initted) return 0;
241 if (!initted) return 0;
245 void VideoWin::initFilterDatabase()
247 /* This method should determine all availiable DirectShow Filters */
248 IFilterMapper2* filtmap=NULL;
250 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
251 IID_IFilterMapper2,(void**)&filtmap);
254 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
257 /* Wishlist, what Mediatypes do we want */
258 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
259 IEnumMoniker *myenum;
260 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
261 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
265 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
270 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
272 VideoFilterDesc desc;
273 ZeroMemory(&desc,sizeof(desc));
276 moni->GetDisplayName(0,0,&string);
277 desc.displayname=new char[wcslen(string)+1];
278 wcstombs(desc.displayname,string,wcslen(string)+1);
279 CoTaskMemFree(string);
281 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
285 result = bag->Read(L"FriendlyName",&vari,NULL);
288 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
289 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
297 videofilterlist.push_back(desc);
305 videofilterselected=-1;
316 void VideoWin::initH264FilterDatabase()
318 /* This method should determine all availiable DirectShow Filters */
319 IFilterMapper2* filtmap=NULL;
321 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
322 IID_IFilterMapper2,(void**)&filtmap);
325 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
328 /* Wishlist, what Mediatypes do we want */
329 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
330 IEnumMoniker *myenum;
331 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
332 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
336 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
341 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
343 VideoFilterDesc desc;
344 ZeroMemory(&desc,sizeof(desc));
347 moni->GetDisplayName(0,0,&string);
348 desc.displayname=new char[wcslen(string)+1];
349 wcstombs(desc.displayname,string,wcslen(string)+1);
350 CoTaskMemFree(string);
352 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
356 result = bag->Read(L"FriendlyName",&vari,NULL);
359 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
360 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
368 videoH264filterlist.push_back(desc);
376 videoH264filterselected=-1;
387 bool VideoWin::loadOptionsFromServer(VDR* vdr)
389 char *name=vdr->configLoad("DirectShow","VideoFilter");
393 for (int i = 0;i <videofilterlist.size();i++)
395 if (strcmp(name,videofilterlist[i].displayname)==0)
397 videofilterselected = i;
402 name=vdr->configLoad("DirectShow","VideoH264Filter");
406 for (int i = 0;i <videoH264filterlist.size();i++)
408 if (strcmp(name,videoH264filterlist[i].displayname)==0)
410 videoH264filterselected = i;
415 name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
418 if (STRCASECMP(name,"NoMix")==0) {
420 } else if (STRCASECMP(name,"None")==0) {
422 } else if (STRCASECMP(name,"Best")==0) {
424 } else if (STRCASECMP(name,"Bob")==0) {
426 } else if (STRCASECMP(name,"Weave")==0) {
431 name=vdr->configLoad("DirectShow", "VideoPresenter");
433 if (STRCASECMP(name,"VMR9")==0) {
434 currentpresenter=VMR9;
435 } else if (STRCASECMP(name,"EVR")==0) {
436 currentpresenter=EVR;
439 if (!dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported()) {
440 currentpresenter=VMR9;
443 name=vdr->configLoad("DirectShow","videoH264dtsfix");
445 if (STRCASECMP(name,"YES")==0) {
446 videoH264dtsfix=true;
448 videoH264dtsfix=false;
451 name=vdr->configLoad("DirectShow","videompeg2dtsfix");
453 if (STRCASECMP(name,"YES")==0) {
454 videompeg2dtsfix=true;
456 videompeg2dtsfix=false;
460 name=vdr->configLoad("DirectGraphics", "StretchFiltering");
462 if (STRCASECMP(name,"None")==0) {
463 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
464 } else if (STRCASECMP(name,"Point")==0) {
465 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
466 } else if (STRCASECMP(name,"Linear")==0) {
467 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
478 bool VideoWin::handleOptionChanges(Option* option)
480 if( Video::handleOptionChanges(option)) return true;
483 if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
484 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
485 } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
486 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
487 } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
488 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
493 if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0) {
495 } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
497 } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0) {
499 } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0) {
501 } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0) {
506 if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0) {
507 currentpresenter=VMR9;
508 } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0) {
509 currentpresenter=EVR;
513 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
514 videoH264dtsfix=true;
516 videoH264dtsfix=false;
520 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
521 videompeg2dtsfix=true;
523 videompeg2dtsfix=false;
531 bool VideoWin::saveOptionstoServer()
533 if (videofilterselected!=-1) {
534 VDR::getInstance()->configSave("DirectShow",
535 "VideoFilter",videofilterlist[videofilterselected].displayname);
536 VDR::getInstance()->configSave("DirectShow",
537 "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
542 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
543 UINT numChoices, UINT defaultChoice, UINT startInt,
544 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
546 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
548 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
554 DWORD scalingcaps=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getFilterCaps();
555 char **scalingopts=new char *[3];
557 scalingopts[i]=new char[strlen("None")+1];
558 strcpy(scalingopts[i],"None");
560 if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0
561 && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
562 scalingopts[i]=new char[strlen("Point")+1];
563 strcpy(scalingopts[i],"Point");
566 if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0
567 && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
568 scalingopts[i]=new char[strlen("Linear")+1];
569 strcpy(scalingopts[i],"Linear");
572 option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
573 options->push_back(option);
574 pane->addOptionLine(option);
575 static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
576 option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
577 options->push_back(option);
578 pane->addOptionLine(option);
580 if (dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported())
582 static const char* presenteropts[]={"EVR","VMR9"};
583 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
584 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
586 static const char* presenteropts[]={"VMR9"};
587 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
589 options->push_back(option);
590 pane->addOptionLine(option);
592 static const char* yesnoopts[]={"Yes","No"};
593 option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
594 options->push_back(option);
595 pane->addOptionLine(option);
597 option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
598 options->push_back(option);
599 pane->addOptionLine(option);
608 IBaseFilter *VideoWin::getVideoFilter()
610 IBaseFilter *curfilter= NULL;
611 if (videofilterselected == -1)
614 for (i = 0;i <videofilterlist.size();i++)
617 if (videofilterlist[i].vmr9tested == true)
619 if (videofilterlist[i].vmr9 == true)
621 videofilterselected = i;
631 IMoniker * moni=NULL;
632 IBindCtx *bindctx=NULL;
633 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
634 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
635 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
639 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
641 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
643 IAMDecoderCaps* desccaps=NULL;
644 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
647 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
648 if (caps == DECODER_CAP_SUPPORTED)
650 videofilterlist[i].vmr9tested = true;
651 videofilterlist[i].vmr9 = true;
652 videofilterselected = i;
656 videofilterlist[i].vmr9tested = true;
657 videofilterlist[i].vmr9 = false;
659 curfilter->Release();
670 if (videofilterlist[i].vmr9) break;
673 if (curfilter != NULL)
675 VDR *vdr=VDR::getInstance();
678 vdr->configSave("DirectShow","VideoFilter",
679 videofilterlist[videofilterselected].displayname);
686 IBindCtx *bindctx=NULL;
687 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
688 IMoniker * moni=NULL;
689 LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
690 mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
691 strlen(videofilterlist[videofilterselected].displayname)+1);
693 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
695 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
697 IAMDecoderCaps* desccaps=NULL;
698 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
701 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
702 if (caps == DECODER_CAP_SUPPORTED)
704 videofilterlist[videofilterselected].vmr9tested = true;
705 videofilterlist[videofilterselected].vmr9 = true;
709 videofilterlist[videofilterselected].vmr9tested = true;
710 videofilterlist[videofilterselected].vmr9 = false;
711 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
729 IBaseFilter *VideoWin::getVideoH264Filter()
731 IBaseFilter *curfilter= NULL;
732 if (videoH264filterselected == -1)
735 for (i = 0;i <videoH264filterlist.size();i++)
738 if (videoH264filterlist[i].vmr9tested == true)
740 if (videoH264filterlist[i].vmr9 == true)
742 videoH264filterselected = i;
752 IMoniker * moni=NULL;
753 IBindCtx *bindctx=NULL;
754 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
755 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
756 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
758 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
762 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
764 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
766 IAMDecoderCaps* desccaps=NULL;
767 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
770 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
771 if (caps == DECODER_CAP_SUPPORTED)
773 videoH264filterlist[i].vmr9tested = true;
774 videoH264filterlist[i].vmr9 = true;
775 videoH264filterselected = i;
779 videoH264filterlist[i].vmr9tested = true;
780 videoH264filterlist[i].vmr9 = false;
782 curfilter->Release();
793 if (videoH264filterlist[i].vmr9) break;
796 if (curfilter != NULL)
798 VDR *vdr=VDR::getInstance();
801 vdr->configSave("DirectShow","VideoH264Filter",
802 videoH264filterlist[videoH264filterselected].displayname);
809 IBindCtx *bindctx=NULL;
810 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
811 IMoniker * moni=NULL;
812 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
813 mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
814 strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
816 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
817 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
819 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
821 IAMDecoderCaps* desccaps=NULL;
822 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
825 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
826 if (caps == DECODER_CAP_SUPPORTED)
828 videoH264filterlist[videoH264filterselected].vmr9tested = true;
829 videoH264filterlist[videoH264filterselected].vmr9 = true;
833 videoH264filterlist[videoH264filterselected].vmr9tested = true;
834 videoH264filterlist[videoH264filterselected].vmr9 = false;
835 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
854 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
855 #include "dshelper.h"
862 if (!initted) return 0;
866 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
868 Boxx *box=new WWinVideoFilter();
869 wtb->addTab(tr("Video Filter"), box);
870 box=new WWinVideoH264Filter();
871 wtb->addTab(tr("H264 Filter"), box);
875 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
877 selected=videofilterselected;
878 return &videofilterlist;
881 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
883 selected=videoH264filterselected;
884 return &videoH264filterlist;
887 bool VideoWin::selectVideoFilter(int filter)
889 IBindCtx *bindctx=NULL;
890 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
891 IMoniker * moni=NULL;
892 LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
893 mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
894 strlen(videofilterlist[filter].displayname)+1);
897 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
899 IBaseFilter* curfilter=NULL;
900 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
902 IAMDecoderCaps* desccaps=NULL;
903 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
906 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
907 if (caps == DECODER_CAP_SUPPORTED)
909 videofilterlist[filter].vmr9tested = true;
910 videofilterlist[filter].vmr9 = true;
915 videofilterlist[filter].vmr9tested = true;
916 videofilterlist[filter].vmr9 = false;
921 videofilterlist[filter].vmr9tested = true;
922 videofilterlist[filter].vmr9 = false;
926 curfilter->Release();
935 videofilterselected=filter;
944 bool VideoWin::selectVideoH264Filter(int filter)
946 IBindCtx *bindctx=NULL;
947 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
948 IMoniker * moni=NULL;
949 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
950 mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
951 strlen(videoH264filterlist[filter].displayname)+1);
954 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
956 IBaseFilter* curfilter=NULL;
957 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
959 IAMDecoderCaps* desccaps=NULL;
960 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
963 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
964 if (caps == DECODER_CAP_SUPPORTED)
966 videoH264filterlist[filter].vmr9tested = true;
967 videoH264filterlist[filter].vmr9 = true;
972 videoH264filterlist[filter].vmr9tested = true;
973 videoH264filterlist[filter].vmr9 = false;
978 videoH264filterlist[filter].vmr9tested = true;
979 videoH264filterlist[filter].vmr9 = false;
983 curfilter->Release();
992 videoH264filterselected=filter;
1001 int VideoWin::dsInitVideoFilter()
1006 //We alloc the vmr9 as next step
1007 if (currentpresenter==VMR9)
1009 Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1010 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1011 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1013 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1014 filtermutex.unlock();
1018 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1020 filtermutex.unlock();
1022 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1025 IVMRFilterConfig9* vmrfilconfig;
1026 if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1028 filtermutex.unlock();
1030 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1033 if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1034 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1035 vmrfilconfig->Release();
1036 if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1037 (void**)& dsvmrsurfnotify) != S_OK)
1039 filtermutex.unlock();
1041 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1044 allocatorvmr=new DsAllocator();
1045 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1046 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1048 IVMRDeinterlaceControl9* deintctrl;
1049 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1051 filtermutex.unlock();
1053 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1057 switch (vmrdeinterlacing)
1059 case 1: //No Deinterlasing
1060 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1063 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1066 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1069 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1072 deintctrl->Release();
1073 /*VMR 9 stuff end */
1075 else if (currentpresenter==EVR)
1077 Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1078 if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1079 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1081 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1082 filtermutex.unlock();
1086 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1088 filtermutex.unlock();
1090 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1095 IMFGetService *evr_services;
1096 if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1098 filtermutex.unlock();
1100 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1104 IMFVideoDisplayControl* mfvideodisplaycontrol;
1105 if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1107 filtermutex.unlock();
1109 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1113 evr_services->Release();
1114 mfvideodisplaycontrol->SetVideoWindow(((WindowsOsd*) Osd::getInstance())->getWindow());
1116 //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1117 //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1119 mfvideodisplaycontrol->Release();
1122 /// if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1124 IMFVideoRenderer *mfvideorenderer;
1125 if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1127 filtermutex.unlock();
1129 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1133 allocatorvmr=new DsAllocator();
1134 HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1136 mfvideorenderer->Release();
1137 //How should I do this in EVR?
1138 /* IVMRDeinterlaceControl9* deintctrl;
1139 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1141 filtermutex.unlock();
1143 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1147 switch (vmrdeinterlacing)
1149 case 1: //No Deinterlasing
1150 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1153 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1156 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1159 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1162 deintctrl->Release();*/
1165 Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1168 IFilterGraph2*fg2=NULL;
1169 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1171 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1172 filtermutex.unlock();
1176 /*#ifndef NEW_DS_MECHANISMENS
1178 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1179 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
1181 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1183 filtermutex.unlock();
1189 IBaseFilter*videofilter;
1192 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1193 videofilter=getVideoH264Filter();
1197 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1198 videofilter=getVideoFilter();
1200 if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK)
1202 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1203 filtermutex.unlock();
1207 IEnumPins *pinenum=NULL;
1210 mptype_video_detail vid_details;
1211 Demuxer* demux=Demuxer::getInstance();
1212 vid_details.width=demux->getHorizontalSize();
1213 vid_details.height=demux->getVerticalSize();
1217 if (vid_details.width!=0 && vid_details.height!=0)
1219 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1223 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1229 if (vid_details.width!=0 && vid_details.height!=0)
1231 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1235 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1238 if (videofilter->EnumPins(&pinenum) == S_OK)
1242 bool firststep=false;
1244 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1247 if (current->QueryDirection(&dir)==S_OK)
1249 if (dir == PINDIR_INPUT)
1251 if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1261 if (firststep==false)
1263 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1264 videofilter->Release();
1265 filtermutex.unlock();
1269 bool secondstep=false;
1271 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1274 if (current->QueryDirection(&dir)==S_OK)
1276 if (dir == PINDIR_OUTPUT)
1279 if (fg2->RenderEx((IPin*)current/*video*/,
1280 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1290 if (secondstep==false)
1292 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1293 videofilter->Release();
1294 filtermutex.unlock();
1299 videofilter->Release();
1313 int VideoWin::setAudioStreamType(UCHAR type)
1316 if (!initted) return 0;
1320 int VideoWin::dsplay()
1322 if (!initted) return 0;
1325 //Build filter graph
1327 //So this is the real code, this prevents the feeder from calling noexisting objects!
1329 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1330 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
1332 filtermutex.unlock();
1336 AddToRot(dsgraphbuilder,&graphidentifier);
1340 if (aud_type==Audio::MP3) {
1341 lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1343 lastaudiomode=MPTYPE_MPEG_AUDIO;
1345 //lastaudiomode=MPTYPE_AC3;
1346 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1348 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
1350 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1351 filtermutex.unlock();
1355 sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1356 /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK)
1358 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1359 filtermutex.unlock();
1363 if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1365 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1366 filtermutex.unlock();
1372 if (dsInitVideoFilter()==0)
1377 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1378 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
1382 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1383 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1385 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1386 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1388 dsbasicaudio->put_Volume(audiovolume);
1392 hresdeb=dsmediacontrol->Run();
1393 iframemode=false;//exit iframe mode
1394 filtermutex.unlock();
1398 int VideoWin::EnterIframePlayback()
1400 if (!initted) return 0;
1402 //So this is the real code, this prevents the feeder from calling noexisting objects!
1404 iframemode=true;//enter iframe mode
1405 //Build filter graph
1407 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1408 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1409 filtermutex.unlock();
1413 AddToRot(dsgraphbuilder,&graphidentifier);
1416 //firstsynched=false;
1417 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1419 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1420 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1421 filtermutex.unlock();
1427 dsInitVideoFilter();
1430 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1431 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1435 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1436 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1438 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1439 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1443 dsmediacontrol->Run();
1444 filtermutex.unlock();
1449 int VideoWin::dsstop()
1451 if (!initted) return 0;
1459 int VideoWin::stop()
1461 if (!initted) return 0;
1467 int VideoWin::reset()
1469 if (!initted) return 0;
1475 int VideoWin::dsreset()
1477 if (!initted) return 0;
1478 iframemode=false;//exit iframe mode
1484 int VideoWin::dspause()
1486 if (!initted) return 0;
1488 if (dsmediacontrol) dsmediacontrol->Pause();
1489 filtermutex.unlock();
1493 int VideoWin::pause()
1495 if (!initted) return 0;
1500 int VideoWin::unPause() // FIXME get rid - same as play!!
1501 {//No on windows this is not the same, I don't get rid of!
1502 if (!initted) return 0;
1506 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1507 {//No on windows this is not the same, I don't get rid of!
1508 if (!initted) return 0;
1510 if (dsmediacontrol) dsmediacontrol->Run();
1511 filtermutex.unlock();
1516 int VideoWin::fastForward()
1518 if (!initted) return 0;
1523 int VideoWin::unFastForward()
1525 if (!initted) return 0;
1530 int VideoWin::attachFrameBuffer()
1532 if (!initted) return 0;
1536 int VideoWin::blank(void)
1538 dynamic_cast<WindowsOsd*>(Osd::getInstance())->Blank();
1542 ULLONG VideoWin::getCurrentTimestamp()
1544 REFERENCE_TIME startoffset;
1545 REFERENCE_TIME ncr_time;
1546 if (iframemode) return 0; //Not in iframe mode!
1547 if (!dsrefclock || !sourcefilter) return 0;
1549 sourcefilter->GetState(10,&state);
1551 if (state==State_Running) dsrefclock->GetTime(&cr_time);
1553 startoffset=sourcefilter->getStartOffset();
1554 if (startoffset==0) return 0;
1555 ncr_time-=startoffset;
1556 ncr_time-=lastreftimeRT;
1557 /* ULLONG result=frameNumberToTimecode(
1558 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1559 long long result=lastreftimePTS;
1560 result+=(ULLONG)(ncr_time/10000LL*90LL);
1561 if (result<0) result=(1LL << 33)-result;
1568 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1570 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1571 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1574 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1576 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1577 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1580 void VideoWin::CleanupDS()
1584 if (dsmediacontrol)dsmediacontrol->Stop();
1585 if (cur_audio_media_sample) {
1586 cur_audio_media_sample->Release();
1587 cur_audio_media_sample=NULL;
1589 if (cur_video_media_sample) {
1590 cur_video_media_sample->Release();
1591 cur_video_media_sample=NULL;
1594 dsbasicaudio->Release();
1597 if (dsvmrsurfnotify) {
1598 dsvmrsurfnotify->Release();
1599 dsvmrsurfnotify=NULL;
1602 dsrenderer->Release();
1607 allocatorvmr->Release();
1612 dsrefclock->Release();
1615 if (dsmediafilter) {
1616 dsmediafilter->Release();
1622 if (dsmediacontrol) {
1623 dsmediacontrol->Stop();
1624 dsmediacontrol->Release();
1625 dsmediacontrol=NULL;
1627 if (dsgraphbuilder){
1629 RemoveFromRot(graphidentifier);
1631 dsgraphbuilder->Release();
1632 dsgraphbuilder=NULL;
1634 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1636 filtermutex.unlock();
1640 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1643 mediapacket = mplist.front();
1646 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1648 DeliverMediaPacket(mediapacket, buffer, samplepos);
1649 if (*samplepos == mediapacket.length) {
1656 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1657 const UCHAR* buffer,
1661 /*First Check, if we have an audio sample*/
1662 if (!isdsinited()) return 0;
1663 if (packet.type == MPTYPE_VIDEO_H264)
1674 *samplepos+=packet.length;
1675 MILLISLEEP(0); //yet not implemented//bad idea
1676 return packet.length;
1678 /*First Check, if we have an audio sample*/
1682 return 0; //Not in iframe mode!
1684 IMediaSample* ms=NULL;
1685 REFERENCE_TIME reftime1=0;
1686 REFERENCE_TIME reftime2=0;
1689 if (packet.disconti) {
1691 DeliverVideoMediaSample();
1696 /*Inspect PES-Header */
1698 if (*samplepos==0) {//stripheader
1699 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1700 *samplepos+=headerstrip;
1701 if ( packet.synched ) {
1702 DeliverVideoMediaSample();//write out old data
1703 /* if (packet.presentation_time<0) { //Preroll?
1704 *samplepos=packet.length;//if we have not processed at least one
1705 return packet.length;//synched packet ignore it!
1708 reftime1=packet.presentation_time;
1709 reftime2=reftime1+1;
1712 if (!firstsynched) {//
1713 *samplepos=packet.length;//if we have not processed at least one
1714 return packet.length;//synched packet ignore it!
1723 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1725 //MessageBox(0,"da isser","hei",0);
1729 ms_pos=ms->GetActualDataLength();
1730 ms_length=ms->GetSize();
1731 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1732 if ((ms_length-ms_pos)<1 ) {
1733 DeliverVideoMediaSample(); //we are full!
1734 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1736 //MessageBox(0,"da isser","hei",0);
1740 ms_pos=ms->GetActualDataLength();
1741 ms_length=ms->GetSize();
1742 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1744 ms->GetPointer(&ms_buf);
1747 if (ms_pos==0) {//will only be changed on first packet
1748 if (packet.disconti) {
1749 ms->SetDiscontinuity(TRUE);
1751 ms->SetDiscontinuity(FALSE);
1753 if (packet.synched) {
1754 ms->SetSyncPoint(TRUE);
1755 ms->SetTime(&reftime1,&reftime2);
1756 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1757 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1758 //ms->SetTime(NULL,NULL);
1759 ms->SetMediaTime(NULL, NULL);
1760 if (reftime1<0) ms->SetPreroll(TRUE);
1761 else ms->SetPreroll(FALSE);
1762 /*Timecode handling*/
1763 lastreftimeRT=reftime1;
1764 lastreftimePTS=packet.pts;
1769 ms->SetSyncPoint(FALSE);
1770 ms->SetTime(NULL,NULL);
1771 ms->SetMediaTime(NULL, NULL);
1772 ms->SetPreroll(FALSE);
1774 // ms->SetSyncPoint(TRUE);
1780 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1781 ms->SetActualDataLength(haveToCopy+ms_pos);
1783 *samplepos+=haveToCopy;
1785 return haveToCopy+headerstrip;
1789 *samplepos+=packet.length;
1790 MILLISLEEP(0); //yet not implemented//bad idea
1791 return packet.length;
1795 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1797 //filtermutex.lock();
1799 // filtermutex.unlock();
1802 if (cur_audio_media_sample) {
1803 *ms=cur_audio_media_sample;//already open
1806 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1807 // filtermutex.unlock();
1809 if (*ms) (*ms)->SetActualDataLength(0);
1810 cur_audio_media_sample=*ms;
1811 //Don't release the mutex before deliver
1815 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1817 //filtermutex.lock();
1819 // filtermutex.unlock();
1822 if (cur_video_media_sample) {
1823 *ms=cur_video_media_sample;//already open
1826 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1827 // filtermutex.unlock();
1829 if (*ms) (*ms)->SetActualDataLength(0);
1831 cur_video_media_sample=*ms;
1832 //Don't release the mutex before deliver
1836 int VideoWin::DeliverAudioMediaSample(){
1837 if (cur_audio_media_sample) {
1838 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1839 cur_audio_media_sample=NULL;
1841 //filtermutex.unlock();
1845 int VideoWin::DeliverVideoMediaSample(){
1846 if (cur_video_media_sample) {
1847 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1848 cur_video_media_sample=NULL;
1850 //filtermutex.unlock();
1854 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1858 startoffset=curreftime;//offset is set for audio
1860 offsetvideonotset=false;
1864 if (offsetvideonotset) {
1865 offsetvideonotset=false;
1868 if ( (curreftime-lastrefvideotime)>10000000LL
1869 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1870 startoffset+=curreftime-lastrefvideotime;
1871 lastrefaudiotime+=curreftime-lastrefvideotime;
1873 offsetaudionotset=true;
1880 lastrefvideotime=curreftime;
1886 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1890 startoffset=curreftime;
1892 offsetaudionotset=false;
1894 if (offsetaudionotset) {
1895 offsetaudionotset=false;
1898 if ( (curreftime-lastrefaudiotime)>10000000LL
1899 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1900 startoffset+=curreftime-lastrefaudiotime;
1901 lastrefvideotime+=curreftime-lastrefaudiotime;
1903 offsetvideonotset=true;
1909 lastrefaudiotime=curreftime;
1913 void VideoWin::ResetTimeOffsets() {
1914 offsetnotset=true; //called from demuxer
1915 offsetvideonotset=true;
1916 offsetaudionotset=true;
1926 void VideoWin::SetAudioVolume(long volume)
1929 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1932 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1934 if (!iframemode) EnterIframePlayback();
1935 if (!isdsinited()) return false;
1938 IMediaSample* ms=NULL;
1939 REFERENCE_TIME reftime1=0;
1940 REFERENCE_TIME reftime2=0;
1941 if (!videoon) return false;
1942 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1948 ms->GetPointer(&ms_buf);
1949 ms_length=ms->GetSize();
1951 /*First Check, if we have an video sample*/
1952 DWORD read_pos = 0, write_pos = 0;
1953 DWORD pattern, packet_length;
1954 DWORD headerstrip=0;
1956 if (length < 4) return false;
1957 //Now we strip the pes header
1958 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1959 while (read_pos + 7 <= length)
1961 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1962 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1968 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1969 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1970 if (read_pos + packet_length > length)
1974 if ( (headerstrip < packet_length) &&
1975 (write_pos+packet_length-headerstrip)>ms_length) {
1977 ms->SetSyncPoint(TRUE);
1978 ms->SetDiscontinuity(TRUE);
1980 } else ms->SetSyncPoint(FALSE);
1981 ms->SetTime(NULL,NULL);
1982 ms->SetMediaTime(NULL, NULL);
1983 ms->SetActualDataLength(write_pos);
1984 DeliverVideoMediaSample();
1986 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1991 ms_length=ms->GetSize();
1992 ms->GetPointer(&ms_buf);
1994 if (packet_length>headerstrip) {
1995 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1996 write_pos += packet_length-headerstrip;
1998 read_pos += packet_length;
2000 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
2001 | (buffer[read_pos+2]);
2006 if (first) {ms->SetSyncPoint(TRUE);
2007 ms->SetDiscontinuity(TRUE);
2009 else ms->SetSyncPoint(FALSE);
2010 ms->SetTime(NULL,NULL);
2011 ms->SetMediaTime(NULL, NULL);
2012 ms->SetActualDataLength(write_pos);
2013 DeliverVideoMediaSample();
2018 // *samplepos+=packet.length;
2019 MILLISLEEP(0); //yet not implemented//bad idea
2024 bool VideoWin::supportsAc3(){
2025 if (sourcefilter != NULL) {
2026 return sourcefilter->supportsAc3();
2032 bool VideoWin::supportsh264()
2034 if (videoH264filterlist.size()>0) return true;
2039 bool VideoWin::changeAType(int type,IMediaSample* ms){
2040 if (sourcefilter!= NULL) {
2042 return sourcefilter->changeAType(type,ms);
2051 int VideoWin::test()
2056 int VideoWin::test2()