2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "dssourcefilter.h"
24 #include "dsallocator.h"
44 lastaudiomode=MPTYPE_MPEG_AUDIO;
45 //lastaudiomode=MPTYPE_AC3;
47 filtermutex=CreateMutex(NULL,FALSE,NULL);
49 offsetvideonotset=true;
50 offsetaudionotset=true;
57 cur_audio_media_sample=NULL;
58 cur_video_media_sample=NULL;
64 iframemode=false;//We are not in Iframe mode at begining
73 CloseHandle(filtermutex);
80 int VideoWin::init(UCHAR tformat)
82 if (initted) return 0;
85 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
89 if (!setFormat(tformat)){ shutdown(); return 0; }
93 int VideoWin::setTVsize(UCHAR ttvsize)
99 int VideoWin::setDefaultAspect()
101 return setAspectRatio(Video::ASPECT4X3);
104 int VideoWin::shutdown()
106 if (!initted) return 0;
111 int VideoWin::setFormat(UCHAR tformat)
113 if (!initted) return 0;
114 if ((tformat != PAL) && (tformat != NTSC)) return 0;
130 int VideoWin::setConnection(UCHAR tconnection)
132 if (!initted) return 0;
133 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
134 connection = tconnection;
139 int VideoWin::setAspectRatio(UCHAR taspectRatio)
141 if (!initted) return 0;
142 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
143 aspectRatio = taspectRatio;
148 int VideoWin::setMode(UCHAR tmode)
150 if (!initted) return 0;
152 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
154 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
155 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
164 int VideoWin::signalOff()
169 int VideoWin::signalOn()
174 int VideoWin::setSource()
176 if (!initted) return 0;
181 int VideoWin::setPosition(int x, int y)
183 if (!initted) return 0;
184 if (mode==QUARTER || mode==EIGHTH) {
193 if (!initted) return 0;
198 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
199 #include "dshelper.h"
206 if (!initted) return 0;
210 int VideoWin::dsplay()
212 if (!initted) return 0;
217 //So this is the real code, this prevents the feeder from calling noexisting objects!
218 WaitForSingleObject(filtermutex,INFINITE);
219 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
220 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
221 ReleaseMutex(filtermutex);
225 AddToRot(dsgraphbuilder,&graphidentifier);
227 //This is just a try to see if building the graph works
228 // dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
231 lastaudiomode=MPTYPE_MPEG_AUDIO;
232 //lastaudiomode=MPTYPE_AC3;
233 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
235 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
236 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
237 ReleaseMutex(filtermutex);
242 if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*/)!=S_OK) {
243 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
244 ReleaseMutex(filtermutex);
251 //We alloc the vmr9 as next step
252 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
253 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
254 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
255 ReleaseMutex(filtermutex);
260 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
261 ReleaseMutex(filtermutex);
263 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
267 IVMRFilterConfig9* vmrfilconfig;
268 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
269 ReleaseMutex(filtermutex);
271 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
274 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
275 vmrfilconfig->Release();
277 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
278 ReleaseMutex(filtermutex);
280 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
284 allocatorvmr=new DsAllocator();
285 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
286 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
292 IFilterGraph2*fg2=NULL;
293 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
294 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
295 ReleaseMutex(filtermutex);
299 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
300 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
301 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
303 ReleaseMutex(filtermutex);
310 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
311 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
315 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
316 HRESULT hresdeb=dsmediafilter->SetSyncSource(dsrefclock);
318 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
319 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
323 hresdeb=dsmediacontrol->Run();
324 iframemode=false;//exit iframe mode
325 ReleaseMutex(filtermutex);
329 int VideoWin::EnterIframePlayback()
331 if (!initted) return 0;
333 //So this is the real code, this prevents the feeder from calling noexisting objects!
334 WaitForSingleObject(filtermutex,INFINITE);
335 iframemode=true;//enter iframe mode
338 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
339 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
340 ReleaseMutex(filtermutex);
344 AddToRot(dsgraphbuilder,&graphidentifier);
347 //firstsynched=false;
348 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
350 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
351 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
352 ReleaseMutex(filtermutex);
358 //We alloc the vmr9 as next step
359 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
360 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
361 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
362 ReleaseMutex(filtermutex);
367 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
368 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
369 ReleaseMutex(filtermutex);
373 IVMRFilterConfig9* vmrfilconfig;
374 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
375 ReleaseMutex(filtermutex);
377 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
381 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
382 vmrfilconfig->Release();
384 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
385 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
386 ReleaseMutex(filtermutex);
390 allocatorvmr=new DsAllocator();
391 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
392 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
395 IFilterGraph2*fg2=NULL;
396 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
397 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
398 ReleaseMutex(filtermutex);
402 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
403 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
404 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
406 ReleaseMutex(filtermutex);
413 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
414 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
418 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
419 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
421 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
422 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
426 dsmediacontrol->Run();
427 ReleaseMutex(filtermutex);
432 int VideoWin::dsstop()
434 if (!initted) return 0;
444 if (!initted) return 0;
450 int VideoWin::reset()
452 if (!initted) return 0;
458 int VideoWin::dsreset()
460 if (!initted) return 0;
463 iframemode=false;//exit iframe mode
469 int VideoWin::dspause()
471 if (!initted) return 0;
472 WaitForSingleObject(filtermutex,INFINITE);
473 if (dsmediacontrol) dsmediacontrol->Pause();
474 ReleaseMutex(filtermutex);
478 int VideoWin::pause()
480 if (!initted) return 0;
485 int VideoWin::unPause() // FIXME get rid - same as play!!
486 {//No on windows this is not the same, I don't get rid of!
487 if (!initted) return 0;
491 int VideoWin::dsunPause() // FIXME get rid - same as play!!
492 {//No on windows this is not the same, I don't get rid of!
493 if (!initted) return 0;
494 WaitForSingleObject(filtermutex,INFINITE);
495 if (dsmediacontrol) dsmediacontrol->Run();
496 ReleaseMutex(filtermutex);
501 int VideoWin::fastForward()
503 if (!initted) return 0;
508 int VideoWin::unFastForward()
510 if (!initted) return 0;
515 int VideoWin::attachFrameBuffer()
517 if (!initted) return 0;
521 int VideoWin::blank(void)
523 ((OsdWin*)Osd::getInstance())->Blank();
527 ULLONG VideoWin::getCurrentTimestamp()
529 REFERENCE_TIME startoffset;
530 REFERENCE_TIME ncr_time;
531 if (iframemode) return 0; //Not in iframe mode!
532 if (!dsrefclock || !sourcefilter) return 0;
534 sourcefilter->GetState(10,&state);
536 if (state==State_Running) dsrefclock->GetTime(&cr_time);
538 startoffset=sourcefilter->getStartOffset();
539 ncr_time-=startoffset;
540 ncr_time-=lastreftimeRT;
541 /* ULLONG result=frameNumberToTimecode(
542 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
543 ULLONG result=lastreftimePTS;
544 result+=(ULLONG)(ncr_time/10000LL*90LL);
549 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
551 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
552 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
555 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
557 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
558 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
561 void VideoWin::CleanupDS()
563 WaitForSingleObject(filtermutex,INFINITE);
565 if (dsmediacontrol)dsmediacontrol->Stop();
566 if (cur_audio_media_sample) {
567 cur_audio_media_sample->Release();
568 cur_audio_media_sample=NULL;
570 if (cur_video_media_sample) {
571 cur_video_media_sample->Release();
572 cur_video_media_sample=NULL;
575 dsbasicaudio->Release();
578 if (dsvmrsurfnotify) {
579 dsvmrsurfnotify->Release();
580 dsvmrsurfnotify=NULL;
583 dsvmrrenderer->Release();
588 allocatorvmr->Release();
593 dsrefclock->Release();
597 dsmediafilter->Release();
603 if (dsmediacontrol) {
604 dsmediacontrol->Stop();
605 dsmediacontrol->Release();
610 RemoveFromRot(graphidentifier);
612 dsgraphbuilder->Release();
615 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
617 ReleaseMutex(filtermutex);
621 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
624 mediapacket = mplist.front();
627 UINT VideoWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)
629 DeliverMediaPacket(mediapacket, buffer, samplepos);
630 if (*samplepos == mediapacket.length) {
637 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
641 /*First Check, if we have an audio sample*/
642 if (!isdsinited()) return 0;
645 *samplepos+=packet.length;
646 MILLISLEEP(0); //yet not implemented//bad idea
647 return packet.length;
649 /*First Check, if we have an audio sample*/
653 return 0; //Not in iframe mode!
655 IMediaSample* ms=NULL;
656 REFERENCE_TIME reftime1=0;
657 REFERENCE_TIME reftime2=0;
660 if (packet.disconti) {
662 DeliverVideoMediaSample();
665 /*Inspect PES-Header */
667 if (*samplepos==0) {//stripheader
668 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
669 *samplepos+=headerstrip;
670 if ( packet.synched ) {
671 DeliverVideoMediaSample();//write out old data
672 /* if (packet.presentation_time<0) { //Preroll?
673 *samplepos=packet.length;//if we have not processed at least one
674 return packet.length;//synched packet ignore it!
677 reftime1=packet.presentation_time;
681 if (!firstsynched) {//
682 *samplepos=packet.length;//if we have not processed at least one
683 return packet.length;//synched packet ignore it!
692 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
697 ms_pos=ms->GetActualDataLength();
698 ms_length=ms->GetSize();
699 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
700 if ((ms_length-ms_pos)<1) {
701 DeliverVideoMediaSample(); //we are full!
702 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
707 ms_pos=ms->GetActualDataLength();
708 ms_length=ms->GetSize();
709 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
711 ms->GetPointer(&ms_buf);
714 if (ms_pos==0) {//will only be changed on first packet
715 if (packet.disconti) {
716 ms->SetDiscontinuity(TRUE);
718 ms->SetDiscontinuity(FALSE);
720 if (packet.synched) {
721 ms->SetSyncPoint(TRUE);
722 ms->SetTime(&reftime1,&reftime2);
723 //ms->SetTime(NULL,NULL);
724 ms->SetMediaTime(NULL, NULL);
725 if (reftime1<0) ms->SetPreroll(TRUE);
726 else ms->SetPreroll(FALSE);
727 /*Timecode handling*/
728 lastreftimeRT=reftime1;
729 lastreftimePTS=packet.pts;
732 ms->SetSyncPoint(FALSE);
733 ms->SetTime(NULL,NULL);
734 ms->SetMediaTime(NULL, NULL);
735 ms->SetPreroll(FALSE);
737 // ms->SetSyncPoint(TRUE);
742 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
743 ms->SetActualDataLength(haveToCopy+ms_pos);
745 *samplepos+=haveToCopy;
747 return haveToCopy+headerstrip;
751 *samplepos+=packet.length;
752 MILLISLEEP(0); //yet not implemented//bad idea
753 return packet.length;
757 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
759 //WaitForSingleObject(filtermutex,INFINITE);
761 // ReleaseMutex(filtermutex);
764 if (cur_audio_media_sample) {
765 *ms=cur_audio_media_sample;//already open
768 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
769 // ReleaseMutex(filtermutex);
771 if (*ms) (*ms)->SetActualDataLength(0);
772 cur_audio_media_sample=*ms;
773 //Don't release the mutex before deliver
777 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
779 //WaitForSingleObject(filtermutex,INFINITE);
781 // ReleaseMutex(filtermutex);
784 if (cur_video_media_sample) {
785 *ms=cur_video_media_sample;//already open
788 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
789 // ReleaseMutex(filtermutex);
791 if (*ms) (*ms)->SetActualDataLength(0);
793 cur_video_media_sample=*ms;
794 //Don't release the mutex before deliver
798 int VideoWin::DeliverAudioMediaSample(){
799 if (cur_audio_media_sample) {
800 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
801 cur_audio_media_sample=NULL;
803 //ReleaseMutex(filtermutex);
807 int VideoWin::DeliverVideoMediaSample(){
808 if (cur_video_media_sample) {
809 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
810 cur_video_media_sample=NULL;
812 //ReleaseMutex(filtermutex);
816 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
820 startoffset=curreftime;//offset is set for audio
822 offsetvideonotset=false;
826 if (offsetvideonotset) {
827 offsetvideonotset=false;
830 if ( (curreftime-lastrefvideotime)>10000000LL
831 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
832 startoffset+=curreftime-lastrefvideotime;
833 lastrefaudiotime+=curreftime-lastrefvideotime;
835 offsetaudionotset=true;
842 lastrefvideotime=curreftime;
848 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
852 startoffset=curreftime;
854 offsetaudionotset=false;
856 if (offsetaudionotset) {
857 offsetaudionotset=false;
860 if ( (curreftime-lastrefaudiotime)>10000000LL
861 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
862 startoffset+=curreftime-lastrefaudiotime;
863 lastrefvideotime+=curreftime-lastrefaudiotime;
865 offsetvideonotset=true;
871 lastrefaudiotime=curreftime;
875 void VideoWin::ResetTimeOffsets() {
876 offsetnotset=true; //called from demuxer
877 offsetvideonotset=true;
878 offsetaudionotset=true;
888 void VideoWin::SetAudioVolume(long volume)
890 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
893 void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
895 if (!iframemode) EnterIframePlayback();
897 if (!isdsinited()) return ;
899 IMediaSample* ms=NULL;
900 REFERENCE_TIME reftime1=0;
901 REFERENCE_TIME reftime2=0;
902 if (!videoon) return;
904 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
910 ms->GetPointer(&ms_buf);
911 ms_length=ms->GetSize();
913 /*First Check, if we have an video sample*/
914 DWORD read_pos = 0, write_pos = 0;
915 DWORD pattern, packet_length;
918 if (length < 4) return ;
919 //Now we strip the pes header
920 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
921 while (read_pos + 7 <= length)
923 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
924 if (pattern < 0x000001E0 || pattern > 0x000001EF)
928 headerstrip=buffer[read_pos+8]+9/*is this right*/;
929 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
930 if (read_pos + packet_length > length)
934 if ((write_pos+packet_length-headerstrip)>ms_length) {
936 ms->SetSyncPoint(TRUE);
937 ms->SetDiscontinuity(TRUE);
939 } else ms->SetSyncPoint(FALSE);
940 ms->SetTime(NULL,NULL);
941 ms->SetMediaTime(NULL, NULL);
942 ms->SetActualDataLength(write_pos);
943 DeliverVideoMediaSample();
945 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
950 ms_length=ms->GetSize();
951 ms->GetPointer(&ms_buf);
953 if (packet_length-headerstrip>0) {
954 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
955 write_pos += packet_length-headerstrip;
957 read_pos += packet_length;
959 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
960 | (buffer[read_pos+2]);
965 if (first) {ms->SetSyncPoint(TRUE);first=false;}
966 else ms->SetSyncPoint(FALSE);
967 ms->SetTime(NULL,NULL);
968 ms->SetMediaTime(NULL, NULL);
969 ms->SetActualDataLength(write_pos);
970 DeliverVideoMediaSample();
974 // *samplepos+=packet.length;
975 MILLISLEEP(0); //yet not implemented//bad idea
980 bool VideoWin::supportsAc3(){
981 if (sourcefilter != NULL) {
982 return sourcefilter->supportsAc3();
988 bool VideoWin::changeAType(int type,IMediaSample* ms){
989 if (sourcefilter!= NULL) {
991 return sourcefilter->changeAType(type,ms);
1000 int VideoWin::test()
1005 int VideoWin::test2()