Ejemplo n.º 1
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; 
}
Ejemplo n.º 2
0
HRESULT STDMETHODCALLTYPE CVCamPin::SetFormat(AM_MEDIA_TYPE *pmt)
{
    DECLARE_PTR(VIDEOINFOHEADER, pvi, m_mt.pbFormat);
    m_mt = *pmt;
    IPin* pin; 
    ConnectedTo(&pin);
    if(pin)
    {
        IFilterGraph *pGraph = m_pParent->GetGraph();
        pGraph->Reconnect(this);
    }
    return S_OK;
}
Ejemplo n.º 3
0
//
// OnConnect
//
// Called when the property page connects to a filter
//
HRESULT CProgramProperties::OnConnect(IUnknown *pUnknown)
{
    ASSERT(m_pProgram == NULL);
    CheckPointer(pUnknown,E_POINTER);

    HRESULT hr = pUnknown->QueryInterface(IID_IMpeg2PsiParser, (void **) &m_pProgram);
    if(FAILED(hr))
    {
        return E_NOINTERFACE;
    }
    ASSERT(m_pProgram);

    IBaseFilter * pParserFilter ;
    hr = m_pProgram->QueryInterface(IID_IBaseFilter, (void **) &pParserFilter);
    RETURN_FALSE_IF_FAILED(TEXT("CProgramProperties::OnUpdate() QueryInterface() failed."), hr);

    FILTER_INFO Info;
    IFilterGraph * pGraph;
    hr = pParserFilter->QueryFilterInfo(&Info);

    RETURN_FALSE_IF_FAILED(TEXT("CProgramProperties::OnUpdate() QueryFilterInfo() failed."), hr);
    pGraph = Info.pGraph;
    pParserFilter->Release();

    hr = pGraph->QueryInterface(IID_IGraphBuilder, (void **) & m_pGraphBuilder);
    RETURN_FALSE_IF_FAILED(TEXT("CProgramProperties::OnUpdate() QueryInterface() failed."), hr);

    // get demux filter
    hr = GetDemuxFilter(pGraph, &m_pDemux);
    RETURN_FALSE_IF_FAILED(TEXT("CProgramProperties::OnUpdate() GetDemuxFilter() failed."), hr);
    pGraph->Release();

    // if there is no streaming, the following variables will not be initialized.
    if(m_pDemux != NULL && m_pGraphBuilder != NULL){
        hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **) & m_pMediaControl);
        RETURN_FALSE_IF_FAILED( TEXT(" CProgramProperties::OnUpdate():Failed to QI IMediaControl."), hr);

        // Get the initial Program value
        m_pProgram->GetTransportStreamId( &m_stream_id);
        m_pProgram->GetPatVersionNumber( &m_pat_version);
        m_pProgram->GetCountOfPrograms( &m_number_of_programs );

    }

    if(!OnUpdate())
        return FALSE;

    return NOERROR;
}
Ejemplo n.º 4
0
HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
{
	//m_mt is the media type of the pin (CMediaType)
	DECLARE_PTR(VIDEOINFOHEADER, pvi, m_mt.pbFormat); // Can probably change this to something more familiar
	m_mt = *pmt;
	IPin* pin;
	ConnectedTo(&pin);
	// if we are currently connected to a pin...
	if (pin)
	{
		IFilterGraph *pGraph = m_pParent->GetGraph(); // get the graph of the parent (What does that do?)
		pGraph->Reconnect(this); // connect the graph
	}
	return S_OK;
}
Ejemplo n.º 5
0
HRESULT STDMETHODCALLTYPE UVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
{
	if(!pmt) return E_POINTER;
	CAutoLock cAutoLock(m_pFilter->pStateLock());
	DECLARE_PTR(VIDEOINFOHEADER, pvi, m_mt.pbFormat);
	m_mt = *pmt;
	IPin* pin; 
	ConnectedTo(&pin);
	if(pin)
	{
		IFilterGraph *pGraph = m_pParent->GetGraph();
		pGraph->Reconnect(this);
	}
	return S_OK;
}
Ejemplo n.º 6
0
void CSubtitlePin::LogCurrentPosition()
{
  IFilterGraph* pGraph = m_pTsReaderFilter->GetFilterGraph();
  IMediaSeeking* pMediaSeeking( NULL );

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

  LONGLONG pos( 0 );
  pMediaSeeking->GetCurrentPosition( &pos );
  //pMediaSeeking->Release();
  float fPos = (float)pos;
  fPos = ( ( fPos / 10000000 ) );
  LogDebug("sub current position %f", fPos );
}
Ejemplo n.º 7
0
HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
{
	vcamLog(50, "CVCamStream::SetFormat");
    //DECLARE_PTR(VIDEOINFOHEADER, pvi, m_mt.pbFormat);
    m_mt = *pmt;
    IPin* pin; 
    ConnectedTo(&pin);
    if(pin)
    {
        IFilterGraph *pGraph = m_pParent->GetGraph();
        pGraph->Reconnect(this);
		vcamLog(50, "   CVCamStream::SetFormat returning S_OK (reconnected to graph)");
    } else {
		vcamLog(50, "   CVCamStream::SetFormat returning S_OK (pin not connected)");
	}
	SafeRelease(&pin);
    return S_OK;
}
Ejemplo n.º 8
0
HRESULT STDMETHODCALLTYPE XnVideoStream::SetFormat(AM_MEDIA_TYPE *pmt)
{
	XN_METHOD_START;

	XN_METHOD_CHECK_POINTER(pmt);
	if (pmt == NULL)
	{
		XN_METHOD_RETURN(E_INVALIDARG);
	}

	xnLogVerbose(XN_MASK_FILTER, "SetFormat was called");

	// check if this format is supported
	CMediaType mediaType(*pmt);
	int index = FindCapability(mediaType);
	if (index == -1)
	{
		XN_METHOD_RETURN(VFW_E_INVALIDMEDIATYPE);
	}

	// keep previous one (so we can rollback)
	int prevPreferred = m_nPreferredMode;

	// set the preferred mode
	m_nPreferredMode = index;

	// try to reconnect (if needed)
	IPin* pin; 
	ConnectedTo(&pin);
	if (pin)
	{
		IFilterGraph *pGraph = ((XnVideoSource*)m_pFilter)->GetGraph();
		HRESULT hr = pGraph->Reconnect(this);
		if (FAILED(hr))
		{
			// rollback
			m_nPreferredMode = prevPreferred;
			XN_METHOD_RETURN(hr);
		}
	}

	XN_METHOD_RETURN(S_OK);
}
HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)
{
	// this is them saying you "must" use this type from now on...unless pmt is NULL that "means" reset...LODO handle it someday...
	if(!pmt) {
	  return S_OK; // *sure* we reset..yeah...sure we did...
	}
	
   if(CheckMediaType((CMediaType *) pmt) != S_OK) {
	return E_FAIL; // just in case :P [FME...]
   }
	
	m_mt = *pmt;

	IPin* pin; 
	ConnectedTo(&pin);
	if(pin)
	{
		IFilterGraph *pGraph = m_pParent->GetGraph();
		pGraph->Reconnect(this);
	}

    return S_OK;
}
// sets fps, size, (etc.) maybe, or maybe just saves it away for later use...
HRESULT STDMETHODCALLTYPE CPushPinDesktop::SetFormat(AM_MEDIA_TYPE *pmt)
{
    CAutoLock cAutoLock(m_pFilter->pStateLock());

	// I *think* it can go back and forth, then.  You can call GetStreamCaps to enumerate, then call
	// SetFormat, then later calls to GetMediaType/GetStreamCaps/EnumMediatypes will all "have" to just give this one
	// though theoretically they could also call EnumMediaTypes, then SetMediaType, and not call SetFormat
	// does flash call both? what order for flash/ffmpeg/vlc calling both?
	// LODO update msdn

	// "they" [can] call this...see msdn for SetFormat

	// NULL means reset to default type...
	if(pmt != NULL)
	{
		if(pmt->formattype != FORMAT_VideoInfo)  // same as {CLSID_KsDataTypeHandlerVideo} 
			return E_FAIL;
	
		// LODO I should do more here...http://msdn.microsoft.com/en-us/library/dd319788.aspx I guess [meh]
	    // LODO should fail if we're already streaming... [?]

		VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pmt->pbFormat;

		if(CheckMediaType((CMediaType *) pmt) != S_OK) {
			return E_FAIL; // just in case :P [did skype get here once?]
		}
		
        // for FMLE's benefit, only accept a setFormat of our "final" width [force setting via registry I guess, otherwise it only shows 80x60 whoa!]	    
		// flash media live encoder uses setFormat to determine widths [?] and then only displays the smallest? oh man that is messed up
        if( pvi->bmiHeader.biWidth != getCaptureDesiredFinalWidth() || 
           pvi->bmiHeader.biHeight != getCaptureDesiredFinalHeight())
        {
          return E_INVALIDARG;
        }

		// ignore other things like cropping requests for now...

		// now save it away...for being able to re-offer it later. We could use SetMediaType but we're just being lazy and re-using m_mt for many things I guess
	    m_mt = *pmt;  

		// The frame rate at which your filter should produce data is determined by the AvgTimePerFrame field of VIDEOINFOHEADER
	    if(pvi->AvgTimePerFrame)
	      m_rtFrameLength = pvi->AvgTimePerFrame; // allow them to set whatever fps they request, i.e. if it's less than the max default.  VLC command line can specify this, for instance...
	    // also setup scaling here, as WFMLE and ffplay and VLC all get here...
	    m_rScreen.right = m_rScreen.left + pvi->bmiHeader.biWidth; // allow them to set whatever "scaling size" they want [set m_rScreen is negotiated right here]
	    m_rScreen.bottom = m_rScreen.top + pvi->bmiHeader.biHeight;
	}

    IPin* pin;
    ConnectedTo(&pin);
    if(pin)
    {
        IFilterGraph *pGraph = m_pParent->GetGraph();
        HRESULT res = pGraph->Reconnect(this);
		if(res != S_OK) // LODO check first, and then just re-use the old one?
		  return res; // else return early...not really sure how to handle this...since we already set m_mt...but it's a pretty rare case I think...
		// plus ours is a weird case...
    } else {
		// graph hasn't been built yet...
		// so we're ok with "whatever" format they pass us, we're just in the setup phase...
	}
	


	// success of some type
	if(pmt == NULL) {		
		m_bFormatAlreadySet = false;
	} else {
		m_bFormatAlreadySet = true;
	}

    return S_OK;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
DWORD WINAPI PushDataThread(PVOID param)
{
	PushParam* pushParam = (PushParam*)param;
	HANDLE PushSemaphore = pushParam->PushSemaphore;
	HANDLE PushDataMutex = pushParam->PushDataMutex;
	NetReceiveFilter* filter = pushParam->filter;
	std::map<REFERENCE_TIME, IMediaSample*>& SampleList = *pushParam->SampleList;

	delete pushParam;

	REFERENCE_TIME startTime,endTime;
	CRefTime streamTime(LONG(0)),lastStreamTime(LONG(0));

	bool first = true;
	AM_MEDIA_TYPE mediaType;
	IMediaSample* sample ;

	while (SampleList.size() == 0) //等待足够多的数据
	{
		WaitForSingleObject(PushSemaphore,INFINITE);
	}

	CBasePin* pin = filter->GetPin(0);
	pin->ConnectionMediaType(&mediaType);
	IFilterGraph* filterGraph = filter->GetFilterGraph();
	ComReleaser filterGraphReleaser(filterGraph);

	HRESULT hr;
	IMediaControl* mediaControl;
	hr = filterGraph->QueryInterface(IID_IMediaControl, (void**)&mediaControl);
	if(FAILED(hr))
	{
		ErrorPrint("Get media control error", hr);
		return false;
	}
	ComReleaser mediaControlReleaser(mediaControl);

	while (true)
	{
		WaitForSingleObject(PushDataMutex, INFINITE);
		if (filter->getPlayMode() == 0) // 如果只是尽快播放,则不考虑时间戳,而且一次一sample的往下传
		{
			if (SampleList.size() == 0)
			{
				ReleaseMutex(PushDataMutex);
				while (SampleList.size() == 0)
				{
					WaitForSingleObject(PushSemaphore,INFINITE);
				}
				WaitForSingleObject(PushDataMutex, INFINITE);
			}
			sample = SampleList.begin()->second;
		}
		else if (filter->getPlayMode() == 1) //需要考虑时间戳
		{
			NetReceiveFilter::State state = filter->getState();
			if (SampleList.size() == 0)
			{
				g_ReferenceTimeFilter->pauseTime(); //暂停时钟
				ReleaseMutex(PushDataMutex);
				while (SampleList.size() == 0) //等待足够多的数据
				{
					WaitForSingleObject(PushSemaphore,INFINITE);
				}
				WaitForSingleObject(PushDataMutex, INFINITE);
				g_ReferenceTimeFilter->startTime(); //启动时钟

			}

			if (state == NetReceiveFilter::Stopped)
			{
				ReleaseMutex(PushDataMutex);
				Sleep(50);
				continue;
			}

			if(g_ReferenceTimeFilter->isStop())
			{
				ReleaseMutex(PushDataMutex);
				Sleep(50);
				continue;
			}

			sample = SampleList.begin()->second;
			sample->GetTime(&startTime,&endTime);
			filter->StreamTime(streamTime); //得到当前的流时间
			g_ReferenceTimeFilter->GetTime(&startTime);
			g_ReferenceTimeFilter->GetTime(&endTime);

			if (mediaType.majortype == MEDIATYPE_Video)
			{
				int a = 0;
			}
			else
			{
				int b = 0;
			}

			if(state != NetReceiveFilter::Paused) //pause时不修正
			{
				if(startTime - 10000000 > streamTime )
				{
					ReleaseMutex(PushDataMutex);
					Sleep(50);
					continue;
				}
				sample->SetTime(&startTime, &endTime);
			}
			

			if (mediaType.majortype == MEDIATYPE_Video)
			{
				int a = 0;
			}
			else
			{
				int b = 0;
			}

		}
// 		if (mediaType.majortype == MEDIATYPE_Video)
// 		{
// 			std::cout<<"Push video data."<<std::endl;
// 		}
		SampleList.erase(SampleList.begin());
		ReleaseMutex(PushDataMutex);
		if(!filter->PushData(sample))
		{
			ErrorPrint("Push data error");
			sample->Release();
			continue;
		}
		sample->Release();
	}
	return 0;
}
Ejemplo n.º 13
0
HRESULT fsPartMediaPlayer::Open(HANDLE hFile, UINT64 uMaxAvail)
{
	HRESULT hr;

	Close ();

	
	m_stream.Attach (hFile, uMaxAvail);

	
	if (m_stream.Get_MediaType () == NULL)
		return E_FAIL;

	m_reader.Set_MediaType (m_stream.Get_MediaType ());

	

	RIF (CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
		IID_IGraphBuilder, (void**) &m_pGB));

	IFilterGraph* pFG = NULL;
	RIF (m_pGB->QueryInterface (IID_IFilterGraph, (void**)&pFG));

	RIF (pFG->AddFilter (&m_reader, NULL));
	pFG->Release ();

	RIF (m_pGB->Render (m_reader.GetPin (0)));

	RIF (m_pGB->QueryInterface (IID_IMediaControl, (void**)&m_pMC));
	RIF (m_pGB->QueryInterface (IID_IMediaEventEx, (void**)&m_pME));
	RIF (m_pGB->QueryInterface (IID_IMediaSeeking, (void**)&m_pMS));
	
	m_pGB->QueryInterface (IID_IVideoWindow, (void**)&m_pVW);
	m_pGB->QueryInterface (IID_IBasicAudio, (void**)&m_pBA);

	IBasicVideo* pBV = NULL;
	m_pGB->QueryInterface (IID_IBasicVideo, (void**) &pBV);
	if (pBV != NULL)
	{
		long nW, nH;
		pBV->get_VideoWidth (&nW);
		pBV->get_VideoHeight (&nH);
		m_fVideoRatio = (double)nW / nH;
		pBV->Release ();
	}
	else
	{
		m_fVideoRatio = 1;
	}

	if (m_pVW)
	{
		if (FAILED (m_pVW->put_MessageDrain ((OAHWND)m_hOutWnd)))
		{
			SAFE_RELEASE (m_pVW);
		}
	}

	RIF (m_pME->SetNotifyWindow ((OAHWND)m_hOutWnd, WM_VIDEONOTIFY, LONG(this)));

	if (m_pVW)
	{
		m_pVW->put_Visible (OAFALSE);
		m_pVW->put_WindowStyle (WS_CHILD);
		m_pVW->put_Owner ((OAHWND)m_hOutWnd);

		AutoSize ();

		m_pVW->put_Visible (OATRUE);

		m_pVW->SetWindowForeground (-1);
	}

	m_state = VFPS_STOPPED;

	return S_OK;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
HRESULT TffdshowVideoInputPin::CheckMediaType(const CMediaType* mt)
{
    if (mt->majortype != MEDIATYPE_Video && !(mt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK && supdvddec)) {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (mt->subtype == MEDIASUBTYPE_DVD_SUBPICTURE) {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    BITMAPINFOHEADER *hdr = NULL, hdr0;

    if (mt->formattype == FORMAT_VideoInfo) {
        VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)mt->pbFormat;
        hdr = &vih->bmiHeader;
        fixMPEGinAVI(hdr->biCompression);
    } else if (mt->formattype == FORMAT_VideoInfo2) {
        VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)mt->pbFormat;
        hdr = &vih2->bmiHeader;
        fixMPEGinAVI(hdr->biCompression);
    } else if (mt->formattype == FORMAT_MPEGVideo) {
        MPEG1VIDEOINFO *mpeg1info = (MPEG1VIDEOINFO*)mt->pbFormat;
        hdr = &(hdr0 = mpeg1info->hdr.bmiHeader);
        hdr->biCompression = FOURCC_MPG1;
    } else if (mt->formattype == FORMAT_MPEG2Video) {
        MPEG2VIDEOINFO *mpeg2info = (MPEG2VIDEOINFO*)mt->pbFormat;
        hdr = &(hdr0 = mpeg2info->hdr.bmiHeader);
        if (hdr->biCompression == 0 || hdr->biCompression == 0x0038002d) {
            if (mt->subtype == MEDIASUBTYPE_H264_TRANSPORT) {
                hdr->biCompression = FOURCC_H264;
            } else if (mt->subtype == MEDIASUBTYPE_AVC1 || mt->subtype == MEDIASUBTYPE_avc1 || mt->subtype == MEDIASUBTYPE_H264 || mt->subtype == MEDIASUBTYPE_h264 || mt->subtype == MEDIASUBTYPE_CCV1) {
                hdr->biCompression = FOURCC_H264;
            } else {
                hdr->biCompression = FOURCC_MPG2;
            }
        }
    } else if (mt->formattype == FORMAT_TheoraIll) {
        sTheoraFormatBlock *oggFormat = (sTheoraFormatBlock*)mt->pbFormat;
        hdr = &hdr0;
        hdr->biWidth = oggFormat->width;
        hdr->biHeight = oggFormat->height;
        hdr->biCompression = FOURCC_THEO;
    } else if (mt->formattype == FORMAT_RLTheora) {
        hdr = &hdr0;
        hdr->biCompression = FOURCC_THEO;
    } else {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    char_t pomS[60];
    DPRINTF(_l("TffdshowVideoInputPin::CheckMediaType: %s, %i, %i"), fourcc2str(hdr2fourcc(hdr, &mt->subtype), pomS, 60), hdr->biWidth, hdr->biHeight);

    /* Information : WMP 11 and Media Center under Vista do not check for uncompressed format anymore, so no way to get
       ffdshow raw video decoder for postprocessing on uncompressed.
       So instead of saying "Media Type not supported", we says it is but only if there is an existing filter that can
       take this format in charge, and then ffdshow will be plugged after this codec (plug is done by TffdshowDecVideo::ConnectCompatibleFilter). */
    int res = getVideoCodecId(hdr, &mt->subtype, NULL);

    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osvi);
    ffstring exeFilename(fv->getExefilename());
    exeFilename.ConvertToLowerCase();

    if (res == 0 && pCompatibleFilter == NULL &&
            fv->deci->getParam2(IDFF_alternateUncompressed) == 1 && // Enable WMP11 postprocessing
            fv->deci->getParam2(IDFF_rawv) != 0 && // Raw video not on disabled
            (exeFilename == _l("wmplayer.exe") ||
             exeFilename == _l("ehshell.exe"))) { // Only WMP and Media Center are concerned
        bool doPostProcessing = false;
        if (osvi.dwMajorVersion > 5) { // OS >= VISTA
            doPostProcessing = true;
        } else if (osvi.dwMajorVersion == 5 // If OS=XP, check version of WMP
                   && exeFilename == _l("ehshell.exe")) { // But only for Media Center
            // Read WMP version from the aRegistry
            HKEY hKey = NULL;
            LONG regErr;

            // Read WMP version from the following registry key
            regErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _l("SOFTWARE\\Microsoft\\MediaPlayer\\Setup\\Installed Versions"), 0, KEY_READ, &hKey);
            if (regErr != ERROR_SUCCESS) {
                return res == AV_CODEC_ID_NONE ? VFW_E_TYPE_NOT_ACCEPTED : S_OK;
            }

            DWORD dwType;
            BYTE buf[4096] = { '\0' };   // make it big enough for any kind of values
            DWORD dwSize = sizeof(buf);
            regErr = RegQueryValueEx(hKey, _T("wmplayer.exe"), 0, &dwType, buf, &dwSize);

            if (hKey) {
                RegCloseKey(hKey);
            }

            if (regErr != ERROR_SUCCESS || dwType != REG_BINARY) {
                return res == AV_CODEC_ID_NONE ? VFW_E_TYPE_NOT_ACCEPTED : S_OK;
            }

            if (buf[2] >= 0x0b) { // Third byte is the major version number
                doPostProcessing = true;
            }
        }


        if (doPostProcessing) {
            DPRINTF(_l("TffdshowVideoInputPin::CheckMediaType: input format disabled or not supported. Trying to maintain in the graph..."));
            IFilterMapper2 *pMapper = NULL;
            IEnumMoniker *pEnum = NULL;

            HRESULT hr = CoCreateInstance(CLSID_FilterMapper2,
                                          NULL, CLSCTX_INPROC, IID_IFilterMapper2,
                                          (void **) &pMapper);

            if (FAILED(hr)) {
                // Error handling omitted for clarity.
            }

            GUID arrayInTypes[2];
            arrayInTypes[0] = mt->majortype;//MEDIATYPE_Video;
            arrayInTypes[1] = mt->subtype;//MEDIASUBTYPE_dvsd;

            hr = pMapper->EnumMatchingFilters(
                     &pEnum,
                     0,                  // Reserved.
                     TRUE,               // Use exact match?
                     MERIT_DO_NOT_USE + 1, // Minimum merit.
                     TRUE,               // At least one input pin?
                     1,                  // Number of major type/subtype pairs for input.
                     arrayInTypes,       // Array of major type/subtype pairs for input.
                     NULL,               // Input medium.
                     NULL,               // Input pin category.
                     FALSE,              // Must be a renderer?
                     TRUE,               // At least one output pin?
                     0,                  // Number of major type/subtype pairs for output.
                     NULL,               // Array of major type/subtype pairs for output.
                     NULL,               // Output medium.
                     NULL);              // Output pin category.

            // Enumerate the monikers.
            IMoniker *pMoniker;
            ULONG cFetched;

            while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK) {
                IPropertyBag *pPropBag = NULL;
                hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
                                             (void **)&pPropBag);

                if (SUCCEEDED(hr)) {
                    // To retrieve the friendly name of the filter, do the following:
                    VARIANT varName;
                    VariantInit(&varName);
                    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                    if (SUCCEEDED(hr)) {
                        if (varName.pbstrVal == NULL || _strnicmp(FFDSHOW_NAME_L, varName.bstrVal, 22) != 0) {
                            // Display the name in your UI somehow.
                            DPRINTF(_l("TffdshowVideoInputPin::CheckMediaType: compatible filter found (%s)"), varName.pbstrVal);
                            hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pCompatibleFilter);
                        }
                    }

                    // Now add the filter to the graph. Remember to release pFilter later.
                    IFilterGraph *pGraph = NULL;
                    fv->deci->getGraph(&pGraph);

                    IGraphBuilder *pGraphBuilder = NULL;
                    hr = pGraph->QueryInterface(IID_IGraphBuilder, (void **)&pGraphBuilder);
                    if (hr == S_OK) {
                        pGraphBuilder->AddFilter(pCompatibleFilter, varName.bstrVal);
                    } else {
                        pCompatibleFilter->Release();
                        pCompatibleFilter = NULL;
                    }

                    // Clean up.
                    VariantClear(&varName);
                    pGraphBuilder->Release();
                    pPropBag->Release();
                }
                pMoniker->Release();
                if (pCompatibleFilter != NULL) {
                    break;
                }
            }

            // Clean up.
            pMapper->Release();
            pEnum->Release();
        }
    }
    if (pCompatibleFilter != NULL) {
        return S_OK;
    }
    return res == AV_CODEC_ID_NONE ? VFW_E_TYPE_NOT_ACCEPTED : S_OK;
}