mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
Add a TMMBR callback
This commit is contained in:
parent
5c2669970f
commit
a244da20ff
11 changed files with 128 additions and 4 deletions
|
|
@ -47,6 +47,7 @@ void linphone_call_notify_transfer_state_changed(LinphoneCall *call, LinphoneCal
|
|||
void linphone_call_notify_stats_updated(LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
void linphone_call_notify_info_message_received(LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
void linphone_call_notify_ack_processing(LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received);
|
||||
void linphone_call_notify_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg);
|
||||
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op);
|
||||
|
|
|
|||
|
|
@ -159,6 +159,20 @@ LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_process
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb);
|
||||
|
||||
/**
|
||||
* Get the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @return The current TMMBR received callback.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received(LinphoneCallCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @param[in] cb The TMMBR received callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_tmmbr_received(LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -87,6 +87,14 @@ typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, Linpho
|
|||
*/
|
||||
typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeaders *ack, bool_t is_received);
|
||||
|
||||
/**
|
||||
* Callback for notifying a received TMMBR.
|
||||
* @param call LinphoneCall for which the TMMBR has changed
|
||||
* @param stream_index the index of the current stream
|
||||
* @param tmmbr the value of the received TMMBR
|
||||
*/
|
||||
typedef void (*LinphoneCallCbsTmmbrReceivedCb)(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct _LinphoneCallCbs {
|
|||
LinphoneCallCbsStatsUpdatedCb statsUpdatedCb;
|
||||
LinphoneCallCbsTransferStateChangedCb transferStateChangedCb;
|
||||
LinphoneCallCbsAckProcessingCb ackProcessing;
|
||||
LinphoneCallCbsTmmbrReceivedCb tmmbrReceivedCb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCallCbs);
|
||||
|
|
@ -124,3 +125,11 @@ LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCal
|
|||
void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb){
|
||||
cbs->ackProcessing = cb;
|
||||
}
|
||||
|
||||
LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received (LinphoneCallCbs *cbs) {
|
||||
return cbs->tmmbrReceivedCb;
|
||||
}
|
||||
|
||||
void linphone_call_cbs_set_tmmbr_received (LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb) {
|
||||
cbs->tmmbrReceivedCb = cb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ void linphone_call_notify_ack_processing (LinphoneCall *call, LinphoneHeaders *m
|
|||
NOTIFY_IF_EXIST(AckProcessing, ack_processing, call, msg, is_received)
|
||||
}
|
||||
|
||||
void linphone_call_notify_tmmbr_received (LinphoneCall *call, int stream_index, int tmmbr) {
|
||||
NOTIFY_IF_EXIST(TmmbrReceived, tmmbr_received, call, stream_index, tmmbr)
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Public functions.
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ private:
|
|||
bool areSoundResourcesAvailable (const std::shared_ptr<CallSession> &session) override;
|
||||
bool isPlayingRingbackTone (const std::shared_ptr<CallSession> &session) override;
|
||||
void onRealTimeTextCharacterReceived (const std::shared_ptr<CallSession> &session, RealtimeTextReceivedCharacter *character) override;
|
||||
void onTmmbrReceived(const std::shared_ptr<CallSession> &session, int streamIndex, int tmmbr) override;
|
||||
|
||||
mutable LinphonePlayer *player = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -491,6 +491,11 @@ void CallPrivate::onRealTimeTextCharacterReceived (const shared_ptr<CallSession>
|
|||
getChatRoom()->getPrivate()->realtimeTextReceived(data->character, q->getSharedFromThis());
|
||||
}
|
||||
|
||||
void CallPrivate::onTmmbrReceived (const shared_ptr<CallSession> &session, int streamIndex, int tmmbr) {
|
||||
L_Q();
|
||||
linphone_call_notify_tmmbr_received(L_GET_C_BACK_PTR(q), streamIndex, tmmbr);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Call::Call (CallPrivate &p, shared_ptr<Core> core) : Object(p), CoreAccessor(core) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void onIncomingCallSessionTimeoutCheck (const std::shared_ptr<CallSession> &session, int elapsed, bool oneSecondElapsed) {}
|
||||
virtual void onInfoReceived (const std::shared_ptr<CallSession> &session, const LinphoneInfoMessage *im) {}
|
||||
virtual void onNoMediaTimeoutCheck (const std::shared_ptr<CallSession> &session, bool oneSecondElapsed) {}
|
||||
virtual void onTmmbrReceived (const std::shared_ptr<CallSession> &session, int streamIndex, int tmmbr) {}
|
||||
|
||||
virtual void onEncryptionChanged (const std::shared_ptr<CallSession> &session, bool activated, const std::string &authToken) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -2238,6 +2238,7 @@ void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) {
|
|||
}
|
||||
|
||||
void MediaSessionPrivate::handleStreamEvents (int streamIndex) {
|
||||
L_Q();
|
||||
MediaStream *ms = (streamIndex == mainAudioStreamIndex) ? &audioStream->ms :
|
||||
(streamIndex == mainVideoStreamIndex ? &videoStream->ms : &textStream->ms);
|
||||
if (ms) {
|
||||
|
|
@ -2272,14 +2273,28 @@ void MediaSessionPrivate::handleStreamEvents (int streamIndex) {
|
|||
stats = videoStats;
|
||||
else
|
||||
stats = textStats;
|
||||
|
||||
OrtpEventType evt = ortp_event_get_type(ev);
|
||||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
|
||||
/*This MUST be done before any call to "linphone_call_stats_fill" since it has ownership over evd->packet*/
|
||||
if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
|
||||
do {
|
||||
if (evd->packet && rtcp_is_RTPFB(evd->packet)) {
|
||||
if (rtcp_RTPFB_get_type(evd->packet) == RTCP_RTPFB_TMMBR) {
|
||||
listener->onTmmbrReceived(q->getSharedFromThis(), streamIndex, (int)rtcp_RTPFB_tmmbr_get_max_bitrate(evd->packet));
|
||||
}
|
||||
}
|
||||
} while (rtcp_next_packet(evd->packet));
|
||||
rtcp_rewind(evd->packet);
|
||||
}
|
||||
|
||||
/* And yes the MediaStream must be taken at each iteration, because it may have changed due to the handling of events
|
||||
* in this loop*/
|
||||
ms = getMediaStream(streamIndex);
|
||||
if (ms)
|
||||
linphone_call_stats_fill(stats, ms, ev);
|
||||
notifyStatsUpdated(streamIndex);
|
||||
OrtpEventType evt = ortp_event_get_type(ev);
|
||||
OrtpEventData *evd = ortp_event_get_data(ev);
|
||||
if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED) {
|
||||
if (streamIndex == mainAudioStreamIndex)
|
||||
audioStreamEncryptionChanged(!!evd->info.zrtp_stream_encrypted);
|
||||
|
|
|
|||
|
|
@ -2008,6 +2008,70 @@ static void video_call_with_thin_congestion(void){
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void on_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr) {
|
||||
if (stream_index == _linphone_call_get_main_video_stream_index(call)) {
|
||||
stats* stat = get_stats(linphone_call_get_core(call));
|
||||
stat->tmmbr_received_from_cb = tmmbr;
|
||||
}
|
||||
}
|
||||
|
||||
static void call_created(LinphoneCore *lc, LinphoneCall *call) {
|
||||
LinphoneCallCbs *cbs = linphone_factory_create_call_cbs(linphone_factory_get());
|
||||
linphone_call_cbs_set_tmmbr_received(cbs, on_tmmbr_received);
|
||||
linphone_call_add_callbacks(call, cbs);
|
||||
linphone_call_cbs_unref(cbs);
|
||||
}
|
||||
|
||||
/*
|
||||
* This test simulates a higher bandwith available from marie than expected.
|
||||
* The stream from pauline to marie is not under test.
|
||||
* It checks that after a few seconds marie received a TMMBR with the approximate value corresponding to the new bandwidth.
|
||||
*
|
||||
**/
|
||||
static void video_call_with_high_bandwidth_available(void) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
|
||||
LinphoneVideoPolicy pol = {0};
|
||||
OrtpNetworkSimulatorParams simparams = { 0 };
|
||||
LinphoneCoreCbs *core_cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
|
||||
linphone_core_enable_video_capture(marie->lc, TRUE);
|
||||
linphone_core_enable_video_display(marie->lc, TRUE);
|
||||
linphone_core_enable_video_capture(pauline->lc, TRUE);
|
||||
linphone_core_enable_video_display(pauline->lc, TRUE);
|
||||
|
||||
pol.automatically_accept = TRUE;
|
||||
pol.automatically_initiate = TRUE;
|
||||
linphone_core_set_video_policy(marie->lc, &pol);
|
||||
linphone_core_set_video_policy(pauline->lc, &pol);
|
||||
|
||||
linphone_core_set_preferred_video_size_by_name(marie->lc, "vga");
|
||||
simparams.mode = OrtpNetworkSimulatorOutbound;
|
||||
simparams.enabled = TRUE;
|
||||
simparams.max_bandwidth = 1000000;
|
||||
simparams.max_buffer_size = (int)simparams.max_bandwidth;
|
||||
simparams.latency = 60;
|
||||
|
||||
linphone_core_set_network_simulator_params(marie->lc, &simparams);
|
||||
|
||||
linphone_core_cbs_set_call_created(core_cbs, call_created);
|
||||
linphone_core_add_callbacks(marie->lc, core_cbs);
|
||||
|
||||
if (BC_ASSERT_TRUE(call(marie, pauline))){
|
||||
/*wait a little in order to have traffic*/
|
||||
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, NULL, 5, 50000));
|
||||
|
||||
BC_ASSERT_GREATER((float)marie->stat.last_tmmbr_value_received, 870000.f, float, "%f");
|
||||
BC_ASSERT_LOWER((float)marie->stat.last_tmmbr_value_received, 1150000.f, float, "%f");
|
||||
|
||||
end_call(marie, pauline);
|
||||
}
|
||||
linphone_core_cbs_unref(core_cbs);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
test_t call_video_tests[] = {
|
||||
#ifdef VIDEO_ENABLED
|
||||
TEST_NO_TAG("Call paused resumed with video", call_paused_resumed_with_video),
|
||||
|
|
@ -2073,10 +2137,11 @@ test_t call_video_tests[] = {
|
|||
TEST_NO_TAG("Classic video entry phone setup", classic_video_entry_phone_setup),
|
||||
TEST_NO_TAG("Incoming REINVITE with invalid SDP in ACK", incoming_reinvite_with_invalid_ack_sdp),
|
||||
TEST_NO_TAG("Outgoing REINVITE with invalid SDP in ACK", outgoing_reinvite_with_invalid_ack_sdp),
|
||||
#endif
|
||||
TEST_NO_TAG("Video call with no audio and no video codec", video_call_with_no_audio_and_no_video_codec),
|
||||
TEST_NO_TAG("Call with early media and no SDP in 200 Ok with video", call_with_early_media_and_no_sdp_in_200_with_video),
|
||||
TEST_NO_TAG("Video call with thin congestion", video_call_with_thin_congestion)
|
||||
TEST_NO_TAG("Video call with thin congestion", video_call_with_thin_congestion),
|
||||
TEST_NO_TAG("Video call with high bandwidth available", video_call_with_high_bandwidth_available)
|
||||
#endif
|
||||
};
|
||||
|
||||
test_suite_t call_video_test_suite = {"Video Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ typedef struct _stats {
|
|||
int number_of_rtcp_generic_nack;
|
||||
int number_of_tmmbr_received;
|
||||
int last_tmmbr_value_received;
|
||||
int tmmbr_received_from_cb;
|
||||
|
||||
int number_of_participants_added;
|
||||
int number_of_participant_admin_statuses_changed;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue