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
66 #ifdef NEW_DS_MECHANISMENS
67 videofilterselected=-1;
77 CloseHandle(filtermutex);
78 #ifdef NEW_DS_MECHANISMENS
80 for (i=0;i<videofilterlist.size();i++)
82 if (videofilterlist[i].displayname) delete [] videofilterlist[i].displayname;
83 if (videofilterlist[i].friendlyname) delete [] videofilterlist[i].friendlyname;
85 videofilterlist.clear();
93 int VideoWin::init(UCHAR tformat)
95 if (initted) return 0;
98 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
101 #ifdef NEW_DS_MECHANISMENS
104 if (!setFormat(tformat)){ shutdown(); return 0; }
110 int VideoWin::setTVsize(UCHAR ttvsize)
112 pseudotvsize=ttvsize;
116 int VideoWin::setDefaultAspect()
118 return setAspectRatio(Video::ASPECT4X3);
121 int VideoWin::shutdown()
123 if (!initted) return 0;
128 int VideoWin::setFormat(UCHAR tformat)
130 if (!initted) return 0;
131 if ((tformat != PAL) && (tformat != NTSC)) return 0;
147 int VideoWin::setConnection(UCHAR tconnection)
149 if (!initted) return 0;
150 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
151 connection = tconnection;
156 int VideoWin::setAspectRatio(UCHAR taspectRatio)
158 if (!initted) return 0;
159 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
160 aspectRatio = taspectRatio;
165 int VideoWin::setMode(UCHAR tmode)
167 if (!initted) return 0;
169 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
171 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
172 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
181 int VideoWin::signalOff()
186 int VideoWin::signalOn()
191 int VideoWin::setSource()
193 if (!initted) return 0;
198 int VideoWin::setPosition(int x, int y)
200 if (!initted) return 0;
201 if (mode==QUARTER || mode==EIGHTH) {
210 if (!initted) return 0;
214 #ifdef NEW_DS_MECHANISMENS
215 void VideoWin::dstest()
217 /* This method should determine all availiable DirectShow Filters */
218 IFilterMapper2* filtmap=NULL;
220 result = CoCreateInstance(CLSID_FilterMapper2,NULL,CLSCTX_INPROC,
221 IID_IFilterMapper2,(void**)&filtmap);
224 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to create FilterMapper!");
227 /* Wishlist, what Mediatypes do we want */
228 GUID mtypesin[]={MEDIATYPE_Video,MEDIASUBTYPE_MPEG2_VIDEO};
229 IEnumMoniker *myenum;
230 result = filtmap->EnumMatchingFilters(&myenum,0,TRUE,MERIT_DO_NOT_USE+1,
231 TRUE,1,mtypesin,NULL,NULL,FALSE,TRUE,0,NULL,NULL,NULL);
235 Log::getInstance()->log("VideoWin", Log::ERR , "Unable to enum Filters!");
240 while(myenum->Next(1,&moni,&gethowmany)==S_OK)
242 VideoFilterDesc desc;
243 ZeroMemory(&desc,sizeof(desc));
245 /* result = CreateBindCtx(0,&bctx);
250 Log::getInstance()->log("VideoWin", Log::ERR , "Failed to create Bindctx!");
254 moni->GetDisplayName(0,0,&string);
255 desc.displayname=new char[wcslen(string)+1];
256 wcstombs(desc.displayname,string,wcslen(string)+1);
257 CoTaskMemFree(string);
259 if (moni->BindToStorage(0,0,IID_IPropertyBag,(void**)&bag) == S_OK)
263 result = bag->Read(L"FriendlyName",&vari,NULL);
266 desc.friendlyname=new char[wcslen(vari.bstrVal)+1];
267 wcstombs(desc.friendlyname,vari.bstrVal,wcslen(vari.bstrVal)+1);
274 if (moni->BindToObject(0,0,IID_IBaseFilter,(void**)&filter) == S_OK)
276 IAMDecoderCaps*desccaps;
277 if (filter->QueryInterface(IID_IAMDecoderCaps,(void**) &desccaps)==S_OK)
280 desccaps->GetDecoderCaps(AM_GETDECODERCAP_QUERY_VMR9_SUPPORT,&caps);
281 if (caps == DECODER_CAP_SUPPORTED)
289 videofilterlist.push_back(desc);
297 videofilterselected=-1;
298 for (i = 0;i <videofilterlist.size();i++)
300 if (videofilterlist[i].vmr9)
302 videofilterselected=i;
306 if (videofilterselected == -1)
308 Log::getInstance()->log("VideoWin", Log::ERR , "No video filter found!");
319 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
320 #include "dshelper.h"
327 if (!initted) return 0;
331 int VideoWin::dsInitVideoFilter()
336 //We alloc the vmr9 as next step
337 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
338 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK)
340 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
341 ReleaseMutex(filtermutex);
345 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK)
347 ReleaseMutex(filtermutex);
349 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
352 IVMRFilterConfig9* vmrfilconfig;
353 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK)
355 ReleaseMutex(filtermutex);
357 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
360 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
361 vmrfilconfig->Release();
363 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,
364 (void**)& dsvmrsurfnotify) != S_OK)
366 ReleaseMutex(filtermutex);
368 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
371 allocatorvmr=new DsAllocator();
372 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
373 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
375 IFilterGraph2*fg2=NULL;
376 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!= S_OK)
378 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
379 ReleaseMutex(filtermutex);
383 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
384 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL) != S_OK)
386 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
388 ReleaseMutex(filtermutex);
397 int VideoWin::dsplay()
399 if (!initted) return 0;
404 //So this is the real code, this prevents the feeder from calling noexisting objects!
405 WaitForSingleObject(filtermutex,INFINITE);
406 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
407 IID_IGraphBuilder,(void**)&dsgraphbuilder) != S_OK)
409 ReleaseMutex(filtermutex);
413 AddToRot(dsgraphbuilder,&graphidentifier);
417 lastaudiomode=MPTYPE_MPEG_AUDIO;
418 //lastaudiomode=MPTYPE_AC3;
419 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
421 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter") != S_OK)
423 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
424 ReleaseMutex(filtermutex);
429 if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*/)!=S_OK)
431 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
432 ReleaseMutex(filtermutex);
436 if (dsInitVideoFilter()==0)
441 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
442 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK)
446 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
447 HRESULT hresdeb = dsmediafilter->SetSyncSource(dsrefclock);
449 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
450 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
452 dsbasicaudio->put_Volume(audiovolume);
456 hresdeb=dsmediacontrol->Run();
457 iframemode=false;//exit iframe mode
458 ReleaseMutex(filtermutex);
462 int VideoWin::EnterIframePlayback()
464 if (!initted) return 0;
466 //So this is the real code, this prevents the feeder from calling noexisting objects!
467 WaitForSingleObject(filtermutex,INFINITE);
468 iframemode=true;//enter iframe mode
471 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
472 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
473 ReleaseMutex(filtermutex);
477 AddToRot(dsgraphbuilder,&graphidentifier);
480 //firstsynched=false;
481 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
483 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
484 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
485 ReleaseMutex(filtermutex);
491 //We alloc the vmr9 as next step
492 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
493 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
494 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
495 ReleaseMutex(filtermutex);
500 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
501 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
502 ReleaseMutex(filtermutex);
506 IVMRFilterConfig9* vmrfilconfig;
507 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
508 ReleaseMutex(filtermutex);
510 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
514 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
515 vmrfilconfig->Release();
517 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
518 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
519 ReleaseMutex(filtermutex);
523 allocatorvmr=new DsAllocator();
524 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
525 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
528 IFilterGraph2*fg2=NULL;
529 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
530 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
531 ReleaseMutex(filtermutex);
535 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
536 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
537 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
539 ReleaseMutex(filtermutex);
546 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
547 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
551 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
552 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
554 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
555 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
559 dsmediacontrol->Run();
560 ReleaseMutex(filtermutex);
565 int VideoWin::dsstop()
567 if (!initted) return 0;
577 if (!initted) return 0;
583 int VideoWin::reset()
585 if (!initted) return 0;
591 int VideoWin::dsreset()
593 if (!initted) return 0;
596 iframemode=false;//exit iframe mode
602 int VideoWin::dspause()
604 if (!initted) return 0;
605 WaitForSingleObject(filtermutex,INFINITE);
606 if (dsmediacontrol) dsmediacontrol->Pause();
607 ReleaseMutex(filtermutex);
611 int VideoWin::pause()
613 if (!initted) return 0;
618 int VideoWin::unPause() // FIXME get rid - same as play!!
619 {//No on windows this is not the same, I don't get rid of!
620 if (!initted) return 0;
624 int VideoWin::dsunPause() // FIXME get rid - same as play!!
625 {//No on windows this is not the same, I don't get rid of!
626 if (!initted) return 0;
627 WaitForSingleObject(filtermutex,INFINITE);
628 if (dsmediacontrol) dsmediacontrol->Run();
629 ReleaseMutex(filtermutex);
634 int VideoWin::fastForward()
636 if (!initted) return 0;
641 int VideoWin::unFastForward()
643 if (!initted) return 0;
648 int VideoWin::attachFrameBuffer()
650 if (!initted) return 0;
654 int VideoWin::blank(void)
656 ((OsdWin*)Osd::getInstance())->Blank();
660 ULLONG VideoWin::getCurrentTimestamp()
662 REFERENCE_TIME startoffset;
663 REFERENCE_TIME ncr_time;
664 if (iframemode) return 0; //Not in iframe mode!
665 if (!dsrefclock || !sourcefilter) return 0;
667 sourcefilter->GetState(10,&state);
669 if (state==State_Running) dsrefclock->GetTime(&cr_time);
671 startoffset=sourcefilter->getStartOffset();
672 ncr_time-=startoffset;
673 ncr_time-=lastreftimeRT;
674 /* ULLONG result=frameNumberToTimecode(
675 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
676 ULLONG result=lastreftimePTS;
677 result+=(ULLONG)(ncr_time/10000LL*90LL);
682 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
684 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
685 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
688 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
690 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
691 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
694 void VideoWin::CleanupDS()
696 WaitForSingleObject(filtermutex,INFINITE);
698 if (dsmediacontrol)dsmediacontrol->Stop();
699 if (cur_audio_media_sample) {
700 cur_audio_media_sample->Release();
701 cur_audio_media_sample=NULL;
703 if (cur_video_media_sample) {
704 cur_video_media_sample->Release();
705 cur_video_media_sample=NULL;
708 dsbasicaudio->Release();
711 if (dsvmrsurfnotify) {
712 dsvmrsurfnotify->Release();
713 dsvmrsurfnotify=NULL;
716 dsvmrrenderer->Release();
721 allocatorvmr->Release();
726 dsrefclock->Release();
730 dsmediafilter->Release();
736 if (dsmediacontrol) {
737 dsmediacontrol->Stop();
738 dsmediacontrol->Release();
743 RemoveFromRot(graphidentifier);
745 dsgraphbuilder->Release();
748 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
750 ReleaseMutex(filtermutex);
754 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
757 mediapacket = mplist.front();
760 UINT VideoWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)
762 DeliverMediaPacket(mediapacket, buffer, samplepos);
763 if (*samplepos == mediapacket.length) {
770 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
774 /*First Check, if we have an audio sample*/
775 if (!isdsinited()) return 0;
778 *samplepos+=packet.length;
779 MILLISLEEP(0); //yet not implemented//bad idea
780 return packet.length;
782 /*First Check, if we have an audio sample*/
786 return 0; //Not in iframe mode!
788 IMediaSample* ms=NULL;
789 REFERENCE_TIME reftime1=0;
790 REFERENCE_TIME reftime2=0;
793 if (packet.disconti) {
795 DeliverVideoMediaSample();
798 /*Inspect PES-Header */
800 if (*samplepos==0) {//stripheader
801 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
802 *samplepos+=headerstrip;
803 if ( packet.synched ) {
804 DeliverVideoMediaSample();//write out old data
805 /* if (packet.presentation_time<0) { //Preroll?
806 *samplepos=packet.length;//if we have not processed at least one
807 return packet.length;//synched packet ignore it!
810 reftime1=packet.presentation_time;
814 if (!firstsynched) {//
815 *samplepos=packet.length;//if we have not processed at least one
816 return packet.length;//synched packet ignore it!
825 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
830 ms_pos=ms->GetActualDataLength();
831 ms_length=ms->GetSize();
832 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
833 if ((ms_length-ms_pos)<1) {
834 DeliverVideoMediaSample(); //we are full!
835 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
840 ms_pos=ms->GetActualDataLength();
841 ms_length=ms->GetSize();
842 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
844 ms->GetPointer(&ms_buf);
847 if (ms_pos==0) {//will only be changed on first packet
848 if (packet.disconti) {
849 ms->SetDiscontinuity(TRUE);
851 ms->SetDiscontinuity(FALSE);
853 if (packet.synched) {
854 ms->SetSyncPoint(TRUE);
855 ms->SetTime(&reftime1,&reftime2);
856 //ms->SetTime(NULL,NULL);
857 ms->SetMediaTime(NULL, NULL);
858 if (reftime1<0) ms->SetPreroll(TRUE);
859 else ms->SetPreroll(FALSE);
860 /*Timecode handling*/
861 lastreftimeRT=reftime1;
862 lastreftimePTS=packet.pts;
865 ms->SetSyncPoint(FALSE);
866 ms->SetTime(NULL,NULL);
867 ms->SetMediaTime(NULL, NULL);
868 ms->SetPreroll(FALSE);
870 // ms->SetSyncPoint(TRUE);
875 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
876 ms->SetActualDataLength(haveToCopy+ms_pos);
878 *samplepos+=haveToCopy;
880 return haveToCopy+headerstrip;
884 *samplepos+=packet.length;
885 MILLISLEEP(0); //yet not implemented//bad idea
886 return packet.length;
890 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
892 //WaitForSingleObject(filtermutex,INFINITE);
894 // ReleaseMutex(filtermutex);
897 if (cur_audio_media_sample) {
898 *ms=cur_audio_media_sample;//already open
901 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
902 // ReleaseMutex(filtermutex);
904 if (*ms) (*ms)->SetActualDataLength(0);
905 cur_audio_media_sample=*ms;
906 //Don't release the mutex before deliver
910 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
912 //WaitForSingleObject(filtermutex,INFINITE);
914 // ReleaseMutex(filtermutex);
917 if (cur_video_media_sample) {
918 *ms=cur_video_media_sample;//already open
921 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
922 // ReleaseMutex(filtermutex);
924 if (*ms) (*ms)->SetActualDataLength(0);
926 cur_video_media_sample=*ms;
927 //Don't release the mutex before deliver
931 int VideoWin::DeliverAudioMediaSample(){
932 if (cur_audio_media_sample) {
933 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
934 cur_audio_media_sample=NULL;
936 //ReleaseMutex(filtermutex);
940 int VideoWin::DeliverVideoMediaSample(){
941 if (cur_video_media_sample) {
942 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
943 cur_video_media_sample=NULL;
945 //ReleaseMutex(filtermutex);
949 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
953 startoffset=curreftime;//offset is set for audio
955 offsetvideonotset=false;
959 if (offsetvideonotset) {
960 offsetvideonotset=false;
963 if ( (curreftime-lastrefvideotime)>10000000LL
964 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
965 startoffset+=curreftime-lastrefvideotime;
966 lastrefaudiotime+=curreftime-lastrefvideotime;
968 offsetaudionotset=true;
975 lastrefvideotime=curreftime;
981 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
985 startoffset=curreftime;
987 offsetaudionotset=false;
989 if (offsetaudionotset) {
990 offsetaudionotset=false;
993 if ( (curreftime-lastrefaudiotime)>10000000LL
994 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
995 startoffset+=curreftime-lastrefaudiotime;
996 lastrefvideotime+=curreftime-lastrefaudiotime;
998 offsetvideonotset=true;
1004 lastrefaudiotime=curreftime;
1008 void VideoWin::ResetTimeOffsets() {
1009 offsetnotset=true; //called from demuxer
1010 offsetvideonotset=true;
1011 offsetaudionotset=true;
1021 void VideoWin::SetAudioVolume(long volume)
1024 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
1027 void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
1029 if (!iframemode) EnterIframePlayback();
1031 if (!isdsinited()) return ;
1033 IMediaSample* ms=NULL;
1034 REFERENCE_TIME reftime1=0;
1035 REFERENCE_TIME reftime2=0;
1036 if (!videoon) return;
1038 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1044 ms->GetPointer(&ms_buf);
1045 ms_length=ms->GetSize();
1047 /*First Check, if we have an video sample*/
1048 DWORD read_pos = 0, write_pos = 0;
1049 DWORD pattern, packet_length;
1050 DWORD headerstrip=0;
1052 if (length < 4) return ;
1053 //Now we strip the pes header
1054 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1055 while (read_pos + 7 <= length)
1057 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
1058 if (pattern < 0x000001E0 || pattern > 0x000001EF)
1062 headerstrip=buffer[read_pos+8]+9/*is this right*/;
1063 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
1064 if (read_pos + packet_length > length)
1068 if ((write_pos+packet_length-headerstrip)>ms_length) {
1070 ms->SetSyncPoint(TRUE);
1071 ms->SetDiscontinuity(TRUE);
1073 } else ms->SetSyncPoint(FALSE);
1074 ms->SetTime(NULL,NULL);
1075 ms->SetMediaTime(NULL, NULL);
1076 ms->SetActualDataLength(write_pos);
1077 DeliverVideoMediaSample();
1079 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
1084 ms_length=ms->GetSize();
1085 ms->GetPointer(&ms_buf);
1087 if (packet_length-headerstrip>0) {
1088 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
1089 write_pos += packet_length-headerstrip;
1091 read_pos += packet_length;
1093 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
1094 | (buffer[read_pos+2]);
1099 if (first) {ms->SetSyncPoint(TRUE);first=false;}
1100 else ms->SetSyncPoint(FALSE);
1101 ms->SetTime(NULL,NULL);
1102 ms->SetMediaTime(NULL, NULL);
1103 ms->SetActualDataLength(write_pos);
1104 DeliverVideoMediaSample();
1108 // *samplepos+=packet.length;
1109 MILLISLEEP(0); //yet not implemented//bad idea
1114 bool VideoWin::supportsAc3(){
1115 if (sourcefilter != NULL) {
1116 return sourcefilter->supportsAc3();
1122 bool VideoWin::changeAType(int type,IMediaSample* ms){
1123 if (sourcefilter!= NULL) {
1125 return sourcefilter->changeAType(type,ms);
1134 int VideoWin::test()
1139 int VideoWin::test2()