[Pkg-voip-commits] [janus] 36/163: Moved VP9 SVC parsing to utils, so that they can be used in other plugins if needed

Jonas Smedegaard dr at jones.dk
Sat Oct 28 01:22:07 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/0.2.5-1
in repository janus.

commit a25c21a0fcf8e1db804a94cb4a1d8e4e39fe6c06
Author: Lorenzo Miniero <lminiero at gmail.com>
Date:   Thu Jul 27 12:25:58 2017 +0200

    Moved VP9 SVC parsing to utils, so that they can be used in other plugins if needed
---
 plugins/janus_videoroom.c | 155 ++--------------------------------------------
 utils.c                   | 137 ++++++++++++++++++++++++++++++++++++++++
 utils.h                   |  16 +++++
 3 files changed, 158 insertions(+), 150 deletions(-)

diff --git a/plugins/janus_videoroom.c b/plugins/janus_videoroom.c
index e4d98e7..13cb0e0 100644
--- a/plugins/janus_videoroom.c
+++ b/plugins/janus_videoroom.c
@@ -451,12 +451,6 @@ static int janus_videoroom_videocodec_pt(janus_videoroom_videocodec vcodec) {
 			return VP8_PT;
 	}
 }
-/* Helper method to parse an RTP video frame and get some SVC-related info
- * (note: this only works with VP9, right now, on an experimental basis) */
-static int janus_videoroom_videocodec_parse_svc(janus_videoroom_videocodec vcodec,
-	char *buf, int total, int *found,
-	int *spatial_layer, int *temporal_layer,
-	uint8_t *p, uint8_t *d, uint8_t *u, uint8_t *b, uint8_t *e);
 
 
 typedef struct janus_videoroom {
@@ -2456,9 +2450,13 @@ void janus_videoroom_incoming_rtp(janus_plugin_session *handle, int video, char
 		packet.svc = FALSE;
 		if(video && videoroom->do_svc) {
 			/* We're doing SVC: let's parse this packet to see which layers are there */
+			int plen = 0;
+			char *payload = janus_rtp_payload(buf, len, &plen);
+			if(payload == NULL)
+				return;
 			uint8_t pbit = 0, dbit = 0, ubit = 0, bbit = 0, ebit = 0;
 			int found = 0, spatial_layer = 0, temporal_layer = 0;
-			if(janus_videoroom_videocodec_parse_svc(videoroom->vcodec, buf, len, &found, &spatial_layer, &temporal_layer, &pbit, &dbit, &ubit, &bbit, &ebit) == 0) {
+			if(janus_vp9_parse_svc(payload, plen, &found, &spatial_layer, &temporal_layer, &pbit, &dbit, &ubit, &bbit, &ebit) == 0) {
 				if(found) {
 					packet.svc = TRUE;
 					packet.spatial_layer = spatial_layer;
@@ -3974,149 +3972,6 @@ error:
 	return NULL;
 }
 
-/* Helper method to parse an RTP video frame and get some SVC-related info */
-static int janus_videoroom_videocodec_parse_svc(janus_videoroom_videocodec vcodec,
-		char *buf, int total, int *found,
-		int *spatial_layer, int *temporal_layer,
-		uint8_t *p, uint8_t *d, uint8_t *u, uint8_t *b, uint8_t *e) {
-	if(found)
-		*found = 0;
-	if(!buf || total < 12)
-		return -1;
-	/* This only works with VP9, right now, on an experimental basis) */
-	if(vcodec != JANUS_VIDEOROOM_VP9)
-		return -2;
-	/* Skip RTP header and extensions */
-	int len = 0;
-	char *buffer = janus_rtp_payload(buf, total, &len);
-	/* VP9 depay: */
-		/* https://tools.ietf.org/html/draft-ietf-payload-vp9-03 */
-	/* Read the first octet (VP9 Payload Descriptor) */
-	uint8_t vp9pd = *buffer;
-	uint8_t ibit = (vp9pd & 0x80) >> 7;
-	uint8_t pbit = (vp9pd & 0x40) >> 6;
-	uint8_t lbit = (vp9pd & 0x20) >> 5;
-	uint8_t fbit = (vp9pd & 0x10) >> 4;
-	uint8_t bbit = (vp9pd & 0x08) >> 3;
-	uint8_t ebit = (vp9pd & 0x04) >> 2;
-	uint8_t vbit = (vp9pd & 0x02) >> 1;
-	if(!lbit) {
-		/* No Layer indices present, no need to go on */
-		if(found)
-			*found = 0;
-		return 0;
-	}
-	/* Move to the next octet and see what's there */
-	buffer++;
-	len--;
-	if(ibit) {
-		/* Read the PictureID octet */
-		vp9pd = *buffer;
-		uint16_t picid = vp9pd, wholepicid = picid;
-		uint8_t mbit = (vp9pd & 0x80);
-		if(!mbit) {
-			buffer++;
-			len--;
-		} else {
-			memcpy(&picid, buffer, sizeof(uint16_t));
-			wholepicid = ntohs(picid);
-			picid = (wholepicid & 0x7FFF);
-			buffer += 2;
-			len -= 2;
-		}
-	}
-	if(lbit) {
-		/* Read the octet and parse the layer indices now */
-		vp9pd = *buffer;
-		int tlid = (vp9pd & 0xE0) >> 5;
-		uint8_t ubit = (vp9pd & 0x10) >> 4;
-		int slid = (vp9pd & 0x0E) >> 1;
-		uint8_t dbit = (vp9pd & 0x01);
-		JANUS_LOG(LOG_HUGE, "Parsed Layer indices: Temporal: %d (%u), Spatial: %d (%u)\n",
-			tlid, ubit, slid, dbit);
-		if(temporal_layer)
-			*temporal_layer = tlid;
-		if(spatial_layer)
-			*spatial_layer = slid;
-		if(p)
-			*p = pbit;
-		if(d)
-			*d = dbit;
-		if(u)
-			*u = ubit;
-		if(b)
-			*b = bbit;
-		if(e)
-			*e = ebit;
-		if(found)
-			*found = 1;
-		/* Go on, just to get to the SS, if available (which we currently ignore anyway) */
-		buffer++;
-		len--;
-		if(!fbit) {
-			/* Non-flexible mode, skip TL0PICIDX */
-			buffer++;
-			len--;
-		}
-	}
-	if(fbit && pbit) {
-		/* Skip reference indices */
-		uint8_t nbit = 1;
-		while(nbit) {
-			vp9pd = *buffer;
-			nbit = (vp9pd & 0x01);
-			buffer++;
-			len--;
-		}
-	}
-	if(vbit) {
-		/* Parse and skip SS */
-		vp9pd = *buffer;
-		int n_s = (vp9pd & 0xE0) >> 5;
-		n_s++;
-		JANUS_LOG(LOG_HUGE, "There are %d spatial layers\n", n_s);
-		uint8_t ybit = (vp9pd & 0x10);
-		uint8_t gbit = (vp9pd & 0x08);
-		if(ybit) {
-			/* Iterate on all spatial layers and get resolution */
-			buffer++;
-			len--;
-			int i=0;
-			for(i=0; i<n_s; i++) {
-				/* Been there, done that: skip skip skip */
-				buffer += 4;
-				len -= 4;
-			}
-		}
-		if(gbit) {
-			if(!ybit) {
-				buffer++;
-				len--;
-			}
-			uint8_t n_g = *buffer;
-			JANUS_LOG(LOG_HUGE, "There are %u frames in a GOF\n", n_g);
-			buffer++;
-			len--;
-			if(n_g > 0) {
-				int i=0;
-				for(i=0; i<n_g; i++) {
-					/* Read the R bits */
-					vp9pd = *buffer;
-					int r = (vp9pd & 0x0C) >> 2;
-					if(r > 0) {
-						/* Skip reference indices */
-						buffer += r;
-						len -= r;
-					}
-					buffer++;
-					len--;
-				}
-			}
-		}
-	}
-	return 0;
-}
-
 /* Helper to quickly relay RTP packets from publishers to subscribers */
 static void janus_videoroom_relay_rtp_packet(gpointer data, gpointer user_data) {
 	janus_videoroom_rtp_relay_packet *packet = (janus_videoroom_rtp_relay_packet *)user_data;
diff --git a/utils.c b/utils.c
index edaac94..cf5091d 100644
--- a/utils.c
+++ b/utils.c
@@ -17,6 +17,8 @@
 #include <sys/file.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
 
 #include "utils.h"
 #include "debug.h"
@@ -494,3 +496,138 @@ gboolean janus_json_is_valid(json_t *val, json_type jtype, unsigned int flags) {
 	}
 	return is_valid;
 }
+
+/* Helper method to parse a VP9 RTP video frame and get some SVC-related info:
+ * notice that this only works with VP9, right now, on an experimental basis */
+int janus_vp9_parse_svc(char *buffer, int len, int *found,
+		int *spatial_layer, int *temporal_layer,
+		uint8_t *p, uint8_t *d, uint8_t *u, uint8_t *b, uint8_t *e) {
+	if(!buffer || len < 0)
+		return -1;
+	/* VP9 depay: */
+		/* https://tools.ietf.org/html/draft-ietf-payload-vp9-04 */
+	/* Read the first octet (VP9 Payload Descriptor) */
+	uint8_t vp9pd = *buffer;
+	uint8_t ibit = (vp9pd & 0x80) >> 7;
+	uint8_t pbit = (vp9pd & 0x40) >> 6;
+	uint8_t lbit = (vp9pd & 0x20) >> 5;
+	uint8_t fbit = (vp9pd & 0x10) >> 4;
+	uint8_t bbit = (vp9pd & 0x08) >> 3;
+	uint8_t ebit = (vp9pd & 0x04) >> 2;
+	uint8_t vbit = (vp9pd & 0x02) >> 1;
+	if(!lbit) {
+		/* No Layer indices present, no need to go on */
+		if(found)
+			*found = 0;
+		return 0;
+	}
+	/* Move to the next octet and see what's there */
+	buffer++;
+	len--;
+	if(ibit) {
+		/* Read the PictureID octet */
+		vp9pd = *buffer;
+		uint16_t picid = vp9pd, wholepicid = picid;
+		uint8_t mbit = (vp9pd & 0x80);
+		if(!mbit) {
+			buffer++;
+			len--;
+		} else {
+			memcpy(&picid, buffer, sizeof(uint16_t));
+			wholepicid = ntohs(picid);
+			picid = (wholepicid & 0x7FFF);
+			buffer += 2;
+			len -= 2;
+		}
+	}
+	if(lbit) {
+		/* Read the octet and parse the layer indices now */
+		vp9pd = *buffer;
+		int tlid = (vp9pd & 0xE0) >> 5;
+		uint8_t ubit = (vp9pd & 0x10) >> 4;
+		int slid = (vp9pd & 0x0E) >> 1;
+		uint8_t dbit = (vp9pd & 0x01);
+		JANUS_LOG(LOG_HUGE, "Parsed Layer indices: Temporal: %d (%u), Spatial: %d (%u)\n",
+			tlid, ubit, slid, dbit);
+		if(temporal_layer)
+			*temporal_layer = tlid;
+		if(spatial_layer)
+			*spatial_layer = slid;
+		if(p)
+			*p = pbit;
+		if(d)
+			*d = dbit;
+		if(u)
+			*u = ubit;
+		if(b)
+			*b = bbit;
+		if(e)
+			*e = ebit;
+		if(found)
+			*found = 1;
+		/* Go on, just to get to the SS, if available (which we currently ignore anyway) */
+		buffer++;
+		len--;
+		if(!fbit) {
+			/* Non-flexible mode, skip TL0PICIDX */
+			buffer++;
+			len--;
+		}
+	}
+	if(fbit && pbit) {
+		/* Skip reference indices */
+		uint8_t nbit = 1;
+		while(nbit) {
+			vp9pd = *buffer;
+			nbit = (vp9pd & 0x01);
+			buffer++;
+			len--;
+		}
+	}
+	if(vbit) {
+		/* Parse and skip SS */
+		vp9pd = *buffer;
+		int n_s = (vp9pd & 0xE0) >> 5;
+		n_s++;
+		JANUS_LOG(LOG_HUGE, "There are %d spatial layers\n", n_s);
+		uint8_t ybit = (vp9pd & 0x10);
+		uint8_t gbit = (vp9pd & 0x08);
+		if(ybit) {
+			/* Iterate on all spatial layers and get resolution */
+			buffer++;
+			len--;
+			int i=0;
+			for(i=0; i<n_s; i++) {
+				/* Been there, done that: skip skip skip */
+				buffer += 4;
+				len -= 4;
+			}
+		}
+		if(gbit) {
+			if(!ybit) {
+				buffer++;
+				len--;
+			}
+			uint8_t n_g = *buffer;
+			JANUS_LOG(LOG_HUGE, "There are %u frames in a GOF\n", n_g);
+			buffer++;
+			len--;
+			if(n_g > 0) {
+				int i=0;
+				for(i=0; i<n_g; i++) {
+					/* Read the R bits */
+					vp9pd = *buffer;
+					int r = (vp9pd & 0x0C) >> 2;
+					if(r > 0) {
+						/* Skip reference indices */
+						buffer += r;
+						len -= r;
+					}
+					buffer++;
+					len--;
+				}
+			}
+		}
+	}
+	return 0;
+}
diff --git a/utils.h b/utils.h
index 487092e..edd4400 100644
--- a/utils.h
+++ b/utils.h
@@ -221,3 +221,19 @@ gboolean janus_json_is_valid(json_t *val, json_type jtype, unsigned int flags);
 	} while(0)
 
 #endif
+
+/*! \brief Helper method to parse a VP9 payload descriptor for SVC-related info (e.g., when SVC is enabled)
+ * @param[in] buffer The RTP payload to process
+ * @param[in] len The length of the RTP payload
+ * @param[out] found Whether any SVC related info has been found or not
+ * @param[out] spatial_layer Spatial layer of the packet
+ * @param[out] temporal_layer Temporal layer of the packet
+ * @param[out] p Inter-picture predicted picture bit
+ * @param[out] d Inter-layer dependency used bit
+ * @param[out] u Switching up point bit
+ * @param[out] b Start of a frame bit
+ * @param[out] e End of a frame bit
+ * @returns 0 in case of success, a negative integer otherwise */
+int janus_vp9_parse_svc(char *buffer, int len, int *found,
+		int *spatial_layer, int *temporal_layer,
+		uint8_t *p, uint8_t *d, uint8_t *u, uint8_t *b, uint8_t *e);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/janus.git



More information about the Pkg-voip-commits mailing list