diff options
7 files changed, 271 insertions, 0 deletions
diff --git a/Swiften/Elements/RTPPayloadType.h b/Swiften/Elements/RTPPayloadType.h new file mode 100644 index 0000000..e61f921 --- /dev/null +++ b/Swiften/Elements/RTPPayloadType.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Payload.h> +#include <boost/shared_ptr.hpp> +#include <boost/cstdint.hpp> + +#include <string> +#include <map> + +namespace Swift { + +class RTPPayloadType : public Payload { +public: + typedef boost::shared_ptr<RTPPayloadType> ref; + typedef std::map<std::string, std::string> ParameterMap; + +public: + RTPPayloadType(boost::uint8_t id = 0, const std::string& name = "", boost::uint32_t clockrate = 0, + boost::uint8_t channels = 1, boost::uint32_t ptime = 0, boost::uint32_t maxptime = 0) : + m_id(id), m_name(name), m_clockrate(clockrate), m_channels(channels), m_ptime(ptime), m_maxptime(maxptime) {} + + void setChannels(boost::uint32_t channels) { m_channels = channels; } + boost::uint32_t getChannels() const { return m_channels; } + + void setClockrate(boost::uint32_t clockrate) { m_clockrate = clockrate; } + boost::uint32_t getClockrate() const { return m_clockrate; } + + void setID(boost::uint8_t id) { m_id = id; } + boost::uint8_t getID() const { return m_id; } + + void setMaxptime(boost::uint32_t maxptime) { m_maxptime = maxptime; } + boost::uint32_t getMaxptime() const { return m_maxptime; } + + void setName(const std::string& name) { m_name = name; } + const std::string& getName() const { return m_name; } + + void setPTime(boost::uint32_t ptime) { m_ptime = ptime; } + boost::uint32_t getPTime() const { return m_ptime; } + + bool addParameter(const std::string& name, const std::string& value) { + return parameters.insert(std::make_pair(name, value)).second; + } + + const ParameterMap& getParameters() const { return parameters; } + +private: + boost::uint8_t m_id; + std::string m_name; + boost::uint32_t m_clockrate; + boost::uint8_t m_channels; + boost::uint32_t m_ptime; + boost::uint32_t m_maxptime; + ParameterMap parameters; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp new file mode 100644 index 0000000..bddf96a --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "RTPPayloadTypeParser.h" + +#include <boost/optional.hpp> +#include <boost/lexical_cast.hpp> + +//#include <Swiften/Base/DateTime.h> +//#include <Swiften/Base/Log.h> + +namespace Swift { + +RTPPayloadTypeParser::RTPPayloadTypeParser() : level(0) { + +} + +void RTPPayloadTypeParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 0) { + // channel + try { + getPayloadInternal()->setChannels(boost::lexical_cast<boost::uint32_t>(attributes.getAttributeValue("channels").get_value_or("1"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setChannels(1); + } + // clockrate + try { + getPayloadInternal()->setClockrate(boost::lexical_cast<boost::uint32_t>(attributes.getAttributeValue("clockrate").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setClockrate(0); + } + // ID + try { + getPayloadInternal()->setID(boost::lexical_cast<boost::uint8_t>(attributes.getAttributeValue("id").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setID(0); + } + // maxptime + try { + getPayloadInternal()->setMaxptime(boost::lexical_cast<boost::uint32_t>(attributes.getAttributeValue("maxptime").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setMaxptime(0); + } + // name + getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or("")); + // ptime + try { + getPayloadInternal()->setPTime(boost::lexical_cast<boost::uint32_t>(attributes.getAttributeValue("ptime").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setPTime(0); + } + } else if (level == 1) { + getPayloadInternal()->addParameter(attributes.getAttributeValue("name").get_value_or(""), + attributes.getAttributeValue("value").get_value_or("")); + } + ++level; +} + +void RTPPayloadTypeParser::handleEndElement(const std::string& element, const std::string&) { + --level; +} + +} diff --git a/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h new file mode 100644 index 0000000..360053f --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/RTPPayloadType.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class RTPPayloadTypeParser : public GenericPayloadParser<RTPPayloadType> { + public: + RTPPayloadTypeParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string&) {}; + + private: + int level; +}; + +} diff --git a/Swiften/SConscript b/Swiften/SConscript index db18cc3..53ce39f 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -204,6 +204,7 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/DeliveryReceiptSerializer.cpp", "Serializer/PayloadSerializers/DeliveryReceiptRequestSerializer.cpp", "Serializer/PayloadSerializers/WhiteboardSerializer.cpp", + "Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamErrorSerializer.cpp", diff --git a/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp new file mode 100644 index 0000000..db21146 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Serializer/XML/XMLElement.h> + + + +namespace Swift { + +RTPPayloadTypeSerializer::RTPPayloadTypeSerializer() { +} + +std::string RTPPayloadTypeSerializer::serializePayload(boost::shared_ptr<RTPPayloadType> payloadType) const { + XMLElement payloadTypeElement("payload-type"); + + if (payloadType->getChannels() != 1) { + payloadTypeElement.setAttribute("channels", boost::lexical_cast<std::string>(payloadType->getChannels())); + } + if (payloadType->getClockrate() != 0) { + payloadTypeElement.setAttribute("clockrate", boost::lexical_cast<std::string>(payloadType->getClockrate())); + } + payloadTypeElement.setAttribute("id", boost::lexical_cast<std::string>(static_cast<int>(payloadType->getID()))); + if (payloadType->getMaxptime() != 0) { + payloadTypeElement.setAttribute("maxptime", boost::lexical_cast<std::string>(payloadType->getMaxptime())); + } + if (!payloadType->getName().empty()) { + payloadTypeElement.setAttribute("name", payloadType->getName()); + } + if (payloadType->getPTime() != 0) { + payloadTypeElement.setAttribute("ptime", boost::lexical_cast<std::string>( payloadType->getPTime())); + } + + const RTPPayloadType::ParameterMap ¶meters = payloadType->getParameters(); + RTPPayloadType::ParameterMap::const_iterator it; + for (it = parameters.begin(); it != parameters.end(); ++it) { + boost::shared_ptr<XMLElement> parameterElement = boost::make_shared<XMLElement>("parameter"); + parameterElement->setAttribute("name", it->first); + parameterElement->setAttribute("value", it->second); + payloadTypeElement.addNode(parameterElement); + } + + return payloadTypeElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h new file mode 100644 index 0000000..dda40ea --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/RTPPayloadType.h> + +#include <Swiften/Serializer/XML/XMLElement.h> + +namespace Swift { + class PayloadSerializerCollection; // NEEDED ? + + class RTPPayloadTypeSerializer : public GenericPayloadSerializer<RTPPayloadType> { + public: + RTPPayloadTypeSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<RTPPayloadType>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp index e3ec8fc..a1526fc 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp @@ -14,6 +14,7 @@ #include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> #include <Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h> #include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> +#include <Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h> #include <Swiften/Elements/JingleFileTransferDescription.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> @@ -21,12 +22,14 @@ #include <Swiften/Elements/JingleFileTransferHash.h> #include <Swiften/Elements/JinglePayload.h> #include <Swiften/Elements/JingleFileTransferReceived.h> +#include <Swiften/Elements/RTPPayloadType.h> #include <Swiften/Base/DateTime.h> using namespace Swift; class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(JingleSerializersTest); + CPPUNIT_TEST(testSerialize_StreamInitiationFileInfo); CPPUNIT_TEST(testSerialize_StreamInitiationFileInfoRange); @@ -43,6 +46,9 @@ class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_TEST(testSerialize_Xep0260_Example1); + CPPUNIT_TEST(testSerialize_RTPPayloadType_Simple); + CPPUNIT_TEST(testSerialize_RTPPayloadType_WithSub); + CPPUNIT_TEST_SUITE_END(); boost::shared_ptr<JinglePayloadSerializer> createTestling() { @@ -504,6 +510,39 @@ class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); } + void testSerialize_RTPPayloadType_Simple() { + std::string expected = "<payload-type clockrate=\"16000\" id=\"96\" name=\"speex\"/>"; + + RTPPayloadType::ref payloadType = boost::make_shared<RTPPayloadType>(96); + payloadType->setName("speex"); + payloadType->setClockrate(16000); + + boost::shared_ptr<RTPPayloadTypeSerializer> serializer = boost::make_shared<RTPPayloadTypeSerializer>(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(payloadType)); + } + + void testSerialize_RTPPayloadType_WithSub() { + std::string expected = "<payload-type clockrate=\"90000\" id=\"98\" name=\"theora\">" + "<parameter name=\"configuration\" value=\"somebase16string\"/>" + "<parameter name=\"delivery-method\" value=\"inline\"/>" + "<parameter name=\"height\" value=\"600\"/>" + "<parameter name=\"sampling\" value=\"YCbCr-4:2:2\"/>" + "<parameter name=\"width\" value=\"800\"/>" + "</payload-type>"; + + RTPPayloadType::ref payloadType = boost::make_shared<RTPPayloadType>(98); + payloadType->setName("theora"); + payloadType->setClockrate(90000); + payloadType->addParameter("height", "600"); + payloadType->addParameter("width", "800"); + payloadType->addParameter("delivery-method", "inline"); + payloadType->addParameter("configuration", "somebase16string"); + payloadType->addParameter("sampling", "YCbCr-4:2:2"); + + boost::shared_ptr<RTPPayloadTypeSerializer> serializer = boost::make_shared<RTPPayloadTypeSerializer>(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(payloadType)); + } + private: FullPayloadSerializerCollection collection; }; |