Opus support continued. Negotiating stuff. Working in server loopback mode.
authorMartin Johansson <martin@fatbob.nu>
Sun, 2 Dec 2012 21:29:13 +0000 (22:29 +0100)
committerMartin Johansson <martin@fatbob.nu>
Tue, 5 Feb 2013 20:30:15 +0000 (21:30 +0100)
src/client.c
src/messagehandler.c

index c3831f757fa47b42a73c6cb9d81d4471c4aedec1..3444882a839e98996a3c1e19184fc38a70b0792a 100644 (file)
@@ -57,7 +57,7 @@ void Client_free(client_t *client);
 declare_list(clients);
 static int clientcount; /* = 0 */
 static int maxBandwidth;
-static bool_t bOpus = true;
+bool_t bOpus = true;
 
 int iCodecAlpha, iCodecBeta;
 bool_t bPreferAlpha;
@@ -212,6 +212,8 @@ void recheckCodecVersions(client_t *connectingClient)
        
        while (Client_iterate(&client_itr) != NULL) {
                codec_itr = NULL;
+               if (client_itr->codec_count == 0 && !client_itr->bOpus)
+                       continue;
                while (Client_codec_iterate(client_itr, &codec_itr) != NULL) {
                        found = false;                      
                        list_iterate(itr, &codec_list) {
@@ -231,12 +233,15 @@ void recheckCodecVersions(client_t *connectingClient)
                                cd->count = 1;
                                list_add_tail(&cd->node, &codec_list);
                        }
-                       users++;
-                       if (client_itr->bOpus)
-                               opus++;
                }
+               users++;
+               if (client_itr->bOpus)
+                       opus++;
        }
-       
+
+       if (users == 0) 
+               return;
+
        enableOpus = ((opus * 100 / users) >= getIntConf(OPUS_THRESHOLD));
 
        list_iterate(itr, &codec_list) {
@@ -272,7 +277,7 @@ void recheckCodecVersions(client_t *connectingClient)
                        uint32_t *tree_id;
                        message_t *sendmsg = NULL;
 
-                       message = malloc(strlen(OPUS_WARN));
+                       message = malloc(strlen(OPUS_WARN) + 1);
                        if (!message)
                                Log_fatal("Out of memory");
                        tree_id = malloc(sizeof(uint32_t));
@@ -291,15 +296,44 @@ void recheckCodecVersions(client_t *connectingClient)
        }
        
        bOpus = enableOpus;
+       Log_info("OPUS codec is %s", bOpus ? "enabled" : "disabled");
 
        sendmsg = Msg_create(CodecVersion);
        sendmsg->payload.codecVersion->alpha = iCodecAlpha;
        sendmsg->payload.codecVersion->beta = iCodecBeta;
        sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
+       sendmsg->payload.codecVersion->has_opus = true;
+       sendmsg->payload.codecVersion->opus = bOpus;
+
        Client_send_message_except(NULL, sendmsg);
        
        Log_info("CELT codec switch 0x%x 0x%x (prefer 0x%x)", iCodecAlpha, iCodecBeta,
                         bPreferAlpha ? iCodecAlpha : iCodecBeta);
+
+       client_itr = NULL;
+       while (Client_iterate(&client_itr) != NULL) {
+               if ((client_itr->authenticated || client_itr == connectingClient) &&
+                   !client_itr->bOpus) {
+                       char *message;
+                       uint32_t *tree_id;
+                       message_t *sendmsg = NULL;
+
+                       message = malloc(strlen(OPUS_WARN) + 1);
+                       if (!message)
+                               Log_fatal("Out of memory");
+                       tree_id = malloc(sizeof(uint32_t));
+                       if (!tree_id)
+                               Log_fatal("Out of memory");
+                       *tree_id = 0;
+                       sendmsg = Msg_create(TextMessage);
+                       sendmsg->payload.textMessage->message = message;
+                       sendmsg->payload.textMessage->n_tree_id = 1;
+                       sendmsg->payload.textMessage->tree_id = tree_id;
+                       sprintf(message, OPUS_WARN);
+                       Client_send_message(client_itr, sendmsg);
+                       sendmsg = NULL;
+               }
+       }
        
 }
 
@@ -389,6 +423,7 @@ void Client_free(client_t *client)
                sendmsg = Msg_create(UserRemove);
                sendmsg->payload.userRemove->session = client->sessionId;
                Client_send_message_except(client, sendmsg);
+               recheckCodecVersions(NULL); /* Can use better codec now? */
        }
        list_iterate_safe(itr, save, &client->txMsgQueue) {
                list_del(&list_get_entry(itr, message_t, node)->node);
index 504c66b0e40b0e258ce8ff4b079f533c403ac2eb..faffea26b4204a697a928747145496ed740af39a 100644 (file)
 #define MAX_TEXT 512
 #define MAX_USERNAME 128
 
+#define NO_CELT_MESSAGE "<strong>WARNING:</strong> Your client doesn't support the CELT codec, you won't be able to talk to or hear most clients. Please make sure your client was built with CELT support."
+
+
 extern channel_t *defaultChan;
 extern int iCodecAlpha, iCodecBeta;
 extern bool_t bPreferAlpha, bOpus;
 
+static bool_t fake_celt_support;
+
 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
 {
        message_t *msg = Msg_create(Reject);
@@ -224,8 +229,9 @@ void Mh_handle_message(client_t *client, message_t *msg)
                                Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
                                
                } else {
-                       Client_codec_add(client, (int32_t)0x8000000a);
+                       Client_codec_add(client, (int32_t)0x8000000b);
                        client->codec_count = 1;
+                       fake_celt_support = true;
                }
                if (msg->payload.authenticate->opus)
                        client->bOpus = true;
@@ -236,8 +242,31 @@ void Mh_handle_message(client_t *client, message_t *msg)
                sendmsg->payload.codecVersion->alpha = iCodecAlpha;
                sendmsg->payload.codecVersion->beta = iCodecBeta;
                sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
+               sendmsg->payload.codecVersion->has_opus = true;
+               sendmsg->payload.codecVersion->opus = bOpus;
                Client_send_message(client, sendmsg);
-               
+
+               if (!bOpus && client->bOpus && fake_celt_support) {
+                       char *message;
+                       uint32_t *tree_id;
+                       message_t *sendmsg = NULL;
+
+                       message = malloc(strlen(NO_CELT_MESSAGE) + 1);
+                       if (!message)
+                               Log_fatal("Out of memory");
+                       tree_id = malloc(sizeof(uint32_t));
+                       if (!tree_id)
+                               Log_fatal("Out of memory");
+                       *tree_id = 0;
+                       sendmsg = Msg_create(TextMessage);
+                       sendmsg->payload.textMessage->message = message;
+                       sendmsg->payload.textMessage->n_tree_id = 1;
+                       sendmsg->payload.textMessage->tree_id = tree_id;
+                       sprintf(message, NO_CELT_MESSAGE);
+                       Client_send_message(client, sendmsg);
+                       sendmsg = NULL;
+               }
+
                /* Iterate channels and send channel info */
                ch_itr = NULL;
                while (Chan_iterate(&ch_itr) != NULL) {