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;
65 iframemode=false;//We are not in Iframe mode at begining
74 CloseHandle(filtermutex);
81 int VideoWin::init(UCHAR tformat)
83 if (initted) return 0;
86 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
90 if (!setFormat(tformat)){ shutdown(); return 0; }
94 int VideoWin::setTVsize(UCHAR ttvsize)
100 int VideoWin::setDefaultAspect()
102 return setAspectRatio(Video::ASPECT4X3);
105 int VideoWin::shutdown()
107 if (!initted) return 0;
112 int VideoWin::setFormat(UCHAR tformat)
114 if (!initted) return 0;
115 if ((tformat != PAL) && (tformat != NTSC)) return 0;
131 int VideoWin::setConnection(UCHAR tconnection)
133 if (!initted) return 0;
134 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
135 connection = tconnection;
140 int VideoWin::setAspectRatio(UCHAR taspectRatio)
142 if (!initted) return 0;
143 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
144 aspectRatio = taspectRatio;
149 int VideoWin::setMode(UCHAR tmode)
151 if (!initted) return 0;
153 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
155 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
156 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
165 int VideoWin::signalOff()
170 int VideoWin::signalOn()
175 int VideoWin::setSource()
177 if (!initted) return 0;
182 int VideoWin::setPosition(int x, int y)
184 if (!initted) return 0;
185 if (mode==QUARTER || mode==EIGHTH) {
194 if (!initted) return 0;
199 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
200 #include "dshelper.h"
207 if (!initted) return 0;
211 int VideoWin::dsplay()
213 if (!initted) return 0;
218 //So this is the real code, this prevents the feeder from calling noexisting objects!
219 WaitForSingleObject(filtermutex,INFINITE);
220 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
221 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
222 ReleaseMutex(filtermutex);
226 AddToRot(dsgraphbuilder,&graphidentifier);
228 //This is just a try to see if building the graph works
229 // dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
232 lastaudiomode=MPTYPE_MPEG_AUDIO;
233 //lastaudiomode=MPTYPE_AC3;
234 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
236 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
237 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
238 ReleaseMutex(filtermutex);
243 if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*/)!=S_OK) {
244 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
245 ReleaseMutex(filtermutex);
252 //We alloc the vmr9 as next step
253 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
254 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
255 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
256 ReleaseMutex(filtermutex);
261 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
262 ReleaseMutex(filtermutex);
264 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
268 IVMRFilterConfig9* vmrfilconfig;
269 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
270 ReleaseMutex(filtermutex);
272 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
275 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
276 vmrfilconfig->Release();
278 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
279 ReleaseMutex(filtermutex);
281 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
285 allocatorvmr=new DsAllocator();
286 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
287 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
293 IFilterGraph2*fg2=NULL;
294 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
295 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
296 ReleaseMutex(filtermutex);
300 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
301 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
302 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
304 ReleaseMutex(filtermutex);
311 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
312 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
316 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
317 HRESULT hresdeb=dsmediafilter->SetSyncSource(dsrefclock);
319 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
320 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
321 if (dsbasicaudio) dsbasicaudio->put_Volume(audiovolume);
325 hresdeb=dsmediacontrol->Run();
326 iframemode=false;//exit iframe mode
327 ReleaseMutex(filtermutex);
331 int VideoWin::EnterIframePlayback()
333 if (!initted) return 0;
335 //So this is the real code, this prevents the feeder from calling noexisting objects!
336 WaitForSingleObject(filtermutex,INFINITE);
337 iframemode=true;//enter iframe mode
340 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
341 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
342 ReleaseMutex(filtermutex);
346 AddToRot(dsgraphbuilder,&graphidentifier);
349 //firstsynched=false;
350 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
352 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
353 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
354 ReleaseMutex(filtermutex);
360 //We alloc the vmr9 as next step
361 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
362 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
363 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
364 ReleaseMutex(filtermutex);
369 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
370 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
371 ReleaseMutex(filtermutex);
375 IVMRFilterConfig9* vmrfilconfig;
376 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
377 ReleaseMutex(filtermutex);
379 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
383 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
384 vmrfilconfig->Release();
386 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
387 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
388 ReleaseMutex(filtermutex);
392 allocatorvmr=new DsAllocator();
393 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
394 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
397 IFilterGraph2*fg2=NULL;
398 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
399 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
400 ReleaseMutex(filtermutex);
404 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
405 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
406 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
408 ReleaseMutex(filtermutex);
415 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
416 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
420 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
421 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
423 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
424 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
428 dsmediacontrol->Run();
429 ReleaseMutex(filtermutex);
434 int VideoWin::dsstop()
436 if (!initted) return 0;
446 if (!initted) return 0;
452 int VideoWin::reset()
454 if (!initted) return 0;
460 int VideoWin::dsreset()
462 if (!initted) return 0;
465 iframemode=false;//exit iframe mode
471 int VideoWin::dspause()
473 if (!initted) return 0;
474 WaitForSingleObject(filtermutex,INFINITE);
475 if (dsmediacontrol) dsmediacontrol->Pause();
476 ReleaseMutex(filtermutex);
480 int VideoWin::pause()
482 if (!initted) return 0;
487 int VideoWin::unPause() // FIXME get rid - same as play!!
488 {//No on windows this is not the same, I don't get rid of!
489 if (!initted) return 0;
493 int VideoWin::dsunPause() // FIXME get rid - same as play!!
494 {//No on windows this is not the same, I don't get rid of!
495 if (!initted) return 0;
496 WaitForSingleObject(filtermutex,INFINITE);
497 if (dsmediacontrol) dsmediacontrol->Run();
498 ReleaseMutex(filtermutex);
503 int VideoWin::fastForward()
505 if (!initted) return 0;
510 int VideoWin::unFastForward()
512 if (!initted) return 0;
517 int VideoWin::attachFrameBuffer()
519 if (!initted) return 0;
523 int VideoWin::blank(void)
525 ((OsdWin*)Osd::getInstance())->Blank();
529 ULLONG VideoWin::getCurrentTimestamp()
531 REFERENCE_TIME startoffset;
532 REFERENCE_TIME ncr_time;
533 if (iframemode) return 0; //Not in iframe mode!
534 if (!dsrefclock || !sourcefilter) return 0;
536 sourcefilter->GetState(10,&state);
538 if (state==State_Running) dsrefclock->GetTime(&cr_time);
540 startoffset=sourcefilter->getStartOffset();
541 ncr_time-=startoffset;
542 ncr_time-=lastreftimeRT;
543 /* ULLONG result=frameNumberToTimecode(
544 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
545 ULLONG result=lastreftimePTS;
546 result+=(ULLONG)(ncr_time/10000LL*90LL);
551 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
553 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
554 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
557 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
559 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
560 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
563 void VideoWin::CleanupDS()
565 WaitForSingleObject(filtermutex,INFINITE);
567 if (dsmediacontrol)dsmediacontrol->Stop();
568 if (cur_audio_media_sample) {
569 cur_audio_media_sample->Release();
570 cur_audio_media_sample=NULL;
572 if (cur_video_media_sample) {
573 cur_video_media_sample->Release();
574 cur_video_media_sample=NULL;
577 dsbasicaudio->Release();
580 if (dsvmrsurfnotify) {
581 dsvmrsurfnotify->Release();
582 dsvmrsurfnotify=NULL;
585 dsvmrrenderer->Release();
590 allocatorvmr->Release();
595 dsrefclock->Release();
599 dsmediafilter->Release();
605 if (dsmediacontrol) {
606 dsmediacontrol->Stop();
607 dsmediacontrol->Release();
612 RemoveFromRot(graphidentifier);
614 dsgraphbuilder->Release();
617 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
619 ReleaseMutex(filtermutex);
623 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
626 mediapacket = mplist.front();
629 UINT VideoWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)
631 DeliverMediaPacket(mediapacket, buffer, samplepos);
632 if (*samplepos == mediapacket.length) {
639 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
643 /*First Check, if we have an audio sample*/
644 if (!isdsinited()) return 0;
647 *samplepos+=packet.length;
648 MILLISLEEP(0); //yet not implemented//bad idea
649 return packet.length;
651 /*First Check, if we have an audio sample*/
655 return 0; //Not in iframe mode!
657 IMediaSample* ms=NULL;
658 REFERENCE_TIME reftime1=0;
659 REFERENCE_TIME reftime2=0;
662 if (packet.disconti) {
664 DeliverVideoMediaSample();
667 /*Inspect PES-Header */
669 if (*samplepos==0) {//stripheader
670 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
671 *samplepos+=headerstrip;
672 if ( packet.synched ) {
673 DeliverVideoMediaSample();//write out old data
674 /* if (packet.presentation_time<0) { //Preroll?
675 *samplepos=packet.length;//if we have not processed at least one
676 return packet.length;//synched packet ignore it!
679 reftime1=packet.presentation_time;
683 if (!firstsynched) {//
684 *samplepos=packet.length;//if we have not processed at least one
685 return packet.length;//synched packet ignore it!
694 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
699 ms_pos=ms->GetActualDataLength();
700 ms_length=ms->GetSize();
701 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
702 if ((ms_length-ms_pos)<1) {
703 DeliverVideoMediaSample(); //we are full!
704 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
709 ms_pos=ms->GetActualDataLength();
710 ms_length=ms->GetSize();
711 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
713 ms->GetPointer(&ms_buf);
716 if (ms_pos==0) {//will only be changed on first packet
717 if (packet.disconti) {
718 ms->SetDiscontinuity(TRUE);
720 ms->SetDiscontinuity(FALSE);
722 if (packet.synched) {
723 ms->SetSyncPoint(TRUE);
724 ms->SetTime(&reftime1,&reftime2);
725 //ms->SetTime(NULL,NULL);
726 ms->SetMediaTime(NULL, NULL);
727 if (reftime1<0) ms->SetPreroll(TRUE);
728 else ms->SetPreroll(FALSE);
729 /*Timecode handling*/
730 lastreftimeRT=reftime1;
731 lastreftimePTS=packet.pts;
734 ms->SetSyncPoint(FALSE);
735 ms->SetTime(NULL,NULL);
736 ms->SetMediaTime(NULL, NULL);
737 ms->SetPreroll(FALSE);
739 // ms->SetSyncPoint(TRUE);
744 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
745 ms->SetActualDataLength(haveToCopy+ms_pos);
747 *samplepos+=haveToCopy;
749 return haveToCopy+headerstrip;
753 *samplepos+=packet.length;
754 MILLISLEEP(0); //yet not implemented//bad idea
755 return packet.length;
759 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
761 //WaitForSingleObject(filtermutex,INFINITE);
763 // ReleaseMutex(filtermutex);
766 if (cur_audio_media_sample) {
767 *ms=cur_audio_media_sample;//already open
770 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
771 // ReleaseMutex(filtermutex);
773 if (*ms) (*ms)->SetActualDataLength(0);
774 cur_audio_media_sample=*ms;
775 //Don't release the mutex before deliver
779 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
781 //WaitForSingleObject(filtermutex,INFINITE);
783 // ReleaseMutex(filtermutex);
786 if (cur_video_media_sample) {
787 *ms=cur_video_media_sample;//already open
790 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
791 // ReleaseMutex(filtermutex);
793 if (*ms) (*ms)->SetActualDataLength(0);
795 cur_video_media_sample=*ms;
796 //Don't release the mutex before deliver
800 int VideoWin::DeliverAudioMediaSample(){
801 if (cur_audio_media_sample) {
802 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
803 cur_audio_media_sample=NULL;
805 //ReleaseMutex(filtermutex);
809 int VideoWin::DeliverVideoMediaSample(){
810 if (cur_video_media_sample) {
811 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
812 cur_video_media_sample=NULL;
814 //ReleaseMutex(filtermutex);
818 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
822 startoffset=curreftime;//offset is set for audio
824 offsetvideonotset=false;
828 if (offsetvideonotset) {
829 offsetvideonotset=false;
832 if ( (curreftime-lastrefvideotime)>10000000LL
833 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
834 startoffset+=curreftime-lastrefvideotime;
835 lastrefaudiotime+=curreftime-lastrefvideotime;
837 offsetaudionotset=true;
844 lastrefvideotime=curreftime;
850 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
854 startoffset=curreftime;
856 offsetaudionotset=false;
858 if (offsetaudionotset) {
859 offsetaudionotset=false;
862 if ( (curreftime-lastrefaudiotime)>10000000LL
863 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
864 startoffset+=curreftime-lastrefaudiotime;
865 lastrefvideotime+=curreftime-lastrefaudiotime;
867 offsetvideonotset=true;
873 lastrefaudiotime=curreftime;
877 void VideoWin::ResetTimeOffsets() {
878 offsetnotset=true; //called from demuxer
879 offsetvideonotset=true;
880 offsetaudionotset=true;
890 void VideoWin::SetAudioVolume(long volume)
893 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
896 void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
898 if (!iframemode) EnterIframePlayback();
900 if (!isdsinited()) return ;
902 IMediaSample* ms=NULL;
903 REFERENCE_TIME reftime1=0;
904 REFERENCE_TIME reftime2=0;
905 if (!videoon) return;
907 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
913 ms->GetPointer(&ms_buf);
914 ms_length=ms->GetSize();
916 /*First Check, if we have an video sample*/
917 DWORD read_pos = 0, write_pos = 0;
918 DWORD pattern, packet_length;
921 if (length < 4) return ;
922 //Now we strip the pes header
923 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
924 while (read_pos + 7 <= length)
926 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
927 if (pattern < 0x000001E0 || pattern > 0x000001EF)
931 headerstrip=buffer[read_pos+8]+9/*is this right*/;
932 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
933 if (read_pos + packet_length > length)
937 if ((write_pos+packet_length-headerstrip)>ms_length) {
939 ms->SetSyncPoint(TRUE);
940 ms->SetDiscontinuity(TRUE);
942 } else ms->SetSyncPoint(FALSE);
943 ms->SetTime(NULL,NULL);
944 ms->SetMediaTime(NULL, NULL);
945 ms->SetActualDataLength(write_pos);
946 DeliverVideoMediaSample();
948 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
953 ms_length=ms->GetSize();
954 ms->GetPointer(&ms_buf);
956 if (packet_length-headerstrip>0) {
957 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
958 write_pos += packet_length-headerstrip;
960 read_pos += packet_length;
962 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
963 | (buffer[read_pos+2]);
968 if (first) {ms->SetSyncPoint(TRUE);first=false;}
969 else ms->SetSyncPoint(FALSE);
970 ms->SetTime(NULL,NULL);
971 ms->SetMediaTime(NULL, NULL);
972 ms->SetActualDataLength(write_pos);
973 DeliverVideoMediaSample();
977 // *samplepos+=packet.length;
978 MILLISLEEP(0); //yet not implemented//bad idea
983 bool VideoWin::supportsAc3(){
984 if (sourcefilter != NULL) {
985 return sourcefilter->supportsAc3();
991 bool VideoWin::changeAType(int type,IMediaSample* ms){
992 if (sourcefilter!= NULL) {
994 return sourcefilter->changeAType(type,ms);
1003 int VideoWin::test()
1008 int VideoWin::test2()