//------------------------------------------------------------------------------
//
// 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:
mp2seek.h
Abstract:
This module contains the IMediaSeeking class declarations.
Revision History:
06-Nov-2000 created
Notes:
--*/
#ifndef __mp2demux_mp2seek_h
#define __mp2demux_mp2seek_h
class CMpeg2DemuxMediaSeekingCore
{
GUID m_guidTimeFormat ;
LONGLONG m_llTotalFileLength ;
REFERENCE_TIME m_rtTotalFileDuration ;
CRefCountedCritSec * m_pcrtSeekingLock ;
CMPEG2Demultiplexer * m_pMpeg2Demultiplexer ;
double m_dPlaybackRate ;
// returns the offset last read
LONGLONG
GetLastRead_ (
) ;
public :
CMpeg2DemuxMediaSeekingCore (
IN CMPEG2Demultiplexer * pMpeg2Demultiplexer,
IN CRefCountedCritSec * pcrtSeekingLock
) ;
~CMpeg2DemuxMediaSeekingCore (
) ;
void SetTotalFileLength (IN LONGLONG ll) { m_llTotalFileLength = ll ; }
LONGLONG GetTotalFileLength () { return m_llTotalFileLength ; }
void SetTotalFileDuration (IN REFERENCE_TIME rt) { m_rtTotalFileDuration = rt ; }
REFERENCE_TIME GetTotalFileDuration () { return m_rtTotalFileDuration ; }
BOOL
IsSeekable (
) ;
BOOL
IsSeekingPin (
IN CMPEG2DemuxOutputPin *
) ;
HRESULT
ByteOffsetToTime (
IN OUT LONGLONG * pll
)
{
// compute assuming it's a valid offset
(* pll) = llMulDiv ((* pll), m_rtTotalFileDuration, m_llTotalFileLength, 0) ;
// make sure it's within bounds
(* pll) = Min ((* pll), m_rtTotalFileDuration) ;
return S_OK ;
}
HRESULT
TimeToByteOffset (
IN OUT LONGLONG * pll
)
{
// compute assuming it's a valid offset
(* pll) = llMulDiv ((* pll), m_llTotalFileLength, m_rtTotalFileDuration, 0) ;
// make sure it's within bounds
(* pll) = Min ((* pll), m_llTotalFileLength) ;
return S_OK ;
}
HRESULT
TimeToCurrentFormat (
IN OUT LONGLONG * pll
)
{
HRESULT hr ;
if (m_guidTimeFormat == TIME_FORMAT_BYTE) {
// convert to a byte offset
hr = TimeToByteOffset (pll) ;
}
else if (m_guidTimeFormat == TIME_FORMAT_MEDIA_TIME) {
// already there
hr = S_OK ;
}
else {
// ??
hr = E_FAIL ;
}
return hr ;
}
HRESULT
ByteOffsetToCurrentFormat (
IN OUT LONGLONG * pll
)
{
HRESULT hr ;
if (m_guidTimeFormat == TIME_FORMAT_BYTE) {
// input is a byte offset; nothing left to do
hr = S_OK ;
}
else if (m_guidTimeFormat == TIME_FORMAT_MEDIA_TIME) {
// byte offset becomes a time
hr = ByteOffsetToTime (pll) ;
}
else {
// ??
hr = E_FAIL ;
}
return hr ;
}
HRESULT
CurrentFormatToByteOffset (
IN OUT LONGLONG * pll
)
{
HRESULT hr ;
if (m_guidTimeFormat == TIME_FORMAT_BYTE) {
// input is a byte offset; nothing left to do
hr = S_OK ;
}
else if (m_guidTimeFormat == TIME_FORMAT_MEDIA_TIME) {
// time must be scaled to byte offset
// compute assuming it's a valid time offset
(* pll) = llMulDiv ((* pll), m_llTotalFileLength, m_rtTotalFileDuration, 0) ;
// make sure it's within bounds
(* pll) = Min ((* pll), m_llTotalFileLength) ;
hr = S_OK ;
}
else {
// ??
hr = E_FAIL ;
}
return hr ;
}
HRESULT
GetSeekingCapabilities (
OUT DWORD * pCapabilities
)
{
ASSERT (pCapabilities) ;
(* pCapabilities) = AM_SEEKING_CanSeekForwards
| AM_SEEKING_CanSeekBackwards
| AM_SEEKING_CanSeekAbsolute
| AM_SEEKING_CanGetStopPos
| AM_SEEKING_CanGetDuration ;
return S_OK ;
}
BOOL
IsSeekingFormatSupported (
IN const GUID * pFormat
) ;
HRESULT
QueryPreferredSeekingFormat (
OUT GUID *
) ;
HRESULT
SetSeekingTimeFormat (
IN const GUID *
) ;
HRESULT
GetSeekingTimeFormat (
OUT GUID *
) ;
HRESULT
GetFileDuration (
OUT LONGLONG *
) ;
HRESULT
GetFileStopPosition (
OUT LONGLONG *
) ;
HRESULT
GetFileStartPosition (
OUT LONGLONG *
) ;
HRESULT
SeekTo (
IN LONGLONG * pllStart
) ;
HRESULT
SeekTo (
IN LONGLONG * pllStart,
IN LONGLONG * pllStop,
IN double dPlaybackRate = 1.0
) ;
HRESULT
SetFileStopPosition (
IN LONGLONG *
) ;
HRESULT
SetPlaybackRate (
IN double
) ;
double GetPlaybackRate () { return m_dPlaybackRate ; }
// callable only by the receiver thread (internal lock logic requires
// this)
HRESULT
RecvThreadGetSegmentValues (
OUT REFERENCE_TIME * prtStart,
OUT REFERENCE_TIME * prtStop,
OUT double * pdRate
) ;
} ;
class CMpeg2DemuxMediaSeekingCOM :
public IMediaSeeking
{
CMPEG2DemuxOutputPin * m_pOutputPin ;
CMPEG2Demultiplexer * m_pMpeg2DemuxFilter ;
GUID m_guidSeekingFormat ;
CCritSec * m_pLock ;
CMpeg2DemuxMediaSeekingCore * m_pSeekingCore ;
void Lock_ () { m_pLock -> Lock () ; }
void Unlock_ () { m_pLock -> Unlock () ; }
public :
CMpeg2DemuxMediaSeekingCOM (
IN CMPEG2DemuxOutputPin * pOutputPin,
IN CMPEG2Demultiplexer * pMpeg2DemuxFilter,
IN CMpeg2DemuxMediaSeekingCore * pSeekingCore,
IN CCritSec * pLock
) ;
~CMpeg2DemuxMediaSeekingCOM (
) ;
// --------------------------------------------------------------------
// IUnknown methods - delegate always
STDMETHODIMP QueryInterface (REFIID riid, void ** ppv) ;
STDMETHODIMP_ (ULONG) AddRef () ;
STDMETHODIMP_ (ULONG) Release () ;
// --------------------------------------------------------------------
// IMediaSeeking interface methods
// Returns the capability flags; S_OK if successful
STDMETHODIMP
GetCapabilities (
OUT DWORD * pCapabilities
) ;
// And's the capabilities flag with the capabilities requested.
// Returns S_OK if all are present, S_FALSE if some are present,
// E_FAIL if none.
// * pCababilities is always updated with the result of the
// 'and'ing and can be checked in the case of an S_FALSE return
// code.
STDMETHODIMP
CheckCapabilities (
IN OUT DWORD * pCapabilities
) ;
// returns S_OK if mode is supported, S_FALSE otherwise
STDMETHODIMP
IsFormatSupported (
IN const GUID * pFormat
) ;
// S_OK if successful
// E_NOTIMPL, E_POINTER if unsuccessful
STDMETHODIMP
QueryPreferredFormat (
OUT GUID * pFormat
) ;
// S_OK if successful
STDMETHODIMP
GetTimeFormat (
OUT GUID * pFormat
) ;
// Returns S_OK if *pFormat is the current time format, otherwise
// S_FALSE
// This may be used instead of the above and will save the copying
// of the GUID
STDMETHODIMP
IsUsingTimeFormat (
IN const GUID * pFormat
) ;
// (may return VFE_E_WRONG_STATE if graph is stopped)
STDMETHODIMP
SetTimeFormat (
IN const GUID * pFormat
) ;
// return current properties
STDMETHODIMP
GetDuration (
OUT LONGLONG * pDuration
) ;
STDMETHODIMP
GetStopPosition (
OUT LONGLONG * pStop
) ;
STDMETHODIMP
GetCurrentPosition (
OUT LONGLONG * pStart
) ;
// Convert time from one format to another.
// We must be able to convert between all of the formats that we
// say we support. (However, we can use intermediate formats
// (e.g. MEDIA_TIME).)
// If a pointer to a format is null, it implies the currently selected format.
STDMETHODIMP
ConvertTimeFormat(
OUT LONGLONG * pTarget,
IN const GUID * pTargetFormat,
IN LONGLONG Source,
IN const GUID * pSourceFormat
) ;
// Set Start and end positions in one operation
// Either pointer may be null, implying no change
STDMETHODIMP
SetPositions (
IN OUT LONGLONG * pStart,
IN DWORD dwStartFlags,
IN OUT LONGLONG * pStop,
IN DWORD dwStopFlags
) ;
// Get StartPosition & StopTime
// Either pointer may be null, implying not interested
STDMETHODIMP
GetPositions (
OUT LONGLONG * pStart,
OUT LONGLONG * pStop
) ;
// Get earliest / latest times to which we can currently seek
// "efficiently". This method is intended to help with graphs
// where the source filter has a very high latency. Seeking
// within the returned limits should just result in a re-pushing
// of already cached data. Seeking beyond these limits may result
// in extended delays while the data is fetched (e.g. across a
// slow network).
// (NULL pointer is OK, means caller isn't interested.)
STDMETHODIMP
GetAvailable (
OUT LONGLONG * pEarliest,
OUT LONGLONG * pLatest
) ;
// Rate stuff
STDMETHODIMP
SetRate (
IN double dRate
) ;
STDMETHODIMP
GetRate (
OUT double * pdRate
) ;
// Preroll
STDMETHODIMP
GetPreroll (
OUT LONGLONG * pllPreroll
) ;
} ;
#endif // __mp2demux_mp2seek_h