Commit 2c90f5e7 authored by Simon Morlat's avatar Simon Morlat

add player api, fix bug in linphone_core_terminate_conference()

parent 9c396a9c
......@@ -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(&params);
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
......
/*
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));
}
}
......
mediastreamer2 @ 4d3ab5f2
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},
......
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