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;
92 CloseHandle(filtermutex);
94 for (i=0;i<videofilterlist.size();i++)
96 if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
97 if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
99 videofilterlist.clear();
101 for (i=0;i<videoH264filterlist.size();i++)
103 if (videoH264filterlist[i].displayname) delete [] videoH264filterlist[i].displayname;
104 if (videoH264filterlist[i].friendlyname) delete [] videoH264filterlist[i].friendlyname;
106 videoH264filterlist.clear();
114 int VideoWin::init(UCHAR tformat)
116 if (initted) return 0;
119 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
122 initFilterDatabase();
123 initH264FilterDatabase();
125 if (!setFormat(tformat)){ shutdown(); return 0; }
131 int VideoWin::setTVsize(UCHAR ttvsize)
133 pseudotvsize=ttvsize;
137 int VideoWin::setDefaultAspect()
139 return setAspectRatio(Video::ASPECT4X3);
142 int VideoWin::shutdown()
144 if (!initted) return 0;
149 int VideoWin::setFormat(UCHAR tformat)
151 if (!initted) return 0;
152 if ((tformat != PAL) && (tformat != NTSC)) return 0;
168 int VideoWin::setConnection(UCHAR tconnection)
170 if (!initted) return 0;
171 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
172 connection = tconnection;
177 int VideoWin::setAspectRatio(UCHAR taspectRatio)
179 if (!initted) return 0;
180 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
181 aspectRatio = taspectRatio;
186 int VideoWin::setMode(UCHAR tmode)
188 if (!initted) return 0;
190 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
192 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
193 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
202 int VideoWin::signalOff()
207 int VideoWin::signalOn()
212 int VideoWin::setSource()
214 if (!initted) return 0;
219 int VideoWin::setPosition(int x, int y)
221 if (!initted) return 0;
222 if (mode==QUARTER || mode==EIGHTH) {
231 if (!initted) return 0;
235 void VideoWin::initFilterDatabase()
237 /* This method should determine all availiable DirectShow Filters */
238 IFilterMapper2* filtmap=NULL;
240 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
241 IID_IFilterMapper2,(void**)&filtmap);
244 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
247 /* Wishlist, what Mediatypes do we want */
248 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
249 IEnumMoniker *myenum;
250 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
251 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
255 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
260 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
262 VideoFilterDesc desc;
263 ZeroMemory(&desc,sizeof(desc));
266 moni->GetDisplayName(0,0,&string);
267 desc.displayname=new char[wcslen(string)+1];
268 wcstombs(desc.displayname,string,wcslen(string)+1);
269 CoTaskMemFree(string);
271 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
275 result = bag->Read(L"FriendlyName",&vari,NULL);
278 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
279 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
287 videofilterlist.push_back(desc);
295 videofilterselected=-1;
306 void VideoWin::initH264FilterDatabase()
308 /* This method should determine all availiable DirectShow Filters */
309 IFilterMapper2* filtmap=NULL;
311 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
312 IID_IFilterMapper2,(void**)&filtmap);
315 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
318 /* Wishlist, what Mediatypes do we want */
319 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
320 IEnumMoniker *myenum;
321 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
322 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
326 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
331 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
333 VideoFilterDesc desc;
334 ZeroMemory(&desc,sizeof(desc));
337 moni->GetDisplayName(0,0,&string);
338 desc.displayname=new char[wcslen(string)+1];
339 wcstombs(desc.displayname,string,wcslen(string)+1);
340 CoTaskMemFree(string);
342 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
346 result = bag->Read(L"FriendlyName",&vari,NULL);
349 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
350 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
358 videoH264filterlist.push_back(desc);
366 videoH264filterselected=-1;
377 bool VideoWin::loadOptionsfromServer(VDR* vdr)
379 char *name=vdr->configLoad("DirectShow","VideoFilter");
383 for (int i = 0;i <videofilterlist.size();i++)
385 if (strcmp(name,videofilterlist[i].displayname)==0)
387 videofilterselected = i;
392 name=vdr->configLoad("DirectShow","VideoH264Filter");
396 for (int i = 0;i <videoH264filterlist.size();i++)
398 if (strcmp(name,videoH264filterlist[i].displayname)==0)
400 videoH264filterselected = i;
405 name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
408 if (STRCASECMP(name,"NoMix")==0) {
410 } else if (STRCASECMP(name,"None")==0) {
412 } else if (STRCASECMP(name,"Best")==0) {
414 } else if (STRCASECMP(name,"Bob")==0) {
416 } else if (STRCASECMP(name,"Weave")==0) {
421 name=vdr->configLoad("DirectShow", "VideoPresenter");
423 if (STRCASECMP(name,"VMR9")==0) {
424 currentpresenter=VMR9;
425 } else if (STRCASECMP(name,"EVR")==0) {
426 currentpresenter=EVR;
429 if (!((OsdWin*)Osd::getInstance())->IsEvrSupported()) {
430 currentpresenter=VMR9;
433 name=vdr->configLoad("DirectGraphics", "StretchFiltering");
435 if (STRCASECMP(name,"None")==0) {
436 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
437 } else if (STRCASECMP(name,"Point")==0) {
438 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
439 } else if (STRCASECMP(name,"Linear")==0) {
440 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
451 bool VideoWin::handleOptionChanges(Option* option)
453 if( Video::handleOptionChanges(option)) return true;
456 if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
457 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
458 } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
459 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
460 } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
461 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
466 if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0) {
468 } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
470 } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0) {
472 } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0) {
474 } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0) {
479 if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0) {
480 currentpresenter=VMR9;
481 } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0) {
482 currentpresenter=EVR;
490 bool VideoWin::saveOptionstoServer()
492 if (videofilterselected!=-1) {
493 VDR::getInstance()->configSave("DirectShow",
494 "VideoFilter",videofilterlist[videofilterselected].displayname);
495 VDR::getInstance()->configSave("DirectShow",
496 "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
501 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
502 UINT numChoices, UINT defaultChoice, UINT startInt,
503 const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
505 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
507 if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
513 DWORD scalingcaps=((OsdWin*)Osd::getInstance())->getFilterCaps();
514 char **scalingopts=new char *[3];
516 scalingopts[i]=new char[strlen("None")+1];
517 strcpy(scalingopts[i],"None");
519 if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0
520 && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
521 scalingopts[i]=new char[strlen("Point")+1];
522 strcpy(scalingopts[i],"Point");
525 if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0
526 && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
527 scalingopts[i]=new char[strlen("Linear")+1];
528 strcpy(scalingopts[i],"Linear");
531 option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
532 options->push_back(option);
533 pane->addOptionLine(option);
534 static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
535 option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
536 options->push_back(option);
537 pane->addOptionLine(option);
539 if (((OsdWin*)Osd::getInstance())->IsEvrSupported())
541 static const char* presenteropts[]={"EVR","VMR9"};
542 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,0,0,presenteropts,NULL,false,this);
544 static const char* presenteropts[]={"VMR9"};
545 option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
547 options->push_back(option);
548 pane->addOptionLine(option);
556 IBaseFilter *VideoWin::getVideoFilter()
558 IBaseFilter *curfilter= NULL;
559 if (videofilterselected == -1)
562 for (i = 0;i <videofilterlist.size();i++)
565 if (videofilterlist[i].vmr9tested == true)
567 if (videofilterlist[i].vmr9 == true)
569 videofilterselected = i;
579 IMoniker * moni=NULL;
580 IBindCtx *bindctx=NULL;
581 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
582 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
583 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
587 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
589 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
591 IAMDecoderCaps* desccaps=NULL;
592 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
595 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
596 if (caps == DECODER_CAP_SUPPORTED)
598 videofilterlist[i].vmr9tested = true;
599 videofilterlist[i].vmr9 = true;
600 videofilterselected = i;
604 videofilterlist[i].vmr9tested = true;
605 videofilterlist[i].vmr9 = false;
607 curfilter->Release();
618 if (videofilterlist[i].vmr9) break;
621 if (curfilter != NULL)
623 VDR *vdr=VDR::getInstance();
626 vdr->configSave("DirectShow","VideoFilter",
627 videofilterlist[videofilterselected].displayname);
634 IBindCtx *bindctx=NULL;
635 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
636 IMoniker * moni=NULL;
637 LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
638 mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
639 strlen(videofilterlist[videofilterselected].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[videofilterselected].vmr9tested = true;
653 videofilterlist[videofilterselected].vmr9 = true;
657 videofilterlist[videofilterselected].vmr9tested = true;
658 videofilterlist[videofilterselected].vmr9 = false;
659 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
677 IBaseFilter *VideoWin::getVideoH264Filter()
679 IBaseFilter *curfilter= NULL;
680 if (videoH264filterselected == -1)
683 for (i = 0;i <videoH264filterlist.size();i++)
686 if (videoH264filterlist[i].vmr9tested == true)
688 if (videoH264filterlist[i].vmr9 == true)
690 videoH264filterselected = i;
700 IMoniker * moni=NULL;
701 IBindCtx *bindctx=NULL;
702 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
703 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
704 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
706 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
710 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
712 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
714 IAMDecoderCaps* desccaps=NULL;
715 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
718 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
719 if (caps == DECODER_CAP_SUPPORTED)
721 videoH264filterlist[i].vmr9tested = true;
722 videoH264filterlist[i].vmr9 = true;
723 videoH264filterselected = i;
727 videoH264filterlist[i].vmr9tested = true;
728 videoH264filterlist[i].vmr9 = false;
730 curfilter->Release();
741 if (videoH264filterlist[i].vmr9) break;
744 if (curfilter != NULL)
746 VDR *vdr=VDR::getInstance();
749 vdr->configSave("DirectShow","VideoH264Filter",
750 videoH264filterlist[videoH264filterselected].displayname);
757 IBindCtx *bindctx=NULL;
758 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
759 IMoniker * moni=NULL;
760 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
761 mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
762 strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
764 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
765 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
767 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
769 IAMDecoderCaps* desccaps=NULL;
770 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
773 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
774 if (caps == DECODER_CAP_SUPPORTED)
776 videoH264filterlist[videoH264filterselected].vmr9tested = true;
777 videoH264filterlist[videoH264filterselected].vmr9 = true;
781 videoH264filterlist[videoH264filterselected].vmr9tested = true;
782 videoH264filterlist[videoH264filterselected].vmr9 = false;
783 Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
802 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
803 #include "dshelper.h"
810 if (!initted) return 0;
814 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
816 Boxx *box=new WWinVideoFilter();
817 wtb->addTab(tr("Video Filter"), box);
818 box=new WWinVideoH264Filter();
819 wtb->addTab(tr("H264 Filter"), box);
823 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
825 selected=videofilterselected;
826 return &videofilterlist;
829 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
831 selected=videoH264filterselected;
832 return &videoH264filterlist;
835 bool VideoWin::selectVideoFilter(int filter)
837 IBindCtx *bindctx=NULL;
838 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
839 IMoniker * moni=NULL;
840 LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
841 mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
842 strlen(videofilterlist[filter].displayname)+1);
845 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
847 IBaseFilter* curfilter=NULL;
848 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
850 IAMDecoderCaps* desccaps=NULL;
851 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
854 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
855 if (caps == DECODER_CAP_SUPPORTED)
857 videofilterlist[filter].vmr9tested = true;
858 videofilterlist[filter].vmr9 = true;
863 videofilterlist[filter].vmr9tested = true;
864 videofilterlist[filter].vmr9 = false;
869 videofilterlist[filter].vmr9tested = true;
870 videofilterlist[filter].vmr9 = false;
874 curfilter->Release();
883 videofilterselected=filter;
892 bool VideoWin::selectVideoH264Filter(int filter)
894 IBindCtx *bindctx=NULL;
895 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
896 IMoniker * moni=NULL;
897 LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
898 mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
899 strlen(videoH264filterlist[filter].displayname)+1);
902 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
904 IBaseFilter* curfilter=NULL;
905 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
907 IAMDecoderCaps* desccaps=NULL;
908 if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
911 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
912 if (caps == DECODER_CAP_SUPPORTED)
914 videoH264filterlist[filter].vmr9tested = true;
915 videoH264filterlist[filter].vmr9 = true;
920 videoH264filterlist[filter].vmr9tested = true;
921 videoH264filterlist[filter].vmr9 = false;
926 videoH264filterlist[filter].vmr9tested = true;
927 videoH264filterlist[filter].vmr9 = false;
931 curfilter->Release();
940 videoH264filterselected=filter;
949 int VideoWin::dsInitVideoFilter()
954 //We alloc the vmr9 as next step
955 if (currentpresenter==VMR9)
957 Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
958 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
959 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
961 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
962 ReleaseMutex(filtermutex);
966 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
968 ReleaseMutex(filtermutex);
970 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
973 IVMRFilterConfig9* vmrfilconfig;
974 if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
976 ReleaseMutex(filtermutex);
978 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
981 if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
982 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
983 vmrfilconfig->Release();
984 if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
985 (void**)& dsvmrsurfnotify) != S_OK)
987 ReleaseMutex(filtermutex);
989 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
992 allocatorvmr=new DsAllocator();
993 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
994 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
996 IVMRDeinterlaceControl9* deintctrl;
997 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
999 ReleaseMutex(filtermutex);
1001 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1005 switch (vmrdeinterlacing)
1007 case 1: //No Deinterlasing
1008 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1011 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1014 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1017 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1020 deintctrl->Release();
1021 /*VMR 9 stuff end */
1023 else if (currentpresenter==EVR)
1025 Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1026 if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1027 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK)
1029 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1030 ReleaseMutex(filtermutex);
1034 if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1036 ReleaseMutex(filtermutex);
1038 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1043 IMFGetService *evr_services;
1044 if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1046 ReleaseMutex(filtermutex);
1048 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1052 IMFVideoDisplayControl* mfvideodisplaycontrol;
1053 if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1055 ReleaseMutex(filtermutex);
1057 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1061 evr_services->Release();
1062 mfvideodisplaycontrol->SetVideoWindow(((OsdWin*) Osd::getInstance())->getWindow());
1064 //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1065 //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1067 mfvideodisplaycontrol->Release();
1070 /// if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1072 IMFVideoRenderer *mfvideorenderer;
1073 if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1075 ReleaseMutex(filtermutex);
1077 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1081 allocatorvmr=new DsAllocator();
1082 HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1084 mfvideorenderer->Release();
1085 //How should I do this in EVR?
1086 /* IVMRDeinterlaceControl9* deintctrl;
1087 if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1089 ReleaseMutex(filtermutex);
1091 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1095 switch (vmrdeinterlacing)
1097 case 1: //No Deinterlasing
1098 deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1101 deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1104 deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1107 deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1110 deintctrl->Release();*/
1113 Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1116 IFilterGraph2*fg2=NULL;
1117 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1119 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1120 ReleaseMutex(filtermutex);
1124 /*#ifndef NEW_DS_MECHANISMENS
1126 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1127 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
1129 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1131 ReleaseMutex(filtermutex);
1137 IBaseFilter*videofilter;
1140 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1141 videofilter=getVideoH264Filter();
1145 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1146 videofilter=getVideoFilter();
1148 if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK)
1150 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1151 ReleaseMutex(filtermutex);
1155 IEnumPins *pinenum=NULL;
1158 mptype_video_detail vid_details;
1159 Demuxer* demux=Demuxer::getInstance();
1160 vid_details.width=demux->getHorizontalSize();
1161 vid_details.height=demux->getVerticalSize();
1165 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1169 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1171 if (videofilter->EnumPins(&pinenum) == S_OK)
1175 bool firststep=false;
1177 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1180 if (current->QueryDirection(&dir)==S_OK)
1182 if (dir == PINDIR_INPUT)
1184 if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1194 if (firststep==false)
1196 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1197 videofilter->Release();
1198 ReleaseMutex(filtermutex);
1202 bool secondstep=false;
1204 while (pinenum->Next(1,¤t,&fetch)==S_OK)
1207 if (current->QueryDirection(&dir)==S_OK)
1209 if (dir == PINDIR_OUTPUT)
1212 if (fg2->RenderEx((IPin*)current/*video*/,
1213 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1223 if (secondstep==false)
1225 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1226 videofilter->Release();
1227 ReleaseMutex(filtermutex);
1232 videofilter->Release();
1246 int VideoWin::setAudioStreamType(UCHAR type)
1249 if (!initted) return 0;
1253 int VideoWin::dsplay()
1255 if (!initted) return 0;
1258 //Build filter graph
1260 //So this is the real code, this prevents the feeder from calling noexisting objects!
1261 WaitForSingleObject(filtermutex,INFINITE);
1262 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1263 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
1265 ReleaseMutex(filtermutex);
1269 AddToRot(dsgraphbuilder,&graphidentifier);
1273 if (aud_type==Audio::MP3) {
1274 lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1276 lastaudiomode=MPTYPE_MPEG_AUDIO;
1278 //lastaudiomode=MPTYPE_AC3;
1279 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1281 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
1283 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1284 ReleaseMutex(filtermutex);
1288 sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1289 /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK)
1291 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1292 ReleaseMutex(filtermutex);
1296 if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1298 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1299 ReleaseMutex(filtermutex);
1305 if (dsInitVideoFilter()==0)
1310 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1311 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
1315 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1316 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1318 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1319 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1321 dsbasicaudio->put_Volume(audiovolume);
1325 hresdeb=dsmediacontrol->Run();
1326 iframemode=false;//exit iframe mode
1327 ReleaseMutex(filtermutex);
1331 int VideoWin::EnterIframePlayback()
1333 if (!initted) return 0;
1335 //So this is the real code, this prevents the feeder from calling noexisting objects!
1336 WaitForSingleObject(filtermutex,INFINITE);
1337 iframemode=true;//enter iframe mode
1338 //Build filter graph
1340 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1341 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1342 ReleaseMutex(filtermutex);
1346 AddToRot(dsgraphbuilder,&graphidentifier);
1349 //firstsynched=false;
1350 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1352 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1353 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1354 ReleaseMutex(filtermutex);
1360 dsInitVideoFilter();
1363 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1364 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1368 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1369 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1371 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1372 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
1376 dsmediacontrol->Run();
1377 ReleaseMutex(filtermutex);
1382 int VideoWin::dsstop()
1384 if (!initted) return 0;
1392 int VideoWin::stop()
1394 if (!initted) return 0;
1400 int VideoWin::reset()
1402 if (!initted) return 0;
1408 int VideoWin::dsreset()
1410 if (!initted) return 0;
1413 iframemode=false;//exit iframe mode
1419 int VideoWin::dspause()
1421 if (!initted) return 0;
1422 WaitForSingleObject(filtermutex,INFINITE);
1423 if (dsmediacontrol) dsmediacontrol->Pause();
1424 ReleaseMutex(filtermutex);
1428 int VideoWin::pause()
1430 if (!initted) return 0;
1435 int VideoWin::unPause() // FIXME get rid - same as play!!
1436 {//No on windows this is not the same, I don't get rid of!
1437 if (!initted) return 0;
1441 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1442 {//No on windows this is not the same, I don't get rid of!
1443 if (!initted) return 0;
1444 WaitForSingleObject(filtermutex,INFINITE);
1445 if (dsmediacontrol) dsmediacontrol->Run();
1446 ReleaseMutex(filtermutex);
1451 int VideoWin::fastForward()
1453 if (!initted) return 0;
1458 int VideoWin::unFastForward()
1460 if (!initted) return 0;
1465 int VideoWin::attachFrameBuffer()
1467 if (!initted) return 0;
1471 int VideoWin::blank(void)
1473 ((OsdWin*)Osd::getInstance())->Blank();
1477 ULLONG VideoWin::getCurrentTimestamp()
1479 REFERENCE_TIME startoffset;
1480 REFERENCE_TIME ncr_time;
1481 if (iframemode) return 0; //Not in iframe mode!
1482 if (!dsrefclock || !sourcefilter) return 0;
1484 sourcefilter->GetState(10,&state);
1486 if (state==State_Running) dsrefclock->GetTime(&cr_time);
1488 startoffset=sourcefilter->getStartOffset();
1489 ncr_time-=startoffset;
1490 ncr_time-=lastreftimeRT;
1491 /* ULLONG result=frameNumberToTimecode(
1492 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1493 ULLONG result=lastreftimePTS;
1494 result+=(ULLONG)(ncr_time/10000LL*90LL);
1499 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1501 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1502 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1505 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1507 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1508 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1511 void VideoWin::CleanupDS()
1513 WaitForSingleObject(filtermutex,INFINITE);
1515 if (dsmediacontrol)dsmediacontrol->Stop();
1516 if (cur_audio_media_sample) {
1517 cur_audio_media_sample->Release();
1518 cur_audio_media_sample=NULL;
1520 if (cur_video_media_sample) {
1521 cur_video_media_sample->Release();
1522 cur_video_media_sample=NULL;
1525 dsbasicaudio->Release();
1528 if (dsvmrsurfnotify) {
1529 dsvmrsurfnotify->Release();
1530 dsvmrsurfnotify=NULL;
1533 dsrenderer->Release();
1538 allocatorvmr->Release();
1543 dsrefclock->Release();
1546 if (dsmediafilter) {
1547 dsmediafilter->Release();
1553 if (dsmediacontrol) {
1554 dsmediacontrol->Stop();
1555 dsmediacontrol->Release();
1556 dsmediacontrol=NULL;
1558 if (dsgraphbuilder){
1560 RemoveFromRot(graphidentifier);
1562 dsgraphbuilder->Release();
1563 dsgraphbuilder=NULL;
1565 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1567 ReleaseMutex(filtermutex);
1571 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1574 mediapacket = mplist.front();
1577 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1579 DeliverMediaPacket(mediapacket, buffer, samplepos);
1580 if (*samplepos == mediapacket.length) {
1587 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1588 const UCHAR* buffer,
1592 /*First Check, if we have an audio sample*/
1593 if (!isdsinited()) return 0;
1594 if (packet.type == MPTYPE_VIDEO_H264)
1605 *samplepos+=packet.length;
1606 MILLISLEEP(0); //yet not implemented//bad idea
1607 return packet.length;
1609 /*First Check, if we have an audio sample*/
1613 return 0; //Not in iframe mode!
1615 IMediaSample* ms=NULL;
1616 REFERENCE_TIME reftime1=0;
1617 REFERENCE_TIME reftime2=0;
1620 if (packet.disconti) {
1622 DeliverVideoMediaSample();
1627 /*Inspect PES-Header */
1629 if (*samplepos==0) {//stripheader
1630 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1631 *samplepos+=headerstrip;
1632 if ( packet.synched ) {
1633 DeliverVideoMediaSample();//write out old data
1634 /* if (packet.presentation_time<0) { //Preroll?
1635 *samplepos=packet.length;//if we have not processed at least one
1636 return packet.length;//synched packet ignore it!
1639 reftime1=packet.presentation_time;
1640 reftime2=reftime1+1;
1643 if (!firstsynched) {//
1644 *samplepos=packet.length;//if we have not processed at least one
1645 return packet.length;//synched packet ignore it!
1654 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1656 //MessageBox(0,"da isser","hei",0);
1660 ms_pos=ms->GetActualDataLength();
1661 ms_length=ms->GetSize();
1662 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1663 if ((ms_length-ms_pos)<1 ) {
1664 DeliverVideoMediaSample(); //we are full!
1665 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1667 //MessageBox(0,"da isser","hei",0);
1671 ms_pos=ms->GetActualDataLength();
1672 ms_length=ms->GetSize();
1673 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1675 ms->GetPointer(&ms_buf);
1678 if (ms_pos==0) {//will only be changed on first packet
1679 if (packet.disconti) {
1680 ms->SetDiscontinuity(TRUE);
1682 ms->SetDiscontinuity(FALSE);
1684 if (packet.synched) {
1685 ms->SetSyncPoint(TRUE);
1686 ms->SetTime(&reftime1,&reftime2);
1687 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1688 //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1689 //ms->SetTime(NULL,NULL);
1690 ms->SetMediaTime(NULL, NULL);
1691 if (reftime1<0) ms->SetPreroll(TRUE);
1692 else ms->SetPreroll(FALSE);
1693 /*Timecode handling*/
1694 lastreftimeRT=reftime1;
1695 lastreftimePTS=packet.pts;
1700 ms->SetSyncPoint(FALSE);
1701 ms->SetTime(NULL,NULL);
1702 ms->SetMediaTime(NULL, NULL);
1703 ms->SetPreroll(FALSE);
1705 // ms->SetSyncPoint(TRUE);
1711 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1712 ms->SetActualDataLength(haveToCopy+ms_pos);
1714 *samplepos+=haveToCopy;
1716 return haveToCopy+headerstrip;
1720 *samplepos+=packet.length;
1721 MILLISLEEP(0); //yet not implemented//bad idea
1722 return packet.length;
1726 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1728 //WaitForSingleObject(filtermutex,INFINITE);
1730 // ReleaseMutex(filtermutex);
1733 if (cur_audio_media_sample) {
1734 *ms=cur_audio_media_sample;//already open
1737 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1738 // ReleaseMutex(filtermutex);
1740 if (*ms) (*ms)->SetActualDataLength(0);
1741 cur_audio_media_sample=*ms;
1742 //Don't release the mutex before deliver
1746 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1748 //WaitForSingleObject(filtermutex,INFINITE);
1750 // ReleaseMutex(filtermutex);
1753 if (cur_video_media_sample) {
1754 *ms=cur_video_media_sample;//already open
1757 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1758 // ReleaseMutex(filtermutex);
1760 if (*ms) (*ms)->SetActualDataLength(0);
1762 cur_video_media_sample=*ms;
1763 //Don't release the mutex before deliver
1767 int VideoWin::DeliverAudioMediaSample(){
1768 if (cur_audio_media_sample) {
1769 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1770 cur_audio_media_sample=NULL;
1772 //ReleaseMutex(filtermutex);
1776 int VideoWin::DeliverVideoMediaSample(){
1777 if (cur_video_media_sample) {
1778 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1779 cur_video_media_sample=NULL;
1781 //ReleaseMutex(filtermutex);
1785 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1789 startoffset=curreftime;//offset is set for audio
1791 offsetvideonotset=false;
1795 if (offsetvideonotset) {
1796 offsetvideonotset=false;
1799 if ( (curreftime-lastrefvideotime)>10000000LL
1800 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1801 startoffset+=curreftime-lastrefvideotime;
1802 lastrefaudiotime+=curreftime-lastrefvideotime;
1804 offsetaudionotset=true;
1811 lastrefvideotime=curreftime;
1817 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1821 startoffset=curreftime;
1823 offsetaudionotset=false;
1825 if (offsetaudionotset) {
1826 offsetaudionotset=false;
1829 if ( (curreftime-lastrefaudiotime)>10000000LL
1830 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1831 startoffset+=curreftime-lastrefaudiotime;
1832 lastrefvideotime+=curreftime-lastrefaudiotime;
1834 offsetvideonotset=true;
1840 lastrefaudiotime=curreftime;
1844 void VideoWin::ResetTimeOffsets() {
1845 offsetnotset=true; //called from demuxer
1846 offsetvideonotset=true;
1847 offsetaudionotset=true;
1857 void VideoWin::SetAudioVolume(long volume)
1860 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1863 void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1865 if (!iframemode) EnterIframePlayback();
1866 if (!isdsinited()) return ;
1869 IMediaSample* ms=NULL;
1870 REFERENCE_TIME reftime1=0;
1871 REFERENCE_TIME reftime2=0;
1872 if (!videoon) return;
1873 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1879 ms->GetPointer(&ms_buf);
1880 ms_length=ms->GetSize();
1882 /*First Check, if we have an video sample*/
1883 DWORD read_pos = 0, write_pos = 0;
1884 DWORD pattern, packet_length;
1885 DWORD headerstrip=0;
1887 if (length < 4) return ;
1888 //Now we strip the pes header
1889 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1890 while (read_pos + 7 <= length)
1892 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1893 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1899 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1900 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1901 if (read_pos + packet_length > length)
1905 if ( (headerstrip < packet_length) &&
1906 (write_pos+packet_length-headerstrip)>ms_length) {
1908 ms->SetSyncPoint(TRUE);
1909 ms->SetDiscontinuity(TRUE);
1911 } else ms->SetSyncPoint(FALSE);
1912 ms->SetTime(NULL,NULL);
1913 ms->SetMediaTime(NULL, NULL);
1914 ms->SetActualDataLength(write_pos);
1915 DeliverVideoMediaSample();
1917 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1922 ms_length=ms->GetSize();
1923 ms->GetPointer(&ms_buf);
1925 if (packet_length>headerstrip) {
1926 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1927 write_pos += packet_length-headerstrip;
1929 read_pos += packet_length;
1931 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
1932 | (buffer[read_pos+2]);
1937 if (first) {ms->SetSyncPoint(TRUE);
1938 ms->SetDiscontinuity(TRUE);
1940 else ms->SetSyncPoint(FALSE);
1941 ms->SetTime(NULL,NULL);
1942 ms->SetMediaTime(NULL, NULL);
1943 ms->SetActualDataLength(write_pos);
1944 DeliverVideoMediaSample();
1948 // *samplepos+=packet.length;
1949 MILLISLEEP(0); //yet not implemented//bad idea
1954 bool VideoWin::supportsAc3(){
1955 if (sourcefilter != NULL) {
1956 return sourcefilter->supportsAc3();
1962 bool VideoWin::supportsh264()
1964 if (videoH264filterlist.size()>0) return true;
1969 bool VideoWin::changeAType(int type,IMediaSample* ms){
1970 if (sourcefilter!= NULL) {
1972 return sourcefilter->changeAType(type,ms);
1981 int VideoWin::test()
1986 int VideoWin::test2()