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
340
RTSPClientLib/ClientSession.h
Normal file
340
RTSPClientLib/ClientSession.h
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
*
|
||||
* @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@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: ClientSession.h
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __CLIENT_SESSION__
|
||||
#define __CLIENT_SESSION__
|
||||
|
||||
#include "Task.h"
|
||||
#include "TimeoutTask.h"
|
||||
|
||||
#include "SVector.h"
|
||||
#include "RTSPClient.h"
|
||||
#include "ClientSocket.h"
|
||||
#include "SDPSourceInfo.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "PlayerSimulator.h"
|
||||
|
||||
class ClientSession : public Task
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
kRTSPUDPClientType = 0,
|
||||
kRTSPTCPClientType = 1,
|
||||
kRTSPHTTPClientType = 2,
|
||||
kRTSPHTTPDropPostClientType = 3,
|
||||
kRTSPReliableUDPClientType = 4
|
||||
};
|
||||
typedef UInt32 ClientType;
|
||||
|
||||
//The constructor will signal itself with Task::kStartEvent
|
||||
ClientSession( UInt32 inAddr, UInt16 inPort, char* inURL,
|
||||
ClientType inClientType,
|
||||
UInt32 inDurationInSec, UInt32 inStartPlayTimeInSec,
|
||||
UInt32 inRTCPIntervalInMS, UInt32 inOptionsIntervalInSec,
|
||||
UInt32 inHTTPCookie, Bool16 inAppendJunkData, UInt32 inReadInterval,
|
||||
UInt32 inSockRcvBufSize, Float32 inLateTolerance, char* inMetaInfoFields,
|
||||
Float32 inSpeed, UInt32 verboseLevel, char* inPacketRangePlayHeader, UInt32 inOverbufferWindowSizeInK,
|
||||
Bool16 sendOptions, Bool16 requestRandomData, SInt32 randomDataSize, Bool16 enable3GPP,
|
||||
UInt32 GBW = 0, UInt32 MBW = 0, UInt32 MTD = 0, Bool16 enableForcePlayoutDelay = false, UInt32 playoutDelay = 0,
|
||||
UInt32 bandwidth = 0, UInt32 bufferSpace = 0, UInt32 delayTime = 0, UInt32 startPlayDelay = 0,
|
||||
char *controlID = NULL, char *name = NULL, char *password = NULL);
|
||||
|
||||
virtual ~ClientSession();
|
||||
|
||||
//
|
||||
// Signals.
|
||||
//
|
||||
// Send a kKillEvent to delete this object.
|
||||
// Send a kTeardownEvent to tell the object to send a TEARDOWN and abort
|
||||
|
||||
enum
|
||||
{
|
||||
kTeardownEvent = 0x00000100
|
||||
};
|
||||
|
||||
virtual SInt64 Run();
|
||||
|
||||
//
|
||||
// States. Find out what the object is currently doing
|
||||
enum
|
||||
{
|
||||
kSendingOptions = 0,
|
||||
kSendingDescribe = 1,
|
||||
kSendingSetup = 2,
|
||||
kSendingPlay = 3,
|
||||
kPlaying = 4,
|
||||
kSendingTeardown = 5,
|
||||
kDone = 6
|
||||
};
|
||||
//
|
||||
// Why did this session die?
|
||||
enum
|
||||
{
|
||||
kDiedNormally = 0, // Session went fine
|
||||
kTeardownFailed = 1, // Teardown failed, but session stats are all valid
|
||||
kRequestFailed = 2, // Session couldn't be setup because the server returned an error
|
||||
kBadSDP = 3, // Server sent back some bad SDP
|
||||
kSessionTimedout = 4, // Server not responding
|
||||
kConnectionFailed = 5, // Couldn't connect at all.
|
||||
kDiedWhilePlaying = 6 // Connection was forceably closed while playing the movie
|
||||
};
|
||||
|
||||
//
|
||||
// Once this client session is completely done with the TEARDOWN and ready to be
|
||||
// destructed, this will return true. Until it returns true, this object should not
|
||||
// be deleted. When it does return true, this object should be deleted.
|
||||
Bool16 IsDone() { return fState == kDone; }
|
||||
|
||||
//
|
||||
// ACCESSORS
|
||||
|
||||
RTSPClient* GetClient() { return fClient; }
|
||||
ClientSocket* GetSocket() { return fSocket; }
|
||||
SDPSourceInfo* GetSDPInfo() { return &fSDPParser; }
|
||||
UInt32 GetState() { return fState; }
|
||||
|
||||
// When this object is in the kDone state, this will tell you why the session died.
|
||||
UInt32 GetReasonForDying() { return fDeathReason; }
|
||||
UInt32 GetRequestStatus() { return fClient->GetStatus(); }
|
||||
|
||||
// Tells you the total time we were receiving packets. You can use this
|
||||
// for computing bit rate
|
||||
SInt64 GetTotalPlayTimeInMsec() { return fTotalPlayTime; }
|
||||
|
||||
QTSS_RTPPayloadType GetTrackType(UInt32 inTrackIndex)
|
||||
{ return fSDPParser.GetStreamInfo(inTrackIndex)->fPayloadType; }
|
||||
UInt32 GetNumPacketsReceived(UInt32 inTrackIndex) { return fStats[inTrackIndex].fNumPacketsReceived; }
|
||||
UInt32 GetNumBytesReceived(UInt32 inTrackIndex) { return fStats[inTrackIndex].fNumBytesReceived; }
|
||||
UInt32 GetNumPacketsOutOfOrder(UInt32 inTrackIndex) { return fStats[inTrackIndex].fNumOutOfOrderPackets; }
|
||||
UInt32 GetNumOutOfBoundPackets(UInt32 inTrackIndex) { return fStats[inTrackIndex].fNumOutOfBoundPackets; }
|
||||
UInt32 GetNumAcks(UInt32 inTrackIndex) { return fStats[inTrackIndex].fNumAcks; }
|
||||
UInt32 Get3gNumPacketsLost(UInt32 inTrackIndex) { return fPlayerSimulator.GetNumPacketsLost(inTrackIndex); }
|
||||
UInt32 Get3gNumDuplicates(UInt32 inTrackIndex) { return fPlayerSimulator.GetNumDuplicates(inTrackIndex); }
|
||||
UInt32 Get3gNumLatePackets(UInt32 inTrackIndex) { return fPlayerSimulator.GetNumLatePackets(inTrackIndex); }
|
||||
UInt32 Get3gNumBufferOverflowedPackets(UInt32 inTrackIndex) { return fPlayerSimulator.GetNumBufferOverflowedPackets(inTrackIndex); }
|
||||
//include packets with bad SSRC
|
||||
UInt32 GetNumMalformedPackets(UInt32 inTrackIndex)
|
||||
{ return fStats[inTrackIndex].fNumMalformedPackets; }
|
||||
|
||||
//Will reset the counter everytime it is called
|
||||
UInt32 GetSessionPacketsReceived() { UInt32 result = fNumPacketsReceived; fNumPacketsReceived = 0; return result; }
|
||||
//
|
||||
// Global stats
|
||||
static UInt32 GetActiveConnections() { return sActiveConnections; }
|
||||
static UInt32 GetPlayingConnections() { return sPlayingConnections; }
|
||||
static UInt32 GetConnectionAttempts() { return sTotalConnectionAttempts; }
|
||||
//The following two functions will reset the global counter every time it is called
|
||||
static UInt32 GetConnectionBytesReceived() { UInt32 result = sBytesReceived; sBytesReceived = 0; return result; }
|
||||
static UInt32 GetConnectionPacketsReceived() { UInt32 result = sPacketsReceived; sPacketsReceived = 0; return result; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
kRawRTSPControlType = 0,
|
||||
kRTSPHTTPControlType = 1,
|
||||
kRTSPHTTPDropPostControlType= 2
|
||||
};
|
||||
typedef UInt32 ControlType;
|
||||
|
||||
enum
|
||||
{
|
||||
kUDPTransportType = 0,
|
||||
kReliableUDPTransportType = 1,
|
||||
kTCPTransportType = 2
|
||||
};
|
||||
typedef UInt32 TransportType;
|
||||
|
||||
//Returns kUInt32_Max if there is no track with such trackID
|
||||
UInt32 TrackID2TrackIndex(UInt32 trackID)
|
||||
{
|
||||
for (UInt32 trackIndex = 0; trackIndex < fSDPParser.GetNumStreams(); trackIndex++)
|
||||
{
|
||||
if (fSDPParser.GetStreamInfo(trackIndex)->fTrackID == trackID)
|
||||
return trackIndex;
|
||||
}
|
||||
return kUInt32_Max;
|
||||
}
|
||||
|
||||
ClientSocket* fSocket; // Connection object
|
||||
RTSPClient* fClient; // Manages the client connection
|
||||
SDPSourceInfo fSDPParser; // Parses the SDP in the DESCRIBE response
|
||||
TimeoutTask fTimeoutTask; // Kills this connection in the event the server isn't responding
|
||||
|
||||
ControlType fControlType;
|
||||
TransportType fTransportType;
|
||||
UInt32 fDurationInSec;
|
||||
UInt32 fStartPlayTimeInSec;
|
||||
UInt32 fRTCPIntervalInMs;
|
||||
UInt32 fOptionsIntervalInSec;
|
||||
|
||||
Bool16 fOptions;
|
||||
Bool16 fOptionsRequestRandomData;
|
||||
SInt32 fOptionsRandomDataSize;
|
||||
SInt64 fTransactionStartTimeMilli;
|
||||
|
||||
UInt32 fState; // For managing the state machine
|
||||
UInt32 fDeathReason;
|
||||
UInt32 fNumSetups;
|
||||
UDPSocket** fUDPSocketArray;
|
||||
|
||||
//these values starts as soon as the RTSP Play is completed; does not corresonds to actual media play time
|
||||
SInt64 fPlayTime;
|
||||
SInt64 fTotalPlayTime;
|
||||
SInt64 fLastRTCPTime;
|
||||
|
||||
Bool16 fTeardownImmediately;
|
||||
Bool16 fAppendJunk;
|
||||
UInt32 fReadInterval;
|
||||
UInt32 fSockRcvBufSize;
|
||||
|
||||
Float32 fSpeed;
|
||||
char* fPacketRangePlayHeader;
|
||||
|
||||
//These values are for the wireless links only -- not end-to-end
|
||||
//Units are in kbps, milliseconds, and bytes
|
||||
UInt32 fGuarenteedBitRate;
|
||||
UInt32 fMaxBitRate;
|
||||
UInt32 fMaxTransferDelay;
|
||||
Bool16 fEnableForcePlayoutDelay;
|
||||
UInt32 fPlayoutDelay;
|
||||
UInt32 fBandwidth; //bps
|
||||
//the buffer space is per stream, not total space
|
||||
UInt32 fBufferSpace;
|
||||
UInt32 fDelayTime; //target buffering delay
|
||||
UInt32 fStartPlayDelay; //how much buffer should we keep before we start playing? in milliseconds
|
||||
Bool16 fEnable3GPP;
|
||||
|
||||
// Client stats
|
||||
struct TrackStats
|
||||
{
|
||||
//Modified by ClientSession
|
||||
UInt32 fNumPacketsReceived; //track only good packets(but include late and duplicates)
|
||||
UInt32 fNumBytesReceived; //includes RTP header
|
||||
UInt32 fNumOutOfOrderPackets; //excludes duplicates
|
||||
UInt32 fNumOutOfBoundPackets;
|
||||
UInt32 fNumMalformedPackets; //include packets with bad SSRC
|
||||
UInt32 fNumAcks; //cumulative; counts ACK packets with masks as 1 ACK
|
||||
|
||||
UInt16 fDestRTCPPort;
|
||||
UInt32 fServerSSRC; //0 for not available
|
||||
UInt32 fClientSSRC;
|
||||
|
||||
//Used for the DLSR and LSR field of the RTCP
|
||||
SInt64 fLastSenderReportNTPTime;
|
||||
SInt64 fLastSenderReportLocalTime;
|
||||
|
||||
//These values are used to calculate the fraction lost and cumulative number of packets lost field in the RTCP RR packet.
|
||||
//See RFC 3550 6.4.1 and A.3
|
||||
|
||||
//fHighestSeqNum is the highest valid sequence number received; note that this is 32 bits so that it never overflows.
|
||||
//An initial value of kUInt32_Max is used as an invalid marker(such that no valid sequence number has been received yet).
|
||||
UInt32 fHighestSeqNum;
|
||||
UInt32 fBaseSeqNum;
|
||||
UInt32 fExpectedPrior;
|
||||
UInt32 fReceivedPrior;
|
||||
|
||||
SVector<UInt32> fPacketsToAck;
|
||||
TrackStats() : fNumPacketsReceived(0), fNumBytesReceived(0), fNumOutOfOrderPackets(0), fNumOutOfBoundPackets(0),
|
||||
fNumMalformedPackets(0), fNumAcks(0), fDestRTCPPort(0), fServerSSRC(0), fClientSSRC(0), fLastSenderReportNTPTime(0),
|
||||
fLastSenderReportLocalTime(0), fHighestSeqNum(kUInt32_Max), fBaseSeqNum(0), fExpectedPrior(0), fReceivedPrior(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
/* Client stats
|
||||
struct TrackStats
|
||||
{
|
||||
enum
|
||||
{
|
||||
kSeqNumMapSize = 100,
|
||||
kHalfSeqNumMap = 50
|
||||
};
|
||||
|
||||
UInt16 fDestRTCPPort;
|
||||
UInt32 fNumPacketsReceived;
|
||||
UInt32 fNumBytesReceived;
|
||||
UInt32 fNumLostPackets;
|
||||
UInt32 fNumOutOfOrderPackets;
|
||||
UInt32 fNumThrownAwayPackets;
|
||||
UInt8 fSequenceNumberMap[kSeqNumMapSize];
|
||||
UInt16 fWrapSeqNum;
|
||||
UInt32 fSSRC;
|
||||
Bool16 fIsSSRCValid;
|
||||
|
||||
UInt16 fHighestSeqNum;
|
||||
UInt16 fLastAckedSeqNum;
|
||||
Bool16 fHighestSeqNumValid;
|
||||
|
||||
UInt32 fNumAcks;
|
||||
UInt32 fNumDuplicates;
|
||||
|
||||
};
|
||||
*/
|
||||
UInt32 fOverbufferWindowSizeInK;
|
||||
UInt32 fCurRTCPTrack; //track index not track id
|
||||
UInt32 fNumPacketsReceived; //track only good packets(but include late and duplicates; see RFC3550 6.4.1)
|
||||
UInt32 fNumBytesReceived; //includes RTP header
|
||||
|
||||
UInt32 fVerboseLevel;
|
||||
|
||||
SVector<TrackStats> fStats; //the index of this vector is the same as fSDPParser.GetStreamInfo
|
||||
|
||||
PlayerSimulator fPlayerSimulator;
|
||||
|
||||
//TrackStats* fStats;
|
||||
|
||||
//
|
||||
// Global stats
|
||||
static UInt32 sActiveConnections;
|
||||
static UInt32 sPlayingConnections;
|
||||
static UInt32 sTotalConnectionAttempts;
|
||||
static UInt32 sBytesReceived;
|
||||
static UInt32 sPacketsReceived;
|
||||
|
||||
//
|
||||
// Helper functions for Run()
|
||||
void SetupUDPSockets();
|
||||
void ProcessRTPPacket(char* inPacket, UInt32 inLength, UInt32 inTrackID);
|
||||
void ProcessRTCPPacket(char* inPacket, UInt32 inLength, UInt32 inTrackID);
|
||||
OS_Error ReadMediaData();
|
||||
OS_Error SendRTCPPackets(UInt32 trackIndex);
|
||||
void SendAckPackets(UInt32 inTrackIndex);
|
||||
|
||||
//Calculates the RTCP RR's fraction lost and cumulative number of packets lost field info.
|
||||
void CalcRTCPRRPacketsLost(UInt32 trackIndex, UInt8 &outFracLost, SInt32 &outCumLostPackets);
|
||||
|
||||
//Returns kUInt32_Max if newSeqNum is out of bound, otherwise returns the corresponding 32 bit sequence number.
|
||||
static UInt32 CalcSeqNum(UInt32 referenceSeqNum, UInt16 newSeqNum);
|
||||
};
|
||||
|
||||
#endif //__CLIENT_SESSION__
|
Loading…
Add table
Add a link
Reference in a new issue