//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // The use and distribution terms for this software are covered by the // Microsoft Limited Public License (Ms-LPL) // which can be found in the file MS-LPL.txt at the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by // the terms of this license. // // The software is licensed “as-is.” // // You must not remove this notice, or any other, from this software. // // // // Demux code for Windows CE // //------------------------------------------------------------------------- //====================================================================== // Demux code for Windows CE //====================================================================== /*++ Module Name: bdademux.cpp Abstract: This module contains the class implementations for the BDA-specific interface implementation object, in the demux Revision History: 02-Sept-1999 created --*/ #include "precomp.h" #include "mp2demux.h" #include "tsstats.h" #include "mp2seek.h" #include "pin_out.h" #include "filter.h" #include "pin_in.h" CBDAMPEG2Demux::CBDAMPEG2Demux ( IN CMPEG2Demultiplexer * punk // controlling unknown, always the filter ) : m_pMPEG2Demux (punk), m_guidNetworkType (GUID_NULL), m_guidTuningSpace (GUID_NULL), m_ulSignalSource (0), m_NextPinID (OUTPUT_PIN_FIRST_ID), m_ulRegistrationContext (0), m_pINetworkProvider (NULL) { // always must be aggregated ASSERT (m_pMPEG2Demux) ; TRACE_CONSTRUCTOR (TEXT ("CBDAMPEG2Demux")) ; } CBDAMPEG2Demux::~CBDAMPEG2Demux ( ) { TRACE_DESTRUCTOR (TEXT ("CBDAMPEG2Demux")) ; UnregisterWithNetworkProvider () ; } STDMETHODIMP CBDAMPEG2Demux::QueryInterface ( IN REFIID riid, OUT void ** ppv ) { // delegate always return m_pMPEG2Demux -> QueryInterface (riid, ppv) ; } STDMETHODIMP_(ULONG) CBDAMPEG2Demux::AddRef ( ) { // delegate always return m_pMPEG2Demux -> AddRef () ; } STDMETHODIMP_(ULONG) CBDAMPEG2Demux::Release ( ) { // hmm.. if we return what the demuxfilter returns, could be the case where // the demux filter destroys itself, and thus destroys this object (if we're // in the destructor), and the code then comes back out through here .. // could this happen .. ? The remedy is to not explicitely delete this object // from the filter's destructor, but instead to examine the value of the // the Release call to the filter and delete self if it's 0 // delegate always return m_pMPEG2Demux -> Release () ; } HRESULT CBDAMPEG2Demux::DeleteInputPinLocked_ ( ) /*++ Locks Held: filter --*/ { #ifndef UNDER_CE HRESULT hr ; #endif //UNDER_CE O_TRACE_ENTER_0 (TEXT("CBDAMPEG2Demux::DeleteInputPin_ ()")) ; // make sure the pin exists if (m_pMPEG2Demux -> m_pInputPin == NULL) { TRACE_ERROR_0 (TEXT ("CBDAMPEG2Demux::DeleteInputPin_ () : input pin does not exist")) ; return E_FAIL ; } // make sure it isn't connected if (m_pMPEG2Demux -> m_pInputPin -> IsConnected ()) { TRACE_ERROR_0 (TEXT ("CBDAMPEG2Demux::DeleteInputPin_ () : input pin is connected")) ; return E_FAIL ; } RELEASE_AND_CLEAR (m_pMPEG2Demux -> m_pInputPin) ; return S_OK ; } ULONG m_ulRegistrationContext ; // get this when we register with the NP IBDA_NetworkProvider * m_pINetworkProvider ; HRESULT DeleteInputPinLocked_ ( ) ; void CBDAMPEG2Demux::RegisterWithNetworkProvider ( ) { HRESULT hr ; IEnumFilters * pIEnumFilters ; IBaseFilter * pIBaseFilter ; ULONG ul ; O_TRACE_ENTER_0 (TEXT("CBDAMPEG2Demux::RegisterWithNetworkProvider ()")) ; ASSERT (m_pMPEG2Demux -> m_pGraph) ; ASSERT (m_pINetworkProvider == NULL) ; pIEnumFilters = NULL ; hr = m_pMPEG2Demux -> m_pGraph -> EnumFilters (& pIEnumFilters) ; if (SUCCEEDED (hr)) { // find the network provider ASSERT (pIEnumFilters) ; pIBaseFilter = NULL ; TRACE_0 (LOG_TRACE, 1, TEXT ("CBDAMPEG2Demux::RegisterWithNetworkProvider () -- Searching ..")) ; for (;;) { hr = pIEnumFilters -> Next (1, & pIBaseFilter, & ul) ; if (FAILED (hr) || ul == 0) { break ; } ASSERT (pIBaseFilter) ; hr = pIBaseFilter -> QueryInterface (IID_IBDA_NetworkProvider, (void **) & m_pINetworkProvider) ; if (SUCCEEDED (hr)) { // found it ASSERT (m_pINetworkProvider) ; TRACE_0 (LOG_TRACE, 1, TEXT ("CBDAMPEG2Demux::RegisterWithNetworkProvider () -- Network Provider discovered")) ; // reset the starting output pin ID before registering m_NextPinID = OUTPUT_PIN_FIRST_ID ; // register ourselves; get the context hr = m_pINetworkProvider -> RegisterDeviceFilter ( m_pMPEG2Demux -> GetOwner (), & m_ulRegistrationContext ) ; // if this call failed, we want to release our ref to the NP if (FAILED (hr)) { RELEASE_AND_CLEAR (m_pINetworkProvider) ; } // release the ref we got from the enumeration RELEASE_AND_CLEAR (pIBaseFilter) ; break ; } else { RELEASE_AND_CLEAR (pIBaseFilter) ; } } RELEASE_AND_CLEAR (pIEnumFilters) ; } } void CBDAMPEG2Demux::UnregisterWithNetworkProvider ( ) { O_TRACE_ENTER_0 (TEXT("CBDAMPEG2Demux::UnregisterWithNetworkProvider ()")) ; if (m_pINetworkProvider) { // frame this in a __try/__except block so we can catch an exception generated // by a poorly written network provider; bottom line is that we clear off our // reference to the network provider __try { m_pINetworkProvider -> UnRegisterDeviceFilter (m_ulRegistrationContext) ; RELEASE_AND_CLEAR (m_pINetworkProvider) ; } __except (EXCEPTION_EXECUTE_HANDLER) { m_pINetworkProvider = NULL ; } ASSERT (m_pINetworkProvider == NULL) ; } }