mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Bunch of random changes
This commit is contained in:
parent
42b25a4d3e
commit
0fa03b9240
|
@ -3,8 +3,8 @@ if BUILD_TESTS
|
|||
#TESTS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
#check_PROGRAMS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
|
||||
TESTS = toxav_basic_test
|
||||
check_PROGRAMS = toxav_basic_test
|
||||
TESTS = toxav_many_test
|
||||
check_PROGRAMS = toxav_many_test
|
||||
|
||||
AUTOTEST_CFLAGS = \
|
||||
$(LIBSODIUM_CFLAGS) \
|
||||
|
@ -76,11 +76,18 @@ endif
|
|||
|
||||
|
||||
if BUILD_AV
|
||||
toxav_basic_test_SOURCES = ../auto_tests/toxav_basic_test.c
|
||||
#toxav_basic_test_SOURCES = ../auto_tests/toxav_basic_test.c
|
||||
|
||||
toxav_basic_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#toxav_basic_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
toxav_basic_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#toxav_basic_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c
|
||||
|
||||
toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
toxav_many_test_LDADD = $(AUTOTEST_LDADD)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
@ -500,11 +500,6 @@ Suite *tox_suite(void)
|
|||
tcase_set_timeout(tc_av_flows, 100); /* Timeout on 100 too much? */
|
||||
suite_add_tcase(s, tc_av_flows);
|
||||
|
||||
TCase *tc_av_three_calls = tcase_create("AV_three_calls");
|
||||
tcase_add_test(tc_av_three_calls, test_AV_three_calls);
|
||||
tcase_set_timeout(tc_av_three_calls, 100); /* Timeout on 100 too much? */
|
||||
suite_add_tcase(s, tc_av_three_calls);
|
||||
|
||||
return s;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <check.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../toxcore/tox.h"
|
||||
#include "../toxcore/logger.h"
|
||||
#include "../toxav/toxav.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#define c_sleep(x) Sleep(1*x)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define c_sleep(x) usleep(1000*x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef enum _CallStatus {
|
||||
none,
|
||||
InCall,
|
||||
Ringing,
|
||||
Ended,
|
||||
Rejected,
|
||||
Cancel
|
||||
|
||||
} CallStatus;
|
||||
|
||||
typedef struct _Party {
|
||||
CallStatus status;
|
||||
ToxAv *av;
|
||||
time_t *CallStarted;
|
||||
int call_index;
|
||||
} Party;
|
||||
|
||||
typedef struct _Status {
|
||||
Party Alice;
|
||||
Party Bob;
|
||||
} Status;
|
||||
|
||||
void accept_friend_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
if (length == 7 && memcmp("gentoo", data, 7) == 0) {
|
||||
tox_add_friend_norequest(m, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void callback_recv_invite ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ringing;
|
||||
cast->call_index = call_index;
|
||||
}
|
||||
void callback_recv_ringing ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ringing;
|
||||
}
|
||||
void callback_recv_starting ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = InCall;
|
||||
toxav_prepare_transmission(cast->av, call_index, 1);
|
||||
}
|
||||
void callback_recv_ending ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ended;
|
||||
}
|
||||
|
||||
void callback_recv_error ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "AV internal error");
|
||||
}
|
||||
|
||||
void callback_call_started ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = InCall;
|
||||
toxav_prepare_transmission(cast->av, call_index, 1);
|
||||
}
|
||||
void callback_call_canceled ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Cancel;
|
||||
}
|
||||
void callback_call_rejected ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Rejected;
|
||||
}
|
||||
void callback_call_ended ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ended;
|
||||
}
|
||||
|
||||
void callback_requ_timeout ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "No answer!");
|
||||
}
|
||||
/*************************************************************************************************/
|
407
auto_tests/toxav_many_test.c
Normal file
407
auto_tests/toxav_many_test.c
Normal file
|
@ -0,0 +1,407 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <check.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../toxcore/tox.h"
|
||||
#include "../toxcore/logger.h"
|
||||
#include "../toxav/toxav.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#define c_sleep(x) Sleep(1*x)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#define c_sleep(x) usleep(1000*x)
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum _CallStatus {
|
||||
none,
|
||||
InCall,
|
||||
Ringing,
|
||||
Ended,
|
||||
Rejected,
|
||||
Cancel
|
||||
|
||||
} CallStatus;
|
||||
|
||||
typedef struct _Party {
|
||||
CallStatus status;
|
||||
ToxAv *av;
|
||||
int id;
|
||||
} Party;
|
||||
|
||||
typedef struct _ACall {
|
||||
pthread_t tid;
|
||||
|
||||
Party Caller;
|
||||
Party Callee;
|
||||
} ACall;
|
||||
|
||||
typedef struct _Status {
|
||||
ACall calls[3]; /* Make 3 calls for this test */
|
||||
} Status;
|
||||
|
||||
void accept_friend_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
if (length == 7 && memcmp("gentoo", data, 7) == 0) {
|
||||
tox_add_friend_norequest(m, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void callback_recv_invite ( uint32_t call_index, void *_arg )
|
||||
{/*
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Callee.status = Ringing;*/
|
||||
}
|
||||
void callback_recv_ringing ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Caller.status = Ringing;
|
||||
}
|
||||
void callback_recv_starting ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Caller.status = InCall;
|
||||
}
|
||||
void callback_recv_ending ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Caller.status = Ended;
|
||||
}
|
||||
|
||||
void callback_recv_error ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "AV internal error");
|
||||
}
|
||||
|
||||
void callback_call_started ( uint32_t call_index, void *_arg )
|
||||
{/*
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Callee.status = InCall;*/
|
||||
}
|
||||
void callback_call_canceled ( uint32_t call_index, void *_arg )
|
||||
{/*
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Callee.status = Cancel;*/
|
||||
}
|
||||
void callback_call_rejected ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Caller.status = Rejected;
|
||||
}
|
||||
void callback_call_ended ( uint32_t call_index, void *_arg )
|
||||
{/*
|
||||
Status *cast = _arg;
|
||||
|
||||
cast->calls[call_index].Callee.status = Ended;*/
|
||||
}
|
||||
|
||||
void callback_requ_timeout ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "No answer!");
|
||||
}
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
void* in_thread_call (void* arg)
|
||||
{
|
||||
#define call_print(call, what, args...) printf("[%d] " what "\n", call, ##args)
|
||||
|
||||
ACall* this_call = arg;
|
||||
uint64_t start = 0;
|
||||
int step = 0,running = 1;
|
||||
int call_idx;
|
||||
|
||||
int16_t sample_payload[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
vpx_image_t *sample_image = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, 128, 128, 1);
|
||||
|
||||
memcpy(sample_image->planes[VPX_PLANE_Y], sample_payload, 10);
|
||||
memcpy(sample_image->planes[VPX_PLANE_U], sample_payload, 10);
|
||||
memcpy(sample_image->planes[VPX_PLANE_V], sample_payload, 10);
|
||||
|
||||
|
||||
/* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
|
||||
while (running) {
|
||||
|
||||
switch ( step ) {
|
||||
case 0: /* CALLER */
|
||||
toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, TypeVideo, 10);
|
||||
call_print(call_idx, "Calling ...");
|
||||
step++;
|
||||
break;
|
||||
case 1: /* CALLEE */
|
||||
if (this_call->Caller.status == Ringing) {
|
||||
call_print(call_idx, "Callee answers ...");
|
||||
toxav_answer(this_call->Callee.av, 0, TypeVideo);
|
||||
step++;
|
||||
start = time(NULL);
|
||||
} break;
|
||||
case 2: /* Rtp transmission */
|
||||
if (this_call->Caller.status == InCall) { /* I think this is okay */
|
||||
call_print(call_idx, "Sending rtp ...");
|
||||
|
||||
c_sleep(1000); /* We have race condition here */
|
||||
toxav_prepare_transmission(this_call->Callee.av, 0, 1);
|
||||
toxav_prepare_transmission(this_call->Caller.av, call_idx, 1);
|
||||
|
||||
while (time(NULL) - start < 10) { /* 10 seconds */
|
||||
/* Both send */
|
||||
toxav_send_audio(this_call->Caller.av, call_idx, sample_payload, 10);
|
||||
toxav_send_video(this_call->Caller.av, call_idx, sample_image);
|
||||
|
||||
toxav_send_audio(this_call->Callee.av, 0, sample_payload, 10);
|
||||
toxav_send_video(this_call->Callee.av, 0, sample_image);
|
||||
|
||||
/* Both receive */
|
||||
int16_t storage[10];
|
||||
vpx_image_t *video_storage;
|
||||
int recved;
|
||||
|
||||
/* Payload from CALLEE */
|
||||
recved = toxav_recv_audio(this_call->Caller.av, call_idx, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");*/
|
||||
memset(storage, 0, 10);
|
||||
}
|
||||
|
||||
/* Video payload */
|
||||
toxav_recv_video(this_call->Caller.av, call_idx, &video_storage);
|
||||
|
||||
if ( video_storage ) {
|
||||
/*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
|
||||
* memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
|
||||
* memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from CALLEE is invalid");*/
|
||||
vpx_img_free(video_storage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Payload from CALLER */
|
||||
recved = toxav_recv_audio(this_call->Callee.av, 0, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");*/
|
||||
}
|
||||
|
||||
/* Video payload */
|
||||
toxav_recv_video(this_call->Callee.av, 0, &video_storage);
|
||||
|
||||
if ( video_storage ) {
|
||||
/*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
|
||||
* memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
|
||||
* memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from CALLER is invalid");*/
|
||||
vpx_img_free(video_storage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
step++; /* This terminates the loop */
|
||||
|
||||
toxav_kill_transmission(this_call->Callee.av, 0);
|
||||
toxav_kill_transmission(this_call->Caller.av, call_idx);
|
||||
|
||||
/* Call over CALLER hangs up */
|
||||
toxav_hangup(this_call->Caller.av, call_idx);
|
||||
call_print(call_idx, "Hanging up ...");
|
||||
}
|
||||
break;
|
||||
case 3: /* Wait for Both to have status ended */
|
||||
if (this_call->Caller.status == Ended) {
|
||||
c_sleep(1000); /* race condition */
|
||||
this_call->Callee.status == Ended;
|
||||
running = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
c_sleep(20);
|
||||
}
|
||||
|
||||
call_print(call_idx, "Call ended successfully!");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
START_TEST(test_AV_three_calls)
|
||||
{
|
||||
long long unsigned int cur_time = time(NULL);
|
||||
Tox *bootstrap_node = tox_new(0);
|
||||
Tox *caller = tox_new(0);
|
||||
Tox *callees[3] = {
|
||||
tox_new(0),
|
||||
tox_new(0),
|
||||
tox_new(0),
|
||||
};
|
||||
|
||||
|
||||
ck_assert_msg(bootstrap_node != NULL, "Failed to create bootstrap node");
|
||||
|
||||
int i = 0;
|
||||
for (; i < 3; i ++) {
|
||||
ck_assert_msg(callees[i] != NULL, "Failed to create 3 tox instances");
|
||||
}
|
||||
|
||||
for ( i = 0; i < 3; i ++ ) {
|
||||
uint32_t to_compare = 974536;
|
||||
tox_callback_friend_request(callees[i], accept_friend_request, &to_compare);
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(callees[i], address);
|
||||
|
||||
int test = tox_add_friend(caller, address, (uint8_t *)"gentoo", 7);
|
||||
ck_assert_msg( test == i, "Failed to add friend error code: %i", test);
|
||||
}
|
||||
|
||||
uint8_t off = 1;
|
||||
|
||||
while (1) {
|
||||
tox_do(bootstrap_node);
|
||||
tox_do(caller);
|
||||
|
||||
for (i = 0; i < 3; i ++) {
|
||||
tox_do(callees[i]);
|
||||
}
|
||||
|
||||
|
||||
if (tox_isconnected(bootstrap_node) &&
|
||||
tox_isconnected(caller) &&
|
||||
tox_isconnected(callees[0]) &&
|
||||
tox_isconnected(callees[1]) &&
|
||||
tox_isconnected(callees[2]) && off) {
|
||||
printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
|
||||
off = 0;
|
||||
}
|
||||
|
||||
|
||||
if (tox_get_friend_connection_status(caller, 0) == 1 &&
|
||||
tox_get_friend_connection_status(caller, 1) == 1 &&
|
||||
tox_get_friend_connection_status(caller, 2) == 1 )
|
||||
break;
|
||||
|
||||
c_sleep(20);
|
||||
}
|
||||
|
||||
printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
|
||||
|
||||
|
||||
ToxAvCodecSettings cast = av_DefaultSettings;
|
||||
|
||||
ToxAv* uniqcallerav = toxav_new(caller, &cast, 3);
|
||||
|
||||
Status status_control = {
|
||||
0,
|
||||
{none, uniqcallerav, 0},
|
||||
{none, toxav_new(callees[0], &cast, 1), 0},
|
||||
|
||||
0,
|
||||
{none, uniqcallerav},
|
||||
{none, toxav_new(callees[1], &cast, 1), 1},
|
||||
|
||||
0,
|
||||
{none, uniqcallerav},
|
||||
{none, toxav_new(callees[2], &cast, 1), 2}
|
||||
};
|
||||
|
||||
|
||||
toxav_register_callstate_callback(callback_call_started, av_OnStart, &status_control);
|
||||
toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, &status_control);
|
||||
toxav_register_callstate_callback(callback_call_rejected, av_OnReject, &status_control);
|
||||
toxav_register_callstate_callback(callback_call_ended, av_OnEnd, &status_control);
|
||||
toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, &status_control);
|
||||
|
||||
toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, &status_control);
|
||||
toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, &status_control);
|
||||
toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, &status_control);
|
||||
|
||||
toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
|
||||
toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
|
||||
|
||||
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
|
||||
|
||||
|
||||
/* Now start 3 calls and they'll run for 10 s */
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
pthread_detach(status_control.calls[i].tid);
|
||||
|
||||
while (
|
||||
status_control.calls[0].Callee.status != Ended && status_control.calls[0].Caller.status != Ended &&
|
||||
status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended &&
|
||||
status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended
|
||||
) {
|
||||
tox_do(bootstrap_node);
|
||||
tox_do(caller);
|
||||
tox_do(callees[0]);
|
||||
tox_do(callees[1]);
|
||||
tox_do(callees[2]);
|
||||
c_sleep(20);
|
||||
}
|
||||
|
||||
toxav_kill(status_control.calls[0].Caller.av);
|
||||
toxav_kill(status_control.calls[0].Callee.av);
|
||||
toxav_kill(status_control.calls[1].Callee.av);
|
||||
toxav_kill(status_control.calls[2].Callee.av);
|
||||
|
||||
tox_kill(bootstrap_node);
|
||||
tox_kill(caller);
|
||||
for ( i = 0; i < 3; i ++)
|
||||
tox_kill(callees[i]);
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
|
||||
|
||||
Suite *tox_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("ToxAV");
|
||||
|
||||
TCase *tc_av_three_calls = tcase_create("AV_three_calls");
|
||||
tcase_add_test(tc_av_three_calls, test_AV_three_calls);
|
||||
tcase_set_timeout(tc_av_three_calls, 150);
|
||||
suite_add_tcase(s, tc_av_three_calls);
|
||||
|
||||
return s;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Suite *tox = tox_suite();
|
||||
SRunner *test_runner = srunner_create(tox);
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
srunner_run_all(test_runner, CK_NORMAL);
|
||||
int number_failed = srunner_ntests_failed(test_runner);
|
||||
|
||||
srunner_free(test_runner);
|
||||
|
||||
return number_failed;
|
||||
|
||||
}
|
93
configure.ac
93
configure.ac
|
@ -31,7 +31,6 @@ BUILD_DHT_BOOTSTRAP_DAEMON="no"
|
|||
BUILD_NTOX="no"
|
||||
BUILD_TESTS="yes"
|
||||
BUILD_AV="yes"
|
||||
BUILD_PHONE="no"
|
||||
BUILD_TESTING="yes"
|
||||
|
||||
LOGGING="no"
|
||||
|
@ -135,23 +134,11 @@ AC_ARG_WITH(logger-path,
|
|||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_ARG_ENABLE([phone],
|
||||
[AC_HELP_STRING([--enable-phone], [build test phone (default: auto)]) ],
|
||||
[
|
||||
if test "x$enableval" = "xno"; then
|
||||
BUILD_PHONE="no"
|
||||
elif test "x$enableval" = "xyes"; then
|
||||
BUILD_PHONE="yes"
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([av],
|
||||
[AC_HELP_STRING([--disable-av], [build AV support libraries (default: auto)]) ],
|
||||
[
|
||||
if test "x$enableval" = "xno"; then
|
||||
BUILD_AV="no"
|
||||
BUILD_PHONE="no"
|
||||
elif test "x$enableval" = "xyes"; then
|
||||
BUILD_AV="yes"
|
||||
fi
|
||||
|
@ -447,94 +434,16 @@ if test "x$BUILD_AV" = "xyes"; then
|
|||
[
|
||||
AC_MSG_WARN([disabling AV support: required pthread library not found])
|
||||
BUILD_AV="no"
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([AVFORMAT], [libavformat],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $AVFORMAT_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([AVCODEC], [libavcodec],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $AVCODEC_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([AVUTIL], [libavutil],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $AVUTIL_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([AVDEVICE], [libavdevice],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $AVDEVICE_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([SWSCALE], [libswscale],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $SWSCALE_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([SDL], [sdl],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $SDL_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
if test "x$BUILD_PHONE" = "xyes"; then
|
||||
PKG_CHECK_MODULES([OPENAL], [openal],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling phone $OPENAL_PKG_ERRORS])
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
#If all dependencies are here add support video define for phone.c
|
||||
if test "x$BUILD_PHONE" == "xyes"; then
|
||||
#Set FFMpeg define
|
||||
AC_DEFINE([TOX_FFMPEG], [1], [Support video])
|
||||
fi
|
||||
|
||||
if test "x$BUILD_AV" = "xyes"; then
|
||||
PKG_CHECK_MODULES([OPUS], [opus],
|
||||
[],
|
||||
[
|
||||
AC_MSG_WARN([disabling AV support $OPUS_PKG_ERRORS])
|
||||
BUILD_AV="no"
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
@ -545,7 +454,6 @@ if test "x$BUILD_AV" = "xyes"; then
|
|||
[
|
||||
AC_MSG_WARN([disabling AV support $VPX_PKG_ERRORS])
|
||||
BUILD_AV="no"
|
||||
BUILD_PHONE="no"
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
@ -719,7 +627,6 @@ AM_CONDITIONAL(BUILD_DHT_BOOTSTRAP_DAEMON, test "x$BUILD_DHT_BOOTSTRAP_DAEMON" =
|
|||
AM_CONDITIONAL(BUILD_TESTS, test "x$BUILD_TESTS" = "xyes")
|
||||
AM_CONDITIONAL(BUILD_NTOX, test "x$BUILD_NTOX" = "xyes")
|
||||
AM_CONDITIONAL(BUILD_AV, test "x$BUILD_AV" = "xyes")
|
||||
AM_CONDITIONAL(BUILD_PHONE, test "x$BUILD_PHONE" = "xyes")
|
||||
AM_CONDITIONAL(BUILD_TESTING, test "x$BUILD_TESTING" = "xyes")
|
||||
AM_CONDITIONAL(WIN32, test "x$WIN32" = "xyes")
|
||||
|
||||
|
|
|
@ -32,43 +32,4 @@ libtoxav_la_LIBADD = libtoxcore.la \
|
|||
$(AV_LIBS)
|
||||
|
||||
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if BUILD_PHONE
|
||||
|
||||
|
||||
noinst_PROGRAMS += phone
|
||||
|
||||
phone_SOURCES = ../toxav/phone.c
|
||||
|
||||
phone_CFLAGS = -I../toxcore \
|
||||
-I../toxav \
|
||||
$(AVFORMAT_CFLAGS) \
|
||||
$(AVCODEC_CFLAGS) \
|
||||
$(AVUTIL_CFLAGS) \
|
||||
$(AVDEVICE_CFLAGS) \
|
||||
$(SWSCALE_CFLAGS) \
|
||||
$(SDL_CFLAGS) \
|
||||
$(OPENAL_CFLAGS)
|
||||
|
||||
phone_LDADD = libtoxav.la \
|
||||
libtoxcore.la \
|
||||
$(AVFORMAT_LIBS) \
|
||||
$(AVCODEC_LIBS) \
|
||||
$(AVUTIL_LIBS) \
|
||||
$(AVDEVICE_LIBS) \
|
||||
$(SWSCALE_LIBS) \
|
||||
$(SDL_LIBS) \
|
||||
$(OPENAL_LIBS) \
|
||||
$(OPUS_LIBS) \
|
||||
$(VPX_LIBS)\
|
||||
$(PTHREAD_LIBS)\
|
||||
$(NACL_LIBS)
|
||||
|
||||
|
||||
endif
|
||||
endif
|
|
@ -26,6 +26,8 @@
|
|||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "../toxcore/logger.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
@ -34,17 +36,6 @@
|
|||
#include "rtp.h"
|
||||
#include "media.h"
|
||||
|
||||
struct jitter_buffer {
|
||||
RTPMessage **queue;
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
uint16_t front;
|
||||
uint16_t rear;
|
||||
uint8_t queue_ready;
|
||||
uint16_t current_id;
|
||||
uint32_t current_ts;
|
||||
uint8_t id_set;
|
||||
};
|
||||
|
||||
int empty_queue(struct jitter_buffer *q)
|
||||
{
|
||||
|
@ -79,14 +70,7 @@ struct jitter_buffer *create_queue(int capacity)
|
|||
return q;
|
||||
}
|
||||
|
||||
/* returns 1 if 'a' has a higher sequence number than 'b' */
|
||||
uint8_t sequence_number_older(uint16_t sn_a, uint16_t sn_b, uint32_t ts_a, uint32_t ts_b)
|
||||
{
|
||||
/* TODO: There is already this kind of function in toxrtp.c.
|
||||
* Maybe merge?
|
||||
*/
|
||||
return (sn_a > sn_b || ts_a > ts_b);
|
||||
}
|
||||
#define sequnum_older(sn_a, sn_b, ts_a, ts_b) (sn_a > sn_b || ts_a > ts_b)
|
||||
|
||||
/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
|
||||
RTPMessage *dequeue(struct jitter_buffer *q, int *success)
|
||||
|
@ -112,14 +96,13 @@ RTPMessage *dequeue(struct jitter_buffer *q, int *success)
|
|||
q->current_id = next_id;
|
||||
q->current_ts = next_ts;
|
||||
} else {
|
||||
if (sequence_number_older(next_id, q->current_id, next_ts, q->current_ts)) {
|
||||
/*printf("nextid: %d current: %d\n", next_id, q->current_id);*/
|
||||
if (sequnum_older(next_id, q->current_id, next_ts, q->current_ts)) {
|
||||
LOGGER_DEBUG("nextid: %d current: %d\n", next_id, q->current_id);
|
||||
q->current_id = (q->current_id + 1) % MAX_SEQU_NUM;
|
||||
*success = 2; /* tell the decoder the packet is lost */
|
||||
return NULL;
|
||||
} else {
|
||||
/* packet too old */
|
||||
/*printf("packet too old\n");*/
|
||||
LOGGER_DEBUG("Packet too old");
|
||||
*success = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -139,12 +122,11 @@ RTPMessage *dequeue(struct jitter_buffer *q, int *success)
|
|||
}
|
||||
|
||||
|
||||
int queue(struct jitter_buffer *q, RTPMessage *pk)
|
||||
void queue(struct jitter_buffer* q, RTPMessage* pk)
|
||||
{
|
||||
if (q->size == q->capacity) { /* Full, empty queue */
|
||||
LOGGER_DEBUG("Queue full, emptying...");
|
||||
empty_queue(q);
|
||||
/*rtp_free_msg(NULL, pk);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (q->size > 8)
|
||||
|
@ -169,13 +151,13 @@ int queue(struct jitter_buffer *q, RTPMessage *pk)
|
|||
if (b < 0)
|
||||
b += q->capacity;
|
||||
|
||||
if (sequence_number_older(q->queue[b]->header->sequnum, q->queue[a]->header->sequnum,
|
||||
q->queue[b]->header->timestamp, q->queue[a]->header->timestamp)) {
|
||||
if (sequnum_older(q->queue[b]->header->sequnum, q->queue[a]->header->sequnum,
|
||||
q->queue[b]->header->timestamp, q->queue[a]->header->timestamp)) {
|
||||
RTPMessage *temp;
|
||||
temp = q->queue[a];
|
||||
q->queue[a] = q->queue[b];
|
||||
q->queue[b] = temp;
|
||||
/*printf("had to swap\n");*/
|
||||
LOGGER_DEBUG("Had to swap");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -185,19 +167,14 @@ int queue(struct jitter_buffer *q, RTPMessage *pk)
|
|||
if (a < 0)
|
||||
a += q->capacity;
|
||||
}
|
||||
|
||||
if (pk)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int init_video_decoder(CodecState *cs)
|
||||
{
|
||||
if (vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0,
|
||||
VPX_DECODER_ABI_VERSION) != VPX_CODEC_OK) {
|
||||
/*fprintf(stderr, "Init video_decoder failed!\n");*/
|
||||
int rc = vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0, VPX_DECODER_ABI_VERSION);
|
||||
if ( rc != VPX_CODEC_OK) {
|
||||
LOGGER_ERROR("Init video_decoder failed: %s", vpx_codec_err_to_string(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -210,7 +187,7 @@ int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
|
|||
cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc );
|
||||
|
||||
if ( rc != OPUS_OK ) {
|
||||
/*fprintf(stderr, "Error while starting audio decoder!\n");*/
|
||||
LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -221,10 +198,10 @@ int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
|
|||
int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate)
|
||||
{
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
|
||||
int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
|
||||
|
||||
if (res) {
|
||||
/*fprintf(stderr, "Failed to get config: %s\n", vpx_codec_err_to_string(res));*/
|
||||
if (rc) {
|
||||
LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -232,9 +209,10 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
|
|||
cfg.g_w = width;
|
||||
cfg.g_h = height;
|
||||
|
||||
if (vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0,
|
||||
VPX_ENCODER_ABI_VERSION) != VPX_CODEC_OK) {
|
||||
/*fprintf(stderr, "Failed to initialize encoder\n");*/
|
||||
rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);
|
||||
|
||||
if ( rc != VPX_CODEC_OK) {
|
||||
LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -243,13 +221,30 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
|
|||
|
||||
int init_audio_encoder(CodecState *cs, uint32_t audio_channels)
|
||||
{
|
||||
int err = OPUS_OK;
|
||||
cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &err);
|
||||
err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate));
|
||||
err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10));
|
||||
int rc = OPUS_OK;
|
||||
cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &rc);
|
||||
|
||||
if ( rc != OPUS_OK ) {
|
||||
LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate));
|
||||
|
||||
if ( rc != OPUS_OK ) {
|
||||
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10));
|
||||
|
||||
if ( rc != OPUS_OK ) {
|
||||
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return err == OPUS_OK ? 0 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,7 +288,7 @@ void codec_terminate_session ( CodecState *cs )
|
|||
|
||||
|
||||
/* TODO: Terminate video
|
||||
* Do what???
|
||||
* Do what?
|
||||
*/
|
||||
if ( cs->capabilities & v_decoding )
|
||||
vpx_codec_destroy(&cs->v_decoder);
|
||||
|
|
|
@ -68,9 +68,22 @@ typedef struct _CodecState {
|
|||
|
||||
} CodecState;
|
||||
|
||||
|
||||
struct jitter_buffer {
|
||||
RTPMessage **queue;
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
uint16_t front;
|
||||
uint16_t rear;
|
||||
uint8_t queue_ready;
|
||||
uint16_t current_id;
|
||||
uint32_t current_ts;
|
||||
uint8_t id_set;
|
||||
};
|
||||
|
||||
struct jitter_buffer *create_queue(int capacity);
|
||||
|
||||
int queue(struct jitter_buffer *q, RTPMessage *pk);
|
||||
void queue(struct jitter_buffer *q, RTPMessage *pk);
|
||||
RTPMessage *dequeue(struct jitter_buffer *q, int *success);
|
||||
|
||||
|
||||
|
|
34
toxav/msi.c
34
toxav/msi.c
|
@ -932,6 +932,7 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
|
|||
|
||||
if ( _call_idx == session->max_calls ) {
|
||||
LOGGER_WARNING("Reached maximum amount of calls!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1017,7 +1018,7 @@ int terminate_call ( MSISession *session, MSICall *call )
|
|||
/********** Request handlers **********/
|
||||
int handle_recv_invite ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'invite' on call: %s", call? (char*)call->id : "making new");
|
||||
LOGGER_DEBUG("Session: %p Handling 'invite' on call: %s", session, call? (char*)call->id : "making new");
|
||||
|
||||
if ( call ) {
|
||||
if ( call->peers[0] == msg->friend_id ) {
|
||||
|
@ -1071,7 +1072,7 @@ int handle_recv_invite ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_start ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'start' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'start' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return -1;
|
||||
|
@ -1095,7 +1096,7 @@ int handle_recv_start ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_reject ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'reject' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'reject' on call: %s", session, call->id);
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1118,7 +1119,7 @@ int handle_recv_reject ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_cancel ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'cancel' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1137,7 +1138,7 @@ int handle_recv_cancel ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_end ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'end' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'end' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1156,7 +1157,7 @@ int handle_recv_end ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
/********** Response handlers **********/
|
||||
int handle_recv_ringing ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'ringing' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'ringing' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1169,7 +1170,7 @@ int handle_recv_ringing ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_starting ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'starting' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'starting' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1210,7 +1211,7 @@ int handle_recv_starting ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
}
|
||||
int handle_recv_ending ( MSISession *session, MSICall* call, MSIMessage *msg )
|
||||
{
|
||||
LOGGER_DEBUG("Handling 'ending' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'ending' on call: %s", session, call->id );
|
||||
|
||||
if ( has_call_error ( session, call, msg ) == 0 )
|
||||
return 0;
|
||||
|
@ -1232,7 +1233,7 @@ int handle_recv_error ( MSISession *session, MSICall* call, MSIMessage *msg )
|
|||
return -1;
|
||||
}
|
||||
|
||||
LOGGER_DEBUG("Handling 'error' on call: %s", call->id );
|
||||
LOGGER_DEBUG("Session: %p Handling 'error' on call: %s", session, call->id );
|
||||
|
||||
/* Handle error accordingly */
|
||||
if ( msg->reason.header_value ) {
|
||||
|
@ -1490,7 +1491,8 @@ int msi_terminate_session ( MSISession *session )
|
|||
}
|
||||
|
||||
m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL);
|
||||
|
||||
|
||||
LOGGER_DEBUG("Terminated session: %p", session);
|
||||
free ( session );
|
||||
return _status;
|
||||
}
|
||||
|
@ -1507,7 +1509,7 @@ int msi_terminate_session ( MSISession *session )
|
|||
*/
|
||||
int msi_invite ( MSISession* session, uint32_t* call_index, MSICallType call_type, uint32_t rngsec, uint32_t friend_id )
|
||||
{
|
||||
LOGGER_DEBUG("Inviting friend: %u", friend_id);
|
||||
LOGGER_DEBUG("Session: %p Inviting friend: %u", session, friend_id);
|
||||
|
||||
MSIMessage *_msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) );
|
||||
|
||||
|
@ -1553,7 +1555,7 @@ int msi_invite ( MSISession* session, uint32_t* call_index, MSICallType call_typ
|
|||
*/
|
||||
int msi_hangup ( MSISession* session, uint32_t call_index )
|
||||
{
|
||||
LOGGER_DEBUG("Hanging up call: %u", call_index);
|
||||
LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index);
|
||||
|
||||
if ( call_index >= session->max_calls || !session->calls[call_index] ) {
|
||||
LOGGER_ERROR("Invalid call index!");
|
||||
|
@ -1592,7 +1594,7 @@ int msi_hangup ( MSISession* session, uint32_t call_index )
|
|||
*/
|
||||
int msi_answer ( MSISession* session, uint32_t call_index, MSICallType call_type )
|
||||
{
|
||||
LOGGER_DEBUG("Answering call: %u", call_index);
|
||||
LOGGER_DEBUG("Session: %p Answering call: %u", session, call_index);
|
||||
|
||||
if ( call_index >= session->max_calls || !session->calls[call_index] ){
|
||||
LOGGER_ERROR("Invalid call index!");
|
||||
|
@ -1641,7 +1643,7 @@ int msi_answer ( MSISession* session, uint32_t call_index, MSICallType call_type
|
|||
*/
|
||||
int msi_cancel ( MSISession *session, uint32_t call_index, uint32_t peer, const char *reason )
|
||||
{
|
||||
LOGGER_DEBUG("Canceling call: %u; reason:", call_index, reason? reason : "Unknown");
|
||||
LOGGER_DEBUG("Session: %p Canceling call: %u; reason:", session, call_index, reason? reason : "Unknown");
|
||||
|
||||
if ( call_index >= session->max_calls || !session->calls[call_index] ){
|
||||
LOGGER_ERROR("Invalid call index!");
|
||||
|
@ -1670,7 +1672,7 @@ int msi_cancel ( MSISession *session, uint32_t call_index, uint32_t peer, const
|
|||
*/
|
||||
int msi_reject ( MSISession *session, uint32_t call_index, const uint8_t *reason )
|
||||
{
|
||||
LOGGER_DEBUG("Rejecting call: %u; reason:", call_index, reason? (char*)reason : "Unknown");
|
||||
LOGGER_DEBUG("Session: %p Rejecting call: %u; reason:", session, call_index, reason? (char*)reason : "Unknown");
|
||||
|
||||
if ( call_index >= session->max_calls || !session->calls[call_index] ){
|
||||
LOGGER_ERROR("Invalid call index!");
|
||||
|
@ -1699,7 +1701,7 @@ int msi_reject ( MSISession *session, uint32_t call_index, const uint8_t *reason
|
|||
*/
|
||||
int msi_stopcall ( MSISession *session, uint32_t call_index )
|
||||
{
|
||||
LOGGER_DEBUG("Stopping call index: %u", call_index);
|
||||
LOGGER_DEBUG("Session: %p Stopping call index: %u", session, call_index);
|
||||
|
||||
if ( call_index >= session->max_calls || !session->calls[call_index] )
|
||||
return -1;
|
||||
|
|
1460
toxav/phone.c
1460
toxav/phone.c
File diff suppressed because it is too large
Load Diff
116
toxav/rtp.c
116
toxav/rtp.c
|
@ -25,6 +25,8 @@
|
|||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "../toxcore/logger.h"
|
||||
|
||||
#include "rtp.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -227,6 +229,7 @@ static const uint32_t payload_table[] = {
|
|||
RTPHeader *extract_header ( const uint8_t *payload, int length )
|
||||
{
|
||||
if ( !payload || !length ) {
|
||||
LOGGER_WARNING("No payload to extract!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -245,6 +248,7 @@ RTPHeader *extract_header ( const uint8_t *payload, int length )
|
|||
|
||||
if ( GET_FLAG_VERSION(_retu) != RTP_VERSION ) {
|
||||
/* Deallocate */
|
||||
LOGGER_WARNING("Invalid version!");
|
||||
free(_retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -258,6 +262,7 @@ RTPHeader *extract_header ( const uint8_t *payload, int length )
|
|||
|
||||
if ( length < _length ) {
|
||||
/* Deallocate */
|
||||
LOGGER_WARNING("Length invalid!");
|
||||
free(_retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -304,6 +309,7 @@ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
|
|||
|
||||
|
||||
if ( length < ( _ext_length * sizeof(uint32_t) ) ) {
|
||||
LOGGER_WARNING("Length invalid!");
|
||||
free(_retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -443,6 +449,7 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
|
|||
_retu->header = extract_header ( data, length ); /* It allocates memory and all */
|
||||
|
||||
if ( !_retu->header ) {
|
||||
LOGGER_WARNING("Header failed to extract!");
|
||||
free(_retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -461,6 +468,7 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
|
|||
_retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
|
||||
_from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
|
||||
} else { /* Error */
|
||||
LOGGER_WARNING("Ext Header failed to extract!");
|
||||
rtp_free_msg(NULL, _retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -471,6 +479,7 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
|
|||
if ( length - _from_pos <= MAX_RTP_SIZE )
|
||||
memcpy ( _retu->data, data + _from_pos, length - _from_pos );
|
||||
else {
|
||||
LOGGER_WARNING("Invalid length!");
|
||||
rtp_free_msg(NULL, _retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -495,9 +504,16 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
{
|
||||
RTPSession *_session = object;
|
||||
RTPMessage *_msg;
|
||||
|
||||
if ( !_session || length < 13 + crypto_secretbox_MACBYTES) /* 12 is the minimum length for rtp + desc. byte */
|
||||
|
||||
if ( !_session || length < 13 + crypto_secretbox_MACBYTES) { /* 12 is the minimum length for rtp + desc. byte */
|
||||
LOGGER_WARNING("No session or invalid length of received buffer!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( _session->queue_limit <= _session->queue_size ) {
|
||||
LOGGER_WARNING("Queue limit reached!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t _plain[MAX_UDP_PACKET_SIZE];
|
||||
|
||||
|
@ -510,8 +526,7 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
increase_nonce ( _calculated, _sequnum );
|
||||
|
||||
/* Decrypt message */
|
||||
int _decrypted_length = decrypt_data_symmetric(
|
||||
(uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
|
||||
int _decrypted_length = decrypt_data_symmetric((uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
|
||||
|
||||
/* This packet is either not encrypted properly or late
|
||||
*/
|
||||
|
@ -524,7 +539,10 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
_decrypted_length = decrypt_data_symmetric(
|
||||
(uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
|
||||
|
||||
if ( _decrypted_length == -1 ) return -1; /* This packet is not encrypted properly */
|
||||
if ( _decrypted_length == -1 ) {
|
||||
LOGGER_WARNING("Packet not ecrypted properly!");
|
||||
return -1; /* This packet is not encrypted properly */
|
||||
}
|
||||
|
||||
/* Otherwise, if decryption is ok with new cycle, set new cycle
|
||||
*/
|
||||
|
@ -533,7 +551,10 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
_decrypted_length = decrypt_data_symmetric(
|
||||
(uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
|
||||
|
||||
if ( _decrypted_length == -1 ) return -1; /* This is just an error */
|
||||
if ( _decrypted_length == -1 ) {
|
||||
LOGGER_WARNING("Error decrypting!");
|
||||
return -1; /* This is just an error */
|
||||
}
|
||||
|
||||
/* A new cycle setting. */
|
||||
memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_secretbox_NONCEBYTES);
|
||||
|
@ -543,7 +564,10 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
|
||||
_msg = msg_parse ( _sequnum, _plain, _decrypted_length );
|
||||
|
||||
if ( !_msg ) return -1;
|
||||
if ( !_msg ) {
|
||||
LOGGER_WARNING("Could not parse message!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hopefully this goes well
|
||||
* NOTE: Is this even used?
|
||||
|
@ -565,6 +589,8 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
_session->last_msg = _session->oldest_msg = _msg;
|
||||
}
|
||||
|
||||
_session->queue_size++;
|
||||
|
||||
pthread_mutex_unlock(&_session->mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -584,8 +610,10 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
|
|||
*/
|
||||
RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t length )
|
||||
{
|
||||
if ( !session )
|
||||
if ( !session ) {
|
||||
LOGGER_WARNING("No session!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *_from_pos;
|
||||
RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
|
||||
|
@ -665,6 +693,7 @@ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t
|
|||
int rtp_release_session_recv ( RTPSession *session )
|
||||
{
|
||||
if ( !session ) {
|
||||
LOGGER_WARNING("No session!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -678,13 +707,39 @@ int rtp_release_session_recv ( RTPSession *session )
|
|||
}
|
||||
|
||||
session->last_msg = session->oldest_msg = NULL;
|
||||
|
||||
session->queue_size = 0;
|
||||
|
||||
pthread_mutex_unlock(&session->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Call this to change queue limit
|
||||
*
|
||||
* @param session The session
|
||||
* @param limit new limit
|
||||
* @return void
|
||||
*/
|
||||
void rtp_queue_adjust_limit(RTPSession* session, uint64_t limit)
|
||||
{
|
||||
RTPMessage *_tmp, * _it;
|
||||
pthread_mutex_lock(&session->mutex);
|
||||
|
||||
for ( _it = session->oldest_msg; session->queue_size > limit; _it = _tmp ) {
|
||||
_tmp = _it->next;
|
||||
rtp_free_msg( session, _it);
|
||||
session->queue_size --;
|
||||
}
|
||||
|
||||
session->oldest_msg = _it;
|
||||
session->queue_limit = limit;
|
||||
|
||||
pthread_mutex_unlock(&session->mutex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets oldest message in the list.
|
||||
*
|
||||
|
@ -694,15 +749,21 @@ int rtp_release_session_recv ( RTPSession *session )
|
|||
*/
|
||||
RTPMessage *rtp_recv_msg ( RTPSession *session )
|
||||
{
|
||||
if ( !session )
|
||||
if ( !session ) {
|
||||
LOGGER_WARNING("No session!");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if ( session->queue_size == 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&session->mutex);
|
||||
|
||||
RTPMessage *_retu = session->oldest_msg;
|
||||
|
||||
pthread_mutex_lock(&session->mutex);
|
||||
|
||||
if ( _retu )
|
||||
session->oldest_msg = _retu->next;
|
||||
/*if (_retu)*/
|
||||
session->oldest_msg = _retu->next;
|
||||
|
||||
if ( !session->oldest_msg )
|
||||
session->last_msg = NULL;
|
||||
|
@ -728,7 +789,10 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
|
|||
{
|
||||
RTPMessage *msg = rtp_new_message (session, data, length);
|
||||
|
||||
if ( !msg ) return -1;
|
||||
if ( !msg ) {
|
||||
LOGGER_WARNING("No session!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t _send_data [ MAX_UDP_PACKET_SIZE ];
|
||||
|
||||
|
@ -749,9 +813,8 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
|
|||
_send_data[2] = msg->data[1];
|
||||
|
||||
|
||||
/*if ( full_length != sendpacket ( messenger->net, *((IP_Port*) &session->dest), _send_data, full_length) ) {*/
|
||||
if ( full_length != send_custom_user_packet(messenger, session->dest, _send_data, full_length) ) {
|
||||
/*fprintf(stderr, "Rtp error: %s\n", strerror(errno));*/
|
||||
LOGGER_WARNING("Failed to send full packet! std error: %s", strerror(errno));
|
||||
rtp_free_msg ( session, msg );
|
||||
return -1;
|
||||
}
|
||||
|
@ -822,9 +885,10 @@ RTPSession *rtp_init_session ( int payload_type,
|
|||
RTPSession *_retu = calloc(1, sizeof(RTPSession));
|
||||
assert(_retu);
|
||||
|
||||
/*networking_registerhandler(messenger->net, payload_type, rtp_handle_packet, _retu);*/
|
||||
if ( -1 == custom_user_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) ) {
|
||||
/*fprintf(stderr, "Error setting custom register handler for rtp session\n");*/
|
||||
if ( -1 == custom_user_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) ||
|
||||
!encrypt_key, !decrypt_key, !encrypt_nonce, !decrypt_nonce
|
||||
) {
|
||||
LOGGER_ERROR("Error setting custom register handler for rtp session");
|
||||
free(_retu);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -843,9 +907,7 @@ RTPSession *rtp_init_session ( int payload_type,
|
|||
_retu->rsequnum = _retu->sequnum = 1;
|
||||
|
||||
_retu->ext_header = NULL; /* When needed allocate */
|
||||
_retu->framerate = -1;
|
||||
_retu->resolution = -1;
|
||||
|
||||
|
||||
_retu->encrypt_key = encrypt_key;
|
||||
_retu->decrypt_key = decrypt_key;
|
||||
|
||||
|
@ -870,6 +932,8 @@ RTPSession *rtp_init_session ( int payload_type,
|
|||
_retu->prefix = payload_type;
|
||||
|
||||
_retu->oldest_msg = _retu->last_msg = NULL;
|
||||
_retu->queue_limit = 100; /* Default */
|
||||
_retu->queue_size = 0;
|
||||
|
||||
pthread_mutex_init(&_retu->mutex, NULL);
|
||||
/*
|
||||
|
@ -890,8 +954,10 @@ RTPSession *rtp_init_session ( int payload_type,
|
|||
*/
|
||||
int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
|
||||
{
|
||||
if ( !session )
|
||||
if ( !session ) {
|
||||
LOGGER_WARNING("No session!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
custom_user_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
|
||||
|
||||
|
|
20
toxav/rtp.h
20
toxav/rtp.h
|
@ -108,11 +108,7 @@ typedef struct _RTPSession {
|
|||
*/
|
||||
RTPExtHeader *ext_header;
|
||||
|
||||
/* External header identifiers */
|
||||
int resolution;
|
||||
int framerate;
|
||||
|
||||
|
||||
|
||||
/* Since these are only references of the
|
||||
* call structure don't allocate or free
|
||||
*/
|
||||
|
@ -126,6 +122,9 @@ typedef struct _RTPSession {
|
|||
|
||||
RTPMessage *oldest_msg;
|
||||
RTPMessage *last_msg; /* tail */
|
||||
|
||||
uint64_t queue_limit;/* Default 100; modify per thy liking */
|
||||
uint64_t queue_size; /* currently holding << messages */
|
||||
|
||||
/* Msg prefix for core to know when recving */
|
||||
uint8_t prefix;
|
||||
|
@ -147,6 +146,15 @@ typedef struct _RTPSession {
|
|||
int rtp_release_session_recv ( RTPSession *session );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Call this to change queue limit
|
||||
*
|
||||
* @param session The session
|
||||
* @param limit new limit
|
||||
* @return void
|
||||
*/
|
||||
void rtp_queue_adjust_limit ( RTPSession *session, uint64_t limit );
|
||||
|
||||
/**
|
||||
* @brief Get's oldest message in the list.
|
||||
*
|
||||
|
@ -195,7 +203,7 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg );
|
|||
* @retval NULL Error occurred.
|
||||
*/
|
||||
RTPSession *rtp_init_session ( int payload_type,
|
||||
Messenger *messenger,
|
||||
Messenger *messenger,
|
||||
int friend_num,
|
||||
const uint8_t *encrypt_key,
|
||||
const uint8_t *decrypt_key,
|
||||
|
|
127
toxav/toxav.c
127
toxav/toxav.c
|
@ -105,7 +105,7 @@ ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings, uint32_t m
|
|||
av->msi_session = msi_init_session(av->messenger, max_calls);
|
||||
av->msi_session->agent_handler = av;
|
||||
|
||||
av->rtp_sessions = calloc(sizeof(RTPSession), max_calls);
|
||||
av->rtp_sessions = calloc(sizeof(CallRTPSessions), max_calls);
|
||||
av->max_calls = max_calls;
|
||||
|
||||
av->j_buf = create_queue(codec_settings->jbuf_capacity);
|
||||
|
@ -288,8 +288,9 @@ int toxav_stop_call ( ToxAv* av, uint32_t call_index )
|
|||
*/
|
||||
int toxav_prepare_transmission ( ToxAv* av, uint32_t call_index, int support_video )
|
||||
{
|
||||
if ( !av->msi_session || !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
if ( !av->msi_session || av->msi_session->max_calls <= call_index || !av->msi_session->calls[call_index] ) {
|
||||
/*fprintf(stderr, "Error while starting audio RTP session: invalid call!\n");*/
|
||||
return ErrorInternal;
|
||||
}
|
||||
|
||||
av->rtp_sessions[call_index].crtps[audio_index] =
|
||||
|
@ -305,10 +306,11 @@ int toxav_prepare_transmission ( ToxAv* av, uint32_t call_index, int support_vid
|
|||
|
||||
|
||||
if ( !av->rtp_sessions[call_index].crtps[audio_index] ) {
|
||||
fprintf(stderr, "Error while starting audio RTP session!\n");
|
||||
/*fprintf(stderr, "Error while starting audio RTP session!\n");*/
|
||||
return ErrorStartingAudioRtp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( support_video ) {
|
||||
av->rtp_sessions[call_index].crtps[video_index] =
|
||||
rtp_init_session (
|
||||
|
@ -323,10 +325,12 @@ int toxav_prepare_transmission ( ToxAv* av, uint32_t call_index, int support_vid
|
|||
|
||||
|
||||
if ( !av->rtp_sessions[call_index].crtps[video_index] ) {
|
||||
fprintf(stderr, "Error while starting video RTP session!\n");
|
||||
/*fprintf(stderr, "Error while starting video RTP session!\n");*/
|
||||
return ErrorStartingVideoRtp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
|
@ -341,12 +345,12 @@ int toxav_prepare_transmission ( ToxAv* av, uint32_t call_index, int support_vid
|
|||
int toxav_kill_transmission ( ToxAv *av, uint32_t call_index )
|
||||
{
|
||||
if ( av->rtp_sessions[call_index].crtps[audio_index] && -1 == rtp_terminate_session(av->rtp_sessions[call_index].crtps[audio_index], av->messenger) ) {
|
||||
fprintf(stderr, "Error while terminating audio RTP session!\n");
|
||||
/*fprintf(stderr, "Error while terminating audio RTP session!\n");*/
|
||||
return ErrorTerminatingAudioRtp;
|
||||
}
|
||||
|
||||
if ( av->rtp_sessions[call_index].crtps[video_index] && -1 == rtp_terminate_session(av->rtp_sessions[call_index].crtps[video_index], av->messenger) ) {
|
||||
fprintf(stderr, "Error while terminating video RTP session!\n");
|
||||
/*fprintf(stderr, "Error while terminating video RTP session!\n");*/
|
||||
return ErrorTerminatingVideoRtp;
|
||||
}
|
||||
|
||||
|
@ -441,13 +445,15 @@ inline__ int toxav_recv_video ( ToxAv *av, uint32_t call_index, vpx_image_t **ou
|
|||
|
||||
uint8_t packet [RTP_PAYLOAD_SIZE];
|
||||
int recved_size = 0;
|
||||
int error;
|
||||
int rc;
|
||||
|
||||
do {
|
||||
recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet);
|
||||
|
||||
if (recved_size > 0 && ( error = vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK)
|
||||
fprintf(stderr, "Error decoding: %s\n", vpx_codec_err_to_string(error));
|
||||
if (recved_size > 0 && ( rc = vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK) {
|
||||
/*fprintf(stderr, "Error decoding video: %s\n", vpx_codec_err_to_string(rc));*/
|
||||
return ErrorInternal;
|
||||
}
|
||||
|
||||
} while (recved_size > 0);
|
||||
|
||||
|
@ -472,8 +478,9 @@ inline__ int toxav_recv_video ( ToxAv *av, uint32_t call_index, vpx_image_t **ou
|
|||
*/
|
||||
inline__ int toxav_send_video ( ToxAv *av, uint32_t call_index, vpx_image_t *input)
|
||||
{
|
||||
if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) {
|
||||
fprintf(stderr, "Could not encode video frame\n");
|
||||
int rc = vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
|
||||
if ( rc != VPX_CODEC_OK) {
|
||||
/*fprintf(stderr, "Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));*/
|
||||
return ErrorInternal;
|
||||
}
|
||||
|
||||
|
@ -491,11 +498,40 @@ inline__ int toxav_send_video ( ToxAv *av, uint32_t call_index, vpx_image_t *inp
|
|||
}
|
||||
|
||||
if (sent > 0)
|
||||
return 0;
|
||||
return ErrorNone;
|
||||
|
||||
return ErrorInternal;
|
||||
}
|
||||
|
||||
int toxav_prepare_video_frame(ToxAv* av, uint8_t* dest, int dest_max, vpx_image_t* input)
|
||||
{
|
||||
int rc = vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
|
||||
if ( rc != VPX_CODEC_OK) {
|
||||
/*fprintf(stderr, "Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));*/
|
||||
return ErrorInternal;
|
||||
}
|
||||
++av->cs->frame_counter;
|
||||
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
int counted = 0, copied = 0;
|
||||
|
||||
while ( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) {
|
||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||
|
||||
if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge;
|
||||
|
||||
mempcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
|
||||
|
||||
if (toxav_send_rtp_payload(av, call_index, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1)
|
||||
++counted;
|
||||
}
|
||||
}
|
||||
|
||||
if (counted > 0)
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive decoded audio frame.
|
||||
*
|
||||
|
@ -517,16 +553,22 @@ inline__ int toxav_recv_audio ( ToxAv *av, uint32_t call_index, int frame_size,
|
|||
int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet);
|
||||
|
||||
if ( recved_size == ErrorAudioPacketLost ) {
|
||||
return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
|
||||
int dec_size = opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
|
||||
|
||||
if ( dec_size != OPUS_OK ) return ErrorInternal;
|
||||
|
||||
} else if ( recved_size ) {
|
||||
return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
|
||||
int dec_size = opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
|
||||
|
||||
if ( dec_size != OPUS_OK ) return ErrorInternal;
|
||||
|
||||
} else {
|
||||
return 0; /* Nothing received */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode and send audio frame.
|
||||
* @brief Send audio frame.
|
||||
*
|
||||
* @param av Handler.
|
||||
* @param frame The frame (raw 16 bit signed pcm with AUDIO_CHANNELS channels audio.)
|
||||
|
@ -538,13 +580,29 @@ inline__ int toxav_recv_audio ( ToxAv *av, uint32_t call_index, int frame_size,
|
|||
*/
|
||||
inline__ int toxav_send_audio ( ToxAv *av, uint32_t call_index, const int16_t *frame, int frame_size)
|
||||
{
|
||||
uint8_t temp_data[RTP_PAYLOAD_SIZE];
|
||||
int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data));
|
||||
return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
|
||||
}
|
||||
|
||||
if (ret <= 0)
|
||||
/**
|
||||
* @brief Encode audio frame
|
||||
*
|
||||
* @param av Handler
|
||||
* @param dest dest
|
||||
* @param dest_max Max dest size
|
||||
* @param frame The frame
|
||||
* @param frame_size The frame size
|
||||
* @return int
|
||||
* @retval ToxAvError On error.
|
||||
* @retval >0 On success
|
||||
*/
|
||||
int toxav_prepare_audio_frame ( ToxAv* av, int16_t* dest, int dest_max, const int16_t* frame, int frame_size)
|
||||
{
|
||||
int32_t rc = opus_encode(av->cs->audio_encoder, frame, frame_size, dest, dest_max);
|
||||
|
||||
if (rc <= 0)
|
||||
return ErrorInternal;
|
||||
|
||||
return toxav_send_rtp_payload(av, call_index, TypeAudio, temp_data, ret);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -598,12 +656,27 @@ inline__ int toxav_capability_supported ( ToxAv* av, ToxAvCapabilities capabilit
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Get messenger handle
|
||||
* @brief Set queue limit
|
||||
*
|
||||
* @param av Handler.
|
||||
* @return Tox*
|
||||
* @param av Handler
|
||||
* @param call_index index
|
||||
* @param limit the limit
|
||||
* @return void
|
||||
*/
|
||||
inline__ Tox* toxav_get_tox ( ToxAv* av )
|
||||
void toxav_set_audio_queue_limit(ToxAv* av, uint32_t call_index, uint64_t limit)
|
||||
{
|
||||
return (Tox*)av->messenger;
|
||||
rtp_queue_adjust_limit(av->rtp_sessions[call_index].crtps[audio_index], limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set queue limit
|
||||
*
|
||||
* @param av Handler
|
||||
* @param call_index index
|
||||
* @param limit the limit
|
||||
* @return void
|
||||
*/
|
||||
void toxav_set_video_queue_limit(ToxAv* av, uint32_t call_index, uint64_t limit)
|
||||
{
|
||||
rtp_queue_adjust_limit(av->rtp_sessions[call_index].crtps[video_index], limit);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,8 @@ typedef enum {
|
|||
ErrorStartingVideoRtp = -8 , /* Error in toxav_prepare_transmission() */
|
||||
ErrorTerminatingAudioRtp = -9, /* Returned in toxav_kill_transmission() */
|
||||
ErrorTerminatingVideoRtp = -10, /* Returned in toxav_kill_transmission() */
|
||||
|
||||
ErrorPacketTooLarge = -11, /* Buffer exceeds size while encoding */
|
||||
|
||||
} ToxAvError;
|
||||
|
||||
|
||||
|
@ -276,7 +277,7 @@ int toxav_recv_audio( ToxAv* av, uint32_t call_index, int frame_size, int16_t* d
|
|||
int toxav_send_video ( ToxAv* av, uint32_t call_index, vpx_image_t* input);
|
||||
|
||||
/**
|
||||
* @brief Encode and send audio frame.
|
||||
* @brief Send audio frame.
|
||||
*
|
||||
* @param av Handler.
|
||||
* @param frame The frame (raw 16 bit signed pcm with AUDIO_CHANNELS channels audio.)
|
||||
|
@ -288,6 +289,22 @@ int toxav_send_video ( ToxAv* av, uint32_t call_index, vpx_image_t* input);
|
|||
*/
|
||||
int toxav_send_audio ( ToxAv* av, uint32_t call_index, const int16_t* frame, int frame_size);
|
||||
|
||||
int toxav_prepare_video_frame ( ToxAv* av, uint8_t* dest, int dest_max, vpx_image_t* input );
|
||||
|
||||
/**
|
||||
* @brief Encode audio frame
|
||||
*
|
||||
* @param av Handler
|
||||
* @param dest dest
|
||||
* @param dest_max Max dest size
|
||||
* @param frame The frame
|
||||
* @param frame_size The frame size
|
||||
* @return int
|
||||
* @retval ToxAvError On error.
|
||||
* @retval >0 On success
|
||||
*/
|
||||
int toxav_prepare_audio_frame ( ToxAv* av, int16_t* dest, int dest_max, const int16_t* frame, int frame_size);
|
||||
|
||||
/**
|
||||
* @brief Get peer transmission type. It can either be audio or video.
|
||||
*
|
||||
|
@ -320,11 +337,23 @@ int toxav_get_peer_id ( ToxAv* av, uint32_t call_index, int peer );
|
|||
int toxav_capability_supported ( ToxAv* av, ToxAvCapabilities capability );
|
||||
|
||||
/**
|
||||
* @brief Get messenger handle
|
||||
* @brief Set queue limit
|
||||
*
|
||||
* @param av Handler.
|
||||
* @return Tox*
|
||||
* @param av Handler
|
||||
* @param call_index index
|
||||
* @param limit the limit
|
||||
* @return void
|
||||
*/
|
||||
Tox* toxav_get_tox ( ToxAv* av );
|
||||
void toxav_set_audio_queue_limit ( ToxAv* av, uint32_t call_index, uint64_t limit );
|
||||
|
||||
/**
|
||||
* @brief Set queue limit
|
||||
*
|
||||
* @param av Handler
|
||||
* @param call_index index
|
||||
* @param limit the limit
|
||||
* @return void
|
||||
*/
|
||||
void toxav_set_video_queue_limit ( ToxAv* av, uint32_t call_index, uint64_t limit );
|
||||
|
||||
#endif /* __TOXAV */
|
Loading…
Reference in New Issue
Block a user