summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c188
1 files changed, 104 insertions, 84 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 12a65737..584b3898 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -40,21 +40,24 @@ enum {
40 video_index, 40 video_index,
41}; 41};
42 42
43typedef struct iToxAVCall 43typedef struct ToxAVCall_s
44{ 44{
45 pthread_mutex_t mutex_control[1]; 45 pthread_mutex_t mutex_control[1];
46 pthread_mutex_t mutex_encoding_audio[1]; 46 pthread_mutex_t mutex_encoding_audio[1];
47 pthread_mutex_t mutex_encoding_video[1]; 47 pthread_mutex_t mutex_encoding_video[1];
48 pthread_mutex_t mutex_do[1]; 48 pthread_mutex_t mutex_do[1];
49 RTPSession *rtps[2]; /** Audio is first and video is second */ 49 RTPSession *rtps[2]; /* Audio is first and video is second */
50 CSSession *cs; 50 CSSession *cs;
51 bool active; 51 bool active;
52 int32_t friend_id;
53 MSICall* msi_call; 52 MSICall* msi_call;
53 uint32_t friend_id;
54 54
55 struct iToxAVCall *prev; 55 uint32_t s_audio_b; /* Sending audio bitrate */
56 struct iToxAVCall *next; 56 uint32_t s_video_b; /* Sending video bitrate */
57} IToxAVCall; 57
58 struct ToxAVCall_s *prev;
59 struct ToxAVCall_s *next;
60} ToxAVCall;
58 61
59struct toxAV 62struct toxAV
60{ 63{
@@ -62,7 +65,7 @@ struct toxAV
62 MSISession* msi; 65 MSISession* msi;
63 66
64 /* Two-way storage: first is array of calls and second is list of calls with head and tail */ 67 /* Two-way storage: first is array of calls and second is list of calls with head and tail */
65 IToxAVCall** calls; 68 ToxAVCall** calls;
66 uint32_t calls_tail; 69 uint32_t calls_tail;
67 uint32_t calls_head; 70 uint32_t calls_head;
68 71
@@ -88,13 +91,13 @@ void i_callback_error(void* toxav_inst, MSICall* call);
88void i_callback_capabilites(void* toxav_inst, MSICall* call); 91void i_callback_capabilites(void* toxav_inst, MSICall* call);
89 92
90TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities); 93TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities);
91IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); 94ToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number);
92IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); 95ToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number);
93void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); 96void i_toxav_remove_call(ToxAV* av, uint32_t friend_number);
94IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); 97ToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
95bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); 98bool i_toxav_audio_bitrate_invalid(uint32_t bitrate);
96bool i_toxav_video_bitrate_invalid(uint32_t bitrate); 99bool i_toxav_video_bitrate_invalid(uint32_t bitrate);
97bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call); 100bool i_toxav_prepare_transmission(ToxAV* av, ToxAVCall* call);
98void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number); 101void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number);
99 102
100 103
@@ -179,15 +182,13 @@ uint32_t toxav_iteration_interval(const ToxAV* av)
179 182
180void toxav_iteration(ToxAV* av) 183void toxav_iteration(ToxAV* av)
181{ 184{
182 msi_do(av->msi);
183
184 if (av->calls == NULL) 185 if (av->calls == NULL)
185 return; 186 return;
186 187
187 uint64_t start = current_time_monotonic(); 188 uint64_t start = current_time_monotonic();
188 uint32_t rc = 200 + av->dmssa; /* If no call is active interval is 200 */ 189 uint32_t rc = 200 + av->dmssa; /* If no call is active interval is 200 */
189 190
190 IToxAVCall* i = av->calls[av->calls_head]; 191 ToxAVCall* i = av->calls[av->calls_head];
191 for (; i; i = i->next) { 192 for (; i; i = i->next) {
192 if (i->active) { 193 if (i->active) {
193 cs_do(i->cs); 194 cs_do(i->cs);
@@ -207,22 +208,22 @@ void toxav_iteration(ToxAV* av)
207 208
208bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) 209bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error)
209{ 210{
210 IToxAVCall* call = i_toxav_init_call(av, friend_number, error); 211 ToxAVCall* call = i_toxav_init_call(av, friend_number, error);
211 if (call == NULL) { 212 if (call == NULL)
212 return false; 213 return false;
213 }
214 214
215 /* TODO remove csettings */ 215 call->s_audio_b = audio_bit_rate;
216 MSICSettings csets; 216 call->s_video_b = video_bit_rate;
217 csets.audio_bitrate = audio_bit_rate;
218 csets.video_bitrate = video_bit_rate;
219 217
220 csets.call_type = video_bit_rate ? msi_TypeVideo : msi_TypeAudio; 218 uint8_t capabilities = 0;
221 219
222 if (msi_invite(av->msi, &call->call_idx, &csets, 1000, friend_number) != 0) { 220 capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0;
221 capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0;
222
223 if (msi_invite(av->msi, &call->msi_call, friend_number, capabilities) != 0) {
223 i_toxav_remove_call(av, friend_number); 224 i_toxav_remove_call(av, friend_number);
224 if (error) 225 if (error)
225 *error = TOXAV_ERR_CALL_MALLOC; /* FIXME: this should be the only reason to fail */ 226 *error = TOXAV_ERR_CALL_MALLOC;
226 return false; 227 return false;
227 } 228 }
228 229
@@ -250,23 +251,23 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
250 goto END; 251 goto END;
251 } 252 }
252 253
253 IToxAVCall* call = i_toxav_get_call(av, friend_number); 254 ToxAVCall* call = i_toxav_get_call(av, friend_number);
254 if (call == NULL || av->msi->calls[call->call_idx]->state != msi_CallRequested) { 255 if (call == NULL) {
255 rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; 256 rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING;
256 goto END; 257 goto END;
257 } 258 }
258 259
259 /* TODO remove csettings */ 260 call->s_audio_b = audio_bit_rate;
260 MSICSettings csets; 261 call->s_video_b = video_bit_rate;
261 csets.audio_bitrate = audio_bit_rate;
262 csets.video_bitrate = video_bit_rate;
263 262
264 csets.call_type = video_bit_rate ? msi_TypeVideo : msi_TypeAudio; 263 uint8_t capabilities = 0;
264
265 capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0;
266 capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0;
267
268 if (msi_answer(call->msi_call, capabilities) != 0)
269 rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; /* the only reason for msi_answer to fail */
265 270
266 if (msi_answer(av->msi, call->call_idx, &csets) != 0) {
267 rc = TOXAV_ERR_ANSWER_MALLOC; /* TODO Some error here */
268 /* TODO Reject call? */
269 }
270 271
271END: 272END:
272 if (error) 273 if (error)
@@ -291,7 +292,7 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
291 } 292 }
292 293
293 294
294 IToxAVCall* call = i_toxav_get_call(av, friend_number); 295 ToxAVCall* call = i_toxav_get_call(av, friend_number);
295 if (call == NULL) { 296 if (call == NULL) {
296 rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; 297 rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL;
297 goto END; 298 goto END;
@@ -309,17 +310,17 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
309 } break; 310 } break;
310 311
311 case TOXAV_CALL_CONTROL_CANCEL: { 312 case TOXAV_CALL_CONTROL_CANCEL: {
312 if (av->msi->calls[call->call_idx]->state == msi_CallActive) { 313 if (call->msi_call->state == msi_CallActive
314 || call->msi_call->state == msi_CallRequesting) {
313 /* Hang up */ 315 /* Hang up */
314 msi_hangup(av->msi, call->call_idx); 316 msi_hangup(call->msi_call);
315 } else if (av->msi->calls[call->call_idx]->state == msi_CallRequested) { 317 } else if (call->msi_call->state == msi_CallRequested) {
316 /* Reject the call */ 318 /* Reject the call */
317 msi_reject(av->msi, call->call_idx, NULL); 319 msi_reject(call->msi_call);
318 } else if (av->msi->calls[call->call_idx]->state == msi_CallRequesting) {
319 /* Cancel the call */
320 msi_cancel(av->msi, call->call_idx, 0, NULL);
321 i_toxav_remove_call(av, friend_number);
322 } 320 }
321
322 // No mather the case, terminate the call
323 i_toxav_remove_call(av, friend_number);
323 } break; 324 } break;
324 325
325 case TOXAV_CALL_CONTROL_MUTE_AUDIO: { 326 case TOXAV_CALL_CONTROL_MUTE_AUDIO: {
@@ -356,7 +357,7 @@ void toxav_callback_request_video_frame(ToxAV* av, toxav_request_video_frame_cb*
356bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, TOXAV_ERR_SEND_FRAME* error) 357bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, TOXAV_ERR_SEND_FRAME* error)
357{ 358{
358 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; 359 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK;
359 IToxAVCall* call; 360 ToxAVCall* call;
360 361
361 if (m_friend_exists(av->m, friend_number) == 0) { 362 if (m_friend_exists(av->m, friend_number) == 0) {
362 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; 363 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
@@ -369,7 +370,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
369 goto END; 370 goto END;
370 } 371 }
371 372
372 if (av->msi->calls[call->call_idx]->state != msi_CallActive) { 373 if (call->msi_call->state != msi_CallActive) {
373 /* TODO */ 374 /* TODO */
374 rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED; 375 rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED;
375 goto END; 376 goto END;
@@ -453,7 +454,7 @@ void toxav_callback_request_audio_frame(ToxAV* av, toxav_request_audio_frame_cb*
453bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME* error) 454bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME* error)
454{ 455{
455 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; 456 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK;
456 IToxAVCall* call; 457 ToxAVCall* call;
457 458
458 if (m_friend_exists(av->m, friend_number) == 0) { 459 if (m_friend_exists(av->m, friend_number) == 0) {
459 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; 460 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
@@ -466,7 +467,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
466 goto END; 467 goto END;
467 } 468 }
468 469
469 if (av->msi->calls[call->call_idx]->state != msi_CallActive) { 470 if (call->msi_call->state != msi_CallActive) {
470 /* TODO */ 471 /* TODO */
471 rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED; 472 rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED;
472 goto END; 473 goto END;
@@ -533,10 +534,10 @@ void i_callback_invite(void* toxav_inst, MSICall* call)
533{ 534{
534 ToxAV* toxav = toxav_inst; 535 ToxAV* toxav = toxav_inst;
535 536
536 IToxAVCall* av_call = i_toxav_init_call(toxav, call->friend_id, NULL); 537 ToxAVCall* av_call = i_toxav_init_call(toxav, call->friend_id, NULL);
537 if (av_call == NULL) { 538 if (av_call == NULL) {
538 LOGGER_WARNING("Failed to start call, rejecting..."); 539 LOGGER_WARNING("Failed to start call, rejecting...");
539 msi_reject(toxav->msi, call); 540 msi_reject(call);
540 return; 541 return;
541 } 542 }
542 543
@@ -559,15 +560,15 @@ void i_callback_start(void* toxav_inst, MSICall* call)
559{ 560{
560 ToxAV* toxav = toxav_inst; 561 ToxAV* toxav = toxav_inst;
561 562
562 IToxAVCall* call = i_toxav_get_call(toxav, call->friend_id); 563 ToxAVCall* av_call = i_toxav_get_call(toxav, call->friend_id);
563 564
564 if (call == NULL || !i_toxav_prepare_transmission(toxav, call)) { 565 if (av_call == NULL || !i_toxav_prepare_transmission(toxav, av_call)) {
565 /* TODO send error */ 566 /* TODO send error */
566 i_toxav_remove_call(toxav, call->friend_id); 567 i_toxav_remove_call(toxav, call->friend_id);
567 return; 568 return;
568 } 569 }
569 570
570 TOXAV_CALL_STATE state = capabilities_to_state(call->msi_call->peer_capabilities); 571 TOXAV_CALL_STATE state = capabilities_to_state(av_call->msi_call->peer_capabilities);
571 572
572 if (toxav->scb.first) 573 if (toxav->scb.first)
573 toxav->scb.first(toxav, call->friend_id, state, toxav->scb.second); 574 toxav->scb.first(toxav, call->friend_id, state, toxav->scb.second);
@@ -594,7 +595,7 @@ void i_callback_error(void* toxav_inst, MSICall* call)
594void i_callback_capabilites(void* toxav_inst, MSICall* call) 595void i_callback_capabilites(void* toxav_inst, MSICall* call)
595{ 596{
596 ToxAV* toxav = toxav_inst; 597 ToxAV* toxav = toxav_inst;
597 /* TODO something something msi */ 598 /* TODO handle this */
598} 599}
599 600
600TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities) 601TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities)
@@ -609,7 +610,7 @@ TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities)
609 return TOXAV_CALL_STATE_PAUSED; 610 return TOXAV_CALL_STATE_PAUSED;
610} 611}
611 612
612IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number) 613ToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
613{ 614{
614 if (av->calls == NULL || av->calls_tail < friend_number) 615 if (av->calls == NULL || av->calls_tail < friend_number)
615 return NULL; 616 return NULL;
@@ -617,9 +618,9 @@ IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
617 return av->calls[friend_number]; 618 return av->calls[friend_number];
618} 619}
619 620
620IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number) 621ToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
621{ 622{
622 IToxAVCall* rc = calloc(sizeof(IToxAVCall), 1); 623 ToxAVCall* rc = calloc(sizeof(ToxAVCall), 1);
623 624
624 if (rc == NULL) 625 if (rc == NULL)
625 return NULL; 626 return NULL;
@@ -639,7 +640,7 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
639 640
640 641
641 if (av->calls == NULL) { /* Creating */ 642 if (av->calls == NULL) { /* Creating */
642 av->calls = calloc (sizeof(IToxAVCall*), friend_number + 1); 643 av->calls = calloc (sizeof(ToxAVCall*), friend_number + 1);
643 644
644 if (av->calls == NULL) { 645 if (av->calls == NULL) {
645 pthread_mutex_destroy(rc->mutex_control); 646 pthread_mutex_destroy(rc->mutex_control);
@@ -651,7 +652,7 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
651 av->calls_tail = av->calls_head = friend_number; 652 av->calls_tail = av->calls_head = friend_number;
652 653
653 } else if (av->calls_tail < friend_number) { /* Appending */ 654 } else if (av->calls_tail < friend_number) { /* Appending */
654 void* tmp = realloc(av->calls, sizeof(IToxAVCall*) * friend_number + 1); 655 void* tmp = realloc(av->calls, sizeof(ToxAVCall*) * friend_number + 1);
655 656
656 if (tmp == NULL) { 657 if (tmp == NULL) {
657 pthread_mutex_destroy(rc->mutex_control); 658 pthread_mutex_destroy(rc->mutex_control);
@@ -684,13 +685,13 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
684 685
685void i_toxav_remove_call(ToxAV* av, uint32_t friend_number) 686void i_toxav_remove_call(ToxAV* av, uint32_t friend_number)
686{ 687{
687 IToxAVCall* tc = i_toxav_get_call(av, friend_number); 688 ToxAVCall* tc = i_toxav_get_call(av, friend_number);
688 689
689 if (tc == NULL) 690 if (tc == NULL)
690 return; 691 return;
691 692
692 IToxAVCall* prev = tc->prev; 693 ToxAVCall* prev = tc->prev;
693 IToxAVCall* next = tc->next; 694 ToxAVCall* next = tc->next;
694 695
695 pthread_mutex_destroy(tc->mutex_control); 696 pthread_mutex_destroy(tc->mutex_control);
696 pthread_mutex_destroy(tc->mutex_do); 697 pthread_mutex_destroy(tc->mutex_do);
@@ -718,10 +719,10 @@ CLEAR:
718 av->calls = NULL; 719 av->calls = NULL;
719} 720}
720 721
721IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) 722ToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error)
722{ 723{
723 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; 724 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK;
724 IToxAVCall* call = NULL; 725 ToxAVCall* call = NULL;
725 726
726 if (m_friend_exists(av->m, friend_number) == 0) { 727 if (m_friend_exists(av->m, friend_number) == 0) {
727 rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND; 728 rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND;
@@ -764,8 +765,12 @@ bool i_toxav_video_bitrate_invalid(uint32_t bitrate)
764 return false; 765 return false;
765} 766}
766 767
767bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call) 768bool i_toxav_prepare_transmission(ToxAV* av, ToxAVCall* call)
768{ 769{
770 if (!av->acb.first && !av->vcb.first)
771 /* It makes no sense to have CSession without callbacks */
772 return false;
773
769 pthread_mutex_lock(call->mutex_control); 774 pthread_mutex_lock(call->mutex_control);
770 775
771 if (call->active) { 776 if (call->active) {
@@ -788,11 +793,9 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
788 goto MUTEX_INIT_ERROR; 793 goto MUTEX_INIT_ERROR;
789 } 794 }
790 795
791 const MSICSettings *c_peer = &av->msi->calls[call->call_idx]->csettings_peer[0]; 796 uint8_t capabilities = call->msi_call->self_capabilities;
792 const MSICSettings *c_self = &av->msi->calls[call->call_idx]->csettings_local;
793 797
794 call->cs = cs_new(c_self->audio_bitrate, c_peer->audio_bitrate, 798 call->cs = cs_new(call->msi_call->peer_vfpsz);
795 c_self->video_bitrate, c_peer->video_bitrate);
796 799
797 if ( !call->cs ) { 800 if ( !call->cs ) {
798 LOGGER_ERROR("Error while starting Codec State!\n"); 801 LOGGER_ERROR("Error while starting Codec State!\n");
@@ -800,19 +803,14 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
800 } 803 }
801 804
802 call->cs->agent = av; 805 call->cs->agent = av;
803 806 call->cs->friend_id = call->friend_id;
804 /* It makes no sense to have CSession without callbacks */
805 assert(av->acb.first || av->vcb.first);
806 807
807 memcpy(&call->cs->acb, &av->acb, sizeof(av->acb)); 808 memcpy(&call->cs->acb, &av->acb, sizeof(av->acb));
808 memcpy(&call->cs->vcb, &av->vcb, sizeof(av->vcb)); 809 memcpy(&call->cs->vcb, &av->vcb, sizeof(av->vcb));
809 810
810 call->cs->friend_number = call->friend_id; 811 if (capabilities & msi_CapSAudio || capabilities & msi_CapRAudio) { /* Prepare audio sending */
811 call->cs->call_idx = call->call_idx; 812
812 813 call->rtps[audio_index] = rtp_new(rtp_TypeAudio, av->m, call->friend_id);
813
814 if (c_self->audio_bitrate > 0 || c_peer->audio_bitrate > 0) { /* Prepare audio rtp */
815 call->rtps[audio_index] = rtp_new(rtp_TypeAudio, av->m, av->msi->calls[call->call_idx]->peers[0]);
816 814
817 if ( !call->rtps[audio_index] ) { 815 if ( !call->rtps[audio_index] ) {
818 LOGGER_ERROR("Error while starting audio RTP session!\n"); 816 LOGGER_ERROR("Error while starting audio RTP session!\n");
@@ -821,12 +819,23 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
821 819
822 call->rtps[audio_index]->cs = call->cs; 820 call->rtps[audio_index]->cs = call->cs;
823 821
824 if (c_peer->audio_bitrate > 0) 822 if (cs_enable_audio_sending(call->cs, call->s_audio_b, 2) != 0) {
823 LOGGER_WARNING("Failed to enable audio sending!");
824 goto FAILURE;
825 }
826
827 if (capabilities & msi_CapRAudio) {
828 if (cs_enable_audio_receiving(call->cs) != 0) {
829 LOGGER_WARNING("Failed to enable audio receiving!");
830 goto FAILURE;
831 }
832
825 rtp_register_for_receiving(call->rtps[audio_index]); 833 rtp_register_for_receiving(call->rtps[audio_index]);
834 }
826 } 835 }
827 836
828 if (c_self->video_bitrate > 0 || c_peer->video_bitrate > 0) { /* Prepare video rtp */ 837 if (capabilities & msi_CapSVideo || capabilities & msi_CapRVideo) { /* Prepare video rtp */
829 call->rtps[video_index] = rtp_new(rtp_TypeVideo, av->m, av->msi->calls[call->call_idx]->peers[0]); 838 call->rtps[video_index] = rtp_new(rtp_TypeVideo, av->m, call->friend_id);
830 839
831 if ( !call->rtps[video_index] ) { 840 if ( !call->rtps[video_index] ) {
832 LOGGER_ERROR("Error while starting video RTP session!\n"); 841 LOGGER_ERROR("Error while starting video RTP session!\n");
@@ -835,8 +844,19 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
835 844
836 call->rtps[video_index]->cs = call->cs; 845 call->rtps[video_index]->cs = call->cs;
837 846
838 if (c_peer->video_bitrate > 0) 847 if (cs_enable_video_sending(call->cs, call->s_video_b) != 0) {
848 LOGGER_WARNING("Failed to enable video sending!");
849 goto FAILURE;
850 }
851
852 if (capabilities & msi_CapRVideo) {
853 if (cs_enable_video_receiving(call->cs) != 0) {
854 LOGGER_WARNING("Failed to enable video receiving!");
855 goto FAILURE;
856 }
857
839 rtp_register_for_receiving(call->rtps[audio_index]); 858 rtp_register_for_receiving(call->rtps[audio_index]);
859 }
840 } 860 }
841 861
842 call->active = 1; 862 call->active = 1;
@@ -866,7 +886,7 @@ MUTEX_INIT_ERROR:
866 886
867void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number) 887void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number)
868{ 888{
869 IToxAVCall* call = i_toxav_get_call(av, friend_number); 889 ToxAVCall* call = i_toxav_get_call(av, friend_number);
870 if (!call) 890 if (!call)
871 return; 891 return;
872 892