summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md20
-rw-r--r--auto_tests/toxav_basic_test.c2
-rw-r--r--toxav/codec.c34
-rw-r--r--toxav/codec.h3
-rw-r--r--toxav/rtp.c8
-rw-r--r--toxav/toxav.c133
-rw-r--r--toxav/toxav.h4
-rw-r--r--toxcore/Messenger.c4
8 files changed, 117 insertions, 91 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 1aed5375..6cdec95b 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -150,6 +150,14 @@ Grab the following packages:
150 * https://gnu.org/software/automake/ 150 * https://gnu.org/software/automake/
151 * https://github.com/jedisct1/libsodium 151 * https://github.com/jedisct1/libsodium
152 * http://check.sourceforge.net/ 152 * http://check.sourceforge.net/
153 * http://yasm.tortall.net/Download.html
154 * https://code.google.com/p/webm/downloads/list
155 * http://www.opus-codec.org/downloads/
156 * http://www.freedesktop.org/wiki/Software/pkg-config/
157
158You must install yasm before installing libvpx, otherwise libvpx will fail to make correctly.
159
160pkg-config is important for enabling a/v support in tox core, failure to install pkg-config will prevent tox core form finding the required libopus/libvpx libraries. (pkg-config may not configure properly, if you get an error about GLIB, run configure with the following parameter, --with-internal-glib).
153 161
154Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below: 162Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below:
155 163
@@ -159,9 +167,8 @@ make
159sudo make install 167sudo make install
160``` 168```
161 169
162In your local TOX repository: 170Compiling and installing Tox Core
163 171
164Then generate makefile, build and install tox:
165```bash 172```bash
166cd ProjectTox-Core 173cd ProjectTox-Core
167autoreconf -i 174autoreconf -i
@@ -170,12 +177,11 @@ make
170make install 177make install
171``` 178```
172 179
173Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory 180If after running ./configure you get an error about core being unable to find libsodium (and you have installed it) run the following in place of ./configure;
174(or the wrong version gets installed) and make your life more annoying. 181
182./configure --with-libsodium-headers=/usr/local/include/ --with-libsodium-libs=/usr/local/lib
175 183
176Another thing: you may want to install is the latest gcc. This caused me a few problems as XCode from 4.3 184Ensure you set the locations correctly depending on where you installed libsodium on your computer.
177no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at
178http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42
179 185
180<a name="windows" /> 186<a name="windows" />
181###Windows: 187###Windows:
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index a1bccd7c..0a710746 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -199,7 +199,7 @@ START_TEST(test_AV_flows)
199 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); 199 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
200 200
201 muhcaps = av_DefaultSettings; 201 muhcaps = av_DefaultSettings;
202 muhcaps.video_height = muhcaps.video_width = 128; 202 muhcaps.max_video_height = muhcaps.max_video_width = 128;
203 203
204 Status status_control = { 204 Status status_control = {
205 {none, toxav_new(Alice, 1), NULL, -1}, 205 {none, toxav_new(Alice, 1), NULL, -1},
diff --git a/toxav/codec.c b/toxav/codec.c
index fbf78d69..ae24a976 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -81,10 +81,10 @@ JitterBuffer *create_queue(int capacity)
81void terminate_queue(JitterBuffer *q) 81void terminate_queue(JitterBuffer *q)
82{ 82{
83 if (!q) return; 83 if (!q) return;
84 84
85 empty_queue(q); 85 empty_queue(q);
86 free(q->queue); 86 free(q->queue);
87 87
88 LOGGER_DEBUG("Terminated jitter buffer: %p", q); 88 LOGGER_DEBUG("Terminated jitter buffer: %p", q);
89 free(q); 89 free(q);
90} 90}
@@ -217,6 +217,9 @@ int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_
217 if (cfg.g_w == width && cfg.g_h == height) 217 if (cfg.g_w == width && cfg.g_h == height)
218 return 0; 218 return 0;
219 219
220 if (width * height > cs->max_width * cs->max_height)
221 return -1;
222
220 LOGGER_DEBUG("New video resolution: %u %u", width, height); 223 LOGGER_DEBUG("New video resolution: %u %u", width, height);
221 cfg.g_w = width; 224 cfg.g_w = width;
222 cfg.g_h = height; 225 cfg.g_h = height;
@@ -249,7 +252,7 @@ int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
249 return 0; 252 return 0;
250} 253}
251 254
252int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) 255int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate)
253{ 256{
254 vpx_codec_enc_cfg_t cfg; 257 vpx_codec_enc_cfg_t cfg;
255 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 258 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
@@ -260,13 +263,18 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
260 } 263 }
261 264
262 cfg.rc_target_bitrate = video_bitrate; 265 cfg.rc_target_bitrate = video_bitrate;
263 cfg.g_w = 8192; 266 cfg.g_w = max_width;
264 cfg.g_h = 8192; 267 cfg.g_h = max_height;
265 cfg.g_pass = VPX_RC_ONE_PASS; 268 cfg.g_pass = VPX_RC_ONE_PASS;
266 cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; 269 cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
267 cfg.g_lag_in_frames = 0; 270 cfg.g_lag_in_frames = 0;
268 cfg.kf_min_dist = 0; 271 cfg.kf_min_dist = 0;
269 cfg.kf_max_dist = 300; 272 cfg.kf_max_dist = 300;
273 cfg.kf_mode = VPX_KF_AUTO;
274
275 cs->max_width = max_width;
276 cs->max_height = max_height;
277 cs->bitrate = video_bitrate;
270 278
271 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); 279 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);
272 280
@@ -282,9 +290,6 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
282 return -1; 290 return -1;
283 } 291 }
284 292
285 if (reconfigure_video_encoder_resolution(cs, width, height) != 0)
286 return -1;
287
288 return 0; 293 return 0;
289} 294}
290 295
@@ -322,8 +327,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
322 uint32_t audio_sample_rate, 327 uint32_t audio_sample_rate,
323 uint32_t audio_channels, 328 uint32_t audio_channels,
324 uint32_t audio_VAD_tolerance_ms, 329 uint32_t audio_VAD_tolerance_ms,
325 uint16_t video_width, 330 uint16_t max_video_width,
326 uint16_t video_height, 331 uint16_t max_video_height,
327 uint32_t video_bitrate ) 332 uint32_t video_bitrate )
328{ 333{
329 CodecState *retu = calloc(sizeof(CodecState), 1); 334 CodecState *retu = calloc(sizeof(CodecState), 1);
@@ -334,11 +339,12 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
334 retu->audio_sample_rate = audio_sample_rate; 339 retu->audio_sample_rate = audio_sample_rate;
335 340
336 /* Encoders */ 341 /* Encoders */
337 if (!video_width || !video_height) { /* Disable video */ 342 if (!max_video_width || !max_video_height) { /* Disable video */
338 /*video_width = 320; 343 /*video_width = 320;
339 video_height = 240; */ 344 video_height = 240; */
340 } else { 345 } else {
341 retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0; 346 retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height,
347 video_bitrate) ) ? v_encoding : 0;
342 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; 348 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
343 } 349 }
344 350
@@ -360,7 +366,7 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
360void codec_terminate_session ( CodecState *cs ) 366void codec_terminate_session ( CodecState *cs )
361{ 367{
362 if (!cs) return; 368 if (!cs) return;
363 369
364 if ( cs->audio_encoder ) 370 if ( cs->audio_encoder )
365 opus_encoder_destroy(cs->audio_encoder); 371 opus_encoder_destroy(cs->audio_encoder);
366 372
@@ -372,7 +378,7 @@ void codec_terminate_session ( CodecState *cs )
372 378
373 if ( cs->capabilities & v_encoding ) 379 if ( cs->capabilities & v_encoding )
374 vpx_codec_destroy(&cs->v_encoder); 380 vpx_codec_destroy(&cs->v_encoder);
375 381
376 LOGGER_DEBUG("Terminated codec state: %p", cs); 382 LOGGER_DEBUG("Terminated codec state: %p", cs);
377 free(cs); 383 free(cs);
378} 384}
diff --git a/toxav/codec.h b/toxav/codec.h
index d8e9f1a7..a464ec8f 100644
--- a/toxav/codec.h
+++ b/toxav/codec.h
@@ -56,6 +56,9 @@ typedef struct _CodecState {
56 56
57 /* video decoding */ 57 /* video decoding */
58 vpx_codec_ctx_t v_decoder; 58 vpx_codec_ctx_t v_decoder;
59 int bitrate;
60 int max_width;
61 int max_height;
59 62
60 /* audio encoding */ 63 /* audio encoding */
61 OpusEncoder *audio_encoder; 64 OpusEncoder *audio_encoder;
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 521e4b22..653a22df 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -705,7 +705,7 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien
705 */ 705 */
706void rtp_terminate_session ( RTPSession *session, Messenger *messenger ) 706void rtp_terminate_session ( RTPSession *session, Messenger *messenger )
707{ 707{
708 if ( !session ) return; 708 if ( !session ) return;
709 709
710 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); 710 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
711 711
@@ -721,8 +721,8 @@ void rtp_terminate_session ( RTPSession *session, Messenger *messenger )
721 pthread_mutex_destroy(&session->mutex); 721 pthread_mutex_destroy(&session->mutex);
722 722
723 LOGGER_DEBUG("Terminated RTP session: %p", session); 723 LOGGER_DEBUG("Terminated RTP session: %p", session);
724 724
725 /* And finally free session */ 725 /* And finally free session */
726 free ( session ); 726 free ( session );
727 727
728} \ No newline at end of file 728}
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 19fcd854..81196af9 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -81,8 +81,8 @@ struct _ToxAv {
81 81
82const ToxAvCodecSettings av_DefaultSettings = { 82const ToxAvCodecSettings av_DefaultSettings = {
83 500, 83 500,
84 800, 84 1280,
85 600, 85 720,
86 86
87 64000, 87 64000,
88 20, 88 20,
@@ -300,7 +300,7 @@ int toxav_stop_call ( ToxAv *av, int32_t call_index )
300int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) 300int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video )
301{ 301{
302 if ( !av->msi_session || cii(call_index, av->msi_session) || 302 if ( !av->msi_session || cii(call_index, av->msi_session) ||
303 !av->msi_session->calls[call_index] || av->calls[call_index].call_active) { 303 !av->msi_session->calls[call_index] || av->calls[call_index].call_active) {
304 LOGGER_ERROR("Error while starting RTP session: invalid call!\n"); 304 LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
305 return ErrorInternal; 305 return ErrorInternal;
306 } 306 }
@@ -350,17 +350,17 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
350 codec_settings->audio_sample_rate, 350 codec_settings->audio_sample_rate,
351 codec_settings->audio_channels, 351 codec_settings->audio_channels,
352 codec_settings->audio_VAD_tolerance, 352 codec_settings->audio_VAD_tolerance,
353 codec_settings->video_width, 353 codec_settings->max_video_width,
354 codec_settings->video_height, 354 codec_settings->max_video_height,
355 codec_settings->video_bitrate) )) { 355 codec_settings->video_bitrate) )) {
356 356
357 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; 357 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
358 358
359 call->call_active = 1; 359 call->call_active = 1;
360 360
361 return ErrorNone; 361 return ErrorNone;
362 } 362 }
363 363
364error: 364error:
365 rtp_terminate_session(call->crtps[audio_index], av->messenger); 365 rtp_terminate_session(call->crtps[audio_index], av->messenger);
366 rtp_terminate_session(call->crtps[video_index], av->messenger); 366 rtp_terminate_session(call->crtps[video_index], av->messenger);
@@ -387,22 +387,27 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
387 } 387 }
388 388
389 CallSpecific *call = &av->calls[call_index]; 389 CallSpecific *call = &av->calls[call_index];
390 390
391 pthread_mutex_lock(&call->mutex); 391 pthread_mutex_lock(&call->mutex);
392 392
393 if (!call->call_active){ 393 if (!call->call_active) {
394 pthread_mutex_unlock(&call->mutex); 394 pthread_mutex_unlock(&call->mutex);
395 LOGGER_WARNING("Action on inactive call: %d", call_index); 395 LOGGER_WARNING("Action on inactive call: %d", call_index);
396 return ErrorNoCall; 396 return ErrorNoCall;
397 } 397 }
398 398
399
399 call->call_active = 0; 400 call->call_active = 0;
400 401
401 rtp_terminate_session(call->crtps[audio_index], av->messenger); call->crtps[audio_index] = NULL; 402 rtp_terminate_session(call->crtps[audio_index], av->messenger);
402 rtp_terminate_session(call->crtps[video_index], av->messenger); call->crtps[video_index] = NULL; 403 call->crtps[audio_index] = NULL;
403 terminate_queue(call->j_buf); call->j_buf = NULL; 404 rtp_terminate_session(call->crtps[video_index], av->messenger);
404 codec_terminate_session(call->cs); call->cs = NULL; 405 call->crtps[video_index] = NULL;
405 406 terminate_queue(call->j_buf);
407 call->j_buf = NULL;
408 codec_terminate_session(call->cs);
409 call->cs = NULL;
410
406 pthread_mutex_unlock(&call->mutex); 411 pthread_mutex_unlock(&call->mutex);
407 pthread_mutex_destroy(&call->mutex); 412 pthread_mutex_destroy(&call->mutex);
408 413
@@ -424,9 +429,10 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
424inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, 429inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload,
425 unsigned int length ) 430 unsigned int length )
426{ 431{
427 CallSpecific* call = &av->calls[call_index]; 432 CallSpecific *call = &av->calls[call_index];
433
428 if (call->crtps[type - TypeAudio]) { 434 if (call->crtps[type - TypeAudio]) {
429 435
430 if (type == TypeAudio) { 436 if (type == TypeAudio) {
431 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length); 437 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length);
432 } else { 438 } else {
@@ -447,10 +453,10 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
447 for (i = 0; i < numparts; i++) { 453 for (i = 0; i < numparts; i++) {
448 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); 454 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE);
449 payload += VIDEOFRAME_PIECE_SIZE; 455 payload += VIDEOFRAME_PIECE_SIZE;
450 456
451 if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, 457 if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger,
452 load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { 458 load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) {
453 459
454 return ErrorInternal; 460 return ErrorInternal;
455 } 461 }
456 462
@@ -460,7 +466,7 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
460 /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ 466 /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */
461 length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; 467 length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1;
462 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); 468 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length);
463 469
464 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length); 470 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length);
465 } 471 }
466 } else { 472 } else {
@@ -483,9 +489,9 @@ inline__ int toxav_recv_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
483 if ( !dest ) return ErrorInternal; 489 if ( !dest ) return ErrorInternal;
484 490
485 CallSpecific *call = &av->calls[call_index]; 491 CallSpecific *call = &av->calls[call_index];
486 492
487 if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession; 493 if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession;
488 494
489 RTPMessage *message; 495 RTPMessage *message;
490 496
491 if ( type == TypeAudio ) { 497 if ( type == TypeAudio ) {
@@ -538,16 +544,15 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
538 return ErrorNoCall; 544 return ErrorNoCall;
539 } 545 }
540 546
541 CallSpecific *call = &av->calls[call_index]; 547 CallSpecific *call = &av->calls[call_index];
542 pthread_mutex_lock(&call->mutex); 548 pthread_mutex_lock(&call->mutex);
543 549
544 if (!call->call_active){ 550 if (!call->call_active) {
545 pthread_mutex_unlock(&call->mutex); 551 pthread_mutex_unlock(&call->mutex);
546 LOGGER_WARNING("Action on inactive call: %d", call_index); 552 LOGGER_WARNING("Action on inactive call: %d", call_index);
547 return ErrorNoCall; 553 return ErrorNoCall;
548 } 554 }
549 555
550
551 uint8_t packet [RTP_PAYLOAD_SIZE]; 556 uint8_t packet [RTP_PAYLOAD_SIZE];
552 int recved_size; 557 int recved_size;
553 558
@@ -598,7 +603,7 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
598 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); 603 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);
599 604
600 *output = img; 605 *output = img;
601 606
602 pthread_mutex_unlock(&call->mutex); 607 pthread_mutex_unlock(&call->mutex);
603 return ErrorNone; 608 return ErrorNone;
604} 609}
@@ -619,19 +624,19 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr
619 return ErrorNoCall; 624 return ErrorNoCall;
620 } 625 }
621 626
622 CallSpecific* call = &av->calls[call_index]; 627 CallSpecific *call = &av->calls[call_index];
623 pthread_mutex_lock(&call->mutex); 628 pthread_mutex_lock(&call->mutex);
624 629
625 630
626 if (!call->call_active){ 631 if (!call->call_active) {
627 pthread_mutex_unlock(&call->mutex); 632 pthread_mutex_unlock(&call->mutex);
628 LOGGER_WARNING("Action on inactive call: %d", call_index); 633 LOGGER_WARNING("Action on inactive call: %d", call_index);
629 return ErrorNoCall; 634 return ErrorNoCall;
630 } 635 }
631 636
632 int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); 637 int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size);
633 pthread_mutex_unlock(&call->mutex); 638 pthread_mutex_unlock(&call->mutex);
634 639
635 return rc; 640 return rc;
636} 641}
637 642
@@ -656,14 +661,17 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
656 661
657 CallSpecific *call = &av->calls[call_index]; 662 CallSpecific *call = &av->calls[call_index];
658 pthread_mutex_lock(&call->mutex); 663 pthread_mutex_lock(&call->mutex);
659 664
660 if (!call->call_active){ 665 if (!call->call_active) {
661 pthread_mutex_unlock(&call->mutex); 666 pthread_mutex_unlock(&call->mutex);
662 LOGGER_WARNING("Action on inactive call: %d", call_index); 667 LOGGER_WARNING("Action on inactive call: %d", call_index);
663 return ErrorNoCall; 668 return ErrorNoCall;
664 } 669 }
665 670
666 reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); 671 if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0) {
672 pthread_mutex_unlock(&call->mutex);
673 return ErrorInternal;
674 }
667 675
668 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); 676 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
669 677
@@ -681,7 +689,7 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
681 689
682 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { 690 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
683 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 691 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
684 if ( copied + pkt->data.frame.sz > dest_max ) { 692 if ( copied + pkt->data.frame.sz > dest_max ) {
685 pthread_mutex_unlock(&call->mutex); 693 pthread_mutex_unlock(&call->mutex);
686 return ErrorPacketTooLarge; 694 return ErrorPacketTooLarge;
687 } 695 }
@@ -719,9 +727,9 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
719 727
720 CallSpecific *call = &av->calls[call_index]; 728 CallSpecific *call = &av->calls[call_index];
721 pthread_mutex_lock(&call->mutex); 729 pthread_mutex_lock(&call->mutex);
722 730
723 731
724 if (!call->call_active){ 732 if (!call->call_active) {
725 pthread_mutex_unlock(&call->mutex); 733 pthread_mutex_unlock(&call->mutex);
726 LOGGER_WARNING("Action on inactive call: %d", call_index); 734 LOGGER_WARNING("Action on inactive call: %d", call_index);
727 return ErrorNoCall; 735 return ErrorNoCall;
@@ -733,9 +741,9 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
733 741
734 if ( recved_size == ErrorAudioPacketLost ) { 742 if ( recved_size == ErrorAudioPacketLost ) {
735 int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); 743 int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
736 744
737 pthread_mutex_unlock(&call->mutex); 745 pthread_mutex_unlock(&call->mutex);
738 746
739 if ( dec_size < 0 ) { 747 if ( dec_size < 0 ) {
740 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); 748 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
741 return ErrorInternal; 749 return ErrorInternal;
@@ -743,9 +751,9 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
743 751
744 } else if ( recved_size ) { 752 } else if ( recved_size ) {
745 int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); 753 int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
746 754
747 pthread_mutex_unlock(&call->mutex); 755 pthread_mutex_unlock(&call->mutex);
748 756
749 if ( dec_size < 0 ) { 757 if ( dec_size < 0 ) {
750 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); 758 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
751 return ErrorInternal; 759 return ErrorInternal;
@@ -774,19 +782,19 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr
774 return ErrorNoCall; 782 return ErrorNoCall;
775 } 783 }
776 784
777 CallSpecific* call = &av->calls[call_index]; 785 CallSpecific *call = &av->calls[call_index];
778 pthread_mutex_lock(&call->mutex); 786 pthread_mutex_lock(&call->mutex);
779 787
780 788
781 if (!call->call_active){ 789 if (!call->call_active) {
782 pthread_mutex_unlock(&call->mutex); 790 pthread_mutex_unlock(&call->mutex);
783 LOGGER_WARNING("Action on inactive call: %d", call_index); 791 LOGGER_WARNING("Action on inactive call: %d", call_index);
784 return ErrorNoCall; 792 return ErrorNoCall;
785 } 793 }
786 794
787 int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); 795 int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
788 pthread_mutex_unlock(&call->mutex); 796 pthread_mutex_unlock(&call->mutex);
789 797
790 return rc; 798 return rc;
791} 799}
792 800
@@ -810,19 +818,18 @@ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t
810 return ErrorNoCall; 818 return ErrorNoCall;
811 } 819 }
812 820
813 CallSpecific* call = &av->calls[call_index]; 821 CallSpecific *call = &av->calls[call_index];
814 pthread_mutex_lock(&call->mutex); 822 pthread_mutex_lock(&call->mutex);
815 823
816 824
817 if (!call->call_active){ 825 if (!call->call_active) {
818 pthread_mutex_unlock(&call->mutex); 826 pthread_mutex_unlock(&call->mutex);
819 LOGGER_WARNING("Action on inactive call: %d", call_index); 827 LOGGER_WARNING("Action on inactive call: %d", call_index);
820 return ErrorNoCall; 828 return ErrorNoCall;
821 } 829 }
822
823 int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max);
824 pthread_mutex_unlock(&call->mutex);
825 830
831 int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max);
832 pthread_mutex_unlock(&call->mutex);
826 833
827 if (rc < 0) { 834 if (rc < 0) {
828 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); 835 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc));
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 2e71c4da..b7659441 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -120,8 +120,8 @@ typedef enum {
120 */ 120 */
121typedef struct _ToxAvCodecSettings { 121typedef struct _ToxAvCodecSettings {
122 uint32_t video_bitrate; /* In kbits/s */ 122 uint32_t video_bitrate; /* In kbits/s */
123 uint16_t video_width; /* In px */ 123 uint16_t max_video_width; /* In px */
124 uint16_t video_height; /* In px */ 124 uint16_t max_video_height; /* In px */
125 125
126 uint32_t audio_bitrate; /* In bits/s */ 126 uint32_t audio_bitrate; /* In bits/s */
127 uint16_t audio_frame_duration; /* In ms */ 127 uint16_t audio_frame_duration; /* In ms */
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 4344fdcb..2adbd870 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -2598,6 +2598,10 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
2598 2598
2599 if (temp.status >= 3) { 2599 if (temp.status >= 3) {
2600 int fnum = m_addfriend_norequest(m, temp.client_id); 2600 int fnum = m_addfriend_norequest(m, temp.client_id);
2601
2602 if (fnum < 0)
2603 continue;
2604
2601 setfriendname(m, fnum, temp.name, ntohs(temp.name_length)); 2605 setfriendname(m, fnum, temp.name, ntohs(temp.name_length));
2602 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length)); 2606 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length));
2603 set_friend_userstatus(m, fnum, temp.userstatus); 2607 set_friend_userstatus(m, fnum, temp.userstatus);