Fixed* api comments and some bugs

This commit is contained in:
mannol 2015-05-01 22:15:12 +02:00
parent 5c4f275686
commit eb6e8aa290
5 changed files with 124 additions and 104 deletions

View File

@ -9,7 +9,6 @@
#include <check.h> #include <check.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <assert.h>
#include <vpx/vpx_image.h> #include <vpx/vpx_image.h>
@ -103,7 +102,7 @@ void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t
(void) userdata; (void) userdata;
if (length == 7 && memcmp("gentoo", data, 7) == 0) { if (length == 7 && memcmp("gentoo", data, 7) == 0) {
assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
} }
} }
@ -133,13 +132,13 @@ START_TEST(test_AV_flows)
TOX_ERR_NEW error; TOX_ERR_NEW error;
bootstrap = tox_new(NULL, NULL, 0, &error); bootstrap = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Alice = tox_new(NULL, NULL, 0, &error); Alice = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Bob = tox_new(NULL, NULL, 0, &error); Bob = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
} }
printf("Created 3 instances of Tox\n"); printf("Created 3 instances of Tox\n");
@ -153,7 +152,7 @@ START_TEST(test_AV_flows)
tox_self_get_address(Alice, address); tox_self_get_address(Alice, address);
assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
uint8_t off = 1; uint8_t off = 1;
@ -178,10 +177,10 @@ START_TEST(test_AV_flows)
{ {
TOXAV_ERR_NEW error; TOXAV_ERR_NEW error;
AliceAV = toxav_new(Alice, &error); AliceAV = toxav_new(Alice, &error);
assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
BobAV = toxav_new(Bob, &error); BobAV = toxav_new(Bob, &error);
assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
} }
toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC); toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC);
@ -208,7 +207,7 @@ START_TEST(test_AV_flows)
\ \
if (rc != TOXAV_ERR_CALL_OK) { \ if (rc != TOXAV_ERR_CALL_OK) { \
printf("toxav_call failed: %d\n", rc); \ printf("toxav_call failed: %d\n", rc); \
exit(1); \ ck_assert(0); \
} \ } \
\ \
\ \
@ -223,7 +222,7 @@ START_TEST(test_AV_flows)
\ \
if (rc != TOXAV_ERR_ANSWER_OK) { \ if (rc != TOXAV_ERR_ANSWER_OK) { \
printf("toxav_answer failed: %d\n", rc); \ printf("toxav_answer failed: %d\n", rc); \
exit(1); \ ck_assert(0); \
} \ } \
BobCC.incoming = false; \ BobCC.incoming = false; \
} else { \ } else { \
@ -236,7 +235,7 @@ START_TEST(test_AV_flows)
\ \
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { \ if (rc != TOXAV_ERR_CALL_CONTROL_OK) { \
printf("toxav_call_control failed: %d\n", rc); \ printf("toxav_call_control failed: %d\n", rc); \
exit(1); \ ck_assert(0); \
} \ } \
} \ } \
} \ } \
@ -275,7 +274,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -289,7 +288,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
printf("toxav_call_control failed: %d\n", rc); printf("toxav_call_control failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -311,7 +310,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -325,7 +324,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
printf("toxav_call_control failed: %d\n", rc); printf("toxav_call_control failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -349,7 +348,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -357,10 +356,10 @@ START_TEST(test_AV_flows)
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
/* At first try all stuff while in invalid state */ /* At first try all stuff while in invalid state */
assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO, NULL));
{ {
TOXAV_ERR_ANSWER rc; TOXAV_ERR_ANSWER rc;
@ -368,7 +367,7 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_ANSWER_OK) { if (rc != TOXAV_ERR_ANSWER_OK) {
printf("toxav_answer failed: %d\n", rc); printf("toxav_answer failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -376,36 +375,36 @@ START_TEST(test_AV_flows)
/* Pause and Resume */ /* Pause and Resume */
printf("Pause and Resume\n"); printf("Pause and Resume\n");
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state == TOXAV_CALL_STATE_PAUSED); ck_assert(BobCC.state == TOXAV_CALL_STATE_PAUSED);
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state & (TOXAV_CALL_STATE_SENDING_A | TOXAV_CALL_STATE_SENDING_V)); ck_assert(BobCC.state & (TOXAV_CALL_STATE_SENDING_A | TOXAV_CALL_STATE_SENDING_V));
/* Mute/Unmute single */ /* Mute/Unmute single */
printf("Mute/Unmute single\n"); printf("Mute/Unmute single\n");
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); ck_assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A);
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); ck_assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A);
/* Mute/Unmute both */ /* Mute/Unmute both */
printf("Mute/Unmute both\n"); printf("Mute/Unmute both\n");
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); ck_assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A);
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_V); ck_assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_V);
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); ck_assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A);
assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); ck_assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO, NULL));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_V); ck_assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_V);
{ {
TOXAV_ERR_CALL_CONTROL rc; TOXAV_ERR_CALL_CONTROL rc;
@ -413,12 +412,12 @@ START_TEST(test_AV_flows)
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
printf("toxav_call_control failed: %d\n", rc); printf("toxav_call_control failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, Alice, Bob);
assert(BobCC.state == TOXAV_CALL_STATE_END); ck_assert(BobCC.state == TOXAV_CALL_STATE_END);
printf("Success!\n"); printf("Success!\n");
} }

View File

@ -9,10 +9,11 @@
#include <check.h> #include <check.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <assert.h>
#include <vpx/vpx_image.h> #include <vpx/vpx_image.h>
#include "helpers.h"
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
@ -97,7 +98,7 @@ void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t
{ {
(void) userdata; (void) userdata;
if (length == 7 && memcmp("gentoo", data, 7) == 0) { if (length == 7 && memcmp("gentoo", data, 7) == 0) {
assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
} }
} }
@ -110,7 +111,7 @@ ToxAV* setup_av_instance(Tox* tox, CallControl *CC)
TOXAV_ERR_NEW error; TOXAV_ERR_NEW error;
ToxAV* av = toxav_new(tox, &error); ToxAV* av = toxav_new(tox, &error);
assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
toxav_callback_call(av, t_toxav_call_cb, CC); toxav_callback_call(av, t_toxav_call_cb, CC);
toxav_callback_call_state(av, t_toxav_call_state_cb, CC); toxav_callback_call_state(av, t_toxav_call_state_cb, CC);
@ -137,7 +138,7 @@ void* call_thread(void* pd)
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -150,7 +151,7 @@ void* call_thread(void* pd)
if (rc != TOXAV_ERR_ANSWER_OK) { if (rc != TOXAV_ERR_ANSWER_OK) {
printf("toxav_answer failed: %d\n", rc); printf("toxav_answer failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
@ -167,7 +168,7 @@ void* call_thread(void* pd)
memset(video_v, 0, sizeof(video_v)); memset(video_v, 0, sizeof(video_v));
time_t start_time = time(NULL); time_t start_time = time(NULL);
while(time(NULL) - start_time < 9) { while(time(NULL) - start_time < 4) {
toxav_iterate(AliceAV); toxav_iterate(AliceAV);
toxav_iterate(BobAV); toxav_iterate(BobAV);
@ -186,11 +187,13 @@ void* call_thread(void* pd)
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
printf("toxav_call_control failed: %d\n", rc); printf("toxav_call_control failed: %d\n", rc);
exit(1); ck_assert(0);
} }
} }
c_sleep(30); c_sleep(30);
printf ("Closing thread\n");
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -206,19 +209,19 @@ START_TEST(test_AV_three_calls)
TOX_ERR_NEW error; TOX_ERR_NEW error;
bootstrap = tox_new(NULL, NULL, 0, &error); bootstrap = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Alice = tox_new(NULL, NULL, 0, &error); Alice = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Bobs[0] = tox_new(NULL, NULL, 0, &error); Bobs[0] = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Bobs[1] = tox_new(NULL, NULL, 0, &error); Bobs[1] = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Bobs[2] = tox_new(NULL, NULL, 0, &error); Bobs[2] = tox_new(NULL, NULL, 0, &error);
assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
} }
printf("Created 5 instances of Tox\n"); printf("Created 5 instances of Tox\n");
@ -232,9 +235,9 @@ START_TEST(test_AV_three_calls)
tox_self_get_address(Alice, address); tox_self_get_address(Alice, address);
assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); ck_assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
uint8_t off = 1; uint8_t off = 1;
@ -302,7 +305,7 @@ START_TEST(test_AV_three_calls)
(void) pthread_detach(tids[2]); (void) pthread_detach(tids[2]);
time_t start_time = time(NULL); time_t start_time = time(NULL);
while (time(NULL) - start_time < 10) { while (time(NULL) - start_time < 5) {
tox_iterate(Alice); tox_iterate(Alice);
tox_iterate(Bobs[0]); tox_iterate(Bobs[0]);
tox_iterate(Bobs[1]); tox_iterate(Bobs[1]);
@ -314,6 +317,7 @@ START_TEST(test_AV_three_calls)
(void) pthread_join(tids[1], NULL); (void) pthread_join(tids[1], NULL);
(void) pthread_join(tids[2], NULL); (void) pthread_join(tids[2], NULL);
printf ("Killing all instances\n");
toxav_kill(BobsAV[0]); toxav_kill(BobsAV[0]);
toxav_kill(BobsAV[1]); toxav_kill(BobsAV[1]);
toxav_kill(BobsAV[2]); toxav_kill(BobsAV[2]);

View File

@ -79,7 +79,7 @@ typedef struct ToxAVCall_s {
struct ToxAVCall_s *next; struct ToxAVCall_s *next;
} ToxAVCall; } ToxAVCall;
struct toxAV { struct ToxAV {
Messenger* m; Messenger* m;
MSISession* msi; MSISession* msi;
@ -116,7 +116,7 @@ bool video_bit_rate_invalid(uint32_t bit_rate);
void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state);
ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); ToxAVCall* call_get(ToxAV* av, uint32_t friend_number);
void call_remove(ToxAVCall* call); ToxAVCall* call_remove(ToxAVCall* call);
bool call_prepare_transmission(ToxAVCall* call); bool call_prepare_transmission(ToxAVCall* call);
void call_kill_transmission(ToxAVCall* call); void call_kill_transmission(ToxAVCall* call);
void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate);
@ -193,9 +193,9 @@ void toxav_kill(ToxAV* av)
/* Msi kill will hang up all calls so just clean these calls */ /* Msi kill will hang up all calls so just clean these calls */
if (av->calls) { if (av->calls) {
ToxAVCall* it = call_get(av, av->calls_head); ToxAVCall* it = call_get(av, av->calls_head);
for (; it; it = it->next) { while (it) {
call_kill_transmission(it); call_kill_transmission(it);
call_remove(it); /* This will eventually free av->calls */ it = call_remove(it); /* This will eventually free av->calls */
} }
} }
@ -318,6 +318,14 @@ void toxav_iterate(ToxAV* av)
bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error)
{ {
if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate))
||(video_bit_rate && video_bit_rate_invalid(video_bit_rate))
) {
if (error)
*error = TOXAV_ERR_CALL_INVALID_BIT_RATE;
return false;
}
pthread_mutex_lock(av->mutex); pthread_mutex_lock(av->mutex);
ToxAVCall* call = call_new(av, friend_number, error); ToxAVCall* call = call_new(av, friend_number, error);
if (call == NULL) { if (call == NULL) {
@ -368,7 +376,7 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate))
||(video_bit_rate && video_bit_rate_invalid(video_bit_rate)) ||(video_bit_rate && video_bit_rate_invalid(video_bit_rate))
) { ) {
rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE;
goto END; goto END;
} }
@ -379,7 +387,7 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
} }
if (!call_prepare_transmission(call)) { if (!call_prepare_transmission(call)) {
rc = TOXAV_ERR_ANSWER_MALLOC; rc = TOXAV_ERR_ANSWER_CODEC_INITIALIZATION;
goto END; goto END;
} }
@ -450,6 +458,9 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
rtp_start_receiving(call->audio.first); rtp_start_receiving(call->audio.first);
rtp_start_receiving(call->video.first); rtp_start_receiving(call->video.first);
} else {
rc = TOXAV_ERR_CALL_CONTROL_NOT_PAUSED;
goto END;
} }
} break; } break;
@ -472,6 +483,9 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
rtp_stop_receiving(call->audio.first); rtp_stop_receiving(call->audio.first);
rtp_stop_receiving(call->video.first); rtp_stop_receiving(call->video.first);
} else {
rc = TOXAV_ERR_CALL_CONTROL_ALREADY_PAUSED;
goto END;
} }
} break; } break;
@ -516,7 +530,7 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
} }
} break; } break;
case TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO: { case TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO: {
if (!call->active) { if (!call->active) {
rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL;
goto END; goto END;
@ -589,7 +603,7 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_
goto END; goto END;
} }
if (call->video_bit_rate == video_bit_rate || call->vba.active || call->vba.bit_rate == video_bit_rate) { if (call->video_bit_rate == video_bit_rate || (call->vba.active && call->vba.bit_rate == video_bit_rate)) {
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
goto END; goto END;
} }
@ -599,6 +613,8 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_
if (video_bit_rate > call->video_bit_rate && !force) if (video_bit_rate > call->video_bit_rate && !force)
ba_set(&call->vba, video_bit_rate); ba_set(&call->vba, video_bit_rate);
else { else {
/* Cancel any previous non forceful bitrate change request */
memset(&call->vba, 0, sizeof(call->vba));
call->video_bit_rate = video_bit_rate; call->video_bit_rate = video_bit_rate;
if (!force && av->vbcb.first) if (!force && av->vbcb.first)
@ -646,16 +662,19 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_
goto END; goto END;
} }
if (call->audio_bit_rate == audio_bit_rate || call->aba.active || call->aba.bit_rate == audio_bit_rate) { if (call->audio_bit_rate == audio_bit_rate || (call->aba.active && call->aba.bit_rate == audio_bit_rate)) {
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
goto END; goto END;
} }
pthread_mutex_lock(call->mutex); pthread_mutex_lock(call->mutex);
if (audio_bit_rate > call->audio_bit_rate && !force) if (audio_bit_rate > call->audio_bit_rate && !force)
ba_set(&call->aba, audio_bit_rate); ba_set(&call->aba, audio_bit_rate);
else { else {
/* Cancel any previous non forceful bitrate change request */
memset(&call->aba, 0, sizeof(call->aba));
call->audio_bit_rate = audio_bit_rate; call->audio_bit_rate = audio_bit_rate;
if (!force && av->abcb.first) if (!force && av->abcb.first)
@ -755,6 +774,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
if (rtp_send_data(call->video.first, iter, part_size, false) < 0) { if (rtp_send_data(call->video.first, iter, part_size, false) < 0) {
pthread_mutex_unlock(call->mutex_video); pthread_mutex_unlock(call->mutex_video);
LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
goto END; goto END;
} }
} }
@ -807,6 +827,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
if (rtp_send_data(call->video.first, pkt->data.frame.buf + i * 1300, 1300, true) < 0) { if (rtp_send_data(call->video.first, pkt->data.frame.buf + i * 1300, 1300, true) < 0) {
pthread_mutex_unlock(call->mutex_video); pthread_mutex_unlock(call->mutex_video);
LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
goto END; goto END;
} }
} }
@ -815,6 +836,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
if (rtp_send_data(call->video.first, pkt->data.frame.buf + parts * 1300, pkt->data.frame.sz % 1300, true) < 0) { if (rtp_send_data(call->video.first, pkt->data.frame.buf + parts * 1300, pkt->data.frame.sz % 1300, true) < 0) {
pthread_mutex_unlock(call->mutex_video); pthread_mutex_unlock(call->mutex_video);
LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
goto END; goto END;
} }
} }
@ -1157,10 +1179,10 @@ ToxAVCall* call_get(ToxAV* av, uint32_t friend_number)
return av->calls[friend_number]; return av->calls[friend_number];
} }
void call_remove(ToxAVCall* call) ToxAVCall* call_remove(ToxAVCall* call)
{ {
if (call == NULL) if (call == NULL)
return; return NULL;
uint32_t friend_number = call->friend_number; uint32_t friend_number = call->friend_number;
ToxAV* av = call->av; ToxAV* av = call->av;
@ -1183,12 +1205,14 @@ void call_remove(ToxAVCall* call)
else goto CLEAR; else goto CLEAR;
av->calls[friend_number] = NULL; av->calls[friend_number] = NULL;
return; return next;
CLEAR: CLEAR:
av->calls_head = av->calls_tail = 0; av->calls_head = av->calls_tail = 0;
free(av->calls); free(av->calls);
av->calls = NULL; av->calls = NULL;
return NULL;
} }
bool call_prepare_transmission(ToxAVCall* call) bool call_prepare_transmission(ToxAVCall* call)

View File

@ -37,7 +37,7 @@ extern "C" {
/** /**
* The type of the Tox Audio/Video subsystem object. * The type of the Tox Audio/Video subsystem object.
*/ */
typedef struct toxAV ToxAV; typedef struct ToxAV ToxAV;
#ifndef TOX_DEFINED #ifndef TOX_DEFINED
#define TOX_DEFINED #define TOX_DEFINED
/** /**
@ -92,8 +92,8 @@ Tox *toxav_get_tox(ToxAV *av);
uint32_t toxav_iteration_interval(ToxAV const *av); uint32_t toxav_iteration_interval(ToxAV const *av);
/** /**
* Main loop for the session. This function needs to be called in intervals of * Main loop for the session. This function needs to be called in intervals of
* toxav_iteration_interval() milliseconds. It is best called in the same loop * toxav_iteration_interval() milliseconds. It is best called in the separate
* as tox_iterate. * thread from tox_iterate.
*/ */
void toxav_iterate(ToxAV *av); void toxav_iterate(ToxAV *av);
/******************************************************************************* /*******************************************************************************
@ -153,10 +153,11 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *function, void *user_data);
typedef enum TOXAV_ERR_ANSWER { typedef enum TOXAV_ERR_ANSWER {
TOXAV_ERR_ANSWER_OK, TOXAV_ERR_ANSWER_OK,
/** /**
* A resource allocation error occurred while trying to create the structures * Failed to initialize codecs for call session. Note that codec initiation
* required for the call. * will fail if there is no receive callback registered for either audio or
* video.
*/ */
TOXAV_ERR_ANSWER_MALLOC, TOXAV_ERR_ANSWER_CODEC_INITIALIZATION,
/** /**
* The friend number did not designate a valid friend. * The friend number did not designate a valid friend.
*/ */
@ -174,8 +175,8 @@ typedef enum TOXAV_ERR_ANSWER {
/** /**
* Accept an incoming call. * Accept an incoming call.
* *
* If an allocation error occurs while answering a call, both participants will * If answering fails for any reason, the call will still be pending and it is
* receive TOXAV_CALL_STATE_ERROR and the call will end. * possible to try and answer it later.
* *
* @param friend_number The friend number of the friend that is calling. * @param friend_number The friend number of the friend that is calling.
* @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable
@ -217,7 +218,8 @@ typedef enum TOXAV_CALL_STATE {
*/ */
TOXAV_CALL_STATE_END = 16, TOXAV_CALL_STATE_END = 16,
/** /**
* Set by the AV core if an error occurred on the remote end. * Set by the AV core if an error occurred on the remote end. This call
* state will never be triggered in combination with other call states.
*/ */
TOXAV_CALL_STATE_ERROR = 32768 TOXAV_CALL_STATE_ERROR = 32768
} TOXAV_CALL_STATE; } TOXAV_CALL_STATE;
@ -266,10 +268,10 @@ typedef enum TOXAV_CALL_CONTROL {
* Request that the friend stops sending video. Regardless of the friend's * Request that the friend stops sending video. Regardless of the friend's
* compliance, this will cause the `receive_video_frame` event to stop being * compliance, this will cause the `receive_video_frame` event to stop being
* triggered on receiving an video frame from the friend. If the video was * triggered on receiving an video frame from the friend. If the video was
* already muted, calling this control will notify client to start sending * already hidden, calling this control will notify client to start sending
* video again. * video again.
*/ */
TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO
} TOXAV_CALL_CONTROL; } TOXAV_CALL_CONTROL;
typedef enum TOXAV_ERR_CALL_CONTROL { typedef enum TOXAV_ERR_CALL_CONTROL {
TOXAV_ERR_CALL_CONTROL_OK, TOXAV_ERR_CALL_CONTROL_OK,
@ -286,21 +288,12 @@ typedef enum TOXAV_ERR_CALL_CONTROL {
* Attempted to resume a call that was not paused. * Attempted to resume a call that was not paused.
*/ */
TOXAV_ERR_CALL_CONTROL_NOT_PAUSED, TOXAV_ERR_CALL_CONTROL_NOT_PAUSED,
/**
* Attempted to resume a call that was paused by the other party. Also set if
* the client attempted to send a system-only control.
*/
TOXAV_ERR_CALL_CONTROL_DENIED,
/** /**
* The call was already paused on this client. It is valid to pause if the * The call was already paused on this client. It is valid to pause if the
* other party paused the call. The call will resume after both parties sent * other party paused the call. The call will resume after both parties sent
* the RESUME control. * the RESUME control.
*/ */
TOXAV_ERR_CALL_CONTROL_ALREADY_PAUSED, TOXAV_ERR_CALL_CONTROL_ALREADY_PAUSED
/**
* Tried to unmute a call that was not already muted.
*/
TOXAV_ERR_CALL_CONTROL_NOT_MUTED
} TOXAV_ERR_CALL_CONTROL; } TOXAV_ERR_CALL_CONTROL;
/** /**
* Sends a call control command to a friend. * Sends a call control command to a friend.
@ -351,7 +344,12 @@ typedef void toxav_audio_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, b
*/ */
void toxav_callback_audio_bit_rate_status(ToxAV *av, toxav_audio_bit_rate_status_cb *function, void *user_data); void toxav_callback_audio_bit_rate_status(ToxAV *av, toxav_audio_bit_rate_status_cb *function, void *user_data);
/** /**
* Set the audio bit rate to be used in subsequent audio frames. * Set the audio bit rate to be used in subsequent audio frames. If the passed
* bit rate is the same as the current bit rate this function will return true
* without calling a callback. If there is an active non forceful setup with the
* passed audio bit rate and the new set request is forceful, the bit rate is
* forcefully set and the previous non forceful request is cancelled. The active
* non forceful setup will be canceled in favour of new non forceful setup.
* *
* @param friend_number The friend number of the friend for which to set the * @param friend_number The friend number of the friend for which to set the
* audio bit rate. * audio bit rate.
@ -380,7 +378,12 @@ typedef void toxav_video_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, b
*/ */
void toxav_callback_video_bit_rate_status(ToxAV *av, toxav_video_bit_rate_status_cb *function, void *user_data); void toxav_callback_video_bit_rate_status(ToxAV *av, toxav_video_bit_rate_status_cb *function, void *user_data);
/** /**
* Set the video bit rate to be used in subsequent video frames. * Set the video bit rate to be used in subsequent video frames. If the passed
* bit rate is the same as the current bit rate this function will return true
* without calling a callback. If there is an active non forceful setup with the
* passed bit rate and the new set request is forceful, the bit rate is
* forcefully set and the previous non forceful request is cancelled. The active
* non forceful setup will be canceled in favour of new non forceful setup.
* *
* @param friend_number The friend number of the friend for which to set the * @param friend_number The friend number of the friend for which to set the
* video bit rate. * video bit rate.
@ -413,11 +416,6 @@ typedef enum TOXAV_ERR_SEND_FRAME {
* This client is currently not in a call with the friend. * This client is currently not in a call with the friend.
*/ */
TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL, TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL,
/**
* No video frame had been requested through the `video_frame_request` event,
* but the client tried to send one, anyway.
*/
TOXAV_ERR_SEND_FRAME_NOT_REQUESTED,
/** /**
* One of the frame parameters was invalid. E.g. the resolution may be too * One of the frame parameters was invalid. E.g. the resolution may be too
* small or too large, or the audio sampling rate may be unsupported. * small or too large, or the audio sampling rate may be unsupported.
@ -431,8 +429,6 @@ typedef enum TOXAV_ERR_SEND_FRAME {
/** /**
* Send a video frame to a friend. * Send a video frame to a friend.
* *
* This is called in response to receiving the `video_frame_request` event.
*
* Y - plane should be of size: height * width * Y - plane should be of size: height * width
* U - plane should be of size: (height/2) * (width/2) * U - plane should be of size: (height/2) * (width/2)
* V - plane should be of size: (height/2) * (width/2) * V - plane should be of size: (height/2) * (width/2)
@ -452,8 +448,6 @@ bool toxav_send_video_frame(ToxAV *av, uint32_t friend_number,
/** /**
* Send an audio frame to a friend. * Send an audio frame to a friend.
* *
* This is called in response to receiving the `audio_frame_request` event.
*
* The expected format of the PCM data is: [s1c1][s1c2][...][s2c1][s2c2][...]... * The expected format of the PCM data is: [s1c1][s1c2][...][s2c1][s2c2][...]...
* Meaning: sample 1 for channel 1, sample 1 for channel 2, ... * Meaning: sample 1 for channel 1, sample 1 for channel 2, ...
* For mono audio, this has no meaning, every sample is subsequent. For stereo, * For mono audio, this has no meaning, every sample is subsequent. For stereo,
@ -467,9 +461,7 @@ bool toxav_send_video_frame(ToxAV *av, uint32_t friend_number,
* @param sample_count Number of samples in this frame. Valid numbers here are * @param sample_count Number of samples in this frame. Valid numbers here are
* ((sample rate) * (audio length) / 1000), where audio length can be * ((sample rate) * (audio length) / 1000), where audio length can be
* 2.5, 5, 10, 20, 40 or 60 millseconds. * 2.5, 5, 10, 20, 40 or 60 millseconds.
* @param channels Number of audio channels. Must be at least 1 for mono. * @param channels Number of audio channels. Supported values are 1 and 2.
* For voice over IP, more than 2 channels (stereo) typically doesn't make
* sense, but up to 255 channels are supported.
* @param sampling_rate Audio sampling rate used in this frame. Valid sampling * @param sampling_rate Audio sampling rate used in this frame. Valid sampling
* rates are 8000, 12000, 16000, 24000, or 48000. * rates are 8000, 12000, 16000, 24000, or 48000.
*/ */

View File

@ -87,6 +87,7 @@ VCSession* vc_new(ToxAV* av, uint32_t friend_number, toxav_receive_video_frame_c
vc->vcb.second = cb_data; vc->vcb.second = cb_data;
vc->friend_number = friend_number; vc->friend_number = friend_number;
vc->peer_video_frame_piece_size = mvfpsz; vc->peer_video_frame_piece_size = mvfpsz;
vc->av = av;
return vc; return vc;
@ -294,7 +295,7 @@ int vc_reconfigure_encoder(VCSession* vc, int32_t bit_rate, uint16_t width, uint
return -1; return -1;
vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc; vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc;
if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) if (cfg.rc_target_bitrate == (uint32_t) bit_rate && cfg.g_w == width && cfg.g_h == height)
return 0; /* Nothing changed */ return 0; /* Nothing changed */
cfg.rc_target_bitrate = bit_rate; cfg.rc_target_bitrate = bit_rate;
@ -315,7 +316,7 @@ int vc_reconfigure_test_encoder(VCSession* vc, int32_t bit_rate, uint16_t width,
return -1; return -1;
vpx_codec_enc_cfg_t cfg = *vc->test_encoder->config.enc; vpx_codec_enc_cfg_t cfg = *vc->test_encoder->config.enc;
if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) if (cfg.rc_target_bitrate == (uint32_t) bit_rate && cfg.g_w == width && cfg.g_h == height)
return 0; /* Nothing changed */ return 0; /* Nothing changed */
cfg.rc_target_bitrate = bit_rate; cfg.rc_target_bitrate = bit_rate;