diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 188 |
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 | ||
43 | typedef struct iToxAVCall | 43 | typedef 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 | ||
59 | struct toxAV | 62 | struct 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); | |||
88 | void i_callback_capabilites(void* toxav_inst, MSICall* call); | 91 | void i_callback_capabilites(void* toxav_inst, MSICall* call); |
89 | 92 | ||
90 | TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities); | 93 | TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities); |
91 | IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); | 94 | ToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); |
92 | IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); | 95 | ToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); |
93 | void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); | 96 | void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); |
94 | IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); | 97 | ToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); |
95 | bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); | 98 | bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); |
96 | bool i_toxav_video_bitrate_invalid(uint32_t bitrate); | 99 | bool i_toxav_video_bitrate_invalid(uint32_t bitrate); |
97 | bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call); | 100 | bool i_toxav_prepare_transmission(ToxAV* av, ToxAVCall* call); |
98 | void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number); | 101 | void 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 | ||
180 | void toxav_iteration(ToxAV* av) | 183 | void 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 | ||
208 | bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) | 209 | bool 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 | ||
271 | END: | 272 | END: |
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* | |||
356 | bool 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 | bool 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* | |||
453 | bool 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 | bool 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) | |||
594 | void i_callback_capabilites(void* toxav_inst, MSICall* call) | 595 | void 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 | ||
600 | TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities) | 601 | TOXAV_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 | ||
612 | IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number) | 613 | ToxAVCall* 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 | ||
620 | IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number) | 621 | ToxAVCall* 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 | ||
685 | void i_toxav_remove_call(ToxAV* av, uint32_t friend_number) | 686 | void 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 | ||
721 | IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) | 722 | ToxAVCall* 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 | ||
767 | bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call) | 768 | bool 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 | ||
867 | void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number) | 887 | void 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 | ||