home *** CD-ROM | disk | FTP | other *** search
- //==========================================================================;
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- // PURPOSE.
- //
- // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
- //
- //--------------------------------------------------------------------------;
-
- #include <streams.h>
- #include <sampvid.h>
- #include <vidprop.h>
- #include <initguid.h>
- #include <olectlid.h>
-
-
- // setup data
-
- AMOVIESETUP_MEDIATYPE sudPinTypes = { &MEDIATYPE_Video // clsMajorType
- , &MEDIASUBTYPE_NULL } ; // clsMinorType
-
- AMOVIESETUP_PIN sudPins = { L"Input" // strName
- , FALSE // bRendered
- , FALSE // bOutput
- , FALSE // bZero
- , FALSE // bMany
- , &CLSID_NULL // clsConnectsToFilter
- , L"Output" // strConnectsToPin
- , 1 // nTypes
- , &sudPinTypes } ; // lpTypes
-
-
- AMOVIESETUP_FILTER sudSampVid = { &CLSID_SampleRenderer // clsID
- , L"Sample Video Renderer" // strName
- , MERIT_DO_NOT_USE // dwMerit
- , 1 // nPins
- , &sudPins }; // lpPin
-
- // We have a precompiled header file which is included in all the source code
- // files in this directory. The precompiled header includes a definition of
- // these CLSIDs but because it does not include initguid it does not allocate
- // the memory for the GUID. We therefore actually declare the GUID in here
-
- DEFINE_GUID(CLSID_SampleRenderer,
- 0x4d4b1600, 0x33ac, 0x11cf, 0xbf, 0x30, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a);
-
- DEFINE_GUID(CLSID_SampleQuality,
- 0xdb76d7f0, 0x97cc, 0x11cf, 0xa0, 0x96, 0x00, 0x80, 0x5f, 0x6c, 0xab, 0x82);
-
- // List of class IDs and creator functions for the class factory. This
- // provides the link between the OLE entry point in the DLL and an object
- // being created. The class factory will call the static CreateInstance
-
- CFactoryTemplate g_Templates[] = {
- {L"Sample Video Renderer", &CLSID_SampleRenderer,CVideoRenderer::CreateInstance},
- {L"Quality Property Page", &CLSID_SampleQuality,CQualityProperties::CreateInstance}
- };
- int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
-
-
- // This goes in the factory template table to create new filter instances
-
- CUnknown *CVideoRenderer::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
- {
- return new CVideoRenderer(NAME("Sample Video Renderer"),pUnk,phr);
- }
-
-
- #pragma warning(disable:4355)
-
- CVideoRenderer::CVideoRenderer(TCHAR *pName,
- LPUNKNOWN pUnk,
- HRESULT *phr) :
-
- CBaseVideoRenderer(CLSID_SampleRenderer,pName,pUnk,phr),
- m_InputPin(NAME("Video Pin"),this,&m_InterfaceLock,phr,L"Input"),
- m_ImageAllocator(this,NAME("Sample video allocator"),phr),
- m_VideoText(NAME("Video properties"),GetOwner(),phr,&m_InterfaceLock,this),
- m_ImagePalette(this,&m_VideoText,&m_DrawImage),
- m_DrawImage(&m_VideoText)
- {
- // Reset the current video size
-
- m_VideoSize.cx = 0;
- m_VideoSize.cy = 0;
-
- // Initialise the window and control interfaces
-
- m_VideoText.SetControlVideoPin(&m_InputPin);
- m_VideoText.SetControlWindowPin(&m_InputPin);
- }
-
-
- // Destructor
-
- CVideoRenderer::~CVideoRenderer()
- {
- m_pInputPin = NULL;
- }
-
- //
- // GetSetupData
- //
- LPAMOVIESETUP_FILTER CVideoRenderer::GetSetupData()
- {
- return &sudSampVid;
- }
-
- // Check the proposed video media type
-
- HRESULT CVideoRenderer::CheckMediaType(const CMediaType *pmtIn)
- {
- return m_Display.CheckMediaType(pmtIn);
- }
-
-
- // We only support one input pin and it is numbered zero
-
- CBasePin *CVideoRenderer::GetPin(int n)
- {
- ASSERT(n == 0);
- if (n != 0) {
- return NULL;
- }
-
- // Assign the input pin if not already done so
-
- if (m_pInputPin == NULL) {
- m_pInputPin = &m_InputPin;
- }
- return m_pInputPin;
- }
-
-
- // Overriden to say what interfaces we support and where
-
- STDMETHODIMP CVideoRenderer::NonDelegatingQueryInterface(REFIID riid,void **ppv)
- {
- CheckPointer(ppv,E_POINTER);
- if (riid == IID_ISpecifyPropertyPages) {
- return GetInterface((ISpecifyPropertyPages *)this, ppv);
- } else if (riid == IID_IVideoWindow) {
- return m_VideoText.NonDelegatingQueryInterface(riid,ppv);
- } else if (riid == IID_IBasicVideo) {
- return m_VideoText.NonDelegatingQueryInterface(riid,ppv);
- }
- return CBaseVideoRenderer::NonDelegatingQueryInterface(riid,ppv);
- }
-
-
- // Return the CLSIDs for the property pages we support
-
- STDMETHODIMP CVideoRenderer::GetPages(CAUUID *pPages)
- {
- CheckPointer(pPages,E_POINTER);
-
- pPages->cElems = 1;
- pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
- if (pPages->pElems == NULL) {
- return E_OUTOFMEMORY;
- }
-
- pPages->pElems[0] = CLSID_SampleQuality;
- return NOERROR;
- }
-
-
- // Have the drawing object render the current image
-
- HRESULT CVideoRenderer::DoRenderSample(IMediaSample *pMediaSample)
- {
- return m_DrawImage.DrawImage(pMediaSample);
- }
-
-
- // Overriden to realise the palette before drawing
-
- void CVideoRenderer::PrepareRender()
- {
- HWND hwnd = m_VideoText.GetWindowHWND();
- SendMessage(hwnd,WM_QUERYNEWPALETTE,0,0);
- NOTE("Sent WM_QUERYNEWPALETTE to window");
- }
-
-
- // The auto show flag is used to have the window shown automatically when we
- // change state. We do this only when moving to paused or running, when there
- // is no outstanding EC_USERABORT set and when the window is not already up
- // This can be changed through the IVideoWindow interface AutoShow property.
- // If the window is not currently visible then we are showing it because of
- // a state change to paused or running, in which case there is no point in
- // the video window sending an EC_REPAINT as we're getting an image anyway
-
- HRESULT CVideoRenderer::Active()
- {
- HWND hwnd = m_VideoText.GetWindowHWND();
- NOTE("AutoShowWindow");
-
- if (m_VideoText.IsAutoShowEnabled() == TRUE) {
- if (m_bAbort == FALSE) {
- if (IsWindowVisible(hwnd) == FALSE) {
- NOTE("Executing AutoShowWindow");
- SetRepaintStatus(FALSE);
- m_VideoText.PerformanceAlignWindow();
- m_VideoText.DoShowWindow(SW_SHOWNORMAL);
- m_VideoText.DoSetWindowForeground(TRUE);
- }
- }
- }
- return CBaseVideoRenderer::Active();
- }
-
-
- // 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)
- {
- CAutoLock cInterfaceLock(&m_InterfaceLock);
- CMediaType StoreFormat(m_mtIn);
- HRESULT hr = NOERROR;
-
- // Fill out the optional fields in the VIDEOINFO
-
- 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);
- if (FAILED(hr)) {
- return hr;
- }
-
- // Complete the initialisation
-
- m_DrawImage.NotifyMediaType(&m_mtIn);
- m_ImageAllocator.NotifyMediaType(&m_mtIn);
- return NOERROR;
- }
-
-
- // This is called when a connection or an attempted connection is terminated
- // and lets us to reset the connection flag held by the base class renderer
- // The filter object may be hanging onto an image to use for refreshing the
- // video window so that must be freed (the allocator decommit may be waiting
- // for that image to return before completing) then we must also uninstall
- // any palette we were using, reset anything set with the control interfaces
- // then set our overall state back to disconnected ready for the next time
-
- HRESULT CVideoRenderer::BreakConnect()
- {
- CAutoLock cInterfaceLock(&m_InterfaceLock);
-
- // Check we are in a valid state
-
- HRESULT hr = CBaseVideoRenderer::BreakConnect();
- if (FAILED(hr)) {
- return hr;
- }
-
- // 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;
- }
-
-
- // 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 disocnnections 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
-
- VIDEOINFO *pVideoInfo = (VIDEOINFO *) m_mtIn.Format();
- if (pVideoInfo->bmiHeader.biWidth == m_VideoSize.cx) {
- if (pVideoInfo->bmiHeader.biHeight == m_VideoSize.cy) {
- return NOERROR;
- }
- }
-
- // 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;
- }
-
-
- // Constructor
-
- CVideoInputPin::CVideoInputPin(TCHAR *pObjectName,
- CVideoRenderer *pRenderer,
- CCritSec *pInterfaceLock,
- HRESULT *phr,
- LPCWSTR pPinName) :
-
- CRendererInputPin(pRenderer,phr,pPinName),
- m_pRenderer(pRenderer),
- m_pInterfaceLock(pInterfaceLock)
- {
- ASSERT(m_pRenderer);
- ASSERT(pInterfaceLock);
- }
-
-
- // 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)
- {
- CAutoLock cInterfaceLock(m_pInterfaceLock);
- CheckPointer(ppAllocator,E_POINTER);
-
- // 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;
- }
-
-
- // 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;
- }
-
-
- // Handle the registration of this filter
-
- HRESULT DllRegisterServer()
- {
- return AMovieDllRegisterServer();
- }
-
-
- HRESULT DllUnregisterServer()
- {
- return AMovieDllUnregisterServer();
- }
-
-