summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-07-26 21:26:32 -0400
committerirungentoo <irungentoo@gmail.com>2014-07-26 21:26:32 -0400
commitab4673e87340b24c58ceaf82e2d41b5a3bee695f (patch)
tree57a628ee871992cb789b310d95cf0cc12f72aabf /toxav
parentd052bbc3ebb378c9a69bbd7e35f001da2e2782aa (diff)
parentee3822f24b14a76e6e1d833f521618f38bdc26b9 (diff)
Merge branch 'mannol1-master'
Diffstat (limited to 'toxav')
-rw-r--r--toxav/msi.c199
-rw-r--r--toxav/msi.h27
-rw-r--r--toxav/toxav.c129
-rw-r--r--toxav/toxav.h44
4 files changed, 279 insertions, 120 deletions
diff --git a/toxav/msi.c b/toxav/msi.c
index 73429a81..c4b09894 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -48,13 +48,14 @@
48 * |id [1 byte]| |size [1 byte]| |data [$size bytes]| |...{repeat}| |0 {end byte}| 48 * |id [1 byte]| |size [1 byte]| |data [$size bytes]| |...{repeat}| |0 {end byte}|
49 */ 49 */
50 50
51typedef uint8_t MSIRawCSettingsType[23];
51 52
52typedef enum { 53typedef enum {
53 IDRequest = 1, 54 IDRequest = 1,
54 IDResponse, 55 IDResponse,
55 IDReason, 56 IDReason,
56 IDCallType,
57 IDCallId, 57 IDCallId,
58 IDCSettings,
58 59
59} MSIHeaderID; 60} MSIHeaderID;
60 61
@@ -91,9 +92,9 @@ _Bool exists; \
91 92
92GENERIC_HEADER ( Request, MSIRequest ) 93GENERIC_HEADER ( Request, MSIRequest )
93GENERIC_HEADER ( Response, MSIResponse ) 94GENERIC_HEADER ( Response, MSIResponse )
94GENERIC_HEADER ( CallType, MSICallType )
95GENERIC_HEADER ( CallId, MSICallIDType ) 95GENERIC_HEADER ( CallId, MSICallIDType )
96GENERIC_HEADER ( Reason, MSIReasonStrType ) 96GENERIC_HEADER ( Reason, MSIReasonStrType )
97GENERIC_HEADER ( CSettings, MSIRawCSettingsType )
97 98
98 99
99/** 100/**
@@ -105,9 +106,9 @@ typedef struct _MSIMessage {
105 106
106 MSIHeaderRequest request; 107 MSIHeaderRequest request;
107 MSIHeaderResponse response; 108 MSIHeaderResponse response;
108 MSIHeaderCallType calltype;
109 MSIHeaderReason reason; 109 MSIHeaderReason reason;
110 MSIHeaderCallId callid; 110 MSIHeaderCallId callid;
111 MSIHeaderCSettings csettings;
111 112
112 int friend_id; 113 int friend_id;
113 114
@@ -173,15 +174,6 @@ static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t lengt
173 msg->response.exists = 1; 174 msg->response.exists = 1;
174 break; 175 break;
175 176
176 case IDCallType:
177 FAIL_CONSTRAINT(size_constraint, 3);
178 FAIL_SIZE(it[1], 1);
179 FAIL_LIMITS(it[2], type_audio, type_video);
180 msg->calltype.value = it[2];
181 it += 3;
182 msg->calltype.exists = 1;
183 break;
184
185 case IDCallId: 177 case IDCallId:
186 FAIL_CONSTRAINT(size_constraint, sizeof(MSICallIDType) + 2); 178 FAIL_CONSTRAINT(size_constraint, sizeof(MSICallIDType) + 2);
187 FAIL_SIZE(it[1], sizeof(MSICallIDType)); 179 FAIL_SIZE(it[1], sizeof(MSICallIDType));
@@ -198,6 +190,14 @@ static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t lengt
198 msg->reason.exists = 1; 190 msg->reason.exists = 1;
199 break; 191 break;
200 192
193 case IDCSettings:
194 FAIL_CONSTRAINT(size_constraint, sizeof(MSIRawCSettingsType) + 2);
195 FAIL_SIZE(it[1], sizeof(MSIRawCSettingsType));
196 memcpy(msg->csettings.value, it + 2, sizeof(MSIRawCSettingsType));
197 it += sizeof(MSIRawCSettingsType) + 2;
198 msg->csettings.exists = 1;
199 break;
200
201 default: 201 default:
202 LOGGER_ERROR("Invalid id byte"); 202 LOGGER_ERROR("Invalid id byte");
203 return -1; 203 return -1;
@@ -336,11 +336,6 @@ uint16_t parse_send ( MSIMessage *msg, uint8_t *dest )
336 it = format_output(it, IDResponse, &cast, 1, &size); 336 it = format_output(it, IDResponse, &cast, 1, &size);
337 } 337 }
338 338
339 if (msg->calltype.exists) {
340 uint8_t cast = msg->calltype.value;
341 it = format_output(it, IDCallType, &cast, 1, &size);
342 }
343
344 if (msg->callid.exists) { 339 if (msg->callid.exists) {
345 it = format_output(it, IDCallId, &msg->callid.value, sizeof(msg->callid.value), &size); 340 it = format_output(it, IDCallId, &msg->callid.value, sizeof(msg->callid.value), &size);
346 } 341 }
@@ -349,21 +344,16 @@ uint16_t parse_send ( MSIMessage *msg, uint8_t *dest )
349 it = format_output(it, IDReason, &msg->reason.value, sizeof(msg->reason.value), &size); 344 it = format_output(it, IDReason, &msg->reason.value, sizeof(msg->reason.value), &size);
350 } 345 }
351 346
347 if (msg->csettings.exists) {
348 it = format_output(it, IDCSettings, &msg->csettings.value, sizeof(msg->csettings.value), &size);
349 }
350
352 *it = 0; 351 *it = 0;
353 size ++; 352 size ++;
354 353
355 return size; 354 return size;
356} 355}
357 356
358
359void msi_msg_set_calltype ( MSIMessage *msg, const MSICallType value )
360{
361 if ( !msg ) return;
362
363 msg->calltype.exists = 1;
364 msg->calltype.value = value;
365}
366
367void msi_msg_set_reason ( MSIMessage *msg, const MSIReasonStrType value ) 357void msi_msg_set_reason ( MSIMessage *msg, const MSIReasonStrType value )
368{ 358{
369 if ( !msg ) return; 359 if ( !msg ) return;
@@ -380,6 +370,84 @@ void msi_msg_set_callid ( MSIMessage *msg, const MSICallIDType value )
380 memcpy(msg->callid.value, value, sizeof(MSICallIDType)); 370 memcpy(msg->callid.value, value, sizeof(MSICallIDType));
381} 371}
382 372
373void msi_msg_set_csettings ( MSIMessage *msg, const MSICSettings *value )
374{
375 if ( !msg ) return;
376
377 msg->csettings.exists = 1;
378
379 msg->csettings.value[0] = value->call_type;
380 uint8_t *iter = msg->csettings.value + 1;
381
382 /* Video bitrate */
383 uint32_t lval = htonl(value->video_bitrate);
384 memcpy(iter, &lval, 4);
385 iter += 4;
386
387 /* Video max width */
388 uint16_t sval = htons(value->max_video_width);
389 memcpy(iter, &sval, 2);
390 iter += 2;
391
392 /* Video max height */
393 sval = htons(value->max_video_height);
394 memcpy(iter, &sval, 2);
395 iter += 2;
396
397 /* Audio bitrate */
398 lval = htonl(value->audio_bitrate);
399 memcpy(iter, &lval, 4);
400 iter += 4;
401
402 /* Audio frame duration */
403 sval = htons(value->audio_frame_duration);
404 memcpy(iter, &sval, 2);
405 iter += 2;
406
407 /* Audio sample rate */
408 lval = htonl(value->audio_sample_rate);
409 memcpy(iter, &lval, 4);
410 iter += 4;
411
412 /* Audio channels */
413 lval = htonl(value->audio_channels);
414 memcpy(iter, &lval, 4);
415}
416
417void msi_msg_get_csettings ( MSIMessage *msg, MSICSettings *dest )
418{
419 if ( !msg || !dest || !msg->csettings.exists ) return;
420
421 dest->call_type = msg->csettings.value[0];
422 uint8_t *iter = msg->csettings.value + 1;
423
424 memcpy(&dest->video_bitrate, iter, 4);
425 iter += 4;
426 dest->video_bitrate = ntohl(dest->video_bitrate);
427
428 memcpy(&dest->max_video_width, iter, 2);
429 iter += 2;
430 dest->max_video_width = ntohs(dest->max_video_width);
431
432 memcpy(&dest->max_video_height, iter, 2);
433 iter += 2;
434 dest->max_video_height = ntohs(dest->max_video_height);
435
436 memcpy(&dest->audio_bitrate, iter, 4);
437 iter += 4;
438 dest->audio_bitrate = ntohl(dest->audio_bitrate);
439
440 memcpy(&dest->audio_frame_duration, iter, 2);
441 iter += 2;
442 dest->audio_frame_duration = ntohs(dest->audio_frame_duration);
443
444 memcpy(&dest->audio_sample_rate, iter, 4);
445 iter += 4;
446 dest->audio_sample_rate = ntohl(dest->audio_sample_rate);
447
448 memcpy(&dest->audio_channels, iter, 4);
449 dest->audio_channels = ntohl(dest->audio_channels);
450}
383 451
384typedef struct _Timer { 452typedef struct _Timer {
385 void *(*func)(void *); 453 void *(*func)(void *);
@@ -753,14 +821,33 @@ static int call_id_bigger( const uint8_t *first, const uint8_t *second)
753 * @param peer_id The peer. 821 * @param peer_id The peer.
754 * @return -1, 0 822 * @return -1, 0
755 */ 823 */
756static int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) 824static int flush_peer_csettings ( MSICall *call, MSIMessage *msg, int peer_id )
757{ 825{
758 if ( msg->calltype.exists ) { 826 if ( msg->csettings.exists ) {
759 call->type_peer[peer_id] = msg->calltype.value; 827 msi_msg_get_csettings(msg, &call->csettings_peer[peer_id]);
828
829 LOGGER_DEBUG("Peer: %d \n"
830 "Type: %u \n"
831 "Video bitrate: %u \n"
832 "Video height: %u \n"
833 "Video width: %u \n"
834 "Audio bitrate: %u \n"
835 "Audio framedur: %u \n"
836 "Audio sample rate: %u \n"
837 "Audio channels: %u \n", peer_id,
838 call->csettings_peer[peer_id].call_type,
839 call->csettings_peer[peer_id].video_bitrate,
840 call->csettings_peer[peer_id].max_video_height,
841 call->csettings_peer[peer_id].max_video_width,
842 call->csettings_peer[peer_id].audio_bitrate,
843 call->csettings_peer[peer_id].audio_frame_duration,
844 call->csettings_peer[peer_id].audio_sample_rate,
845 call->csettings_peer[peer_id].audio_channels );
846
760 return 0; 847 return 0;
761 } 848 }
762 849
763 LOGGER_WARNING("No call type header!"); 850 LOGGER_WARNING("No csettings header!");
764 return -1; 851 return -1;
765} 852}
766 853
@@ -904,7 +991,7 @@ static MSICall *init_call ( MSISession *session, int peers, int ringing_timeout
904 991
905 call->call_idx = call_idx; 992 call->call_idx = call_idx;
906 993
907 if ( !(call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) { 994 if ( !(call->csettings_peer = calloc ( sizeof ( MSICSettings ), peers )) ) {
908 LOGGER_WARNING("Allocation failed! Program might misbehave!"); 995 LOGGER_WARNING("Allocation failed! Program might misbehave!");
909 free(call); 996 free(call);
910 return NULL; 997 return NULL;
@@ -912,8 +999,6 @@ static MSICall *init_call ( MSISession *session, int peers, int ringing_timeout
912 999
913 call->session = session; 1000 call->session = session;
914 1001
915 /*_call->_participant_count = _peers;*/
916
917 call->request_timer_id = 0; 1002 call->request_timer_id = 0;
918 call->ringing_timer_id = 0; 1003 call->ringing_timer_id = 0;
919 1004
@@ -954,7 +1039,7 @@ static int terminate_call ( MSISession *session, MSICall *call )
954 1039
955 session->calls[call->call_idx] = NULL; 1040 session->calls[call->call_idx] = NULL;
956 1041
957 free ( call->type_peer ); 1042 free ( call->csettings_peer );
958 free ( call->peers); 1043 free ( call->peers);
959 1044
960 /* Release handle */ 1045 /* Release handle */
@@ -1012,8 +1097,8 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
1012 1097
1013 pthread_mutex_lock(&session->mutex); 1098 pthread_mutex_lock(&session->mutex);
1014 1099
1015 if (!msg->calltype.exists) {/**/ 1100 if (!msg->csettings.exists) {/**/
1016 LOGGER_WARNING("Peer sent invalid call type!"); 1101 LOGGER_WARNING("Peer sent invalid codec settings!");
1017 send_error ( session, call, error_no_callid, msg->friend_id ); 1102 send_error ( session, call, error_no_callid, msg->friend_id );
1018 pthread_mutex_unlock(&session->mutex); 1103 pthread_mutex_unlock(&session->mutex);
1019 return 0; 1104 return 0;
@@ -1049,14 +1134,14 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
1049 } 1134 }
1050 } else if (call->state == call_active) { 1135 } else if (call->state == call_active) {
1051 /* Request for media change; call callback and send starting response */ 1136 /* Request for media change; call callback and send starting response */
1052 if (flush_peer_type(call, msg, 0) != 0) { /**/ 1137 if (flush_peer_csettings(call, msg, 0) != 0) { /**/
1053 LOGGER_WARNING("Peer sent invalid call type!"); 1138 LOGGER_WARNING("Peer sent invalid csetting!");
1054 send_error ( session, call, error_no_callid, msg->friend_id ); 1139 send_error ( session, call, error_no_callid, msg->friend_id );
1055 pthread_mutex_unlock(&session->mutex); 1140 pthread_mutex_unlock(&session->mutex);
1056 return 0; 1141 return 0;
1057 } 1142 }
1058 1143
1059 LOGGER_DEBUG("Set new call type: %s", call->type_peer[0] == type_audio ? "audio" : "video"); 1144 LOGGER_DEBUG("Set new call type: %s", call->csettings_peer[0].call_type == type_audio ? "audio" : "video");
1060 send_reponse(session, call, starting, msg->friend_id); 1145 send_reponse(session, call, starting, msg->friend_id);
1061 pthread_mutex_unlock(&session->mutex); 1146 pthread_mutex_unlock(&session->mutex);
1062 invoke_callback(session, call->call_idx, MSI_OnMediaChange); 1147 invoke_callback(session, call->call_idx, MSI_OnMediaChange);
@@ -1090,7 +1175,7 @@ static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *
1090 1175
1091 add_peer( call, msg->friend_id); 1176 add_peer( call, msg->friend_id);
1092 1177
1093 flush_peer_type ( call, msg, 0 ); 1178 flush_peer_csettings ( call, msg, 0 );
1094 1179
1095 send_reponse(session, call, ringing, msg->friend_id); 1180 send_reponse(session, call, ringing, msg->friend_id);
1096 1181
@@ -1234,7 +1319,7 @@ static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage
1234 free ( msg_start ); 1319 free ( msg_start );
1235 1320
1236 1321
1237 flush_peer_type ( call, msg, 0 ); 1322 flush_peer_csettings ( call, msg, 0 );
1238 1323
1239 /* This is here in case of glare */ 1324 /* This is here in case of glare */
1240 timer_release ( session->timer_handler, call->ringing_timer_id, 1 ); 1325 timer_release ( session->timer_handler, call->ringing_timer_id, 1 );
@@ -1536,7 +1621,7 @@ int msi_terminate_session ( MSISession *session )
1536 * @param friend_id The friend. 1621 * @param friend_id The friend.
1537 * @return int 1622 * @return int
1538 */ 1623 */
1539int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ) 1624int msi_invite ( MSISession *session, int32_t *call_index, MSICSettings csettings, uint32_t rngsec, uint32_t friend_id )
1540{ 1625{
1541 pthread_mutex_lock(&session->mutex); 1626 pthread_mutex_lock(&session->mutex);
1542 1627
@@ -1567,11 +1652,11 @@ int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type
1567 1652
1568 add_peer ( call, friend_id ); 1653 add_peer ( call, friend_id );
1569 1654
1570 call->type_local = call_type; 1655 call->csettings_local = csettings;
1571 1656
1572 MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite ); 1657 MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite );
1573 1658
1574 msi_msg_set_calltype(msg_invite, call_type); 1659 msi_msg_set_csettings(msg_invite, &csettings);
1575 send_message ( session, call, msg_invite, friend_id ); 1660 send_message ( session, call, msg_invite, friend_id );
1576 free( msg_invite ); 1661 free( msg_invite );
1577 1662
@@ -1641,7 +1726,7 @@ int msi_hangup ( MSISession *session, int32_t call_index )
1641 * @param call_type Answer with Audio or Video(both). 1726 * @param call_type Answer with Audio or Video(both).
1642 * @return int 1727 * @return int
1643 */ 1728 */
1644int msi_answer ( MSISession *session, int32_t call_index, MSICallType call_type ) 1729int msi_answer ( MSISession *session, int32_t call_index, MSICSettings csettings )
1645{ 1730{
1646 pthread_mutex_lock(&session->mutex); 1731 pthread_mutex_lock(&session->mutex);
1647 LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index); 1732 LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index);
@@ -1654,9 +1739,9 @@ int msi_answer ( MSISession *session, int32_t call_index, MSICallType call_type
1654 1739
1655 MSIMessage *msg_starting = msi_new_message ( TypeResponse, starting ); 1740 MSIMessage *msg_starting = msi_new_message ( TypeResponse, starting );
1656 1741
1657 session->calls[call_index]->type_local = call_type; 1742 session->calls[call_index]->csettings_local = csettings;
1658 1743
1659 msi_msg_set_calltype(msg_starting, call_type); 1744 msi_msg_set_csettings(msg_starting, &csettings);
1660 1745
1661 send_message ( session, session->calls[call_index], msg_starting, session->calls[call_index]->peers[0] ); 1746 send_message ( session, session->calls[call_index], msg_starting, session->calls[call_index]->peers[0] );
1662 free ( msg_starting ); 1747 free ( msg_starting );
@@ -1766,7 +1851,7 @@ int msi_reject ( MSISession *session, int32_t call_index, const char *reason )
1766 * @param friend_id The friend. 1851 * @param friend_id The friend.
1767 * @return int 1852 * @return int
1768 */ 1853 */
1769int msi_change_type(MSISession *session, int32_t call_index, MSICallType call_type) 1854int msi_change_csettings(MSISession *session, int32_t call_index, MSICSettings csettings)
1770{ 1855{
1771 pthread_mutex_lock(&session->mutex); 1856 pthread_mutex_lock(&session->mutex);
1772 1857
@@ -1786,17 +1871,27 @@ int msi_change_type(MSISession *session, int32_t call_index, MSICallType call_ty
1786 return -1; 1871 return -1;
1787 } 1872 }
1788 1873
1789 if ( call->type_local == call_type ) { 1874 MSICSettings *local = &call->csettings_local;
1790 LOGGER_ERROR("Call is already set to the requested type!"); 1875
1876 if (
1877 local->call_type == csettings.call_type &&
1878 local->video_bitrate == csettings.video_bitrate &&
1879 local->max_video_width == csettings.max_video_width &&
1880 local->max_video_height == csettings.max_video_height &&
1881 local->audio_bitrate == csettings.audio_bitrate &&
1882 local->audio_frame_duration == csettings.audio_frame_duration &&
1883 local->audio_sample_rate == csettings.audio_sample_rate &&
1884 local->audio_channels == csettings.audio_channels ) {
1885 LOGGER_ERROR("Call is already set accordingly!");
1791 pthread_mutex_unlock(&session->mutex); 1886 pthread_mutex_unlock(&session->mutex);
1792 return -1; 1887 return -1;
1793 } 1888 }
1794 1889
1795 call->type_local = call_type; 1890 *local = csettings;
1796 1891
1797 MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite ); 1892 MSIMessage *msg_invite = msi_new_message ( TypeRequest, invite );
1798 1893
1799 msi_msg_set_calltype ( msg_invite, call_type ); 1894 msi_msg_set_csettings ( msg_invite, local );
1800 send_message ( session, call, msg_invite, call->peers[0] ); 1895 send_message ( session, call, msg_invite, call->peers[0] );
1801 free ( msg_invite ); 1896 free ( msg_invite );
1802 1897
diff --git a/toxav/msi.h b/toxav/msi.h
index b99b2de8..64fa0881 100644
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -54,6 +54,22 @@ typedef enum {
54} MSICallState; 54} MSICallState;
55 55
56 56
57/**
58 * @brief Encoding settings.
59 */
60typedef struct _MSICodecSettings {
61 MSICallType call_type;
62
63 uint32_t video_bitrate; /* In kbits/s */
64 uint16_t max_video_width; /* In px */
65 uint16_t max_video_height; /* In px */
66
67 uint32_t audio_bitrate; /* In bits/s */
68 uint16_t audio_frame_duration; /* In ms */
69 uint32_t audio_sample_rate; /* In Hz */
70 uint32_t audio_channels;
71} MSICSettings;
72
57 73
58/** 74/**
59 * @brief Callbacks ids that handle the states 75 * @brief Callbacks ids that handle the states
@@ -94,8 +110,8 @@ typedef struct _MSICall { /* Call info structure */
94 110
95 MSICallState state; 111 MSICallState state;
96 112
97 MSICallType type_local; /* Type of payload user is ending */ 113 MSICSettings csettings_local; /* Local call settings */
98 MSICallType *type_peer; /* Type of payload others are sending */ 114 MSICSettings *csettings_peer; /* Peers call settings */
99 115
100 MSICallIDType id; /* Random value identifying the call */ 116 MSICallIDType id; /* Random value identifying the call */
101 117
@@ -176,7 +192,8 @@ int msi_terminate_session ( MSISession *session );
176 * @param friend_id The friend. 192 * @param friend_id The friend.
177 * @return int 193 * @return int
178 */ 194 */
179int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ); 195int msi_invite ( MSISession *session, int32_t *call_index, MSICSettings csettings, uint32_t rngsec,
196 uint32_t friend_id );
180 197
181 198
182/** 199/**
@@ -199,7 +216,7 @@ int msi_hangup ( MSISession *session, int32_t call_index );
199 * @param call_type Answer with Audio or Video(both). 216 * @param call_type Answer with Audio or Video(both).
200 * @return int 217 * @return int
201 */ 218 */
202int msi_answer ( MSISession *session, int32_t call_index, MSICallType call_type ); 219int msi_answer ( MSISession *session, int32_t call_index, MSICSettings csettings );
203 220
204 221
205/** 222/**
@@ -235,7 +252,7 @@ int msi_reject ( MSISession *session, int32_t call_index, const char *reason );
235 * @param friend_id The friend. 252 * @param friend_id The friend.
236 * @return int 253 * @return int
237 */ 254 */
238int msi_change_type ( MSISession *session, int32_t call_index, MSICallType call_type ); 255int msi_change_csettings ( MSISession *session, int32_t call_index, MSICSettings csettings );
239 256
240 257
241/** 258/**
diff --git a/toxav/toxav.c b/toxav/toxav.c
index e15c409d..1e5847a4 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -51,6 +51,24 @@
51/* call index invalid: true if invalid */ 51/* call index invalid: true if invalid */
52#define cii(c_idx, session) (c_idx < 0 || c_idx >= session->max_calls) 52#define cii(c_idx, session) (c_idx < 0 || c_idx >= session->max_calls)
53 53
54
55const ToxAvCSettings av_DefaultSettings = {
56 TypeAudio,
57
58 500,
59 1280,
60 720,
61
62 64000,
63 20,
64 48000,
65 1
66};
67
68const uint32_t av_jbufdc = 3;
69const uint32_t av_VADd = 40;
70
71
54static const uint8_t audio_index = 0, video_index = 1; 72static const uint8_t audio_index = 0, video_index = 1;
55 73
56typedef struct _CallSpecific { 74typedef struct _CallSpecific {
@@ -84,20 +102,39 @@ struct _ToxAv {
84 uint32_t max_calls; 102 uint32_t max_calls;
85}; 103};
86 104
87const ToxAvCodecSettings av_DefaultSettings = { 105static MSICSettings msicsettings_cast (const ToxAvCSettings *from)
88 500, 106{
89 1280, 107 MSICSettings csettings;
90 720, 108 csettings.call_type = from->call_type;
91 109
92 64000, 110 csettings.video_bitrate = from->video_bitrate;
93 20, 111 csettings.max_video_width = from->max_video_width;
94 48000, 112 csettings.max_video_height = from->max_video_height;
95 1,
96 600,
97 113
98 3 114 csettings.audio_bitrate = from->audio_bitrate;
99}; 115 csettings.audio_frame_duration = from->audio_frame_duration;
116 csettings.audio_sample_rate = from->audio_sample_rate;
117 csettings.audio_channels = from->audio_channels;
118
119 return csettings;
120}
121
122static ToxAvCSettings toxavcsettings_cast (const MSICSettings *from)
123{
124 ToxAvCSettings csettings;
125 csettings.call_type = from->call_type;
126
127 csettings.video_bitrate = from->video_bitrate;
128 csettings.max_video_width = from->max_video_width;
129 csettings.max_video_height = from->max_video_height;
100 130
131 csettings.audio_bitrate = from->audio_bitrate;
132 csettings.audio_frame_duration = from->audio_frame_duration;
133 csettings.audio_sample_rate = from->audio_sample_rate;
134 csettings.audio_channels = from->audio_channels;
135
136 return csettings;
137}
101 138
102/** 139/**
103 * @brief Start new A/V session. There can only be one session at the time. If you register more 140 * @brief Start new A/V session. There can only be one session at the time. If you register more
@@ -205,9 +242,9 @@ void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, in
205 * @retval 0 Success. 242 * @retval 0 Success.
206 * @retval ToxAvError On error. 243 * @retval ToxAvError On error.
207 */ 244 */
208int toxav_call (ToxAv *av, int32_t *call_index, int user, ToxAvCallType call_type, int ringing_seconds ) 245int toxav_call (ToxAv *av, int32_t *call_index, int user, const ToxAvCSettings *csettings, int ringing_seconds )
209{ 246{
210 return msi_invite(av->msi_session, call_index, call_type, ringing_seconds * 1000, user); 247 return msi_invite(av->msi_session, call_index, msicsettings_cast(csettings), ringing_seconds * 1000, user);
211} 248}
212 249
213/** 250/**
@@ -240,7 +277,7 @@ int toxav_hangup ( ToxAv *av, int32_t call_index )
240 * @retval 0 Success. 277 * @retval 0 Success.
241 * @retval ToxAvError On error. 278 * @retval ToxAvError On error.
242 */ 279 */
243int toxav_answer ( ToxAv *av, int32_t call_index, ToxAvCallType call_type ) 280int toxav_answer ( ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings )
244{ 281{
245 if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { 282 if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) {
246 return ErrorNoCall; 283 return ErrorNoCall;
@@ -250,7 +287,7 @@ int toxav_answer ( ToxAv *av, int32_t call_index, ToxAvCallType call_type )
250 return ErrorInvalidState; 287 return ErrorInvalidState;
251 } 288 }
252 289
253 return msi_answer(av->msi_session, call_index, call_type); 290 return msi_answer(av->msi_session, call_index, msicsettings_cast(csettings));
254} 291}
255 292
256/** 293/**
@@ -307,13 +344,13 @@ int toxav_cancel ( ToxAv *av, int32_t call_index, int peer_id, const char *reaso
307 * @retval 0 Success. 344 * @retval 0 Success.
308 * @retval ToxAvError On error. 345 * @retval ToxAvError On error.
309 */ 346 */
310int toxav_change_type(ToxAv *av, int32_t call_index, ToxAvCallType call_type) 347int toxav_change_settings(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings)
311{ 348{
312 if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { 349 if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) {
313 return ErrorNoCall; 350 return ErrorNoCall;
314 } 351 }
315 352
316 return msi_change_type(av->msi_session, call_index, call_type); 353 return msi_change_csettings(av->msi_session, call_index, msicsettings_cast(csettings));
317} 354}
318 355
319/** 356/**
@@ -341,10 +378,12 @@ int toxav_stop_call ( ToxAv *av, int32_t call_index )
341 * @retval 0 Success. 378 * @retval 0 Success.
342 * @retval ToxAvError On error. 379 * @retval ToxAvError On error.
343 */ 380 */
344int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) 381int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, uint32_t jbuf_capacity, uint32_t VAD_treshold,
382 int support_video )
345{ 383{
346 if ( !av->msi_session || cii(call_index, av->msi_session) || 384 if ( !av->msi_session || cii(call_index, av->msi_session) ||
347 !av->msi_session->calls[call_index] || av->calls[call_index].call_active) { 385 !av->msi_session->calls[call_index] || !av->msi_session->calls[call_index]->csettings_peer ||
386 av->calls[call_index].call_active) {
348 LOGGER_ERROR("Error while starting RTP session: invalid call!\n"); 387 LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
349 return ErrorInternal; 388 return ErrorInternal;
350 } 389 }
@@ -388,22 +427,42 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
388 427
389 } 428 }
390 429
391 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) { 430 if ( !(call->j_buf = create_queue(jbuf_capacity)) ) {
392 LOGGER_WARNING("Jitter buffer creaton failed!"); 431 LOGGER_WARNING("Jitter buffer creaton failed!");
393 goto error; 432 goto error;
394 } 433 }
395 434
396 if ( (call->cs = codec_init_session(codec_settings->audio_bitrate, 435 ToxAvCSettings csettings = toxavcsettings_cast(&av->msi_session->calls[call_index]->csettings_peer[0]);
397 codec_settings->audio_frame_duration, 436 LOGGER_DEBUG(
398 codec_settings->audio_sample_rate, 437 "Type: %u \n"
399 codec_settings->audio_channels, 438 "Video bitrate: %u \n"
400 codec_settings->audio_VAD_tolerance, 439 "Video height: %u \n"
401 codec_settings->max_video_width, 440 "Video width: %u \n"
402 codec_settings->max_video_height, 441 "Audio bitrate: %u \n"
403 codec_settings->video_bitrate) )) { 442 "Audio framedur: %u \n"
443 "Audio sample rate: %u \n"
444 "Audio channels: %u \n",
445 csettings.call_type,
446 csettings.video_bitrate,
447 csettings.max_video_height,
448 csettings.max_video_width,
449 csettings.audio_bitrate,
450 csettings.audio_frame_duration,
451 csettings.audio_sample_rate,
452 csettings.audio_channels );
453
454 if ( (call->cs = codec_init_session(csettings.audio_bitrate,
455 csettings.audio_frame_duration,
456 csettings.audio_sample_rate,
457 csettings.audio_channels,
458 VAD_treshold,
459 csettings.max_video_width,
460 csettings.max_video_height,
461 csettings.video_bitrate) )) {
404 462
405 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; 463 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
406 464
465 LOGGER_WARNING("Got here");
407 call->call_active = 1; 466 call->call_active = 1;
408 467
409 return ErrorNone; 468 return ErrorNone;
@@ -701,13 +760,14 @@ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t
701 * @retval ToxAvCallType On success. 760 * @retval ToxAvCallType On success.
702 * @retval ToxAvError On error. 761 * @retval ToxAvError On error.
703 */ 762 */
704int toxav_get_peer_transmission_type ( ToxAv *av, int32_t call_index, int peer ) 763int toxav_get_peer_csettings ( ToxAv *av, int32_t call_index, int peer, ToxAvCSettings *dest )
705{ 764{
706 if ( peer < 0 || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] 765 if ( peer < 0 || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index]
707 || av->msi_session->calls[call_index]->peer_count <= peer ) 766 || av->msi_session->calls[call_index]->peer_count <= peer )
708 return ErrorInternal; 767 return ErrorInternal;
709 768
710 return av->msi_session->calls[call_index]->type_peer[peer]; 769 *dest = toxavcsettings_cast(&av->msi_session->calls[call_index]->csettings_peer[peer]);
770 return ErrorNone;
711} 771}
712 772
713/** 773/**
@@ -782,7 +842,11 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
782 queue(call->j_buf, _msg); 842 queue(call->j_buf, _msg);
783 843
784 int success = 0, dec_size; 844 int success = 0, dec_size;
785 int frame_size = 960; 845
846 ToxAvCSettings csettings;
847 toxav_get_peer_csettings(av, call_index, 0, &csettings);
848
849 int frame_size = 10000; /* FIXME: not static? */
786 int16_t dest[frame_size]; 850 int16_t dest[frame_size];
787 851
788 while ((_msg = dequeue(call->j_buf, &success)) || success == 2) { 852 while ((_msg = dequeue(call->j_buf, &success)) || success == 2) {
@@ -799,10 +863,11 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
799 } 863 }
800 864
801 if ( av->audio_callback ) 865 if ( av->audio_callback )
802 av->audio_callback(av, call_index, dest, frame_size); 866 av->audio_callback(av, call_index, dest, dec_size);
803 else 867 else
804 LOGGER_WARNING("Audio packet dropped due to missing callback!"); 868 LOGGER_WARNING("Audio packet dropped due to missing callback!");
805 } 869 }
870
806 } else { 871 } else {
807 uint8_t *packet = _msg->data; 872 uint8_t *packet = _msg->data;
808 int recved_size = _msg->length; 873 int recved_size = _msg->length;
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 7e0a7fc2..593f3a2a 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -119,6 +119,8 @@ typedef enum {
119 * @brief Encoding settings. 119 * @brief Encoding settings.
120 */ 120 */
121typedef struct _ToxAvCodecSettings { 121typedef struct _ToxAvCodecSettings {
122 ToxAvCallType call_type;
123
122 uint32_t video_bitrate; /* In kbits/s */ 124 uint32_t video_bitrate; /* In kbits/s */
123 uint16_t max_video_width; /* In px */ 125 uint16_t max_video_width; /* In px */
124 uint16_t max_video_height; /* In px */ 126 uint16_t max_video_height; /* In px */
@@ -127,12 +129,11 @@ typedef struct _ToxAvCodecSettings {
127 uint16_t audio_frame_duration; /* In ms */ 129 uint16_t audio_frame_duration; /* In ms */
128 uint32_t audio_sample_rate; /* In Hz */ 130 uint32_t audio_sample_rate; /* In Hz */
129 uint32_t audio_channels; 131 uint32_t audio_channels;
130 uint32_t audio_VAD_tolerance; /* In ms */ 132} ToxAvCSettings;
131
132 uint32_t jbuf_capacity; /* Size of jitter buffer */
133} ToxAvCodecSettings;
134 133
135extern const ToxAvCodecSettings av_DefaultSettings; 134extern const ToxAvCSettings av_DefaultSettings;
135extern const uint32_t av_jbufdc; /* Jitter buffer default capacity */
136extern const uint32_t av_VADd; /* VAD default treshold */
136 137
137/** 138/**
138 * @brief Start new A/V session. There can only be one session at the time. If you register more 139 * @brief Start new A/V session. There can only be one session at the time. If you register more
@@ -194,7 +195,7 @@ void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, in
194 * @retval 0 Success. 195 * @retval 0 Success.
195 * @retval ToxAvError On error. 196 * @retval ToxAvError On error.
196 */ 197 */
197int toxav_call(ToxAv *av, int32_t *call_index, int user, ToxAvCallType call_type, int ringing_seconds); 198int toxav_call(ToxAv *av, int32_t *call_index, int user, const ToxAvCSettings *csettings, int ringing_seconds);
198 199
199/** 200/**
200 * @brief Hangup active call. 201 * @brief Hangup active call.
@@ -215,7 +216,7 @@ int toxav_hangup(ToxAv *av, int32_t call_index);
215 * @retval 0 Success. 216 * @retval 0 Success.
216 * @retval ToxAvError On error. 217 * @retval ToxAvError On error.
217 */ 218 */
218int toxav_answer(ToxAv *av, int32_t call_index, ToxAvCallType call_type ); 219int toxav_answer(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings );
219 220
220/** 221/**
221 * @brief Reject incomming call. 222 * @brief Reject incomming call.
@@ -241,14 +242,14 @@ int toxav_reject(ToxAv *av, int32_t call_index, const char *reason);
241int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason); 242int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason);
242 243
243/** 244/**
244 * @brief Notify peer that we are changing call type 245 * @brief Notify peer that we are changing call settings
245 * 246 *
246 * @param av Handler. 247 * @param av Handler.
247 * @return int 248 * @return int
248 * @retval 0 Success. 249 * @retval 0 Success.
249 * @retval ToxAvError On error. 250 * @retval ToxAvError On error.
250 */ 251 */
251int toxav_change_type(ToxAv *av, int32_t call_index, ToxAvCallType call_type); 252int toxav_change_settings(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings);
252 253
253/** 254/**
254 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. 255 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
@@ -269,7 +270,8 @@ int toxav_stop_call(ToxAv *av, int32_t call_index);
269 * @retval 0 Success. 270 * @retval 0 Success.
270 * @retval ToxAvError On error. 271 * @retval ToxAvError On error.
271 */ 272 */
272int toxav_prepare_transmission(ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video); 273int toxav_prepare_transmission(ToxAv *av, int32_t call_index, uint32_t jbuf_size, uint32_t VAD_treshold,
274 int support_video);
273 275
274/** 276/**
275 * @brief Call this at the end of the transmission. 277 * @brief Call this at the end of the transmission.
@@ -343,7 +345,7 @@ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, in
343 * @retval ToxAvCallType On success. 345 * @retval ToxAvCallType On success.
344 * @retval ToxAvError On error. 346 * @retval ToxAvError On error.
345 */ 347 */
346int toxav_get_peer_transmission_type ( ToxAv *av, int32_t call_index, int peer ); 348int toxav_get_peer_csettings ( ToxAv *av, int32_t call_index, int peer, ToxAvCSettings *dest );
347 349
348/** 350/**
349 * @brief Get id of peer participating in conversation 351 * @brief Get id of peer participating in conversation
@@ -374,26 +376,6 @@ ToxAvCallState toxav_get_call_state ( ToxAv *av, int32_t call_index );
374 */ 376 */
375int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCapabilities capability ); 377int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCapabilities capability );
376 378
377/**
378 * @brief Set queue limit
379 *
380 * @param av Handler
381 * @param call_index index
382 * @param limit the limit
383 * @return void
384 */
385int toxav_set_audio_queue_limit ( ToxAv *av, int32_t call_index, uint64_t limit );
386
387/**
388 * @brief Set queue limit
389 *
390 * @param av Handler
391 * @param call_index index
392 * @param limit the limit
393 * @return void
394 */
395int toxav_set_video_queue_limit ( ToxAv *av, int32_t call_index, uint64_t limit );
396
397 379
398Tox *toxav_get_tox(ToxAv *av); 380Tox *toxav_get_tox(ToxAv *av);
399 381