예제 #1
0
HRESULT FFmpegDecodeServices::SetInputMediaType(IMFMediaType* pMediaType)
{
	std::lock_guard<decltype(_mutex)> lock(_mutex);
	if (pMediaType == NULL) {
		_inputMediaType.Reset();
		_outputMediaType.Reset();
		return S_OK;
	}

	HRESULT hr = CheckMediaType(pMediaType);
	if (FAILED(hr))
		return hr;

	if (avcodec_find_decoder(ConvertGuidToCodecId(pMediaType)) == NULL)
		return E_ABORT;

	GUID majorType = GUID_NULL;
	pMediaType->GetGUID(MF_MT_MAJOR_TYPE, &majorType);
	if (majorType != MFMediaType_Video &&
		majorType != MFMediaType_Audio)
		return MF_E_INVALID_CODEC_MERIT;

	hr = (majorType == MFMediaType_Video ? InitVideoDecoder(pMediaType) : InitAudioDecoder(pMediaType));
	if (FAILED(hr))
		return hr;

	MFCreateMediaType(&_inputMediaType);
	pMediaType->CopyAllItems(_inputMediaType.Get());
	return S_OK;
}
예제 #2
0
ErrorCode BasePinImpl::QueryAccept(MediaType* pmt)
{
	ErrorCode hr = CheckMediaType(pmt);
	if (hr < 0)
		return 1;

	return hr;
}
예제 #3
0
HRESULT CAMROutputPin::SetMediaType(const CMediaType *pmt)
{
	// just set internal media type
	if (FAILED(CheckMediaType(pmt))) {
		return E_FAIL;
	}
	return CBaseOutputPin::SetMediaType(pmt);
}
// Set the agree media type set up the necessary parameters
HRESULT CScreenCaptureSourcePin::SetMediaType(const CMediaType *pMediaType)
{
	CHECK_POINTER_RETURN_VALUE_IF_FAIL(pMediaType, E_POINTER);
	if (NULL == pMediaType->Format())
	{
		return VFW_E_INVALIDMEDIATYPE;
	}
	HRESULT hr = E_FAIL;
	//CAutoLock cAutoLock(m_pFilter->pStateLock());

#ifdef _DEBUG
	DX_VERIFY(CheckMediaType(pMediaType));
	if (FAILED(hr))
	{
		return hr;
	}
#endif 

	{
		CAutoLock cAutoLock(m_pFilter->pStateLock());
	COM_VERIFY(__super::SetMediaType(pMediaType));
	if (SUCCEEDED(hr))
	{
		VIDEOINFO *pvi = (VIDEOINFO*)m_mt.Format();

		//ASSERT(m_iImageWidth == pvi->bmiHeader.biWidth);
        //ASSERT(m_iImageHeight == abs(pvi->bmiHeader.biHeight));
        //ASSERT(m_nCurrentBitDepth == pvi->bmiHeader.biBitCount);

		//CAutoLock cAutoLock(&m_cStateLock);
		//if (m_pScreenCaptureImpl)
		//{
		//	SAFE_DELETE(m_pScreenCaptureImpl);
		//}
			FTLASSERT(pvi->bmiHeader.biHeight > 0);
		FTLASSERT(pvi->bmiHeader.biWidth > 0);
		m_nWidth = pvi->bmiHeader.biWidth;
			m_nHeight = FTL_ABS(pvi->bmiHeader.biHeight);
		m_nBitCount = pvi->bmiHeader.biBitCount;

		m_nAvgTimePerFrame = pvi->AvgTimePerFrame;

		//m_bmpInfo.bmiHeader.biWidth = pvi->bmiHeader.biWidth;
		//m_bmpInfo.bmiHeader.biHeight = pvi->bmiHeader.biHeight;
		//m_bmpInfo.bmiHeader.biBitCount = m_nBitCount;
		//m_bmpInfo.bmiHeader.biCompression = BI_RGB;
		//m_bmpInfo.bmiHeader.biPlanes = 1;
		//m_bmpInfo.bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
		}
	}
	return NOERROR;
}
예제 #5
0
STDMETHODIMP
BasePin::ReceiveConnection(IPin * aPin,
                             const AM_MEDIA_TYPE *aMediaType)
{
  if (!aPin)
    return E_POINTER;

  if (!aMediaType)
    E_POINTER;

  CriticalSectionAutoEnter monitor(*mLock);

  if (IsConnected())
    return VFW_E_ALREADY_CONNECTED;

  if (!IsStopped())
    return VFW_E_NOT_STOPPED;

  HRESULT hr = CheckConnect(aPin);
  if (FAILED(hr)) {
    BreakConnect();
    return hr;
  }

  // See if subclass supports the specified media type.
  const MediaType* mediaType = reinterpret_cast<const MediaType*>(aMediaType);
  hr = CheckMediaType(mediaType);
  if (FAILED(hr)) {
    BreakConnect();
    return hr;
  }

  // Supported, set it.
  hr = SetMediaType(mediaType);
  if (FAILED(hr))
    return hr;

  // Complete the connection.
  mConnectedPin = aPin;
  // Give the subclass one last chance to refuse the connection.
  hr = CompleteConnect(aPin);
  if (FAILED(hr)) {
    // Subclass refused connection, fail...
    mConnectedPin = NULL;
    BreakConnect();
    return hr;
  }

  // It's all good, we're connected.
  return S_OK;
}
//--------------------------------------------------------------------
//
//--------------------------------------------------------------------
HRESULT DSFilterRenderStreamDSMediaSample::SetMediaType(const CMediaType *pmt)
{
    /*NWStreamBlockDSMediaSample* streamBlock = NEW NWStreamBlockDSMediaSample();
    streamBlock->init();

    // Set the time
    streamBlock->setTime(0);

    // Add the streamblock to the stream
    mStream->writeBlock(streamBlock,false);*/

    HRESULT hr = CheckMediaType(pmt);
    return hr;
}
예제 #7
0
HRESULT CAMRInputPin::SetMediaType(const CMediaType* pmt)
{
	// let the baseclass know
	if (FAILED(CheckMediaType(pmt))) {
		return E_FAIL;
	}

	HRESULT hr = CBasePin::SetMediaType(pmt);
	if (FAILED(hr)) {
		return hr;
	}

	return NOERROR;
}
예제 #8
0
STDMETHODIMP
BasePin::QueryAccept(const AM_MEDIA_TYPE *aMediaType)
{
  if (!aMediaType)
    return E_POINTER;

  // Defer to subclasses CheckMediaType() function. Map all errors to S_FALSE,
  // so that we match the spec for QueryAccept().

  if (FAILED(CheckMediaType((MediaType*)aMediaType)))
    return S_FALSE;

  return S_OK;
}
예제 #9
0
// Attempt to connect this pin to |aPin| using given media type.
HRESULT
BasePin::AttemptConnection(IPin* aPin,
                             const MediaType* aMediaType)
{
  CriticalSectionAutoEnter monitor(*mLock);

  // Ensure we can connect to the other pin. Gives subclasses a chance
  // to prevent connection.
  HRESULT hr = CheckConnect(aPin);
  if (FAILED(hr)) {
    BreakConnect();
    return hr;
  }

  // Ensure we can connect with this media type. This gives subclasses a
  // chance to abort the connection.
  hr = CheckMediaType(aMediaType);
  if (FAILED(hr))
    return hr;

  hr = SetMediaType(aMediaType);
  if (FAILED(hr))
    return hr;

  // Ask the other pin if it will accept a connection with our media type.
  hr = aPin->ReceiveConnection(static_cast<IPin*>(this), aMediaType);
  if (FAILED(hr))
    return hr;

  // Looks good so far, give subclass one final chance to refuse connection...
  mConnectedPin = aPin;
  hr = CompleteConnect(aPin);

  if (FAILED(hr)) {
    // Subclass refused the connection, inform the other pin that we're
    // disconnecting, and break the connection.
    aPin->Disconnect();
    BreakConnect();
    mConnectedPin = NULL;
    mMediaType.Clear();
    return VFW_E_TYPE_NOT_ACCEPTED;
  }

  // Otherwise, we're all good!
  return S_OK;
}
예제 #10
0
//////////////////////////////////////////////////////////////////////
// 入力ピンのメディアタイプチェック
HRESULT ThroughEx::CheckInputType(const CMediaType *mtIn)
{
    CheckPointer(mtIn,E_POINTER);

    // check this is a VIDEOINFOHEADER type

    if (*mtIn->FormatType() != FORMAT_VideoInfo) {
        return E_INVALIDARG;
    }

    // Can we transform this type

    if (CheckMediaType(mtIn)) {
        return NOERROR;
    }
    return E_FAIL;
}
예제 #11
0
ErrorCode BasePinImpl::ReceiveConnection(IPin *pConnector, MediaType* pMediaType)
{
	if (pConnector == NULL)
	{
		ASSERT(0);
		//return E_INVALIDARG;
		throw -1;
	}

	if (m_dir != PINDIR_INPUT)
	{
		ASSERT(0);
		return Error;
	}

	ErrorCode hr;

	hr = CheckConnect(pConnector);
	if (hr < 0)
	{
		BreakConnect();
		return hr;
	}

	hr = CheckMediaType(pMediaType);
	if (hr < 0)
	{
		BreakConnect();
		return hr;
	}

	// Is the order of these last two correct?

	SetMediaType(pMediaType);

	hr = CompleteConnect(pConnector);
	if (hr < 0)
	{
		// BreakConnect(); ??
		return hr;
	}

	return 0;
}
예제 #12
0
STDMETHODIMP
CBasePin::QueryAccept(
					  const AM_MEDIA_TYPE *pmt
					  )
{
	CheckPointer(pmt,E_POINTER);
	ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE));

	/* The CheckMediaType method is valid to return error codes if the media
	type is horrible, an example might be E_INVALIDARG. What we do here
	is map all the error codes into either S_OK or S_FALSE regardless */

	HRESULT hr = CheckMediaType((CMediaType*)pmt);
	if (FAILED(hr)) {
		return S_FALSE;
	}
	// note that the only defined success codes should be S_OK and S_FALSE...
	return hr;
}
예제 #13
0
ErrorCode BasePinImpl::AttemptConnection(IPin *pReceivePin, MediaType* mt)
{
	ErrorCode hr;

	//CheckConnect( Why Is this called here, it will be called multiple times if it's here?

	hr = CheckConnect(pReceivePin);
	if (hr < 0)
	{
		BreakConnect();
		return hr;
	}

	hr = CheckMediaType(mt);
	if (hr < 0)
	{
		BreakConnect();
		return hr;
	}

	hr = pReceivePin->ReceiveConnection(this, mt);
	if (hr < 0) return hr;

	hr = SetMediaType(mt);	// ?? Have this here??
	if (hr < 0)
	{
		BreakConnect();
		return hr;
	}

	hr = CompleteConnect(pReceivePin);
	if (hr < 0)
	{
		Disconnect();
		return hr;
	}

	return 0;
}
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;
}
예제 #16
0
STDMETHODIMP
CBasePin::ReceiveConnection(
							IPin * pConnector,      // this is the pin who we will connect to
							const AM_MEDIA_TYPE *pmt    // this is the media type we will exchange
							)
{
	CheckPointer(pConnector,E_POINTER);
	CheckPointer(pmt,E_POINTER);
	ValidateReadPtr(pConnector,sizeof(IPin));
	ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE));
	CComAutoLock cObjectLock(m_pLock);

#ifdef _DEBUG
	PIN_INFO PinInfo;

	if(!FAILED(pConnector->QueryPinInfo(&PinInfo)))
	{

		CEasyString PinName=PinInfo.achName;



		PrintSystemLog(0,"RecvPin:%s",(LPCTSTR)PinName);


		if(PinInfo.pFilter)
		{

			FILTER_INFO FilterInfo;
			if (!FAILED(PinInfo.pFilter->QueryFilterInfo(&FilterInfo)))
			{

				CLSID ClassID;

				PinInfo.pFilter->GetClassID(&ClassID);

				CEasyString FilterName=FilterInfo.achName;

				PrintSystemLog(0,"RecvPinFilter:%s",(LPCTSTR)FilterName);


				// The FILTER_INFO structure holds a pointer to the Filter Graph
				// Manager, with a reference count that must be released.
				if (FilterInfo.pGraph != NULL)
				{
					FilterInfo.pGraph->Release();
				}
			}

			PinInfo.pFilter->Release();
		}

		//MessageBox(NULL, (LPCTSTR)PinName, TEXT("Filter Name"), MB_OK);
	}

#endif

	/* Are we already connected */
	if (m_Connected) {
		return VFW_E_ALREADY_CONNECTED;
	}

	/* See if the filter is active */
	if (!IsStopped() && !m_bCanReconnectWhenActive) {
		return VFW_E_NOT_STOPPED;
	}

	HRESULT hr = CheckConnect(pConnector);
	if (FAILED(hr)) {
		// Since the procedure is already returning an error code, there
		// is nothing else this function can do to report the error.
		EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );


		return hr;
	}

	/* Ask derived class if this media type is ok */

	CMediaType * pcmt = (CMediaType*) pmt;
	hr = CheckMediaType(pcmt);
	if (hr != NOERROR) {
		// no -we don't support this media type

		// Since the procedure is already returning an error code, there
		// is nothing else this function can do to report the error.
		EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

		// return a specific media type error if there is one
		// or map a general failure code to something more helpful
		// (in particular S_FALSE gets changed to an error code)
		if (SUCCEEDED(hr) ||
			(hr == E_FAIL) ||
			(hr == E_INVALIDARG)) {
				hr = VFW_E_TYPE_NOT_ACCEPTED;
		}


		return hr;
	}

	/* Complete the connection */

	m_Connected = pConnector;
	m_Connected->AddRef();
	hr = SetMediaType(pcmt);
	if (SUCCEEDED(hr)) {
		hr = CompleteConnect(pConnector);
		if (SUCCEEDED(hr)) {


			return NOERROR;
		}
	}

	DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to set the media type or failed to complete the connection.")));
	m_Connected->Release();
	m_Connected = NULL;

	// Since the procedure is already returning an error code, there
	// is nothing else this function can do to report the error.
	EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );


	return hr;
}
예제 #17
0
STDMETHODIMP TffdshowVideoInputPin::ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt)
{
    HRESULT hr;
    DPRINTF(_l("TffdshowVideoInputPin::ReceiveConnection"));
    CAutoLock cObjectLock(m_pLock);
    const CLSID &ref = GetCLSID(pConnector);
    if (ref == CLSID_MPC_MatroskaSplitter || ref == CLSID_GabestMatroskaSplitter) {
        connectedSplitter = MPC_matroska_splitter;
    } else if (ref == CLSID_HaaliMediaSplitter) {
        connectedSplitter = Haali_Media_splitter;
    } else if (ref == CLSID_MPC_MpegSourceFilter || ref == CLSID_MPC_MpegSplitterFilter) {
        connectedSplitter = MPC_mpegSplitters;
    } else if (ref == CLSID_DVBSourceFilter) {
        connectedSplitter = DVBSourceFilter;
    } else if (ref == CLSID_PBDA_DTFilter) {
        connectedSplitter = PBDA_DTFilter;
    } else if (ref == CLSID_NeuviewSource) {
        connectedSplitter = NeuviewSource;
    }

#if 0
    PIN_INFO pininfo;
    FILTER_INFO filterinfo;
    pConnector->QueryPinInfo(&pininfo);
    if (pininfo.pFilter) {
        pininfo.pFilter->QueryFilterInfo(&filterinfo);
        DPRINTF(_l("TffdshowVideoInputPin::ReceiveConnection filter=%s pin=%s"), filterinfo.achName, pininfo.achName);
        if (filterinfo.pGraph) {
            filterinfo.pGraph->Release();
        }
        pininfo.pFilter->Release();
    }
    DPRINTF(_l("CLSID 0x%x,0x%x,0x%x"), ref.Data1, ref.Data2, ref.Data3);
    for (int i = 0; i < 8; i++) {
        DPRINTF(_l(",0x%2x"), ref.Data4[i]);
    }
#endif

    if (m_Connected) {
        CMediaType mt(*pmt);

        BITMAPINFOHEADER bih, bihCur;
        ExtractBIH(mt, &bih);
        ExtractBIH(m_mt, &bihCur);

        // HACK: for the intervideo filter, when it tries to change the pitch from 720 to 704...
        //if(bihCur.biWidth != bih.biWidth  && bihCur.biHeight == bih.biHeight)
        // return S_OK;

        return (CheckMediaType(&mt) != S_OK || SetMediaType(&mt) != S_OK/* || !initVideo(mt)*/)
               ? VFW_E_TYPE_NOT_ACCEPTED
               : S_OK;

        // TODO: send ReceiveConnection downstream
    } else {
        hr = fv->deci->checkInputConnect(pConnector);
        if (hr != S_OK) {
            return hr;
        }
    }

    hr = TinputPin::ReceiveConnection(pConnector, pmt);
    return hr;
}
HRESULT CWaveOutRenderer::CheckInputType(const CMediaType* mtIn)
{
    return CheckMediaType(mtIn);
}
예제 #19
0
HRESULT CMpcAudioRenderer::CheckInputType(const CMediaType *pmt)
{
    return CheckMediaType(pmt);
}
예제 #20
0
// given a specific media type, attempt a connection (includes
// checking that the type is acceptable to this pin)
HRESULT
CBasePin::AttemptConnection(
							IPin* pReceivePin,      // connect to this pin
							const CMediaType* pmt   // using this type
							)
{
	// The caller should hold the filter lock becasue this function
	// uses m_Connected.  The caller should also hold the filter lock
	// because this function calls SetMediaType(), IsStopped() and
	// CompleteConnect().
	ASSERT(CritCheckIn(m_pLock));

	// Check that the connection is valid  -- need to do this for every
	// connect attempt since BreakConnect will undo it.
	HRESULT hr = CheckConnect(pReceivePin);
	if (FAILED(hr)) {
		DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("CheckConnect failed")));

		// Since the procedure is already returning an error code, there
		// is nothing else this function can do to report the error.
		EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

		return hr;
	}

	DisplayTypeInfo(pReceivePin, pmt);

	/* Check we will accept this media type */

	hr = CheckMediaType(pmt);
	if (hr == NOERROR) {

		/*  Make ourselves look connected otherwise ReceiveConnection
		may not be able to complete the connection
		*/
		m_Connected = pReceivePin;
		m_Connected->AddRef();
		hr = SetMediaType(pmt);
		if (SUCCEEDED(hr)) {
			/* See if the other pin will accept this type */

			hr = pReceivePin->ReceiveConnection((IPin *)this, pmt);
			if (SUCCEEDED(hr)) {
				/* Complete the connection */

				hr = CompleteConnect(pReceivePin);
				if (SUCCEEDED(hr)) {
					return hr;
				} else {
					DbgLog((LOG_TRACE,
						CONNECT_TRACE_LEVEL,
						TEXT("Failed to complete connection")));
					pReceivePin->Disconnect();
				}
			}
		}
	} else {
		// we cannot use this media type

		// return a specific media type error if there is one
		// or map a general failure code to something more helpful
		// (in particular S_FALSE gets changed to an error code)
		if (SUCCEEDED(hr) ||
			(hr == E_FAIL) ||
			(hr == E_INVALIDARG)) {
				hr = VFW_E_TYPE_NOT_ACCEPTED;
		}
	}

	// BreakConnect and release any connection here in case CheckMediaType
	// failed, or if we set anything up during a call back during
	// ReceiveConnection.

	// Since the procedure is already returning an error code, there
	// is nothing else this function can do to report the error.
	EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

	/*  If failed then undo our state */
	if (m_Connected) {
		m_Connected->Release();
		m_Connected = NULL;
	}

	return hr;
}