00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef OPAL_RTP_RTP_H
00035 #define OPAL_RTP_RTP_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <opal/buildopts.h>
00042
00043 #include <ptclib/url.h>
00044
00045 #include <set>
00046
00047
00049
00050
00053 class RTP_DataFrame : public PBYTEArray
00054 {
00055 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00056
00057 public:
00058 RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
00059 RTP_DataFrame(const BYTE * data, PINDEX len, bool dynamic = true);
00060
00061 enum {
00062 ProtocolVersion = 2,
00063 MinHeaderSize = 12,
00064
00065 MaxMtuPayloadSize = (576-20-16-12)
00066 };
00067
00068 enum PayloadTypes {
00069 PCMU,
00070 FS1016,
00071 G721,
00072 G726 = G721,
00073 GSM,
00074 G7231,
00075 DVI4_8k,
00076 DVI4_16k,
00077 LPC,
00078 PCMA,
00079 G722,
00080 L16_Stereo,
00081 L16_Mono,
00082 G723,
00083 CN,
00084 MPA,
00085 G728,
00086 DVI4_11k,
00087 DVI4_22k,
00088 G729,
00089 Cisco_CN,
00090
00091 CelB = 25,
00092 JPEG,
00093 H261 = 31,
00094 MPV,
00095 MP2T,
00096 H263,
00097
00098 T38 = 38,
00099
00100 LastKnownPayloadType,
00101
00102 DynamicBase = 96,
00103 MaxPayloadType = 127,
00104 IllegalPayloadType
00105 };
00106
00107 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00108
00109 bool GetExtension() const { return (theArray[0]&0x10) != 0; }
00110 void SetExtension(bool ext);
00111
00112 bool GetMarker() const { return (theArray[1]&0x80) != 0; }
00113 void SetMarker(bool m);
00114
00115 bool GetPadding() const { return (theArray[0]&0x20) != 0; }
00116 void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
00117 BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
00118
00119 PINDEX GetPaddingSize() const { return m_paddingSize; }
00120 bool SetPaddingSize(PINDEX sz);
00121
00122 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00123 void SetPayloadType(PayloadTypes t);
00124
00125 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00126 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00127
00128 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00129 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00130
00131 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00132 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00133
00134 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00135 DWORD GetContribSource(PINDEX idx) const;
00136 void SetContribSource(PINDEX idx, DWORD src);
00137
00138 PINDEX GetHeaderSize() const { return m_headerSize; }
00139
00140 void CopyHeader(const RTP_DataFrame & other);
00141
00148 BYTE * GetHeaderExtension(
00149 unsigned & id,
00150 PINDEX & length,
00151 int idx = -1
00152 ) const;
00153
00155 enum HeaderExtensionType {
00156 RFC3550,
00157 RFC5285_OneByte,
00158 RFC5285_TwoByte
00159 };
00160
00164 BYTE * GetHeaderExtension(
00165 HeaderExtensionType type,
00166 unsigned id,
00167 PINDEX & length
00168 ) const;
00169
00176 bool SetHeaderExtension(
00177 unsigned id,
00178 PINDEX length,
00179 const BYTE * data,
00180 HeaderExtensionType type
00181 );
00182
00183 PINDEX GetExtensionSizeDWORDs() const;
00184 bool SetExtensionSizeDWORDs(PINDEX sz);
00185
00186 PINDEX GetPayloadSize() const { return m_payloadSize; }
00187 bool SetPayloadSize(PINDEX sz);
00188 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
00189
00190 virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
00191 virtual void PrintOn(ostream & strm) const;
00192
00193
00194
00195 bool SetPacketSize(PINDEX sz);
00196
00199 PTime GetAbsoluteTime() const { return m_absoluteTime; }
00200
00203 void SetAbsoluteTime() { m_absoluteTime.SetCurrentTime(); }
00204 void SetAbsoluteTime(const PTime & t) { m_absoluteTime = t; }
00205
00210 unsigned GetDiscontinuity() const { return m_discontinuity; }
00211
00212 void SetDiscontinuity(unsigned lost) { m_discontinuity = lost; }
00213
00214 protected:
00215 PINDEX m_headerSize;
00216 PINDEX m_payloadSize;
00217 PINDEX m_paddingSize;
00218 PTime m_absoluteTime;
00219 unsigned m_discontinuity;
00220
00221 #if PTRACING
00222 friend ostream & operator<<(ostream & o, PayloadTypes t);
00223 #endif
00224 };
00225
00226 PLIST(RTP_DataFrameList, RTP_DataFrame);
00227
00228
00231 class RTP_ControlFrame : public PBYTEArray
00232 {
00233 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00234
00235 public:
00236 RTP_ControlFrame(PINDEX compoundSize = 2048);
00237
00238 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00239
00240 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00241 void SetCount(unsigned count);
00242
00243 enum PayloadTypes {
00244 e_IntraFrameRequest = 192,
00245 e_SenderReport = 200,
00246 e_ReceiverReport = 201,
00247 e_SourceDescription = 202,
00248 e_Goodbye = 203,
00249 e_ApplDefined = 204,
00250 e_TransportLayerFeedBack = 205,
00251 e_PayloadSpecificFeedBack = 206,
00252 e_ExtendedReport = 207
00253 };
00254
00255 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00256 void SetPayloadType(unsigned t);
00257
00258 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00259 void SetPayloadSize(PINDEX sz);
00260
00261 BYTE * GetPayloadPtr() const;
00262
00263 bool ReadNextPacket();
00264 bool StartNewPacket();
00265 void EndPacket();
00266
00267 PINDEX GetCompoundSize() const;
00268
00269 void Reset(PINDEX size);
00270
00271 #pragma pack(1)
00272 struct ReceiverReport {
00273 PUInt32b ssrc;
00274 BYTE fraction;
00275 BYTE lost[3];
00276 PUInt32b last_seq;
00277 PUInt32b jitter;
00278 PUInt32b lsr;
00279 PUInt32b dlsr;
00280
00281 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00282 void SetLostPackets(unsigned lost);
00283 };
00284
00285 struct SenderReport {
00286 PUInt32b ntp_sec;
00287 PUInt32b ntp_frac;
00288 PUInt32b rtp_ts;
00289 PUInt32b psent;
00290 PUInt32b osent;
00291 };
00292
00293 struct ExtendedReport {
00294
00295 BYTE bt;
00296 BYTE type_specific;
00297 PUInt16b length;
00298 PUInt32b ssrc;
00299 BYTE loss_rate;
00300 BYTE discard_rate;
00301 BYTE burst_density;
00302 BYTE gap_density;
00303 PUInt16b burst_duration;
00304 PUInt16b gap_duration;
00305 PUInt16b round_trip_delay;
00306 PUInt16b end_system_delay;
00307 BYTE signal_level;
00308 BYTE noise_level;
00309 BYTE rerl;
00310 BYTE gmin;
00311 BYTE r_factor;
00312 BYTE ext_r_factor;
00313 BYTE mos_lq;
00314 BYTE mos_cq;
00315 BYTE rx_config;
00316 BYTE reserved;
00317 PUInt16b jb_nominal;
00318 PUInt16b jb_maximum;
00319 PUInt16b jb_absolute;
00320 };
00321
00322 enum DescriptionTypes {
00323 e_END,
00324 e_CNAME,
00325 e_NAME,
00326 e_EMAIL,
00327 e_PHONE,
00328 e_LOC,
00329 e_TOOL,
00330 e_NOTE,
00331 e_PRIV,
00332 NumDescriptionTypes
00333 };
00334
00335 struct SourceDescription {
00336 PUInt32b src;
00337 struct Item {
00338 BYTE type;
00339 BYTE length;
00340 char data[1];
00341
00342
00343
00344
00345
00346 unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
00347 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00348 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00349 } item[1];
00350 };
00351
00352 void StartSourceDescription(
00353 DWORD src
00354 );
00355
00356 void AddSourceDescriptionItem(
00357 unsigned type,
00358 const PString & data
00359 );
00360
00361
00362 unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00363 void SetFbType(unsigned type, PINDEX fciSize);
00364
00365 enum TransportLayerFbTypes {
00366 e_TransportNACK = 1,
00367 e_TMMBR = 3,
00368 e_TMMBN
00369 };
00370
00371 enum PayloadSpecificFbTypes {
00372 e_PictureLossIndication = 1,
00373 e_SliceLostIndication,
00374 e_ReferencePictureSelectionIndication,
00375 e_FullIntraRequest,
00376 e_TemporalSpatialTradeOffRequest,
00377 e_TemporalSpatialTradeOffNotification,
00378 e_VideoBackChannelMessage,
00379 e_ApplicationLayerFbMessage = 15
00380 };
00381
00382 struct FbFCI {
00383 PUInt32b senderSSRC;
00384 PUInt32b mediaSSRC;
00385 };
00386
00387 struct FbFIR {
00388 FbFCI fci;
00389 PUInt32b requestSSRC;
00390 BYTE sequenceNUmber;
00391 };
00392
00393 struct FbTSTO {
00394 FbFCI fci;
00395 PUInt32b requestSSRC;
00396 BYTE sequenceNUmber;
00397 BYTE reserver[2];
00398 BYTE tradeOff;
00399 };
00400
00401
00402 struct FbTMMB {
00403 FbFCI fci;
00404 PUInt32b requestSSRC;
00405 PUInt32b bitRateAndOverhead;
00406
00407 unsigned GetBitRate() const;
00408 unsigned GetOverhead() const { return bitRateAndOverhead & 0x1ff; }
00409 };
00410
00411 #pragma pack()
00412
00413 protected:
00414 PINDEX compoundOffset;
00415 PINDEX payloadSize;
00416 };
00417
00418
00420
00423 class RTPExtensionHeaderInfo : public PObject
00424 {
00425 PCLASSINFO(RTPExtensionHeaderInfo, PObject);
00426 public:
00427 unsigned m_id;
00428
00429 enum Direction {
00430 Undefined = -1,
00431 Inactive,
00432 RecvOnly,
00433 SendOnly,
00434 SendRecv
00435 } m_direction;
00436
00437 PURL m_uri;
00438
00439 PString m_attributes;
00440
00441 RTPExtensionHeaderInfo();
00442 virtual Comparison Compare(const PObject & other) const;
00443
00444 #if OPAL_SIP
00445 bool ParseSDP(const PString & param);
00446 void OutputSDP(ostream & strm) const;
00447 #endif
00448 };
00449
00450 typedef std::set<RTPExtensionHeaderInfo> RTPExtensionHeaders;
00451
00452
00453 #endif // OPAL_RTP_RTP_H
00454