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