//------------------------------------------------------------------------------ // // 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: stubs.cpp Abstract: This module contains the MPEG2 demux - specific COM interface entry points. The methods here should be kept _slim_. The job of these methods is to validate all parameters the rest of the code doesn't have to. Invalid parameters are turned back here. This module also is a handy place to put in breakpoints for method calls. Revision History: 06-Jul-1999 created --*/ #include "precomp.h" #include // for ksmedia.h #include // for bdamedia.h #include // for KSDATAFORMAT_TYPE_MPEG2_SECTIONS #include "mp2demux.h" #include "mp2enum.h" #include "tsstats.h" #include "mp2seek.h" #include "pin_out.h" #include "filter.h" #include "pin_in.h" #include "bufsrc.h" #include "plparse.h" #include "program.h" #include "tsctrlr.h" // --------------------------------------------------------------------------- // IMpeg2Demultiplexer // --------------------------------------------------------------------------- STDMETHODIMP CDShowMPEG2Demux::CreateOutputPin ( IN AM_MEDIA_TYPE * pMediaType, IN LPWSTR pszPinID, OUT IPin ** ppIPin ) { HRESULT hr ; DEMUX_PIN_RECORD * pPinRecord ; O_TRACE_ENTER_3 (TEXT("CDShowMPEG2Demux::CreateOutputPin (%08xh, %08xh, %08xh)"), pMediaType, pszPinID, ppIPin) ; // validate the parameters; // 128 is the length of achName member of the PIN_INFO data struct if (pMediaType == NULL || // no media block ppIPin == NULL || // no outgoing interface pointer pszPinID == NULL || // no pin name pszPinID [0] == L'\0' || // no pin name (0 length) wcslen (pszPinID) >= 128) { // pin name too long TRACE_ERROR_0 (TEXT("CDShowMPEG2Demux::CreateOutputPin () : Invalid Argument")) ; return E_INVALIDARG ; } // attempt the operation hr = m_pMPEG2Demux -> CreateOutputPin_ ( pszPinID, pMediaType, & pPinRecord ) ; NE_SPEW (hr, S_OK, TEXT ("CDShowMPEG2Demux::CreateOutputPin () : CreateOutputPin_ () returned an error")) ; if (SUCCEEDED (hr)) { ASSERT (pPinRecord) ; ASSERT (pPinRecord -> pDemuxPin) ; // set outgoing (* ppIPin) = pPinRecord -> pDemuxPin ; // outgoing ref (* ppIPin) -> AddRef () ; // we are done with the pin record pPinRecord -> Release () ; } else { // deliberately clear this (* ppIPin) = NULL ; } return hr ; } STDMETHODIMP CDShowMPEG2Demux::SetOutputPinMediaType ( IN LPWSTR pszPinID, IN AM_MEDIA_TYPE * pMediaType ) { HRESULT hr ; DEMUX_PIN_RECORD * pPinRecord ; CMediaType cmt ; CAutoLock lock (m_pMPEG2Demux -> m_pLock) ; O_TRACE_ENTER_2 (TEXT("CDShowMPEG2Demux::SetOutputPinMediaType (%08xh, %08xh)"), pszPinID, pMediaType) ; if (pMediaType == NULL || pszPinID == NULL) { return E_POINTER ; } cmt = (* pMediaType) ; // an output pin // need to find the pin ID of the given string pPinRecord = NULL ; hr = m_pMPEG2Demux -> FindPinRecordLocked_ ( pszPinID, & pPinRecord ) ; if (SUCCEEDED (hr)) { ASSERT (pPinRecord) ; ASSERT (pPinRecord -> pDemuxPin) ; hr = m_pMPEG2Demux -> SetPinMediaTypeLocked_ ( pPinRecord -> pDemuxPin, & cmt ) ; pPinRecord -> Release () ; } return hr ; } STDMETHODIMP CDShowMPEG2Demux::DeleteOutputPin ( IN LPWSTR pszPinID ) { O_TRACE_ENTER_1 (TEXT("CDShowMPEG2Demux::DeleteOutputPin (%08xh)"), pszPinID) ; // validate the parameter if (pszPinID == NULL) { return E_INVALIDARG ; } return m_pMPEG2Demux -> DeletePin_ ( pszPinID ) ; } // IMpeg2DemultiplexerTesting method STDMETHODIMP CDShowMPEG2Demux::GetMpeg2StreamType ( OUT DWORD * pdwMpeg2StreamType ) { if (pdwMpeg2StreamType == NULL) { return E_POINTER ; } (* pdwMpeg2StreamType) = m_pMPEG2Demux -> GetStreamType () ; return S_OK ; } // --------------------------------------------------------------------------- // CMPEG2DemuxOutputPin // --------------------------------------------------------------------------- STDMETHODIMP CMPEG2DemuxOutputPin::MapPID ( IN ULONG culPID, IN ULONG * pulPID, IN MEDIA_SAMPLE_CONTENT MediaSampleContent ) { HRESULT hr ; DWORD dwMediaSampleContent ; O_TRACE_ENTER_3 (TEXT("CMPEG2DemuxOutputPin::MapPID (%08xh, %08xh, %08xh)"), culPID, pulPID, MediaSampleContent) ; if (culPID == 0 || pulPID == NULL || !IN_RANGE (MediaSampleContent, MEDIA_TRANSPORT_PACKET, MEDIA_TRANSPORT_PAYLOAD)) { TRACE_ERROR_0 (TEXT("CMPEG2DemuxOutputPin::MapPID () : invalid argument")) ; return E_INVALIDARG ; } hr = TransportMediaSampleContentEtoI ( MediaSampleContent, & dwMediaSampleContent ) ; ASSERT (SUCCEEDED (hr)) ; // should have failed test above ASSERT (m_pFilter) ; ASSERT (m_pName) ; return (static_cast (m_pFilter)) -> CreateStreamMap_ ( culPID, pulPID, m_pName, dwMediaSampleContent, 0x00001fff, NULL ) ; } STDMETHODIMP CMPEG2DemuxOutputPin::UnmapPID ( IN ULONG culPID, IN ULONG * pulPID ) { O_TRACE_ENTER_2 (TEXT("CMPEG2DemuxOutputPin::UnmapPID (%08xh, %08xh)"), culPID, pulPID) ; if (culPID == 0 || pulPID == NULL) { TRACE_ERROR_0 (TEXT("CMPEG2DemuxOutputPin::UnmapPID () : invalid argument")) ; return E_INVALIDARG ; } ASSERT (m_pFilter) ; ASSERT (m_pName) ; return (static_cast (m_pFilter)) -> DeleteStreamMap_ ( culPID, pulPID, m_pName, 0x00001fff ) ; } STDMETHODIMP CMPEG2DemuxOutputPin::EnumPIDMap ( OUT IEnumPIDMap ** ppIEnum ) { HRESULT hr ; CDBDADemuxEnumPIDMap * pEnumPIDMap ; O_TRACE_ENTER_1 (TEXT("CMPEG2DemuxOutputPin::EnumPIDMap (%08xh)"), ppIEnum) ; // validate the parameters if (ppIEnum == NULL) { return E_INVALIDARG ; } // create our PID map enum object pEnumPIDMap = new CDBDADemuxEnumPIDMap ; if (pEnumPIDMap == NULL) { return E_OUTOFMEMORY ; } // send it to the filter to be filled hr = (static_cast (m_pFilter)) -> m_pMPEG2Controller -> EnumStreamMap ( this, pEnumPIDMap ) ; if (SUCCEEDED (hr)) { * ppIEnum = pEnumPIDMap ; } else { TRACE_ERROR_0 (TEXT ("STUBS.CPP : m_pMPEG2Controller -> EnumStreamMap () call failed")) ; * ppIEnum = NULL ; delete pEnumPIDMap ; } return hr ; } STDMETHODIMP CMPEG2DemuxOutputPin::MapStreamId ( IN ULONG ulStreamId, IN DWORD MediaSampleContent, IN ULONG ulSubstreamFilterValue, IN int iDataOffset ) { HRESULT hr ; DWORD dwMediaSampleContent ; AUDIO_FILTER_INFO AudioFilterInfo ; O_TRACE_ENTER_2 (TEXT("CMPEG2DemuxOutputPin::MapStreamId (%08xh, %08xh)"), ulStreamId, MediaSampleContent) ; if (MediaSampleContent > MPEG2_PROGRAM_SYSTEM_HEADER || (iDataOffset > 0 && MediaSampleContent != MPEG2_PROGRAM_ELEMENTARY_STREAM)) { TRACE_ERROR_0 (TEXT("CMPEG2DemuxOutputPin::MapStreamId () : invalid argument")) ; return E_INVALIDARG ; } hr = ProgramMediaSampleContentEtoI ( MediaSampleContent, & dwMediaSampleContent ) ; ASSERT (SUCCEEDED (hr)) ; // should have failed test above ASSERT (m_pFilter) ; ASSERT (m_pName) ; AudioFilterInfo.dwSubstreamValue = (iDataOffset > 0 ? ulSubstreamFilterValue : SUBSTREAM_FILTER_VAL_NONE) ; AudioFilterInfo.iDataOffset = iDataOffset ; return (static_cast (m_pFilter)) -> CreateStreamMap_ ( 1, & ulStreamId, m_pName, dwMediaSampleContent, 0xffffffff, (LPVOID) & AudioFilterInfo ) ; } STDMETHODIMP CMPEG2DemuxOutputPin::UnmapStreamId ( IN ULONG culStreamId, IN ULONG * pulStreamId ) { O_TRACE_ENTER_2 (TEXT("CMPEG2DemuxOutputPin::UnmapStreamId (%08xh, %08xh)"), culStreamId, pulStreamId) ; if (culStreamId == 0 || pulStreamId == NULL) { TRACE_ERROR_0 (TEXT("CMPEG2DemuxOutputPin::UnmapStreamId () : invalid argument")) ; return E_INVALIDARG ; } ASSERT (m_pFilter) ; ASSERT (m_pName) ; return (static_cast (m_pFilter)) -> DeleteStreamMap_ ( culStreamId, pulStreamId, m_pName, 0x000000ff ) ; } STDMETHODIMP CMPEG2DemuxOutputPin::EnumStreamIdMap ( OUT IEnumStreamIdMap ** ppIEnum ) { HRESULT hr ; CDBDADemuxEnumStreamIdMap * pEnumStreamIdMap ; O_TRACE_ENTER_1 (TEXT("CMPEG2DemuxOutputPin::EnumStreamIdMap (%08xh)"), ppIEnum) ; // validate the parameters if (ppIEnum == NULL) { return E_INVALIDARG ; } // create our PID map enum object pEnumStreamIdMap = new CDBDADemuxEnumStreamIdMap ; if (pEnumStreamIdMap == NULL) { return E_OUTOFMEMORY ; } // send it to the filter to be filled hr = (static_cast (m_pFilter)) -> m_pMPEG2Controller -> EnumStreamMap ( this, pEnumStreamIdMap ) ; if (SUCCEEDED (hr)) { (* ppIEnum) = pEnumStreamIdMap ; } else { TRACE_ERROR_0 (TEXT ("STUBS.CPP : m_pMPEG2Controller -> EnumStreamMap () call failed")) ; (* ppIEnum) = NULL ; delete pEnumStreamIdMap ; } return hr ; }