diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 124 |
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 | ||
99 | void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata); | 92 | void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data); |
100 | 93 | ||
101 | int callback_invite(void *toxav_inst, MSICall *call, void *userdata); | 94 | int callback_invite(void *toxav_inst, MSICall *call); |
102 | int callback_start(void *toxav_inst, MSICall *call, void *userdata); | 95 | int callback_start(void *toxav_inst, MSICall *call); |
103 | int callback_end(void *toxav_inst, MSICall *call, void *userdata); | 96 | int callback_end(void *toxav_inst, MSICall *call); |
104 | int callback_error(void *toxav_inst, MSICall *call, void *userdata); | 97 | int callback_error(void *toxav_inst, MSICall *call); |
105 | int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata); | 98 | int callback_capabilites(void *toxav_inst, MSICall *call); |
106 | 99 | ||
107 | bool audio_bit_rate_invalid(uint32_t bit_rate); | 100 | bool audio_bit_rate_invalid(uint32_t bit_rate); |
108 | bool video_bit_rate_invalid(uint32_t bit_rate); | 101 | bool video_bit_rate_invalid(uint32_t bit_rate); |
109 | bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata); | 102 | bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); |
110 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); | 103 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); |
111 | ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); | 104 | ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); |
112 | ToxAVCall *call_remove(ToxAVCall *call); | 105 | ToxAVCall *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 | } |
240 | void toxav_iterate(ToxAV *av, void *userdata) | 233 | void 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 | } |
339 | void toxav_callback_call(ToxAV *av, toxav_call_cb *callback) | 332 | void 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 | } |
345 | bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, | 339 | bool 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 | } |
397 | void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback) | 391 | void 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 | } |
403 | bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) | 398 | bool 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 | } |
672 | void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback) | 667 | void 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 | } |
678 | bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, | 674 | bool 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 | } |
863 | void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback) | 859 | void 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 | } |
869 | void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback) | 866 | void 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 | ******************************************************************************/ |
882 | void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata) | 880 | void 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 | } |
920 | int callback_invite(void *toxav_inst, MSICall *call, void *userdata) | 918 | int 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 | } |
948 | int callback_start(void *toxav_inst, MSICall *call, void *userdata) | 946 | int 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 | } |
976 | int callback_end(void *toxav_inst, MSICall *call, void *userdata) | 974 | int 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 | } |
991 | int callback_error(void *toxav_inst, MSICall *call, void *userdata) | 989 | int 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 | } |
1006 | int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata) | 1004 | int 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 | } |
1041 | bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata) | 1039 | bool 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"); |