summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c262
1 files changed, 137 insertions, 125 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index b40a1c02..f704bc6b 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -1,5 +1,5 @@
1/** toxav.c 1/** toxav.c
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -44,27 +44,26 @@ typedef enum {
44 ts_closing, 44 ts_closing,
45 ts_running, 45 ts_running,
46 ts_closed 46 ts_closed
47 47
48} ThreadState; 48} ThreadState;
49 49
50typedef struct _ToxAv 50typedef struct _ToxAv {
51{ 51 Messenger *messenger;
52 Messenger* messenger; 52
53 53 MSISession *msi_session; /** Main msi session */
54 MSISession* msi_session; /** Main msi session */ 54
55 55 RTPSession *rtp_sessions[2]; /* Audio is first and video is second */
56 RTPSession* rtp_sessions[2]; /* Audio is first and video is second */ 56
57 57 struct jitter_buffer *j_buf;
58 struct jitter_buffer* j_buf; 58 CodecState *cs;
59 CodecState* cs; 59
60 60 void *agent_handler;
61 void* agent_handler;
62} ToxAv; 61} ToxAv;
63 62
64/** 63/**
65 * @brief Start new A/V session. There can only be one session at the time. If you register more 64 * @brief Start new A/V session. There can only be one session at the time. If you register more
66 * it will result in undefined behaviour. 65 * it will result in undefined behaviour.
67 * 66 *
68 * @param messenger The messenger handle. 67 * @param messenger The messenger handle.
69 * @param useragent The agent handling A/V session (i.e. phone). 68 * @param useragent The agent handling A/V session (i.e. phone).
70 * @param ua_name Useragent name. 69 * @param ua_name Useragent name.
@@ -73,67 +72,69 @@ typedef struct _ToxAv
73 * @return ToxAv* 72 * @return ToxAv*
74 * @retval NULL On error. 73 * @retval NULL On error.
75 */ 74 */
76ToxAv* toxav_new( Tox* messenger, void* useragent, const char* ua_name , uint16_t video_width, uint16_t video_height) 75ToxAv *toxav_new( Tox *messenger, void *useragent, const char *ua_name , uint16_t video_width, uint16_t video_height)
77{ 76{
78 ToxAv* av = calloc ( sizeof(ToxAv), 1); 77 ToxAv *av = calloc ( sizeof(ToxAv), 1);
78
79 if (av == NULL) 79 if (av == NULL)
80 return NULL; 80 return NULL;
81 81
82 av->messenger = (Messenger *)messenger; 82 av->messenger = (Messenger *)messenger;
83 83
84 av->msi_session = msi_init_session(av->messenger, (const unsigned char*) ua_name ); 84 av->msi_session = msi_init_session(av->messenger, (const unsigned char *) ua_name );
85 av->msi_session->agent_handler = av; 85 av->msi_session->agent_handler = av;
86 86
87 av->rtp_sessions[0] = av->rtp_sessions [1] = NULL; 87 av->rtp_sessions[0] = av->rtp_sessions [1] = NULL;
88 88
89 /* NOTE: This should be user defined or? */ 89 /* NOTE: This should be user defined or? */
90 av->j_buf = create_queue(20); 90 av->j_buf = create_queue(20);
91 91
92 av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width, video_height, VIDEO_BITRATE); 92 av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width,
93 93 video_height, VIDEO_BITRATE);
94
94 av->agent_handler = useragent; 95 av->agent_handler = useragent;
95 96
96 return av; 97 return av;
97} 98}
98 99
99/** 100/**
100 * @brief Remove A/V session. 101 * @brief Remove A/V session.
101 * 102 *
102 * @param av Handler. 103 * @param av Handler.
103 * @return void 104 * @return void
104 */ 105 */
105void toxav_kill ( ToxAv* av ) 106void toxav_kill ( ToxAv *av )
106{ 107{
107 msi_terminate_session(av->msi_session); 108 msi_terminate_session(av->msi_session);
108 109
109 if ( av->rtp_sessions[audio_index] ) { 110 if ( av->rtp_sessions[audio_index] ) {
110 rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle); 111 rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle);
111 } 112 }
112 113
113 if ( av->rtp_sessions[video_index] ) { 114 if ( av->rtp_sessions[video_index] ) {
114 rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle); 115 rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle);
115 } 116 }
116 117
117 codec_terminate_session(av->cs); 118 codec_terminate_session(av->cs);
118 119
119 free(av); 120 free(av);
120} 121}
121 122
122/** 123/**
123 * @brief Register callback for call state. 124 * @brief Register callback for call state.
124 * 125 *
125 * @param callback The callback 126 * @param callback The callback
126 * @param id One of the ToxAvCallbackID values 127 * @param id One of the ToxAvCallbackID values
127 * @return void 128 * @return void
128 */ 129 */
129void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id ) 130void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id )
130{ 131{
131 msi_register_callback((MSICallback)callback, (MSICallbackID) id); 132 msi_register_callback((MSICallback)callback, (MSICallbackID) id);
132} 133}
133 134
134/** 135/**
135 * @brief Call user. Use its friend_id. 136 * @brief Call user. Use its friend_id.
136 * 137 *
137 * @param av Handler. 138 * @param av Handler.
138 * @param user The user. 139 * @param user The user.
139 * @param call_type Call type. 140 * @param call_type Call type.
@@ -142,68 +143,68 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID
142 * @retval 0 Success. 143 * @retval 0 Success.
143 * @retval ToxAvError On error. 144 * @retval ToxAvError On error.
144 */ 145 */
145int toxav_call (ToxAv* av, int user, ToxAvCallType call_type, int ringing_seconds ) 146int toxav_call (ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds )
146{ 147{
147 if ( av->msi_session->call ) { 148 if ( av->msi_session->call ) {
148 return ErrorAlreadyInCall; 149 return ErrorAlreadyInCall;
149 } 150 }
150 151
151 return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user); 152 return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user);
152} 153}
153 154
154/** 155/**
155 * @brief Hangup active call. 156 * @brief Hangup active call.
156 * 157 *
157 * @param av Handler. 158 * @param av Handler.
158 * @return int 159 * @return int
159 * @retval 0 Success. 160 * @retval 0 Success.
160 * @retval ToxAvError On error. 161 * @retval ToxAvError On error.
161 */ 162 */
162int toxav_hangup ( ToxAv* av ) 163int toxav_hangup ( ToxAv *av )
163{ 164{
164 if ( !av->msi_session->call ) { 165 if ( !av->msi_session->call ) {
165 return ErrorNoCall; 166 return ErrorNoCall;
166 } 167 }
167 168
168 if ( av->msi_session->call->state != call_active ) { 169 if ( av->msi_session->call->state != call_active ) {
169 return ErrorInvalidState; 170 return ErrorInvalidState;
170 } 171 }
171 172
172 return msi_hangup(av->msi_session); 173 return msi_hangup(av->msi_session);
173} 174}
174 175
175/** 176/**
176 * @brief Answer incomming call. 177 * @brief Answer incomming call.
177 * 178 *
178 * @param av Handler. 179 * @param av Handler.
179 * @param call_type Answer with... 180 * @param call_type Answer with...
180 * @return int 181 * @return int
181 * @retval 0 Success. 182 * @retval 0 Success.
182 * @retval ToxAvError On error. 183 * @retval ToxAvError On error.
183 */ 184 */
184int toxav_answer ( ToxAv* av, ToxAvCallType call_type ) 185int toxav_answer ( ToxAv *av, ToxAvCallType call_type )
185{ 186{
186 if ( !av->msi_session->call ) { 187 if ( !av->msi_session->call ) {
187 return ErrorNoCall; 188 return ErrorNoCall;
188 } 189 }
189 190
190 if ( av->msi_session->call->state != call_starting ) { 191 if ( av->msi_session->call->state != call_starting ) {
191 return ErrorInvalidState; 192 return ErrorInvalidState;
192 } 193 }
193 194
194 return msi_answer(av->msi_session, call_type); 195 return msi_answer(av->msi_session, call_type);
195} 196}
196 197
197/** 198/**
198 * @brief Reject incomming call. 199 * @brief Reject incomming call.
199 * 200 *
200 * @param av Handler. 201 * @param av Handler.
201 * @param reason Optional reason. Set NULL if none. 202 * @param reason Optional reason. Set NULL if none.
202 * @return int 203 * @return int
203 * @retval 0 Success. 204 * @retval 0 Success.
204 * @retval ToxAvError On error. 205 * @retval ToxAvError On error.
205 */ 206 */
206int toxav_reject ( ToxAv* av, const char* reason ) 207int toxav_reject ( ToxAv *av, const char *reason )
207{ 208{
208 if ( !av->msi_session->call ) { 209 if ( !av->msi_session->call ) {
209 return ErrorNoCall; 210 return ErrorNoCall;
@@ -213,126 +214,127 @@ int toxav_reject ( ToxAv* av, const char* reason )
213 return ErrorInvalidState; 214 return ErrorInvalidState;
214 } 215 }
215 216
216 return msi_reject(av->msi_session, (const uint8_t*) reason); 217 return msi_reject(av->msi_session, (const uint8_t *) reason);
217} 218}
218 219
219/** 220/**
220 * @brief Cancel outgoing request. 221 * @brief Cancel outgoing request.
221 * 222 *
222 * @param av Handler. 223 * @param av Handler.
223 * @param reason Optional reason. 224 * @param reason Optional reason.
224 * @return int 225 * @return int
225 * @retval 0 Success. 226 * @retval 0 Success.
226 * @retval ToxAvError On error. 227 * @retval ToxAvError On error.
227 */ 228 */
228int toxav_cancel ( ToxAv* av, const char* reason ) 229int toxav_cancel ( ToxAv *av, const char *reason )
229{ 230{
230 if ( !av->msi_session->call ) { 231 if ( !av->msi_session->call ) {
231 return ErrorNoCall; 232 return ErrorNoCall;
232 } 233 }
233 234
234 return msi_cancel(av->msi_session, 0, (const uint8_t*)reason); 235 return msi_cancel(av->msi_session, 0, (const uint8_t *)reason);
235} 236}
236 237
237/** 238/**
238 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. 239 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
239 * 240 *
240 * @param av Handler. 241 * @param av Handler.
241 * @return int 242 * @return int
242 * @retval 0 Success. 243 * @retval 0 Success.
243 * @retval ToxAvError On error. 244 * @retval ToxAvError On error.
244 */ 245 */
245int toxav_stop_call ( ToxAv* av ) 246int toxav_stop_call ( ToxAv *av )
246{ 247{
247 if ( !av->msi_session->call ) { 248 if ( !av->msi_session->call ) {
248 return ErrorNoCall; 249 return ErrorNoCall;
249 } 250 }
250 251
251 return msi_stopcall(av->msi_session); 252 return msi_stopcall(av->msi_session);
252} 253}
253 254
254/** 255/**
255 * @brief Must be call before any RTP transmission occurs. 256 * @brief Must be call before any RTP transmission occurs.
256 * 257 *
257 * @param av Handler. 258 * @param av Handler.
258 * @return int 259 * @return int
259 * @retval 0 Success. 260 * @retval 0 Success.
260 * @retval ToxAvError On error. 261 * @retval ToxAvError On error.
261 */ 262 */
262int toxav_prepare_transmission ( ToxAv* av ) 263int toxav_prepare_transmission ( ToxAv *av )
263{ 264{
264 assert(av->msi_session); 265 assert(av->msi_session);
266
265 if ( !av->msi_session || !av->msi_session->call ) { 267 if ( !av->msi_session || !av->msi_session->call ) {
266 return ErrorNoCall; 268 return ErrorNoCall;
267 } 269 }
268 270
269 av->rtp_sessions[audio_index] = rtp_init_session( 271 av->rtp_sessions[audio_index] = rtp_init_session(
270 type_audio, 272 type_audio,
271 av->messenger, 273 av->messenger,
272 av->msi_session->call->peers[0], 274 av->msi_session->call->peers[0],
273 av->msi_session->call->key_peer, 275 av->msi_session->call->key_peer,
274 av->msi_session->call->key_local, 276 av->msi_session->call->key_local,
275 av->msi_session->call->nonce_peer, 277 av->msi_session->call->nonce_peer,
276 av->msi_session->call->nonce_local 278 av->msi_session->call->nonce_local
277 ); 279 );
278 280
279 281
280 if ( !av->rtp_sessions[audio_index] ) { 282 if ( !av->rtp_sessions[audio_index] ) {
281 fprintf(stderr, "Error while starting audio RTP session!\n"); 283 fprintf(stderr, "Error while starting audio RTP session!\n");
282 return ErrorStartingAudioRtp; 284 return ErrorStartingAudioRtp;
283 } 285 }
284 286
285 av->rtp_sessions[video_index] = rtp_init_session ( 287 av->rtp_sessions[video_index] = rtp_init_session (
286 type_video, 288 type_video,
287 av->messenger, 289 av->messenger,
288 av->msi_session->call->peers[0], 290 av->msi_session->call->peers[0],
289 av->msi_session->call->key_peer, 291 av->msi_session->call->key_peer,
290 av->msi_session->call->key_local, 292 av->msi_session->call->key_local,
291 av->msi_session->call->nonce_peer, 293 av->msi_session->call->nonce_peer,
292 av->msi_session->call->nonce_local 294 av->msi_session->call->nonce_local
293 ); 295 );
294 296
295 297
296 if ( !av->rtp_sessions[video_index] ) { 298 if ( !av->rtp_sessions[video_index] ) {
297 fprintf(stderr, "Error while starting video RTP session!\n"); 299 fprintf(stderr, "Error while starting video RTP session!\n");
298 return ErrorStartingVideoRtp; 300 return ErrorStartingVideoRtp;
299 } 301 }
300 302
301 return ErrorNone; 303 return ErrorNone;
302} 304}
303 305
304/** 306/**
305 * @brief Call this at the end of the transmission. 307 * @brief Call this at the end of the transmission.
306 * 308 *
307 * @param av Handler. 309 * @param av Handler.
308 * @return int 310 * @return int
309 * @retval 0 Success. 311 * @retval 0 Success.
310 * @retval ToxAvError On error. 312 * @retval ToxAvError On error.
311 */ 313 */
312int toxav_kill_transmission ( ToxAv* av ) 314int toxav_kill_transmission ( ToxAv *av )
313{ 315{
314 /* Both sessions should be active at any time */ 316 /* Both sessions should be active at any time */
315 if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] ) 317 if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] )
316 return ErrorNoTransmission; 318 return ErrorNoTransmission;
317 319
318 320
319 if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) { 321 if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
320 fprintf(stderr, "Error while terminating audio RTP session!\n"); 322 fprintf(stderr, "Error while terminating audio RTP session!\n");
321 return ErrorTerminatingAudioRtp; 323 return ErrorTerminatingAudioRtp;
322 } 324 }
323 325
324 if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) { 326 if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) {
325 fprintf(stderr, "Error while terminating video RTP session!\n"); 327 fprintf(stderr, "Error while terminating video RTP session!\n");
326 return ErrorTerminatingVideoRtp; 328 return ErrorTerminatingVideoRtp;
327 } 329 }
328 330
329 return ErrorNone; 331 return ErrorNone;
330} 332}
331 333
332 334
333/** 335/**
334 * @brief Send RTP payload. 336 * @brief Send RTP payload.
335 * 337 *
336 * @param av Handler. 338 * @param av Handler.
337 * @param type Type of payload. 339 * @param type Type of payload.
338 * @param payload The payload. 340 * @param payload The payload.
@@ -341,7 +343,7 @@ int toxav_kill_transmission ( ToxAv* av )
341 * @retval 0 Success. 343 * @retval 0 Success.
342 * @retval -1 Failure. 344 * @retval -1 Failure.
343 */ 345 */
344inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8_t* payload, uint16_t length ) 346inline__ int toxav_send_rtp_payload ( ToxAv *av, ToxAvCallType type, const uint8_t *payload, uint16_t length )
345{ 347{
346 if ( av->rtp_sessions[type - TypeAudio] ) 348 if ( av->rtp_sessions[type - TypeAudio] )
347 return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length ); 349 return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length );
@@ -350,7 +352,7 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8
350 352
351/** 353/**
352 * @brief Receive RTP payload. 354 * @brief Receive RTP payload.
353 * 355 *
354 * @param av Handler. 356 * @param av Handler.
355 * @param type Type of the payload. 357 * @param type Type of the payload.
356 * @param dest Storage. 358 * @param dest Storage.
@@ -358,123 +360,131 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8
358 * @retval ToxAvError On Error. 360 * @retval ToxAvError On Error.
359 * @retval >=0 Size of received payload. 361 * @retval >=0 Size of received payload.
360 */ 362 */
361inline__ int toxav_recv_rtp_payload ( ToxAv* av, ToxAvCallType type, uint8_t* dest ) 363inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *dest )
362{ 364{
363 if ( !dest ) return ErrorInternal; 365 if ( !dest ) return ErrorInternal;
364 366
365 if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession; 367 if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession;
366 368
367 RTPMessage* message; 369 RTPMessage *message;
368 370
369 if ( type == TypeAudio ) { 371 if ( type == TypeAudio ) {
370 372
371 do { 373 do {
372 message = rtp_recv_msg(av->rtp_sessions[audio_index]); 374 message = rtp_recv_msg(av->rtp_sessions[audio_index]);
373 375
374 if (message) { 376 if (message) {
375 /* push the packet into the queue */ 377 /* push the packet into the queue */
376 queue(av->j_buf, message); 378 queue(av->j_buf, message);
377 } 379 }
378 } while(message); 380 } while (message);
379 381
380 int success = 0; 382 int success = 0;
381 message = dequeue(av->j_buf, &success); 383 message = dequeue(av->j_buf, &success);
382 384
383 if ( success == 2) return ErrorAudioPacketLost; 385 if ( success == 2) return ErrorAudioPacketLost;
384 } 386 } else {
385 else {
386 message = rtp_recv_msg(av->rtp_sessions[video_index]); 387 message = rtp_recv_msg(av->rtp_sessions[video_index]);
387 } 388 }
388 389
389 if ( message ) { 390 if ( message ) {
390 memcpy(dest, message->data, message->length); 391 memcpy(dest, message->data, message->length);
391 392
392 int length = message->length; 393 int length = message->length;
393 394
394 rtp_free_msg(NULL, message); 395 rtp_free_msg(NULL, message);
395 396
396 return length; 397 return length;
397 } 398 }
398 399
399 return 0; 400 return 0;
400} 401}
401 402
402/** 403/**
403 * @brief Receive decoded video packet. 404 * @brief Receive decoded video packet.
404 * 405 *
405 * @param av Handler. 406 * @param av Handler.
406 * @param output Storage. 407 * @param output Storage.
407 * @return int 408 * @return int
408 * @retval 0 Success. 409 * @retval 0 Success.
409 * @retval ToxAvError On Error. 410 * @retval ToxAvError On Error.
410 */ 411 */
411inline__ int toxav_recv_video ( ToxAv* av, vpx_image_t **output) 412inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
412{ 413{
413 if ( !output ) return ErrorInternal; 414 if ( !output ) return ErrorInternal;
415
414 uint8_t packet [RTP_PAYLOAD_SIZE]; 416 uint8_t packet [RTP_PAYLOAD_SIZE];
415 int recved_size = 0; 417 int recved_size = 0;
418
416 do { 419 do {
417 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet); 420 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet);
421
418 if (recved_size > 0) { 422 if (recved_size > 0) {
419 printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0))); 423 printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0)));
420 } 424 }
421 }while (recved_size > 0); 425 } while (recved_size > 0);
426
422 vpx_codec_iter_t iter = NULL; 427 vpx_codec_iter_t iter = NULL;
423 vpx_image_t *img; 428 vpx_image_t *img;
424 img = vpx_codec_get_frame(&av->cs->v_decoder, &iter); 429 img = vpx_codec_get_frame(&av->cs->v_decoder, &iter);
430
425 if (img == NULL) 431 if (img == NULL)
426 return ErrorInternal; 432 return ErrorInternal;
427 433
428 *output = img; 434 *output = img;
429 return 0; 435 return 0;
430} 436}
431 437
432/** 438/**
433 * @brief Encode and send video packet. 439 * @brief Encode and send video packet.
434 * 440 *
435 * @param av Handler. 441 * @param av Handler.
436 * @param input The packet. 442 * @param input The packet.
437 * @return int 443 * @return int
438 * @retval 0 Success. 444 * @retval 0 Success.
439 * @retval ToxAvError On error. 445 * @retval ToxAvError On error.
440 */ 446 */
441inline__ int toxav_send_video ( ToxAv* av, vpx_image_t *input) 447inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
442{ 448{
443 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) { 449 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) {
444 printf("could not encode video frame\n"); 450 printf("could not encode video frame\n");
445 return ErrorInternal; 451 return ErrorInternal;
446 } 452 }
453
447 ++av->cs->frame_counter; 454 ++av->cs->frame_counter;
448 455
449 vpx_codec_iter_t iter = NULL; 456 vpx_codec_iter_t iter = NULL;
450 const vpx_codec_cx_pkt_t *pkt; 457 const vpx_codec_cx_pkt_t *pkt;
451 int sent = 0; 458 int sent = 0;
452 while( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) { 459
460 while ( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) {
453 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 461 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
454 if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1) 462 if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1)
455 ++sent; 463 ++sent;
456 } 464 }
457 } 465 }
466
458 if (sent > 0) 467 if (sent > 0)
459 return 0; 468 return 0;
460 469
461 return ErrorInternal; 470 return ErrorInternal;
462} 471}
463 472
464/** 473/**
465 * @brief Receive decoded audio frame. 474 * @brief Receive decoded audio frame.
466 * 475 *
467 * @param av Handler. 476 * @param av Handler.
468 * @param frame_size ... 477 * @param frame_size ...
469 * @param dest Destination of the packet. Make sure it has enough space for 478 * @param dest Destination of the packet. Make sure it has enough space for
470 * RTP_PAYLOAD_SIZE bytes. 479 * RTP_PAYLOAD_SIZE bytes.
471 * @return int 480 * @return int
472 * @retval >=0 Size of received packet. 481 * @retval >=0 Size of received packet.
473 * @retval ToxAvError On error. 482 * @retval ToxAvError On error.
474 */ 483 */
475inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) 484inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest )
476{ 485{
477 if ( !dest ) return ErrorInternal; 486 if ( !dest ) return ErrorInternal;
487
478 uint8_t packet [RTP_PAYLOAD_SIZE]; 488 uint8_t packet [RTP_PAYLOAD_SIZE];
479 489
480 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet); 490 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet);
@@ -482,7 +492,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
482 if ( recved_size == ErrorAudioPacketLost ) { 492 if ( recved_size == ErrorAudioPacketLost ) {
483 printf("Lost packet\n"); 493 printf("Lost packet\n");
484 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1); 494 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
485 } else if ( recved_size ){ 495 } else if ( recved_size ) {
486 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); 496 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
487 } else { 497 } else {
488 return 0; /* Nothing received */ 498 return 0; /* Nothing received */
@@ -491,7 +501,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
491 501
492/** 502/**
493 * @brief Encode and send audio frame. 503 * @brief Encode and send audio frame.
494 * 504 *
495 * @param av Handler. 505 * @param av Handler.
496 * @param frame The frame. 506 * @param frame The frame.
497 * @param frame_size It's size. 507 * @param frame_size It's size.
@@ -499,10 +509,11 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
499 * @retval 0 Success. 509 * @retval 0 Success.
500 * @retval ToxAvError On error. 510 * @retval ToxAvError On error.
501 */ 511 */
502inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size) 512inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size)
503{ 513{
504 uint8_t temp_data[RTP_PAYLOAD_SIZE]; 514 uint8_t temp_data[RTP_PAYLOAD_SIZE];
505 int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data)); 515 int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data));
516
506 if (ret <= 0) 517 if (ret <= 0)
507 return ErrorInternal; 518 return ErrorInternal;
508 519
@@ -511,29 +522,30 @@ inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size)
511 522
512/** 523/**
513 * @brief Get peer transmission type. It can either be audio or video. 524 * @brief Get peer transmission type. It can either be audio or video.
514 * 525 *
515 * @param av Handler. 526 * @param av Handler.
516 * @param peer The peer 527 * @param peer The peer
517 * @return int 528 * @return int
518 * @retval ToxAvCallType On success. 529 * @retval ToxAvCallType On success.
519 * @retval ToxAvError On error. 530 * @retval ToxAvError On error.
520 */ 531 */
521int toxav_get_peer_transmission_type ( ToxAv* av, int peer ) 532int toxav_get_peer_transmission_type ( ToxAv *av, int peer )
522{ 533{
523 assert(av->msi_session); 534 assert(av->msi_session);
535
524 if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer ) 536 if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer )
525 return ErrorInternal; 537 return ErrorInternal;
526 538
527 return av->msi_session->call->type_peer[peer]; 539 return av->msi_session->call->type_peer[peer];
528} 540}
529 541
530/** 542/**
531 * @brief Get reference to an object that is handling av session. 543 * @brief Get reference to an object that is handling av session.
532 * 544 *
533 * @param av Handler. 545 * @param av Handler.
534 * @return void* 546 * @return void*
535 */ 547 */
536void* toxav_get_agent_handler ( ToxAv* av ) 548void *toxav_get_agent_handler ( ToxAv *av )
537{ 549{
538 return av->agent_handler; 550 return av->agent_handler;
539} 551}