summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxhe <xw897002528@gmail.com>2018-01-14 21:46:06 +0800
committeriphydf <iphydf@users.noreply.github.com>2018-01-25 14:29:01 +0000
commit0becafd272997ab1fcbe93ce3d56b27aae6cd80a (patch)
treee09f947a654b05e173229f6dd9c8be8124464536
parentcd8080f6d180677d03edff4878305c655c29bd69 (diff)
Split bit_rate_set(), one for audio, one for video.
Fixes #572. As discussed in the issue, there's a risk that toxcore may not hold the maximum bitrates libvpx supports, if toxcore insists on using integer type. I initially proposed to have another flag in set(), so that we can use unsigned type instead. iphydf came up with a better solution, that is splitting the original functions, one for audio, one for video. Now, we could safely replace int32_t with uint32_t. Also: clean video_bit_rate_invalid() Though this is not a part of issue #572, as it's used in the toxav_bit_rate_set(), i cleaned the code. As mannol said, there should be a check. Uint32_t is large enough to hold the maximum bitrates libvpx supports, but user may pass a value larger than uint while smaller than uint32_t. Thanks to the reminding from nurupo, it's no longer a stub function. Bitrate error enums are shared for both audio and video https://github.com/TokTok/c-toxcore/pull/578#issuecomment-360095609, just as iphydf said.
-rw-r--r--auto_tests/toxav_basic_test.c6
-rw-r--r--toxav/toxav.api.h59
-rw-r--r--toxav/toxav.c169
-rw-r--r--toxav/toxav.h31
4 files changed, 152 insertions, 113 deletions
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index 2b77da37..bc55d69c 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -476,19 +476,19 @@ START_TEST(test_AV_flows)
476 476
477 printf("Call started as audio only\n"); 477 printf("Call started as audio only\n");
478 printf("Turning on video for Alice...\n"); 478 printf("Turning on video for Alice...\n");
479 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 1000, NULL)); 479 ck_assert(toxav_bit_rate_set_video(AliceAV, 0, 1000, NULL));
480 480
481 iterate_tox(bootstrap, Alice, Bob); 481 iterate_tox(bootstrap, Alice, Bob);
482 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V); 482 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V);
483 483
484 printf("Turning off video for Alice...\n"); 484 printf("Turning off video for Alice...\n");
485 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 0, NULL)); 485 ck_assert(toxav_bit_rate_set_video(AliceAV, 0, 0, NULL));
486 486
487 iterate_tox(bootstrap, Alice, Bob); 487 iterate_tox(bootstrap, Alice, Bob);
488 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V)); 488 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V));
489 489
490 printf("Turning off audio for Alice...\n"); 490 printf("Turning off audio for Alice...\n");
491 ck_assert(toxav_bit_rate_set(AliceAV, 0, 0, -1, NULL)); 491 ck_assert(toxav_bit_rate_set_audio(AliceAV, 0, 0, NULL));
492 492
493 iterate_tox(bootstrap, Alice, Bob); 493 iterate_tox(bootstrap, Alice, Bob);
494 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A)); 494 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A));
diff --git a/toxav/toxav.api.h b/toxav/toxav.api.h
index d6f30c67..511b9e2d 100644
--- a/toxav/toxav.api.h
+++ b/toxav/toxav.api.h
@@ -386,40 +386,45 @@ bool call_control(uint32_t friend_number, CALL_CONTROL control) {
386 ******************************************************************************/ 386 ******************************************************************************/
387 387
388 388
389error for bit_rate_set {
390 /**
391 * Synchronization error occurred.
392 */
393 SYNC,
394 /**
395 * The bit rate passed was not one of the supported values.
396 */
397 INVALID_BIT_RATE,
398 /**
399 * The friend_number passed did not designate a valid friend.
400 */
401 FRIEND_NOT_FOUND,
402 /**
403 * This client is currently not in a call with the friend.
404 */
405 FRIEND_NOT_IN_CALL,
406}
407
389namespace bit_rate { 408namespace bit_rate {
390 /** 409 /**
391 * Set the bit rate to be used in subsequent audio/video frames. 410 * Set the bit rate to be used in subsequent audio frames.
392 * 411 *
393 * @param friend_number The friend number of the friend for which to set the 412 * @param friend_number The friend number of the friend for which to set the
394 * bit rate. 413 * bit rate.
395 * @param audio_bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable 414 * @param audio_bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable.
396 * audio sending. Set to -1 to leave unchanged.
397 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable
398 * video sending. Set to -1 to leave unchanged.
399 * 415 *
400 */ 416 */
401 bool set(uint32_t friend_number, int32_t audio_bit_rate, int32_t video_bit_rate) { 417
402 /** 418 bool set_audio(uint32_t friend_number, uint32_t audio_bit_rate) with error for bit_rate_set;
403 * Synchronization error occurred. 419 /**
404 */ 420 * Set the bit rate to be used in subsequent video frames.
405 SYNC, 421 *
406 /** 422 * @param friend_number The friend number of the friend for which to set the
407 * The audio bit rate passed was not one of the supported values. 423 * bit rate.
408 */ 424 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable.
409 INVALID_AUDIO_BIT_RATE, 425 *
410 /** 426 */
411 * The video bit rate passed was not one of the supported values. 427 bool set_video(uint32_t friend_number, uint32_t video_bit_rate) with error for bit_rate_set;
412 */
413 INVALID_VIDEO_BIT_RATE,
414 /**
415 * The friend_number passed did not designate a valid friend.
416 */
417 FRIEND_NOT_FOUND,
418 /**
419 * This client is currently not in a call with the friend.
420 */
421 FRIEND_NOT_IN_CALL,
422 }
423 428
424 event status { 429 event status {
425 /** 430 /**
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 74836691..27575063 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -32,6 +32,7 @@
32 32
33#include <assert.h> 33#include <assert.h>
34#include <errno.h> 34#include <errno.h>
35#include <limits.h>
35#include <stdlib.h> 36#include <stdlib.h>
36#include <string.h> 37#include <string.h>
37 38
@@ -524,8 +525,8 @@ END:
524 525
525 return rc == TOXAV_ERR_CALL_CONTROL_OK; 526 return rc == TOXAV_ERR_CALL_CONTROL_OK;
526} 527}
527bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rate, 528bool toxav_bit_rate_set_audio(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate,
528 int32_t video_bit_rate, TOXAV_ERR_BIT_RATE_SET *error) 529 TOXAV_ERR_BIT_RATE_SET *error)
529{ 530{
530 TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK; 531 TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK;
531 ToxAVCall *call; 532 ToxAVCall *call;
@@ -536,12 +537,7 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
536 } 537 }
537 538
538 if (audio_bit_rate > 0 && audio_bit_rate_invalid(audio_bit_rate)) { 539 if (audio_bit_rate > 0 && audio_bit_rate_invalid(audio_bit_rate)) {
539 rc = TOXAV_ERR_BIT_RATE_SET_INVALID_AUDIO_BIT_RATE; 540 rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE;
540 goto END;
541 }
542
543 if (video_bit_rate > 0 && video_bit_rate_invalid(video_bit_rate)) {
544 rc = TOXAV_ERR_BIT_RATE_SET_INVALID_VIDEO_BIT_RATE;
545 goto END; 541 goto END;
546 } 542 }
547 543
@@ -554,84 +550,114 @@ bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rat
554 goto END; 550 goto END;
555 } 551 }
556 552
557 if (audio_bit_rate >= 0) { 553 LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", audio_bit_rate);
558 LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", audio_bit_rate); 554
555 if (call->audio_bit_rate == audio_bit_rate) {
556 LOGGER_DEBUG(av->m->log, "Audio bitrate already set to: %d", audio_bit_rate);
557 } else if (audio_bit_rate == 0) {
558 LOGGER_DEBUG(av->m->log, "Turned off audio sending");
559 559
560 if (call->audio_bit_rate == audio_bit_rate) { 560 if (msi_change_capabilities(call->msi_call, call->msi_call->
561 LOGGER_DEBUG(av->m->log, "Audio bitrate already set to: %d", audio_bit_rate); 561 self_capabilities ^ msi_CapSAudio) != 0) {
562 } else if (audio_bit_rate == 0) { 562 pthread_mutex_unlock(av->mutex);
563 LOGGER_DEBUG(av->m->log, "Turned off audio sending"); 563 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
564 goto END;
565 }
566
567 /* Audio sending is turned off; notify peer */
568 call->audio_bit_rate = 0;
569 } else {
570 pthread_mutex_lock(call->mutex);
564 571
565 if (msi_change_capabilities(call->msi_call, call->msi_call-> 572 if (call->audio_bit_rate == 0) {
566 self_capabilities ^ msi_CapSAudio) != 0) { 573 LOGGER_DEBUG(av->m->log, "Turned on audio sending");
574
575 /* The audio has been turned off before this */
576 if (msi_change_capabilities(call->msi_call, call->
577 msi_call->self_capabilities | msi_CapSAudio) != 0) {
578 pthread_mutex_unlock(call->mutex);
567 pthread_mutex_unlock(av->mutex); 579 pthread_mutex_unlock(av->mutex);
568 rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 580 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
569 goto END; 581 goto END;
570 } 582 }
571
572 /* Audio sending is turned off; notify peer */
573 call->audio_bit_rate = 0;
574 } else { 583 } else {
575 pthread_mutex_lock(call->mutex); 584 LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", audio_bit_rate);
585 }
576 586
577 if (call->audio_bit_rate == 0) { 587 call->audio_bit_rate = audio_bit_rate;
578 LOGGER_DEBUG(av->m->log, "Turned on audio sending"); 588 pthread_mutex_unlock(call->mutex);
589 }
579 590
580 /* The audio has been turned off before this */ 591 pthread_mutex_unlock(av->mutex);
581 if (msi_change_capabilities(call->msi_call, call-> 592END:
582 msi_call->self_capabilities | msi_CapSAudio) != 0) {
583 pthread_mutex_unlock(call->mutex);
584 pthread_mutex_unlock(av->mutex);
585 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
586 goto END;
587 }
588 } else {
589 LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", audio_bit_rate);
590 }
591 593
592 call->audio_bit_rate = audio_bit_rate; 594 if (error) {
593 pthread_mutex_unlock(call->mutex); 595 *error = rc;
594 }
595 } 596 }
596 597
597 if (video_bit_rate >= 0) { 598 return rc == TOXAV_ERR_BIT_RATE_SET_OK;
598 LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", video_bit_rate); 599}
600bool toxav_bit_rate_set_video(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate,
601 TOXAV_ERR_BIT_RATE_SET *error)
602{
603 TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK;
604 ToxAVCall *call;
599 605
600 if (call->video_bit_rate == video_bit_rate) { 606 if (m_friend_exists(av->m, friend_number) == 0) {
601 LOGGER_DEBUG(av->m->log, "Video bitrate already set to: %d", video_bit_rate); 607 rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
602 } else if (video_bit_rate == 0) { 608 goto END;
603 LOGGER_DEBUG(av->m->log, "Turned off video sending"); 609 }
604 610
605 /* Video sending is turned off; notify peer */ 611 if (video_bit_rate > 0 && video_bit_rate_invalid(video_bit_rate)) {
606 if (msi_change_capabilities(call->msi_call, call->msi_call-> 612 rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE;
607 self_capabilities ^ msi_CapSVideo) != 0) { 613 goto END;
614 }
615
616 pthread_mutex_lock(av->mutex);
617 call = call_get(av, friend_number);
618
619 if (call == NULL || !call->active || call->msi_call->state != msi_CallActive) {
620 pthread_mutex_unlock(av->mutex);
621 rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL;
622 goto END;
623 }
624
625 LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", video_bit_rate);
626
627 if (call->video_bit_rate == video_bit_rate) {
628 LOGGER_DEBUG(av->m->log, "Video bitrate already set to: %d", video_bit_rate);
629 } else if (video_bit_rate == 0) {
630 LOGGER_DEBUG(av->m->log, "Turned off video sending");
631
632 /* Video sending is turned off; notify peer */
633 if (msi_change_capabilities(call->msi_call, call->msi_call->
634 self_capabilities ^ msi_CapSVideo) != 0) {
635 pthread_mutex_unlock(av->mutex);
636 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
637 goto END;
638 }
639
640 call->video_bit_rate = 0;
641 } else {
642 pthread_mutex_lock(call->mutex);
643
644 if (call->video_bit_rate == 0) {
645 LOGGER_DEBUG(av->m->log, "Turned on video sending");
646
647 /* The video has been turned off before this */
648 if (msi_change_capabilities(call->msi_call, call->
649 msi_call->self_capabilities | msi_CapSVideo) != 0) {
650 pthread_mutex_unlock(call->mutex);
608 pthread_mutex_unlock(av->mutex); 651 pthread_mutex_unlock(av->mutex);
609 rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 652 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
610 goto END; 653 goto END;
611 } 654 }
612
613 call->video_bit_rate = 0;
614 } else { 655 } else {
615 pthread_mutex_lock(call->mutex); 656 LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", video_bit_rate);
616
617 if (call->video_bit_rate == 0) {
618 LOGGER_DEBUG(av->m->log, "Turned on video sending");
619
620 /* The video has been turned off before this */
621 if (msi_change_capabilities(call->msi_call, call->
622 msi_call->self_capabilities | msi_CapSVideo) != 0) {
623 pthread_mutex_unlock(call->mutex);
624 pthread_mutex_unlock(av->mutex);
625 rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
626 goto END;
627 }
628 } else {
629 LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", video_bit_rate);
630 }
631
632 call->video_bit_rate = video_bit_rate;
633 pthread_mutex_unlock(call->mutex);
634 } 657 }
658
659 call->video_bit_rate = video_bit_rate;
660 pthread_mutex_unlock(call->mutex);
635 } 661 }
636 662
637 pthread_mutex_unlock(av->mutex); 663 pthread_mutex_unlock(av->mutex);
@@ -1020,9 +1046,14 @@ bool audio_bit_rate_invalid(uint32_t bit_rate)
1020} 1046}
1021bool video_bit_rate_invalid(uint32_t bit_rate) 1047bool video_bit_rate_invalid(uint32_t bit_rate)
1022{ 1048{
1023 (void) bit_rate; 1049 /* https://www.webmproject.org/docs/webm-sdk/structvpx__codec__enc__cfg.html shows the following:
1024 /* TODO(mannol): If anyone knows the answer to this one please fill it up */ 1050 * unsigned int rc_target_bitrate
1025 return false; 1051 * the range of uint varies from platform to platform
1052 * though, uint32_t should be large enough to store bitrates,
1053 * we may want to prevent from passing overflowed bitrates to libvpx
1054 * more in detail, it's the case where bit_rate is larger than uint, but smaller than uint32_t
1055 */
1056 return bit_rate > UINT_MAX;
1026} 1057}
1027bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state) 1058bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
1028{ 1059{
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 2e48d599..f8a683a6 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -494,14 +494,9 @@ typedef enum TOXAV_ERR_BIT_RATE_SET {
494 TOXAV_ERR_BIT_RATE_SET_SYNC, 494 TOXAV_ERR_BIT_RATE_SET_SYNC,
495 495
496 /** 496 /**
497 * The audio bit rate passed was not one of the supported values. 497 * The bit rate passed was not one of the supported values.
498 */ 498 */
499 TOXAV_ERR_BIT_RATE_SET_INVALID_AUDIO_BIT_RATE, 499 TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE,
500
501 /**
502 * The video bit rate passed was not one of the supported values.
503 */
504 TOXAV_ERR_BIT_RATE_SET_INVALID_VIDEO_BIT_RATE,
505 500
506 /** 501 /**
507 * The friend_number passed did not designate a valid friend. 502 * The friend_number passed did not designate a valid friend.
@@ -517,18 +512,26 @@ typedef enum TOXAV_ERR_BIT_RATE_SET {
517 512
518 513
519/** 514/**
520 * Set the bit rate to be used in subsequent audio/video frames. 515 * Set the bit rate to be used in subsequent audio frames.
516 *
517 * @param friend_number The friend number of the friend for which to set the
518 * bit rate.
519 * @param audio_bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable.
520 *
521 */
522bool toxav_bit_rate_set_audio(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate,
523 TOXAV_ERR_BIT_RATE_SET *error);
524
525/**
526 * Set the bit rate to be used in subsequent video frames.
521 * 527 *
522 * @param friend_number The friend number of the friend for which to set the 528 * @param friend_number The friend number of the friend for which to set the
523 * bit rate. 529 * bit rate.
524 * @param audio_bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable 530 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable.
525 * audio sending. Set to -1 to leave unchanged.
526 * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable
527 * video sending. Set to -1 to leave unchanged.
528 * 531 *
529 */ 532 */
530bool toxav_bit_rate_set(ToxAV *av, uint32_t friend_number, int32_t audio_bit_rate, int32_t video_bit_rate, 533bool toxav_bit_rate_set_video(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate,
531 TOXAV_ERR_BIT_RATE_SET *error); 534 TOXAV_ERR_BIT_RATE_SET *error);
532 535
533/** 536/**
534 * The function type for the bit_rate_status callback. The event is triggered 537 * The function type for the bit_rate_status callback. The event is triggered