From 9ed2cf5e25dd88e9b3fe95c6987c0f281be2cc6a Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 11 Mar 2010 12:59:40 +0000 Subject: [PATCH] Windows HDTV --- demuxer.cc | 54 +++++++++++++++++++++++++++++++++++---- demuxer.h | 1 + demuxerts.cc | 6 +++-- draintarget.h | 2 ++ dsallocator.cc | 20 ++++++++++----- osdwin.cc | 4 +-- stream.cc | 2 +- videowin.cc | 69 +++++++++++++++++++++++++++++++++++++++++++++++++- videowin.h | 3 +++ 9 files changed, 144 insertions(+), 17 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index 0c07d00..3d3f358 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -301,6 +301,35 @@ UINT PESPacket::findPictureHeader(bool h264) const } } +UINT PESPacket::countPictureHeaders(bool h264) const +{ + if (size < 12) return 0; + UINT pattern = ( ((UINT)data[ 8] << 24) | + ((UINT)data[ 9] << 16) | + ((UINT)data[10] << 8) | + (UINT)data[11] ); + UINT pos = 11; + UINT count=0; + if (h264) { + + while (pos= PESTYPE_VID0 && packet.getPacketType() <= PESTYPE_VIDMAX) { - ULONG frame_num = (frameNumber)++; + frameNumber+=numpicts; + ULONG frame_num = frameNumber; if ((h264 || packet.findSeqHeader(h264) > 1) && packet.hasPTS()) { PTSMapEntry me; diff --git a/draintarget.h b/draintarget.h index e40bcd0..772b606 100644 --- a/draintarget.h +++ b/draintarget.h @@ -62,6 +62,8 @@ class DrainTarget virtual long long SetStartOffset(long long curreftime, bool *rsync)=0; virtual void ResetTimeOffsets()=0; + virtual bool dtsTimefix(){return false;} //determines if the draintargets needs a mixure of pts and dts or not + // The following two functions are used by the Stream // to deliver media packets to the front end (DrainTarget). // diff --git a/dsallocator.cc b/dsallocator.cc index f405730..9c719a3 100644 --- a/dsallocator.cc +++ b/dsallocator.cc @@ -50,8 +50,8 @@ DsAllocator::DsAllocator() { } DsAllocator::~DsAllocator() { - ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); + ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); CleanupSurfaces(); } @@ -286,10 +286,11 @@ HRESULT STDMETHODCALLTYPE DsAllocator::GetService(const GUID &guid,const IID &ii void DsAllocator::GetEVRSamples() { + Lock(); MFCLOCK_STATE clockstate; if (mfclock) mfclock->GetState(0,&clockstate); //MessageBox(0,"get samples","samples",0); - Lock(); + if (mfclock && clockstate==MFCLOCK_STATE_STOPPED && fullevrsamples.size()>0) { Unlock(); @@ -381,14 +382,14 @@ HRESULT STDMETHODCALLTYPE DsAllocator::ProcessMessage(MFVP_MESSAGE_TYPE mess,ULO //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_PROCESSINPUTNOTIFY received"); GetEVRSamples(); } break; case MFVP_MESSAGE_BEGINSTREAMING:{ - //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received"); + Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_BEGINSTREAMING received"); ResetSyncOffsets(); ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); - ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started); + //((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started);//No need to do this causes misbehaviout endofstream=false; }break; case MFVP_MESSAGE_ENDSTREAMING: { - //Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received"); + Log::getInstance()->log("DsAllocator", Log::DEBUG , "EVR Message MFVP_MESSAGE_ENDSTREAMING received"); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); //FlushEVRSamples(); @@ -424,6 +425,7 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStart(MFTIME systime,LONGLONG star if (PRESENTATION_CURRENT_POSITION!=startoffset) FlushEVRSamples(); ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStart"); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started); GetEVRSamples(); @@ -435,6 +437,8 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockStop(MFTIME systime) timeEndPeriod(1); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_off); + + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockStop"); ((OsdWin*)Osd::getInstance())->setExternalDriving(NULL,vwidth,vheight); FlushEVRSamples(); return S_OK; @@ -444,6 +448,8 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime) { timeEndPeriod(1); ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockPause"); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_pause); return S_OK; } @@ -451,6 +457,8 @@ HRESULT STDMETHODCALLTYPE DsAllocator::OnClockPause(MFTIME systime) HRESULT STDMETHODCALLTYPE DsAllocator::OnClockRestart(MFTIME systime) { ((OsdWin*)Osd::getInstance())->setExternalDriving(this,vwidth,vheight); + + Log::getInstance()->log("DsAllocator", Log::DEBUG , "OnClockRestart"); ((OsdWin*)Osd::getInstance())->SetEVRStatus(OsdWin::EVR_pres_started); return S_OK; @@ -737,7 +745,7 @@ void DsAllocator::DiscardSurfaceandgetWait(DWORD *waittime) HRESULT hres=sample->GetSampleTime(&prestime); if (hres==S_OK) { - mfclock->GetCorrelatedTime(0,¤ttime,&systime); + if (mfclock) mfclock->GetCorrelatedTime(0,¤ttime,&systime); } LONGLONG delta=prestime-currenttime; diff --git a/osdwin.cc b/osdwin.cc index e433a86..1583460 100644 --- a/osdwin.cc +++ b/osdwin.cc @@ -302,7 +302,7 @@ void OsdWin::threadMethod() } else if (evrstate==EVR_pres_started) { LPDIRECT3DSURFACE9 surf; - dsallocator->GetNextSurface(&surf,&waittime); + if (dsallocator) dsallocator->GetNextSurface(&surf,&waittime); if (surf==NULL) { Render(); @@ -311,7 +311,7 @@ void OsdWin::threadMethod() { RenderDS(surf); surf->Release(); - dsallocator->DiscardSurfaceandgetWait(&waittime); + if (dsallocator) dsallocator->DiscardSurfaceandgetWait(&waittime); } } } diff --git a/stream.cc b/stream.cc index b0318ae..0b1a090 100644 --- a/stream.cc +++ b/stream.cc @@ -106,7 +106,7 @@ int Stream::put(const UCHAR* inbuf, int len, UCHAR type,unsigned int index) } #ifdef WIN32 //ok we have the pts now convert it to a continously time code in 100ns units - if (hasdts ) newPacket.presentation_time=(ULLONG)(newPacket.dts*10000LL/90LL); + if (hasdts && draintarget->dtsTimefix()) newPacket.presentation_time=(ULLONG)(newPacket.dts*10000LL/90LL); else newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL); //newPacket.presentation_time-=draintarget->SetStartOffset((ULLONG)(newPacket.pts*10000LL/90LL),&newPacket.disconti); diff --git a/videowin.cc b/videowin.cc index 8e0a4dd..357f5a7 100644 --- a/videowin.cc +++ b/videowin.cc @@ -79,7 +79,17 @@ VideoWin::VideoWin() vmrdeinterlacing=2;//Best videofilterselected=-1; videoH264filterselected=-1; + OSVERSIONINFO verinfo; + verinfo.dwOSVersionInfoSize=sizeof(verinfo); + GetVersionEx(&verinfo); + + if (verinfo.dwMajorVersion>=6) { currentpresenter=EVR; + } else { + currentpresenter=VMR9; + } + videoH264dtsfix=false; + videompeg2dtsfix=false; @@ -430,6 +440,23 @@ bool VideoWin::loadOptionsfromServer(VDR* vdr) currentpresenter=VMR9; } + name=vdr->configLoad("DirectShow","videoH264dtsfix"); + if (name!=NULL) { + if (STRCASECMP(name,"YES")==0) { + videoH264dtsfix=true; + } else { + videoH264dtsfix=false; + } + } + name=vdr->configLoad("DirectShow","videompeg2dtsfix"); + if (name!=NULL) { + if (STRCASECMP(name,"YES")==0) { + videompeg2dtsfix=true; + } else { + videompeg2dtsfix=false; + } + } + name=vdr->configLoad("DirectGraphics", "StretchFiltering"); if (name!=NULL) { if (STRCASECMP(name,"None")==0) { @@ -482,6 +509,20 @@ bool VideoWin::handleOptionChanges(Option* option) currentpresenter=EVR; } }break; + case 4: { + if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) { + videoH264dtsfix=true; + } else { + videoH264dtsfix=false; + } + }break; + case 5: { + if (STRCASECMP(option->options[option->userSetChoice],"Yes")==0) { + videompeg2dtsfix=true; + } else { + videompeg2dtsfix=false; + } + }break; }; return false; @@ -539,7 +580,8 @@ bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pa if (((OsdWin*)Osd::getInstance())->IsEvrSupported()) { static const char* presenteropts[]={"EVR","VMR9"}; - option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2,0,0,presenteropts,NULL,false,this); + option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,2, + (currentpresenter==EVR)?0:1,0,presenteropts,NULL,false,this); } else { static const char* presenteropts[]={"VMR9"}; option = new Option(3,tr("Video Presenter Filter"),"DirectShow", "VideoPresenter",Option::TYPE_TEXT,1,0,0,presenteropts,NULL,false,this); @@ -547,6 +589,16 @@ bool VideoWin::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pa options->push_back(option); pane->addOptionLine(option); + static const char* yesnoopts[]={"Yes","No"}; + option = new Option(4,tr("Video H264 fix dts time"), "DirectShow","videoH264dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this); + options->push_back(option); + pane->addOptionLine(option); + + option = new Option(5,tr("Video Mpeg2 fix dts time"), "DirectShow","videompeg2dtsfix",Option::TYPE_TEXT,2,1,0,yesnoopts,NULL,false,this); + options->push_back(option); + pane->addOptionLine(option); + + } @@ -1162,12 +1214,27 @@ int VideoWin::dsInitVideoFilter() if (h264) { + if (vid_details.width!=0 && vid_details.height!=0) + { sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,&vid_details); } else { + sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_H264,NULL); + } + + } + else + { + if (vid_details.width!=0 && vid_details.height!=0) + { sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,&vid_details); } + else + { + sourcefilter->GetVideoPin()->SetPinMode(MPTYPE_VIDEO_MPEG2,NULL); + } + } if (videofilter->EnumPins(&pinenum) == S_OK) { IPin *current=NULL; diff --git a/videowin.h b/videowin.h index 814efdc..7090d6c 100644 --- a/videowin.h +++ b/videowin.h @@ -101,6 +101,7 @@ public: virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos); virtual UINT DeliverMediaSample(UCHAR* buffer, UINT *samplepos); UINT DeliverMediaPacket(const MediaPacket packet, const UCHAR* buffer, UINT *samplepos); + virtual bool dtsTimefix() {if (h264)return videoH264dtsfix; else return videompeg2dtsfix;} virtual bool supportsh264(); @@ -170,6 +171,8 @@ private: IBaseFilter *getVideoH264Filter(); VideoFilterDescList videoH264filterlist; int videoH264filterselected; + bool videoH264dtsfix; + bool videompeg2dtsfix; #endif int dsInitVideoFilter(); IMediaControl* dsmediacontrol; -- 2.39.2