diff options
-rw-r--r-- | toxav/codec.c | 57 | ||||
-rw-r--r-- | toxav/codec.h | 10 | ||||
-rw-r--r-- | toxav/msi.c | 111 | ||||
-rw-r--r-- | toxav/msi.h | 12 | ||||
-rw-r--r-- | toxav/toxav.c | 188 | ||||
-rw-r--r-- | toxav/toxav_new_1.c | 1 |
6 files changed, 154 insertions, 225 deletions
diff --git a/toxav/codec.c b/toxav/codec.c index 9fc14071..e44387df 100644 --- a/toxav/codec.c +++ b/toxav/codec.c | |||
@@ -44,9 +44,7 @@ | |||
44 | #define MAX_ENCODE_TIME_US VPX_DL_GOOD_QUALITY | 44 | #define MAX_ENCODE_TIME_US VPX_DL_GOOD_QUALITY |
45 | #define MAX_DECODE_TIME_US 0 | 45 | #define MAX_DECODE_TIME_US 0 |
46 | 46 | ||
47 | // TODO this has to be exchanged in msi | ||
48 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ | 47 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ |
49 | #define VIDEOFRAME_PIECE_SIZE 0x500 /* 1.25 KiB*/ | ||
50 | #define VIDEOFRAME_HEADER_SIZE 0x2 | 48 | #define VIDEOFRAME_HEADER_SIZE 0x2 |
51 | 49 | ||
52 | /* FIXME: Might not be enough */ | 50 | /* FIXME: Might not be enough */ |
@@ -296,7 +294,7 @@ void cs_do(CSSession *cs) | |||
296 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); | 294 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); |
297 | } else if (cs->acb.first) { | 295 | } else if (cs->acb.first) { |
298 | /* Play */ | 296 | /* Play */ |
299 | cs->acb.first(cs->agent, cs->friend_number, tmp, rc, | 297 | cs->acb.first(cs->agent, cs->friend_id, tmp, rc, |
300 | cs->last_pack_channels, cs->last_packet_sampling_rate, cs->acb.second); | 298 | cs->last_pack_channels, cs->last_packet_sampling_rate, cs->acb.second); |
301 | } | 299 | } |
302 | 300 | ||
@@ -323,7 +321,7 @@ void cs_do(CSSession *cs) | |||
323 | /* Play decoded images */ | 321 | /* Play decoded images */ |
324 | for (; dest; dest = vpx_codec_get_frame(cs->v_decoder, &iter)) { | 322 | for (; dest; dest = vpx_codec_get_frame(cs->v_decoder, &iter)) { |
325 | if (cs->vcb.first) | 323 | if (cs->vcb.first) |
326 | cs->vcb.first(cs->agent, cs->call_idx, dest->d_w, dest->d_h, | 324 | cs->vcb.first(cs->agent, cs->friend_id, dest->d_w, dest->d_h, |
327 | (const uint8_t**)dest->planes, dest->stride, cs->vcb.second); | 325 | (const uint8_t**)dest->planes, dest->stride, cs->vcb.second); |
328 | 326 | ||
329 | vpx_img_free(dest); | 327 | vpx_img_free(dest); |
@@ -336,7 +334,7 @@ void cs_do(CSSession *cs) | |||
336 | pthread_mutex_unlock(cs->queue_mutex); | 334 | pthread_mutex_unlock(cs->queue_mutex); |
337 | } | 335 | } |
338 | 336 | ||
339 | CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, uint32_t p_video_b) | 337 | CSSession *cs_new(uint32_t peer_video_frame_piece_size) |
340 | { | 338 | { |
341 | CSSession *cs = calloc(sizeof(CSSession), 1); | 339 | CSSession *cs = calloc(sizeof(CSSession), 1); |
342 | 340 | ||
@@ -345,29 +343,7 @@ CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, ui | |||
345 | return NULL; | 343 | return NULL; |
346 | } | 344 | } |
347 | 345 | ||
348 | /* TODO this has to be exchanged in msi */ | 346 | cs->peer_video_frame_piece_size = peer_video_frame_piece_size; |
349 | cs->max_video_frame_size = MAX_VIDEOFRAME_SIZE; | ||
350 | cs->video_frame_piece_size = VIDEOFRAME_PIECE_SIZE; | ||
351 | |||
352 | if (s_audio_b > 0 && 0 != cs_enable_audio_sending(cs, s_audio_b, 2)) { /* Sending audio enabled */ | ||
353 | LOGGER_WARNING("Failed to enable audio sending!"); | ||
354 | goto FAILURE; | ||
355 | } | ||
356 | |||
357 | if (p_audio_b > 0 && 0 != cs_enable_audio_receiving(cs)) { /* Receiving audio enabled */ | ||
358 | LOGGER_WARNING("Failed to enable audio receiving!"); | ||
359 | goto FAILURE; | ||
360 | } | ||
361 | |||
362 | if (s_video_b > 0 && 0 != cs_enable_video_sending(cs, s_video_b)) { /* Sending video enabled */ | ||
363 | LOGGER_WARNING("Failed to enable video sending!"); | ||
364 | goto FAILURE; | ||
365 | } | ||
366 | |||
367 | if (p_video_b > 0 && 0 != cs_enable_video_receiving(cs)) { /* Receiving video enabled */ | ||
368 | LOGGER_WARNING("Failed to enable video receiving!"); | ||
369 | goto FAILURE; | ||
370 | } | ||
371 | 347 | ||
372 | return cs; | 348 | return cs; |
373 | 349 | ||
@@ -415,22 +391,22 @@ int cs_update_video_splitter_cycle(CSSession *cs, const uint8_t *payload, uint16 | |||
415 | cs->processing_video_frame = payload; | 391 | cs->processing_video_frame = payload; |
416 | cs->processing_video_frame_size = length; | 392 | cs->processing_video_frame_size = length; |
417 | 393 | ||
418 | return ((length - 1) / cs->video_frame_piece_size) + 1; | 394 | return ((length - 1) / VIDEOFRAME_PIECE_SIZE) + 1; |
419 | } | 395 | } |
420 | 396 | ||
421 | const uint8_t *cs_iterate_split_video_frame(CSSession *cs, uint16_t *size) | 397 | const uint8_t *cs_iterate_split_video_frame(CSSession *cs, uint16_t *size) |
422 | { | 398 | { |
423 | if (!cs || !size) return NULL; | 399 | if (!cs || !size) return NULL; |
424 | 400 | ||
425 | if (cs->processing_video_frame_size > cs->video_frame_piece_size) { | 401 | if (cs->processing_video_frame_size > VIDEOFRAME_PIECE_SIZE) { |
426 | memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE, | 402 | memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE, |
427 | cs->processing_video_frame, | 403 | cs->processing_video_frame, |
428 | cs->video_frame_piece_size); | 404 | VIDEOFRAME_PIECE_SIZE); |
429 | 405 | ||
430 | cs->processing_video_frame += cs->video_frame_piece_size; | 406 | cs->processing_video_frame += VIDEOFRAME_PIECE_SIZE; |
431 | cs->processing_video_frame_size -= cs->video_frame_piece_size; | 407 | cs->processing_video_frame_size -= VIDEOFRAME_PIECE_SIZE; |
432 | 408 | ||
433 | *size = cs->video_frame_piece_size + VIDEOFRAME_HEADER_SIZE; | 409 | *size = VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE; |
434 | } else { | 410 | } else { |
435 | memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE, | 411 | memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE, |
436 | cs->processing_video_frame, | 412 | cs->processing_video_frame, |
@@ -492,7 +468,7 @@ int cs_set_sending_video_bitrate(CSSession *cs, uint32_t bitrate) | |||
492 | if (cfg.rc_target_bitrate == bitrate) | 468 | if (cfg.rc_target_bitrate == bitrate) |
493 | return 0; | 469 | return 0; |
494 | 470 | ||
495 | LOGGER_DEBUG("New video bitrate: %u", video_bitrate); | 471 | LOGGER_DEBUG("New video bitrate: %u", bitrate); |
496 | cfg.rc_target_bitrate = bitrate; | 472 | cfg.rc_target_bitrate = bitrate; |
497 | 473 | ||
498 | int rc = vpx_codec_enc_config_set(cs->v_encoder, &cfg); | 474 | int rc = vpx_codec_enc_config_set(cs->v_encoder, &cfg); |
@@ -528,7 +504,7 @@ int cs_enable_video_sending(CSSession* cs, uint32_t bitrate) | |||
528 | /* So that we can use cs_disable_video_sending to clean up */ | 504 | /* So that we can use cs_disable_video_sending to clean up */ |
529 | cs->v_encoding = true; | 505 | cs->v_encoding = true; |
530 | 506 | ||
531 | if ( !(cs->split_video_frame = calloc(cs->video_frame_piece_size + VIDEOFRAME_HEADER_SIZE, 1)) ) | 507 | if ( !(cs->split_video_frame = calloc(VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE, 1)) ) |
532 | goto FAILURE; | 508 | goto FAILURE; |
533 | 509 | ||
534 | cfg.rc_target_bitrate = bitrate; | 510 | cfg.rc_target_bitrate = bitrate; |
@@ -579,7 +555,7 @@ int cs_enable_video_receiving(CSSession* cs) | |||
579 | /* So that we can use cs_disable_video_sending to clean up */ | 555 | /* So that we can use cs_disable_video_sending to clean up */ |
580 | cs->v_decoding = true; | 556 | cs->v_decoding = true; |
581 | 557 | ||
582 | if ( !(cs->frame_buf = calloc(cs->max_video_frame_size, 1)) ) | 558 | if ( !(cs->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1)) ) |
583 | goto FAILURE; | 559 | goto FAILURE; |
584 | 560 | ||
585 | if ( !(cs->vbuf_raw = buffer_new(VIDEO_DECODE_BUFFER_SIZE)) ) | 561 | if ( !(cs->vbuf_raw = buffer_new(VIDEO_DECODE_BUFFER_SIZE)) ) |
@@ -837,10 +813,10 @@ void queue_message(RTPSession *session, RTPMessage *msg) | |||
837 | 813 | ||
838 | uint8_t piece_number = packet[1]; | 814 | uint8_t piece_number = packet[1]; |
839 | 815 | ||
840 | uint32_t length_before_piece = ((piece_number - 1) * cs->video_frame_piece_size); | 816 | uint32_t length_before_piece = ((piece_number - 1) * cs->peer_video_frame_piece_size); |
841 | uint32_t framebuf_new_length = length_before_piece + (packet_size - VIDEOFRAME_HEADER_SIZE); | 817 | uint32_t framebuf_new_length = length_before_piece + (packet_size - VIDEOFRAME_HEADER_SIZE); |
842 | 818 | ||
843 | if (framebuf_new_length > cs->max_video_frame_size) { | 819 | if (framebuf_new_length > MAX_VIDEOFRAME_SIZE) { |
844 | goto end; | 820 | goto end; |
845 | } | 821 | } |
846 | 822 | ||
@@ -851,9 +827,8 @@ void queue_message(RTPSession *session, RTPMessage *msg) | |||
851 | packet + VIDEOFRAME_HEADER_SIZE, | 827 | packet + VIDEOFRAME_HEADER_SIZE, |
852 | packet_size - VIDEOFRAME_HEADER_SIZE); | 828 | packet_size - VIDEOFRAME_HEADER_SIZE); |
853 | 829 | ||
854 | if (framebuf_new_length > cs->frame_size) { | 830 | if (framebuf_new_length > cs->frame_size) |
855 | cs->frame_size = framebuf_new_length; | 831 | cs->frame_size = framebuf_new_length; |
856 | } | ||
857 | 832 | ||
858 | end: | 833 | end: |
859 | rtp_free_msg(NULL, msg); | 834 | rtp_free_msg(NULL, msg); |
diff --git a/toxav/codec.h b/toxav/codec.h index b5eb19e2..6a673990 100644 --- a/toxav/codec.h +++ b/toxav/codec.h | |||
@@ -86,13 +86,12 @@ typedef struct CSSession_s { | |||
86 | 86 | ||
87 | /* Data handling */ | 87 | /* Data handling */ |
88 | uint8_t *frame_buf; /* buffer for split video payloads */ | 88 | uint8_t *frame_buf; /* buffer for split video payloads */ |
89 | uint32_t frame_size; /* largest address written to in frame_buf for current input frame*/ | 89 | uint32_t frame_size; /* largest address written to in frame_buf for current input frame */ |
90 | uint8_t frameid_in, frameid_out; /* id of input and output video frame */ | 90 | uint8_t frameid_in, frameid_out; /* id of input and output video frame */ |
91 | uint32_t last_timestamp; /* calculating cycles */ | 91 | uint32_t last_timestamp; /* calculating cycles */ |
92 | 92 | ||
93 | /* Limits */ | 93 | /* Limits */ |
94 | uint32_t video_frame_piece_size; | 94 | uint32_t peer_video_frame_piece_size; |
95 | uint32_t max_video_frame_size; | ||
96 | 95 | ||
97 | /* Splitting */ | 96 | /* Splitting */ |
98 | uint8_t *split_video_frame; | 97 | uint8_t *split_video_frame; |
@@ -129,8 +128,7 @@ typedef struct CSSession_s { | |||
129 | * | 128 | * |
130 | */ | 129 | */ |
131 | void *agent; /* Pointer to ToxAV TODO make this pointer to ToxAV*/ | 130 | void *agent; /* Pointer to ToxAV TODO make this pointer to ToxAV*/ |
132 | int32_t call_idx; | 131 | int32_t friend_id; |
133 | int32_t friend_number; | ||
134 | 132 | ||
135 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ | 133 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ |
136 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ | 134 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ |
@@ -145,7 +143,7 @@ typedef struct CSSession_s { | |||
145 | void cs_do(CSSession *cs); | 143 | void cs_do(CSSession *cs); |
146 | 144 | ||
147 | /* Make sure to be called BEFORE corresponding rtp_new */ | 145 | /* Make sure to be called BEFORE corresponding rtp_new */ |
148 | CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, uint32_t p_video_b); | 146 | CSSession *cs_new(uint32_t peer_mvfpsz); |
149 | /* Make sure to be called AFTER corresponding rtp_kill */ | 147 | /* Make sure to be called AFTER corresponding rtp_kill */ |
150 | void cs_kill(CSSession *cs); | 148 | void cs_kill(CSSession *cs); |
151 | 149 | ||
diff --git a/toxav/msi.c b/toxav/msi.c index cc855613..16476364 100644 --- a/toxav/msi.c +++ b/toxav/msi.c | |||
@@ -50,8 +50,7 @@ typedef enum { | |||
50 | IDResponse, | 50 | IDResponse, |
51 | IDError, | 51 | IDError, |
52 | IDCapabilities, | 52 | IDCapabilities, |
53 | IDMVFSZ, | 53 | IDVFPSZ, |
54 | IDMVFPSZ, | ||
55 | 54 | ||
56 | } MSIHeaderID; | 55 | } MSIHeaderID; |
57 | 56 | ||
@@ -79,8 +78,7 @@ GENERIC_HEADER ( Request, MSIRequest ); | |||
79 | GENERIC_HEADER ( Response, MSIResponse ); | 78 | GENERIC_HEADER ( Response, MSIResponse ); |
80 | GENERIC_HEADER ( Error, MSIError ); | 79 | GENERIC_HEADER ( Error, MSIError ); |
81 | GENERIC_HEADER ( Capabilities, uint8_t ); | 80 | GENERIC_HEADER ( Capabilities, uint8_t ); |
82 | GENERIC_HEADER ( MVFSZ, uint16_t ); | 81 | GENERIC_HEADER ( VFPSZ, uint16_t ); |
83 | GENERIC_HEADER ( MVFPSZ, uint16_t ); | ||
84 | 82 | ||
85 | 83 | ||
86 | typedef struct { | 84 | typedef struct { |
@@ -88,8 +86,7 @@ typedef struct { | |||
88 | MSIHeaderResponse response; | 86 | MSIHeaderResponse response; |
89 | MSIHeaderError error; | 87 | MSIHeaderError error; |
90 | MSIHeaderCapabilities capabilities; | 88 | MSIHeaderCapabilities capabilities; |
91 | MSIHeaderMVFSZ mvfsz; /* Max video frame size. NOTE: Value must be in network b-order */ | 89 | MSIHeaderVFPSZ vfpsz; /* Video frame piece size. NOTE: Value must be in network b-order */ |
92 | MSIHeaderMVFPSZ mvfpsz; /* Max video frame piece size. NOTE: Value must be in network b-order */ | ||
93 | } MSIMessage; | 90 | } MSIMessage; |
94 | 91 | ||
95 | 92 | ||
@@ -200,12 +197,9 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_ | |||
200 | 197 | ||
201 | msg_invite.capabilities.exists = true; | 198 | msg_invite.capabilities.exists = true; |
202 | msg_invite.capabilities.value = capabilities; | 199 | msg_invite.capabilities.value = capabilities; |
203 | 200 | ||
204 | msg_invite.mvfsz.exists = true; | 201 | msg_invite.vfpsz.exists = true; |
205 | msg_invite.mvfsz.value = htons(D_MVFSZ); | 202 | msg_invite.vfpsz.value = htons(VIDEOFRAME_PIECE_SIZE); |
206 | |||
207 | msg_invite.mvfpsz.exists = true; | ||
208 | msg_invite.mvfpsz.value = htons(D_MVFPSZ); | ||
209 | 203 | ||
210 | send_message ( (*call)->session->messenger, (*call)->friend_id, &msg_invite ); | 204 | send_message ( (*call)->session->messenger, (*call)->friend_id, &msg_invite ); |
211 | 205 | ||
@@ -216,7 +210,7 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_ | |||
216 | } | 210 | } |
217 | int msi_hangup ( MSICall* call ) | 211 | int msi_hangup ( MSICall* call ) |
218 | { | 212 | { |
219 | LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index); | 213 | LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_id); |
220 | 214 | ||
221 | MSIMessage msg_end; | 215 | MSIMessage msg_end; |
222 | msg_end.request.exists = true; | 216 | msg_end.request.exists = true; |
@@ -244,11 +238,8 @@ int msi_answer ( MSICall* call, uint8_t capabilities ) | |||
244 | msg_starting.capabilities.exists = true; | 238 | msg_starting.capabilities.exists = true; |
245 | msg_starting.capabilities.value = capabilities; | 239 | msg_starting.capabilities.value = capabilities; |
246 | 240 | ||
247 | msg_starting.mvfsz.exists = true; | 241 | msg_starting.vfpsz.exists = true; |
248 | msg_starting.mvfsz.value = htons(D_MVFSZ); | 242 | msg_starting.vfpsz.value = htons(VIDEOFRAME_PIECE_SIZE); |
249 | |||
250 | msg_starting.mvfpsz.exists = true; | ||
251 | msg_starting.mvfpsz.value = htons(D_MVFPSZ); | ||
252 | 243 | ||
253 | send_message ( call->session->messenger, call->friend_id, &msg_starting ); | 244 | send_message ( call->session->messenger, call->friend_id, &msg_starting ); |
254 | 245 | ||
@@ -256,7 +247,7 @@ int msi_answer ( MSICall* call, uint8_t capabilities ) | |||
256 | } | 247 | } |
257 | int msi_reject ( MSICall* call ) | 248 | int msi_reject ( MSICall* call ) |
258 | { | 249 | { |
259 | LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown"); | 250 | LOGGER_DEBUG("Session: %p Rejecting call with friend: %u", call->session, call->friend_id); |
260 | 251 | ||
261 | if ( call->state != msi_CallRequested ) { | 252 | if ( call->state != msi_CallRequested ) { |
262 | LOGGER_ERROR("Call is in invalid state!"); | 253 | LOGGER_ERROR("Call is in invalid state!"); |
@@ -353,14 +344,9 @@ int msg_parse_in ( MSIMessage *dest, const uint8_t *data, uint16_t length ) | |||
353 | SET_UINT8(it, dest->capabilities); | 344 | SET_UINT8(it, dest->capabilities); |
354 | break; | 345 | break; |
355 | 346 | ||
356 | case IDMVFSZ: | 347 | case IDVFPSZ: |
357 | CHECK_SIZE(it, size_constraint, 2); | ||
358 | SET_UINT16(it, dest->mvfsz); | ||
359 | break; | ||
360 | |||
361 | case IDMVFPSZ: | ||
362 | CHECK_SIZE(it, size_constraint, 2); | 348 | CHECK_SIZE(it, size_constraint, 2); |
363 | SET_UINT16(it, dest->mvfpsz); | 349 | SET_UINT16(it, dest->vfpsz); |
364 | break; | 350 | break; |
365 | 351 | ||
366 | default: | 352 | default: |
@@ -408,33 +394,28 @@ int send_message ( Messenger* m, uint32_t friend_id, const MSIMessage *msg ) | |||
408 | if (msg->request.exists) { | 394 | if (msg->request.exists) { |
409 | uint8_t cast = msg->request.value; | 395 | uint8_t cast = msg->request.value; |
410 | it = msg_parse_header_out(IDRequest, it, &cast, | 396 | it = msg_parse_header_out(IDRequest, it, &cast, |
411 | sizeof(cast), &size); | 397 | sizeof(cast), &size); |
412 | } | 398 | } |
413 | 399 | ||
414 | if (msg->response.exists) { | 400 | if (msg->response.exists) { |
415 | uint8_t cast = msg->response.value; | 401 | uint8_t cast = msg->response.value; |
416 | it = msg_parse_header_out(IDResponse, it, &cast, | 402 | it = msg_parse_header_out(IDResponse, it, &cast, |
417 | sizeof(cast), &size); | 403 | sizeof(cast), &size); |
418 | } | 404 | } |
419 | 405 | ||
420 | if (msg->error.exists) { | 406 | if (msg->error.exists) { |
421 | it = msg_parse_header_out(IDError, it, &msg->error.value, | 407 | it = msg_parse_header_out(IDError, it, &msg->error.value, |
422 | sizeof(msg->error.value), &size); | 408 | sizeof(msg->error.value), &size); |
423 | } | 409 | } |
424 | 410 | ||
425 | if (msg->capabilities.exists) { | 411 | if (msg->capabilities.exists) { |
426 | it = msg_parse_header_out(IDCapabilities, it, &msg->capabilities.value, | 412 | it = msg_parse_header_out(IDCapabilities, it, &msg->capabilities.value, |
427 | sizeof(msg->capabilities.value), &size); | 413 | sizeof(msg->capabilities.value), &size); |
428 | } | 414 | } |
429 | 415 | ||
430 | if (msg->mvfsz.exists) { | 416 | if (msg->vfpsz.exists) { |
431 | it = msg_parse_header_out(IDMVFSZ, it, &msg->mvfsz.value, | 417 | it = msg_parse_header_out(IDVFPSZ, it, &msg->vfpsz.value, |
432 | sizeof(msg->mvfsz.value), &size); | 418 | sizeof(msg->vfpsz.value), &size); |
433 | } | ||
434 | |||
435 | if (msg->mvfpsz.exists) { | ||
436 | it = msg_parse_header_out(IDMVFPSZ, it, &msg->mvfpsz.value, | ||
437 | sizeof(msg->mvfpsz.value), &size); | ||
438 | } | 419 | } |
439 | 420 | ||
440 | *it = 0; | 421 | *it = 0; |
@@ -494,6 +475,7 @@ MSICall *new_call ( MSISession *session, uint32_t friend_id ) | |||
494 | if (rc == NULL) | 475 | if (rc == NULL) |
495 | return NULL; | 476 | return NULL; |
496 | 477 | ||
478 | rc->session = session; | ||
497 | rc->friend_id = friend_id; | 479 | rc->friend_id = friend_id; |
498 | 480 | ||
499 | if (session->calls == NULL) { /* Creating */ | 481 | if (session->calls == NULL) { /* Creating */ |
@@ -617,28 +599,14 @@ int handle_recv_invite ( MSICall *call, const MSIMessage *msg ) | |||
617 | 599 | ||
618 | LOGGER_DEBUG("Glare detected!"); | 600 | LOGGER_DEBUG("Glare detected!"); |
619 | 601 | ||
620 | if (!msg->mvfsz.exists) { | 602 | if (!msg->vfpsz.exists) { |
621 | LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'"); | ||
622 | call->error = msi_InvalidMessage; | ||
623 | return -1; | ||
624 | } | ||
625 | |||
626 | if (!msg->mvfpsz.exists) { | ||
627 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); | 603 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); |
628 | call->error = msi_InvalidMessage; | 604 | call->error = msi_InvalidMessage; |
629 | return -1; | 605 | return -1; |
630 | } | 606 | } |
631 | 607 | ||
632 | call->peer_capabilities = msg->capabilities.value; | 608 | call->peer_capabilities = msg->capabilities.value; |
633 | 609 | call->peer_vfpsz = ntohs(msg->vfpsz.value); | |
634 | call->peer_mvfsz = ntohs(msg->mvfsz.value); | ||
635 | call->peer_mvfpsz = ntohs(msg->mvfpsz.value); | ||
636 | |||
637 | if (call->peer_mvfsz > call->peer_mvfpsz) { | ||
638 | LOGGER_WARNING("Session: %p mvfsz param greater than mvfpsz on 'invite'"); | ||
639 | call->error = msi_InvalidParam; | ||
640 | return -1; | ||
641 | } | ||
642 | 610 | ||
643 | /* Send response */ | 611 | /* Send response */ |
644 | response.response.value = resp_starting; | 612 | response.response.value = resp_starting; |
@@ -665,24 +633,14 @@ int handle_recv_invite ( MSICall *call, const MSIMessage *msg ) | |||
665 | return 0; | 633 | return 0; |
666 | } | 634 | } |
667 | 635 | ||
668 | 636 | if (!msg->vfpsz.exists) { | |
669 | if (!msg->mvfsz.exists) { | ||
670 | LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'"); | ||
671 | call->error = msi_InvalidMessage; | ||
672 | return -1; | ||
673 | } | ||
674 | |||
675 | if (!msg->mvfpsz.exists) { | ||
676 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); | 637 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); |
677 | call->error = msi_InvalidMessage; | 638 | call->error = msi_InvalidMessage; |
678 | return -1; | 639 | return -1; |
679 | } | 640 | } |
680 | 641 | ||
681 | call->peer_capabilities = msg->capabilities.value; | 642 | call->peer_capabilities = msg->capabilities.value; |
682 | 643 | call->peer_vfpsz = ntohs(msg->vfpsz.value); | |
683 | call->peer_mvfsz = ntohs(msg->mvfsz.value); | ||
684 | call->peer_mvfpsz = ntohs(msg->mvfpsz.value); | ||
685 | |||
686 | call->state = msi_CallRequested; | 644 | call->state = msi_CallRequested; |
687 | 645 | ||
688 | /* Send response */ | 646 | /* Send response */ |
@@ -781,31 +739,16 @@ int handle_recv_starting ( MSICall *call, const MSIMessage *msg ) | |||
781 | return -1; | 739 | return -1; |
782 | } | 740 | } |
783 | 741 | ||
784 | if (!msg->mvfsz.exists) { | 742 | if (!msg->vfpsz.exists) { |
785 | LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'"); | ||
786 | call->error = msi_InvalidParam; | ||
787 | return -1; | ||
788 | } | ||
789 | |||
790 | if (!msg->mvfpsz.exists) { | ||
791 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); | 743 | LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'"); |
792 | call->error = msi_InvalidParam; | 744 | call->error = msi_InvalidParam; |
793 | return -1; | 745 | return -1; |
794 | } | 746 | } |
795 | 747 | ||
796 | call->peer_capabilities = msg->capabilities.value; | 748 | call->peer_capabilities = msg->capabilities.value; |
797 | 749 | call->peer_vfpsz = ntohs(msg->vfpsz.value); | |
798 | call->peer_mvfsz = ntohs(msg->mvfsz.value); | ||
799 | call->peer_mvfpsz = ntohs(msg->mvfpsz.value); | ||
800 | |||
801 | |||
802 | if (call->peer_mvfsz > call->peer_mvfpsz) { | ||
803 | LOGGER_WARNING("Session: %p mvfsz param greater than mvfpsz on 'invite'"); | ||
804 | call->error = msi_InvalidParam; | ||
805 | return -1; | ||
806 | } | ||
807 | |||
808 | call->state = msi_CallActive; | 750 | call->state = msi_CallActive; |
751 | |||
809 | invoke_callback(call, msi_OnStart); | 752 | invoke_callback(call, msi_OnStart); |
810 | } | 753 | } |
811 | /* Otherwise it's a glare case so don't start until 'start' is recved */ | 754 | /* Otherwise it's a glare case so don't start until 'start' is recved */ |
diff --git a/toxav/msi.h b/toxav/msi.h index 4f27b9f8..a55d8567 100644 --- a/toxav/msi.h +++ b/toxav/msi.h | |||
@@ -28,9 +28,8 @@ | |||
28 | #include "codec.h" | 28 | #include "codec.h" |
29 | #include "../toxcore/Messenger.h" | 29 | #include "../toxcore/Messenger.h" |
30 | 30 | ||
31 | /** Preconfigured values for video splitting */ | 31 | /** Preconfigured value for video splitting */ |
32 | #define D_MVFSZ 40000 /* 256KiB */ | 32 | #define VIDEOFRAME_PIECE_SIZE 500 /* 1.25 KiB*/ |
33 | #define D_MVFPSZ 500 /* 1.25 KiB*/ | ||
34 | 33 | ||
35 | /** | 34 | /** |
36 | * Error codes. | 35 | * Error codes. |
@@ -87,15 +86,10 @@ typedef struct MSICall_s { | |||
87 | struct MSISession_s *session; /* Session pointer */ | 86 | struct MSISession_s *session; /* Session pointer */ |
88 | 87 | ||
89 | MSICallState state; | 88 | MSICallState state; |
90 | |||
91 | uint8_t peer_capabilities; /* Peer capabilities */ | 89 | uint8_t peer_capabilities; /* Peer capabilities */ |
92 | uint8_t self_capabilities; /* Self capabilities */ | 90 | uint8_t self_capabilities; /* Self capabilities */ |
93 | 91 | uint16_t peer_vfpsz; /* Video frame piece size */ | |
94 | uint16_t peer_mvfsz; /* Max video frame size */ | ||
95 | uint16_t peer_mvfpsz; /* Max video frame part size */ | ||
96 | |||
97 | uint32_t friend_id; /* Index of this call in MSISession */ | 92 | uint32_t friend_id; /* Index of this call in MSISession */ |
98 | |||
99 | MSIError error; /* Last error */ | 93 | MSIError error; /* Last error */ |
100 | 94 | ||
101 | void* av_call; /* Pointer to av call handler */ | 95 | void* av_call; /* Pointer to av call handler */ |
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 | ||
diff --git a/toxav/toxav_new_1.c b/toxav/toxav_new_1.c index ee7f49a6..145dcf48 100644 --- a/toxav/toxav_new_1.c +++ b/toxav/toxav_new_1.c | |||
@@ -317,7 +317,6 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, int support_vide | |||
317 | } | 317 | } |
318 | 318 | ||
319 | call->cs->agent = av; | 319 | call->cs->agent = av; |
320 | call->cs->call_idx = call_index; | ||
321 | 320 | ||
322 | call->cs->acb.first = av->acb.first; | 321 | call->cs->acb.first = av->acb.first; |
323 | call->cs->acb.second = av->acb.second; | 322 | call->cs->acb.second = av->acb.second; |