📄 rtptran.h
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef _RTPTRAN_H_
#define _RTPTRAN_H_
// #define RTP_MESSAGE_DEBUG
#include "hxengin.h"
#include "hxmon.h"
#include "transbuf.h"
#include "statinfo.h"
#include "hxsmbw.h"
#include "ntptime.h"
#include "tconverter.h"
#include "chxkeepalive.h"
// GCC won't let me forward declare CHXMapLongToObj::Iterator,
// so I have to include this. -JR
#include "hxmap.h"
#include "hxslist.h"
#include "hxqossig.h"
#include "hxqos.h"
#include "packfilt.h"
struct IHXQoSTransportAdaptationInfo;
struct IHXScheduler;
struct IHXUDPSocket;
struct IHXPacket;
struct IHXBuffer;
struct IHXCommonClassFactory;
struct IHXInternalReset;
struct IHXPlayerState;
struct IHXAccurateClock;
class RTSPResendBuffer;
class CHXBitset;
class HX_deque;
class Timeval;
class CHXTimestampConverter;
class RTCPBaseTransport;
class RTCPUDPTransport;
class RTCPTCPTransport;
class RTCPPacket;
class ReportHandler;
_INTERFACE IHXQoSSignal;
_INTERFACE IHXQoSSignalBus;
_INTERFACE IHXQoSSignalSourceResponse;
HX_RESULT
FixRTPHeader(IHXCommonClassFactory* pCCF,
IHXBuffer* pOrigBuf,
REF(IHXBuffer*) pNewBuf,
UINT16 unSeqNoOffset,
UINT32 ulRTPTSOffset);
HX_RESULT
FixRTCPSR(IHXCommonClassFactory* pCCF,
IHXBuffer* pOrigBuf,
REF(IHXBuffer*) pNewBuf,
UINT32 ulRTPTSOffset);
/* The largest number of SR records we will keep */
#define LSR_HIST_SZ 64
struct LSRRecord
{
UINT32 m_ulSourceLSR;
UINT32 m_ulServerLSR;
};
/******************************************************************************
* RTP RTP RTP RTP RTP
******************************************************************************/
class RTPBaseTransport: public RTSPTransport, public IHXSourceBandwidthInfo
{
public:
RTPBaseTransport (BOOL bIsSource);
~RTPBaseTransport ();
STDMETHOD(QueryInterface) (THIS_
REFIID riid,
void** ppvObj);
STDMETHOD_(ULONG32,AddRef) (THIS);
STDMETHOD_(ULONG32,Release) (THIS);
/*
* IHXSourceBandwidthInfo methods
*/
STDMETHOD(InitBw) (THIS_
IHXBandwidthManagerInput* pBwMgr);
STDMETHOD(SetTransmitRate) (THIS_
UINT32 ulBitRate);
void Done ();
RTSPTransportTypeEnum tag ()
{
HX_ASSERT(!"don't call this");
return RTSP_TR_NONE;
};
HX_RESULT sendPacket (BasePacket* pPacket)
{
HX_ASSERT(!"don't call this");
return HXR_UNEXPECTED;
}
HX_RESULT init ();
HX_RESULT reflectPacket (BasePacket* pBasePacket, REF(IHXBuffer*)pSendBuf);
HX_RESULT makePacket (BasePacket* pPacket, REF(IHXBuffer*) pPacketBuf);
void updateQoSInfo (UINT32 ulBytesSent);
HX_RESULT handlePacket (IHXBuffer* pBuffer);
HX_RESULT handleMasterSync (ULONG32 ulHXTime, LONG32 lHXOffsetToMaster);
HX_RESULT anchorSync (ULONG32 ulHXTime, ULONG32 ulNTPTime);
virtual HX_RESULT handleRTCPSync (NTPTime ntpTime, ULONG32 ulRTPTime);
HX_RESULT streamDone (UINT16 streamNumber);
// IHXUDPSocket* getUDPSocket ();
void addStreamInfo (RTSPStreamInfo* pStreamInfo,
UINT32 ulBufferDepth = TRANSPORT_BUF_DURATION_UNDEF);
/* RTP-Info */
HX_RESULT setFirstSeqNum (UINT16 streamNumber, UINT16 seqNum);
void notifyEmptyRTPInfo (void);
void setFirstTimeStamp (UINT16 uStreamNumber, UINT32 ulTS,
BOOL bIsRaw = FALSE);
void setPlayRange (UINT32 ulFrom, UINT32 ulTo);
HX_RESULT setFirstPlayTime (Timeval* pTv);
void setRTCPTransport (RTCPBaseTransport* pRTCPTran);
void Reset(){}
void Restart(){}
BOOL isRTP() { return TRUE; }
BOOL isReflector() { return (m_ulPayloadWirePacket==1); }
void SyncTimestamp (IHXPacket* pPacket);
inline BOOL isRTCPRule (UINT16 unRuleNo)
{
return (m_bHasRTCPRule && (unRuleNo == m_RTCPRuleNumber));
}
/* XXXMC
* Special-case handling for PV clients
*/
void setPVEmulationMode (BOOL bEmulatePVSession);
protected:
#ifdef RTP_MESSAGE_DEBUG
void messageFormatDebugFileOut(const char* fmt, ...);
#endif // RTP_MESSAGE_DEBUG
void resetStartInfoWaitQueue (void);
/*
* Marker Bit Handling Routine
*/
typedef void (RTPBaseTransport::*HandleMBitFunc)(REF(UINT8),IHXPacket*,UINT16);
inline void MBitRTPPktInfo (REF(UINT8)bMBit, IHXPacket* pPkt, UINT16 unRuleNo);
inline void MBitASMRuleNo (REF(UINT8)bMBit, IHXPacket* pPkt, UINT16 unRuleNo);
IHXBandwidthManagerInput* m_pBwMgrInput;
IHXTransportSyncServer* m_pSyncServer;
UINT16 m_streamNumber;
INT32 m_lRefCount;
UINT8 m_rtpPayloadType;
BOOL m_bHasMarkerRule;
UINT16 m_markerRuleNumber;
BOOL m_bIsSyncMaster;
#ifdef RTP_MESSAGE_DEBUG
BOOL m_bMessageDebug;
CHXString m_messageDebugFileName;
#endif // RTP_MESSAGE_DEBUG
/*
* Reflection support
*/
BOOL m_bHasRTCPRule;
UINT32 m_ulPayloadWirePacket;
UINT16 m_RTCPRuleNumber;
UINT16 m_uFirstSeqNum;
UINT32 m_ulFirstRTPTS;
BOOL m_bFirstSet;
BOOL m_bWeakStartSync;
INT32 m_lTimeOffsetHX;
INT32 m_lTimeOffsetRTP;
INT32 m_lOffsetToMasterHX;
INT32 m_lOffsetToMasterRTP;
INT32 m_lSyncOffsetHX;
INT32 m_lSyncOffsetRTP;
INT32 m_lNTPtoHXOffset;
BOOL m_bNTPtoHXOffsetSet;
ULONG32 m_ulLastRTPTS;
ULONG32 m_ulLastHXTS;
ULONG32 m_ulLastRawRTPTS;
BOOL m_bLastTSSet;
CHXSimpleList m_StartInfoWaitQueue;
BOOL m_bWaitForStartInfo;
BOOL m_bAbortWaitForStartInfo;
ULONG32 m_ulStartInfoWaitStartTime;
BOOL m_bSSRCDetermined;
UINT32 m_ulSSRCDetermined;
/*
* RTP-Info: According to RFC2326, it is possible not to have one of them,
* so if it is missing, take care of it right here in transport
*/
BOOL m_bSeqNoSet;
/* m_bRTPTimeSet is used differently on the server and the client */
BOOL m_bRTPTimeSet;
// Since client is expecting RTP timestap starting at 0, we need to offset
// it in here. btw, this is a security risk...
UINT32 m_ulBaseTS;
Timeval* m_pFirstPlayTime;
/* this class does everything for RTCP */
ReportHandler* m_pReportHandler;
RTCPBaseTransport* m_pRTCPTran;
BOOL m_bIsLive;
UINT32 m_ulExtensionSupport;
/*
* This stream may not have been SETUPed.
*/
BOOL m_bActive;
/* XXXMC
* Support for PV Emulation
*/
BOOL m_bEmulatePVSession;
/*
* Markerbit Handling
*/
HandleMBitFunc m_pMBitHandler;
/*
* Reflector RTP-Info
*/
struct ReflectorInfo
{
ReflectorInfo()
: m_unSeqNoOffset(0)
, m_ulRTPTSOffset(0)
{}
UINT16 m_unSeqNoOffset;
UINT32 m_ulRTPTSOffset;
} m_reflectorInfo;
UINT8 m_cLSRRead;
UINT8 m_cLSRWrite;
LSRRecord m_LSRHistory [LSR_HIST_SZ];
UINT32 MapLSR(UINT32 ulSourceLSR);
IHXQoSTransportAdaptationInfo* m_pQoSInfo;
friend class RTCPBaseTransport;
friend class RTCPUDPTransport;
friend class RTCPTCPTransport;
private:
HX_RESULT _handlePacket(IHXBuffer* pBuffer, BOOL bIsRealTime);
};
/*
* NOTE:
* Each RTP transport represents a RTP session because transport is bounded to a pair
* of addr and ports.
* As it is currently implemented, RTP transport can NOT have more than one stream.
* Currently, we do NOT support RTSP/RTP multicast. so we don't need to do a number
* of things that should be done if we were to support multicast.
* 1. Maintain a table of members (instread we have just one member)
* 2. Don't really need to calculate RTCP intervals (instead every 5 sec)
* There are two assumptions due to the nature of 1 to 1 or 1 to many session
* 1. A server (server) never receives RTP.
* 2. There is only one sender (server) in a session.
*/
class RTPUDPTransport: public RTPBaseTransport
{
public:
RTPUDPTransport (BOOL bIsSource);
~RTPUDPTransport ();
void Done ();
RTSPTransportTypeEnum tag ();
HX_RESULT init (IUnknown* pContext,
IHXUDPSocket* pSocket,
IHXRTSPTransportResponse* pResp);
void setForeignAddress (UINT32 foreignAddr,
UINT16 foreignPort);
HX_RESULT sendPacket (BasePacket* pPacket);
IHXUDPSocket* getUDPSocket ();
// void setRTCPTransport (RTCPUDPTransport* pRTCPTran);
/* XXXMC
* Special-case handling for PV clients
*/
HX_RESULT sendPVHandshakeResponse(UINT8* pPktPayload);
HX_RESULT handlePacket(IHXBuffer* pBuffer);
void JoinMulticast(UINT32 ulAddress, UINT32 ulPort, IHXUDPSocket* pUDP);
IHXUDPSocket* getMulticastSocket(void);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -