Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
353
Server.tproj/RTPSessionInterface.h
Normal file
353
Server.tproj/RTPSessionInterface.h
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
Contains: API interface for objects to use to get access to attributes,
|
||||
data items, whatever, specific to RTP sessions (see RTPSession.h
|
||||
for more details on what that object is). This object
|
||||
implements the RTP Session Dictionary.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _RTPSESSIONINTERFACE_H_
|
||||
#define _RTPSESSIONINTERFACE_H_
|
||||
|
||||
#include "QTSSDictionary.h"
|
||||
|
||||
#include "RTCPSRPacket.h"
|
||||
#include "RTSPSessionInterface.h"
|
||||
#include "TimeoutTask.h"
|
||||
#include "Task.h"
|
||||
#include "RTPBandwidthTracker.h"
|
||||
#include "RTPOverbufferWindow.h"
|
||||
#include "QTSServerInterface.h"
|
||||
#include "OSMutex.h"
|
||||
#include "atomic.h"
|
||||
#include "RTPSession3GPP.h"
|
||||
|
||||
class RTSPRequestInterface;
|
||||
|
||||
class RTPSessionInterface : public QTSSDictionary, public Task
|
||||
{
|
||||
public:
|
||||
|
||||
// Initializes dictionary resources
|
||||
static void Initialize();
|
||||
|
||||
//
|
||||
// CONSTRUCTOR / DESTRUCTOR
|
||||
|
||||
RTPSessionInterface();
|
||||
virtual ~RTPSessionInterface()
|
||||
{
|
||||
if (GetQualityLevel() != 0)
|
||||
QTSServerInterface::GetServer()->IncrementNumThinned(-1);
|
||||
if (fRTSPSession != NULL)
|
||||
fRTSPSession->DecrementObjectHolderCount();
|
||||
delete [] fSRBuffer.Ptr;
|
||||
delete [] fAuthNonce.Ptr;
|
||||
delete [] fAuthOpaque.Ptr;
|
||||
}
|
||||
|
||||
virtual void SetValueComplete(UInt32 inAttrIndex, QTSSDictionaryMap* inMap,
|
||||
UInt32 inValueIndex, void* inNewValue, UInt32 inNewValueLen);
|
||||
|
||||
//Timeouts. This allows clients to refresh the timeout on this session
|
||||
void RefreshTimeout() { fTimeoutTask.RefreshTimeout(); }
|
||||
void RefreshRTSPTimeout() { if (fRTSPSession != NULL) fRTSPSession->RefreshTimeout(); }
|
||||
void RefreshTimeouts() { RefreshTimeout(); RefreshRTSPTimeout();}
|
||||
|
||||
//
|
||||
// ACCESSORS
|
||||
|
||||
Bool16 IsFirstPlay() { return fIsFirstPlay; }
|
||||
SInt64 GetFirstPlayTime() { return fFirstPlayTime; }
|
||||
//Time (msec) most recent play was issued
|
||||
SInt64 GetPlayTime() { return fPlayTime; }
|
||||
SInt64 GetNTPPlayTime() { return fNTPPlayTime; }
|
||||
SInt64 GetSessionCreateTime() { return fSessionCreateTime; }
|
||||
//Time (msec) most recent play, adjusted for start time of the movie
|
||||
//ex: PlayTime() == 20,000. Client said start 10 sec into the movie,
|
||||
//so AdjustedPlayTime() == 10,000
|
||||
QTSS_PlayFlags GetPlayFlags() { return fPlayFlags; }
|
||||
OSMutex* GetSessionMutex() { return &fSessionMutex; }
|
||||
UInt32 GetPacketsSent() { return fPacketsSent; }
|
||||
UInt32 GetBytesSent() { return fBytesSent; }
|
||||
OSRef* GetRef() { return &fRTPMapElem; }
|
||||
RTSPSessionInterface* GetRTSPSession() { return fRTSPSession; }
|
||||
UInt32 GetMovieAvgBitrate(){ return fMovieAverageBitRate; }
|
||||
QTSS_CliSesTeardownReason GetTeardownReason() { return fTeardownReason; }
|
||||
QTSS_RTPSessionState GetSessionState() { return fState; }
|
||||
void SetUniqueID(UInt32 theID) {fUniqueID = theID;}
|
||||
UInt32 GetUniqueID() { return fUniqueID; }
|
||||
RTPBandwidthTracker* GetBandwidthTracker() { return &fTracker; }
|
||||
RTPOverbufferWindow* GetOverbufferWindow() { return &fOverbufferWindow; }
|
||||
UInt32 GetFramesSkipped() { return fFramesSkipped; }
|
||||
|
||||
//
|
||||
// MEMORY FOR RTCP PACKETS
|
||||
|
||||
//
|
||||
// Class for easily building a standard RTCP SR
|
||||
RTCPSRPacket* GetSRPacket() { return &fRTCPSRPacket; }
|
||||
|
||||
//
|
||||
// Memory if you want to build your own
|
||||
char* GetSRBuffer(UInt32 inSRLen);
|
||||
|
||||
//
|
||||
// STATISTICS UPDATING
|
||||
|
||||
//The session tracks the total number of bytes sent during the session.
|
||||
//Streams can update that value by calling this function
|
||||
void UpdateBytesSent(UInt32 bytesSent) { fBytesSent += bytesSent; }
|
||||
|
||||
//The session tracks the total number of packets sent during the session.
|
||||
//Streams can update that value by calling this function
|
||||
void UpdatePacketsSent(UInt32 packetsSent) { fPacketsSent += packetsSent; }
|
||||
|
||||
void UpdateCurrentBitRate(const SInt64& curTime)
|
||||
{ if (curTime > (fLastBitRateUpdateTime + 3000)) this->UpdateBitRateInternal(curTime); }
|
||||
|
||||
void SetAllTracksInterleaved(Bool16 newValue) { fAllTracksInterleaved = newValue; }
|
||||
//
|
||||
// RTSP RESPONSES
|
||||
|
||||
// This function appends a session header to the SETUP response, and
|
||||
// checks to see if it is a 304 Not Modified. If it is, it sends the entire
|
||||
// response and returns an error
|
||||
QTSS_Error DoSessionSetupResponse(RTSPRequestInterface* inRequest);
|
||||
|
||||
//
|
||||
// RTSP SESSION
|
||||
|
||||
// This object has a current RTSP session. This may change over the
|
||||
// life of the RTSPSession, so update it. It keeps an RTSP session in
|
||||
// case interleaved data or commands need to be sent back to the client.
|
||||
void UpdateRTSPSession(RTSPSessionInterface* inNewRTSPSession);
|
||||
|
||||
// let's RTSP Session pass along it's query string
|
||||
void SetQueryString( StrPtrLen* queryString );
|
||||
|
||||
// SETTERS and ACCESSORS for auth information
|
||||
// Authentication information that needs to be kept around
|
||||
// for the duration of the session
|
||||
QTSS_AuthScheme GetAuthScheme() { return fAuthScheme; }
|
||||
StrPtrLen* GetAuthNonce() { return &fAuthNonce; }
|
||||
UInt32 GetAuthQop() { return fAuthQop; }
|
||||
UInt32 GetAuthNonceCount() { return fAuthNonceCount; }
|
||||
StrPtrLen* GetAuthOpaque() { return &fAuthOpaque; }
|
||||
void SetAuthScheme(QTSS_AuthScheme scheme) { fAuthScheme = scheme; }
|
||||
// Use this if the auth scheme or the qop has to be changed from the defaults
|
||||
// of scheme = Digest, and qop = auth
|
||||
void SetChallengeParams(QTSS_AuthScheme scheme, UInt32 qop, Bool16 newNonce, Bool16 createOpaque);
|
||||
// Use this otherwise...if newNonce == true, it will create a new nonce
|
||||
// and reset nonce count. If newNonce == false but nonce was never created earlier
|
||||
// a nonce will be created. If newNonce == false, and there is an existing nonce,
|
||||
// the nounce count will be incremented.
|
||||
void UpdateDigestAuthChallengeParams(Bool16 newNonce, Bool16 createOpaque, UInt32 qop);
|
||||
|
||||
Float32* GetPacketLossPercent() { UInt32 outLen;return (Float32*) this->PacketLossPercent(this, &outLen);}
|
||||
|
||||
SInt32 GetQualityLevel() { return fSessionQualityLevel; }
|
||||
SInt32* GetQualityLevelPtr() { return &fSessionQualityLevel; }
|
||||
void SetQualityLevel(SInt32 level) { if (fSessionQualityLevel == 0 && level != 0)
|
||||
QTSServerInterface::GetServer()->IncrementNumThinned(1);
|
||||
else if (fSessionQualityLevel != 0 && level == 0)
|
||||
QTSServerInterface::GetServer()->IncrementNumThinned(-1);
|
||||
fSessionQualityLevel = level;
|
||||
}
|
||||
SInt64 fLastQualityCheckTime;
|
||||
SInt64 fLastQualityCheckMediaTime;
|
||||
Bool16 fStartedThinning;
|
||||
|
||||
// Used by RTPStream to increment the RTCP packet and byte counts.
|
||||
void IncrTotalRTCPPacketsRecv() { fTotalRTCPPacketsRecv++; }
|
||||
UInt32 GetTotalRTCPPacketsRecv() { return fTotalRTCPPacketsRecv; }
|
||||
void IncrTotalRTCPBytesRecv(UInt16 cnt) { fTotalRTCPBytesRecv += cnt; }
|
||||
UInt32 GetTotalRTCPBytesRecv() { return fTotalRTCPBytesRecv; }
|
||||
|
||||
UInt32 GetLastRTSPBandwithBits() { return fLastRTSPBandwidthHeaderBits; }
|
||||
UInt32 GetCurrentMovieBitRate() { return fMovieCurrentBitRate; }
|
||||
|
||||
UInt32 GetMaxBandwidthBits() { UInt32 maxRTSP = GetLastRTSPBandwithBits(); UInt32 maxLink = fRTPSession3GPP.GetLinkCharMaxKBits()* 1000; return (maxRTSP > maxLink) ? maxRTSP : maxLink; }
|
||||
|
||||
void SetIs3GPPSession(Bool16 is3GPP) { fIs3GPPSession = is3GPP; }
|
||||
|
||||
protected:
|
||||
|
||||
RTPSession3GPP* Get3GPPSessPtr() { return fRTPSession3GPPPtr; }
|
||||
|
||||
// These variables are setup by the derived RTPSession object when
|
||||
// Play and Pause get called
|
||||
|
||||
//Some stream related information that is shared amongst all streams
|
||||
Bool16 fIsFirstPlay;
|
||||
Bool16 fAllTracksInterleaved;
|
||||
SInt64 fFirstPlayTime;//in milliseconds
|
||||
SInt64 fPlayTime;
|
||||
SInt64 fAdjustedPlayTime;
|
||||
SInt64 fNTPPlayTime;
|
||||
SInt64 fNextSendPacketsTime;
|
||||
|
||||
SInt32 fSessionQualityLevel;
|
||||
|
||||
//keeps track of whether we are playing or not
|
||||
QTSS_RTPSessionState fState;
|
||||
|
||||
// If we are playing, this are the play flags that were set on play
|
||||
QTSS_PlayFlags fPlayFlags;
|
||||
|
||||
//Session mutex. This mutex should be grabbed before invoking the module
|
||||
//responsible for managing this session. This allows the module to be
|
||||
//non-preemptive-safe with respect to a session
|
||||
OSMutex fSessionMutex;
|
||||
|
||||
//Stores the session ID
|
||||
OSRef fRTPMapElem;
|
||||
char fRTSPSessionIDBuf[QTSS_MAX_SESSION_ID_LENGTH + 4];
|
||||
|
||||
UInt32 fLastBitRateBytes;
|
||||
SInt64 fLastBitRateUpdateTime;
|
||||
UInt32 fMovieCurrentBitRate;
|
||||
|
||||
// In order to facilitate sending data over the RTSP channel from
|
||||
// an RTP session, we store a pointer to the RTSP session used in
|
||||
// the last RTSP request.
|
||||
RTSPSessionInterface* fRTSPSession;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Utility function for calculating current bit rate
|
||||
void UpdateBitRateInternal(const SInt64& curTime);
|
||||
|
||||
static void* PacketLossPercent(QTSSDictionary* inSession, UInt32* outLen);
|
||||
static void* TimeConnected(QTSSDictionary* inSession, UInt32* outLen);
|
||||
static void* CurrentBitRate(QTSSDictionary* inSession, UInt32* outLen);
|
||||
|
||||
// Create nonce
|
||||
void CreateDigestAuthenticationNonce();
|
||||
|
||||
// One of the RTP session attributes is an iterated list of all streams.
|
||||
// As an optimization, we preallocate a "large" buffer of stream pointers,
|
||||
// even though we don't know how many streams we need at first.
|
||||
enum
|
||||
{
|
||||
kStreamBufSize = 4,
|
||||
kUserAgentBufSize = 256,
|
||||
kPresentationURLSize = 256,
|
||||
kFullRequestURLBufferSize = 256,
|
||||
kRequestHostNameBufferSize = 80,
|
||||
|
||||
kIPAddrStrBufSize = 20,
|
||||
kLocalDNSBufSize = 80,
|
||||
|
||||
kAuthNonceBufSize = 32,
|
||||
kAuthOpaqueBufSize = 32,
|
||||
|
||||
};
|
||||
|
||||
void* fStreamBuffer[kStreamBufSize];
|
||||
|
||||
|
||||
// theses are dictionary items picked up by the RTSPSession
|
||||
// but we need to store copies of them for logging purposes.
|
||||
char fUserAgentBuffer[kUserAgentBufSize];
|
||||
char fPresentationURL[kPresentationURLSize]; // eg /foo/bar.mov
|
||||
char fFullRequestURL[kFullRequestURLBufferSize]; // eg rtsp://yourdomain.com/foo/bar.mov
|
||||
char fRequestHostName[kRequestHostNameBufferSize]; // eg yourdomain.com
|
||||
|
||||
char fRTSPSessRemoteAddrStr[kIPAddrStrBufSize];
|
||||
char fRTSPSessLocalDNS[kLocalDNSBufSize];
|
||||
char fRTSPSessLocalAddrStr[kIPAddrStrBufSize];
|
||||
|
||||
char fUserNameBuf[RTSPSessionInterface::kMaxUserNameLen];
|
||||
char fUserPasswordBuf[RTSPSessionInterface::kMaxUserPasswordLen];
|
||||
char fUserRealmBuf[RTSPSessionInterface::kMaxUserRealmLen];
|
||||
UInt32 fLastRTSPReqRealStatusCode;
|
||||
|
||||
//for timing out this session
|
||||
TimeoutTask fTimeoutTask;
|
||||
UInt32 fTimeout;
|
||||
|
||||
// Time when this session got created
|
||||
SInt64 fSessionCreateTime;
|
||||
|
||||
//Packet priority levels. Each stream has a current level, and
|
||||
//the module that owns this session sets what the number of levels is.
|
||||
UInt32 fNumQualityLevels;
|
||||
|
||||
//Statistics
|
||||
UInt32 fBytesSent;
|
||||
UInt32 fPacketsSent;
|
||||
Float32 fPacketLossPercent;
|
||||
SInt64 fTimeConnected;
|
||||
UInt32 fTotalRTCPPacketsRecv;
|
||||
UInt32 fTotalRTCPBytesRecv;
|
||||
// Movie size & movie duration. It may not be so good to associate these
|
||||
// statistics with the movie, for a session MAY have multiple movies...
|
||||
// however, the 1 movie assumption is in too many subsystems at this point
|
||||
Float64 fMovieDuration;
|
||||
UInt64 fMovieSizeInBytes;
|
||||
UInt32 fMovieAverageBitRate;
|
||||
|
||||
QTSS_CliSesTeardownReason fTeardownReason;
|
||||
// So the streams can send sender reports
|
||||
UInt32 fUniqueID;
|
||||
|
||||
RTCPSRPacket fRTCPSRPacket;
|
||||
StrPtrLen fSRBuffer;
|
||||
|
||||
RTPBandwidthTracker fTracker;
|
||||
RTPOverbufferWindow fOverbufferWindow;
|
||||
|
||||
// Built in dictionary attributes
|
||||
static QTSSAttrInfoDict::AttrInfo sAttributes[];
|
||||
static unsigned int sRTPSessionIDCounter;
|
||||
|
||||
// Authentication information that needs to be kept around
|
||||
// for the duration of the session
|
||||
QTSS_AuthScheme fAuthScheme;
|
||||
StrPtrLen fAuthNonce;
|
||||
UInt32 fAuthQop;
|
||||
UInt32 fAuthNonceCount;
|
||||
StrPtrLen fAuthOpaque;
|
||||
UInt32 fQualityUpdate;
|
||||
|
||||
UInt32 fFramesSkipped;
|
||||
|
||||
RTPSession3GPP fRTPSession3GPP;
|
||||
RTPSession3GPP* fRTPSession3GPPPtr;
|
||||
UInt32 fLastRTSPBandwidthHeaderBits;
|
||||
Bool16 fIs3GPPSession;
|
||||
|
||||
};
|
||||
|
||||
#endif //_RTPSESSIONINTERFACE_H_
|
Loading…
Add table
Add a link
Reference in a new issue