Commit 2ce82cfe authored by Rafaël Carré's avatar Rafaël Carré

* 6594 : configuration dialog for video codecs

remove a bunch of unused functions
remove a bunch of pointer indirection
remove a bunch of memleaks

video codecs are identified by their name rather than by their payload,
because for most (all?) codecs the payload is dynamic.

remove unused codecs bandwidth information
parent 670123ca
......@@ -82,8 +82,9 @@ typedef struct {
GHashTable * properties;
GPtrArray * credential_information;
/* The codec list */
/* The codec lists */
GQueue *codecs;
GQueue *vcodecs;
guint _messages_number;
} account_t;
......
......@@ -370,7 +370,12 @@ gboolean sflphone_init (GError **error)
history = calltab_init (TRUE, HISTORY);
account_list_init ();
codec_capabilities_load ();
if (!codecs_load ()) {
ERROR ("No codecs found");
dbus_unregister (getpid());
exit (1);
}
conferencelist_init (current_calls);
conferencelist_init (history);
......@@ -391,9 +396,9 @@ void sflphone_fill_ip2ip_profile (void)
ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}
void sflphone_get_ip2ip_properties (GHashTable **properties)
GHashTable *sflphone_get_ip2ip_properties (void)
{
*properties = ip2ip_profile;
return ip2ip_profile;
}
void
......@@ -1186,83 +1191,86 @@ sflphone_rec_call()
void sflphone_fill_codec_list ()
{
guint account_list_size;
guint i;
account_t *current = NULL;
DEBUG ("SFLphone: Fill codec list");
account_list_size = account_list_get_size ();
guint i, account_list_size = account_list_get_size ();
for (i=0; i<account_list_size; i++) {
current = account_list_get_nth (i);
if (current) {
sflphone_fill_codec_list_per_account (&current);
}
account_t *current = account_list_get_nth (i);
if (current)
sflphone_fill_codec_list_per_account (current);
}
}
void sflphone_fill_codec_list_per_account (account_t **account)
static void sflphone_fill_codec_list_per_account_cat (account_t *account, gboolean is_audio)
{
gchar **order;
gchar** pl;
GQueue *codeclist;
gboolean active = FALSE;
order = (gchar**) dbus_get_active_audio_codec_list ( (*account)->accountID);
codeclist = (*account)->codecs;
order = is_audio
? dbus_get_active_audio_codec_list (account->accountID)
: dbus_get_active_video_codec_list (account->accountID);
if (is_audio) {
if (!account->codecs)
account->codecs = g_queue_new();
codeclist = account->codecs;
} else {
if (!account->vcodecs)
account->vcodecs = g_queue_new();
codeclist = account->vcodecs;
}
// First clean the list
codec_list_clear (&codeclist);
g_queue_clear (codeclist);
if (! (*order))
ERROR ("SFLphone: No codec list provided");
GQueue* codecs = is_audio ? get_audio_codecs_list() : get_video_codecs_list();
gchar **pl;
for (pl=order; *pl; pl++) {
codec_t * cpy = NULL;
// Each account will have a copy of the system-wide capabilities
codec_create_new_from_caps (codec_list_get_by_payload ( (gconstpointer) (size_t) atoi (*pl), NULL), &cpy);
if (cpy) {
cpy->is_active = TRUE;
codec_list_add (cpy, &codeclist);
} else
ERROR ("SFLphone: Couldn't find codec");
codec_t *orig;
if (is_audio)
orig = codec_list_get_by_payload (atoi(*pl), codecs);
else
orig = codec_list_get_by_name(*pl, codecs);
codec_t *c = codec_create_new_from_caps (orig);
if (c)
g_queue_push_tail (codeclist, (gpointer) c);
else
ERROR ("SFLphone: Couldn't find codec %s %p", *pl, orig);
g_free(*pl);
}
g_free(order);
// Test here if we just added some active codec.
active = (codeclist->length == 0) ? TRUE : FALSE;
guint caps_size = codec_list_get_size (), i=0;
// if no codecs were added, activate them all
gboolean active = codeclist->length == 0;
guint i, caps_size = g_queue_get_length(codecs);
for (i=0; i<caps_size; i++) {
codec_t * current_cap = capabilities_get_nth (i);
codec_t * codec = g_queue_peek_nth (codecs, i);
gboolean found;
// Check if this codec has already been enabled for this account
if (codec_list_get_by_payload ( (gconstpointer) (size_t) (current_cap->_payload), codeclist) == NULL) {
// codec_t *cpy;
// codec_create_new_from_caps (current_cap, &cpy);
current_cap->is_active = active;
codec_list_add (current_cap, &codeclist);
} else {
if (is_audio)
found = codec_list_get_by_payload (codec->payload, codeclist) != NULL;
else
found = codec_list_get_by_name(codec->name, codeclist) != NULL;
if (!found) {
codec->is_active = active;
g_queue_push_tail (codeclist, (gpointer)codec);
}
}
}
(*account)->codecs = codeclist;
void sflphone_fill_codec_list_per_account (account_t *account)
{
sflphone_fill_codec_list_per_account_cat(account, TRUE);
sflphone_fill_codec_list_per_account_cat(account, FALSE);
}
void sflphone_fill_call_list (void)
{
gchar** calls = (gchar**) dbus_get_call_list();
gchar** calls = dbus_get_call_list();
GHashTable *call_details;
callable_obj_t *c;
gchar *callID;
......
......@@ -172,7 +172,7 @@ void sflphone_fill_ip2ip_profile (void);
* @return The internal hash table representing
* the settings for the ip2ip profile.
*/
void sflphone_get_ip2ip_properties (GHashTable **properties);
GHashTable *sflphone_get_ip2ip_properties (void);
/**
* Initialize the accounts data structure
......@@ -192,7 +192,7 @@ void sflphone_set_current_account();
*/
void sflphone_fill_codec_list ();
void sflphone_fill_codec_list_per_account (account_t **);
void sflphone_fill_codec_list_per_account (account_t *);
void sflphone_add_participant();
......
......@@ -96,19 +96,13 @@ gchar* call_get_peer_number (const gchar *format)
gchar* call_get_audio_codec (callable_obj_t *obj)
{
gchar *audio_codec = "";
codec_t *codec;
gchar *format ="";
int samplerate;
gchar *format = NULL;
if (obj) {
audio_codec = dbus_get_current_audio_codec_name (obj);
codec = codec_list_get_by_name (audio_codec, NULL);
if (codec) {
samplerate = codec->sample_rate;
format = g_markup_printf_escaped ("%s/%i", audio_codec, samplerate);
}
gchar *audio_codec = dbus_get_current_audio_codec_name (obj);
codec_t *codec = codec_list_get_by_name (audio_codec, get_audio_codecs_list());
if (codec)
format = g_markup_printf_escaped ("%s/%s", audio_codec, codec->sample_rate);
g_free(audio_codec);
}
return format;
......
......@@ -32,333 +32,220 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include "dbus.h"
static GQueue * codecsCapabilities = NULL;
static GQueue audioCodecs = G_QUEUE_INIT;
static GQueue videoCodecs = G_QUEUE_INIT;
gint
is_name_codecstruct (gconstpointer a, gconstpointer b)
{
codec_t * c = (codec_t *) a;
if (strcmp (c->name, (const gchar *) b) ==0)
return 0;
else
return 1;
}
gint
is_payload_codecstruct (gconstpointer a, gconstpointer b)
/*
* Instanciate a new codec
*
* @param payload The unique RTP payload
* @return codec The new codec instance, or NULL
*/
static codec_t *codec_create (gint payload, gchar **specs)
{
codec_t * c = (codec_t *) a;
codec_t *codec = g_new0 (codec_t, 1);
if (!codec) {
g_strfreev(specs);
return NULL;
}
if (c->_payload == GPOINTER_TO_INT (b))
return 0;
else
return 1;
}
codec->payload = payload;
codec->name = specs[0];
codec->bitrate = specs[1];
codec->sample_rate = specs[2];
codec->is_active = TRUE;
void codec_list_init (GQueue **queue)
{
g_free(specs);
// Create the queue object that will contain the audio codecs
*queue = g_queue_new();
return codec;
}
void codec_capabilities_load (void)
static gboolean codecs_audio_load (void)
{
guint payload;
// Create the queue object that will contain the global list of audio codecs
if (codecsCapabilities != NULL)
g_queue_free (codecsCapabilities);
codecsCapabilities = g_queue_new();
// This is a global list inherited by all accounts
gchar **codecs = dbus_audio_codec_list ();
gchar **codecs = dbus_audio_codec_list();
gchar **codecs_orig = codecs;
if (codecs != NULL) {
// Add the codecs in the list
for (; *codecs; codecs++) {
codec_t *c;
payload = atoi (*codecs);
gchar **specs = dbus_audio_codec_details (payload);
codec_create_new_with_specs (payload, specs, TRUE, &c);
g_strfreev(specs);
g_queue_push_tail (codecsCapabilities, (gpointer*) c);
g_free(*codecs);
}
g_free(codecs_orig);
if (!codecs)
return FALSE;
// Add the codecs in the list
for (; *codecs; codecs++) {
int payload = atoi(*codecs);
codec_t *c = codec_create(payload, dbus_audio_codec_details(payload));
if (c)
g_queue_push_tail (&audioCodecs, (gpointer*) c);
g_free(*codecs);
}
g_free(codecs_orig);
// If we didn't load any codecs, problem ...
if (g_queue_get_length (codecsCapabilities) == 0) {
// Error message
ERROR ("No audio codecs found");
dbus_unregister (getpid());
exit (1);
if (g_queue_get_length (&audioCodecs) == 0) {
return FALSE;
}
}
void account_create_codec_list (account_t **acc)
{
GQueue *_codecs;
_codecs = (*acc)->codecs;
if (_codecs != NULL)
g_queue_free (_codecs);
_codecs = g_queue_new ();
(*acc)->codecs = _codecs;
return TRUE;
}
void codec_create_new (gint payload, gboolean active, codec_t **c)
{
codec_t *codec;
gchar **specs;
codec = g_new0 (codec_t, 1);
codec->_payload = payload;
specs = (gchar **) dbus_audio_codec_details (payload);
codec->name = specs[0];
codec->sample_rate = atoi (specs[1]);
codec->_bitrate = atoi (specs[2]);
codec->_bandwidth = atoi (specs[3]);
codec->is_active = active;
*c = codec;
}
void codec_create_new_with_specs (gint payload, gchar **specs, gboolean active, codec_t **c)
{
codec_t *codec;
codec = g_new0 (codec_t, 1);
codec->_payload = payload;
codec->name = strdup(specs[0]);
codec->sample_rate = atoi (specs[1]);
codec->_bitrate = atoi (specs[2]);
codec->_bandwidth = atoi (specs[3]);
codec->is_active = active;
*c = codec;
}
void codec_create_new_from_caps (codec_t *original, codec_t **copy)
static gboolean codecs_video_load (void)
{
gchar **codecs = dbus_video_codec_list();
gchar **codecs_orig = codecs;
codec_t *codec;
if (!codecs)
return FALSE;
if (!original) {
*copy = NULL;
return;
int payload = 96; // dynamic payloads
// Add the codecs in the list
for (; *codecs; codecs++) {
codec_t *c = codec_create(payload++, dbus_video_codec_details(*codecs));
if (c)
g_queue_push_tail (&videoCodecs, (gpointer*) c);
g_free(*codecs);
}
g_free(codecs_orig);
codec = g_new0 (codec_t, 1);
codec->_payload = original->_payload;
codec->name = original->name;
codec->sample_rate = original->sample_rate;
codec->_bitrate = original->_bitrate;
codec->_bandwidth = original->_bandwidth;
codec->is_active = original->is_active;
// If we didn't load any codecs, problem ...
if (g_queue_get_length (&videoCodecs) == 0) {
return FALSE;
}
*copy = codec;
return TRUE;
}
void codec_list_clear (GQueue **queue)
gboolean codecs_load(void)
{
if (*queue != NULL)
g_queue_free (*queue);
*queue = g_queue_new();
return codecs_audio_load() && codecs_video_load();
}
/*void codec_list_clear (void) {
g_queue_free (codecsCapabilities);
codecsCapabilities = g_queue_new();
}*/
void codec_list_add (codec_t * c, GQueue **queue)
static void codec_free(gpointer data, gpointer user_data UNUSED)
{
// Add a codec to a specific list
g_queue_push_tail (*queue, (gpointer *) c);
codec_t *codec = (codec_t*)data;
g_free(codec->name);
g_free(codec->sample_rate);
g_free(codec->bitrate);
}
void codec_set_active (codec_t **c)
void codecs_unload (void)
{
if (c) {
DEBUG ("%s set active", (*c)->name);
(*c)->is_active = TRUE;
}
g_queue_foreach(&audioCodecs, codec_free, NULL);
}
void codec_set_inactive (codec_t **c)
codec_t *codec_create_new_from_caps (codec_t *original)
{
if (!original)
return NULL;
if (c) {
DEBUG ("%s set active", (*c)->name);
(*c)->is_active = FALSE;
codec_t *codec = g_new0 (codec_t, 1);
if (codec) {
memcpy(codec, original, sizeof *codec);
codec->is_active = TRUE;
}
return codec;
}
guint codec_list_get_size ()
static gint
is_name_codecstruct (gconstpointer a, gconstpointer b)
{
// The system wide codec list and the one per account have exactly the same size
// The only difference may be the order and the enabled codecs
return g_queue_get_length (codecsCapabilities);
return strcmp (((codec_t*)a)->name, (const gchar *) b);
}
codec_t* codec_list_get_by_name (gconstpointer name, GQueue *q)
{
// If NULL is passed as argument, we look into the global capabilities
if (q == NULL)
q = codecsCapabilities;
GList * c = g_queue_find_custom (q, name, is_name_codecstruct);
if (c)
return (codec_t *) c->data;
else
return NULL;
}
codec_t* codec_list_get_by_payload (gconstpointer payload, GQueue *q)
{
// If NULL is passed as argument, we look into the global capabilities
if (q == NULL)
q = codecsCapabilities;
GList * c = g_queue_find_custom (q, payload, is_payload_codecstruct);
if (c)
return (codec_t *) c->data;
else
return NULL;
return c ? (codec_t *) c->data : NULL;
}
codec_t* codec_list_get_nth (guint index, GQueue *q)
static gint
is_payload_codecstruct (gconstpointer a, gconstpointer b)
{
return g_queue_peek_nth (q, index);
return ((codec_t*)a)->payload != GPOINTER_TO_INT (b);
}
codec_t* capabilities_get_nth (guint index)
codec_t* codec_list_get_by_payload (int payload, GQueue *q)
{
return g_queue_peek_nth (codecsCapabilities, index);
GList * c = g_queue_find_custom (q, (gconstpointer)(uintptr_t)payload, is_payload_codecstruct);
return c ? (codec_t *) c->data : NULL;
}
void codec_set_prefered_order (guint index, GQueue *q)
{
codec_t * prefered = codec_list_get_nth (index, q);
codec_t * prefered = g_queue_peek_nth (q, index);
g_queue_pop_nth (q, index);
g_queue_push_head (q, prefered);
}
void codec_list_move_codec_up (guint index, GQueue **q)
void codec_list_move (guint index, GQueue *q, gboolean up)
{
guint already = up ? 0 : q->length;
gint new = up ? index - 1 : index + 1;
DEBUG ("Codec list Size: %i \n", codec_list_get_size ());
GQueue *tmp = *q;
if (index != 0) {
gpointer codec = g_queue_pop_nth (tmp, index);
g_queue_push_nth (tmp, codec, index-1);
}
*q = tmp;
}
void codec_list_move_codec_down (guint index, GQueue **q)
{
DEBUG ("Codec list Size: %i \n",codec_list_get_size());
GQueue *tmp = *q;
if (index != tmp->length) {
gpointer codec = g_queue_pop_nth (tmp, index);
g_queue_push_nth (tmp, codec, index+1);
}
*q = tmp;
if (index == already)
return;
gpointer codec = g_queue_pop_nth (q, index);
g_queue_push_nth (q, codec, new);
}
void codec_list_update_to_daemon (account_t *acc)
static void codec_list_update_to_daemon_cat (account_t *acc, gboolean is_audio)
{
gchar** codecList = NULL;
// String listing codecs payloads
const gchar** codecList;
// Length of the codec list
int length = acc->codecs->length;
// Initiate double array char list for one string
codecList = (void*) malloc (sizeof (void*));
GQueue *q = is_audio ? acc->codecs : acc->vcodecs;
int length = q->length;
// Get all codecs in queue
int c = 0;
int i = 0;
int i, c = 0;
for (i = 0; i < length; i++) {
codec_t* currentCodec = codec_list_get_nth (i, acc->codecs);
// Assert not null