Commit c3529c41 authored by Gautier Pelloux-Prayer's avatar Gautier Pelloux-Prayer

Merge remote-tracking branch 'origin/new_adaptive_algorithm'

parents 412be981 52e7672e
......@@ -41,11 +41,18 @@ enum _MSRateControlActionType{
MSRateControlActionDecreasePacketRate,
MSRateControlActionIncreaseQuality,
};
typedef enum _MSRateControlActionType MSRateControlActionType;
const char *ms_rate_control_action_type_name(MSRateControlActionType t);
enum _MSQosAnalyzerNetworkState{
MSQosAnalyzerNetworkFine,
MSQosAnalyzerNetworkUnstable,
MSQosAnalyzerNetworkCongested,
MSQosAnalyzerNetworkLossy,
};
typedef enum _MSQosAnalyzerNetworkState MSQosAnalyzerNetworkState;
const char *ms_qos_analyzer_network_state_name(MSQosAnalyzerNetworkState state);
typedef struct _MSRateControlAction{
MSRateControlActionType type;
int value;
......@@ -60,7 +67,7 @@ struct _MSBitrateDriverDesc{
};
/*
* The MSBitrateDriver has the responsability to execute rate control actions.
* The MSBitrateDriver has the responsibility to execute rate control actions.
* This is an abstract interface.
**/
struct _MSBitrateDriver{
......@@ -74,59 +81,68 @@ void ms_bitrate_driver_unref(MSBitrateDriver *obj);
MSBitrateDriver *ms_audio_bitrate_driver_new(RtpSession *session, MSFilter *encoder);
MSBitrateDriver *ms_av_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
MSBitrateDriver *ms_bandwidth_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
typedef struct _MSQosAnalyser MSQosAnalyser;
typedef struct _MSQosAnalyserDesc MSQosAnalyserDesc;
typedef struct _MSQosAnalyzer MSQosAnalyzer;
typedef struct _MSQosAnalyzerDesc MSQosAnalyzerDesc;
struct _MSQosAnalyserDesc{
bool_t (*process_rtcp)(MSQosAnalyser *obj, mblk_t *rtcp);
void (*suggest_action)(MSQosAnalyser *obj, MSRateControlAction *action);
bool_t (*has_improved)(MSQosAnalyser *obj);
void (*uninit)(MSQosAnalyser *);
struct _MSQosAnalyzerDesc{
bool_t (*process_rtcp)(MSQosAnalyzer *obj, mblk_t *rtcp);
void (*suggest_action)(MSQosAnalyzer *obj, MSRateControlAction *action);
bool_t (*has_improved)(MSQosAnalyzer *obj);
void (*update)(MSQosAnalyzer *);
void (*uninit)(MSQosAnalyzer *);
};
/**
* A MSQosAnalyzer is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* This is an abstract interface.
**/
struct _MSQosAnalyser{
MSQosAnalyserDesc *desc;
struct _MSQosAnalyzer{
MSQosAnalyzerDesc *desc;
void (*on_action_suggested)(void*, const char*,const char*);
void *on_action_suggested_user_pointer;
int refcnt;
enum {
Simple,
Stateful,
} type;
};
MSQosAnalyser * ms_qos_analyser_ref(MSQosAnalyser *obj);
void ms_qos_analyser_unref(MSQosAnalyser *obj);
void ms_qos_analyser_suggest_action(MSQosAnalyser *obj, MSRateControlAction *action);
bool_t ms_qos_analyser_has_improved(MSQosAnalyser *obj);
bool_t ms_qos_analyser_process_rtcp(MSQosAnalyser *obj, mblk_t *rtcp);
void ms_qos_analyser_set_on_action_suggested(MSQosAnalyser *obj, void (*on_action_suggested)(void*,const char*,const char*),void* u);
MSQosAnalyzer * ms_qos_analyzer_ref(MSQosAnalyzer *obj);
void ms_qos_analyzer_unref(MSQosAnalyzer *obj);
void ms_qos_analyzer_suggest_action(MSQosAnalyzer *obj, MSRateControlAction *action);
bool_t ms_qos_analyzer_has_improved(MSQosAnalyzer *obj);
bool_t ms_qos_analyzer_process_rtcp(MSQosAnalyzer *obj, mblk_t *rtcp);
void ms_qos_analyzer_update(MSQosAnalyzer *obj);
void ms_qos_analyzer_set_on_action_suggested(MSQosAnalyzer *obj, void (*on_action_suggested)(void*,const char*,const char*),void* u);
/**
* The simple qos analyzer is an implementation of MSQosAnalyser that performs analysis for single stream.
* The simple qos analyzer is an implementation of MSQosAnalyzer that performs analysis for single stream.
**/
MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session);
MSQosAnalyzer * ms_simple_qos_analyzer_new(RtpSession *session);
MSQosAnalyzer * ms_stateful_qos_analyzer_new(RtpSession *session);
/**
* The audio/video qos analyser is an implementation of MSQosAnalyser that performs analysis of two audio and video streams.
* The audio/video qos analyzer is an implementation of MSQosAnalyzer that performs analysis of two audio and video streams.
**/
MSQosAnalyser * ms_av_qos_analyser_new(RtpSession *asession, RtpSession *vsession);
/*MSQosAnalyzer * ms_av_qos_analyzer_new(RtpSession *asession, RtpSession *vsession);*/
/**
* The MSBitrateController the overall behavior and state machine of the adaptive rate control system.
* It requires a MSQosAnalyser to obtain analyse of the quality of service, and a MSBitrateDriver
* It requires a MSQosAnalyzer to obtain analyse of the quality of service, and a MSBitrateDriver
* to run the actions on media streams, like decreasing or increasing bitrate.
**/
typedef struct _MSBitrateController MSBitrateController;
/**
* Instanciates MSBitrateController
* @param qosanalyser a Qos analyser object
* @param qosanalyzer a Qos analyzer object
* @param driver a bitrate driver object.
* The newly created bitrate controller owns references to the analyser and the driver.
* The newly created bitrate controller owns references to the analyzer and the driver.
**/
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBitrateDriver *driver);
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyzer *qosanalyzer, MSBitrateDriver *driver);
/**
* Asks the bitrate controller to process a newly received RTCP packet.
......@@ -138,20 +154,21 @@ MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBit
**/
void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp);
void ms_bitrate_controller_update(MSBitrateController *obj);
/**
* Returns the QoS analyzer used by the bitrate controller
* Return the QoS analyzer associated to the bitrate controller
**/
MSQosAnalyser * ms_bitrate_controller_get_qos_analyser(MSBitrateController *obj);
MSQosAnalyzer * ms_bitrate_controller_get_qos_analyzer(MSBitrateController *obj);
/**
* Destroys the bitrate controller
*
* If no other entity holds references to the underlyings MSQosAnalyser and MSBitrateDriver object,
* If no other entity holds references to the underlyings MSQosAnalyzer and MSBitrateDriver object,
* then they will be destroyed too.
**/
void ms_bitrate_controller_destroy(MSBitrateController *obj);
/**
* Convenience function to create a bitrate controller managing a single audio stream.
* @param session the RtpSession object for the media stream
......@@ -160,7 +177,7 @@ void ms_bitrate_controller_destroy(MSBitrateController *obj);
* This function actually calls internally:
* <br>
* \code
* ms_bitrate_controller_new(ms_simple_qos_analyser_new(session),ms_audio_bitrate_driver_new(encoder));
* ms_bitrate_controller_new(ms_simple_qos_analyzer_new(session),ms_audio_bitrate_driver_new(encoder));
* \endcode
**/
MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags);
......@@ -174,11 +191,12 @@ MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilt
* This function actually calls internally:
* <br>
* \code
* ms_bitrate_controller_new(ms_av_qos_analyser_new(asession,vsession),ms_av_bitrate_driver_new(aenc,venc));
* ms_bitrate_controller_new(ms_av_qos_analyzer_new(asession,vsession),ms_av_bitrate_driver_new(aenc,venc));
* \endcode
**/
MSBitrateController *ms_av_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
MSBitrateController *ms_bandwidth_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc);
#ifdef __cplusplus
}
#endif
......
......@@ -143,7 +143,7 @@ struct _MediaStream {
time_t last_packet_time;
bool_t use_rc;
bool_t owns_sessions;
bool_t pad[1];
bool_t pad;
/**
* defines encoder target network bit rate, uses #media_stream_set_target_network_bitrate() setter.
* */
......@@ -319,11 +319,11 @@ MS2_PUBLIC int audio_stream_start_with_files (AudioStream * stream, RtpProfile *
/**
* Starts an audio stream from/to local wav files or soundcards.
*
*
* This method starts the processing of the audio stream, that is playing from wav file or soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and wav file recording or soundcard playback.
*
*
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param profile a RtpProfile containing all PayloadType possible during the audio session.
* @param rem_rtp_ip remote IP address where to send the encoded audio.
......@@ -393,16 +393,16 @@ MS2_PUBLIC AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessio
MS2_PUBLIC uint32_t audio_stream_get_features(AudioStream *st);
MS2_PUBLIC void audio_stream_set_features(AudioStream *st, uint32_t features);
MS2_PUBLIC void audio_stream_prepare_sound(AudioStream *st, MSSndCard *playcard, MSSndCard *captcard);
MS2_PUBLIC void audio_stream_unprepare_sound(AudioStream *st);
MS2_PUBLIC bool_t audio_stream_started(AudioStream *stream);
/**
* Starts an audio stream from local soundcards.
*
*
* This method starts the processing of the audio stream, that is capture from soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and soundcard playback.
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param prof a RtpProfile containing all PayloadType possible during the audio session.
* @param remip remote IP address where to send the encoded audio.
......
......@@ -192,6 +192,7 @@ set(VOIP_SOURCE_FILES
voip/msvoip.c
voip/private.h
voip/qosanalyzer.c
voip/qosanalyzer.h
voip/qualityindicator.c
voip/ringstream.c
)
......
......@@ -65,7 +65,7 @@ libmediastreamer_voip_la_SOURCES+= voip/private.h \
voip/qualityindicator.c \
voip/audioconference.c \
voip/bitratedriver.c \
voip/qosanalyzer.c \
voip/qosanalyzer.c voip/qosanalyzer.h \
voip/bitratecontrol.c
else
libmediastreamer_base_la_SOURCES+= ortp-deps/logging.c \
......
......@@ -109,7 +109,7 @@ static void apply_max_bitrate(SpeexEncState *s){
}else{
/*convert from codec bitrate to network bitrate */
s->ip_bitrate=( (s->bitrate/(pps*8))+20+12+8)*8*pps;
ms_message("Using bitrate %i for speex encoder, ip bitrate is %i",s->bitrate,s->ip_bitrate);
ms_message("Using bitrate %i for speex encoder, ip bitrate is %i",s->bitrate,s->ip_bitrate);
}
}
......@@ -317,7 +317,7 @@ static int enc_set_ptime(MSFilter *f, void *arg){
s->ptime=*(int*)arg;
/*if the ptime is not a mulptiple of 20, go to the next multiple*/
if (s->ptime%20)
s->ptime = s->ptime - s->ptime%20 + 20;
s->ptime = s->ptime - s->ptime%20 + 20;
ms_message("MSSpeexEnc: got ptime=%i",s->ptime);
return 0;
}
......@@ -379,7 +379,7 @@ static int enc_add_fmtp(MSFilter *f, void *arg){
int val=atoi(buf);
enc_set_ptime(f,&val);
}
return 0;
}
......@@ -565,17 +565,17 @@ static void dec_process(MSFilter *f){
SpeexBits bits;
int bytes=s->frsz*2;
bool_t bits_initd=FALSE;
while((im=ms_queue_get(f->inputs[0]))!=NULL){
int rem_bits=(im->b_wptr-im->b_rptr)*8;
if (!bits_initd) {
speex_bits_init(&bits);
bits_initd=TRUE;
}else speex_bits_reset(&bits);
speex_bits_read_from(&bits,(char*)im->b_rptr,im->b_wptr-im->b_rptr);
/* support for multiple frame in one RTP packet */
do{
om=allocb(bytes,0);
......@@ -588,10 +588,10 @@ static void dec_process(MSFilter *f){
if (s->sample_time==0) s->sample_time=f->ticker->time;
s->sample_time+=20;
if (s->plc_count>0){
ms_warning("Did speex packet loss concealment during %i ms",s->plc_count*20);
// ms_warning("Did speex packet loss concealment during %i ms",s->plc_count*20);
s->plc_count=0;
}
}else {
if (err==-1)
ms_warning("speex end of stream");
......@@ -610,7 +610,7 @@ static void dec_process(MSFilter *f){
om->b_wptr+=bytes;
mblk_set_plc_flag(om, 1);
ms_queue_put(f->outputs[0],om);
s->sample_time+=20;
s->plc_count++;
if (s->plc_count>=plc_max){
......
......@@ -118,7 +118,7 @@ static void audio_stream_configure_resampler(MSFilter *resampler,MSFilter *from,
ms_filter_call_method(resampler, MS_FILTER_SET_NCHANNELS, &from_channels);
ms_filter_call_method(resampler, MS_FILTER_SET_OUTPUT_NCHANNELS, &to_channels);
ms_message("configuring %s-->%s from rate [%i] to rate [%i] and from channel [%i] to channel [%i]",
from->desc->name, to->desc->name, from_rate, to_rate, from_channels, to_channels);
from->desc->name, to->desc->name, from_rate, to_rate, from_channels, to_channels);
}
static void audio_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
......@@ -353,7 +353,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
tel_ev=rtp_profile_get_payload_from_mime (profile,"telephone-event");
if ((stream->features & AUDIO_STREAM_FEATURE_DTMF_ECHO) != 0 && (tel_ev==NULL || ( (tel_ev->flags & PAYLOAD_TYPE_FLAG_CAN_RECV) && !(tel_ev->flags & PAYLOAD_TYPE_FLAG_CAN_SEND)))
&& ( strcasecmp(pt->mime_type,"pcmu")==0 || strcasecmp(pt->mime_type,"pcma")==0)){
&& ( strcasecmp(pt->mime_type,"pcmu")==0 || strcasecmp(pt->mime_type,"pcma")==0)){
/*if no telephone-event payload is usable and pcma or pcmu is used, we will generate
inband dtmf*/
stream->dtmfgen_rtp=ms_filter_new (MS_DTMF_GEN_ID);
......
......@@ -42,7 +42,7 @@ const char *state_name(enum state_t st){
}
struct _MSBitrateController{
MSQosAnalyser *analyser;
MSQosAnalyzer *analyzer;
MSBitrateDriver *driver;
enum state_t state;
int stable_count;
......@@ -50,9 +50,9 @@ struct _MSBitrateController{
};
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyser *qosanalyser, MSBitrateDriver *driver){
MSBitrateController *ms_bitrate_controller_new(MSQosAnalyzer *qosanalyzer, MSBitrateDriver *driver){
MSBitrateController *obj=ms_new0(MSBitrateController,1);
obj->analyser=ms_qos_analyser_ref(qosanalyser);
obj->analyzer=ms_qos_analyzer_ref(qosanalyzer);
obj->driver=ms_bitrate_driver_ref(driver);
return obj;
}
......@@ -67,7 +67,7 @@ static void state_machine(MSBitrateController *obj){
case Stable:
obj->stable_count++;
case Init:
ms_qos_analyser_suggest_action(obj->analyser,&action);
ms_qos_analyzer_suggest_action(obj->analyzer,&action);
if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action);
obj->state=Probing;
......@@ -81,10 +81,10 @@ static void state_machine(MSBitrateController *obj){
break;
case Probing:
obj->stable_count=0;
if (ms_qos_analyser_has_improved(obj->analyser)){
if (ms_qos_analyzer_has_improved(obj->analyzer)){
obj->state=Stable;
}else{
ms_qos_analyser_suggest_action(obj->analyser,&action);
ms_qos_analyzer_suggest_action(obj->analyzer,&action);
if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action);
}
......@@ -93,7 +93,7 @@ static void state_machine(MSBitrateController *obj){
case ProbingUp:
obj->stable_count=0;
obj->probing_up_count++;
ms_qos_analyser_suggest_action(obj->analyser,&action);
ms_qos_analyzer_suggest_action(obj->analyzer,&action);
if (action.type!=MSRateControlActionDoNothing){
execute_action(obj,&action);
obj->state=Probing;
......@@ -119,31 +119,40 @@ static void state_machine(MSBitrateController *obj){
void ms_bitrate_controller_process_rtcp(MSBitrateController *obj, mblk_t *rtcp){
if (ms_qos_analyser_process_rtcp(obj->analyser,rtcp)){
if (ms_qos_analyzer_process_rtcp(obj->analyzer,rtcp)){
state_machine(obj);
}
}
MSQosAnalyser * ms_bitrate_controller_get_qos_analyser(MSBitrateController *obj){
return obj->analyser;
void ms_bitrate_controller_update(MSBitrateController *obj){
ms_qos_analyzer_update(obj->analyzer);
}
MSQosAnalyzer * ms_bitrate_controller_get_qos_analyzer(MSBitrateController *obj){
return obj->analyzer;
}
void ms_bitrate_controller_destroy(MSBitrateController *obj){
ms_qos_analyser_unref(obj->analyser);
ms_qos_analyzer_unref(obj->analyzer);
ms_bitrate_driver_unref(obj->driver);
ms_free(obj);
}
MSBitrateController *ms_audio_bitrate_controller_new(RtpSession *session, MSFilter *encoder, unsigned int flags){
return ms_bitrate_controller_new(
ms_simple_qos_analyser_new(session),
ms_simple_qos_analyzer_new(session),
ms_audio_bitrate_driver_new(session, encoder));
}
MSBitrateController *ms_av_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
return ms_bitrate_controller_new(
ms_simple_qos_analyser_new(vsession),
ms_simple_qos_analyzer_new(vsession),
ms_av_bitrate_driver_new(asession, aenc, vsession, venc));
}
MSBitrateController *ms_bandwidth_bitrate_controller_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
return ms_bitrate_controller_new(
ms_stateful_qos_analyzer_new(vsession?vsession:asession),
ms_bandwidth_bitrate_driver_new(asession, aenc, vsession, venc));
}
......@@ -294,3 +294,116 @@ MSBitrateDriver *ms_av_bitrate_driver_new(RtpSession *asession, MSFilter *aenc,
}
typedef struct _MSBandwidthBitrateDriver{
MSBitrateDriver parent;
MSBitrateDriver *audio_driver;
RtpSession *vsession;
MSFilter *venc;
int nom_bitrate;
int cur_bitrate;
}MSBandwidthBitrateDriver;
static int bandwidth_change_ptime(MSAudioBitrateDriver *obj, int percent){
return apply_ptime(obj,obj->min_ptime + (max_ptime - obj->min_ptime) * percent / 100.f);
}
static int bandwidth_dec_video_bitrate(MSBandwidthBitrateDriver *obj, const MSRateControlAction *action){
int new_br;
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
new_br=((float)obj->cur_bitrate)*(100.0-(float)action->value)/100.0;
if (new_br<min_video_bitrate){
ms_message("MSBandwidthBitrateDriver: reaching low bound.");
new_br=min_video_bitrate;
}
ms_message("MSBandwidthBitrateDriver: targeting %i bps for video encoder.",new_br);
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&new_br);
obj->cur_bitrate=new_br;
rtp_session_set_target_upload_bandwidth(obj->vsession, obj->cur_bitrate);
return new_br==min_video_bitrate ? -1 : 0;
}
static int bandwidth_inc_video_bitrate(MSBandwidthBitrateDriver *obj, const MSRateControlAction *action){
int newbr;
int ret=0;
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->cur_bitrate);
if (obj->cur_bitrate==0){
ms_message("MSBandwidthBitrateDriver: current bitrate was not known.");
return -1; /*current bitrate was not known*/
}
newbr= (float)obj->cur_bitrate*(100.0+(float)action->value)/100.0;
if (newbr>obj->nom_bitrate){
newbr=obj->nom_bitrate;
ret=-1;
}
ms_message("MSBandwidthBitrateDriver: increasing bitrate from %i to %i bps for video encoder.",obj->cur_bitrate,newbr);
obj->cur_bitrate=newbr;
rtp_session_set_target_upload_bandwidth(obj->vsession, obj->cur_bitrate);
ms_filter_call_method(obj->venc,MS_FILTER_SET_BITRATE,&obj->cur_bitrate);
return ret;
}
static int bandwidth_driver_execute_action(MSBitrateDriver *objbase, const MSRateControlAction *action){
MSBandwidthBitrateDriver *obj=(MSBandwidthBitrateDriver*)objbase;
int ret=0;
if (obj->nom_bitrate==0&&obj->venc){
ms_filter_call_method(obj->venc,MS_FILTER_GET_BITRATE,&obj->nom_bitrate);
if (obj->nom_bitrate==0){
ms_warning("MSBandwidthBitrateDriver: Not doing adaptive rate control on video encoder, it does not seem to support that.");
return -1;
}
}
if (!obj->venc){
ret=1;
}
switch(action->type){
case MSRateControlActionDecreaseBitrate:
if (obj->venc){
ret=bandwidth_dec_video_bitrate(obj,action);
}
if (ret!=0 && obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
break;
case MSRateControlActionDecreasePacketRate:
if (obj->audio_driver){
ret=bandwidth_change_ptime((MSAudioBitrateDriver*) obj->audio_driver, 100);
}else{
ret=1;
}
break;
case MSRateControlActionIncreaseQuality:
if (obj->venc){
ret=bandwidth_inc_video_bitrate(obj,action);
}
if (ret!=0 && obj->audio_driver){
ret=ms_bitrate_driver_execute_action(obj->audio_driver,action);
}
break;
case MSRateControlActionDoNothing:
break;
}
ms_message("MSBandwidthBitrateDriver: Action %s %s", ms_rate_control_action_type_name(action->type), ret == 0 ? "succeeded" : "failed");
return ret;
}
static void bandwidth_bitrate_driver_uninit(MSBitrateDriver *objbase){
}
static MSBitrateDriverDesc bandwidth_bitrate_driver={
bandwidth_driver_execute_action,
bandwidth_bitrate_driver_uninit
};
MSBitrateDriver *ms_bandwidth_bitrate_driver_new(RtpSession *asession, MSFilter *aenc, RtpSession *vsession, MSFilter *venc){
MSBandwidthBitrateDriver *obj=ms_new0(MSBandwidthBitrateDriver,1);
obj->parent.desc=&bandwidth_bitrate_driver;
obj->vsession = vsession;
obj->audio_driver=(aenc!=NULL) ? ms_bitrate_driver_ref(ms_audio_bitrate_driver_new(asession,aenc)) : NULL;
obj->venc=venc;
return (MSBitrateDriver*)obj;
}
......@@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MS_MINIMAL_MTU
/*this is used for determining the minimum size of recv buffers for RTP packets
Keep 1500 for maximum interoparibility*/
#define MS_MINIMAL_MTU 1500
#define MS_MINIMAL_MTU 1500
#endif
......@@ -81,12 +81,12 @@ static void media_stream_change_decoder(MediaStream *stream, int payload) {
RtpSession *session = stream->sessions.rtp_session;
RtpProfile *prof = rtp_session_get_profile(session);
PayloadType *pt = rtp_profile_get_payload(prof, payload);
if (stream->decoder == NULL){
ms_message("media_stream_change_decoder(): ignored, no decoder.");
return;
}
if (pt != NULL){
MSFilter *dec;
......@@ -225,7 +225,7 @@ void media_stream_free(MediaStream *stream) {
if (stream->decoder != NULL) ms_filter_destroy(stream->decoder);
if (stream->voidsink != NULL) ms_filter_destroy(stream->voidsink);
if (stream->qi) ms_quality_indicator_destroy(stream->qi);
}
void media_stream_set_rtcp_information(MediaStream *stream, const char *cname, const char *tool) {
......@@ -261,7 +261,7 @@ static int check_srtp_session_created(MediaStream *stream){
err_status_t err;
srtp_t session;
RtpTransport *rtp=NULL,*rtcp=NULL;
err = ortp_srtp_create(&session, NULL);
if (err != 0) {
ms_error("Failed to create srtp session (%d)", err);
......@@ -283,9 +283,9 @@ static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, cons
err_status_t err;
unsigned b64_key_length = strlen(b64_key);
ssrc_t ssrc_conf;
memset(&policy,0,sizeof(policy));
switch(suite){
case MS_AES_128_SHA1_32:
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
......@@ -332,22 +332,22 @@ static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, cons
}
if (!inbound)
policy.allow_repeat_tx=1; /*necessary for telephone-events*/
/*ssrc_conf.type=inbound ? ssrc_any_inbound : ssrc_specific;*/
ssrc_conf.type=ssrc_specific;
ssrc_conf.value=ssrc;
policy.ssrc = ssrc_conf;
policy.key = key;
policy.next = NULL;
err = srtp_add_stream(srtp, &policy);
if (err != err_status_ok) {
ortp_error("Failed to add stream to srtp session (%d)", err);
ortp_free(key);
return -1;
}
ortp_free(key);
return 0;
}
......@@ -373,7 +373,7 @@ bool_t media_stream_srtp_supported(void){
}
int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
return -1;
......@@ -382,14 +382,14 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
{
uint32_t ssrc,send_ssrc;
bool_t updated=FALSE;
if (check_srtp_session_created(stream)==-1)
return -1;
/*check if a previous key was configured, in which case remove it*/
send_ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
ssrc=find_other_ssrc(stream->sessions.srtp_session,htonl(send_ssrc));
/*careful: remove_stream takes the SSRC in network byte order...*/
if (ortp_srtp_remove_stream(stream->sessions.srtp_session,ssrc)==0)
updated=TRUE;
......@@ -403,20 +403,20 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
}
int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
return -1;
}
#ifdef ORTP_HAVE_SRTP
{
uint32_t ssrc;
bool_t updated=FALSE;
if (check_srtp_session_created(stream)==-1)
return -1;
/*check if a previous key was configured, in which case remove it*/
ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
if (ssrc!=0){
......@@ -483,23 +483,26 @@ static void media_stream_process_rtcp(MediaStream *stream, mblk_t *m, time_t cur
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("media_stream_process_rtcp[stream=%p]: remote statistics available for [%s] stream\n\tremote's interarrival jitter=%u\n"
"\tremote's lost packets percentage since last report=%f\n\tround trip time=%f seconds",stream,media_stream_type_str(stream),ij,flost,rt);
if (stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->use_rc&&stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
}
stream->process_rtcp(stream,m);
}while(rtcp_next_packet(m));
}
void media_stream_iterate(MediaStream *stream){
time_t curtime=ms_time(NULL);
if (stream->ice_check_list) ice_check_list_process(stream->ice_check_list,stream->sessions.rtp_session);
/*we choose to update the quality indicator as much as possible, since local statistics can be computed realtime. */
if (stream->state==MSStreamStarted){
if (stream->qi && curtime>stream->last_iterate_time) ms_quality_indicator_update_local(stream->qi);
}
stream->last_iterate_time=curtime;
if (stream->rc) ms_bitrate_controller_update(stream->rc);
if (stream->evq){
OrtpEvent *ev=NULL;
......@@ -516,7 +519,7 @@ void media_stream_iterate(MediaStream *stream){
} else if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED) {
OrtpEventData *evd=ortp_event_get_data(ev);
stream->sessions.is_secured=evd->info.zrtp_stream_encrypted;
ms_message("%s stream [%p] is %s ",media_stream_type_str(stream) , stream, stream->sessions.is_secured ? "encrypted" : "not encrypted");
ms_message("%s_stream_iterate[%p]: is %s ",media_stream_type_str(stream) , stream, stream->sessions.is_secured ? "encrypted" : "not encrypted");
}
ortp_event_destroy(ev);
}
......@@ -645,7 +648,7 @@ int ms_crypto_suite_to_name_params(MSCryptoSuite cs, MSCryptoSuiteNameParams *pa
break;
case MS_AES_128_SHA1_32:
params->name="AES_CM_128_HMAC_SHA1_32";
break;
break;
case MS_AES_128_NO_AUTH:
params->name="AES_CM_128_HMAC_SHA1_80";
params->params="UNAUTHENTICATED_SRTP";
......
This diff is collapsed.
/*
mediastreamer2 library - modular sound and video processing and streaming
* Copyright (C) 2011 Belledonne Communications, Grenoble, France
Author: Simon Morlat <simon.morlat@linphone.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.