home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / nullip.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  12.8 KB  |  466 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11.  
  12.  
  13. /*
  14.  * Null-InPlace
  15.  *
  16.  *
  17.  */
  18.  
  19.  /* An example of a transform-in-place filter.
  20.     This filter has one input pin, one output pin and
  21.     does its transform in-place (i.e. without copying the data)
  22.     on the push thread (i.e. it is called with a buffer, which it
  23.     transforms and gives to the next filter downstream.  It is
  24.     then blocked until that filter returns.  It then returns
  25.     to its own caller.
  26.  
  27. */
  28.  
  29.  
  30. #include <streams.h>              // quartz, includes windows
  31. #include <measure.h>              // performance measurement (MSR_)
  32.  
  33. #include <initguid.h>
  34. #include <olectl.h>
  35. #include <olectlid.h>
  36.  
  37. #include "nullUids.h"             // our own uuids
  38.  
  39. #include "INull.h"
  40. #include "nullprop.h"
  41. #include "NullIP.h"               //
  42.  
  43.  
  44. // Put out the name of the function and instance on the debugger.
  45. #define DbgFunc(a) DbgLog(( LOG_TRACE                        \
  46.                           , 2                                \
  47.                           , TEXT("CNullInPlace(Instance %d)::%s") \
  48.                           , m_nThisInstance                  \
  49.                           , TEXT(a)                          \
  50.                          ));
  51.  
  52. // setup data
  53.  
  54. AMOVIESETUP_MEDIATYPE sudPinTypes =   { &MEDIATYPE_NULL                // clsMajorType
  55.                                            , &MEDIASUBTYPE_NULL }  ;       // clsMinorType
  56.  
  57. AMOVIESETUP_PIN psudPins[] = { { L"Input"            // strName
  58.                                , FALSE               // bRendered
  59.                                , FALSE               // bOutput
  60.                                , FALSE               // bZero
  61.                                , FALSE               // bMany
  62.                                , &CLSID_NULL         // clsConnectsToFilter
  63.                                , L"Output"           // strConnectsToPin
  64.                                , 1                   // nTypes
  65.                                , &sudPinTypes }      // lpTypes
  66.                              , { L"Output"           // strName
  67.                                , FALSE               // bRendered
  68.                                , TRUE                // bOutput
  69.                                , FALSE               // bZero
  70.                                , FALSE               // bMany
  71.                                , &CLSID_NULL         // clsConnectsToFilter
  72.                                , L"Input"            // strConnectsToPin
  73.                                , 1                   // nTypes
  74.                                , &sudPinTypes } };   // lpTypes
  75.  
  76.  
  77. AMOVIESETUP_FILTER sudNullIP = { &CLSID_NullInPlace                 // clsID
  78.                                   , L"Null In Place"                // strName
  79.                                   , MERIT_DO_NOT_USE                // dwMerit
  80.                                   , 2                               // nPins
  81.                                   , psudPins };                     // lpPin
  82.  
  83.  
  84. // Needed for the CreateInstance mechanism
  85. CFactoryTemplate g_Templates[]=
  86.     {   {L"Null-In-Place", &CLSID_NullInPlace,   CNullInPlace::CreateInstance},
  87.         {L"Null IP Property Page", &CLSID_NullIPPropertyPage, NullIPProperties::CreateInstance}
  88.  
  89.     };
  90. int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
  91.  
  92. // initialise the static instance count.
  93. int CNullInPlace::m_nInstanceCount = 0;
  94.  
  95.  
  96. /****************************/
  97. /*** CNullInPlaceInputPin ***/
  98. /****************************/
  99.  
  100. // CheckMediaType
  101. // - agree to anything if not connected, other wise pass through to
  102. //   the downstream filter
  103. HRESULT CNullInPlaceInputPin::CheckMediaType( const CMediaType *pmt )
  104. {   CNullInPlace *pNull = (CNullInPlace *) m_pTIPFilter;
  105.  
  106. #ifdef DEBUG
  107.     DisplayType(TEXT("Input type proposed"),pmt);
  108. #endif
  109.  
  110.     if (pNull->m_mtPreferred.IsValid() == FALSE)
  111.     {
  112.         if( pNull->m_pOutput->IsConnected() ) {
  113.             if ( *pmt->Subtype() == *pNull->m_pOutput->CurrentMediaType().Subtype() ) {
  114.                 return pNull->m_pOutput->GetConnected()->QueryAccept( pmt );
  115.             }
  116.             return VFW_E_TYPE_NOT_ACCEPTED;
  117.         }
  118.         return S_OK;
  119.     }
  120.     else
  121.         if (*pmt == pNull->m_mtPreferred)
  122.             return S_OK  ;
  123.         else
  124.             return VFW_E_TYPE_NOT_ACCEPTED;
  125.  
  126. }
  127.  
  128. /****************************/
  129. /*** CNullInPlaceOutputPin ***/
  130. /****************************/
  131.  
  132. // CheckMediaType
  133. //
  134. // Pass on to base class unless there is a preferred format set.
  135.  
  136. HRESULT CNullInPlaceOutputPin::CheckMediaType( const CMediaType *pmt )
  137. {   CNullInPlace *pNull = (CNullInPlace *) m_pTIPFilter;
  138.  
  139.     if (pNull->m_mtPreferred.IsValid() == FALSE)
  140.     {
  141.         return CTransInPlaceOutputPin::CheckMediaType (pmt) ;
  142.     }
  143.     else
  144.         if (*pmt == pNull->m_mtPreferred)
  145.             return S_OK  ;
  146.         else
  147.             return VFW_E_TYPE_NOT_ACCEPTED;
  148.  
  149. }
  150.  
  151. /********************/
  152. /*** CNullInPlace ***/
  153. /********************/
  154.  
  155. //
  156. // CNullInPlace::Constructor
  157. //
  158. CNullInPlace::CNullInPlace(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
  159.     : CTransInPlaceFilter (tszName, punk, CLSID_NullInPlace, phr)
  160. {
  161.     m_nThisInstance = ++m_nInstanceCount;
  162.     m_mtPreferred.InitMediaType () ;
  163.     DbgFunc("CNullInPlace");
  164.  
  165. #ifdef PERF
  166.     TCHAR msg[64];
  167.     wsprintf(msg, TEXT("Null %d passthru"), m_nThisInstance);
  168.     m_idReceive = Msr_Register(msg);
  169. #endif
  170.  
  171. } // (CNullInPlace constructor)
  172.  
  173.  
  174. //
  175. // CreateInstance
  176. //
  177. // Provide the way for COM to create a CNullInPlace object
  178. CUnknown *CNullInPlace::CreateInstance(LPUNKNOWN punk, HRESULT *phr) {
  179.  
  180.     CNullInPlace *pNewObject = new CNullInPlace(NAME("Null-In-Place Filter"), punk, phr );
  181.     if (pNewObject == NULL) {
  182.         *phr = E_OUTOFMEMORY;
  183.     }
  184.  
  185.     return pNewObject;
  186. } // CreateInstance
  187.  
  188.  
  189. //
  190. // GetSetupData
  191. //
  192. LPAMOVIESETUP_FILTER CNullInPlace::GetSetupData()
  193. {
  194.   return &sudNullIP;
  195. }
  196.  
  197. // return a non-addrefed CBasePin * for the user to addref if he holds onto it
  198. // for longer than his pointer to us.
  199. CBasePin *CNullInPlace::GetPin(int n)
  200. {
  201.     /* Create the single input and output pins */
  202.  
  203.     if (m_pInput == NULL || m_pOutput == NULL) {
  204.  
  205.         HRESULT hr = S_OK;
  206.  
  207.         m_pInput = new CNullInPlaceInputPin(NAME("Null input pin"),
  208.                                           this,              // Owner filter
  209.                                           &hr,               // Result code
  210.                                           L"Input");         // Pin name
  211.  
  212.         // a failed return code should delete the object
  213.  
  214.         if (FAILED(hr) || m_pInput == NULL) {
  215.             delete m_pInput;
  216.             m_pInput = NULL;
  217.             return NULL;
  218.         }
  219.  
  220.         m_pOutput = new CNullInPlaceOutputPin(NAME("Null output pin"),
  221.                                             this,            // Owner filter
  222.                                             &hr,             // Result code
  223.                                             L"Output");      // Pin name
  224.  
  225.         // failed return codes cause both objects to be deleted
  226.  
  227.         if (FAILED(hr) || m_pOutput == NULL) {
  228.             delete m_pInput;
  229.             m_pInput = NULL;
  230.             delete m_pOutput;
  231.             m_pOutput = NULL;
  232.             return NULL;
  233.         }
  234.     }
  235.  
  236.     /* Find which pin is required */
  237.  
  238.     switch(n) {
  239.         case 0:
  240.             return m_pInput;
  241.         case 1:
  242.            return m_pOutput;
  243.     }
  244.     return NULL;
  245. }
  246.  
  247.  
  248. //
  249. // NonDelegatingQueryInterface
  250. //
  251. STDMETHODIMP CNullInPlace::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
  252.  
  253.     if (riid == IID_INullIPP) {
  254.         return GetInterface((INullIPP *) this, ppv);
  255.     }
  256.     else if (riid == IID_ISpecifyPropertyPages) {
  257.         return GetInterface((ISpecifyPropertyPages *) this, ppv);
  258.     }
  259.     else {
  260.         return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
  261.     }
  262.  
  263. } // NonDelegatingQueryInterface
  264.  
  265. //
  266. // Receive the sample from upstream and process it in place.
  267. //
  268. HRESULT CNullInPlace::Receive(IMediaSample *pSample)
  269. {
  270.  
  271.     // By declaring a dummy variable (foo) of type CAutoLock we enter
  272.     // a CRITICAL_SECTION and automatically leave it at the end of
  273.     // the function.
  274.     CAutoLock foo(&m_NullIPLock);
  275.     HRESULT hr;
  276.  
  277.     DbgFunc("Receive");
  278.  
  279. #ifdef PERF
  280.     Msr_Start(m_idReceive);
  281. #endif
  282.  
  283.     hr = m_pOutput->Deliver(pSample);
  284.  
  285. #ifdef PERF
  286.     Msr_Stop(m_idReceive);
  287. #endif
  288.  
  289.     return hr;
  290. } // Receive
  291.  
  292.  
  293. //
  294. // --- INullIPP
  295. //
  296.  
  297.  
  298. //
  299. // get_IPin
  300. //
  301.  
  302. STDMETHODIMP CNullInPlace::get_IPin (IPin **ppPin)
  303. {
  304.     CAutoLock l(&m_NullIPLock);
  305.     if (!m_pInput)
  306.     {
  307.         *ppPin = NULL ;
  308.         return NOERROR ;
  309.     }
  310.     if( !m_pInput->IsConnected() )
  311.         *ppPin = NULL ;
  312.     else
  313.     {
  314.         *ppPin = m_pInput->GetConnected () ;
  315.         (*ppPin)->AddRef() ;
  316.     }
  317.     return NOERROR ;
  318. }
  319.  
  320. //
  321. // put_MediaType
  322. //
  323.  
  324. STDMETHODIMP CNullInPlace::put_MediaType(CMediaType *pmt)
  325. {
  326.     CAutoLock l(&m_NullIPLock);
  327.  
  328.     // if the state of the graph is running, fail the call.
  329.     if (m_State == State_Running)
  330.         return E_UNEXPECTED ;
  331.  
  332.     // check the source and sink filters like this media type
  333.  
  334.     if (pmt == NULL)
  335.         m_mtPreferred.InitMediaType () ;
  336.     else {
  337.         IPin *pPin= m_pInput->GetConnected();
  338.         if (pPin) {
  339.             if (pPin->QueryAccept(pmt) != NOERROR) {
  340.                 MessageBox(NULL,TEXT("Source filter cannot provide this type"),
  341.                            TEXT("Format Selection"),
  342.                            MB_OK | MB_ICONEXCLAMATION);
  343.                 return VFW_E_TYPE_NOT_ACCEPTED;
  344.             }
  345.         }
  346.         pPin= m_pOutput->GetConnected();
  347.         if (pPin) {
  348.             if (pPin->QueryAccept(pmt) != NOERROR) {
  349.                 MessageBox(NULL,TEXT("Target filter cannot accept this type"),
  350.                            TEXT("Format Selection"),
  351.                            MB_OK | MB_ICONEXCLAMATION);
  352.                 return VFW_E_TYPE_NOT_ACCEPTED;
  353.             }
  354.         }
  355.         m_mtPreferred = *pmt ;
  356.     }
  357.  
  358.     // force reconnect of input if the media type of connection does not match.
  359.     if( m_pInput->IsConnected() )
  360.     {
  361.         if (m_pInput->CurrentMediaType()!= m_mtPreferred)
  362.             m_pGraph->Reconnect(m_pInput);
  363.     }
  364.     return NOERROR ;
  365. }
  366.  
  367. STDMETHODIMP CNullInPlace::get_MediaType(CMediaType **pmt)
  368. {
  369.     CAutoLock l(&m_NullIPLock);
  370.  
  371.     *pmt = &m_mtPreferred ;
  372.     return NOERROR ;
  373. }
  374.  
  375.  
  376. //
  377. // get_State
  378. //
  379. STDMETHODIMP CNullInPlace::get_State(FILTER_STATE *state)
  380. {
  381.     CAutoLock l(&m_NullIPLock);
  382.     *state = m_State ;
  383.     return NOERROR;
  384. }
  385.  
  386.  
  387. // Reconnect the input and output pins as necessary
  388.  
  389. HRESULT CNullInPlace::CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin)
  390. {
  391.     ASSERT(m_pInput);
  392.     ASSERT(m_pOutput);
  393.  
  394.     // Always reconnect the input to account for buffering changes
  395.  
  396.     if (dir == PINDIR_OUTPUT) {
  397.         if( m_pInput->IsConnected() ) {
  398.             return m_pGraph->Reconnect( m_pInput );
  399.         }
  400.         return NOERROR;
  401.     }
  402.  
  403.     ASSERT(dir == PINDIR_INPUT);
  404.  
  405.     // Reconnect output if necessary
  406.  
  407.     if( m_pOutput->IsConnected() ) {
  408.         if ( *m_pInput->CurrentMediaType().Subtype() !=
  409.          *m_pOutput->CurrentMediaType().Subtype() ) {
  410.             return m_pGraph->Reconnect( m_pOutput );
  411.         }
  412.     }
  413.     return NOERROR;
  414. }
  415.  
  416.  
  417. //
  418. // --- ISpecifyPropertyPages ---
  419. //
  420.  
  421.  
  422. //
  423. // GetPages
  424. //
  425. // Returns the clsid's of the property pages we support
  426. STDMETHODIMP CNullInPlace::GetPages(CAUUID *pPages) {
  427.  
  428.     pPages->cElems = 1;
  429.     pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
  430.     if (pPages->pElems == NULL) {
  431.         return E_OUTOFMEMORY;
  432.     }
  433.     *(pPages->pElems) = CLSID_NullIPPropertyPage;
  434.  
  435.     return NOERROR;
  436. }
  437.  
  438. /******************************Public*Routine******************************\
  439. * exported entry points for registration and
  440. * unregistration (in this case they only call
  441. * through to default implmentations).
  442. *
  443. *
  444. *
  445. * History:
  446. *
  447. \**************************************************************************/
  448. HRESULT
  449. DllRegisterServer()
  450. {
  451.   return AMovieDllRegisterServer();
  452. }
  453.  
  454. HRESULT
  455. DllUnregisterServer()
  456. {
  457.   return AMovieDllUnregisterServer();
  458. }
  459.  
  460.  
  461. // Microsoft C Compiler will give hundreds of warnings about
  462. // unused inline functions in header files.  Try to disable them.
  463. #pragma warning( disable:4514)
  464.  
  465.  
  466.