Example #1
0
HRESULT CVideoRenderer::BreakConnect()
{
    CAutoLock cInterfaceLock(&m_InterfaceLock);

    // Check we are in a valid state

    HRESULT hr = CBaseVideoRenderer::BreakConnect();
    if (FAILED(hr)) {
        return hr;
    }

    // The window is not used when disconnected
    IPin *pPin = m_InputPin.GetConnected();
    if (pPin) 
        SendNotifyWindow(pPin,NULL);

    // The base class break connect disables us from sending any EC_REPAINT
    // events which is important otherwise when we come down here to remove
    // our palette we end up painting the window again - which in turn sees
    // there is no image to draw and would otherwise send a redundant event

    m_ImagePalette.RemovePalette();
    m_mtIn.ResetFormatBuffer();

    return NOERROR;

} // BreakConnect
Example #2
0
//
// SetMediaType
//
// We store a copy of the media type used for the connection in the renderer
// because it is required by many different parts of the running renderer
// This can be called when we come to draw a media sample that has a format
// change with it. We normally delay type changes until they are really due
// for rendering otherwise we will change types too early if the source has
// allocated a queue of samples. In our case this isn't a problem because we
// only ever receive one sample at a time so it's safe to change immediately
//
HRESULT CVideoRenderer::SetMediaType(const CMediaType *pmt)
{
    CheckPointer(pmt,E_POINTER);

    HRESULT hr = NOERROR;
    CAutoLock cInterfaceLock(&m_InterfaceLock);
    CMediaType StoreFormat(m_mtIn);

    // Fill out the optional fields in the VIDEOINFOHEADER

    m_mtIn = *pmt;
    VIDEOINFO *pVideoInfo = (VIDEOINFO *) m_mtIn.Format();
    m_Display.UpdateFormat(pVideoInfo);

    // We set the new palette before completing so that the method can look
    // at the old RGB colours we used and compare them with the new set, if
    // they're all identical colours we don't need to change the palette

    hr = m_ImagePalette.PreparePalette(&m_mtIn,&StoreFormat,NULL);
    if (FAILED(hr)) {
        return hr;
    }

    // Complete the initialisation

    m_DrawImage.NotifyMediaType(&m_mtIn);
    m_ImageAllocator.NotifyMediaType(&m_mtIn);
    return NOERROR;

} // SetMediaType
Example #3
0
STDMETHODIMP CMPAudioRenderer::SetRate(double dRate)
{
  CAutoLock cInterfaceLock(&m_InterfaceLock);

  if (dRate < 0.1)
    return VFW_E_UNSUPPORTED_AUDIO;

  if (m_pTimeStretch)
    m_pTimeStretch->setRate(dRate);

  m_dRate = dRate;
  return S_OK;
}
Example #4
0
//----------------------------------------------------------------------------
//! @brief	  	アロケータが決まったときに呼び出されます。
//! @param		pAllocator 今回の接続で使用するアロケータを指定します。
//! @param		bReadOnly このアロケータからのサンプルが読みとり専用ならTRUEを指定します。
//! @return		エラーコード
//----------------------------------------------------------------------------
STDMETHODIMP TBufferRendererInputPin::NotifyAllocator( IMemAllocator * pAllocator, BOOL bReadOnly )
{
	CAutoLock cInterfaceLock(m_pInterfaceLock);

	// 基底クラス呼び出し
	HRESULT hr = CBaseInputPin::NotifyAllocator(pAllocator, bReadOnly);
	if( FAILED(hr) )
		return hr;

	//自前のアロケータが有効かどうかを記録します
	m_ActiveAllocator = (pAllocator == (&(m_pRenderer->m_Allocator)));

	return S_OK;
}
Example #5
0
STDMETHODIMP CMPAudioRenderer::SetRate(double dRate)
{
  {
    CAutoLock cInterfaceLock(&m_csAudioRenderer);

    if (dRate < 0.1)
      return VFW_E_UNSUPPORTED_AUDIO;

    if (m_pTimeStretch)
      m_pTimeStretch->setRate(dRate);

    m_dRate = dRate;
  }

  return m_pPosition->SetRate(dRate);
}
Example #6
0
//----------------------------------------------------------------------------
//! @brief	  	自前のアロケータオブジェクトを割り当てます。
//! @param		ppAllocator : 返すアロケーター
//----------------------------------------------------------------------------
STDMETHODIMP TBufferRendererInputPin::GetAllocator( IMemAllocator **ppAllocator )
{
	CAutoLock cInterfaceLock(m_pInterfaceLock);
	CheckPointer(ppAllocator,E_POINTER);

	// アロケータがまだ設定されていないとき
	if (m_pAllocator == NULL) {
		m_pAllocator = &(m_pRenderer->m_Allocator);
		m_pAllocator->AddRef();
	}
	// 参照カウントを残すのはインタフェースの仕様です。
	m_pAllocator->AddRef();
	*ppAllocator = m_pAllocator;

	return S_OK;
}
Example #7
0
//
// GetAllocator
//
// This overrides the CBaseInputPin virtual method to return our allocator
// we create to pass shared memory DIB buffers that GDI can directly access
// When NotifyAllocator is called it sets the current allocator in the base
// input pin class (m_pAllocator), this is what GetAllocator should return
// unless it is NULL in which case we return the allocator we would like
//
STDMETHODIMP CVideoInputPin::GetAllocator(IMemAllocator **ppAllocator)
{
    CheckPointer(ppAllocator,E_POINTER);
    CAutoLock cInterfaceLock(m_pInterfaceLock);

    // Has an allocator been set yet in the base class

    if (m_pAllocator == NULL) 
    {
        m_pAllocator = &m_pRenderer->m_ImageAllocator;
        m_pAllocator->AddRef();
    }

    m_pAllocator->AddRef();
    *ppAllocator = m_pAllocator;

    return NOERROR;

} // GetAllocator
Example #8
0
//
// NotifyAllocator
//
// The COM specification says any two IUnknown pointers to the same object
// should always match which provides a way for us to see if they are using
// our DIB allocator or not. Since we are only really interested in equality
// and our object always hands out the same IMemAllocator interface we can
// just see if the pointers match. If they are we set a flag in the main
// renderer as the window needs to know whether it can do fast rendering
//
STDMETHODIMP
CVideoInputPin::NotifyAllocator(IMemAllocator *pAllocator,BOOL bReadOnly)
{
    CAutoLock cInterfaceLock(m_pInterfaceLock);

    // Make sure the base class gets a look

    HRESULT hr = CBaseInputPin::NotifyAllocator(pAllocator,bReadOnly);
    if (FAILED(hr))
        return hr;

    // Whose allocator is the source going to use?

    m_pRenderer->m_DrawImage.NotifyAllocator(FALSE);
    if (pAllocator == &m_pRenderer->m_ImageAllocator)
        m_pRenderer->m_DrawImage.NotifyAllocator(TRUE);

    return NOERROR;

} // NotifyAllocator
Example #9
0
//
// CompleteConnect
//
// When we complete connection we need to see if the video has changed sizes
// If it has then we activate the window and reset the source and destination
// rectangles. If the video is the same size then we bomb out early. By doing
// this we make sure that temporary disconnections such as when we go into a
// fullscreen mode do not cause unnecessary property changes. The basic ethos
// is that all properties should be persistent across connections if possible
//
HRESULT CVideoRenderer::CompleteConnect(IPin *pReceivePin)
{
    CAutoLock cInterfaceLock(&m_InterfaceLock);

    CBaseVideoRenderer::CompleteConnect(pReceivePin);
    m_DrawImage.ResetPaletteVersion();

    // Has the video size changed between connections

    VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *) m_mtIn.Format();
    if (pVideoInfo->bmiHeader.biWidth == m_VideoSize.cx) 
    {
        if (pVideoInfo->bmiHeader.biHeight == m_VideoSize.cy) 
        {
            return NOERROR;
        }
    }

    // Pass the video window handle upstream
    HWND hwnd = m_VideoText.GetWindowHWND();
    NOTE1("Sending EC_NOTIFY_WINDOW %x",hwnd);

    SendNotifyWindow(pReceivePin,hwnd);

    // Set them for the current video dimensions

    m_DrawImage.SetDrawContext();
    m_VideoSize.cx = pVideoInfo->bmiHeader.biWidth;
    m_VideoSize.cy = pVideoInfo->bmiHeader.biHeight;

    m_VideoText.SetDefaultSourceRect();
    m_VideoText.SetDefaultTargetRect();
    m_VideoText.OnVideoSizeChange();
    m_VideoText.ActivateWindow();

    return NOERROR;

} // CompleteConnect