📄 rtp.cxx
字号:
/* * rtp.cxx * * RTP protocol handler * * Open H323 Library * * Copyright (c) 1998-2000 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Open H323 Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions of this code were written with the assisance of funding from * Vovida Networks, Inc. http://www.vovida.com. * * Contributor(s): ______________________________________. * * $Log: rtp.cxx,v $ * Revision 1.46 2000/05/30 10:35:41 robertj * Fixed GNU compiler warning. * * Revision 1.45 2000/05/30 06:52:26 robertj * Fixed problem with Cisco restarting sequence numbers when changing H.323 logical channels. * * Revision 1.44 2000/05/23 12:57:37 robertj * Added ability to change IP Type Of Service code from applications. * * Revision 1.43 2000/05/12 00:27:35 robertj * Fixed bug in UseSession() that caused asserts on BSD and possible race condition everywhere. * * Revision 1.42 2000/05/04 11:52:35 robertj * Added Packets Too Late statistics, requiring major rearrangement of jitter * buffer code, not also changes semantics of codec Write() function slightly. * * Revision 1.41 2000/05/02 04:32:27 robertj * Fixed copyright notice comment. * * Revision 1.40 2000/05/01 01:01:49 robertj * Added flag for what to do with out of orer packets (use if jitter, don't if not). * * Revision 1.39 2000/04/30 03:55:09 robertj * Improved the RTCP messages, epecially reports * * Revision 1.38 2000/04/28 12:56:39 robertj * Fixed transmission of SDES record in RTCP channel. * * Revision 1.37 2000/04/19 01:50:05 robertj * Improved debugging messages. * * Revision 1.36 2000/04/13 18:07:39 robertj * Fixed missing mutex release causing possible deadlocks. * * Revision 1.35 2000/04/10 17:40:05 robertj * Fixed debug output of RTP payload types to allow for unknown numbers. * * Revision 1.34 2000/04/05 04:09:24 robertj * Fixed portability problem with max() macro. * * Revision 1.33 2000/04/05 03:17:32 robertj * Added more RTP statistics gathering and H.245 round trip delay calculation. * * Revision 1.32 2000/04/03 18:15:44 robertj * Added "fractional" part of RTCP status NTP timestamp field. * * Revision 1.31 2000/03/23 02:54:57 robertj * Added sending of SDES control packets. * * Revision 1.30 2000/03/20 20:53:42 robertj * Fixed problem with being able to reopen for reading an RTP_Session (Cisco compatibilty) * * Revision 1.29 2000/03/04 12:32:23 robertj * Added setting of TOS field in IP header to get poor mans QoS on some routers. * * Revision 1.28 2000/02/29 13:00:13 robertj * Added extra statistic display for RTP packets out of order. * * Revision 1.27 2000/02/29 02:13:56 robertj * Fixed RTP receive of both control and data, ignores ECONNRESET/ECONNREFUSED errors. * * Revision 1.26 2000/02/27 10:56:24 robertj * Fixed error in code allowing non-consecutive RTP port numbers coming from broken stacks, thanks Vassili Leonov. * * Revision 1.25 2000/02/17 12:07:44 robertj * Used ne wPWLib random number generator after finding major problem in MSVC rand(). * * Revision 1.24 2000/01/29 07:10:20 robertj * Fixed problem with RTP transmit to host that is not yet ready causing the * receive side to die with ECONNRESET, thanks Ian MacDonald * * Revision 1.23 2000/01/20 05:57:46 robertj * Added extra flexibility in receiving incorrectly formed OpenLogicalChannel PDU's * * Revision 1.22 2000/01/14 00:31:40 robertj * Bug fix for RTP port allocation (MSVC optimised version), Thanks to Ian MacDonald. * * Revision 1.21 1999/12/30 09:14:49 robertj * Changed payload type functions to use enum. * * Revision 1.20 1999/12/23 23:02:36 robertj * File reorganision for separating RTP from H.323 and creation of LID for VPB support. * * Revision 1.19 1999/11/29 04:50:11 robertj * Added adaptive threshold calculation to silence detection. * * Revision 1.18 1999/11/22 00:09:59 robertj * Fixed error in RTP transmit rewrite for ternary state, didn't transmit at all! * * Revision 1.17 1999/11/20 05:35:48 robertj * Fixed possibly I/O block in RTP read loops. * * Revision 1.16 1999/11/19 13:13:31 robertj * Fixed Windows 95 compatibility issue in shutdown of RTP reading. * * Revision 1.15 1999/11/19 10:23:16 robertj * Fixed local binding of socket to correct address on multi-homes systems. * * Revision 1.14 1999/11/19 09:17:15 robertj * Fixed problems with aycnhronous shut down of logical channels. * * Revision 1.13 1999/11/17 03:49:51 robertj * Added RTP statistics display. * * Revision 1.12 1999/11/14 11:41:07 robertj * Added access functions to RTP statistics. * * Revision 1.11 1999/10/18 23:55:11 robertj * Fixed bug in setting contributing sources, length put into wrong spot in PDU header * * Revision 1.10 1999/09/21 14:10:04 robertj * Removed warnings when no tracing enabled. * * Revision 1.9 1999/09/05 00:58:37 robertj * Removed requirement that OpenLogicalChannalAck sessionId match original OLC. * * Revision 1.8 1999/09/03 02:17:50 robertj * Added more debugging * * Revision 1.7 1999/08/31 12:34:19 robertj * Added gatekeeper support. * * Revision 1.6 1999/07/16 02:13:54 robertj * Slowed down the control channel statistics packets. * * Revision 1.5 1999/07/13 09:53:24 robertj * Fixed some problems with jitter buffer and added more debugging. * * Revision 1.4 1999/07/09 06:09:52 robertj * Major implementation. An ENORMOUS amount of stuff added everywhere. * * Revision 1.3 1999/06/22 13:49:40 robertj * Added GSM support and further RTP protocol enhancements. * * Revision 1.2 1999/06/14 08:42:52 robertj * Fixed bug in dropped packets display was negative. * * Revision 1.1 1999/06/14 06:12:25 robertj * Changes for using RTP sessions correctly in H323 Logical Channel context * */#include <ptlib.h>#include <ptclib/random.h>#include "rtp.h"#include "jitter.h"#define new PNEW#if !PTRACING // Stuff to remove unised parameters warning#define PTRACE_sender#define PTRACE_reports#define PTRACE_count#define PTRACE_src#define PTRACE_description#define PTRACE_reason#define PTRACE_type#define PTRACE_subtype#define PTRACE_size#define PTRACE_name#define PTRACE_port#endifconst unsigned SecondsFrom1900to1970 = (70*365+17)*24*60*60U;#define UDP_BUFFER_SIZE 32768/////////////////////////////////////////////////////////////////////////////RTP_DataFrame::RTP_DataFrame(PINDEX sz) : PBYTEArray(12+sz){ payloadSize = sz; theArray[0] = '\x80';}void RTP_DataFrame::SetExtension(BOOL ext){ if (ext) theArray[0] |= 0x10; else theArray[0] &= 0xef;}void RTP_DataFrame::SetMarker(BOOL m){ if (m) theArray[1] |= 0x80; else theArray[1] &= 0x7f;}void RTP_DataFrame::SetPayloadType(PayloadTypes t){ PAssert(t <= 0x7f, PInvalidParameter); theArray[1] &= 0x80; theArray[1] |= t;}DWORD RTP_DataFrame::GetContribSource(PINDEX idx) const{ PAssert(idx < GetContribSrcCount(), PInvalidParameter); return ((PUInt32b *)&theArray[12])[idx];}void RTP_DataFrame::SetContribSource(PINDEX idx, DWORD src){ PAssert(idx <= 15, PInvalidParameter); if (idx >= GetContribSrcCount()) { BYTE * oldPayload = GetPayloadPtr(); theArray[0] &= 0xf0; theArray[0] |= idx+1; SetSize(GetHeaderSize()+payloadSize); memmove(GetPayloadPtr(), oldPayload, payloadSize); } ((PUInt32b *)&theArray[12])[idx] = src;}BOOL RTP_DataFrame::SetPayloadSize(PINDEX sz){ payloadSize = sz; return SetMinSize(GetHeaderSize()+payloadSize);}#if PTRACINGstatic const char * const PayloadTypesNames[RTP_DataFrame::LastKnownPayloadType] = { "PCMU", "FS1016", "G721", "GSM", "G7231", "DVI4_8k", "DVI4_16k", "LPC", "PCMA", "G722", "L16_Stereo", "L16_Mono", "G723", "CN", "MPA", "G728", "DVI4_11k", "DVI4_22k", "G729", "", "", "", "", "", "", "CelB", "JPEG", "", "", "", "", "H261", "MPV", "MP2T", "H263"};ostream & operator<<(ostream & o, RTP_DataFrame::PayloadTypes t){ if ((PINDEX)t < PARRAYSIZE(PayloadTypesNames)) o << PayloadTypesNames[t]; else o << "PayloadType(" << (int)t << ')'; return o;}#endif/////////////////////////////////////////////////////////////////////////////RTP_ControlFrame::RTP_ControlFrame(PINDEX sz){ SetPayloadSize(sz); theArray[0] = '\x80';}void RTP_ControlFrame::SetCount(unsigned count){ PAssert(count < 32, PInvalidParameter); theArray[0] &= 0xe0; theArray[0] |= count;}void RTP_ControlFrame::SetPayloadType(unsigned t){ PAssert(t < 256, PInvalidParameter); theArray[1] = (BYTE)t;}void RTP_ControlFrame::SetPayloadSize(PINDEX sz){ sz = (sz+3)/4; PAssert(sz <= 0xffff, PInvalidParameter); SetMinSize(4*(sz+1)); *(PUInt16b *)&theArray[2] = (WORD)sz;}RTP_ControlFrame::SourceDescription & RTP_ControlFrame::AddSourceDescription(DWORD src){ SetPayloadType(RTP_ControlFrame::e_SourceDescription); PINDEX index = GetCount(); SetCount(index+1); PINDEX originalPayloadSize = index != 0 ? GetPayloadSize() : 0; SetPayloadSize(originalPayloadSize+sizeof(SourceDescription)); SourceDescription & sdes = *(SourceDescription *)(GetPayloadPtr()+originalPayloadSize); sdes.src = src; sdes.item[0].type = e_END; return sdes;}RTP_ControlFrame::SourceDescription::Item & RTP_ControlFrame::AddSourceDescriptionItem(SourceDescription & sdes, unsigned type, const PString & data){ PINDEX dataLength = data.GetLength(); SetPayloadSize(GetPayloadSize()+sizeof(SourceDescription::Item)+dataLength-1); SourceDescription::Item * item = sdes.item; while (item->type != e_END) item = item->GetNextItem(); item->type = (BYTE)type; item->length = (BYTE)dataLength; memcpy(item->data, (const char *)data, item->length); item->GetNextItem()->type = e_END; return *item;}void RTP_ControlFrame::ReceiverReport::SetLostPackets(unsigned packets){ lost[0] = (BYTE)(packets >> 16); lost[1] = (BYTE)(packets >> 8); lost[2] = (BYTE)packets;}/////////////////////////////////////////////////////////////////////////////void RTP_UserData::OnTxStatistics(const RTP_Session & /*session*/) const{}void RTP_UserData::OnRxStatistics(const RTP_Session & /*session*/) const{}/////////////////////////////////////////////////////////////////////////////RTP_Session::RTP_Session(unsigned id, RTP_UserData * data){ PAssert(id > 0 && id < 256, PInvalidParameter); sessionID = (BYTE)id; referenceCount = 1; userData = data; jitter = NULL; expectedSequenceNumber = 0; lastSentSequenceNumber = (WORD)PRandom::Number(); syncSourceOut = PRandom::Number(); ignoreOutOfOrderPackets = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -