[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