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;
60 filtermutex=CreateMutex(NULL,FALSE,NULL);
62 offsetvideonotset=true;
63 offsetaudionotset=true;
70 cur_audio_media_sample=NULL;
71 cur_video_media_sample=NULL;
76 aud_type=Audio::MPEG2_PES;
77 iframemode=false;//We are not in Iframe mode at begining
78 vmrdeinterlacing=2;//Best
79 videofilterselected=-1;
80 videoH264filterselected=-1;
81 OSVERSIONINFO verinfo;
82 verinfo.dwOSVersionInfoSize=sizeof(verinfo);
83 GetVersionEx(&verinfo);
85 if (verinfo.dwMajorVersion>=6) {
88 currentpresenter=VMR9;
90 videoH264dtsfix=false;
91 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 Osd *osd = Osd::getInstance();
150 if (dynamic_cast<OsdWinVector*>(osd)) {
151 return setAspectRatio(Video::ASPECT16X9, parx, pary);
154 return setAspectRatio(Video::ASPECT4X3, parx, pary);
158 int VideoWin::shutdown()
160 if (!initted) return 0;
165 int VideoWin::setFormat(UCHAR tformat)
167 if (!initted) return 0;
168 if ((tformat != PAL) && (tformat != NTSC)) return 0;
184 int VideoWin::setConnection(UCHAR tconnection)
186 if (!initted) return 0;
187 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
188 connection = tconnection;
193 int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
195 if (!initted) return 0;
198 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
199 aspectRatio = taspectRatio;
204 int VideoWin::setMode(UCHAR tmode)
206 if (!initted) return 0;
208 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
210 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
211 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
212 if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
218 int VideoWin::signalOff()
223 int VideoWin::signalOn()
228 int VideoWin::setSource()
230 if (!initted) return 0;
238 if (!initted) return 0;
242 void VideoWin::initFilterDatabase()
244 /* This method should determine all availiable DirectShow Filters */
245 IFilterMapper2* filtmap=NULL;
247 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
248 IID_IFilterMapper2,(void**)&filtmap);
251 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
254 /* Wishlist, what Mediatypes do we want */
255 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
256 IEnumMoniker *myenum;
257 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
258 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
262 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
267 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
269 VideoFilterDesc desc;
270 ZeroMemory(&desc,sizeof(desc));
273 moni->GetDisplayName(0,0,&string);
274 desc.displayname=new char[wcslen(string)+1];
275 wcstombs(desc.displayname,string,wcslen(string)+1);
276 CoTaskMemFree(string);
278 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
282 result = bag->Read(L"FriendlyName",&vari,NULL);
285 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
286 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
294 videofilterlist.push_back(desc);
302 videofilterselected=-1;
313 void VideoWin::initH264FilterDatabase()
315 /* This method should determine all availiable DirectShow Filters */
316 IFilterMapper2* filtmap=NULL;
318 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
319 IID_IFilterMapper2,(void**)&filtmap);
322 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
325 /* Wishlist, what Mediatypes do we want */
326 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
327 IEnumMoniker *myenum;
328 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
329 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
333 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
338 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
340 VideoFilterDesc desc;
341 ZeroMemory(&desc,sizeof(desc));
344 moni->GetDisplayName(0,0,&string);
345 desc.displayname=new char[wcslen(string)+1];
346 wcstombs(desc.displayname,string,wcslen(string)+1);
347 CoTaskMemFree(string);
349 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
353 result = bag->Read(L"FriendlyName",&vari,NULL);
356 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
357 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
365 videoH264filterlist.push_back(desc);
373 videoH264filterselected=-1;
384 bool VideoWin::loadOptionsfromServer(VDR* vdr)
386 char *name=vdr->configLoad("DirectShow","VideoFilter");
390 for (int i = 0;i <videofilterlist.size();i++)
392 if (strcmp(name,videofilterlist[i].displayname)==0)
394 videofilterselected = i;
399 name=vdr->configLoad("DirectShow","VideoH264Filter");
403 for (int i = 0;i <videoH264filterlist.size();i++)
405 if (strcmp(name,videoH264filterlist[i].displayname)==0)
407 videoH264filterselected = i;
412 name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
415 if (STRCASECMP(name,"NoMix")==0) {
417 } else if (STRCASECMP(name,"None")==0) {
419 } else if (STRCASECMP(name,"Best")==0) {
421 } else if (STRCASECMP(name,"Bob")==0) {
423 } else if (STRCASECMP(name,"Weave")==0) {
428 name=vdr->configLoad("DirectShow", "VideoPresenter");
430 if (STRCASECMP(name,"VMR9")==0) {
431 currentpresenter=VMR9;
432 } else if (STRCASECMP(name,"EVR")==0) {
433 currentpresenter=EVR;
436 if (!dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported()) {
437 currentpresenter=VMR9;
440 name=vdr->configLoad("DirectShow","videoH264dtsfix");
442 if (STRCASECMP(name,"YES")==0) {
443 videoH264dtsfix=true;
445 videoH264dtsfix=false;
448 name=vdr->configLoad("DirectShow","videompeg2dtsfix");
450 if (STRCASECMP(name,"YES")==0) {
451 videompeg2dtsfix=true;
453 videompeg2dtsfix=false;
457 name=vdr->configLoad("DirectGraphics", "StretchFiltering");
459 if (STRCASECMP(name,"None")==0) {
460 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
461 } else if (STRCASECMP(name,"Point")==0) {
462 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
463 } else if (STRCASECMP(name,"Linear")==0) {
464 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
475 bool VideoWin::handleOptionChanges(Option* option)
477 if( Video::handleOptionChanges(option)) return true;
480 if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
481 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
482 } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
483 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
484 } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
485 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
490 if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0) {
492 } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
494 } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0) {
496 } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0) {
498 } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0) {
503 if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0) {
504 currentpresenter=VMR9;
505 } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0) {
506 currentpresenter=EVR;
510 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
511 videoH264dtsfix=true;
513 videoH264dtsfix=false;
517 if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
518 videompeg2dtsfix=true;
520 videompeg2dtsfix=false;
528 bool VideoWin::saveOptionstoServer()
530 if (videofilterselected!=-1) {
531 VDR::getInstance()->configSave("DirectShow",
532 "VideoFilter",videofilterlist[videofilterselected].displayname);
533 VDR::getInstance()->configSave("DirectShow",
534 "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
539 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
540 UINT numChoices, UINT defaultChoice, UINT startInt,
541 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
543 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
545 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
551 DWORD scalingcaps=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getFilterCaps();
552 char **scalingopts=new char *[3];
554 scalingopts[i]=new char[strlen("None")+1];
555 strcpy(scalingopts[i],"None");
557 if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0
558 && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
559 scalingopts[i]=new char[strlen("Point")+1];
560 strcpy(scalingopts[i],"Point");
563 if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0
564 && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
565 scalingopts[i]=new char[strlen("Linear")+1];
566 strcpy(scalingopts[i],"Linear");
569 option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
570 options->push_back(option);
571 pane->addOptionLine(option);
572 static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
573 option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
574 options->push_back(option);
575 pane->addOptionLine(option);
577 if (dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported())
579 static const char* presenteropts[]={"EVR","VMR9"};
580 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
581 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
583 static const char* presenteropts[]={"VMR9"};
584 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
586 options->push_back(option);
587 pane->addOptionLine(option);
589 static const char* yesnoopts[]={"Yes","No"};
590 option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
591 options->push_back(option);
592 pane->addOptionLine(option);
594 option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
595 options->push_back(option);
596 pane->addOptionLine(option);
605 IBaseFilter *VideoWin::getVideoFilter()
607 IBaseFilter *curfilter= NULL;
608 if (videofilterselected == -1)
611 for (i = 0;i <videofilterlist.size();i++)
614 if (videofilterlist[i].vmr9tested == true)
616 if (videofilterlist[i].vmr9 == true)
618 videofilterselected = i;
628 IMoniker * moni=NULL;
629 IBindCtx *bindctx=NULL;
630 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
631 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
632 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
636 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
638 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
640 IAMDecoderCaps* desccaps=NULL;
641 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
644 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
645 if (caps == DECODER_CAP_SUPPORTED)
647 videofilterlist[i].vmr9tested = true;
648 videofilterlist[i].vmr9 = true;
649 videofilterselected = i;
653 videofilterlist[i].vmr9tested = true;
654 videofilterlist[i].vmr9 = false;
656 curfilter->Release();
667 if (videofilterlist[i].vmr9) break;
670 if (curfilter != NULL)
672 VDR *vdr=VDR::getInstance();
675 vdr->configSave("DirectShow","VideoFilter",
676 videofilterlist[videofilterselected].displayname);
683 IBindCtx *bindctx=NULL;
684 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
685 IMoniker * moni=NULL;
686 LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
687 mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
688 strlen(videofilterlist[videofilterselected].displayname)+1);
690 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
692 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
694 IAMDecoderCaps* desccaps=NULL;
695 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
698 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
699 if (caps == DECODER_CAP_SUPPORTED)
701 videofilterlist[videofilterselected].vmr9tested = true;
702 videofilterlist[videofilterselected].vmr9 = true;
706 videofilterlist[videofilterselected].vmr9tested = true;
707 videofilterlist[videofilterselected].vmr9 = false;
708 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
726 IBaseFilter *VideoWin::getVideoH264Filter()
728 IBaseFilter *curfilter= NULL;
729 if (videoH264filterselected == -1)
732 for (i = 0;i <videoH264filterlist.size();i++)
735 if (videoH264filterlist[i].vmr9tested == true)
737 if (videoH264filterlist[i].vmr9 == true)
739 videoH264filterselected = i;
749 IMoniker * moni=NULL;
750 IBindCtx *bindctx=NULL;
751 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
752 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
753 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
755 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
759 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
761 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
763 IAMDecoderCaps* desccaps=NULL;
764 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
767 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
768 if (caps == DECODER_CAP_SUPPORTED)
770 videoH264filterlist[i].vmr9tested = true;
771 videoH264filterlist[i].vmr9 = true;
772 videoH264filterselected = i;
776 videoH264filterlist[i].vmr9tested = true;
777 videoH264filterlist[i].vmr9 = false;
779 curfilter->Release();
790 if (videoH264filterlist[i].vmr9) break;
793 if (curfilter != NULL)
795 VDR *vdr=VDR::getInstance();
798 vdr->configSave("DirectShow","VideoH264Filter",
799 videoH264filterlist[videoH264filterselected].displayname);
806 IBindCtx *bindctx=NULL;
807 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
808 IMoniker * moni=NULL;
809 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
810 mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
811 strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
813 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
814 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
816 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
818 IAMDecoderCaps* desccaps=NULL;
819 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
822 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
823 if (caps == DECODER_CAP_SUPPORTED)
825 videoH264filterlist[videoH264filterselected].vmr9tested = true;
826 videoH264filterlist[videoH264filterselected].vmr9 = true;
830 videoH264filterlist[videoH264filterselected].vmr9tested = true;
831 videoH264filterlist[videoH264filterselected].vmr9 = false;
832 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
851 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
852 #include "dshelper.h"
859 if (!initted) return 0;
863 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
865 Boxx *box=new WWinVideoFilter();
866 wtb->addTab(tr("Video Filter"), box);
867 box=new WWinVideoH264Filter();
868 wtb->addTab(tr("H264 Filter"), box);
872 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
874 selected=videofilterselected;
875 return &videofilterlist;
878 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
880 selected=videoH264filterselected;
881 return &videoH264filterlist;
884 bool VideoWin::selectVideoFilter(int filter)
886 IBindCtx *bindctx=NULL;
887 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
888 IMoniker * moni=NULL;
889 LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
890 mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
891 strlen(videofilterlist[filter].displayname)+1);
894 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
896 IBaseFilter* curfilter=NULL;
897 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
899 IAMDecoderCaps* desccaps=NULL;
900 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
903 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
904 if (caps == DECODER_CAP_SUPPORTED)
906 videofilterlist[filter].vmr9tested = true;
907 videofilterlist[filter].vmr9 = true;
912 videofilterlist[filter].vmr9tested = true;
913 videofilterlist[filter].vmr9 = false;
918 videofilterlist[filter].vmr9tested = true;
919 videofilterlist[filter].vmr9 = false;
923 curfilter->Release();
932 videofilterselected=filter;
941 bool VideoWin::selectVideoH264Filter(int filter)
943 IBindCtx *bindctx=NULL;
944 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
945 IMoniker * moni=NULL;
946 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
947 mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
948 strlen(videoH264filterlist[filter].displayname)+1);
951 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
953 IBaseFilter* curfilter=NULL;
954 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
956 IAMDecoderCaps* desccaps=NULL;
957 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
960 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
961 if (caps == DECODER_CAP_SUPPORTED)
963 videoH264filterlist[filter].vmr9tested = true;
964 videoH264filterlist[filter].vmr9 = true;
969 videoH264filterlist[filter].vmr9tested = true;
970 videoH264filterlist[filter].vmr9 = false;
975 videoH264filterlist[filter].vmr9tested = true;
976 videoH264filterlist[filter].vmr9 = false;
980 curfilter->Release();
989 videoH264filterselected=filter;
998 int VideoWin::dsInitVideoFilter()
1003 //We alloc the vmr9 as next step
1004 if (currentpresenter==VMR9)
1006 Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1007 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1008 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1010 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1011 ReleaseMutex(filtermutex);
1015 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1017 ReleaseMutex(filtermutex);
1019 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1022 IVMRFilterConfig9* vmrfilconfig;
1023 if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1025 ReleaseMutex(filtermutex);
1027 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1030 if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1031 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1032 vmrfilconfig->Release();
1033 if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1034 (void**)& dsvmrsurfnotify) != S_OK)
1036 ReleaseMutex(filtermutex);
1038 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1041 allocatorvmr=new DsAllocator();
1042 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1043 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1045 IVMRDeinterlaceControl9* deintctrl;
1046 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1048 ReleaseMutex(filtermutex);
1050 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1054 switch (vmrdeinterlacing)
1056 case 1: //No Deinterlasing
1057 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1060 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1063 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1066 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1069 deintctrl->Release();
1070 /*VMR 9 stuff end */
1072 else if (currentpresenter==EVR)
1074 Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1075 if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1076 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1078 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1079 ReleaseMutex(filtermutex);
1083 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1085 ReleaseMutex(filtermutex);
1087 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1092 IMFGetService *evr_services;
1093 if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1095 ReleaseMutex(filtermutex);
1097 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1101 IMFVideoDisplayControl* mfvideodisplaycontrol;
1102 if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1104 ReleaseMutex(filtermutex);
1106 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1110 evr_services->Release();
1111 mfvideodisplaycontrol->SetVideoWindow(((WindowsOsd*) Osd::getInstance())->getWindow());
1113 //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1114 //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1116 mfvideodisplaycontrol->Release();
1119 /// if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1121 IMFVideoRenderer *mfvideorenderer;
1122 if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1124 ReleaseMutex(filtermutex);
1126 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1130 allocatorvmr=new DsAllocator();
1131 HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1133 mfvideorenderer->Release();
1134 //How should I do this in EVR?
1135 /* IVMRDeinterlaceControl9* deintctrl;
1136 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1138 ReleaseMutex(filtermutex);
1140 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1144 switch (vmrdeinterlacing)
1146 case 1: //No Deinterlasing
1147 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1150 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1153 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1156 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1159 deintctrl->Release();*/
1162 Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1165 IFilterGraph2*fg2=NULL;
1166 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1168 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1169 ReleaseMutex(filtermutex);
1173 /*#ifndef NEW_DS_MECHANISMENS
1175 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1176 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
1178 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1180 ReleaseMutex(filtermutex);
1186 IBaseFilter*videofilter;
1189 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1190 videofilter=getVideoH264Filter();
1194 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1195 videofilter=getVideoFilter();
1197 if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK)
1199 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1200 ReleaseMutex(filtermutex);
1204 IEnumPins *pinenum=NULL;
1207 mptype_video_detail vid_details;
1208 Demuxer* demux=Demuxer::getInstance();
1209 vid_details.width=demux->getHorizontalSize();
1210 vid_details.height=demux->getVerticalSize();
1214 if (vid_details.width!=0 && vid_details.height!=0)
1216 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1220 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1226 if (vid_details.width!=0 && vid_details.height!=0)
1228 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1232 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1235 if (videofilter->EnumPins(&pinenum) == S_OK)
1239 bool firststep=false;
1241 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1244 if (current->QueryDirection(&dir)==S_OK)
1246 if (dir == PINDIR_INPUT)
1248 if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1258 if (firststep==false)
1260 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1261 videofilter->Release();
1262 ReleaseMutex(filtermutex);
1266 bool secondstep=false;
1268 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1271 if (current->QueryDirection(&dir)==S_OK)
1273 if (dir == PINDIR_OUTPUT)
1276 if (fg2->RenderEx((IPin*)current/*video*/,
1277 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1287 if (secondstep==false)
1289 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1290 videofilter->Release();
1291 ReleaseMutex(filtermutex);
1296 videofilter->Release();
1310 int VideoWin::setAudioStreamType(UCHAR type)
1313 if (!initted) return 0;
1317 int VideoWin::dsplay()
1319 if (!initted) return 0;
1322 //Build filter graph
1324 //So this is the real code, this prevents the feeder from calling noexisting objects!
1325 WaitForSingleObject(filtermutex,INFINITE);
1326 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1327 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
1329 ReleaseMutex(filtermutex);
1333 AddToRot(dsgraphbuilder,&graphidentifier);
1337 if (aud_type==Audio::MP3) {
1338 lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1340 lastaudiomode=MPTYPE_MPEG_AUDIO;
1342 //lastaudiomode=MPTYPE_AC3;
1343 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1345 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
1347 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1348 ReleaseMutex(filtermutex);
1352 sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1353 /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK)
1355 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1356 ReleaseMutex(filtermutex);
1360 if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1362 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1363 ReleaseMutex(filtermutex);
1369 if (dsInitVideoFilter()==0)
1374 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1375 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
1379 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1380 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1382 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1383 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1385 dsbasicaudio->put_Volume(audiovolume);
1389 hresdeb=dsmediacontrol->Run();
1390 iframemode=false;//exit iframe mode
1391 ReleaseMutex(filtermutex);
1395 int VideoWin::EnterIframePlayback()
1397 if (!initted) return 0;
1399 //So this is the real code, this prevents the feeder from calling noexisting objects!
1400 WaitForSingleObject(filtermutex,INFINITE);
1401 iframemode=true;//enter iframe mode
1402 //Build filter graph
1404 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1405 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1406 ReleaseMutex(filtermutex);
1410 AddToRot(dsgraphbuilder,&graphidentifier);
1413 //firstsynched=false;
1414 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1416 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1417 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1418 ReleaseMutex(filtermutex);
1424 dsInitVideoFilter();
1427 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1428 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1432 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1433 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1435 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1436 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1440 dsmediacontrol->Run();
1441 ReleaseMutex(filtermutex);
1446 int VideoWin::dsstop()
1448 if (!initted) return 0;
1456 int VideoWin::stop()
1458 if (!initted) return 0;
1464 int VideoWin::reset()
1466 if (!initted) return 0;
1472 int VideoWin::dsreset()
1474 if (!initted) return 0;
1475 iframemode=false;//exit iframe mode
1481 int VideoWin::dspause()
1483 if (!initted) return 0;
1484 WaitForSingleObject(filtermutex,INFINITE);
1485 if (dsmediacontrol) dsmediacontrol->Pause();
1486 ReleaseMutex(filtermutex);
1490 int VideoWin::pause()
1492 if (!initted) return 0;
1497 int VideoWin::unPause() // 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;
1503 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1504 {//No on windows this is not the same, I don't get rid of!
1505 if (!initted) return 0;
1506 WaitForSingleObject(filtermutex,INFINITE);
1507 if (dsmediacontrol) dsmediacontrol->Run();
1508 ReleaseMutex(filtermutex);
1513 int VideoWin::fastForward()
1515 if (!initted) return 0;
1520 int VideoWin::unFastForward()
1522 if (!initted) return 0;
1527 int VideoWin::attachFrameBuffer()
1529 if (!initted) return 0;
1533 int VideoWin::blank(void)
1535 dynamic_cast<WindowsOsd*>(Osd::getInstance())->Blank();
1539 ULLONG VideoWin::getCurrentTimestamp()
1541 REFERENCE_TIME startoffset;
1542 REFERENCE_TIME ncr_time;
1543 if (iframemode) return 0; //Not in iframe mode!
1544 if (!dsrefclock || !sourcefilter) return 0;
1546 sourcefilter->GetState(10,&state);
1548 if (state==State_Running) dsrefclock->GetTime(&cr_time);
1550 startoffset=sourcefilter->getStartOffset();
1551 if (startoffset==0) return 0;
1552 ncr_time-=startoffset;
1553 ncr_time-=lastreftimeRT;
1554 /* ULLONG result=frameNumberToTimecode(
1555 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1556 long long result=lastreftimePTS;
1557 result+=(ULLONG)(ncr_time/10000LL*90LL);
1558 if (result<0) result=(1LL << 33)-result;
1565 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1567 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1568 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1571 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1573 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1574 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1577 void VideoWin::CleanupDS()
1579 WaitForSingleObject(filtermutex,INFINITE);
1581 if (dsmediacontrol)dsmediacontrol->Stop();
1582 if (cur_audio_media_sample) {
1583 cur_audio_media_sample->Release();
1584 cur_audio_media_sample=NULL;
1586 if (cur_video_media_sample) {
1587 cur_video_media_sample->Release();
1588 cur_video_media_sample=NULL;
1591 dsbasicaudio->Release();
1594 if (dsvmrsurfnotify) {
1595 dsvmrsurfnotify->Release();
1596 dsvmrsurfnotify=NULL;
1599 dsrenderer->Release();
1604 allocatorvmr->Release();
1609 dsrefclock->Release();
1612 if (dsmediafilter) {
1613 dsmediafilter->Release();
1619 if (dsmediacontrol) {
1620 dsmediacontrol->Stop();
1621 dsmediacontrol->Release();
1622 dsmediacontrol=NULL;
1624 if (dsgraphbuilder){
1626 RemoveFromRot(graphidentifier);
1628 dsgraphbuilder->Release();
1629 dsgraphbuilder=NULL;
1631 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1633 ReleaseMutex(filtermutex);
1637 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1640 mediapacket = mplist.front();
1643 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1645 DeliverMediaPacket(mediapacket, buffer, samplepos);
1646 if (*samplepos == mediapacket.length) {
1653 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1654 const UCHAR* buffer,
1658 /*First Check, if we have an audio sample*/
1659 if (!isdsinited()) return 0;
1660 if (packet.type == MPTYPE_VIDEO_H264)
1671 *samplepos+=packet.length;
1672 MILLISLEEP(0); //yet not implemented//bad idea
1673 return packet.length;
1675 /*First Check, if we have an audio sample*/
1679 return 0; //Not in iframe mode!
1681 IMediaSample* ms=NULL;
1682 REFERENCE_TIME reftime1=0;
1683 REFERENCE_TIME reftime2=0;
1686 if (packet.disconti) {
1688 DeliverVideoMediaSample();
1693 /*Inspect PES-Header */
1695 if (*samplepos==0) {//stripheader
1696 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1697 *samplepos+=headerstrip;
1698 if ( packet.synched ) {
1699 DeliverVideoMediaSample();//write out old data
1700 /* if (packet.presentation_time<0) { //Preroll?
1701 *samplepos=packet.length;//if we have not processed at least one
1702 return packet.length;//synched packet ignore it!
1705 reftime1=packet.presentation_time;
1706 reftime2=reftime1+1;
1709 if (!firstsynched) {//
1710 *samplepos=packet.length;//if we have not processed at least one
1711 return packet.length;//synched packet ignore it!
1720 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1722 //MessageBox(0,"da isser","hei",0);
1726 ms_pos=ms->GetActualDataLength();
1727 ms_length=ms->GetSize();
1728 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1729 if ((ms_length-ms_pos)<1 ) {
1730 DeliverVideoMediaSample(); //we are full!
1731 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1733 //MessageBox(0,"da isser","hei",0);
1737 ms_pos=ms->GetActualDataLength();
1738 ms_length=ms->GetSize();
1739 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1741 ms->GetPointer(&ms_buf);
1744 if (ms_pos==0) {//will only be changed on first packet
1745 if (packet.disconti) {
1746 ms->SetDiscontinuity(TRUE);
1748 ms->SetDiscontinuity(FALSE);
1750 if (packet.synched) {
1751 ms->SetSyncPoint(TRUE);
1752 ms->SetTime(&reftime1,&reftime2);
1753 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1754 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1755 //ms->SetTime(NULL,NULL);
1756 ms->SetMediaTime(NULL, NULL);
1757 if (reftime1<0) ms->SetPreroll(TRUE);
1758 else ms->SetPreroll(FALSE);
1759 /*Timecode handling*/
1760 lastreftimeRT=reftime1;
1761 lastreftimePTS=packet.pts;
1766 ms->SetSyncPoint(FALSE);
1767 ms->SetTime(NULL,NULL);
1768 ms->SetMediaTime(NULL, NULL);
1769 ms->SetPreroll(FALSE);
1771 // ms->SetSyncPoint(TRUE);
1777 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1778 ms->SetActualDataLength(haveToCopy+ms_pos);
1780 *samplepos+=haveToCopy;
1782 return haveToCopy+headerstrip;
1786 *samplepos+=packet.length;
1787 MILLISLEEP(0); //yet not implemented//bad idea
1788 return packet.length;
1792 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1794 //WaitForSingleObject(filtermutex,INFINITE);
1796 // ReleaseMutex(filtermutex);
1799 if (cur_audio_media_sample) {
1800 *ms=cur_audio_media_sample;//already open
1803 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1804 // ReleaseMutex(filtermutex);
1806 if (*ms) (*ms)->SetActualDataLength(0);
1807 cur_audio_media_sample=*ms;
1808 //Don't release the mutex before deliver
1812 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1814 //WaitForSingleObject(filtermutex,INFINITE);
1816 // ReleaseMutex(filtermutex);
1819 if (cur_video_media_sample) {
1820 *ms=cur_video_media_sample;//already open
1823 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1824 // ReleaseMutex(filtermutex);
1826 if (*ms) (*ms)->SetActualDataLength(0);
1828 cur_video_media_sample=*ms;
1829 //Don't release the mutex before deliver
1833 int VideoWin::DeliverAudioMediaSample(){
1834 if (cur_audio_media_sample) {
1835 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1836 cur_audio_media_sample=NULL;
1838 //ReleaseMutex(filtermutex);
1842 int VideoWin::DeliverVideoMediaSample(){
1843 if (cur_video_media_sample) {
1844 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1845 cur_video_media_sample=NULL;
1847 //ReleaseMutex(filtermutex);
1851 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1855 startoffset=curreftime;//offset is set for audio
1857 offsetvideonotset=false;
1861 if (offsetvideonotset) {
1862 offsetvideonotset=false;
1865 if ( (curreftime-lastrefvideotime)>10000000LL
1866 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1867 startoffset+=curreftime-lastrefvideotime;
1868 lastrefaudiotime+=curreftime-lastrefvideotime;
1870 offsetaudionotset=true;
1877 lastrefvideotime=curreftime;
1883 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1887 startoffset=curreftime;
1889 offsetaudionotset=false;
1891 if (offsetaudionotset) {
1892 offsetaudionotset=false;
1895 if ( (curreftime-lastrefaudiotime)>10000000LL
1896 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1897 startoffset+=curreftime-lastrefaudiotime;
1898 lastrefvideotime+=curreftime-lastrefaudiotime;
1900 offsetvideonotset=true;
1906 lastrefaudiotime=curreftime;
1910 void VideoWin::ResetTimeOffsets() {
1911 offsetnotset=true; //called from demuxer
1912 offsetvideonotset=true;
1913 offsetaudionotset=true;
1923 void VideoWin::SetAudioVolume(long volume)
1926 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1929 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1931 if (!iframemode) EnterIframePlayback();
1932 if (!isdsinited()) return false;
1935 IMediaSample* ms=NULL;
1936 REFERENCE_TIME reftime1=0;
1937 REFERENCE_TIME reftime2=0;
1938 if (!videoon) return false;
1939 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1945 ms->GetPointer(&ms_buf);
1946 ms_length=ms->GetSize();
1948 /*First Check, if we have an video sample*/
1949 DWORD read_pos = 0, write_pos = 0;
1950 DWORD pattern, packet_length;
1951 DWORD headerstrip=0;
1953 if (length < 4) return false;
1954 //Now we strip the pes header
1955 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1956 while (read_pos + 7 <= length)
1958 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1959 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1965 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1966 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1967 if (read_pos + packet_length > length)
1971 if ( (headerstrip < packet_length) &&
1972 (write_pos+packet_length-headerstrip)>ms_length) {
1974 ms->SetSyncPoint(TRUE);
1975 ms->SetDiscontinuity(TRUE);
1977 } else ms->SetSyncPoint(FALSE);
1978 ms->SetTime(NULL,NULL);
1979 ms->SetMediaTime(NULL, NULL);
1980 ms->SetActualDataLength(write_pos);
1981 DeliverVideoMediaSample();
1983 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1988 ms_length=ms->GetSize();
1989 ms->GetPointer(&ms_buf);
1991 if (packet_length>headerstrip) {
1992 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1993 write_pos += packet_length-headerstrip;
1995 read_pos += packet_length;
1997 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
1998 | (buffer[read_pos+2]);
2003 if (first) {ms->SetSyncPoint(TRUE);
2004 ms->SetDiscontinuity(TRUE);
2006 else ms->SetSyncPoint(FALSE);
2007 ms->SetTime(NULL,NULL);
2008 ms->SetMediaTime(NULL, NULL);
2009 ms->SetActualDataLength(write_pos);
2010 DeliverVideoMediaSample();
2015 // *samplepos+=packet.length;
2016 MILLISLEEP(0); //yet not implemented//bad idea
2021 bool VideoWin::supportsAc3(){
2022 if (sourcefilter != NULL) {
2023 return sourcefilter->supportsAc3();
2029 bool VideoWin::supportsh264()
2031 if (videoH264filterlist.size()>0) return true;
2036 bool VideoWin::changeAType(int type,IMediaSample* ms){
2037 if (sourcefilter!= NULL) {
2039 return sourcefilter->changeAType(type,ms);
2048 int VideoWin::test()
2053 int VideoWin::test2()