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