//------------------------------------------------------------------------------ // // 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: tsstats.cpp Abstract: This module contains the class implementation for transport stream stats. Revision History: 7-Oct-1999 created --*/ #include "precomp.h" #include "mp2demux.h" #include "trace.h" #include "tsstats.h" #include "mp2seek.h" #include "pin_out.h" #include "bufsrc.h" #include "plparse.h" #include "program.h" CMpeg2SharedMem::CMpeg2SharedMem ( IN TCHAR * szName, IN DWORD dwSize, OUT HRESULT * phr ) : m_pbShared (NULL), m_dwSize (0), m_hMapping (NULL) { TRACE_CONSTRUCTOR (TEXT ("CMpeg2SharedMem")) ; (* phr) = Create_ (szName, dwSize) ; } CMpeg2SharedMem::~CMpeg2SharedMem ( ) { TRACE_DESTRUCTOR (TEXT ("CMpeg2SharedMem")) ; Free_ () ; } HRESULT CMpeg2SharedMem::Create_ ( IN TCHAR * pszName, IN DWORD dwSize ) { HRESULT hr ; DWORD dw ; Free_ () ; ASSERT (m_hMapping == NULL) ; ASSERT (m_dwSize == 0) ; ASSERT (m_pbShared == NULL) ; ASSERT (dwSize > 0) ; m_dwSize = dwSize ; hr = S_OK ; m_hMapping = CreateFileMapping ( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_dwSize, pszName ) ; if (m_hMapping == NULL) { dw = GetLastError () ; hr = HRESULT_FROM_WIN32 (dw) ; goto cleanup ; } m_pbShared = reinterpret_cast (MapViewOfFile ( m_hMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 )) ; if (m_pbShared == NULL) { dw = GetLastError () ; hr = HRESULT_FROM_WIN32 (dw) ; goto cleanup ; } cleanup : if (FAILED (hr)) { Free_ () ; } return hr ; } void CMpeg2SharedMem::Free_ ( ) { if (m_pbShared != NULL) { ASSERT (m_hMapping != NULL) ; UnmapViewOfFile (m_pbShared) ; } if (m_hMapping != NULL) { CloseHandle (m_hMapping) ; } m_hMapping = NULL ; m_pbShared = NULL ; m_dwSize = 0 ; } // ============================================================================ // ============================================================================ HRESULT CMpeg2TransportStatsCOM::GetSharedMemory ( OUT BYTE ** ppbShared, OUT DWORD * pdwSize ) { if (!ppbShared || !pdwSize) { return E_POINTER ; } (* ppbShared) = GetSharedMem () ; (* pdwSize) = GetSharedSize () ; return S_OK ; } HRESULT CMpeg2TransportStatsCOM::Enable ( IN OUT BOOL * pfEnable ) { if (!pfEnable) { return E_POINTER ; } return EnableStats ( REG_MPEG2_TRANSPORT_DEMUX, pfEnable ) ; } // ============================================================================ // ============================================================================ HRESULT CMpeg2ProgramStatsCOM::GetSharedMemory ( OUT BYTE ** ppbShared, OUT DWORD * pdwSize ) { if (!ppbShared || !pdwSize) { return E_POINTER ; } (* ppbShared) = GetSharedMem () ; (* pdwSize) = GetSharedSize () ; return S_OK ; } HRESULT CMpeg2ProgramStatsCOM::Enable ( IN OUT BOOL * pfEnable ) { if (!pfEnable) { return E_POINTER ; } return EnableStats ( REG_MPEG2_PROGRAM_DEMUX, pfEnable ) ; } // ============================================================================ // ============================================================================ CMpeg2StatsCOM::CMpeg2StatsCOM ( IN IUnknown * pIUnknown ) : CUnknown (TEXT ("CMpeg2StatsCOM"), pIUnknown), m_pTransportStatsCOM (NULL), m_pProgramStatsCOM (NULL) {} CMpeg2StatsCOM::~CMpeg2StatsCOM ( ) { delete m_pTransportStatsCOM ; delete m_pProgramStatsCOM ; } STDMETHODIMP CMpeg2StatsCOM::NonDelegatingQueryInterface ( IN REFIID riid, OUT void ** ppv ) { HRESULT hr ; if (riid == IID_IMpeg2TransportStatsRaw) { if (!m_pTransportStatsCOM) { m_pTransportStatsCOM = new CMpeg2TransportStatsCOM ( GetOwner (), & hr ) ; if (!m_pTransportStatsCOM || FAILED (hr)) { hr = (m_pTransportStatsCOM ? hr : E_OUTOFMEMORY) ; DELETE_RESET (m_pTransportStatsCOM) ; return hr ; } } ASSERT (m_pTransportStatsCOM) ; return GetInterface ( (IMpeg2TransportStatsRaw *) m_pTransportStatsCOM, ppv ) ; } else if (riid == IID_IMpeg2ProgramStatsRaw) { if (!m_pProgramStatsCOM) { m_pProgramStatsCOM = new CMpeg2ProgramStatsCOM ( GetOwner (), & hr ) ; if (!m_pProgramStatsCOM || FAILED (hr)) { hr = (FAILED (hr) ? hr : E_OUTOFMEMORY) ; DELETE_RESET (m_pProgramStatsCOM) ; return hr ; } } ASSERT (m_pProgramStatsCOM) ; return GetInterface ( (IMpeg2ProgramStatsRaw *) m_pProgramStatsCOM, ppv ) ; } return CUnknown::NonDelegatingQueryInterface (riid, ppv) ; } // class factory CUnknown * WINAPI CMpeg2StatsCOM::CreateInstance ( IN IUnknown * pIUnknown, OUT HRESULT * phr ) { CMpeg2StatsCOM * pMpeg2Stats ; pMpeg2Stats = new CMpeg2StatsCOM ( pIUnknown ) ; if (pMpeg2Stats) { (* phr) = S_OK ; } else { (* phr) = E_OUTOFMEMORY ; } return pMpeg2Stats ; } // ============================================================================ // ============================================================================ CMpeg2Stats::CMpeg2Stats ( ) : m_cRef (1), m_pStats (NULL), m_pTransportStats (NULL), m_pProgramStats (NULL), m_Mpeg2StreamType (MPEG2_STREAM_UNDEFINED), m_hMapping (NULL), m_dwSize (0), m_pSharedMem (NULL) { TRACE_CONSTRUCTOR (TEXT ("CMpeg2Stats")) ; } CMpeg2Stats::~CMpeg2Stats ( ) { TRACE_DESTRUCTOR (TEXT ("CMpeg2Stats")) ; Free () ; } HRESULT CMpeg2Stats::Initialize ( IN BOOL fEnable, IN DWORD Mpeg2StreamType ) // defaults to none if the parameter value is not exactly one of the presets { #ifndef UNDER_CE DWORD dw ; VOID * pv ; #endif //UNDER_CE TCHAR * pszName ; HRESULT hr ; ASSERT (m_hMapping == NULL) ; ASSERT (m_pStats == NULL) ; ASSERT (m_dwSize == 0) ; // success if we're to do nothing if (!fEnable) { return S_OK ; } // determine size and name of mapping if (Mpeg2StreamType == MPEG2_STREAM_TRANSPORT) { m_dwSize = sizeof MPEG2_TRANSPORT_STATS ; pszName = MPEG2_TRANSPORT_STATS_NAME ; } else if (Mpeg2StreamType == MPEG2_STREAM_PROGRAM) { m_dwSize = sizeof MPEG2_PROGRAM_STATS ; pszName = MPEG2_PROGRAM_STATS_NAME ; } else { // huh ? return S_OK ; } ASSERT (m_dwSize > 0) ; // // create the memory mapped object // m_pSharedMem = new CMpeg2SharedMem ( pszName, m_dwSize, & hr ) ; if (m_pSharedMem == NULL || FAILED (hr)) { hr = (m_pSharedMem ? hr : E_OUTOFMEMORY) ; // Free () frees & resets m_pSharedMem Free () ; return hr ; } ASSERT (m_pSharedMem -> GetSharedMem ()) ; ASSERT (m_pSharedMem -> GetSharedSize () == m_dwSize) ; m_pStats = reinterpret_cast (m_pSharedMem -> GetSharedMem ()) ; // stream-type specific pointers switch (Mpeg2StreamType) { case MPEG2_STREAM_TRANSPORT : m_pTransportStats = reinterpret_cast (m_pStats) ; break ; case MPEG2_STREAM_PROGRAM : m_pProgramStats = reinterpret_cast (m_pStats) ; break ; } ; // we frame the following in a __try/__except block because it probes the // entire mapping; it's possible for another process to actually create the // named mapping, but with a smaller size than we request; our call does not // fail, but we get an AV when we try to write beyond the originally allocated // size; __try { Clear () ; } __except (GetExceptionCode () == STATUS_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // free what's been mapped, and return an error code Free () ; return HRESULT_FROM_WIN32 (STATUS_ACCESS_VIOLATION) ; } // last - set the stream type m_Mpeg2StreamType = Mpeg2StreamType ; return S_OK ; } void CMpeg2Stats::Free ( ) { DELETE_RESET (m_pSharedMem) ; } void CMpeg2Stats::Clear ( ) { if (m_pStats) { ASSERT (m_dwSize > 0) ; ZeroMemory (m_pStats, m_dwSize) ; // transport specific memset ((void *) m_ExpectedContinuityCounter, 0xff, DISTINCT_PID_COUNT * sizeof BYTE) ; // set the version m_pStats -> ullVersion = MPEG2_STATS_VERSION (MPEG2_STATS_VERSION_MAJOR, MPEG2_STATS_VERSION_MINOR) ; } }