]> git.vomp.tv Git - vompclient-marten.git/blob - videowin.cc
Add files for debian package generation
[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);
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)
188 {
189   if (!initted) return 0;
190   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
191   aspectRatio = taspectRatio;
192   AdjustWindow();
193   return 1;
194 }
195
196 int VideoWin::setMode(UCHAR tmode)
197 {
198   if (!initted) return 0;
199
200   //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
201
202   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
203       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
204   mode = tmode;
205   videoposx=0;
206   videoposy=0;
207   AdjustWindow();
208
209   return 1;
210 }
211
212 int VideoWin::signalOff()
213 {
214   return 1;
215 }
216
217 int VideoWin::signalOn()
218 {
219   return 1;
220 }
221
222 int VideoWin::setSource()
223 {
224   if (!initted) return 0;
225
226   return 1;
227 }
228
229 int VideoWin::setPosition(int x, int y)
230 {
231   if (!initted) return 0;
232   if (mode==QUARTER || mode==EIGHTH) {
233   videoposx=x;
234   videoposy=y;
235   }
236   return 1;
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 (!((OsdWin*)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            ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
464        } else if (STRCASECMP(name,"Point")==0) {
465            ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
466        } else if (STRCASECMP(name,"Linear")==0) {
467            ((OsdWin*)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                 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_NONE);
485             } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
486                 ((OsdWin*)Osd::getInstance())->setFilterType(D3DTEXF_POINT);
487             } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
488                 ((OsdWin*)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=((OsdWin*)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 (((OsdWin*)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                                 ReleaseMutex(filtermutex);
1015                                 CleanupDS();
1016                         }
1017                         /*VMR 9 stuff**/
1018                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1019                         {
1020                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
1083                                 CleanupDS();
1084                         }
1085                         /*EVR stuff**/
1086                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1087                         {
1088                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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(((OsdWin*) 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                                 ReleaseMutex(filtermutex);
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                                 ReleaseMutex(filtermutex);
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             ReleaseMutex(filtermutex);
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                 ReleaseMutex(filtermutex);
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             ReleaseMutex(filtermutex);
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                 ReleaseMutex(filtermutex);
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                 ReleaseMutex(filtermutex);
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     WaitForSingleObject(filtermutex,INFINITE);
1329     if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1330         IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK) 
1331     {
1332         ReleaseMutex(filtermutex);
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        ReleaseMutex(filtermutex);
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            ReleaseMutex(filtermutex);
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            ReleaseMutex(filtermutex);
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     ReleaseMutex(filtermutex);
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    WaitForSingleObject(filtermutex,INFINITE);
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                          ReleaseMutex(filtermutex);
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      ReleaseMutex(filtermutex);  
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    ReleaseMutex(filtermutex);
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   videoposx=0;
1479   videoposy=0;
1480   iframemode=false;//exit iframe mode
1481   CleanupDS();
1482
1483   return 1;
1484 }
1485
1486 int VideoWin::dspause()
1487 {
1488   if (!initted) return 0;
1489   WaitForSingleObject(filtermutex,INFINITE);
1490   if (dsmediacontrol) dsmediacontrol->Pause();
1491   ReleaseMutex(filtermutex);
1492   return 1;
1493 }
1494
1495 int VideoWin::pause()
1496 {
1497   if (!initted) return 0;
1498   
1499   return 1;
1500 }
1501
1502 int VideoWin::unPause() // FIXME get rid - same as play!!
1503 {//No on windows this is not the same, I don't get rid of!
1504   if (!initted) return 0;
1505   return 1;
1506 }
1507
1508 int VideoWin::dsunPause() // FIXME get rid - same as play!!
1509 {//No on windows this is not the same, I don't get rid of!
1510   if (!initted) return 0;
1511   WaitForSingleObject(filtermutex,INFINITE);
1512   if (dsmediacontrol) dsmediacontrol->Run();
1513   ReleaseMutex(filtermutex);
1514
1515   return 1;
1516 }
1517
1518 int VideoWin::fastForward()
1519 {
1520   if (!initted) return 0;
1521
1522   return 1;
1523 }
1524
1525 int VideoWin::unFastForward()
1526 {
1527   if (!initted) return 0;
1528   
1529   return 1;
1530 }
1531
1532 int VideoWin::attachFrameBuffer()
1533 {
1534   if (!initted) return 0;
1535   return 1;
1536 }
1537
1538 int VideoWin::blank(void)
1539 {
1540   ((OsdWin*)Osd::getInstance())->Blank();
1541   return 1;
1542 }
1543
1544 ULLONG VideoWin::getCurrentTimestamp()
1545 {
1546         REFERENCE_TIME startoffset;
1547         REFERENCE_TIME ncr_time;
1548   if (iframemode) return 0; //Not in iframe mode!
1549   if (!dsrefclock || !sourcefilter) return 0;
1550         FILTER_STATE state;
1551         sourcefilter->GetState(10,&state);
1552
1553         if (state==State_Running) dsrefclock->GetTime(&cr_time);
1554         ncr_time=cr_time;
1555   startoffset=sourcefilter->getStartOffset();
1556   if (startoffset==0) return 0;
1557         ncr_time-=startoffset;
1558         ncr_time-=lastreftimeRT;
1559  /* ULLONG result=frameNumberToTimecode(
1560     VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
1561         long long result=lastreftimePTS;
1562         result+=(ULLONG)(ncr_time/10000LL*90LL);
1563         if (result<0) result=(1LL << 33)-result;
1564   return result;
1565
1566 }
1567
1568
1569 /* //to beremoved
1570 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
1571 {
1572   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1573   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
1574 }
1575
1576 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
1577 {
1578   if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
1579   else               return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
1580 }
1581 */
1582 void VideoWin::CleanupDS()
1583 {
1584   WaitForSingleObject(filtermutex,INFINITE);
1585   dsinited=false;
1586   if (dsmediacontrol)dsmediacontrol->Stop();
1587   if (cur_audio_media_sample) {
1588     cur_audio_media_sample->Release();
1589     cur_audio_media_sample=NULL;
1590   }
1591   if (cur_video_media_sample) {
1592     cur_video_media_sample->Release();
1593     cur_video_media_sample=NULL;
1594   }
1595   if (dsbasicaudio) {
1596           dsbasicaudio->Release();
1597           dsbasicaudio=NULL;
1598   }
1599   if (dsvmrsurfnotify) {
1600     dsvmrsurfnotify->Release();
1601     dsvmrsurfnotify=NULL;
1602   }
1603   if (dsrenderer) {
1604     dsrenderer->Release();
1605     dsrenderer=NULL;
1606   }
1607
1608   if (allocatorvmr) {
1609     allocatorvmr->Release();
1610     allocatorvmr=NULL;
1611   }
1612
1613   if (dsrefclock) {
1614     dsrefclock->Release();
1615     dsrefclock=NULL;
1616   }
1617   if (dsmediafilter) {
1618     dsmediafilter->Release();
1619     dsmediafilter=NULL;
1620   }
1621
1622
1623
1624   if (dsmediacontrol) {
1625     dsmediacontrol->Stop();
1626     dsmediacontrol->Release();
1627     dsmediacontrol=NULL;
1628   }
1629   if (dsgraphbuilder){
1630 #ifdef DS_DEBUG
1631     RemoveFromRot(graphidentifier);
1632 #endif
1633         dsgraphbuilder->Release();
1634     dsgraphbuilder=NULL;
1635         
1636     sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
1637   }
1638   ReleaseMutex(filtermutex);
1639
1640 }
1641
1642 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
1643      UINT samplepos)
1644 {
1645   mediapacket = mplist.front();
1646 }
1647
1648 UINT VideoWin::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1649 {
1650   DeliverMediaPacket(mediapacket, buffer, samplepos);
1651   if (*samplepos == mediapacket.length) {
1652     *samplepos = 0;
1653     return 1;
1654   }
1655   else return 0;
1656 }
1657
1658 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
1659                                   const UCHAR* buffer,
1660                                   UINT *samplepos)
1661 {
1662
1663     /*First Check, if we have an audio sample*/
1664     if (!isdsinited()) return 0;
1665     if (packet.type == MPTYPE_VIDEO_H264)
1666     {
1667         h264=true;
1668     }
1669     else
1670     {
1671         h264=false;
1672     }
1673
1674 #ifdef DO_VIDEO
1675     if (!videoon) {
1676         *samplepos+=packet.length;
1677         MILLISLEEP(0); //yet not implemented//bad idea
1678         return packet.length;
1679     }
1680     /*First Check, if we have an audio sample*/
1681     if (iframemode) {
1682         //samplepos=0;
1683         MILLISLEEP(10);
1684         return 0; //Not in iframe mode!
1685     }
1686     IMediaSample* ms=NULL;
1687     REFERENCE_TIME reftime1=0;
1688     REFERENCE_TIME reftime2=0;
1689
1690     UINT headerstrip=0;
1691     if (packet.disconti) {
1692         firstsynched=false;
1693         DeliverVideoMediaSample();
1694     }
1695
1696     
1697
1698     /*Inspect PES-Header */
1699
1700     if (*samplepos==0) {//stripheader
1701         headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1702         *samplepos+=headerstrip;
1703         if ( packet.synched ) {
1704             DeliverVideoMediaSample();//write out old data
1705             /*   if (packet.presentation_time<0) { //Preroll?
1706             *samplepos=packet.length;//if we have not processed at least one
1707             return packet.length;//synched packet ignore it!
1708             }*/
1709
1710             reftime1=packet.presentation_time;
1711             reftime2=reftime1+1;
1712             firstsynched=true;
1713         } else {
1714             if (!firstsynched) {//
1715                 *samplepos=packet.length;//if we have not processed at least one
1716                 return packet.length;//synched packet ignore it!
1717             }
1718         }
1719     }
1720     BYTE *ms_buf;
1721     UINT ms_length;
1722     UINT ms_pos;
1723     UINT haveToCopy;
1724
1725     if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1726         //samplepos=0;
1727         //MessageBox(0,"da isser","hei",0);
1728         //MILLISLEEP(1);
1729         return 0;
1730     }
1731     ms_pos=ms->GetActualDataLength();
1732     ms_length=ms->GetSize();
1733     haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1734     if ((ms_length-ms_pos)<1 ) {
1735         DeliverVideoMediaSample(); //we are full!
1736         if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1737             //samplepos=0;
1738             //MessageBox(0,"da isser","hei",0);
1739             //MILLISLEEP(10);
1740             return 0;
1741         }
1742         ms_pos=ms->GetActualDataLength();
1743         ms_length=ms->GetSize();
1744         haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
1745     }
1746     ms->GetPointer(&ms_buf);
1747
1748
1749     if (ms_pos==0) {//will only be changed on first packet
1750         if (packet.disconti) {
1751             ms->SetDiscontinuity(TRUE);
1752         } else {
1753             ms->SetDiscontinuity(FALSE);
1754         }
1755         if (packet.synched) {
1756             ms->SetSyncPoint(TRUE);
1757             ms->SetTime(&reftime1,&reftime2);
1758             //Log::getInstance()->log("VideoWin", Log::DEBUG , "Setted videotime to %lld %lld",reftime1,reftime2);
1759             //Log::getInstance()->log("VideoWin", Log::DEBUG , "Packet pts %lld dts %lld",packet.pts,packet.dts);
1760             //ms->SetTime(NULL,NULL);
1761             ms->SetMediaTime(NULL, NULL);
1762             if (reftime1<0) ms->SetPreroll(TRUE);
1763             else ms->SetPreroll(FALSE);
1764             /*Timecode handling*/
1765             lastreftimeRT=reftime1;
1766             lastreftimePTS=packet.pts;
1767
1768         }
1769         else
1770         {
1771             ms->SetSyncPoint(FALSE);
1772             ms->SetTime(NULL,NULL);
1773             ms->SetMediaTime(NULL, NULL);
1774             ms->SetPreroll(FALSE);
1775
1776             //  ms->SetSyncPoint(TRUE);
1777         }
1778     }
1779     
1780
1781
1782     memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1783     ms->SetActualDataLength(haveToCopy+ms_pos);
1784
1785     *samplepos+=haveToCopy;
1786
1787     return haveToCopy+headerstrip;
1788
1789 #else
1790
1791     *samplepos+=packet.length;
1792     MILLISLEEP(0); //yet not implemented//bad idea
1793     return packet.length;
1794 #endif
1795 }
1796
1797 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
1798 {
1799   //WaitForSingleObject(filtermutex,INFINITE);
1800   if (!sourcefilter){
1801   //  ReleaseMutex(filtermutex);
1802     return 0;
1803   }
1804   if (cur_audio_media_sample) {
1805     *ms=cur_audio_media_sample;//already open
1806     return 1;
1807   }
1808   if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
1809   //  ReleaseMutex(filtermutex);
1810   }
1811   if (*ms) (*ms)->SetActualDataLength(0);
1812   cur_audio_media_sample=*ms;
1813   //Don't release the mutex before deliver
1814   return 1;
1815 }
1816
1817 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
1818 {
1819   //WaitForSingleObject(filtermutex,INFINITE);
1820   if (!sourcefilter){
1821   //  ReleaseMutex(filtermutex);
1822     return 0;
1823   }
1824   if (cur_video_media_sample) {
1825     *ms=cur_video_media_sample;//already open
1826     return 1;
1827   }
1828   if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
1829   //  ReleaseMutex(filtermutex);
1830   }
1831   if (*ms) (*ms)->SetActualDataLength(0);
1832
1833   cur_video_media_sample=*ms;
1834   //Don't release the mutex before deliver
1835   return 1;
1836 }
1837
1838 int VideoWin::DeliverAudioMediaSample(){
1839   if (cur_audio_media_sample) {
1840     sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
1841     cur_audio_media_sample=NULL;
1842   }
1843   //ReleaseMutex(filtermutex);
1844   return 1;
1845 }
1846
1847 int VideoWin::DeliverVideoMediaSample(){
1848   if (cur_video_media_sample) {
1849     sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
1850     cur_video_media_sample=NULL;
1851   }
1852   //ReleaseMutex(filtermutex);
1853   return 1;
1854 }
1855
1856 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
1857 {
1858   *rsync=false;
1859   if (offsetnotset) {
1860     startoffset=curreftime;//offset is set for audio
1861     offsetnotset=false;
1862     offsetvideonotset=false;
1863
1864
1865   } else {
1866     if (offsetvideonotset) {
1867       offsetvideonotset=false;
1868       *rsync=true;
1869     } else {
1870       if ( (curreftime-lastrefvideotime)>10000000LL
1871         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1872         startoffset+=curreftime-lastrefvideotime;
1873         lastrefaudiotime+=curreftime-lastrefvideotime;
1874         //*rsync=true;
1875         offsetaudionotset=true;
1876
1877       }
1878     }
1879
1880   }
1881
1882   lastrefvideotime=curreftime;
1883   
1884   return startoffset;
1885
1886 }
1887
1888 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
1889 {
1890   *rsync=false;
1891   if (offsetnotset) {
1892     startoffset=curreftime;
1893     offsetnotset=false;
1894     offsetaudionotset=false;
1895   }else {
1896     if (offsetaudionotset) {
1897       offsetaudionotset=false;
1898       *rsync=true;
1899     } else {
1900       if ( (curreftime-lastrefaudiotime)>10000000LL
1901         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1902         startoffset+=curreftime-lastrefaudiotime;
1903         lastrefvideotime+=curreftime-lastrefaudiotime;
1904         //*rsync=true;
1905         offsetvideonotset=true;
1906
1907       }
1908     }
1909
1910   }
1911   lastrefaudiotime=curreftime;
1912   return startoffset;
1913
1914 }
1915 void VideoWin::ResetTimeOffsets() {
1916   offsetnotset=true; //called from demuxer
1917   offsetvideonotset=true;
1918   offsetaudionotset=true;
1919   startoffset=0;
1920   lastrefaudiotime=0;
1921   lastrefvideotime=0;
1922   lastreftimeRT=0;
1923   lastreftimePTS=0;
1924
1925
1926 }
1927
1928 void VideoWin::SetAudioVolume(long volume)
1929 {
1930     audiovolume=volume;
1931         if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1932 }
1933
1934 bool VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1935 {
1936         if (!iframemode) EnterIframePlayback();
1937         if (!isdsinited()) return false;
1938         
1939 #ifdef DO_VIDEO
1940   IMediaSample* ms=NULL;
1941   REFERENCE_TIME reftime1=0;
1942   REFERENCE_TIME reftime2=0;
1943   if (!videoon) return;
1944   if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1945     MILLISLEEP(10);
1946     return ;
1947   }
1948   BYTE *ms_buf;
1949   DWORD ms_length;
1950   ms->GetPointer(&ms_buf);
1951   ms_length=ms->GetSize();
1952   
1953   /*First Check, if we have an video sample*/
1954   DWORD read_pos = 0, write_pos = 0;
1955   DWORD pattern, packet_length;
1956   DWORD headerstrip=0;
1957   bool first=true;
1958   if (length < 4) return ;
1959   //Now we strip the pes header
1960   pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1961   while (read_pos + 7 <= length)
1962   {
1963     pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1964     if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1965       read_pos++;
1966       continue;
1967     }
1968     else
1969     {
1970           headerstrip=buffer[read_pos+8]+9/*is this right*/;
1971       packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1972       if (read_pos + packet_length > length)
1973         read_pos = length;
1974       else
1975       {
1976                   if ( (headerstrip < packet_length) &&
1977               (write_pos+packet_length-headerstrip)>ms_length) {
1978                           if (first) {
1979                   ms->SetSyncPoint(TRUE);
1980                   ms->SetDiscontinuity(TRUE);
1981                   first=false;
1982               } else ms->SetSyncPoint(FALSE);
1983                           ms->SetTime(NULL,NULL);
1984                           ms->SetMediaTime(NULL, NULL);
1985                           ms->SetActualDataLength(write_pos);
1986                           DeliverVideoMediaSample();
1987
1988                           if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1989                                 MILLISLEEP(10);
1990                                 return ;
1991                           }
1992                           write_pos=0;
1993                           ms_length=ms->GetSize();
1994                           ms->GetPointer(&ms_buf);
1995                   }
1996                   if (packet_length>headerstrip) {
1997                         memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1998                         write_pos += packet_length-headerstrip;
1999                   }
2000                   read_pos += packet_length;
2001                   
2002                   pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
2003                                         | (buffer[read_pos+2]);
2004       }
2005     }
2006   }
2007  
2008   if (first) {ms->SetSyncPoint(TRUE);
2009   ms->SetDiscontinuity(TRUE);
2010   first=false;} 
2011   else ms->SetSyncPoint(FALSE);
2012   ms->SetTime(NULL,NULL);
2013   ms->SetMediaTime(NULL, NULL);
2014   ms->SetActualDataLength(write_pos);
2015   DeliverVideoMediaSample();
2016
2017   return true;
2018 #else
2019
2020     //   *samplepos+=packet.length;
2021       MILLISLEEP(0); //yet not implemented//bad idea
2022        return  true;
2023 #endif
2024 }
2025
2026 bool VideoWin::supportsAc3(){
2027     if (sourcefilter != NULL) {
2028         return sourcefilter->supportsAc3();
2029     } else {
2030         return false;
2031     }
2032 }
2033
2034 bool VideoWin::supportsh264()
2035 {
2036         if (videoH264filterlist.size()>0) return true;
2037         else return false;
2038 }
2039
2040
2041 bool VideoWin::changeAType(int type,IMediaSample* ms){
2042     if (sourcefilter!= NULL) {
2043         lastaudiomode=type;
2044         return sourcefilter->changeAType(type,ms);
2045     }
2046     else 
2047     {
2048         return false;
2049     }
2050 }
2051
2052 #ifdef DEV
2053 int VideoWin::test()
2054 {
2055   return 0;
2056 }
2057
2058 int VideoWin::test2()
2059 {
2060   return 0;
2061 }
2062 #endif
2063
2064
2065
2066