Commit ca35de0f authored by Simon Morlat's avatar Simon Morlat

Add an API for plugins to declare their own offer/answer logic for a given codec.

This can then be used by the upper layer (like liblinphone) to correctly perform the SDP offer/answer logic.
parent 3caf5664
dnl Process this file with autoconf to produce a configure script.
AC_INIT([mediastreamer],[2.12.1])
AC_INIT([mediastreamer],[2.13.0])
AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A mediastreaming library for telephony application.])
AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)])
......
......@@ -108,6 +108,66 @@ struct _MSRtpPayloadPickerContext {
RtpPayloadPicker picker;
};
struct _MSOfferAnswerContext;
#ifndef MS_OFFER_ANSWER_CONTEXT_DEFINED
#define MS_OFFER_ANSWER_CONTEXT_DEFINED
typedef struct _MSOfferAnswerContext MSOfferAnswerContext;
#endif
/* SDP offer answer payload matching API*/
/**
* The MSPayloadMatcherFunc prototype takes:
* - a list of local payload types
* - a remote payload type (offered or answered) by remote to be matched agains payload types of the local payload type list.
* - the full list of remote (offered or answered) payload types, which is sometimes necessary to do the matching in ambiguous situations.
* - is_reading, a boolean indicating whether we are doing the match processing while reading a SDP response, or (if FALSE) to prepare a response to be sent.
* The expected return value is a newly allocated PayloadType similar to the local payload type that was matched.
* Due to specific per codec offer/answer logic, the fmtp of the payload type might be changed compared to the original local payload type.
* If there is no match, NULL must be returned.
**/
typedef PayloadType * (*MSPayloadMatcherFunc)(MSOfferAnswerContext *context, const MSList *local_payloads, const PayloadType *remote_payload, const MSList *remote_payloads, bool_t is_reading);
/**
* The MSOfferAnswerContext is only there to provide a context during the SDP offer/answer handshake.
* It could be used in the future to provide extra information, for the moment the context is almost useless*/
struct _MSOfferAnswerContext{
MSPayloadMatcherFunc match_payload;
void (*destroy)(MSOfferAnswerContext *ctx);
void *context_data;
};
/**
* Executes an offer/answer processing for a given codec.
* @param context the context
* @param local_payloads the local payload type supported
* @param remote_payload a remote payload type (offered or answered) by remote to be matched agains payload types of the local payload type list.
* @param remote_payloads the full list of remote (offered or answered) payload types, which is sometimes necessary to do the matching in ambiguous situations.
* @param is_reading, a boolean indicating whether we are doing the match processing while reading a SDP response, or (if FALSE) to prepare a response to be sent.
* The expected return value is a newly allocated PayloadType similar to the local payload type that was matched.
* Due to specific per codec offer/answer logic, the fmtp of the payload type might be changed compared to the original local payload type.
* If there is no match, NULL must be returned.
**/
MS2_PUBLIC PayloadType * ms_offer_answer_context_match_payload(MSOfferAnswerContext *context, const MSList *local_payloads, const PayloadType *remote_payload, const MSList *remote_payloads, bool_t is_reading);
MS2_PUBLIC void ms_offer_answer_context_destroy(MSOfferAnswerContext *ctx);
/**
* A convenience function to instanciate an offer answer context giving only the payload matching function pointer.
**/
MS2_PUBLIC MSOfferAnswerContext *ms_offer_answer_create_simple_context(MSPayloadMatcherFunc func);
/**
* The struct to declare offer-answer provider, that act as factories per mime type to instanciate MSOfferAnswerContext object able to take in charge
* the offer answer model for a particular codec
**/
struct _MSOfferAnswerProvider{
const char *mime_type;
MSOfferAnswerContext *(*create_context)(void);
};
#ifdef __cplusplus
}
#endif
......
......@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct _MSFactory{
MSList *desc_list;
MSList *stats_list;
MSList *offer_answer_provider_list;
#ifdef _WIN32
MSList *ms_plugins_loaded_list;
#endif
......@@ -295,6 +296,41 @@ MS2_PUBLIC int ms_factory_enable_filter_from_name(MSFactory *factory, const char
*/
MS2_PUBLIC bool_t ms_factory_filter_from_name_enabled(const MSFactory *factory, const char *name);
#ifndef MS_OFFER_ANSWER_CONTEXT_DEFINED
#define MS_OFFER_ANSWER_CONTEXT_DEFINED
typedef struct _MSOfferAnswerContext MSOfferAnswerContext;
#endif
typedef struct _MSOfferAnswerProvider MSOfferAnswerProvider;
/**
* Registers an offer-answer provider. An offer answer provider is a kind of factory that creates
* context objects able to execute the particular offer/answer logic for a given codec.
* Indeed, several codecs have complex parameter handling specified in their RFC, and hence cannot be
* treated in a generic way by the global SDP offer answer logic.
* Mediastreamer2 plugins can then register with this method their offer/answer logic together with the encoder
* and decoder filters, so that it can be used by the signaling layer of the application.
* @param factory
* @param offer_answer_prov the offer answer provider descriptor.
**/
MS2_PUBLIC void ms_factory_register_offer_answer_provider(MSFactory *f, MSOfferAnswerProvider *offer_answer_prov);
/**
* Retrieve an offer answer provider previously registered, giving the codec name.
* @param f the factory
* @param mime_type the codec mime type.
* @return an MSOfferAnswerProvider or NULL if none was registered for this codec.
**/
MS2_PUBLIC MSOfferAnswerProvider * ms_factory_get_offer_answer_provider(MSFactory *f, const char *mime_type);
/**
* Directly creates an offer-answer context giving the codec mime-type.
* @param f the factory
* @param the mime-type of the codec.
* @return an MSOfferAnswerContext or NULL if none was registered for this codec.
**/
MS2_PUBLIC MSOfferAnswerContext * ms_factory_create_offer_answer_context(MSFactory *f, const char *mime_type);
#ifdef __cplusplus
}
#endif
......
......@@ -251,6 +251,7 @@ void ms_factory_destroy(MSFactory *factory){
factory->desc_list=ms_list_free(factory->desc_list);
ms_list_for_each(factory->stats_list,ms_free);
factory->stats_list=ms_list_free(factory->stats_list);
factory->offer_answer_provider_list = ms_list_free(factory->offer_answer_provider_list);
ms_list_for_each(factory->platform_tags, ms_free);
factory->platform_tags = ms_list_free(factory->platform_tags);
if (factory->plugins_dir) ms_free(factory->plugins_dir);
......@@ -838,6 +839,28 @@ bool_t ms_factory_filter_from_name_enabled(const MSFactory *factory, const char
return !!(desc->flags & MS_FILTER_IS_ENABLED);
}
void ms_factory_register_offer_answer_provider(MSFactory *f, MSOfferAnswerProvider *offer_answer_prov){
if (ms_list_find(f->offer_answer_provider_list, offer_answer_prov)) return; /*avoid registering several time the same pointer*/
f->offer_answer_provider_list = ms_list_prepend(f->offer_answer_provider_list, offer_answer_prov);
}
MSOfferAnswerProvider * ms_factory_get_offer_answer_provider(MSFactory *f, const char *mime_type){
const MSList *elem;
for (elem = f->offer_answer_provider_list; elem != NULL; elem = elem->next){
MSOfferAnswerProvider *prov = (MSOfferAnswerProvider*) elem->data;
if (strcasecmp(mime_type, prov->mime_type) == 0)
return prov;
}
return NULL;
}
MSOfferAnswerContext * ms_factory_create_offer_answer_context(MSFactory *f, const char *mime_type){
MSOfferAnswerProvider *prov = ms_factory_get_offer_answer_provider(f, mime_type);
if (prov) return prov->create_context();
return NULL;
}
#ifdef ANDROID
#include "sys/system_properties.h"
#include <jni.h>
......
......@@ -343,6 +343,22 @@ void ms_voip_exit(){
ms_factory_uninit_voip(ms_factory_get_fallback());
}
PayloadType * ms_offer_answer_context_match_payload(MSOfferAnswerContext *context, const MSList *local_payloads, const PayloadType *remote_payload, const MSList *remote_payloads, bool_t is_reading){
return context->match_payload(context, local_payloads, remote_payload, remote_payloads, is_reading);
}
MSOfferAnswerContext *ms_offer_answer_create_simple_context(MSPayloadMatcherFunc func){
MSOfferAnswerContext *ctx = ms_new0(MSOfferAnswerContext,1);
ctx->match_payload = func;
ctx->destroy = (void (*)(MSOfferAnswerContext *)) ms_free;
return ctx;
}
void ms_offer_answer_context_destroy(MSOfferAnswerContext *ctx){
if (ctx->destroy)
ctx->destroy(ctx);
}
#ifdef __cplusplus
}
#endif
......@@ -278,7 +278,7 @@ VideoStream *video_stream_new2(const char* ip, int loc_rtp_port, int loc_rtcp_po
sessions.rtp_session=ms_create_duplex_rtp_session(ip,loc_rtp_port,loc_rtcp_port);
obj=video_stream_new_with_sessions(&sessions);
obj->ms.owns_sessions=TRUE;
return obj;
return obj;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment