diff options
author | mannol <eniz_vukovic@hotmail.com> | 2014-03-07 03:13:04 +0100 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2014-03-07 03:13:04 +0100 |
commit | 6a78e2e71c1471b89646a71a1adeb0529cfb73d4 (patch) | |
tree | 1d4a05504f63efe64339155ae30e31799bafda57 | |
parent | 71284fabf881604ace3167830a0b1667832e971f (diff) |
Fixed several bugs and added some features
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | libtoxav.pc | 11 | ||||
-rw-r--r-- | toxav/media.c | 113 | ||||
-rw-r--r-- | toxav/media.h | 11 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/msi.c | 102 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/msi.h | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/phone.c | 172 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/rtp.c | 62 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/rtp.h | 14 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/toxav.c | 143 | ||||
-rwxr-xr-x[-rw-r--r--] | toxav/toxav.h | 86 |
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 | |||
487 | if test "x$BUILD_AV" = "xyes"; then | 487 | if 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 @@ | |||
1 | prefix=/usr/local | ||
2 | exec_prefix=${prefix} | ||
3 | libdir=${exec_prefix}/lib | ||
4 | includedir=${prefix}/include | ||
5 | |||
6 | Name: libtoxav | ||
7 | Description: Tox A/V library | ||
8 | Requires: | ||
9 | Version: 0.0.0 | ||
10 | Libs: -L${libdir} -ltoxav -lopus -lvpx -lm -pthread | ||
11 | Cflags: -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 | ||
49 | int 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 | ||
50 | struct jitter_buffer *create_queue(int capacity) | 66 | struct 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 */ |
82 | RTPMessage *dequeue(struct jitter_buffer *q, int *success) | 92 | RTPMessage *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 | ||
131 | int 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 | ||
147 | int queue(struct jitter_buffer *q, RTPMessage *pk) | 142 | int 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 | ||
299 | void codec_terminate_session ( CodecState *cs ) | 286 | void 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 | ||
41 | enum _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 | ||
42 | typedef struct _CodecState { | 50 | typedef 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 | ||
61 | typedef struct _RTPMessage RTPMessage; | 71 | typedef struct _RTPMessage RTPMessage; |
62 | 72 | ||
63 | struct jitter_buffer *create_queue(int capacity); | 73 | struct jitter_buffer *create_queue(int capacity); |
64 | int empty_queue(struct jitter_buffer *q); | ||
65 | 74 | ||
66 | int queue(struct jitter_buffer *q, RTPMessage *pk); | 75 | int queue(struct jitter_buffer *q, RTPMessage *pk); |
67 | RTPMessage *dequeue(struct jitter_buffer *q, int *success); | 76 | RTPMessage *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 ) | |||
616 | void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id ) | 616 | void 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 ) | |||
999 | int handle_recv_ending ( MSISession *session, MSIMessage *msg ) | 1004 | int 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 | } |
1013 | int handle_recv_error ( MSISession *session, MSIMessage *msg ) | 1026 | int 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 | */ |
1355 | int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason ) | 1373 | int 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 | */ |
209 | int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason ); | 209 | int 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 | ||
736 | void *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 | ||
739 | int phone_startmedia_loop ( ToxAv *arg ) | 846 | int 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 | |||
1133 | failed_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 | |||
801 | void rtp_free_msg ( RTPSession *session, RTPMessage *msg ) | 780 | void 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 | ||
44 | typedef struct _RTPHeader { | 44 | typedef 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 | */ |
272 | int toxav_prepare_transmission ( ToxAv *av ) | 272 | int 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 | */ |
323 | int toxav_kill_transmission ( ToxAv *av ) | 324 | int 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) | |||
456 | inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input) | 457 | inline__ 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 | */ | ||
561 | int 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 | */ | ||
590 | inline__ 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 | */ | ||
604 | inline__ 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 | */ | ||
617 | inline__ 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 | */ | ||
631 | inline__ 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 | */ | ||
642 | inline__ 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 | */ |
58 | typedef enum { | 58 | typedef 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 | */ |
212 | int toxav_prepare_transmission(ToxAv *av); | 212 | int 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); | |||
282 | int toxav_get_peer_transmission_type ( ToxAv *av, int peer ); | 282 | int 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 | */ | ||
292 | int 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 | */ |
290 | void *toxav_get_agent_handler ( ToxAv *av ); | 300 | void *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 | */ | ||
310 | int 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 | */ | ||
320 | int 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 | */ | ||
330 | int 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 | */ | ||
340 | int toxav_audio_decoding ( ToxAv* av ); | ||
341 | |||
342 | /** | ||
343 | * @brief Get messenger handle | ||
344 | * | ||
345 | * @param av Handler. | ||
346 | * @return Tox* | ||
347 | */ | ||
348 | Tox* toxav_get_tox ( ToxAv* av ); | ||
349 | |||
292 | #endif /* __TOXAV */ \ No newline at end of file | 350 | #endif /* __TOXAV */ \ No newline at end of file |