summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
Diffstat (limited to 'toxav')
-rw-r--r--toxav/av_test.c126
-rw-r--r--toxav/codec.c39
-rw-r--r--toxav/codec.h5
-rw-r--r--toxav/msi.c46
-rw-r--r--toxav/rtp.h8
-rw-r--r--toxav/toxav.c167
6 files changed, 227 insertions, 164 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c
index 28d19ec8..a04aff7c 100644
--- a/toxav/av_test.c
+++ b/toxav/av_test.c
@@ -51,8 +51,8 @@
51#define TEST_REJECT 0 51#define TEST_REJECT 0
52#define TEST_CANCEL 0 52#define TEST_CANCEL 0
53#define TEST_MUTE_UNMUTE 0 53#define TEST_MUTE_UNMUTE 0
54#define TEST_TRANSFER_A 0 54#define TEST_TRANSFER_A 1
55#define TEST_TRANSFER_V 1 55#define TEST_TRANSFER_V 0
56 56
57 57
58typedef struct { 58typedef struct {
@@ -128,7 +128,6 @@ void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
128 IplImage* header = cvCreateImageHeader(sz, 1, 3); 128 IplImage* header = cvCreateImageHeader(sz, 1, 3);
129 IplImage* img = cvGetImage(&mat, header); 129 IplImage* img = cvGetImage(&mat, header);
130 cvShowImage(vdout, img); 130 cvShowImage(vdout, img);
131 cvWaitKey(1);
132 free(img_data); 131 free(img_data);
133} 132}
134void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, 133void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
@@ -139,7 +138,7 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
139 void *user_data) 138 void *user_data)
140{ 139{
141 uint32_t bufid; 140 uint32_t bufid;
142 int32_t processed, queued; 141 int32_t processed = 0, queued = 16;
143 alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed); 142 alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed);
144 alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued); 143 alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued);
145 144
@@ -147,12 +146,12 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
147 uint32_t bufids[processed]; 146 uint32_t bufids[processed];
148 alSourceUnqueueBuffers(adout, processed, bufids); 147 alSourceUnqueueBuffers(adout, processed, bufids);
149 alDeleteBuffers(processed - 1, bufids + 1); 148 alDeleteBuffers(processed - 1, bufids + 1);
150 bufid = bufids[0]; 149// bufid = bufids[0];
151 } 150 }
152 else if(queued < 16) 151// else if(queued < 16)
153 alGenBuffers(1, &bufid); 152 alGenBuffers(1, &bufid);
154 else 153// else
155 return; 154// return;
156 155
157 156
158 alBufferData(bufid, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, 157 alBufferData(bufid, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
@@ -246,22 +245,27 @@ int iterate_tox(Tox* bootstrap, ToxAV* AliceAV, ToxAV* BobAV)
246 tox_do(toxav_get_tox(AliceAV)); 245 tox_do(toxav_get_tox(AliceAV));
247 tox_do(toxav_get_tox(BobAV)); 246 tox_do(toxav_get_tox(BobAV));
248 247
249 uint32_t rc = MIN(tox_do_interval(toxav_get_tox(AliceAV)), tox_do_interval(toxav_get_tox(BobAV))); 248 return MIN(tox_do_interval(toxav_get_tox(AliceAV)), tox_do_interval(toxav_get_tox(BobAV)));
250 c_sleep(rc);
251 return rc;
252} 249}
253void* iterate_toxav (void * data) 250void* iterate_toxav (void * data)
254{ 251{
255 struct toxav_thread_data* data_cast = data; 252 struct toxav_thread_data* data_cast = data;
253
254// cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
255
256 while (data_cast->sig == 0) { 256 while (data_cast->sig == 0) {
257 toxav_iterate(data_cast->AliceAV); 257 toxav_iterate(data_cast->AliceAV);
258 toxav_iterate(data_cast->BobAV); 258 toxav_iterate(data_cast->BobAV);
259// c_sleep(1); 259 int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV));
260
261 printf("\rToxAV interval: %d ", rc);
262 fflush(stdout);
263 cvWaitKey(rc);
260 } 264 }
261 265
262 data_cast->sig = 1; 266 data_cast->sig = 1;
263 267
264 cvDestroyWindow(vdout); 268// cvDestroyWindow(vdout);
265 pthread_exit(NULL); 269 pthread_exit(NULL);
266} 270}
267 271
@@ -314,19 +318,8 @@ ALCdevice* open_audio_device(const char* audio_out_dev_name)
314 ALCcontext* out_ctx = alcCreateContext(rc, NULL); 318 ALCcontext* out_ctx = alcCreateContext(rc, NULL);
315 alcMakeContextCurrent(out_ctx); 319 alcMakeContextCurrent(out_ctx);
316 320
317 uint32_t buffers[10];
318 alGenBuffers(10, buffers);
319 alGenSources((uint32_t)1, &adout); 321 alGenSources((uint32_t)1, &adout);
320 alSourcei(adout, AL_LOOPING, AL_FALSE); 322 alSourcei(adout, AL_LOOPING, AL_FALSE);
321
322 int16_t zeros[10000];
323 memset(zeros, 0, sizeof(zeros));
324
325 int i;
326 for ( i = 0; i < 10; ++i )
327 alBufferData(buffers[i], AL_FORMAT_STEREO16, zeros, sizeof(zeros), 48000);
328
329 alSourceQueueBuffers(adout, 10, buffers);
330 alSourcePlay(adout); 323 alSourcePlay(adout);
331 324
332 return rc; 325 return rc;
@@ -351,8 +344,10 @@ int print_audio_devices()
351int print_help (const char* name) 344int print_help (const char* name)
352{ 345{
353 printf("Usage: %s -[a:v:o:dh]\n" 346 printf("Usage: %s -[a:v:o:dh]\n"
354 "-a <path> video input file\n" 347 "-a <path> audio input file\n"
348 "-b <ms> audio frame duration\n"
355 "-v <path> video input file\n" 349 "-v <path> video input file\n"
350 "-x <ms> video frame duration\n"
356 "-o <idx> output audio device index\n" 351 "-o <idx> output audio device index\n"
357 "-d print output audio devices\n" 352 "-d print output audio devices\n"
358 "-h print this help\n", name); 353 "-h print this help\n", name);
@@ -363,7 +358,6 @@ int print_help (const char* name)
363 358
364int main (int argc, char** argv) 359int main (int argc, char** argv)
365{ 360{
366 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
367 struct stat st; 361 struct stat st;
368 362
369 /* AV files for testing */ 363 /* AV files for testing */
@@ -371,14 +365,35 @@ int main (int argc, char** argv)
371 const char* vf_name = NULL; 365 const char* vf_name = NULL;
372 long audio_out_dev_idx = 0; 366 long audio_out_dev_idx = 0;
373 367
374 /* Pasre settings */ 368 int32_t audio_frame_duration = 20;
375 CHECK_ARG: switch (getopt(argc, argv, "a:v:o:dh")) { 369 int32_t video_frame_duration = 10;
370
371 /* Parse settings */
372 CHECK_ARG: switch (getopt(argc, argv, "a:b:v:x:o:dh")) {
376 case 'a': 373 case 'a':
377 af_name = optarg; 374 af_name = optarg;
378 goto CHECK_ARG; 375 goto CHECK_ARG;
376 case 'b':{
377 char *d;
378 audio_frame_duration = strtol(optarg, &d, 10);
379 if (*d) {
380 printf("Invalid value for argument: 'b'");
381 exit(1);
382 }
383 goto CHECK_ARG;
384 }
379 case 'v': 385 case 'v':
380 vf_name = optarg; 386 vf_name = optarg;
381 goto CHECK_ARG; 387 goto CHECK_ARG;
388 case 'x':{
389 char *d;
390 video_frame_duration = strtol(optarg, &d, 10);
391 if (*d) {
392 printf("Invalid value for argument: 'x'");
393 exit(1);
394 }
395 goto CHECK_ARG;
396 }
382 case 'o': { 397 case 'o': {
383 char *d; 398 char *d;
384 audio_out_dev_idx = strtol(optarg, &d, 10); 399 audio_out_dev_idx = strtol(optarg, &d, 10);
@@ -434,7 +449,40 @@ int main (int argc, char** argv)
434 printf("Using audio file: %s\n", af_name); 449 printf("Using audio file: %s\n", af_name);
435 printf("Using video file: %s\n", vf_name); 450 printf("Using video file: %s\n", vf_name);
436 451
452 if (0) {
453 /* Open audio file */
454 SF_INFO af_info;
455 SNDFILE* af_handle = sf_open(af_name, SFM_READ, &af_info);
456 if (af_handle == NULL)
457 {
458 printf("Failed to open the file.\n");
459 exit(1);
460 }
461 ALCdevice* audio_out_device = open_audio_device(audio_out_dev_name);
462
463
464 int16_t PCM[5760];
465
466 time_t start_time = time(NULL);
467 time_t expected_time = af_info.frames / af_info.samplerate + 2;
468
469 printf("Sample rate %d\n", af_info.samplerate);
470 while ( start_time + expected_time > time(NULL) ) {
471 int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels;
472
473 int64_t count = sf_read_short(af_handle, PCM, frame_size);
474 if (count > 0)
475 t_toxav_receive_audio_frame_cb(NULL, 0, PCM, count, af_info.channels, af_info.samplerate, NULL);
476 c_sleep(audio_frame_duration);
477 }
437 478
479
480 printf("Played file in: %lu\n", time(NULL) - start_time);
481
482 alcCloseDevice(audio_out_device);
483 sf_close(af_handle);
484 return 0;
485 }
438 /* START TOX NETWORK */ 486 /* START TOX NETWORK */
439 487
440 Tox *bootstrap; 488 Tox *bootstrap;
@@ -714,8 +762,6 @@ int main (int argc, char** argv)
714 } 762 }
715 ALCdevice* audio_out_device = open_audio_device(audio_out_dev_name); 763 ALCdevice* audio_out_device = open_audio_device(audio_out_dev_name);
716 764
717
718 uint32_t frame_duration = 10;
719 int16_t PCM[5760]; 765 int16_t PCM[5760];
720 766
721 time_t start_time = time(NULL); 767 time_t start_time = time(NULL);
@@ -724,8 +770,8 @@ int main (int argc, char** argv)
724 770
725 /* Start decode thread */ 771 /* Start decode thread */
726 struct toxav_thread_data data = { 772 struct toxav_thread_data data = {
727 .AliceAV = AliceAV, 773 .AliceAV = AliceAV,
728 .BobAV = BobAV, 774 .BobAV = BobAV,
729 .sig = 0 775 .sig = 0
730 }; 776 };
731 777
@@ -733,8 +779,9 @@ int main (int argc, char** argv)
733 pthread_create(&dect, NULL, iterate_toxav, &data); 779 pthread_create(&dect, NULL, iterate_toxav, &data);
734 pthread_detach(dect); 780 pthread_detach(dect);
735 781
782 printf("Sample rate %d\n", af_info.samplerate);
736 while ( start_time + expected_time > time(NULL) ) { 783 while ( start_time + expected_time > time(NULL) ) {
737 int frame_size = (af_info.samplerate * frame_duration / 1000) * af_info.channels; 784 int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels;
738 785
739 int64_t count = sf_read_short(af_handle, PCM, frame_size); 786 int64_t count = sf_read_short(af_handle, PCM, frame_size);
740 if (count > 0) { 787 if (count > 0) {
@@ -746,7 +793,7 @@ int main (int argc, char** argv)
746 } 793 }
747 } 794 }
748 iterate_tox(bootstrap, AliceAV, BobAV); 795 iterate_tox(bootstrap, AliceAV, BobAV);
749// c_sleep(frame_duration); 796 c_sleep(audio_frame_duration);
750 } 797 }
751 798
752 799
@@ -770,7 +817,8 @@ int main (int argc, char** argv)
770 817
771 /* Stop decode thread */ 818 /* Stop decode thread */
772 data.sig = -1; 819 data.sig = -1;
773 while(data.sig != 1); 820 while(data.sig != 1)
821 pthread_yield();
774 822
775 printf("Success!"); 823 printf("Success!");
776 } 824 }
@@ -824,13 +872,14 @@ int main (int argc, char** argv)
824 } 872 }
825 873
826 time_t start_time = time(NULL); 874 time_t start_time = time(NULL);
827 while(start_time + 6 > time(NULL)) { 875 while(start_time + 90 > time(NULL)) {
828 IplImage* frame = cvQueryFrame( capture ); 876 IplImage* frame = cvQueryFrame( capture );
829 if (!frame) 877 if (!frame)
830 break; 878 break;
831 879
832 send_opencv_img(AliceAV, 0, frame); 880 send_opencv_img(AliceAV, 0, frame);
833 iterate_tox(bootstrap, AliceAV, BobAV); 881 iterate_tox(bootstrap, AliceAV, BobAV);
882 c_sleep(video_frame_duration);
834 } 883 }
835 884
836 cvReleaseCapture(&capture); 885 cvReleaseCapture(&capture);
@@ -849,9 +898,10 @@ int main (int argc, char** argv)
849 assert(BobCC.state == TOXAV_CALL_STATE_END); 898 assert(BobCC.state == TOXAV_CALL_STATE_END);
850 899
851 /* Stop decode thread */ 900 /* Stop decode thread */
852 printf("Stopping decode thread"); 901 printf("Stopping decode thread\n");
853 data.sig = -1; 902 data.sig = -1;
854 while(data.sig != 1); 903 while(data.sig != 1)
904 pthread_yield();
855 905
856 printf("Success!"); 906 printf("Success!");
857 } 907 }
diff --git a/toxav/codec.c b/toxav/codec.c
index c3f5d740..cd26d1e3 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -38,7 +38,7 @@
38#include "rtp.h" 38#include "rtp.h"
39#include "codec.h" 39#include "codec.h"
40 40
41#define DEFAULT_JBUF 3 41#define DEFAULT_JBUF 6
42 42
43/* Good quality encode. */ 43/* Good quality encode. */
44#define MAX_DECODE_TIME_US 0 44#define MAX_DECODE_TIME_US 0
@@ -324,17 +324,17 @@ void cs_do(CSession *cs)
324 324
325 int success = 0; 325 int success = 0;
326 326
327 pthread_mutex_lock(cs->queue_mutex); 327 LOGGED_LOCK(cs->queue_mutex);
328 328
329 /********************* AUDIO *********************/ 329 /********************* AUDIO *********************/
330 if (cs->audio_decoder) { /* If receiving enabled */ 330 if (cs->audio_decoder) {
331 RTPMessage *msg; 331 RTPMessage *msg;
332 332
333 /* The maximum for 120 ms 48 KHz audio */ 333 /* The maximum for 120 ms 48 KHz audio */
334 int16_t tmp[5760]; 334 int16_t tmp[5760];
335 335
336 while ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) { 336 while ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) {
337 pthread_mutex_unlock(cs->queue_mutex); 337 LOGGED_UNLOCK(cs->queue_mutex);
338 338
339 if (success == 2) { 339 if (success == 2) {
340 LOGGER_DEBUG("OPUS correction"); 340 LOGGER_DEBUG("OPUS correction");
@@ -377,7 +377,7 @@ void cs_do(CSession *cs)
377 cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); 377 cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second);
378 } 378 }
379 379
380 pthread_mutex_lock(cs->queue_mutex); 380 LOGGED_LOCK(cs->queue_mutex);
381 } 381 }
382 } 382 }
383 383
@@ -387,7 +387,7 @@ void cs_do(CSession *cs)
387 buffer_read(cs->vbuf_raw, &p); 387 buffer_read(cs->vbuf_raw, &p);
388 388
389 /* Leave space for (possibly) other thread to queue more data after we read it here */ 389 /* Leave space for (possibly) other thread to queue more data after we read it here */
390 pthread_mutex_unlock(cs->queue_mutex); 390 LOGGED_UNLOCK(cs->queue_mutex);
391 391
392 rc = vpx_codec_decode(cs->v_decoder, p->data, p->size, NULL, MAX_DECODE_TIME_US); 392 rc = vpx_codec_decode(cs->v_decoder, p->data, p->size, NULL, MAX_DECODE_TIME_US);
393 free(p); 393 free(p);
@@ -411,7 +411,7 @@ void cs_do(CSession *cs)
411 return; 411 return;
412 } 412 }
413 413
414 pthread_mutex_unlock(cs->queue_mutex); 414 LOGGED_UNLOCK(cs->queue_mutex);
415} 415}
416 416
417CSession *cs_new(uint32_t peer_video_frame_piece_size) 417CSession *cs_new(uint32_t peer_video_frame_piece_size)
@@ -423,7 +423,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size)
423 return NULL; 423 return NULL;
424 } 424 }
425 425
426 if (pthread_mutex_init(cs->queue_mutex, NULL) != 0) { 426 if (create_recursive_mutex(cs->queue_mutex) != 0) {
427 LOGGER_WARNING("Failed to create recursive mutex!"); 427 LOGGER_WARNING("Failed to create recursive mutex!");
428 free(cs); 428 free(cs);
429 return NULL; 429 return NULL;
@@ -481,6 +481,8 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size)
481 if ( !(cs->split_video_frame = calloc(VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE, 1)) ) 481 if ( !(cs->split_video_frame = calloc(VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE, 1)) )
482 goto FAILURE; 482 goto FAILURE;
483 483
484 cs->linfts = current_time_monotonic();
485 cs->lcfd = 10;
484 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 486 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
485 487
486 /* Initialize encoders with default values */ 488 /* Initialize encoders with default values */
@@ -621,6 +623,8 @@ int cs_reconfigure_audio_encoder(CSession* cs, int32_t bitrate, int32_t sampling
621 cs->last_encoding_bitrate = bitrate; 623 cs->last_encoding_bitrate = bitrate;
622 cs->last_encoding_sampling_rate = sampling_rate; 624 cs->last_encoding_sampling_rate = sampling_rate;
623 cs->last_encoding_channel_count = channels; 625 cs->last_encoding_channel_count = channels;
626
627 LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels);
624 return 0; 628 return 0;
625} 629}
626 630
@@ -628,9 +632,6 @@ int cs_reconfigure_audio_encoder(CSession* cs, int32_t bitrate, int32_t sampling
628/* Called from RTP */ 632/* Called from RTP */
629void queue_message(RTPSession *session, RTPMessage *msg) 633void queue_message(RTPSession *session, RTPMessage *msg)
630{ 634{
631 /* This function is unregistered during call termination befor destroying
632 * Codec session so no need to check for validity of cs TODO properly check video cycle
633 */
634 CSession *cs = session->cs; 635 CSession *cs = session->cs;
635 636
636 if (!cs) 637 if (!cs)
@@ -638,9 +639,9 @@ void queue_message(RTPSession *session, RTPMessage *msg)
638 639
639 /* Audio */ 640 /* Audio */
640 if (session->payload_type == rtp_TypeAudio % 128) { 641 if (session->payload_type == rtp_TypeAudio % 128) {
641 pthread_mutex_lock(cs->queue_mutex); 642 LOGGED_LOCK(cs->queue_mutex);
642 int ret = jbuf_write(cs->j_buf, msg); 643 int ret = jbuf_write(cs->j_buf, msg);
643 pthread_mutex_unlock(cs->queue_mutex); 644 LOGGED_UNLOCK(cs->queue_mutex);
644 645
645 if (ret == -1) { 646 if (ret == -1) {
646 rtp_free_msg(NULL, msg); 647 rtp_free_msg(NULL, msg);
@@ -662,7 +663,7 @@ void queue_message(RTPSession *session, RTPMessage *msg)
662 Payload *p = malloc(sizeof(Payload) + cs->frame_size); 663 Payload *p = malloc(sizeof(Payload) + cs->frame_size);
663 664
664 if (p) { 665 if (p) {
665 pthread_mutex_lock(cs->queue_mutex); 666 LOGGED_LOCK(cs->queue_mutex);
666 667
667 if (buffer_full(cs->vbuf_raw)) { 668 if (buffer_full(cs->vbuf_raw)) {
668 LOGGER_DEBUG("Dropped video frame"); 669 LOGGER_DEBUG("Dropped video frame");
@@ -673,15 +674,19 @@ void queue_message(RTPSession *session, RTPMessage *msg)
673 p->size = cs->frame_size; 674 p->size = cs->frame_size;
674 memcpy(p->data, cs->frame_buf, cs->frame_size); 675 memcpy(p->data, cs->frame_buf, cs->frame_size);
675 } 676 }
676 677
678 /* Calculate time took for peer to send us this frame */
679 uint32_t t_lcfd = current_time_monotonic() - cs->linfts;
680 cs->lcfd = t_lcfd > 100 ? cs->lcfd : t_lcfd;
681 cs->linfts = current_time_monotonic();
682
677 buffer_write(cs->vbuf_raw, p); 683 buffer_write(cs->vbuf_raw, p);
678 pthread_mutex_unlock(cs->queue_mutex); 684 LOGGED_UNLOCK(cs->queue_mutex);
679 } else { 685 } else {
680 LOGGER_WARNING("Allocation failed! Program might misbehave!"); 686 LOGGER_WARNING("Allocation failed! Program might misbehave!");
681 goto end; 687 goto end;
682 } 688 }
683 689
684 cs->last_timestamp = msg->header->timestamp;
685 cs->frameid_in = packet[0]; 690 cs->frameid_in = packet[0];
686 memset(cs->frame_buf, 0, cs->frame_size); 691 memset(cs->frame_buf, 0, cs->frame_size);
687 cs->frame_size = 0; 692 cs->frame_size = 0;
diff --git a/toxav/codec.h b/toxav/codec.h
index b13203f1..93b08cd2 100644
--- a/toxav/codec.h
+++ b/toxav/codec.h
@@ -61,8 +61,9 @@ typedef struct CSession_s {
61 uint8_t *frame_buf; /* buffer for split video payloads */ 61 uint8_t *frame_buf; /* buffer for split video payloads */
62 uint32_t frame_size; /* largest address written to in frame_buf for current input frame */ 62 uint32_t frame_size; /* largest address written to in frame_buf for current input frame */
63 uint8_t frameid_in, frameid_out; /* id of input and output video frame */ 63 uint8_t frameid_in, frameid_out; /* id of input and output video frame */
64 uint32_t last_timestamp; /* calculating cycles */ 64 uint64_t linfts; /* Last received frame time stamp */
65 65 uint32_t lcfd; /* Last calculated frame duration for incoming video payload */
66
66 /* Limits */ 67 /* Limits */
67 uint32_t peer_video_frame_piece_size; 68 uint32_t peer_video_frame_piece_size;
68 69
diff --git a/toxav/msi.c b/toxav/msi.c
index e21ec948..29e053ec 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -99,9 +99,9 @@ void handle_msi_packet ( Messenger *m, int friend_id, const uint8_t *data, uint1
99 */ 99 */
100void msi_register_callback ( MSISession *session, MSICallbackType callback, MSICallbackID id) 100void msi_register_callback ( MSISession *session, MSICallbackType callback, MSICallbackID id)
101{ 101{
102 pthread_mutex_lock(session->mutex); 102 LOGGED_LOCK(session->mutex);
103 session->callbacks[id] = callback; 103 session->callbacks[id] = callback;
104 pthread_mutex_unlock(session->mutex); 104 LOGGED_UNLOCK(session->mutex);
105} 105}
106MSISession *msi_new ( Messenger *messenger ) 106MSISession *msi_new ( Messenger *messenger )
107{ 107{
@@ -141,7 +141,7 @@ int msi_kill ( MSISession *session )
141 } 141 }
142 142
143 m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL); 143 m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL);
144 pthread_mutex_lock(session->mutex); 144 LOGGED_LOCK(session->mutex);
145 145
146 if (session->calls) { 146 if (session->calls) {
147 MSIMessage msg; 147 MSIMessage msg;
@@ -154,7 +154,7 @@ int msi_kill ( MSISession *session )
154 } 154 }
155 } 155 }
156 156
157 pthread_mutex_unlock(session->mutex); 157 LOGGED_UNLOCK(session->mutex);
158 pthread_mutex_destroy(session->mutex); 158 pthread_mutex_destroy(session->mutex);
159 159
160 LOGGER_DEBUG("Terminated session: %p", session); 160 LOGGER_DEBUG("Terminated session: %p", session);
@@ -165,17 +165,17 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_
165{ 165{
166 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id); 166 LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id);
167 167
168 pthread_mutex_lock(session->mutex); 168 LOGGED_LOCK(session->mutex);
169 if (get_call(session, friend_id) != NULL) { 169 if (get_call(session, friend_id) != NULL) {
170 LOGGER_ERROR("Already in a call"); 170 LOGGER_ERROR("Already in a call");
171 pthread_mutex_unlock(session->mutex); 171 LOGGED_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_id );
176 176
177 if ( *call == NULL ) { 177 if ( *call == NULL ) {
178 pthread_mutex_unlock(session->mutex); 178 LOGGED_UNLOCK(session->mutex);
179 return -1; 179 return -1;
180 } 180 }
181 181
@@ -195,7 +195,7 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_
195 (*call)->state = msi_CallRequesting; 195 (*call)->state = msi_CallRequesting;
196 196
197 LOGGER_DEBUG("Invite sent"); 197 LOGGER_DEBUG("Invite sent");
198 pthread_mutex_unlock(session->mutex); 198 LOGGED_UNLOCK(session->mutex);
199 return 0; 199 return 0;
200} 200}
201int msi_hangup ( MSICall* call ) 201int msi_hangup ( MSICall* call )
@@ -203,7 +203,7 @@ int msi_hangup ( MSICall* call )
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_id);
204 204
205 MSISession* session = call->session; 205 MSISession* session = call->session;
206 pthread_mutex_lock(session->mutex); 206 LOGGED_LOCK(session->mutex);
207 207
208 MSIMessage msg; 208 MSIMessage msg;
209 msg_init(&msg, requ_pop); 209 msg_init(&msg, requ_pop);
@@ -211,7 +211,7 @@ int msi_hangup ( MSICall* call )
211 send_message ( session->messenger, call->friend_id, &msg ); 211 send_message ( session->messenger, call->friend_id, &msg );
212 212
213 kill_call(call); 213 kill_call(call);
214 pthread_mutex_unlock(session->mutex); 214 LOGGED_UNLOCK(session->mutex);
215 return 0; 215 return 0;
216} 216}
217int msi_answer ( MSICall* call, uint8_t capabilities ) 217int msi_answer ( MSICall* call, uint8_t capabilities )
@@ -219,13 +219,13 @@ int msi_answer ( MSICall* call, uint8_t capabilities )
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_id);
220 220
221 MSISession* session = call->session; 221 MSISession* session = call->session;
222 pthread_mutex_lock(session->mutex); 222 LOGGED_LOCK(session->mutex);
223 223
224 if ( call->state != msi_CallRequested ) { 224 if ( call->state != msi_CallRequested ) {
225 /* Though sending in invalid state will not cause anything wierd 225 /* Though sending in invalid state will not cause anything wierd
226 * Its better to not do it like a maniac */ 226 * Its better to not do it like a maniac */
227 LOGGER_ERROR("Call is in invalid state!"); 227 LOGGER_ERROR("Call is in invalid state!");
228 pthread_mutex_unlock(session->mutex); 228 LOGGED_UNLOCK(session->mutex);
229 return -1; 229 return -1;
230 } 230 }
231 231
@@ -243,7 +243,7 @@ int msi_answer ( MSICall* call, uint8_t capabilities )
243 send_message ( session->messenger, call->friend_id, &msg ); 243 send_message ( session->messenger, call->friend_id, &msg );
244 244
245 call->state = msi_CallActive; 245 call->state = msi_CallActive;
246 pthread_mutex_unlock(session->mutex); 246 LOGGED_UNLOCK(session->mutex);
247 247
248 return 0; 248 return 0;
249} 249}
@@ -252,7 +252,7 @@ int msi_change_capabilities( MSICall* call, uint8_t capabilities )
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_id);
253 253
254 MSISession* session = call->session; 254 MSISession* session = call->session;
255 pthread_mutex_lock(session->mutex); 255 LOGGED_LOCK(session->mutex);
256 256
257 if ( call->state != msi_CallActive ) { 257 if ( call->state != msi_CallActive ) {
258 /* Sending capabilities change can cause error on other side if 258 /* Sending capabilities change can cause error on other side if
@@ -263,7 +263,7 @@ int msi_change_capabilities( MSICall* call, uint8_t capabilities )
263 * like new. TODO: explain this better 263 * like new. TODO: explain this better
264 */ 264 */
265 LOGGER_ERROR("Call is in invalid state!"); 265 LOGGER_ERROR("Call is in invalid state!");
266 pthread_mutex_unlock(session->mutex); 266 LOGGED_UNLOCK(session->mutex);
267 return -1; 267 return -1;
268 } 268 }
269 269
@@ -277,7 +277,7 @@ int msi_change_capabilities( MSICall* call, uint8_t capabilities )
277 277
278 send_message ( call->session->messenger, call->friend_id, &msg ); 278 send_message ( call->session->messenger, call->friend_id, &msg );
279 279
280 pthread_mutex_unlock(session->mutex); 280 LOGGED_UNLOCK(session->mutex);
281 return 0; 281 return 0;
282} 282}
283 283
@@ -581,17 +581,17 @@ void on_peer_status(Messenger *m, int friend_id, uint8_t status, void *data)
581 case 0: { /* Friend is now offline */ 581 case 0: { /* Friend is now offline */
582 LOGGER_DEBUG("Friend %d is now offline", friend_id); 582 LOGGER_DEBUG("Friend %d is now offline", friend_id);
583 583
584 pthread_mutex_lock(session->mutex); 584 LOGGED_LOCK(session->mutex);
585 MSICall* call = get_call(session, friend_id); 585 MSICall* call = get_call(session, friend_id);
586 586
587 if (call == NULL) { 587 if (call == NULL) {
588 pthread_mutex_unlock(session->mutex); 588 LOGGED_UNLOCK(session->mutex);
589 return; 589 return;
590 } 590 }
591 591
592 invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */ 592 invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */
593 kill_call(call); 593 kill_call(call);
594 pthread_mutex_unlock(session->mutex); 594 LOGGED_UNLOCK(session->mutex);
595 } 595 }
596 break; 596 break;
597 597
@@ -759,20 +759,20 @@ void handle_msi_packet ( Messenger *m, int friend_id, const uint8_t *data, uint1
759 LOGGER_DEBUG("Successfully parsed message"); 759 LOGGER_DEBUG("Successfully parsed message");
760 } 760 }
761 761
762 pthread_mutex_lock(session->mutex); 762 LOGGED_LOCK(session->mutex);
763 MSICall *call = get_call(session, friend_id); 763 MSICall *call = get_call(session, friend_id);
764 764
765 if (call == NULL) { 765 if (call == NULL) {
766 if (msg.request.value != requ_push) { 766 if (msg.request.value != requ_push) {
767 send_error(m, friend_id, msi_EStrayMessage); 767 send_error(m, friend_id, msi_EStrayMessage);
768 pthread_mutex_unlock(session->mutex); 768 LOGGED_UNLOCK(session->mutex);
769 return; 769 return;
770 } 770 }
771 771
772 call = new_call(session, friend_id); 772 call = new_call(session, friend_id);
773 if (call == NULL) { 773 if (call == NULL) {
774 send_error(m, friend_id, msi_ESystem); 774 send_error(m, friend_id, msi_ESystem);
775 pthread_mutex_unlock(session->mutex); 775 LOGGED_UNLOCK(session->mutex);
776 return; 776 return;
777 } 777 }
778 } 778 }
@@ -782,5 +782,5 @@ void handle_msi_packet ( Messenger *m, int friend_id, const uint8_t *data, uint1
782 else 782 else
783 handle_pop(call, &msg); /* always kills the call */ 783 handle_pop(call, &msg); /* always kills the call */
784 784
785 pthread_mutex_unlock(session->mutex); 785 LOGGED_UNLOCK(session->mutex);
786} 786}
diff --git a/toxav/rtp.h b/toxav/rtp.h
index b47be18a..6b796d5a 100644
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -29,15 +29,15 @@
29#include "../toxcore/Messenger.h" 29#include "../toxcore/Messenger.h"
30 30
31#define LOGGED_LOCK(mutex) do { \ 31#define LOGGED_LOCK(mutex) do { \
32 LOGGER_DEBUG("Locking mutex: %p", mutex);\ 32 /*LOGGER_DEBUG("Locking mutex: %p", mutex);*/\
33 pthread_mutex_lock(mutex);\ 33 pthread_mutex_lock(mutex);\
34 LOGGER_DEBUG("Locked mutex: %p", mutex);\ 34 /*LOGGER_DEBUG("Locked mutex: %p", mutex);*/\
35} while(0) 35} while(0)
36 36
37#define LOGGED_UNLOCK(mutex) do { \ 37#define LOGGED_UNLOCK(mutex) do { \
38 LOGGER_DEBUG("Unlocking mutex: %p", mutex);\ 38 /*LOGGER_DEBUG("Unlocking mutex: %p", mutex);*/\
39 pthread_mutex_unlock(mutex);\ 39 pthread_mutex_unlock(mutex);\
40 LOGGER_DEBUG("Unlocked mutex: %p", mutex);\ 40 /*LOGGER_DEBUG("Unlocked mutex: %p", mutex);*/\
41} while(0) 41} while(0)
42 42
43#define MAX_SEQU_NUM 65535 43#define MAX_SEQU_NUM 65535
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 54554918..0f16fde2 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -129,8 +129,7 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error)
129 goto FAILURE; 129 goto FAILURE;
130 } 130 }
131 131
132// if (create_recursive_mutex(av->mutex) == -1) { 132 if (create_recursive_mutex(av->mutex) != 0) {
133 if (pthread_mutex_init(av->mutex, NULL) == -1) {
134 LOGGER_WARNING("Mutex creation failed!"); 133 LOGGER_WARNING("Mutex creation failed!");
135 rc = TOXAV_ERR_NEW_MALLOC; 134 rc = TOXAV_ERR_NEW_MALLOC;
136 goto FAILURE; 135 goto FAILURE;
@@ -174,7 +173,7 @@ void toxav_kill(ToxAV* av)
174{ 173{
175 if (av == NULL) 174 if (av == NULL)
176 return; 175 return;
177 pthread_mutex_lock(av->mutex); 176 LOGGED_LOCK(av->mutex);
178 177
179 msi_kill(av->msi); 178 msi_kill(av->msi);
180 179
@@ -187,7 +186,7 @@ void toxav_kill(ToxAV* av)
187 } 186 }
188 } 187 }
189 188
190 pthread_mutex_unlock(av->mutex); 189 LOGGED_UNLOCK(av->mutex);
191 pthread_mutex_destroy(av->mutex); 190 pthread_mutex_destroy(av->mutex);
192 free(av); 191 free(av);
193} 192}
@@ -205,9 +204,9 @@ uint32_t toxav_iteration_interval(const ToxAV* av)
205 204
206void toxav_iterate(ToxAV* av) 205void toxav_iterate(ToxAV* av)
207{ 206{
208 pthread_mutex_lock(av->mutex); 207 LOGGED_LOCK(av->mutex);
209 if (av->calls == NULL) { 208 if (av->calls == NULL) {
210 pthread_mutex_unlock(av->mutex); 209 LOGGED_UNLOCK(av->mutex);
211 return; 210 return;
212 } 211 }
213 212
@@ -215,20 +214,28 @@ void toxav_iterate(ToxAV* av)
215 uint32_t rc = 500; 214 uint32_t rc = 500;
216 215
217 ToxAVCall* i = av->calls[av->calls_head]; 216 ToxAVCall* i = av->calls[av->calls_head];
218 while (i) { 217 for (; i; i = i->next) {
219 if (i->active) { 218 if (i->active) {
220 pthread_mutex_lock(i->mutex_decoding); 219 LOGGED_LOCK(i->mutex_decoding);
221 pthread_mutex_unlock(av->mutex); 220 LOGGED_UNLOCK(av->mutex);
222 221
223 cs_do(i->cs); 222 cs_do(i->cs);
224 rc = MIN(i->cs->last_packet_frame_duration, rc); 223 if (i->last_self_capabilities & msi_CapRAudio) /* Receiving audio */
224 rc = MIN(i->cs->last_packet_frame_duration, rc);
225 if (i->last_self_capabilities & msi_CapRVideo) /* Receiving video */
226 rc = MIN(i->cs->lcfd, rc);
225 227
226 pthread_mutex_lock(av->mutex); 228 uint32_t fid = i->friend_id;
227 pthread_mutex_unlock(i->mutex_decoding); 229
228 i = i->next; 230 LOGGED_UNLOCK(i->mutex_decoding);
231 LOGGED_LOCK(av->mutex);
232
233 /* In case this call is popped from container stop iteration */
234 if (call_get(av, fid) != i)
235 break;
229 } 236 }
230 } 237 }
231 pthread_mutex_unlock(av->mutex); 238 LOGGED_UNLOCK(av->mutex);
232 239
233 av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); 240 av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa);
234 av->dmsst += current_time_monotonic() - start; 241 av->dmsst += current_time_monotonic() - start;
@@ -242,10 +249,10 @@ void toxav_iterate(ToxAV* av)
242 249
243bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) 250bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error)
244{ 251{
245 pthread_mutex_lock(av->mutex); 252 LOGGED_LOCK(av->mutex);
246 ToxAVCall* call = call_new(av, friend_number, error); 253 ToxAVCall* call = call_new(av, friend_number, error);
247 if (call == NULL) { 254 if (call == NULL) {
248 pthread_mutex_unlock(av->mutex); 255 LOGGED_UNLOCK(av->mutex);
249 return false; 256 return false;
250 } 257 }
251 258
@@ -261,27 +268,27 @@ bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint
261 call_remove(call); 268 call_remove(call);
262 if (error) 269 if (error)
263 *error = TOXAV_ERR_CALL_MALLOC; 270 *error = TOXAV_ERR_CALL_MALLOC;
264 pthread_mutex_unlock(av->mutex); 271 LOGGED_UNLOCK(av->mutex);
265 return false; 272 return false;
266 } 273 }
267 274
268 call->msi_call->av_call = call; 275 call->msi_call->av_call = call;
269 pthread_mutex_unlock(av->mutex); 276 LOGGED_UNLOCK(av->mutex);
270 277
271 return true; 278 return true;
272} 279}
273 280
274void toxav_callback_call(ToxAV* av, toxav_call_cb* function, void* user_data) 281void toxav_callback_call(ToxAV* av, toxav_call_cb* function, void* user_data)
275{ 282{
276 pthread_mutex_lock(av->mutex); 283 LOGGED_LOCK(av->mutex);
277 av->ccb.first = function; 284 av->ccb.first = function;
278 av->ccb.second = user_data; 285 av->ccb.second = user_data;
279 pthread_mutex_unlock(av->mutex); 286 LOGGED_UNLOCK(av->mutex);
280} 287}
281 288
282bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER* error) 289bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER* error)
283{ 290{
284 pthread_mutex_lock(av->mutex); 291 LOGGED_LOCK(av->mutex);
285 292
286 TOXAV_ERR_ANSWER rc = TOXAV_ERR_ANSWER_OK; 293 TOXAV_ERR_ANSWER rc = TOXAV_ERR_ANSWER_OK;
287 if (m_friend_exists(av->m, friend_number) == 0) { 294 if (m_friend_exists(av->m, friend_number) == 0) {
@@ -320,7 +327,7 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
320 327
321 328
322END: 329END:
323 pthread_mutex_unlock(av->mutex); 330 LOGGED_UNLOCK(av->mutex);
324 331
325 if (error) 332 if (error)
326 *error = rc; 333 *error = rc;
@@ -330,15 +337,15 @@ END:
330 337
331void toxav_callback_call_state(ToxAV* av, toxav_call_state_cb* function, void* user_data) 338void toxav_callback_call_state(ToxAV* av, toxav_call_state_cb* function, void* user_data)
332{ 339{
333 pthread_mutex_lock(av->mutex); 340 LOGGED_LOCK(av->mutex);
334 av->scb.first = function; 341 av->scb.first = function;
335 av->scb.second = user_data; 342 av->scb.second = user_data;
336 pthread_mutex_unlock(av->mutex); 343 LOGGED_UNLOCK(av->mutex);
337} 344}
338 345
339bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL* error) 346bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL* error)
340{ 347{
341 pthread_mutex_lock(av->mutex); 348 LOGGED_LOCK(av->mutex);
342 TOXAV_ERR_CALL_CONTROL rc = TOXAV_ERR_CALL_CONTROL_OK; 349 TOXAV_ERR_CALL_CONTROL rc = TOXAV_ERR_CALL_CONTROL_OK;
343 350
344 if (m_friend_exists(av->m, friend_number) == 0) { 351 if (m_friend_exists(av->m, friend_number) == 0) {
@@ -474,7 +481,7 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
474 } 481 }
475 482
476END: 483END:
477 pthread_mutex_unlock(av->mutex); 484 LOGGED_UNLOCK(av->mutex);
478 485
479 if (error) 486 if (error)
480 *error = rc; 487 *error = rc;
@@ -497,17 +504,17 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_
497 goto END; 504 goto END;
498 } 505 }
499 506
500 pthread_mutex_lock(av->mutex); 507 LOGGED_LOCK(av->mutex);
501 call = call_get(av, friend_number); 508 call = call_get(av, friend_number);
502 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 509 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
503 pthread_mutex_unlock(av->mutex); 510 LOGGED_UNLOCK(av->mutex);
504 rc = TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL; 511 rc = TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL;
505 goto END; 512 goto END;
506 } 513 }
507 514
508 /* NOTE: no need to lock*/ 515 /* NOTE: no need to lock*/
509 call->audio_bit_rate = audio_bit_rate; 516 call->audio_bit_rate = audio_bit_rate;
510 pthread_mutex_unlock(av->mutex); 517 LOGGED_UNLOCK(av->mutex);
511 518
512END: 519END:
513 if (error) 520 if (error)
@@ -531,17 +538,17 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_
531 goto END; 538 goto END;
532 } 539 }
533 540
534 pthread_mutex_lock(av->mutex); 541 LOGGED_LOCK(av->mutex);
535 call = call_get(av, friend_number); 542 call = call_get(av, friend_number);
536 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 543 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
537 pthread_mutex_unlock(av->mutex); 544 LOGGED_UNLOCK(av->mutex);
538 rc = TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL; 545 rc = TOXAV_ERR_BIT_RATE_FRIEND_NOT_IN_CALL;
539 goto END; 546 goto END;
540 } 547 }
541 548
542 /* NOTE: no need to lock*/ 549 /* NOTE: no need to lock*/
543 call->video_bit_rate = video_bit_rate; 550 call->video_bit_rate = video_bit_rate;
544 pthread_mutex_unlock(av->mutex); 551 LOGGED_UNLOCK(av->mutex);
545 552
546END: 553END:
547 if (error) 554 if (error)
@@ -552,10 +559,10 @@ END:
552 559
553void toxav_callback_video_frame_request(ToxAV* av, toxav_video_frame_request_cb* function, void* user_data) 560void toxav_callback_video_frame_request(ToxAV* av, toxav_video_frame_request_cb* function, void* user_data)
554{ 561{
555 pthread_mutex_lock(av->mutex); 562 LOGGED_LOCK(av->mutex);
556 av->rvcb.first = function; 563 av->rvcb.first = function;
557 av->rvcb.second = user_data; 564 av->rvcb.second = user_data;
558 pthread_mutex_unlock(av->mutex); 565 LOGGED_UNLOCK(av->mutex);
559} 566}
560 567
561bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, TOXAV_ERR_SEND_FRAME* error) 568bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, TOXAV_ERR_SEND_FRAME* error)
@@ -568,25 +575,25 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
568 goto END; 575 goto END;
569 } 576 }
570 577
571 pthread_mutex_lock(av->mutex); 578 LOGGED_LOCK(av->mutex);
572 call = call_get(av, friend_number); 579 call = call_get(av, friend_number);
573 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 580 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
574 pthread_mutex_unlock(av->mutex); 581 LOGGED_UNLOCK(av->mutex);
575 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; 582 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL;
576 goto END; 583 goto END;
577 } 584 }
578 585
579 pthread_mutex_lock(call->mutex_video_sending); 586 LOGGED_LOCK(call->mutex_video_sending);
580 pthread_mutex_unlock(av->mutex); 587 LOGGED_UNLOCK(av->mutex);
581 588
582 if ( y == NULL || u == NULL || v == NULL ) { 589 if ( y == NULL || u == NULL || v == NULL ) {
583 pthread_mutex_unlock(call->mutex_video_sending); 590 LOGGED_UNLOCK(call->mutex_video_sending);
584 rc = TOXAV_ERR_SEND_FRAME_NULL; 591 rc = TOXAV_ERR_SEND_FRAME_NULL;
585 goto END; 592 goto END;
586 } 593 }
587 594
588 if ( cs_reconfigure_video_encoder(call->cs, call->video_bit_rate, width, height) != 0 ) { 595 if ( cs_reconfigure_video_encoder(call->cs, call->video_bit_rate, width, height) != 0 ) {
589 pthread_mutex_unlock(call->mutex_video_sending); 596 LOGGED_UNLOCK(call->mutex_video_sending);
590 rc = TOXAV_ERR_SEND_FRAME_INVALID; 597 rc = TOXAV_ERR_SEND_FRAME_INVALID;
591 goto END; 598 goto END;
592 } 599 }
@@ -608,7 +615,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
608 615
609 vpx_img_free(&img); 616 vpx_img_free(&img);
610 if ( vrc != VPX_CODEC_OK) { 617 if ( vrc != VPX_CODEC_OK) {
611 pthread_mutex_unlock(call->mutex_video_sending); 618 LOGGED_UNLOCK(call->mutex_video_sending);
612 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc)); 619 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc));
613 rc = TOXAV_ERR_SEND_FRAME_INVALID; 620 rc = TOXAV_ERR_SEND_FRAME_INVALID;
614 goto END; 621 goto END;
@@ -639,7 +646,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
639 iter = cs_iterate_split_video_frame(call->cs, &part_size); 646 iter = cs_iterate_split_video_frame(call->cs, &part_size);
640 647
641 if (rtp_send_msg(call->rtps[video_index], iter, part_size) < 0) { 648 if (rtp_send_msg(call->rtps[video_index], iter, part_size) < 0) {
642 pthread_mutex_unlock(call->mutex_video_sending); 649 LOGGED_UNLOCK(call->mutex_video_sending);
643 LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno)); 650 LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
644 goto END; 651 goto END;
645 } 652 }
@@ -648,7 +655,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
648 } 655 }
649 } 656 }
650 657
651 pthread_mutex_unlock(call->mutex_video_sending); 658 LOGGED_UNLOCK(call->mutex_video_sending);
652 659
653END: 660END:
654 if (error) 661 if (error)
@@ -659,10 +666,10 @@ END:
659 666
660void toxav_callback_audio_frame_request(ToxAV* av, toxav_audio_frame_request_cb* function, void* user_data) 667void toxav_callback_audio_frame_request(ToxAV* av, toxav_audio_frame_request_cb* function, void* user_data)
661{ 668{
662 pthread_mutex_lock(av->mutex); 669 LOGGED_LOCK(av->mutex);
663 av->racb.first = function; 670 av->racb.first = function;
664 av->racb.second = user_data; 671 av->racb.second = user_data;
665 pthread_mutex_unlock(av->mutex); 672 LOGGED_UNLOCK(av->mutex);
666} 673}
667 674
668bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME* error) 675bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME* error)
@@ -675,32 +682,32 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
675 goto END; 682 goto END;
676 } 683 }
677 684
678 pthread_mutex_lock(av->mutex); 685 LOGGED_LOCK(av->mutex);
679 call = call_get(av, friend_number); 686 call = call_get(av, friend_number);
680 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) { 687 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
681 pthread_mutex_unlock(av->mutex); 688 LOGGED_UNLOCK(av->mutex);
682 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; 689 rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL;
683 goto END; 690 goto END;
684 } 691 }
685 692
686 pthread_mutex_lock(call->mutex_audio_sending); 693 LOGGED_LOCK(call->mutex_audio_sending);
687 pthread_mutex_unlock(av->mutex); 694 LOGGED_UNLOCK(av->mutex);
688 695
689 if ( pcm == NULL ) { 696 if ( pcm == NULL ) {
690 pthread_mutex_unlock(call->mutex_audio_sending); 697 LOGGED_UNLOCK(call->mutex_audio_sending);
691 rc = TOXAV_ERR_SEND_FRAME_NULL; 698 rc = TOXAV_ERR_SEND_FRAME_NULL;
692 goto END; 699 goto END;
693 } 700 }
694 701
695 if ( channels > 2 ) { 702 if ( channels > 2 ) {
696 pthread_mutex_unlock(call->mutex_audio_sending); 703 LOGGED_UNLOCK(call->mutex_audio_sending);
697 rc = TOXAV_ERR_SEND_FRAME_INVALID; 704 rc = TOXAV_ERR_SEND_FRAME_INVALID;
698 goto END; 705 goto END;
699 } 706 }
700 707
701 { /* Encode and send */ 708 { /* Encode and send */
702 if (cs_reconfigure_audio_encoder(call->cs, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { 709 if (cs_reconfigure_audio_encoder(call->cs, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) {
703 pthread_mutex_unlock(call->mutex_audio_sending); 710 LOGGED_UNLOCK(call->mutex_audio_sending);
704 rc = TOXAV_ERR_SEND_FRAME_INVALID; 711 rc = TOXAV_ERR_SEND_FRAME_INVALID;
705 goto END; 712 goto END;
706 } 713 }
@@ -711,7 +718,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
711 718
712 if (vrc < 0) { 719 if (vrc < 0) {
713 LOGGER_WARNING("Failed to encode frame"); 720 LOGGER_WARNING("Failed to encode frame");
714 pthread_mutex_unlock(call->mutex_audio_sending); 721 LOGGED_UNLOCK(call->mutex_audio_sending);
715 rc = TOXAV_ERR_SEND_FRAME_INVALID; 722 rc = TOXAV_ERR_SEND_FRAME_INVALID;
716 goto END; 723 goto END;
717 } 724 }
@@ -722,7 +729,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
722 } 729 }
723 } 730 }
724 731
725 pthread_mutex_unlock(call->mutex_audio_sending); 732 LOGGED_UNLOCK(call->mutex_audio_sending);
726 733
727END: 734END:
728 if (error) 735 if (error)
@@ -733,18 +740,18 @@ END:
733 740
734void toxav_callback_receive_video_frame(ToxAV* av, toxav_receive_video_frame_cb* function, void* user_data) 741void toxav_callback_receive_video_frame(ToxAV* av, toxav_receive_video_frame_cb* function, void* user_data)
735{ 742{
736 pthread_mutex_lock(av->mutex); 743 LOGGED_LOCK(av->mutex);
737 av->vcb.first = function; 744 av->vcb.first = function;
738 av->vcb.second = user_data; 745 av->vcb.second = user_data;
739 pthread_mutex_unlock(av->mutex); 746 LOGGED_UNLOCK(av->mutex);
740} 747}
741 748
742void toxav_callback_receive_audio_frame(ToxAV* av, toxav_receive_audio_frame_cb* function, void* user_data) 749void toxav_callback_receive_audio_frame(ToxAV* av, toxav_receive_audio_frame_cb* function, void* user_data)
743{ 750{
744 pthread_mutex_lock(av->mutex); 751 LOGGED_LOCK(av->mutex);
745 av->acb.first = function; 752 av->acb.first = function;
746 av->acb.second = user_data; 753 av->acb.second = user_data;
747 pthread_mutex_unlock(av->mutex); 754 LOGGED_UNLOCK(av->mutex);
748} 755}
749 756
750 757
@@ -756,12 +763,12 @@ void toxav_callback_receive_audio_frame(ToxAV* av, toxav_receive_audio_frame_cb*
756int callback_invite(void* toxav_inst, MSICall* call) 763int callback_invite(void* toxav_inst, MSICall* call)
757{ 764{
758 ToxAV* toxav = toxav_inst; 765 ToxAV* toxav = toxav_inst;
759 pthread_mutex_lock(toxav->mutex); 766 LOGGED_LOCK(toxav->mutex);
760 767
761 ToxAVCall* av_call = call_new(toxav, call->friend_id, NULL); 768 ToxAVCall* av_call = call_new(toxav, call->friend_id, NULL);
762 if (av_call == NULL) { 769 if (av_call == NULL) {
763 LOGGER_WARNING("Failed to initialize call..."); 770 LOGGER_WARNING("Failed to initialize call...");
764 pthread_mutex_unlock(toxav->mutex); 771 LOGGED_UNLOCK(toxav->mutex);
765 return -1; 772 return -1;
766 } 773 }
767 774
@@ -772,41 +779,41 @@ int callback_invite(void* toxav_inst, MSICall* call)
772 toxav->ccb.first(toxav, call->friend_id, call->peer_capabilities & msi_CapSAudio, 779 toxav->ccb.first(toxav, call->friend_id, call->peer_capabilities & msi_CapSAudio,
773 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second); 780 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second);
774 781
775 pthread_mutex_unlock(toxav->mutex); 782 LOGGED_UNLOCK(toxav->mutex);
776 return 0; 783 return 0;
777} 784}
778 785
779int callback_start(void* toxav_inst, MSICall* call) 786int callback_start(void* toxav_inst, MSICall* call)
780{ 787{
781 ToxAV* toxav = toxav_inst; 788 ToxAV* toxav = toxav_inst;
782 pthread_mutex_lock(toxav->mutex); 789 LOGGED_LOCK(toxav->mutex);
783 790
784 ToxAVCall* av_call = call_get(toxav, call->friend_id); 791 ToxAVCall* av_call = call_get(toxav, call->friend_id);
785 792
786 if (av_call == NULL) { 793 if (av_call == NULL) {
787 /* Should this ever happen? */ 794 /* Should this ever happen? */
788 pthread_mutex_unlock(toxav->mutex); 795 LOGGED_UNLOCK(toxav->mutex);
789 return -1; 796 return -1;
790 } 797 }
791 798
792 if (!call_prepare_transmission(av_call)) { 799 if (!call_prepare_transmission(av_call)) {
793 callback_error(toxav_inst, call); 800 callback_error(toxav_inst, call);
794 call_remove(av_call); 801 call_remove(av_call);
795 pthread_mutex_unlock(toxav->mutex); 802 LOGGED_UNLOCK(toxav->mutex);
796 return -1; 803 return -1;
797 } 804 }
798 805
799 if (toxav->scb.first) 806 if (toxav->scb.first)
800 toxav->scb.first(toxav, call->friend_id, call->peer_capabilities, toxav->scb.second); 807 toxav->scb.first(toxav, call->friend_id, call->peer_capabilities, toxav->scb.second);
801 808
802 pthread_mutex_unlock(toxav->mutex); 809 LOGGED_UNLOCK(toxav->mutex);
803 return 0; 810 return 0;
804} 811}
805 812
806int callback_end(void* toxav_inst, MSICall* call) 813int callback_end(void* toxav_inst, MSICall* call)
807{ 814{
808 ToxAV* toxav = toxav_inst; 815 ToxAV* toxav = toxav_inst;
809 pthread_mutex_lock(toxav->mutex); 816 LOGGED_LOCK(toxav->mutex);
810 817
811 if (toxav->scb.first) 818 if (toxav->scb.first)
812 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_END, toxav->scb.second); 819 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_END, toxav->scb.second);
@@ -814,14 +821,14 @@ int callback_end(void* toxav_inst, MSICall* call)
814 call_kill_transmission(call->av_call); 821 call_kill_transmission(call->av_call);
815 call_remove(call->av_call); 822 call_remove(call->av_call);
816 823
817 pthread_mutex_unlock(toxav->mutex); 824 LOGGED_UNLOCK(toxav->mutex);
818 return 0; 825 return 0;
819} 826}
820 827
821int callback_error(void* toxav_inst, MSICall* call) 828int callback_error(void* toxav_inst, MSICall* call)
822{ 829{
823 ToxAV* toxav = toxav_inst; 830 ToxAV* toxav = toxav_inst;
824 pthread_mutex_lock(toxav->mutex); 831 LOGGED_LOCK(toxav->mutex);
825 832
826 if (toxav->scb.first) 833 if (toxav->scb.first)
827 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_ERROR, toxav->scb.second); 834 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_ERROR, toxav->scb.second);
@@ -829,21 +836,21 @@ int callback_error(void* toxav_inst, MSICall* call)
829 call_kill_transmission(call->av_call); 836 call_kill_transmission(call->av_call);
830 call_remove(call->av_call); 837 call_remove(call->av_call);
831 838
832 pthread_mutex_unlock(toxav->mutex); 839 LOGGED_UNLOCK(toxav->mutex);
833 return 0; 840 return 0;
834} 841}
835 842
836int callback_capabilites(void* toxav_inst, MSICall* call) 843int callback_capabilites(void* toxav_inst, MSICall* call)
837{ 844{
838 ToxAV* toxav = toxav_inst; 845 ToxAV* toxav = toxav_inst;
839 pthread_mutex_lock(toxav->mutex); 846 LOGGED_LOCK(toxav->mutex);
840 847
841 /* TODO modify cs? */ 848 /* TODO modify cs? */
842 849
843 if (toxav->scb.first) 850 if (toxav->scb.first)
844 toxav->scb.first(toxav, call->friend_id, call->peer_capabilities, toxav->scb.second); 851 toxav->scb.first(toxav, call->friend_id, call->peer_capabilities, toxav->scb.second);
845 852
846 pthread_mutex_unlock(toxav->mutex); 853 LOGGED_UNLOCK(toxav->mutex);
847 return 0; 854 return 0;
848} 855}
849 856
@@ -969,14 +976,14 @@ bool call_prepare_transmission(ToxAVCall* call)
969 return true; 976 return true;
970 } 977 }
971 978
972 if (pthread_mutex_init(call->mutex_audio_sending, NULL) != 0) 979 if (create_recursive_mutex(call->mutex_audio_sending) != 0)
973 return false; 980 return false;
974 981
975 if (pthread_mutex_init(call->mutex_video_sending, NULL) != 0) { 982 if (create_recursive_mutex(call->mutex_video_sending) != 0) {
976 goto AUDIO_SENDING_MUTEX_CLEANUP; 983 goto AUDIO_SENDING_MUTEX_CLEANUP;
977 } 984 }
978 985
979 if (pthread_mutex_init(call->mutex_decoding, NULL) != 0) { 986 if (create_recursive_mutex(call->mutex_decoding) != 0) {
980 goto VIDEO_SENDING_MUTEX_CLEANUP; 987 goto VIDEO_SENDING_MUTEX_CLEANUP;
981 } 988 }
982 989
@@ -1058,12 +1065,12 @@ void call_kill_transmission(ToxAVCall* call)
1058 rtp_kill(call->rtps[video_index]); 1065 rtp_kill(call->rtps[video_index]);
1059 call->rtps[video_index] = NULL; 1066 call->rtps[video_index] = NULL;
1060 1067
1061 pthread_mutex_lock(call->mutex_audio_sending); 1068 LOGGED_LOCK(call->mutex_audio_sending);
1062 pthread_mutex_unlock(call->mutex_audio_sending); 1069 LOGGED_UNLOCK(call->mutex_audio_sending);
1063 pthread_mutex_lock(call->mutex_video_sending); 1070 LOGGED_LOCK(call->mutex_video_sending);
1064 pthread_mutex_unlock(call->mutex_video_sending); 1071 LOGGED_UNLOCK(call->mutex_video_sending);
1065 pthread_mutex_lock(call->mutex_decoding); 1072 LOGGED_LOCK(call->mutex_decoding);
1066 pthread_mutex_unlock(call->mutex_decoding); 1073 LOGGED_UNLOCK(call->mutex_decoding);
1067 1074
1068 cs_kill(call->cs); 1075 cs_kill(call->cs);
1069 call->cs = NULL; 1076 call->cs = NULL;