]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Windows HDTV
authorChris Tallon <chris@vomp.tv>
Thu, 11 Mar 2010 12:59:40 +0000 (12:59 +0000)
committerChris Tallon <chris@vomp.tv>
Thu, 11 Mar 2010 12:59:40 +0000 (12:59 +0000)
demuxer.cc
demuxer.h
demuxerts.cc
draintarget.h
dsallocator.cc
osdwin.cc
stream.cc
videowin.cc
videowin.h

index 0c07d00bdcd8e1255d0f21922f86c0c7935536ea..3d3f3585ac4efd1eb873d077475952fe0c890bcb 100644 (file)
@@ -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<size)
+         {
+          pos++;
+                 pattern = (pattern << 8) | data[pos];
+          if (pattern==DEMUXER_H264_ACCESS_UNIT) count++;
+         }
+         return count;
+  } else {
+      while (pos<size)
+         {
+          pos++;
+                 pattern = (pattern << 8) | data[pos];
+          if (pattern==DEMUXER_PIC_HEAD) count++;
+         }
+         return count;
+  }
+}
+
 UINT PESPacket::findSeqHeader(bool h264) const
 {
   if (seq_header != 1) return seq_header;
@@ -707,9 +736,11 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV
                 nalu.getBits(8); //constraints
                 nalu.getBits(8); //level_idc
                 nalu.getUe(); //seq_parameter_set_id
+                int chroma=1;
                 if (profile==100 || profile==110 || profile==122 || profile==144)
                 {
-                    if (nalu.getUe()==3)
+                    chroma=nalu.getUe();
+                    if (chroma==3)
                     {
                         nalu.getBits(1);
                     }
@@ -749,6 +780,19 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV
                         }
                     }
                 }
+                int chromunitx=1;
+                int chromunity=1;
+                switch (chroma) {
+                case 0:
+                    chromunitx=chromunity=1; break;
+                case 1:
+                    chromunitx=chromunity=2; break;
+                case 2:
+                    chromunitx=2;chromunity=1; break;
+                case 3:
+                    chromunitx=chromunity=1; break;
+                };
+
                 nalu.getUe(); //log2framenum
                 UINT temp=nalu.getUe();
                 if (temp==0) //pict order
@@ -773,10 +817,10 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV
                 nalu.getBits(1);
                 if (nalu.getBits(1))
                 {
-                    nalu.getUe();
-                    nalu.getUe();
-                    nalu.getUe();
-                    nalu.getUe();
+                    horizontal_size-=nalu.getUe()*chromunitx;
+                    horizontal_size-=nalu.getUe()*chromunitx;
+                    vertical_size-=nalu.getUe()*(2-interlaced)*chromunity;
+                    vertical_size-=nalu.getUe()*(2-interlaced)*chromunity;
                 }
                 if (nalu.getBits(1))
                 {
index c0acf8559b7f351bd2158059d2d9393bcad6542b..85c347003b1914badca2bf24c827be1da5ae123b 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -62,6 +62,7 @@ class PESPacket
 
     UINT findPictureHeader(bool h264) const;
     UINT findSeqHeader(bool h264) const;
+    UINT countPictureHeaders(bool h264) const;
     static const ULLONG PTS_INVALID = (1LL << 33);
   protected:
     void copyFrom(const PESPacket& packet);
index 330e7ad687126900c2b968d2b5cf17994d77ba88..5fac53ffc6a21272c746ecb521b88cf767cb1f87 100644 (file)
@@ -658,12 +658,14 @@ void DemuxerTS::parseTSPacketDetails(PESPacket &packet) // Only important stuff
     {
         packetNumber++;
     }
+    UINT numpicts=packet.countPictureHeaders(h264);
 
-  if (frameCounting && packet.findPictureHeader(h264) &&
+  if (frameCounting && numpicts &&
       packet.getPacketType() >= 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;
index e40bcd0d6ea915c005b617850ac2194c8d9bb34d..772b606c1ce1a245ed20fcf65c3742cebce02573 100644 (file)
@@ -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).
 //
index f40573059bae868edfbd34db39ab275d15b08323..9c719a38a7341610c1db578a3a3af46d874270e2 100644 (file)
@@ -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,&currenttime,&systime);
+            if (mfclock) mfclock->GetCorrelatedTime(0,&currenttime,&systime);
         }
         LONGLONG delta=prestime-currenttime;
 
index e433a8630cd1eb1c5a9d8c58f1d3767d6aa23f41..1583460bf9ba07edafec8fc1fb5c82210e8b4034 100644 (file)
--- 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);
                                }
                        }
                }
index b0318ae526e4ab32768337be17f6706516915cd6..0b1a090700ca005e86591219132b24bdb0c1c26b 100644 (file)
--- 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);
index 8e0a4ddab629a2a86cc0ee2447928630db47aa75..357f5a72bb4a8bd778ab37bf3623d0335204e98c 100644 (file)
@@ -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;
index 814efdc55ad49eac7e5eeda5764cb531d3fac820..7090d6cac7c4bc8b0d172bb86ab38f402a32ddf6 100644 (file)
@@ -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;