//------------------------------------------------------------------------------
//
// 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) ;
}
}