summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
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");