HRESULT CTedTestMediaTypeHandler::SetCurrentMediaType(IMFMediaType* pMediaType)
{
    if(NULL == pMediaType)
    {
        return E_POINTER;
    }

    HRESULT hr = S_OK;
    if(FAILED(IsMediaTypeSupported(pMediaType, NULL)))
    {
        return hr;
    }

    m_spCurrentType = pMediaType;

    return S_OK;
}
Ejemplo n.º 2
0
// Attempts to set an output type on the mixer.
HRESULT EVRCustomPresenter::RenegotiateMediaType()
{
  Log("EVRCustomPresenter::RenegotiateMediaType");

  HRESULT hr = S_OK;
  BOOL bFoundMediaType = FALSE;

  IMFMediaType *pMixerType = NULL;
  IMFMediaType *pOptimalType = NULL;
  IMFVideoMediaType *pVideoType = NULL;

  CheckPointer(m_pMixer, MF_E_INVALIDREQUEST);

  // Loop through all of the mixer's proposed output types.
  DWORD iTypeIndex = 0;
  while (!bFoundMediaType && (hr != MF_E_NO_MORE_TYPES))
  {
    SAFE_RELEASE(pMixerType);
    SAFE_RELEASE(pOptimalType);

    // Step 1. Get the next media type supported by mixer.
    hr = m_pMixer->GetOutputAvailableType(0, iTypeIndex++, &pMixerType);
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType no usable media type found");
      break;
    }

    // From now on, if anything in this loop fails, try the next type, until we succeed or the mixer runs out of types.

    // Step 2. Check if we support this media type. 
    hr = IsMediaTypeSupported(pMixerType);
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType EVRCustomPresenter::IsMediaTypeSupported failed");
      continue;
    }

    // Step 3. Adjust the mixer's type to match our requirements.
    hr = CreateOptimalVideoType(pMixerType, &pOptimalType);
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType EVRCustomPresenter::CreateOptimalVideoType failed");
      continue;
    }

    // Step 4. Check if the mixer will accept this media type.
    hr = m_pMixer->SetOutputType(0, pOptimalType, MFT_SET_TYPE_TEST_ONLY);
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType IMFTransform::SetOutputType");
      continue;
    }

    // Step 5. Try to set the media type on ourselves.
    hr = SetMediaType(pOptimalType);
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType EVRCustomPresenter::SetMediaType failed");
      continue;
    }

    // Step 6. Set output media type on mixer.
    hr = m_pMixer->SetOutputType(0, pOptimalType, 0);
    assert(SUCCEEDED(hr)); // This should succeed unless the MFT lied in the previous call.
    if (FAILED(hr))
    {
      Log("EVRCustomPresenter::RenegotiateMediaType IMFTransform::SetOutputType failed");
      SetMediaType(NULL);
      continue;
    }

    // valid media type found and output set, exit loop
    bFoundMediaType = TRUE;
  }

  SAFE_RELEASE(pMixerType);
  SAFE_RELEASE(pOptimalType);
  SAFE_RELEASE(pVideoType);

  return hr;
}
Ejemplo n.º 3
0
bool WinCaptureDevice::InitializeFirst(std::string& error)
{
	HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
	if (!SUCCEEDED(hr))
	{
		return false;
		error = "CoInitializeEx failed";
	}

	hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
	if (!SUCCEEDED(hr))
	{
		error = "MFStartup failed";
		return false;
	}

	Close();

	memset(&InputType, 0, sizeof(InputType));

	IMFActivate* activate = WinCaptureDevice::ChooseFirst(error);
	if (!activate)
		return false;

	IMFMediaSource  *pSource = NULL;
	IMFAttributes   *pAttributes = NULL;
	IMFMediaType    *pType = NULL;

	UINT32 m_cchSymbolicLink = 0;

	// Create the media source for the device.
	if (SUCCEEDED(hr))
		hr = activate->ActivateObject(__uuidof(IMFMediaSource), (void**) &pSource);

	// Get the symbolic link.
	if (SUCCEEDED(hr))
		hr = activate->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &SymbolicLink, &m_cchSymbolicLink);

	//
	// Create the source reader.
	//

	// Create an attribute store to hold initialization settings.

	if (SUCCEEDED(hr))
		hr = MFCreateAttributes(&pAttributes, 2);

	if (SUCCEEDED(hr))
		hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE);

	// Set the callback pointer.
	if (SUCCEEDED(hr))
		hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this);

	if (SUCCEEDED(hr))
		hr = MFCreateSourceReaderFromMediaSource(pSource, pAttributes, &Reader);

	// Try to find a suitable input type.
	if (SUCCEEDED(hr))
	{
		for (uint i = 0; ; i++)
		{
			hr = Reader->GetNativeMediaType((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, i, &pType);
			if (FAILED(hr))
			{
				error = "Failed to find a supported output format (ie RGB24)";
				break;
			}
			memset(&InputType, 0, sizeof(InputType));
			bool isTypeOK = IsMediaTypeSupported(pType, InputType);
			if (isTypeOK)
			{
				// Get the frame size.
				hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &InputWidth, &InputHeight);
				// Get the image stride.
				hr = GetDefaultStride(pType, &InputDefaultStride);
				// Get the interlace mode. Default: assume progressive.
				InputInterlaceMode = (MFVideoInterlaceMode) MFGetAttributeUINT32(pType, MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
			}
			SafeRelease(&pType);
			if (isTypeOK)
				break;
		}
	}

	if (SUCCEEDED(hr))
	{
		// Ask for the first sample.
		EnableCapture = 1;
		hr = Reader->ReadSample((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL);
	}

	if (FAILED(hr))
	{
		if (pSource)
		{
			pSource->Shutdown();
			// NOTE: The source reader shuts down the media source by default, but we might not have gotten that far.
		}
		Close();
	}

	SafeRelease(&pSource);
	SafeRelease(&pAttributes);
	SafeRelease(&pType);
	SafeRelease(&activate);

	if (FAILED(hr) && error.length() == 0)
		error = ErrorMessage(L"Failed to initialize video capture device", hr);

	return SUCCEEDED(hr);
}