]> sjero.net Git - linphone/commitdiff
Add call audio/video stats
authorYann Diorcet <yann.diorcet@belledonne-communications.com>
Mon, 21 May 2012 13:35:14 +0000 (15:35 +0200)
committerYann Diorcet <yann.diorcet@belledonne-communications.com>
Mon, 21 May 2012 13:35:14 +0000 (15:35 +0200)
coreapi/linphonecall.c
coreapi/linphonecore.h
coreapi/private.h

index 69f9266a14dce11e1b2a392a4332b26520cebf00..8dccf96120aaf92f9293b9537d9a5299bc987aa3 100644 (file)
@@ -68,6 +68,14 @@ LinphoneCore *linphone_call_get_core(const LinphoneCall *call){
        return call->core;
 }
 
+const LinphoneCallStats *linphone_call_get_audio_stats(const LinphoneCall *call) {
+       return &call->stats[LINPHONE_CALL_STATS_AUDIO];
+}
+
+const LinphoneCallStats *linphone_call_get_video_stats(const LinphoneCall *call) {
+       return &call->stats[LINPHONE_CALL_STATS_VIDEO];
+}
+
 const char* linphone_call_get_authentication_token(LinphoneCall *call){
        return call->auth_token;
 }
@@ -305,7 +313,14 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
        if (port_offset==-1) return;
        call->audio_port=linphone_core_get_audio_port(call->core)+port_offset;
        call->video_port=linphone_core_get_video_port(call->core)+port_offset;
+       linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO);
+       linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO);
+}
 
+void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
+       stats->type = LINPHONE_CALL_STATS_AUDIO;
+       stats->received_rtcp = NULL;
+       stats->sent_rtcp = NULL;
 }
 
 static void discover_mtu(LinphoneCore *lc, const char *remote){
@@ -1594,6 +1609,7 @@ static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
 }
 
 void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed){
+       LinphoneCore* lc = call->core;
        int disconnect_timeout = linphone_core_get_nortp_timeout(call->core);
        bool_t disconnected=FALSE;
 
@@ -1623,9 +1639,25 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
                        OrtpEvent *ev;
                        while (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq))){
                                OrtpEventType evt=ortp_event_get_type(ev);
+                               OrtpEventData *evd=ortp_event_get_data(ev);
                                if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
-                                       OrtpEventData *evd=ortp_event_get_data(ev);
                                        linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
+                               } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
+                                       call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->session);
+                                       if(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp != NULL)
+                                               freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp);
+                                       call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp = evd->packet;
+                                       evd->packet = NULL;
+                                       if (lc->vtable.call_stats_updated)
+                                               lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
+                               } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
+                                       memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->session), sizeof(jitter_stats_t));
+                                       if(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp != NULL)
+                                               freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp);
+                                       call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp = evd->packet;
+                                       evd->packet = NULL;
+                                       if (lc->vtable.call_stats_updated)
+                                               lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
                                }
                                ortp_event_destroy(ev);
                        }
@@ -1641,12 +1673,27 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
                        OrtpEvent *ev;
                        while (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq))){
                                OrtpEventType evt=ortp_event_get_type(ev);
+                               OrtpEventData *evd=ortp_event_get_data(ev);
                                if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
-                                       OrtpEventData *evd=ortp_event_get_data(ev);
                                        linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
                                } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) {
-                                       OrtpEventData *evd=ortp_event_get_data(ev);
                                        linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified);
+                               } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
+                                       call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->session);
+                                       if(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp != NULL)
+                                               freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp);
+                                       call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp = evd->packet;
+                                       evd->packet = NULL;
+                                       if (lc->vtable.call_stats_updated)
+                                               lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
+                               } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
+                                       memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->session), sizeof(jitter_stats_t));
+                                       if(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp != NULL)
+                                               freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp);
+                                       call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp = evd->packet;
+                                       evd->packet = NULL;
+                                       if (lc->vtable.call_stats_updated)
+                                               lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
                                }
                                ortp_event_destroy(ev);
                        }
index bd10556a054e6925a98e9644819e85b81e2e248d..9b0de2e7159baf40a91a8a223ad97fe85ea26542 100644 (file)
@@ -228,7 +228,23 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy;
 **/
 struct _LinphoneCall;
 typedef struct _LinphoneCall LinphoneCall;
-    
+
+
+#define LINPHONE_CALL_STATS_AUDIO 0
+#define LINPHONE_CALL_STATS_VIDEO 1
+
+typedef struct _LinphoneCallStats {
+       int             type;
+       jitter_stats_t  jitter_stats;
+       mblk_t*         received_rtcp;
+       mblk_t*         sent_rtcp;
+       float           round_trip_delay;
+} LinphoneCallStats;
+
+const LinphoneCallStats *linphone_call_get_audio_stats(const LinphoneCall *call);
+const LinphoneCallStats *linphone_call_get_video_stats(const LinphoneCall *call);
+
+
 /** Callback prototype */
 typedef void (*LinphoneCallCbFunc)(struct _LinphoneCall *call,void * user_data);
 
@@ -624,6 +640,8 @@ typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to);
 typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf);
 /** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */
 typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state);
+/** Callback prototype */
+typedef void (*CallStatsUpdated)(struct _LinphoneCore *lc, LinphoneCall *call, LinphoneCallStats *stats);
 
 /**
  * This structure holds all callbacks that the application should implement.
@@ -641,9 +659,10 @@ typedef struct _LinphoneVTable{
        DtmfReceived dtmf_received; /**< A dtmf has been received received */
        ReferReceived refer_received; /**< An out of call refer was received */
        CallEncryptionChangedCb call_encryption_changed; /**<Notifies on change in the encryption of call streams */
-    LinphoneTransferStateChanged transfer_state_changed; /**<Notifies when a transfer is in progress */
+       LinphoneTransferStateChanged transfer_state_changed; /**<Notifies when a transfer is in progress */
        BuddyInfoUpdated buddy_info_updated; /**< a LinphoneFriend's BuddyInfo has changed*/
        NotifyReceivedCb notify_recv; /**< Other notifications*/
+       CallStatsUpdated call_stats_updated; /**<Notifies on change in the stats of call */
        DisplayStatusCb display_status; /**< Callback that notifies various events with human readable text.*/
        DisplayMessageCb display_message;/**< Callback to display a message to the user */
        DisplayMessageCb display_warning;/** Callback to display a warning to the user */
index a790276dd23f714350896cd6c942d6a2af832899..773e77882a0d789a9a01b8d6060d556b76fbf5cd 100644 (file)
@@ -133,7 +133,8 @@ struct _LinphoneCall
        bool_t auth_token_verified;
        bool_t defer_update;
        bool_t was_automatically_paused;
-    CallCallbackObj nextVideoFrameDecoded;
+       CallCallbackObj nextVideoFrameDecoded;
+       LinphoneCallStats stats[2];
 };
 
 
@@ -238,6 +239,8 @@ void linphone_core_text_received(LinphoneCore *lc, const char *from, const char
 
 void linphone_core_play_tone(LinphoneCore *lc);
 
+void linphone_call_init_stats(LinphoneCallStats *stats, int type);
+
 void linphone_call_init_media_streams(LinphoneCall *call);
 void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
 void linphone_call_stop_media_streams(LinphoneCall *call);