]> git.vomp.tv Git - vompclient-marten.git/blob - videowin.cc
Fix bug in demuxer widescreen signaling
[vompclient-marten.git] / videowin.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
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.
10
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.
15
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.
19 */
20
21
22
23 #include "videowin.h"
24 #include "log.h"
25 #include "dssourcefilter.h"
26 #include "dsallocator.h"
27 #include "vdr.h"
28 #include "osdwin.h"
29 #include "audiowin.h"
30 #include "wwinvideofilter.h"
31 #include "wwinvideoh264filter.h"
32 #include "wtabbar.h"
33 #include "woptionpane.h"
34 #include "i18n.h"
35 #include "demuxer.h"
36
37 #include <Mfapi.h>
38 #include <mferror.h>
39
40 void AdjustWindow();
41
42
43
44 VideoWin::VideoWin()
45 {
46   dsinited=false;
47   dsgraphbuilder=NULL;
48   dsmediacontrol=NULL;
49   dsrenderer=NULL;
50   dsrefclock=NULL;
51   dsmediafilter=NULL;
52   dsbasicaudio=NULL;
53   sourcefilter=NULL;
54   allocatorvmr=NULL;
55   cr_time=0;
56   lastaudiomode=MPTYPE_MPEG_AUDIO;
57   //lastaudiomode=MPTYPE_AC3;
58   dsvmrsurfnotify=NULL;
59   filtermutex=CreateMutex(NULL,FALSE,NULL);
60   offsetnotset=true;
61   offsetvideonotset=true;
62   offsetaudionotset=true;
63   startoffset=0;
64   lastrefaudiotime=0;
65   lastrefvideotime=0;
66   lastreftimeRT=0;
67   lastreftimePTS=0;
68   firstsynched=false;
69   cur_audio_media_sample=NULL;
70   cur_video_media_sample=NULL;
71   videoon=true;
72   audioon=true;
73   audiovolume=0;
74   pseudotvsize=0;
75   videoposx=0;
76   videoposy=0;
77   aud_type=Audio::MPEG2_PES;
78   iframemode=false;//We are not in Iframe mode at begining
79   vmrdeinterlacing=2;//Best
80   videofilterselected=-1;
81   videoH264filterselected=-1;
82   OSVERSIONINFO verinfo;
83   verinfo.dwOSVersionInfoSize=sizeof(verinfo);
84   GetVersionEx(&verinfo);
85
86   if (verinfo.dwMajorVersion>=6) {
87   currentpresenter=EVR;
88   } else {
89       currentpresenter=VMR9;
90   }
91   videoH264dtsfix=false;
92   videompeg2dtsfix=false;
93
94
95
96
97 }
98
99 VideoWin::~VideoWin()
100 {
101   CleanupDS();
102   CloseHandle(filtermutex);
103   unsigned int i;
104   for (i=0;i<videofilterlist.size();i++)
105   {
106    if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
107    if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
108   }
109   videofilterlist.clear();
110
111   for (i=0;i<videoH264filterlist.size();i++)
112   {
113    if (videoH264filterlist[i].displayname) delete [] videoH264filterlist[i].displayname;
114    if (videoH264filterlist[i].friendlyname) delete [] videoH264filterlist[i].friendlyname;
115   }
116   videoH264filterlist.clear();
117
118
119
120
121   instance = NULL;
122 }
123
124 int VideoWin::init(UCHAR tformat)
125 {
126   if (initted) return 0;
127
128   initted = 1;
129   tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
130   videoposx=0;
131   videoposy=0;
132   initFilterDatabase();
133   initH264FilterDatabase();
134
135   if (!setFormat(tformat)){ shutdown(); return 0; }
136   return 1;
137 }
138
139
140
141 int VideoWin::setTVsize(UCHAR ttvsize)
142 {
143   pseudotvsize=ttvsize;
144   return 1;
145 }
146
147 int VideoWin::setDefaultAspect()
148 {
149   return setAspectRatio(Video::ASPECT4X3,parx,pary);
150 }
151
152 int VideoWin::shutdown()
153 {
154   if (!initted) return 0;
155   initted = 0;
156   return 1;
157 }
158
159 int VideoWin::setFormat(UCHAR tformat)
160 {
161   if (!initted) return 0;
162   if ((tformat != PAL) && (tformat != NTSC)) return 0;
163   format = tformat;
164   if (format == NTSC)
165   {
166     screenWidth = 720;
167     screenHeight = 480;
168   }
169   if (format == PAL)
170   {
171     screenWidth = 720;
172     screenHeight = 576;
173   }
174
175   return 1;
176 }
177
178 int VideoWin::setConnection(UCHAR tconnection)
179 {
180   if (!initted) return 0;
181   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
182   connection = tconnection;
183
184   return 1;
185 }
186
187 int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
188 {
189   if (!initted) return 0;
190   parx=tparx;
191   pary=tpary;
192   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
193   aspectRatio = taspectRatio;
194   AdjustWindow();
195   return 1;
196 }
197
198 int VideoWin::setMode(UCHAR tmode)
199 {
200   if (!initted) return 0;
201
202   //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
203
204   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
205       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
206   mode = tmode;
207   videoposx=0;
208   videoposy=0;
209   AdjustWindow();
210
211   return 1;
212 }
213
214 int VideoWin::signalOff()
215 {
216   return 1;
217 }
218
219 int VideoWin::signalOn()
220 {
221   return 1;
222 }
223
224 int VideoWin::setSource()
225 {
226   if (!initted) return 0;
227
228   return 1;
229 }
230
231 int VideoWin::setPosition(int x, int y)
232 {
233   if (!initted) return 0;
234   if (mode==QUARTER || mode==EIGHTH) {
235   videoposx=x;
236   videoposy=y;
237   }
238   return 1;
239 }
240
241 int VideoWin::sync()
242 {
243   if (!initted) return 0;
244
245   return 1;
246 }
247 void VideoWin::initFilterDatabase()
248 {
249     /* This method should determine all availiable DirectShow Filters */
250     IFilterMapper2* filtmap=NULL;
251     HRESULT result;
252     result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
253                 IID_IFilterMapper2,(void**)&filtmap);
254     if (result != S_OK)
255     {
256         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
257         return;
258     }
259     /* Wishlist, what Mediatypes do we want */
260     GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
261     IEnumMoniker *myenum;
262     result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
263                     TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
264     if (result != S_OK)
265     {
266         filtmap->Release();
267         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
268         return;
269     }
270     ULONG gethowmany;
271     IMoniker * moni;
272     while(myenum->Next(1,&moni,&gethowmany)==S_OK)
273     {
274         VideoFilterDesc desc;
275         ZeroMemory(&desc,sizeof(desc));
276    
277         LPOLESTR string;
278         moni->GetDisplayName(0,0,&string);
279         desc.displayname=new char[wcslen(string)+1];
280         wcstombs(desc.displayname,string,wcslen(string)+1);
281         CoTaskMemFree(string);
282         IPropertyBag *bag;
283         if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
284         {
285             VARIANT vari;
286             VariantInit(&vari);
287             result = bag->Read(L"FriendlyName",&vari,NULL);
288             if (result == S_OK)
289             {
290                 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
291                 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
292             }
293             VariantClear(&vari);
294             bag->Release();
295
296         }
297         
298        
299         videofilterlist.push_back(desc);
300        
301
302         
303         moni->Release();
304        // bctx->Release();
305     }
306     int i;
307     videofilterselected=-1;
308     
309     
310   
311     myenum->Release();
312
313
314
315     filtmap->Release();
316 }
317
318 void VideoWin::initH264FilterDatabase()
319 {
320     /* This method should determine all availiable DirectShow Filters */
321     IFilterMapper2* filtmap=NULL;
322     HRESULT result;
323     result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
324                 IID_IFilterMapper2,(void**)&filtmap);
325     if (result != S_OK)
326     {
327         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
328         return;
329     }
330     /* Wishlist, what Mediatypes do we want */
331     GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
332     IEnumMoniker *myenum;
333     result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
334                     TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
335     if (result != S_OK)
336     {
337         filtmap->Release();
338         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
339         return;
340     }
341     ULONG gethowmany;
342     IMoniker * moni;
343     while(myenum->Next(1,&moni,&gethowmany)==S_OK)
344     {
345         VideoFilterDesc desc;
346         ZeroMemory(&desc,sizeof(desc));
347    
348         LPOLESTR string;
349         moni->GetDisplayName(0,0,&string);
350         desc.displayname=new char[wcslen(string)+1];
351         wcstombs(desc.displayname,string,wcslen(string)+1);
352         CoTaskMemFree(string);
353         IPropertyBag *bag;
354         if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
355         {
356             VARIANT vari;
357             VariantInit(&vari);
358             result = bag->Read(L"FriendlyName",&vari,NULL);
359             if (result == S_OK)
360             {
361                 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
362                 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
363             }
364             VariantClear(&vari);
365             bag->Release();
366
367         }
368         
369        
370         videoH264filterlist.push_back(desc);
371        
372
373         
374         moni->Release();
375        // bctx->Release();
376     }
377     int i;
378     videoH264filterselected=-1;
379     
380     
381   
382     myenum->Release();
383
384
385
386     filtmap->Release();
387 }
388
389 bool VideoWin::loadOptionsfromServer(VDR* vdr)
390 {
391     char *name=vdr->configLoad("DirectShow","VideoFilter");
392     
393     if (name != NULL) 
394     {
395         for (int i = 0;i <videofilterlist.size();i++)
396         {
397             if (strcmp(name,videofilterlist[i].displayname)==0)
398             {
399                 videofilterselected = i;
400                 break;
401             }
402         }
403    }
404    name=vdr->configLoad("DirectShow","VideoH264Filter");
405     
406     if (name != NULL) 
407     {
408         for (int i = 0;i <videoH264filterlist.size();i++)
409         {
410             if (strcmp(name,videoH264filterlist[i].displayname)==0)
411             {
412                 videoH264filterselected = i;
413                 break;
414             }
415         }
416    }
417    name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
418    if (name != NULL) 
419    {
420        if (STRCASECMP(name,"NoMix")==0)  {
421            vmrdeinterlacing=0;
422        } else if (STRCASECMP(name,"None")==0)  {
423            vmrdeinterlacing=1;
424        } else if (STRCASECMP(name,"Best")==0)  {
425            vmrdeinterlacing=2;
426        } else if (STRCASECMP(name,"Bob")==0)  {
427            vmrdeinterlacing=3;
428        } else if (STRCASECMP(name,"Weave")==0)  {
429            vmrdeinterlacing=4;
430        }
431    }
432
433    name=vdr->configLoad("DirectShow", "VideoPresenter");
434    if (name!=NULL) {
435        if (STRCASECMP(name,"VMR9")==0) {
436            currentpresenter=VMR9;
437            } else if (STRCASECMP(name,"EVR")==0) {
438            currentpresenter=EVR;
439        } 
440    }
441    if (!((OsdWin*)Osd::getInstance())->IsEvrSupported()) {
442            currentpresenter=VMR9;
443    }
444
445    name=vdr->configLoad("DirectShow","videoH264dtsfix");
446    if (name!=NULL) {
447        if (STRCASECMP(name,"YES")==0) {
448            videoH264dtsfix=true;
449        } else {
450            videoH264dtsfix=false;
451        }
452    }
453    name=vdr->configLoad("DirectShow","videompeg2dtsfix");
454    if (name!=NULL) {
455        if (STRCASECMP(name,"YES")==0) {
456            videompeg2dtsfix=true;
457        } else {
458            videompeg2dtsfix=false;
459        }
460    }
461
462    name=vdr->configLoad("DirectGraphics", "StretchFiltering");
463    if (name!=NULL) {
464        if (STRCASECMP(name,"None")==0) {
465            ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
466        } else if (STRCASECMP(name,"Point")==0) {
467            ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
468        } else if (STRCASECMP(name,"Linear")==0) {
469            ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
470        }
471    }
472
473    
474
475
476    return true;
477
478 }
479
480 bool VideoWin::handleOptionChanges(Option* option)
481 {
482     if( Video::handleOptionChanges(option)) return true;
483     switch(option->id) {
484         case 1: {
485             if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
486                 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
487             } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
488                 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
489             } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
490                 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
491             }
492    return true;
493                 } break;
494         case 2: {
495             if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0)  {
496                 vmrdeinterlacing=0;
497             } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0)  {
498                 vmrdeinterlacing=1;
499             } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0)  {
500                 vmrdeinterlacing=2;
501             } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0)  {
502                 vmrdeinterlacing=3;
503             } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0)  {
504                 vmrdeinterlacing=4;
505             } 
506                 }break;
507                  case 3: {
508             if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0)  {
509                 currentpresenter=VMR9;
510             } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0)  {
511                 currentpresenter=EVR;
512             } 
513                 }break;
514          case 4: {
515              if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
516                 videoH264dtsfix=true;
517              } else {
518                  videoH264dtsfix=false;
519              }
520                  }break;
521          case 5: {
522              if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
523                 videompeg2dtsfix=true;
524              } else {
525                  videompeg2dtsfix=false;
526              }
527                  }break;
528     };
529     return false;
530
531 }
532
533 bool VideoWin::saveOptionstoServer()
534 {
535     if (videofilterselected!=-1) {
536         VDR::getInstance()->configSave("DirectShow",
537             "VideoFilter",videofilterlist[videofilterselected].displayname);
538                  VDR::getInstance()->configSave("DirectShow",
539             "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
540     }
541     return true;
542 }
543
544 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType, 
545            UINT numChoices, UINT defaultChoice, UINT startInt,
546            const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
547
548 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
549 {
550     if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
551
552
553     Option* option;
554     if (panenumber == 2) 
555     {
556         DWORD scalingcaps=((OsdWin*)Osd::getInstance())->getFilterCaps();
557         char **scalingopts=new char *[3];
558         int i=0;
559         scalingopts[i]=new char[strlen("None")+1];
560         strcpy(scalingopts[i],"None");
561         i++;
562         if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0 
563             && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
564             scalingopts[i]=new char[strlen("Point")+1];
565             strcpy(scalingopts[i],"Point");
566             i++;
567         }
568         if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0 
569             && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
570             scalingopts[i]=new char[strlen("Linear")+1];
571             strcpy(scalingopts[i],"Linear");
572             i++;
573         }
574         option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
575         options->push_back(option);
576         pane->addOptionLine(option);
577         static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
578         option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
579         options->push_back(option);
580         pane->addOptionLine(option);
581
582                 if (((OsdWin*)Osd::getInstance())->IsEvrSupported()) 
583                 {
584                         static const char* presenteropts[]={"EVR","VMR9"};
585             option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
586                 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
587                 } else {
588                         static const char* presenteropts[]={"VMR9"};
589                         option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
590                 }
591                 options->push_back(option);
592         pane->addOptionLine(option);
593
594         static const char* yesnoopts[]={"Yes","No"};
595         option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
596         options->push_back(option);
597         pane->addOptionLine(option);
598
599         option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
600         options->push_back(option);
601         pane->addOptionLine(option);
602
603
604       
605     }
606
607     return true;
608 }
609
610 IBaseFilter *VideoWin::getVideoFilter()
611 {
612     IBaseFilter *curfilter= NULL;
613     if (videofilterselected == -1)
614     {
615         int i;
616         for (i = 0;i <videofilterlist.size();i++)
617         {
618             
619             if (videofilterlist[i].vmr9tested == true)
620             {
621                 if (videofilterlist[i].vmr9 == true)
622                 {
623                     videofilterselected = i;
624                     break;
625                 } 
626                 else
627                 {
628                     continue;
629                 }
630             }
631             else
632             {
633                 IMoniker * moni=NULL;
634                 IBindCtx *bindctx=NULL;
635                 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
636                 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
637                 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
638                 ULONG eater=0;
639                 
640
641                 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
642                 {
643                     if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
644                     {
645                         IAMDecoderCaps* desccaps=NULL;
646                         if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
647                         {
648                             DWORD caps;
649                             desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
650                             if (caps == DECODER_CAP_SUPPORTED)
651                             {
652                                 videofilterlist[i].vmr9tested =  true;
653                                 videofilterlist[i].vmr9 = true;
654                                 videofilterselected = i;
655                             } 
656                             else
657                             {
658                                 videofilterlist[i].vmr9tested =  true;
659                                 videofilterlist[i].vmr9 = false;
660                                 
661                                 curfilter->Release();
662                                 curfilter=NULL;
663                             }
664                         }
665                         desccaps->Release();
666                     }
667                     moni->Release();
668                 } 
669                 delete [] name;
670                 bindctx->Release();
671             }
672             if (videofilterlist[i].vmr9) break;
673             
674         }
675         if (curfilter != NULL)
676         {
677             VDR *vdr=VDR::getInstance();
678             if (vdr != NULL)
679             {
680                 vdr->configSave("DirectShow","VideoFilter",
681                     videofilterlist[videofilterselected].displayname);
682             }
683             return curfilter;
684         }
685     } 
686     else
687     {
688         IBindCtx *bindctx=NULL;
689         if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
690         IMoniker * moni=NULL;
691         LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
692         mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
693             strlen(videofilterlist[videofilterselected].displayname)+1);
694         ULONG eater;
695         if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
696         {
697             if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
698             {
699                     IAMDecoderCaps* desccaps=NULL;
700                     if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
701                     {
702                         DWORD caps;
703                         desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
704                         if (caps == DECODER_CAP_SUPPORTED)
705                         {
706                             videofilterlist[videofilterselected].vmr9tested =  true;
707                             videofilterlist[videofilterselected].vmr9 = true;
708                         } 
709                         else
710                         {
711                             videofilterlist[videofilterselected].vmr9tested =  true;
712                             videofilterlist[videofilterselected].vmr9 = false;
713                             Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
714                         }
715                     }
716                     moni->Release();
717                     delete [] name;
718                     bindctx->Release();
719                     return curfilter;
720              } 
721             moni->Release();
722         }
723         bindctx->Release();
724         delete [] name;
725         return NULL;         
726     }
727     return NULL;
728     
729 }
730
731 IBaseFilter *VideoWin::getVideoH264Filter()
732 {
733     IBaseFilter *curfilter= NULL;
734     if (videoH264filterselected == -1)
735     {
736         int i;
737         for (i = 0;i <videoH264filterlist.size();i++)
738         {
739             
740             if (videoH264filterlist[i].vmr9tested == true)
741             {
742                 if (videoH264filterlist[i].vmr9 == true)
743                 {
744                     videoH264filterselected = i;
745                     break;
746                 } 
747                 else
748                 {
749                     continue;
750                 }
751             }
752             else
753             {
754                 IMoniker * moni=NULL;
755                 IBindCtx *bindctx=NULL;
756                 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
757                 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
758                 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
759                 ULONG eater=0;
760                                 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
761
762                 
763
764                 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
765                 {
766                     if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
767                     {
768                         IAMDecoderCaps* desccaps=NULL;
769                         if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
770                         {
771                             DWORD caps;
772                             desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
773                             if (caps == DECODER_CAP_SUPPORTED)
774                             {
775                                 videoH264filterlist[i].vmr9tested =  true;
776                                 videoH264filterlist[i].vmr9 = true;
777                                 videoH264filterselected = i;
778                             } 
779                             else
780                             {
781                                 videoH264filterlist[i].vmr9tested =  true;
782                                 videoH264filterlist[i].vmr9 = false;
783                                 
784                                 curfilter->Release();
785                                 curfilter=NULL;
786                             }
787                         }
788                         desccaps->Release();
789                     }
790                     moni->Release();
791                 } 
792                 delete [] name;
793                 bindctx->Release();
794             }
795             if (videoH264filterlist[i].vmr9) break;
796             
797         }
798         if (curfilter != NULL)
799         {
800             VDR *vdr=VDR::getInstance();
801             if (vdr != NULL)
802             {
803                 vdr->configSave("DirectShow","VideoH264Filter",
804                     videoH264filterlist[videoH264filterselected].displayname);
805             }
806             return curfilter;
807         }
808     } 
809     else
810     {
811         IBindCtx *bindctx=NULL;
812         if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
813         IMoniker * moni=NULL;
814         LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
815         mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
816             strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
817         ULONG eater;
818                 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
819         if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
820         {
821             if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
822             {
823                     IAMDecoderCaps* desccaps=NULL;
824                     if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
825                     {
826                         DWORD caps;
827                         desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
828                         if (caps == DECODER_CAP_SUPPORTED)
829                         {
830                             videoH264filterlist[videoH264filterselected].vmr9tested =  true;
831                             videoH264filterlist[videoH264filterselected].vmr9 = true;
832                         } 
833                         else
834                         {
835                             videoH264filterlist[videoH264filterselected].vmr9tested =  true;
836                             videoH264filterlist[videoH264filterselected].vmr9 = false;
837                             Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
838                         }
839                     }
840                     moni->Release();
841                     delete [] name;
842                     bindctx->Release();
843                     return curfilter;
844              } 
845             moni->Release();
846         }
847         bindctx->Release();
848         delete [] name;
849         return NULL;         
850     }
851     return NULL;
852     
853 }
854
855
856 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
857 #include "dshelper.h"
858 #endif
859
860 #define DO_VIDEO
861
862 int VideoWin::play()
863 {
864   if (!initted) return 0;
865   return 1;
866 }
867
868 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
869 {
870     Boxx *box=new WWinVideoFilter();
871     wtb->addTab(tr("Video Filter"), box);
872         box=new WWinVideoH264Filter();
873     wtb->addTab(tr("H264 Filter"), box);
874     return true;
875 }
876
877 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
878 {
879     selected=videofilterselected;
880     return &videofilterlist;
881 }
882
883 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
884 {
885     selected=videoH264filterselected;
886     return &videoH264filterlist;
887 }
888
889 bool VideoWin::selectVideoFilter(int filter)
890 {
891     IBindCtx *bindctx=NULL;
892     if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
893     IMoniker * moni=NULL;
894     LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
895     mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
896     strlen(videofilterlist[filter].displayname)+1);
897     ULONG eater;
898     bool success=false;
899     if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
900     {
901         IBaseFilter* curfilter=NULL;
902         if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
903         {
904             IAMDecoderCaps* desccaps=NULL;
905             if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
906             {
907                 DWORD caps;
908                 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
909                 if (caps == DECODER_CAP_SUPPORTED)
910                 {
911                     videofilterlist[filter].vmr9tested =  true;
912                     videofilterlist[filter].vmr9 = true;
913                     success=true;
914                 } 
915                 else
916                 {
917                     videofilterlist[filter].vmr9tested =  true;
918                     videofilterlist[filter].vmr9 = false;
919                     success=false;
920                  }
921                 desccaps->Release();
922             } else {
923                 videofilterlist[filter].vmr9tested =  true;
924                 videofilterlist[filter].vmr9 = false;
925                 success=false;
926             }
927
928              curfilter->Release();
929              
930         } 
931         moni->Release();
932     }
933     bindctx->Release();
934     delete [] name;
935     if (success || true) 
936     {
937         videofilterselected=filter;
938         return true;
939     } 
940     else
941     {
942         return false;
943     }
944 }
945
946 bool VideoWin::selectVideoH264Filter(int filter)
947 {
948     IBindCtx *bindctx=NULL;
949     if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
950     IMoniker * moni=NULL;
951     LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
952     mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
953     strlen(videoH264filterlist[filter].displayname)+1);
954     ULONG eater;
955     bool success=false;
956     if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
957     {
958         IBaseFilter* curfilter=NULL;
959         if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
960         {
961             IAMDecoderCaps* desccaps=NULL;
962             if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
963             {
964                 DWORD caps;
965                 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
966                 if (caps == DECODER_CAP_SUPPORTED)
967                 {
968                     videoH264filterlist[filter].vmr9tested =  true;
969                     videoH264filterlist[filter].vmr9 = true;
970                     success=true;
971                 } 
972                 else
973                 {
974                     videoH264filterlist[filter].vmr9tested =  true;
975                     videoH264filterlist[filter].vmr9 = false;
976                     success=false;
977                  }
978                 desccaps->Release();
979             } else {
980                 videoH264filterlist[filter].vmr9tested =  true;
981                 videoH264filterlist[filter].vmr9 = false;
982                 success=false;
983             }
984
985              curfilter->Release();
986              
987         } 
988         moni->Release();
989     }
990     bindctx->Release();
991     delete [] name;
992     if (success || true) 
993     {
994         videoH264filterselected=filter;
995         return true;
996     } 
997     else
998     {
999         return false;
1000     }
1001 }
1002
1003 int VideoWin::dsInitVideoFilter()
1004 {
1005     #ifdef DO_VIDEO
1006     HRESULT hres;
1007     if (videoon) {
1008     //We alloc the vmr9 as next step
1009                 if (currentpresenter==VMR9) 
1010                 {
1011                         Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1012                         if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1013                                 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK) 
1014                         {
1015                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1016                                 ReleaseMutex(filtermutex);
1017                                 CleanupDS();
1018                         }
1019                         /*VMR 9 stuff**/
1020                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1021                         {
1022                                 ReleaseMutex(filtermutex);
1023                                 CleanupDS();
1024                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1025                                 return 0;
1026                         }
1027                         IVMRFilterConfig9* vmrfilconfig;
1028                         if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1029                         {
1030                                 ReleaseMutex(filtermutex);
1031                                 CleanupDS();
1032                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1033                                 return 0;
1034                         }
1035                         if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1036                         vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1037                         vmrfilconfig->Release();
1038                         if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1039                                 (void**)& dsvmrsurfnotify) != S_OK)
1040                         {
1041                                 ReleaseMutex(filtermutex);
1042                                 CleanupDS();
1043                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1044                                 return 0;
1045                         }
1046                         allocatorvmr=new DsAllocator();
1047                         dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1048                         allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1049                         
1050                         IVMRDeinterlaceControl9* deintctrl;
1051                         if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1052                         {
1053                                 ReleaseMutex(filtermutex);
1054                                 CleanupDS();
1055                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1056                                 return 0;
1057                         }
1058                         /*turnoff*/
1059                         switch (vmrdeinterlacing)
1060                         {
1061                         case 1: //No Deinterlasing
1062                          deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1063             break;
1064                         case 2: //Best
1065              deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1066             break;
1067                         case 3: //Bob
1068              deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1069                         break;
1070                         case 4: //Weave
1071              deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1072              break;
1073                         };
1074                         deintctrl->Release();
1075                         /*VMR 9 stuff end */
1076                 }
1077                 else if (currentpresenter==EVR)
1078                 {
1079                         Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1080                         if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1081                                 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK) 
1082                         {
1083                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1084                                 ReleaseMutex(filtermutex);
1085                                 CleanupDS();
1086                         }
1087                         /*EVR stuff**/
1088                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1089                         {
1090                                 ReleaseMutex(filtermutex);
1091                                 CleanupDS();
1092                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1093                                 return 0;
1094                         }
1095                         
1096                         
1097                         IMFGetService *evr_services;
1098                         if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1099                         {
1100                                 ReleaseMutex(filtermutex);
1101                                 CleanupDS();
1102                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1103                                 return 0;
1104                         }
1105
1106                         IMFVideoDisplayControl* mfvideodisplaycontrol;
1107                         if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1108                         {
1109                                 ReleaseMutex(filtermutex);
1110                                 CleanupDS();
1111                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1112                                 return 0;
1113                         }
1114
1115                         evr_services->Release();
1116                         mfvideodisplaycontrol->SetVideoWindow(((OsdWin*) Osd::getInstance())->getWindow());
1117                         //RECT client;
1118                     //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1119                         //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1120
1121                         mfvideodisplaycontrol->Release();
1122
1123
1124                 ///     if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1125
1126                         IMFVideoRenderer *mfvideorenderer;
1127                         if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1128                         {
1129                                 ReleaseMutex(filtermutex);
1130                                 CleanupDS();
1131                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1132                                 return 0;
1133                         }
1134                         
1135                         allocatorvmr=new DsAllocator();
1136                         HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1137
1138                         mfvideorenderer->Release();
1139                         //How should I do this in EVR?
1140                 /*      IVMRDeinterlaceControl9* deintctrl;
1141                         if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1142                         {
1143                                 ReleaseMutex(filtermutex);
1144                                 CleanupDS();
1145                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1146                                 return 0;
1147                         }
1148                         /*turnoff*
1149                         switch (vmrdeinterlacing)
1150                         {
1151                         case 1: //No Deinterlasing
1152                          deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1153             break;
1154                         case 2: //Best
1155              deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1156             break;
1157                         case 3: //Bob
1158              deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1159                         break;
1160                         case 4: //Weave
1161              deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1162              break;
1163                         };
1164                         deintctrl->Release();*/
1165                         /*EVR stuff end */
1166                 } else {
1167                         Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1168                         return -1;
1169                 }
1170         IFilterGraph2*fg2=NULL;
1171         if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1172         {
1173             Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1174             ReleaseMutex(filtermutex);
1175                 CleanupDS();
1176             return 0;
1177         }
1178 /*#ifndef NEW_DS_MECHANISMENS
1179         
1180         if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1181             AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK) 
1182         {
1183             Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1184                 fg2->Release();
1185                 ReleaseMutex(filtermutex);
1186                 CleanupDS();
1187             return 0;
1188         }
1189         
1190 #else*/
1191         IBaseFilter*videofilter;
1192                 if (h264)  
1193                 {
1194                         Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1195                         videofilter=getVideoH264Filter();
1196                 } 
1197                 else
1198                 {
1199                         Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1200                         videofilter=getVideoFilter();
1201                 }
1202         if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK) 
1203         {
1204             Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1205             ReleaseMutex(filtermutex);
1206             CleanupDS();
1207             return 0;
1208         }
1209         IEnumPins *pinenum=NULL;
1210         bool error=false;
1211
1212         mptype_video_detail vid_details;
1213         Demuxer* demux=Demuxer::getInstance();
1214         vid_details.width=demux->getHorizontalSize();
1215         vid_details.height=demux->getVerticalSize();
1216
1217                 if (h264)
1218                 {
1219             if (vid_details.width!=0 && vid_details.height!=0)
1220             {
1221                         sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1222                 }
1223                 else
1224                 {
1225                             sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1226             }
1227
1228                 }
1229                 else
1230                 {
1231             if (vid_details.width!=0 && vid_details.height!=0)
1232             {
1233                         sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1234                 }
1235             else
1236             {
1237                 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1238             } 
1239                 }
1240         if (videofilter->EnumPins(&pinenum) == S_OK)
1241         {
1242             IPin *current=NULL;
1243             ULONG fetch=0;
1244             bool firststep=false;
1245
1246             while (pinenum->Next(1,&current,&fetch)==S_OK)
1247             {
1248                 PIN_DIRECTION dir;
1249                 if (current->QueryDirection(&dir)==S_OK)
1250                 {
1251                     if (dir == PINDIR_INPUT)
1252                     {
1253                         if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1254                         {
1255                             current->Release();
1256                             firststep=true;
1257                             break;
1258                         }
1259                     }
1260                 }
1261                 current->Release();
1262             }
1263             if (firststep==false)
1264             {
1265                 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1266                 videofilter->Release();
1267                 ReleaseMutex(filtermutex);
1268                 CleanupDS();
1269                 return 0;
1270             }
1271             bool secondstep=false;
1272             pinenum->Reset();
1273             while (pinenum->Next(1,&current,&fetch)==S_OK)
1274             {
1275                 PIN_DIRECTION dir;
1276                 if (current->QueryDirection(&dir)==S_OK)
1277                 {
1278                     if (dir == PINDIR_OUTPUT)
1279                     {
1280                         
1281                         if (fg2->RenderEx((IPin*)current/*video*/,
1282                                 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1283                         {
1284                             current->Release();
1285                             secondstep=true;
1286                             break;
1287                         }
1288                     }
1289                 }
1290                 current->Release();
1291             }
1292             if (secondstep==false)
1293             {
1294                 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1295                 videofilter->Release();
1296                 ReleaseMutex(filtermutex);
1297                 CleanupDS();
1298                 return 0;
1299             }
1300             
1301             videofilter->Release();
1302             pinenum->Release();
1303
1304         }
1305
1306
1307
1308         fg2->Release();
1309         return 1;
1310     }
1311 #endif 
1312         return 1;
1313 }
1314
1315 int VideoWin::setAudioStreamType(UCHAR type)
1316 {
1317   aud_type=type;
1318   if (!initted) return 0;
1319   return 1;
1320 }
1321
1322 int VideoWin::dsplay()
1323 {
1324     if (!initted) return 0;
1325     CleanupDS();
1326     
1327     //Build filter graph
1328     HRESULT hres;
1329     //So this is the real code, this prevents the feeder from calling noexisting objects!
1330     WaitForSingleObject(filtermutex,INFINITE);
1331     if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1332         IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK) 
1333     {
1334         ReleaseMutex(filtermutex);
1335         return 0;
1336     }
1337    #ifdef DS_DEBUG
1338    AddToRot(dsgraphbuilder,&graphidentifier);
1339    #endif
1340    
1341    firstsynched=false;
1342    if (aud_type==Audio::MP3) {
1343        lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1344    } else {
1345        lastaudiomode=MPTYPE_MPEG_AUDIO;
1346    }
1347    //lastaudiomode=MPTYPE_AC3;
1348    sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1349    // to DirectShow
1350    if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK) 
1351    {
1352        Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1353        ReleaseMutex(filtermutex);
1354        CleanupDS();
1355        return 0;
1356    }
1357    sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1358    /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK) 
1359    {
1360        Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1361            ReleaseMutex(filtermutex);
1362        CleanupDS();
1363        return 0;
1364    }*/
1365    if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1366    {
1367        Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1368            ReleaseMutex(filtermutex);
1369        CleanupDS();
1370        return 0;
1371    }
1372
1373
1374     if (dsInitVideoFilter()==0)
1375     { 
1376         return 0;
1377     }
1378
1379     if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1380         IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) 
1381     {
1382         return 0;
1383     }
1384     dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1385     HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1386
1387     dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1388     dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);    
1389     if (dsbasicaudio) 
1390        dsbasicaudio->put_Volume(audiovolume);
1391     dsinited=true;
1392    //MILLISLEEP(100);
1393
1394     hresdeb=dsmediacontrol->Run();
1395     iframemode=false;//exit iframe mode
1396     ReleaseMutex(filtermutex);
1397     return 1;
1398 }
1399
1400 int VideoWin::EnterIframePlayback()
1401 {
1402         if (!initted) return 0;
1403         CleanupDS();
1404         //So this is the real code, this prevents the feeder from calling noexisting objects!
1405    WaitForSingleObject(filtermutex,INFINITE);
1406         iframemode=true;//enter iframe mode
1407         //Build filter graph
1408         HRESULT hres;
1409         if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1410                  IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1411                          ReleaseMutex(filtermutex);
1412                          return 0;
1413         }
1414 #ifdef DS_DEBUG
1415         AddToRot(dsgraphbuilder,&graphidentifier);
1416 #endif
1417    
1418    //firstsynched=false;
1419    sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1420    // to DirectShow
1421    if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1422    Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1423      ReleaseMutex(filtermutex);  
1424      CleanupDS();
1425      return 0;
1426    }
1427 #ifdef DO_VIDEO
1428     if (videoon) {
1429         dsInitVideoFilter();
1430    }
1431 #endif
1432 /*   if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1433     IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1434       return 0;
1435    }*/
1436
1437    dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1438    dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1439
1440    dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1441    dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);     
1442   dsinited=true;
1443   
1444
1445    dsmediacontrol->Run();
1446    ReleaseMutex(filtermutex);
1447   return 1;
1448
1449 }
1450
1451 int VideoWin::dsstop()
1452 {
1453   if (!initted) return 0;
1454
1455   CleanupDS();
1456
1457
1458   return 1;
1459 }
1460
1461 int VideoWin::stop()
1462 {
1463   if (!initted) return 0;
1464
1465
1466   return 1;
1467 }
1468
1469 int VideoWin::reset()
1470 {
1471   if (!initted) return 0;
1472   
1473
1474   return 1;
1475 }
1476
1477 int VideoWin::dsreset()
1478 {
1479   if (!initted) return 0;
1480   videoposx=0;
1481   videoposy=0;
1482   iframemode=false;//exit iframe mode
1483   CleanupDS();
1484
1485   return 1;
1486 }
1487
1488 int VideoWin::dspause()
1489 {
1490   if (!initted) return 0;
1491   WaitForSingleObject(filtermutex,INFINITE);
1492   if (dsmediacontrol) dsmediacontrol->Pause();
1493   ReleaseMutex(filtermutex);
1494   return 1;
1495 }
1496
1497 int VideoWin::pause()
1498 {
1499   if (!initted) return 0;
1500   
1501   return 1;
1502 }
1503
1504 int VideoWin::unPause() // FIXME get rid - same as play!!
1505 {//No on windows this is not the same, I don't get rid of!
1506   if (!initted) return 0;
1507   return 1;
1508 }
1509
1510 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1511 {//No on windows this is not the same, I don't get rid of!
1512   if (!initted) return 0;
1513   WaitForSingleObject(filtermutex,INFINITE);
1514   if (dsmediacontrol) dsmediacontrol->Run();
1515   ReleaseMutex(filtermutex);
1516
1517   return 1;
1518 }
1519
1520 int VideoWin::fastForward()
1521 {
1522   if (!initted) return 0;
1523
1524   return 1;
1525 }
1526
1527 int VideoWin::unFastForward()
1528 {
1529   if (!initted) return 0;
1530   
1531   return 1;
1532 }
1533
1534 int VideoWin::attachFrameBuffer()
1535 {
1536   if (!initted) return 0;
1537   return 1;
1538 }
1539
1540 int VideoWin::blank(void)
1541 {
1542   ((OsdWin*)Osd::getInstance())->Blank();
1543   return 1;
1544 }
1545
1546 ULLONG VideoWin::getCurrentTimestamp()
1547 {
1548         REFERENCE_TIME startoffset;
1549         REFERENCE_TIME ncr_time;
1550   if (iframemode) return 0; //Not in iframe mode!
1551   if (!dsrefclock || !sourcefilter) return 0;
1552         FILTER_STATE state;
1553         sourcefilter->GetState(10,&state);
1554
1555         if (state==State_Running) dsrefclock->GetTime(&cr_time);
1556         ncr_time=cr_time;
1557   startoffset=sourcefilter->getStartOffset();
1558   if (startoffset==0) return 0;
1559         ncr_time-=startoffset;
1560         ncr_time-=lastreftimeRT;
1561  /* ULLONG result=frameNumberToTimecode(
1562     VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1563         long long result=lastreftimePTS;
1564         result+=(ULLONG)(ncr_time/10000LL*90LL);
1565         if (result<0) result=(1LL << 33)-result;
1566   return result;
1567
1568 }
1569
1570
1571 /* //to beremoved
1572 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1573 {
1574   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1575   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
1576 }
1577
1578 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1579 {
1580   if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1581   else               return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1582 }
1583 */
1584 void VideoWin::CleanupDS()
1585 {
1586   WaitForSingleObject(filtermutex,INFINITE);
1587   dsinited=false;
1588   if (dsmediacontrol)dsmediacontrol->Stop();
1589   if (cur_audio_media_sample) {
1590     cur_audio_media_sample->Release();
1591     cur_audio_media_sample=NULL;
1592   }
1593   if (cur_video_media_sample) {
1594     cur_video_media_sample->Release();
1595     cur_video_media_sample=NULL;
1596   }
1597   if (dsbasicaudio) {
1598           dsbasicaudio->Release();
1599           dsbasicaudio=NULL;
1600   }
1601   if (dsvmrsurfnotify) {
1602     dsvmrsurfnotify->Release();
1603     dsvmrsurfnotify=NULL;
1604   }
1605   if (dsrenderer) {
1606     dsrenderer->Release();
1607     dsrenderer=NULL;
1608   }
1609
1610   if (allocatorvmr) {
1611     allocatorvmr->Release();
1612     allocatorvmr=NULL;
1613   }
1614
1615   if (dsrefclock) {
1616     dsrefclock->Release();
1617     dsrefclock=NULL;
1618   }
1619   if (dsmediafilter) {
1620     dsmediafilter->Release();
1621     dsmediafilter=NULL;
1622   }
1623
1624
1625
1626   if (dsmediacontrol) {
1627     dsmediacontrol->Stop();
1628     dsmediacontrol->Release();
1629     dsmediacontrol=NULL;
1630   }
1631   if (dsgraphbuilder){
1632 #ifdef DS_DEBUG
1633     RemoveFromRot(graphidentifier);
1634 #endif
1635         dsgraphbuilder->Release();
1636     dsgraphbuilder=NULL;
1637         
1638     sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1639   }
1640   ReleaseMutex(filtermutex);
1641
1642 }
1643
1644 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1645      UINT samplepos)
1646 {
1647   mediapacket = mplist.front();
1648 }
1649
1650 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1651 {
1652   DeliverMediaPacket(mediapacket, buffer, samplepos);
1653   if (*samplepos == mediapacket.length) {
1654     *samplepos = 0;
1655     return 1;
1656   }
1657   else return 0;
1658 }
1659
1660 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1661                                   const UCHAR* buffer,
1662                                   UINT *samplepos)
1663 {
1664
1665     /*First Check, if we have an audio sample*/
1666     if (!isdsinited()) return 0;
1667     if (packet.type == MPTYPE_VIDEO_H264)
1668     {
1669         h264=true;
1670     }
1671     else
1672     {
1673         h264=false;
1674     }
1675
1676 #ifdef DO_VIDEO
1677     if (!videoon) {
1678         *samplepos+=packet.length;
1679         MILLISLEEP(0); //yet not implemented//bad idea
1680         return packet.length;
1681     }
1682     /*First Check, if we have an audio sample*/
1683     if (iframemode) {
1684         //samplepos=0;
1685         MILLISLEEP(10);
1686         return 0; //Not in iframe mode!
1687     }
1688     IMediaSample* ms=NULL;
1689     REFERENCE_TIME reftime1=0;
1690     REFERENCE_TIME reftime2=0;
1691
1692     UINT headerstrip=0;
1693     if (packet.disconti) {
1694         firstsynched=false;
1695         DeliverVideoMediaSample();
1696     }
1697
1698     
1699
1700     /*Inspect PES-Header */
1701
1702     if (*samplepos==0) {//stripheader
1703         headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1704         *samplepos+=headerstrip;
1705         if ( packet.synched ) {
1706             DeliverVideoMediaSample();//write out old data
1707             /*   if (packet.presentation_time<0) { //Preroll?
1708             *samplepos=packet.length;//if we have not processed at least one
1709             return packet.length;//synched packet ignore it!
1710             }*/
1711
1712             reftime1=packet.presentation_time;
1713             reftime2=reftime1+1;
1714             firstsynched=true;
1715         } else {
1716             if (!firstsynched) {//
1717                 *samplepos=packet.length;//if we have not processed at least one
1718                 return packet.length;//synched packet ignore it!
1719             }
1720         }
1721     }
1722     BYTE *ms_buf;
1723     UINT ms_length;
1724     UINT ms_pos;
1725     UINT haveToCopy;
1726
1727     if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1728         //samplepos=0;
1729         //MessageBox(0,"da isser","hei",0);
1730         //MILLISLEEP(1);
1731         return 0;
1732     }
1733     ms_pos=ms->GetActualDataLength();
1734     ms_length=ms->GetSize();
1735     haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1736     if ((ms_length-ms_pos)<1 ) {
1737         DeliverVideoMediaSample(); //we are full!
1738         if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1739             //samplepos=0;
1740             //MessageBox(0,"da isser","hei",0);
1741             //MILLISLEEP(10);
1742             return 0;
1743         }
1744         ms_pos=ms->GetActualDataLength();
1745         ms_length=ms->GetSize();
1746         haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1747     }
1748     ms->GetPointer(&ms_buf);
1749
1750
1751     if (ms_pos==0) {//will only be changed on first packet
1752         if (packet.disconti) {
1753             ms->SetDiscontinuity(TRUE);
1754         } else {
1755             ms->SetDiscontinuity(FALSE);
1756         }
1757         if (packet.synched) {
1758             ms->SetSyncPoint(TRUE);
1759             ms->SetTime(&reftime1,&reftime2);
1760             //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1761             //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1762             //ms->SetTime(NULL,NULL);
1763             ms->SetMediaTime(NULL, NULL);
1764             if (reftime1<0) ms->SetPreroll(TRUE);
1765             else ms->SetPreroll(FALSE);
1766             /*Timecode handling*/
1767             lastreftimeRT=reftime1;
1768             lastreftimePTS=packet.pts;
1769
1770         }
1771         else
1772         {
1773             ms->SetSyncPoint(FALSE);
1774             ms->SetTime(NULL,NULL);
1775             ms->SetMediaTime(NULL, NULL);
1776             ms->SetPreroll(FALSE);
1777
1778             //  ms->SetSyncPoint(TRUE);
1779         }
1780     }
1781     
1782
1783
1784     memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1785     ms->SetActualDataLength(haveToCopy+ms_pos);
1786
1787     *samplepos+=haveToCopy;
1788
1789     return haveToCopy+headerstrip;
1790
1791 #else
1792
1793     *samplepos+=packet.length;
1794     MILLISLEEP(0); //yet not implemented//bad idea
1795     return packet.length;
1796 #endif
1797 }
1798
1799 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1800 {
1801   //WaitForSingleObject(filtermutex,INFINITE);
1802   if (!sourcefilter){
1803   //  ReleaseMutex(filtermutex);
1804     return 0;
1805   }
1806   if (cur_audio_media_sample) {
1807     *ms=cur_audio_media_sample;//already open
1808     return 1;
1809   }
1810   if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1811   //  ReleaseMutex(filtermutex);
1812   }
1813   if (*ms) (*ms)->SetActualDataLength(0);
1814   cur_audio_media_sample=*ms;
1815   //Don't release the mutex before deliver
1816   return 1;
1817 }
1818
1819 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1820 {
1821   //WaitForSingleObject(filtermutex,INFINITE);
1822   if (!sourcefilter){
1823   //  ReleaseMutex(filtermutex);
1824     return 0;
1825   }
1826   if (cur_video_media_sample) {
1827     *ms=cur_video_media_sample;//already open
1828     return 1;
1829   }
1830   if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1831   //  ReleaseMutex(filtermutex);
1832   }
1833   if (*ms) (*ms)->SetActualDataLength(0);
1834
1835   cur_video_media_sample=*ms;
1836   //Don't release the mutex before deliver
1837   return 1;
1838 }
1839
1840 int VideoWin::DeliverAudioMediaSample(){
1841   if (cur_audio_media_sample) {
1842     sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1843     cur_audio_media_sample=NULL;
1844   }
1845   //ReleaseMutex(filtermutex);
1846   return 1;
1847 }
1848
1849 int VideoWin::DeliverVideoMediaSample(){
1850   if (cur_video_media_sample) {
1851     sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1852     cur_video_media_sample=NULL;
1853   }
1854   //ReleaseMutex(filtermutex);
1855   return 1;
1856 }
1857
1858 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1859 {
1860   *rsync=false;
1861   if (offsetnotset) {
1862     startoffset=curreftime;//offset is set for audio
1863     offsetnotset=false;
1864     offsetvideonotset=false;
1865
1866
1867   } else {
1868     if (offsetvideonotset) {
1869       offsetvideonotset=false;
1870       *rsync=true;
1871     } else {
1872       if ( (curreftime-lastrefvideotime)>10000000LL
1873         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1874         startoffset+=curreftime-lastrefvideotime;
1875         lastrefaudiotime+=curreftime-lastrefvideotime;
1876         //*rsync=true;
1877         offsetaudionotset=true;
1878
1879       }
1880     }
1881
1882   }
1883
1884   lastrefvideotime=curreftime;
1885   
1886   return startoffset;
1887
1888 }
1889
1890 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1891 {
1892   *rsync=false;
1893   if (offsetnotset) {
1894     startoffset=curreftime;
1895     offsetnotset=false;
1896     offsetaudionotset=false;
1897   }else {
1898     if (offsetaudionotset) {
1899       offsetaudionotset=false;
1900       *rsync=true;
1901     } else {
1902       if ( (curreftime-lastrefaudiotime)>10000000LL
1903         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1904         startoffset+=curreftime-lastrefaudiotime;
1905         lastrefvideotime+=curreftime-lastrefaudiotime;
1906         //*rsync=true;
1907         offsetvideonotset=true;
1908
1909       }
1910     }
1911
1912   }
1913   lastrefaudiotime=curreftime;
1914   return startoffset;
1915
1916 }
1917 void VideoWin::ResetTimeOffsets() {
1918   offsetnotset=true; //called from demuxer
1919   offsetvideonotset=true;
1920   offsetaudionotset=true;
1921   startoffset=0;
1922   lastrefaudiotime=0;
1923   lastrefvideotime=0;
1924   lastreftimeRT=0;
1925   lastreftimePTS=0;
1926
1927
1928 }
1929
1930 void VideoWin::SetAudioVolume(long volume)
1931 {
1932     audiovolume=volume;
1933         if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1934 }
1935
1936 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1937 {
1938         if (!iframemode) EnterIframePlayback();
1939         if (!isdsinited()) return false;
1940         
1941 #ifdef DO_VIDEO
1942   IMediaSample* ms=NULL;
1943   REFERENCE_TIME reftime1=0;
1944   REFERENCE_TIME reftime2=0;
1945   if (!videoon) return false;
1946   if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1947     MILLISLEEP(10);
1948     return false;
1949   }
1950   BYTE *ms_buf;
1951   DWORD ms_length;
1952   ms->GetPointer(&ms_buf);
1953   ms_length=ms->GetSize();
1954   
1955   /*First Check, if we have an video sample*/
1956   DWORD read_pos = 0, write_pos = 0;
1957   DWORD pattern, packet_length;
1958   DWORD headerstrip=0;
1959   bool first=true;
1960   if (length < 4) return false;
1961   //Now we strip the pes header
1962   pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1963   while (read_pos + 7 <= length)
1964   {
1965     pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1966     if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1967       read_pos++;
1968       continue;
1969     }
1970     else
1971     {
1972           headerstrip=buffer[read_pos+8]+9/*is this right*/;
1973       packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1974       if (read_pos + packet_length > length)
1975         read_pos = length;
1976       else
1977       {
1978                   if ( (headerstrip < packet_length) &&
1979               (write_pos+packet_length-headerstrip)>ms_length) {
1980                           if (first) {
1981                   ms->SetSyncPoint(TRUE);
1982                   ms->SetDiscontinuity(TRUE);
1983                   first=false;
1984               } else ms->SetSyncPoint(FALSE);
1985                           ms->SetTime(NULL,NULL);
1986                           ms->SetMediaTime(NULL, NULL);
1987                           ms->SetActualDataLength(write_pos);
1988                           DeliverVideoMediaSample();
1989
1990                           if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1991                                 MILLISLEEP(10);
1992                                 return false;
1993                           }
1994                           write_pos=0;
1995                           ms_length=ms->GetSize();
1996                           ms->GetPointer(&ms_buf);
1997                   }
1998                   if (packet_length>headerstrip) {
1999                         memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
2000                         write_pos += packet_length-headerstrip;
2001                   }
2002                   read_pos += packet_length;
2003                   
2004                   pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
2005                                         | (buffer[read_pos+2]);
2006       }
2007     }
2008   }
2009  
2010   if (first) {ms->SetSyncPoint(TRUE);
2011   ms->SetDiscontinuity(TRUE);
2012   first=false;} 
2013   else ms->SetSyncPoint(FALSE);
2014   ms->SetTime(NULL,NULL);
2015   ms->SetMediaTime(NULL, NULL);
2016   ms->SetActualDataLength(write_pos);
2017   DeliverVideoMediaSample();
2018
2019   return true;
2020 #else
2021
2022     //   *samplepos+=packet.length;
2023       MILLISLEEP(0); //yet not implemented//bad idea
2024        return  true;
2025 #endif
2026 }
2027
2028 bool VideoWin::supportsAc3(){
2029     if (sourcefilter != NULL) {
2030         return sourcefilter->supportsAc3();
2031     } else {
2032         return false;
2033     }
2034 }
2035
2036 bool VideoWin::supportsh264()
2037 {
2038         if (videoH264filterlist.size()>0) return true;
2039         else return false;
2040 }
2041
2042
2043 bool VideoWin::changeAType(int type,IMediaSample* ms){
2044     if (sourcefilter!= NULL) {
2045         lastaudiomode=type;
2046         return sourcefilter->changeAType(type,ms);
2047     }
2048     else 
2049     {
2050         return false;
2051     }
2052 }
2053
2054 #ifdef DEV
2055 int VideoWin::test()
2056 {
2057   return 0;
2058 }
2059
2060 int VideoWin::test2()
2061 {
2062   return 0;
2063 }
2064 #endif
2065
2066
2067
2068