示例#1
0
HRESULT CAudioPin::CompleteConnect(IPin *pReceivePin)
{
  m_bInFillBuffer = false;
  m_bPinNoAddPMT = false;
  m_bAddPMT = true;
  m_bDisableSlowPlayDiscontinuity=false;
  //LogDebug("audPin:CompleteConnect()");
  HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
  if (!SUCCEEDED(hr)) return E_FAIL;

  PIN_INFO pinInfo;
  FILTER_INFO filterInfo;
  hr=pReceivePin->QueryPinInfo(&pinInfo);
  if (!SUCCEEDED(hr)) return E_FAIL;
  else if (pinInfo.pFilter==NULL) return E_FAIL;
  else pinInfo.pFilter->Release(); // we dont need the filter just the info
    
  hr=pinInfo.pFilter->QueryFilterInfo(&filterInfo);
  filterInfo.pGraph->Release();

  if (SUCCEEDED(hr)) 
  {
    char szName[MAX_FILTER_NAME];
    int cch = WideCharToMultiByte(CP_ACP, 0, filterInfo.achName, MAX_FILTER_NAME, szName, MAX_FILTER_NAME, 0, 0);
    LogDebug("audPin:CompleteConnect() ok, filter: %s, iPosition: %d", szName, m_iPosition);
    
    m_bConnected=true;

    CLSID &ref=m_pTsReaderFilter->GetCLSIDFromPin(pReceivePin);
    m_pTsReaderFilter->m_audioDecoderCLSID = ref;
    if (m_pTsReaderFilter->m_audioDecoderCLSID == CLSID_LAVAUDIO)
    {
      m_bDisableSlowPlayDiscontinuity = (m_pTsReaderFilter->m_regLAV_AutoAVSync > 0);
      LogDebug("audPin:CompleteConnect() DisableSlowPlayDiscontinuity = %d", m_bDisableSlowPlayDiscontinuity);
    }
  }
  else
  {
    LogDebug("audPin:CompleteConnect() failed:%x, iPosition: %d", hr, m_iPosition);
    return E_FAIL;
  }

  if (m_pTsReaderFilter->IsTimeShifting())
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  else
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  //LogDebug("audPin:CompleteConnect() end");
  return hr;
}
HRESULT CSubtitlePin::CompleteConnect(IPin *pReceivePin)
{
  m_bInFillBuffer=false;
  //LogDebug("subPin:CompleteConnect()");
  HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
  if (!SUCCEEDED(hr)) return E_FAIL;

  PIN_INFO pinInfo;
  FILTER_INFO filterInfo;
  hr=pReceivePin->QueryPinInfo(&pinInfo);
  if (!SUCCEEDED(hr)) return E_FAIL;
  else if (pinInfo.pFilter==NULL) return E_FAIL;
  else pinInfo.pFilter->Release(); // we dont need the filter just the info
    
  hr=pinInfo.pFilter->QueryFilterInfo(&filterInfo);
  filterInfo.pGraph->Release();

  if (SUCCEEDED(hr)) 
  {
    char szName[MAX_FILTER_NAME];
    int cch = WideCharToMultiByte(CP_ACP, 0, filterInfo.achName, MAX_FILTER_NAME, szName, MAX_FILTER_NAME, 0, 0);
    LogDebug("subPin:CompleteConnect() ok, filter: %s", szName);
    
    m_bConnected=true;
  }
  else
  {
    LogDebug("subPin:CompleteConnect() failed:%x",hr);
    return E_FAIL;
  }

  if (m_pTsReaderFilter->IsTimeShifting())
  {
    //m_rtDuration=CRefTime(MAX_TIME);
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  else
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }

  //LogDebug("subPin:CompleteConnect() end");
  return hr;
}
void TsMPEG2TransportFileServerMediaSubsession::seekStreamSource(FramedSource* inputSource, double& seekNPT, double streamDuration, u_int64_t& numBytes)
{  
  if (m_pDuration==NULL)
  {
	  LogDebug("TsMp2TFSMediaSubsession::seekStreamSource - error, m_pDuration is NULL");
    return;
  }

	TsMPEG2TransportStreamFramer* framer=(TsMPEG2TransportStreamFramer*)inputSource;
	TsStreamFileSource* source=(TsStreamFileSource*)framer->inputSource();
	if (seekNPT==0.0)
	{
		source->seekToByteAbsolute(0LL);
		return;
	}
	double fileDuration=duration();

	if (seekNPT>(fileDuration-0.1)) seekNPT=(fileDuration-0.1);
	if (seekNPT <0) seekNPT=0;

	double pos=seekNPT / fileDuration;
	__int64 fileSize=source->fileSize();
	pos*=fileSize;
	pos/=188;
	pos*=188;

  source->seekToTimeAbsolute(CRefTime((LONG)(seekNPT*1000.0)), *m_pDuration) ;
  
  m_iDurationCount = 0;
  
	//LogDebug("TsMp2TFSMediaSubsession::seekStreamSource %f / %f", seekNPT, fileDuration);
}
示例#4
0
STDMETHODIMP CVideoPin::GetDuration(LONGLONG *pDuration)
{
  REFERENCE_TIME refTime;
  m_pFilter->GetDuration(&refTime);
  m_rtDuration = CRefTime(refTime);

  return CSourceSeeking::GetDuration(pDuration);
}
示例#5
0
//******************************************************
/// Returns the file duration in REFERENCE_TIME
/// For nomal .ts files it returns the current pcr - first pcr in the file
/// for timeshifting files it returns the current pcr - the first pcr ever read
/// So the duration keeps growing, even if timeshifting files are wrapped and being resued!
//
STDMETHODIMP CSubtitlePin::GetDuration(LONGLONG *pDuration)
{
    if (m_pTsReaderFilter->IsTimeShifting())
    {
        CRefTime totalDuration = m_pTsReaderFilter->m_duration.TotalDuration();
        m_rtDuration = totalDuration;
    }
    else
    {
        REFERENCE_TIME refTime;
        m_pTsReaderFilter->GetDuration(&refTime);
        m_rtDuration=CRefTime(refTime);
    }
    return CSourceSeeking::GetDuration(pDuration);
}
示例#6
0
//******************************************************
/// Returns the file duration in REFERENCE_TIME
/// For nomal .ts files it returns the current pcr - first pcr in the file
/// for timeshifting files it returns the current pcr - the first pcr ever read
/// So the duration keeps growing, even if timeshifting files are wrapped and being resued!
//
STDMETHODIMP CAudioPin::GetDuration(LONGLONG *pDuration)
{
  //LogDebug("audPin:GetDuration");
  if (m_pTsReaderFilter->IsTimeShifting())
  {
    CRefTime totalDuration=m_pTsReaderFilter->m_duration.TotalDuration();
    m_rtDuration=totalDuration;
  }
  else
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  if (pDuration!=NULL)
  {
    return CSourceSeeking::GetDuration(pDuration);
  }
  //LogDebug("audPin:GetDuration duration = %.3f ms, TotDuration = %.3f ms", (float)m_pTsReaderFilter->m_duration.Duration().Millisecs(), (float)m_pTsReaderFilter->m_duration.TotalDuration().Millisecs());
  return S_OK;
}
示例#7
0
HRESULT CAudioPin::CompleteConnect(IPin *pReceivePin)
{
  HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
  if (SUCCEEDED(hr))
  {
    LogDebug("aud:CompleteConnect() done");
    m_bConnected = true;
  }
  else
  {
    LogDebug("aud:CompleteConnect() failed:%x", hr);
    return hr;
  }

  REFERENCE_TIME refTime;
  m_pFilter->GetDuration(&refTime);
  m_rtDuration = CRefTime(refTime);
  
  pReceivePin->QueryInterface(IID_IPinConnection, (void**)&m_pPinConnection);
  m_pReceiver = pReceivePin;

  return hr;
}
示例#8
0
HRESULT CVideoPin::CompleteConnect(IPin* pReceivePin)
{
  HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
  if (SUCCEEDED(hr))
  {
    LogDebug("vid:CompleteConnect() done");
    m_bConnected = true;
    m_currentDecoder = GetDecoderCLSID(pReceivePin);
  }
  else
  {
    LogDebug("vid:CompleteConnect() failed:%x", hr);
    m_currentDecoder = GUID_NULL;
    return hr;
  }

  REFERENCE_TIME refTime;
  m_pFilter->GetDuration(&refTime);
  m_rtDuration = CRefTime(refTime);

  m_pReceiver = pReceivePin;

  return hr;
}
void CTsReaderFilter::SeekPreStart(CRefTime& rtAbsSeek)
{
  bool doSeek = true;
  CTsDuration tsduration=GetDuration();

  SetMediaPosition(rtAbsSeek.m_time) ;

  //Note that the seek timestamp (m_rtStart) is done in the range
  //from earliest - latest from GetAvailable()
  //We however would like the seek timestamp to be in the range 0-fileduration
  CRefTime rtSeek = rtAbsSeek;
  float seekTime = (float)rtSeek.Millisecs();
  seekTime /= 1000.0f;

  //get the earliest timestamp available in the file
  float earliesTimeStamp = 0;
  earliesTimeStamp = tsduration.StartPcr().ToClock() - tsduration.FirstStartPcr().ToClock();

  if (earliesTimeStamp < 0) earliesTimeStamp = 0;

  //correct the seek time
  seekTime -= earliesTimeStamp;
  if (seekTime < 0) seekTime = 0;

  seekTime *= 1000.0f;
  rtSeek = CRefTime((LONG)seekTime);
  // Now rtSeek contains the "relative" position from "0 to buffer/file duration"

  // Should we really seek ?
  
  // Because all skips generated after "Stop()" cause a lot of problem
  // This remove all these stupid skips. 
  if(m_State == State_Stopped)
  {   
    if ((m_bStoppedForUnexpectedSeek || (m_absSeekTime==rtAbsSeek)) && !m_bForceSeekOnStop && !m_bForceSeekAfterRateChange)
    {
//      LogDebug("CTsReaderFilter::--SeekStart() Stopped state -- No new seek %f", 
//      (float)rtSeek.Millisecs()/1000.0f);
      m_bStoppedForUnexpectedSeek=false ;
      m_seekTime = rtSeek ;
      m_absSeekTime = rtAbsSeek ;
      return ;
    }
  }

  if (((m_absSeekTime==rtAbsSeek) && !m_bStreamCompensated && !m_bForceSeekAfterRateChange) || (m_demultiplexer.IsMediaChanging() && !m_bOnZap && !m_bForceSeekOnStop && !m_bForceSeekAfterRateChange))  
  {
    doSeek = false;
    LogDebug("CTsReaderFilter::--SeekStart()-- No new seek %f ( Abs %f / %f ) - Stream compensated: %d, OnZap: %d, Force %d, Media changing: %d", 
		(float)rtSeek.Millisecs()/1000.0f, (float)rtAbsSeek.Millisecs()/1000.0f, (float)m_duration.EndPcr().ToClock(),m_bStreamCompensated,m_bOnZap,m_bForceSeekOnStop, m_demultiplexer.IsMediaChanging());
//	  m_bStreamCompensated=false ;
    m_bForceSeekOnStop = false ;
  }
  else
  {
    LogDebug("CTsReaderFilter::--SeekStart()-- LiveTv : %d, TimeShifting: %d %3.3f ( Abs %f / %f ), OnZap: %d, Force %d, ForceRC %d, Media changing %d",
		m_bLiveTv,m_bTimeShifting,(float)rtSeek.Millisecs()/1000.0,(float)rtAbsSeek.Millisecs()/1000.0f, (float)m_duration.EndPcr().ToClock(),m_bOnZap,m_bForceSeekOnStop,m_bForceSeekAfterRateChange,m_demultiplexer.IsMediaChanging());

    m_bForceSeekOnStop = false ;
    
    if (m_bForceSeekAfterRateChange)
    {
      m_bSeekAfterRcDone = true;
      m_bForceSeekAfterRateChange = false ; 
    }

    if (m_bTimeShifting)
    {
      LONG duration = m_duration.Duration().Millisecs() ;
      LONG seekTime = rtSeek.Millisecs() ;
      if (seekTime + 200 > duration) // End of timeshift buffer requested.
      {
        if (m_bLiveTv && !m_bAnalog  && (m_fileDuration != NULL)) doSeek=false ;       // Live & not analog & not RTSP do not seek
        m_bLiveTv=true ;
      }
      else
        m_bLiveTv=false ;

      LogDebug("Zap to File Seek : %d mS ( %f / %f ) LiveTv : %d, Seek : %d",GetTickCount()-m_lastPause, (float)seekTime/1000.0f, (float)duration/1000.0f, m_bLiveTv, doSeek);
    }

    m_seekTime=rtSeek ;
    m_absSeekTime = rtAbsSeek ;

    if (!doSeek && !m_bOnZap) return ;

//    m_demultiplexer.SetHoldAudio(true) ;
//    m_demultiplexer.SetHoldVideo(true) ;
 
    m_WaitForSeekToEof=1 ; // 

    m_demultiplexer.CallTeletextEventCallback(TELETEXT_EVENT_SEEK_START,TELETEXT_EVENTVALUE_NONE);
 
    // Stop threads ////

    if (GetAudioPin()->IsConnected())
    {
      //deliver a begin-flush to the codec filter so it stops asking for data
      GetAudioPin()->DeliverBeginFlush();

      //stop the thread
      GetAudioPin()->Stop();
    }

    if (GetVideoPin()->IsConnected())
    {
      //deliver a begin-flush to the codec filter so it stops asking for data
      GetVideoPin()->DeliverBeginFlush();

      //stop the thread
      GetVideoPin()->Stop();
    }

    m_bStreamCompensated=false ;
    m_demultiplexer.m_bAudioVideoReady=false ;

	  if (!m_bOnZap || !m_demultiplexer.IsNewPatReady() || m_bAnalog) // On zapping, new PAT has occured, we should not flush to avoid loosing data.
	  {                                                               //             new PAT has not occured, we should flush to avoid restart with old data.							
	    m_demultiplexer.FlushAudio() ;
	    m_demultiplexer.FlushVideo() ;
    }
    m_bOnZap=false ;
//    m_demultiplexer.SetHoldAudio(false) ;
//    m_demultiplexer.SetHoldVideo(false) ;

    //do the seek...
    if (doSeek && !m_demultiplexer.IsMediaChanging()&& !m_demultiplexer.IsAudioChanging()) Seek(rtSeek, true);

    //tell filter we're done with seeking
//    m_pTsReaderFilter->SeekDone(rtSeek);

    m_WaitForSeekToEof=0 ; // 

    if (m_fileDuration != NULL)
    {
      if (rtSeek >= m_duration.Duration())
      {
        rtSeek=m_duration.Duration();
      }
    }

    if (GetAudioPin()->IsConnected())
    {
      // deliver a end-flush to the codec filter so it will start asking for data again
      GetAudioPin()->DeliverEndFlush();

      // Update m_rtStart in case of has not seeked yet
      GetAudioPin()->SetStart(rtAbsSeek) ;

      // and restart the thread
      GetAudioPin()->Run();
    }

    if (GetVideoPin()->IsConnected())
    {
      //deliver a end-flush to the codec filter so it will start asking for data again
      GetVideoPin()->DeliverEndFlush();

      // Update m_rtStart in case of has not seeked yet
      GetVideoPin()->SetStart(rtAbsSeek) ;

      // and restart the thread
      GetVideoPin()->Run();
    }

    m_demultiplexer.CallTeletextEventCallback(TELETEXT_EVENT_SEEK_END,TELETEXT_EVENTVALUE_NONE);

    if (m_pDVBSubtitle)
    {
      m_pDVBSubtitle->SetFirstPcr(m_duration.FirstStartPcr().PcrReferenceBase);
      m_pDVBSubtitle->SeekDone(rtSeek);
    }
  }

  return ;
}
示例#10
0
STDMETHODIMP CTsReaderFilter::Load(LPCOLESTR pszFileName,const AM_MEDIA_TYPE *pmt)
{
  LogDebug("CTsReaderFilter::Load()");
  //clean up any old file readers
  if (m_fileReader != NULL)
    delete m_fileReader;
  if (m_fileDuration != NULL)
    delete m_fileDuration;
  m_fileReader = NULL;
  m_fileDuration = NULL;
  m_seekTime = CRefTime(0L);
  m_absSeekTime = CRefTime(0L);
  m_WaitForSeekToEof=0;
  m_bRecording=false ;

  wcscpy(m_fileName, pszFileName);
  char url[MAX_PATH];
  WideCharToMultiByte(CP_ACP, 0 ,m_fileName, -1, url, MAX_PATH, 0, 0);
  //check file type
  int length=strlen(url);
  if ((length > 5) && (_strcmpi(&url[length-4], ".tsp") == 0))
  {
    // .tsp file
    m_bTimeShifting = true;
    m_bLiveTv = true;

    FILE* fd = fopen(url, "rb");
    if (fd == NULL) return E_FAIL;
    fread(url, 1, 100, fd);
    int bytesRead = fread(url, 1, sizeof(url), fd);
    if (bytesRead >= 0) url[bytesRead] = 0;
    fclose(fd);

    LogDebug("open %s", url);
    if ( !m_rtspClient.OpenStream(url)) return E_FAIL;

    m_buffer.Clear();
    m_buffer.Run(true);
    m_rtspClient.Play(0.0,0.0);
    m_tickCount = GetTickCount();
    m_fileReader = new CMemoryReader(m_buffer);
    m_demultiplexer.SetFileReader(m_fileReader);
    m_demultiplexer.Start();
    m_buffer.Run(false);

    LogDebug("close rtsp:%s", url);
    m_rtspClient.Stop();

    m_tickCount = GetTickCount()-m_rtspClient.Duration();   // Will be ready to update "virtual end Pcr" on recording in progress.

    double duration = m_rtspClient.Duration() / 1000.0f;
    CPcr pcrstart, pcrEnd, pcrMax;
    pcrstart = m_duration.StartPcr();
    duration += pcrstart.ToClock();
    pcrEnd.FromClock(duration);
    pcrstart.IsValid=true ;
    m_duration.Set(pcrstart, pcrEnd, pcrMax);    //Load()
  }
  else if ((length > 7) && (strnicmp(url, "rtsp://",7) == 0))
  {
    //rtsp:// stream
    //open stream
    LogDebug("open rtsp:%s", url);
    if ( !m_rtspClient.OpenStream(url)) return E_FAIL;

    m_bTimeShifting = true;
    m_bLiveTv = true;

    //are we playing a recording via RTSP
    if (strstr(url, "/stream") == NULL)
    {
      //yes, then we're not timeshifting
      m_bTimeShifting = false;
      m_bLiveTv = false;
    }

    //play
    m_buffer.Clear();
    m_buffer.Run(true);
    m_rtspClient.Play(0.0,0.0);
    m_fileReader = new CMemoryReader(m_buffer);

    //get audio /video pids
    m_demultiplexer.SetFileReader(m_fileReader);
    m_demultiplexer.Start();
    m_buffer.Run(false);

    // stop streaming
    LogDebug("close rtsp:%s", url);
    m_rtspClient.Stop();

    m_tickCount = GetTickCount()-m_rtspClient.Duration();

    //get the duration of the stream

    double duration = m_rtspClient.Duration() / 1000.0f;
    CPcr pcrstart, pcrEnd, pcrMax;
    pcrstart = m_duration.StartPcr();
    duration += pcrstart.ToClock();
    pcrEnd.FromClock(duration);
    pcrstart.IsValid=true ;
    m_duration.Set(pcrstart, pcrEnd, pcrMax);    //Load()
  }
  else
  {
    if ((length < 9) || (_strcmpi(&url[length-9], ".tsbuffer") != 0))
    {
      //local .ts file
      m_bTimeShifting = false;
      m_bLiveTv = false ;
      m_fileReader = new FileReader();
      m_fileDuration = new FileReader();
    }
    else
    {
      //local timeshift buffer file file
      m_bTimeShifting = true;
      m_bLiveTv = true;
      m_fileReader = new MultiFileReader();
      m_fileDuration = new MultiFileReader();
    }

    //open file
    m_fileReader->SetFileName(m_fileName);
    m_fileReader->OpenFile();

    m_fileDuration->SetFileName(m_fileName);
    m_fileDuration->OpenFile();

    //detect audio/video pids
    m_demultiplexer.SetFileReader(m_fileReader);
    m_demultiplexer.Start();

    //get file duration
    m_duration.SetFileReader(m_fileDuration);
    m_duration.UpdateDuration();

    float milli = m_duration.Duration().Millisecs();
    milli /= 1000.0;
    LogDebug("start:%x end:%x %f",
      (DWORD)m_duration.StartPcr().PcrReferenceBase, (DWORD) m_duration.EndPcr().PcrReferenceBase, milli);
    m_fileReader->SetFilePointer(0LL, FILE_BEGIN);
  }

  //AddGraphToRot(GetFilterGraph());
  SetDuration();

  return S_OK;
}
示例#11
0
// Constructor
CTsReaderFilter::CTsReaderFilter(IUnknown *pUnk, HRESULT *phr):
  CSource(NAME("CTsReaderFilter"), pUnk, CLSID_TSReader),
  m_pAudioPin(NULL),
  m_demultiplexer( m_duration, *this),
  m_rtspClient(m_buffer),
  m_pDVBSubtitle(NULL),
  m_pCallback(NULL),
  m_pRequestAudioCallback(NULL)
{
  // use the following line if you are having trouble setting breakpoints
  // #pragma comment( lib, "strmbasd" )
  TCHAR filename[1024];
  GetLogFile(filename);
  ::DeleteFile(filename);
  LogDebug("---------- v0.4.12 -------------------");

  m_fileReader=NULL;
  m_fileDuration=NULL;
  Compensation=CRefTime(0L);

  LogDebug("CTsReaderFilter::ctor");
  m_pAudioPin = new CAudioPin(GetOwner(), this, phr,&m_section);
  m_pVideoPin = new CVideoPin(GetOwner(), this, phr,&m_section);
  m_pSubtitlePin = new CSubtitlePin(GetOwner(), this, phr,&m_section);

  if (m_pAudioPin == NULL)
  {
    *phr = E_OUTOFMEMORY;
    return;
  }
  wcscpy(m_fileName,L"");
  m_dwGraphRegister = 0;
  m_rtspClient.Initialize();
  HKEY key;
  if (ERROR_SUCCESS==RegCreateKey(HKEY_CURRENT_USER, "Software\\MediaPortal\\TsReader",&key))
  {
    RegCloseKey(key);
  }

  // Set default filtering mode (normal), if not overriden externaly (see ITSReader::SetRelaxedMode)
  m_demultiplexer.m_DisableDiscontinuitiesFiltering = false;
  
  if(!DoNotAllowSlowMotionDuringZapping())
  {
    LogDebug("Slow motion video allowed during zapping");
    m_pAudioPin->m_EnableSlowMotionOnZapping = true;
  }
  else
  {
    LogDebug("No slow motion video allowed during zapping");
    m_pAudioPin->m_EnableSlowMotionOnZapping = false;
  }
  
  LogDebug("Wait for seeking to eof - false - constructor");
  m_WaitForSeekToEof=0;
  m_bLiveTv = false;
  m_RandomCompensation = 0;     
  m_bAnalog = false;
  m_bStopping = false;
  m_bOnZap = false;
  m_bPauseOnClockTooFast = false;
  SetMediaPosition(0) ;
  m_bStoppedForUnexpectedSeek=false ;
  m_bForceSeekOnStop=false ;
  m_bForceSeekAfterRateChange=false ;
  m_bSeekAfterRcDone=false ;
  m_videoDecoderCLSID=GUID_NULL;
  m_bFastSyncFFDShow=false;
  m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO;
  m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO;
  
  m_MPmainThreadID = GetCurrentThreadId() ;
}
示例#12
0
HRESULT CVideoPin::CompleteConnect(IPin *pReceivePin)
{
  m_bInFillBuffer = false;
  m_bPinNoNewSegFlush = false;
  m_bPinNoAddPMT = false;
  m_bAddPMT = true;
  if (m_pTsReaderFilter->m_bForceFFDShowSyncFix)
  {
    m_pTsReaderFilter->m_bFastSyncFFDShow = true;
  }
  else
  {
    m_pTsReaderFilter->m_bFastSyncFFDShow = false;
  }
  HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
  if (!SUCCEEDED(hr)) return E_FAIL;

  PIN_INFO pinInfo;
  FILTER_INFO filterInfo;
  hr=pReceivePin->QueryPinInfo(&pinInfo);
  if (!SUCCEEDED(hr)) return E_FAIL;
  else if (pinInfo.pFilter==NULL) return E_FAIL;
  else pinInfo.pFilter->Release(); // we dont need the filter just the info
    
  hr=pinInfo.pFilter->QueryFilterInfo(&filterInfo);
  filterInfo.pGraph->Release();

  if (SUCCEEDED(hr)) 
  {
    char szName[MAX_FILTER_NAME];
    int cch = WideCharToMultiByte(CP_ACP, 0, filterInfo.achName, MAX_FILTER_NAME, szName, MAX_FILTER_NAME, 0, 0);
    LogDebug("vidPin:CompleteConnect() ok, filter: %s", szName);
    
    m_bConnected=true;
        
    CLSID &ref=m_pTsReaderFilter->GetCLSIDFromPin(pReceivePin);
    m_pTsReaderFilter->m_videoDecoderCLSID = ref;
    if (m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_FFDSHOWVIDEO)
    {
      m_pTsReaderFilter->m_bFastSyncFFDShow=true;
      //LogDebug("vidPin:CompleteConnect() FFDShow Video Decoder connected");
    }
    else if (m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_FFDSHOWDXVA)
    {
      m_bPinNoAddPMT = true;
      //LogDebug("vidPin:CompleteConnect() FFDShow DXVA Video Decoder connected, disable AddPMT");
    }
    else if (m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_MSDTVDVDVIDEO)
    {
      m_bPinNoNewSegFlush = true;
      //LogDebug("vidPin:CompleteConnect() MS DTV-DVD Video Decoder connected, disable NewSegFlush");
    }    
  }
  else
  {
    LogDebug("vidPin:CompleteConnect() failed:%x",hr);
    return E_FAIL;
  }


  if (m_pTsReaderFilter->IsTimeShifting())
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  else
  {
    REFERENCE_TIME refTime;
    m_pTsReaderFilter->GetDuration(&refTime);
    m_rtDuration=CRefTime(refTime);
  }
  //LogDebug("vidPin:CompleteConnect() end");
  return hr;
}