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