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