forked from mirrors/linphone-iphone
add player api, fix bug in linphone_core_terminate_conference()
This commit is contained in:
parent
9c396a9cd9
commit
2c90f5e702
9 changed files with 231 additions and 4 deletions
|
|
@ -60,6 +60,7 @@ liblinphone_la_SOURCES=\
|
|||
remote_provisioning.c \
|
||||
quality_reporting.c quality_reporting.h\
|
||||
call_log.c \
|
||||
player.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ static void conference_check_init(LinphoneConference *ctx, int samplerate){
|
|||
MSAudioConferenceParams params;
|
||||
params.samplerate=samplerate;
|
||||
ctx->conf=ms_audio_conference_new(¶ms);
|
||||
ctx->terminated=FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ void linphone_core_conference_check_uninit(LinphoneCore *lc){
|
|||
if (ctx->conf){
|
||||
int remote_count=remote_participants_count(ctx);
|
||||
ms_message("conference_check_uninit(): size=%i",linphone_conference_get_size(ctx));
|
||||
if (remote_count==1){
|
||||
if (remote_count==1 && !ctx->terminated){
|
||||
convert_conference_to_call(lc);
|
||||
}
|
||||
if (remote_count==0){
|
||||
|
|
@ -251,7 +252,6 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a
|
|||
ms_message("Pausing call to actually remove from conference");
|
||||
err=_linphone_core_pause_call(lc,call);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -388,6 +388,9 @@ int linphone_core_add_all_to_conference(LinphoneCore *lc) {
|
|||
**/
|
||||
int linphone_core_terminate_conference(LinphoneCore *lc) {
|
||||
MSList *calls=lc->calls;
|
||||
LinphoneConference *conf=&lc->conf_ctx;
|
||||
conf->terminated=TRUE;
|
||||
|
||||
while (calls) {
|
||||
LinphoneCall *call=(LinphoneCall*)calls->data;
|
||||
calls=calls->next;
|
||||
|
|
|
|||
|
|
@ -3240,3 +3240,9 @@ void linphone_call_set_contact_op(LinphoneCall* call) {
|
|||
linphone_address_destroy(contact);
|
||||
}
|
||||
}
|
||||
|
||||
LinphonePlayer *linphone_call_get_player(LinphoneCall *call){
|
||||
if (call->player==NULL)
|
||||
call->player=linphone_call_build_player(call);
|
||||
return call->player;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -645,6 +645,27 @@ LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number(
|
|||
/** Callback prototype */
|
||||
typedef void (*LinphoneCallCbFunc)(LinphoneCall *call,void * user_data);
|
||||
|
||||
/**
|
||||
* Player interface.
|
||||
* @ingroup call_control
|
||||
**/
|
||||
typedef struct _LinphonePlayer LinphonePlayer;
|
||||
|
||||
/**
|
||||
* Callback for notifying end of play (file).
|
||||
* @param obj the LinphonePlayer
|
||||
* @param user_data the user_data provided when calling linphone_player_open().
|
||||
* @ingroup call_control
|
||||
**/
|
||||
typedef void (*LinphonePlayerEofCallback)(struct _LinphonePlayer *obj, void *user_data);
|
||||
|
||||
int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback, void *user_data);
|
||||
int linphone_player_start(LinphonePlayer *obj);
|
||||
int linphone_player_pause(LinphonePlayer *obj);
|
||||
int linphone_player_seek(LinphonePlayer *obj, int time_ms);
|
||||
MSPlayerState linphone_player_get_state(LinphonePlayer *obj);
|
||||
void linphone_player_close(LinphonePlayer *obj);
|
||||
|
||||
/**
|
||||
* LinphoneCallState enum represents the different state a call can reach into.
|
||||
* The application is notified of state changes through the LinphoneCoreVTable::call_state_changed callback.
|
||||
|
|
@ -758,6 +779,7 @@ LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall
|
|||
LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy);
|
||||
LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC LinphonePlayer * linphone_call_get_player(LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Return TRUE if this call is currently part of a conference
|
||||
|
|
|
|||
168
coreapi/player.c
Normal file
168
coreapi/player.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2014 Belledonne Communications SARL
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
/**
|
||||
* Open a new source on this player.
|
||||
* @param obj the player
|
||||
* @param filename file to open.
|
||||
* @param cb a callback used to notify end of play.
|
||||
* @param user_data a user-data provided in the callback to help the application to retrieve its context.
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback cb, void *user_data){
|
||||
obj->user_data=user_data;
|
||||
obj->cb=cb;
|
||||
return obj->open(obj->impl,filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a play operation. The player must have been open previously with linphone_player_open().
|
||||
* @param obj the player.
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_player_start(LinphonePlayer *obj){
|
||||
return obj->start(obj->impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspend a play operation. The player must have been started previously with linphone_player_start().
|
||||
* @param obj the player.
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_player_pause(LinphonePlayer *obj){
|
||||
return obj->pause(obj->impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek at a given position given in milliseconds. The player must be in the paused state.
|
||||
* @param obj the player.
|
||||
* @param time_ms the position to seek to.
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_player_seek(LinphonePlayer *obj, int time_ms){
|
||||
return obj->seek(obj->impl,time_ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of play operation.
|
||||
* @param obj the player.
|
||||
* @return the state of the player within MSPlayerClosed, MSPlayerStarted, MSPlayerPaused.
|
||||
**/
|
||||
MSPlayerState linphone_player_get_state(LinphonePlayer *obj){
|
||||
return obj->get_state(obj->impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the player.
|
||||
* @param obj the player.
|
||||
**/
|
||||
void linphone_player_close(LinphonePlayer *obj){
|
||||
return obj->close(obj->impl);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call player implementation below.
|
||||
*/
|
||||
|
||||
|
||||
static bool_t call_player_check_state(LinphonePlayer *player, bool_t check_player){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
if (call->state!=LinphoneCallStreamsRunning){
|
||||
ms_warning("Call [%p]: in-call player not usable in state [%s]",call,linphone_call_state_to_string(call->state));
|
||||
return FALSE;
|
||||
}
|
||||
if (call->audiostream==NULL) {
|
||||
ms_error("call_player_check_state(): no audiostream.");
|
||||
return FALSE;
|
||||
}
|
||||
if (check_player && call->audiostream->av_player.player==NULL){
|
||||
ms_error("call_player_check_state(): no player.");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_eof(void *user_data, MSFilter *f, unsigned int event_id, void *arg){
|
||||
LinphonePlayer *player=(LinphonePlayer *)user_data;
|
||||
if (player->cb) player->cb(player,user_data);
|
||||
}
|
||||
|
||||
static int call_player_open(LinphonePlayer* player, const char *filename){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
MSFilter *filter;
|
||||
if (!call_player_check_state(player,FALSE)) return -1;
|
||||
filter=audio_stream_open_remote_play(call->audiostream,filename);
|
||||
if (!filter) return -1;
|
||||
ms_filter_add_notify_callback(filter,&on_eof,player,FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int call_player_start(LinphonePlayer *player){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
if (!call_player_check_state(player,TRUE)) return -1;
|
||||
return ms_filter_call_method_noarg(call->audiostream->av_player.player,MS_PLAYER_START);
|
||||
}
|
||||
|
||||
static int call_player_pause(LinphonePlayer *player){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
if (!call_player_check_state(player,TRUE)) return -1;
|
||||
return ms_filter_call_method_noarg(call->audiostream->av_player.player,MS_PLAYER_PAUSE);
|
||||
}
|
||||
|
||||
static MSPlayerState call_player_get_state(LinphonePlayer *player){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
MSPlayerState state=MSPlayerClosed;
|
||||
if (!call_player_check_state(player,TRUE)) return MSPlayerClosed;
|
||||
ms_filter_call_method(call->audiostream->av_player.player,MS_PLAYER_GET_STATE,&state);
|
||||
return state;
|
||||
}
|
||||
|
||||
static int call_player_seek(LinphonePlayer *player, int time_ms){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
if (!call_player_check_state(player,TRUE)) return -1;
|
||||
return ms_filter_call_method(call->audiostream->av_player.player,MS_PLAYER_SEEK_MS,&time_ms);
|
||||
}
|
||||
|
||||
static void call_player_close(LinphonePlayer *player){
|
||||
LinphoneCall *call=(LinphoneCall*)player->impl;
|
||||
if (!call_player_check_state(player,TRUE)) return;
|
||||
ms_filter_call_method_noarg(call->audiostream->av_player.player,MS_PLAYER_CLOSE);
|
||||
|
||||
}
|
||||
|
||||
static void on_call_destroy(void *obj, belle_sip_object_t *call_being_destroyed){
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
LinphonePlayer *linphone_call_build_player(LinphoneCall *call){
|
||||
LinphonePlayer *obj=ms_new0(LinphonePlayer,1);
|
||||
obj->open=call_player_open;
|
||||
obj->close=call_player_close;
|
||||
obj->start=call_player_start;
|
||||
obj->seek=call_player_seek;
|
||||
obj->pause=call_player_pause;
|
||||
obj->get_state=call_player_get_state;
|
||||
obj->impl=call;
|
||||
belle_sip_object_weak_ref(call,on_call_destroy,obj);
|
||||
return obj;
|
||||
}
|
||||
|
|
@ -230,6 +230,7 @@ struct _LinphoneCall
|
|||
LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/
|
||||
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
|
||||
int localdesc_changed;/*not a boolean, contains a mask representing changes*/
|
||||
LinphonePlayer *player;
|
||||
|
||||
bool_t refer_pending;
|
||||
bool_t expect_media_in_ack;
|
||||
|
|
@ -262,6 +263,7 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *lo
|
|||
void linphone_call_log_completed(LinphoneCall *call);
|
||||
void linphone_call_log_destroy(LinphoneCallLog *cl);
|
||||
void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state);
|
||||
LinphonePlayer *linphone_call_build_player(LinphoneCall*call);
|
||||
|
||||
void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos);
|
||||
|
||||
|
|
@ -629,6 +631,7 @@ struct _LinphoneConference{
|
|||
MSAudioEndpoint *record_endpoint;
|
||||
RtpProfile *local_dummy_profile;
|
||||
bool_t local_muted;
|
||||
bool_t terminated;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -878,6 +881,23 @@ void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState
|
|||
int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Player interface
|
||||
****************************************************************************/
|
||||
|
||||
struct _LinphonePlayer{
|
||||
int (*open)(struct _LinphonePlayer* player, const char *filename);
|
||||
int (*start)(struct _LinphonePlayer* player);
|
||||
int (*pause)(struct _LinphonePlayer* player);
|
||||
int (*seek)(struct _LinphonePlayer* player, int time_ms);
|
||||
MSPlayerState (*get_state)(struct _LinphonePlayer* player);
|
||||
void (*close)(struct _LinphonePlayer* player);
|
||||
LinphonePlayerEofCallback cb;
|
||||
void *user_data;
|
||||
void *impl;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* XML UTILITY FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call){
|
|||
gtk_box_pack_start(GTK_BOX(conferencee_box),participant,FALSE,FALSE,PADDING_PIXELS);
|
||||
g_object_set_data_full(G_OBJECT(participant),"call",linphone_call_ref(call),(GDestroyNotify)linphone_call_unref);
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(viewswitch),
|
||||
gtk_notebook_page_num(GTK_NOTEBOOK(viewswitch),conf_frame));
|
||||
gtk_notebook_page_num(GTK_NOTEBOOK(viewswitch),conf_frame));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3c16405c515e5f49ef39400f7b8593c52fb90e0d
|
||||
Subproject commit 4d3ab5f253334282baad3177bf9d33e57e65c71d
|
||||
|
|
@ -23,6 +23,12 @@
|
|||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
|
||||
static void linphone_version_test(void){
|
||||
const char *version=linphone_core_get_version();
|
||||
/*make sure the git version is always included in the version number*/
|
||||
CU_ASSERT_TRUE(strstr(version,"unknown")==NULL);
|
||||
}
|
||||
|
||||
static void core_init_test(void) {
|
||||
LinphoneCoreVTable v_table;
|
||||
LinphoneCore* lc;
|
||||
|
|
@ -177,6 +183,7 @@ static void chat_root_test(void) {
|
|||
}
|
||||
|
||||
test_t setup_tests[] = {
|
||||
{ "Version check", linphone_version_test },
|
||||
{ "Linphone Address", linphone_address_test },
|
||||
{ "Linphone proxy config address equal (internal api)", linphone_proxy_config_address_equal_test},
|
||||
{ "Linphone proxy config server address change (internal api)", linphone_proxy_config_is_server_config_changed_test},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue