diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-29 01:01:25 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-29 01:01:25 +0200 |
commit | 9bba7a0434d0967d5dd76b8afc7783ea2edad0cf (patch) | |
tree | 6486c250acb38429a63a62e54cd1e4bcb0a029ee | |
parent | e4a020333d76bc30172f54f2545677f01bdd54b6 (diff) |
Done
-rw-r--r-- | auto_tests/Makefile.inc | 10 | ||||
-rw-r--r-- | auto_tests/toxav_basic_test.c | 875 | ||||
-rw-r--r-- | auto_tests/toxav_many_test.c | 459 | ||||
-rw-r--r-- | testing/av_test.c (renamed from toxav/av_test.c) | 264 | ||||
-rw-r--r-- | toxav/Makefile.inc | 21 | ||||
-rw-r--r-- | toxav/audio.c | 35 | ||||
-rw-r--r-- | toxav/audio.h | 33 | ||||
-rw-r--r-- | toxav/msi.c | 124 | ||||
-rw-r--r-- | toxav/msi.h | 24 | ||||
-rw-r--r-- | toxav/rtp.c | 67 | ||||
-rw-r--r-- | toxav/rtp.h | 11 | ||||
-rw-r--r-- | toxav/toxav.c | 132 | ||||
-rw-r--r-- | toxav/toxav.h | 40 | ||||
-rw-r--r-- | toxav/video.c | 25 | ||||
-rw-r--r-- | toxav/video.h | 36 |
15 files changed, 764 insertions, 1392 deletions
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc index d78a6a5a..741ca7fa 100644 --- a/auto_tests/Makefile.inc +++ b/auto_tests/Makefile.inc | |||
@@ -21,8 +21,8 @@ AUTOTEST_LDADD = \ | |||
21 | 21 | ||
22 | 22 | ||
23 | if BUILD_AV | 23 | if BUILD_AV |
24 | TESTS += toxav_basic_test toxav_many_test | 24 | TESTS += toxav_basic_test #toxav_many_test |
25 | check_PROGRAMS += toxav_basic_test toxav_many_test | 25 | check_PROGRAMS += toxav_basic_test #toxav_many_test |
26 | AUTOTEST_LDADD += libtoxav.la | 26 | AUTOTEST_LDADD += libtoxav.la |
27 | endif | 27 | endif |
28 | 28 | ||
@@ -90,11 +90,11 @@ toxav_basic_test_CFLAGS = $(AUTOTEST_CFLAGS) | |||
90 | toxav_basic_test_LDADD = $(AUTOTEST_LDADD) $(AV_LIBS) | 90 | toxav_basic_test_LDADD = $(AUTOTEST_LDADD) $(AV_LIBS) |
91 | 91 | ||
92 | 92 | ||
93 | toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c | 93 | #toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c |
94 | 94 | ||
95 | toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS) | 95 | #toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS) |
96 | 96 | ||
97 | toxav_many_test_LDADD = $(AUTOTEST_LDADD) | 97 | #toxav_many_test_LDADD = $(AUTOTEST_LDADD) |
98 | endif | 98 | endif |
99 | 99 | ||
100 | endif | 100 | endif |
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c index a43b7c2f..7598c0db 100644 --- a/auto_tests/toxav_basic_test.c +++ b/auto_tests/toxav_basic_test.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <vpx/vpx_image.h> | 14 | #include <vpx/vpx_image.h> |
15 | 15 | ||
16 | #include "../toxcore/tox.h" | 16 | #include "../toxcore/tox.h" |
17 | #include "../toxcore/util.h" | ||
17 | #include "../toxcore/logger.h" | 18 | #include "../toxcore/logger.h" |
18 | #include "../toxcore/crypto_core.h" | 19 | #include "../toxcore/crypto_core.h" |
19 | #include "../toxav/toxav.h" | 20 | #include "../toxav/toxav.h" |
@@ -28,600 +29,406 @@ | |||
28 | #endif | 29 | #endif |
29 | 30 | ||
30 | 31 | ||
32 | #define TEST_REGULAR_AV 1 | ||
33 | #define TEST_REGULAR_A 1 | ||
34 | #define TEST_REGULAR_V 1 | ||
35 | #define TEST_REJECT 1 | ||
36 | #define TEST_CANCEL 1 | ||
37 | #define TEST_MUTE_UNMUTE 1 | ||
31 | 38 | ||
32 | typedef enum _CallStatus { | ||
33 | none, | ||
34 | InCall, | ||
35 | Ringing, | ||
36 | Ended, | ||
37 | Rejected, | ||
38 | Canceled, | ||
39 | TimedOut | ||
40 | 39 | ||
41 | } CallStatus; | 40 | typedef struct { |
41 | bool incoming; | ||
42 | uint32_t state; | ||
43 | |||
44 | } CallControl; | ||
42 | 45 | ||
43 | typedef struct _Party { | ||
44 | CallStatus status; | ||
45 | ToxAv *av; | ||
46 | time_t *CallStarted; | ||
47 | int call_index; | ||
48 | } Party; | ||
49 | 46 | ||
50 | typedef struct _Status { | 47 | /** |
51 | Party Alice; | 48 | * Callbacks |
52 | Party Bob; | 49 | */ |
53 | } Status; | 50 | void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) |
54 | |||
55 | /* My default settings */ | ||
56 | static ToxAvCSettings muhcaps; | ||
57 | |||
58 | void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | ||
59 | { | ||
60 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { | ||
61 | tox_friend_add_norequest(m, public_key, 0); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | |||
66 | /******************************************************************************/ | ||
67 | void callback_recv_invite ( void *av, int32_t call_index, void *_arg ) | ||
68 | { | ||
69 | Status *cast = _arg; | ||
70 | |||
71 | if (cast->Alice.av == av) { | ||
72 | // ... | ||
73 | } else if (cast->Bob.av == av) { | ||
74 | /* Bob always receives invite */ | ||
75 | cast->Bob.status = Ringing; | ||
76 | cast->Bob.call_index = call_index; | ||
77 | } | ||
78 | } | ||
79 | void callback_recv_ringing ( void *av, int32_t call_index, void *_arg ) | ||
80 | { | ||
81 | Status *cast = _arg; | ||
82 | |||
83 | if (cast->Alice.av == av) { | ||
84 | /* Alice always sends invite */ | ||
85 | cast->Alice.status = Ringing; | ||
86 | } else if (cast->Bob.av == av) { | ||
87 | // ... | ||
88 | } | ||
89 | } | ||
90 | |||
91 | |||
92 | void callback_call_started ( void *av, int32_t call_index, void *_arg ) | ||
93 | { | ||
94 | Status *cast = _arg; | ||
95 | |||
96 | if (cast->Alice.av == av) { | ||
97 | printf("Call started on Alices side...\n"); | ||
98 | cast->Alice.status = InCall; | ||
99 | toxav_prepare_transmission(av, call_index, 1); | ||
100 | } else if (cast->Bob.av == av) { | ||
101 | printf("Call started on Bob side...\n"); | ||
102 | cast->Bob.status = InCall; | ||
103 | toxav_prepare_transmission(av, call_index, 1); | ||
104 | } | ||
105 | } | ||
106 | void callback_call_canceled ( void *av, int32_t call_index, void *_arg ) | ||
107 | { | 51 | { |
108 | Status *cast = _arg; | 52 | printf("Handling CALL callback\n"); |
109 | 53 | ((CallControl*)user_data)->incoming = true; | |
110 | if (cast->Alice.av == av) { | ||
111 | // ... | ||
112 | } else if (cast->Bob.av == av) { | ||
113 | printf ( "Call Canceled for Bob!\n" ); | ||
114 | cast->Bob.status = Canceled; | ||
115 | } | ||
116 | } | 54 | } |
117 | void callback_call_rejected ( void *av, int32_t call_index, void *_arg ) | 55 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) |
118 | { | 56 | { |
119 | Status *cast = _arg; | 57 | printf("Handling CALL STATE callback: %d\n", state); |
120 | 58 | ((CallControl*)user_data)->state = state; | |
121 | printf ( "Call rejected by Bob!\n" | ||
122 | "Call ended for Alice!\n" ); | ||
123 | |||
124 | /* If Bob rejects, call is ended for alice and she sends ending */ | ||
125 | if (cast->Alice.av == av) { | ||
126 | cast->Alice.status = Rejected; | ||
127 | } else if (cast->Bob.av == av) { | ||
128 | //... ignor | ||
129 | } | ||
130 | } | 59 | } |
131 | void callback_call_ended ( void *av, int32_t call_index, void *_arg ) | 60 | void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, |
61 | uint16_t width, uint16_t height, | ||
62 | uint8_t const *y, uint8_t const *u, uint8_t const *v, | ||
63 | int32_t ystride, int32_t ustride, int32_t vstride, | ||
64 | void *user_data) | ||
132 | { | 65 | { |
133 | Status *cast = _arg; | 66 | (void) av; |
134 | 67 | (void) friend_number; | |
135 | if (cast->Alice.av == av) { | 68 | (void) width; |
136 | printf ( "Call ended for Alice!\n" ); | 69 | (void) height; |
137 | cast->Alice.status = Ended; | 70 | (void) y; |
138 | } else if (cast->Bob.av == av) { | 71 | (void) u; |
139 | printf ( "Call ended for Bob!\n" ); | 72 | (void) v; |
140 | cast->Bob.status = Ended; | 73 | (void) ystride; |
141 | } | 74 | (void) ustride; |
75 | (void) vstride; | ||
76 | (void) user_data; | ||
142 | } | 77 | } |
143 | 78 | void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |
144 | void callback_peer_cs_change ( void *av, int32_t call_index, void *_arg ) | 79 | int16_t const *pcm, |
80 | size_t sample_count, | ||
81 | uint8_t channels, | ||
82 | uint32_t sampling_rate, | ||
83 | void *user_data) | ||
145 | { | 84 | { |
146 | ToxAvCSettings csettings; | 85 | (void) av; |
147 | toxav_get_peer_csettings(av, call_index, 0, &csettings); | 86 | (void) friend_number; |
148 | 87 | (void) pcm; | |
149 | printf("Peer changing settings to: \n" | 88 | (void) sample_count; |
150 | "Type: %u \n" | 89 | (void) channels; |
151 | "Video bitrate: %u \n" | 90 | (void) sampling_rate; |
152 | "Video height: %u \n" | 91 | (void) user_data; |
153 | "Video width: %u \n" | ||
154 | "Audio bitrate: %u \n" | ||
155 | "Audio framedur: %u \n" | ||
156 | "Audio sample rate: %u \n" | ||
157 | "Audio channels: %u \n", | ||
158 | csettings.call_type, | ||
159 | csettings.video_bitrate, | ||
160 | csettings.max_video_height, | ||
161 | csettings.max_video_width, | ||
162 | csettings.audio_bitrate, | ||
163 | csettings.audio_frame_duration, | ||
164 | csettings.audio_sample_rate, | ||
165 | csettings.audio_channels | ||
166 | ); | ||
167 | } | 92 | } |
168 | 93 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | |
169 | void callback_self_cs_change ( void *av, int32_t call_index, void *_arg ) | ||
170 | { | 94 | { |
171 | ToxAvCSettings csettings; | 95 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { |
172 | toxav_get_peer_csettings(av, call_index, 0, &csettings); | 96 | assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); |
173 | |||
174 | printf("Changed settings to: \n" | ||
175 | "Type: %u \n" | ||
176 | "Video bitrate: %u \n" | ||
177 | "Video height: %u \n" | ||
178 | "Video width: %u \n" | ||
179 | "Audio bitrate: %u \n" | ||
180 | "Audio framedur: %u \n" | ||
181 | "Audio sample rate: %u \n" | ||
182 | "Audio channels: %u \n", | ||
183 | csettings.call_type, | ||
184 | csettings.video_bitrate, | ||
185 | csettings.max_video_height, | ||
186 | csettings.max_video_width, | ||
187 | csettings.audio_bitrate, | ||
188 | csettings.audio_frame_duration, | ||
189 | csettings.audio_sample_rate, | ||
190 | csettings.audio_channels | ||
191 | ); | ||
192 | } | ||
193 | |||
194 | void callback_requ_timeout ( void *av, int32_t call_index, void *_arg ) | ||
195 | { | ||
196 | Status *cast = _arg; | ||
197 | printf("Call timed-out!\n"); | ||
198 | |||
199 | if (cast->Alice.av == av) { | ||
200 | cast->Alice.status = TimedOut; | ||
201 | } else if (cast->Bob.av == av) { | ||
202 | cast->Bob.status = TimedOut; | ||
203 | } | 97 | } |
204 | } | 98 | } |
205 | 99 | ||
206 | void callback_audio (void *agent, int32_t call_idx, const int16_t *PCM, uint16_t size, void *data) | ||
207 | {} | ||
208 | |||
209 | void callback_video (void *agent, int32_t call_idx, const vpx_image_t *img, void *data) | ||
210 | {} | ||
211 | 100 | ||
212 | void register_callbacks(ToxAv *av, void *data) | 101 | /** |
102 | * Iterate helper | ||
103 | */ | ||
104 | int iterate_tox(Tox* bootstrap, Tox* Alice, Tox* Bob) | ||
213 | { | 105 | { |
214 | toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); | 106 | tox_iterate(bootstrap); |
215 | toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); | 107 | tox_iterate(Alice); |
216 | toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); | 108 | tox_iterate(Bob); |
217 | toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); | 109 | |
218 | toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); | 110 | return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob)); |
219 | toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data); | ||
220 | toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data); | ||
221 | toxav_register_callstate_callback(av, callback_peer_cs_change, av_OnPeerCSChange, data); | ||
222 | toxav_register_callstate_callback(av, callback_self_cs_change, av_OnSelfCSChange, data); | ||
223 | toxav_register_audio_callback(av, callback_audio, NULL); | ||
224 | toxav_register_video_callback(av, callback_video, NULL); | ||
225 | } | 111 | } |
226 | 112 | ||
227 | 113 | ||
228 | /*************************************************************************************************/ | ||
229 | |||
230 | /* Alice calls bob and the call starts. | ||
231 | * What happens during the call is defined after. To quit the loop use: step++; | ||
232 | */ | ||
233 | #define CALL_AND_START_LOOP(AliceCallType, BobCallType) \ | ||
234 | { int step = 0, running = 1; while (running) {\ | ||
235 | tox_iterate(bootstrap_node); tox_iterate(Alice); tox_iterate(Bob); \ | ||
236 | toxav_do(status_control.Bob.av); toxav_do(status_control.Alice.av); \ | ||
237 | switch ( step ) {\ | ||
238 | case 0: /* Alice */ printf("Alice is calling...\n");\ | ||
239 | toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); step++; break;\ | ||
240 | case 1: /* Bob */ if (status_control.Bob.status == Ringing) { printf("Bob answers...\n");\ | ||
241 | cur_time = time(NULL); toxav_answer(status_control.Bob.av, status_control.Bob.call_index, &muhcaps); step++; } break; \ | ||
242 | case 2: /* Rtp transmission */ \ | ||
243 | if (status_control.Bob.status == InCall && status_control.Alice.status == InCall) | ||
244 | |||
245 | |||
246 | #define TERMINATE_SCOPE() break;\ | ||
247 | case 3: /* Wait for Both to have status ended */\ | ||
248 | if (status_control.Alice.status == Ended && status_control.Bob.status == Ended) running = 0; break; } c_sleep(20); } } printf("\n"); | ||
249 | 114 | ||
250 | START_TEST(test_AV_flows) | 115 | START_TEST(test_AV_flows) |
251 | { | 116 | { |
117 | Tox* Alice, *Bob, *bootstrap; | ||
118 | ToxAV* AliceAV, *BobAV; | ||
119 | |||
120 | CallControl AliceCC, BobCC; | ||
121 | |||
122 | { | ||
123 | TOX_ERR_NEW error; | ||
124 | |||
125 | bootstrap = tox_new(NULL, NULL, 0, &error); | ||
126 | assert(error == TOX_ERR_NEW_OK); | ||
127 | |||
128 | Alice = tox_new(NULL, NULL, 0, &error); | ||
129 | assert(error == TOX_ERR_NEW_OK); | ||
130 | |||
131 | Bob = tox_new(NULL, NULL, 0, &error); | ||
132 | assert(error == TOX_ERR_NEW_OK); | ||
133 | } | ||
134 | |||
135 | printf("Created 3 instances of Tox\n"); | ||
136 | printf("Preparing network...\n"); | ||
252 | long long unsigned int cur_time = time(NULL); | 137 | long long unsigned int cur_time = time(NULL); |
253 | Tox *bootstrap_node = tox_new(0, 0, 0, 0); | 138 | |
254 | Tox *Alice = tox_new(0, 0, 0, 0); | ||
255 | Tox *Bob = tox_new(0, 0, 0, 0); | ||
256 | |||
257 | ck_assert_msg(bootstrap_node || Alice || Bob, "Failed to create 3 tox instances"); | ||
258 | |||
259 | uint32_t to_compare = 974536; | 139 | uint32_t to_compare = 974536; |
260 | tox_callback_friend_request(Alice, accept_friend_request, &to_compare); | ||
261 | uint8_t address[TOX_ADDRESS_SIZE]; | 140 | uint8_t address[TOX_ADDRESS_SIZE]; |
141 | |||
142 | tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare); | ||
262 | tox_self_get_address(Alice, address); | 143 | tox_self_get_address(Alice, address); |
263 | uint32_t test = tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, 0); | 144 | |
264 | 145 | ||
265 | ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); | 146 | assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); |
266 | 147 | ||
267 | uint8_t off = 1; | 148 | uint8_t off = 1; |
268 | 149 | ||
269 | while (1) { | 150 | while (1) { |
270 | tox_iterate(bootstrap_node); | 151 | iterate_tox(bootstrap, Alice, Bob); |
271 | tox_iterate(Alice); | 152 | |
272 | tox_iterate(Bob); | 153 | if (tox_self_get_connection_status(bootstrap) && |
273 | 154 | tox_self_get_connection_status(Alice) && | |
274 | if (tox_self_get_connection_status(bootstrap_node) && tox_self_get_connection_status(Alice) | 155 | tox_self_get_connection_status(Bob) && off) { |
275 | && tox_self_get_connection_status(Bob) | ||
276 | && off) { | ||
277 | printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); | 156 | printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); |
278 | off = 0; | 157 | off = 0; |
279 | } | 158 | } |
280 | 159 | ||
281 | if (tox_friend_get_connection_status(Alice, 0, 0) && tox_friend_get_connection_status(Bob, 0, 0)) | 160 | if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP && |
161 | tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP) | ||
282 | break; | 162 | break; |
283 | 163 | ||
284 | c_sleep(20); | 164 | c_sleep(20); |
285 | } | 165 | } |
286 | 166 | ||
287 | printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); | 167 | |
288 | 168 | { | |
289 | muhcaps = av_DefaultSettings; | 169 | TOXAV_ERR_NEW error; |
290 | muhcaps.max_video_height = muhcaps.max_video_width = 128; | 170 | AliceAV = toxav_new(Alice, &error); |
291 | 171 | assert(error == TOXAV_ERR_NEW_OK); | |
292 | Status status_control = { | 172 | |
293 | {none, toxav_new(Alice, 1), NULL, -1}, | 173 | BobAV = toxav_new(Bob, &error); |
294 | {none, toxav_new(Bob, 1), NULL, -1}, | 174 | assert(error == TOXAV_ERR_NEW_OK); |
295 | }; | ||
296 | |||
297 | ck_assert_msg(status_control.Alice.av || status_control.Bob.av, "Failed to create 2 toxav instances"); | ||
298 | |||
299 | |||
300 | register_callbacks(status_control.Alice.av, &status_control); | ||
301 | register_callbacks(status_control.Bob.av, &status_control); | ||
302 | |||
303 | const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); | ||
304 | int16_t sample_payload[frame_size]; | ||
305 | randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size); | ||
306 | |||
307 | uint8_t prepared_payload[RTP_PAYLOAD_SIZE]; | ||
308 | int payload_size; | ||
309 | |||
310 | vpx_image_t *sample_image = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, 128, 128, 1); | ||
311 | |||
312 | memcpy(sample_image->planes[VPX_PLANE_Y], sample_payload, 10); | ||
313 | memcpy(sample_image->planes[VPX_PLANE_U], sample_payload, 10); | ||
314 | memcpy(sample_image->planes[VPX_PLANE_V], sample_payload, 10); | ||
315 | |||
316 | |||
317 | /************************************************************************************************* | ||
318 | * Successful flows (when call starts) | ||
319 | */ | ||
320 | |||
321 | /* | ||
322 | * Call with audio only on both sides. Alice calls Bob. | ||
323 | */ | ||
324 | |||
325 | |||
326 | CALL_AND_START_LOOP(TypeAudio, TypeAudio) { | ||
327 | /* Both send */ | ||
328 | payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, | ||
329 | 1000, sample_payload, frame_size); | ||
330 | |||
331 | if ( payload_size < 0 ) { | ||
332 | ck_assert_msg ( 0, "Failed to encode payload" ); | ||
333 | } | ||
334 | |||
335 | toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); | ||
336 | |||
337 | payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, | ||
338 | sample_payload, frame_size); | ||
339 | |||
340 | if ( payload_size < 0 ) { | ||
341 | ck_assert_msg ( 0, "Failed to encode payload" ); | ||
342 | } | ||
343 | |||
344 | toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); | ||
345 | |||
346 | if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ | ||
347 | step++; /* This terminates the loop */ | ||
348 | toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); | ||
349 | toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); | ||
350 | |||
351 | /* Call over Alice hangs up */ | ||
352 | toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); | ||
353 | } | ||
354 | } | 175 | } |
355 | TERMINATE_SCOPE() | 176 | |
356 | 177 | toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC); | |
357 | 178 | toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC); | |
358 | /* | 179 | toxav_callback_receive_video_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC); |
359 | * Call with audio on both sides and video on one side. Alice calls Bob. | 180 | toxav_callback_receive_audio_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC); |
360 | */ | 181 | |
361 | CALL_AND_START_LOOP(TypeAudio, TypeVideo) { | 182 | toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC); |
362 | /* Both send */ | 183 | toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC); |
363 | payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, | 184 | toxav_callback_receive_video_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC); |
364 | 1000, sample_payload, frame_size); | 185 | toxav_callback_receive_audio_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC); |
365 | 186 | ||
366 | if ( payload_size < 0 ) { | 187 | printf("Created 2 instances of ToxAV\n"); |
367 | ck_assert_msg ( 0, "Failed to encode payload" ); | 188 | printf("All set after %llu seconds!\n", time(NULL) - cur_time); |
368 | } | 189 | |
369 | 190 | ||
370 | toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); | 191 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ |
371 | 192 | do { \ | |
372 | payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, | 193 | memset(&AliceCC, 0, sizeof(CallControl)); \ |
373 | sample_payload, frame_size); | 194 | memset(&BobCC, 0, sizeof(CallControl)); \ |
374 | 195 | \ | |
375 | if ( payload_size < 0 ) { | 196 | TOXAV_ERR_CALL rc; \ |
376 | ck_assert_msg ( 0, "Failed to encode payload" ); | 197 | toxav_call(AliceAV, 0, A_BR, V_BR, &rc); \ |
377 | } | 198 | \ |
378 | 199 | if (rc != TOXAV_ERR_CALL_OK) { \ | |
379 | toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); | 200 | printf("toxav_call failed: %d\n", rc); \ |
380 | 201 | exit(1); \ | |
381 | // toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); | 202 | } \ |
382 | 203 | \ | |
383 | if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ | 204 | \ |
384 | step++; /* This terminates the loop */ | 205 | long long unsigned int start_time = time(NULL); \ |
385 | toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); | 206 | \ |
386 | toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); | 207 | \ |
387 | 208 | while (BobCC.state != TOXAV_CALL_STATE_END) { \ | |
388 | /* Call over Alice hangs up */ | 209 | \ |
389 | toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); | 210 | if (BobCC.incoming) { \ |
390 | } | 211 | TOXAV_ERR_ANSWER rc; \ |
212 | toxav_answer(BobAV, 0, A_BR, V_BR, &rc); \ | ||
213 | \ | ||
214 | if (rc != TOXAV_ERR_ANSWER_OK) { \ | ||
215 | printf("toxav_answer failed: %d\n", rc); \ | ||
216 | exit(1); \ | ||
217 | } \ | ||
218 | BobCC.incoming = false; \ | ||
219 | } else { \ | ||
220 | /* TODO rtp */ \ | ||
221 | \ | ||
222 | if (time(NULL) - start_time == 5) { \ | ||
223 | \ | ||
224 | TOXAV_ERR_CALL_CONTROL rc; \ | ||
225 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); \ | ||
226 | \ | ||
227 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { \ | ||
228 | printf("toxav_call_control failed: %d\n", rc); \ | ||
229 | exit(1); \ | ||
230 | } \ | ||
231 | } \ | ||
232 | } \ | ||
233 | \ | ||
234 | iterate_tox(bootstrap, Alice, Bob); \ | ||
235 | } \ | ||
236 | printf("Success!\n");\ | ||
237 | } while(0) | ||
238 | |||
239 | if (TEST_REGULAR_AV) { | ||
240 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
241 | REGULAR_CALL_FLOW(48, 4000); | ||
391 | } | 242 | } |
392 | TERMINATE_SCOPE() | 243 | |
393 | 244 | if (TEST_REGULAR_A) { | |
394 | 245 | printf("\nTrying regular call (Audio only)...\n"); | |
395 | /* | 246 | REGULAR_CALL_FLOW(48, 0); |
396 | * Call with audio and video on both sides. Alice calls Bob. | ||
397 | */ | ||
398 | CALL_AND_START_LOOP(TypeVideo, TypeVideo) { | ||
399 | /* Both send */ | ||
400 | |||
401 | payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, | ||
402 | 1000, sample_payload, frame_size); | ||
403 | |||
404 | if ( payload_size < 0 ) { | ||
405 | ck_assert_msg ( 0, "Failed to encode payload" ); | ||
406 | } | ||
407 | |||
408 | toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); | ||
409 | |||
410 | payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, | ||
411 | sample_payload, frame_size); | ||
412 | |||
413 | if ( payload_size < 0 ) { | ||
414 | ck_assert_msg ( 0, "Failed to encode payload" ); | ||
415 | } | ||
416 | |||
417 | toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); | ||
418 | |||
419 | // toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image); | ||
420 | // toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); | ||
421 | |||
422 | |||
423 | if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ | ||
424 | step++; /* This terminates the loop */ | ||
425 | toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); | ||
426 | toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); | ||
427 | |||
428 | /* Call over Alice hangs up */ | ||
429 | toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); | ||
430 | } | ||
431 | } | 247 | } |
432 | TERMINATE_SCOPE() | 248 | |
433 | 249 | if (TEST_REGULAR_V) { | |
434 | 250 | printf("\nTrying regular call (Video only)...\n"); | |
435 | uint64_t times_they_are_a_changin = time(NULL); | 251 | REGULAR_CALL_FLOW(0, 4000); |
436 | /* Media change */ | 252 | } |
437 | CALL_AND_START_LOOP(TypeAudio, TypeAudio) { | 253 | |
438 | /* Both send */ | 254 | #undef REGULAR_CALL_FLOW |
439 | payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, | 255 | |
440 | 1000, sample_payload, frame_size); | 256 | if (TEST_REJECT) { /* Alice calls; Bob rejects */ |
441 | 257 | printf("\nTrying reject flow...\n"); | |
442 | if ( payload_size < 0 ) { | 258 | |
443 | ck_assert_msg ( 0, "Failed to encode payload" ); | 259 | memset(&AliceCC, 0, sizeof(CallControl)); |
260 | memset(&BobCC, 0, sizeof(CallControl)); | ||
261 | |||
262 | { | ||
263 | TOXAV_ERR_CALL rc; | ||
264 | toxav_call(AliceAV, 0, 48, 0, &rc); | ||
265 | |||
266 | if (rc != TOXAV_ERR_CALL_OK) { | ||
267 | printf("toxav_call failed: %d\n", rc); | ||
268 | exit(1); | ||
269 | } | ||
444 | } | 270 | } |
445 | 271 | ||
446 | toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); | 272 | while (!BobCC.incoming) |
447 | 273 | iterate_tox(bootstrap, Alice, Bob); | |
448 | payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, | 274 | |
449 | sample_payload, frame_size); | 275 | /* Reject */ |
450 | 276 | { | |
451 | if ( payload_size < 0 ) { | 277 | TOXAV_ERR_CALL_CONTROL rc; |
452 | ck_assert_msg ( 0, "Failed to encode payload" ); | 278 | toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); |
279 | |||
280 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
281 | printf("toxav_call_control failed: %d\n", rc); | ||
282 | exit(1); | ||
283 | } | ||
453 | } | 284 | } |
454 | 285 | ||
455 | toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); | 286 | while (AliceCC.state != TOXAV_CALL_STATE_END) |
456 | 287 | iterate_tox(bootstrap, Alice, Bob); | |
457 | /* Wait 2 seconds and change transmission type */ | 288 | |
458 | if (time(NULL) - times_they_are_a_changin > 2) { | 289 | printf("Success!\n"); |
459 | times_they_are_a_changin = time(NULL); | 290 | } |
460 | muhcaps.audio_bitrate ++; | 291 | |
461 | toxav_change_settings(status_control.Alice.av, status_control.Alice.call_index, &muhcaps); | 292 | if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ |
293 | printf("\nTrying cancel (while ringing) flow...\n"); | ||
294 | |||
295 | memset(&AliceCC, 0, sizeof(CallControl)); | ||
296 | memset(&BobCC, 0, sizeof(CallControl)); | ||
297 | |||
298 | { | ||
299 | TOXAV_ERR_CALL rc; | ||
300 | toxav_call(AliceAV, 0, 48, 0, &rc); | ||
301 | |||
302 | if (rc != TOXAV_ERR_CALL_OK) { | ||
303 | printf("toxav_call failed: %d\n", rc); | ||
304 | exit(1); | ||
305 | } | ||
462 | } | 306 | } |
463 | 307 | ||
464 | if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ | 308 | while (!BobCC.incoming) |
465 | step++; /* This terminates the loop */ | 309 | iterate_tox(bootstrap, Alice, Bob); |
466 | toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); | 310 | |
467 | toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); | 311 | /* Cancel */ |
468 | 312 | { | |
469 | /* Call over Alice hangs up */ | 313 | TOXAV_ERR_CALL_CONTROL rc; |
470 | toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); | 314 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); |
315 | |||
316 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
317 | printf("toxav_call_control failed: %d\n", rc); | ||
318 | exit(1); | ||
319 | } | ||
471 | } | 320 | } |
321 | |||
322 | /* Alice will not receive end state */ | ||
323 | while (BobCC.state != TOXAV_CALL_STATE_END) | ||
324 | iterate_tox(bootstrap, Alice, Bob); | ||
325 | |||
326 | printf("Success!\n"); | ||
472 | } | 327 | } |
473 | TERMINATE_SCOPE() | 328 | |
474 | 329 | if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ | |
475 | 330 | printf("\nTrying mute functionality...\n"); | |
476 | /************************************************************************************************* | 331 | |
477 | * Other flows | 332 | memset(&AliceCC, 0, sizeof(CallControl)); |
478 | */ | 333 | memset(&BobCC, 0, sizeof(CallControl)); |
479 | 334 | ||
480 | /* | 335 | /* Assume sending audio and video */ |
481 | * Call and reject | 336 | { |
482 | */ | 337 | TOXAV_ERR_CALL rc; |
483 | { | 338 | toxav_call(AliceAV, 0, 48, 1000, &rc); |
484 | int step = 0; | 339 | |
485 | int running = 1; | 340 | if (rc != TOXAV_ERR_CALL_OK) { |
486 | 341 | printf("toxav_call failed: %d\n", rc); | |
487 | while (running) { | 342 | exit(1); |
488 | tox_iterate(bootstrap_node); | ||
489 | tox_iterate(Alice); | ||
490 | tox_iterate(Bob); | ||
491 | |||
492 | switch ( step ) { | ||
493 | case 0: /* Alice */ | ||
494 | printf("Alice is calling...\n"); | ||
495 | toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); | ||
496 | step++; | ||
497 | break; | ||
498 | |||
499 | case 1: /* Bob */ | ||
500 | if (status_control.Bob.status == Ringing) { | ||
501 | printf("Bob rejects...\n"); | ||
502 | toxav_reject(status_control.Bob.av, status_control.Bob.call_index, "Who likes D's anyway?"); | ||
503 | step++; | ||
504 | } | ||
505 | |||
506 | break; | ||
507 | |||
508 | case 2: /* Wait for Both to have status ended */ | ||
509 | if (status_control.Alice.status == Rejected && status_control.Bob.status == Ended) running = 0; | ||
510 | |||
511 | break; | ||
512 | } | 343 | } |
513 | |||
514 | c_sleep(20); | ||
515 | } | 344 | } |
516 | 345 | ||
517 | printf("\n"); | 346 | while (!BobCC.incoming) |
518 | } | 347 | iterate_tox(bootstrap, Alice, Bob); |
519 | 348 | ||
520 | 349 | /* At first try all stuff while in invalid state */ | |
521 | /* | 350 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); |
522 | * Call and cancel | 351 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); |
523 | */ | 352 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); |
524 | { | 353 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); |
525 | int step = 0; | 354 | |
526 | int running = 1; | 355 | { |
527 | 356 | TOXAV_ERR_ANSWER rc; | |
528 | while (running) { | 357 | toxav_answer(BobAV, 0, 48, 4000, &rc); |
529 | tox_iterate(bootstrap_node); | 358 | |
530 | tox_iterate(Alice); | 359 | if (rc != TOXAV_ERR_ANSWER_OK) { |
531 | tox_iterate(Bob); | 360 | printf("toxav_answer failed: %d\n", rc); |
532 | 361 | exit(1); | |
533 | toxav_do(status_control.Alice.av); | ||
534 | toxav_do(status_control.Bob.av); | ||
535 | |||
536 | |||
537 | switch ( step ) { | ||
538 | case 0: /* Alice */ | ||
539 | printf("Alice is calling...\n"); | ||
540 | toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); | ||
541 | step++; | ||
542 | break; | ||
543 | |||
544 | |||
545 | case 1: /* Alice again */ | ||
546 | if (status_control.Bob.status == Ringing) { | ||
547 | printf("Alice cancels...\n"); | ||
548 | toxav_cancel(status_control.Alice.av, status_control.Alice.call_index, 0, "Who likes D's anyway?"); | ||
549 | step++; | ||
550 | } | ||
551 | |||
552 | break; | ||
553 | |||
554 | case 2: /* Wait for Both to have status ended */ | ||
555 | if (status_control.Bob.status == Canceled) running = 0; | ||
556 | |||
557 | break; | ||
558 | } | 362 | } |
559 | |||
560 | c_sleep(20); | ||
561 | } | 363 | } |
562 | 364 | ||
563 | printf("\n"); | 365 | iterate_tox(bootstrap, Alice, Bob); |
564 | } | 366 | |
565 | 367 | /* Pause and Resume */ | |
566 | /* | 368 | printf("Pause and Resume\n"); |
567 | * Timeout | 369 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); |
568 | */ | 370 | iterate_tox(bootstrap, Alice, Bob); |
569 | { | 371 | assert(BobCC.state == TOXAV_CALL_STATE_PAUSED); |
570 | int step = 0; | 372 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); |
571 | int running = 1; | 373 | iterate_tox(bootstrap, Alice, Bob); |
572 | 374 | assert(BobCC.state & (TOXAV_CALL_STATE_SENDING_A | TOXAV_CALL_STATE_SENDING_V)); | |
573 | while (running) { | 375 | |
574 | tox_iterate(bootstrap_node); | 376 | /* Mute/Unmute single */ |
575 | tox_iterate(Alice); | 377 | printf("Mute/Unmute single\n"); |
576 | tox_iterate(Bob); | 378 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); |
577 | 379 | iterate_tox(bootstrap, Alice, Bob); | |
578 | toxav_do(status_control.Alice.av); | 380 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); |
579 | toxav_do(status_control.Bob.av); | 381 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); |
580 | 382 | iterate_tox(bootstrap, Alice, Bob); | |
581 | switch ( step ) { | 383 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); |
582 | case 0: | 384 | |
583 | printf("Alice is calling...\n"); | 385 | /* Mute/Unmute both */ |
584 | toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); | 386 | printf("Mute/Unmute both\n"); |
585 | step++; | 387 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); |
586 | break; | 388 | iterate_tox(bootstrap, Alice, Bob); |
587 | 389 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); | |
588 | case 1: | 390 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); |
589 | if (status_control.Alice.status == TimedOut) running = 0; | 391 | iterate_tox(bootstrap, Alice, Bob); |
590 | 392 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_V); | |
591 | break; | 393 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); |
394 | iterate_tox(bootstrap, Alice, Bob); | ||
395 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); | ||
396 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); | ||
397 | iterate_tox(bootstrap, Alice, Bob); | ||
398 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_V); | ||
399 | |||
400 | { | ||
401 | TOXAV_ERR_CALL_CONTROL rc; | ||
402 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); | ||
403 | |||
404 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
405 | printf("toxav_call_control failed: %d\n", rc); | ||
406 | exit(1); | ||
592 | } | 407 | } |
593 | |||
594 | c_sleep(20); | ||
595 | } | 408 | } |
596 | 409 | ||
597 | printf("\n"); | 410 | iterate_tox(bootstrap, Alice, Bob); |
411 | assert(BobCC.state == TOXAV_CALL_STATE_END); | ||
412 | |||
413 | printf("Success!\n"); | ||
598 | } | 414 | } |
599 | 415 | ||
600 | vpx_img_free(sample_image); | 416 | toxav_kill(BobAV); |
601 | toxav_kill(status_control.Alice.av); | 417 | toxav_kill(AliceAV); |
602 | toxav_kill(status_control.Bob.av); | ||
603 | tox_kill(bootstrap_node); | ||
604 | tox_kill(Alice); | ||
605 | tox_kill(Bob); | 418 | tox_kill(Bob); |
606 | 419 | tox_kill(Alice); | |
607 | printf("Calls ended!\n"); | 420 | tox_kill(bootstrap); |
421 | |||
422 | printf("\nTest successful!\n"); | ||
608 | } | 423 | } |
609 | END_TEST | 424 | END_TEST |
610 | 425 | ||
611 | /*************************************************************************************************/ | ||
612 | |||
613 | |||
614 | /*************************************************************************************************/ | ||
615 | |||
616 | /*************************************************************************************************/ | ||
617 | |||
618 | 426 | ||
619 | Suite *tox_suite(void) | 427 | Suite *tox_suite(void) |
620 | { | 428 | { |
621 | Suite *s = suite_create("ToxAV"); | 429 | Suite *s = suite_create("ToxAV"); |
622 | 430 | ||
623 | DEFTESTCASE_SLOW(AV_flows, 200); | 431 | DEFTESTCASE_SLOW(AV_flows, 200); |
624 | |||
625 | return s; | 432 | return s; |
626 | } | 433 | } |
627 | int main(int argc, char *argv[]) | 434 | int main(int argc, char *argv[]) |
@@ -637,6 +444,4 @@ int main(int argc, char *argv[]) | |||
637 | srunner_free(test_runner); | 444 | srunner_free(test_runner); |
638 | 445 | ||
639 | return number_failed; | 446 | return number_failed; |
640 | |||
641 | // return test_AV_flows(); | ||
642 | } | 447 | } |
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index 4287118f..ef59b2b2 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <vpx/vpx_image.h> | 14 | #include <vpx/vpx_image.h> |
15 | 15 | ||
16 | #include "../toxcore/tox.h" | 16 | #include "../toxcore/tox.h" |
17 | #include "../toxcore/util.h" | ||
17 | #include "../toxcore/logger.h" | 18 | #include "../toxcore/logger.h" |
18 | #include "../toxcore/crypto_core.h" | 19 | #include "../toxcore/crypto_core.h" |
19 | #include "../toxav/toxav.h" | 20 | #include "../toxav/toxav.h" |
@@ -26,359 +27,177 @@ | |||
26 | #define c_sleep(x) usleep(1000*x) | 27 | #define c_sleep(x) usleep(1000*x) |
27 | #endif | 28 | #endif |
28 | 29 | ||
29 | pthread_mutex_t muhmutex; | ||
30 | 30 | ||
31 | typedef enum _CallStatus { | 31 | typedef struct { |
32 | none, | 32 | bool incoming; |
33 | InCall, | 33 | uint32_t state; |
34 | Ringing, | 34 | |
35 | Ended, | 35 | } CallControl; |
36 | Rejected, | ||
37 | Canceled | ||
38 | 36 | ||
39 | } CallStatus; | ||
40 | 37 | ||
41 | typedef struct _Party { | 38 | /** |
42 | CallStatus status; | 39 | * Callbacks |
43 | ToxAv *av; | 40 | */ |
44 | int id; | 41 | void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) |
45 | } Party; | ||
46 | |||
47 | typedef struct _ACall { | ||
48 | pthread_t tid; | ||
49 | int idx; | ||
50 | |||
51 | Party Caller; | ||
52 | Party Callee; | ||
53 | } ACall; | ||
54 | |||
55 | typedef struct _Status { | ||
56 | ACall calls[3]; /* Make 3 calls for this test */ | ||
57 | } Status; | ||
58 | |||
59 | Status status_control; | ||
60 | |||
61 | void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | ||
62 | { | ||
63 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { | ||
64 | tox_friend_add_norequest(m, public_key, 0); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | |||
69 | /******************************************************************************/ | ||
70 | void callback_recv_invite ( void *av, int32_t call_index, void *_arg ) | ||
71 | { | 42 | { |
72 | Status *cast = _arg; | 43 | printf("Handling CALL callback\n"); |
73 | cast->calls[call_index].Callee.status = Ringing; | 44 | ((CallControl*)user_data)->incoming = true; |
74 | } | 45 | } |
75 | void callback_recv_ringing ( void *av, int32_t call_index, void *_arg ) | 46 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) |
76 | { | 47 | { |
77 | Status *cast = _arg; | 48 | printf("Handling CALL STATE callback: %d\n", state); |
78 | cast->calls[call_index].Caller.status = Ringing; | 49 | ((CallControl*)user_data)->state = state; |
79 | } | 50 | } |
80 | void callback_call_ended ( void *av, int32_t call_index, void *_arg ) | 51 | void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, |
52 | uint16_t width, uint16_t height, | ||
53 | uint8_t const *y, uint8_t const *u, uint8_t const *v, | ||
54 | int32_t ystride, int32_t ustride, int32_t vstride, | ||
55 | void *user_data) | ||
81 | { | 56 | { |
82 | Status *cast = _arg; | 57 | (void) av; |
83 | 58 | (void) friend_number; | |
84 | if (av == cast->calls[call_index].Caller.av) | 59 | (void) width; |
85 | cast->calls[call_index].Caller.status = Ended; | 60 | (void) height; |
86 | else | 61 | (void) y; |
87 | cast->calls[call_index].Callee.status = Ended; | 62 | (void) u; |
63 | (void) v; | ||
64 | (void) ystride; | ||
65 | (void) ustride; | ||
66 | (void) vstride; | ||
67 | (void) user_data; | ||
88 | } | 68 | } |
89 | void callback_call_started ( void *av, int32_t call_index, void *_arg ) | 69 | void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, |
70 | int16_t const *pcm, | ||
71 | size_t sample_count, | ||
72 | uint8_t channels, | ||
73 | uint32_t sampling_rate, | ||
74 | void *user_data) | ||
90 | { | 75 | { |
91 | Status *cast = _arg; | 76 | (void) av; |
92 | 77 | (void) friend_number; | |
93 | if (av == cast->calls[call_index].Caller.av) | 78 | (void) pcm; |
94 | cast->calls[call_index].Caller.status = InCall; | 79 | (void) sample_count; |
95 | else | 80 | (void) channels; |
96 | cast->calls[call_index].Callee.status = InCall; | 81 | (void) sampling_rate; |
82 | (void) user_data; | ||
97 | } | 83 | } |
98 | void callback_call_canceled ( void *av, int32_t call_index, void *_arg ) | 84 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) |
99 | { | 85 | { |
86 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { | ||
87 | assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0); | ||
88 | } | ||
100 | } | 89 | } |
101 | void callback_call_rejected ( void *av, int32_t call_index, void *_arg ) | ||
102 | { | ||
103 | Status *cast = _arg; | ||
104 | cast->calls[call_index].Caller.status = Rejected; | ||
105 | } | ||
106 | |||
107 | void callback_requ_timeout ( void *av, int32_t call_index, void *_arg ) | ||
108 | { | ||
109 | ck_assert_msg(0, "No answer!"); | ||
110 | } | ||
111 | |||
112 | void callback_audio (void *agent, int32_t call_idx, const int16_t *PCM, uint16_t size, void *data) | ||
113 | {} | ||
114 | 90 | ||
115 | void callback_video (void *agent, int32_t call_idx, const vpx_image_t *img, void *data) | ||
116 | {} | ||
117 | 91 | ||
118 | void register_callbacks(ToxAv *av, void *data) | 92 | /** |
93 | * Iterate helper | ||
94 | */ | ||
95 | ToxAV* setup_av_instance(Tox* tox, CallControl *CC) | ||
119 | { | 96 | { |
120 | toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); | 97 | TOXAV_ERR_NEW error; |
121 | toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); | 98 | |
122 | toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); | 99 | ToxAV* av = toxav_new(tox, &error); |
123 | toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); | 100 | assert(error == TOXAV_ERR_NEW_OK); |
124 | toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); | 101 | |
125 | toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data); | 102 | toxav_callback_call(av, t_toxav_call_cb, CC); |
126 | toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data); | 103 | toxav_callback_call_state(av, t_toxav_call_state_cb, CC); |
127 | 104 | toxav_callback_receive_video_frame(av, t_toxav_receive_video_frame_cb, CC); | |
128 | 105 | toxav_callback_receive_audio_frame(av, t_toxav_receive_audio_frame_cb, CC); | |
129 | toxav_register_audio_callback(av, callback_audio, NULL); | 106 | |
130 | toxav_register_video_callback(av, callback_video, NULL); | 107 | return av; |
131 | } | 108 | } |
132 | /*************************************************************************************************/ | 109 | void* call_thread(ToxAV* Alice, ToxAV* Bob) |
133 | |||
134 | int call_running[3]; | ||
135 | |||
136 | void *in_thread_call (void *arg) | ||
137 | { | 110 | { |
138 | #define call_print(call, what, args...) printf("[%d] " what "\n", call, ##args) | ||
139 | |||
140 | ACall *this_call = arg; | ||
141 | uint64_t start = 0; | ||
142 | int step = 0; | ||
143 | int call_idx; | ||
144 | |||
145 | const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); | ||
146 | int16_t sample_payload[frame_size]; | ||
147 | randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size); | ||
148 | |||
149 | uint8_t prepared_payload[RTP_PAYLOAD_SIZE]; | ||
150 | |||
151 | register_callbacks(this_call->Caller.av, &status_control); | ||
152 | register_callbacks(this_call->Callee.av, arg); | ||
153 | |||
154 | /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */ | ||
155 | pthread_mutex_lock(&muhmutex); | ||
156 | |||
157 | while (call_running[this_call->idx]) { | ||
158 | |||
159 | pthread_mutex_unlock(&muhmutex); | ||
160 | |||
161 | switch ( step ) { | ||
162 | case 0: /* CALLER */ | ||
163 | toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, &av_DefaultSettings, 10); | ||
164 | call_print(call_idx, "Calling ..."); | ||
165 | step++; | ||
166 | break; | ||
167 | |||
168 | case 1: /* CALLEE */ | ||
169 | pthread_mutex_lock(&muhmutex); | ||
170 | |||
171 | if (this_call->Caller.status == Ringing) { | ||
172 | call_print(call_idx, "Callee answers ..."); | ||
173 | pthread_mutex_unlock(&muhmutex); | ||
174 | toxav_answer(this_call->Callee.av, 0, &av_DefaultSettings); | ||
175 | step++; | ||
176 | start = time(NULL); | ||
177 | pthread_mutex_lock(&muhmutex); | ||
178 | } | ||
179 | |||
180 | pthread_mutex_unlock(&muhmutex); | ||
181 | break; | ||
182 | |||
183 | case 2: /* Rtp transmission */ | ||
184 | pthread_mutex_lock(&muhmutex); | ||
185 | |||
186 | if (this_call->Caller.status == InCall) { /* I think this is okay */ | ||
187 | call_print(call_idx, "Sending rtp ..."); | ||
188 | pthread_mutex_unlock(&muhmutex); | ||
189 | |||
190 | c_sleep(1000); /* We have race condition here */ | ||
191 | toxav_prepare_transmission(this_call->Callee.av, 0, 1); | ||
192 | toxav_prepare_transmission(this_call->Caller.av, call_idx, 1); | ||
193 | |||
194 | int payload_size = toxav_prepare_audio_frame(this_call->Caller.av, call_idx, prepared_payload, RTP_PAYLOAD_SIZE, | ||
195 | sample_payload, frame_size); | ||
196 | |||
197 | if ( payload_size < 0 ) { | ||
198 | ck_assert_msg ( 0, "Failed to encode payload" ); | ||
199 | } | ||
200 | |||
201 | |||
202 | while (time(NULL) - start < 10) { /* 10 seconds */ | ||
203 | /* Both send */ | ||
204 | toxav_send_audio(this_call->Caller.av, call_idx, prepared_payload, payload_size); | ||
205 | |||
206 | toxav_send_audio(this_call->Callee.av, 0, prepared_payload, payload_size); | ||
207 | |||
208 | /* Both receive */ | ||
209 | int16_t storage[RTP_PAYLOAD_SIZE]; | ||
210 | int recved; | ||
211 | |||
212 | c_sleep(20); | ||
213 | } | ||
214 | |||
215 | step++; /* This terminates the loop */ | ||
216 | |||
217 | pthread_mutex_lock(&muhmutex); | ||
218 | toxav_kill_transmission(this_call->Callee.av, 0); | ||
219 | toxav_kill_transmission(this_call->Caller.av, call_idx); | ||
220 | pthread_mutex_unlock(&muhmutex); | ||
221 | |||
222 | /* Call over CALLER hangs up */ | ||
223 | toxav_hangup(this_call->Caller.av, call_idx); | ||
224 | call_print(call_idx, "Hanging up ..."); | ||
225 | |||
226 | pthread_mutex_lock(&muhmutex); | ||
227 | } | ||
228 | |||
229 | pthread_mutex_unlock(&muhmutex); | ||
230 | break; | ||
231 | |||
232 | case 3: /* Wait for Both to have status ended */ | ||
233 | pthread_mutex_lock(&muhmutex); | ||
234 | |||
235 | if (this_call->Caller.status == Ended) { | ||
236 | pthread_mutex_unlock(&muhmutex); | ||
237 | c_sleep(1000); /* race condition */ | ||
238 | pthread_mutex_lock(&muhmutex); | ||
239 | this_call->Callee.status = Ended; | ||
240 | call_running[this_call->idx] = 0; | ||
241 | } | ||
242 | |||
243 | pthread_mutex_unlock(&muhmutex); | ||
244 | |||
245 | break; | ||
246 | |||
247 | } | ||
248 | |||
249 | c_sleep(20); | ||
250 | |||
251 | pthread_mutex_lock(&muhmutex); | ||
252 | } | ||
253 | |||
254 | pthread_mutex_unlock(&muhmutex); | ||
255 | call_print(call_idx, "Call ended successfully!"); | ||
256 | pthread_exit(NULL); | 111 | pthread_exit(NULL); |
257 | } | 112 | } |
258 | 113 | ||
259 | |||
260 | |||
261 | |||
262 | |||
263 | START_TEST(test_AV_three_calls) | 114 | START_TEST(test_AV_three_calls) |
264 | // void test_AV_three_calls() | ||
265 | { | 115 | { |
266 | long long unsigned int cur_time = time(NULL); | 116 | Tox* Alice, *bootstrap, *Bobs[3]; |
267 | Tox *bootstrap_node = tox_new(0, 0, 0, 0); | 117 | ToxAV* AliceAV, *BobsAV[3]; |
268 | Tox *caller = tox_new(0, 0, 0, 0); | 118 | |
269 | Tox *callees[3] = { | 119 | CallControl AliceCC[3], BobsCC[3]; |
270 | tox_new(0, 0, 0, 0), | 120 | |
271 | tox_new(0, 0, 0, 0), | ||
272 | tox_new(0, 0, 0, 0), | ||
273 | }; | ||
274 | |||
275 | |||
276 | ck_assert_msg(bootstrap_node != NULL, "Failed to create bootstrap node"); | ||
277 | |||
278 | int i = 0; | 121 | int i = 0; |
279 | 122 | { | |
280 | for (; i < 3; i ++) { | 123 | TOX_ERR_NEW error; |
281 | ck_assert_msg(callees[i] != NULL, "Failed to create 3 tox instances"); | 124 | |
282 | } | 125 | bootstrap = tox_new(NULL, NULL, 0, &error); |
283 | 126 | assert(error == TOX_ERR_NEW_OK); | |
284 | for ( i = 0; i < 3; i ++ ) { | 127 | |
285 | uint32_t to_compare = 974536; | 128 | Alice = tox_new(NULL, NULL, 0, &error); |
286 | tox_callback_friend_request(callees[i], accept_friend_request, &to_compare); | 129 | assert(error == TOX_ERR_NEW_OK); |
287 | uint8_t address[TOX_ADDRESS_SIZE]; | 130 | |
288 | tox_self_get_address(callees[i], address); | 131 | for (; i < 3; i ++) { |
289 | 132 | BobsAV[i] = tox_new(NULL, NULL, 0, &error); | |
290 | uint32_t test = tox_friend_add(caller, address, (uint8_t *)"gentoo", 7, 0); | 133 | assert(error == TOX_ERR_NEW_OK); |
291 | ck_assert_msg( test == i, "Failed to add friend error code: %i", test); | 134 | } |
292 | } | 135 | } |
293 | 136 | ||
137 | printf("Created 5 instances of Tox\n"); | ||
138 | printf("Preparing network...\n"); | ||
139 | long long unsigned int cur_time = time(NULL); | ||
140 | |||
141 | uint32_t to_compare = 974536; | ||
142 | uint8_t address[TOX_ADDRESS_SIZE]; | ||
143 | |||
144 | tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare); | ||
145 | tox_self_get_address(Alice, address); | ||
146 | |||
147 | |||
148 | assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); | ||
149 | assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); | ||
150 | assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0); | ||
151 | |||
294 | uint8_t off = 1; | 152 | uint8_t off = 1; |
295 | 153 | ||
296 | while (1) { | 154 | while (1) { |
297 | tox_iterate(bootstrap_node); | 155 | tox_iterate(bootstrap); |
298 | tox_iterate(caller); | 156 | tox_iterate(Alice); |
299 | 157 | tox_iterate(Bobs[0]); | |
300 | for (i = 0; i < 3; i ++) { | 158 | tox_iterate(Bobs[1]); |
301 | tox_iterate(callees[i]); | 159 | tox_iterate(Bobs[2]); |
302 | } | 160 | |
303 | 161 | if (tox_self_get_connection_status(bootstrap) && | |
304 | 162 | tox_self_get_connection_status(Alice) && | |
305 | if (tox_self_get_connection_status(bootstrap_node) && | 163 | tox_self_get_connection_status(Bobs[0]) && |
306 | tox_self_get_connection_status(caller) && | 164 | tox_self_get_connection_status(Bobs[1]) && |
307 | tox_self_get_connection_status(callees[0]) && | 165 | tox_self_get_connection_status(Bobs[2]) && off) { |
308 | tox_self_get_connection_status(callees[1]) && | ||
309 | tox_self_get_connection_status(callees[2]) && off) { | ||
310 | printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); | 166 | printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); |
311 | off = 0; | 167 | off = 0; |
312 | } | 168 | } |
313 | 169 | ||
314 | 170 | if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP && | |
315 | if (tox_friend_get_connection_status(caller, 0, 0) && | 171 | tox_friend_get_connection_status(Alice, 1, NULL) == TOX_CONNECTION_UDP && |
316 | tox_friend_get_connection_status(caller, 1, 0) && | 172 | tox_friend_get_connection_status(Alice, 2, NULL) == TOX_CONNECTION_UDP && |
317 | tox_friend_get_connection_status(caller, 2, 0) ) | 173 | tox_friend_get_connection_status(Bobs[0], 0, NULL) == TOX_CONNECTION_UDP && |
174 | tox_friend_get_connection_status(Bobs[1], 0, NULL) == TOX_CONNECTION_UDP && | ||
175 | tox_friend_get_connection_status(Bobs[2], 0, NULL) == TOX_CONNECTION_UDP) | ||
318 | break; | 176 | break; |
319 | 177 | ||
320 | c_sleep(20); | 178 | c_sleep(20); |
321 | } | 179 | } |
322 | 180 | ||
323 | printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); | 181 | AliceAV = setup_av_instance(Alice, &AliceCC); |
324 | 182 | BobsAV[0] = setup_av_instance(Bobs[0], &BobsCC[0]); | |
325 | ToxAv *uniqcallerav = toxav_new(caller, 3); | 183 | BobsAV[1] = setup_av_instance(Bobs[1], &BobsCC[1]); |
326 | 184 | BobsAV[2] = setup_av_instance(Bobs[2], &BobsCC[2]); | |
185 | |||
186 | printf("Created 4 instances of ToxAV\n"); | ||
187 | printf("All set after %llu seconds!\n", time(NULL) - cur_time); | ||
188 | |||
189 | |||
190 | |||
191 | tox_kill(bootstrap); | ||
192 | tox_kill(Alice); | ||
193 | toxav_kill(AliceAV); | ||
194 | |||
327 | for (i = 0; i < 3; i ++) { | 195 | for (i = 0; i < 3; i ++) { |
328 | status_control.calls[i].idx = i; | 196 | tox_kill(Bobs[i]); |
329 | 197 | toxav_kill(BobsAV[i]); | |
330 | status_control.calls[i].Caller.av = uniqcallerav; | ||
331 | status_control.calls[i].Caller.id = 0; | ||
332 | status_control.calls[i].Caller.status = none; | ||
333 | |||
334 | status_control.calls[i].Callee.av = toxav_new(callees[i], 1); | ||
335 | status_control.calls[i].Callee.id = i; | ||
336 | status_control.calls[i].Callee.status = none; | ||
337 | } | 198 | } |
338 | 199 | ||
339 | pthread_mutex_init(&muhmutex, NULL); | 200 | printf("\nTest successful!\n"); |
340 | |||
341 | for ( i = 0; i < 3; i++ ) { | ||
342 | call_running[i] = 1; | ||
343 | pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]); | ||
344 | } | ||
345 | |||
346 | /* Now start 3 calls and they'll run for 10 s */ | ||
347 | |||
348 | for ( i = 0; i < 3; i++ ) | ||
349 | pthread_detach(status_control.calls[i].tid); | ||
350 | |||
351 | while (call_running[0] || call_running[1] || call_running[2]) { | ||
352 | pthread_mutex_lock(&muhmutex); | ||
353 | |||
354 | tox_iterate(bootstrap_node); | ||
355 | tox_iterate(caller); | ||
356 | tox_iterate(callees[0]); | ||
357 | tox_iterate(callees[1]); | ||
358 | tox_iterate(callees[2]); | ||
359 | |||
360 | for ( i = 0; i < 3; i++ ) | ||
361 | toxav_do(status_control.calls[0].Caller.av); | ||
362 | |||
363 | toxav_do(status_control.calls[0].Callee.av); | ||
364 | toxav_do(status_control.calls[1].Callee.av); | ||
365 | toxav_do(status_control.calls[2].Callee.av); | ||
366 | |||
367 | pthread_mutex_unlock(&muhmutex); | ||
368 | c_sleep(20); | ||
369 | } | ||
370 | |||
371 | toxav_kill(status_control.calls[0].Caller.av); | ||
372 | toxav_kill(status_control.calls[0].Callee.av); | ||
373 | toxav_kill(status_control.calls[1].Callee.av); | ||
374 | toxav_kill(status_control.calls[2].Callee.av); | ||
375 | |||
376 | tox_kill(bootstrap_node); | ||
377 | tox_kill(caller); | ||
378 | |||
379 | for ( i = 0; i < 3; i ++) | ||
380 | tox_kill(callees[i]); | ||
381 | |||
382 | } | 201 | } |
383 | END_TEST | 202 | END_TEST |
384 | 203 | ||
@@ -410,8 +229,4 @@ int main(int argc, char *argv[]) | |||
410 | srunner_free(test_runner); | 229 | srunner_free(test_runner); |
411 | 230 | ||
412 | return number_failed; | 231 | return number_failed; |
413 | |||
414 | // test_AV_three_calls(); | ||
415 | |||
416 | // return 0; | ||
417 | } | 232 | } |
diff --git a/toxav/av_test.c b/testing/av_test.c index 86deebdf..7298ed23 100644 --- a/toxav/av_test.c +++ b/testing/av_test.c | |||
@@ -70,13 +70,6 @@ | |||
70 | #define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U) + 128) >> 8) | 70 | #define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U) + 128) >> 8) |
71 | 71 | ||
72 | 72 | ||
73 | /* Enable/disable tests */ | ||
74 | #define TEST_REGULAR_AV 0 | ||
75 | #define TEST_REGULAR_A 0 | ||
76 | #define TEST_REGULAR_V 0 | ||
77 | #define TEST_REJECT 0 | ||
78 | #define TEST_CANCEL 0 | ||
79 | #define TEST_MUTE_UNMUTE 0 | ||
80 | #define TEST_TRANSFER_A 0 | 73 | #define TEST_TRANSFER_A 0 |
81 | #define TEST_TRANSFER_V 1 | 74 | #define TEST_TRANSFER_V 1 |
82 | 75 | ||
@@ -126,7 +119,7 @@ void* pa_write_thread (void* d) | |||
126 | } | 119 | } |
127 | 120 | ||
128 | 121 | ||
129 | /** | 122 | /** |
130 | * Callbacks | 123 | * Callbacks |
131 | */ | 124 | */ |
132 | void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) | 125 | void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) |
@@ -187,21 +180,21 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |||
187 | free(rb_write(cc->arb, f)); | 180 | free(rb_write(cc->arb, f)); |
188 | pthread_mutex_unlock(cc->arb_mutex); | 181 | pthread_mutex_unlock(cc->arb_mutex); |
189 | } | 182 | } |
190 | void t_toxav_audio_bitrate_control_cb(ToxAV *av, uint32_t friend_number, | 183 | void t_toxav_audio_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, |
191 | bool good, uint32_t bit_rate, void *user_data) | 184 | bool stable, uint32_t bit_rate, void *user_data) |
192 | { | 185 | { |
193 | if (good) | 186 | if (stable) |
194 | printf ("Set new audio bitrate to: %d\n", bit_rate); | 187 | printf ("Set new audio bit rate to: %d\n", bit_rate); |
195 | else | 188 | else |
196 | printf ("The network is overly saturated with audio bitrate at: %d\n", bit_rate); | 189 | printf ("The network is overly saturated with audio bit rate at: %d\n", bit_rate); |
197 | } | 190 | } |
198 | void t_toxav_video_bitrate_control_cb(ToxAV *av, uint32_t friend_number, | 191 | void t_toxav_video_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, |
199 | bool good, uint32_t bit_rate, void *user_data) | 192 | bool stable, uint32_t bit_rate, void *user_data) |
200 | { | 193 | { |
201 | if (good) | 194 | if (stable) |
202 | printf ("Set new video bitrate to: %d", bit_rate); | 195 | printf ("Set new video bit rate to: %d", bit_rate); |
203 | else | 196 | else |
204 | printf ("The network is overly saturated with video bitrate at: %d", bit_rate); | 197 | printf ("The network is overly saturated with video bit rate at: %d", bit_rate); |
205 | } | 198 | } |
206 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | 199 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) |
207 | { | 200 | { |
@@ -287,16 +280,16 @@ void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxA | |||
287 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); | 280 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); |
288 | toxav_callback_receive_video_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC); | 281 | toxav_callback_receive_video_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC); |
289 | toxav_callback_receive_audio_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC); | 282 | toxav_callback_receive_audio_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC); |
290 | toxav_callback_audio_bitrate_control(*AliceAV, t_toxav_audio_bitrate_control_cb, AliceCC); | 283 | toxav_callback_audio_bit_rate_status(*AliceAV, t_toxav_audio_bit_rate_status_cb, AliceCC); |
291 | toxav_callback_video_bitrate_control(*AliceAV, t_toxav_video_bitrate_control_cb, AliceCC); | 284 | toxav_callback_video_bit_rate_status(*AliceAV, t_toxav_video_bit_rate_status_cb, AliceCC); |
292 | 285 | ||
293 | /* Bob */ | 286 | /* Bob */ |
294 | toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC); | 287 | toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC); |
295 | toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC); | 288 | toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC); |
296 | toxav_callback_receive_video_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC); | 289 | toxav_callback_receive_video_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC); |
297 | toxav_callback_receive_audio_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC); | 290 | toxav_callback_receive_audio_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC); |
298 | toxav_callback_audio_bitrate_control(*BobAV, t_toxav_audio_bitrate_control_cb, BobCC); | 291 | toxav_callback_audio_bit_rate_status(*BobAV, t_toxav_audio_bit_rate_status_cb, BobCC); |
299 | toxav_callback_video_bitrate_control(*BobAV, t_toxav_video_bitrate_control_cb, BobCC); | 292 | toxav_callback_video_bit_rate_status(*BobAV, t_toxav_video_bit_rate_status_cb, BobCC); |
300 | 293 | ||
301 | 294 | ||
302 | printf("Created 2 instances of ToxAV\n"); | 295 | printf("Created 2 instances of ToxAV\n"); |
@@ -513,232 +506,7 @@ int main (int argc, char** argv) | |||
513 | 506 | ||
514 | initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC); | 507 | initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC); |
515 | 508 | ||
516 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ | 509 | if (TEST_TRANSFER_A) { |
517 | do { \ | ||
518 | memset(&AliceCC, 0, sizeof(CallControl)); \ | ||
519 | memset(&BobCC, 0, sizeof(CallControl)); \ | ||
520 | \ | ||
521 | TOXAV_ERR_CALL rc; \ | ||
522 | toxav_call(AliceAV, 0, A_BR, V_BR, &rc); \ | ||
523 | \ | ||
524 | if (rc != TOXAV_ERR_CALL_OK) { \ | ||
525 | printf("toxav_call failed: %d\n", rc); \ | ||
526 | exit(1); \ | ||
527 | } \ | ||
528 | \ | ||
529 | \ | ||
530 | long long unsigned int start_time = time(NULL); \ | ||
531 | \ | ||
532 | \ | ||
533 | while (BobCC.state != TOXAV_CALL_STATE_END) { \ | ||
534 | \ | ||
535 | if (BobCC.incoming) { \ | ||
536 | TOXAV_ERR_ANSWER rc; \ | ||
537 | toxav_answer(BobAV, 0, A_BR, V_BR, &rc); \ | ||
538 | \ | ||
539 | if (rc != TOXAV_ERR_ANSWER_OK) { \ | ||
540 | printf("toxav_answer failed: %d\n", rc); \ | ||
541 | exit(1); \ | ||
542 | } \ | ||
543 | BobCC.incoming = false; \ | ||
544 | } else { \ | ||
545 | /* TODO rtp */ \ | ||
546 | \ | ||
547 | if (time(NULL) - start_time == 5) { \ | ||
548 | \ | ||
549 | TOXAV_ERR_CALL_CONTROL rc; \ | ||
550 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); \ | ||
551 | \ | ||
552 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { \ | ||
553 | printf("toxav_call_control failed: %d\n", rc); \ | ||
554 | exit(1); \ | ||
555 | } \ | ||
556 | } \ | ||
557 | } \ | ||
558 | \ | ||
559 | iterate_tox(bootstrap, AliceAV, BobAV); \ | ||
560 | } \ | ||
561 | printf("Success!\n");\ | ||
562 | } while(0) | ||
563 | |||
564 | if (TEST_REGULAR_AV) { | ||
565 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
566 | REGULAR_CALL_FLOW(48, 4000); | ||
567 | } | ||
568 | |||
569 | if (TEST_REGULAR_A) { | ||
570 | printf("\nTrying regular call (Audio only)...\n"); | ||
571 | REGULAR_CALL_FLOW(48, 0); | ||
572 | } | ||
573 | |||
574 | if (TEST_REGULAR_V) { | ||
575 | printf("\nTrying regular call (Video only)...\n"); | ||
576 | REGULAR_CALL_FLOW(0, 4000); | ||
577 | } | ||
578 | |||
579 | #undef REGULAR_CALL_FLOW | ||
580 | |||
581 | if (TEST_REJECT) { /* Alice calls; Bob rejects */ | ||
582 | printf("\nTrying reject flow...\n"); | ||
583 | |||
584 | memset(&AliceCC, 0, sizeof(CallControl)); | ||
585 | memset(&BobCC, 0, sizeof(CallControl)); | ||
586 | |||
587 | { | ||
588 | TOXAV_ERR_CALL rc; | ||
589 | toxav_call(AliceAV, 0, 48, 0, &rc); | ||
590 | |||
591 | if (rc != TOXAV_ERR_CALL_OK) { | ||
592 | printf("toxav_call failed: %d\n", rc); | ||
593 | exit(1); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | while (!BobCC.incoming) | ||
598 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
599 | |||
600 | /* Reject */ | ||
601 | { | ||
602 | TOXAV_ERR_CALL_CONTROL rc; | ||
603 | toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); | ||
604 | |||
605 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
606 | printf("toxav_call_control failed: %d\n", rc); | ||
607 | exit(1); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | while (AliceCC.state != TOXAV_CALL_STATE_END) | ||
612 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
613 | |||
614 | printf("Success!\n"); | ||
615 | } | ||
616 | |||
617 | if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ | ||
618 | printf("\nTrying cancel (while ringing) flow...\n"); | ||
619 | |||
620 | memset(&AliceCC, 0, sizeof(CallControl)); | ||
621 | memset(&BobCC, 0, sizeof(CallControl)); | ||
622 | |||
623 | { | ||
624 | TOXAV_ERR_CALL rc; | ||
625 | toxav_call(AliceAV, 0, 48, 0, &rc); | ||
626 | |||
627 | if (rc != TOXAV_ERR_CALL_OK) { | ||
628 | printf("toxav_call failed: %d\n", rc); | ||
629 | exit(1); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | while (!BobCC.incoming) | ||
634 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
635 | |||
636 | /* Cancel */ | ||
637 | { | ||
638 | TOXAV_ERR_CALL_CONTROL rc; | ||
639 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); | ||
640 | |||
641 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
642 | printf("toxav_call_control failed: %d\n", rc); | ||
643 | exit(1); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* Alice will not receive end state */ | ||
648 | while (BobCC.state != TOXAV_CALL_STATE_END) | ||
649 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
650 | |||
651 | printf("Success!\n"); | ||
652 | } | ||
653 | |||
654 | if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ | ||
655 | printf("\nTrying mute functionality...\n"); | ||
656 | |||
657 | memset(&AliceCC, 0, sizeof(CallControl)); | ||
658 | memset(&BobCC, 0, sizeof(CallControl)); | ||
659 | |||
660 | /* Assume sending audio and video */ | ||
661 | { | ||
662 | TOXAV_ERR_CALL rc; | ||
663 | toxav_call(AliceAV, 0, 48, 1000, &rc); | ||
664 | |||
665 | if (rc != TOXAV_ERR_CALL_OK) { | ||
666 | printf("toxav_call failed: %d\n", rc); | ||
667 | exit(1); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | while (!BobCC.incoming) | ||
672 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
673 | |||
674 | /* At first try all stuff while in invalid state */ | ||
675 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); | ||
676 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); | ||
677 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); | ||
678 | assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); | ||
679 | |||
680 | { | ||
681 | TOXAV_ERR_ANSWER rc; | ||
682 | toxav_answer(BobAV, 0, 48, 4000, &rc); | ||
683 | |||
684 | if (rc != TOXAV_ERR_ANSWER_OK) { | ||
685 | printf("toxav_answer failed: %d\n", rc); | ||
686 | exit(1); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
691 | |||
692 | /* Pause and Resume */ | ||
693 | printf("Pause and Resume\n"); | ||
694 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL)); | ||
695 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
696 | assert(BobCC.state == TOXAV_CALL_STATE_PAUSED); | ||
697 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL)); | ||
698 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
699 | assert(BobCC.state & (TOXAV_CALL_STATE_SENDING_A | TOXAV_CALL_STATE_SENDING_V)); | ||
700 | |||
701 | /* Mute/Unmute single */ | ||
702 | printf("Mute/Unmute single\n"); | ||
703 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); | ||
704 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
705 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); | ||
706 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); | ||
707 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
708 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); | ||
709 | |||
710 | /* Mute/Unmute both */ | ||
711 | printf("Mute/Unmute both\n"); | ||
712 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); | ||
713 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
714 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A); | ||
715 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); | ||
716 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
717 | assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_V); | ||
718 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL)); | ||
719 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
720 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A); | ||
721 | assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL)); | ||
722 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
723 | assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_V); | ||
724 | |||
725 | { | ||
726 | TOXAV_ERR_CALL_CONTROL rc; | ||
727 | toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); | ||
728 | |||
729 | if (rc != TOXAV_ERR_CALL_CONTROL_OK) { | ||
730 | printf("toxav_call_control failed: %d\n", rc); | ||
731 | exit(1); | ||
732 | } | ||
733 | } | ||
734 | |||
735 | iterate_tox(bootstrap, AliceAV, BobAV); | ||
736 | assert(BobCC.state == TOXAV_CALL_STATE_END); | ||
737 | |||
738 | printf("Success!\n"); | ||
739 | } | ||
740 | |||
741 | if (TEST_TRANSFER_A) { /* Audio encoding/decoding and transfer */ | ||
742 | SNDFILE* af_handle; | 510 | SNDFILE* af_handle; |
743 | SF_INFO af_info; | 511 | SF_INFO af_info; |
744 | 512 | ||
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index 0434a3c6..3907951e 100644 --- a/toxav/Makefile.inc +++ b/toxav/Makefile.inc | |||
@@ -37,25 +37,4 @@ libtoxav_la_LIBADD = libtoxcore.la \ | |||
37 | $(PTHREAD_LIBS) \ | 37 | $(PTHREAD_LIBS) \ |
38 | $(AV_LIBS) | 38 | $(AV_LIBS) |
39 | 39 | ||
40 | |||
41 | |||
42 | #noinst_PROGRAMS += av_test | ||
43 | |||
44 | #av_test_SOURCES = ../toxav/av_test.c | ||
45 | |||
46 | #av_test_CFLAGS = $(LIBSODIUM_CFLAGS) \ | ||
47 | $(NACL_CFLAGS) | ||
48 | |||
49 | #av_test_LDADD = $(LIBSODIUM_LDFLAGS) \ | ||
50 | $(NACL_LDFLAGS) \ | ||
51 | libtoxav.la \ | ||
52 | libtoxcore.la \ | ||
53 | $(LIBSODIUM_LIBS) \ | ||
54 | $(NACL_OBJECTS) \ | ||
55 | -lopenal \ | ||
56 | -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab \ | ||
57 | -lsndfile \ | ||
58 | $(NACL_LIBS) | ||
59 | |||
60 | |||
61 | endif \ No newline at end of file | 40 | endif \ No newline at end of file |
diff --git a/toxav/audio.c b/toxav/audio.c index 2f068c85..c592a7da 100644 --- a/toxav/audio.c +++ b/toxav/audio.c | |||
@@ -31,14 +31,14 @@ static void jbuf_clear(struct JitterBuffer *q); | |||
31 | static void jbuf_free(struct JitterBuffer *q); | 31 | static void jbuf_free(struct JitterBuffer *q); |
32 | static int jbuf_write(struct JitterBuffer *q, RTPMessage *m); | 32 | static int jbuf_write(struct JitterBuffer *q, RTPMessage *m); |
33 | static RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success); | 33 | static RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success); |
34 | 34 | OpusEncoder* create_audio_encoder (int32_t bit_rate, int32_t sampling_rate, int32_t channel_count); | |
35 | OpusEncoder* create_audio_encoder (int32_t bitrate, int32_t sampling_rate, int32_t channel_count); | ||
36 | bool reconfigure_audio_encoder(OpusEncoder** e, int32_t new_br, int32_t new_sr, uint8_t new_ch, | 35 | bool reconfigure_audio_encoder(OpusEncoder** e, int32_t new_br, int32_t new_sr, uint8_t new_ch, |
37 | int32_t *old_br, int32_t *old_sr, int32_t *old_ch); | 36 | int32_t *old_br, int32_t *old_sr, int32_t *old_ch); |
38 | bool reconfigure_audio_decoder(ACSession* ac, int32_t sampling_rate, int8_t channels); | 37 | bool reconfigure_audio_decoder(ACSession* ac, int32_t sampling_rate, int8_t channels); |
39 | 38 | ||
40 | 39 | ||
41 | ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *cb, void *cb_data) | 40 | |
41 | ACSession* ac_new(ToxAV* av, uint32_t friend_number, toxav_receive_audio_frame_cb *cb, void *cb_data) | ||
42 | { | 42 | { |
43 | ACSession *ac = calloc(sizeof(ACSession), 1); | 43 | ACSession *ac = calloc(sizeof(ACSession), 1); |
44 | 44 | ||
@@ -78,11 +78,11 @@ ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *c | |||
78 | goto DECODER_CLEANUP; | 78 | goto DECODER_CLEANUP; |
79 | } | 79 | } |
80 | 80 | ||
81 | ac->last_encoding_bitrate = 48000; | 81 | ac->last_encoding_bit_rate = 48000; |
82 | ac->last_encoding_sampling_rate = 48000; | 82 | ac->last_encoding_sampling_rate = 48000; |
83 | ac->last_encoding_channel_count = 2; | 83 | ac->last_encoding_channel_count = 2; |
84 | 84 | ||
85 | ac->last_test_encoding_bitrate = 48000; | 85 | ac->last_test_encoding_bit_rate = 48000; |
86 | ac->last_test_encoding_sampling_rate = 48000; | 86 | ac->last_test_encoding_sampling_rate = 48000; |
87 | ac->last_test_encoding_channel_count = 2; | 87 | ac->last_test_encoding_channel_count = 2; |
88 | 88 | ||
@@ -97,7 +97,7 @@ ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *c | |||
97 | ac->last_packet_channel_count = 1; | 97 | ac->last_packet_channel_count = 1; |
98 | 98 | ||
99 | ac->av = av; | 99 | ac->av = av; |
100 | ac->friend_id = friend_id; | 100 | ac->friend_number = friend_number; |
101 | ac->acb.first = cb; | 101 | ac->acb.first = cb; |
102 | ac->acb.second = cb_data; | 102 | ac->acb.second = cb_data; |
103 | 103 | ||
@@ -181,7 +181,7 @@ void ac_do(ACSession* ac) | |||
181 | } else if (ac->acb.first) { | 181 | } else if (ac->acb.first) { |
182 | ac->last_packet_frame_duration = (rc * 1000) / ac->last_packet_sampling_rate; | 182 | ac->last_packet_frame_duration = (rc * 1000) / ac->last_packet_sampling_rate; |
183 | 183 | ||
184 | ac->acb.first(ac->av, ac->friend_id, tmp, rc * ac->last_packet_channel_count, | 184 | ac->acb.first(ac->av, ac->friend_number, tmp, rc * ac->last_packet_channel_count, |
185 | ac->last_packet_channel_count, ac->last_packet_sampling_rate, ac->acb.second); | 185 | ac->last_packet_channel_count, ac->last_packet_sampling_rate, ac->acb.second); |
186 | } | 186 | } |
187 | 187 | ||
@@ -220,28 +220,27 @@ int ac_queue_message(void* acp, struct RTPMessage_s *msg) | |||
220 | 220 | ||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels) | 223 | int ac_reconfigure_encoder(ACSession* ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels) |
224 | { | 224 | { |
225 | if (!ac || !reconfigure_audio_encoder(&ac->encoder, bitrate, sampling_rate, channels, | 225 | if (!ac || !reconfigure_audio_encoder(&ac->encoder, bit_rate, sampling_rate, channels, |
226 | &ac->last_encoding_bitrate, &ac->last_encoding_sampling_rate, &ac->last_encoding_channel_count)) | 226 | &ac->last_encoding_bit_rate, &ac->last_encoding_sampling_rate, &ac->last_encoding_channel_count)) |
227 | return -1; | 227 | return -1; |
228 | 228 | ||
229 | LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels); | 229 | LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bit_rate, sampling_rate, channels); |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | int ac_reconfigure_test_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels) | 232 | int ac_reconfigure_test_encoder(ACSession* ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels) |
233 | { | 233 | { |
234 | if (!ac || !reconfigure_audio_encoder(&ac->test_encoder, bitrate, sampling_rate, channels, | 234 | if (!ac || !reconfigure_audio_encoder(&ac->test_encoder, bit_rate, sampling_rate, channels, |
235 | &ac->last_encoding_bitrate, &ac->last_encoding_sampling_rate, &ac->last_encoding_channel_count)) | 235 | &ac->last_encoding_bit_rate, &ac->last_encoding_sampling_rate, &ac->last_encoding_channel_count)) |
236 | return -1; | 236 | return -1; |
237 | 237 | ||
238 | LOGGER_DEBUG ("Reconfigured test audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels); | 238 | LOGGER_DEBUG ("Reconfigured test audio encoder br: %d sr: %d cc:%d", bit_rate, sampling_rate, channels); |
239 | return 0; | 239 | return 0; |
240 | } | 240 | } |
241 | 241 | ||
242 | 242 | ||
243 | 243 | ||
244 | /* JITTER BUFFER WORK */ | ||
245 | struct JitterBuffer { | 244 | struct JitterBuffer { |
246 | RTPMessage **queue; | 245 | RTPMessage **queue; |
247 | uint32_t size; | 246 | uint32_t size; |
@@ -340,7 +339,7 @@ static RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success) | |||
340 | *success = 0; | 339 | *success = 0; |
341 | return NULL; | 340 | return NULL; |
342 | } | 341 | } |
343 | OpusEncoder* create_audio_encoder (int32_t bitrate, int32_t sampling_rate, int32_t channel_count) | 342 | OpusEncoder* create_audio_encoder (int32_t bit_rate, int32_t sampling_rate, int32_t channel_count) |
344 | { | 343 | { |
345 | int status = OPUS_OK; | 344 | int status = OPUS_OK; |
346 | OpusEncoder* rc = opus_encoder_create(sampling_rate, channel_count, OPUS_APPLICATION_AUDIO, &status); | 345 | OpusEncoder* rc = opus_encoder_create(sampling_rate, channel_count, OPUS_APPLICATION_AUDIO, &status); |
@@ -350,7 +349,7 @@ OpusEncoder* create_audio_encoder (int32_t bitrate, int32_t sampling_rate, int32 | |||
350 | return NULL; | 349 | return NULL; |
351 | } | 350 | } |
352 | 351 | ||
353 | status = opus_encoder_ctl(rc, OPUS_SET_BITRATE(bitrate)); | 352 | status = opus_encoder_ctl(rc, OPUS_SET_BITRATE(bit_rate)); |
354 | 353 | ||
355 | if ( status != OPUS_OK ) { | 354 | if ( status != OPUS_OK ) { |
356 | LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(status)); | 355 | LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(status)); |
diff --git a/toxav/audio.h b/toxav/audio.h index a36396f1..c003bac0 100644 --- a/toxav/audio.h +++ b/toxav/audio.h | |||
@@ -31,18 +31,21 @@ | |||
31 | 31 | ||
32 | struct RTPMessage_s; | 32 | struct RTPMessage_s; |
33 | 33 | ||
34 | /* | ||
35 | * Base Audio Codec session type. | ||
36 | */ | ||
34 | typedef struct ACSession_s { | 37 | typedef struct ACSession_s { |
35 | /* encoding */ | 38 | /* encoding */ |
36 | OpusEncoder *encoder; | 39 | OpusEncoder *encoder; |
37 | int32_t last_encoding_sampling_rate; | 40 | int32_t last_encoding_sampling_rate; |
38 | int32_t last_encoding_channel_count; | 41 | int32_t last_encoding_channel_count; |
39 | int32_t last_encoding_bitrate; | 42 | int32_t last_encoding_bit_rate; |
40 | 43 | ||
41 | /* Testing encoder for dynamic bitrate streaming */ | 44 | /* Testing encoder for dynamic bit rate streaming */ |
42 | OpusEncoder *test_encoder; | 45 | OpusEncoder *test_encoder; |
43 | int32_t last_test_encoding_sampling_rate; | 46 | int32_t last_test_encoding_sampling_rate; |
44 | int32_t last_test_encoding_channel_count; | 47 | int32_t last_test_encoding_channel_count; |
45 | int32_t last_test_encoding_bitrate; | 48 | int32_t last_test_encoding_bit_rate; |
46 | 49 | ||
47 | /* decoding */ | 50 | /* decoding */ |
48 | OpusDecoder *decoder; | 51 | OpusDecoder *decoder; |
@@ -57,14 +60,30 @@ typedef struct ACSession_s { | |||
57 | pthread_mutex_t queue_mutex[1]; | 60 | pthread_mutex_t queue_mutex[1]; |
58 | 61 | ||
59 | ToxAV* av; | 62 | ToxAV* av; |
60 | uint32_t friend_id; | 63 | uint32_t friend_number; |
61 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ | 64 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ |
62 | } ACSession; | 65 | } ACSession; |
63 | 66 | ||
64 | ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *cb, void *cb_data); | 67 | /* |
68 | * Create new Audio Codec session. | ||
69 | */ | ||
70 | ACSession* ac_new(ToxAV* av, uint32_t friend_number, toxav_receive_audio_frame_cb *cb, void *cb_data); | ||
71 | /* | ||
72 | * Kill the Audio Codec session. | ||
73 | */ | ||
65 | void ac_kill(ACSession* ac); | 74 | void ac_kill(ACSession* ac); |
75 | /* | ||
76 | * Do periodic work. Work is consisted out of decoding only. | ||
77 | */ | ||
66 | void ac_do(ACSession* ac); | 78 | void ac_do(ACSession* ac); |
79 | /* | ||
80 | * Queue new rtp message. | ||
81 | */ | ||
67 | int ac_queue_message(void *acp, struct RTPMessage_s *msg); | 82 | int ac_queue_message(void *acp, struct RTPMessage_s *msg); |
68 | int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels); | 83 | /* |
69 | int ac_reconfigure_test_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels); | 84 | * Set new values to the encoders. |
85 | */ | ||
86 | int ac_reconfigure_encoder(ACSession* ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels); | ||
87 | int ac_reconfigure_test_encoder(ACSession* ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels); | ||
88 | |||
70 | #endif /* AUDIO_H */ \ No newline at end of file | 89 | #endif /* AUDIO_H */ \ No newline at end of file |
diff --git a/toxav/msi.c b/toxav/msi.c index 0bd04c56..f8bc8451 100644 --- a/toxav/msi.c +++ b/toxav/msi.c | |||
@@ -75,37 +75,37 @@ typedef struct { | |||
75 | MSIHeaderRequest request; | 75 | MSIHeaderRequest request; |
76 | MSIHeaderError error; | 76 | MSIHeaderError error; |
77 | MSIHeaderCapabilities capabilities; | 77 | MSIHeaderCapabilities capabilities; |
78 | MSIHeaderVFPSZ vfpsz; /* Video frame piece size. NOTE: Value must be in network b-order */ | 78 | MSIHeaderVFPSZ vfpsz; /* Video frame piece size. NOTE: Value must be in network b-order TODO: get rid of this eventually */ |
79 | } MSIMessage; | 79 | } MSIMessage; |
80 | 80 | ||
81 | 81 | ||
82 | void msg_init (MSIMessage *dest, MSIRequest request); | 82 | void msg_init (MSIMessage *dest, MSIRequest request); |
83 | int msg_parse_in ( MSIMessage *dest, const uint8_t *data, uint16_t length ); | 83 | int msg_parse_in ( MSIMessage *dest, const uint8_t *data, uint16_t length ); |
84 | uint8_t *msg_parse_header_out ( MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length ); | 84 | uint8_t *msg_parse_header_out ( MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length ); |
85 | int send_message ( Messenger* m, uint32_t friend_id, const MSIMessage *msg ); | 85 | int send_message ( Messenger* m, uint32_t friend_number, const MSIMessage *msg ); |
86 | int send_error ( Messenger* m, uint32_t friend_id, MSIError error ); | 86 | int send_error ( Messenger* m, uint32_t friend_number, MSIError error ); |
87 | static int invoke_callback(MSICall* call, MSICallbackID cb); | 87 | static int invoke_callback(MSICall* call, MSICallbackID cb); |
88 | static MSICall *get_call ( MSISession *session, uint32_t friend_id ); | 88 | static MSICall *get_call ( MSISession *session, uint32_t friend_number ); |
89 | MSICall *new_call ( MSISession *session, uint32_t friend_id ); | 89 | MSICall *new_call ( MSISession *session, uint32_t friend_number ); |
90 | void kill_call ( MSICall *call ); | 90 | void kill_call ( MSICall *call ); |
91 | void on_peer_status(Messenger *m, uint32_t friend_id, uint8_t status, void *data); | 91 | void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data); |
92 | void handle_push ( MSICall *call, const MSIMessage *msg ); | 92 | void handle_push ( MSICall *call, const MSIMessage *msg ); |
93 | void handle_pop ( MSICall *call, const MSIMessage *msg ); | 93 | void handle_pop ( MSICall *call, const MSIMessage *msg ); |
94 | void handle_msi_packet ( Messenger *m, uint32_t friend_id, const uint8_t *data, uint16_t length, void *object ); | 94 | void handle_msi_packet ( Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object ); |
95 | 95 | ||
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Public functions | 98 | * Public functions |
99 | */ | 99 | */ |
100 | void msi_register_callback ( MSISession *session, MSICallbackType callback, MSICallbackID id) | 100 | void msi_register_callback ( MSISession* session, msi_action_cb* callback, MSICallbackID id) |
101 | { | 101 | { |
102 | pthread_mutex_lock(session->mutex); | 102 | pthread_mutex_lock(session->mutex); |
103 | session->callbacks[id] = callback; | 103 | session->callbacks[id] = callback; |
104 | pthread_mutex_unlock(session->mutex); | 104 | pthread_mutex_unlock(session->mutex); |
105 | } | 105 | } |
106 | MSISession *msi_new ( Messenger *messenger ) | 106 | MSISession *msi_new ( Messenger *m ) |
107 | { | 107 | { |
108 | if (messenger == NULL) { | 108 | if (m == NULL) { |
109 | LOGGER_ERROR("Could not init session on empty messenger!"); | 109 | LOGGER_ERROR("Could not init session on empty messenger!"); |
110 | return NULL; | 110 | return NULL; |
111 | } | 111 | } |
@@ -123,12 +123,12 @@ MSISession *msi_new ( Messenger *messenger ) | |||
123 | return NULL; | 123 | return NULL; |
124 | } | 124 | } |
125 | 125 | ||
126 | retu->messenger = messenger; | 126 | retu->messenger = m; |
127 | 127 | ||
128 | m_callback_msi_packet(messenger, handle_msi_packet, retu ); | 128 | m_callback_msi_packet(m, handle_msi_packet, retu ); |
129 | 129 | ||
130 | /* This is called when remote terminates session */ | 130 | /* This is called when remote terminates session */ |
131 | m_callback_connectionstatus_internal_av(messenger, on_peer_status, retu); | 131 | m_callback_connectionstatus_internal_av(m, on_peer_status, retu); |
132 | 132 | ||
133 | LOGGER_DEBUG("New msi session: %p ", retu); | 133 | LOGGER_DEBUG("New msi session: %p ", retu); |
134 | return retu; | 134 | return retu; |
@@ -149,7 +149,7 @@ int msi_kill ( MSISession *session ) | |||
149 | 149 | ||
150 | MSICall* it = get_call(session, session->calls_head); | 150 | MSICall* it = get_call(session, session->calls_head); |
151 | for (; it; it = it->next) { | 151 | for (; it; it = it->next) { |
152 | send_message(session->messenger, it->friend_id, &msg); | 152 | send_message(session->messenger, it->friend_number, &msg); |
153 | kill_call(it); /* This will eventually free session->calls */ | 153 | kill_call(it); /* This will eventually free session->calls */ |
154 | } | 154 | } |
155 | } | 155 | } |
@@ -161,18 +161,18 @@ int msi_kill ( MSISession *session ) | |||
161 | free ( session ); | 161 | free ( session ); |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_t capabilities ) | 164 | int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities ) |
165 | { | 165 | { |
166 | LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id); | 166 | LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_number); |
167 | 167 | ||
168 | pthread_mutex_lock(session->mutex); | 168 | pthread_mutex_lock(session->mutex); |
169 | if (get_call(session, friend_id) != NULL) { | 169 | if (get_call(session, friend_number) != NULL) { |
170 | LOGGER_ERROR("Already in a call"); | 170 | LOGGER_ERROR("Already in a call"); |
171 | pthread_mutex_unlock(session->mutex); | 171 | pthread_mutex_unlock(session->mutex); |
172 | return -1; | 172 | return -1; |
173 | } | 173 | } |
174 | 174 | ||
175 | (*call) = new_call ( session, friend_id ); | 175 | (*call) = new_call ( session, friend_number ); |
176 | 176 | ||
177 | if ( *call == NULL ) { | 177 | if ( *call == NULL ) { |
178 | pthread_mutex_unlock(session->mutex); | 178 | pthread_mutex_unlock(session->mutex); |
@@ -190,7 +190,7 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_ | |||
190 | msg.vfpsz.exists = true; | 190 | msg.vfpsz.exists = true; |
191 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; | 191 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; |
192 | 192 | ||
193 | send_message ( (*call)->session->messenger, (*call)->friend_id, &msg ); | 193 | send_message ( (*call)->session->messenger, (*call)->friend_number, &msg ); |
194 | 194 | ||
195 | (*call)->state = msi_CallRequesting; | 195 | (*call)->state = msi_CallRequesting; |
196 | 196 | ||
@@ -200,7 +200,7 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_ | |||
200 | } | 200 | } |
201 | int msi_hangup ( MSICall* call ) | 201 | int msi_hangup ( MSICall* call ) |
202 | { | 202 | { |
203 | LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_id); | 203 | LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_number); |
204 | 204 | ||
205 | MSISession* session = call->session; | 205 | MSISession* session = call->session; |
206 | pthread_mutex_lock(session->mutex); | 206 | pthread_mutex_lock(session->mutex); |
@@ -208,7 +208,7 @@ int msi_hangup ( MSICall* call ) | |||
208 | MSIMessage msg; | 208 | MSIMessage msg; |
209 | msg_init(&msg, requ_pop); | 209 | msg_init(&msg, requ_pop); |
210 | 210 | ||
211 | send_message ( session->messenger, call->friend_id, &msg ); | 211 | send_message ( session->messenger, call->friend_number, &msg ); |
212 | 212 | ||
213 | kill_call(call); | 213 | kill_call(call); |
214 | pthread_mutex_unlock(session->mutex); | 214 | pthread_mutex_unlock(session->mutex); |
@@ -216,7 +216,7 @@ int msi_hangup ( MSICall* call ) | |||
216 | } | 216 | } |
217 | int msi_answer ( MSICall* call, uint8_t capabilities ) | 217 | int msi_answer ( MSICall* call, uint8_t capabilities ) |
218 | { | 218 | { |
219 | LOGGER_DEBUG("Session: %p Answering call from: %u", call->session, call->friend_id); | 219 | LOGGER_DEBUG("Session: %p Answering call from: %u", call->session, call->friend_number); |
220 | 220 | ||
221 | MSISession* session = call->session; | 221 | MSISession* session = call->session; |
222 | pthread_mutex_lock(session->mutex); | 222 | pthread_mutex_lock(session->mutex); |
@@ -240,7 +240,7 @@ int msi_answer ( MSICall* call, uint8_t capabilities ) | |||
240 | msg.vfpsz.exists = true; | 240 | msg.vfpsz.exists = true; |
241 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; | 241 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; |
242 | 242 | ||
243 | send_message ( session->messenger, call->friend_id, &msg ); | 243 | send_message ( session->messenger, call->friend_number, &msg ); |
244 | 244 | ||
245 | call->state = msi_CallActive; | 245 | call->state = msi_CallActive; |
246 | pthread_mutex_unlock(session->mutex); | 246 | pthread_mutex_unlock(session->mutex); |
@@ -249,7 +249,7 @@ int msi_answer ( MSICall* call, uint8_t capabilities ) | |||
249 | } | 249 | } |
250 | int msi_change_capabilities( MSICall* call, uint8_t capabilities ) | 250 | int msi_change_capabilities( MSICall* call, uint8_t capabilities ) |
251 | { | 251 | { |
252 | LOGGER_DEBUG("Session: %p Trying to change capabilities to friend %u", call->session, call->friend_id); | 252 | LOGGER_DEBUG("Session: %p Trying to change capabilities to friend %u", call->session, call->friend_number); |
253 | 253 | ||
254 | MSISession* session = call->session; | 254 | MSISession* session = call->session; |
255 | pthread_mutex_lock(session->mutex); | 255 | pthread_mutex_lock(session->mutex); |
@@ -275,7 +275,7 @@ int msi_change_capabilities( MSICall* call, uint8_t capabilities ) | |||
275 | msg.capabilities.exists = true; | 275 | msg.capabilities.exists = true; |
276 | msg.capabilities.value = capabilities; | 276 | msg.capabilities.value = capabilities; |
277 | 277 | ||
278 | send_message ( call->session->messenger, call->friend_id, &msg ); | 278 | send_message ( call->session->messenger, call->friend_number, &msg ); |
279 | 279 | ||
280 | pthread_mutex_unlock(session->mutex); | 280 | pthread_mutex_unlock(session->mutex); |
281 | return 0; | 281 | return 0; |
@@ -394,7 +394,7 @@ uint8_t *msg_parse_header_out ( MSIHeaderID id, uint8_t *dest, const void *value | |||
394 | 394 | ||
395 | return dest + value_len; /* Set to next position ready to be written */ | 395 | return dest + value_len; /* Set to next position ready to be written */ |
396 | } | 396 | } |
397 | int send_message ( Messenger* m, uint32_t friend_id, const MSIMessage *msg ) | 397 | int send_message ( Messenger* m, uint32_t friend_number, const MSIMessage *msg ) |
398 | { | 398 | { |
399 | /* Parse and send message */ | 399 | /* Parse and send message */ |
400 | assert(m); | 400 | assert(m); |
@@ -438,19 +438,19 @@ int send_message ( Messenger* m, uint32_t friend_id, const MSIMessage *msg ) | |||
438 | *it = 0; | 438 | *it = 0; |
439 | size ++; | 439 | size ++; |
440 | 440 | ||
441 | if ( m_msi_packet(m, friend_id, parsed, size) ) { | 441 | if ( m_msi_packet(m, friend_number, parsed, size) ) { |
442 | LOGGER_DEBUG("Sent message"); | 442 | LOGGER_DEBUG("Sent message"); |
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | 445 | ||
446 | return -1; | 446 | return -1; |
447 | } | 447 | } |
448 | int send_error ( Messenger* m, uint32_t friend_id, MSIError error ) | 448 | int send_error ( Messenger* m, uint32_t friend_number, MSIError error ) |
449 | { | 449 | { |
450 | /* Send error message */ | 450 | /* Send error message */ |
451 | assert(m); | 451 | assert(m); |
452 | 452 | ||
453 | LOGGER_DEBUG("Sending error: %d to friend: %d", error, friend_id); | 453 | LOGGER_DEBUG("Sending error: %d to friend: %d", error, friend_number); |
454 | 454 | ||
455 | MSIMessage msg; | 455 | MSIMessage msg; |
456 | msg_init(&msg, requ_pop); | 456 | msg_init(&msg, requ_pop); |
@@ -458,7 +458,7 @@ int send_error ( Messenger* m, uint32_t friend_id, MSIError error ) | |||
458 | msg.error.exists = true; | 458 | msg.error.exists = true; |
459 | msg.error.value = error; | 459 | msg.error.value = error; |
460 | 460 | ||
461 | send_message ( m, friend_id, &msg ); | 461 | send_message ( m, friend_number, &msg ); |
462 | return 0; | 462 | return 0; |
463 | } | 463 | } |
464 | int invoke_callback(MSICall* call, MSICallbackID cb) | 464 | int invoke_callback(MSICall* call, MSICallbackID cb) |
@@ -484,16 +484,16 @@ FAILURE: | |||
484 | call->error = msi_EHandle; | 484 | call->error = msi_EHandle; |
485 | return -1; | 485 | return -1; |
486 | } | 486 | } |
487 | static MSICall *get_call ( MSISession *session, uint32_t friend_id ) | 487 | static MSICall *get_call ( MSISession *session, uint32_t friend_number ) |
488 | { | 488 | { |
489 | assert(session); | 489 | assert(session); |
490 | 490 | ||
491 | if (session->calls == NULL || session->calls_tail < friend_id) | 491 | if (session->calls == NULL || session->calls_tail < friend_number) |
492 | return NULL; | 492 | return NULL; |
493 | 493 | ||
494 | return session->calls[friend_id]; | 494 | return session->calls[friend_number]; |
495 | } | 495 | } |
496 | MSICall *new_call ( MSISession *session, uint32_t friend_id ) | 496 | MSICall *new_call ( MSISession *session, uint32_t friend_number ) |
497 | { | 497 | { |
498 | assert(session); | 498 | assert(session); |
499 | 499 | ||
@@ -503,20 +503,20 @@ MSICall *new_call ( MSISession *session, uint32_t friend_id ) | |||
503 | return NULL; | 503 | return NULL; |
504 | 504 | ||
505 | rc->session = session; | 505 | rc->session = session; |
506 | rc->friend_id = friend_id; | 506 | rc->friend_number = friend_number; |
507 | 507 | ||
508 | if (session->calls == NULL) { /* Creating */ | 508 | if (session->calls == NULL) { /* Creating */ |
509 | session->calls = calloc (sizeof(MSICall*), friend_id + 1); | 509 | session->calls = calloc (sizeof(MSICall*), friend_number + 1); |
510 | 510 | ||
511 | if (session->calls == NULL) { | 511 | if (session->calls == NULL) { |
512 | free(rc); | 512 | free(rc); |
513 | return NULL; | 513 | return NULL; |
514 | } | 514 | } |
515 | 515 | ||
516 | session->calls_tail = session->calls_head = friend_id; | 516 | session->calls_tail = session->calls_head = friend_number; |
517 | 517 | ||
518 | } else if (session->calls_tail < friend_id) { /* Appending */ | 518 | } else if (session->calls_tail < friend_number) { /* Appending */ |
519 | void* tmp = realloc(session->calls, sizeof(MSICall*) * friend_id + 1); | 519 | void* tmp = realloc(session->calls, sizeof(MSICall*) * friend_number + 1); |
520 | 520 | ||
521 | if (tmp == NULL) { | 521 | if (tmp == NULL) { |
522 | free(rc); | 522 | free(rc); |
@@ -526,22 +526,22 @@ MSICall *new_call ( MSISession *session, uint32_t friend_id ) | |||
526 | session->calls = tmp; | 526 | session->calls = tmp; |
527 | 527 | ||
528 | /* Set fields in between to null */ | 528 | /* Set fields in between to null */ |
529 | int32_t i = session->calls_tail; | 529 | int32_t i = session->calls_tail + 1; |
530 | for (; i < friend_id; i ++) | 530 | for (; i < friend_number; i ++) |
531 | session->calls[i] = NULL; | 531 | session->calls[i] = NULL; |
532 | 532 | ||
533 | rc->prev = session->calls[session->calls_tail]; | 533 | rc->prev = session->calls[session->calls_tail]; |
534 | session->calls[session->calls_tail]->next = rc; | 534 | session->calls[session->calls_tail]->next = rc; |
535 | 535 | ||
536 | session->calls_tail = friend_id; | 536 | session->calls_tail = friend_number; |
537 | 537 | ||
538 | } else if (session->calls_head > friend_id) { /* Inserting at front */ | 538 | } else if (session->calls_head > friend_number) { /* Inserting at front */ |
539 | rc->next = session->calls[session->calls_head]; | 539 | rc->next = session->calls[session->calls_head]; |
540 | session->calls[session->calls_head]->prev = rc; | 540 | session->calls[session->calls_head]->prev = rc; |
541 | session->calls_head = friend_id; | 541 | session->calls_head = friend_number; |
542 | } | 542 | } |
543 | 543 | ||
544 | session->calls[friend_id] = rc; | 544 | session->calls[friend_number] = rc; |
545 | return rc; | 545 | return rc; |
546 | } | 546 | } |
547 | void kill_call ( MSICall *call ) | 547 | void kill_call ( MSICall *call ) |
@@ -560,16 +560,16 @@ void kill_call ( MSICall *call ) | |||
560 | if (prev) | 560 | if (prev) |
561 | prev->next = next; | 561 | prev->next = next; |
562 | else if (next) | 562 | else if (next) |
563 | session->calls_head = next->friend_id; | 563 | session->calls_head = next->friend_number; |
564 | else goto CLEAR_CONTAINER; | 564 | else goto CLEAR_CONTAINER; |
565 | 565 | ||
566 | if (next) | 566 | if (next) |
567 | next->prev = prev; | 567 | next->prev = prev; |
568 | else if (prev) | 568 | else if (prev) |
569 | session->calls_tail = prev->friend_id; | 569 | session->calls_tail = prev->friend_number; |
570 | else goto CLEAR_CONTAINER; | 570 | else goto CLEAR_CONTAINER; |
571 | 571 | ||
572 | session->calls[call->friend_id] = NULL; | 572 | session->calls[call->friend_number] = NULL; |
573 | free(call); | 573 | free(call); |
574 | return; | 574 | return; |
575 | 575 | ||
@@ -579,17 +579,17 @@ CLEAR_CONTAINER: | |||
579 | free(call); | 579 | free(call); |
580 | session->calls = NULL; | 580 | session->calls = NULL; |
581 | } | 581 | } |
582 | void on_peer_status(Messenger* m, uint32_t friend_id, uint8_t status, void* data) | 582 | void on_peer_status(Messenger* m, uint32_t friend_number, uint8_t status, void* data) |
583 | { | 583 | { |
584 | (void)m; | 584 | (void)m; |
585 | MSISession *session = data; | 585 | MSISession *session = data; |
586 | 586 | ||
587 | switch ( status ) { | 587 | switch ( status ) { |
588 | case 0: { /* Friend is now offline */ | 588 | case 0: { /* Friend is now offline */ |
589 | LOGGER_DEBUG("Friend %d is now offline", friend_id); | 589 | LOGGER_DEBUG("Friend %d is now offline", friend_number); |
590 | 590 | ||
591 | pthread_mutex_lock(session->mutex); | 591 | pthread_mutex_lock(session->mutex); |
592 | MSICall* call = get_call(session, friend_id); | 592 | MSICall* call = get_call(session, friend_number); |
593 | 593 | ||
594 | if (call == NULL) { | 594 | if (call == NULL) { |
595 | pthread_mutex_unlock(session->mutex); | 595 | pthread_mutex_unlock(session->mutex); |
@@ -610,9 +610,7 @@ void handle_push ( MSICall *call, const MSIMessage *msg ) | |||
610 | { | 610 | { |
611 | assert(call); | 611 | assert(call); |
612 | 612 | ||
613 | MSISession* session = call->session; | 613 | LOGGER_DEBUG("Session: %p Handling 'push' friend: %d", call->session, call->friend_number); |
614 | |||
615 | LOGGER_DEBUG("Session: %p Handling 'push' friend: %d", call->session, call->friend_id); | ||
616 | 614 | ||
617 | if (!msg->capabilities.exists) { | 615 | if (!msg->capabilities.exists) { |
618 | LOGGER_WARNING("Session: %p Invalid capabilities on 'push'"); | 616 | LOGGER_WARNING("Session: %p Invalid capabilities on 'push'"); |
@@ -670,7 +668,7 @@ void handle_push ( MSICall *call, const MSIMessage *msg ) | |||
670 | msg.vfpsz.exists = true; | 668 | msg.vfpsz.exists = true; |
671 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; | 669 | msg.vfpsz.value = VIDEOFRAME_PIECE_SIZE; |
672 | 670 | ||
673 | send_message ( call->session->messenger, call->friend_id, &msg ); | 671 | send_message ( call->session->messenger, call->friend_number, &msg ); |
674 | 672 | ||
675 | /* If peer changed capabilities during re-call they will | 673 | /* If peer changed capabilities during re-call they will |
676 | * be handled accordingly during the next step | 674 | * be handled accordingly during the next step |
@@ -708,14 +706,14 @@ void handle_push ( MSICall *call, const MSIMessage *msg ) | |||
708 | return; | 706 | return; |
709 | 707 | ||
710 | FAILURE: | 708 | FAILURE: |
711 | send_error(call->session->messenger, call->friend_id, call->error); | 709 | send_error(call->session->messenger, call->friend_number, call->error); |
712 | kill_call(call); | 710 | kill_call(call); |
713 | } | 711 | } |
714 | void handle_pop ( MSICall *call, const MSIMessage *msg ) | 712 | void handle_pop ( MSICall *call, const MSIMessage *msg ) |
715 | { | 713 | { |
716 | assert(call); | 714 | assert(call); |
717 | 715 | ||
718 | LOGGER_DEBUG("Session: %p Handling 'pop', friend id: %d", call->session, call->friend_id); | 716 | LOGGER_DEBUG("Session: %p Handling 'pop', friend id: %d", call->session, call->friend_number); |
719 | 717 | ||
720 | /* callback errors are ignored */ | 718 | /* callback errors are ignored */ |
721 | 719 | ||
@@ -751,7 +749,7 @@ void handle_pop ( MSICall *call, const MSIMessage *msg ) | |||
751 | 749 | ||
752 | kill_call ( call ); | 750 | kill_call ( call ); |
753 | } | 751 | } |
754 | void handle_msi_packet ( Messenger* m, uint32_t friend_id, const uint8_t* data, uint16_t length, void* object ) | 752 | void handle_msi_packet ( Messenger* m, uint32_t friend_number, const uint8_t* data, uint16_t length, void* object ) |
755 | { | 753 | { |
756 | LOGGER_DEBUG("Got msi message"); | 754 | LOGGER_DEBUG("Got msi message"); |
757 | 755 | ||
@@ -760,25 +758,25 @@ void handle_msi_packet ( Messenger* m, uint32_t friend_id, const uint8_t* data, | |||
760 | 758 | ||
761 | if ( msg_parse_in ( &msg, data, length ) == -1 ) { | 759 | if ( msg_parse_in ( &msg, data, length ) == -1 ) { |
762 | LOGGER_WARNING("Error parsing message"); | 760 | LOGGER_WARNING("Error parsing message"); |
763 | send_error(m, friend_id, msi_EInvalidMessage); | 761 | send_error(m, friend_number, msi_EInvalidMessage); |
764 | return; | 762 | return; |
765 | } else { | 763 | } else { |
766 | LOGGER_DEBUG("Successfully parsed message"); | 764 | LOGGER_DEBUG("Successfully parsed message"); |
767 | } | 765 | } |
768 | 766 | ||
769 | pthread_mutex_lock(session->mutex); | 767 | pthread_mutex_lock(session->mutex); |
770 | MSICall *call = get_call(session, friend_id); | 768 | MSICall *call = get_call(session, friend_number); |
771 | 769 | ||
772 | if (call == NULL) { | 770 | if (call == NULL) { |
773 | if (msg.request.value != requ_push) { | 771 | if (msg.request.value != requ_push) { |
774 | send_error(m, friend_id, msi_EStrayMessage); | 772 | send_error(m, friend_number, msi_EStrayMessage); |
775 | pthread_mutex_unlock(session->mutex); | 773 | pthread_mutex_unlock(session->mutex); |
776 | return; | 774 | return; |
777 | } | 775 | } |
778 | 776 | ||
779 | call = new_call(session, friend_id); | 777 | call = new_call(session, friend_number); |
780 | if (call == NULL) { | 778 | if (call == NULL) { |
781 | send_error(m, friend_id, msi_ESystem); | 779 | send_error(m, friend_number, msi_ESystem); |
782 | pthread_mutex_unlock(session->mutex); | 780 | pthread_mutex_unlock(session->mutex); |
783 | return; | 781 | return; |
784 | } | 782 | } |
diff --git a/toxav/msi.h b/toxav/msi.h index 457d3148..4836ae89 100644 --- a/toxav/msi.h +++ b/toxav/msi.h | |||
@@ -89,7 +89,7 @@ typedef struct MSICall_s { | |||
89 | uint8_t peer_capabilities; /* Peer capabilities */ | 89 | uint8_t peer_capabilities; /* Peer capabilities */ |
90 | uint8_t self_capabilities; /* Self capabilities */ | 90 | uint8_t self_capabilities; /* Self capabilities */ |
91 | uint16_t peer_vfpsz; /* Video frame piece size */ | 91 | uint16_t peer_vfpsz; /* Video frame piece size */ |
92 | uint32_t friend_id; /* Index of this call in MSISession */ | 92 | uint32_t friend_number; /* Index of this call in MSISession */ |
93 | MSIError error; /* Last error */ | 93 | MSIError error; /* Last error */ |
94 | 94 | ||
95 | void* av_call; /* Pointer to av call handler */ | 95 | void* av_call; /* Pointer to av call handler */ |
@@ -100,12 +100,11 @@ typedef struct MSICall_s { | |||
100 | 100 | ||
101 | 101 | ||
102 | /** | 102 | /** |
103 | * Msi callback type. 'agent' is a pointer to ToxAv. | ||
104 | * Expected return on success is 0, if any other number is | 103 | * Expected return on success is 0, if any other number is |
105 | * returned the call is considered errored and will be handled | 104 | * returned the call is considered errored and will be handled |
106 | * as such which means it will be terminated without any notice. | 105 | * as such which means it will be terminated without any notice. |
107 | */ | 106 | */ |
108 | typedef int ( *MSICallbackType ) ( void *agent, MSICall* call); | 107 | typedef int msi_action_cb ( void *av, MSICall* call); |
109 | 108 | ||
110 | /** | 109 | /** |
111 | * Control session struct. Please do not modify outside msi.c | 110 | * Control session struct. Please do not modify outside msi.c |
@@ -119,43 +118,34 @@ typedef struct MSISession_s { | |||
119 | void *av; | 118 | void *av; |
120 | Messenger *messenger; | 119 | Messenger *messenger; |
121 | 120 | ||
122 | /* The mutex controls async access from control | ||
123 | * thread(s) and core thread. | ||
124 | */ | ||
125 | pthread_mutex_t mutex[1]; | 121 | pthread_mutex_t mutex[1]; |
126 | MSICallbackType callbacks[7]; | 122 | msi_action_cb* callbacks[7]; |
127 | } MSISession; | 123 | } MSISession; |
128 | 124 | ||
129 | /** | 125 | /** |
130 | * Start the control session. | 126 | * Start the control session. |
131 | */ | 127 | */ |
132 | MSISession *msi_new ( Messenger *messenger ); | 128 | MSISession *msi_new ( Messenger *m ); |
133 | |||
134 | /** | 129 | /** |
135 | * Terminate control session. NOTE: all calls will be freed | 130 | * Terminate control session. NOTE: all calls will be freed |
136 | */ | 131 | */ |
137 | int msi_kill ( MSISession *session ); | 132 | int msi_kill ( MSISession *session ); |
138 | |||
139 | /** | 133 | /** |
140 | * Callback setter. | 134 | * Callback setter. |
141 | */ | 135 | */ |
142 | void msi_register_callback(MSISession *session, MSICallbackType callback, MSICallbackID id); | 136 | void msi_register_callback(MSISession *session, msi_action_cb* callback, MSICallbackID id); |
143 | |||
144 | /** | 137 | /** |
145 | * Send invite request to friend_id. | 138 | * Send invite request to friend_number. |
146 | */ | 139 | */ |
147 | int msi_invite ( MSISession* session, MSICall** call, uint32_t friend_id, uint8_t capabilities ); | 140 | int msi_invite ( MSISession* session, MSICall** call, uint32_t friend_number, uint8_t capabilities ); |
148 | |||
149 | /** | 141 | /** |
150 | * Hangup call. NOTE: 'call' will be freed | 142 | * Hangup call. NOTE: 'call' will be freed |
151 | */ | 143 | */ |
152 | int msi_hangup ( MSICall* call ); | 144 | int msi_hangup ( MSICall* call ); |
153 | |||
154 | /** | 145 | /** |
155 | * Answer call request. | 146 | * Answer call request. |
156 | */ | 147 | */ |
157 | int msi_answer ( MSICall* call, uint8_t capabilities ); | 148 | int msi_answer ( MSICall* call, uint8_t capabilities ); |
158 | |||
159 | /** | 149 | /** |
160 | * Change capabilities of the call. | 150 | * Change capabilities of the call. |
161 | */ | 151 | */ |
diff --git a/toxav/rtp.c b/toxav/rtp.c index 6c603f79..2219805b 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c | |||
@@ -78,11 +78,11 @@ int handle_rtcp_packet ( Messenger *m, uint32_t friendnumber, const uint8_t *dat | |||
78 | void send_rtcp_report ( RTCPSession* session, Messenger* m, uint32_t friendnumber ); | 78 | void send_rtcp_report ( RTCPSession* session, Messenger* m, uint32_t friendnumber ); |
79 | 79 | ||
80 | 80 | ||
81 | RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num, void* cs, int (*mcb) (void*, RTPMessage*) ) | 81 | RTPSession *rtp_new ( int payload_type, Messenger *m, int friend_num, void* cs, int (*mcb) (void*, RTPMessage*) ) |
82 | { | 82 | { |
83 | assert(mcb); | 83 | assert(mcb); |
84 | assert(cs); | 84 | assert(cs); |
85 | assert(messenger); | 85 | assert(m); |
86 | 86 | ||
87 | RTPSession *retu = calloc(1, sizeof(RTPSession)); | 87 | RTPSession *retu = calloc(1, sizeof(RTPSession)); |
88 | 88 | ||
@@ -95,8 +95,8 @@ RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num, vo | |||
95 | retu->ssrc = random_int(); | 95 | retu->ssrc = random_int(); |
96 | retu->payload_type = payload_type % 128; | 96 | retu->payload_type = payload_type % 128; |
97 | 97 | ||
98 | retu->m = messenger; | 98 | retu->m = m; |
99 | retu->friend_id = friend_num; | 99 | retu->friend_number = friend_num; |
100 | 100 | ||
101 | if ( !(retu->csrc = calloc(1, sizeof(uint32_t))) ) { | 101 | if ( !(retu->csrc = calloc(1, sizeof(uint32_t))) ) { |
102 | LOGGER_WARNING("Alloc failed! Program might misbehave!"); | 102 | LOGGER_WARNING("Alloc failed! Program might misbehave!"); |
@@ -161,7 +161,7 @@ int rtp_do(RTPSession *session) | |||
161 | return rtp_StateNormal; | 161 | return rtp_StateNormal; |
162 | 162 | ||
163 | if (current_time_monotonic() - session->rtcp_session->last_sent_report_ts >= RTCP_REPORT_INTERVAL_MS) { | 163 | if (current_time_monotonic() - session->rtcp_session->last_sent_report_ts >= RTCP_REPORT_INTERVAL_MS) { |
164 | send_rtcp_report(session->rtcp_session, session->m, session->friend_id); | 164 | send_rtcp_report(session->rtcp_session, session->m, session->friend_number); |
165 | } | 165 | } |
166 | 166 | ||
167 | if (rb_full(session->rtcp_session->pl_stats)) { | 167 | if (rb_full(session->rtcp_session->pl_stats)) { |
@@ -209,15 +209,15 @@ int rtp_start_receiving(RTPSession* session) | |||
209 | if (session == NULL) | 209 | if (session == NULL) |
210 | return -1; | 210 | return -1; |
211 | 211 | ||
212 | if (m_callback_rtp_packet(session->m, session->friend_id, session->prefix, | 212 | if (m_callback_rtp_packet(session->m, session->friend_number, session->prefix, |
213 | handle_rtp_packet, session) == -1) { | 213 | handle_rtp_packet, session) == -1) { |
214 | LOGGER_WARNING("Failed to register rtp receive handler"); | 214 | LOGGER_WARNING("Failed to register rtp receive handler"); |
215 | return -1; | 215 | return -1; |
216 | } | 216 | } |
217 | if (m_callback_rtp_packet(session->m, session->friend_id, session->rtcp_session->prefix, | 217 | if (m_callback_rtp_packet(session->m, session->friend_number, session->rtcp_session->prefix, |
218 | handle_rtcp_packet, session->rtcp_session) == -1) { | 218 | handle_rtcp_packet, session->rtcp_session) == -1) { |
219 | LOGGER_WARNING("Failed to register rtcp receive handler"); | 219 | LOGGER_WARNING("Failed to register rtcp receive handler"); |
220 | m_callback_rtp_packet(session->m, session->friend_id, session->prefix, NULL, NULL); | 220 | m_callback_rtp_packet(session->m, session->friend_number, session->prefix, NULL, NULL); |
221 | return -1; | 221 | return -1; |
222 | } | 222 | } |
223 | 223 | ||
@@ -228,8 +228,8 @@ int rtp_stop_receiving(RTPSession* session) | |||
228 | if (session == NULL) | 228 | if (session == NULL) |
229 | return -1; | 229 | return -1; |
230 | 230 | ||
231 | m_callback_rtp_packet(session->m, session->friend_id, session->prefix, NULL, NULL); | 231 | m_callback_rtp_packet(session->m, session->friend_number, session->prefix, NULL, NULL); |
232 | m_callback_rtp_packet(session->m, session->friend_id, session->rtcp_session->prefix, NULL, NULL); /* RTCP */ | 232 | m_callback_rtp_packet(session->m, session->friend_number, session->rtcp_session->prefix, NULL, NULL); /* RTCP */ |
233 | 233 | ||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
@@ -243,7 +243,8 @@ int rtp_send_data ( RTPSession *session, const uint8_t *data, uint16_t length, b | |||
243 | uint8_t parsed[MAX_RTP_SIZE]; | 243 | uint8_t parsed[MAX_RTP_SIZE]; |
244 | uint8_t *it; | 244 | uint8_t *it; |
245 | 245 | ||
246 | RTPHeader header[1]; | 246 | RTPHeader header[1] = {0}; |
247 | |||
247 | ADD_FLAG_VERSION ( header, session->version ); | 248 | ADD_FLAG_VERSION ( header, session->version ); |
248 | ADD_FLAG_PADDING ( header, session->padding ); | 249 | ADD_FLAG_PADDING ( header, session->padding ); |
249 | ADD_FLAG_EXTENSION ( header, session->extension ); | 250 | ADD_FLAG_EXTENSION ( header, session->extension ); |
@@ -278,12 +279,11 @@ int rtp_send_data ( RTPSession *session, const uint8_t *data, uint16_t length, b | |||
278 | 279 | ||
279 | memcpy(it, data, length); | 280 | memcpy(it, data, length); |
280 | 281 | ||
281 | if ( -1 == send_custom_lossy_packet(session->m, session->friend_id, parsed, parsed_len) ) { | 282 | if ( -1 == send_custom_lossy_packet(session->m, session->friend_number, parsed, parsed_len) ) { |
282 | LOGGER_WARNING("Failed to send full packet (len: %d)! std error: %s", length, strerror(errno)); | 283 | LOGGER_WARNING("Failed to send full packet (len: %d)! std error: %s", length, strerror(errno)); |
283 | return -1; | 284 | return -1; |
284 | } | 285 | } |
285 | 286 | ||
286 | /* Set sequ number */ | ||
287 | session->sequnum = session->sequnum >= MAX_SEQU_NUM ? 0 : session->sequnum + 1; | 287 | session->sequnum = session->sequnum >= MAX_SEQU_NUM ? 0 : session->sequnum + 1; |
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
@@ -300,7 +300,6 @@ void rtp_free_msg ( RTPMessage *msg ) | |||
300 | 300 | ||
301 | 301 | ||
302 | 302 | ||
303 | |||
304 | RTPHeader *parse_header_in ( const uint8_t *payload, int length ) | 303 | RTPHeader *parse_header_in ( const uint8_t *payload, int length ) |
305 | { | 304 | { |
306 | if ( !payload || !length ) { | 305 | if ( !payload || !length ) { |
@@ -322,12 +321,7 @@ RTPHeader *parse_header_in ( const uint8_t *payload, int length ) | |||
322 | 321 | ||
323 | retu->flags = *it; | 322 | retu->flags = *it; |
324 | ++it; | 323 | ++it; |
325 | 324 | ||
326 | /* This indicates if the first 2 bits are valid. | ||
327 | * Now it may happen that this is out of order but | ||
328 | * it cuts down chances of parsing some invalid value | ||
329 | */ | ||
330 | |||
331 | if ( GET_FLAG_VERSION(retu) != RTP_VERSION ) { | 325 | if ( GET_FLAG_VERSION(retu) != RTP_VERSION ) { |
332 | /* Deallocate */ | 326 | /* Deallocate */ |
333 | LOGGER_WARNING("Invalid version!"); | 327 | LOGGER_WARNING("Invalid version!"); |
@@ -335,15 +329,10 @@ RTPHeader *parse_header_in ( const uint8_t *payload, int length ) | |||
335 | return NULL; | 329 | return NULL; |
336 | } | 330 | } |
337 | 331 | ||
338 | /* | ||
339 | * Added a check for the size of the header little sooner so | ||
340 | * I don't need to parse the other stuff if it's bad | ||
341 | */ | ||
342 | uint8_t cc = GET_FLAG_CSRCC ( retu ); | 332 | uint8_t cc = GET_FLAG_CSRCC ( retu ); |
343 | int total = 12 /* Minimum header len */ + ( cc * 4 ); | 333 | int total = 12 /* Minimum header len */ + ( cc * 4 ); |
344 | 334 | ||
345 | if ( length < total ) { | 335 | if ( length < total ) { |
346 | /* Deallocate */ | ||
347 | LOGGER_WARNING("Length invalid!"); | 336 | LOGGER_WARNING("Length invalid!"); |
348 | free(retu); | 337 | free(retu); |
349 | return NULL; | 338 | return NULL; |
@@ -355,9 +344,10 @@ RTPHeader *parse_header_in ( const uint8_t *payload, int length ) | |||
355 | 344 | ||
356 | 345 | ||
357 | memcpy(&retu->timestamp, it, sizeof(retu->timestamp)); | 346 | memcpy(&retu->timestamp, it, sizeof(retu->timestamp)); |
358 | retu->timestamp = ntohl(retu->timestamp); | ||
359 | it += 4; | 347 | it += 4; |
360 | memcpy(&retu->ssrc, it, sizeof(retu->ssrc)); | 348 | memcpy(&retu->ssrc, it, sizeof(retu->ssrc)); |
349 | |||
350 | retu->timestamp = ntohl(retu->timestamp); | ||
361 | retu->ssrc = ntohl(retu->ssrc); | 351 | retu->ssrc = ntohl(retu->ssrc); |
362 | 352 | ||
363 | uint8_t x; | 353 | uint8_t x; |
@@ -380,34 +370,31 @@ RTPExtHeader *parse_ext_header_in ( const uint8_t *payload, uint16_t length ) | |||
380 | return NULL; | 370 | return NULL; |
381 | } | 371 | } |
382 | 372 | ||
383 | uint16_t ext_length; | 373 | memcpy(&retu->length, it, sizeof(retu->length)); |
384 | memcpy(&ext_length, it, sizeof(ext_length)); | 374 | retu->length = ntohs(retu->length); |
385 | ext_length = ntohs(ext_length); | ||
386 | it += 2; | 375 | it += 2; |
387 | 376 | ||
388 | 377 | if ( length < ( retu->length * sizeof(uint32_t) ) ) { | |
389 | if ( length < ( ext_length * sizeof(uint32_t) ) ) { | ||
390 | LOGGER_WARNING("Length invalid!"); | 378 | LOGGER_WARNING("Length invalid!"); |
391 | free(retu); | 379 | free(retu); |
392 | return NULL; | 380 | return NULL; |
393 | } | 381 | } |
394 | 382 | ||
395 | retu->length = ext_length; | ||
396 | memcpy(&retu->type, it, sizeof(retu->type)); | 383 | memcpy(&retu->type, it, sizeof(retu->type)); |
397 | retu->type = ntohs(retu->type); | 384 | retu->type = ntohs(retu->type); |
385 | |||
398 | it += 2; | 386 | it += 2; |
399 | 387 | ||
400 | if ( !(retu->table = calloc(ext_length, sizeof (uint32_t))) ) { | 388 | if ( !(retu->table = calloc(retu->length, sizeof (uint32_t))) ) { |
401 | LOGGER_WARNING("Alloc failed! Program might misbehave!"); | 389 | LOGGER_WARNING("Alloc failed! Program might misbehave!"); |
402 | free(retu); | 390 | free(retu); |
403 | return NULL; | 391 | return NULL; |
404 | } | 392 | } |
405 | 393 | ||
406 | uint16_t x; | 394 | uint16_t x; |
407 | 395 | for ( x = 0; x < retu->length; x++ ) { | |
408 | for ( x = 0; x < ext_length; x++ ) { | ||
409 | it += 4; | 396 | it += 4; |
410 | memcpy(&(retu->table[x]), it, sizeof(retu->table[x])); | 397 | memcpy(retu->table + x, it, sizeof(*retu->table)); |
411 | retu->table[x] = ntohl(retu->table[x]); | 398 | retu->table[x] = ntohl(retu->table[x]); |
412 | } | 399 | } |
413 | 400 | ||
@@ -433,7 +420,6 @@ uint8_t *parse_header_out ( const RTPHeader *header, uint8_t *payload ) | |||
433 | *it = header->marker_payloadt; | 420 | *it = header->marker_payloadt; |
434 | ++it; | 421 | ++it; |
435 | 422 | ||
436 | |||
437 | timestamp = htonl(header->timestamp); | 423 | timestamp = htonl(header->timestamp); |
438 | memcpy(it, ×tamp, sizeof(timestamp)); | 424 | memcpy(it, ×tamp, sizeof(timestamp)); |
439 | it += 4; | 425 | it += 4; |
@@ -579,7 +565,6 @@ int handle_rtcp_packet ( Messenger* m, uint32_t friendnumber, const uint8_t* dat | |||
579 | report->received_packets = ntohl(report->received_packets); | 565 | report->received_packets = ntohl(report->received_packets); |
580 | report->expected_packets = ntohl(report->expected_packets); | 566 | report->expected_packets = ntohl(report->expected_packets); |
581 | 567 | ||
582 | /* Invalid values */ | ||
583 | if (report->expected_packets == 0 || report->received_packets > report->expected_packets) { | 568 | if (report->expected_packets == 0 || report->received_packets > report->expected_packets) { |
584 | LOGGER_WARNING("Malformed rtcp report! %d %d", report->expected_packets, report->received_packets); | 569 | LOGGER_WARNING("Malformed rtcp report! %d %d", report->expected_packets, report->received_packets); |
585 | free(report); | 570 | free(report); |
diff --git a/toxav/rtp.h b/toxav/rtp.h index c973d262..a158d724 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h | |||
@@ -113,10 +113,9 @@ typedef struct { | |||
113 | uint8_t prefix; | 113 | uint8_t prefix; |
114 | 114 | ||
115 | Messenger *m; | 115 | Messenger *m; |
116 | int friend_id; | 116 | int friend_number; |
117 | struct RTCPSession_s *rtcp_session; | 117 | struct RTCPSession_s *rtcp_session; |
118 | 118 | ||
119 | |||
120 | void *cs; | 119 | void *cs; |
121 | int (*mcb) (void*, RTPMessage* msg); | 120 | int (*mcb) (void*, RTPMessage* msg); |
122 | 121 | ||
@@ -125,33 +124,27 @@ typedef struct { | |||
125 | /** | 124 | /** |
126 | * Must be called before calling any other rtp function. | 125 | * Must be called before calling any other rtp function. |
127 | */ | 126 | */ |
128 | RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num, void* cs, int (*mcb) (void*, RTPMessage*) ); | 127 | RTPSession *rtp_new ( int payload_type, Messenger *m, int friend_num, void* cs, int (*mcb) (void*, RTPMessage*) ); |
129 | |||
130 | /** | 128 | /** |
131 | * Terminate the session. | 129 | * Terminate the session. |
132 | */ | 130 | */ |
133 | void rtp_kill ( RTPSession* session ); | 131 | void rtp_kill ( RTPSession* session ); |
134 | |||
135 | /** | 132 | /** |
136 | * Do periodical rtp work. | 133 | * Do periodical rtp work. |
137 | */ | 134 | */ |
138 | int rtp_do(RTPSession *session); | 135 | int rtp_do(RTPSession *session); |
139 | |||
140 | /** | 136 | /** |
141 | * By default rtp is in receiving state | 137 | * By default rtp is in receiving state |
142 | */ | 138 | */ |
143 | int rtp_start_receiving (RTPSession *session); | 139 | int rtp_start_receiving (RTPSession *session); |
144 | |||
145 | /** | 140 | /** |
146 | * Pause rtp receiving mode. | 141 | * Pause rtp receiving mode. |
147 | */ | 142 | */ |
148 | int rtp_stop_receiving (RTPSession *session); | 143 | int rtp_stop_receiving (RTPSession *session); |
149 | |||
150 | /** | 144 | /** |
151 | * Sends msg to RTPSession::dest | 145 | * Sends msg to RTPSession::dest |
152 | */ | 146 | */ |
153 | int rtp_send_data ( RTPSession* session, const uint8_t* data, uint16_t length, bool dummy ); | 147 | int rtp_send_data ( RTPSession* session, const uint8_t* data, uint16_t length, bool dummy ); |
154 | |||
155 | /** | 148 | /** |
156 | * Dealloc msg. | 149 | * Dealloc msg. |
157 | */ | 150 | */ |
diff --git a/toxav/toxav.c b/toxav/toxav.c index 8d47f5cd..25a2857c 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -58,10 +58,10 @@ typedef struct ToxAVCall_s { | |||
58 | 58 | ||
59 | bool active; | 59 | bool active; |
60 | MSICall* msi_call; | 60 | MSICall* msi_call; |
61 | uint32_t friend_id; | 61 | uint32_t friend_number; |
62 | 62 | ||
63 | uint32_t audio_bit_rate; /* Sending audio bitrate */ | 63 | uint32_t audio_bit_rate; /* Sending audio bit rate */ |
64 | uint32_t video_bit_rate; /* Sending video bitrate */ | 64 | uint32_t video_bit_rate; /* Sending video bit rate */ |
65 | 65 | ||
66 | ToxAvBitrateAdapter aba; | 66 | ToxAvBitrateAdapter aba; |
67 | ToxAvBitrateAdapter vba; | 67 | ToxAvBitrateAdapter vba; |
@@ -93,8 +93,8 @@ struct toxAV { | |||
93 | PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */ | 93 | PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */ |
94 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ | 94 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ |
95 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ | 95 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ |
96 | PAIR(toxav_audio_bitrate_control_cb *, void *) abcb; /* Audio bitrate control callback */ | 96 | PAIR(toxav_audio_bit_rate_status_cb *, void *) abcb; /* Audio bit rate control callback */ |
97 | PAIR(toxav_video_bitrate_control_cb *, void *) vbcb; /* Video bitrate control callback */ | 97 | PAIR(toxav_video_bit_rate_status_cb *, void *) vbcb; /* Video bit rate control callback */ |
98 | 98 | ||
99 | /** Decode time measures */ | 99 | /** Decode time measures */ |
100 | int32_t dmssc; /** Measure count */ | 100 | int32_t dmssc; /** Measure count */ |
@@ -111,8 +111,8 @@ int callback_end(void* toxav_inst, MSICall* call); | |||
111 | int callback_error(void* toxav_inst, MSICall* call); | 111 | int callback_error(void* toxav_inst, MSICall* call); |
112 | int callback_capabilites(void* toxav_inst, MSICall* call); | 112 | int callback_capabilites(void* toxav_inst, MSICall* call); |
113 | 113 | ||
114 | bool audio_bitrate_invalid(uint32_t bitrate); | 114 | bool audio_bit_rate_invalid(uint32_t bit_rate); |
115 | bool video_bitrate_invalid(uint32_t bitrate); | 115 | bool video_bit_rate_invalid(uint32_t bit_rate); |
116 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); | 116 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); |
117 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); | 117 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); |
118 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); | 118 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); |
@@ -129,12 +129,12 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | |||
129 | 129 | ||
130 | if (tox == NULL) { | 130 | if (tox == NULL) { |
131 | rc = TOXAV_ERR_NEW_NULL; | 131 | rc = TOXAV_ERR_NEW_NULL; |
132 | goto FAILURE; | 132 | goto END; |
133 | } | 133 | } |
134 | 134 | ||
135 | if (((Messenger*)tox)->msi_packet) { | 135 | if (((Messenger*)tox)->msi_packet) { |
136 | rc = TOXAV_ERR_NEW_MULTIPLE; | 136 | rc = TOXAV_ERR_NEW_MULTIPLE; |
137 | goto FAILURE; | 137 | goto END; |
138 | } | 138 | } |
139 | 139 | ||
140 | av = calloc (sizeof(ToxAV), 1); | 140 | av = calloc (sizeof(ToxAV), 1); |
@@ -142,13 +142,13 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | |||
142 | if (av == NULL) { | 142 | if (av == NULL) { |
143 | LOGGER_WARNING("Allocation failed!"); | 143 | LOGGER_WARNING("Allocation failed!"); |
144 | rc = TOXAV_ERR_NEW_MALLOC; | 144 | rc = TOXAV_ERR_NEW_MALLOC; |
145 | goto FAILURE; | 145 | goto END; |
146 | } | 146 | } |
147 | 147 | ||
148 | if (create_recursive_mutex(av->mutex) != 0) { | 148 | if (create_recursive_mutex(av->mutex) != 0) { |
149 | LOGGER_WARNING("Mutex creation failed!"); | 149 | LOGGER_WARNING("Mutex creation failed!"); |
150 | rc = TOXAV_ERR_NEW_MALLOC; | 150 | rc = TOXAV_ERR_NEW_MALLOC; |
151 | goto FAILURE; | 151 | goto END; |
152 | } | 152 | } |
153 | 153 | ||
154 | av->m = (Messenger *)tox; | 154 | av->m = (Messenger *)tox; |
@@ -157,7 +157,7 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | |||
157 | if (av->msi == NULL) { | 157 | if (av->msi == NULL) { |
158 | pthread_mutex_destroy(av->mutex); | 158 | pthread_mutex_destroy(av->mutex); |
159 | rc = TOXAV_ERR_NEW_MALLOC; | 159 | rc = TOXAV_ERR_NEW_MALLOC; |
160 | goto FAILURE; | 160 | goto END; |
161 | } | 161 | } |
162 | 162 | ||
163 | av->interval = 200; | 163 | av->interval = 200; |
@@ -170,19 +170,16 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | |||
170 | msi_register_callback(av->msi, callback_error, msi_OnPeerTimeout); | 170 | msi_register_callback(av->msi, callback_error, msi_OnPeerTimeout); |
171 | msi_register_callback(av->msi, callback_capabilites, msi_OnCapabilities); | 171 | msi_register_callback(av->msi, callback_capabilites, msi_OnCapabilities); |
172 | 172 | ||
173 | 173 | END: | |
174 | if (error) | ||
175 | *error = rc; | ||
176 | |||
177 | return av; | ||
178 | |||
179 | FAILURE: | ||
180 | if (error) | 174 | if (error) |
181 | *error = rc; | 175 | *error = rc; |
182 | 176 | ||
183 | free(av); | 177 | if (rc != TOXAV_ERR_NEW_OK) { |
178 | free(av); | ||
179 | av = NULL; | ||
180 | } | ||
184 | 181 | ||
185 | return NULL; | 182 | return av; |
186 | } | 183 | } |
187 | 184 | ||
188 | void toxav_kill(ToxAV* av) | 185 | void toxav_kill(ToxAV* av) |
@@ -249,14 +246,14 @@ void toxav_iterate(ToxAV* av) | |||
249 | 246 | ||
250 | /* Notify app */ | 247 | /* Notify app */ |
251 | if (av->abcb.first) | 248 | if (av->abcb.first) |
252 | av->abcb.first (av, i->friend_id, false, bb, av->abcb.second); | 249 | av->abcb.first (av, i->friend_number, false, bb, av->abcb.second); |
253 | } else if (i->aba.active && i->aba.end_time < current_time_monotonic()) { | 250 | } else if (i->aba.active && i->aba.end_time < current_time_monotonic()) { |
254 | 251 | ||
255 | i->audio_bit_rate = i->aba.bit_rate; | 252 | i->audio_bit_rate = i->aba.bit_rate; |
256 | 253 | ||
257 | /* Notify user about the new bitrate */ | 254 | /* Notify user about the new bit rate */ |
258 | if (av->abcb.first) | 255 | if (av->abcb.first) |
259 | av->abcb.first (av, i->friend_id, true, i->aba.bit_rate, av->abcb.second); | 256 | av->abcb.first (av, i->friend_number, true, i->aba.bit_rate, av->abcb.second); |
260 | 257 | ||
261 | /* Stop sending dummy packets */ | 258 | /* Stop sending dummy packets */ |
262 | memset(&i->aba, 0, sizeof(i->aba)); | 259 | memset(&i->aba, 0, sizeof(i->aba)); |
@@ -275,15 +272,15 @@ void toxav_iterate(ToxAV* av) | |||
275 | 272 | ||
276 | /* Notify app */ | 273 | /* Notify app */ |
277 | if (av->vbcb.first) | 274 | if (av->vbcb.first) |
278 | av->vbcb.first (av, i->friend_id, false, bb, av->vbcb.second); | 275 | av->vbcb.first (av, i->friend_number, false, bb, av->vbcb.second); |
279 | 276 | ||
280 | } else if (i->vba.active && i->vba.end_time < current_time_monotonic()) { | 277 | } else if (i->vba.active && i->vba.end_time < current_time_monotonic()) { |
281 | 278 | ||
282 | i->video_bit_rate = i->vba.bit_rate; | 279 | i->video_bit_rate = i->vba.bit_rate; |
283 | 280 | ||
284 | /* Notify user about the new bitrate */ | 281 | /* Notify user about the new bit rate */ |
285 | if (av->vbcb.first) | 282 | if (av->vbcb.first) |
286 | av->vbcb.first (av, i->friend_id, true, i->vba.bit_rate, av->vbcb.second); | 283 | av->vbcb.first (av, i->friend_number, true, i->vba.bit_rate, av->vbcb.second); |
287 | 284 | ||
288 | /* Stop sending dummy packets */ | 285 | /* Stop sending dummy packets */ |
289 | memset(&i->vba, 0, sizeof(i->vba)); | 286 | memset(&i->vba, 0, sizeof(i->vba)); |
@@ -297,7 +294,7 @@ void toxav_iterate(ToxAV* av) | |||
297 | i->msi_call->peer_capabilities & msi_CapSVideo) | 294 | i->msi_call->peer_capabilities & msi_CapSVideo) |
298 | rc = MIN(i->video.second->lcfd, rc); | 295 | rc = MIN(i->video.second->lcfd, rc); |
299 | 296 | ||
300 | uint32_t fid = i->friend_id; | 297 | uint32_t fid = i->friend_number; |
301 | 298 | ||
302 | pthread_mutex_unlock(i->mutex); | 299 | pthread_mutex_unlock(i->mutex); |
303 | pthread_mutex_lock(av->mutex); | 300 | pthread_mutex_lock(av->mutex); |
@@ -356,7 +353,7 @@ void toxav_callback_call(ToxAV* av, toxav_call_cb* function, void* user_data) | |||
356 | av->ccb.first = function; | 353 | av->ccb.first = function; |
357 | av->ccb.second = user_data; | 354 | av->ccb.second = user_data; |
358 | pthread_mutex_unlock(av->mutex); | 355 | pthread_mutex_unlock(av->mutex); |
359 | }/** Required for monitoring */ | 356 | } |
360 | 357 | ||
361 | bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER* error) | 358 | bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER* error) |
362 | { | 359 | { |
@@ -368,8 +365,8 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui | |||
368 | goto END; | 365 | goto END; |
369 | } | 366 | } |
370 | 367 | ||
371 | if ((audio_bit_rate && audio_bitrate_invalid(audio_bit_rate)) | 368 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) |
372 | ||(video_bit_rate && video_bitrate_invalid(video_bit_rate)) | 369 | ||(video_bit_rate && video_bit_rate_invalid(video_bit_rate)) |
373 | ) { | 370 | ) { |
374 | rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; | 371 | rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; |
375 | goto END; | 372 | goto END; |
@@ -561,7 +558,7 @@ END: | |||
561 | return rc == TOXAV_ERR_CALL_CONTROL_OK; | 558 | return rc == TOXAV_ERR_CALL_CONTROL_OK; |
562 | } | 559 | } |
563 | 560 | ||
564 | void toxav_callback_video_bitrate_control(ToxAV* av, toxav_video_bitrate_control_cb* function, void* user_data) | 561 | void toxav_callback_video_bit_rate_status(ToxAV* av, toxav_video_bit_rate_status_cb* function, void* user_data) |
565 | { | 562 | { |
566 | pthread_mutex_lock(av->mutex); | 563 | pthread_mutex_lock(av->mutex); |
567 | av->vbcb.first = function; | 564 | av->vbcb.first = function; |
@@ -579,7 +576,7 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
579 | goto END; | 576 | goto END; |
580 | } | 577 | } |
581 | 578 | ||
582 | if (video_bitrate_invalid(video_bit_rate)) { | 579 | if (video_bit_rate_invalid(video_bit_rate)) { |
583 | rc = TOXAV_ERR_BIT_RATE_INVALID; | 580 | rc = TOXAV_ERR_BIT_RATE_INVALID; |
584 | goto END; | 581 | goto END; |
585 | } | 582 | } |
@@ -605,7 +602,7 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
605 | call->video_bit_rate = video_bit_rate; | 602 | call->video_bit_rate = video_bit_rate; |
606 | 603 | ||
607 | if (!force && av->vbcb.first) | 604 | if (!force && av->vbcb.first) |
608 | av->vbcb.first (av, call->friend_id, true, video_bit_rate, av->vbcb.second); | 605 | av->vbcb.first (av, call->friend_number, true, video_bit_rate, av->vbcb.second); |
609 | } | 606 | } |
610 | 607 | ||
611 | pthread_mutex_unlock(call->mutex); | 608 | pthread_mutex_unlock(call->mutex); |
@@ -618,7 +615,7 @@ END: | |||
618 | return rc == TOXAV_ERR_BIT_RATE_OK; | 615 | return rc == TOXAV_ERR_BIT_RATE_OK; |
619 | } | 616 | } |
620 | 617 | ||
621 | void toxav_callback_audio_bitrate_control(ToxAV* av, toxav_audio_bitrate_control_cb* function, void* user_data) | 618 | void toxav_callback_audio_bit_rate_status(ToxAV* av, toxav_audio_bit_rate_status_cb* function, void* user_data) |
622 | { | 619 | { |
623 | pthread_mutex_lock(av->mutex); | 620 | pthread_mutex_lock(av->mutex); |
624 | av->abcb.first = function; | 621 | av->abcb.first = function; |
@@ -636,7 +633,7 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_ | |||
636 | goto END; | 633 | goto END; |
637 | } | 634 | } |
638 | 635 | ||
639 | if (audio_bitrate_invalid(audio_bit_rate)) { | 636 | if (audio_bit_rate_invalid(audio_bit_rate)) { |
640 | rc = TOXAV_ERR_BIT_RATE_INVALID; | 637 | rc = TOXAV_ERR_BIT_RATE_INVALID; |
641 | goto END; | 638 | goto END; |
642 | } | 639 | } |
@@ -662,7 +659,7 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_ | |||
662 | call->audio_bit_rate = audio_bit_rate; | 659 | call->audio_bit_rate = audio_bit_rate; |
663 | 660 | ||
664 | if (!force && av->abcb.first) | 661 | if (!force && av->abcb.first) |
665 | av->abcb.first (av, call->friend_id, true, audio_bit_rate, av->abcb.second); | 662 | av->abcb.first (av, call->friend_number, true, audio_bit_rate, av->abcb.second); |
666 | } | 663 | } |
667 | 664 | ||
668 | pthread_mutex_unlock(call->mutex); | 665 | pthread_mutex_unlock(call->mutex); |
@@ -897,11 +894,11 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc | |||
897 | } | 894 | } |
898 | 895 | ||
899 | 896 | ||
900 | /* For bitrate measurement; send dummy packet */ | 897 | /* For bit rate measurement; send dummy packet */ |
901 | if (ba_shoud_send_dummy(&call->aba)) { | 898 | if (ba_shoud_send_dummy(&call->aba)) { |
902 | sampling_rate = ntohl(sampling_rate); | 899 | sampling_rate = ntohl(sampling_rate); |
903 | if (ac_reconfigure_test_encoder(call->audio.second, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { | 900 | if (ac_reconfigure_test_encoder(call->audio.second, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { |
904 | /* FIXME should the bitrate changing fail here? */ | 901 | /* FIXME should the bit rate changing fail here? */ |
905 | pthread_mutex_unlock(call->mutex_audio); | 902 | pthread_mutex_unlock(call->mutex_audio); |
906 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 903 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
907 | goto END; | 904 | goto END; |
@@ -966,7 +963,7 @@ int callback_invite(void* toxav_inst, MSICall* call) | |||
966 | ToxAV* toxav = toxav_inst; | 963 | ToxAV* toxav = toxav_inst; |
967 | pthread_mutex_lock(toxav->mutex); | 964 | pthread_mutex_lock(toxav->mutex); |
968 | 965 | ||
969 | ToxAVCall* av_call = call_new(toxav, call->friend_id, NULL); | 966 | ToxAVCall* av_call = call_new(toxav, call->friend_number, NULL); |
970 | if (av_call == NULL) { | 967 | if (av_call == NULL) { |
971 | LOGGER_WARNING("Failed to initialize call..."); | 968 | LOGGER_WARNING("Failed to initialize call..."); |
972 | pthread_mutex_unlock(toxav->mutex); | 969 | pthread_mutex_unlock(toxav->mutex); |
@@ -977,7 +974,7 @@ int callback_invite(void* toxav_inst, MSICall* call) | |||
977 | av_call->msi_call = call; | 974 | av_call->msi_call = call; |
978 | 975 | ||
979 | if (toxav->ccb.first) | 976 | if (toxav->ccb.first) |
980 | toxav->ccb.first(toxav, call->friend_id, call->peer_capabilities & msi_CapSAudio, | 977 | toxav->ccb.first(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, |
981 | call->peer_capabilities & msi_CapSVideo, toxav->ccb.second); | 978 | call->peer_capabilities & msi_CapSVideo, toxav->ccb.second); |
982 | 979 | ||
983 | pthread_mutex_unlock(toxav->mutex); | 980 | pthread_mutex_unlock(toxav->mutex); |
@@ -989,7 +986,7 @@ int callback_start(void* toxav_inst, MSICall* call) | |||
989 | ToxAV* toxav = toxav_inst; | 986 | ToxAV* toxav = toxav_inst; |
990 | pthread_mutex_lock(toxav->mutex); | 987 | pthread_mutex_lock(toxav->mutex); |
991 | 988 | ||
992 | ToxAVCall* av_call = call_get(toxav, call->friend_id); | 989 | ToxAVCall* av_call = call_get(toxav, call->friend_number); |
993 | 990 | ||
994 | if (av_call == NULL) { | 991 | if (av_call == NULL) { |
995 | /* Should this ever happen? */ | 992 | /* Should this ever happen? */ |
@@ -1004,7 +1001,7 @@ int callback_start(void* toxav_inst, MSICall* call) | |||
1004 | return -1; | 1001 | return -1; |
1005 | } | 1002 | } |
1006 | 1003 | ||
1007 | invoke_call_state(toxav, call->friend_id, call->peer_capabilities); | 1004 | invoke_call_state(toxav, call->friend_number, call->peer_capabilities); |
1008 | 1005 | ||
1009 | pthread_mutex_unlock(toxav->mutex); | 1006 | pthread_mutex_unlock(toxav->mutex); |
1010 | return 0; | 1007 | return 0; |
@@ -1015,7 +1012,7 @@ int callback_end(void* toxav_inst, MSICall* call) | |||
1015 | ToxAV* toxav = toxav_inst; | 1012 | ToxAV* toxav = toxav_inst; |
1016 | pthread_mutex_lock(toxav->mutex); | 1013 | pthread_mutex_lock(toxav->mutex); |
1017 | 1014 | ||
1018 | invoke_call_state(toxav, call->friend_id, TOXAV_CALL_STATE_END); | 1015 | invoke_call_state(toxav, call->friend_number, TOXAV_CALL_STATE_END); |
1019 | 1016 | ||
1020 | call_kill_transmission(call->av_call); | 1017 | call_kill_transmission(call->av_call); |
1021 | call_remove(call->av_call); | 1018 | call_remove(call->av_call); |
@@ -1029,7 +1026,7 @@ int callback_error(void* toxav_inst, MSICall* call) | |||
1029 | ToxAV* toxav = toxav_inst; | 1026 | ToxAV* toxav = toxav_inst; |
1030 | pthread_mutex_lock(toxav->mutex); | 1027 | pthread_mutex_lock(toxav->mutex); |
1031 | 1028 | ||
1032 | invoke_call_state(toxav, call->friend_id, TOXAV_CALL_STATE_ERROR); | 1029 | invoke_call_state(toxav, call->friend_number, TOXAV_CALL_STATE_ERROR); |
1033 | 1030 | ||
1034 | call_kill_transmission(call->av_call); | 1031 | call_kill_transmission(call->av_call); |
1035 | call_remove(call->av_call); | 1032 | call_remove(call->av_call); |
@@ -1043,21 +1040,21 @@ int callback_capabilites(void* toxav_inst, MSICall* call) | |||
1043 | ToxAV* toxav = toxav_inst; | 1040 | ToxAV* toxav = toxav_inst; |
1044 | pthread_mutex_lock(toxav->mutex); | 1041 | pthread_mutex_lock(toxav->mutex); |
1045 | 1042 | ||
1046 | invoke_call_state(toxav, call->friend_id, call->peer_capabilities); | 1043 | invoke_call_state(toxav, call->friend_number, call->peer_capabilities); |
1047 | 1044 | ||
1048 | pthread_mutex_unlock(toxav->mutex); | 1045 | pthread_mutex_unlock(toxav->mutex); |
1049 | return 0; | 1046 | return 0; |
1050 | } | 1047 | } |
1051 | 1048 | ||
1052 | bool audio_bitrate_invalid(uint32_t bitrate) | 1049 | bool audio_bit_rate_invalid(uint32_t bit_rate) |
1053 | { | 1050 | { |
1054 | /* Opus RFC 6716 section-2.1.1 dictates the following: | 1051 | /* Opus RFC 6716 section-2.1.1 dictates the following: |
1055 | * Opus supports all bitrates from 6 kbit/s to 510 kbit/s. | 1052 | * Opus supports all bit rates from 6 kbit/s to 510 kbit/s. |
1056 | */ | 1053 | */ |
1057 | return bitrate < 6 || bitrate > 510; | 1054 | return bit_rate < 6 || bit_rate > 510; |
1058 | } | 1055 | } |
1059 | 1056 | ||
1060 | bool video_bitrate_invalid(uint32_t bitrate) | 1057 | bool video_bit_rate_invalid(uint32_t bit_rate) |
1061 | { | 1058 | { |
1062 | /* TODO: If anyone knows the answer to this one please fill it up */ | 1059 | /* TODO: If anyone knows the answer to this one please fill it up */ |
1063 | return false; | 1060 | return false; |
@@ -1099,7 +1096,7 @@ ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) | |||
1099 | } | 1096 | } |
1100 | 1097 | ||
1101 | call->av = av; | 1098 | call->av = av; |
1102 | call->friend_id = friend_number; | 1099 | call->friend_number = friend_number; |
1103 | 1100 | ||
1104 | if (av->calls == NULL) { /* Creating */ | 1101 | if (av->calls == NULL) { /* Creating */ |
1105 | av->calls = calloc (sizeof(ToxAVCall*), friend_number + 1); | 1102 | av->calls = calloc (sizeof(ToxAVCall*), friend_number + 1); |
@@ -1126,7 +1123,7 @@ ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) | |||
1126 | av->calls = tmp; | 1123 | av->calls = tmp; |
1127 | 1124 | ||
1128 | /* Set fields in between to null */ | 1125 | /* Set fields in between to null */ |
1129 | int32_t i = av->calls_tail; | 1126 | int32_t i = av->calls_tail + 1; |
1130 | for (; i < friend_number; i ++) | 1127 | for (; i < friend_number; i ++) |
1131 | av->calls[i] = NULL; | 1128 | av->calls[i] = NULL; |
1132 | 1129 | ||
@@ -1164,7 +1161,7 @@ void call_remove(ToxAVCall* call) | |||
1164 | if (call == NULL) | 1161 | if (call == NULL) |
1165 | return; | 1162 | return; |
1166 | 1163 | ||
1167 | uint32_t friend_id = call->friend_id; | 1164 | uint32_t friend_number = call->friend_number; |
1168 | ToxAV* av = call->av; | 1165 | ToxAV* av = call->av; |
1169 | 1166 | ||
1170 | ToxAVCall* prev = call->prev; | 1167 | ToxAVCall* prev = call->prev; |
@@ -1175,16 +1172,16 @@ void call_remove(ToxAVCall* call) | |||
1175 | if (prev) | 1172 | if (prev) |
1176 | prev->next = next; | 1173 | prev->next = next; |
1177 | else if (next) | 1174 | else if (next) |
1178 | av->calls_head = next->friend_id; | 1175 | av->calls_head = next->friend_number; |
1179 | else goto CLEAR; | 1176 | else goto CLEAR; |
1180 | 1177 | ||
1181 | if (next) | 1178 | if (next) |
1182 | next->prev = prev; | 1179 | next->prev = prev; |
1183 | else if (prev) | 1180 | else if (prev) |
1184 | av->calls_tail = prev->friend_id; | 1181 | av->calls_tail = prev->friend_number; |
1185 | else goto CLEAR; | 1182 | else goto CLEAR; |
1186 | 1183 | ||
1187 | av->calls[friend_id] = NULL; | 1184 | av->calls[friend_number] = NULL; |
1188 | return; | 1185 | return; |
1189 | 1186 | ||
1190 | CLEAR: | 1187 | CLEAR: |
@@ -1214,17 +1211,16 @@ bool call_prepare_transmission(ToxAVCall* call) | |||
1214 | if (create_recursive_mutex(call->mutex_audio) != 0) | 1211 | if (create_recursive_mutex(call->mutex_audio) != 0) |
1215 | return false; | 1212 | return false; |
1216 | 1213 | ||
1217 | if (create_recursive_mutex(call->mutex_video) != 0) { | 1214 | if (create_recursive_mutex(call->mutex_video) != 0) |
1218 | goto AUDIO_SENDING_MUTEX_CLEANUP; | 1215 | goto FAILURE_3; |
1219 | } | 1216 | |
1217 | if (create_recursive_mutex(call->mutex) != 0) | ||
1218 | goto FAILURE_2; | ||
1220 | 1219 | ||
1221 | if (create_recursive_mutex(call->mutex) != 0) { | ||
1222 | goto VIDEO_SENDING_MUTEX_CLEANUP; | ||
1223 | } | ||
1224 | 1220 | ||
1225 | { /* Prepare audio */ | 1221 | { /* Prepare audio */ |
1226 | call->audio.second = ac_new(av, call->friend_id, av->acb.first, av->acb.second); | 1222 | call->audio.second = ac_new(av, call->friend_number, av->acb.first, av->acb.second); |
1227 | call->audio.first = rtp_new(rtp_TypeAudio, av->m, call->friend_id, call->audio.second, ac_queue_message); | 1223 | call->audio.first = rtp_new(rtp_TypeAudio, av->m, call->friend_number, call->audio.second, ac_queue_message); |
1228 | 1224 | ||
1229 | if ( !call->audio.first || !call->audio.second ) { | 1225 | if ( !call->audio.first || !call->audio.second ) { |
1230 | LOGGER_ERROR("Error while starting audio!\n"); | 1226 | LOGGER_ERROR("Error while starting audio!\n"); |
@@ -1233,8 +1229,8 @@ bool call_prepare_transmission(ToxAVCall* call) | |||
1233 | } | 1229 | } |
1234 | 1230 | ||
1235 | { /* Prepare video */ | 1231 | { /* Prepare video */ |
1236 | call->video.second = vc_new(av, call->friend_id, av->vcb.first, av->vcb.second, call->msi_call->peer_vfpsz); | 1232 | call->video.second = vc_new(av, call->friend_number, av->vcb.first, av->vcb.second, call->msi_call->peer_vfpsz); |
1237 | call->video.first = rtp_new(rtp_TypeVideo, av->m, call->friend_id, call->video.second, vc_queue_message); | 1233 | call->video.first = rtp_new(rtp_TypeVideo, av->m, call->friend_number, call->video.second, vc_queue_message); |
1238 | 1234 | ||
1239 | if ( !call->video.first || !call->video.second ) { | 1235 | if ( !call->video.first || !call->video.second ) { |
1240 | LOGGER_ERROR("Error while starting video!\n"); | 1236 | LOGGER_ERROR("Error while starting video!\n"); |
@@ -1255,9 +1251,9 @@ FAILURE: | |||
1255 | call->video.first = NULL; | 1251 | call->video.first = NULL; |
1256 | call->video.second = NULL; | 1252 | call->video.second = NULL; |
1257 | pthread_mutex_destroy(call->mutex); | 1253 | pthread_mutex_destroy(call->mutex); |
1258 | VIDEO_SENDING_MUTEX_CLEANUP: | 1254 | FAILURE_2: |
1259 | pthread_mutex_destroy(call->mutex_video); | 1255 | pthread_mutex_destroy(call->mutex_video); |
1260 | AUDIO_SENDING_MUTEX_CLEANUP: | 1256 | FAILURE_3: |
1261 | pthread_mutex_destroy(call->mutex_audio); | 1257 | pthread_mutex_destroy(call->mutex_audio); |
1262 | return false; | 1258 | return false; |
1263 | } | 1259 | } |
diff --git a/toxav/toxav.h b/toxav/toxav.h index f2c3b2b3..b8db223e 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h | |||
@@ -333,23 +333,23 @@ typedef enum TOXAV_ERR_BIT_RATE { | |||
333 | TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL | 333 | TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL |
334 | } TOXAV_ERR_BIT_RATE; | 334 | } TOXAV_ERR_BIT_RATE; |
335 | /** | 335 | /** |
336 | * The function type for the `audio_bitrate_control` callback. | 336 | * The function type for the `audio_bit_rate_status` callback. |
337 | * | 337 | * |
338 | * @param friend_number The friend number of the friend for which to set the | 338 | * @param friend_number The friend number of the friend for which to set the |
339 | * audio bit rate. | 339 | * audio bit rate. |
340 | * @param good Is the stream good enough to keep the said bitrate. Upon failed | 340 | * @param stable Is the stream stable enough to keep the bit rate. |
341 | * non forceful bit rate setup this will be set to false and 'bit_rate' | 341 | * Upon successful, non forceful, bit rate change, this is set to |
342 | * will be set to the bit rate that failed, otherwise 'good' will be set to | 342 | * true and 'bit_rate' is set to new bit rate. |
343 | * true with 'bit_rate' set to new bit rate. If the stream becomes bad, | 343 | * The stable is set to false with bit_rate set to the unstable |
344 | * the 'good' wil be set to false with 'bit_rate' set to the current bit rate. | 344 | * bit rate when either current stream is unstable with said bit rate |
345 | * This callback will never be called when the stream is good. | 345 | * or the non forceful change failed. |
346 | * @param bit_rate The bit rate in Kb/sec. | 346 | * @param bit_rate The bit rate in Kb/sec. |
347 | */ | 347 | */ |
348 | typedef void toxav_audio_bitrate_control_cb(ToxAV *av, uint32_t friend_number, bool good, uint32_t bit_rate, void *user_data); | 348 | typedef void toxav_audio_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data); |
349 | /** | 349 | /** |
350 | * Set the callback for the `audio_bitrate_control` event. Pass NULL to unset. | 350 | * Set the callback for the `audio_bit_rate_status` event. Pass NULL to unset. |
351 | */ | 351 | */ |
352 | void toxav_callback_audio_bitrate_control(ToxAV *av, toxav_audio_bitrate_control_cb *function, void *user_data); | 352 | void toxav_callback_audio_bit_rate_status(ToxAV *av, toxav_audio_bit_rate_status_cb *function, void *user_data); |
353 | /** | 353 | /** |
354 | * Set the audio bit rate to be used in subsequent audio frames. | 354 | * Set the audio bit rate to be used in subsequent audio frames. |
355 | * | 355 | * |
@@ -362,23 +362,23 @@ void toxav_callback_audio_bitrate_control(ToxAV *av, toxav_audio_bitrate_control | |||
362 | */ | 362 | */ |
363 | bool toxav_set_audio_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_BIT_RATE *error); | 363 | bool toxav_set_audio_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_BIT_RATE *error); |
364 | /** | 364 | /** |
365 | * The function type for the `video_bitrate_control` callback. | 365 | * The function type for the `video_bit_rate_status` callback. |
366 | * | 366 | * |
367 | * @param friend_number The friend number of the friend for which to set the | 367 | * @param friend_number The friend number of the friend for which to set the |
368 | * video bit rate. | 368 | * video bit rate. |
369 | * @param good Is the stream good enough to keep the said bitrate. Upon failed | 369 | * @param stable Is the stream stable enough to keep the bit rate. |
370 | * non forceful bit rate setup this will be set to false and 'bit_rate' | 370 | * Upon successful, non forceful, bit rate change, this is set to |
371 | * will be set to the bit rate that failed, otherwise 'good' will be set to | 371 | * true and 'bit_rate' is set to new bit rate. |
372 | * true with 'bit_rate' set to new bit rate. If the stream becomes bad, | 372 | * The stable is set to false with bit_rate set to the unstable |
373 | * the 'good' wil be set to false with 'bit_rate' set to the current bit rate. | 373 | * bit rate when either current stream is unstable with said bit rate |
374 | * This callback will never be called when the stream is good. | 374 | * or the non forceful change failed. |
375 | * @param bit_rate The bit rate in Kb/sec. | 375 | * @param bit_rate The bit rate in Kb/sec. |
376 | */ | 376 | */ |
377 | typedef void toxav_video_bitrate_control_cb(ToxAV *av, uint32_t friend_number, bool good, uint32_t bit_rate, void *user_data); | 377 | typedef void toxav_video_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data); |
378 | /** | 378 | /** |
379 | * Set the callback for the `video_bitrate_control` event. Pass NULL to unset. | 379 | * Set the callback for the `video_bit_rate_status` event. Pass NULL to unset. |
380 | */ | 380 | */ |
381 | void toxav_callback_video_bitrate_control(ToxAV *av, toxav_video_bitrate_control_cb *function, void *user_data); | 381 | void toxav_callback_video_bit_rate_status(ToxAV *av, toxav_video_bit_rate_status_cb *function, void *user_data); |
382 | /** | 382 | /** |
383 | * Set the video bit rate to be used in subsequent video frames. | 383 | * Set the video bit rate to be used in subsequent video frames. |
384 | * | 384 | * |
diff --git a/toxav/video.c b/toxav/video.c index c540af3b..22ca2bee 100644 --- a/toxav/video.c +++ b/toxav/video.c | |||
@@ -35,15 +35,14 @@ | |||
35 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ | 35 | #define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */ |
36 | #define VIDEOFRAME_HEADER_SIZE 0x2 | 36 | #define VIDEOFRAME_HEADER_SIZE 0x2 |
37 | 37 | ||
38 | /* FIXME: Might not be enough? NOTE: I think it is enough */ | ||
39 | #define VIDEO_DECODE_BUFFER_SIZE 20 | 38 | #define VIDEO_DECODE_BUFFER_SIZE 20 |
40 | 39 | ||
41 | typedef struct { uint16_t size; uint8_t data[]; } Payload; | 40 | typedef struct { uint16_t size; uint8_t data[]; } Payload; |
42 | 41 | ||
43 | bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bitrate); | 42 | bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bit_rate); |
44 | 43 | ||
45 | 44 | ||
46 | VCSession* vc_new(ToxAV* av, uint32_t friend_id, toxav_receive_video_frame_cb* cb, void* cb_data, uint32_t mvfpsz) | 45 | VCSession* vc_new(ToxAV* av, uint32_t friend_number, toxav_receive_video_frame_cb* cb, void* cb_data, uint32_t mvfpsz) |
47 | { | 46 | { |
48 | VCSession *vc = calloc(sizeof(VCSession), 1); | 47 | VCSession *vc = calloc(sizeof(VCSession), 1); |
49 | 48 | ||
@@ -86,7 +85,7 @@ VCSession* vc_new(ToxAV* av, uint32_t friend_id, toxav_receive_video_frame_cb* c | |||
86 | vc->lcfd = 60; | 85 | vc->lcfd = 60; |
87 | vc->vcb.first = cb; | 86 | vc->vcb.first = cb; |
88 | vc->vcb.second = cb_data; | 87 | vc->vcb.second = cb_data; |
89 | vc->friend_id = friend_id; | 88 | vc->friend_number = friend_number; |
90 | vc->peer_video_frame_piece_size = mvfpsz; | 89 | vc->peer_video_frame_piece_size = mvfpsz; |
91 | 90 | ||
92 | return vc; | 91 | return vc; |
@@ -140,7 +139,7 @@ void vc_do(VCSession* vc) | |||
140 | /* Play decoded images */ | 139 | /* Play decoded images */ |
141 | for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) { | 140 | for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) { |
142 | if (vc->vcb.first) | 141 | if (vc->vcb.first) |
143 | vc->vcb.first(vc->av, vc->friend_id, dest->d_w, dest->d_h, | 142 | vc->vcb.first(vc->av, vc->friend_number, dest->d_w, dest->d_h, |
144 | (const uint8_t*)dest->planes[0], (const uint8_t*)dest->planes[1], (const uint8_t*)dest->planes[2], | 143 | (const uint8_t*)dest->planes[0], (const uint8_t*)dest->planes[1], (const uint8_t*)dest->planes[2], |
145 | dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb.second); | 144 | dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb.second); |
146 | 145 | ||
@@ -289,16 +288,16 @@ end: | |||
289 | rtp_free_msg(msg); | 288 | rtp_free_msg(msg); |
290 | return 0; | 289 | return 0; |
291 | } | 290 | } |
292 | int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height) | 291 | int vc_reconfigure_encoder(VCSession* vc, int32_t bit_rate, uint16_t width, uint16_t height) |
293 | { | 292 | { |
294 | if (!vc) | 293 | if (!vc) |
295 | return -1; | 294 | return -1; |
296 | 295 | ||
297 | vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc; | 296 | vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc; |
298 | if (cfg.rc_target_bitrate == bitrate && cfg.g_w == width && cfg.g_h == height) | 297 | if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) |
299 | return 0; /* Nothing changed */ | 298 | return 0; /* Nothing changed */ |
300 | 299 | ||
301 | cfg.rc_target_bitrate = bitrate; | 300 | cfg.rc_target_bitrate = bit_rate; |
302 | cfg.g_w = width; | 301 | cfg.g_w = width; |
303 | cfg.g_h = height; | 302 | cfg.g_h = height; |
304 | 303 | ||
@@ -310,16 +309,16 @@ int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint1 | |||
310 | 309 | ||
311 | return 0; | 310 | return 0; |
312 | } | 311 | } |
313 | int vc_reconfigure_test_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height) | 312 | int vc_reconfigure_test_encoder(VCSession* vc, int32_t bit_rate, uint16_t width, uint16_t height) |
314 | { | 313 | { |
315 | if (!vc) | 314 | if (!vc) |
316 | return -1; | 315 | return -1; |
317 | 316 | ||
318 | vpx_codec_enc_cfg_t cfg = *vc->test_encoder->config.enc; | 317 | vpx_codec_enc_cfg_t cfg = *vc->test_encoder->config.enc; |
319 | if (cfg.rc_target_bitrate == bitrate && cfg.g_w == width && cfg.g_h == height) | 318 | if (cfg.rc_target_bitrate == bit_rate && cfg.g_w == width && cfg.g_h == height) |
320 | return 0; /* Nothing changed */ | 319 | return 0; /* Nothing changed */ |
321 | 320 | ||
322 | cfg.rc_target_bitrate = bitrate; | 321 | cfg.rc_target_bitrate = bit_rate; |
323 | cfg.g_w = width; | 322 | cfg.g_w = width; |
324 | cfg.g_h = height; | 323 | cfg.g_h = height; |
325 | 324 | ||
@@ -334,7 +333,7 @@ int vc_reconfigure_test_encoder(VCSession* vc, int32_t bitrate, uint16_t width, | |||
334 | 333 | ||
335 | 334 | ||
336 | 335 | ||
337 | bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bitrate) | 336 | bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bit_rate) |
338 | { | 337 | { |
339 | assert(dest); | 338 | assert(dest); |
340 | 339 | ||
@@ -354,7 +353,7 @@ bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bitrate) | |||
354 | return false; | 353 | return false; |
355 | } | 354 | } |
356 | 355 | ||
357 | cfg.rc_target_bitrate = bitrate; | 356 | cfg.rc_target_bitrate = bit_rate; |
358 | cfg.g_w = 800; | 357 | cfg.g_w = 800; |
359 | cfg.g_h = 600; | 358 | cfg.g_h = 600; |
360 | cfg.g_pass = VPX_RC_ONE_PASS; | 359 | cfg.g_pass = VPX_RC_ONE_PASS; |
diff --git a/toxav/video.h b/toxav/video.h index 78003ef3..8da15578 100644 --- a/toxav/video.h +++ b/toxav/video.h | |||
@@ -38,6 +38,9 @@ | |||
38 | 38 | ||
39 | struct RTPMessage_s; | 39 | struct RTPMessage_s; |
40 | 40 | ||
41 | /* | ||
42 | * Base Video Codec session type. | ||
43 | */ | ||
41 | typedef struct VCSession_s { | 44 | typedef struct VCSession_s { |
42 | 45 | ||
43 | /* encoding */ | 46 | /* encoding */ |
@@ -65,23 +68,46 @@ typedef struct VCSession_s { | |||
65 | const uint8_t *processing_video_frame; | 68 | const uint8_t *processing_video_frame; |
66 | uint16_t processing_video_frame_size; | 69 | uint16_t processing_video_frame_size; |
67 | 70 | ||
68 | |||
69 | ToxAV *av; | 71 | ToxAV *av; |
70 | int32_t friend_id; | 72 | uint32_t friend_number; |
71 | 73 | ||
72 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ | 74 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ |
73 | 75 | ||
74 | pthread_mutex_t queue_mutex[1]; | 76 | pthread_mutex_t queue_mutex[1]; |
75 | } VCSession; | 77 | } VCSession; |
76 | 78 | ||
77 | VCSession* vc_new(ToxAV* av, uint32_t friend_id, toxav_receive_video_frame_cb *cb, void *cb_data, uint32_t mvfpsz); | 79 | /* |
80 | * Create new Video Codec session. | ||
81 | */ | ||
82 | VCSession* vc_new(ToxAV* av, uint32_t friend_number, toxav_receive_video_frame_cb *cb, void *cb_data, uint32_t mvfpsz); | ||
83 | /* | ||
84 | * Kill the Video Codec session. | ||
85 | */ | ||
78 | void vc_kill(VCSession* vc); | 86 | void vc_kill(VCSession* vc); |
87 | /* | ||
88 | * Do periodic work. Work is consisted out of decoding only. | ||
89 | */ | ||
79 | void vc_do(VCSession* vc); | 90 | void vc_do(VCSession* vc); |
91 | /* | ||
92 | * Set new video splitting cycle. This is requirement in order to send video packets. | ||
93 | */ | ||
80 | void vc_init_video_splitter_cycle(VCSession* vc); | 94 | void vc_init_video_splitter_cycle(VCSession* vc); |
95 | /* | ||
96 | * Update the video splitter cycle with new data. | ||
97 | */ | ||
81 | int vc_update_video_splitter_cycle(VCSession* vc, const uint8_t* payload, uint16_t length); | 98 | int vc_update_video_splitter_cycle(VCSession* vc, const uint8_t* payload, uint16_t length); |
99 | /* | ||
100 | * Iterate over splitted cycle. | ||
101 | */ | ||
82 | const uint8_t *vc_iterate_split_video_frame(VCSession* vc, uint16_t *size); | 102 | const uint8_t *vc_iterate_split_video_frame(VCSession* vc, uint16_t *size); |
103 | /* | ||
104 | * Queue new rtp message. | ||
105 | */ | ||
83 | int vc_queue_message(void *vcp, struct RTPMessage_s *msg); | 106 | int vc_queue_message(void *vcp, struct RTPMessage_s *msg); |
84 | int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height); | 107 | /* |
85 | int vc_reconfigure_test_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height); | 108 | * Set new values to the encoders. |
109 | */ | ||
110 | int vc_reconfigure_encoder(VCSession* vc, int32_t bit_rate, uint16_t width, uint16_t height); | ||
111 | int vc_reconfigure_test_encoder(VCSession* vc, int32_t bit_rate, uint16_t width, uint16_t height); | ||
86 | 112 | ||
87 | #endif /* VIDEO_H */ \ No newline at end of file | 113 | #endif /* VIDEO_H */ \ No newline at end of file |