/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc. All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This 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 #include #include #include #if (! __MACOS__) #ifndef __Win32__ #include #include #include #include #include #include #include #endif #endif #if (__MACOS__) #include "bogusdefs.h" #endif #include "playlist_array.h" #include "OSHeaders.h" #include "playlist_SimpleParse.h" #include "QTRTPFile.h" #include "BroadcasterSession.h" class MediaStream; struct SoundDescription { long descSize; /* total size of SoundDescription including extra data */ long dataFormat; /* sound format */ long resvd1; /* reserved for apple use. set to zero */ short resvd2; /* reserved for apple use. set to zero */ short dataRefIndex; short version; /* which version is this data */ short revlevel; /* what version of that codec did this */ long vendor; /* whose codec compressed this data */ short numChannels; /* number of channels of sound */ short sampleSize; /* number of bits per sample */ short compressionID; /* unused. set to zero. */ short packetSize; /* unused. set to zero. */ unsigned long 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 fPayLoadTypes; ArrayList fPayLoads; }; class RTpPacket { struct SoundHeader { char bytes[4]; long skip1; char sndtype[4]; long skip2; char test[4]; }; public: enum { kRTpHeaderSize = 12 }; char *fThePacket; int fLength; bool fHasSoundDescription; long 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; long fSavedSoundDescSize; short 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