summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2014-03-07 03:13:04 +0100
committermannol <eniz_vukovic@hotmail.com>2014-03-07 03:13:04 +0100
commit6a78e2e71c1471b89646a71a1adeb0529cfb73d4 (patch)
tree1d4a05504f63efe64339155ae30e31799bafda57
parent71284fabf881604ace3167830a0b1667832e971f (diff)
Fixed several bugs and added some features
-rw-r--r--configure.ac3
-rw-r--r--libtoxav.pc11
-rw-r--r--toxav/media.c113
-rw-r--r--toxav/media.h11
-rwxr-xr-x[-rw-r--r--]toxav/msi.c102
-rwxr-xr-x[-rw-r--r--]toxav/msi.h2
-rwxr-xr-x[-rw-r--r--]toxav/phone.c172
-rwxr-xr-x[-rw-r--r--]toxav/rtp.c62
-rwxr-xr-x[-rw-r--r--]toxav/rtp.h14
-rwxr-xr-x[-rw-r--r--]toxav/toxav.c143
-rwxr-xr-x[-rw-r--r--]toxav/toxav.h86
11 files changed, 494 insertions, 225 deletions
diff --git a/configure.ac b/configure.ac
index 6d856828..e916b4a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -487,7 +487,8 @@ fi
487if test "x$BUILD_AV" = "xyes"; then 487if test "x$BUILD_AV" = "xyes"; then
488 # toxcore lib needs an global? 488 # toxcore lib needs an global?
489 # So far this works okay 489 # So far this works okay
490 AV_LIBS="$OPUS_LIBS $VPX_LIBS" 490 ## What about pthread?
491 AV_LIBS="$OPUS_LIBS $VPX_LIBS -pthread"
491 AC_SUBST(AV_LIBS) 492 AC_SUBST(AV_LIBS)
492 493
493 AV_CFLAGS="$OPUS_CFLAGS $VPX_CFLAGS" 494 AV_CFLAGS="$OPUS_CFLAGS $VPX_CFLAGS"
diff --git a/libtoxav.pc b/libtoxav.pc
new file mode 100644
index 00000000..48bc1cc4
--- /dev/null
+++ b/libtoxav.pc
@@ -0,0 +1,11 @@
1prefix=/usr/local
2exec_prefix=${prefix}
3libdir=${exec_prefix}/lib
4includedir=${prefix}/include
5
6Name: libtoxav
7Description: Tox A/V library
8Requires:
9Version: 0.0.0
10Libs: -L${libdir} -ltoxav -lopus -lvpx -lm -pthread
11Cflags: -I${includedir}
diff --git a/toxav/media.c b/toxav/media.c
index 2594f99a..59ca49b7 100644
--- a/toxav/media.c
+++ b/toxav/media.c
@@ -46,18 +46,28 @@ struct jitter_buffer {
46 uint8_t id_set; 46 uint8_t id_set;
47}; 47};
48 48
49int empty_queue(struct jitter_buffer *q)
50{
51 while (q->size > 0) {
52 rtp_free_msg(NULL, q->queue[q->front]);
53 q->front++;
54
55 if (q->front == q->capacity)
56 q->front = 0;
57
58 q->size--;
59 }
60
61 q->id_set = 0;
62 q->queue_ready = 0;
63 return 0;
64}
49 65
50struct jitter_buffer *create_queue(int capacity) 66struct jitter_buffer *create_queue(int capacity)
51{ 67{
52 struct jitter_buffer *q; 68 struct jitter_buffer *q;
53 q = (struct jitter_buffer *)calloc(sizeof(struct jitter_buffer), 1); 69 q = calloc(sizeof(struct jitter_buffer), 1);
54 q->queue = (RTPMessage **)calloc(sizeof(RTPMessage *), capacity); 70 q->queue = calloc(sizeof(RTPMessage *), capacity);
55 int i = 0;
56
57 for (i = 0; i < capacity; ++i) {
58 q->queue[i] = NULL;
59 }
60
61 q->size = 0; 71 q->size = 0;
62 q->capacity = capacity; 72 q->capacity = capacity;
63 q->front = 0; 73 q->front = 0;
@@ -81,7 +91,7 @@ uint8_t sequence_number_older(uint16_t sn_a, uint16_t sn_b, uint32_t ts_a, uint3
81/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */ 91/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
82RTPMessage *dequeue(struct jitter_buffer *q, int *success) 92RTPMessage *dequeue(struct jitter_buffer *q, int *success)
83{ 93{
84 if (q->size == 0 || q->queue_ready == 0) { 94 if (q->size == 0 || q->queue_ready == 0) { /* Empty queue */
85 q->queue_ready = 0; 95 q->queue_ready = 0;
86 *success = 0; 96 *success = 0;
87 return NULL; 97 return NULL;
@@ -103,13 +113,13 @@ RTPMessage *dequeue(struct jitter_buffer *q, int *success)
103 q->current_ts = next_ts; 113 q->current_ts = next_ts;
104 } else { 114 } else {
105 if (sequence_number_older(next_id, q->current_id, next_ts, q->current_ts)) { 115 if (sequence_number_older(next_id, q->current_id, next_ts, q->current_ts)) {
106 printf("nextid: %d current: %d\n", next_id, q->current_id); 116 /*printf("nextid: %d current: %d\n", next_id, q->current_id);*/
107 q->current_id = (q->current_id + 1) % MAX_SEQU_NUM; 117 q->current_id = (q->current_id + 1) % MAX_SEQU_NUM;
108 *success = 2; /* tell the decoder the packet is lost */ 118 *success = 2; /* tell the decoder the packet is lost */
109 return NULL; 119 return NULL;
110 } else { 120 } else {
111 /* packet too old */ 121 /* packet too old */
112 printf("packet too old\n"); 122 /*printf("packet too old\n");*/
113 *success = 0; 123 *success = 0;
114 return NULL; 124 return NULL;
115 } 125 }
@@ -128,27 +138,12 @@ RTPMessage *dequeue(struct jitter_buffer *q, int *success)
128 return q->queue[front]; 138 return q->queue[front];
129} 139}
130 140
131int empty_queue(struct jitter_buffer *q)
132{
133 while (q->size > 0) {
134 q->size--;
135 rtp_free_msg(NULL, q->queue[q->front]);
136 q->front++;
137
138 if (q->front == q->capacity)
139 q->front = 0;
140 }
141
142 q->id_set = 0;
143 q->queue_ready = 0;
144 return 0;
145}
146 141
147int queue(struct jitter_buffer *q, RTPMessage *pk) 142int queue(struct jitter_buffer *q, RTPMessage *pk)
148{ 143{
149 if (q->size == q->capacity) { 144 if (q->size == q->capacity) { /* Full, empty queue */
150 printf("buffer full, emptying buffer...\n");
151 empty_queue(q); 145 empty_queue(q);
146 /*rtp_free_msg(NULL, pk);*/
152 return 0; 147 return 0;
153 } 148 }
154 149
@@ -180,7 +175,7 @@ int queue(struct jitter_buffer *q, RTPMessage *pk)
180 temp = q->queue[a]; 175 temp = q->queue[a];
181 q->queue[a] = q->queue[b]; 176 q->queue[a] = q->queue[b];
182 q->queue[b] = temp; 177 q->queue[b] = temp;
183 printf("had to swap\n"); 178 /*printf("had to swap\n");*/
184 } else { 179 } else {
185 break; 180 break;
186 } 181 }
@@ -229,7 +224,7 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
229 int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 224 int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
230 225
231 if (res) { 226 if (res) {
232 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); 227 fprintf(stderr, "Failed to get config: %s\n", vpx_codec_err_to_string(res));
233 return -1; 228 return -1;
234 } 229 }
235 230
@@ -266,49 +261,43 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
266 uint16_t video_height, 261 uint16_t video_height,
267 uint32_t video_bitrate ) 262 uint32_t video_bitrate )
268{ 263{
269 CodecState *_retu = calloc(sizeof(CodecState), 1); 264 CodecState *retu = calloc(sizeof(CodecState), 1);
270 assert(_retu); 265 assert(retu);
271 266
272 _retu->audio_bitrate = audio_bitrate; 267 retu->audio_bitrate = audio_bitrate;
273 _retu->audio_sample_rate = audio_sample_rate; 268 retu->audio_sample_rate = audio_sample_rate;
274 269
275 /* Encoders */ 270 /* Encoders */
276 if (!video_width || !video_height) { 271 if (!video_width || !video_height) { /* Disable video */
277 video_width = 320; 272 /*video_width = 320;
278 video_height = 240; 273 video_height = 240; */
274 }
275 else {
276 retu->supported_actions |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0;
277 retu->supported_actions |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
279 } 278 }
280 279
281 if ( 0 == init_video_encoder(_retu, video_width, video_height, video_bitrate) ) 280 retu->supported_actions |= ( 0 == init_audio_encoder(retu, audio_channels) ) ? a_encoding : 0;
282 printf("Video encoder initialized!\n"); 281 retu->supported_actions |= ( 0 == init_audio_decoder(retu, audio_channels) ) ? a_decoding : 0;
283
284 if ( 0 == init_audio_encoder(_retu, audio_channels) )
285 printf("Audio encoder initialized!\n");
286
287
288 /* Decoders */
289 if ( 0 == init_video_decoder(_retu) )
290 printf("Video decoder initialized!\n");
291
292 if ( 0 == init_audio_decoder(_retu, audio_channels) )
293 printf("Audio decoder initialized!\n");
294
295 282
296 return _retu; 283 return retu;
297} 284}
298 285
299void codec_terminate_session ( CodecState *cs ) 286void codec_terminate_session ( CodecState *cs )
300{ 287{
301 if ( cs->audio_encoder ) { 288 if ( cs->audio_encoder )
302 opus_encoder_destroy(cs->audio_encoder); 289 opus_encoder_destroy(cs->audio_encoder);
303 printf("Terminated encoder!\n"); 290
304 } 291 if ( cs->audio_decoder )
305
306 if ( cs->audio_decoder ) {
307 opus_decoder_destroy(cs->audio_decoder); 292 opus_decoder_destroy(cs->audio_decoder);
308 printf("Terminated decoder!\n"); 293
309 }
310 294
311 /* TODO: Terminate video */ 295 /* TODO: Terminate video
312 vpx_codec_destroy(&cs->v_decoder); 296 * Do what???
313 vpx_codec_destroy(&cs->v_encoder); 297 */
298 if ( cs->supported_actions & v_decoding )
299 vpx_codec_destroy(&cs->v_decoder);
300
301 if ( cs->supported_actions & v_encoding )
302 vpx_codec_destroy(&cs->v_encoder);
314} 303}
diff --git a/toxav/media.h b/toxav/media.h
index aed57ea2..323d22fd 100644
--- a/toxav/media.h
+++ b/toxav/media.h
@@ -38,6 +38,14 @@
38/* Audio encoding/decoding */ 38/* Audio encoding/decoding */
39#include <opus/opus.h> 39#include <opus/opus.h>
40 40
41enum _actions
42{
43 no_actions,
44 a_encoding = 1 << 0,
45 a_decoding = 1 << 1,
46 v_encoding = 1 << 2,
47 v_decoding = 1 << 3
48};
41 49
42typedef struct _CodecState { 50typedef struct _CodecState {
43 51
@@ -56,12 +64,13 @@ typedef struct _CodecState {
56 /* audio decoding */ 64 /* audio decoding */
57 OpusDecoder *audio_decoder; 65 OpusDecoder *audio_decoder;
58 66
67 uint64_t supported_actions; /* Encoding decoding etc */
68
59} CodecState; 69} CodecState;
60 70
61typedef struct _RTPMessage RTPMessage; 71typedef struct _RTPMessage RTPMessage;
62 72
63struct jitter_buffer *create_queue(int capacity); 73struct jitter_buffer *create_queue(int capacity);
64int empty_queue(struct jitter_buffer *q);
65 74
66int queue(struct jitter_buffer *q, RTPMessage *pk); 75int queue(struct jitter_buffer *q, RTPMessage *pk);
67RTPMessage *dequeue(struct jitter_buffer *q, int *success); 76RTPMessage *dequeue(struct jitter_buffer *q, int *success);
diff --git a/toxav/msi.c b/toxav/msi.c
index e5e1e1c5..a38ab730 100644..100755
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -616,10 +616,15 @@ int send_message ( MSISession *session, MSIMessage *msg, uint32_t to )
616void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id ) 616void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id )
617{ 617{
618 if ( msg->calltype.header_value ) { 618 if ( msg->calltype.header_value ) {
619 if ( strcmp ( ( const char * ) msg->calltype.header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) { 619 uint8_t hdrval [MSI_MAXMSG_SIZE]; /* Make sure no overflow */
620
621 memcpy(hdrval, msg->calltype.header_value, msg->calltype.size);
622 hdrval[msg->calltype.size] = '\0';
623
624 if ( strcmp ( ( const char * ) hdrval, CT_AUDIO_HEADER_VALUE ) == 0 ) {
620 session->call->type_peer[peer_id] = type_audio; 625 session->call->type_peer[peer_id] = type_audio;
621 626
622 } else if ( strcmp ( ( const char * ) msg->calltype.header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) { 627 } else if ( strcmp ( ( const char * ) hdrval, CT_VIDEO_HEADER_VALUE ) == 0 ) {
623 session->call->type_peer[peer_id] = type_video; 628 session->call->type_peer[peer_id] = type_video;
624 } else {} /* Error */ 629 } else {} /* Error */
625 } else {} /* Error */ 630 } else {} /* Error */
@@ -670,7 +675,7 @@ int handle_error ( MSISession *session, MSICallError errid, uint32_t to )
670 session->last_error_id = errid; 675 session->last_error_id = errid;
671 session->last_error_str = stringify_error ( errid ); 676 session->last_error_str = stringify_error ( errid );
672 677
673 event.rise ( callbacks[MSI_OnError], session->agent_handler ); 678 if ( callbacks[MSI_OnError] ) event.rise ( callbacks[MSI_OnError], session->agent_handler );
674 679
675 return 0; 680 return 0;
676} 681}
@@ -723,12 +728,12 @@ void *handle_timeout ( void *arg )
723 uint16_t _it = 0; 728 uint16_t _it = 0;
724 729
725 for ( ; _it < _peer_count; _it++ ) 730 for ( ; _it < _peer_count; _it++ )
726 msi_cancel ( arg, _peers[_it], (const uint8_t *)"Timeout" ); 731 msi_cancel ( arg, _peers[_it], "Timeout" );
727 732
728 } 733 }
729 734
730 ( *callbacks[MSI_OnRequestTimeout] ) ( _session->agent_handler ); 735 if ( callbacks[MSI_OnRequestTimeout] ) callbacks[MSI_OnRequestTimeout] ( _session->agent_handler );
731 ( *callbacks[MSI_OnEnding ] ) ( _session->agent_handler ); 736 if ( callbacks[MSI_OnEnding] ) callbacks[MSI_OnEnding ] ( _session->agent_handler );
732 737
733 return NULL; 738 return NULL;
734} 739}
@@ -864,7 +869,7 @@ int handle_recv_invite ( MSISession *session, MSIMessage *msg )
864 send_message ( session, _msg_ringing, msg->friend_id ); 869 send_message ( session, _msg_ringing, msg->friend_id );
865 free_message ( _msg_ringing ); 870 free_message ( _msg_ringing );
866 871
867 event.rise ( callbacks[MSI_OnInvite], session->agent_handler ); 872 if ( callbacks[MSI_OnInvite] ) event.rise ( callbacks[MSI_OnInvite], session->agent_handler );
868 873
869 return 1; 874 return 1;
870} 875}
@@ -888,7 +893,7 @@ int handle_recv_start ( MSISession *session, MSIMessage *msg )
888 893
889 flush_peer_type ( session, msg, 0 ); 894 flush_peer_type ( session, msg, 0 );
890 895
891 event.rise ( callbacks[MSI_OnStart], session->agent_handler ); 896 if ( callbacks[MSI_OnStart] ) event.rise ( callbacks[MSI_OnStart], session->agent_handler );
892 897
893 return 1; 898 return 1;
894} 899}
@@ -905,7 +910,7 @@ int handle_recv_reject ( MSISession *session, MSIMessage *msg )
905 free_message ( _msg_end ); 910 free_message ( _msg_end );
906 911
907 event.timer_release ( session->call->request_timer_id ); 912 event.timer_release ( session->call->request_timer_id );
908 event.rise ( callbacks[MSI_OnReject], session->agent_handler ); 913 if ( callbacks[MSI_OnReject] ) event.rise ( callbacks[MSI_OnReject], session->agent_handler );
909 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 914 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
910 915
911 return 1; 916 return 1;
@@ -920,7 +925,7 @@ int handle_recv_cancel ( MSISession *session, MSIMessage *msg )
920 925
921 terminate_call ( session ); 926 terminate_call ( session );
922 927
923 event.rise ( callbacks[MSI_OnCancel], session->agent_handler ); 928 if ( callbacks[MSI_OnCancel] ) event.rise ( callbacks[MSI_OnCancel], session->agent_handler );
924 929
925 return 1; 930 return 1;
926} 931}
@@ -938,7 +943,7 @@ int handle_recv_end ( MSISession *session, MSIMessage *msg )
938 943
939 terminate_call ( session ); 944 terminate_call ( session );
940 945
941 event.rise ( callbacks[MSI_OnEnd], session->agent_handler ); 946 if ( callbacks[MSI_OnEnd] ) event.rise ( callbacks[MSI_OnEnd], session->agent_handler );
942 947
943 return 1; 948 return 1;
944} 949}
@@ -952,7 +957,7 @@ int handle_recv_ringing ( MSISession *session, MSIMessage *msg )
952 return 0; 957 return 0;
953 958
954 session->call->ringing_timer_id = event.timer_alloc ( handle_timeout, session, session->call->ringing_tout_ms ); 959 session->call->ringing_timer_id = event.timer_alloc ( handle_timeout, session, session->call->ringing_tout_ms );
955 event.rise ( callbacks[MSI_OnRinging], session->agent_handler ); 960 if ( callbacks[MSI_OnRinging] ) event.rise ( callbacks[MSI_OnRinging], session->agent_handler );
956 961
957 return 1; 962 return 1;
958} 963}
@@ -991,7 +996,7 @@ int handle_recv_starting ( MSISession *session, MSIMessage *msg )
991 996
992 flush_peer_type ( session, msg, 0 ); 997 flush_peer_type ( session, msg, 0 );
993 998
994 event.rise ( callbacks[MSI_OnStarting], session->agent_handler ); 999 if ( callbacks[MSI_OnStarting] ) event.rise ( callbacks[MSI_OnStarting], session->agent_handler );
995 event.timer_release ( session->call->ringing_timer_id ); 1000 event.timer_release ( session->call->ringing_timer_id );
996 1001
997 return 1; 1002 return 1;
@@ -999,15 +1004,23 @@ int handle_recv_starting ( MSISession *session, MSIMessage *msg )
999int handle_recv_ending ( MSISession *session, MSIMessage *msg ) 1004int handle_recv_ending ( MSISession *session, MSIMessage *msg )
1000{ 1005{
1001 assert ( session ); 1006 assert ( session );
1002 1007
1003 if ( has_call_error ( session, msg ) == 0 ) 1008 if ( has_call_error ( session, msg ) == 0 )
1004 return 0; 1009 return 0;
1005 1010
1006 1011 /* Do the callback before ending
1012 if ( callbacks[MSI_OnEnding] ) event.rise ( callbacks[MSI_OnEnding], session->agent_handler );
1013 */
1014
1015 /* Stop timer */
1016 event.timer_release ( session->call->request_timer_id );
1017
1018 /* Call callback */
1019 if ( callbacks[MSI_OnEnding] ) callbacks[MSI_OnEnding](session->agent_handler);
1020
1021 /* Terminate call */
1007 terminate_call ( session ); 1022 terminate_call ( session );
1008 1023
1009 event.rise ( callbacks[MSI_OnEnding], session->agent_handler );
1010
1011 return 1; 1024 return 1;
1012} 1025}
1013int handle_recv_error ( MSISession *session, MSIMessage *msg ) 1026int handle_recv_error ( MSISession *session, MSIMessage *msg )
@@ -1023,7 +1036,7 @@ int handle_recv_error ( MSISession *session, MSIMessage *msg )
1023 1036
1024 terminate_call ( session ); 1037 terminate_call ( session );
1025 1038
1026 event.rise ( callbacks[MSI_OnEnding], session->agent_handler ); 1039 if ( callbacks[MSI_OnEnding] ) event.rise ( callbacks[MSI_OnEnding], session->agent_handler );
1027 1040
1028 return 1; 1041 return 1;
1029} 1042}
@@ -1081,8 +1094,13 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1081 /* Now handle message */ 1094 /* Now handle message */
1082 1095
1083 if ( _msg->request.header_value ) { /* Handle request */ 1096 if ( _msg->request.header_value ) { /* Handle request */
1084 1097
1085 const uint8_t *_request_value = _msg->request.header_value; 1098 if ( _msg->response.size > 32 ) goto free_end;
1099
1100 uint8_t _request_value[32];
1101
1102 memcpy(_request_value, _msg->request.header_value, _msg->request.size);
1103 _request_value[_msg->request.size] = '\0';
1086 1104
1087 if ( same ( _request_value, stringify_request ( invite ) ) ) { 1105 if ( same ( _request_value, stringify_request ( invite ) ) ) {
1088 handle_recv_invite ( _session, _msg ); 1106 handle_recv_invite ( _session, _msg );
@@ -1100,15 +1118,17 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1100 handle_recv_end ( _session, _msg ); 1118 handle_recv_end ( _session, _msg );
1101 } 1119 }
1102 1120
1103 else { 1121 else goto free_end;
1104 free_message ( _msg );
1105 return;
1106 }
1107 1122
1108 } else if ( _msg->response.header_value ) { /* Handle response */ 1123 } else if ( _msg->response.header_value ) { /* Handle response */
1109 1124
1110 const uint8_t *_response_value = _msg->response.header_value; 1125 if ( _msg->response.size > 32 ) goto free_end;
1111 1126
1127 uint8_t _response_value[32];
1128
1129 memcpy(_response_value, _msg->response.header_value, _msg->response.size);
1130 _response_value[_msg->response.size] = '\0';
1131
1112 if ( same ( _response_value, stringify_response ( ringing ) ) ) { 1132 if ( same ( _response_value, stringify_response ( ringing ) ) ) {
1113 handle_recv_ringing ( _session, _msg ); 1133 handle_recv_ringing ( _session, _msg );
1114 1134
@@ -1120,10 +1140,8 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1120 1140
1121 } else if ( same ( _response_value, stringify_response ( error ) ) ) { 1141 } else if ( same ( _response_value, stringify_response ( error ) ) ) {
1122 handle_recv_error ( _session, _msg ); 1142 handle_recv_error ( _session, _msg );
1123 } else { 1143
1124 free_message ( _msg ); 1144 } else goto free_end;
1125 return;
1126 }
1127 1145
1128 /* Got response so cancel timer */ 1146 /* Got response so cancel timer */
1129 if ( _session->call ) 1147 if ( _session->call )
@@ -1131,7 +1149,7 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1131 1149
1132 } 1150 }
1133 1151
1134 free_message ( _msg ); 1152 free_end:free_message ( _msg );
1135} 1153}
1136 1154
1137 1155
@@ -1286,19 +1304,19 @@ int msi_hangup ( MSISession *session )
1286 if ( !session->call || session->call->state != call_active ) 1304 if ( !session->call || session->call->state != call_active )
1287 return -1; 1305 return -1;
1288 1306
1289 MSIMessage *_msg_ending = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) ); 1307 MSIMessage *_msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
1290 1308
1291 /* hangup for each peer */ 1309 /* hangup for each peer */
1292 int _it = 0; 1310 int _it = 0;
1311
1312 for ( ; _it < session->call->peer_count; _it ++ )
1313 send_message ( session, _msg_end, session->call->peers[_it] );
1314
1293 1315
1294 for ( ; _it < session->call->peer_count; _it ++ ) 1316 free_message ( _msg_end );
1295 send_message ( session, _msg_ending, session->call->peers[_it] );
1296
1297
1298 free_message ( _msg_ending );
1299 1317
1300 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1318 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
1301 1319
1302 return 0; 1320 return 0;
1303} 1321}
1304 1322
@@ -1352,13 +1370,13 @@ int msi_answer ( MSISession *session, MSICallType call_type )
1352 * @param reason Set optional reason header. Pass NULL if none. 1370 * @param reason Set optional reason header. Pass NULL if none.
1353 * @return int 1371 * @return int
1354 */ 1372 */
1355int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason ) 1373int msi_cancel ( MSISession *session, uint32_t peer, const char *reason )
1356{ 1374{
1357 assert ( session ); 1375 assert ( session );
1358 1376
1359 MSIMessage *_msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) ); 1377 MSIMessage *_msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) );
1360 1378
1361 if ( reason ) msi_msg_set_reason(_msg_cancel, reason, strlen((const char *)reason)); 1379 if ( reason ) msi_msg_set_reason(_msg_cancel, (const uint8_t*)reason, strlen(reason));
1362 1380
1363 send_message ( session, _msg_cancel, peer ); 1381 send_message ( session, _msg_cancel, peer );
1364 free_message ( _msg_cancel ); 1382 free_message ( _msg_cancel );
diff --git a/toxav/msi.h b/toxav/msi.h
index a70685f8..83de0117 100644..100755
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -206,7 +206,7 @@ int msi_answer ( MSISession *session, MSICallType call_type );
206 * @param reason Set optional reason header. Pass NULL if none. 206 * @param reason Set optional reason header. Pass NULL if none.
207 * @return int 207 * @return int
208 */ 208 */
209int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason ); 209int msi_cancel ( MSISession* session, uint32_t peer, const char* reason );
210 210
211 211
212/** 212/**
diff --git a/toxav/phone.c b/toxav/phone.c
index 98e97873..95b49231 100644..100755
--- a/toxav/phone.c
+++ b/toxav/phone.c
@@ -428,17 +428,16 @@ void *encode_audio_thread(void *arg)
428 int frame_size = AUDIO_FRAME_SIZE; 428 int frame_size = AUDIO_FRAME_SIZE;
429 ALint sample = 0; 429 ALint sample = 0;
430 alcCaptureStart((ALCdevice *)_phone->audio_capture_device); 430 alcCaptureStart((ALCdevice *)_phone->audio_capture_device);
431
432 while (_phone->running_encaud) { 431 while (_phone->running_encaud) {
432
433 alcGetIntegerv((ALCdevice *)_phone->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample); 433 alcGetIntegerv((ALCdevice *)_phone->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample);
434 434
435 if (sample >= frame_size) { 435 if (sample >= frame_size) {
436 alcCaptureSamples((ALCdevice *)_phone->audio_capture_device, frame, frame_size); 436 alcCaptureSamples((ALCdevice *)_phone->audio_capture_device, frame, frame_size);
437 437
438 ret = toxav_send_audio(_phone->av, frame, frame_size); 438 ret = toxav_send_audio(_phone->av, frame, frame_size);
439 439
440 if (ret < 0) 440 if (ret < 0) printf("Could not encode or send audio packet\n");
441 printf("Could not encode or send audio packet\n");
442 441
443 } else { 442 } else {
444 usleep(1000); 443 usleep(1000);
@@ -734,6 +733,114 @@ ending:
734 733
735 734
736 735
736void *one_threaded_audio(void *arg)
737{
738 INFO("Started audio thread!");
739 av_session_t *_phone = arg;
740 _phone->running_decaud = 1;
741
742 //int recved_size;
743 //uint8_t dest [RTP_PAYLOAD_SIZE];
744
745 int frame_size = AUDIO_FRAME_SIZE;
746
747 int16_t frame[4096];
748 ALint sample = 0;
749 alcCaptureStart((ALCdevice *)_phone->audio_capture_device);
750
751 ALCdevice *dev;
752 ALCcontext *ctx;
753 ALuint source, *buffers;
754 dev = alcOpenDevice(NULL);
755 ctx = alcCreateContext(dev, NULL);
756 alcMakeContextCurrent(ctx);
757 int openal_buffers = 5;
758
759 buffers = calloc(sizeof(ALuint) * openal_buffers, 1);
760 alGenBuffers(openal_buffers, buffers);
761 alGenSources((ALuint)1, &source);
762 alSourcei(source, AL_LOOPING, AL_FALSE);
763
764 ALuint buffer;
765 ALint ready;
766
767 uint16_t zeros[frame_size];
768 memset(zeros, 0, frame_size);
769 int16_t PCM[frame_size];
770
771 int i;
772
773 for (i = 0; i < openal_buffers; ++i) {
774 alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000);
775 }
776
777 alSourceQueueBuffers(source, openal_buffers, buffers);
778 alSourcePlay(source);
779
780 if (alGetError() != AL_NO_ERROR) {
781 fprintf(stderr, "Error starting audio\n");
782 goto ending;
783 }
784
785 int dec_frame_len;
786
787 while (_phone->running_decaud) {
788
789 // combo
790 alcGetIntegerv((ALCdevice *)_phone->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample);
791
792 // record and send
793 if (sample >= frame_size) {
794 alcCaptureSamples((ALCdevice *)_phone->audio_capture_device, frame, frame_size);
795
796 if (toxav_send_audio(_phone->av, frame, frame_size) < 0)
797 printf("Could not encode or send audio packet\n");
798
799 } else {
800 usleep(5000);
801 }
802
803 // play received
804
805 alGetSourcei(source, AL_BUFFERS_PROCESSED, &ready);
806
807 if (ready <= 0)
808 continue;
809
810 dec_frame_len = toxav_recv_audio(_phone->av, frame_size, PCM);
811
812 /* Play the packet */
813 if (dec_frame_len > 0) {
814 alSourceUnqueueBuffers(source, 1, &buffer);
815 alBufferData(buffer, AL_FORMAT_MONO16, PCM, dec_frame_len * 2 * 1, 48000);
816 int error = alGetError();
817
818 if (error != AL_NO_ERROR) {
819 fprintf(stderr, "Error setting buffer %d\n", error);
820 break;
821 }
822
823 alSourceQueueBuffers(source, 1, &buffer);
824
825 if (alGetError() != AL_NO_ERROR) {
826 fprintf(stderr, "Error: could not buffer audio\n");
827 break;
828 }
829
830 alGetSourcei(source, AL_SOURCE_STATE, &ready);
831
832 if (ready != AL_PLAYING) alSourcePlay(source);
833 }
834
835 usleep(1000);
836 }
837
838
839 ending:
840 _phone->running_decaud = -1;
841
842 pthread_exit ( NULL );
843}
737 844
738 845
739int phone_startmedia_loop ( ToxAv *arg ) 846int phone_startmedia_loop ( ToxAv *arg )
@@ -742,7 +849,7 @@ int phone_startmedia_loop ( ToxAv *arg )
742 return -1; 849 return -1;
743 } 850 }
744 851
745 toxav_prepare_transmission(arg); 852 toxav_prepare_transmission(arg, 1);
746 853
747 /* 854 /*
748 * Rise all threads 855 * Rise all threads
@@ -759,10 +866,10 @@ int phone_startmedia_loop ( ToxAv *arg )
759#endif 866#endif
760 867
761 /* Always send audio */ 868 /* Always send audio */
762 if ( 0 > event.rise(encode_audio_thread, toxav_get_agent_handler(arg)) ) { 869 /*if ( 0 > event.rise(encode_audio_thread, toxav_get_agent_handler(arg)) ) {
763 INFO("Error while starting encode_audio_thread()"); 870 INFO("Error while starting encode_audio_thread()");
764 return -1; 871 return -1;
765 } 872 } */
766 873
767 /* Only checks for last peer */ 874 /* Only checks for last peer */
768 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo && 875 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo &&
@@ -771,12 +878,19 @@ int phone_startmedia_loop ( ToxAv *arg )
771 return -1; 878 return -1;
772 } 879 }
773 880
774 if ( 0 > event.rise(decode_audio_thread, toxav_get_agent_handler(arg)) ) { 881 /*if ( 0 > event.rise(decode_audio_thread, toxav_get_agent_handler(arg)) ) {
775 INFO("Error while starting decode_audio_thread()"); 882 INFO("Error while starting decode_audio_thread()");
776 return -1; 883 return -1;
777 } 884 } */
778 885
779 886
887 /* One threaded audio */
888
889 if ( 0 > event.rise(one_threaded_audio, toxav_get_agent_handler(arg)) ) {
890 INFO ("Shit-head");
891 return -1;
892 }
893
780 return 0; 894 return 0;
781} 895}
782 896
@@ -888,15 +1002,17 @@ void *callback_call_ended ( void *_arg )
888 _phone->running_encvid = 0; 1002 _phone->running_encvid = 0;
889 _phone->running_decvid = 0; 1003 _phone->running_decvid = 0;
890 1004
891 /* Wait until all threads are done */ 1005 /* Wait until all threads are done
892 1006
893 while ( _phone->running_encaud != -1 || 1007 while ( _phone->running_encaud != -1 ||
894 _phone->running_decaud != -1 || 1008 _phone->running_decaud != -1 ||
895 _phone->running_encvid != -1 || 1009 _phone->running_encvid != -1 ||
896 _phone->running_decvid != -1 ) 1010 _phone->running_decvid != -1 )
897 1011
898 usleep(10000000); 1012 usleep(1000000);*/
899 1013
1014 while (_phone->running_decaud != -1) usleep(1000000);
1015
900 toxav_kill_transmission(_phone->av); 1016 toxav_kill_transmission(_phone->av);
901 INFO ( "Call ended!" ); 1017 INFO ( "Call ended!" );
902 pthread_exit(NULL); 1018 pthread_exit(NULL);
@@ -977,7 +1093,7 @@ av_session_t *av_init_session()
977 if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) { 1093 if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) {
978 fprintf(stderr, "Opening video_input_format failed!\n"); 1094 fprintf(stderr, "Opening video_input_format failed!\n");
979 //return -1; 1095 //return -1;
980 return NULL; 1096 goto failed_init_ffmpeg;
981 } 1097 }
982 1098
983 avformat_find_stream_info(_retu->video_format_ctx, NULL); 1099 avformat_find_stream_info(_retu->video_format_ctx, NULL);
@@ -996,23 +1112,25 @@ av_session_t *av_init_session()
996 if (_retu->webcam_decoder == NULL) { 1112 if (_retu->webcam_decoder == NULL) {
997 fprintf(stderr, "Unsupported codec!\n"); 1113 fprintf(stderr, "Unsupported codec!\n");
998 //return -1; 1114 //return -1;
999 return NULL; 1115 goto failed_init_ffmpeg;
1000 } 1116 }
1001 1117
1002 if (_retu->webcam_decoder_ctx == NULL) { 1118 if (_retu->webcam_decoder_ctx == NULL) {
1003 fprintf(stderr, "Init webcam_decoder_ctx failed!\n"); 1119 fprintf(stderr, "Init webcam_decoder_ctx failed!\n");
1004 //return -1; 1120 //return -1;
1005 return NULL; 1121 goto failed_init_ffmpeg;
1006 } 1122 }
1007 1123
1008 if (avcodec_open2(_retu->webcam_decoder_ctx, _retu->webcam_decoder, NULL) < 0) { 1124 if (avcodec_open2(_retu->webcam_decoder_ctx, _retu->webcam_decoder, NULL) < 0) {
1009 fprintf(stderr, "Opening webcam decoder failed!\n"); 1125 fprintf(stderr, "Opening webcam decoder failed!\n");
1010 //return -1; 1126 //return -1;
1011 return NULL; 1127 goto failed_init_ffmpeg;
1012 } 1128 }
1013 1129
1014 width = _retu->webcam_decoder_ctx->width; 1130 width = _retu->webcam_decoder_ctx->width;
1015 height = _retu->webcam_decoder_ctx->height; 1131 height = _retu->webcam_decoder_ctx->height;
1132
1133failed_init_ffmpeg: ;
1016#endif 1134#endif
1017 uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE]; 1135 uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE];
1018 tox_get_address(_retu->_messenger, _byte_address ); 1136 tox_get_address(_retu->_messenger, _byte_address );
@@ -1023,18 +1141,18 @@ av_session_t *av_init_session()
1023 1141
1024 /* ------------------ */ 1142 /* ------------------ */
1025 1143
1026 toxav_register_callstate_callback(callback_call_started, OnStart); 1144 toxav_register_callstate_callback(callback_call_started, av_OnStart);
1027 toxav_register_callstate_callback(callback_call_canceled, OnCancel); 1145 toxav_register_callstate_callback(callback_call_canceled, av_OnCancel);
1028 toxav_register_callstate_callback(callback_call_rejected, OnReject); 1146 toxav_register_callstate_callback(callback_call_rejected, av_OnReject);
1029 toxav_register_callstate_callback(callback_call_ended, OnEnd); 1147 toxav_register_callstate_callback(callback_call_ended, av_OnEnd);
1030 toxav_register_callstate_callback(callback_recv_invite, OnInvite); 1148 toxav_register_callstate_callback(callback_recv_invite, av_OnInvite);
1031 1149
1032 toxav_register_callstate_callback(callback_recv_ringing, OnRinging); 1150 toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging);
1033 toxav_register_callstate_callback(callback_recv_starting, OnStarting); 1151 toxav_register_callstate_callback(callback_recv_starting, av_OnStarting);
1034 toxav_register_callstate_callback(callback_recv_ending, OnEnding); 1152 toxav_register_callstate_callback(callback_recv_ending, av_OnEnding);
1035 1153
1036 toxav_register_callstate_callback(callback_recv_error, OnError); 1154 toxav_register_callstate_callback(callback_recv_error, av_OnError);
1037 toxav_register_callstate_callback(callback_requ_timeout, OnRequestTimeout); 1155 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout);
1038 1156
1039 /* ------------------ */ 1157 /* ------------------ */
1040 1158
@@ -1310,6 +1428,8 @@ int main ( int argc, char *argv [] )
1310 1428
1311 av_session_t *_phone = av_init_session(); 1429 av_session_t *_phone = av_init_session();
1312 1430
1431 assert ( _phone );
1432
1313 tox_callback_friend_request(_phone->_messenger, av_friend_requ, _phone); 1433 tox_callback_friend_request(_phone->_messenger, av_friend_requ, _phone);
1314 tox_callback_status_message(_phone->_messenger, av_friend_active, _phone); 1434 tox_callback_status_message(_phone->_messenger, av_friend_active, _phone);
1315 1435
@@ -1341,7 +1461,7 @@ int main ( int argc, char *argv [] )
1341 "================================================================================\n" 1461 "================================================================================\n"
1342 "%s\n" 1462 "%s\n"
1343 "================================================================================" 1463 "================================================================================"
1344 , _phone->_my_public_id ); 1464 , trim_spaces(_phone->_my_public_id) );
1345 1465
1346 1466
1347 do_phone (_phone); 1467 do_phone (_phone);
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 8eca46d4..9b8cd652 100644..100755
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -262,17 +262,8 @@ RTPHeader *extract_header ( const uint8_t *payload, int length )
262 return NULL; 262 return NULL;
263 } 263 }
264 264
265 if ( _cc > 0 ) { 265 memset(_retu->csrc, 0, 16);
266 _retu->csrc = calloc (_cc, sizeof (uint32_t)); 266
267 assert(_retu->csrc);
268
269 } else { /* But this should not happen ever */
270 /* Deallocate */
271 free(_retu);
272 return NULL;
273 }
274
275
276 _retu->marker_payloadt = *_it; 267 _retu->marker_payloadt = *_it;
277 ++_it; 268 ++_it;
278 _retu->length = _length; 269 _retu->length = _length;
@@ -362,13 +353,11 @@ uint8_t *add_header ( RTPHeader *header, uint8_t *payload )
362 _it += 4; 353 _it += 4;
363 U32_to_bytes( _it, header->ssrc); 354 U32_to_bytes( _it, header->ssrc);
364 355
365 if ( header->csrc ) { 356 uint8_t _x;
366 uint8_t _x;
367 357
368 for ( _x = 0; _x < _cc; _x++ ) { 358 for ( _x = 0; _x < _cc; _x++ ) {
369 _it += 4; 359 _it += 4;
370 U32_to_bytes( _it, header->csrc[_x]); 360 U32_to_bytes( _it, header->csrc[_x]);
371 }
372 } 361 }
373 362
374 return _it + 4; 363 return _it + 4;
@@ -424,19 +413,11 @@ RTPHeader *build_header ( RTPSession *session )
424 _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */ 413 _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */
425 _retu->ssrc = session->ssrc; 414 _retu->ssrc = session->ssrc;
426 415
427 if ( session->cc > 0 ) { 416 int i;
428 _retu->csrc = calloc(session->cc, sizeof (uint32_t));
429 assert(_retu->csrc);
430
431 int i;
432
433 for ( i = 0; i < session->cc; i++ ) {
434 _retu->csrc[i] = session->csrc[i];
435 }
436 } else {
437 _retu->csrc = NULL;
438 }
439 417
418 for ( i = 0; i < session->cc; i++ )
419 _retu->csrc[i] = session->csrc[i];
420
440 _retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 ); 421 _retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 );
441 422
442 return _retu; 423 return _retu;
@@ -480,9 +461,7 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
480 _retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 461 _retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
481 _from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 462 _from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
482 } else { /* Error */ 463 } else { /* Error */
483 free (_retu->ext_header); 464 rtp_free_msg(NULL, _retu);
484 free (_retu->header);
485 free (_retu);
486 return NULL; 465 return NULL;
487 } 466 }
488 } else { 467 } else {
@@ -545,7 +524,7 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
545 _decrypted_length = decrypt_data_symmetric( 524 _decrypted_length = decrypt_data_symmetric(
546 (uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain ); 525 (uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
547 526
548 if ( !_decrypted_length ) return -1; /* This packet is not encrypted properly */ 527 if ( _decrypted_length == -1 ) return -1; /* This packet is not encrypted properly */
549 528
550 /* Otherwise, if decryption is ok with new cycle, set new cycle 529 /* Otherwise, if decryption is ok with new cycle, set new cycle
551 */ 530 */
@@ -554,7 +533,7 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
554 _decrypted_length = decrypt_data_symmetric( 533 _decrypted_length = decrypt_data_symmetric(
555 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain ); 534 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
556 535
557 if ( !_decrypted_length ) return -1; /* This is just an error */ 536 if ( _decrypted_length == -1 ) return -1; /* This is just an error */
558 537
559 /* A new cycle setting. */ 538 /* A new cycle setting. */
560 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_secretbox_NONCEBYTES); 539 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_secretbox_NONCEBYTES);
@@ -801,16 +780,11 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
801void rtp_free_msg ( RTPSession *session, RTPMessage *msg ) 780void rtp_free_msg ( RTPSession *session, RTPMessage *msg )
802{ 781{
803 if ( !session ) { 782 if ( !session ) {
804 free ( msg->header->csrc );
805
806 if ( msg->ext_header ) { 783 if ( msg->ext_header ) {
807 free ( msg->ext_header->table ); 784 free ( msg->ext_header->table );
808 free ( msg->ext_header ); 785 free ( msg->ext_header );
809 } 786 }
810 } else { 787 } else {
811 if ( session->csrc != msg->header->csrc )
812 free ( msg->header->csrc );
813
814 if ( msg->ext_header && session->ext_header != msg->ext_header ) { 788 if ( msg->ext_header && session->ext_header != msg->ext_header ) {
815 free ( msg->ext_header->table ); 789 free ( msg->ext_header->table );
816 free ( msg->ext_header ); 790 free ( msg->ext_header );
@@ -917,15 +891,21 @@ int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
917{ 891{
918 if ( !session ) 892 if ( !session )
919 return -1; 893 return -1;
920 894
921 custom_user_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); 895 custom_user_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
922 896
897 rtp_release_session_recv(session);
898
899 pthread_mutex_lock(&session->mutex);
900
923 free ( session->ext_header ); 901 free ( session->ext_header );
924 free ( session->csrc ); 902 free ( session->csrc );
925 free ( session->decrypt_nonce ); 903 free ( session->decrypt_nonce );
926 free ( session->encrypt_nonce ); 904 free ( session->encrypt_nonce );
927 free ( session->nonce_cycle ); 905 free ( session->nonce_cycle );
928 906
907 pthread_mutex_unlock(&session->mutex);
908
929 pthread_mutex_destroy(&session->mutex); 909 pthread_mutex_destroy(&session->mutex);
930 910
931 /* And finally free session */ 911 /* And finally free session */
diff --git a/toxav/rtp.h b/toxav/rtp.h
index c2b68b01..58b16ab1 100644..100755
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -42,13 +42,13 @@
42 */ 42 */
43 43
44typedef struct _RTPHeader { 44typedef struct _RTPHeader {
45 uint8_t flags; /* Version(2),Padding(1), Ext(1), Cc(4) */ 45 uint8_t flags; /* Version(2),Padding(1), Ext(1), Cc(4) */
46 uint8_t marker_payloadt; /* Marker(1), PlayLoad Type(7) */ 46 uint8_t marker_payloadt; /* Marker(1), PlayLoad Type(7) */
47 uint16_t sequnum; /* Sequence Number */ 47 uint16_t sequnum; /* Sequence Number */
48 uint32_t timestamp; /* Timestamp */ 48 uint32_t timestamp; /* Timestamp */
49 uint32_t ssrc; /* SSRC */ 49 uint32_t ssrc; /* SSRC */
50 uint32_t *csrc; /* CSRC's table */ 50 uint32_t csrc[16]; /* CSRC's table */
51 uint32_t length; /* Length of the header in payload string. */ 51 uint32_t length; /* Length of the header in payload string. */
52 52
53} RTPHeader; 53} RTPHeader;
54 54
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 977415dc..698fac3b 100644..100755
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -241,7 +241,7 @@ int toxav_cancel ( ToxAv *av, const char *reason )
241 return ErrorNoCall; 241 return ErrorNoCall;
242 } 242 }
243 243
244 return msi_cancel(av->msi_session, 0, (const uint8_t *)reason); 244 return msi_cancel(av->msi_session, 0, reason);
245} 245}
246 246
247/** 247/**
@@ -269,7 +269,7 @@ int toxav_stop_call ( ToxAv *av )
269 * @retval 0 Success. 269 * @retval 0 Success.
270 * @retval ToxAvError On error. 270 * @retval ToxAvError On error.
271 */ 271 */
272int toxav_prepare_transmission ( ToxAv *av ) 272int toxav_prepare_transmission ( ToxAv* av, int support_video )
273{ 273{
274 assert(av->msi_session); 274 assert(av->msi_session);
275 275
@@ -293,22 +293,23 @@ int toxav_prepare_transmission ( ToxAv *av )
293 return ErrorStartingAudioRtp; 293 return ErrorStartingAudioRtp;
294 } 294 }
295 295
296 av->rtp_sessions[video_index] = rtp_init_session ( 296 if ( support_video ) {
297 type_video, 297 av->rtp_sessions[video_index] = rtp_init_session (
298 av->messenger, 298 type_video,
299 av->msi_session->call->peers[0], 299 av->messenger,
300 av->msi_session->call->key_peer, 300 av->msi_session->call->peers[0],
301 av->msi_session->call->key_local, 301 av->msi_session->call->key_peer,
302 av->msi_session->call->nonce_peer, 302 av->msi_session->call->key_local,
303 av->msi_session->call->nonce_local 303 av->msi_session->call->nonce_peer,
304 ); 304 av->msi_session->call->nonce_local
305 305 );
306 306
307 if ( !av->rtp_sessions[video_index] ) { 307
308 fprintf(stderr, "Error while starting video RTP session!\n"); 308 if ( !av->rtp_sessions[video_index] ) {
309 return ErrorStartingVideoRtp; 309 fprintf(stderr, "Error while starting video RTP session!\n");
310 return ErrorStartingVideoRtp;
311 }
310 } 312 }
311
312 return ErrorNone; 313 return ErrorNone;
313} 314}
314 315
@@ -322,21 +323,20 @@ int toxav_prepare_transmission ( ToxAv *av )
322 */ 323 */
323int toxav_kill_transmission ( ToxAv *av ) 324int toxav_kill_transmission ( ToxAv *av )
324{ 325{
325 /* Both sessions should be active at any time */ 326 if ( av->rtp_sessions[audio_index] && -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
326 if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] )
327 return ErrorNoTransmission;
328
329
330 if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
331 fprintf(stderr, "Error while terminating audio RTP session!\n"); 327 fprintf(stderr, "Error while terminating audio RTP session!\n");
332 return ErrorTerminatingAudioRtp; 328 return ErrorTerminatingAudioRtp;
333 } 329 }
334 330
335 if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) { 331 if ( av->rtp_sessions[video_index] && -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) {
336 fprintf(stderr, "Error while terminating video RTP session!\n"); 332 fprintf(stderr, "Error while terminating video RTP session!\n");
337 return ErrorTerminatingVideoRtp; 333 return ErrorTerminatingVideoRtp;
338 } 334 }
339 335
336 av->rtp_sessions[audio_index] = NULL;
337 av->rtp_sessions[video_index] = NULL;
338
339
340 return ErrorNone; 340 return ErrorNone;
341} 341}
342 342
@@ -424,13 +424,14 @@ inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
424 424
425 uint8_t packet [RTP_PAYLOAD_SIZE]; 425 uint8_t packet [RTP_PAYLOAD_SIZE];
426 int recved_size = 0; 426 int recved_size = 0;
427 427 int error;
428
428 do { 429 do {
429 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet); 430 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet);
430 431
431 if (recved_size > 0) { 432 if (recved_size > 0)
432 printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0))); 433 fprintf(stderr, "Error decoding: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0)));
433 } 434
434 } while (recved_size > 0); 435 } while (recved_size > 0);
435 436
436 vpx_codec_iter_t iter = NULL; 437 vpx_codec_iter_t iter = NULL;
@@ -456,7 +457,7 @@ inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
456inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input) 457inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
457{ 458{
458 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) { 459 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) {
459 printf("could not encode video frame\n"); 460 fprintf(stderr, "Could not encode video frame\n");
460 return ErrorInternal; 461 return ErrorInternal;
461 } 462 }
462 463
@@ -500,7 +501,6 @@ inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest )
500 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet); 501 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet);
501 502
502 if ( recved_size == ErrorAudioPacketLost ) { 503 if ( recved_size == ErrorAudioPacketLost ) {
503 printf("Lost packet\n");
504 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1); 504 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
505 } else if ( recved_size ) { 505 } else if ( recved_size ) {
506 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); 506 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
@@ -551,6 +551,24 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int peer )
551} 551}
552 552
553/** 553/**
554 * @brief Get id of peer participating in conversation
555 *
556 * @param av Handler
557 * @param peer peer index
558 * @return int
559 * @retval ToxAvError No peer id
560 */
561int toxav_get_peer_id ( ToxAv* av, int peer )
562{
563 assert(av->msi_session);
564
565 if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer )
566 return ErrorInternal;
567
568 return av->msi_session->call->peers[peer];
569}
570
571/**
554 * @brief Get reference to an object that is handling av session. 572 * @brief Get reference to an object that is handling av session.
555 * 573 *
556 * @param av Handler. 574 * @param av Handler.
@@ -560,3 +578,68 @@ void *toxav_get_agent_handler ( ToxAv *av )
560{ 578{
561 return av->agent_handler; 579 return av->agent_handler;
562} 580}
581
582/**
583 * @brief Is video encoding supported
584 *
585 * @param av Handler
586 * @return int
587 * @retval 1 Yes.
588 * @retval 0 No.
589 */
590inline__ int toxav_video_encoding ( ToxAv* av )
591{
592 return av->cs->supported_actions & v_encoding;
593}
594
595
596/**
597 * @brief Is video decoding supported
598 *
599 * @param av Handler
600 * @return int
601 * @retval 1 Yes.
602 * @retval 0 No.
603 */
604inline__ int toxav_video_decoding ( ToxAv* av )
605{
606 return av->cs->supported_actions & v_decoding;
607}
608
609/**
610 * @brief Is audio encoding supported
611 *
612 * @param av Handler
613 * @return int
614 * @retval 1 Yes.
615 * @retval 0 No.
616 */
617inline__ int toxav_audio_encoding ( ToxAv* av )
618{
619 return av->cs->supported_actions & a_encoding;
620}
621
622
623/**
624 * @brief Is audio decoding supported
625 *
626 * @param av Handler
627 * @return int
628 * @retval 1 Yes.
629 * @retval 0 No.
630 */
631inline__ int toxav_audio_decoding ( ToxAv* av )
632{
633 return av->cs->supported_actions & a_decoding;
634}
635
636/**
637 * @brief Get messenger handle
638 *
639 * @param av Handler.
640 * @return Tox*
641 */
642inline__ Tox* toxav_get_tox ( ToxAv* av )
643{
644 return (Tox*)av->messenger;
645} \ No newline at end of file
diff --git a/toxav/toxav.h b/toxav/toxav.h
index df5acfc6..3e66c230 100644..100755
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -57,20 +57,20 @@ typedef struct Tox Tox;
57 */ 57 */
58typedef enum { 58typedef enum {
59 /* Requests */ 59 /* Requests */
60 OnInvite, 60 av_OnInvite,
61 OnStart, 61 av_OnStart,
62 OnCancel, 62 av_OnCancel,
63 OnReject, 63 av_OnReject,
64 OnEnd, 64 av_OnEnd,
65 65
66 /* Responses */ 66 /* Responses */
67 OnRinging, 67 av_OnRinging,
68 OnStarting, 68 av_OnStarting,
69 OnEnding, 69 av_OnEnding,
70 70
71 /* Protocol */ 71 /* Protocol */
72 OnError, 72 av_OnError,
73 OnRequestTimeout 73 av_OnRequestTimeout
74 74
75} ToxAvCallbackID; 75} ToxAvCallbackID;
76 76
@@ -98,9 +98,8 @@ typedef enum {
98 ErrorAudioPacketLost = -6, /* Indicating packet loss */ 98 ErrorAudioPacketLost = -6, /* Indicating packet loss */
99 ErrorStartingAudioRtp = -7, /* Error in toxav_prepare_transmission() */ 99 ErrorStartingAudioRtp = -7, /* Error in toxav_prepare_transmission() */
100 ErrorStartingVideoRtp = -8 , /* Error in toxav_prepare_transmission() */ 100 ErrorStartingVideoRtp = -8 , /* Error in toxav_prepare_transmission() */
101 ErrorNoTransmission = -9, /* Returned in toxav_kill_transmission() */ 101 ErrorTerminatingAudioRtp = -9, /* Returned in toxav_kill_transmission() */
102 ErrorTerminatingAudioRtp = -10, /* Returned in toxav_kill_transmission() */ 102 ErrorTerminatingVideoRtp = -10, /* Returned in toxav_kill_transmission() */
103 ErrorTerminatingVideoRtp = -11, /* Returned in toxav_kill_transmission() */
104 103
105} ToxAvError; 104} ToxAvError;
106 105
@@ -205,11 +204,12 @@ int toxav_stop_call(ToxAv *av);
205 * @brief Must be call before any RTP transmission occurs. 204 * @brief Must be call before any RTP transmission occurs.
206 * 205 *
207 * @param av Handler. 206 * @param av Handler.
207 * @param support_video Is video supported ? 1 : 0
208 * @return int 208 * @return int
209 * @retval 0 Success. 209 * @retval 0 Success.
210 * @retval ToxAvError On error. 210 * @retval ToxAvError On error.
211 */ 211 */
212int toxav_prepare_transmission(ToxAv *av); 212int toxav_prepare_transmission(ToxAv *av, int support_video);
213 213
214/** 214/**
215 * @brief Call this at the end of the transmission. 215 * @brief Call this at the end of the transmission.
@@ -282,6 +282,16 @@ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size);
282int toxav_get_peer_transmission_type ( ToxAv *av, int peer ); 282int toxav_get_peer_transmission_type ( ToxAv *av, int peer );
283 283
284/** 284/**
285 * @brief Get id of peer participating in conversation
286 *
287 * @param av Handler
288 * @param peer peer index
289 * @return int
290 * @retval ToxAvError No peer id
291 */
292int toxav_get_peer_id ( ToxAv* av, int peer );
293
294/**
285 * @brief Get reference to an object that is handling av session. 295 * @brief Get reference to an object that is handling av session.
286 * 296 *
287 * @param av Handler. 297 * @param av Handler.
@@ -289,4 +299,52 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int peer );
289 */ 299 */
290void *toxav_get_agent_handler ( ToxAv *av ); 300void *toxav_get_agent_handler ( ToxAv *av );
291 301
302/**
303 * @brief Is video encoding supported
304 *
305 * @param av Handler
306 * @return int
307 * @retval 1 Yes.
308 * @retval 0 No.
309 */
310int toxav_video_encoding ( ToxAv* av );
311
312/**
313 * @brief Is video decoding supported
314 *
315 * @param av Handler
316 * @return int
317 * @retval 1 Yes.
318 * @retval 0 No.
319 */
320int toxav_video_decoding ( ToxAv* av );
321
322/**
323 * @brief Is audio encoding supported
324 *
325 * @param av Handler
326 * @return int
327 * @retval 1 Yes.
328 * @retval 0 No.
329 */
330int toxav_audio_encoding ( ToxAv* av );
331
332/**
333 * @brief Is audio decoding supported
334 *
335 * @param av Handler
336 * @return int
337 * @retval 1 Yes.
338 * @retval 0 No.
339 */
340int toxav_audio_decoding ( ToxAv* av );
341
342/**
343 * @brief Get messenger handle
344 *
345 * @param av Handler.
346 * @return Tox*
347 */
348Tox* toxav_get_tox ( ToxAv* av );
349
292#endif /* __TOXAV */ \ No newline at end of file 350#endif /* __TOXAV */ \ No newline at end of file