2 Copyright 2004-2005 Chris Tallon
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
21 #include "videowin.h"
\r
23 #include "dssourcefilter.h"
\r
24 #include "dsallocator.h"
\r
28 void AdjustWindow();
\r
32 VideoWin::VideoWin()
\r
34 dsgraphbuilder=NULL;
\r
35 dsmediacontrol=NULL;
\r
43 dsvmrsurfnotify=NULL;
\r
44 filtermutex=CreateMutex(NULL,FALSE,NULL);
\r
46 offsetvideonotset=true;
\r
47 offsetaudionotset=true;
\r
54 cur_audio_media_sample=NULL;
\r
55 cur_video_media_sample=NULL;
\r
61 iframemode=false;//We are not in Iframe mode at begining
\r
67 VideoWin::~VideoWin()
\r
70 CloseHandle(filtermutex);
\r
77 int VideoWin::init(UCHAR tformat)
\r
79 if (initted) return 0;
\r
82 tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV
\r
86 if (!setFormat(tformat)){ shutdown(); return 0; }
\r
90 int VideoWin::setTVsize(UCHAR ttvsize)
\r
92 pseudotvsize=ttvsize;
\r
96 int VideoWin::setDefaultAspect()
\r
98 return setAspectRatio(Video::ASPECT4X3);
\r
101 int VideoWin::shutdown()
\r
103 if (!initted) return 0;
\r
108 int VideoWin::setFormat(UCHAR tformat)
\r
110 if (!initted) return 0;
\r
111 if ((tformat != PAL) && (tformat != NTSC)) return 0;
\r
113 if (format == NTSC)
\r
116 screenHeight = 480;
\r
121 screenHeight = 576;
\r
127 int VideoWin::setConnection(UCHAR tconnection)
\r
129 if (!initted) return 0;
\r
130 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
\r
131 connection = tconnection;
\r
136 int VideoWin::setAspectRatio(UCHAR taspectRatio)
\r
138 if (!initted) return 0;
\r
139 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
\r
140 aspectRatio = taspectRatio;
\r
145 int VideoWin::setMode(UCHAR tmode)
\r
147 if (!initted) return 0;
\r
149 //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
\r
151 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
\r
152 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
\r
161 int VideoWin::signalOff()
\r
166 int VideoWin::signalOn()
\r
171 int VideoWin::setSource()
\r
173 if (!initted) return 0;
\r
178 int VideoWin::setPosition(int x, int y)
\r
180 if (!initted) return 0;
\r
181 if (mode==QUARTER || mode==EIGHTH) {
\r
188 int VideoWin::sync()
\r
190 if (!initted) return 0;
\r
195 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
\r
196 #include "dshelper.h"
\r
201 int VideoWin::play()
\r
203 if (!initted) return 0;
\r
207 int VideoWin::dsplay()
\r
209 if (!initted) return 0;
\r
212 //Build filter graph
\r
214 //So this is the real code, this prevents the feeder from calling noexisting objects!
\r
215 WaitForSingleObject(filtermutex,INFINITE);
\r
216 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
\r
217 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
\r
218 ReleaseMutex(filtermutex);
\r
222 AddToRot(dsgraphbuilder,&graphidentifier);
\r
224 //This is just a try to see if building the graph works
\r
225 // dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
\r
227 firstsynched=false;
\r
228 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
\r
230 sourcefilter->AddRef();
\r
231 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
\r
232 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
\r
233 ReleaseMutex(filtermutex);
\r
238 if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*/)!=S_OK) {
\r
239 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
\r
240 ReleaseMutex(filtermutex);
\r
247 //We alloc the vmr9 as next step
\r
248 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
\r
249 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
\r
250 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
\r
251 ReleaseMutex(filtermutex);
\r
256 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
\r
257 ReleaseMutex(filtermutex);
\r
259 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
\r
263 IVMRFilterConfig9* vmrfilconfig;
\r
264 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
\r
265 ReleaseMutex(filtermutex);
\r
267 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
\r
270 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
\r
271 vmrfilconfig->Release();
\r
273 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
\r
274 ReleaseMutex(filtermutex);
\r
276 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
\r
280 allocatorvmr=new DsAllocator();
\r
281 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
\r
282 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
\r
287 /*VMR 9 stuff end */
\r
288 IFilterGraph2*fg2=NULL;
\r
289 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
\r
290 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
\r
291 ReleaseMutex(filtermutex);
\r
295 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
\r
296 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
\r
297 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
\r
299 ReleaseMutex(filtermutex);
\r
306 if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
\r
307 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
\r
311 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
\r
312 HRESULT hresdeb=dsmediafilter->SetSyncSource(dsrefclock);
\r
314 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
\r
315 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
\r
317 hresdeb=dsmediacontrol->Run();
\r
318 iframemode=false;//exit iframe mode
\r
319 ReleaseMutex(filtermutex);
\r
323 int VideoWin::EnterIframePlayback()
\r
325 if (!initted) return 0;
\r
327 //So this is the real code, this prevents the feeder from calling noexisting objects!
\r
328 WaitForSingleObject(filtermutex,INFINITE);
\r
329 iframemode=true;//enter iframe mode
\r
330 //Build filter graph
\r
332 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
\r
333 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
\r
334 ReleaseMutex(filtermutex);
\r
338 AddToRot(dsgraphbuilder,&graphidentifier);
\r
341 //firstsynched=false;
\r
342 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
\r
344 sourcefilter->AddRef();
\r
345 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
\r
346 Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
\r
347 ReleaseMutex(filtermutex);
\r
353 //We alloc the vmr9 as next step
\r
354 if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
\r
355 CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
\r
356 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
\r
357 ReleaseMutex(filtermutex);
\r
362 if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
\r
363 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
\r
364 ReleaseMutex(filtermutex);
\r
368 IVMRFilterConfig9* vmrfilconfig;
\r
369 if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
\r
370 ReleaseMutex(filtermutex);
\r
372 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
\r
376 vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
\r
377 vmrfilconfig->Release();
\r
379 if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
\r
380 Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
\r
381 ReleaseMutex(filtermutex);
\r
385 allocatorvmr=new DsAllocator();
\r
386 dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
\r
387 allocatorvmr->AdviseNotify(dsvmrsurfnotify);
\r
389 /*VMR 9 stuff end */
\r
390 IFilterGraph2*fg2=NULL;
\r
391 if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
\r
392 Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
\r
393 ReleaseMutex(filtermutex);
\r
397 if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
\r
398 AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
\r
399 Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
\r
401 ReleaseMutex(filtermutex);
\r
408 /* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
\r
409 IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {
\r
413 dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);
\r
414 dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
\r
416 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
\r
417 dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
\r
419 dsmediacontrol->Run();
\r
420 ReleaseMutex(filtermutex);
\r
425 int VideoWin::dsstop()
\r
427 if (!initted) return 0;
\r
435 int VideoWin::stop()
\r
437 if (!initted) return 0;
\r
443 int VideoWin::reset()
\r
445 if (!initted) return 0;
\r
451 int VideoWin::dsreset()
\r
453 if (!initted) return 0;
\r
456 iframemode=false;//exit iframe mode
\r
462 int VideoWin::dspause()
\r
464 if (!initted) return 0;
\r
465 WaitForSingleObject(filtermutex,INFINITE);
\r
466 if (dsmediacontrol) dsmediacontrol->Pause();
\r
467 ReleaseMutex(filtermutex);
\r
471 int VideoWin::pause()
\r
473 if (!initted) return 0;
\r
478 int VideoWin::unPause() // FIXME get rid - same as play!!
\r
479 {//No on windows this is not the same, I don't get rid of!
\r
480 if (!initted) return 0;
\r
484 int VideoWin::dsunPause() // FIXME get rid - same as play!!
\r
485 {//No on windows this is not the same, I don't get rid of!
\r
486 if (!initted) return 0;
\r
487 WaitForSingleObject(filtermutex,INFINITE);
\r
488 if (dsmediacontrol) dsmediacontrol->Run();
\r
489 ReleaseMutex(filtermutex);
\r
494 int VideoWin::fastForward()
\r
496 if (!initted) return 0;
\r
501 int VideoWin::unFastForward()
\r
503 if (!initted) return 0;
\r
508 int VideoWin::attachFrameBuffer()
\r
510 if (!initted) return 0;
\r
514 int VideoWin::blank(void)
\r
516 ((OsdWin*)Osd::getInstance())->Blank();
\r
520 ULLONG VideoWin::getCurrentTimestamp()
\r
522 REFERENCE_TIME startoffset;
\r
523 REFERENCE_TIME ncr_time;
\r
524 if (iframemode) return 0; //Not in iframe mode!
\r
525 if (!dsrefclock || !sourcefilter) return 0;
\r
526 FILTER_STATE state;
\r
527 sourcefilter->GetState(10,&state);
\r
529 if (state==State_Running) dsrefclock->GetTime(&cr_time);
\r
531 startoffset=sourcefilter->getStartOffset();
\r
532 ncr_time-=startoffset;
\r
533 ncr_time-=lastreftimeRT;
\r
534 /* ULLONG result=frameNumberToTimecode(
\r
535 VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
\r
536 ULLONG result=lastreftimePTS;
\r
537 result+=(ULLONG)(ncr_time/10000LL*90LL);
\r
542 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
\r
544 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
\r
545 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
\r
548 ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)
\r
550 if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);
\r
551 else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);
\r
554 void VideoWin::CleanupDS()
\r
556 WaitForSingleObject(filtermutex,INFINITE);
\r
557 if (dsmediacontrol)dsmediacontrol->Stop();
\r
558 if (cur_audio_media_sample) {
\r
559 cur_audio_media_sample->Release();
\r
560 cur_audio_media_sample=NULL;
\r
562 if (cur_video_media_sample) {
\r
563 cur_video_media_sample->Release();
\r
564 cur_video_media_sample=NULL;
\r
566 if (dsbasicaudio) {
\r
567 dsbasicaudio->Release();
\r
570 if (dsvmrsurfnotify) {
\r
571 dsvmrsurfnotify->Release();
\r
572 dsvmrsurfnotify=NULL;
\r
574 if (dsvmrrenderer) {
\r
575 dsvmrrenderer->Release();
\r
576 dsvmrrenderer=NULL;
\r
579 if (allocatorvmr) {
\r
580 allocatorvmr->Release();
\r
585 dsrefclock->Release();
\r
588 if (dsmediafilter) {
\r
589 dsmediafilter->Release();
\r
590 dsmediafilter=NULL;
\r
595 if (dsmediacontrol) {
\r
596 dsmediacontrol->Stop();
\r
597 dsmediacontrol->Release();
\r
598 dsmediacontrol=NULL;
\r
600 if (dsgraphbuilder){
\r
602 RemoveFromRot(graphidentifier);
\r
604 dsgraphbuilder->Release();
\r
605 dsgraphbuilder=NULL;
\r
606 sourcefilter->Release();
\r
607 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
\r
609 ReleaseMutex(filtermutex);
\r
613 void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,
\r
616 mediapacket = mplist.front();
\r
619 UINT VideoWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)
\r
621 DeliverMediaPacket(mediapacket, buffer, samplepos);
\r
622 if (*samplepos == mediapacket.length) {
\r
629 UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
\r
630 const UCHAR* buffer,
\r
633 /*First Check, if we have an audio sample*/
\r
636 *samplepos+=packet.length;
\r
637 MILLISLEEP(0); //yet not implemented//bad idea
\r
638 return packet.length;
\r
640 /*First Check, if we have an audio sample*/
\r
644 return 0; //Not in iframe mode!
\r
646 IMediaSample* ms=NULL;
\r
647 REFERENCE_TIME reftime1=0;
\r
648 REFERENCE_TIME reftime2=0;
\r
650 UINT headerstrip=0;
\r
651 if (packet.disconti) {
\r
652 firstsynched=false;
\r
653 DeliverVideoMediaSample();
\r
658 /*Inspect PES-Header */
\r
660 if (*samplepos==0) {//stripheader
\r
661 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
\r
662 *samplepos+=headerstrip;
\r
663 if ( packet.synched ) {
\r
664 DeliverVideoMediaSample();//write out old data
\r
665 /* if (packet.presentation_time<0) { //Preroll?
\r
666 *samplepos=packet.length;//if we have not processed at least one
\r
667 return packet.length;//synched packet ignore it!
\r
670 reftime1=packet.presentation_time;
\r
671 reftime2=reftime1+1;
\r
674 if (!firstsynched) {//
\r
675 *samplepos=packet.length;//if we have not processed at least one
\r
676 return packet.length;//synched packet ignore it!
\r
685 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
\r
690 ms_pos=ms->GetActualDataLength();
\r
691 ms_length=ms->GetSize();
\r
692 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
\r
693 if ((ms_length-ms_pos)<1) {
\r
694 DeliverVideoMediaSample(); //we are full!
\r
695 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
\r
700 ms_pos=ms->GetActualDataLength();
\r
701 ms_length=ms->GetSize();
\r
702 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
\r
704 ms->GetPointer(&ms_buf);
\r
707 if (ms_pos==0) {//will only be changed on first packet
\r
708 if (packet.disconti) {
\r
709 ms->SetDiscontinuity(TRUE);
\r
711 ms->SetDiscontinuity(FALSE);
\r
713 if (packet.synched) {
\r
714 ms->SetSyncPoint(TRUE);
\r
715 ms->SetTime(&reftime1,&reftime2);
\r
716 //ms->SetTime(NULL,NULL);
\r
717 ms->SetMediaTime(NULL, NULL);
\r
718 if (reftime1<0) ms->SetPreroll(TRUE);
\r
719 else ms->SetPreroll(FALSE);
\r
720 /*Timecode handling*/
\r
721 lastreftimeRT=reftime1;
\r
722 lastreftimePTS=packet.pts;
\r
725 ms->SetSyncPoint(FALSE);
\r
726 ms->SetTime(NULL,NULL);
\r
727 ms->SetMediaTime(NULL, NULL);
\r
728 ms->SetPreroll(FALSE);
\r
730 // ms->SetSyncPoint(TRUE);
\r
735 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
\r
736 ms->SetActualDataLength(haveToCopy+ms_pos);
\r
738 *samplepos+=haveToCopy;
\r
740 return haveToCopy+headerstrip;
\r
744 *samplepos+=packet.length;
\r
745 MILLISLEEP(0); //yet not implemented//bad idea
\r
746 return packet.length;
\r
750 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
\r
752 //WaitForSingleObject(filtermutex,INFINITE);
\r
753 if (!sourcefilter){
\r
754 // ReleaseMutex(filtermutex);
\r
757 if (cur_audio_media_sample) {
\r
758 *ms=cur_audio_media_sample;//already open
\r
761 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
\r
762 // ReleaseMutex(filtermutex);
\r
764 if (*ms) (*ms)->SetActualDataLength(0);
\r
765 cur_audio_media_sample=*ms;
\r
766 //Don't release the mutex before deliver
\r
770 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
\r
772 //WaitForSingleObject(filtermutex,INFINITE);
\r
773 if (!sourcefilter){
\r
774 // ReleaseMutex(filtermutex);
\r
777 if (cur_video_media_sample) {
\r
778 *ms=cur_video_media_sample;//already open
\r
781 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
\r
782 // ReleaseMutex(filtermutex);
\r
784 if (*ms) (*ms)->SetActualDataLength(0);
\r
786 cur_video_media_sample=*ms;
\r
787 //Don't release the mutex before deliver
\r
791 int VideoWin::DeliverAudioMediaSample(){
\r
792 if (cur_audio_media_sample) {
\r
793 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
\r
794 cur_audio_media_sample=NULL;
\r
796 //ReleaseMutex(filtermutex);
\r
800 int VideoWin::DeliverVideoMediaSample(){
\r
801 if (cur_video_media_sample) {
\r
802 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
\r
803 cur_video_media_sample=NULL;
\r
805 //ReleaseMutex(filtermutex);
\r
809 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
\r
812 if (offsetnotset) {
\r
813 startoffset=curreftime;//offset is set for audio
\r
814 offsetnotset=false;
\r
815 offsetvideonotset=false;
\r
819 if (offsetvideonotset) {
\r
820 offsetvideonotset=false;
\r
823 if ( (curreftime-lastrefvideotime)>10000000LL
\r
824 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
\r
825 startoffset+=curreftime-lastrefvideotime;
\r
826 lastrefaudiotime+=curreftime-lastrefvideotime;
\r
828 offsetaudionotset=true;
\r
835 lastrefvideotime=curreftime;
\r
837 return startoffset;
\r
841 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
\r
844 if (offsetnotset) {
\r
845 startoffset=curreftime;
\r
846 offsetnotset=false;
\r
847 offsetaudionotset=false;
\r
849 if (offsetaudionotset) {
\r
850 offsetaudionotset=false;
\r
853 if ( (curreftime-lastrefaudiotime)>10000000LL
\r
854 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
\r
855 startoffset+=curreftime-lastrefaudiotime;
\r
856 lastrefvideotime+=curreftime-lastrefaudiotime;
\r
858 offsetvideonotset=true;
\r
864 lastrefaudiotime=curreftime;
\r
865 return startoffset;
\r
868 void VideoWin::ResetTimeOffsets() {
\r
869 offsetnotset=true; //called from demuxer
\r
870 offsetvideonotset=true;
\r
871 offsetaudionotset=true;
\r
873 lastrefaudiotime=0;
\r
874 lastrefvideotime=0;
\r
881 void VideoWin::SetAudioVolume(long volume)
\r
883 if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
\r
886 void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
\r
888 if (!iframemode) EnterIframePlayback();
\r
892 IMediaSample* ms=NULL;
\r
893 REFERENCE_TIME reftime1=0;
\r
894 REFERENCE_TIME reftime2=0;
\r
895 if (!videoon) return;
\r
897 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
\r
903 ms->GetPointer(&ms_buf);
\r
904 ms_length=ms->GetSize();
\r
906 /*First Check, if we have an video sample*/
\r
907 DWORD read_pos = 0, write_pos = 0;
\r
908 DWORD pattern, packet_length;
\r
909 DWORD headerstrip=0;
\r
911 if (length < 4) return ;
\r
912 //Now we strip the pes header
\r
913 pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
\r
914 while (read_pos + 7 <= length)
\r
916 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];
\r
917 if (pattern < 0x000001E0 || pattern > 0x000001EF)
\r
921 headerstrip=buffer[read_pos+8]+9/*is this right*/;
\r
922 packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
\r
923 if (read_pos + packet_length > length)
\r
927 if ((write_pos+packet_length-headerstrip)>ms_length) {
\r
928 if (first) {ms->SetSyncPoint(TRUE);first=false;}
\r
929 else ms->SetSyncPoint(FALSE);
\r
930 ms->SetTime(NULL,NULL);
\r
931 ms->SetMediaTime(NULL, NULL);
\r
932 ms->SetActualDataLength(write_pos);
\r
933 DeliverVideoMediaSample();
\r
935 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
\r
940 ms_length=ms->GetSize();
\r
941 ms->GetPointer(&ms_buf);
\r
943 if (packet_length-headerstrip>0) {
\r
944 memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
\r
945 write_pos += packet_length-headerstrip;
\r
947 read_pos += packet_length;
\r
949 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
\r
950 | (buffer[read_pos+2]);
\r
955 if (first) {ms->SetSyncPoint(TRUE);first=false;}
\r
956 else ms->SetSyncPoint(FALSE);
\r
957 ms->SetTime(NULL,NULL);
\r
958 ms->SetMediaTime(NULL, NULL);
\r
959 ms->SetActualDataLength(write_pos);
\r
960 DeliverVideoMediaSample();
\r
964 // *samplepos+=packet.length;
\r
965 MILLISLEEP(0); //yet not implemented//bad idea
\r
972 int VideoWin::test()
\r
977 int VideoWin::test2()
\r