summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/dht_test.c6
-rw-r--r--auto_tests/toxav_basic_test.c224
-rw-r--r--auto_tests/toxav_many_test.c169
-rw-r--r--testing/av_test.c487
-rw-r--r--toxav/audio.c10
-rw-r--r--toxav/bwcontroler.c62
-rw-r--r--toxav/msi.c79
-rw-r--r--toxav/rtp.c27
-rw-r--r--toxav/toxav.c57
-rw-r--r--toxav/toxav.h541
-rw-r--r--toxav/video.c23
-rw-r--r--toxav/video.h2
-rw-r--r--toxcore/util.c26
-rw-r--r--toxcore/util.h6
-rw-r--r--toxdns/toxdns.c2
15 files changed, 890 insertions, 831 deletions
diff --git a/auto_tests/dht_test.c b/auto_tests/dht_test.c
index 32985bca..8304a046 100644
--- a/auto_tests/dht_test.c
+++ b/auto_tests/dht_test.c
@@ -153,7 +153,8 @@ void test_addto_lists_bad(DHT *dht,
153{ 153{
154 // check "bad" clients replacement 154 // check "bad" clients replacement
155 int used, test1, test2, test3; 155 int used, test1, test2, test3;
156 uint8_t public_key[crypto_box_PUBLICKEYBYTES], test_id1[crypto_box_PUBLICKEYBYTES], test_id2[crypto_box_PUBLICKEYBYTES], test_id3[crypto_box_PUBLICKEYBYTES]; 156 uint8_t public_key[crypto_box_PUBLICKEYBYTES], test_id1[crypto_box_PUBLICKEYBYTES], test_id2[crypto_box_PUBLICKEYBYTES],
157 test_id3[crypto_box_PUBLICKEYBYTES];
157 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0; 158 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
158 159
159 randombytes(public_key, sizeof(public_key)); 160 randombytes(public_key, sizeof(public_key));
@@ -196,7 +197,8 @@ void test_addto_lists_possible_bad(DHT *dht,
196{ 197{
197 // check "possibly bad" clients replacement 198 // check "possibly bad" clients replacement
198 int used, test1, test2, test3; 199 int used, test1, test2, test3;
199 uint8_t public_key[crypto_box_PUBLICKEYBYTES], test_id1[crypto_box_PUBLICKEYBYTES], test_id2[crypto_box_PUBLICKEYBYTES], test_id3[crypto_box_PUBLICKEYBYTES]; 200 uint8_t public_key[crypto_box_PUBLICKEYBYTES], test_id1[crypto_box_PUBLICKEYBYTES], test_id2[crypto_box_PUBLICKEYBYTES],
201 test_id3[crypto_box_PUBLICKEYBYTES];
200 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0; 202 uint8_t ipv6 = ip_port->ip.family == AF_INET6 ? 1 : 0;
201 203
202 randombytes(public_key, sizeof(public_key)); 204 randombytes(public_key, sizeof(public_key));
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index 5821a6d4..20432dca 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -49,12 +49,12 @@
49typedef struct { 49typedef struct {
50 bool incoming; 50 bool incoming;
51 uint32_t state; 51 uint32_t state;
52 52
53} CallControl; 53} CallControl;
54 54
55 55
56/** 56/**
57 * Callbacks 57 * Callbacks
58 */ 58 */
59void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) 59void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data)
60{ 60{
@@ -62,17 +62,17 @@ void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool
62 (void) friend_number; 62 (void) friend_number;
63 (void) audio_enabled; 63 (void) audio_enabled;
64 (void) video_enabled; 64 (void) video_enabled;
65 65
66 printf("Handling CALL callback\n"); 66 printf("Handling CALL callback\n");
67 ((CallControl*)user_data)->incoming = true; 67 ((CallControl *)user_data)->incoming = true;
68} 68}
69void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) 69void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
70{ 70{
71 (void) av; 71 (void) av;
72 (void) friend_number; 72 (void) friend_number;
73 73
74 printf("Handling CALL STATE callback: %d\n", state); 74 printf("Handling CALL STATE callback: %d\n", state);
75 ((CallControl*)user_data)->state = state; 75 ((CallControl *)user_data)->state = state;
76} 76}
77void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, 77void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
78 uint16_t width, uint16_t height, 78 uint16_t width, uint16_t height,
@@ -112,7 +112,7 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
112void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) 112void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
113{ 113{
114 (void) userdata; 114 (void) userdata;
115 115
116 if (length == 7 && memcmp("gentoo", data, 7) == 0) { 116 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
117 ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); 117 ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
118 } 118 }
@@ -122,12 +122,12 @@ void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t
122/** 122/**
123 * Iterate helper 123 * Iterate helper
124 */ 124 */
125int iterate_tox(Tox* bootstrap, Tox* Alice, Tox* Bob) 125int iterate_tox(Tox *bootstrap, Tox *Alice, Tox *Bob)
126{ 126{
127 tox_iterate(bootstrap); 127 tox_iterate(bootstrap);
128 tox_iterate(Alice); 128 tox_iterate(Alice);
129 tox_iterate(Bob); 129 tox_iterate(Bob);
130 130
131 return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob)); 131 return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob));
132} 132}
133 133
@@ -135,80 +135,80 @@ int iterate_tox(Tox* bootstrap, Tox* Alice, Tox* Bob)
135 135
136START_TEST(test_AV_flows) 136START_TEST(test_AV_flows)
137{ 137{
138 Tox* Alice, *Bob, *bootstrap; 138 Tox *Alice, *Bob, *bootstrap;
139 ToxAV* AliceAV, *BobAV; 139 ToxAV *AliceAV, *BobAV;
140 140
141 CallControl AliceCC, BobCC; 141 CallControl AliceCC, BobCC;
142 142
143 { 143 {
144 TOX_ERR_NEW error; 144 TOX_ERR_NEW error;
145 145
146 bootstrap = tox_new(NULL, &error); 146 bootstrap = tox_new(NULL, &error);
147 ck_assert(error == TOX_ERR_NEW_OK); 147 ck_assert(error == TOX_ERR_NEW_OK);
148 148
149 Alice = tox_new(NULL, &error); 149 Alice = tox_new(NULL, &error);
150 ck_assert(error == TOX_ERR_NEW_OK); 150 ck_assert(error == TOX_ERR_NEW_OK);
151 151
152 Bob = tox_new(NULL, &error); 152 Bob = tox_new(NULL, &error);
153 ck_assert(error == TOX_ERR_NEW_OK); 153 ck_assert(error == TOX_ERR_NEW_OK);
154 } 154 }
155 155
156 printf("Created 3 instances of Tox\n"); 156 printf("Created 3 instances of Tox\n");
157 printf("Preparing network...\n"); 157 printf("Preparing network...\n");
158 long long unsigned int cur_time = time(NULL); 158 long long unsigned int cur_time = time(NULL);
159 159
160 uint32_t to_compare = 974536; 160 uint32_t to_compare = 974536;
161 uint8_t address[TOX_ADDRESS_SIZE]; 161 uint8_t address[TOX_ADDRESS_SIZE];
162 162
163 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare); 163 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare);
164 tox_self_get_address(Alice, address); 164 tox_self_get_address(Alice, address);
165 165
166 166
167 ck_assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); 167 ck_assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
168 168
169 uint8_t off = 1; 169 uint8_t off = 1;
170 170
171 while (1) { 171 while (1) {
172 iterate_tox(bootstrap, Alice, Bob); 172 iterate_tox(bootstrap, Alice, Bob);
173 173
174 if (tox_self_get_connection_status(bootstrap) && 174 if (tox_self_get_connection_status(bootstrap) &&
175 tox_self_get_connection_status(Alice) && 175 tox_self_get_connection_status(Alice) &&
176 tox_self_get_connection_status(Bob) && off) { 176 tox_self_get_connection_status(Bob) && off) {
177 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); 177 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
178 off = 0; 178 off = 0;
179 } 179 }
180 180
181 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP && 181 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP &&
182 tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP) 182 tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP)
183 break; 183 break;
184 184
185 c_sleep(20); 185 c_sleep(20);
186 } 186 }
187 187
188 188
189 { 189 {
190 TOXAV_ERR_NEW error; 190 TOXAV_ERR_NEW error;
191 AliceAV = toxav_new(Alice, &error); 191 AliceAV = toxav_new(Alice, &error);
192 ck_assert(error == TOXAV_ERR_NEW_OK); 192 ck_assert(error == TOXAV_ERR_NEW_OK);
193 193
194 BobAV = toxav_new(Bob, &error); 194 BobAV = toxav_new(Bob, &error);
195 ck_assert(error == TOXAV_ERR_NEW_OK); 195 ck_assert(error == TOXAV_ERR_NEW_OK);
196 } 196 }
197 197
198 toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC); 198 toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC);
199 toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC); 199 toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC);
200 toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC); 200 toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC);
201 toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC); 201 toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC);
202 202
203 toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC); 203 toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC);
204 toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC); 204 toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC);
205 toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC); 205 toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC);
206 toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC); 206 toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC);
207 207
208 printf("Created 2 instances of ToxAV\n"); 208 printf("Created 2 instances of ToxAV\n");
209 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 209 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
210 210
211 211
212#define REGULAR_CALL_FLOW(A_BR, V_BR) \ 212#define REGULAR_CALL_FLOW(A_BR, V_BR) \
213 do { \ 213 do { \
214 memset(&AliceCC, 0, sizeof(CallControl)); \ 214 memset(&AliceCC, 0, sizeof(CallControl)); \
@@ -256,117 +256,117 @@ START_TEST(test_AV_flows)
256 } \ 256 } \
257 printf("Success!\n");\ 257 printf("Success!\n");\
258 } while(0) 258 } while(0)
259 259
260 if (TEST_REGULAR_AV) { 260 if (TEST_REGULAR_AV) {
261 printf("\nTrying regular call (Audio and Video)...\n"); 261 printf("\nTrying regular call (Audio and Video)...\n");
262 REGULAR_CALL_FLOW(48, 4000); 262 REGULAR_CALL_FLOW(48, 4000);
263 } 263 }
264 264
265 if (TEST_REGULAR_A) { 265 if (TEST_REGULAR_A) {
266 printf("\nTrying regular call (Audio only)...\n"); 266 printf("\nTrying regular call (Audio only)...\n");
267 REGULAR_CALL_FLOW(48, 0); 267 REGULAR_CALL_FLOW(48, 0);
268 } 268 }
269 269
270 if (TEST_REGULAR_V) { 270 if (TEST_REGULAR_V) {
271 printf("\nTrying regular call (Video only)...\n"); 271 printf("\nTrying regular call (Video only)...\n");
272 REGULAR_CALL_FLOW(0, 4000); 272 REGULAR_CALL_FLOW(0, 4000);
273 } 273 }
274 274
275#undef REGULAR_CALL_FLOW 275#undef REGULAR_CALL_FLOW
276 276
277 if (TEST_REJECT) { /* Alice calls; Bob rejects */ 277 if (TEST_REJECT) { /* Alice calls; Bob rejects */
278 printf("\nTrying reject flow...\n"); 278 printf("\nTrying reject flow...\n");
279 279
280 memset(&AliceCC, 0, sizeof(CallControl)); 280 memset(&AliceCC, 0, sizeof(CallControl));
281 memset(&BobCC, 0, sizeof(CallControl)); 281 memset(&BobCC, 0, sizeof(CallControl));
282 282
283 { 283 {
284 TOXAV_ERR_CALL rc; 284 TOXAV_ERR_CALL rc;
285 toxav_call(AliceAV, 0, 48, 0, &rc); 285 toxav_call(AliceAV, 0, 48, 0, &rc);
286 286
287 if (rc != TOXAV_ERR_CALL_OK) { 287 if (rc != TOXAV_ERR_CALL_OK) {
288 printf("toxav_call failed: %d\n", rc); 288 printf("toxav_call failed: %d\n", rc);
289 ck_assert(0); 289 ck_assert(0);
290 } 290 }
291 } 291 }
292 292
293 while (!BobCC.incoming) 293 while (!BobCC.incoming)
294 iterate_tox(bootstrap, Alice, Bob); 294 iterate_tox(bootstrap, Alice, Bob);
295 295
296 /* Reject */ 296 /* Reject */
297 { 297 {
298 TOXAV_ERR_CALL_CONTROL rc; 298 TOXAV_ERR_CALL_CONTROL rc;
299 toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 299 toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
300 300
301 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 301 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
302 printf("toxav_call_control failed: %d\n", rc); 302 printf("toxav_call_control failed: %d\n", rc);
303 ck_assert(0); 303 ck_assert(0);
304 } 304 }
305 } 305 }
306 306
307 while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) 307 while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED)
308 iterate_tox(bootstrap, Alice, Bob); 308 iterate_tox(bootstrap, Alice, Bob);
309 309
310 printf("Success!\n"); 310 printf("Success!\n");
311 } 311 }
312 312
313 if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ 313 if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */
314 printf("\nTrying cancel (while ringing) flow...\n"); 314 printf("\nTrying cancel (while ringing) flow...\n");
315 315
316 memset(&AliceCC, 0, sizeof(CallControl)); 316 memset(&AliceCC, 0, sizeof(CallControl));
317 memset(&BobCC, 0, sizeof(CallControl)); 317 memset(&BobCC, 0, sizeof(CallControl));
318 318
319 { 319 {
320 TOXAV_ERR_CALL rc; 320 TOXAV_ERR_CALL rc;
321 toxav_call(AliceAV, 0, 48, 0, &rc); 321 toxav_call(AliceAV, 0, 48, 0, &rc);
322 322
323 if (rc != TOXAV_ERR_CALL_OK) { 323 if (rc != TOXAV_ERR_CALL_OK) {
324 printf("toxav_call failed: %d\n", rc); 324 printf("toxav_call failed: %d\n", rc);
325 ck_assert(0); 325 ck_assert(0);
326 } 326 }
327 } 327 }
328 328
329 while (!BobCC.incoming) 329 while (!BobCC.incoming)
330 iterate_tox(bootstrap, Alice, Bob); 330 iterate_tox(bootstrap, Alice, Bob);
331 331
332 /* Cancel */ 332 /* Cancel */
333 { 333 {
334 TOXAV_ERR_CALL_CONTROL rc; 334 TOXAV_ERR_CALL_CONTROL rc;
335 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 335 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
336 336
337 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 337 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
338 printf("toxav_call_control failed: %d\n", rc); 338 printf("toxav_call_control failed: %d\n", rc);
339 ck_assert(0); 339 ck_assert(0);
340 } 340 }
341 } 341 }
342 342
343 /* Alice will not receive end state */ 343 /* Alice will not receive end state */
344 while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) 344 while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED)
345 iterate_tox(bootstrap, Alice, Bob); 345 iterate_tox(bootstrap, Alice, Bob);
346 346
347 printf("Success!\n"); 347 printf("Success!\n");
348 } 348 }
349 349
350 if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ 350 if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */
351 printf("\nTrying mute functionality...\n"); 351 printf("\nTrying mute functionality...\n");
352 352
353 memset(&AliceCC, 0, sizeof(CallControl)); 353 memset(&AliceCC, 0, sizeof(CallControl));
354 memset(&BobCC, 0, sizeof(CallControl)); 354 memset(&BobCC, 0, sizeof(CallControl));
355 355
356 /* Assume sending audio and video */ 356 /* Assume sending audio and video */
357 { 357 {
358 TOXAV_ERR_CALL rc; 358 TOXAV_ERR_CALL rc;
359 toxav_call(AliceAV, 0, 48, 1000, &rc); 359 toxav_call(AliceAV, 0, 48, 1000, &rc);
360 360
361 if (rc != TOXAV_ERR_CALL_OK) { 361 if (rc != TOXAV_ERR_CALL_OK) {
362 printf("toxav_call failed: %d\n", rc); 362 printf("toxav_call failed: %d\n", rc);
363 ck_assert(0); 363 ck_assert(0);
364 } 364 }
365 } 365 }
366 366
367 while (!BobCC.incoming) 367 while (!BobCC.incoming)
368 iterate_tox(bootstrap, Alice, Bob); 368 iterate_tox(bootstrap, Alice, Bob);
369 369
370 /* At first try all stuff while in invalid state */ 370 /* At first try all stuff while in invalid state */
371 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); 371 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
372 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); 372 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
@@ -374,19 +374,19 @@ START_TEST(test_AV_flows)
374 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, NULL)); 374 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, NULL));
375 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO, NULL)); 375 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO, NULL));
376 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, NULL)); 376 ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, NULL));
377 377
378 { 378 {
379 TOXAV_ERR_ANSWER rc; 379 TOXAV_ERR_ANSWER rc;
380 toxav_answer(BobAV, 0, 48, 4000, &rc); 380 toxav_answer(BobAV, 0, 48, 4000, &rc);
381 381
382 if (rc != TOXAV_ERR_ANSWER_OK) { 382 if (rc != TOXAV_ERR_ANSWER_OK) {
383 printf("toxav_answer failed: %d\n", rc); 383 printf("toxav_answer failed: %d\n", rc);
384 ck_assert(0); 384 ck_assert(0);
385 } 385 }
386 } 386 }
387 387
388 iterate_tox(bootstrap, Alice, Bob); 388 iterate_tox(bootstrap, Alice, Bob);
389 389
390 /* Pause and Resume */ 390 /* Pause and Resume */
391 printf("Pause and Resume\n"); 391 printf("Pause and Resume\n");
392 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); 392 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
@@ -395,7 +395,7 @@ START_TEST(test_AV_flows)
395 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); 395 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
396 iterate_tox(bootstrap, Alice, Bob); 396 iterate_tox(bootstrap, Alice, Bob);
397 ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V)); 397 ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V));
398 398
399 /* Mute/Unmute single */ 399 /* Mute/Unmute single */
400 printf("Mute/Unmute single\n"); 400 printf("Mute/Unmute single\n");
401 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, NULL)); 401 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, NULL));
@@ -404,7 +404,7 @@ START_TEST(test_AV_flows)
404 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, NULL)); 404 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, NULL));
405 iterate_tox(bootstrap, Alice, Bob); 405 iterate_tox(bootstrap, Alice, Bob);
406 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); 406 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
407 407
408 /* Mute/Unmute both */ 408 /* Mute/Unmute both */
409 printf("Mute/Unmute both\n"); 409 printf("Mute/Unmute both\n");
410 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, NULL)); 410 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, NULL));
@@ -419,122 +419,122 @@ START_TEST(test_AV_flows)
419 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, NULL)); 419 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, NULL));
420 iterate_tox(bootstrap, Alice, Bob); 420 iterate_tox(bootstrap, Alice, Bob);
421 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); 421 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V);
422 422
423 { 423 {
424 TOXAV_ERR_CALL_CONTROL rc; 424 TOXAV_ERR_CALL_CONTROL rc;
425 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 425 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
426 426
427 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 427 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
428 printf("toxav_call_control failed: %d\n", rc); 428 printf("toxav_call_control failed: %d\n", rc);
429 ck_assert(0); 429 ck_assert(0);
430 } 430 }
431 } 431 }
432 432
433 iterate_tox(bootstrap, Alice, Bob); 433 iterate_tox(bootstrap, Alice, Bob);
434 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 434 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
435 435
436 printf("Success!\n"); 436 printf("Success!\n");
437 } 437 }
438 438
439 if (TEST_STOP_RESUME_PAYLOAD) { /* Stop and resume audio/video payload */ 439 if (TEST_STOP_RESUME_PAYLOAD) { /* Stop and resume audio/video payload */
440 printf("\nTrying stop/resume functionality...\n"); 440 printf("\nTrying stop/resume functionality...\n");
441 441
442 memset(&AliceCC, 0, sizeof(CallControl)); 442 memset(&AliceCC, 0, sizeof(CallControl));
443 memset(&BobCC, 0, sizeof(CallControl)); 443 memset(&BobCC, 0, sizeof(CallControl));
444 444
445 /* Assume sending audio and video */ 445 /* Assume sending audio and video */
446 { 446 {
447 TOXAV_ERR_CALL rc; 447 TOXAV_ERR_CALL rc;
448 toxav_call(AliceAV, 0, 48, 0, &rc); 448 toxav_call(AliceAV, 0, 48, 0, &rc);
449 449
450 if (rc != TOXAV_ERR_CALL_OK) { 450 if (rc != TOXAV_ERR_CALL_OK) {
451 printf("toxav_call failed: %d\n", rc); 451 printf("toxav_call failed: %d\n", rc);
452 ck_assert(0); 452 ck_assert(0);
453 } 453 }
454 } 454 }
455 455
456 while (!BobCC.incoming) 456 while (!BobCC.incoming)
457 iterate_tox(bootstrap, Alice, Bob); 457 iterate_tox(bootstrap, Alice, Bob);
458 458
459 { 459 {
460 TOXAV_ERR_ANSWER rc; 460 TOXAV_ERR_ANSWER rc;
461 toxav_answer(BobAV, 0, 48, 0, &rc); 461 toxav_answer(BobAV, 0, 48, 0, &rc);
462 462
463 if (rc != TOXAV_ERR_ANSWER_OK) { 463 if (rc != TOXAV_ERR_ANSWER_OK) {
464 printf("toxav_answer failed: %d\n", rc); 464 printf("toxav_answer failed: %d\n", rc);
465 ck_assert(0); 465 ck_assert(0);
466 } 466 }
467 } 467 }
468 468
469 iterate_tox(bootstrap, Alice, Bob); 469 iterate_tox(bootstrap, Alice, Bob);
470 470
471 printf("Call started as audio only\n"); 471 printf("Call started as audio only\n");
472 printf("Turning on video for Alice...\n"); 472 printf("Turning on video for Alice...\n");
473 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 1000, NULL)); 473 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 1000, NULL));
474 474
475 iterate_tox(bootstrap, Alice, Bob); 475 iterate_tox(bootstrap, Alice, Bob);
476 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V); 476 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V);
477 477
478 printf("Turning off video for Alice...\n"); 478 printf("Turning off video for Alice...\n");
479 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 0, NULL)); 479 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 0, NULL));
480 480
481 iterate_tox(bootstrap, Alice, Bob); 481 iterate_tox(bootstrap, Alice, Bob);
482 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V)); 482 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V));
483 483
484 printf("Turning off audio for Alice...\n"); 484 printf("Turning off audio for Alice...\n");
485 ck_assert(toxav_bit_rate_set(AliceAV, 0, 0, -1, NULL)); 485 ck_assert(toxav_bit_rate_set(AliceAV, 0, 0, -1, NULL));
486 486
487 iterate_tox(bootstrap, Alice, Bob); 487 iterate_tox(bootstrap, Alice, Bob);
488 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A)); 488 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A));
489 489
490 { 490 {
491 TOXAV_ERR_CALL_CONTROL rc; 491 TOXAV_ERR_CALL_CONTROL rc;
492 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 492 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
493 493
494 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 494 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
495 printf("toxav_call_control failed: %d\n", rc); 495 printf("toxav_call_control failed: %d\n", rc);
496 ck_assert(0); 496 ck_assert(0);
497 } 497 }
498 } 498 }
499 499
500 iterate_tox(bootstrap, Alice, Bob); 500 iterate_tox(bootstrap, Alice, Bob);
501 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 501 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
502 502
503 printf("Success!\n"); 503 printf("Success!\n");
504 } 504 }
505 505
506 if (TEST_PAUSE_RESUME_SEND) { /* Stop and resume audio/video payload and test send options */ 506 if (TEST_PAUSE_RESUME_SEND) { /* Stop and resume audio/video payload and test send options */
507 printf("\nTrying stop/resume functionality...\n"); 507 printf("\nTrying stop/resume functionality...\n");
508 508
509 memset(&AliceCC, 0, sizeof(CallControl)); 509 memset(&AliceCC, 0, sizeof(CallControl));
510 memset(&BobCC, 0, sizeof(CallControl)); 510 memset(&BobCC, 0, sizeof(CallControl));
511 511
512 /* Assume sending audio and video */ 512 /* Assume sending audio and video */
513 { 513 {
514 TOXAV_ERR_CALL rc; 514 TOXAV_ERR_CALL rc;
515 toxav_call(AliceAV, 0, 48, 0, &rc); 515 toxav_call(AliceAV, 0, 48, 0, &rc);
516 516
517 if (rc != TOXAV_ERR_CALL_OK) { 517 if (rc != TOXAV_ERR_CALL_OK) {
518 printf("toxav_call failed: %d\n", rc); 518 printf("toxav_call failed: %d\n", rc);
519 ck_assert(0); 519 ck_assert(0);
520 } 520 }
521 } 521 }
522 522
523 while (!BobCC.incoming) 523 while (!BobCC.incoming)
524 iterate_tox(bootstrap, Alice, Bob); 524 iterate_tox(bootstrap, Alice, Bob);
525 525
526 { 526 {
527 TOXAV_ERR_ANSWER rc; 527 TOXAV_ERR_ANSWER rc;
528 toxav_answer(BobAV, 0, 48, 0, &rc); 528 toxav_answer(BobAV, 0, 48, 0, &rc);
529 529
530 if (rc != TOXAV_ERR_ANSWER_OK) { 530 if (rc != TOXAV_ERR_ANSWER_OK) {
531 printf("toxav_answer failed: %d\n", rc); 531 printf("toxav_answer failed: %d\n", rc);
532 ck_assert(0); 532 ck_assert(0);
533 } 533 }
534 } 534 }
535 535
536 int16_t PCM[5670]; 536 int16_t PCM[5670];
537 537
538 iterate_tox(bootstrap, Alice, Bob); 538 iterate_tox(bootstrap, Alice, Bob);
539 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); 539 ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
540 iterate_tox(bootstrap, Alice, Bob); 540 iterate_tox(bootstrap, Alice, Bob);
@@ -545,29 +545,29 @@ START_TEST(test_AV_flows)
545 ck_assert(toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL)); 545 ck_assert(toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL));
546 ck_assert(toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL)); 546 ck_assert(toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL));
547 iterate_tox(bootstrap, Alice, Bob); 547 iterate_tox(bootstrap, Alice, Bob);
548 548
549 { 549 {
550 TOXAV_ERR_CALL_CONTROL rc; 550 TOXAV_ERR_CALL_CONTROL rc;
551 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 551 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
552 552
553 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 553 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
554 printf("toxav_call_control failed: %d\n", rc); 554 printf("toxav_call_control failed: %d\n", rc);
555 ck_assert(0); 555 ck_assert(0);
556 } 556 }
557 } 557 }
558 558
559 iterate_tox(bootstrap, Alice, Bob); 559 iterate_tox(bootstrap, Alice, Bob);
560 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 560 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
561 561
562 printf("Success!\n"); 562 printf("Success!\n");
563 } 563 }
564 564
565 toxav_kill(BobAV); 565 toxav_kill(BobAV);
566 toxav_kill(AliceAV); 566 toxav_kill(AliceAV);
567 tox_kill(Bob); 567 tox_kill(Bob);
568 tox_kill(Alice); 568 tox_kill(Alice);
569 tox_kill(bootstrap); 569 tox_kill(bootstrap);
570 570
571 printf("\nTest successful!\n"); 571 printf("\nTest successful!\n");
572} 572}
573END_TEST 573END_TEST
@@ -577,7 +577,7 @@ int main(int argc, char *argv[])
577{ 577{
578 (void) argc; 578 (void) argc;
579 (void) argv; 579 (void) argv;
580 580
581 test_AV_flows(); 581 test_AV_flows();
582 return 0; 582 return 0;
583} 583}
@@ -593,7 +593,7 @@ int main(int argc, char *argv[])
593{ 593{
594 (void) argc; 594 (void) argc;
595 (void) argv; 595 (void) argv;
596 596
597 Suite *tox = tox_suite(); 597 Suite *tox = tox_suite();
598 SRunner *test_runner = srunner_create(tox); 598 SRunner *test_runner = srunner_create(tox);
599 599
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index 9819b694..ab496024 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -42,29 +42,29 @@ typedef struct {
42} CallControl; 42} CallControl;
43 43
44typedef struct { 44typedef struct {
45 ToxAV* AliceAV; 45 ToxAV *AliceAV;
46 ToxAV* BobAV; 46 ToxAV *BobAV;
47 CallControl* AliceCC; 47 CallControl *AliceCC;
48 CallControl* BobCC; 48 CallControl *BobCC;
49 uint32_t friend_number; 49 uint32_t friend_number;
50} thread_data; 50} thread_data;
51 51
52/** 52/**
53 * Callbacks 53 * Callbacks
54 */ 54 */
55void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) 55void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data)
56{ 56{
57 (void) av; 57 (void) av;
58 (void) audio_enabled; 58 (void) audio_enabled;
59 (void) video_enabled; 59 (void) video_enabled;
60 60
61 printf("Handling CALL callback\n"); 61 printf("Handling CALL callback\n");
62 ((CallControl*)user_data)[friend_number].incoming = true; 62 ((CallControl *)user_data)[friend_number].incoming = true;
63} 63}
64void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) 64void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
65{ 65{
66 printf("Handling CALL STATE callback: %d %p\n", state, av); 66 printf("Handling CALL STATE callback: %d %p\n", state, av);
67 ((CallControl*)user_data)[friend_number].state = state; 67 ((CallControl *)user_data)[friend_number].state = state;
68} 68}
69void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, 69void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
70 uint16_t width, uint16_t height, 70 uint16_t width, uint16_t height,
@@ -102,6 +102,7 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
102void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) 102void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
103{ 103{
104 (void) userdata; 104 (void) userdata;
105
105 if (length == 7 && memcmp("gentoo", data, 7) == 0) { 106 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
106 ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); 107 ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
107 } 108 }
@@ -111,92 +112,93 @@ void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t
111/** 112/**
112 * Iterate helper 113 * Iterate helper
113 */ 114 */
114ToxAV* setup_av_instance(Tox* tox, CallControl *CC) 115ToxAV *setup_av_instance(Tox *tox, CallControl *CC)
115{ 116{
116 TOXAV_ERR_NEW error; 117 TOXAV_ERR_NEW error;
117 118
118 ToxAV* av = toxav_new(tox, &error); 119 ToxAV *av = toxav_new(tox, &error);
119 ck_assert(error == TOXAV_ERR_NEW_OK); 120 ck_assert(error == TOXAV_ERR_NEW_OK);
120 121
121 toxav_callback_call(av, t_toxav_call_cb, CC); 122 toxav_callback_call(av, t_toxav_call_cb, CC);
122 toxav_callback_call_state(av, t_toxav_call_state_cb, CC); 123 toxav_callback_call_state(av, t_toxav_call_state_cb, CC);
123 toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb, CC); 124 toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb, CC);
124 toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, CC); 125 toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, CC);
125 126
126 return av; 127 return av;
127} 128}
128void* call_thread(void* pd) 129void *call_thread(void *pd)
129{ 130{
130 ToxAV* AliceAV = ((thread_data*) pd)->AliceAV; 131 ToxAV *AliceAV = ((thread_data *) pd)->AliceAV;
131 ToxAV* BobAV = ((thread_data*) pd)->BobAV; 132 ToxAV *BobAV = ((thread_data *) pd)->BobAV;
132 CallControl* AliceCC = ((thread_data*) pd)->AliceCC; 133 CallControl *AliceCC = ((thread_data *) pd)->AliceCC;
133 CallControl* BobCC = ((thread_data*) pd)->BobCC; 134 CallControl *BobCC = ((thread_data *) pd)->BobCC;
134 uint32_t friend_number = ((thread_data*) pd)->friend_number; 135 uint32_t friend_number = ((thread_data *) pd)->friend_number;
135 136
136 137
137 memset(AliceCC, 0, sizeof(CallControl)); 138 memset(AliceCC, 0, sizeof(CallControl));
138 memset(BobCC, 0, sizeof(CallControl)); 139 memset(BobCC, 0, sizeof(CallControl));
139 140
140 { /* Call */ 141 { /* Call */
141 TOXAV_ERR_CALL rc; 142 TOXAV_ERR_CALL rc;
142 toxav_call(AliceAV, friend_number, 48, 3000, &rc); 143 toxav_call(AliceAV, friend_number, 48, 3000, &rc);
143 144
144 if (rc != TOXAV_ERR_CALL_OK) { 145 if (rc != TOXAV_ERR_CALL_OK) {
145 printf("toxav_call failed: %d\n", rc); 146 printf("toxav_call failed: %d\n", rc);
146 ck_assert(0); 147 ck_assert(0);
147 } 148 }
148 } 149 }
149 150
150 while (!BobCC->incoming) 151 while (!BobCC->incoming)
151 c_sleep(10); 152 c_sleep(10);
152 153
153 { /* Answer */ 154 { /* Answer */
154 TOXAV_ERR_ANSWER rc; 155 TOXAV_ERR_ANSWER rc;
155 toxav_answer(BobAV, 0, 8, 500, &rc); 156 toxav_answer(BobAV, 0, 8, 500, &rc);
156 157
157 if (rc != TOXAV_ERR_ANSWER_OK) { 158 if (rc != TOXAV_ERR_ANSWER_OK) {
158 printf("toxav_answer failed: %d\n", rc); 159 printf("toxav_answer failed: %d\n", rc);
159 ck_assert(0); 160 ck_assert(0);
160 } 161 }
161 } 162 }
162 163
163 c_sleep(30); 164 c_sleep(30);
164 165
165 int16_t PCM[960]; 166 int16_t PCM[960];
166 uint8_t video_y[800*600]; 167 uint8_t video_y[800 * 600];
167 uint8_t video_u[800*600 / 2]; 168 uint8_t video_u[800 * 600 / 2];
168 uint8_t video_v[800*600 / 2]; 169 uint8_t video_v[800 * 600 / 2];
169 170
170 memset(PCM, 0, sizeof(PCM)); 171 memset(PCM, 0, sizeof(PCM));
171 memset(video_y, 0, sizeof(video_y)); 172 memset(video_y, 0, sizeof(video_y));
172 memset(video_u, 0, sizeof(video_u)); 173 memset(video_u, 0, sizeof(video_u));
173 memset(video_v, 0, sizeof(video_v)); 174 memset(video_v, 0, sizeof(video_v));
174 175
175 time_t start_time = time(NULL); 176 time_t start_time = time(NULL);
176 while(time(NULL) - start_time < 4) { 177
178 while (time(NULL) - start_time < 4) {
177 toxav_iterate(AliceAV); 179 toxav_iterate(AliceAV);
178 toxav_iterate(BobAV); 180 toxav_iterate(BobAV);
179 181
180 toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, NULL); 182 toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, NULL);
181 toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL); 183 toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL);
182 184
183 toxav_video_send_frame(AliceAV, friend_number, 800, 600, video_y, video_u, video_v, NULL); 185 toxav_video_send_frame(AliceAV, friend_number, 800, 600, video_y, video_u, video_v, NULL);
184 toxav_video_send_frame(BobAV, 0, 800, 600, video_y, video_u, video_v, NULL); 186 toxav_video_send_frame(BobAV, 0, 800, 600, video_y, video_u, video_v, NULL);
185 187
186 c_sleep(10); 188 c_sleep(10);
187 } 189 }
188 190
189 { /* Hangup */ 191 { /* Hangup */
190 TOXAV_ERR_CALL_CONTROL rc; 192 TOXAV_ERR_CALL_CONTROL rc;
191 toxav_call_control(AliceAV, friend_number, TOXAV_CALL_CONTROL_CANCEL, &rc); 193 toxav_call_control(AliceAV, friend_number, TOXAV_CALL_CONTROL_CANCEL, &rc);
192 194
193 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 195 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
194 printf("toxav_call_control failed: %d %p %p\n", rc, AliceAV, BobAV); 196 printf("toxav_call_control failed: %d %p %p\n", rc, AliceAV, BobAV);
195 } 197 }
196 } 198 }
197 199
198 c_sleep(30); 200 c_sleep(30);
199 201
200 printf ("Closing thread\n"); 202 printf ("Closing thread\n");
201 pthread_exit(NULL); 203 pthread_exit(NULL);
202} 204}
@@ -204,111 +206,112 @@ void* call_thread(void* pd)
204 206
205START_TEST(test_AV_three_calls) 207START_TEST(test_AV_three_calls)
206{ 208{
207 Tox* Alice, *bootstrap, *Bobs[3]; 209 Tox *Alice, *bootstrap, *Bobs[3];
208 ToxAV* AliceAV, *BobsAV[3]; 210 ToxAV *AliceAV, *BobsAV[3];
209 211
210 CallControl AliceCC[3], BobsCC[3]; 212 CallControl AliceCC[3], BobsCC[3];
211 213
212 { 214 {
213 TOX_ERR_NEW error; 215 TOX_ERR_NEW error;
214 216
215 bootstrap = tox_new(NULL, &error); 217 bootstrap = tox_new(NULL, &error);
216 ck_assert(error == TOX_ERR_NEW_OK); 218 ck_assert(error == TOX_ERR_NEW_OK);
217 219
218 Alice = tox_new(NULL, &error); 220 Alice = tox_new(NULL, &error);
219 ck_assert(error == TOX_ERR_NEW_OK); 221 ck_assert(error == TOX_ERR_NEW_OK);
220 222
221 Bobs[0] = tox_new(NULL, &error); 223 Bobs[0] = tox_new(NULL, &error);
222 ck_assert(error == TOX_ERR_NEW_OK); 224 ck_assert(error == TOX_ERR_NEW_OK);
223 225
224 Bobs[1] = tox_new(NULL, &error); 226 Bobs[1] = tox_new(NULL, &error);
225 ck_assert(error == TOX_ERR_NEW_OK); 227 ck_assert(error == TOX_ERR_NEW_OK);
226 228
227 Bobs[2] = tox_new(NULL, &error); 229 Bobs[2] = tox_new(NULL, &error);
228 ck_assert(error == TOX_ERR_NEW_OK); 230 ck_assert(error == TOX_ERR_NEW_OK);
229 } 231 }
230 232
231 printf("Created 5 instances of Tox\n"); 233 printf("Created 5 instances of Tox\n");
232 printf("Preparing network...\n"); 234 printf("Preparing network...\n");
233 long long unsigned int cur_time = time(NULL); 235 long long unsigned int cur_time = time(NULL);
234 236
235 uint32_t to_compare = 974536; 237 uint32_t to_compare = 974536;
236 uint8_t address[TOX_ADDRESS_SIZE]; 238 uint8_t address[TOX_ADDRESS_SIZE];
237 239
238 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare); 240 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare);
239 tox_self_get_address(Alice, address); 241 tox_self_get_address(Alice, address);
240 242
241 243
242 ck_assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); 244 ck_assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
243 ck_assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); 245 ck_assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
244 ck_assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); 246 ck_assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
245 247
246 uint8_t off = 1; 248 uint8_t off = 1;
247 249
248 while (1) { 250 while (1) {
249 tox_iterate(bootstrap); 251 tox_iterate(bootstrap);
250 tox_iterate(Alice); 252 tox_iterate(Alice);
251 tox_iterate(Bobs[0]); 253 tox_iterate(Bobs[0]);
252 tox_iterate(Bobs[1]); 254 tox_iterate(Bobs[1]);
253 tox_iterate(Bobs[2]); 255 tox_iterate(Bobs[2]);
254 256
255 if (tox_self_get_connection_status(bootstrap) && 257 if (tox_self_get_connection_status(bootstrap) &&
256 tox_self_get_connection_status(Alice) && 258 tox_self_get_connection_status(Alice) &&
257 tox_self_get_connection_status(Bobs[0]) && 259 tox_self_get_connection_status(Bobs[0]) &&
258 tox_self_get_connection_status(Bobs[1]) && 260 tox_self_get_connection_status(Bobs[1]) &&
259 tox_self_get_connection_status(Bobs[2]) && off) { 261 tox_self_get_connection_status(Bobs[2]) && off) {
260 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); 262 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
261 off = 0; 263 off = 0;
262 } 264 }
263 265
264 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP && 266 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP &&
265 tox_friend_get_connection_status(Alice, 1, NULL) == TOX_CONNECTION_UDP && 267 tox_friend_get_connection_status(Alice, 1, NULL) == TOX_CONNECTION_UDP &&
266 tox_friend_get_connection_status(Alice, 2, NULL) == TOX_CONNECTION_UDP && 268 tox_friend_get_connection_status(Alice, 2, NULL) == TOX_CONNECTION_UDP &&
267 tox_friend_get_connection_status(Bobs[0], 0, NULL) == TOX_CONNECTION_UDP && 269 tox_friend_get_connection_status(Bobs[0], 0, NULL) == TOX_CONNECTION_UDP &&
268 tox_friend_get_connection_status(Bobs[1], 0, NULL) == TOX_CONNECTION_UDP && 270 tox_friend_get_connection_status(Bobs[1], 0, NULL) == TOX_CONNECTION_UDP &&
269 tox_friend_get_connection_status(Bobs[2], 0, NULL) == TOX_CONNECTION_UDP) 271 tox_friend_get_connection_status(Bobs[2], 0, NULL) == TOX_CONNECTION_UDP)
270 break; 272 break;
271 273
272 c_sleep(20); 274 c_sleep(20);
273 } 275 }
274 276
275 AliceAV = setup_av_instance(Alice, AliceCC); 277 AliceAV = setup_av_instance(Alice, AliceCC);
276 BobsAV[0] = setup_av_instance(Bobs[0], BobsCC + 0); 278 BobsAV[0] = setup_av_instance(Bobs[0], BobsCC + 0);
277 BobsAV[1] = setup_av_instance(Bobs[1], BobsCC + 1); 279 BobsAV[1] = setup_av_instance(Bobs[1], BobsCC + 1);
278 BobsAV[2] = setup_av_instance(Bobs[2], BobsCC + 2); 280 BobsAV[2] = setup_av_instance(Bobs[2], BobsCC + 2);
279 281
280 printf("Created 4 instances of ToxAV\n"); 282 printf("Created 4 instances of ToxAV\n");
281 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 283 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
282 284
283 thread_data tds[3]; 285 thread_data tds[3];
284 tds[0].AliceAV = AliceAV; 286 tds[0].AliceAV = AliceAV;
285 tds[0].BobAV = BobsAV[0]; 287 tds[0].BobAV = BobsAV[0];
286 tds[0].AliceCC = AliceCC + 0; 288 tds[0].AliceCC = AliceCC + 0;
287 tds[0].BobCC = BobsCC + 0; 289 tds[0].BobCC = BobsCC + 0;
288 tds[0].friend_number = 0; 290 tds[0].friend_number = 0;
289 291
290 tds[1].AliceAV = AliceAV; 292 tds[1].AliceAV = AliceAV;
291 tds[1].BobAV = BobsAV[1]; 293 tds[1].BobAV = BobsAV[1];
292 tds[1].AliceCC = AliceCC + 1; 294 tds[1].AliceCC = AliceCC + 1;
293 tds[1].BobCC = BobsCC + 1; 295 tds[1].BobCC = BobsCC + 1;
294 tds[1].friend_number = 1; 296 tds[1].friend_number = 1;
295 297
296 tds[2].AliceAV = AliceAV; 298 tds[2].AliceAV = AliceAV;
297 tds[2].BobAV = BobsAV[2]; 299 tds[2].BobAV = BobsAV[2];
298 tds[2].AliceCC = AliceCC + 2; 300 tds[2].AliceCC = AliceCC + 2;
299 tds[2].BobCC = BobsCC + 2; 301 tds[2].BobCC = BobsCC + 2;
300 tds[2].friend_number = 2; 302 tds[2].friend_number = 2;
301 303
302 pthread_t tids[3]; 304 pthread_t tids[3];
303 (void) pthread_create(tids + 0, NULL, call_thread, tds + 0); 305 (void) pthread_create(tids + 0, NULL, call_thread, tds + 0);
304 (void) pthread_create(tids + 1, NULL, call_thread, tds + 1); 306 (void) pthread_create(tids + 1, NULL, call_thread, tds + 1);
305 (void) pthread_create(tids + 2, NULL, call_thread, tds + 2); 307 (void) pthread_create(tids + 2, NULL, call_thread, tds + 2);
306 308
307 (void) pthread_detach(tids[0]); 309 (void) pthread_detach(tids[0]);
308 (void) pthread_detach(tids[1]); 310 (void) pthread_detach(tids[1]);
309 (void) pthread_detach(tids[2]); 311 (void) pthread_detach(tids[2]);
310 312
311 time_t start_time = time(NULL); 313 time_t start_time = time(NULL);
314
312 while (time(NULL) - start_time < 5) { 315 while (time(NULL) - start_time < 5) {
313 tox_iterate(Alice); 316 tox_iterate(Alice);
314 tox_iterate(Bobs[0]); 317 tox_iterate(Bobs[0]);
@@ -316,11 +319,11 @@ START_TEST(test_AV_three_calls)
316 tox_iterate(Bobs[2]); 319 tox_iterate(Bobs[2]);
317 c_sleep(20); 320 c_sleep(20);
318 } 321 }
319 322
320 (void) pthread_join(tids[0], NULL); 323 (void) pthread_join(tids[0], NULL);
321 (void) pthread_join(tids[1], NULL); 324 (void) pthread_join(tids[1], NULL);
322 (void) pthread_join(tids[2], NULL); 325 (void) pthread_join(tids[2], NULL);
323 326
324 printf ("Killing all instances\n"); 327 printf ("Killing all instances\n");
325 toxav_kill(BobsAV[0]); 328 toxav_kill(BobsAV[0]);
326 toxav_kill(BobsAV[1]); 329 toxav_kill(BobsAV[1]);
@@ -331,7 +334,7 @@ START_TEST(test_AV_three_calls)
331 tox_kill(Bobs[2]); 334 tox_kill(Bobs[2]);
332 tox_kill(Alice); 335 tox_kill(Alice);
333 tox_kill(bootstrap); 336 tox_kill(bootstrap);
334 337
335 printf("\nTest successful!\n"); 338 printf("\nTest successful!\n");
336} 339}
337END_TEST 340END_TEST
@@ -342,7 +345,7 @@ int main(int argc, char *argv[])
342{ 345{
343 (void) argc; 346 (void) argc;
344 (void) argv; 347 (void) argv;
345 348
346 test_AV_three_calls(); 349 test_AV_three_calls();
347 return 0; 350 return 0;
348} 351}
@@ -363,7 +366,7 @@ int main(int argc, char *argv[])
363{ 366{
364 (void) argc; 367 (void) argc;
365 (void) argv; 368 (void) argv;
366 369
367 Suite *tox = tox_suite(); 370 Suite *tox = tox_suite();
368 SRunner *test_runner = srunner_create(tox); 371 SRunner *test_runner = srunner_create(tox);
369 372
diff --git a/testing/av_test.c b/testing/av_test.c
index fa6a831f..4b2fe61d 100644
--- a/testing/av_test.c
+++ b/testing/av_test.c
@@ -16,8 +16,8 @@
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * Compile with (Linux only; in newly created directory toxcore/dir_name): 20 * Compile with (Linux only; in newly created directory toxcore/dir_name):
21 * gcc -o av_test ../toxav/av_test.c ../build/.libs/libtox*.a -lopencv_core \ 21 * gcc -o av_test ../toxav/av_test.c ../build/.libs/libtox*.a -lopencv_core \
22 * -lopencv_highgui -lopencv_imgproc -lsndfile -pthread -lvpx -lopus -lsodium -lportaudio 22 * -lopencv_highgui -lopencv_imgproc -lsndfile -pthread -lvpx -lopus -lsodium -lportaudio
23 */ 23 */
@@ -75,35 +75,36 @@ typedef struct {
75 bool incoming; 75 bool incoming;
76 uint32_t state; 76 uint32_t state;
77 pthread_mutex_t arb_mutex[1]; 77 pthread_mutex_t arb_mutex[1];
78 RingBuffer* arb; /* Audio ring buffer */ 78 RingBuffer *arb; /* Audio ring buffer */
79 79
80} CallControl; 80} CallControl;
81 81
82struct toxav_thread_data { 82struct toxav_thread_data {
83 ToxAV* AliceAV; 83 ToxAV *AliceAV;
84 ToxAV* BobAV; 84 ToxAV *BobAV;
85 int32_t sig; 85 int32_t sig;
86}; 86};
87 87
88const char* vdout = "AV Test"; /* Video output */ 88const char *vdout = "AV Test"; /* Video output */
89PaStream* adout = NULL; /* Audio output */ 89PaStream *adout = NULL; /* Audio output */
90 90
91typedef struct { 91typedef struct {
92 uint16_t size; 92 uint16_t size;
93 int16_t data[]; 93 int16_t data[];
94} frame; 94} frame;
95 95
96void* pa_write_thread (void* d) 96void *pa_write_thread (void *d)
97{ 97{
98 /* The purpose of this thread is to make sure Pa_WriteStream will not block 98 /* The purpose of this thread is to make sure Pa_WriteStream will not block
99 * toxav_iterate thread 99 * toxav_iterate thread
100 */ 100 */
101 CallControl* cc = d; 101 CallControl *cc = d;
102 102
103 while (Pa_IsStreamActive(adout)) { 103 while (Pa_IsStreamActive(adout)) {
104 frame* f; 104 frame *f;
105 pthread_mutex_lock(cc->arb_mutex); 105 pthread_mutex_lock(cc->arb_mutex);
106 if (rb_read(cc->arb, (void**)&f)) { 106
107 if (rb_read(cc->arb, (void **)&f)) {
107 pthread_mutex_unlock(cc->arb_mutex); 108 pthread_mutex_unlock(cc->arb_mutex);
108 Pa_WriteStream(adout, f->data, f->size); 109 Pa_WriteStream(adout, f->data, f->size);
109 free(f); 110 free(f);
@@ -115,17 +116,17 @@ void* pa_write_thread (void* d)
115} 116}
116 117
117/** 118/**
118 * Callbacks 119 * Callbacks
119 */ 120 */
120void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) 121void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data)
121{ 122{
122 printf("Handling CALL callback\n"); 123 printf("Handling CALL callback\n");
123 ((CallControl*)user_data)->incoming = true; 124 ((CallControl *)user_data)->incoming = true;
124} 125}
125void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) 126void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
126{ 127{
127 printf("Handling CALL STATE callback: %d\n", state); 128 printf("Handling CALL STATE callback: %d\n", state);
128 ((CallControl*)user_data)->state = state; 129 ((CallControl *)user_data)->state = state;
129} 130}
130void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, 131void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
131 uint16_t width, uint16_t height, 132 uint16_t width, uint16_t height,
@@ -136,30 +137,31 @@ void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
136 ystride = abs(ystride); 137 ystride = abs(ystride);
137 ustride = abs(ustride); 138 ustride = abs(ustride);
138 vstride = abs(vstride); 139 vstride = abs(vstride);
139 140
140 uint16_t *img_data = malloc(height * width * 6); 141 uint16_t *img_data = malloc(height * width * 6);
141 142
142 unsigned long int i, j; 143 unsigned long int i, j;
144
143 for (i = 0; i < height; ++i) { 145 for (i = 0; i < height; ++i) {
144 for (j = 0; j < width; ++j) { 146 for (j = 0; j < width; ++j) {
145 uint8_t *point = (uint8_t*) img_data + 3 * ((i * width) + j); 147 uint8_t *point = (uint8_t *) img_data + 3 * ((i * width) + j);
146 int yx = y[(i * ystride) + j]; 148 int yx = y[(i * ystride) + j];
147 int ux = u[((i / 2) * ustride) + (j / 2)]; 149 int ux = u[((i / 2) * ustride) + (j / 2)];
148 int vx = v[((i / 2) * vstride) + (j / 2)]; 150 int vx = v[((i / 2) * vstride) + (j / 2)];
149 151
150 point[0] = YUV2R(yx, ux, vx); 152 point[0] = YUV2R(yx, ux, vx);
151 point[1] = YUV2G(yx, ux, vx); 153 point[1] = YUV2G(yx, ux, vx);
152 point[2] = YUV2B(yx, ux, vx); 154 point[2] = YUV2B(yx, ux, vx);
153 } 155 }
154 } 156 }
155 157
156 158
157 CvMat mat = cvMat(height, width, CV_8UC3, img_data); 159 CvMat mat = cvMat(height, width, CV_8UC3, img_data);
158 160
159 CvSize sz = {.height = height, .width = width}; 161 CvSize sz = {.height = height, .width = width};
160 162
161 IplImage* header = cvCreateImageHeader(sz, 1, 3); 163 IplImage *header = cvCreateImageHeader(sz, 1, 3);
162 IplImage* img = cvGetImage(&mat, header); 164 IplImage *img = cvGetImage(&mat, header);
163 cvShowImage(vdout, img); 165 cvShowImage(vdout, img);
164 free(img_data); 166 free(img_data);
165} 167}
@@ -170,16 +172,16 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
170 uint32_t sampling_rate, 172 uint32_t sampling_rate,
171 void *user_data) 173 void *user_data)
172{ 174{
173 CallControl* cc = user_data; 175 CallControl *cc = user_data;
174 frame* f = malloc(sizeof(uint16_t) + sample_count * sizeof(int16_t) * channels); 176 frame *f = malloc(sizeof(uint16_t) + sample_count * sizeof(int16_t) * channels);
175 memcpy(f->data, pcm, sample_count * sizeof(int16_t) * channels); 177 memcpy(f->data, pcm, sample_count * sizeof(int16_t) * channels);
176 f->size = sample_count; 178 f->size = sample_count;
177 179
178 pthread_mutex_lock(cc->arb_mutex); 180 pthread_mutex_lock(cc->arb_mutex);
179 free(rb_write(cc->arb, f)); 181 free(rb_write(cc->arb, f));
180 pthread_mutex_unlock(cc->arb_mutex); 182 pthread_mutex_unlock(cc->arb_mutex);
181} 183}
182void t_toxav_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, 184void t_toxav_bit_rate_status_cb(ToxAV *av, uint32_t friend_number,
183 uint32_t audio_bit_rate, uint32_t video_bit_rate, 185 uint32_t audio_bit_rate, uint32_t video_bit_rate,
184 void *user_data) 186 void *user_data)
185{ 187{
@@ -194,156 +196,159 @@ void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t
194 196
195/** 197/**
196 */ 198 */
197void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxAV** BobAV, CallControl* BobCC) 199void initialize_tox(Tox **bootstrap, ToxAV **AliceAV, CallControl *AliceCC, ToxAV **BobAV, CallControl *BobCC)
198{ 200{
199 Tox* Alice; 201 Tox *Alice;
200 Tox* Bob; 202 Tox *Bob;
201 203
202 struct Tox_Options opts; 204 struct Tox_Options opts;
203 tox_options_default(&opts); 205 tox_options_default(&opts);
204 206
205 opts.end_port = 0; 207 opts.end_port = 0;
206 opts.ipv6_enabled = false; 208 opts.ipv6_enabled = false;
207 209
208 { 210 {
209 TOX_ERR_NEW error; 211 TOX_ERR_NEW error;
210 212
211 opts.start_port = 33445; 213 opts.start_port = 33445;
212 *bootstrap = tox_new(&opts, &error); 214 *bootstrap = tox_new(&opts, &error);
213 assert(error == TOX_ERR_NEW_OK); 215 assert(error == TOX_ERR_NEW_OK);
214 216
215 opts.start_port = 33455; 217 opts.start_port = 33455;
216 Alice = tox_new(&opts, &error); 218 Alice = tox_new(&opts, &error);
217 assert(error == TOX_ERR_NEW_OK); 219 assert(error == TOX_ERR_NEW_OK);
218 220
219 opts.start_port = 33465; 221 opts.start_port = 33465;
220 Bob = tox_new(&opts, &error); 222 Bob = tox_new(&opts, &error);
221 assert(error == TOX_ERR_NEW_OK); 223 assert(error == TOX_ERR_NEW_OK);
222 } 224 }
223 225
224 printf("Created 3 instances of Tox\n"); 226 printf("Created 3 instances of Tox\n");
225 printf("Preparing network...\n"); 227 printf("Preparing network...\n");
226 long long unsigned int cur_time = time(NULL); 228 long long unsigned int cur_time = time(NULL);
227 229
228 uint32_t to_compare = 974536; 230 uint32_t to_compare = 974536;
229 uint8_t address[TOX_ADDRESS_SIZE]; 231 uint8_t address[TOX_ADDRESS_SIZE];
230 232
231 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare); 233 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare);
232 tox_self_get_address(Alice, address); 234 tox_self_get_address(Alice, address);
233 235
234 236
235 assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); 237 assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
236 238
237 uint8_t off = 1; 239 uint8_t off = 1;
238 240
239 while (1) { 241 while (1) {
240 tox_iterate(*bootstrap); 242 tox_iterate(*bootstrap);
241 tox_iterate(Alice); 243 tox_iterate(Alice);
242 tox_iterate(Bob); 244 tox_iterate(Bob);
243 245
244 if (tox_self_get_connection_status(*bootstrap) && 246 if (tox_self_get_connection_status(*bootstrap) &&
245 tox_self_get_connection_status(Alice) && 247 tox_self_get_connection_status(Alice) &&
246 tox_self_get_connection_status(Bob) && off) { 248 tox_self_get_connection_status(Bob) && off) {
247 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); 249 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
248 off = 0; 250 off = 0;
249 } 251 }
250 252
251 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP && 253 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP &&
252 tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP) 254 tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP)
253 break; 255 break;
254 256
255 c_sleep(20); 257 c_sleep(20);
256 } 258 }
257 259
258 260
259 TOXAV_ERR_NEW rc; 261 TOXAV_ERR_NEW rc;
260 *AliceAV = toxav_new(Alice, &rc); 262 *AliceAV = toxav_new(Alice, &rc);
261 assert(rc == TOXAV_ERR_NEW_OK); 263 assert(rc == TOXAV_ERR_NEW_OK);
262 264
263 *BobAV = toxav_new(Bob, &rc); 265 *BobAV = toxav_new(Bob, &rc);
264 assert(rc == TOXAV_ERR_NEW_OK); 266 assert(rc == TOXAV_ERR_NEW_OK);
265 267
266 268
267 /* Alice */ 269 /* Alice */
268 toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC); 270 toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC);
269 toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); 271 toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC);
270 toxav_callback_bit_rate_status(*AliceAV, t_toxav_bit_rate_status_cb, AliceCC); 272 toxav_callback_bit_rate_status(*AliceAV, t_toxav_bit_rate_status_cb, AliceCC);
271 toxav_callback_video_receive_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC); 273 toxav_callback_video_receive_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC);
272 toxav_callback_audio_receive_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC); 274 toxav_callback_audio_receive_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC);
273 275
274 /* Bob */ 276 /* Bob */
275 toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC); 277 toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC);
276 toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC); 278 toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC);
277 toxav_callback_bit_rate_status(*BobAV, t_toxav_bit_rate_status_cb, BobCC); 279 toxav_callback_bit_rate_status(*BobAV, t_toxav_bit_rate_status_cb, BobCC);
278 toxav_callback_video_receive_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC); 280 toxav_callback_video_receive_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC);
279 toxav_callback_audio_receive_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC); 281 toxav_callback_audio_receive_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC);
280 282
281 283
282 printf("Created 2 instances of ToxAV\n"); 284 printf("Created 2 instances of ToxAV\n");
283 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 285 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
284} 286}
285int iterate_tox(Tox* bootstrap, ToxAV* AliceAV, ToxAV* BobAV) 287int iterate_tox(Tox *bootstrap, ToxAV *AliceAV, ToxAV *BobAV)
286{ 288{
287 tox_iterate(bootstrap); 289 tox_iterate(bootstrap);
288 tox_iterate(toxav_get_tox(AliceAV)); 290 tox_iterate(toxav_get_tox(AliceAV));
289 tox_iterate(toxav_get_tox(BobAV)); 291 tox_iterate(toxav_get_tox(BobAV));
290 292
291 return MIN(tox_iteration_interval(toxav_get_tox(AliceAV)), tox_iteration_interval(toxav_get_tox(BobAV))); 293 return MIN(tox_iteration_interval(toxav_get_tox(AliceAV)), tox_iteration_interval(toxav_get_tox(BobAV)));
292} 294}
293void* iterate_toxav (void * data) 295void *iterate_toxav (void *data)
294{ 296{
295 struct toxav_thread_data* data_cast = data; 297 struct toxav_thread_data *data_cast = data;
296#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1 298#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1
297 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE); 299 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
298#endif 300#endif
299 301
300 while (data_cast->sig == 0) { 302 while (data_cast->sig == 0) {
301 toxav_iterate(data_cast->AliceAV); 303 toxav_iterate(data_cast->AliceAV);
302 toxav_iterate(data_cast->BobAV); 304 toxav_iterate(data_cast->BobAV);
303 int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); 305 int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV));
304 306
305 printf("\rIteration interval: %d ", rc); 307 printf("\rIteration interval: %d ", rc);
306 fflush(stdout); 308 fflush(stdout);
307 309
308#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1 310#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1
311
309 if (!rc) 312 if (!rc)
310 rc = 1; 313 rc = 1;
311 314
312 cvWaitKey(rc); 315 cvWaitKey(rc);
313#else 316#else
314 c_sleep(rc); 317 c_sleep(rc);
315#endif 318#endif
316 } 319 }
317 320
318 data_cast->sig = 1; 321 data_cast->sig = 1;
319 322
320#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1 323#if defined TEST_TRANSFER_V && TEST_TRANSFER_V == 1
321 cvDestroyWindow(vdout); 324 cvDestroyWindow(vdout);
322#endif 325#endif
323 326
324 pthread_exit(NULL); 327 pthread_exit(NULL);
325} 328}
326 329
327int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img) 330int send_opencv_img(ToxAV *av, uint32_t friend_number, const IplImage *img)
328{ 331{
329 int32_t strides[3] = { 1280, 640, 640 }; 332 int32_t strides[3] = { 1280, 640, 640 };
330 uint8_t* planes[3] = { 333 uint8_t *planes[3] = {
331 malloc(img->height * img->width), 334 malloc(img->height * img->width),
332 malloc(img->height * img->width / 4), 335 malloc(img->height * img->width / 4),
333 malloc(img->height * img->width / 4), 336 malloc(img->height * img->width / 4),
334 }; 337 };
335 338
336 int x_chroma_shift = 1; 339 int x_chroma_shift = 1;
337 int y_chroma_shift = 1; 340 int y_chroma_shift = 1;
338 341
339 int x, y; 342 int x, y;
343
340 for (y = 0; y < img->height; ++y) { 344 for (y = 0; y < img->height; ++y) {
341 for (x = 0; x < img->width; ++x) { 345 for (x = 0; x < img->width; ++x) {
342 uint8_t r = img->imageData[(x + y * img->width) * 3 + 0]; 346 uint8_t r = img->imageData[(x + y * img->width) * 3 + 0];
343 uint8_t g = img->imageData[(x + y * img->width) * 3 + 1]; 347 uint8_t g = img->imageData[(x + y * img->width) * 3 + 1];
344 uint8_t b = img->imageData[(x + y * img->width) * 3 + 2]; 348 uint8_t b = img->imageData[(x + y * img->width) * 3 + 2];
345 349
346 planes[0][x + y * strides[0]] = RGB2Y(r, g, b); 350 planes[0][x + y * strides[0]] = RGB2Y(r, g, b);
351
347 if (!(x % (1 << x_chroma_shift)) && !(y % (1 << y_chroma_shift))) { 352 if (!(x % (1 << x_chroma_shift)) && !(y % (1 << y_chroma_shift))) {
348 const int i = x / (1 << x_chroma_shift); 353 const int i = x / (1 << x_chroma_shift);
349 const int j = y / (1 << y_chroma_shift); 354 const int j = y / (1 << y_chroma_shift);
@@ -363,15 +368,17 @@ int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
363int print_audio_devices() 368int print_audio_devices()
364{ 369{
365 int i = 0; 370 int i = 0;
371
366 for (i = 0; i < Pa_GetDeviceCount(); ++i) { 372 for (i = 0; i < Pa_GetDeviceCount(); ++i) {
367 const PaDeviceInfo* info = Pa_GetDeviceInfo(i); 373 const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
374
368 if (info) 375 if (info)
369 printf("%d) %s\n", i, info->name); 376 printf("%d) %s\n", i, info->name);
370 } 377 }
371 378
372 return 0; 379 return 0;
373} 380}
374int print_help (const char* name) 381int print_help (const char *name)
375{ 382{
376 printf("Usage: %s -[a:v:o:dh]\n" 383 printf("Usage: %s -[a:v:o:dh]\n"
377 "-a <path> audio input file\n" 384 "-a <path> audio input file\n"
@@ -381,351 +388,379 @@ int print_help (const char* name)
381 "-o <idx> output audio device index\n" 388 "-o <idx> output audio device index\n"
382 "-d print output audio devices\n" 389 "-d print output audio devices\n"
383 "-h print this help\n", name); 390 "-h print this help\n", name);
384 391
385 return 0; 392 return 0;
386} 393}
387 394
388int main (int argc, char** argv) 395int main (int argc, char **argv)
389{ 396{
390 freopen("/dev/zero", "w", stderr); 397 freopen("/dev/zero", "w", stderr);
391 Pa_Initialize(); 398 Pa_Initialize();
392 399
393 struct stat st; 400 struct stat st;
394 401
395 /* AV files for testing */ 402 /* AV files for testing */
396 const char* af_name = NULL; 403 const char *af_name = NULL;
397 const char* vf_name = NULL; 404 const char *vf_name = NULL;
398 long audio_out_dev_idx = -1; 405 long audio_out_dev_idx = -1;
399 406
400 int32_t audio_frame_duration = 20; 407 int32_t audio_frame_duration = 20;
401 int32_t video_frame_duration = 10; 408 int32_t video_frame_duration = 10;
402 409
403 /* Parse settings */ 410 /* Parse settings */
404 CHECK_ARG: switch (getopt(argc, argv, "a:b:v:x:o:dh")) { 411CHECK_ARG:
405 case 'a': 412
406 af_name = optarg; 413 switch (getopt(argc, argv, "a:b:v:x:o:dh")) {
407 goto CHECK_ARG; 414 case 'a':
408 case 'b':{ 415 af_name = optarg;
409 char *d; 416 goto CHECK_ARG;
410 audio_frame_duration = strtol(optarg, &d, 10); 417
411 if (*d) { 418 case 'b': {
412 printf("Invalid value for argument: 'b'"); 419 char *d;
413 exit(1); 420 audio_frame_duration = strtol(optarg, &d, 10);
421
422 if (*d) {
423 printf("Invalid value for argument: 'b'");
424 exit(1);
425 }
426
427 goto CHECK_ARG;
414 } 428 }
415 goto CHECK_ARG; 429
416 } 430 case 'v':
417 case 'v': 431 vf_name = optarg;
418 vf_name = optarg; 432 goto CHECK_ARG;
419 goto CHECK_ARG; 433
420 case 'x':{ 434 case 'x': {
421 char *d; 435 char *d;
422 video_frame_duration = strtol(optarg, &d, 10); 436 video_frame_duration = strtol(optarg, &d, 10);
423 if (*d) { 437
424 printf("Invalid value for argument: 'x'"); 438 if (*d) {
425 exit(1); 439 printf("Invalid value for argument: 'x'");
440 exit(1);
441 }
442
443 goto CHECK_ARG;
426 } 444 }
427 goto CHECK_ARG; 445
428 } 446 case 'o': {
429 case 'o': { 447 char *d;
430 char *d; 448 audio_out_dev_idx = strtol(optarg, &d, 10);
431 audio_out_dev_idx = strtol(optarg, &d, 10); 449
432 if (*d) { 450 if (*d) {
433 printf("Invalid value for argument: 'o'"); 451 printf("Invalid value for argument: 'o'");
434 exit(1); 452 exit(1);
453 }
454
455 goto CHECK_ARG;
435 } 456 }
436 goto CHECK_ARG; 457
437 } 458 case 'd':
438 case 'd': 459 return print_audio_devices();
439 return print_audio_devices(); 460
440 case 'h': 461 case 'h':
441 return print_help(argv[0]); 462 return print_help(argv[0]);
442 case '?': 463
443 exit(1); 464 case '?':
444 case -1:; 465 exit(1);
466
467 case -1:
468 ;
445 } 469 }
446 470
447 { /* Check files */ 471 { /* Check files */
448 if (!af_name) { 472 if (!af_name) {
449 printf("Required audio input file!\n"); 473 printf("Required audio input file!\n");
450 exit(1); 474 exit(1);
451 } 475 }
452 476
453 if (!vf_name) { 477 if (!vf_name) {
454 printf("Required video input file!\n"); 478 printf("Required video input file!\n");
455 exit(1); 479 exit(1);
456 } 480 }
457 481
458 /* Check for files */ 482 /* Check for files */
459 if(stat(af_name, &st) != 0 || !S_ISREG(st.st_mode)) 483 if (stat(af_name, &st) != 0 || !S_ISREG(st.st_mode)) {
460 {
461 printf("%s doesn't seem to be a regular file!\n", af_name); 484 printf("%s doesn't seem to be a regular file!\n", af_name);
462 exit(1); 485 exit(1);
463 } 486 }
464 487
465 if(stat(vf_name, &st) != 0 || !S_ISREG(st.st_mode)) 488 if (stat(vf_name, &st) != 0 || !S_ISREG(st.st_mode)) {
466 {
467 printf("%s doesn't seem to be a regular file!\n", vf_name); 489 printf("%s doesn't seem to be a regular file!\n", vf_name);
468 exit(1); 490 exit(1);
469 } 491 }
470 } 492 }
471 493
472 if (audio_out_dev_idx < 0) 494 if (audio_out_dev_idx < 0)
473 audio_out_dev_idx = Pa_GetDefaultOutputDevice(); 495 audio_out_dev_idx = Pa_GetDefaultOutputDevice();
474 496
475 const PaDeviceInfo* audio_dev = Pa_GetDeviceInfo(audio_out_dev_idx); 497 const PaDeviceInfo *audio_dev = Pa_GetDeviceInfo(audio_out_dev_idx);
498
476 if (!audio_dev) { 499 if (!audio_dev) {
477 fprintf(stderr, "Device under index: %ld invalid", audio_out_dev_idx); 500 fprintf(stderr, "Device under index: %ld invalid", audio_out_dev_idx);
478 return 1; 501 return 1;
479 } 502 }
480 503
481 printf("Using audio device: %s\n", audio_dev->name); 504 printf("Using audio device: %s\n", audio_dev->name);
482 printf("Using audio file: %s\n", af_name); 505 printf("Using audio file: %s\n", af_name);
483 printf("Using video file: %s\n", vf_name); 506 printf("Using video file: %s\n", vf_name);
484 507
485 /* START TOX NETWORK */ 508 /* START TOX NETWORK */
486 509
487 Tox *bootstrap; 510 Tox *bootstrap;
488 ToxAV *AliceAV; 511 ToxAV *AliceAV;
489 ToxAV *BobAV; 512 ToxAV *BobAV;
490 513
491 CallControl AliceCC; 514 CallControl AliceCC;
492 CallControl BobCC; 515 CallControl BobCC;
493 516
494 initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC); 517 initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC);
495 518
496 if (TEST_TRANSFER_A) { 519 if (TEST_TRANSFER_A) {
497 SNDFILE* af_handle; 520 SNDFILE *af_handle;
498 SF_INFO af_info; 521 SF_INFO af_info;
499 522
500 printf("\nTrying audio enc/dec...\n"); 523 printf("\nTrying audio enc/dec...\n");
501 524
502 memset(&AliceCC, 0, sizeof(CallControl)); 525 memset(&AliceCC, 0, sizeof(CallControl));
503 memset(&BobCC, 0, sizeof(CallControl)); 526 memset(&BobCC, 0, sizeof(CallControl));
504 527
505 pthread_mutex_init(AliceCC.arb_mutex, NULL); 528 pthread_mutex_init(AliceCC.arb_mutex, NULL);
506 pthread_mutex_init(BobCC.arb_mutex, NULL); 529 pthread_mutex_init(BobCC.arb_mutex, NULL);
507 530
508 AliceCC.arb = rb_new(16); 531 AliceCC.arb = rb_new(16);
509 BobCC.arb = rb_new(16); 532 BobCC.arb = rb_new(16);
510 533
511 { /* Call */ 534 { /* Call */
512 TOXAV_ERR_CALL rc; 535 TOXAV_ERR_CALL rc;
513 toxav_call(AliceAV, 0, 48, 0, &rc); 536 toxav_call(AliceAV, 0, 48, 0, &rc);
514 537
515 if (rc != TOXAV_ERR_CALL_OK) { 538 if (rc != TOXAV_ERR_CALL_OK) {
516 printf("toxav_call failed: %d\n", rc); 539 printf("toxav_call failed: %d\n", rc);
517 exit(1); 540 exit(1);
518 } 541 }
519 } 542 }
520 543
521 while (!BobCC.incoming) 544 while (!BobCC.incoming)
522 iterate_tox(bootstrap, AliceAV, BobAV); 545 iterate_tox(bootstrap, AliceAV, BobAV);
523 546
524 { /* Answer */ 547 { /* Answer */
525 TOXAV_ERR_ANSWER rc; 548 TOXAV_ERR_ANSWER rc;
526 toxav_answer(BobAV, 0, 48, 0, &rc); 549 toxav_answer(BobAV, 0, 48, 0, &rc);
527 550
528 if (rc != TOXAV_ERR_ANSWER_OK) { 551 if (rc != TOXAV_ERR_ANSWER_OK) {
529 printf("toxav_answer failed: %d\n", rc); 552 printf("toxav_answer failed: %d\n", rc);
530 exit(1); 553 exit(1);
531 } 554 }
532 } 555 }
533 556
534 while (AliceCC.state == 0) 557 while (AliceCC.state == 0)
535 iterate_tox(bootstrap, AliceAV, BobAV); 558 iterate_tox(bootstrap, AliceAV, BobAV);
536 559
537 /* Open audio file */ 560 /* Open audio file */
538 af_handle = sf_open(af_name, SFM_READ, &af_info); 561 af_handle = sf_open(af_name, SFM_READ, &af_info);
562
539 if (af_handle == NULL) { 563 if (af_handle == NULL) {
540 printf("Failed to open the file.\n"); 564 printf("Failed to open the file.\n");
541 exit(1); 565 exit(1);
542 } 566 }
543 567
544 int16_t PCM[5760]; 568 int16_t PCM[5760];
545 569
546 time_t start_time = time(NULL); 570 time_t start_time = time(NULL);
547 time_t expected_time = af_info.frames / af_info.samplerate + 2; 571 time_t expected_time = af_info.frames / af_info.samplerate + 2;
548 572
549 573
550 /* Start decode thread */ 574 /* Start decode thread */
551 struct toxav_thread_data data = { 575 struct toxav_thread_data data = {
552 .AliceAV = AliceAV, 576 .AliceAV = AliceAV,
553 .BobAV = BobAV, 577 .BobAV = BobAV,
554 .sig = 0 578 .sig = 0
555 }; 579 };
556 580
557 pthread_t dect; 581 pthread_t dect;
558 pthread_create(&dect, NULL, iterate_toxav, &data); 582 pthread_create(&dect, NULL, iterate_toxav, &data);
559 pthread_detach(dect); 583 pthread_detach(dect);
560 584
561 int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; 585 int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels;
562 586
563 struct PaStreamParameters output; 587 struct PaStreamParameters output;
564 output.device = audio_out_dev_idx; 588 output.device = audio_out_dev_idx;
565 output.channelCount = af_info.channels; 589 output.channelCount = af_info.channels;
566 output.sampleFormat = paInt16; 590 output.sampleFormat = paInt16;
567 output.suggestedLatency = audio_dev->defaultHighOutputLatency; 591 output.suggestedLatency = audio_dev->defaultHighOutputLatency;
568 output.hostApiSpecificStreamInfo = NULL; 592 output.hostApiSpecificStreamInfo = NULL;
569 593
570 PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL); 594 PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL);
571 assert(err == paNoError); 595 assert(err == paNoError);
572 596
573 err = Pa_StartStream(adout); 597 err = Pa_StartStream(adout);
574 assert(err == paNoError); 598 assert(err == paNoError);
575 599
576// toxav_audio_bit_rate_set(AliceAV, 0, 64, false, NULL); 600// toxav_audio_bit_rate_set(AliceAV, 0, 64, false, NULL);
577 601
578 /* Start write thread */ 602 /* Start write thread */
579 pthread_t t; 603 pthread_t t;
580 pthread_create(&t, NULL, pa_write_thread, &BobCC); 604 pthread_create(&t, NULL, pa_write_thread, &BobCC);
581 pthread_detach(t); 605 pthread_detach(t);
582 606
583 printf("Sample rate %d\n", af_info.samplerate); 607 printf("Sample rate %d\n", af_info.samplerate);
584 while (start_time + expected_time > time(NULL) ) { 608
609 while (start_time + expected_time > time(NULL) ) {
585 uint64_t enc_start_time = current_time_monotonic(); 610 uint64_t enc_start_time = current_time_monotonic();
586 int64_t count = sf_read_short(af_handle, PCM, frame_size); 611 int64_t count = sf_read_short(af_handle, PCM, frame_size);
612
587 if (count > 0) { 613 if (count > 0) {
588 TOXAV_ERR_SEND_FRAME rc; 614 TOXAV_ERR_SEND_FRAME rc;
589 if (toxav_audio_send_frame(AliceAV, 0, PCM, count/af_info.channels, af_info.channels, af_info.samplerate, &rc) == false) { 615
616 if (toxav_audio_send_frame(AliceAV, 0, PCM, count / af_info.channels, af_info.channels, af_info.samplerate,
617 &rc) == false) {
590 printf("Error sending frame of size %ld: %d\n", count, rc); 618 printf("Error sending frame of size %ld: %d\n", count, rc);
591 } 619 }
592 } 620 }
621
593 iterate_tox(bootstrap, AliceAV, BobAV); 622 iterate_tox(bootstrap, AliceAV, BobAV);
594 c_sleep(abs(audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1)); 623 c_sleep(abs(audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1));
595 } 624 }
596 625
597 printf("Played file in: %lu; stopping stream...\n", time(NULL) - start_time); 626 printf("Played file in: %lu; stopping stream...\n", time(NULL) - start_time);
598 627
599 Pa_StopStream(adout); 628 Pa_StopStream(adout);
600 sf_close(af_handle); 629 sf_close(af_handle);
601 630
602 { /* Hangup */ 631 { /* Hangup */
603 TOXAV_ERR_CALL_CONTROL rc; 632 TOXAV_ERR_CALL_CONTROL rc;
604 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 633 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
605 634
606 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 635 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
607 printf("toxav_call_control failed: %d\n", rc); 636 printf("toxav_call_control failed: %d\n", rc);
608 exit(1); 637 exit(1);
609 } 638 }
610 } 639 }
611 640
612 iterate_tox(bootstrap, AliceAV, BobAV); 641 iterate_tox(bootstrap, AliceAV, BobAV);
613 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 642 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
614 643
615 /* Stop decode thread */ 644 /* Stop decode thread */
616 data.sig = -1; 645 data.sig = -1;
617 while(data.sig != 1) 646
647 while (data.sig != 1)
618 pthread_yield(); 648 pthread_yield();
619 649
620 pthread_mutex_destroy(AliceCC.arb_mutex); 650 pthread_mutex_destroy(AliceCC.arb_mutex);
621 pthread_mutex_destroy(BobCC.arb_mutex); 651 pthread_mutex_destroy(BobCC.arb_mutex);
622 652
623 void* f = NULL; 653 void *f = NULL;
624 while(rb_read(AliceCC.arb, &f)) 654
655 while (rb_read(AliceCC.arb, &f))
625 free(f); 656 free(f);
626 657
627 while(rb_read(BobCC.arb, &f)) 658 while (rb_read(BobCC.arb, &f))
628 free(f); 659 free(f);
629 660
630 printf("Success!"); 661 printf("Success!");
631 } 662 }
632 663
633 if (TEST_TRANSFER_V) { 664 if (TEST_TRANSFER_V) {
634 printf("\nTrying video enc/dec...\n"); 665 printf("\nTrying video enc/dec...\n");
635 666
636 memset(&AliceCC, 0, sizeof(CallControl)); 667 memset(&AliceCC, 0, sizeof(CallControl));
637 memset(&BobCC, 0, sizeof(CallControl)); 668 memset(&BobCC, 0, sizeof(CallControl));
638 669
639 { /* Call */ 670 { /* Call */
640 TOXAV_ERR_CALL rc; 671 TOXAV_ERR_CALL rc;
641 toxav_call(AliceAV, 0, 0, 2000, &rc); 672 toxav_call(AliceAV, 0, 0, 2000, &rc);
642 673
643 if (rc != TOXAV_ERR_CALL_OK) { 674 if (rc != TOXAV_ERR_CALL_OK) {
644 printf("toxav_call failed: %d\n", rc); 675 printf("toxav_call failed: %d\n", rc);
645 exit(1); 676 exit(1);
646 } 677 }
647 } 678 }
648 679
649 while (!BobCC.incoming) 680 while (!BobCC.incoming)
650 iterate_tox(bootstrap, AliceAV, BobAV); 681 iterate_tox(bootstrap, AliceAV, BobAV);
651 682
652 { /* Answer */ 683 { /* Answer */
653 TOXAV_ERR_ANSWER rc; 684 TOXAV_ERR_ANSWER rc;
654 toxav_answer(BobAV, 0, 0, 5000, &rc); 685 toxav_answer(BobAV, 0, 0, 5000, &rc);
655 686
656 if (rc != TOXAV_ERR_ANSWER_OK) { 687 if (rc != TOXAV_ERR_ANSWER_OK) {
657 printf("toxav_answer failed: %d\n", rc); 688 printf("toxav_answer failed: %d\n", rc);
658 exit(1); 689 exit(1);
659 } 690 }
660 } 691 }
661 692
662 iterate_tox(bootstrap, AliceAV, BobAV); 693 iterate_tox(bootstrap, AliceAV, BobAV);
663 694
664 /* Start decode thread */ 695 /* Start decode thread */
665 struct toxav_thread_data data = { 696 struct toxav_thread_data data = {
666 .AliceAV = AliceAV, 697 .AliceAV = AliceAV,
667 .BobAV = BobAV, 698 .BobAV = BobAV,
668 .sig = 0 699 .sig = 0
669 }; 700 };
670 701
671 pthread_t dect; 702 pthread_t dect;
672 pthread_create(&dect, NULL, iterate_toxav, &data); 703 pthread_create(&dect, NULL, iterate_toxav, &data);
673 pthread_detach(dect); 704 pthread_detach(dect);
674 705
675 CvCapture* capture = cvCreateFileCapture(vf_name); 706 CvCapture *capture = cvCreateFileCapture(vf_name);
707
676 if (!capture) { 708 if (!capture) {
677 printf("Failed to open video file: %s\n", vf_name); 709 printf("Failed to open video file: %s\n", vf_name);
678 exit(1); 710 exit(1);
679 } 711 }
680 712
681// toxav_video_bit_rate_set(AliceAV, 0, 5000, false, NULL); 713// toxav_video_bit_rate_set(AliceAV, 0, 5000, false, NULL);
682 714
683 time_t start_time = time(NULL); 715 time_t start_time = time(NULL);
684 while(start_time + 90 > time(NULL)) { 716
685 IplImage* frame = cvQueryFrame(capture ); 717 while (start_time + 90 > time(NULL)) {
718 IplImage *frame = cvQueryFrame(capture );
719
686 if (!frame) 720 if (!frame)
687 break; 721 break;
688 722
689 send_opencv_img(AliceAV, 0, frame); 723 send_opencv_img(AliceAV, 0, frame);
690 iterate_tox(bootstrap, AliceAV, BobAV); 724 iterate_tox(bootstrap, AliceAV, BobAV);
691 c_sleep(10); 725 c_sleep(10);
692 } 726 }
693 727
694 cvReleaseCapture(&capture); 728 cvReleaseCapture(&capture);
695 729
696 { /* Hangup */ 730 { /* Hangup */
697 TOXAV_ERR_CALL_CONTROL rc; 731 TOXAV_ERR_CALL_CONTROL rc;
698 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); 732 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
699 733
700 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 734 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
701 printf("toxav_call_control failed: %d\n", rc); 735 printf("toxav_call_control failed: %d\n", rc);
702 exit(1); 736 exit(1);
703 } 737 }
704 } 738 }
705 739
706 iterate_tox(bootstrap, AliceAV, BobAV); 740 iterate_tox(bootstrap, AliceAV, BobAV);
707 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 741 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
708 742
709 /* Stop decode thread */ 743 /* Stop decode thread */
710 printf("Stopping decode thread\n"); 744 printf("Stopping decode thread\n");
711 data.sig = -1; 745 data.sig = -1;
712 while(data.sig != 1) 746
747 while (data.sig != 1)
713 pthread_yield(); 748 pthread_yield();
714 749
715 printf("Success!"); 750 printf("Success!");
716 } 751 }
717 752
718 753
719 Tox* Alice = toxav_get_tox(AliceAV); 754 Tox *Alice = toxav_get_tox(AliceAV);
720 Tox* Bob = toxav_get_tox(BobAV); 755 Tox *Bob = toxav_get_tox(BobAV);
721 toxav_kill(BobAV); 756 toxav_kill(BobAV);
722 toxav_kill(AliceAV); 757 toxav_kill(AliceAV);
723 tox_kill(Bob); 758 tox_kill(Bob);
724 tox_kill(Alice); 759 tox_kill(Alice);
725 tox_kill(bootstrap); 760 tox_kill(bootstrap);
726 761
727 printf("\nTest successful!\n"); 762 printf("\nTest successful!\n");
728 763
729 Pa_Terminate(); 764 Pa_Terminate();
730 return 0; 765 return 0;
731} 766}
diff --git a/toxav/audio.c b/toxav/audio.c
index 4f9d3562..ad543502 100644
--- a/toxav/audio.c
+++ b/toxav/audio.c
@@ -76,11 +76,11 @@ ACSession *ac_new(ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_c
76 76
77 if (ac->encoder == NULL) 77 if (ac->encoder == NULL)
78 goto DECODER_CLEANUP; 78 goto DECODER_CLEANUP;
79 79
80 ac->le_bit_rate = 48000; 80 ac->le_bit_rate = 48000;
81 ac->le_sample_rate = 48000; 81 ac->le_sample_rate = 48000;
82 ac->le_channel_count = 2; 82 ac->le_channel_count = 2;
83 83
84 ac->ld_channel_count = 2; 84 ac->ld_channel_count = 2;
85 ac->ld_sample_rate = 48000; 85 ac->ld_sample_rate = 48000;
86 ac->ldrts = 0; /* Make it possible to reconfigure straight away */ 86 ac->ldrts = 0; /* Make it possible to reconfigure straight away */
@@ -126,7 +126,7 @@ void ac_iterate(ACSession *ac)
126 return; 126 return;
127 127
128 /* TODO fix this and jitter buffering */ 128 /* TODO fix this and jitter buffering */
129 129
130 /* Enough space for the maximum frame size (120 ms 48 KHz stereo audio) */ 130 /* Enough space for the maximum frame size (120 ms 48 KHz stereo audio) */
131 int16_t tmp[5760 * 2]; 131 int16_t tmp[5760 * 2];
132 132
@@ -221,9 +221,9 @@ int ac_queue_message(void *acp, struct RTPMessage *msg)
221} 221}
222int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels) 222int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels)
223{ 223{
224 if (!ac || !reconfigure_audio_encoder(&ac->encoder, bit_rate, 224 if (!ac || !reconfigure_audio_encoder(&ac->encoder, bit_rate,
225 sampling_rate, channels, 225 sampling_rate, channels,
226 &ac->le_bit_rate, 226 &ac->le_bit_rate,
227 &ac->le_sample_rate, 227 &ac->le_sample_rate,
228 &ac->le_channel_count)) 228 &ac->le_channel_count))
229 return -1; 229 return -1;
diff --git a/toxav/bwcontroler.c b/toxav/bwcontroler.c
index 2530e7fd..9dd15c93 100644
--- a/toxav/bwcontroler.c
+++ b/toxav/bwcontroler.c
@@ -34,7 +34,7 @@
34#define BWC_AVG_PKT_COUNT 20 34#define BWC_AVG_PKT_COUNT 20
35 35
36/** 36/**
37 * 37 *
38 */ 38 */
39 39
40struct BWControler_s { 40struct BWControler_s {
@@ -77,10 +77,11 @@ BWControler *bwc_new(Messenger *m, uint32_t friendnumber,
77 77
78 /* Fill with zeros */ 78 /* Fill with zeros */
79 int i = 0; 79 int i = 0;
80
80 for (; i < BWC_AVG_PKT_COUNT; i ++) 81 for (; i < BWC_AVG_PKT_COUNT; i ++)
81 rb_write(retu->rcvpkt.rb, retu->rcvpkt.rb_s + i); 82 rb_write(retu->rcvpkt.rb, retu->rcvpkt.rb_s + i);
82 83
83 m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu); 84 m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu);
84 85
85 return retu; 86 return retu;
86} 87}
@@ -88,19 +89,19 @@ void bwc_kill(BWControler *bwc)
88{ 89{
89 if (!bwc) 90 if (!bwc)
90 return; 91 return;
91 92
92 m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, NULL, NULL); 93 m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, NULL, NULL);
93 94
94 rb_kill(bwc->rcvpkt.rb); 95 rb_kill(bwc->rcvpkt.rb);
95 free(bwc); 96 free(bwc);
96} 97}
97void bwc_feed_avg(BWControler* bwc, uint32_t bytes) 98void bwc_feed_avg(BWControler *bwc, uint32_t bytes)
98{ 99{
99 uint32_t *p; 100 uint32_t *p;
100 101
101 rb_read(bwc->rcvpkt.rb, (void**) &p); 102 rb_read(bwc->rcvpkt.rb, (void **) &p);
102 rb_write(bwc->rcvpkt.rb, p); 103 rb_write(bwc->rcvpkt.rb, p);
103 104
104 *p = bytes; 105 *p = bytes;
105} 106}
106void bwc_add_lost(BWControler *bwc, uint32_t bytes) 107void bwc_add_lost(BWControler *bwc, uint32_t bytes)
@@ -109,21 +110,22 @@ void bwc_add_lost(BWControler *bwc, uint32_t bytes)
109 return; 110 return;
110 111
111 if (!bytes) { 112 if (!bytes) {
112 uint32_t* t_avg[BWC_AVG_PKT_COUNT], c = 1; 113 uint32_t *t_avg[BWC_AVG_PKT_COUNT], c = 1;
113 114
114 rb_data(bwc->rcvpkt.rb, (void**) t_avg); 115 rb_data(bwc->rcvpkt.rb, (void **) t_avg);
115 116
116 int i = 0; 117 int i = 0;
118
117 for (; i < BWC_AVG_PKT_COUNT; i ++) { 119 for (; i < BWC_AVG_PKT_COUNT; i ++) {
118 bytes += *(t_avg[i]); 120 bytes += *(t_avg[i]);
119 121
120 if (*(t_avg[i])) 122 if (*(t_avg[i]))
121 c++; 123 c++;
122 } 124 }
123 125
124 bytes /= c; 126 bytes /= c;
125 } 127 }
126 128
127 bwc->cycle.lost += bytes; 129 bwc->cycle.lost += bytes;
128 send_update(bwc); 130 send_update(bwc);
129} 131}
@@ -131,7 +133,7 @@ void bwc_add_recv(BWControler *bwc, uint32_t bytes)
131{ 133{
132 if (!bwc || !bytes) 134 if (!bwc || !bytes)
133 return; 135 return;
134 136
135 bwc->cycle.recv += bytes; 137 bwc->cycle.recv += bytes;
136 send_update(bwc); 138 send_update(bwc);
137} 139}
@@ -145,21 +147,19 @@ struct BWCMessage {
145void send_update(BWControler *bwc) 147void send_update(BWControler *bwc)
146{ 148{
147 if (current_time_monotonic() - bwc->cycle.lfu > BWC_REFRESH_INTERVAL_MS) { 149 if (current_time_monotonic() - bwc->cycle.lfu > BWC_REFRESH_INTERVAL_MS) {
148 150
149 bwc->cycle.lost /= 10; 151 bwc->cycle.lost /= 10;
150 bwc->cycle.recv /= 10; 152 bwc->cycle.recv /= 10;
151 bwc->cycle.lfu = current_time_monotonic(); 153 bwc->cycle.lfu = current_time_monotonic();
152 } 154 } else if (current_time_monotonic() - bwc->cycle.lsu > BWC_SEND_INTERVAL_MS) {
153 else if (current_time_monotonic() - bwc->cycle.lsu > BWC_SEND_INTERVAL_MS) { 155
154 156 if (bwc->cycle.lost) {
155 if (bwc->cycle.lost)
156 {
157 LOGGER_DEBUG ("%p Sent update rcv: %u lost: %u", 157 LOGGER_DEBUG ("%p Sent update rcv: %u lost: %u",
158 bwc, bwc->cycle.recv, bwc->cycle.lost); 158 bwc, bwc->cycle.recv, bwc->cycle.lost);
159 159
160 uint8_t p_msg[sizeof(struct BWCMessage) + 1]; 160 uint8_t p_msg[sizeof(struct BWCMessage) + 1];
161 struct BWCMessage* b_msg = (struct BWCMessage*)(p_msg + 1); 161 struct BWCMessage *b_msg = (struct BWCMessage *)(p_msg + 1);
162 162
163 p_msg[0] = BWC_PACKET_ID; 163 p_msg[0] = BWC_PACKET_ID;
164 b_msg->lost = htonl(bwc->cycle.lost); 164 b_msg->lost = htonl(bwc->cycle.lost);
165 b_msg->recv = htonl(bwc->cycle.recv); 165 b_msg->recv = htonl(bwc->cycle.recv);
@@ -167,27 +167,27 @@ void send_update(BWControler *bwc)
167 if (-1 == send_custom_lossy_packet(bwc->m, bwc->friend_number, p_msg, sizeof(p_msg))) 167 if (-1 == send_custom_lossy_packet(bwc->m, bwc->friend_number, p_msg, sizeof(p_msg)))
168 LOGGER_WARNING("BWC send failed (len: %d)! std error: %s", sizeof(p_msg), strerror(errno)); 168 LOGGER_WARNING("BWC send failed (len: %d)! std error: %s", sizeof(p_msg), strerror(errno));
169 } 169 }
170 170
171 bwc->cycle.lsu = current_time_monotonic(); 171 bwc->cycle.lsu = current_time_monotonic();
172 } 172 }
173} 173}
174int on_update (BWControler *bwc, struct BWCMessage *msg) 174int on_update (BWControler *bwc, struct BWCMessage *msg)
175{ 175{
176 LOGGER_DEBUG ("%p Got update from peer", bwc); 176 LOGGER_DEBUG ("%p Got update from peer", bwc);
177 177
178 /* Peer must respect time boundary */ 178 /* Peer must respect time boundary */
179 if (current_time_monotonic() < bwc->cycle.lru + BWC_SEND_INTERVAL_MS) { 179 if (current_time_monotonic() < bwc->cycle.lru + BWC_SEND_INTERVAL_MS) {
180 LOGGER_DEBUG("%p Rejecting extra update", bwc); 180 LOGGER_DEBUG("%p Rejecting extra update", bwc);
181 return -1; 181 return -1;
182 } 182 }
183 183
184 bwc->cycle.lru = current_time_monotonic(); 184 bwc->cycle.lru = current_time_monotonic();
185 185
186 msg->recv = ntohl(msg->recv); 186 msg->recv = ntohl(msg->recv);
187 msg->lost = ntohl(msg->lost); 187 msg->lost = ntohl(msg->lost);
188 188
189 LOGGER_DEBUG ("recved: %u lost: %u", msg->recv, msg->lost); 189 LOGGER_DEBUG ("recved: %u lost: %u", msg->recv, msg->lost);
190 190
191 if (msg->lost && bwc->mcb) 191 if (msg->lost && bwc->mcb)
192 bwc->mcb(bwc, bwc->friend_number, 192 bwc->mcb(bwc, bwc->friend_number,
193 ((float) (msg->lost) / (msg->recv + msg->lost)), 193 ((float) (msg->lost) / (msg->recv + msg->lost)),
@@ -195,7 +195,7 @@ int on_update (BWControler *bwc, struct BWCMessage *msg)
195 195
196 return 0; 196 return 0;
197} 197}
198int bwc_handle_data(Messenger* m, uint32_t friendnumber, const uint8_t* data, uint16_t length, void* object) 198int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object)
199{ 199{
200 if (length - 1 != sizeof(struct BWCMessage)) 200 if (length - 1 != sizeof(struct BWCMessage))
201 return -1; 201 return -1;
diff --git a/toxav/msi.c b/toxav/msi.c
index 7ad39a54..c08c0135 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -99,7 +99,7 @@ void msi_register_callback (MSISession *session, msi_action_cb *callback, MSICal
99{ 99{
100 if (!session) 100 if (!session)
101 return; 101 return;
102 102
103 pthread_mutex_lock(session->mutex); 103 pthread_mutex_lock(session->mutex);
104 session->callbacks[id] = callback; 104 session->callbacks[id] = callback;
105 pthread_mutex_unlock(session->mutex); 105 pthread_mutex_unlock(session->mutex);
@@ -142,7 +142,7 @@ int msi_kill (MSISession *session)
142 } 142 }
143 143
144 m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL); 144 m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL);
145 145
146 if (pthread_mutex_trylock(session->mutex) != 0) { 146 if (pthread_mutex_trylock(session->mutex) != 0) {
147 LOGGER_ERROR ("Failed to aquire lock on msi mutex"); 147 LOGGER_ERROR ("Failed to aquire lock on msi mutex");
148 return -1; 148 return -1;
@@ -171,7 +171,7 @@ int msi_invite (MSISession *session, MSICall **call, uint32_t friend_number, uin
171{ 171{
172 if (!session) 172 if (!session)
173 return -1; 173 return -1;
174 174
175 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_number); 175 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_number);
176 176
177 if (pthread_mutex_trylock(session->mutex) != 0) { 177 if (pthread_mutex_trylock(session->mutex) != 0) {
@@ -212,11 +212,11 @@ int msi_hangup (MSICall *call)
212{ 212{
213 if (!call || !call->session) 213 if (!call || !call->session)
214 return -1; 214 return -1;
215 215
216 LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_number); 216 LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_number);
217 217
218 MSISession *session = call->session; 218 MSISession *session = call->session;
219 219
220 if (pthread_mutex_trylock(session->mutex) != 0) { 220 if (pthread_mutex_trylock(session->mutex) != 0) {
221 LOGGER_ERROR ("Failed to aquire lock on msi mutex"); 221 LOGGER_ERROR ("Failed to aquire lock on msi mutex");
222 return -1; 222 return -1;
@@ -278,7 +278,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities)
278{ 278{
279 if (!call || !call->session) 279 if (!call || !call->session)
280 return -1; 280 return -1;
281 281
282 LOGGER_DEBUG("Session: %p Trying to change capabilities to friend %u", call->session, call->friend_number); 282 LOGGER_DEBUG("Session: %p Trying to change capabilities to friend %u", call->session, call->friend_number);
283 283
284 MSISession *session = call->session; 284 MSISession *session = call->session;
@@ -619,19 +619,18 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *
619 break; 619 break;
620 } 620 }
621} 621}
622void handle_init (MSICall* call, const MSIMessage* msg) 622void handle_init (MSICall *call, const MSIMessage *msg)
623{ 623{
624 assert(call); 624 assert(call);
625 LOGGER_DEBUG("Session: %p Handling 'init' friend: %d", call->session, call->friend_number); 625 LOGGER_DEBUG("Session: %p Handling 'init' friend: %d", call->session, call->friend_number);
626 626
627 if (!msg->capabilities.exists) { 627 if (!msg->capabilities.exists) {
628 LOGGER_WARNING("Session: %p Invalid capabilities on 'init'"); 628 LOGGER_WARNING("Session: %p Invalid capabilities on 'init'");
629 call->error = msi_EInvalidMessage; 629 call->error = msi_EInvalidMessage;
630 goto FAILURE; 630 goto FAILURE;
631 } 631 }
632 632
633 switch (call->state) 633 switch (call->state) {
634 {
635 case msi_CallInactive: { 634 case msi_CallInactive: {
636 /* Call requested */ 635 /* Call requested */
637 call->peer_capabilities = msg->capabilities.value; 636 call->peer_capabilities = msg->capabilities.value;
@@ -641,7 +640,7 @@ void handle_init (MSICall* call, const MSIMessage* msg)
641 goto FAILURE; 640 goto FAILURE;
642 } 641 }
643 break; 642 break;
644 643
645 case msi_CallActive: { 644 case msi_CallActive: {
646 /* If peer sent init while the call is already 645 /* If peer sent init while the call is already
647 * active it's probable that he is trying to 646 * active it's probable that he is trying to
@@ -649,9 +648,9 @@ void handle_init (MSICall* call, const MSIMessage* msg)
649 * on our side. We can assume that in this case 648 * on our side. We can assume that in this case
650 * we can automatically answer the re-call. 649 * we can automatically answer the re-call.
651 */ 650 */
652 651
653 LOGGER_INFO("Friend is recalling us"); 652 LOGGER_INFO("Friend is recalling us");
654 653
655 MSIMessage msg; 654 MSIMessage msg;
656 msg_init(&msg, requ_push); 655 msg_init(&msg, requ_push);
657 656
@@ -665,7 +664,7 @@ void handle_init (MSICall* call, const MSIMessage* msg)
665 */ 664 */
666 } 665 }
667 break; 666 break;
668 667
669 default: { 668 default: {
670 LOGGER_WARNING("Session: %p Invalid state on 'init'"); 669 LOGGER_WARNING("Session: %p Invalid state on 'init'");
671 call->error = msi_EInvalidState; 670 call->error = msi_EInvalidState;
@@ -673,7 +672,7 @@ void handle_init (MSICall* call, const MSIMessage* msg)
673 } 672 }
674 break; 673 break;
675 } 674 }
676 675
677 return; 676 return;
678FAILURE: 677FAILURE:
679 send_error(call->session->messenger, call->friend_number, call->error); 678 send_error(call->session->messenger, call->friend_number, call->error);
@@ -746,33 +745,33 @@ void handle_pop (MSICall *call, const MSIMessage *msg)
746 invoke_callback(call, msi_OnError); 745 invoke_callback(call, msi_OnError);
747 746
748 } else switch (call->state) { 747 } else switch (call->state) {
749 case msi_CallInactive: { 748 case msi_CallInactive: {
750 LOGGER_ERROR("Handling what should be impossible case"); 749 LOGGER_ERROR("Handling what should be impossible case");
751 abort(); 750 abort();
752 } 751 }
753 break; 752 break;
754 753
755 case msi_CallActive: { 754 case msi_CallActive: {
756 /* Hangup */ 755 /* Hangup */
757 LOGGER_INFO("Friend hung up on us"); 756 LOGGER_INFO("Friend hung up on us");
758 invoke_callback(call, msi_OnEnd); 757 invoke_callback(call, msi_OnEnd);
759 } 758 }
760 break; 759 break;
761 760
762 case msi_CallRequesting: { 761 case msi_CallRequesting: {
763 /* Reject */ 762 /* Reject */
764 LOGGER_INFO("Friend rejected our call"); 763 LOGGER_INFO("Friend rejected our call");
765 invoke_callback(call, msi_OnEnd); 764 invoke_callback(call, msi_OnEnd);
766 } 765 }
767 break; 766 break;
768 767
769 case msi_CallRequested: { 768 case msi_CallRequested: {
770 /* Cancel */ 769 /* Cancel */
771 LOGGER_INFO("Friend canceled call invite"); 770 LOGGER_INFO("Friend canceled call invite");
772 invoke_callback(call, msi_OnEnd); 771 invoke_callback(call, msi_OnEnd);
772 }
773 break;
773 } 774 }
774 break;
775 }
776 775
777 kill_call (call); 776 kill_call (call);
778} 777}
@@ -814,9 +813,11 @@ void handle_msi_packet (Messenger *m, uint32_t friend_number, const uint8_t *dat
814 case requ_init: 813 case requ_init:
815 handle_init(call, &msg); 814 handle_init(call, &msg);
816 break; 815 break;
816
817 case requ_push: 817 case requ_push:
818 handle_push(call, &msg); 818 handle_push(call, &msg);
819 break; 819 break;
820
820 case requ_pop: 821 case requ_pop:
821 handle_pop(call, &msg); /* always kills the call */ 822 handle_pop(call, &msg); /* always kills the call */
822 break; 823 break;
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 763166cd..1813725a 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -189,17 +189,18 @@ bool chloss (const RTPSession *session, const struct RTPHeader *header)
189{ 189{
190 if (ntohl(header->timestamp) < session->rtimestamp) { 190 if (ntohl(header->timestamp) < session->rtimestamp) {
191 uint16_t hosq, lost = 0; 191 uint16_t hosq, lost = 0;
192 192
193 hosq = ntohs(header->sequnum); 193 hosq = ntohs(header->sequnum);
194 194
195 lost = (hosq > session->rsequnum) ? 195 lost = (hosq > session->rsequnum) ?
196 (session->rsequnum + 65535) - hosq : 196 (session->rsequnum + 65535) - hosq :
197 session->rsequnum - hosq; 197 session->rsequnum - hosq;
198 198
199 puts ("Lost packet"); 199 puts ("Lost packet");
200
200 while (lost --) 201 while (lost --)
201 bwc_add_lost(session->bwc ,0); 202 bwc_add_lost(session->bwc , 0);
202 203
203 return true; 204 return true;
204 } 205 }
205 206
@@ -251,7 +252,7 @@ int handle_rtp_packet (Messenger *m, uint32_t friendnumber, const uint8_t *data,
251 } 252 }
252 253
253 bwc_feed_avg(session->bwc, length); 254 bwc_feed_avg(session->bwc, length);
254 255
255 if (ntohs(header->tlen) == length - sizeof (struct RTPHeader)) { 256 if (ntohs(header->tlen) == length - sizeof (struct RTPHeader)) {
256 /* The message is sent in single part */ 257 /* The message is sent in single part */
257 258
@@ -267,7 +268,7 @@ int handle_rtp_packet (Messenger *m, uint32_t friendnumber, const uint8_t *data,
267 } 268 }
268 269
269 bwc_add_recv(session->bwc, length); 270 bwc_add_recv(session->bwc, length);
270 271
271 /* Invoke processing of active multiparted message */ 272 /* Invoke processing of active multiparted message */
272 if (session->mp) { 273 if (session->mp) {
273 if (session->mcb) 274 if (session->mcb)
@@ -341,11 +342,11 @@ int handle_rtp_packet (Messenger *m, uint32_t friendnumber, const uint8_t *data,
341 /* Measure missing parts of the old message */ 342 /* Measure missing parts of the old message */
342 bwc_add_lost(session->bwc, 343 bwc_add_lost(session->bwc,
343 (session->mp->header.tlen - session->mp->len) + 344 (session->mp->header.tlen - session->mp->len) +
344 345
345 /* Must account sizes of rtp headers too */ 346 /* Must account sizes of rtp headers too */
346 ((session->mp->header.tlen - session->mp->len) / 347 ((session->mp->header.tlen - session->mp->len) /
347 MAX_CRYPTO_DATA_SIZE) * sizeof(struct RTPHeader) ); 348 MAX_CRYPTO_DATA_SIZE) * sizeof(struct RTPHeader) );
348 349
349 /* Push the previous message for processing */ 350 /* Push the previous message for processing */
350 if (session->mcb) 351 if (session->mcb)
351 session->mcb (session->cs, session->mp); 352 session->mcb (session->cs, session->mp);
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 6a17f55d..9eda3412 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -190,7 +190,7 @@ void toxav_kill(ToxAV *av)
190 return; 190 return;
191 191
192 pthread_mutex_lock(av->mutex); 192 pthread_mutex_lock(av->mutex);
193 193
194 /* To avoid possible deadlocks */ 194 /* To avoid possible deadlocks */
195 while (av->msi && msi_kill(av->msi) != 0) { 195 while (av->msi && msi_kill(av->msi) != 0) {
196 pthread_mutex_unlock(av->mutex); 196 pthread_mutex_unlock(av->mutex);
@@ -206,10 +206,10 @@ void toxav_kill(ToxAV *av)
206 it = call_remove(it); /* This will eventually free av->calls */ 206 it = call_remove(it); /* This will eventually free av->calls */
207 } 207 }
208 } 208 }
209 209
210 pthread_mutex_unlock(av->mutex); 210 pthread_mutex_unlock(av->mutex);
211 pthread_mutex_destroy(av->mutex); 211 pthread_mutex_destroy(av->mutex);
212 212
213 free(av); 213 free(av);
214} 214}
215Tox *toxav_get_tox(const ToxAV *av) 215Tox *toxav_get_tox(const ToxAV *av)
@@ -277,11 +277,11 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint
277 TOXAV_ERR_CALL *error) 277 TOXAV_ERR_CALL *error)
278{ 278{
279 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; 279 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK;
280 280
281 pthread_mutex_lock(av->mutex); 281 pthread_mutex_lock(av->mutex);
282 282
283 if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) 283 if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate))
284 || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))) { 284 || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))) {
285 rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; 285 rc = TOXAV_ERR_CALL_INVALID_BIT_RATE;
286 goto END; 286 goto END;
287 } 287 }
@@ -311,7 +311,7 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint
311 311
312END: 312END:
313 pthread_mutex_unlock(av->mutex); 313 pthread_mutex_unlock(av->mutex);
314 314
315 if (error) 315 if (error)
316 *error = rc; 316 *error = rc;
317 317
@@ -337,7 +337,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
337 } 337 }
338 338
339 if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) 339 if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate))
340 || (video_bit_rate && video_bit_rate_invalid(video_bit_rate)) 340 || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))
341 ) { 341 ) {
342 rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE; 342 rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE;
343 goto END; 343 goto END;
@@ -441,9 +441,10 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co
441 case TOXAV_CALL_CONTROL_CANCEL: { 441 case TOXAV_CALL_CONTROL_CANCEL: {
442 /* Hang up */ 442 /* Hang up */
443 pthread_mutex_lock(call->mutex); 443 pthread_mutex_lock(call->mutex);
444
444 if (msi_hangup(call->msi_call) != 0) { 445 if (msi_hangup(call->msi_call) != 0) {
445 rc = TOXAV_ERR_CALL_CONTROL_SYNC; 446 rc = TOXAV_ERR_CALL_CONTROL_SYNC;
446 pthread_mutex_unlock(call->mutex); 447 pthread_mutex_unlock(call->mutex);
447 goto END; 448 goto END;
448 } 449 }
449 450
@@ -566,18 +567,22 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
566 LOGGER_DEBUG("Audio bitrate already set to: %d", audio_bit_rate); 567 LOGGER_DEBUG("Audio bitrate already set to: %d", audio_bit_rate);
567 } else if (audio_bit_rate == 0) { 568 } else if (audio_bit_rate == 0) {
568 LOGGER_DEBUG("Turned off audio sending"); 569 LOGGER_DEBUG("Turned off audio sending");
570
569 if (msi_change_capabilities(call->msi_call, call->msi_call-> 571 if (msi_change_capabilities(call->msi_call, call->msi_call->
570 self_capabilities ^ msi_CapSAudio) != 0) { 572 self_capabilities ^ msi_CapSAudio) != 0) {
571 pthread_mutex_unlock(av->mutex); 573 pthread_mutex_unlock(av->mutex);
572 rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 574 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
573 goto END; 575 goto END;
574 } 576 }
577
575 /* Audio sending is turned off; notify peer */ 578 /* Audio sending is turned off; notify peer */
576 call->audio_bit_rate = 0; 579 call->audio_bit_rate = 0;
577 } else { 580 } else {
578 pthread_mutex_lock(call->mutex); 581 pthread_mutex_lock(call->mutex);
582
579 if (call->audio_bit_rate == 0) { 583 if (call->audio_bit_rate == 0) {
580 LOGGER_DEBUG("Turned on audio sending"); 584 LOGGER_DEBUG("Turned on audio sending");
585
581 /* The audio has been turned off before this */ 586 /* The audio has been turned off before this */
582 if (msi_change_capabilities(call->msi_call, call-> 587 if (msi_change_capabilities(call->msi_call, call->
583 msi_call->self_capabilities | msi_CapSAudio) != 0) { 588 msi_call->self_capabilities | msi_CapSAudio) != 0) {
@@ -588,6 +593,7 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
588 } 593 }
589 } else 594 } else
590 LOGGER_DEBUG("Set new audio bit rate %d", audio_bit_rate); 595 LOGGER_DEBUG("Set new audio bit rate %d", audio_bit_rate);
596
591 call->audio_bit_rate = audio_bit_rate; 597 call->audio_bit_rate = audio_bit_rate;
592 pthread_mutex_unlock(call->mutex); 598 pthread_mutex_unlock(call->mutex);
593 } 599 }
@@ -600,6 +606,7 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
600 LOGGER_DEBUG("Video bitrate already set to: %d", video_bit_rate); 606 LOGGER_DEBUG("Video bitrate already set to: %d", video_bit_rate);
601 } else if (video_bit_rate == 0) { 607 } else if (video_bit_rate == 0) {
602 LOGGER_DEBUG("Turned off video sending"); 608 LOGGER_DEBUG("Turned off video sending");
609
603 /* Video sending is turned off; notify peer */ 610 /* Video sending is turned off; notify peer */
604 if (msi_change_capabilities(call->msi_call, call->msi_call-> 611 if (msi_change_capabilities(call->msi_call, call->msi_call->
605 self_capabilities ^ msi_CapSVideo) != 0) { 612 self_capabilities ^ msi_CapSVideo) != 0) {
@@ -607,11 +614,14 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
607 rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 614 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
608 goto END; 615 goto END;
609 } 616 }
617
610 call->video_bit_rate = 0; 618 call->video_bit_rate = 0;
611 } else { 619 } else {
612 pthread_mutex_lock(call->mutex); 620 pthread_mutex_lock(call->mutex);
621
613 if (call->video_bit_rate == 0) { 622 if (call->video_bit_rate == 0) {
614 LOGGER_DEBUG("Turned on video sending"); 623 LOGGER_DEBUG("Turned on video sending");
624
615 /* The video has been turned off before this */ 625 /* The video has been turned off before this */
616 if (msi_change_capabilities(call->msi_call, call-> 626 if (msi_change_capabilities(call->msi_call, call->
617 msi_call->self_capabilities | msi_CapSVideo) != 0) { 627 msi_call->self_capabilities | msi_CapSVideo) != 0) {
@@ -622,13 +632,15 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
622 } 632 }
623 } else 633 } else
624 LOGGER_DEBUG("Set new video bit rate %d", video_bit_rate); 634 LOGGER_DEBUG("Set new video bit rate %d", video_bit_rate);
635
625 call->video_bit_rate = video_bit_rate; 636 call->video_bit_rate = video_bit_rate;
626 pthread_mutex_unlock(call->mutex); 637 pthread_mutex_unlock(call->mutex);
627 } 638 }
628 } 639 }
629 640
630 pthread_mutex_unlock(av->mutex); 641 pthread_mutex_unlock(av->mutex);
631END: 642END:
643
632 if (error) 644 if (error)
633 *error = rc; 645 *error = rc;
634 646
@@ -656,7 +668,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc
656 rc = TOXAV_ERR_SEND_FRAME_SYNC; 668 rc = TOXAV_ERR_SEND_FRAME_SYNC;
657 goto END; 669 goto END;
658 } 670 }
659 671
660 call = call_get(av, friend_number); 672 call = call_get(av, friend_number);
661 673
662 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 674 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
@@ -719,6 +731,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc
719 pthread_mutex_unlock(call->mutex_audio); 731 pthread_mutex_unlock(call->mutex_audio);
720 732
721END: 733END:
734
722 if (error) 735 if (error)
723 *error = rc; 736 *error = rc;
724 737
@@ -739,7 +752,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
739 rc = TOXAV_ERR_SEND_FRAME_SYNC; 752 rc = TOXAV_ERR_SEND_FRAME_SYNC;
740 goto END; 753 goto END;
741 } 754 }
742 755
743 call = call_get(av, friend_number); 756 call = call_get(av, friend_number);
744 757
745 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 758 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
@@ -817,6 +830,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
817 pthread_mutex_unlock(call->mutex_video); 830 pthread_mutex_unlock(call->mutex_video);
818 831
819END: 832END:
833
820 if (error) 834 if (error)
821 *error = rc; 835 *error = rc;
822 836
@@ -843,7 +857,7 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb
843 * :: Internal 857 * :: Internal
844 * 858 *
845 ******************************************************************************/ 859 ******************************************************************************/
846void callback_bwc(BWControler* bwc, uint32_t friend_number, float loss, void* user_data) 860void callback_bwc(BWControler *bwc, uint32_t friend_number, float loss, void *user_data)
847{ 861{
848 /* Callback which is called when the internal measure mechanism reported packet loss. 862 /* Callback which is called when the internal measure mechanism reported packet loss.
849 * We report suggested lowered bitrate to an app. If app is sending both audio and video, 863 * We report suggested lowered bitrate to an app. If app is sending both audio and video,
@@ -851,22 +865,23 @@ void callback_bwc(BWControler* bwc, uint32_t friend_number, float loss, void* us
851 * takes more than 90% bandwidth. Otherwise, we report lowered bitrate on audio. 865 * takes more than 90% bandwidth. Otherwise, we report lowered bitrate on audio.
852 * The application may choose to disable video totally if the stream is too bad. 866 * The application may choose to disable video totally if the stream is too bad.
853 */ 867 */
854 868
855 ToxAVCall* call = user_data; 869 ToxAVCall *call = user_data;
856 assert(call); 870 assert(call);
857 871
858 LOGGER_DEBUG("Reported loss of %f%%", loss*100); 872 LOGGER_DEBUG("Reported loss of %f%%", loss * 100);
859 873
860 if (loss < .01f) 874 if (loss < .01f)
861 return; 875 return;
862 876
863 pthread_mutex_lock(call->av->mutex); 877 pthread_mutex_lock(call->av->mutex);
878
864 if (!call->av->bcb.first) { 879 if (!call->av->bcb.first) {
865 pthread_mutex_unlock(call->av->mutex); 880 pthread_mutex_unlock(call->av->mutex);
866 LOGGER_WARNING("No callback to report loss on"); 881 LOGGER_WARNING("No callback to report loss on");
867 return; 882 return;
868 } 883 }
869 884
870 if (call->video_bit_rate) 885 if (call->video_bit_rate)
871 (*call->av->bcb.first) (call->av, friend_number, call->audio_bit_rate, 886 (*call->av->bcb.first) (call->av, friend_number, call->audio_bit_rate,
872 call->video_bit_rate - (call->video_bit_rate * loss), 887 call->video_bit_rate - (call->video_bit_rate * loss),
@@ -875,7 +890,7 @@ void callback_bwc(BWControler* bwc, uint32_t friend_number, float loss, void* us
875 (*call->av->bcb.first) (call->av, friend_number, 890 (*call->av->bcb.first) (call->av, friend_number,
876 call->audio_bit_rate - (call->audio_bit_rate * loss), 891 call->audio_bit_rate - (call->audio_bit_rate * loss),
877 0, call->av->bcb.second); 892 0, call->av->bcb.second);
878 893
879 pthread_mutex_unlock(call->av->mutex); 894 pthread_mutex_unlock(call->av->mutex);
880} 895}
881int callback_invite(void *toxav_inst, MSICall *call) 896int callback_invite(void *toxav_inst, MSICall *call)
@@ -1167,7 +1182,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1167 1182
1168 /* Prepare bwc */ 1183 /* Prepare bwc */
1169 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call); 1184 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call);
1170 1185
1171 { /* Prepare audio */ 1186 { /* Prepare audio */
1172 call->audio.second = ac_new(av, call->friend_number, av->acb.first, av->acb.second); 1187 call->audio.second = ac_new(av, call->friend_number, av->acb.first, av->acb.second);
1173 1188
@@ -1236,7 +1251,7 @@ void call_kill_transmission(ToxAVCall *call)
1236 pthread_mutex_unlock(call->mutex); 1251 pthread_mutex_unlock(call->mutex);
1237 1252
1238 bwc_kill(call->bwc); 1253 bwc_kill(call->bwc);
1239 1254
1240 rtp_kill(call->audio.first); 1255 rtp_kill(call->audio.first);
1241 ac_kill(call->audio.second); 1256 ac_kill(call->audio.second);
1242 call->audio.first = NULL; 1257 call->audio.first = NULL;
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 5c5195b3..08a6d265 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -1,5 +1,5 @@
1/* toxav.h 1/* toxav.h
2 * 2 *
3 * Copyright (C) 2013-2015 Tox project All Rights Reserved. 3 * Copyright (C) 2013-2015 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 */ 20 */
21 21
22#ifndef TOXAV_H 22#ifndef TOXAV_H
@@ -31,37 +31,37 @@ extern "C" {
31#endif 31#endif
32 32
33/** \page av Public audio/video API for Tox clients. 33/** \page av Public audio/video API for Tox clients.
34 * 34 *
35 * This API can handle multiple calls. Each call has its state, in very rare 35 * This API can handle multiple calls. Each call has its state, in very rare
36 * occasions the library can change the state of the call without apps knowledge. 36 * occasions the library can change the state of the call without apps knowledge.
37 * 37 *
38 */ 38 */
39/** \subsection events Events and callbacks 39/** \subsection events Events and callbacks
40 * 40 *
41 * As in Core API, events are handled by callbacks. One callback can be 41 * As in Core API, events are handled by callbacks. One callback can be
42 * registered per event. All events have a callback function type named 42 * registered per event. All events have a callback function type named
43 * `toxav_{event}_cb` and a function to register it named `toxav_callback_{event}`. 43 * `toxav_{event}_cb` and a function to register it named `toxav_callback_{event}`.
44 * Passing a NULL callback will result in no callback being registered for that 44 * Passing a NULL callback will result in no callback being registered for that
45 * event. Only one callback per event can be registered, so if a client needs 45 * event. Only one callback per event can be registered, so if a client needs
46 * multiple event listeners, it needs to implement the dispatch functionality 46 * multiple event listeners, it needs to implement the dispatch functionality
47 * itself. Unlike Core API, lack of some event handlers will cause the the 47 * itself. Unlike Core API, lack of some event handlers will cause the the
48 * library to drop calls before they are started. Hanging up call from a 48 * library to drop calls before they are started. Hanging up call from a
49 * callback causes undefined behaviour. 49 * callback causes undefined behaviour.
50 * 50 *
51 */ 51 */
52/** \subsection threading Threading implications 52/** \subsection threading Threading implications
53 * 53 *
54 * Unlike the Core API, this API is fully thread-safe. The library will ensure 54 * Unlike the Core API, this API is fully thread-safe. The library will ensure
55 * the proper synchronization of parallel calls. 55 * the proper synchronization of parallel calls.
56 * 56 *
57 * A common way to run ToxAV (multiple or single instance) is to have a thread, 57 * A common way to run ToxAV (multiple or single instance) is to have a thread,
58 * separate from tox instance thread, running a simple toxav_iterate loop, 58 * separate from tox instance thread, running a simple toxav_iterate loop,
59 * sleeping for toxav_iteration_interval * milliseconds on each iteration. 59 * sleeping for toxav_iteration_interval * milliseconds on each iteration.
60 * 60 *
61 * An important thing to note is that events are triggered from both tox and 61 * An important thing to note is that events are triggered from both tox and
62 * toxav thread (see above). Audio and video receive frame events are triggered 62 * toxav thread (see above). Audio and video receive frame events are triggered
63 * from toxav thread while all the other events are triggered from tox thread. 63 * from toxav thread while all the other events are triggered from tox thread.
64 * 64 *
65 * Tox thread has priority with mutex mechanisms. Any api function can 65 * Tox thread has priority with mutex mechanisms. Any api function can
66 * fail if mutexes are held by tox thread in which case they will set SYNC 66 * fail if mutexes are held by tox thread in which case they will set SYNC
67 * error code. 67 * error code.
@@ -81,9 +81,9 @@ typedef struct Tox Tox;
81 * The ToxAV instance type. Each ToxAV instance can be bound to only one Tox 81 * The ToxAV instance type. Each ToxAV instance can be bound to only one Tox
82 * instance, and Tox instance can have only one ToxAV instance. One must make 82 * instance, and Tox instance can have only one ToxAV instance. One must make
83 * sure to close ToxAV instance prior closing Tox instance otherwise undefined 83 * sure to close ToxAV instance prior closing Tox instance otherwise undefined
84 * behaviour occurs. Upon closing of ToxAV instance, all active calls will be 84 * behaviour occurs. Upon closing of ToxAV instance, all active calls will be
85 * forcibly terminated without notifying peers. 85 * forcibly terminated without notifying peers.
86 * 86 *
87 */ 87 */
88#ifndef TOXAV_DEFINED 88#ifndef TOXAV_DEFINED
89#define TOXAV_DEFINED 89#define TOXAV_DEFINED
@@ -164,28 +164,28 @@ bool toxav_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch)
164 164
165 165
166/******************************************************************************* 166/*******************************************************************************
167 * 167 *
168 * :: Creation and destruction 168 * :: Creation and destruction
169 * 169 *
170 ******************************************************************************/ 170 ******************************************************************************/
171typedef enum TOXAV_ERR_NEW { 171typedef enum TOXAV_ERR_NEW {
172 /** 172 /**
173 * The function returned successfully. 173 * The function returned successfully.
174 */ 174 */
175 TOXAV_ERR_NEW_OK, 175 TOXAV_ERR_NEW_OK,
176 /** 176 /**
177 * One of the arguments to the function was NULL when it was not expected. 177 * One of the arguments to the function was NULL when it was not expected.
178 */ 178 */
179 TOXAV_ERR_NEW_NULL, 179 TOXAV_ERR_NEW_NULL,
180 /** 180 /**
181 * Memory allocation failure while trying to allocate structures required for 181 * Memory allocation failure while trying to allocate structures required for
182 * the A/V session. 182 * the A/V session.
183 */ 183 */
184 TOXAV_ERR_NEW_MALLOC, 184 TOXAV_ERR_NEW_MALLOC,
185 /** 185 /**
186 * Attempted to create a second session for the same Tox instance. 186 * Attempted to create a second session for the same Tox instance.
187 */ 187 */
188 TOXAV_ERR_NEW_MULTIPLE, 188 TOXAV_ERR_NEW_MULTIPLE,
189} TOXAV_ERR_NEW; 189} TOXAV_ERR_NEW;
190 190
191/** 191/**
@@ -209,7 +209,7 @@ Tox *toxav_get_tox(const ToxAV *toxAV);
209 209
210 210
211/******************************************************************************* 211/*******************************************************************************
212 * 212 *
213 * :: A/V event loop 213 * :: A/V event loop
214 * 214 *
215 ******************************************************************************/ 215 ******************************************************************************/
@@ -221,48 +221,48 @@ uint32_t toxav_iteration_interval(const ToxAV *toxAV);
221 221
222/** 222/**
223 * Main loop for the session. This function needs to be called in intervals of 223 * Main loop for the session. This function needs to be called in intervals of
224 * toxav_iteration_interval() milliseconds. It is best called in the separate 224 * toxav_iteration_interval() milliseconds. It is best called in the separate
225 * thread from tox_iterate. 225 * thread from tox_iterate.
226 */ 226 */
227void toxav_iterate(ToxAV *toxAV); 227void toxav_iterate(ToxAV *toxAV);
228 228
229 229
230/******************************************************************************* 230/*******************************************************************************
231 * 231 *
232 * :: Call setup 232 * :: Call setup
233 * 233 *
234 ******************************************************************************/ 234 ******************************************************************************/
235typedef enum TOXAV_ERR_CALL { 235typedef enum TOXAV_ERR_CALL {
236 /** 236 /**
237 * The function returned successfully. 237 * The function returned successfully.
238 */ 238 */
239 TOXAV_ERR_CALL_OK, 239 TOXAV_ERR_CALL_OK,
240 /** 240 /**
241 * A resource allocation error occurred while trying to create the structures 241 * A resource allocation error occurred while trying to create the structures
242 * required for the call. 242 * required for the call.
243 */ 243 */
244 TOXAV_ERR_CALL_MALLOC, 244 TOXAV_ERR_CALL_MALLOC,
245 /** 245 /**
246 * Synchronization error occurred. 246 * Synchronization error occurred.
247 */ 247 */
248 TOXAV_ERR_CALL_SYNC, 248 TOXAV_ERR_CALL_SYNC,
249 /** 249 /**
250 * The friend number did not designate a valid friend. 250 * The friend number did not designate a valid friend.
251 */ 251 */
252 TOXAV_ERR_CALL_FRIEND_NOT_FOUND, 252 TOXAV_ERR_CALL_FRIEND_NOT_FOUND,
253 /** 253 /**
254 * The friend was valid, but not currently connected. 254 * The friend was valid, but not currently connected.
255 */ 255 */
256 TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED, 256 TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED,
257 /** 257 /**
258 * Attempted to call a friend while already in an audio or video call with 258 * Attempted to call a friend while already in an audio or video call with
259 * them. 259 * them.
260 */ 260 */
261 TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL, 261 TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL,
262 /** 262 /**
263 * Audio or video bit rate is invalid. 263 * Audio or video bit rate is invalid.
264 */ 264 */
265 TOXAV_ERR_CALL_INVALID_BIT_RATE, 265 TOXAV_ERR_CALL_INVALID_BIT_RATE,
266} TOXAV_ERR_CALL; 266} TOXAV_ERR_CALL;
267 267
268/** 268/**
@@ -270,7 +270,7 @@ typedef enum TOXAV_ERR_CALL {
270 * 270 *
271 * It is the client's responsibility to stop ringing after a certain timeout, 271 * It is the client's responsibility to stop ringing after a certain timeout,
272 * if such behaviour is desired. If the client does not stop ringing, the 272 * if such behaviour is desired. If the client does not stop ringing, the
273 * library will not stop until the friend is disconnected. Audio and video 273 * library will not stop until the friend is disconnected. Audio and video
274 * receiving are both enabled by default. 274 * receiving are both enabled by default.
275 * 275 *
276 * @param friend_number The friend number of the friend that should be called. 276 * @param friend_number The friend number of the friend that should be called.
@@ -284,7 +284,7 @@ bool toxav_call(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate,
284 284
285/** 285/**
286 * The function type for the call callback. 286 * The function type for the call callback.
287 * 287 *
288 * @param friend_number The friend number from which the call is incoming. 288 * @param friend_number The friend number from which the call is incoming.
289 * @param audio_enabled True if friend is sending audio. 289 * @param audio_enabled True if friend is sending audio.
290 * @param video_enabled True if friend is sending video. 290 * @param video_enabled True if friend is sending video.
@@ -299,33 +299,33 @@ typedef void toxav_call_cb(ToxAV *toxAV, uint32_t friend_number, bool audio_enab
299void toxav_callback_call(ToxAV *toxAV, toxav_call_cb *callback, void *user_data); 299void toxav_callback_call(ToxAV *toxAV, toxav_call_cb *callback, void *user_data);
300 300
301typedef enum TOXAV_ERR_ANSWER { 301typedef enum TOXAV_ERR_ANSWER {
302 /** 302 /**
303 * The function returned successfully. 303 * The function returned successfully.
304 */ 304 */
305 TOXAV_ERR_ANSWER_OK, 305 TOXAV_ERR_ANSWER_OK,
306 /** 306 /**
307 * Synchronization error occurred. 307 * Synchronization error occurred.
308 */ 308 */
309 TOXAV_ERR_ANSWER_SYNC, 309 TOXAV_ERR_ANSWER_SYNC,
310 /** 310 /**
311 * Failed to initialize codecs for call session. Note that codec initiation 311 * Failed to initialize codecs for call session. Note that codec initiation
312 * will fail if there is no receive callback registered for either audio or 312 * will fail if there is no receive callback registered for either audio or
313 * video. 313 * video.
314 */ 314 */
315 TOXAV_ERR_ANSWER_CODEC_INITIALIZATION, 315 TOXAV_ERR_ANSWER_CODEC_INITIALIZATION,
316 /** 316 /**
317 * The friend number did not designate a valid friend. 317 * The friend number did not designate a valid friend.
318 */ 318 */
319 TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND, 319 TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND,
320 /** 320 /**
321 * The friend was valid, but they are not currently trying to initiate a call. 321 * The friend was valid, but they are not currently trying to initiate a call.
322 * This is also returned if this client is already in a call with the friend. 322 * This is also returned if this client is already in a call with the friend.
323 */ 323 */
324 TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING, 324 TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING,
325 /** 325 /**
326 * Audio or video bit rate is invalid. 326 * Audio or video bit rate is invalid.
327 */ 327 */
328 TOXAV_ERR_ANSWER_INVALID_BIT_RATE, 328 TOXAV_ERR_ANSWER_INVALID_BIT_RATE,
329} TOXAV_ERR_ANSWER; 329} TOXAV_ERR_ANSWER;
330 330
331/** 331/**
@@ -341,44 +341,45 @@ typedef enum TOXAV_ERR_ANSWER {
341 * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable 341 * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable
342 * video sending. 342 * video sending.
343 */ 343 */
344bool toxav_answer(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER *error); 344bool toxav_answer(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
345 TOXAV_ERR_ANSWER *error);
345 346
346 347
347/******************************************************************************* 348/*******************************************************************************
348 * 349 *
349 * :: Call state graph 350 * :: Call state graph
350 * 351 *
351 ******************************************************************************/ 352 ******************************************************************************/
352enum TOXAV_FRIEND_CALL_STATE { 353enum TOXAV_FRIEND_CALL_STATE {
353 /** 354 /**
354 * Set by the AV core if an error occurred on the remote end or if friend 355 * Set by the AV core if an error occurred on the remote end or if friend
355 * timed out. This is the final state after which no more state 356 * timed out. This is the final state after which no more state
356 * transitions can occur for the call. This call state will never be triggered 357 * transitions can occur for the call. This call state will never be triggered
357 * in combination with other call states. 358 * in combination with other call states.
358 */ 359 */
359 TOXAV_FRIEND_CALL_STATE_ERROR = 1, 360 TOXAV_FRIEND_CALL_STATE_ERROR = 1,
360 /** 361 /**
361 * The call has finished. This is the final state after which no more state 362 * The call has finished. This is the final state after which no more state
362 * transitions can occur for the call. This call state will never be 363 * transitions can occur for the call. This call state will never be
363 * triggered in combination with other call states. 364 * triggered in combination with other call states.
364 */ 365 */
365 TOXAV_FRIEND_CALL_STATE_FINISHED = 2, 366 TOXAV_FRIEND_CALL_STATE_FINISHED = 2,
366 /** 367 /**
367 * The flag that marks that friend is sending audio. 368 * The flag that marks that friend is sending audio.
368 */ 369 */
369 TOXAV_FRIEND_CALL_STATE_SENDING_A = 4, 370 TOXAV_FRIEND_CALL_STATE_SENDING_A = 4,
370 /** 371 /**
371 * The flag that marks that friend is sending video. 372 * The flag that marks that friend is sending video.
372 */ 373 */
373 TOXAV_FRIEND_CALL_STATE_SENDING_V = 8, 374 TOXAV_FRIEND_CALL_STATE_SENDING_V = 8,
374 /** 375 /**
375 * The flag that marks that friend is receiving audio. 376 * The flag that marks that friend is receiving audio.
376 */ 377 */
377 TOXAV_FRIEND_CALL_STATE_ACCEPTING_A = 16, 378 TOXAV_FRIEND_CALL_STATE_ACCEPTING_A = 16,
378 /** 379 /**
379 * The flag that marks that friend is receiving video. 380 * The flag that marks that friend is receiving video.
380 */ 381 */
381 TOXAV_FRIEND_CALL_STATE_ACCEPTING_V = 32, 382 TOXAV_FRIEND_CALL_STATE_ACCEPTING_V = 32,
382}; 383};
383 384
384/** 385/**
@@ -399,70 +400,70 @@ typedef void toxav_call_state_cb(ToxAV *toxAV, uint32_t friend_number, uint32_t
399void toxav_callback_call_state(ToxAV *toxAV, toxav_call_state_cb *callback, void *user_data); 400void toxav_callback_call_state(ToxAV *toxAV, toxav_call_state_cb *callback, void *user_data);
400 401
401/******************************************************************************* 402/*******************************************************************************
402 * 403 *
403 * :: Call control 404 * :: Call control
404 * 405 *
405 ******************************************************************************/ 406 ******************************************************************************/
406typedef enum TOXAV_CALL_CONTROL { 407typedef enum TOXAV_CALL_CONTROL {
407 /** 408 /**
408 * Resume a previously paused call. Only valid if the pause was caused by this 409 * Resume a previously paused call. Only valid if the pause was caused by this
409 * client, if not, this control is ignored. Not valid before the call is accepted. 410 * client, if not, this control is ignored. Not valid before the call is accepted.
410 */ 411 */
411 TOXAV_CALL_CONTROL_RESUME, 412 TOXAV_CALL_CONTROL_RESUME,
412 /** 413 /**
413 * Put a call on hold. Not valid before the call is accepted. 414 * Put a call on hold. Not valid before the call is accepted.
414 */ 415 */
415 TOXAV_CALL_CONTROL_PAUSE, 416 TOXAV_CALL_CONTROL_PAUSE,
416 /** 417 /**
417 * Reject a call if it was not answered, yet. Cancel a call after it was 418 * Reject a call if it was not answered, yet. Cancel a call after it was
418 * answered. 419 * answered.
419 */ 420 */
420 TOXAV_CALL_CONTROL_CANCEL, 421 TOXAV_CALL_CONTROL_CANCEL,
421 /** 422 /**
422 * Request that the friend stops sending audio. Regardless of the friend's 423 * Request that the friend stops sending audio. Regardless of the friend's
423 * compliance, this will cause the audio_receive_frame event to stop being 424 * compliance, this will cause the audio_receive_frame event to stop being
424 * triggered on receiving an audio frame from the friend. 425 * triggered on receiving an audio frame from the friend.
425 */ 426 */
426 TOXAV_CALL_CONTROL_MUTE_AUDIO, 427 TOXAV_CALL_CONTROL_MUTE_AUDIO,
427 /** 428 /**
428 * Calling this control will notify client to start sending audio again. 429 * Calling this control will notify client to start sending audio again.
429 */ 430 */
430 TOXAV_CALL_CONTROL_UNMUTE_AUDIO, 431 TOXAV_CALL_CONTROL_UNMUTE_AUDIO,
431 /** 432 /**
432 * Request that the friend stops sending video. Regardless of the friend's 433 * Request that the friend stops sending video. Regardless of the friend's
433 * compliance, this will cause the video_receive_frame event to stop being 434 * compliance, this will cause the video_receive_frame event to stop being
434 * triggered on receiving a video frame from the friend. 435 * triggered on receiving a video frame from the friend.
435 */ 436 */
436 TOXAV_CALL_CONTROL_HIDE_VIDEO, 437 TOXAV_CALL_CONTROL_HIDE_VIDEO,
437 /** 438 /**
438 * Calling this control will notify client to start sending video again. 439 * Calling this control will notify client to start sending video again.
439 */ 440 */
440 TOXAV_CALL_CONTROL_SHOW_VIDEO, 441 TOXAV_CALL_CONTROL_SHOW_VIDEO,
441} TOXAV_CALL_CONTROL; 442} TOXAV_CALL_CONTROL;
442 443
443typedef enum TOXAV_ERR_CALL_CONTROL { 444typedef enum TOXAV_ERR_CALL_CONTROL {
444 /** 445 /**
445 * The function returned successfully. 446 * The function returned successfully.
446 */ 447 */
447 TOXAV_ERR_CALL_CONTROL_OK, 448 TOXAV_ERR_CALL_CONTROL_OK,
448 /** 449 /**
449 * Synchronization error occurred. 450 * Synchronization error occurred.
450 */ 451 */
451 TOXAV_ERR_CALL_CONTROL_SYNC, 452 TOXAV_ERR_CALL_CONTROL_SYNC,
452 /** 453 /**
453 * The friend_number passed did not designate a valid friend. 454 * The friend_number passed did not designate a valid friend.
454 */ 455 */
455 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND, 456 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND,
456 /** 457 /**
457 * This client is currently not in a call with the friend. Before the call is 458 * This client is currently not in a call with the friend. Before the call is
458 * answered, only CANCEL is a valid control. 459 * answered, only CANCEL is a valid control.
459 */ 460 */
460 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL, 461 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL,
461 /** 462 /**
462 * Happens if user tried to pause an already paused call or if trying to 463 * Happens if user tried to pause an already paused call or if trying to
463 * resume a call that is not paused. 464 * resume a call that is not paused.
464 */ 465 */
465 TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION, 466 TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION,
466} TOXAV_ERR_CALL_CONTROL; 467} TOXAV_ERR_CALL_CONTROL;
467 468
468/** 469/**
@@ -474,39 +475,40 @@ typedef enum TOXAV_ERR_CALL_CONTROL {
474 * 475 *
475 * @return true on success. 476 * @return true on success.
476 */ 477 */
477bool toxav_call_control(ToxAV *toxAV, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error); 478bool toxav_call_control(ToxAV *toxAV, uint32_t friend_number, TOXAV_CALL_CONTROL control,
479 TOXAV_ERR_CALL_CONTROL *error);
478 480
479 481
480/******************************************************************************* 482/*******************************************************************************
481 * 483 *
482 * :: Controlling bit rates 484 * :: Controlling bit rates
483 * 485 *
484 ******************************************************************************/ 486 ******************************************************************************/
485typedef enum TOXAV_ERR_BIT_RATE_SET { 487typedef enum TOXAV_ERR_BIT_RATE_SET {
486 /** 488 /**
487 * The function returned successfully. 489 * The function returned successfully.
488 */ 490 */
489 TOXAV_ERR_BIT_RATE_SET_OK, 491 TOXAV_ERR_BIT_RATE_SET_OK,
490 /** 492 /**
491 * Synchronization error occurred. 493 * Synchronization error occurred.
492 */ 494 */
493 TOXAV_ERR_BIT_RATE_SET_SYNC, 495 TOXAV_ERR_BIT_RATE_SET_SYNC,
494 /** 496 /**
495 * The audio bit rate passed was not one of the supported values. 497 * The audio bit rate passed was not one of the supported values.
496 */ 498 */
497 TOXAV_ERR_BIT_RATE_SET_INVALID_AUDIO_BIT_RATE, 499 TOXAV_ERR_BIT_RATE_SET_INVALID_AUDIO_BIT_RATE,
498 /** 500 /**
499 * The video bit rate passed was not one of the supported values. 501 * The video bit rate passed was not one of the supported values.
500 */ 502 */
501 TOXAV_ERR_BIT_RATE_SET_INVALID_VIDEO_BIT_RATE, 503 TOXAV_ERR_BIT_RATE_SET_INVALID_VIDEO_BIT_RATE,
502 /** 504 /**
503 * The friend_number passed did not designate a valid friend. 505 * The friend_number passed did not designate a valid friend.
504 */ 506 */
505 TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND, 507 TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND,
506 /** 508 /**
507 * This client is currently not in a call with the friend. 509 * This client is currently not in a call with the friend.
508 */ 510 */
509 TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL, 511 TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL,
510} TOXAV_ERR_BIT_RATE_SET; 512} TOXAV_ERR_BIT_RATE_SET;
511 513
512/** 514/**
@@ -518,22 +520,23 @@ typedef enum TOXAV_ERR_BIT_RATE_SET {
518 * audio sending. Set to -1 to leave unchanged. 520 * audio sending. Set to -1 to leave unchanged.
519 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable 521 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable
520 * video sending. Set to -1 to leave unchanged. 522 * video sending. Set to -1 to leave unchanged.
521 * 523 *
522 */ 524 */
523bool toxav_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, int32_t audio_bit_rate, 525bool toxav_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, int32_t audio_bit_rate,
524 int32_t video_bit_rate, TOXAV_ERR_BIT_RATE_SET *error); 526 int32_t video_bit_rate, TOXAV_ERR_BIT_RATE_SET *error);
525 527
526/** 528/**
527 * The function type for the bit_rate_status callback. The event is triggered 529 * The function type for the bit_rate_status callback. The event is triggered
528 * when the network becomes too saturated for current bit rates at which 530 * when the network becomes too saturated for current bit rates at which
529 * point core suggests new bit rates. 531 * point core suggests new bit rates.
530 * 532 *
531 * @param friend_number The friend number of the friend for which to set the 533 * @param friend_number The friend number of the friend for which to set the
532 * bit rate. 534 * bit rate.
533 * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec. 535 * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec.
534 * @param video_bit_rate Suggested maximum video bit rate in Kb/sec. 536 * @param video_bit_rate Suggested maximum video bit rate in Kb/sec.
535 */ 537 */
536typedef void toxav_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, void *user_data); 538typedef void toxav_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate,
539 uint32_t video_bit_rate, void *user_data);
537 540
538/** 541/**
539 * Set the callback for the `bit_rate_status` event. Pass NULL to unset. 542 * Set the callback for the `bit_rate_status` event. Pass NULL to unset.
@@ -543,46 +546,46 @@ void toxav_callback_bit_rate_status(ToxAV *toxAV, toxav_bit_rate_status_cb *call
543 546
544 547
545/******************************************************************************* 548/*******************************************************************************
546 * 549 *
547 * :: A/V sending 550 * :: A/V sending
548 * 551 *
549 ******************************************************************************/ 552 ******************************************************************************/
550typedef enum TOXAV_ERR_SEND_FRAME { 553typedef enum TOXAV_ERR_SEND_FRAME {
551 /** 554 /**
552 * The function returned successfully. 555 * The function returned successfully.
553 */ 556 */
554 TOXAV_ERR_SEND_FRAME_OK, 557 TOXAV_ERR_SEND_FRAME_OK,
555 /** 558 /**
556 * In case of video, one of Y, U, or V was NULL. In case of audio, the samples 559 * In case of video, one of Y, U, or V was NULL. In case of audio, the samples
557 * data pointer was NULL. 560 * data pointer was NULL.
558 */ 561 */
559 TOXAV_ERR_SEND_FRAME_NULL, 562 TOXAV_ERR_SEND_FRAME_NULL,
560 /** 563 /**
561 * The friend_number passed did not designate a valid friend. 564 * The friend_number passed did not designate a valid friend.
562 */ 565 */
563 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND, 566 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND,
564 /** 567 /**
565 * This client is currently not in a call with the friend. 568 * This client is currently not in a call with the friend.
566 */ 569 */
567 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL, 570 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL,
568 /** 571 /**
569 * Synchronization error occurred. 572 * Synchronization error occurred.
570 */ 573 */
571 TOXAV_ERR_SEND_FRAME_SYNC, 574 TOXAV_ERR_SEND_FRAME_SYNC,
572 /** 575 /**
573 * One of the frame parameters was invalid. E.g. the resolution may be too 576 * One of the frame parameters was invalid. E.g. the resolution may be too
574 * small or too large, or the audio sampling rate may be unsupported. 577 * small or too large, or the audio sampling rate may be unsupported.
575 */ 578 */
576 TOXAV_ERR_SEND_FRAME_INVALID, 579 TOXAV_ERR_SEND_FRAME_INVALID,
577 /** 580 /**
578 * Either friend turned off audio or video receiving or we turned off sending 581 * Either friend turned off audio or video receiving or we turned off sending
579 * for the said payload. 582 * for the said payload.
580 */ 583 */
581 TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED, 584 TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED,
582 /** 585 /**
583 * Failed to push frame through rtp interface. 586 * Failed to push frame through rtp interface.
584 */ 587 */
585 TOXAV_ERR_SEND_FRAME_RTP_FAILED, 588 TOXAV_ERR_SEND_FRAME_RTP_FAILED,
586} TOXAV_ERR_SEND_FRAME; 589} TOXAV_ERR_SEND_FRAME;
587 590
588/** 591/**
@@ -605,7 +608,7 @@ typedef enum TOXAV_ERR_SEND_FRAME {
605 * @param sampling_rate Audio sampling rate used in this frame. Valid sampling 608 * @param sampling_rate Audio sampling rate used in this frame. Valid sampling
606 * rates are 8000, 12000, 16000, 24000, or 48000. 609 * rates are 8000, 12000, 16000, 24000, or 48000.
607 */ 610 */
608bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, 611bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm,
609 size_t sample_count, uint8_t channels, uint32_t sampling_rate, 612 size_t sample_count, uint8_t channels, uint32_t sampling_rate,
610 TOXAV_ERR_SEND_FRAME *error); 613 TOXAV_ERR_SEND_FRAME *error);
611 614
@@ -624,13 +627,13 @@ bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t
624 * @param u U (Chroma) plane data. 627 * @param u U (Chroma) plane data.
625 * @param v V (Chroma) plane data. 628 * @param v V (Chroma) plane data.
626 */ 629 */
627bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width, 630bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width,
628 uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, 631 uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v,
629 TOXAV_ERR_SEND_FRAME *error); 632 TOXAV_ERR_SEND_FRAME *error);
630 633
631 634
632/******************************************************************************* 635/*******************************************************************************
633 * 636 *
634 * :: A/V receiving 637 * :: A/V receiving
635 * 638 *
636 ******************************************************************************/ 639 ******************************************************************************/
@@ -638,7 +641,7 @@ bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width
638 * The function type for the audio_receive_frame callback. The callback can be 641 * The function type for the audio_receive_frame callback. The callback can be
639 * called multiple times per single iteration depending on the amount of queued 642 * called multiple times per single iteration depending on the amount of queued
640 * frames in the buffer. The received format is the same as in send function. 643 * frames in the buffer. The received format is the same as in send function.
641 * 644 *
642 * @param friend_number The friend number of the friend who sent an audio frame. 645 * @param friend_number The friend number of the friend who sent an audio frame.
643 * @param pcm An array of audio samples (sample_count * channels elements). 646 * @param pcm An array of audio samples (sample_count * channels elements).
644 * @param sample_count The number of audio samples per channel in the PCM array. 647 * @param sample_count The number of audio samples per channel in the PCM array.
@@ -647,8 +650,8 @@ bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width
647 * 650 *
648 */ 651 */
649typedef void toxav_audio_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, 652typedef void toxav_audio_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm,
650 size_t sample_count, uint8_t channels, uint32_t sampling_rate, 653 size_t sample_count, uint8_t channels, uint32_t sampling_rate,
651 void *user_data); 654 void *user_data);
652 655
653/** 656/**
654 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. 657 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset.
@@ -662,24 +665,24 @@ void toxav_callback_audio_receive_frame(ToxAV *toxAV, toxav_audio_receive_frame_
662 * @param friend_number The friend number of the friend who sent a video frame. 665 * @param friend_number The friend number of the friend who sent a video frame.
663 * @param width Width of the frame in pixels. 666 * @param width Width of the frame in pixels.
664 * @param height Height of the frame in pixels. 667 * @param height Height of the frame in pixels.
665 * @param y 668 * @param y
666 * @param u 669 * @param u
667 * @param v Plane data. 670 * @param v Plane data.
668 * The size of plane data is derived from width and height where 671 * The size of plane data is derived from width and height where
669 * Y = MAX(width, abs(ystride)) * height, 672 * Y = MAX(width, abs(ystride)) * height,
670 * U = MAX(width/2, abs(ustride)) * (height/2) and 673 * U = MAX(width/2, abs(ustride)) * (height/2) and
671 * V = MAX(width/2, abs(vstride)) * (height/2). 674 * V = MAX(width/2, abs(vstride)) * (height/2).
672 * @param ystride 675 * @param ystride
673 * @param ustride 676 * @param ustride
674 * @param vstride Strides data. Strides represent padding for each plane 677 * @param vstride Strides data. Strides represent padding for each plane
675 * that may or may not be present. You must handle strides in 678 * that may or may not be present. You must handle strides in
676 * your image processing code. Strides are negative if the 679 * your image processing code. Strides are negative if the
677 * image is bottom-up hence why you MUST abs() it when 680 * image is bottom-up hence why you MUST abs() it when
678 * calculating plane buffer size. 681 * calculating plane buffer size.
679 */ 682 */
680typedef void toxav_video_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, uint16_t width, 683typedef void toxav_video_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, uint16_t width,
681 uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, 684 uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v,
682 int32_t ystride, int32_t ustride, int32_t vstride, void *user_data); 685 int32_t ystride, int32_t ustride, int32_t vstride, void *user_data);
683 686
684/** 687/**
685 * Set the callback for the `video_receive_frame` event. Pass NULL to unset. 688 * Set the callback for the `video_receive_frame` event. Pass NULL to unset.
@@ -700,7 +703,7 @@ void toxav_callback_video_receive_frame(ToxAV *toxAV, toxav_video_receive_frame_
700 * 703 *
701 * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). 704 * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
702 */ 705 */
703int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void*, int, int, const int16_t *, unsigned int, uint8_t, 706int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, int, int, const int16_t *, unsigned int, uint8_t,
704 unsigned int, void *), void *userdata); 707 unsigned int, void *), void *userdata);
705 708
706/* Join a AV group (you need to have been invited first.) 709/* Join a AV group (you need to have been invited first.)
@@ -714,7 +717,7 @@ int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void*, int, int, con
714 * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). 717 * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
715 */ 718 */
716int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length, 719int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length,
717 void (*audio_callback)(void*, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata); 720 void (*audio_callback)(void *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata);
718 721
719/* Send audio to the group chat. 722/* Send audio to the group chat.
720 * 723 *
diff --git a/toxav/video.c b/toxav/video.c
index acc1852b..8a832201 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -207,43 +207,40 @@ int vc_queue_message(void *vcp, struct RTPMessage *msg)
207 207
208 return 0; 208 return 0;
209} 209}
210int vc_reconfigure_encoder(VCSession* vc, uint32_t bit_rate, uint16_t width, uint16_t height) 210int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height)
211{ 211{
212 if (!vc) 212 if (!vc)
213 return -1; 213 return -1;
214 214
215 vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc; 215 vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc;
216 int rc; 216 int rc;
217 217
218 if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) 218 if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height)
219 return 0; /* Nothing changed */ 219 return 0; /* Nothing changed */
220 220
221 if (cfg.g_w == width && cfg.g_h == height) 221 if (cfg.g_w == width && cfg.g_h == height) {
222 {
223 /* Only bit rate changed */ 222 /* Only bit rate changed */
224 cfg.rc_target_bitrate = bit_rate; 223 cfg.rc_target_bitrate = bit_rate;
225 224
226 rc = vpx_codec_enc_config_set(vc->encoder, &cfg); 225 rc = vpx_codec_enc_config_set(vc->encoder, &cfg);
227 226
228 if (rc != VPX_CODEC_OK) { 227 if (rc != VPX_CODEC_OK) {
229 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); 228 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
230 return -1; 229 return -1;
231 } 230 }
232 } 231 } else {
233 else
234 {
235 /* Resolution is changed, must reinitialize encoder since libvpx v1.4 doesn't support 232 /* Resolution is changed, must reinitialize encoder since libvpx v1.4 doesn't support
236 * reconfiguring encoder to use resolutions greater than initially set. 233 * reconfiguring encoder to use resolutions greater than initially set.
237 */ 234 */
238 235
239 LOGGER_DEBUG("Have to reinitialize vpx encoder on session %p", vc); 236 LOGGER_DEBUG("Have to reinitialize vpx encoder on session %p", vc);
240 237
241 cfg.rc_target_bitrate = bit_rate; 238 cfg.rc_target_bitrate = bit_rate;
242 cfg.g_w = width; 239 cfg.g_w = width;
243 cfg.g_h = height; 240 cfg.g_h = height;
244 241
245 vpx_codec_ctx_t new_c; 242 vpx_codec_ctx_t new_c;
246 243
247 rc = vpx_codec_enc_init(&new_c, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 244 rc = vpx_codec_enc_init(&new_c, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
248 245
249 if (rc != VPX_CODEC_OK) { 246 if (rc != VPX_CODEC_OK) {
@@ -258,7 +255,7 @@ int vc_reconfigure_encoder(VCSession* vc, uint32_t bit_rate, uint16_t width, uin
258 vpx_codec_destroy(&new_c); 255 vpx_codec_destroy(&new_c);
259 return -1; 256 return -1;
260 } 257 }
261 258
262 vpx_codec_destroy(vc->encoder); 259 vpx_codec_destroy(vc->encoder);
263 memcpy(vc->encoder, &new_c, sizeof(new_c)); 260 memcpy(vc->encoder, &new_c, sizeof(new_c));
264 } 261 }
diff --git a/toxav/video.h b/toxav/video.h
index 51f34318..fb836a35 100644
--- a/toxav/video.h
+++ b/toxav/video.h
@@ -58,7 +58,7 @@ typedef struct VCSession_s {
58 pthread_mutex_t queue_mutex[1]; 58 pthread_mutex_t queue_mutex[1];
59} VCSession; 59} VCSession;
60 60
61VCSession *vc_new(ToxAV* av, uint32_t friend_number, toxav_video_receive_frame_cb* cb, void* cb_data); 61VCSession *vc_new(ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data);
62void vc_kill(VCSession *vc); 62void vc_kill(VCSession *vc);
63void vc_iterate(VCSession *vc); 63void vc_iterate(VCSession *vc);
64int vc_queue_message(void *vcp, struct RTPMessage *msg); 64int vc_queue_message(void *vcp, struct RTPMessage *msg);
diff --git a/toxcore/util.c b/toxcore/util.c
index 81fa84c6..28d8721c 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -209,18 +209,19 @@ bool rb_empty(const RingBuffer *b)
209{ 209{
210 return b->end == b->start; 210 return b->end == b->start;
211} 211}
212void* rb_write(RingBuffer *b, void *p) 212void *rb_write(RingBuffer *b, void *p)
213{ 213{
214 void* rc = NULL; 214 void *rc = NULL;
215
215 if ((b->end + 1) % b->size == b->start) /* full */ 216 if ((b->end + 1) % b->size == b->start) /* full */
216 rc = b->data[b->start]; 217 rc = b->data[b->start];
217 218
218 b->data[b->end] = p; 219 b->data[b->end] = p;
219 b->end = (b->end + 1) % b->size; 220 b->end = (b->end + 1) % b->size;
220 221
221 if (b->end == b->start) 222 if (b->end == b->start)
222 b->start = (b->start + 1) % b->size; 223 b->start = (b->start + 1) % b->size;
223 224
224 return rc; 225 return rc;
225} 226}
226bool rb_read(RingBuffer *b, void **p) 227bool rb_read(RingBuffer *b, void **p)
@@ -229,7 +230,7 @@ bool rb_read(RingBuffer *b, void **p)
229 *p = NULL; 230 *p = NULL;
230 return false; 231 return false;
231 } 232 }
232 233
233 *p = b->data[b->start]; 234 *p = b->data[b->start];
234 b->start = (b->start + 1) % b->size; 235 b->start = (b->start + 1) % b->size;
235 return true; 236 return true;
@@ -256,21 +257,22 @@ void rb_kill(RingBuffer *b)
256 free(b); 257 free(b);
257 } 258 }
258} 259}
259uint16_t rb_size(const RingBuffer* b) 260uint16_t rb_size(const RingBuffer *b)
260{ 261{
261 if (rb_empty(b)) 262 if (rb_empty(b))
262 return 0; 263 return 0;
263 264
264 return 265 return
265 b->end > b->start ? 266 b->end > b->start ?
266 b->end - b->start : 267 b->end - b->start :
267 (b->size - b->start) + b->end; 268 (b->size - b->start) + b->end;
268} 269}
269uint16_t rb_data(const RingBuffer* b, void** dest) 270uint16_t rb_data(const RingBuffer *b, void **dest)
270{ 271{
271 uint16_t i = 0; 272 uint16_t i = 0;
273
272 for (; i < rb_size(b); i++) 274 for (; i < rb_size(b); i++)
273 dest[i] = b->data[(b->start + i) % b->size]; 275 dest[i] = b->data[(b->start + i) % b->size];
274 276
275 return i; 277 return i;
276} 278}
diff --git a/toxcore/util.h b/toxcore/util.h
index 7cf63178..bdbf7d3b 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -62,11 +62,11 @@ int create_recursive_mutex(pthread_mutex_t *mutex);
62typedef struct RingBuffer RingBuffer; 62typedef struct RingBuffer RingBuffer;
63bool rb_full(const RingBuffer *b); 63bool rb_full(const RingBuffer *b);
64bool rb_empty(const RingBuffer *b); 64bool rb_empty(const RingBuffer *b);
65void* rb_write(RingBuffer* b, void* p); 65void *rb_write(RingBuffer *b, void *p);
66bool rb_read(RingBuffer* b, void** p); 66bool rb_read(RingBuffer *b, void **p);
67RingBuffer *rb_new(int size); 67RingBuffer *rb_new(int size);
68void rb_kill(RingBuffer *b); 68void rb_kill(RingBuffer *b);
69uint16_t rb_size(const RingBuffer *b); 69uint16_t rb_size(const RingBuffer *b);
70uint16_t rb_data(const RingBuffer* b, void** dest); 70uint16_t rb_data(const RingBuffer *b, void **dest);
71 71
72#endif /* __UTIL_H__ */ 72#endif /* __UTIL_H__ */
diff --git a/toxdns/toxdns.c b/toxdns/toxdns.c
index f7df5df3..1fbf4a00 100644
--- a/toxdns/toxdns.c
+++ b/toxdns/toxdns.c
@@ -44,7 +44,7 @@ uint8_t i = 0; \
44 } \ 44 } \
45 } \ 45 } \
46} \ 46} \
47 47
48typedef struct { 48typedef struct {
49 uint8_t temp_pk[crypto_box_PUBLICKEYBYTES]; 49 uint8_t temp_pk[crypto_box_PUBLICKEYBYTES];
50 uint8_t temp_sk[crypto_box_SECRETKEYBYTES]; 50 uint8_t temp_sk[crypto_box_SECRETKEYBYTES];