//
// FindSubtitleFilter
//
// be careful with this method, can cause deadlock with CSync::Stop, so should only be called in Run()
HRESULT CTsReaderFilter::FindSubtitleFilter()
{
  if( m_pDVBSubtitle )
  {
    return S_OK;
  }
  //LogDebug( "FindSubtitleFilter - start");

  IEnumFilters * piEnumFilters = NULL;
  if (GetFilterGraph() && SUCCEEDED(GetFilterGraph()->EnumFilters(&piEnumFilters)))
  {
    IBaseFilter * pFilter;
    while (piEnumFilters->Next(1, &pFilter, 0) == NOERROR )
    {
      FILTER_INFO filterInfo;
      if (pFilter->QueryFilterInfo(&filterInfo) == S_OK)
      {
        if (!wcsicmp(L"MediaPortal DVBSub2", filterInfo.achName))
        {
          HRESULT fhr = pFilter->QueryInterface( IID_IDVBSubtitle2, ( void**)&m_pDVBSubtitle );
          assert( fhr == S_OK);
          //LogDebug("Testing that DVBSub2 works");
          m_pDVBSubtitle->Test(1);
        }
        filterInfo.pGraph->Release();
      }
      pFilter->Release();
      pFilter = NULL;
    }
    piEnumFilters->Release();
  }
  //LogDebug( "FindSubtitleFilter - End");
  return S_OK;
}
Example #2
0
HRESULT CBDReaderFilter::FindSubtitleFilter()
{
  if (m_pDVBSubtitle)
    return S_OK;

  HRESULT hr = S_FALSE;
  ULONG fetched = 0;

  IEnumFilters * piEnumFilters = NULL;
  if (GetFilterGraph() && SUCCEEDED(GetFilterGraph()->EnumFilters(&piEnumFilters)))
  {
    IBaseFilter * pFilter;
    while (piEnumFilters->Next(1, &pFilter, &fetched) == NOERROR)
    {
      FILTER_INFO filterInfo;
      if (pFilter->QueryFilterInfo(&filterInfo) == S_OK)
      {
        if (!wcsicmp(L"MediaPortal DVBSub3", filterInfo.achName))
          hr = pFilter->QueryInterface(IID_IDVBSubtitle3, (void**)&m_pDVBSubtitle);

        filterInfo.pGraph->Release();
      }
      pFilter->Release();
      pFilter = NULL;
    }
    piEnumFilters->Release();
  }

  return hr;
}
HRESULT CWavPackDSSplitter::CleanupOnInputBreakConnect()
{
    HRESULT hr = S_OK;

    DebugLog("CWavPackDSSplitter::CleanupOnInputBreakConnect... 0x%08X", GetCurrentThreadId());

    IFilterGraph* pFG = GetFilterGraph();

    if(m_pInputPinCorr != NULL)
    {
        if(m_pInputPinCorr->IsConnected())
        {
            m_pInputPinCorr->GetConnected()->Disconnect();
            m_pInputPinCorr->Disconnect();
        }        
    }

    if(m_pOutputPin != NULL)
    {
        if(m_pOutputPin->IsConnected())
        {
            m_pOutputPin->GetConnected()->Disconnect();
            m_pOutputPin->Disconnect();
        }
    }

    m_bDontTryToLoadCorrectionFileAgain = FALSE;

    return hr;
}
Example #4
0
extern "C" int WINAPI pos(HWND,HWND,char *data,char*,BOOL,BOOL)
{
	CComPtr<IFilterGraph> pFG;
	if(!GetFilterGraph(&pFG))
		return 1;

	CComQIPtr<IMediaSeeking> pMS = pFG;
	REFERENCE_TIME pos, dur;
	if(FAILED(pMS->GetCurrentPosition(&pos)) || FAILED(pMS->GetDuration(&dur)))
		return 1;

	if(dur > 10000000i64*60*60)
	{
		sprintf(data, _T("%02d:%02d:%02d/%02d:%02d:%02d"), 
			(int)(pos/10000000/60/60), (int)(pos/10000000/60)%60, (int)(pos/10000000)%60,
			(int)(dur/10000000/60/60), (int)(dur/10000000/60)%60, (int)(dur/10000000)%60);
	}
	else
	{
		sprintf(data, _T("%02d:%02d/%02d:%02d"), 
			(int)(pos/10000000/60)%60, (int)(pos/10000000)%60,
			(int)(dur/10000000/60)%60, (int)(dur/10000000)%60);
	}

	return 3;
}
Example #5
0
//
// Run
//
STDMETHODIMP CDVBSub::Run( REFERENCE_TIME tStart )
{
  CAutoLock cObjectLock( m_pLock );
  LogDebug( "CDVBSub::Run" );
  m_startTimestamp = tStart;

  HRESULT hr = CBaseFilter::Run( tStart );

  if( hr != S_OK )
  {
    LogDebug( "CDVBSub::Run - BaseFilter returned %i", hr );
    return hr;
  }

  // Get media seeking interface if missing
  if( !m_pIMediaSeeking )
  {
    IFilterGraph *pGraph = GetFilterGraph();    
    if( pGraph )
    {
      pGraph->QueryInterface( &m_pIMediaSeeking );
      pGraph->Release();
    }
  }

  LogDebug( "CDVBSub::Run - done" );
  return hr; 
}
Example #6
0
extern "C" int WINAPI running(HWND,HWND,char *data,char*,BOOL,BOOL)
{
	sprintf(data, _T("2"));

	CComPtr<IFilterGraph> pFG;
	CComQIPtr<IMediaControl> pMC;
	OAFilterState fs;
	if(!GetFilterGraph(&pFG) || !(pMC = pFG) || FAILED(pMC->GetState(0, &fs)))
		return 3;

	sprintf(data, _T("%d"), fs == State_Running ? 1 : 0);

	return 3;
}
void CTsReaderFilter::SetMediaPosition(REFERENCE_TIME MediaPos)
{
  {
    CAutoLock cObjectLock(&m_GetTimeLock);
    m_MediaPos = MediaPos ;
    m_BaseTime = (REFERENCE_TIME)GetTickCount() * 10000 ; // m_pClock->GetTime(&m_BaseTime) ;
    m_LastTime=m_BaseTime ;
  }
//  LogDebug("SetMediaPos : %f %f",(float)MediaPos/10000,(float)m_LastTime/10000) ; 

// This is not really the right place, but this is the only method called by "MPmain" that could allow
// TsReader to "Pause" itself without deadlock issue.
// This is also here to allow compatibility with previous releases, avoiding a new callback from MP.

  if (m_bRenderingClockTooFast)
  {
    if (m_bPauseOnClockTooFast)
      return ;                  // Do not re-enter !
    if (GetCurrentThreadId()!=m_MPmainThreadID) 
      return ;                  // Only MPmain can do that !
    if (((m_MediaPos/10000)-m_absSeekTime.Millisecs()) < 30*1000)
    {
      return ;                  
    }

    m_bPauseOnClockTooFast=true ;
    if (State() == State_Running)
    {
      IMediaControl * ptrMediaCtrl;
      if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaControl, (void**)&ptrMediaCtrl)))
      {
        LogDebug("Pause 200mS renderer clock to match provider/RTSP clock...") ; 
        ptrMediaCtrl->Pause() ;
        Sleep(200) ;
//        m_TestTime = GetTickCount() ;
        ptrMediaCtrl->Run() ;
        m_bRenderingClockTooFast=false ;
      }
      else
        LogDebug("Pause failed...") ; 
    }
    m_bPauseOnClockTooFast=false ;
  }
}
Example #8
0
extern "C" int WINAPI file(HWND,HWND,char *data,char*,BOOL,BOOL)
{
	CComPtr<IFilterGraph> pFG;
	if(!GetFilterGraph(&pFG))
		return 1;

	CString fn;

	CComPtr<IEnumFilters> pEF;
	if(FAILED(pFG->EnumFilters(&pEF)))
		return 1;

	ULONG cFetched = 0;
	for(CComPtr<IBaseFilter> pBF; S_OK == pEF->Next(1, &pBF, &cFetched); pBF = NULL)
	{
		if(CComQIPtr<IFileSourceFilter> pFSF = pBF)
		{
			LPOLESTR pFileName = NULL;
			AM_MEDIA_TYPE mt;
			if(FAILED(pFSF->GetCurFile(&pFileName, &mt)))
				continue;

			fn = CStringW(pFileName);

			CoTaskMemFree(pFileName);
			FreeMediaType(mt);

			break;
		}
	}

	if(fn.IsEmpty())
		return 1;

	sprintf(data, _T("%s"), fn);

	return 3;
}
HRESULT CWavPackDSSplitter::TryToLoadCorrectionFile()
{
    // Here is the nasty hacky stuff :>

    HRESULT hr = S_FALSE;
    IPin *pPinOutSrc = NULL;
    IFileSourceFilter *pFSF = NULL;
    LPOLESTR pszFileName = NULL;
    IBaseFilter* pSrcFilterCorr = NULL;
    IFileSourceFilter*	pFSFCorr = NULL;
    IEnumPins *pEnum = NULL;
    IPin *pPinNew = NULL;
    BOOL bCorrectionFileLoaded = FALSE;
    IEnumFilters* pEnumFilers = NULL;
    BOOL bSrcFileAlreadyLoaded = FALSE;

    DebugLog("===> Entering CWavPackDSSplitter::TryToLoadCorrectionFile... 0x%08X", GetCurrentThreadId());

    if((m_bDontTryToLoadCorrectionFileAgain == TRUE) ||
       (m_pInputPinCorr == NULL) ||
       (m_pInputPinCorr->IsConnected() == TRUE))
    {
        DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile already loaded ?... 0x%08X", GetCurrentThreadId());
        return hr;
    }

    if((m_pInputPin->m_pWavPackParser->first_wphdr.flags & HYBRID_FLAG) != HYBRID_FLAG)
    {
        // Not an hybrid file, don't even try
        m_bDontTryToLoadCorrectionFileAgain = TRUE;
        DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile not hybrid... 0x%08X", GetCurrentThreadId());
        return hr;
    }
    
#define IF_FAIL_BREAK(x) if(FAILED(x)) { break; }
    
    do {
        hr = m_pInputPin->ConnectedTo(&pPinOutSrc);
        IF_FAIL_BREAK(hr);

        // Get a pointer on the source filter
        PIN_INFO pi;
        pi.pFilter = NULL;
        hr = pPinOutSrc->QueryPinInfo(&pi);
        IF_FAIL_BREAK(hr);
        
        // Get source filter IFileSourceFilter interface    
        hr = pi.pFilter->QueryInterface(IID_IFileSourceFilter, (void **)&pFSF);
        IF_FAIL_BREAK(hr);
        
        // Get filename
        hr = pFSF->GetCurFile(&pszFileName, NULL);
        IF_FAIL_BREAK(hr);

        // Create correction file filename
        WCHAR pszFileNameC[MAX_PATH];
        ZeroMemory(pszFileNameC, sizeof(WCHAR)*MAX_PATH);
        int cch = lstrlenW(pszFileName);
        CopyMemory(pszFileNameC, pszFileName, cch*sizeof(WCHAR));
        pszFileNameC[cch] = 'c';
        
        IFilterGraph* pFG = GetFilterGraph();

        // Search in the graph in case the source filter with correction file already exist
        hr = pFG->EnumFilters(&pEnumFilers);
        IF_FAIL_BREAK(hr);
        while(pEnumFilers->Next(1, &pSrcFilterCorr, 0) == S_OK)
        {
            HRESULT lhr;
            lhr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr);
            if(SUCCEEDED(lhr))
            {
                LPOLESTR pszFileNameCandidate = NULL;
                pFSFCorr->GetCurFile(&pszFileNameCandidate, NULL);
                if(memcmp(pszFileNameCandidate,pszFileNameC,(cch+1)*sizeof(WCHAR)) == 0)
                {
                    // This is the good file
                    bSrcFileAlreadyLoaded = TRUE;
                    if(pszFileNameCandidate != NULL)
                    {
                        CoTaskMemFree(pszFileNameCandidate);
                    }
                    break;
                }
                if(pszFileNameCandidate != NULL)
                {
                    CoTaskMemFree(pszFileNameCandidate);
                }
            }
            pSrcFilterCorr->Release();
            pSrcFilterCorr = NULL;
        }

        if(bSrcFileAlreadyLoaded == FALSE)
        {        
            // Create new file source filter
            hr = CoCreateInstance(CLSID_AsyncReader,
                NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
                (void**)&pSrcFilterCorr);
            IF_FAIL_BREAK(hr);
        
            hr = pFG->AddFilter(pSrcFilterCorr, pszFileNameC);
            IF_FAIL_BREAK(hr);
        
            hr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr);
            IF_FAIL_BREAK(hr);

            hr = pFSFCorr->Load(pszFileNameC, NULL);
            IF_FAIL_BREAK(hr);
        }
        
        // Get first pin and connect it
        hr = pSrcFilterCorr->EnumPins(&pEnum);
        IF_FAIL_BREAK(hr);
        if(pEnum->Next(1, &pPinNew, 0) == S_OK)
        {            
            hr = pFG->ConnectDirect(pPinNew, m_pInputPinCorr, NULL);
            bCorrectionFileLoaded = SUCCEEDED(hr);
        }
        
    } while(0);
    
    if((bCorrectionFileLoaded == FALSE) && (pSrcFilterCorr != NULL))
    {
        IFilterGraph* pFG = GetFilterGraph();
        pFG->RemoveFilter(pSrcFilterCorr);
    }

    // Cleanup
    SAFE_RELEASE(pPinNew);
    SAFE_RELEASE(pEnum);
    SAFE_RELEASE(pEnumFilers);
    SAFE_RELEASE(pFSFCorr);
    SAFE_RELEASE(pSrcFilterCorr);
    if(pszFileName != NULL)
    {
        CoTaskMemFree(pszFileName);
    }
    SAFE_RELEASE(pFSF);
    SAFE_RELEASE(pPinOutSrc);
    
#undef IF_FAIL_BREAK
    
    m_bDontTryToLoadCorrectionFileAgain = bCorrectionFileLoaded;

    if(bCorrectionFileLoaded)
    {
        DebugLog("<=== Leaving TryToLoadCorrectionFile successfull 0x%08X", GetCurrentThreadId());
    }
    else
    {
        DebugLog("<=== Leaving TryToLoadCorrectionFile FAILED 0x%08X", GetCurrentThreadId());
    }

    return hr;
}
STDMETHODIMP CTsReaderFilter::Pause()
{
  //m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO;
  //m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO;

  LogDebug("CTsReaderFilter::Pause() - IsTimeShifting = %d - state = %d", IsTimeShifting(), m_State);
  CAutoLock cObjectLock(m_pLock);

  if (m_State == State_Running)
  {
    m_lastPause = GetTickCount();
    m_RandomCompensation = 0;
  }

  //pause filter
  HRESULT hr=CSource::Pause();

  if (!m_bPauseOnClockTooFast)
  {
    //are we using rtsp?
    if (m_fileDuration==NULL)
    {
    //yes, are we busy seeking?
    if (!IsSeeking())
    {
      //not seeking, is rtsp streaming at the moment?
      if (!m_rtspClient.IsRunning())
      {
        //not streaming atm
        double startTime=m_seekTime.Millisecs();
        startTime/=1000.0;

        long Old_rtspDuration = m_rtspClient.Duration() ;
        //clear buffers
        LogDebug("  -- Pause()  ->start rtsp from %f", startTime);
        m_buffer.Clear();
        m_demultiplexer.Flush();

        //start streaming
        m_buffer.Run(true);
        m_rtspClient.Play(startTime,0.0);
//        m_tickCount = GetTickCount();
        LogDebug("  -- Pause()  ->rtsp started");

        //update the duration of the stream
        CPcr pcrStart, pcrEnd, pcrMax ;
        double duration = m_rtspClient.Duration() / 1000.0f ;

        if (m_bTimeShifting)
        {
          // EndPcr is continuously increasing ( until ~26 hours for rollover that will fail ! )
          // So, we refer duration to End, and just update start.
          pcrEnd   = m_duration.EndPcr() ;
          double start  = pcrEnd.ToClock() - duration;
	        if (start<0) start=0 ;
          pcrStart.FromClock(start) ;
          m_duration.Set( pcrStart, pcrEnd, pcrMax) ;     // Pause()-RTSP
        }
        else
        {
          // It's a record, eventually end can increase if recording is in progress, let the end virtually updated by ThreadProc()
          //m_bRecording = (Old_rtspDuration != m_rtspClient.Duration()) ;
          m_bRecording = true; // duration may have not increased in such a short time
        }
        LogDebug("Timeshift %d, Recording %d, StartPCR %f, EndPcr %f, Duration %f",m_bTimeShifting,m_bRecording,m_duration.StartPcr().ToClock(),m_duration.EndPcr().ToClock(),(float)m_duration.Duration().Millisecs()/1000.0f) ;
      }
      else
      {
        //we are streaming at the moment.
       
        //query the current position, so it can resume on un-pause at this position
        //can be required in multiseat with rtsp when changing audio streams 
        IMediaSeeking * ptrMediaPos;
        if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos)))
        {
          ptrMediaPos->GetCurrentPosition(&m_seekTime.m_time);
          ptrMediaPos->Release();
        }
        //pause the streaming
        LogDebug("  -- Pause()  ->pause rtsp at position: %f", (m_seekTime.Millisecs() / 1000.0f));
        m_rtspClient.Pause();
      }
    }
    else //we are seeking
    {
      IMediaSeeking * ptrMediaPos;

      if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos)))
      {
        LONGLONG currentPos;
        ptrMediaPos->GetCurrentPosition(&currentPos);
        ptrMediaPos->Release();
        double clock = currentPos;clock /= 10000000.0;
        float clockEnd = m_duration.EndPcr().ToClock() ;
        if (clock >= clockEnd && clockEnd > 0 )
        {
          LogDebug("End of rtsp stream...");
          m_demultiplexer.SetEndOfFile(true);
        }
      }
    }
    }
    m_demultiplexer.m_LastDataFromRtsp = GetTickCount() ;
  }

  //is the duration update thread running?
  if (!IsThreadRunning())
  {
    //nop? then start it
    //LogDebug("  CTsReaderFilter::Pause()->start duration thread");
    StartThread();
  }

  LogDebug("CTsReaderFilter::Pause() - END - state = %d", m_State);
  return hr;
}
Example #11
0
DWORD WINAPI CBDReaderFilter::CommandThread()
{
  SetThreadName(-1, "BDReader_COMMAND");
  
  IFilterGraph* pGraph = NULL;

  pGraph = GetFilterGraph();

  if (pGraph)
  {
    pGraph->QueryInterface(&m_pMediaSeeking);
    pGraph->Release();
  }

  HANDLE handles[2];
  handles[0] = m_hStopCommandThreadEvent;
  handles[1] = m_hCommandEvent;

  if (m_pMediaSeeking)
  {
    while(1)
    {
      //DWORD result = WaitForMultipleObjects(2, handles, false, 40);
	    DWORD result = WaitForMultipleObjects(2, handles, false, INFINITE);
      if (result == WAIT_OBJECT_0) // exit event
      {
        LogDebug("CBDReaderFilter::Command thread: closing down");
        return 0;
      }
      /*
      else if (result == WAIT_TIMEOUT)
      {
        LONGLONG pos = 0;
        HRESULT hr = m_pMediaSeeking->GetCurrentPosition(&pos);
        if (SUCCEEDED(hr))
        {
          lib.ProvideUserInput(CONVERT_DS_90KHz(pos), BD_VK_NONE);
        }
      }
      */
      else if (result == WAIT_OBJECT_0 + 1) // command in queue
      {
        LONGLONG posEnd = 0;
        LONGLONG zeroPos = 0;

        m_pMediaSeeking->GetDuration(&posEnd);

        ivecCommandQueue it;
        DS_CMD cmd;

        { // just fetch the command and release the lock
          CAutoLock lock(&m_csCommandQueue);
          it = m_commandQueue.begin();
          cmd = (*it);
          m_commandQueue.erase(it);
          if (m_commandQueue.empty())
          {
            ResetEvent(m_hCommandEvent);
          }
        }

        switch (cmd.id)
        {
        case REBUILD:
          {
            LogDebug("CBDReaderFilter::Command thread: issue rebuild!");
          
            LONGLONG pos = 0;
            if (cmd.refTime.m_time < 0)
            {
              CAutoLock lock(&m_csClock);
              pos = m_rtCurrentTime;
            }
            else
              pos = cmd.refTime.m_time;

            m_eRebuild.Reset();
            TriggerOnMediaChanged();
            m_eRebuild.Wait();

            if (m_bRebuildOngoing)
            {
              LogDebug("CBDReaderFilter::Command thread: graph rebuild has failed?");
              return 0;
            }

            m_bUpdateStreamPositionOnly = true;

            LogDebug("CBDReaderFilter::Command thread: seek - pos: %06.3f (rebuild)", cmd.refTime.Millisecs() / 1000.0);
            m_pMediaSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_FakeSeek, &posEnd, AM_SEEKING_NoPositioning);

            m_eSeekDone.Wait();
            m_eSeekDone.Reset();

            m_demultiplexer.SetMediaChanging(false);
            m_demultiplexer.m_bRebuildOngoing = false;

            break;
		      }

        case SEEK:
          m_bUpdateStreamPositionOnly = true;
          
          LogDebug("CBDReaderFilter::Command thread: seek requested - pos: %06.3f", cmd.refTime.Millisecs() / 1000.0);
          HRESULT hr = m_pMediaSeeking->SetPositions((LONGLONG*)&cmd.refTime.m_time, AM_SEEKING_AbsolutePositioning | AM_SEEKING_FakeSeek, &posEnd, AM_SEEKING_NoPositioning);

          m_eSeekDone.Wait();
          m_eSeekDone.Reset();

          break;
        }
      }
      else
      {
        DWORD error = GetLastError();
        LogDebug("CBDReaderFilter::Command thread: WaitForMultipleObjects failed: %d", error);
      }
    }
  }

  return 0;
}