diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c index e7807592..1817916b 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -79,7 +79,7 @@ typedef struct ToxAVCall_s { | |||
79 | struct ToxAVCall_s *next; | 79 | struct ToxAVCall_s *next; |
80 | } ToxAVCall; | 80 | } ToxAVCall; |
81 | 81 | ||
82 | struct toxAV { | 82 | struct ToxAV { |
83 | Messenger* m; | 83 | Messenger* m; |
84 | MSISession* msi; | 84 | MSISession* msi; |
85 | 85 | ||
@@ -116,7 +116,7 @@ bool video_bit_rate_invalid(uint32_t bit_rate); | |||
116 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); | 116 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); |
117 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); | 117 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); |
118 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); | 118 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); |
119 | void call_remove(ToxAVCall* call); | 119 | ToxAVCall* call_remove(ToxAVCall* call); |
120 | bool call_prepare_transmission(ToxAVCall* call); | 120 | bool call_prepare_transmission(ToxAVCall* call); |
121 | void call_kill_transmission(ToxAVCall* call); | 121 | void call_kill_transmission(ToxAVCall* call); |
122 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); | 122 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); |
@@ -193,9 +193,9 @@ void toxav_kill(ToxAV* av) | |||
193 | /* Msi kill will hang up all calls so just clean these calls */ | 193 | /* Msi kill will hang up all calls so just clean these calls */ |
194 | if (av->calls) { | 194 | if (av->calls) { |
195 | ToxAVCall* it = call_get(av, av->calls_head); | 195 | ToxAVCall* it = call_get(av, av->calls_head); |
196 | for (; it; it = it->next) { | 196 | while (it) { |
197 | call_kill_transmission(it); | 197 | call_kill_transmission(it); |
198 | call_remove(it); /* This will eventually free av->calls */ | 198 | it = call_remove(it); /* This will eventually free av->calls */ |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
@@ -318,6 +318,14 @@ void toxav_iterate(ToxAV* av) | |||
318 | 318 | ||
319 | bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) | 319 | bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) |
320 | { | 320 | { |
321 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) | ||
322 | ||(video_bit_rate && video_bit_rate_invalid(video_bit_rate)) | ||
323 | ) { | ||
324 | if (error) | ||
325 | *error = TOXAV_ERR_CALL_INVALID_BIT_RATE; | ||
326 | return false; | ||
327 | } | ||
328 | |||
321 | pthread_mutex_lock(av->mutex); | 329 | pthread_mutex_lock(av->mutex); |
322 | ToxAVCall* call = call_new(av, friend_number, error); | 330 | ToxAVCall* call = call_new(av, friend_number, error); |
323 | if (call == NULL) { | 331 | if (call == NULL) { |
@@ -368,7 +376,7 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui | |||
368 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) | 376 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) |
369 | ||(video_bit_rate && video_bit_rate_invalid(video_bit_rate)) | 377 | ||(video_bit_rate && video_bit_rate_invalid(video_bit_rate)) |
370 | ) { | 378 | ) { |
371 | rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; | 379 | rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE; |
372 | goto END; | 380 | goto END; |
373 | } | 381 | } |
374 | 382 | ||
@@ -379,7 +387,7 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui | |||
379 | } | 387 | } |
380 | 388 | ||
381 | if (!call_prepare_transmission(call)) { | 389 | if (!call_prepare_transmission(call)) { |
382 | rc = TOXAV_ERR_ANSWER_MALLOC; | 390 | rc = TOXAV_ERR_ANSWER_CODEC_INITIALIZATION; |
383 | goto END; | 391 | goto END; |
384 | } | 392 | } |
385 | 393 | ||
@@ -450,6 +458,9 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
450 | 458 | ||
451 | rtp_start_receiving(call->audio.first); | 459 | rtp_start_receiving(call->audio.first); |
452 | rtp_start_receiving(call->video.first); | 460 | rtp_start_receiving(call->video.first); |
461 | } else { | ||
462 | rc = TOXAV_ERR_CALL_CONTROL_NOT_PAUSED; | ||
463 | goto END; | ||
453 | } | 464 | } |
454 | } break; | 465 | } break; |
455 | 466 | ||
@@ -472,6 +483,9 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
472 | 483 | ||
473 | rtp_stop_receiving(call->audio.first); | 484 | rtp_stop_receiving(call->audio.first); |
474 | rtp_stop_receiving(call->video.first); | 485 | rtp_stop_receiving(call->video.first); |
486 | } else { | ||
487 | rc = TOXAV_ERR_CALL_CONTROL_ALREADY_PAUSED; | ||
488 | goto END; | ||
475 | } | 489 | } |
476 | } break; | 490 | } break; |
477 | 491 | ||
@@ -516,7 +530,7 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
516 | } | 530 | } |
517 | } break; | 531 | } break; |
518 | 532 | ||
519 | case TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO: { | 533 | case TOXAV_CALL_CONTROL_TOGGLE_HIDE_VIDEO: { |
520 | if (!call->active) { | 534 | if (!call->active) { |
521 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; | 535 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; |
522 | goto END; | 536 | goto END; |
@@ -589,7 +603,7 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
589 | goto END; | 603 | goto END; |
590 | } | 604 | } |
591 | 605 | ||
592 | if (call->video_bit_rate == video_bit_rate || call->vba.active || call->vba.bit_rate == video_bit_rate) { | 606 | if (call->video_bit_rate == video_bit_rate || (call->vba.active && call->vba.bit_rate == video_bit_rate)) { |
593 | pthread_mutex_unlock(av->mutex); | 607 | pthread_mutex_unlock(av->mutex); |
594 | goto END; | 608 | goto END; |
595 | } | 609 | } |
@@ -599,6 +613,8 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
599 | if (video_bit_rate > call->video_bit_rate && !force) | 613 | if (video_bit_rate > call->video_bit_rate && !force) |
600 | ba_set(&call->vba, video_bit_rate); | 614 | ba_set(&call->vba, video_bit_rate); |
601 | else { | 615 | else { |
616 | /* Cancel any previous non forceful bitrate change request */ | ||
617 | memset(&call->vba, 0, sizeof(call->vba)); | ||
602 | call->video_bit_rate = video_bit_rate; | 618 | call->video_bit_rate = video_bit_rate; |
603 | 619 | ||
604 | if (!force && av->vbcb.first) | 620 | if (!force && av->vbcb.first) |
@@ -646,16 +662,19 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_ | |||
646 | goto END; | 662 | goto END; |
647 | } | 663 | } |
648 | 664 | ||
649 | if (call->audio_bit_rate == audio_bit_rate || call->aba.active || call->aba.bit_rate == audio_bit_rate) { | 665 | if (call->audio_bit_rate == audio_bit_rate || (call->aba.active && call->aba.bit_rate == audio_bit_rate)) { |
650 | pthread_mutex_unlock(av->mutex); | 666 | pthread_mutex_unlock(av->mutex); |
651 | goto END; | 667 | goto END; |
652 | } | 668 | } |
653 | 669 | ||
670 | |||
654 | pthread_mutex_lock(call->mutex); | 671 | pthread_mutex_lock(call->mutex); |
655 | 672 | ||
656 | if (audio_bit_rate > call->audio_bit_rate && !force) | 673 | if (audio_bit_rate > call->audio_bit_rate && !force) |
657 | ba_set(&call->aba, audio_bit_rate); | 674 | ba_set(&call->aba, audio_bit_rate); |
658 | else { | 675 | else { |
676 | /* Cancel any previous non forceful bitrate change request */ | ||
677 | memset(&call->aba, 0, sizeof(call->aba)); | ||
659 | call->audio_bit_rate = audio_bit_rate; | 678 | call->audio_bit_rate = audio_bit_rate; |
660 | 679 | ||
661 | if (!force && av->abcb.first) | 680 | if (!force && av->abcb.first) |
@@ -755,6 +774,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u | |||
755 | if (rtp_send_data(call->video.first, iter, part_size, false) < 0) { | 774 | if (rtp_send_data(call->video.first, iter, part_size, false) < 0) { |
756 | pthread_mutex_unlock(call->mutex_video); | 775 | pthread_mutex_unlock(call->mutex_video); |
757 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); | 776 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); |
777 | rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; | ||
758 | goto END; | 778 | goto END; |
759 | } | 779 | } |
760 | } | 780 | } |
@@ -807,6 +827,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u | |||
807 | if (rtp_send_data(call->video.first, pkt->data.frame.buf + i * 1300, 1300, true) < 0) { | 827 | if (rtp_send_data(call->video.first, pkt->data.frame.buf + i * 1300, 1300, true) < 0) { |
808 | pthread_mutex_unlock(call->mutex_video); | 828 | pthread_mutex_unlock(call->mutex_video); |
809 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); | 829 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); |
830 | rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; | ||
810 | goto END; | 831 | goto END; |
811 | } | 832 | } |
812 | } | 833 | } |
@@ -815,6 +836,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u | |||
815 | if (rtp_send_data(call->video.first, pkt->data.frame.buf + parts * 1300, pkt->data.frame.sz % 1300, true) < 0) { | 836 | if (rtp_send_data(call->video.first, pkt->data.frame.buf + parts * 1300, pkt->data.frame.sz % 1300, true) < 0) { |
816 | pthread_mutex_unlock(call->mutex_video); | 837 | pthread_mutex_unlock(call->mutex_video); |
817 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); | 838 | LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); |
839 | rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; | ||
818 | goto END; | 840 | goto END; |
819 | } | 841 | } |
820 | } | 842 | } |
@@ -1157,10 +1179,10 @@ ToxAVCall* call_get(ToxAV* av, uint32_t friend_number) | |||
1157 | return av->calls[friend_number]; | 1179 | return av->calls[friend_number]; |
1158 | } | 1180 | } |
1159 | 1181 | ||
1160 | void call_remove(ToxAVCall* call) | 1182 | ToxAVCall* call_remove(ToxAVCall* call) |
1161 | { | 1183 | { |
1162 | if (call == NULL) | 1184 | if (call == NULL) |
1163 | return; | 1185 | return NULL; |
1164 | 1186 | ||
1165 | uint32_t friend_number = call->friend_number; | 1187 | uint32_t friend_number = call->friend_number; |
1166 | ToxAV* av = call->av; | 1188 | ToxAV* av = call->av; |
@@ -1183,12 +1205,14 @@ void call_remove(ToxAVCall* call) | |||
1183 | else goto CLEAR; | 1205 | else goto CLEAR; |
1184 | 1206 | ||
1185 | av->calls[friend_number] = NULL; | 1207 | av->calls[friend_number] = NULL; |
1186 | return; | 1208 | return next; |
1187 | 1209 | ||
1188 | CLEAR: | 1210 | CLEAR: |
1189 | av->calls_head = av->calls_tail = 0; | 1211 | av->calls_head = av->calls_tail = 0; |
1190 | free(av->calls); | 1212 | free(av->calls); |
1191 | av->calls = NULL; | 1213 | av->calls = NULL; |
1214 | |||
1215 | return NULL; | ||
1192 | } | 1216 | } |
1193 | 1217 | ||
1194 | bool call_prepare_transmission(ToxAVCall* call) | 1218 | bool call_prepare_transmission(ToxAVCall* call) |