/* * Copyright (c) 2012 Yoann Blein * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ #include #include //#include #include #include #include #include #include #include namespace Swift { RTPSessionImpl::RTPSessionImpl(const HostAddressPort& remotePeer, PayloadType payloadType, int frequency) : RTPSession(remotePeer, payloadType, frequency) { jrtplib::RTPExternalTransmissionParams transparams(&sender, 0); jrtplib::RTPSessionParams sessparams; // IMPORTANT: The local timestamp unit MUST be set, otherwise RTCP Sender Report info will be calculated wrong sessparams.SetOwnTimestampUnit(1.0 / frequency); checkError(session.Create(sessparams, &transparams, jrtplib::RTPTransmitter::ExternalProto)); //session.SetDefaultPayloadType(VP8); packetInjecter = static_cast(session.GetTransmissionInfo())->GetPacketInjector(); nativeAddressToJRTPAddress(remotePeer, jRTPRemotePeer); } RTPSessionImpl::~RTPSessionImpl() { } void RTPSessionImpl::poll() { checkError(session.Poll()); // Required if threading disabled } void RTPSessionImpl::checkIncomingPackets() { // session.BeginDataAccess(); // useless without threading if (session.GotoFirstSourceWithData() && session.GetCurrentSourceInfo()->GetRTPDataAddress()->IsSameAddress(&jRTPRemotePeer)) { do { jrtplib::RTPPacket *pack; while ((pack = session.GetNextPacket()) != NULL) { onIncomingPacket(pack->GetPayloadData(), pack->GetPayloadLength(), pack->HasMarker()); session.DeletePacket(pack); } } while (session.GotoNextSourceWithData()); } // session.EndDataAccess(); // useless without threading } void RTPSessionImpl::sendPacket(const SafeByteArray& data, int timestampinc, bool marker) { checkError(session.SendPacket((void*)(&data[0]), data.size(), payloadType, marker, timestampinc)); poll(); } void RTPSessionImpl::injectData(const SafeByteArray& data) { packetInjecter->InjectRTPorRTCP((void*)(&data[0]), data.size(), jRTPRemotePeer); checkIncomingPackets(); poll(); } void RTPSessionImpl::stop(int maxWaitMs) { session.BYEDestroy(jrtplib::RTPTime(0, maxWaitMs * 1000), "", 0); // TODO: shutdown socket } void RTPSessionImpl::checkError(int rtperr) const { if (rtperr < 0) throw RTPException(jrtplib::RTPGetErrorString(rtperr)); } void RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort, jrtplib::RTPIPv4Address& jRTPAddress) { // Split address std::vector subStrings; std::string ipAddress = hostAddressPort.getAddress().toString(); boost::algorithm::split(subStrings, ipAddress, boost::is_any_of(".")); // Cast sub strings array to array of byte uint8_t ipNumbers[4]; for (int i = 0; i < std::min(4, (int)subStrings.size()); ++i) ipNumbers[i] = boost::numeric_cast(boost::lexical_cast(subStrings[i])); jRTPAddress.SetIP(ipNumbers); jRTPAddress.SetPort(boost::numeric_cast(hostAddressPort.getPort())); } }