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