You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
15 KiB
547 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1995-1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
medistrm.h
|
|
|
|
Abstract:
|
|
Contains constants and class declarations for the abstract MediaStream object. A MediaStream
|
|
represents a single unidirectional stream, such as a received Video channel.
|
|
|
|
--*/
|
|
#ifndef _MEDISTRM_H_
|
|
#define _MEDISTRM_H_
|
|
|
|
#include "dtmf.h"
|
|
|
|
#include <pshpack8.h> /* Assume 8 byte packing throughout */
|
|
|
|
|
|
class DataPump;
|
|
class TxStream;
|
|
class RxStream;
|
|
class AcmFilter;
|
|
class VcmFilter;
|
|
class MediaControl;
|
|
class BufferPool;
|
|
class AudioPacket;
|
|
class VideoPacket;
|
|
|
|
class SendMediaStream : public IMediaChannel {
|
|
friend class SendAudioStream;
|
|
protected:
|
|
DataPump *m_pDP;
|
|
TxStream *m_SendStream;
|
|
MediaControl *m_InMedia;
|
|
UINT m_CaptureDevice; // device id used for recording
|
|
UINT m_PreviousCaptureDevice; // device id used for recording
|
|
IRTPSession *m_Net;
|
|
IRTPSend *m_pRTPSend;
|
|
BYTE m_RTPPayload; // payload type
|
|
//BufferPool *m_NetBufferPool;
|
|
DWORD m_SendTimestamp;
|
|
DWORD m_SavedTickCount;
|
|
DWORD m_ThreadFlags;
|
|
DWORD m_DPFlags;
|
|
BOOL m_fSending;
|
|
MEDIA_FORMAT_ID m_PrevFormatId;
|
|
DWORD m_dwDstSize;
|
|
|
|
|
|
FLOWSPEC m_flowspec;
|
|
HRESULT SetFlowSpec();
|
|
|
|
|
|
HANDLE m_hCapturingThread;
|
|
DWORD m_CaptureThId;
|
|
|
|
CRITICAL_SECTION m_crsQos;
|
|
|
|
// IQOS interface pointer and two resources requests: one for BW and one for CPU
|
|
struct {
|
|
int cResourceRequests;
|
|
RESOURCEREQUEST aResourceRequest[2];
|
|
} m_aRRq;
|
|
|
|
// Performance statistics
|
|
struct {
|
|
DWORD dwMsCap; // Capture CPU usage (ms)
|
|
DWORD dwMsComp; // Compression CPU usage (ms)
|
|
DWORD dwBits; // Compressed audio or video frame size (bits)
|
|
DWORD dwCount; // Number of video frames captured or audio packets recorded
|
|
DWORD dwOldestTs; // Oldest QoS callback timestamp
|
|
DWORD dwNewestTs; // Most recent QoS callback timestamp
|
|
HKEY hPerfKey; // Handle to CPU perf data collection reg key on Win95/98
|
|
DWORD dwSmoothedCPUUsage; // Previous CPU usage value - used to compute slow-varying average in CPU usage
|
|
BOOL fWinNT; // Are we running on WinNT or Win95/98?
|
|
struct { // Structure used to extract CPU usage performance on NT
|
|
DWORD cbPerfData;
|
|
PBYTE pbyPerfData;
|
|
HANDLE hPerfData;
|
|
LONGLONG llPerfTime100nSec;
|
|
PLONGLONG pllCounterValue;
|
|
DWORD dwProcessorIndex;
|
|
DWORD dwPercentProcessorIndex;
|
|
DWORD dwNumProcessors;
|
|
} NtCPUUsage;
|
|
} m_Stats;
|
|
|
|
RTP_STATS m_RTPStats; // network stats
|
|
public:
|
|
SendMediaStream()
|
|
{
|
|
InitializeCriticalSection(&m_crsQos);
|
|
};
|
|
virtual ~SendMediaStream()
|
|
{
|
|
DeleteCriticalSection(&m_crsQos);
|
|
}
|
|
|
|
// Implementation of IMediaChannel::GetState
|
|
STDMETHODIMP_(DWORD) GetState()
|
|
{
|
|
if (m_DPFlags & DPFLAG_STARTED_SEND) return MSSTATE_STARTED;
|
|
else if (m_DPFlags & DPFLAG_CONFIGURED_SEND) return MSSTATE_CONFIGURED;
|
|
else return MSSTATE_UNCONFIGURED;
|
|
}
|
|
|
|
virtual HRESULT Initialize(DataPump *) = 0;
|
|
virtual DWORD Send() = 0;
|
|
virtual void EndSend() = 0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetNetworkInterface(IUnknown *pUnknown);
|
|
|
|
|
|
} ;
|
|
|
|
class RecvMediaStream : public IMediaChannel
|
|
{
|
|
friend class DataPump;
|
|
friend BOOL RTPRecvCallback(DWORD_PTR,WSABUF *);
|
|
protected:
|
|
DataPump *m_pDP;
|
|
RxStream *m_RecvStream;
|
|
MediaControl *m_OutMedia;
|
|
UINT m_RenderingDevice; // device id used for playback
|
|
|
|
IRTPSession *m_Net;
|
|
IRTPRecv *m_pIRTPRecv;
|
|
|
|
//BufferPool *m_NetBufferPool;
|
|
DWORD m_ThreadFlags;
|
|
DWORD m_DPFlags;
|
|
BOOL m_fReceiving;
|
|
DWORD m_PlaybackTimestamp; // last played sample
|
|
|
|
HANDLE m_hRecvThreadStopEvent;
|
|
HANDLE m_hRenderingThread;
|
|
DWORD m_RenderingThId;
|
|
UINT m_nRecvBuffersPending;
|
|
|
|
DWORD m_dwSrcSize;
|
|
|
|
FLOWSPEC m_flowspec;
|
|
HRESULT SetFlowSpec();
|
|
|
|
|
|
|
|
public:
|
|
RecvMediaStream(){};
|
|
virtual HRESULT Initialize(DataPump *) = 0;
|
|
virtual BOOL IsEmpty() = 0;
|
|
|
|
// Implementation of IMediaChannel::GetState
|
|
STDMETHODIMP_(DWORD) GetState()
|
|
{
|
|
if (m_DPFlags & DPFLAG_STARTED_RECV) return MSSTATE_STARTED;
|
|
else if (m_DPFlags & DPFLAG_CONFIGURED_RECV) return MSSTATE_CONFIGURED;
|
|
else return MSSTATE_UNCONFIGURED;
|
|
}
|
|
|
|
virtual HRESULT RTPCallback(WSABUF *pWsaBuf, DWORD timestamp, UINT seq, UINT fMark)=0;
|
|
|
|
virtual HRESULT GetCurrentPlayNTPTime(NTP_TS *)=0;
|
|
virtual HRESULT StartRecv(HWND)=0;
|
|
virtual HRESULT StopRecv()=0;
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE SetNetworkInterface(IUnknown *pUnknown);
|
|
|
|
|
|
virtual HRESULT DTMFBeep() {return S_OK;}
|
|
virtual HRESULT OnDTMFBeep() {return S_OK;}
|
|
|
|
};
|
|
|
|
|
|
class SendVideoStream : public SendMediaStream, public IVideoRender,
|
|
public IVideoChannel
|
|
{
|
|
friend class DataPump;
|
|
protected:
|
|
CCaptureChain* m_pCaptureChain;
|
|
VIDEOFORMATEX m_fDevSend;
|
|
VIDEOFORMATEX m_fCodecOutput;
|
|
RECT m_cliprect;
|
|
DWORD m_maxfps;
|
|
DWORD m_frametime;
|
|
|
|
int *m_pTSTable; // NULL if table isn't used
|
|
DWORD m_dwCurrentTSSetting;
|
|
|
|
VcmFilter *m_pVideoFilter;
|
|
IUnknown *m_pIUnknown; // Pointer to IUnkown from which we'll query the Stream Signal interface
|
|
|
|
class MediaPacket *m_pNextPacketToRender; // current recv video frame
|
|
UINT m_cRendering; // count of packets given out by GetFrame()
|
|
HANDLE m_hRenderEvent; // IVideoRender event for recv notification
|
|
LPFNFRAMEREADY m_pfFrameReadyCallback; // callback function
|
|
CRITICAL_SECTION m_crs;
|
|
|
|
CRITICAL_SECTION m_crsVidQoS; // Allows QoS thread to read the video statistics while capture and compression are running
|
|
|
|
// the capture thread (and it's launch function)
|
|
static DWORD CALLBACK StartCaptureThread(LPVOID pVoid);
|
|
DWORD CapturingThread();
|
|
|
|
|
|
HRESULT SendPacket(VideoPacket *pVP, UINT *puBytesSent);
|
|
STDMETHODIMP_(void) UnConfigure(void);
|
|
|
|
LONG m_lRefCount;
|
|
|
|
public:
|
|
SendVideoStream(): SendMediaStream(){m_Net=NULL; m_lRefCount=0; };
|
|
virtual ~SendVideoStream();
|
|
|
|
// IUnknown
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
|
|
|
|
// IMediaChannel APIs
|
|
// new version of Configure()
|
|
HRESULT STDMETHODCALLTYPE Configure(
|
|
BYTE *pFormat,
|
|
UINT cbFormat,
|
|
BYTE *pChannelParams,
|
|
UINT cbParams,
|
|
IUnknown *pUnknown);
|
|
|
|
STDMETHODIMP Start(void);
|
|
STDMETHODIMP Stop(void);
|
|
|
|
HRESULT STDMETHODCALLTYPE SetNetworkInterface(IUnknown *pUnknown)
|
|
{
|
|
return SendMediaStream::SetNetworkInterface(pUnknown);
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) GetState()
|
|
{
|
|
return SendMediaStream::GetState();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE SetMaxBitrate(UINT uMaxBitrate);
|
|
|
|
|
|
// IVideoChannel
|
|
virtual HRESULT __stdcall SetTemporalSpatialTradeOff(DWORD dwVal);
|
|
virtual HRESULT __stdcall GetTemporalSpatialTradeOff(DWORD *pdwVal);
|
|
virtual HRESULT __stdcall SendKeyFrame(void);
|
|
virtual HRESULT __stdcall ShowDeviceDialog(DWORD dwFlags);
|
|
virtual HRESULT __stdcall GetDeviceDialog(DWORD *pdwFlags);
|
|
|
|
// IProperty methods
|
|
STDMETHODIMP GetProperty(DWORD dwProp, PVOID pBuf, LPUINT pcbBuf);
|
|
STDMETHODIMP SetProperty(DWORD dwProp, PVOID pBuf, UINT cbBuf);
|
|
|
|
// IVideoRender methods
|
|
STDMETHODIMP Init( DWORD_PTR dwUser, LPFNFRAMEREADY pfCallback);
|
|
STDMETHODIMP Done(void);
|
|
STDMETHODIMP GetFrame(FRAMECONTEXT* pfc);
|
|
STDMETHODIMP ReleaseFrame(FRAMECONTEXT *pfc);
|
|
|
|
// Other virtual methods
|
|
virtual HRESULT Initialize(DataPump *);
|
|
|
|
// Non virtual methods
|
|
static HRESULT CALLBACK QosNotifyVideoCB(LPRESOURCEREQUESTLIST lpResourceRequestList, DWORD_PTR dwThis);
|
|
void UnConfigureSendVideo(BOOL fNewDeviceSettings, BOOL fNewDevice);
|
|
void StartCPUUsageCollection(void);
|
|
BOOL GetCPUUsage(PDWORD pdwOverallCPUUsage);
|
|
void StopCPUUsageCollection(void);
|
|
BOOL SetTargetRates(DWORD dwTargetFrameRate, DWORD dwTargetBitrate);
|
|
DWORD Send();
|
|
void EndSend();
|
|
|
|
|
|
};
|
|
|
|
class RecvVideoStream : public RecvMediaStream, public IVideoRender {
|
|
friend class DataPump;
|
|
protected:
|
|
VIDEOFORMATEX m_fDevRecv;
|
|
RECT m_cliprect;
|
|
class MediaPacket *m_pNextPacketToRender; // current recv video frame
|
|
UINT m_cRendering; // count of packets given out by GetFrame()
|
|
HANDLE m_hRenderEvent; // IVideoRender event for recv notification
|
|
LPFNFRAMEREADY m_pfFrameReadyCallback; // callback function
|
|
CRITICAL_SECTION m_crs;
|
|
VcmFilter *m_pVideoFilter;
|
|
IUnknown *m_pIUnknown; // Pointer to IUnkown from which we'll query the Stream Signal interface
|
|
IStreamSignal *m_pIStreamSignal; // Pointer to I-Frame request interface
|
|
CRITICAL_SECTION m_crsIStreamSignal; // Used to serialize access to the interface between Stop() and the RTP callback
|
|
UINT m_ulLastSeq; // Last received RTP sequence number
|
|
DWORD m_dwLastIFrameRequest; // When was the last I-frame request sent? Used to make sure we don't send requests too often
|
|
BOOL m_fDiscontinuity; // Signals that a discontinuity (RTP packet lost or receive frame buffer overflow) was detected
|
|
|
|
CRITICAL_SECTION m_crsVidQoS; // Allows QoS thread to read the video statistics while capture and compression are running
|
|
|
|
static DWORD CALLBACK StartRenderingThread(PVOID pVoid);
|
|
DWORD RenderingThread();
|
|
|
|
STDMETHODIMP_(void) UnConfigure(void);
|
|
|
|
LONG m_lRefCount;
|
|
|
|
public:
|
|
RecvVideoStream() : RecvMediaStream(){m_Net=NULL; m_lRefCount=0; };
|
|
virtual ~RecvVideoStream();
|
|
|
|
// IUnknown
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
|
|
// IMediaChannel APIs
|
|
HRESULT STDMETHODCALLTYPE Configure(
|
|
BYTE *pFormat,
|
|
UINT cbFormat,
|
|
BYTE *pChannelParams,
|
|
UINT cbParams,
|
|
IUnknown *pUnknown);
|
|
|
|
|
|
STDMETHODIMP Start(void);
|
|
STDMETHODIMP Stop(void);
|
|
|
|
HRESULT STDMETHODCALLTYPE SetMaxBitrate(UINT uMaxBitrate)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IProperty methods
|
|
STDMETHODIMP GetProperty(DWORD dwProp, PVOID pBuf, LPUINT pcbBuf);
|
|
STDMETHODIMP SetProperty(DWORD dwProp, PVOID pBuf, UINT cbBuf);
|
|
|
|
// IVideoRender methods
|
|
STDMETHODIMP Init( DWORD_PTR dwUser, LPFNFRAMEREADY pfCallback);
|
|
STDMETHODIMP Done(void);
|
|
STDMETHODIMP GetFrame(FRAMECONTEXT* pfc);
|
|
STDMETHODIMP ReleaseFrame(FRAMECONTEXT *pfc);
|
|
|
|
// Other virtual methods
|
|
virtual HRESULT Initialize(DataPump *);
|
|
virtual BOOL IsEmpty();
|
|
HRESULT GetCurrentPlayNTPTime(NTP_TS *);
|
|
virtual HRESULT StartRecv(HWND);
|
|
virtual HRESULT StopRecv();
|
|
|
|
virtual HRESULT RTPCallback(WSABUF *pWsaBuf, DWORD timestamp, UINT seq, UINT fMark);
|
|
|
|
|
|
// Non virtual methods
|
|
|
|
};
|
|
|
|
extern char LogScale[];
|
|
|
|
class AudioSilenceDetector {
|
|
private:
|
|
UINT m_uManualSilenceLevel; // silence level in unit of 1/1000
|
|
DWORD m_dwMaxStrength; // signal strength in units of 1/1000
|
|
INT m_iSilenceLevel; // adaptive silence threshold
|
|
INT m_iSilenceAvg; // scale factor 256
|
|
INT m_iTalkAvg; // average strength of non-silent signal
|
|
|
|
public:
|
|
AudioSilenceDetector();
|
|
void SetSilenceLevel(UINT level) {m_uManualSilenceLevel = level;}
|
|
UINT GetSilenceLevel(void) {return m_uManualSilenceLevel;}
|
|
UINT GetSignalStrength(void) {return LogScale[m_dwMaxStrength >> 8];}
|
|
BOOL SilenceDetect(WORD strength);
|
|
};
|
|
|
|
class SendAudioStream : public SendMediaStream, public IAudioChannel, public IDTMFSend
|
|
{
|
|
friend class DataPump;
|
|
private:
|
|
WAVEFORMATEX m_fDevSend;
|
|
WAVEFORMATEX m_wfCompressed;
|
|
AcmFilter *m_pAudioFilter; // this will replace m_fSendFilter
|
|
MMIOSRC m_mmioSrc;
|
|
AudioSilenceDetector m_AudioMonitor;
|
|
BOOL m_bAutoMix;
|
|
|
|
static DWORD CALLBACK StartRecordingThread (LPVOID pVoid);
|
|
DWORD RecordingThread();
|
|
|
|
HRESULT SendPacket(AudioPacket *pAP, UINT *puBytesSent);
|
|
STDMETHODIMP_(void) UnConfigure(void);
|
|
|
|
LONG m_lRefCount;
|
|
|
|
DTMFQueue *m_pDTMF;
|
|
HRESULT __stdcall SendDTMF();
|
|
|
|
public:
|
|
SendAudioStream() : SendMediaStream(){m_Net=NULL;m_lRefCount=0;};
|
|
virtual ~SendAudioStream();
|
|
|
|
|
|
// IUnknown
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
|
|
// IMediaChannel APIs
|
|
// new version of Configure()
|
|
HRESULT STDMETHODCALLTYPE Configure(
|
|
BYTE *pFormat,
|
|
UINT cbFormat,
|
|
BYTE *pChannelParams,
|
|
UINT cbParams,
|
|
IUnknown *pUnknown);
|
|
|
|
STDMETHODIMP Start(void);
|
|
STDMETHODIMP Stop(void);
|
|
|
|
HRESULT STDMETHODCALLTYPE SetNetworkInterface(IUnknown *pUnknown)
|
|
{
|
|
return SendMediaStream::SetNetworkInterface(pUnknown);
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) GetState()
|
|
{
|
|
return SendMediaStream::GetState();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE SetMaxBitrate(UINT uMaxBitrate);
|
|
|
|
// IAudioChannel
|
|
STDMETHODIMP GetSignalLevel(UINT *pSignalStrength);
|
|
|
|
|
|
// IDTMFSend
|
|
virtual HRESULT __stdcall AddDigit(int nDigit);
|
|
virtual HRESULT __stdcall ResetDTMF();
|
|
|
|
|
|
// IProperty methods
|
|
STDMETHODIMP GetProperty(DWORD dwProp, PVOID pBuf, LPUINT pcbBuf);
|
|
STDMETHODIMP SetProperty(DWORD dwProp, PVOID pBuf, UINT cbBuf);
|
|
|
|
// Other virtual methods
|
|
virtual HRESULT Initialize(DataPump *pdp);
|
|
|
|
// Non virtual methods
|
|
static HRESULT CALLBACK QosNotifyAudioCB(LPRESOURCEREQUESTLIST lpResourceRequestList, DWORD_PTR dwThis);
|
|
|
|
HRESULT OpenSrcFile (void);
|
|
HRESULT CloseSrcFile (void);
|
|
DWORD Send();
|
|
void EndSend();
|
|
|
|
};
|
|
|
|
class RecvAudioStream : public RecvMediaStream, public IAudioChannel
|
|
{
|
|
friend class DataPump;
|
|
private:
|
|
WAVEFORMATEX m_fDevRecv;
|
|
IAppAudioCap* m_pAudioCaps; // pointer to the audio capabilities object
|
|
// mmio file operations
|
|
MMIODEST m_mmioDest;
|
|
|
|
AcmFilter *m_pAudioFilter; // this will replace m_fSendFilter
|
|
|
|
AudioSilenceDetector m_AudioMonitor;
|
|
|
|
CRITICAL_SECTION m_crsAudQoS; // Allows QoS thread to read the audio statistics while recording and compression are running
|
|
|
|
static DWORD CALLBACK StartPlaybackThread(LPVOID pVoid);
|
|
DWORD PlaybackThread();
|
|
|
|
STDMETHODIMP_(void) UnConfigure(void);
|
|
|
|
LONG m_lRefCount;
|
|
|
|
virtual HRESULT DTMFBeep();
|
|
|
|
|
|
public:
|
|
RecvAudioStream() :RecvMediaStream(){m_Net=NULL;m_lRefCount=0;};
|
|
virtual ~RecvAudioStream();
|
|
|
|
|
|
// IUnknown
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
|
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
|
|
|
|
// IMediaChannel APIs
|
|
HRESULT STDMETHODCALLTYPE Configure(
|
|
BYTE *pFormat,
|
|
UINT cbFormat,
|
|
BYTE *pChannelParams,
|
|
UINT cbParams,
|
|
IUnknown *pUnknown);
|
|
|
|
|
|
STDMETHODIMP Start(void);
|
|
STDMETHODIMP Stop(void);
|
|
|
|
HRESULT STDMETHODCALLTYPE SetNetworkInterface(IUnknown *pUnknown)
|
|
{
|
|
return RecvMediaStream::SetNetworkInterface(pUnknown);
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) GetState()
|
|
{
|
|
return RecvMediaStream::GetState();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE SetMaxBitrate(UINT uMaxBitrate)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// IAudioChannel
|
|
STDMETHODIMP GetSignalLevel(UINT *pSignalStrength);
|
|
|
|
|
|
// IProperty methods
|
|
STDMETHODIMP GetProperty(DWORD dwProp, PVOID pBuf, LPUINT pcbBuf);
|
|
STDMETHODIMP SetProperty(DWORD dwProp, PVOID pBuf, UINT cbBuf);
|
|
|
|
// Other virtual inherited methods
|
|
virtual HRESULT Initialize(DataPump *);
|
|
virtual BOOL IsEmpty();
|
|
HRESULT GetCurrentPlayNTPTime(NTP_TS *);
|
|
virtual HRESULT StartRecv(HWND);
|
|
virtual HRESULT StopRecv();
|
|
|
|
virtual HRESULT RTPCallback(WSABUF *pWsaBuf, DWORD timestamp, UINT seq, UINT fMark);
|
|
|
|
|
|
|
|
};
|
|
|
|
#include <poppack.h> /* End byte packing */
|
|
|
|
|
|
#endif // _MEDISTRM_H_
|
|
|