summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c133
1 files changed, 70 insertions, 63 deletions
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));