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