Esempio n. 1
0
HRESULT Outpin::Connect(
    IPin* pin,
    const AM_MEDIA_TYPE* pmt)
{
    if (pin == 0)
        return E_POINTER;

    GraphUtil::IMemInputPinPtr pInputPin;

    HRESULT hr = pin->QueryInterface(&pInputPin);

    if (hr != S_OK)
        return hr;

    Filter::Lock lock;

    hr = lock.Seize(m_pFilter);

    if (FAILED(hr))
        return hr;

    if (m_pFilter->m_state != State_Stopped)
        return VFW_E_NOT_STOPPED;

    if (m_connection)
        return VFW_E_ALREADY_CONNECTED;

    m_connection_mtv.Clear();

    if (pmt)
    {
        hr = QueryAccept(pmt);

        if (hr != S_OK)
            return VFW_E_TYPE_NOT_ACCEPTED;

        //The media type could me only a partial match,
        //so we need to fill it in before attemping
        //to use it.

        const ULONG n = m_preferred_mtv.Size();
        LONG idx = -1;

        for (ULONG i = 0; i < n; ++i)
        {
            const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

            if (pmt->subtype == mt.subtype)
            {
                idx = i;
                break;
            }
        }

        if (idx < 0)  //weird
            return VFW_E_TYPE_NOT_ACCEPTED;

        const AM_MEDIA_TYPE& mt = m_preferred_mtv[idx];

        hr = pin->ReceiveConnection(this, &mt);

        if (FAILED(hr))
            return hr;

        //const AM_MEDIA_TYPE& mt = *pmt;

        //hr = m_pTrack->SetConnectionMediaType(mt);
        //
        //if (FAILED(hr))
        //    return VFW_E_TYPE_NOT_ACCEPTED;

        m_connection_mtv.Add(mt);
    }
    else
    {
        ULONG i = 0;
        const ULONG j = m_preferred_mtv.Size();

        while (i < j)
        {
            const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

            hr = pin->ReceiveConnection(this, &mt);

#if 0
            if (SUCCEEDED(hr))
            {
                hr = m_pTrack->SetConnectionMediaType(mt);

                if (SUCCEEDED(hr))
                    break;
            }
#else
            if (SUCCEEDED(hr))
                break;
#endif

            ++i;
        }

        if (i >= j)
            return VFW_E_NO_ACCEPTABLE_TYPES;

        const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

        m_connection_mtv.Add(mt);
    }

    hr = m_pTrack->SetConnectionMediaType(m_connection_mtv[0]);
    assert(SUCCEEDED(hr));

    GraphUtil::IMemAllocatorPtr pAllocator;

    hr = pInputPin->GetAllocator(&pAllocator);

    if (FAILED(hr))
    {
        hr = CMediaSample::CreateAllocator(&pAllocator);

        if (FAILED(hr))
            return VFW_E_NO_ALLOCATOR;
    }

    assert(bool(pAllocator));

    ALLOCATOR_PROPERTIES props, actual;

    props.cBuffers = -1;    //number of buffers
    props.cbBuffer = -1;    //size of each buffer, excluding prefix
    props.cbAlign = -1;     //applies to prefix, too
    props.cbPrefix = -1;    //imediasample::getbuffer does NOT include prefix

    hr = pInputPin->GetAllocatorRequirements(&props);

    m_pTrack->UpdateAllocatorProperties(props);  //modify props as req'd

    hr = pAllocator->SetProperties(&props, &actual);

    if (FAILED(hr))
        return hr;

    hr = pInputPin->NotifyAllocator(pAllocator, 0);  //allow writes

    if (FAILED(hr) && (hr != E_NOTIMPL))
        return hr;

    m_pAllocator = pAllocator;

    m_connection = pin;  //TODO: use com smartptr here
    m_connection->AddRef();

    m_pInputPin = pInputPin;

    return S_OK;
}
Esempio n. 2
0
HRESULT Outpin::Connect(IPin* pin, const AM_MEDIA_TYPE* pmt) {
  if (pin == 0)
    return E_POINTER;

  GraphUtil::IMemInputPinPtr pInputPin;

  HRESULT hr = pin->QueryInterface(&pInputPin);

  if (hr != S_OK)
    return hr;

  Filter::Lock lock;

  hr = lock.Seize(m_pFilter);

  if (FAILED(hr))
    return hr;

  if (m_pFilter->GetStateLocked() != State_Stopped)
    return VFW_E_NOT_STOPPED;

  if (bool(m_pPinConnection))
    return VFW_E_ALREADY_CONNECTED;

  if (!bool(m_pFilter->m_inpin.m_pPinConnection))
    return VFW_E_NO_TYPES;  // VFW_E_NOT_CONNECTED?

  m_connection_mtv.Clear();

  if (pmt) {
    hr = QueryAccept(pmt);

    if (hr != S_OK)
      return VFW_E_TYPE_NOT_ACCEPTED;

    if ((pmt->formattype == FORMAT_VideoInfo) ||
        (pmt->formattype == FORMAT_VideoInfo2)) {
      hr = pin->ReceiveConnection(this, pmt);

      if (FAILED(hr))
        return hr;

      m_connection_mtv.Add(*pmt);
    } else  { // partial media type
      const ULONG n = m_preferred_mtv.Size();
      LONG idx = -1;

      for (ULONG i = 0; i < n; ++i) {
        const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

        if (pmt->subtype == mt.subtype) {
          idx = i;
          break;
        }
      }

      if (idx < 0)  // weird
        return VFW_E_TYPE_NOT_ACCEPTED;

      const AM_MEDIA_TYPE& mt = m_preferred_mtv[idx];

      hr = pin->ReceiveConnection(this, &mt);

      if (FAILED(hr))
        return hr;

      m_connection_mtv.Add(mt);
    }
  } else {
    ULONG i = 0;
    const ULONG j = m_preferred_mtv.Size();

    while (i < j) {
      const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

      hr = pin->ReceiveConnection(this, &mt);

      if (SUCCEEDED(hr))
        break;

      ++i;
    }

    if (i >= j)
      return VFW_E_NO_ACCEPTABLE_TYPES;

    const AM_MEDIA_TYPE& mt = m_preferred_mtv[i];

    m_connection_mtv.Add(mt);
  }

  GraphUtil::IMemAllocatorPtr pAllocator;

  hr = pInputPin->GetAllocator(&pAllocator);

  if (FAILED(hr)) {
    // hr = CMemAllocator::CreateInstance(&m_sample_factory, &pAllocator);
    hr = CMediaSample::CreateAllocator(&pAllocator);

    if (FAILED(hr))
      return VFW_E_NO_ALLOCATOR;
  }

  assert(bool(pAllocator));

  ALLOCATOR_PROPERTIES props, actual;

  props.cBuffers = -1;  // number of buffers
  props.cbBuffer = -1;  // size of each buffer, excluding prefix
  props.cbAlign = -1;  // applies to prefix, too
  props.cbPrefix = -1;  // imediasample::getbuffer does NOT include prefix

  hr = pInputPin->GetAllocatorRequirements(&props);

  if (props.cBuffers <= 0)
    props.cBuffers = 1;

  LONG w, h;
  GetConnectionDimensions(w, h);

  const long cbBuffer = 2 * w * h;

  if (props.cbBuffer < cbBuffer)
    props.cbBuffer = cbBuffer;

  if (props.cbAlign <= 0)
    props.cbAlign = 1;

  if (props.cbPrefix < 0)
    props.cbPrefix = 0;

  hr = pAllocator->SetProperties(&props, &actual);

  if (FAILED(hr))
    return hr;

  hr = pInputPin->NotifyAllocator(pAllocator, 0);  // allow writes

  if (FAILED(hr) && (hr != E_NOTIMPL))
    return hr;

  m_pPinConnection = pin;
  m_pAllocator = pAllocator;
  m_pInputPin = pInputPin;

  return S_OK;
}
Esempio n. 3
0
HRESULT OutpinVideo::PostConnectStats(IPin* p)
{
    IStreamPtr pStream;

    HRESULT hr = p->QueryInterface(&pStream);

    if (FAILED(hr))
        return hr;

    const GraphUtil::IMemInputPinPtr pMemInput(p);

    if (bool(pMemInput))
    {
        GraphUtil::IMemAllocatorPtr pAllocator;

        hr = pMemInput->GetAllocator(&pAllocator);

        if (FAILED(hr))
        {
            hr = CMediaSample::CreateAllocator(&pAllocator);

            if (FAILED(hr))
                return VFW_E_NO_ALLOCATOR;
        }

        assert(bool(pAllocator));

        ALLOCATOR_PROPERTIES props;

        props.cBuffers = -1;    //number of buffers
        props.cbBuffer = -1;    //size of each buffer, excluding prefix
        props.cbAlign = -1;     //applies to prefix, too
        props.cbPrefix = -1;    //imediasample::getbuf does NOT include prefix

        hr = pMemInput->GetAllocatorRequirements(&props);

        if (props.cBuffers < 0)
            props.cBuffers = 0;

        if (props.cbBuffer < 0)
            props.cbBuffer = 0;

        if (props.cbAlign <= 0)
            props.cbAlign = 1;

        if (props.cbPrefix < 0)
            props.cbPrefix = 0;

        ALLOCATOR_PROPERTIES actual;

        hr = pAllocator->SetProperties(&props, &actual);

        if (FAILED(hr))
            return hr;

        hr = pMemInput->NotifyAllocator(pAllocator, 0);  //allow writes

        if (FAILED(hr) && (hr != E_NOTIMPL))
            return hr;

        m_pAllocator = pAllocator;
        m_pInputPin = pMemInput;
    }

    m_pStream = pStream;

    return S_OK;
}