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