Browse Source

Merge pull request #950 from troman123/master

Add AAC extend Support
Paul-Louis Ageneau 1 year ago
parent
commit
09963b818f

+ 2 - 0
CMakeLists.txt

@@ -75,6 +75,7 @@ set(LIBDATACHANNEL_SOURCES
 	${CMAKE_CURRENT_SOURCE_DIR}/src/rtppacketizer.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/opusrtppacketizer.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/opuspacketizationhandler.cpp
+	${CMAKE_CURRENT_SOURCE_DIR}/src/aacrtppacketizer.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/h264rtppacketizer.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/nalunit.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/h264packetizationhandler.cpp
@@ -112,6 +113,7 @@ set(LIBDATACHANNEL_HEADERS
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/rtppacketizer.hpp
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/opusrtppacketizer.hpp
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/opuspacketizationhandler.hpp
+	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/aacrtppacketizer.hpp
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/h264rtppacketizer.hpp
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/nalunit.hpp
 	${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/h264packetizationhandler.hpp

+ 61 - 0
include/rtc/aacrtppacketizer.hpp

@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2020 Filip Klembara (in2core)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef RTC_AAC_RTP_PACKETIZER_H
+#define RTC_AAC_RTP_PACKETIZER_H
+
+#if RTC_ENABLE_MEDIA
+
+#include "mediahandlerrootelement.hpp"
+#include "mediachainablehandler.hpp"
+#include "rtppacketizer.hpp"
+
+namespace rtc {
+
+/// RTP packetizer for aac
+class RTC_CPP_EXPORT AACRtpPacketizer final : public RtpPacketizer,
+                                               public MediaHandlerRootElement {
+public:
+	/// default clock rate used in aac RTP communication
+	inline static const uint32_t defaultClockRate = 48 * 1000;
+
+	/// Constructs aac packetizer with given RTP configuration.
+	/// @note RTP configuration is used in packetization process which may change some configuration
+	/// properties such as sequence number.
+	/// @param rtpConfig  RTP configuration
+	AACRtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig);
+
+	/// Creates RTP packet for given payload based on `rtpConfig`.
+	/// @note This function increase sequence number after packetization.
+	/// @param payload RTP payload
+	/// @param setMark This needs to be `false` for all RTP packets with aac payload
+	binary_ptr packetize(binary_ptr payload, bool setMark) override;
+
+	/// Creates RTP packet for given samples (all samples share same RTP timesamp)
+	/// @param messages aac samples
+	/// @param control RTCP
+	/// @returns RTP packets and unchanged `control`
+	ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages,
+	                                                    message_ptr control) override;
+};
+
+/// Handler for aac packetization
+class RTC_CPP_EXPORT AACPacketizationHandler final : public MediaChainableHandler {
+
+public:
+  /// Construct handler for aac packetization.
+  /// @param packetizer RTP packetizer for aac
+  AACPacketizationHandler(shared_ptr<AACRtpPacketizer> packetizer)
+      : MediaChainableHandler(packetizer) {}
+};
+
+} // namespace rtc
+
+#endif /* RTC_ENABLE_MEDIA */
+
+#endif /* RTC_AAC_RTP_PACKETIZER_H */

+ 2 - 0
include/rtc/description.hpp

@@ -237,6 +237,8 @@ public:
 		void addPCMACodec(int payloadType, optional<string> profile = std::nullopt);
 
 		void addPCMUCodec(int payloadType, optional<string> profile = std::nullopt);
+		
+		void addAacCodec(int payloadType, optional<string> profile = std::nullopt);
 	};
 
 	class RTC_CPP_EXPORT Video : public Media {

+ 9 - 1
include/rtc/rtc.h

@@ -116,7 +116,8 @@ typedef enum {
 	// audio
 	RTC_CODEC_OPUS = 128,
 	RTC_CODEC_PCMU = 129,
-	RTC_CODEC_PCMA = 130
+	RTC_CODEC_PCMA = 130,
+	RTC_CODEC_AAC = 131,
 } rtcCodec;
 
 typedef enum {
@@ -273,6 +274,10 @@ typedef struct {
 	const char *name;    // optional
 	const char *msid;    // optional
 	const char *trackId; // optional, track ID used in MSID
+
+	//indicate the coder capability and configuration
+	//e.g: aac latm streammuxconfig
+	const char *profile;
 } rtcTrackInit;
 
 RTC_C_EXPORT int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb);
@@ -343,6 +348,9 @@ RTC_C_EXPORT int rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHa
 // Set OpusPacketizationHandler for track
 RTC_C_EXPORT int rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
 
+// Set AACPacketizationHandler for track
+RTC_C_EXPORT int rtcSetAACPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
+
 // Chain RtcpSrReporter to handler chain for given track
 RTC_C_EXPORT int rtcChainRtcpSrReporter(int tr);
 

+ 1 - 0
include/rtc/rtc.hpp

@@ -37,5 +37,6 @@
 #include "h264packetizationhandler.hpp"
 #include "av1packetizationhandler.hpp"
 #include "opuspacketizationhandler.hpp"
+#include "aacrtppacketizer.hpp"
 
 #endif // RTC_ENABLE_MEDIA

+ 38 - 0
src/aacrtppacketizer.cpp

@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2020 Filip Klembara (in2core)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+#if RTC_ENABLE_MEDIA
+
+#include "aacrtppacketizer.hpp"
+
+#include <cassert>
+
+namespace rtc {
+
+AACRtpPacketizer::AACRtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig)
+    : RtpPacketizer(rtpConfig), MediaHandlerRootElement() {}
+
+binary_ptr AACRtpPacketizer::packetize(binary_ptr payload, [[maybe_unused]] bool setMark) {
+	assert(!setMark);
+	return RtpPacketizer::packetize(payload, false);
+}
+
+ChainedOutgoingProduct
+AACRtpPacketizer::processOutgoingBinaryMessage(ChainedMessagesProduct messages,
+                                                message_ptr control) {
+	ChainedMessagesProduct packets = make_chained_messages_product();
+	packets->reserve(messages->size());
+	for (auto message : *messages) {
+		packets->push_back(packetize(message, false));
+	}
+	return {packets, control};
+}
+
+} // namespace rtc
+
+#endif /* RTC_ENABLE_MEDIA */

+ 23 - 1
src/capi.cpp

@@ -1026,6 +1026,7 @@ int rtcAddTrackEx(int pc, const rtcTrackInit *init) {
 			case RTC_CODEC_OPUS:
 			case RTC_CODEC_PCMU:
 			case RTC_CODEC_PCMA:
+			case RTC_CODEC_AAC:
 				mid = "audio";
 				break;
 			default:
@@ -1059,7 +1060,8 @@ int rtcAddTrackEx(int pc, const rtcTrackInit *init) {
 		}
 		case RTC_CODEC_OPUS:
 		case RTC_CODEC_PCMU:
-		case RTC_CODEC_PCMA: {
+		case RTC_CODEC_PCMA:
+		case RTC_CODEC_AAC: {
 			auto desc = Description::Audio(mid, direction);
 			switch (init->codec) {
 			case RTC_CODEC_OPUS:
@@ -1071,6 +1073,9 @@ int rtcAddTrackEx(int pc, const rtcTrackInit *init) {
 			case RTC_CODEC_PCMA:
 				desc.addPCMACodec(init->payloadType);
 				break;
+			case RTC_CODEC_AAC:
+					desc.addAacCodec(init->payloadType, init->profile ? std::make_optional(string(init->profile)) : nullopt);
+					break;
 			default:
 				break;
 			}
@@ -1227,6 +1232,23 @@ int rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *in
 	});
 }
 
+int rtcSetAACPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
+	return wrap([&] {
+		auto track = getTrack(tr);
+		// create RTP configuration
+		auto rtpConfig = createRtpPacketizationConfig(init);
+		// create packetizer
+		auto packetizer = std::make_shared<AACRtpPacketizer>(rtpConfig);
+		// create AAC handler
+		auto aacHandler = std::make_shared<AACPacketizationHandler>(packetizer);
+		emplaceMediaChainableHandler(aacHandler, tr);
+		emplaceRtpConfig(rtpConfig, tr);
+		// set handler
+		track->setMediaHandler(aacHandler);
+		return RTC_ERR_SUCCESS;
+  });
+}
+
 int rtcChainRtcpSrReporter(int tr) {
 	return wrap([tr] {
 		auto config = getRtpConfig(tr);

+ 9 - 0
src/description.cpp

@@ -1138,6 +1138,15 @@ void Description::Audio::addPCMUCodec(int payloadType, optional<string> profile)
 	addAudioCodec(payloadType, "PCMU", profile);
 }
 
+void Description::Audio::addAacCodec(int payloadType, optional<string> profile) {
+	if (profile) {
+		addAudioCodec(payloadType, "MP4A-LATM", profile);
+	} else {
+		addAudioCodec(payloadType, "MP4A-LATM", "cpresent=1");
+	}
+	
+}
+
 Description::Video::Video(string mid, Direction dir)
     : Media("video 9 UDP/TLS/RTP/SAVPF", std::move(mid), dir) {}