Very rough first start, not even everything added
This commit is contained in:
commit
af3619d4fa
88 changed files with 24251 additions and 0 deletions
288
PlaylistBroadcaster.tproj/BroadcasterSession.h
Executable file
288
PlaylistBroadcaster.tproj/BroadcasterSession.h
Executable file
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
*
|
||||
* @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: BroadcasterSession.h
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __BROADCASTER_SESSION__
|
||||
#define __BROADCASTER_SESSION__
|
||||
|
||||
|
||||
#include "Task.h"
|
||||
|
||||
#include "TimeoutTask.h"
|
||||
|
||||
|
||||
#include "RTSPClient.h"
|
||||
#include "ClientSocket.h"
|
||||
#include "SDPSourceInfo.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "StrPtrLen.h"
|
||||
#include "OSMutex.h"
|
||||
|
||||
class BroadcasterSession : public Task
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
kRTSPUDPBroadcasterType = 0,
|
||||
kRTSPTCPBroadcasterType = 1,
|
||||
kRTSPHTTPBroadcasterType = 2,
|
||||
kRTSPHTTPDropPostBroadcasterType = 3,
|
||||
kRTSPReliableUDPBroadcasterType = 4
|
||||
};
|
||||
typedef UInt32 BroadcasterType;
|
||||
|
||||
BroadcasterSession( UInt32 inAddr, UInt16 inPort, char* inURL,
|
||||
BroadcasterType inBroadcasterType,
|
||||
UInt32 inDurationInSec, UInt32 inStartPlayTimeInSec,
|
||||
UInt32 inRTCPIntervalInSec, UInt32 inOptionsIntervalInSec,
|
||||
UInt32 inHTTPCookie, Bool16 inAppendJunkData, UInt32 inReadInterval,
|
||||
UInt32 inSockRcvBufSize,
|
||||
StrPtrLen *sdpSPLPtr,
|
||||
char *namePtr,
|
||||
char *passwordPtr,
|
||||
Bool16 deepDebug,
|
||||
Bool16 burst);
|
||||
virtual ~BroadcasterSession();
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
kSendingAnnounce = 0,
|
||||
kSendingSetup = 1,
|
||||
kSendingReceive = 2,
|
||||
kBroadcasting = 3,
|
||||
kSendingTeardown = 4,
|
||||
kDone = 5
|
||||
};
|
||||
//
|
||||
// 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.
|
||||
kDiedWhileBroadcasting = 6, // Connection was forceably closed while Broadcasting the movie
|
||||
kMemoryError = 7
|
||||
};
|
||||
|
||||
//
|
||||
// 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* GetBroadcaster() { return fRTSPClient; }
|
||||
ClientSocket* GetSocket() { return fSocket; }
|
||||
SDPSourceInfo* GetSDPInfo() { return &fSDPParser; }
|
||||
UInt32 GetState() { return fState; }
|
||||
UInt32 GetDeathState() { return fDeathState; }
|
||||
|
||||
// When this object is in the kDone state, this will tell you why the session died.
|
||||
UInt32 GetReasonForDying() { return fDeathReason; }
|
||||
UInt32 GetRequestStatus() { return fRTSPClient->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 GetNumPacketsLost(UInt32 inTrackIndex)
|
||||
{ return fStats[inTrackIndex].fNumLostPackets; }
|
||||
UInt32 GetNumPacketsOutOfOrder(UInt32 inTrackIndex)
|
||||
{ return fStats[inTrackIndex].fNumOutOfOrderPackets; }
|
||||
UInt32 GetNumDuplicates(UInt32 inTrackIndex)
|
||||
{ return fStats[inTrackIndex].fNumDuplicates; }
|
||||
UInt32 GetNumAcks(UInt32 inTrackIndex)
|
||||
{ return fStats[inTrackIndex].fNumAcks; }
|
||||
UInt32 GetNumStreams()
|
||||
{ return fSDPParser.GetNumStreams();}
|
||||
UInt32 GetStreamDestPort(UInt32 inIndex)
|
||||
{ return fStats[inIndex].fDestRTPPort;}
|
||||
|
||||
void TearDownNow() {fTeardownImmediately = true; this->Signal(Task::kKillEvent);}
|
||||
//
|
||||
// Global stats
|
||||
static UInt32 GetActiveConnections() { return sActiveConnections; }
|
||||
static UInt32 GetBroadcastingConnections() { return sBroadcastingConnections; }
|
||||
static UInt32 GetConnectionAttempts() { return sTotalConnectionAttempts; }
|
||||
char* GetNextPacket(UInt32 *packetLen, UInt8 *channel);
|
||||
OS_Error SendPacket(char* data, UInt32 len,UInt8 channel);
|
||||
OS_Error SendWaitingPackets();
|
||||
|
||||
enum
|
||||
{
|
||||
kUDPTransportType = 0,
|
||||
kReliableUDPTransportType = 1,
|
||||
kTCPTransportType = 2
|
||||
};
|
||||
typedef UInt32 TransportType;
|
||||
|
||||
TransportType GetTransportType() { return fTransportType; }
|
||||
|
||||
UInt32 GetPacketQLen() { return fPacketQueue.GetLength(); }
|
||||
OSMutex* GetMutex() { return &fMutex; }
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
kRawRTSPControlType = 0,
|
||||
kRTSPHTTPControlType = 1,
|
||||
kRTSPHTTPDropPostControlType= 2
|
||||
};
|
||||
typedef UInt32 ControlType;
|
||||
|
||||
|
||||
ClientSocket* fSocket; // Connection object
|
||||
RTSPClient* fRTSPClient; // 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 fRTCPIntervalInSec;
|
||||
UInt32 fOptionsIntervalInSec;
|
||||
|
||||
UInt32 fState; // For managing the state machine
|
||||
UInt32 fDeathState; // state at time of death
|
||||
UInt32 fDeathReason;
|
||||
UInt32 fNumSetups;
|
||||
UDPSocket** fUDPSocketArray;
|
||||
|
||||
SInt64 fPlayTime;
|
||||
SInt64 fTotalPlayTime;
|
||||
SInt64 fLastRTCPTime;
|
||||
|
||||
Bool16 fTeardownImmediately;
|
||||
Bool16 fAppendJunk;
|
||||
UInt32 fReadInterval;
|
||||
UInt32 fSockRcvBufSize;
|
||||
Bool16 fBurst;
|
||||
UInt32 fBurstTime;
|
||||
//
|
||||
// Broadcaster stats
|
||||
struct TrackStats
|
||||
{
|
||||
enum
|
||||
{
|
||||
kSeqNumMapSize = 100,
|
||||
kHalfSeqNumMap = 50
|
||||
};
|
||||
|
||||
UInt16 fDestRTPPort;
|
||||
UInt16 fDestRTCPPort;
|
||||
UInt32 fNumPacketsReceived;
|
||||
UInt32 fNumBytesReceived;
|
||||
UInt32 fNumLostPackets;
|
||||
UInt32 fNumOutOfOrderPackets;
|
||||
UInt32 fNumThrownAwayPackets;
|
||||
UInt8 fSequenceNumberMap[kSeqNumMapSize];
|
||||
UInt16 fWrapSeqNum;
|
||||
UInt16 fLastSeqNum;
|
||||
UInt32 fSSRC;
|
||||
Bool16 fIsSSRCValid;
|
||||
|
||||
UInt16 fHighestSeqNum;
|
||||
UInt16 fLastAckedSeqNum;
|
||||
Bool16 fHighestSeqNumValid;
|
||||
|
||||
UInt32 fNumAcks;
|
||||
UInt32 fNumDuplicates;
|
||||
|
||||
};
|
||||
TrackStats* fStats;
|
||||
|
||||
static char* fPacket;
|
||||
//
|
||||
// Global stats
|
||||
static UInt32 sActiveConnections;
|
||||
static UInt32 sBroadcastingConnections;
|
||||
static UInt32 sTotalConnectionAttempts;
|
||||
|
||||
//
|
||||
// Helper functions for Run()
|
||||
void SetupUDPSockets();
|
||||
void ProcessMediaPacket(char* inPacket, UInt32 inLength, UInt32 inTrackID, Bool16 isRTCP);
|
||||
OS_Error ReadMediaData();
|
||||
void SendReceiverReport();
|
||||
void AckPackets(UInt32 inTrackIndex, UInt16 inCurSeqNum, Bool16 inCurSeqNumValid);
|
||||
|
||||
OSMutex fMutex;//this data structure is shared!
|
||||
|
||||
struct RTPPacket
|
||||
{
|
||||
RTPPacket() : fQueueElem(NULL), fData(NULL), fLen(0), fChannel(0),fCount(0){}
|
||||
~RTPPacket() { fData = NULL; fLen = 0; fChannel = 0; }
|
||||
void SetEnclosingObject(void *obj) {fQueueElem.SetEnclosingObject(obj);}
|
||||
void SetPacketData(char* data, UInt32 len,UInt8 channel) { fData = data; fLen = len; fChannel = channel; }
|
||||
OSQueueElem *GetQElement() {return &fQueueElem;}
|
||||
OSQueueElem fQueueElem;
|
||||
char* fData;
|
||||
UInt32 fLen;
|
||||
UInt8 fChannel;
|
||||
UInt64 fCount;
|
||||
};
|
||||
UInt64 fPacketCount;
|
||||
OSQueue fPacketQueue;
|
||||
|
||||
UInt32 fPacketLen;
|
||||
UInt8 fChannel;
|
||||
// char* fPacket;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //__BROADCASTER_SESSION__
|
Loading…
Add table
Add a link
Reference in a new issue