[Pkg-voip-commits] [janus] 148/282: Made EchoTest and VideoCall recordings aware of negotiated codecs

Jonas Smedegaard dr at jones.dk
Wed Dec 20 21:53:36 UTC 2017


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

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

commit 531365e8350424aed3237d9441be2bf582482ff8
Author: Lorenzo Miniero <lminiero at gmail.com>
Date:   Tue Oct 24 14:54:04 2017 +0200

    Made EchoTest and VideoCall recordings aware of negotiated codecs
---
 plugins/janus_echotest.c   |  23 +++++++++--
 plugins/janus_recordplay.c |  81 +++++++++++-------------------------
 plugins/janus_videocall.c  |  53 ++++++++++++++++++++++--
 sdp-utils.c                | 101 +++++++++++++++++++++++++++++++++++++++++++++
 sdp-utils.h                |  25 +++++++++++
 5 files changed, 217 insertions(+), 66 deletions(-)

diff --git a/plugins/janus_echotest.c b/plugins/janus_echotest.c
index 28f3a7c..1aa0533 100644
--- a/plugins/janus_echotest.c
+++ b/plugins/janus_echotest.c
@@ -185,6 +185,8 @@ typedef struct janus_echotest_session {
 	gboolean has_data;
 	gboolean audio_active;
 	gboolean video_active;
+	const char *acodec;		/* Codec used for audio, if available */
+	const char *vcodec;		/* Codec used for video, if available */
 	uint32_t bitrate, peer_bitrate;
 	janus_rtp_switching_context context;
 	uint32_t ssrc[3];		/* Only needed in case VP8 simulcasting is involved */
@@ -454,6 +456,10 @@ json_t *janus_echotest_query_session(janus_plugin_session *handle) {
 	json_t *info = json_object();
 	json_object_set_new(info, "audio_active", session->audio_active ? json_true() : json_false());
 	json_object_set_new(info, "video_active", session->video_active ? json_true() : json_false());
+	if(session->acodec)
+		json_object_set_new(info, "audio_codec", json_string(session->acodec));
+	if(session->vcodec)
+		json_object_set_new(info, "video_codec", json_string(session->vcodec));
 	json_object_set_new(info, "bitrate", json_integer(session->bitrate));
 	json_object_set_new(info, "peer-bitrate", json_integer(session->peer_bitrate));
 	if(session->ssrc[0] != 0) {
@@ -816,6 +822,8 @@ void janus_echotest_hangup_media(janus_plugin_session *handle) {
 	session->has_data = FALSE;
 	session->audio_active = TRUE;
 	session->video_active = TRUE;
+	session->acodec = NULL;
+	session->vcodec = NULL;
 	session->bitrate = 0;
 	session->peer_bitrate = 0;
 	session->ssrc[0] = 0;
@@ -1052,7 +1060,7 @@ static void *janus_echotest_handler(void *data) {
 					if(recording_base) {
 						/* Use the filename and path we have been provided */
 						g_snprintf(filename, 255, "%s-audio", recording_base);
-						session->arc = janus_recorder_create(NULL, "opus", filename);
+						session->arc = janus_recorder_create(NULL, session->acodec, filename);
 						if(session->arc == NULL) {
 							/* FIXME We should notify the fact the recorder could not be created */
 							JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this EchoTest user!\n");
@@ -1060,7 +1068,7 @@ static void *janus_echotest_handler(void *data) {
 					} else {
 						/* Build a filename */
 						g_snprintf(filename, 255, "echotest-%p-%"SCNi64"-audio", session, now);
-						session->arc = janus_recorder_create(NULL, "opus", filename);
+						session->arc = janus_recorder_create(NULL, session->acodec, filename);
 						if(session->arc == NULL) {
 							/* FIXME We should notify the fact the recorder could not be created */
 							JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this EchoTest user!\n");
@@ -1073,7 +1081,7 @@ static void *janus_echotest_handler(void *data) {
 					if(recording_base) {
 						/* Use the filename and path we have been provided */
 						g_snprintf(filename, 255, "%s-video", recording_base);
-						session->vrc = janus_recorder_create(NULL, "vp8", filename);
+						session->vrc = janus_recorder_create(NULL, session->vcodec, filename);
 						if(session->vrc == NULL) {
 							/* FIXME We should notify the fact the recorder could not be created */
 							JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this EchoTest user!\n");
@@ -1081,7 +1089,7 @@ static void *janus_echotest_handler(void *data) {
 					} else {
 						/* Build a filename */
 						g_snprintf(filename, 255, "echotest-%p-%"SCNi64"-video", session, now);
-						session->vrc = janus_recorder_create(NULL, "vp8", filename);
+						session->vrc = janus_recorder_create(NULL, session->vcodec, filename);
 						if(session->vrc == NULL) {
 							/* FIXME We should notify the fact the recorder could not be created */
 							JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this EchoTest user!\n");
@@ -1203,6 +1211,13 @@ static void *janus_echotest_handler(void *data) {
 				session->ssrc[1] = 0;
 				session->ssrc[2] = 0;
 			}
+			/* Check which codecs we ended up using */
+			janus_sdp_find_first_codecs(answer, &session->acodec, &session->vcodec);
+			JANUS_LOG(LOG_WARN, "%s, %s\n", session->acodec, session->vcodec);
+			if(session->acodec == NULL)
+				session->has_audio = FALSE;
+			if(session->vcodec == NULL)
+				session->has_video = FALSE;
 			char *sdp = janus_sdp_write(answer);
 			janus_sdp_free(offer);
 			janus_sdp_free(answer);
diff --git a/plugins/janus_recordplay.c b/plugins/janus_recordplay.c
index dbc8da8..18634fe 100644
--- a/plugins/janus_recordplay.c
+++ b/plugins/janus_recordplay.c
@@ -428,16 +428,6 @@ void janus_recordplay_send_rtcp_feedback(janus_plugin_session *handle, int video
 #define AUDIO_PT		111
 #define VIDEO_PT		100
 
-/* Preferred codecs when negotiating audio and video to record */
-static const char *preferred_audio_codecs[] = {
-	"opus", "pcmu", "pcma", "g722", "isac16", "isac32"
-};
-static uint audio_codecs = sizeof(preferred_audio_codecs)/sizeof(*preferred_audio_codecs);
-static const char *preferred_video_codecs[] = {
-	"vp8", "vp9", "h264"
-};
-static uint video_codecs = sizeof(preferred_video_codecs)/sizeof(*preferred_video_codecs);
-
 /* Helper method to check which codec was used in a specific recording */
 static const char *janus_recordplay_parse_codec(const char *dir, const char *filename) {
 	if(dir == NULL || filename == NULL)
@@ -487,11 +477,11 @@ static const char *janus_recordplay_parse_codec(const char *dir, const char *fil
 				if(prebuffer[0] == 'v') {
 					JANUS_LOG(LOG_VERB, "This is an old video recording, assuming VP8\n");
 					fclose(file);
-					return preferred_video_codecs[0];
+					return "opus";
 				} else if(prebuffer[0] == 'a') {
 					JANUS_LOG(LOG_VERB, "This is an old audio recording, assuming Opus\n");
 					fclose(file);
-					return preferred_audio_codecs[0];
+					return "vp8";
 				}
 			}
 			JANUS_LOG(LOG_WARN, "Unsupported recording media type...\n");
@@ -550,14 +540,12 @@ static const char *janus_recordplay_parse_codec(const char *dir, const char *fil
 					return NULL;
 				}
 				const char *c = json_string_value(codec);
-				uint i=0;
-				for(i=0; i<(video ? video_codecs : audio_codecs); i++) {
-					if(!strcasecmp(c, (video ? preferred_video_codecs[i] : preferred_audio_codecs[i]))) {
-						/* Found! */
-						json_decref(info);
-						fclose(file);
-						return video ? preferred_video_codecs[i] : preferred_audio_codecs[i];
-					}
+				const char *mcodec = janus_sdp_match_preferred_codec(video ? JANUS_SDP_VIDEO : JANUS_SDP_AUDIO, (char *)c);
+				if(mcodec != NULL) {
+					/* Found! */
+					json_decref(info);
+					fclose(file);
+					return mcodec;
 				}
 				json_decref(info);
 			}
@@ -1290,44 +1278,21 @@ static void *janus_recordplay_handler(void *data) {
 			janus_mutex_init(&rec->mutex);
 			/* Check which codec we should record for audio and/or video */
 			gboolean audio = FALSE, video = FALSE;
-			GList *temp = offer->m_lines;
-			while(temp) {
-				/* Which media are available? */
-				janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
-				if(m->type == JANUS_SDP_AUDIO && m->port > 0 &&
-						m->direction != JANUS_SDP_RECVONLY && m->direction != JANUS_SDP_INACTIVE) {
-					audio = TRUE;
-					if(rec->acodec == NULL) {
-						uint i=0;
-						for(i=0; i<audio_codecs; i++) {
-							if(janus_sdp_get_codec_pt(offer, preferred_audio_codecs[i]) > 0) {
-								rec->acodec = preferred_audio_codecs[i];
-								break;
-							}
-						}
-						if(rec->acodec == NULL) {
-							JANUS_LOG(LOG_WARN, "No supported audio codec found..?\n");
-							audio = FALSE;
-						}
-					}
-				} else if(m->type == JANUS_SDP_VIDEO && m->port > 0 &&
-						m->direction != JANUS_SDP_RECVONLY && m->direction != JANUS_SDP_INACTIVE) {
-					video = TRUE;
-					if(rec->vcodec == NULL) {
-						uint i=0;
-						for(i=0; i<video_codecs; i++) {
-							if(janus_sdp_get_codec_pt(offer, preferred_video_codecs[i]) > 0) {
-								rec->vcodec = preferred_video_codecs[i];
-								break;
-							}
-						}
-						if(rec->vcodec == NULL) {
-							JANUS_LOG(LOG_WARN, "No supported video codec found..?\n");
-							video = FALSE;
-						}
-					}
-				}
-				temp = temp->next;
+			janus_sdp_find_preferred_codecs(offer, &rec->acodec, &rec->vcodec);
+			/* We found preferred codecs: let's just make sure the direction is what we need */
+			janus_sdp_mline *m = janus_sdp_mline_find(offer, JANUS_SDP_AUDIO);
+			if(m != NULL && m->direction == JANUS_SDP_RECVONLY)
+				rec->acodec = NULL;
+			audio = (rec->acodec != NULL);
+			if(audio) {
+				JANUS_LOG(LOG_WARN, "Audio codec: %s\n", rec->acodec);
+			}
+			m = janus_sdp_mline_find(offer, JANUS_SDP_VIDEO);
+			if(m != NULL && m->direction == JANUS_SDP_RECVONLY)
+				rec->vcodec = NULL;
+			video = (rec->vcodec != NULL);
+			if(video) {
+				JANUS_LOG(LOG_WARN, "Video codec: %s\n", rec->acodec);
 			}
 			rec->audio_pt = AUDIO_PT;
 			if(rec->acodec) {
diff --git a/plugins/janus_videocall.c b/plugins/janus_videocall.c
index c37b077..f2be10d 100644
--- a/plugins/janus_videocall.c
+++ b/plugins/janus_videocall.c
@@ -238,6 +238,7 @@
 #include "../record.h"
 #include "../rtp.h"
 #include "../rtcp.h"
+#include "../sdp-utils.h"
 #include "../utils.h"
 
 
@@ -361,6 +362,8 @@ typedef struct janus_videocall_session {
 	gboolean has_data;
 	gboolean audio_active;
 	gboolean video_active;
+	const char *acodec;		/* Codec used for audio, if available */
+	const char *vcodec;		/* Codec used for video, if available */
 	uint32_t bitrate;
 	guint16 slowlink_count;
 	struct janus_videocall_session *peer;
@@ -401,6 +404,7 @@ static janus_mutex sessions_mutex = JANUS_MUTEX_INITIALIZER;
 #define JANUS_VIDEOCALL_ERROR_ALREADY_IN_CALL		480
 #define JANUS_VIDEOCALL_ERROR_NO_CALL				481
 #define JANUS_VIDEOCALL_ERROR_MISSING_SDP			482
+#define JANUS_VIDEOCALL_ERROR_INVALID_SDP			483
 
 
 /* VideoCall watchdog/garbage collector (sort of) */
@@ -628,6 +632,11 @@ json_t *janus_videocall_query_session(janus_plugin_session *handle) {
 		json_object_set_new(info, "peer", session->peer->username ? json_string(session->peer->username) : NULL);
 		json_object_set_new(info, "audio_active", session->audio_active ? json_true() : json_false());
 		json_object_set_new(info, "video_active", session->video_active ? json_true() : json_false());
+		if(session->acodec)
+			json_object_set_new(info, "audio_codec", json_string(session->acodec));
+		if(session->vcodec)
+			json_object_set_new(info, "video_codec", json_string(session->vcodec));
+		json_object_set_new(info, "video_active", session->video_active ? json_true() : json_false());
 		json_object_set_new(info, "bitrate", json_integer(session->bitrate));
 		json_object_set_new(info, "slowlink_count", json_integer(session->slowlink_count));
 	}
@@ -1011,6 +1020,8 @@ void janus_videocall_hangup_media(janus_plugin_session *handle) {
 	session->has_data = FALSE;
 	session->audio_active = TRUE;
 	session->video_active = TRUE;
+	session->acodec = NULL;
+	session->vcodec = NULL;
 	session->bitrate = 0;
 	janus_rtp_switching_context_reset(&session->context);
 }
@@ -1185,6 +1196,15 @@ static void *janus_videocall_handler(void *data) {
 					g_snprintf(error_cause, 512, "Missing SDP");
 					goto error;
 				}
+				char error_str[512];
+				janus_sdp *offer = janus_sdp_parse(msg_sdp, error_str, sizeof(error_str));
+				if(offer == NULL) {
+					JANUS_LOG(LOG_ERR, "Error parsing offer: %s\n", error_str);
+					error_code = JANUS_VIDEOCALL_ERROR_INVALID_SDP;
+					g_snprintf(error_cause, 512, "Error parsing offer: %s", error_str);
+					goto error;
+				}
+				janus_sdp_free(offer);
 				janus_mutex_lock(&sessions_mutex);
 				session->peer = peer;
 				peer->peer = session;
@@ -1240,6 +1260,14 @@ static void *janus_videocall_handler(void *data) {
 				g_snprintf(error_cause, 512, "Missing SDP");
 				goto error;
 			}
+			char error_str[512];
+			janus_sdp *answer = janus_sdp_parse(msg_sdp, error_str, sizeof(error_str));
+			if(answer == NULL) {
+				JANUS_LOG(LOG_ERR, "Error parsing answer: %s\n", error_str);
+				error_code = JANUS_VIDEOCALL_ERROR_INVALID_SDP;
+				g_snprintf(error_cause, 512, "Error parsing answer: %s", error_str);
+				goto error;
+			}
 			JANUS_LOG(LOG_VERB, "%s is accepting a call from %s\n", session->username, session->peer->username);
 			JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg_sdp_type, msg_sdp);
 			session->has_audio = (strstr(msg_sdp, "m=audio") != NULL);
@@ -1262,6 +1290,23 @@ static void *janus_videocall_handler(void *data) {
 					session->peer->ssrc[2] = 0;
 				}
 			}
+			/* Check which codecs we ended up using */
+			janus_sdp_find_first_codecs(answer, &session->acodec, &session->vcodec);
+			if(session->acodec == NULL) {
+				session->has_audio = FALSE;
+				if(session->peer)
+					session->peer->has_audio = FALSE;
+			} else if(session->peer) {
+				session->peer->acodec = session->acodec;
+			}
+			if(session->vcodec == NULL) {
+				session->has_video = FALSE;
+				if(session->peer)
+					session->peer->has_video = FALSE;
+			} else if(session->peer) {
+				session->peer->vcodec = session->vcodec;
+			}
+			janus_sdp_free(answer);
 			/* Send SDP to our peer */
 			json_t *jsep = json_pack("{ssss}", "type", msg_sdp_type, "sdp", msg_sdp);
 			json_t *call = json_object();
@@ -1372,7 +1417,7 @@ static void *janus_videocall_handler(void *data) {
 						if(recording_base) {
 							/* Use the filename and path we have been provided */
 							g_snprintf(filename, 255, "%s-audio", recording_base);
-							session->arc = janus_recorder_create(NULL, "opus", filename);
+							session->arc = janus_recorder_create(NULL, session->acodec, filename);
 							if(session->arc == NULL) {
 								/* FIXME We should notify the fact the recorder could not be created */
 								JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this VideoCall user!\n");
@@ -1383,7 +1428,7 @@ static void *janus_videocall_handler(void *data) {
 								session->username ? session->username : "unknown",
 								(session->peer && session->peer->username) ? session->peer->username : "unknown",
 								now);
-							session->arc = janus_recorder_create(NULL, "opus", filename);
+							session->arc = janus_recorder_create(NULL, session->acodec, filename);
 							if(session->arc == NULL) {
 								/* FIXME We should notify the fact the recorder could not be created */
 								JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this VideoCall user!\n");
@@ -1396,7 +1441,7 @@ static void *janus_videocall_handler(void *data) {
 						if(recording_base) {
 							/* Use the filename and path we have been provided */
 							g_snprintf(filename, 255, "%s-video", recording_base);
-							session->vrc = janus_recorder_create(NULL, "vp8", filename);
+							session->vrc = janus_recorder_create(NULL, session->vcodec, filename);
 							if(session->vrc == NULL) {
 								/* FIXME We should notify the fact the recorder could not be created */
 								JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this VideoCall user!\n");
@@ -1407,7 +1452,7 @@ static void *janus_videocall_handler(void *data) {
 								session->username ? session->username : "unknown",
 								(session->peer && session->peer->username) ? session->peer->username : "unknown",
 								now);
-							session->vrc = janus_recorder_create(NULL, "vp8", filename);
+							session->vrc = janus_recorder_create(NULL, session->vcodec, filename);
 							if(session->vrc == NULL) {
 								/* FIXME We should notify the fact the recorder could not be created */
 								JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this VideoCall user!\n");
diff --git a/sdp-utils.c b/sdp-utils.c
index 5c853ca..66961f2 100644
--- a/sdp-utils.c
+++ b/sdp-utils.c
@@ -20,6 +20,16 @@
 
 #define JANUS_BUFSIZE	8192
 
+/* Preferred codecs when negotiating audio/video, and number of supported codecs */
+const char *janus_preferred_audio_codecs[] = {
+	"opus", "pcmu", "pcma", "g722", "isac16", "isac32"
+};
+uint janus_audio_codecs = sizeof(janus_preferred_audio_codecs)/sizeof(*janus_preferred_audio_codecs);
+const char *janus_preferred_video_codecs[] = {
+	"vp8", "vp9", "h264"
+};
+uint janus_video_codecs = sizeof(janus_preferred_video_codecs)/sizeof(*janus_preferred_video_codecs);
+
 void janus_sdp_free(janus_sdp *sdp) {
 	if(!sdp)
 		return;
@@ -785,6 +795,97 @@ char *janus_sdp_write(janus_sdp *imported) {
 	return sdp;
 }
 
+void janus_sdp_find_preferred_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec) {
+	if(sdp == NULL)
+		return;
+	gboolean audio = FALSE, video = FALSE;
+	GList *temp = sdp->m_lines;
+	while(temp) {
+		/* Which media are available? */
+		janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
+		if(m->type == JANUS_SDP_AUDIO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
+			if(audio == FALSE) {
+				uint i=0;
+				for(i=0; i<janus_audio_codecs; i++) {
+					if(janus_sdp_get_codec_pt(sdp, janus_preferred_audio_codecs[i]) > 0) {
+						audio = TRUE;
+						if(acodec)
+							*acodec = janus_preferred_audio_codecs[i];
+						break;
+					}
+				}
+			}
+		} else if(m->type == JANUS_SDP_VIDEO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
+			if(video == FALSE) {
+				uint i=0;
+				for(i=0; i<janus_video_codecs; i++) {
+					if(janus_sdp_get_codec_pt(sdp, janus_preferred_video_codecs[i]) > 0) {
+						if(vcodec)
+							*vcodec = janus_preferred_video_codecs[i];
+						break;
+					}
+				}
+			}
+		}
+		if(audio && video)
+			break;
+		temp = temp->next;
+	}
+}
+
+void janus_sdp_find_first_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec) {
+	if(sdp == NULL)
+		return;
+	gboolean audio = FALSE, video = FALSE;
+	GList *temp = sdp->m_lines;
+	while(temp) {
+		/* Which media are available? */
+		janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
+		if(m->type == JANUS_SDP_AUDIO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
+			if(audio == FALSE && m->ptypes) {
+				int pt = GPOINTER_TO_INT(m->ptypes->data);
+				const char *codec = janus_sdp_get_codec_name(sdp, pt);
+				codec = janus_sdp_match_preferred_codec(m->type, (char *)codec);
+				if(codec) {
+					audio = TRUE;
+					if(acodec)
+						*acodec = codec;
+				}
+			}
+		} else if(m->type == JANUS_SDP_VIDEO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
+			if(video == FALSE && m->ptypes) {
+				int pt = GPOINTER_TO_INT(m->ptypes->data);
+				const char *codec = janus_sdp_get_codec_name(sdp, pt);
+				codec = janus_sdp_match_preferred_codec(m->type, (char *)codec);
+				if(codec) {
+					video = TRUE;
+					if(vcodec)
+						*vcodec = codec;
+				}
+			}
+		}
+		if(audio && video)
+			break;
+		temp = temp->next;
+	}
+}
+
+const char *janus_sdp_match_preferred_codec(janus_sdp_mtype type, char *codec) {
+	if(codec == NULL)
+		return NULL;
+	if(type != JANUS_SDP_AUDIO && type != JANUS_SDP_VIDEO)
+		return NULL;
+	gboolean video = (type == JANUS_SDP_VIDEO);
+	uint i=0;
+	for(i=0; i<(video ? janus_video_codecs : janus_audio_codecs); i++) {
+		if(!strcasecmp(codec, (video ? janus_preferred_video_codecs[i] : janus_preferred_audio_codecs[i]))) {
+			/* Found! */
+			return video ? janus_preferred_video_codecs[i] : janus_preferred_audio_codecs[i];
+		}
+	}
+	return NULL;
+}
+
 janus_sdp *janus_sdp_new(const char *name, const char *address) {
 	janus_sdp *sdp = g_malloc0(sizeof(janus_sdp));
 	/* Fill in some predefined stuff */
diff --git a/sdp-utils.h b/sdp-utils.h
index ba21c7b..24003e8 100644
--- a/sdp-utils.h
+++ b/sdp-utils.h
@@ -93,6 +93,31 @@ janus_sdp_mdirection janus_sdp_parse_mdirection(const char *direction);
  * @returns The direction as a string, if valid, or NULL otherwise */
 const char *janus_sdp_mdirection_str(janus_sdp_mdirection direction);
 
+/*! \brief Helper method to return the preferred audio and video codecs in an SDP offer or answer,
+ * (where by preferred we mean the codecs we prefer ourselves, and not the m-line SDP order)
+ * as long as the m-line direction is not disabled (port=0 or direction=inactive) in the SDP
+ * \note The acodec and vcodec arguments are input/output, and they'll be set to a static value
+ * in janus_preferred_audio_codecs and janus_preferred_video_codecs, so don't free them.
+ * @param[in] sdp The Janus SDP object to parse
+ * @param[out] acodec The audio codec that was found
+ * @param[out] vcodec The video codec that was found */
+void janus_sdp_find_preferred_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec);
+/*! \brief Helper method to return the first audio and video codecs in an SDP offer or answer,
+ * (no matter whether we personally prefer them ourselves or not)
+ * as long as the m-line direction is not disabled (port=0 or direction=inactive) in the SDP
+ * \note The acodec and vcodec arguments are input/output, and they'll be set to a static value
+ * in janus_preferred_audio_codecs and janus_preferred_video_codecs, so don't free them.
+ * @param[in] sdp The Janus SDP object to parse
+ * @param[out] acodec The audio codec that was found
+ * @param[out] vcodec The video codec that was found */
+void janus_sdp_find_first_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec);
+/*! \brief Helper method to match a codec to one of the preferred codecs
+ * \note Don't free the returned value, as it's a constant value
+ * @param[in] type The type of media to match
+ * @param[in] codec The codec to match
+ * @returns The codec, if found, or NULL otherwise */
+const char *janus_sdp_match_preferred_codec(janus_sdp_mtype type, char *codec);
+
 /*! \brief SDP m-line representation */
 typedef struct janus_sdp_mline {
 	/*! \brief Media type as a janus_sdp_mtype enumerator */

-- 
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