]> git.vomp.tv Git - vompclient.git/blob - videowin.cc
Fix text corruption in channel number display on live tv
[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   filtermutex=CreateMutex(NULL,FALSE,NULL);
61   offsetnotset=true;
62   offsetvideonotset=true;
63   offsetaudionotset=true;
64   startoffset=0;
65   lastrefaudiotime=0;
66   lastrefvideotime=0;
67   lastreftimeRT=0;
68   lastreftimePTS=0;
69   firstsynched=false;
70   cur_audio_media_sample=NULL;
71   cur_video_media_sample=NULL;
72   videoon=true;
73   audioon=true;
74   audiovolume=0;
75   pseudotvsize=0;
76   aud_type=Audio::MPEG2_PES;
77   iframemode=false;//We are not in Iframe mode at begining
78   vmrdeinterlacing=2;//Best
79   videofilterselected=-1;
80   videoH264filterselected=-1;
81   OSVERSIONINFO verinfo;
82   verinfo.dwOSVersionInfoSize=sizeof(verinfo);
83
84 #if WIN32
85   // FIXME win pragma
86 #pragma warning(disable : 4996)
87 #endif
88   GetVersionEx(&verinfo);
89
90   if (verinfo.dwMajorVersion>=6) {
91   currentpresenter=EVR;
92   } else {
93       currentpresenter=VMR9;
94   }
95   videoH264dtsfix=false;
96   videompeg2dtsfix=false;
97
98   vd.mode = Fullscreen;
99
100
101
102 }
103
104 VideoWin::~VideoWin()
105 {
106   CleanupDS();
107   CloseHandle(filtermutex);
108   unsigned int i;
109   for (i=0;i<videofilterlist.size();i++)
110   {
111    if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
112    if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
113   }
114   videofilterlist.clear();
115
116   for (i=0;i<videoH264filterlist.size();i++)
117   {
118    if (videoH264filterlist[i].displayname) delete [] videoH264filterlist[i].displayname;
119    if (videoH264filterlist[i].friendlyname) delete [] videoH264filterlist[i].friendlyname;
120   }
121   videoH264filterlist.clear();
122
123
124
125
126   instance = NULL;
127 }
128
129 int VideoWin::init(UCHAR tformat)
130 {
131   if (initted) return 0;
132
133   initted = 1;
134   tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
135
136   vd.mode = Fullscreen;
137   initFilterDatabase();
138   initH264FilterDatabase();
139
140   if (!setFormat(tformat)){ shutdown(); return 0; }
141   return 1;
142 }
143
144
145
146 int VideoWin::setTVsize(UCHAR ttvsize)
147 {
148   pseudotvsize=ttvsize;
149   return 1;
150 }
151
152 int VideoWin::setDefaultAspect()
153 {
154         Osd *osd = Osd::getInstance();
155         if (dynamic_cast<OsdWinVector*>(osd)) {
156                 return setAspectRatio(Video::ASPECT16X9, parx, pary);
157         }
158         else {
159                 return setAspectRatio(Video::ASPECT4X3, parx, pary);
160         }
161 }
162
163 int VideoWin::shutdown()
164 {
165   if (!initted) return 0;
166   initted = 0;
167   return 1;
168 }
169
170 int VideoWin::setFormat(UCHAR tformat)
171 {
172   if (!initted) return 0;
173   if ((tformat != PAL) && (tformat != NTSC)) return 0;
174   format = tformat;
175   if (format == NTSC)
176   {
177     screenWidth = 720;
178     screenHeight = 480;
179   }
180   if (format == PAL)
181   {
182     screenWidth = 720;
183     screenHeight = 576;
184   }
185
186   return 1;
187 }
188
189 int VideoWin::setConnection(UCHAR tconnection)
190 {
191   if (!initted) return 0;
192   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
193   connection = tconnection;
194
195   return 1;
196 }
197
198 int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary)
199 {
200   if (!initted) return 0;
201   parx=tparx;
202   pary=tpary;
203   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
204   aspectRatio = taspectRatio;
205   AdjustWindow();
206   return 1;
207 }
208
209 int VideoWin::setMode(UCHAR tmode)
210 {
211   if (!initted) return 0;
212
213   //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
214
215   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
216       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
217   if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
218   AdjustWindow();
219
220   return 1;
221 }
222
223 int VideoWin::signalOff()
224 {
225   return 1;
226 }
227
228 int VideoWin::signalOn()
229 {
230   return 1;
231 }
232
233 int VideoWin::setSource()
234 {
235   if (!initted) return 0;
236
237   return 1;
238 }
239
240
241 int VideoWin::sync()
242 {
243   if (!initted) return 0;
244
245   return 1;
246 }
247 void VideoWin::initFilterDatabase()
248 {
249     /* This method should determine all availiable DirectShow Filters */
250     IFilterMapper2* filtmap=NULL;
251     HRESULT result;
252     result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
253                 IID_IFilterMapper2,(void**)&filtmap);
254     if (result != S_OK)
255     {
256         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
257         return;
258     }
259     /* Wishlist, what Mediatypes do we want */
260     GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
261     IEnumMoniker *myenum;
262     result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
263                     TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
264     if (result != S_OK)
265     {
266         filtmap->Release();
267         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
268         return;
269     }
270     ULONG gethowmany;
271     IMoniker * moni;
272     while(myenum->Next(1,&moni,&gethowmany)==S_OK)
273     {
274         VideoFilterDesc desc;
275         ZeroMemory(&desc,sizeof(desc));
276    
277         LPOLESTR string;
278         moni->GetDisplayName(0,0,&string);
279         desc.displayname=new char[wcslen(string)+1];
280         wcstombs(desc.displayname,string,wcslen(string)+1);
281         CoTaskMemFree(string);
282         IPropertyBag *bag;
283         if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
284         {
285             VARIANT vari;
286             VariantInit(&vari);
287             result = bag->Read(L"FriendlyName",&vari,NULL);
288             if (result == S_OK)
289             {
290                 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
291                 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
292             }
293             VariantClear(&vari);
294             bag->Release();
295
296         }
297         
298        
299         videofilterlist.push_back(desc);
300        
301
302         
303         moni->Release();
304        // bctx->Release();
305     }
306     int i;
307     videofilterselected=-1;
308     
309     
310   
311     myenum->Release();
312
313
314
315     filtmap->Release();
316 }
317
318 void VideoWin::initH264FilterDatabase()
319 {
320     /* This method should determine all availiable DirectShow Filters */
321     IFilterMapper2* filtmap=NULL;
322     HRESULT result;
323     result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
324                 IID_IFilterMapper2,(void**)&filtmap);
325     if (result != S_OK)
326     {
327         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
328         return;
329     }
330     /* Wishlist, what Mediatypes do we want */
331     GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_H264};
332     IEnumMoniker *myenum;
333     result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
334                     TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
335     if (result != S_OK)
336     {
337         filtmap->Release();
338         Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
339         return;
340     }
341     ULONG gethowmany;
342     IMoniker * moni;
343     while(myenum->Next(1,&moni,&gethowmany)==S_OK)
344     {
345         VideoFilterDesc desc;
346         ZeroMemory(&desc,sizeof(desc));
347    
348         LPOLESTR string;
349         moni->GetDisplayName(0,0,&string);
350         desc.displayname=new char[wcslen(string)+1];
351         wcstombs(desc.displayname,string,wcslen(string)+1);
352         CoTaskMemFree(string);
353         IPropertyBag *bag;
354         if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
355         {
356             VARIANT vari;
357             VariantInit(&vari);
358             result = bag->Read(L"FriendlyName",&vari,NULL);
359             if (result == S_OK)
360             {
361                 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
362                 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
363             }
364             VariantClear(&vari);
365             bag->Release();
366
367         }
368         
369        
370         videoH264filterlist.push_back(desc);
371        
372
373         
374         moni->Release();
375        // bctx->Release();
376     }
377     int i;
378     videoH264filterselected=-1;
379     
380     
381   
382     myenum->Release();
383
384
385
386     filtmap->Release();
387 }
388
389 bool VideoWin::loadOptionsfromServer(VDR* vdr)
390 {
391     char *name=vdr->configLoad("DirectShow","VideoFilter");
392     
393     if (name != NULL) 
394     {
395         for (int i = 0;i <videofilterlist.size();i++)
396         {
397             if (strcmp(name,videofilterlist[i].displayname)==0)
398             {
399                 videofilterselected = i;
400                 break;
401             }
402         }
403    }
404    name=vdr->configLoad("DirectShow","VideoH264Filter");
405     
406     if (name != NULL) 
407     {
408         for (int i = 0;i <videoH264filterlist.size();i++)
409         {
410             if (strcmp(name,videoH264filterlist[i].displayname)==0)
411             {
412                 videoH264filterselected = i;
413                 break;
414             }
415         }
416    }
417    name=vdr->configLoad("DirectShow","VMR9DeinterlacingMode");
418    if (name != NULL) 
419    {
420        if (STRCASECMP(name,"NoMix")==0)  {
421            vmrdeinterlacing=0;
422        } else if (STRCASECMP(name,"None")==0)  {
423            vmrdeinterlacing=1;
424        } else if (STRCASECMP(name,"Best")==0)  {
425            vmrdeinterlacing=2;
426        } else if (STRCASECMP(name,"Bob")==0)  {
427            vmrdeinterlacing=3;
428        } else if (STRCASECMP(name,"Weave")==0)  {
429            vmrdeinterlacing=4;
430        }
431    }
432
433    name=vdr->configLoad("DirectShow", "VideoPresenter");
434    if (name!=NULL) {
435        if (STRCASECMP(name,"VMR9")==0) {
436            currentpresenter=VMR9;
437            } else if (STRCASECMP(name,"EVR")==0) {
438            currentpresenter=EVR;
439        } 
440    }
441    if (!dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported()) {
442            currentpresenter=VMR9;
443    }
444
445    name=vdr->configLoad("DirectShow","videoH264dtsfix");
446    if (name!=NULL) {
447        if (STRCASECMP(name,"YES")==0) {
448            videoH264dtsfix=true;
449        } else {
450            videoH264dtsfix=false;
451        }
452    }
453    name=vdr->configLoad("DirectShow","videompeg2dtsfix");
454    if (name!=NULL) {
455        if (STRCASECMP(name,"YES")==0) {
456            videompeg2dtsfix=true;
457        } else {
458            videompeg2dtsfix=false;
459        }
460    }
461
462    name=vdr->configLoad("DirectGraphics", "StretchFiltering");
463    if (name!=NULL) {
464        if (STRCASECMP(name,"None")==0) {
465            dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
466        } else if (STRCASECMP(name,"Point")==0) {
467            dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
468        } else if (STRCASECMP(name,"Linear")==0) {
469            dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
470        }
471    }
472
473    
474
475
476    return true;
477
478 }
479
480 bool VideoWin::handleOptionChanges(Option* option)
481 {
482     if( Video::handleOptionChanges(option)) return true;
483     switch(option->id) {
484         case 1: {
485             if (STRCASECMP(option->options[option->userSetChoice],"None")==0) {
486                 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_NONE);
487             } else if (STRCASECMP(option->options[option->userSetChoice],"Point")==0) {
488                                 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_POINT);
489             } else if (STRCASECMP(option->options[option->userSetChoice],"Linear")==0) {
490                                 dynamic_cast<WindowsOsd*>(Osd::getInstance())->setFilterType(D3DTEXF_LINEAR);
491             }
492    return true;
493                 } break;
494         case 2: {
495             if (STRCASECMP(option->options[option->userSetChoice],"NoMix")==0)  {
496                 vmrdeinterlacing=0;
497             } else if (STRCASECMP(option->options[option->userSetChoice],"None")==0)  {
498                 vmrdeinterlacing=1;
499             } else if (STRCASECMP(option->options[option->userSetChoice],"Best")==0)  {
500                 vmrdeinterlacing=2;
501             } else if (STRCASECMP(option->options[option->userSetChoice],"Bob")==0)  {
502                 vmrdeinterlacing=3;
503             } else if (STRCASECMP(option->options[option->userSetChoice],"Weave")==0)  {
504                 vmrdeinterlacing=4;
505             } 
506                 }break;
507                  case 3: {
508             if (STRCASECMP(option->options[option->userSetChoice],"VMR9")==0)  {
509                 currentpresenter=VMR9;
510             } else if (STRCASECMP(option->options[option->userSetChoice],"EVR")==0)  {
511                 currentpresenter=EVR;
512             } 
513                 }break;
514          case 4: {
515              if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
516                 videoH264dtsfix=true;
517              } else {
518                  videoH264dtsfix=false;
519              }
520                  }break;
521          case 5: {
522              if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) {
523                 videompeg2dtsfix=true;
524              } else {
525                  videompeg2dtsfix=false;
526              }
527                  }break;
528     };
529     return false;
530
531 }
532
533 bool VideoWin::saveOptionstoServer()
534 {
535     if (videofilterselected!=-1) {
536         VDR::getInstance()->configSave("DirectShow",
537             "VideoFilter",videofilterlist[videofilterselected].displayname);
538                  VDR::getInstance()->configSave("DirectShow",
539             "VideoH264Filter",videoH264filterlist[videoH264filterselected].displayname);
540     }
541     return true;
542 }
543
544 /*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType, 
545            UINT numChoices, UINT defaultChoice, UINT startInt,
546            const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
547
548 bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
549 {
550     if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
551
552
553     Option* option;
554     if (panenumber == 2) 
555     {
556         DWORD scalingcaps=dynamic_cast<WindowsOsd*>(Osd::getInstance())->getFilterCaps();
557         char **scalingopts=new char *[3];
558         int i=0;
559         scalingopts[i]=new char[strlen("None")+1];
560         strcpy(scalingopts[i],"None");
561         i++;
562         if ((scalingcaps & D3DPTFILTERCAPS_MINFPOINT)!=0 
563             && (scalingcaps & D3DPTFILTERCAPS_MAGFPOINT)!=0) {
564             scalingopts[i]=new char[strlen("Point")+1];
565             strcpy(scalingopts[i],"Point");
566             i++;
567         }
568         if ((scalingcaps & D3DPTFILTERCAPS_MINFLINEAR)!=0 
569             && (scalingcaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0) {
570             scalingopts[i]=new char[strlen("Linear")+1];
571             strcpy(scalingopts[i],"Linear");
572             i++;
573         }
574         option = new Option(1 ,tr("Video Stretching Filter"), "DirectGraphics", "StretchFiltering", Option::TYPE_TEXT, i, (i-1), 0, scalingopts,NULL,true, this);
575         options->push_back(option);
576         pane->addOptionLine(option);
577         static const char* deintopts[]={"NoMix","None","Best","Bob","Weave"};
578         option = new Option(2,tr("VMR9 Deinterlacing Mode"), "DirectShow","VMR9DeinterlacingMode",Option::TYPE_TEXT,5,2,0,deintopts,NULL,false,this);
579         options->push_back(option);
580         pane->addOptionLine(option);
581
582                 if (dynamic_cast<WindowsOsd*>(Osd::getInstance())->IsEvrSupported()) 
583                 {
584                         static const char* presenteropts[]={"EVR","VMR9"};
585             option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,
586                 (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this);
587                 } else {
588                         static const char* presenteropts[]={"VMR9"};
589                         option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this);
590                 }
591                 options->push_back(option);
592         pane->addOptionLine(option);
593
594         static const char* yesnoopts[]={"Yes","No"};
595         option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
596         options->push_back(option);
597         pane->addOptionLine(option);
598
599         option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this);
600         options->push_back(option);
601         pane->addOptionLine(option);
602
603
604       
605     }
606
607     return true;
608 }
609
610 IBaseFilter *VideoWin::getVideoFilter()
611 {
612     IBaseFilter *curfilter= NULL;
613     if (videofilterselected == -1)
614     {
615         int i;
616         for (i = 0;i <videofilterlist.size();i++)
617         {
618             
619             if (videofilterlist[i].vmr9tested == true)
620             {
621                 if (videofilterlist[i].vmr9 == true)
622                 {
623                     videofilterselected = i;
624                     break;
625                 } 
626                 else
627                 {
628                     continue;
629                 }
630             }
631             else
632             {
633                 IMoniker * moni=NULL;
634                 IBindCtx *bindctx=NULL;
635                 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
636                 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videofilterlist[i].displayname)+1];
637                 mbstowcs((wchar_t*)name,videofilterlist[i].displayname,strlen(videofilterlist[i].displayname)+1);
638                 ULONG eater=0;
639                 
640
641                 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
642                 {
643                     if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
644                     {
645                         IAMDecoderCaps* desccaps=NULL;
646                         if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
647                         {
648                             DWORD caps;
649                             desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
650                             if (caps == DECODER_CAP_SUPPORTED)
651                             {
652                                 videofilterlist[i].vmr9tested =  true;
653                                 videofilterlist[i].vmr9 = true;
654                                 videofilterselected = i;
655                             } 
656                             else
657                             {
658                                 videofilterlist[i].vmr9tested =  true;
659                                 videofilterlist[i].vmr9 = false;
660                                 
661                                 curfilter->Release();
662                                 curfilter=NULL;
663                             }
664                         }
665                         desccaps->Release();
666                     }
667                     moni->Release();
668                 } 
669                 delete [] name;
670                 bindctx->Release();
671             }
672             if (videofilterlist[i].vmr9) break;
673             
674         }
675         if (curfilter != NULL)
676         {
677             VDR *vdr=VDR::getInstance();
678             if (vdr != NULL)
679             {
680                 vdr->configSave("DirectShow","VideoFilter",
681                     videofilterlist[videofilterselected].displayname);
682             }
683             return curfilter;
684         }
685     } 
686     else
687     {
688         IBindCtx *bindctx=NULL;
689         if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
690         IMoniker * moni=NULL;
691         LPCOLESTR name=new WCHAR[strlen(videofilterlist[videofilterselected].displayname)+1];
692         mbstowcs((wchar_t*)name,videofilterlist[videofilterselected].displayname,
693             strlen(videofilterlist[videofilterselected].displayname)+1);
694         ULONG eater;
695         if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
696         {
697             if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
698             {
699                     IAMDecoderCaps* desccaps=NULL;
700                     if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
701                     {
702                         DWORD caps;
703                         desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
704                         if (caps == DECODER_CAP_SUPPORTED)
705                         {
706                             videofilterlist[videofilterselected].vmr9tested =  true;
707                             videofilterlist[videofilterselected].vmr9 = true;
708                         } 
709                         else
710                         {
711                             videofilterlist[videofilterselected].vmr9tested =  true;
712                             videofilterlist[videofilterselected].vmr9 = false;
713                             Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
714                         }
715                     }
716                     moni->Release();
717                     delete [] name;
718                     bindctx->Release();
719                     return curfilter;
720              } 
721             moni->Release();
722         }
723         bindctx->Release();
724         delete [] name;
725         return NULL;         
726     }
727     return NULL;
728     
729 }
730
731 IBaseFilter *VideoWin::getVideoH264Filter()
732 {
733     IBaseFilter *curfilter= NULL;
734     if (videoH264filterselected == -1)
735     {
736         int i;
737         for (i = 0;i <videoH264filterlist.size();i++)
738         {
739             
740             if (videoH264filterlist[i].vmr9tested == true)
741             {
742                 if (videoH264filterlist[i].vmr9 == true)
743                 {
744                     videoH264filterselected = i;
745                     break;
746                 } 
747                 else
748                 {
749                     continue;
750                 }
751             }
752             else
753             {
754                 IMoniker * moni=NULL;
755                 IBindCtx *bindctx=NULL;
756                 if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
757                 LPCOLESTR name=(LPCOLESTR)new WCHAR[strlen(videoH264filterlist[i].displayname)+1];
758                 mbstowcs((wchar_t*)name,videoH264filterlist[i].displayname,strlen(videoH264filterlist[i].displayname)+1);
759                 ULONG eater=0;
760                                 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[i].friendlyname);
761
762                 
763
764                 if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
765                 {
766                     if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
767                     {
768                         IAMDecoderCaps* desccaps=NULL;
769                         if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
770                         {
771                             DWORD caps;
772                             desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
773                             if (caps == DECODER_CAP_SUPPORTED)
774                             {
775                                 videoH264filterlist[i].vmr9tested =  true;
776                                 videoH264filterlist[i].vmr9 = true;
777                                 videoH264filterselected = i;
778                             } 
779                             else
780                             {
781                                 videoH264filterlist[i].vmr9tested =  true;
782                                 videoH264filterlist[i].vmr9 = false;
783                                 
784                                 curfilter->Release();
785                                 curfilter=NULL;
786                             }
787                         }
788                         desccaps->Release();
789                     }
790                     moni->Release();
791                 } 
792                 delete [] name;
793                 bindctx->Release();
794             }
795             if (videoH264filterlist[i].vmr9) break;
796             
797         }
798         if (curfilter != NULL)
799         {
800             VDR *vdr=VDR::getInstance();
801             if (vdr != NULL)
802             {
803                 vdr->configSave("DirectShow","VideoH264Filter",
804                     videoH264filterlist[videoH264filterselected].displayname);
805             }
806             return curfilter;
807         }
808     } 
809     else
810     {
811         IBindCtx *bindctx=NULL;
812         if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
813         IMoniker * moni=NULL;
814         LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[videoH264filterselected].displayname)+1];
815         mbstowcs((wchar_t*)name,videoH264filterlist[videoH264filterselected].displayname,
816             strlen(videoH264filterlist[videoH264filterselected].displayname)+1);
817         ULONG eater;
818                 Log::getInstance()->log("VideoWin", Log::DEBUG ,"Creating filter: %s",videoH264filterlist[videoH264filterselected].friendlyname);
819         if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
820         {
821             if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
822             {
823                     IAMDecoderCaps* desccaps=NULL;
824                     if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
825                     {
826                         DWORD caps;
827                         desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
828                         if (caps == DECODER_CAP_SUPPORTED)
829                         {
830                             videoH264filterlist[videoH264filterselected].vmr9tested =  true;
831                             videoH264filterlist[videoH264filterselected].vmr9 = true;
832                         } 
833                         else
834                         {
835                             videoH264filterlist[videoH264filterselected].vmr9tested =  true;
836                             videoH264filterlist[videoH264filterselected].vmr9 = false;
837                             Log::getInstance()->log("VideoWin", Log::WARN ,"Filter does not support VMR9, but is selected, manual selection!");
838                         }
839                     }
840                     moni->Release();
841                     delete [] name;
842                     bindctx->Release();
843                     return curfilter;
844              } 
845             moni->Release();
846         }
847         bindctx->Release();
848         delete [] name;
849         return NULL;         
850     }
851     return NULL;
852     
853 }
854
855
856 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
857 #include "dshelper.h"
858 #endif
859
860 #define DO_VIDEO
861
862 int VideoWin::play()
863 {
864   if (!initted) return 0;
865   return 1;
866 }
867
868 bool VideoWin::addOptionPagesToWTB(WTabBar *wtb)
869 {
870     Boxx *box=new WWinVideoFilter();
871     wtb->addTab(tr("Video Filter"), box);
872         box=new WWinVideoH264Filter();
873     wtb->addTab(tr("H264 Filter"), box);
874     return true;
875 }
876
877 const VideoFilterDescList *VideoWin::getVideoFilterList(int &selected)
878 {
879     selected=videofilterselected;
880     return &videofilterlist;
881 }
882
883 const VideoFilterDescList *VideoWin::getVideoH264FilterList(int &selected)
884 {
885     selected=videoH264filterselected;
886     return &videoH264filterlist;
887 }
888
889 bool VideoWin::selectVideoFilter(int filter)
890 {
891     IBindCtx *bindctx=NULL;
892     if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
893     IMoniker * moni=NULL;
894     LPCOLESTR name=new WCHAR[strlen(videofilterlist[filter].displayname)+1];
895     mbstowcs((wchar_t*)name,videofilterlist[filter].displayname,
896     strlen(videofilterlist[filter].displayname)+1);
897     ULONG eater;
898     bool success=false;
899     if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
900     {
901         IBaseFilter* curfilter=NULL;
902         if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
903         {
904             IAMDecoderCaps* desccaps=NULL;
905             if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
906             {
907                 DWORD caps;
908                 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
909                 if (caps == DECODER_CAP_SUPPORTED)
910                 {
911                     videofilterlist[filter].vmr9tested =  true;
912                     videofilterlist[filter].vmr9 = true;
913                     success=true;
914                 } 
915                 else
916                 {
917                     videofilterlist[filter].vmr9tested =  true;
918                     videofilterlist[filter].vmr9 = false;
919                     success=false;
920                  }
921                 desccaps->Release();
922             } else {
923                 videofilterlist[filter].vmr9tested =  true;
924                 videofilterlist[filter].vmr9 = false;
925                 success=false;
926             }
927
928              curfilter->Release();
929              
930         } 
931         moni->Release();
932     }
933     bindctx->Release();
934     delete [] name;
935     if (success || true) 
936     {
937         videofilterselected=filter;
938         return true;
939     } 
940     else
941     {
942         return false;
943     }
944 }
945
946 bool VideoWin::selectVideoH264Filter(int filter)
947 {
948     IBindCtx *bindctx=NULL;
949     if (CreateBindCtx(0,&bindctx)!=S_OK) return NULL;
950     IMoniker * moni=NULL;
951     LPCOLESTR name=new WCHAR[strlen(videoH264filterlist[filter].displayname)+1];
952     mbstowcs((wchar_t*)name,videoH264filterlist[filter].displayname,
953     strlen(videoH264filterlist[filter].displayname)+1);
954     ULONG eater;
955     bool success=false;
956     if (MkParseDisplayName(bindctx,name,&eater,&moni)==S_OK)
957     {
958         IBaseFilter* curfilter=NULL;
959         if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&curfilter) == S_OK)
960         {
961             IAMDecoderCaps* desccaps=NULL;
962             if (curfilter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
963             {
964                 DWORD caps;
965                 HRESULT hres=desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
966                 if (caps == DECODER_CAP_SUPPORTED)
967                 {
968                     videoH264filterlist[filter].vmr9tested =  true;
969                     videoH264filterlist[filter].vmr9 = true;
970                     success=true;
971                 } 
972                 else
973                 {
974                     videoH264filterlist[filter].vmr9tested =  true;
975                     videoH264filterlist[filter].vmr9 = false;
976                     success=false;
977                  }
978                 desccaps->Release();
979             } else {
980                 videoH264filterlist[filter].vmr9tested =  true;
981                 videoH264filterlist[filter].vmr9 = false;
982                 success=false;
983             }
984
985              curfilter->Release();
986              
987         } 
988         moni->Release();
989     }
990     bindctx->Release();
991     delete [] name;
992     if (success || true) 
993     {
994         videoH264filterselected=filter;
995         return true;
996     } 
997     else
998     {
999         return false;
1000     }
1001 }
1002
1003 int VideoWin::dsInitVideoFilter()
1004 {
1005     #ifdef DO_VIDEO
1006     HRESULT hres;
1007     if (videoon) {
1008     //We alloc the vmr9 as next step
1009                 if (currentpresenter==VMR9) 
1010                 {
1011                         Log::getInstance()->log("VideoWin", Log::INFO ,"VMR9 Videopresenter selected!");
1012                         if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
1013                                 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK) 
1014                         {
1015                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
1016                                 ReleaseMutex(filtermutex);
1017                                 CleanupDS();
1018                         }
1019                         /*VMR 9 stuff**/
1020                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"VMR9")!=S_OK)
1021                         {
1022                                 ReleaseMutex(filtermutex);
1023                                 CleanupDS();
1024                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
1025                                 return 0;
1026                         }
1027                         IVMRFilterConfig9* vmrfilconfig;
1028                         if (dsrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
1029                         {
1030                                 ReleaseMutex(filtermutex);
1031                                 CleanupDS();
1032                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
1033                                 return 0;
1034                         }
1035                         if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode
1036                         vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
1037                         vmrfilconfig->Release();
1038                         if (dsrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
1039                                 (void**)& dsvmrsurfnotify) != S_OK)
1040                         {
1041                                 ReleaseMutex(filtermutex);
1042                                 CleanupDS();
1043                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
1044                                 return 0;
1045                         }
1046                         allocatorvmr=new DsAllocator();
1047                         dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
1048                         allocatorvmr->AdviseNotify(dsvmrsurfnotify);
1049                         
1050                         IVMRDeinterlaceControl9* deintctrl;
1051                         if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1052                         {
1053                                 ReleaseMutex(filtermutex);
1054                                 CleanupDS();
1055                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1056                                 return 0;
1057                         }
1058                         /*turnoff*/
1059                         switch (vmrdeinterlacing)
1060                         {
1061                         case 1: //No Deinterlasing
1062                          deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1063             break;
1064                         case 2: //Best
1065              deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1066             break;
1067                         case 3: //Bob
1068              deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1069                         break;
1070                         case 4: //Weave
1071              deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1072              break;
1073                         };
1074                         deintctrl->Release();
1075                         /*VMR 9 stuff end */
1076                 }
1077                 else if (currentpresenter==EVR)
1078                 {
1079                         Log::getInstance()->log("VideoWin", Log::INFO ,"EVR Videopresenter selected!");
1080                         if (hres=CoCreateInstance(CLSID_EnhancedVideoRenderer,0,
1081                                 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsrenderer)!=S_OK) 
1082                         {
1083                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating EVR renderer!");
1084                                 ReleaseMutex(filtermutex);
1085                                 CleanupDS();
1086                         }
1087                         /*EVR stuff**/
1088                         if (hres=dsgraphbuilder->AddFilter(dsrenderer,L"EVR")!=S_OK)
1089                         {
1090                                 ReleaseMutex(filtermutex);
1091                                 CleanupDS();
1092                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding EVR renderer!");
1093                                 return 0;
1094                         }
1095                         
1096                         
1097                         IMFGetService *evr_services;
1098                         if (dsrenderer->QueryInterface(IID_IMFGetService,(void**)&evr_services)!=S_OK)
1099                         {
1100                                 ReleaseMutex(filtermutex);
1101                                 CleanupDS();
1102                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFGetServices interface!");
1103                                 return 0;
1104                         }
1105
1106                         IMFVideoDisplayControl* mfvideodisplaycontrol;
1107                         if (evr_services->GetService(MR_VIDEO_RENDER_SERVICE,IID_IMFVideoDisplayControl,(void**)&mfvideodisplaycontrol)!=S_OK)
1108                         {
1109                                 ReleaseMutex(filtermutex);
1110                                 CleanupDS();
1111                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoDisplayControl interface!");
1112                                 return 0;
1113                         }
1114
1115                         evr_services->Release();
1116                         mfvideodisplaycontrol->SetVideoWindow(((WindowsOsd*) Osd::getInstance())->getWindow());
1117                         //RECT client;
1118                     //GetClientRect(((OsdWin*) Osd::getInstance())->getWindow(), &client);
1119                         //mfvideodisplaycontrol->SetVideoPosition(NULL,&client);
1120
1121                         mfvideodisplaycontrol->Release();
1122
1123
1124                 ///     if (vmrdeinterlacing!=0) vmrfilconfig->SetNumberOfStreams(1);//Enter Mixing Mode //always the case for evr!
1125
1126                         IMFVideoRenderer *mfvideorenderer;
1127                         if (dsrenderer->QueryInterface(IID_IMFVideoRenderer,(void**)&mfvideorenderer)!=S_OK)
1128                         {
1129                                 ReleaseMutex(filtermutex);
1130                                 CleanupDS();
1131                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting EVR IMFVideoRenderer interface!");
1132                                 return 0;
1133                         }
1134                         
1135                         allocatorvmr=new DsAllocator();
1136                         HRESULT hres=mfvideorenderer->InitializeRenderer(NULL,allocatorvmr);
1137
1138                         mfvideorenderer->Release();
1139                         //How should I do this in EVR?
1140                 /*      IVMRDeinterlaceControl9* deintctrl;
1141                         if (dsrenderer->QueryInterface(IID_IVMRDeinterlaceControl9,(void**)&deintctrl)!=S_OK)
1142                         {
1143                                 ReleaseMutex(filtermutex);
1144                                 CleanupDS();
1145                                 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Deinterlace control!");
1146                                 return 0;
1147                         }
1148                         /*turnoff*
1149                         switch (vmrdeinterlacing)
1150                         {
1151                         case 1: //No Deinterlasing
1152                          deintctrl->SetDeinterlaceMode(0xFFFFFFFF,(LPGUID)&GUID_NULL);//Turn Off
1153             break;
1154                         case 2: //Best
1155              deintctrl->SetDeinterlacePrefs(DeinterlacePref_NextBest);//Choose Next Best
1156             break;
1157                         case 3: //Bob
1158              deintctrl->SetDeinterlacePrefs(DeinterlacePref_BOB);//Choose NBob
1159                         break;
1160                         case 4: //Weave
1161              deintctrl->SetDeinterlacePrefs(DeinterlacePref_Weave);//Choose Weave
1162              break;
1163                         };
1164                         deintctrl->Release();*/
1165                         /*EVR stuff end */
1166                 } else {
1167                         Log::getInstance()->log("VideoWin", Log::ERR ,"No videopresenter selected! Please post on the forum!");
1168                         return -1;
1169                 }
1170         IFilterGraph2*fg2=NULL;
1171         if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
1172         {
1173             Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
1174             ReleaseMutex(filtermutex);
1175                 CleanupDS();
1176             return 0;
1177         }
1178 /*#ifndef NEW_DS_MECHANISMENS
1179         
1180         if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*,
1181             AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK) 
1182         {
1183             Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
1184                 fg2->Release();
1185                 ReleaseMutex(filtermutex);
1186                 CleanupDS();
1187             return 0;
1188         }
1189         
1190 #else*/
1191         IBaseFilter*videofilter;
1192                 if (h264)  
1193                 {
1194                         Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering h264 playback...");
1195                         videofilter=getVideoH264Filter();
1196                 } 
1197                 else
1198                 {
1199                         Log::getInstance()->log("VideoWin", Log::DEBUG ,"Entering MPEG2 playback...");
1200                         videofilter=getVideoFilter();
1201                 }
1202         if (hres=dsgraphbuilder->AddFilter(videofilter,NULL) != S_OK) 
1203         {
1204             Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Video Filter!");
1205             ReleaseMutex(filtermutex);
1206             CleanupDS();
1207             return 0;
1208         }
1209         IEnumPins *pinenum=NULL;
1210         bool error=false;
1211
1212         mptype_video_detail vid_details;
1213         Demuxer* demux=Demuxer::getInstance();
1214         vid_details.width=demux->getHorizontalSize();
1215         vid_details.height=demux->getVerticalSize();
1216
1217                 if (h264)
1218                 {
1219             if (vid_details.width!=0 && vid_details.height!=0)
1220             {
1221                         sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details);
1222                 }
1223                 else
1224                 {
1225                             sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL);
1226             }
1227
1228                 }
1229                 else
1230                 {
1231             if (vid_details.width!=0 && vid_details.height!=0)
1232             {
1233                         sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details);
1234                 }
1235             else
1236             {
1237                 sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL);
1238             } 
1239                 }
1240         if (videofilter->EnumPins(&pinenum) == S_OK)
1241         {
1242             IPin *current=NULL;
1243             ULONG fetch=0;
1244             bool firststep=false;
1245
1246             while (pinenum->Next(1,&current,&fetch)==S_OK)
1247             {
1248                 PIN_DIRECTION dir;
1249                 if (current->QueryDirection(&dir)==S_OK)
1250                 {
1251                     if (dir == PINDIR_INPUT)
1252                     {
1253                         if (sourcefilter->GetVideoPin()->Connect(current,NULL)==S_OK)
1254                         {
1255                             current->Release();
1256                             firststep=true;
1257                             break;
1258                         }
1259                     }
1260                 }
1261                 current->Release();
1262             }
1263             if (firststep==false)
1264             {
1265                 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable input!");
1266                 videofilter->Release();
1267                 ReleaseMutex(filtermutex);
1268                 CleanupDS();
1269                 return 0;
1270             }
1271             bool secondstep=false;
1272             pinenum->Reset();
1273             while (pinenum->Next(1,&current,&fetch)==S_OK)
1274             {
1275                 PIN_DIRECTION dir;
1276                 if (current->QueryDirection(&dir)==S_OK)
1277                 {
1278                     if (dir == PINDIR_OUTPUT)
1279                     {
1280                         
1281                         if (fg2->RenderEx((IPin*)current/*video*/,
1282                                 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) ==S_OK)
1283                         {
1284                             current->Release();
1285                             secondstep=true;
1286                             break;
1287                         }
1288                     }
1289                 }
1290                 current->Release();
1291             }
1292             if (secondstep==false)
1293             {
1294                 Log::getInstance()->log("VideoWin", Log::WARN , "Video Filter has no suitable output!");
1295                 videofilter->Release();
1296                 ReleaseMutex(filtermutex);
1297                 CleanupDS();
1298                 return 0;
1299             }
1300             
1301             videofilter->Release();
1302             pinenum->Release();
1303
1304         }
1305
1306
1307
1308         fg2->Release();
1309         return 1;
1310     }
1311 #endif 
1312         return 1;
1313 }
1314
1315 int VideoWin::setAudioStreamType(UCHAR type)
1316 {
1317   aud_type=type;
1318   if (!initted) return 0;
1319   return 1;
1320 }
1321
1322 int VideoWin::dsplay()
1323 {
1324     if (!initted) return 0;
1325     CleanupDS();
1326     
1327     //Build filter graph
1328     HRESULT hres;
1329     //So this is the real code, this prevents the feeder from calling noexisting objects!
1330     WaitForSingleObject(filtermutex,INFINITE);
1331     if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1332         IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK) 
1333     {
1334         ReleaseMutex(filtermutex);
1335         return 0;
1336     }
1337    #ifdef DS_DEBUG
1338    AddToRot(dsgraphbuilder,&graphidentifier);
1339    #endif
1340    
1341    firstsynched=false;
1342    if (aud_type==Audio::MP3) {
1343        lastaudiomode=MPTYPE_MPEG_AUDIO_LAYER3;
1344    } else {
1345        lastaudiomode=MPTYPE_MPEG_AUDIO;
1346    }
1347    //lastaudiomode=MPTYPE_AC3;
1348    sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1349    // to DirectShow
1350    if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK) 
1351    {
1352        Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1353        ReleaseMutex(filtermutex);
1354        CleanupDS();
1355        return 0;
1356    }
1357    sourcefilter->GetAudioPin()->SetPinMode(lastaudiomode);
1358    /*if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*)!=S_OK) 
1359    {
1360        Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1361            ReleaseMutex(filtermutex);
1362        CleanupDS();
1363        return 0;
1364    }*/
1365    if (((AudioWin*)Audio::getInstance())->dsInitAudioFilter(dsgraphbuilder)==0)
1366    {
1367        Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
1368            ReleaseMutex(filtermutex);
1369        CleanupDS();
1370        return 0;
1371    }
1372
1373
1374     if (dsInitVideoFilter()==0)
1375     { 
1376         return 0;
1377     }
1378
1379     if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1380         IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) 
1381     {
1382         return 0;
1383     }
1384     dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1385     HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
1386
1387     dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1388     dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);    
1389     if (dsbasicaudio) 
1390        dsbasicaudio->put_Volume(audiovolume);
1391     dsinited=true;
1392    //MILLISLEEP(100);
1393
1394     hresdeb=dsmediacontrol->Run();
1395     iframemode=false;//exit iframe mode
1396     ReleaseMutex(filtermutex);
1397     return 1;
1398 }
1399
1400 int VideoWin::EnterIframePlayback()
1401 {
1402         if (!initted) return 0;
1403         CleanupDS();
1404         //So this is the real code, this prevents the feeder from calling noexisting objects!
1405    WaitForSingleObject(filtermutex,INFINITE);
1406         iframemode=true;//enter iframe mode
1407         //Build filter graph
1408         HRESULT hres;
1409         if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
1410                  IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
1411                          ReleaseMutex(filtermutex);
1412                          return 0;
1413         }
1414 #ifdef DS_DEBUG
1415         AddToRot(dsgraphbuilder,&graphidentifier);
1416 #endif
1417    
1418    //firstsynched=false;
1419    sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
1420    // to DirectShow
1421    if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
1422    Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
1423      ReleaseMutex(filtermutex);  
1424      CleanupDS();
1425      return 0;
1426    }
1427 #ifdef DO_VIDEO
1428     if (videoon) {
1429         dsInitVideoFilter();
1430    }
1431 #endif
1432 /*   if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
1433     IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
1434       return 0;
1435    }*/
1436
1437    dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
1438    dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
1439
1440    dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
1441    dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);     
1442   dsinited=true;
1443   
1444
1445    dsmediacontrol->Run();
1446    ReleaseMutex(filtermutex);
1447   return 1;
1448
1449 }
1450
1451 int VideoWin::dsstop()
1452 {
1453   if (!initted) return 0;
1454
1455   CleanupDS();
1456
1457
1458   return 1;
1459 }
1460
1461 int VideoWin::stop()
1462 {
1463   if (!initted) return 0;
1464
1465
1466   return 1;
1467 }
1468
1469 int VideoWin::reset()
1470 {
1471   if (!initted) return 0;
1472   
1473
1474   return 1;
1475 }
1476
1477 int VideoWin::dsreset()
1478 {
1479   if (!initted) return 0;
1480   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   dynamic_cast<WindowsOsd*>(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 false;
1944   if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1945     MILLISLEEP(10);
1946     return false;
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 false;
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 false;
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