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