summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxav/codec.c9
-rw-r--r--toxav/msi.c62
-rw-r--r--toxav/rtp.c12
-rw-r--r--toxav/rtp.h2
-rw-r--r--toxav/toxav.c117
5 files changed, 115 insertions, 87 deletions
diff --git a/toxav/codec.c b/toxav/codec.c
index a5946b38..ed0c8e54 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -80,8 +80,12 @@ JitterBuffer *create_queue(int capacity)
80 80
81void terminate_queue(JitterBuffer *q) 81void terminate_queue(JitterBuffer *q)
82{ 82{
83 if (!q) return;
84
83 empty_queue(q); 85 empty_queue(q);
84 free(q->queue); 86 free(q->queue);
87
88 LOGGER_DEBUG("Terminated jitter buffer: %p", q);
85 free(q); 89 free(q);
86} 90}
87 91
@@ -355,6 +359,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
355 359
356void codec_terminate_session ( CodecState *cs ) 360void codec_terminate_session ( CodecState *cs )
357{ 361{
362 if (!cs) return;
363
358 if ( cs->audio_encoder ) 364 if ( cs->audio_encoder )
359 opus_encoder_destroy(cs->audio_encoder); 365 opus_encoder_destroy(cs->audio_encoder);
360 366
@@ -366,6 +372,9 @@ void codec_terminate_session ( CodecState *cs )
366 372
367 if ( cs->capabilities & v_encoding ) 373 if ( cs->capabilities & v_encoding )
368 vpx_codec_destroy(&cs->v_encoder); 374 vpx_codec_destroy(&cs->v_encoder);
375
376 LOGGER_DEBUG("Terminated codec state: %p", cs);
377 free(cs);
369} 378}
370 379
371inline float calculate_sum_sq (int16_t *n, uint16_t k) 380inline float calculate_sum_sq (int16_t *n, uint16_t k)
diff --git a/toxav/msi.c b/toxav/msi.c
index 3a0577ae..999f86b6 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -1043,12 +1043,12 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
1043 return NULL; 1043 return NULL;
1044 } 1044 }
1045 1045
1046 int32_t _call_idx = 0; 1046 int32_t call_idx = 0;
1047 1047
1048 for (; _call_idx < session->max_calls; _call_idx ++) { 1048 for (; call_idx < session->max_calls; call_idx ++) {
1049 if ( !session->calls[_call_idx] ) { 1049 if ( !session->calls[call_idx] ) {
1050 1050
1051 if (!(session->calls[_call_idx] = calloc ( sizeof ( MSICall ), 1 ))) { 1051 if (!(session->calls[call_idx] = calloc ( sizeof ( MSICall ), 1 ))) {
1052 LOGGER_WARNING("Allocation failed! Program might misbehave!"); 1052 LOGGER_WARNING("Allocation failed! Program might misbehave!");
1053 return NULL; 1053 return NULL;
1054 } 1054 }
@@ -1057,35 +1057,35 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
1057 } 1057 }
1058 } 1058 }
1059 1059
1060 if ( _call_idx == session->max_calls ) { 1060 if ( call_idx == session->max_calls ) {
1061 LOGGER_WARNING("Reached maximum amount of calls!"); 1061 LOGGER_WARNING("Reached maximum amount of calls!");
1062 return NULL; 1062 return NULL;
1063 } 1063 }
1064 1064
1065 1065
1066 MSICall *_call = session->calls[_call_idx]; 1066 MSICall *call = session->calls[call_idx];
1067 1067
1068 _call->call_idx = _call_idx; 1068 call->call_idx = call_idx;
1069 1069
1070 if ( !(_call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) { 1070 if ( !(call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) {
1071 LOGGER_WARNING("Allocation failed! Program might misbehave!"); 1071 LOGGER_WARNING("Allocation failed! Program might misbehave!");
1072 free(_call); 1072 free(call);
1073 return NULL; 1073 return NULL;
1074 } 1074 }
1075 1075
1076 _call->session = session; 1076 call->session = session;
1077 1077
1078 /*_call->_participant_count = _peers;*/ 1078 /*_call->_participant_count = _peers;*/
1079 1079
1080 _call->request_timer_id = 0; 1080 call->request_timer_id = 0;
1081 _call->ringing_timer_id = 0; 1081 call->ringing_timer_id = 0;
1082 1082
1083 _call->ringing_tout_ms = ringing_timeout; 1083 call->ringing_tout_ms = ringing_timeout;
1084 1084
1085 pthread_mutex_init ( &_call->mutex, NULL ); 1085 pthread_mutex_init ( &call->mutex, NULL );
1086 1086
1087 LOGGER_DEBUG("Started new call with index: %u", _call_idx); 1087 LOGGER_DEBUG("Started new call with index: %u", call_idx);
1088 return _call; 1088 return call;
1089} 1089}
1090 1090
1091 1091
@@ -1603,38 +1603,38 @@ MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls )
1603 return NULL; 1603 return NULL;
1604 } 1604 }
1605 1605
1606 MSISession *_retu = calloc ( sizeof ( MSISession ), 1 ); 1606 MSISession *retu = calloc ( sizeof ( MSISession ), 1 );
1607 1607
1608 if (_retu == NULL) { 1608 if (retu == NULL) {
1609 LOGGER_ERROR("Allocation failed! Program might misbehave!"); 1609 LOGGER_ERROR("Allocation failed! Program might misbehave!");
1610 return NULL; 1610 return NULL;
1611 } 1611 }
1612 1612
1613 _retu->messenger_handle = messenger; 1613 retu->messenger_handle = messenger;
1614 _retu->agent_handler = NULL; 1614 retu->agent_handler = NULL;
1615 _retu->timer_handler = handler; 1615 retu->timer_handler = handler;
1616 1616
1617 if (!(_retu->calls = calloc( sizeof (MSICall *), max_calls ))) { 1617 if (!(retu->calls = calloc( sizeof (MSICall *), max_calls ))) {
1618 LOGGER_ERROR("Allocation failed! Program might misbehave!"); 1618 LOGGER_ERROR("Allocation failed! Program might misbehave!");
1619 free(_retu); 1619 free(retu);
1620 return NULL; 1620 return NULL;
1621 } 1621 }
1622 1622
1623 _retu->max_calls = max_calls; 1623 retu->max_calls = max_calls;
1624 1624
1625 _retu->frequ = 10000; /* default value? */ 1625 retu->frequ = 10000; /* default value? */
1626 _retu->call_timeout = 30000; /* default value? */ 1626 retu->call_timeout = 30000; /* default value? */
1627 1627
1628 1628
1629 m_callback_msi_packet(messenger, msi_handle_packet, _retu ); 1629 m_callback_msi_packet(messenger, msi_handle_packet, retu );
1630 1630
1631 /* This is called when remote terminates session */ 1631 /* This is called when remote terminates session */
1632 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu); 1632 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, retu);
1633 1633
1634 pthread_mutex_init(&_retu->mutex, NULL); 1634 pthread_mutex_init(&retu->mutex, NULL);
1635 1635
1636 LOGGER_DEBUG("New msi session: %p max calls: %u", _retu, max_calls); 1636 LOGGER_DEBUG("New msi session: %p max calls: %u", retu, max_calls);
1637 return _retu; 1637 return retu;
1638} 1638}
1639 1639
1640 1640
diff --git a/toxav/rtp.c b/toxav/rtp.c
index aa5e2635..653a22df 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -703,12 +703,9 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien
703 * @retval -1 Error occurred. 703 * @retval -1 Error occurred.
704 * @retval 0 Success. 704 * @retval 0 Success.
705 */ 705 */
706int rtp_terminate_session ( RTPSession *session, Messenger *messenger ) 706void rtp_terminate_session ( RTPSession *session, Messenger *messenger )
707{ 707{
708 if ( !session ) { 708 if ( !session ) return;
709 LOGGER_WARNING("No session!");
710 return -1;
711 }
712 709
713 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); 710 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
714 711
@@ -723,8 +720,9 @@ int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
723 720
724 pthread_mutex_destroy(&session->mutex); 721 pthread_mutex_destroy(&session->mutex);
725 722
723 LOGGER_DEBUG("Terminated RTP session: %p", session);
724
726 /* And finally free session */ 725 /* And finally free session */
727 free ( session ); 726 free ( session );
728 727
729 return 0; 728}
730} \ No newline at end of file
diff --git a/toxav/rtp.h b/toxav/rtp.h
index 63c8ce3d..727839c6 100644
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -195,7 +195,7 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien
195 * @retval -1 Error occurred. 195 * @retval -1 Error occurred.
196 * @retval 0 Success. 196 * @retval 0 Success.
197 */ 197 */
198int rtp_terminate_session ( RTPSession *session, Messenger *messenger ); 198void rtp_terminate_session ( RTPSession *session, Messenger *messenger );
199 199
200 200
201 201
diff --git a/toxav/toxav.c b/toxav/toxav.c
index b97f84ea..9a1c5e3e 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -68,6 +68,7 @@ typedef struct _CallSpecific {
68 void *frame_buf; /* buffer for split video payloads */ 68 void *frame_buf; /* buffer for split video payloads */
69 69
70 _Bool call_active; 70 _Bool call_active;
71 pthread_mutex_t mutex;
71} CallSpecific; 72} CallSpecific;
72 73
73 74
@@ -312,7 +313,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
312 313
313 if ( !call->crtps[audio_index] ) { 314 if ( !call->crtps[audio_index] ) {
314 LOGGER_ERROR("Error while starting audio RTP session!\n"); 315 LOGGER_ERROR("Error while starting audio RTP session!\n");
315 return ErrorStartingAudioRtp; 316 return ErrorInternal;
316 } 317 }
317 318
318 319
@@ -323,9 +324,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
323 324
324 if ( !call->crtps[video_index] ) { 325 if ( !call->crtps[video_index] ) {
325 LOGGER_ERROR("Error while starting video RTP session!\n"); 326 LOGGER_ERROR("Error while starting video RTP session!\n");
326 327 goto error;
327 rtp_terminate_session(call->crtps[audio_index], av->messenger);
328 return ErrorStartingVideoRtp;
329 } 328 }
330 329
331 call->frame_limit = 0; 330 call->frame_limit = 0;
@@ -335,20 +334,15 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
335 call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1); 334 call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);
336 335
337 if (!call->frame_buf) { 336 if (!call->frame_buf) {
338 rtp_terminate_session(call->crtps[audio_index], av->messenger);
339 rtp_terminate_session(call->crtps[video_index], av->messenger);
340 LOGGER_WARNING("Frame buffer allocation failed!"); 337 LOGGER_WARNING("Frame buffer allocation failed!");
341 return ErrorInternal; 338 goto error;
342 } 339 }
343 340
344 } 341 }
345 342
346 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) { 343 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) {
347 rtp_terminate_session(call->crtps[audio_index], av->messenger);
348 rtp_terminate_session(call->crtps[video_index], av->messenger);
349 free(call->frame_buf);
350 LOGGER_WARNING("Jitter buffer creaton failed!"); 344 LOGGER_WARNING("Jitter buffer creaton failed!");
351 return ErrorInternal; 345 goto error;
352 } 346 }
353 347
354 if ( (call->cs = codec_init_session(codec_settings->audio_bitrate, 348 if ( (call->cs = codec_init_session(codec_settings->audio_bitrate,
@@ -359,14 +353,20 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
359 codec_settings->video_width, 353 codec_settings->video_width,
360 codec_settings->video_height, 354 codec_settings->video_height,
361 codec_settings->video_bitrate) )) { 355 codec_settings->video_bitrate) )) {
356
357 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
358
362 call->call_active = 1; 359 call->call_active = 1;
360
363 return ErrorNone; 361 return ErrorNone;
364 } 362 }
365 363
364error:
366 rtp_terminate_session(call->crtps[audio_index], av->messenger); 365 rtp_terminate_session(call->crtps[audio_index], av->messenger);
367 rtp_terminate_session(call->crtps[video_index], av->messenger); 366 rtp_terminate_session(call->crtps[video_index], av->messenger);
368 free(call->frame_buf); 367 free(call->frame_buf);
369 terminate_queue(call->j_buf); 368 terminate_queue(call->j_buf);
369 codec_terminate_session(call->cs);
370 370
371 return ErrorInternal; 371 return ErrorInternal;
372} 372}
@@ -388,30 +388,21 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
388 388
389 CallSpecific *call = &av->calls[call_index]; 389 CallSpecific *call = &av->calls[call_index];
390 390
391 call->call_active = 0; 391 pthread_mutex_lock(&call->mutex);
392
393 if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) {
394 LOGGER_ERROR("Error while terminating audio RTP session!\n");
395 /*return ErrorTerminatingAudioRtp;*/
396 } else call->crtps[audio_index] = NULL;
397 392
398 if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) { 393 call->call_active = 0;
399 LOGGER_ERROR("Error while terminating video RTP session!\n");
400 /*return ErrorTerminatingVideoRtp;*/
401 } else call->crtps[video_index] = NULL;
402
403 if ( call->j_buf ) {
404 terminate_queue(call->j_buf);
405 call->j_buf = NULL;
406 LOGGER_DEBUG("Terminated j queue");
407 } else LOGGER_DEBUG("No j queue");
408 394
409 if ( call->cs ) { 395 rtp_terminate_session(call->crtps[audio_index], av->messenger);
410 codec_terminate_session(call->cs); 396 call->crtps[audio_index] = NULL;
411 call->cs = NULL; 397 rtp_terminate_session(call->crtps[video_index], av->messenger);
412 LOGGER_DEBUG("Terminated codec session"); 398 call->crtps[video_index] = NULL;
413 } else LOGGER_DEBUG("No codec session"); 399 terminate_queue(call->j_buf);
400 call->j_buf = NULL;
401 codec_terminate_session(call->cs);
402 call->cs = NULL;
414 403
404 pthread_mutex_unlock(&call->mutex);
405 pthread_mutex_destroy(&call->mutex);
415 406
416 return ErrorNone; 407 return ErrorNone;
417} 408}
@@ -431,22 +422,23 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
431inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, 422inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload,
432 unsigned int length ) 423 unsigned int length )
433{ 424{
434#define send(data, len) rtp_send_msg(av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, data, len) 425 CallSpecific *call = &av->calls[call_index];
426
427 if (call->crtps[type - TypeAudio]) {
435 428
436 if (av->calls[call_index].crtps[type - TypeAudio]) {
437 if (type == TypeAudio) { 429 if (type == TypeAudio) {
438 return send(payload, length); 430 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length);
439 } else { 431 } else {
440 if (length == 0 || length > MAX_VIDEOFRAME_SIZE) { 432 if (length == 0 || length > MAX_VIDEOFRAME_SIZE) {
441 LOGGER_ERROR("Invalid video frame size: %u\n", length); 433 LOGGER_ERROR("Invalid video frame size: %u\n", length);
442 return -1; 434 return ErrorInternal;
443 } 435 }
444 436
445 /* number of pieces - 1*/ 437 /* number of pieces - 1*/
446 uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE; 438 uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE;
447 439
448 uint8_t load[2 + VIDEOFRAME_PIECE_SIZE]; 440 uint8_t load[2 + VIDEOFRAME_PIECE_SIZE];
449 load[0] = av->calls[call_index].frame_outid++; 441 load[0] = call->frame_outid++;
450 load[1] = 0; 442 load[1] = 0;
451 443
452 int i; 444 int i;
@@ -455,8 +447,10 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
455 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); 447 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE);
456 payload += VIDEOFRAME_PIECE_SIZE; 448 payload += VIDEOFRAME_PIECE_SIZE;
457 449
458 if (send(load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { 450 if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger,
459 return -1; 451 load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) {
452
453 return ErrorInternal;
460 } 454 }
461 455
462 load[1]++; 456 load[1]++;
@@ -465,13 +459,12 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
465 /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ 459 /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */
466 length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; 460 length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1;
467 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); 461 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length);
468 return send(load, VIDEOFRAME_HEADER_SIZE + length); 462
463 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length);
469 } 464 }
470 } else { 465 } else {
471 return -1; 466 return ErrorNoRtpSession;
472 } 467 }
473
474#undef send
475} 468}
476 469
477/** 470/**
@@ -545,9 +538,10 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
545 } 538 }
546 539
547 540
548 uint8_t packet [RTP_PAYLOAD_SIZE];
549 CallSpecific *call = &av->calls[call_index]; 541 CallSpecific *call = &av->calls[call_index];
542 pthread_mutex_lock(&call->mutex);
550 543
544 uint8_t packet [RTP_PAYLOAD_SIZE];
551 int recved_size; 545 int recved_size;
552 546
553 while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) { 547 while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) {
@@ -597,7 +591,9 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
597 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); 591 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);
598 592
599 *output = img; 593 *output = img;
600 return 0; 594
595 pthread_mutex_unlock(&call->mutex);
596 return ErrorNone;
601} 597}
602 598
603/** 599/**
@@ -617,7 +613,11 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr
617 } 613 }
618 614
619 615
620 return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); 616 pthread_mutex_lock(&av->calls[call_index].mutex);
617 int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size);
618 pthread_mutex_unlock(&av->calls[call_index].mutex);
619
620 return rc;
621} 621}
622 622
623/** 623/**
@@ -640,12 +640,15 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
640 640
641 641
642 CallSpecific *call = &av->calls[call_index]; 642 CallSpecific *call = &av->calls[call_index];
643 pthread_mutex_lock(&call->mutex);
644
643 reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); 645 reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h);
644 646
645 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); 647 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
646 648
647 if ( rc != VPX_CODEC_OK) { 649 if ( rc != VPX_CODEC_OK) {
648 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); 650 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));
651 pthread_mutex_unlock(&call->mutex);
649 return ErrorInternal; 652 return ErrorInternal;
650 } 653 }
651 654
@@ -657,13 +660,17 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
657 660
658 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { 661 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
659 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 662 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
660 if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge; 663 if ( copied + pkt->data.frame.sz > dest_max ) {
664 pthread_mutex_unlock(&call->mutex);
665 return ErrorPacketTooLarge;
666 }
661 667
662 memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); 668 memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
663 copied += pkt->data.frame.sz; 669 copied += pkt->data.frame.sz;
664 } 670 }
665 } 671 }
666 672
673 pthread_mutex_unlock(&call->mutex);
667 return copied; 674 return copied;
668} 675}
669 676
@@ -690,6 +697,7 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
690 697
691 698
692 CallSpecific *call = &av->calls[call_index]; 699 CallSpecific *call = &av->calls[call_index];
700 pthread_mutex_lock(&call->mutex);
693 701
694 uint8_t packet [RTP_PAYLOAD_SIZE]; 702 uint8_t packet [RTP_PAYLOAD_SIZE];
695 703
@@ -698,6 +706,8 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
698 if ( recved_size == ErrorAudioPacketLost ) { 706 if ( recved_size == ErrorAudioPacketLost ) {
699 int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); 707 int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
700 708
709 pthread_mutex_unlock(&call->mutex);
710
701 if ( dec_size < 0 ) { 711 if ( dec_size < 0 ) {
702 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); 712 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
703 return ErrorInternal; 713 return ErrorInternal;
@@ -706,11 +716,14 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
706 } else if ( recved_size ) { 716 } else if ( recved_size ) {
707 int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); 717 int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
708 718
719 pthread_mutex_unlock(&call->mutex);
720
709 if ( dec_size < 0 ) { 721 if ( dec_size < 0 ) {
710 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); 722 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
711 return ErrorInternal; 723 return ErrorInternal;
712 } else return dec_size; 724 } else return dec_size;
713 } else { 725 } else {
726 pthread_mutex_unlock(&call->mutex);
714 return 0; /* Nothing received */ 727 return 0; /* Nothing received */
715 } 728 }
716} 729}
@@ -734,7 +747,11 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr
734 } 747 }
735 748
736 749
737 return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); 750 pthread_mutex_lock(&av->calls[call_index].mutex);
751 int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
752 pthread_mutex_unlock(&av->calls[call_index].mutex);
753
754 return rc;
738} 755}
739 756
740/** 757/**
@@ -758,8 +775,12 @@ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t
758 } 775 }
759 776
760 777
778 pthread_mutex_lock(&av->calls[call_index].mutex);
779
761 int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); 780 int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max);
762 781
782 pthread_mutex_unlock(&av->calls[call_index].mutex);
783
763 if (rc < 0) { 784 if (rc < 0) {
764 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); 785 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc));
765 return ErrorInternal; 786 return ErrorInternal;