Darwin-Streaming-Server/PlaylistBroadcaster.tproj/playlist_elements.h

327 lines
11 KiB
C++

/*
*
* @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@
*
*/
#ifndef playlist_elements_H
#define playlist_elements_H
#include <stdio.h>
#include <stdlib.h>
#include "SafeStdLib.h"
#include <string.h>
#include <errno.h>
#ifndef __Win32__
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#endif
#include "playlist_array.h"
#include "OSHeaders.h"
#include "playlist_SimpleParse.h"
#include "QTRTPFile.h"
#include "BroadcasterSession.h"
class MediaStream;
struct SoundDescription {
SInt32 descSize; /* total size of SoundDescription including extra data */
SInt32 dataFormat; /* sound format */
SInt32 resvd1; /* reserved for apple use. set to zero */
SInt16 resvd2; /* reserved for apple use. set to zero */
SInt16 dataRefIndex;
SInt16 version; /* which version is this data */
SInt16 revlevel; /* what version of that codec did this */
SInt32 vendor; /* whose codec compressed this data */
SInt16 numChannels; /* number of channels of sound */
SInt16 sampleSize; /* number of bits per sample */
SInt16 compressionID; /* unused. set to zero. */
SInt16 packetSize; /* unused. set to zero. */
UInt32 sampleRate; /* sample rate sound is captured at */
};
class PayLoad {
public:
PayLoad(void) : payloadID(0), timeScale(1) {};
int payloadID;
SimpleString payLoadString;
UInt32 timeScale;
};
class TypeMap {
public:
TypeMap(void) : fMediaStreamPtr(0), fTrackID(0), fPort(0), fTimeScale(1) {};
~TypeMap() { } ;
MediaStream *fMediaStreamPtr;
int fTrackID;
int fPort;
UInt32 fTimeScale;
SimpleString fTheTypeStr;
SimpleString fProtocolStr;
ArrayList<PayLoad> fPayLoadTypes;
ArrayList<SInt16> fPayLoads;
};
class RTpPacket
{
struct SoundHeader {
char bytes[4];
SInt32 skip1;
char sndtype[4];
SInt32 skip2;
char test[4];
};
public:
enum { kRTpHeaderSize = 12 };
char *fThePacket;
int fLength;
bool fHasSoundDescription;
SInt32 fSoundDescriptionLen;
RTpPacket() : fThePacket(NULL), fLength(0), fHasSoundDescription(false), fSoundDescriptionLen(0) {};
void SetPacketData(char *thePacket, int length) {fThePacket = thePacket; fLength = length; };
SInt16 SetHeaderInfo( UInt32 timeStamp, UInt16 sequence,UInt32 SSRC,unsigned char payloadType);
SInt16 GetHeaderInfo( UInt32 *timeStampPtr, UInt16 *sequencePtr,UInt32 *SSRCPtr,unsigned char*payloadType);
bool HasSoundDescription();
SInt16 GetSoundDescriptionRef(SoundDescription **soundDescriptionPtr);
protected:
enum { cSequenceNumber = 1, cTimeStamp = 1, cSSRC = 2, cPayloadType = 1};
};
class UDPSocketPair
{
public:
enum
{
kBound = 1L << 0,
kConnected = 1L << 1
};
enum { eBindMaxTries = 100,
eSourcePortStart = 49152, // rtp + rtcp
eSourcePortRange = 65535 // 49152,49153 - 65534,65535
};
enum
{
kInvalidSocket = -1, //int
kPortRTCpufSizeInBytes = 8, //UInt32
kMaxIPAddrSizeInBytes = 20 //UInt32
};
int fMaxBindAttempts;
int fState;
int fSocketRTp;
struct sockaddr_in fLocalAddrRTp;
struct sockaddr_in fDestAddrRTp;
int fSocketRTCp;
struct sockaddr_in fLocalAddrRTCp;
struct sockaddr_in fDestAddrRTCp;
BroadcasterSession *fBroadcasterSession;
UInt8 fChannel;
Bool16 fIsMultiCast;
Bool16 fMultiCastJoined;
UDPSocketPair() : fMaxBindAttempts(eBindMaxTries),
fState(0),
fSocketRTp(0),
fSocketRTCp(0),
fBroadcasterSession(NULL),
fChannel(0),
fIsMultiCast(false),
fMultiCastJoined(false)
{};
~UDPSocketPair() { Close(); };
SInt16 Open();
void Close();
void InitPorts(UInt32 addr);
SInt16 Bind(UInt32 addr);
SInt16 OpenAndBind( UInt16 rtpPort,UInt16 rtcpPort,char *destAddress);
SInt16 SetDestination (char *destAddress,UInt16 destPortRTp, UInt16 destPortRTCp);
SInt16 SetTTL(SInt16 timeToLive);
SInt16 JoinMulticast();
SInt16 LeaveMulticast();
SInt16 SetMulticastInterface();
SInt16 SetMultiCastOptions(SInt16 ttl);
SInt16 SendTo(int socket, sockaddr *destAddrPtr, char* inBuffer, UInt32 inLength );
SInt16 SendRTp(char* inBuffer, UInt32 inLength);
SInt16 SendRTCp(char* inBuffer, UInt32 inLength);
SInt16 RecvFrom(sockaddr *recvAddrPtr, int socket, char* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen);
SInt16 RecvRTp(char* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen);
SInt16 RecvRTCp(char* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen);
void SetRTSPSession(BroadcasterSession *theSession,UInt8 channel) {fBroadcasterSession = theSession, fChannel=channel;}
};
class ReceiveBuffer
{
public:
enum { kReadBufferSize = 256 }; //UInt32
char fReadBuffer[kReadBufferSize];
UInt32 fReceiveLen;
};
class MediaStream
{
protected:
int SendRTp(RTpPacket *packet);
int CalcRTCps();
int SendRTCp_SenderReport();
static UInt32 GetACName(char* ioCNameBuffer);
void MapToStream(UInt32 curRTpTimeStamp, UInt16 curRTpSequenceNumber, unsigned char curPayload, UInt32 *outRTpTimeStampPtr, UInt16 *outRTpSequenceNumberPtr, unsigned char *outPayloadPtr);
void UpdatePacketInStream(RTpPacket *packetPtr);
SInt16 Accounting(RTpPacket *packetPtr);
void BuildStaticRTCpReport();
void InitIfAudio();
void TestAndIncSoundDescriptor(RTpPacket *packetPtr);
public:
enum { kMaxCNameLen = 20 }; //UInt32
enum { eMaxSoundDescriptionSize = 1024};
enum {
kSenderReportSizeInBytes = 36, //UInt32
kMaxRTCpPacketSizeInBytes = 1024, //All are UInt32s
kMaxSsrcSizeInBytes = 25,
kSenderReportIntervalInSecs = 5
};
enum {
eSocketNotOpen,
eSocketFailed
};
struct MemberData {
ReceiveBuffer fPortRTpReadBuff;
ReceiveBuffer fPortRTCpReadBuff;
UInt64 fRTCpTimer;
SInt16 fState;
UInt64 fBytesSent;
UInt64 fPacketsSent;
SInt64 fStreamStartTime;
SInt64 fNTPPlayTime;
char fSenderReportBuffer[kSenderReportSizeInBytes + kMaxCNameLen];
UInt32 fSenderReportSize;
//who am i sending to?
UInt16 fRemoteRTpPort;
UInt16 fRemoteRTCpPort;
//RTCp stuff
SInt64 fLastSenderReportTime;
UInt32 fPacketCount;
UInt32 fByteCount;
Bool16 fSenderReportReady;
UInt32 fLastTimeStamp;
// current RTP packet info
UInt32 fLastTimeStampOffset;
UInt32 fTimeStamp;
UInt32 fSsrc;
UInt16 fLastSequenceNumber;
UInt32 fInitSSRC; // initial SSRC
UInt64 fCurStreamRTpSequenceNumber; // now
TypeMap *fStreamMediaTypePtr;
TypeMap *fMovieMediaTypePtr;
SInt64 fMovieStartTime;
SInt64 fMovieEndTime;
Float64 fLastMovieDurationSecs;
UInt64 fMediaStartOffsetMediaScale;
UInt64 fMovieStartOffset;
UInt32 fSeqRandomOffset;
UInt32 fRTpRandomOffset;
bool fNewMovieStarted;
bool fNewStreamStarted;
bool fIsSoundStream;
bool fIsVideoStream;
char *fSoundDescriptionBuffer;
SInt32 fSavedSoundDescSize;
SInt16 fSavedDataRefIndex;
UDPSocketPair *fSocketPair;
QTRTPFile *fRTPFilePtr;
};
MemberData fData;
bool fSend;
~MediaStream();
MediaStream();
char* GetRTCpSR() { return fData.fSenderReportBuffer; }
UInt32 GetRTCpSRLen() { return fData.fSenderReportSize; }
SInt64 GetPlayTime() { return fData.fStreamStartTime; }
SInt64 GetNTPPlayTime() { return fData.fNTPPlayTime; }
SInt16 Send(RTpPacket *packetPtr);
void ReceiveOnPorts();
int UpdateSenderReport(SInt64 theTime);
void StreamStart(SInt64 startTime);
void MovieStart(SInt64 startTime);
void MovieEnd(SInt64 endTime);
};
#endif // playlist_elements_H