Commit 1961a498 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #13382: video: bitrate now modifiable in daemon and client

parent 6c077092
......@@ -96,10 +96,10 @@
<method name="setCodecs" tp:name-for-bindings="setCodecs">
<tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
<arg type="aa{ss}" name="details" direction="in">
</arg>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="aa{ss}" name="details" direction="in">
</arg>
</method>
<method name="startPreview" tp:name-for-bindings="startPreview">
......
......@@ -66,7 +66,8 @@ VideoControls::getCodecs(const std::string &accountID)
}
void
VideoControls::setCodecs(const std::vector<std::map<std::string, std::string> > &details, const std::string& accountID)
VideoControls::setCodecs(const std::string& accountID,
const std::vector<std::map<std::string, std::string> > &details)
{
Account *acc = Manager::instance().getAccount(accountID);
if (acc != NULL) {
......
......@@ -71,8 +71,8 @@ class VideoControls : public org::sflphone::SFLphone::VideoControls_adaptor,
getCodecs(const std::string& accountID);
void
setCodecs(const std::vector<std::map<std::string, std::string> > &details,
const std::string& accountID);
setCodecs(const std::string& accountID,
const std::vector<std::map<std::string, std::string> > &details);
std::vector<std::string>
getDeviceList();
......
......@@ -479,6 +479,19 @@ std::string Sdp::getActiveOutgoingVideoCodec() const
return string(codec_buf);
}
std::string Sdp::getActiveOutgoingVideoBitrate(const std::string &codec) const
{
for (vector<map<string, string> >::const_iterator i = video_codec_list_.begin(); i != video_codec_list_.end(); ++i) {
map<string, string>::const_iterator name = i->find("name");
if (name != i->end() and (codec == name->second)) {
map<string, string>::const_iterator bitrate = i->find("bitrate");
if (bitrate != i->end())
return bitrate->second;
}
}
return "0";
}
std::string Sdp::getActiveOutgoingVideoPayload() const
{
string videoLine(getLineFromSession(activeRemoteSession_, "m=video"));
......
......@@ -115,6 +115,7 @@ class Sdp {
*/
std::string getActiveIncomingVideoDescription() const;
std::string getActiveOutgoingVideoCodec() const;
std::string getActiveOutgoingVideoBitrate(const std::string &codec) const;
std::string getActiveOutgoingVideoPayload() const;
/*
......
......@@ -47,10 +47,7 @@ using std::string;
VideoRtpSession::VideoRtpSession(const string &callID, const map<string, string> &txArgs) :
sendThread_(), receiveThread_(), txArgs_(txArgs),
rxArgs_(), sending_(false), receiving_(false), callID_(callID)
{
// FIXME: bitrate must be configurable
txArgs_["bitrate"] = "500000";
}
{}
void VideoRtpSession::updateSDP(const Sdp &sdp)
{
......@@ -94,6 +91,7 @@ void VideoRtpSession::updateSDP(const Sdp &sdp)
sending_ = false;
} else {
txArgs_["codec"] = encoder;
txArgs_["bitrate"] = sdp.getActiveOutgoingVideoBitrate(codec);
}
} else {
sending_ = false;
......
......@@ -95,9 +95,8 @@ void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
#endif
// set some encoder settings here
// FIXME: don't hardcode this
// encoderCtx_->bit_rate = atoi(args_["bitrate"].c_str());
encoderCtx_->bit_rate = 400000;
encoderCtx_->bit_rate = 1000 * atoi(args_["bitrate"].c_str());
DEBUG("Using bitrate %d", encoderCtx_->bit_rate);
// resolution must be a multiple of two
if (args_["width"].empty() and inputDecoderCtx_)
......
......@@ -84,7 +84,6 @@ typedef struct {
/* The codec lists */
GQueue *acodecs;
GQueue *vcodecs;
guint _messages_number;
} account_t;
......
......@@ -859,41 +859,6 @@ sflphone_mute_call()
toggle_slider_mute_microphone();
}
#ifdef SFL_VIDEO
static void
sflphone_fill_video_codec_list_per_account(account_t *account)
{
if (!account->vcodecs)
account->vcodecs = g_queue_new();
else
g_queue_clear(account->vcodecs);
/* First add the active codecs for this account */
GQueue* system_vcodecs = get_video_codecs_list();
gchar **order = dbus_get_active_video_codec_list(account->accountID);
for (gchar **pl = order; *pl; pl++) {
codec_t *orig = codec_list_get_by_name(*pl, system_vcodecs);
codec_t *c = codec_create_new_from_caps(orig);
if (c)
g_queue_push_tail(account->vcodecs, c);
else
ERROR("Couldn't find codec %s %p", *pl, orig);
g_free(*pl);
}
g_free(order);
/* Here we add installed codecs that aren't active for the account */
guint caps_size = g_queue_get_length(system_vcodecs);
for (guint i = 0; i < caps_size; ++i) {
codec_t * vcodec = g_queue_peek_nth(system_vcodecs, i);
if (codec_list_get_by_name(vcodec->name, account->vcodecs) == NULL) {
vcodec->is_active = FALSE;
g_queue_push_tail(account->vcodecs, vcodec);
}
}
}
#endif
static void
sflphone_fill_audio_codec_list_per_account(account_t *account)
{
......@@ -931,9 +896,6 @@ sflphone_fill_audio_codec_list_per_account(account_t *account)
void sflphone_fill_codec_list_per_account(account_t *account)
{
sflphone_fill_audio_codec_list_per_account(account);
#ifdef SFL_VIDEO
sflphone_fill_video_codec_list_per_account(account);
#endif
}
void sflphone_fill_call_list(void)
......
......@@ -43,7 +43,6 @@
#include "dbus.h"
static GQueue audioCodecs = G_QUEUE_INIT;
static GQueue videoCodecs = G_QUEUE_INIT;
/*
* Instantiate a new codec
......@@ -113,60 +112,6 @@ static void codecs_audio_unload(void)
g_queue_foreach(&audioCodecs, codec_free, NULL);
}
#ifdef SFL_VIDEO
static
codec_t *
codec_create_from_hash_table(gint payload, GHashTable *details)
{
codec_t *codec = g_new0(codec_t, 1);
codec->payload = payload;
codec->name = g_strdup(g_hash_table_lookup(details, "name"));
codec->bitrate = g_strdup(g_hash_table_lookup(details, "bitrate"));
codec->is_active = TRUE;
return codec;
}
static gboolean codecs_video_load(void)
{
gchar **codecs = dbus_video_codec_list();
gchar **codecs_orig = codecs;
if (!codecs)
return FALSE;
int payload = 96; // dynamic payloads
// Add the codecs in the list
for (; codecs && *codecs; ++codecs) {
GHashTable *codec_details = dbus_video_codec_details(*codecs);
codec_t *c = codec_create_from_hash_table(payload++, codec_details);
g_queue_push_tail(&videoCodecs, c);
g_free(*codecs);
}
g_free(codecs_orig);
// If we didn't load any codecs, problem ...
return g_queue_get_length(&videoCodecs) > 0;
}
gboolean codecs_load(void)
{
return codecs_audio_load() && codecs_video_load();
}
static void codecs_video_unload(void)
{
g_queue_foreach(&videoCodecs, codec_free, NULL);
}
void codecs_unload(void)
{
codecs_audio_unload();
codecs_video_unload();
}
#else
gboolean codecs_load(void)
{
return codecs_audio_load();
......@@ -176,7 +121,6 @@ void codecs_unload(void)
{
codecs_audio_unload();
}
#endif // SFL_VIDEO
codec_t *codec_create_new_from_caps(codec_t *original)
{
......@@ -306,33 +250,12 @@ codec_list_update_to_daemon_audio(const account_t *acc)
g_slist_free_full(activeCodecs, g_free);
}
#ifdef SFL_VIDEO
static void codec_list_update_to_daemon_video(const account_t *acc)
{
GSList *activeCodecs = codec_list_get_active_codecs(acc->vcodecs, FALSE);
gchar **activeCodecsStr = get_items_from_list(activeCodecs);
// call dbus function with array of strings
dbus_set_active_video_codec_list((const gchar **) activeCodecsStr, acc->accountID);
g_free(activeCodecsStr);
g_slist_free_full(activeCodecs, g_free);
}
#endif
void codec_list_update_to_daemon(const account_t *acc)
{
codec_list_update_to_daemon_audio(acc);
#ifdef SFL_VIDEO
codec_list_update_to_daemon_video(acc);
#endif
}
GQueue* get_audio_codecs_list(void)
{
return &audioCodecs;
}
GQueue* get_video_codecs_list(void)
{
return &videoCodecs;
}
......@@ -86,8 +86,6 @@ void codec_list_update_to_daemon(const account_t *acc);
codec_t* codec_list_get_by_payload(gint payload, GQueue *q);
GQueue* get_video_codecs_list(void);
GQueue* get_audio_codecs_list(void);
/*
......
......@@ -144,28 +144,33 @@ update_preview_button_label()
static void
preferences_dialog_fill_codec_list(account_t *acc)
{
if (!acc) {
ERROR("Account is NULL");
return;
}
// Get model of view and clear it
GtkListStore *codecStore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView)));
gtk_list_store_clear(codecStore);
GQueue *list = acc ? acc->vcodecs : get_video_codecs_list();
GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
// Add the codecs in the list
for (size_t i = 0; i < list->length; i++) {
codec_t *c = g_queue_peek_nth(list, i);
for (size_t i = 0; i < vcodecs->len; ++i) {
GHashTable *c = g_ptr_array_index(vcodecs, i);
if (c) {
DEBUG("%s is %sactive", c->name, c->is_active ? "" : "not ");
GtkTreeIter iter;
gtk_list_store_append(codecStore, &iter);
gchar *bitrate = g_strdup_printf("%s", c->bitrate);
const gchar *bitrate = g_hash_table_lookup(c, "bitrate");
const gboolean is_active = !g_strcmp0(g_hash_table_lookup(c, "enabled"), "true");
const gchar *name = g_hash_table_lookup(c, "name");
gtk_list_store_set(codecStore, &iter, COLUMN_CODEC_ACTIVE,
c->is_active, COLUMN_CODEC_NAME, c->name,
is_active, COLUMN_CODEC_NAME, name,
COLUMN_CODEC_BITRATE, bitrate, -1);
g_free(bitrate);
}
}
g_ptr_array_free(vcodecs, TRUE);
}
/**
......@@ -173,6 +178,35 @@ preferences_dialog_fill_codec_list(account_t *acc)
* and in configuration files
*/
static gboolean
video_codec_has_name(GHashTable *codec, const gchar *name)
{
return g_strcmp0(g_hash_table_lookup(codec, "name"), name) == 0;
}
static void
video_codec_set_active(GHashTable *codec, gboolean active)
{
g_hash_table_replace(codec, g_strdup("enabled"), active ? g_strdup("true") : g_strdup("false"));
}
static void
video_codec_set_bitrate(GHashTable *codec, const gchar *bitrate)
{
g_hash_table_replace(codec, g_strdup("bitrate"), g_strdup(bitrate));
}
static GHashTable *
video_codec_list_get_by_name(GPtrArray *vcodecs, const gchar *name)
{
for (guint i = 0; i < vcodecs->len; ++i) {
GHashTable *codec = g_ptr_array_index(vcodecs, i);
if (video_codec_has_name(codec, name))
return codec;
}
return NULL;
}
static void
codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
gpointer data)
......@@ -198,9 +232,8 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
COLUMN_CODEC_NAME, &name, -1);
DEBUG("%s", name);
DEBUG("video codecs length %i", g_queue_get_length(acc->vcodecs));
codec_t *codec = codec_list_get_by_name((gconstpointer) name, acc->vcodecs);
GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
DEBUG("video codecs length %i", vcodecs->len);
// Toggle active value
active = !active;
......@@ -209,8 +242,11 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_CODEC_ACTIVE,
active, -1);
// Modify codec queue to represent change
codec->is_active = active;
GHashTable *codec = video_codec_list_get_by_name(vcodecs, name);
if (codec) {
video_codec_set_active(codec, active);
dbus_set_video_codecs(acc->accountID, vcodecs);
}
}
/**
......@@ -255,11 +291,13 @@ codec_move(gboolean move_up, gpointer data)
gtk_tree_iter_free(iter_cpy);
g_free(path);
#if 0
// Perpetuate changes in codec queue
if (move_up)
codec_list_move_codec_up(pos, &((account_t *) data)->vcodecs);
else
codec_list_move_codec_down(pos, &((account_t *) data)->vcodecs);
#endif
}
/**
......@@ -290,6 +328,7 @@ bitrate_edited_cb(GtkCellRenderer *renderer UNUSED, gchar *path, gchar *new_text
ERROR("No account selected");
return;
}
DEBUG("updating bitrate for %s", acc->accountID);
// Get active value and name at iteration
const gint base = 10;
gchar *endptr;
......@@ -307,11 +346,17 @@ bitrate_edited_cb(GtkCellRenderer *renderer UNUSED, gchar *path, gchar *new_text
gchar *name = NULL;
gtk_tree_model_get(model, &iter, COLUMN_CODEC_NAME, &name, -1);
DEBUG("Setting new bitrate for %s", name);
codec_t *codec = codec_list_get_by_name((gconstpointer) name, acc->vcodecs);
/* Don't free this, we want it to persist in the codec structure */
codec->bitrate = g_strdup_printf("%llu", val);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_CODEC_BITRATE, codec->bitrate, -1);
gchar *bitrate = g_strdup_printf("%llu", val);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_CODEC_BITRATE, bitrate, -1);
GPtrArray *vcodecs = dbus_get_video_codecs(name);
GHashTable *codec = video_codec_list_get_by_name(vcodecs, name);
if (codec) {
video_codec_set_bitrate(codec, bitrate);
dbus_set_video_codecs(acc->accountID, vcodecs);
}
g_ptr_array_free(vcodecs, TRUE);
}
}
......
......@@ -1229,33 +1229,22 @@ dbus_audio_codec_list()
}
#ifdef SFL_VIDEO
gchar **
dbus_video_codec_list()
{
GError *error = NULL;
gchar **array = NULL;
org_sflphone_SFLphone_VideoControls_get_codec_list(video_proxy, &array, &error);
check_error(error);
return array;
}
gchar **
dbus_get_active_video_codec_list(const gchar *accountID)
GPtrArray *
dbus_get_video_codecs(const gchar *accountID)
{
gchar **array = NULL;
GError *error = NULL;
org_sflphone_SFLphone_VideoControls_get_active_codec_list(video_proxy, accountID, &array, &error);
GPtrArray *array = NULL;
org_sflphone_SFLphone_VideoControls_get_codecs(video_proxy, accountID, &array, &error);
check_error(error);
return array;
}
void
dbus_set_active_video_codec_list(const gchar** list, const gchar *accountID)
dbus_set_video_codecs(const gchar *accountID, const GPtrArray *list)
{
GError *error = NULL;
org_sflphone_SFLphone_VideoControls_set_active_codec_list(video_proxy, list, accountID, &error);
org_sflphone_SFLphone_VideoControls_set_codecs(video_proxy, accountID, list, &error);
check_error(error);
}
#endif
......@@ -1271,16 +1260,6 @@ dbus_audio_codec_details(int payload)
}
#ifdef SFL_VIDEO
GHashTable*
dbus_video_codec_details(const gchar *codec)
{
GError *error = NULL;
GHashTable *details = NULL;
org_sflphone_SFLphone_VideoControls_get_codec_details(video_proxy,
codec, &details, &error);
check_error(error);
return details;
}
gchar *
dbus_get_current_video_codec_name(const callable_obj_t *c)
......
......@@ -194,12 +194,6 @@ void dbus_play_dtmf(const gchar *key);
*/
GArray *dbus_audio_codec_list();
/**
* ConfigurationManager - Get the video codecs list
* @return gchar** The list of video codecs
*/
gchar** dbus_video_codec_list();
/**
* ConfigurationManager - Get the audio codec details
* @param payload The payload of the audio codec
......@@ -237,13 +231,16 @@ void dbus_set_active_audio_codec_list(const gchar **list, const gchar *);
* ConfigurationManager - Get the list of the audio codecs used for media negotiation
* @return gchar** The list of audio codecs
*/
gchar **dbus_get_active_video_codec_list(const gchar *accountID);
GPtrArray *
dbus_get_video_codecs(const gchar *accountID);
/**
* ConfigurationManager - Set the list of audio codecs used for media negociation
* @param list The list of audio codecs
* @param id The accountID
* @param list The list of codecs
*/
void dbus_set_active_video_codec_list(const gchar **list, const gchar *);
void
dbus_set_video_codecs(const gchar *id, const GPtrArray *list);
/**
* CallManager - return the video codec name
......
......@@ -96,10 +96,10 @@
<method name="setCodecs" tp:name-for-bindings="setCodecs">
<tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
<arg type="aa{ss}" name="details" direction="in">
</arg>
<arg type="s" name="accountID" direction="in">
</arg>
<arg type="aa{ss}" name="details" direction="in">
</arg>
</method>
<method name="startPreview" tp:name-for-bindings="startPreview">
......
Supports Markdown
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