summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2016-09-19 21:49:04 +0100
committeriphydf <iphydf@users.noreply.github.com>2016-09-19 21:53:40 +0100
commit51d18236c8effffb14ffe6c5e3f738c1ceb1ae25 (patch)
treee18ff983aba08aee690cc001f7cf4928a94f80d3 /toxav/toxav.c
parent67ac9138ab773728f0a8d1093aaa80d40a9f9efc (diff)
Revert "Make ToxAV stateless"
This reverts commit 21f8db12c45bd56293262cd4abfb73cd9abec821. It is currently broken. Incoming call callbacks are not invoked, and instead the client goes offline immediately.
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c124
1 files changed, 61 insertions, 63 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 29046265..1ae914e8 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -42,16 +42,10 @@ typedef struct ToxAVCall_s {
42 ToxAV *av; 42 ToxAV *av;
43 43
44 pthread_mutex_t mutex_audio[1]; 44 pthread_mutex_t mutex_audio[1];
45 struct { 45 PAIR(RTPSession *, ACSession *) audio;
46 RTPSession *first;
47 ACSession *second;
48 } audio;
49 46
50 pthread_mutex_t mutex_video[1]; 47 pthread_mutex_t mutex_video[1];
51 struct { 48 PAIR(RTPSession *, VCSession *) video;
52 RTPSession *first;
53 VCSession *second;
54 } video;
55 49
56 BWController *bwc; 50 BWController *bwc;
57 51
@@ -81,12 +75,11 @@ struct ToxAV {
81 uint32_t calls_head; 75 uint32_t calls_head;
82 pthread_mutex_t mutex[1]; 76 pthread_mutex_t mutex[1];
83 77
84 toxav_call_cb *on_call; 78 PAIR(toxav_call_cb *, void *) ccb; /* Call callback */
85 toxav_call_state_cb *on_call_state; 79 PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */
86 toxav_bit_rate_status_cb *on_bit_rate_status_change; 80 PAIR(toxav_audio_receive_frame_cb *, void *) acb; /* Audio frame receive callback */
87 81 PAIR(toxav_video_receive_frame_cb *, void *) vcb; /* Video frame receive callback */
88 toxav_audio_receive_frame_cb *on_audio_frame; 82 PAIR(toxav_bit_rate_status_cb *, void *) bcb; /* Bit rate control callback */
89 toxav_video_receive_frame_cb *on_video_frame;
90 83
91 /** Decode time measures */ 84 /** Decode time measures */
92 int32_t dmssc; /** Measure count */ 85 int32_t dmssc; /** Measure count */
@@ -96,17 +89,17 @@ struct ToxAV {
96 uint32_t interval; /** Calculated interval */ 89 uint32_t interval; /** Calculated interval */
97}; 90};
98 91
99void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata); 92void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
100 93
101int callback_invite(void *toxav_inst, MSICall *call, void *userdata); 94int callback_invite(void *toxav_inst, MSICall *call);
102int callback_start(void *toxav_inst, MSICall *call, void *userdata); 95int callback_start(void *toxav_inst, MSICall *call);
103int callback_end(void *toxav_inst, MSICall *call, void *userdata); 96int callback_end(void *toxav_inst, MSICall *call);
104int callback_error(void *toxav_inst, MSICall *call, void *userdata); 97int callback_error(void *toxav_inst, MSICall *call);
105int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata); 98int callback_capabilites(void *toxav_inst, MSICall *call);
106 99
107bool audio_bit_rate_invalid(uint32_t bit_rate); 100bool audio_bit_rate_invalid(uint32_t bit_rate);
108bool video_bit_rate_invalid(uint32_t bit_rate); 101bool video_bit_rate_invalid(uint32_t bit_rate);
109bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata); 102bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state);
110ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); 103ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error);
111ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); 104ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
112ToxAVCall *call_remove(ToxAVCall *call); 105ToxAVCall *call_remove(ToxAVCall *call);
@@ -237,7 +230,7 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
237 /* If no call is active interval is 200 */ 230 /* If no call is active interval is 200 */
238 return av->calls ? av->interval : 200; 231 return av->calls ? av->interval : 200;
239} 232}
240void toxav_iterate(ToxAV *av, void *userdata) 233void toxav_iterate(ToxAV *av)
241{ 234{
242 pthread_mutex_lock(av->mutex); 235 pthread_mutex_lock(av->mutex);
243 236
@@ -256,8 +249,8 @@ void toxav_iterate(ToxAV *av, void *userdata)
256 pthread_mutex_lock(i->mutex); 249 pthread_mutex_lock(i->mutex);
257 pthread_mutex_unlock(av->mutex); 250 pthread_mutex_unlock(av->mutex);
258 251
259 ac_iterate(i->audio.second, userdata); 252 ac_iterate(i->audio.second);
260 vc_iterate(i->video.second, userdata); 253 vc_iterate(i->video.second);
261 254
262 if (i->msi_call->self_capabilities & msi_CapRAudio && 255 if (i->msi_call->self_capabilities & msi_CapRAudio &&
263 i->msi_call->peer_capabilities & msi_CapSAudio) { 256 i->msi_call->peer_capabilities & msi_CapSAudio) {
@@ -336,10 +329,11 @@ END:
336 329
337 return rc == TOXAV_ERR_CALL_OK; 330 return rc == TOXAV_ERR_CALL_OK;
338} 331}
339void toxav_callback_call(ToxAV *av, toxav_call_cb *callback) 332void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
340{ 333{
341 pthread_mutex_lock(av->mutex); 334 pthread_mutex_lock(av->mutex);
342 av->on_call = callback; 335 av->ccb.first = callback;
336 av->ccb.second = user_data;
343 pthread_mutex_unlock(av->mutex); 337 pthread_mutex_unlock(av->mutex);
344} 338}
345bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, 339bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
@@ -394,10 +388,11 @@ END:
394 388
395 return rc == TOXAV_ERR_ANSWER_OK; 389 return rc == TOXAV_ERR_ANSWER_OK;
396} 390}
397void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback) 391void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data)
398{ 392{
399 pthread_mutex_lock(av->mutex); 393 pthread_mutex_lock(av->mutex);
400 av->on_call_state = callback; 394 av->scb.first = callback;
395 av->scb.second = user_data;
401 pthread_mutex_unlock(av->mutex); 396 pthread_mutex_unlock(av->mutex);
402} 397}
403bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) 398bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error)
@@ -669,10 +664,11 @@ END:
669 664
670 return rc == TOXAV_ERR_BIT_RATE_SET_OK; 665 return rc == TOXAV_ERR_BIT_RATE_SET_OK;
671} 666}
672void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback) 667void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback, void *user_data)
673{ 668{
674 pthread_mutex_lock(av->mutex); 669 pthread_mutex_lock(av->mutex);
675 av->on_bit_rate_status_change = callback; 670 av->bcb.first = callback;
671 av->bcb.second = user_data;
676 pthread_mutex_unlock(av->mutex); 672 pthread_mutex_unlock(av->mutex);
677} 673}
678bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, 674bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count,
@@ -860,16 +856,18 @@ END:
860 856
861 return rc == TOXAV_ERR_SEND_FRAME_OK; 857 return rc == TOXAV_ERR_SEND_FRAME_OK;
862} 858}
863void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback) 859void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback, void *user_data)
864{ 860{
865 pthread_mutex_lock(av->mutex); 861 pthread_mutex_lock(av->mutex);
866 av->on_audio_frame = callback; 862 av->acb.first = callback;
863 av->acb.second = user_data;
867 pthread_mutex_unlock(av->mutex); 864 pthread_mutex_unlock(av->mutex);
868} 865}
869void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback) 866void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback, void *user_data)
870{ 867{
871 pthread_mutex_lock(av->mutex); 868 pthread_mutex_lock(av->mutex);
872 av->on_video_frame = callback; 869 av->vcb.first = callback;
870 av->vcb.second = user_data;
873 pthread_mutex_unlock(av->mutex); 871 pthread_mutex_unlock(av->mutex);
874} 872}
875 873
@@ -879,7 +877,7 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb
879 * :: Internal 877 * :: Internal
880 * 878 *
881 ******************************************************************************/ 879 ******************************************************************************/
882void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata) 880void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data)
883{ 881{
884 /* Callback which is called when the internal measure mechanism reported packet loss. 882 /* Callback which is called when the internal measure mechanism reported packet loss.
885 * We report suggested lowered bitrate to an app. If app is sending both audio and video, 883 * We report suggested lowered bitrate to an app. If app is sending both audio and video,
@@ -888,7 +886,7 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *c
888 * The application may choose to disable video totally if the stream is too bad. 886 * The application may choose to disable video totally if the stream is too bad.
889 */ 887 */
890 888
891 ToxAVCall *call = call_data; 889 ToxAVCall *call = user_data;
892 assert(call); 890 assert(call);
893 891
894 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100); 892 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100);
@@ -899,25 +897,25 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *c
899 897
900 pthread_mutex_lock(call->av->mutex); 898 pthread_mutex_lock(call->av->mutex);
901 899
902 if (!call->av->on_bit_rate_status_change) { 900 if (!call->av->bcb.first) {
903 pthread_mutex_unlock(call->av->mutex); 901 pthread_mutex_unlock(call->av->mutex);
904 LOGGER_WARNING(call->av->m->log, "No callback to report loss on"); 902 LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
905 return; 903 return;
906 } 904 }
907 905
908 if (call->video_bit_rate) { 906 if (call->video_bit_rate) {
909 (*call->av->on_bit_rate_status_change)(call->av, friend_number, call->audio_bit_rate, 907 (*call->av->bcb.first)(call->av, friend_number, call->audio_bit_rate,
910 call->video_bit_rate - (call->video_bit_rate * loss), 908 call->video_bit_rate - (call->video_bit_rate * loss),
911 userdata); 909 call->av->bcb.second);
912 } else if (call->audio_bit_rate) { 910 } else if (call->audio_bit_rate) {
913 (*call->av->on_bit_rate_status_change)(call->av, friend_number, 911 (*call->av->bcb.first)(call->av, friend_number,
914 call->audio_bit_rate - (call->audio_bit_rate * loss), 912 call->audio_bit_rate - (call->audio_bit_rate * loss),
915 0, userdata); 913 0, call->av->bcb.second);
916 } 914 }
917 915
918 pthread_mutex_unlock(call->av->mutex); 916 pthread_mutex_unlock(call->av->mutex);
919} 917}
920int callback_invite(void *toxav_inst, MSICall *call, void *userdata) 918int callback_invite(void *toxav_inst, MSICall *call)
921{ 919{
922 ToxAV *toxav = toxav_inst; 920 ToxAV *toxav = toxav_inst;
923 pthread_mutex_lock(toxav->mutex); 921 pthread_mutex_lock(toxav->mutex);
@@ -933,9 +931,9 @@ int callback_invite(void *toxav_inst, MSICall *call, void *userdata)
933 call->av_call = av_call; 931 call->av_call = av_call;
934 av_call->msi_call = call; 932 av_call->msi_call = call;
935 933
936 if (toxav->on_call) { 934 if (toxav->ccb.first) {
937 toxav->on_call(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, 935 toxav->ccb.first(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio,
938 call->peer_capabilities & msi_CapSVideo, userdata); 936 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second);
939 } else { 937 } else {
940 /* No handler to capture the call request, send failure */ 938 /* No handler to capture the call request, send failure */
941 pthread_mutex_unlock(toxav->mutex); 939 pthread_mutex_unlock(toxav->mutex);
@@ -945,7 +943,7 @@ int callback_invite(void *toxav_inst, MSICall *call, void *userdata)
945 pthread_mutex_unlock(toxav->mutex); 943 pthread_mutex_unlock(toxav->mutex);
946 return 0; 944 return 0;
947} 945}
948int callback_start(void *toxav_inst, MSICall *call, void *userdata) 946int callback_start(void *toxav_inst, MSICall *call)
949{ 947{
950 ToxAV *toxav = toxav_inst; 948 ToxAV *toxav = toxav_inst;
951 pthread_mutex_lock(toxav->mutex); 949 pthread_mutex_lock(toxav->mutex);
@@ -959,13 +957,13 @@ int callback_start(void *toxav_inst, MSICall *call, void *userdata)
959 } 957 }
960 958
961 if (!call_prepare_transmission(av_call)) { 959 if (!call_prepare_transmission(av_call)) {
962 callback_error(toxav_inst, call, userdata); 960 callback_error(toxav_inst, call);
963 pthread_mutex_unlock(toxav->mutex); 961 pthread_mutex_unlock(toxav->mutex);
964 return -1; 962 return -1;
965 } 963 }
966 964
967 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata)) { 965 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities)) {
968 callback_error(toxav_inst, call, userdata); 966 callback_error(toxav_inst, call);
969 pthread_mutex_unlock(toxav->mutex); 967 pthread_mutex_unlock(toxav->mutex);
970 return -1; 968 return -1;
971 } 969 }
@@ -973,12 +971,12 @@ int callback_start(void *toxav_inst, MSICall *call, void *userdata)
973 pthread_mutex_unlock(toxav->mutex); 971 pthread_mutex_unlock(toxav->mutex);
974 return 0; 972 return 0;
975} 973}
976int callback_end(void *toxav_inst, MSICall *call, void *userdata) 974int callback_end(void *toxav_inst, MSICall *call)
977{ 975{
978 ToxAV *toxav = toxav_inst; 976 ToxAV *toxav = toxav_inst;
979 pthread_mutex_lock(toxav->mutex); 977 pthread_mutex_lock(toxav->mutex);
980 978
981 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED, userdata); 979 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED);
982 980
983 if (call->av_call) { 981 if (call->av_call) {
984 call_kill_transmission(call->av_call); 982 call_kill_transmission(call->av_call);
@@ -988,12 +986,12 @@ int callback_end(void *toxav_inst, MSICall *call, void *userdata)
988 pthread_mutex_unlock(toxav->mutex); 986 pthread_mutex_unlock(toxav->mutex);
989 return 0; 987 return 0;
990} 988}
991int callback_error(void *toxav_inst, MSICall *call, void *userdata) 989int callback_error(void *toxav_inst, MSICall *call)
992{ 990{
993 ToxAV *toxav = toxav_inst; 991 ToxAV *toxav = toxav_inst;
994 pthread_mutex_lock(toxav->mutex); 992 pthread_mutex_lock(toxav->mutex);
995 993
996 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR, userdata); 994 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR);
997 995
998 if (call->av_call) { 996 if (call->av_call) {
999 call_kill_transmission(call->av_call); 997 call_kill_transmission(call->av_call);
@@ -1003,7 +1001,7 @@ int callback_error(void *toxav_inst, MSICall *call, void *userdata)
1003 pthread_mutex_unlock(toxav->mutex); 1001 pthread_mutex_unlock(toxav->mutex);
1004 return 0; 1002 return 0;
1005} 1003}
1006int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata) 1004int callback_capabilites(void *toxav_inst, MSICall *call)
1007{ 1005{
1008 ToxAV *toxav = toxav_inst; 1006 ToxAV *toxav = toxav_inst;
1009 pthread_mutex_lock(toxav->mutex); 1007 pthread_mutex_lock(toxav->mutex);
@@ -1020,7 +1018,7 @@ int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata)
1020 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first); 1018 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first);
1021 } 1019 }
1022 1020
1023 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata); 1021 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities);
1024 1022
1025 pthread_mutex_unlock(toxav->mutex); 1023 pthread_mutex_unlock(toxav->mutex);
1026 return 0; 1024 return 0;
@@ -1038,10 +1036,10 @@ bool video_bit_rate_invalid(uint32_t bit_rate)
1038 /* TODO(mannol): If anyone knows the answer to this one please fill it up */ 1036 /* TODO(mannol): If anyone knows the answer to this one please fill it up */
1039 return false; 1037 return false;
1040} 1038}
1041bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata) 1039bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
1042{ 1040{
1043 if (av->on_call_state) { 1041 if (av->scb.first) {
1044 av->on_call_state(av, friend_number, state, userdata); 1042 av->scb.first(av, friend_number, state, av->scb.second);
1045 } else { 1043 } else {
1046 return false; 1044 return false;
1047 } 1045 }
@@ -1196,7 +1194,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1196 1194
1197 ToxAV *av = call->av; 1195 ToxAV *av = call->av;
1198 1196
1199 if (!av->on_audio_frame && !av->on_video_frame) { 1197 if (!av->acb.first && !av->vcb.first) {
1200 /* It makes no sense to have CSession without callbacks */ 1198 /* It makes no sense to have CSession without callbacks */
1201 return false; 1199 return false;
1202 } 1200 }
@@ -1222,7 +1220,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1222 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call); 1220 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call);
1223 1221
1224 { /* Prepare audio */ 1222 { /* Prepare audio */
1225 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->on_audio_frame); 1223 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->acb.first, av->acb.second);
1226 1224
1227 if (!call->audio.second) { 1225 if (!call->audio.second) {
1228 LOGGER_ERROR(av->m->log, "Failed to create audio codec session"); 1226 LOGGER_ERROR(av->m->log, "Failed to create audio codec session");
@@ -1238,7 +1236,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1238 } 1236 }
1239 } 1237 }
1240 { /* Prepare video */ 1238 { /* Prepare video */
1241 call->video.second = vc_new(av->m->log, av, call->friend_number, av->on_video_frame); 1239 call->video.second = vc_new(av->m->log, av, call->friend_number, av->vcb.first, av->vcb.second);
1242 1240
1243 if (!call->video.second) { 1241 if (!call->video.second) {
1244 LOGGER_ERROR(av->m->log, "Failed to create video codec session"); 1242 LOGGER_ERROR(av->m->log, "Failed to create video codec session");