Skip to content

Commit

Permalink
make ToxAV independent of toxcore internals.
Browse files Browse the repository at this point in the history
  • Loading branch information
zoff99 authored and iphydf committed Aug 29, 2023
1 parent 620e07e commit dfd6c81
Show file tree
Hide file tree
Showing 25 changed files with 953 additions and 835 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ if(BUILD_TOXAV)
toxav/rtp.h
toxav/toxav.c
toxav/toxav.h
toxav/toxav_hacks.h
toxav/toxav_old.c
toxav/video.c
toxav/video.h)
Expand Down
5 changes: 0 additions & 5 deletions toxav/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ cc_library(
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util",
],
)
Expand All @@ -69,7 +68,6 @@ cc_library(
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util",
],
)
Expand All @@ -96,7 +94,6 @@ cc_library(
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:util",
"@opus",
],
)
Expand All @@ -116,7 +113,6 @@ cc_library(
":public_api",
":ring_buffer",
":rtp",
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
Expand All @@ -133,7 +129,6 @@ cc_library(
deps = [
"//c-toxcore/toxcore",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:group",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
Expand Down
1 change: 1 addition & 0 deletions toxav/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \
../toxav/ring_buffer.h \
../toxav/ring_buffer.c \
../toxav/toxav.h \
../toxav/toxav_hacks.h \
../toxav/toxav.c \
../toxav/toxav_old.c

Expand Down
19 changes: 14 additions & 5 deletions toxav/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "../toxcore/ccompat.h"
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/network.h"

static struct JitterBuffer *jbuf_new(uint32_t capacity);
static void jbuf_clear(struct JitterBuffer *q);
Expand All @@ -27,7 +28,7 @@ static bool reconfigure_audio_decoder(ACSession *ac, uint32_t sampling_rate, uin



ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
ACSession *ac_new(Mono_Time *mono_time, const Logger *log, Tox *tox, ToxAV *av, uint32_t friend_number,
toxav_audio_receive_frame_cb *cb, void *cb_data)
{
ACSession *ac = (ACSession *)calloc(1, sizeof(ACSession));
Expand Down Expand Up @@ -127,7 +128,7 @@ void ac_iterate(ACSession *ac)
int16_t *temp_audio_buffer = (int16_t *)malloc(AUDIO_MAX_BUFFER_SIZE_PCM16 * AUDIO_MAX_CHANNEL_COUNT * sizeof(int16_t));

if (temp_audio_buffer == nullptr) {
LOGGER_ERROR(ac->log, "Failed to allocate memory for audio buffer");
LOGGER_DEBUG(ac->log, "Failed to allocate memory for audio buffer");
return;
}

Expand All @@ -152,9 +153,9 @@ void ac_iterate(ACSession *ac)

ac->lp_channel_count = opus_packet_get_nb_channels(msg->data + 4);

/* NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
* it didn't work quite well.
*/
/** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
* it didn't work quite well.
*/
if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) {
LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!");
free(msg);
Expand Down Expand Up @@ -277,6 +278,7 @@ static struct JitterBuffer *jbuf_new(uint32_t capacity)
q->capacity = capacity;
return q;
}

static void jbuf_clear(struct JitterBuffer *q)
{
while (q->bottom != q->top) {
Expand All @@ -285,6 +287,7 @@ static void jbuf_clear(struct JitterBuffer *q)
++q->bottom;
}
}

static void jbuf_free(struct JitterBuffer *q)
{
if (q == nullptr) {
Expand All @@ -295,6 +298,11 @@ static void jbuf_free(struct JitterBuffer *q)
free(q->queue);
free(q);
}

/*
* if -1 is returned the RTPMessage m needs to be free'd by the caller
* if 0 is returned the RTPMessage m is stored in the ringbuffer and must NOT be freed by the caller
*/
static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessage *m)
{
const uint16_t sequnum = m->header.sequnum;
Expand Down Expand Up @@ -323,6 +331,7 @@ static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessa

return 0;
}

static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success)
{
if (q->top == q->bottom) {
Expand Down
8 changes: 7 additions & 1 deletion toxav/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
#define AUDIO_MAX_BUFFER_SIZE_PCM16 ((AUDIO_MAX_SAMPLE_RATE * AUDIO_MAX_FRAME_DURATION_MS) / 1000)
#define AUDIO_MAX_BUFFER_SIZE_BYTES (AUDIO_MAX_BUFFER_SIZE_PCM16 * 2)

#ifndef TOX_DEFINED
#define TOX_DEFINED
typedef struct Tox Tox;
#endif /* TOX_DEFINED */

typedef struct ACSession {
Mono_Time *mono_time;
const Logger *log;
Expand Down Expand Up @@ -61,9 +66,10 @@ typedef struct ACSession {
/* Audio frame receive callback */
toxav_audio_receive_frame_cb *acb;
void *acb_user_data;
Tox *tox;
} ACSession;

ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
ACSession *ac_new(Mono_Time *mono_time, const Logger *log, Tox *tox, ToxAV *av, uint32_t friend_number,
toxav_audio_receive_frame_cb *cb, void *cb_data);
void ac_kill(ACSession *ac);
void ac_iterate(ACSession *ac);
Expand Down
101 changes: 64 additions & 37 deletions toxav/bwcontroller.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
#include <string.h>

#include "ring_buffer.h"
#include "toxav_hacks.h"

#include "../toxcore/ccompat.h"
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/network.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h"


#define BWC_PACKET_ID 196
#define BWC_SEND_INTERVAL_MS 950 // 0.95s
#define BWC_AVG_PKT_COUNT 20
Expand All @@ -38,9 +42,8 @@ typedef struct BWCRcvPkt {
struct BWController {
m_cb *mcb;
void *mcb_user_data;

Messenger *m;
Tox *tox;
const Logger *log;
uint32_t friend_number;

BWCCycle cycle;
Expand All @@ -49,18 +52,19 @@ struct BWController {

uint32_t packet_loss_counted_cycles;
Mono_Time *bwc_mono_time;
bool bwc_receive_active; /* if this is set to false then incoming bwc packets will not be processed by bwc_handle_data() */
};

struct BWCMessage {
uint32_t lost;
uint32_t recv;
};

static int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object);
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length);
static void bwc_handle_data(Tox *tox, uint32_t friendnumber, const uint8_t *data, size_t length, void *dummy);
static void send_update(BWController *bwc);

BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,

BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
Mono_Time *bwc_mono_time)
{
BWController *retu = (BWController *)calloc(1, sizeof(BWController));
Expand All @@ -69,16 +73,18 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
return nullptr;
}

LOGGER_DEBUG(m->log, "Creating bandwidth controller");
LOGGER_DEBUG(log, "Creating bandwidth controller");

retu->mcb = mcb;
retu->mcb_user_data = mcb_user_data;
retu->m = m;
retu->friend_number = friendnumber;
retu->bwc_mono_time = bwc_mono_time;
const uint64_t now = current_time_monotonic(bwc_mono_time);
retu->cycle.last_sent_timestamp = now;
retu->cycle.last_refresh_timestamp = now;
retu->tox = tox;
retu->log = log;
retu->bwc_receive_active = true;
retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT);
retu->cycle.lost = 0;
retu->cycle.recv = 0;
Expand All @@ -89,7 +95,6 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]);
}

m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu);
return retu;
}

Expand All @@ -99,7 +104,6 @@ void bwc_kill(BWController *bwc)
return;
}

m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr);
rb_kill(bwc->rcvpkt.rb);
free(bwc);
}
Expand All @@ -111,7 +115,7 @@ void bwc_add_lost(BWController *bwc, uint32_t bytes_lost)
}

if (bytes_lost > 0) {
LOGGER_DEBUG(bwc->m->log, "BWC lost(1): %d", (int)bytes_lost);
LOGGER_DEBUG(bwc->log, "BWC lost(1): %d", (int)bytes_lost);
bwc->cycle.lost += bytes_lost;
send_update(bwc);
}
Expand All @@ -135,7 +139,7 @@ static void send_update(BWController *bwc)
bwc->packet_loss_counted_cycles = 0;

if (bwc->cycle.lost != 0) {
LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
LOGGER_DEBUG(bwc->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
(void *)bwc, bwc->cycle.recv, bwc->cycle.lost,
((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0);
uint8_t bwc_packet[sizeof(struct BWCMessage) + 1];
Expand All @@ -148,13 +152,11 @@ static void send_update(BWController *bwc)
offset += net_pack_u32(bwc_packet + offset, bwc->cycle.recv);
assert(offset == sizeof(bwc_packet));

if (bwc_send_custom_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet)) == -1) {
char *netstrerror = net_new_strerror(net_error());
char *stdstrerror = net_new_strerror(errno);
LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %u)! std error: %s, net error %s",
(unsigned)sizeof(bwc_packet), stdstrerror, netstrerror);
net_kill_strerror(stdstrerror);
net_kill_strerror(netstrerror);
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet), &error);

if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
LOGGER_WARNING(bwc->log, "BWC send failed: %d", error);
}
}

Expand All @@ -166,11 +168,11 @@ static void send_update(BWController *bwc)

static int on_update(BWController *bwc, const struct BWCMessage *msg)
{
LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", (void *)bwc);
LOGGER_DEBUG(bwc->log, "%p Got update from peer", (void *)bwc);

/* Peers sent update too soon */
if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic(bwc->bwc_mono_time)) {
LOGGER_INFO(bwc->m->log, "%p Rejecting extra update", (void *)bwc);
LOGGER_INFO(bwc->log, "%p Rejecting extra update", (void *)bwc);
return -1;
}

Expand All @@ -180,8 +182,8 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)

if (lost != 0 && bwc->mcb != nullptr) {
const uint32_t recv = msg->recv;
LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
((double)lost / (recv + lost)) * 100.0);
LOGGER_DEBUG(bwc->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
((double) lost / (recv + lost)) * 100.0);
bwc->mcb(bwc, bwc->friend_number,
(float)lost / (recv + lost),
bwc->mcb_user_data);
Expand All @@ -190,26 +192,41 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
return 0;
}

/*
* return -1 on failure, 0 on success
*
*/
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length)
static void bwc_handle_data(Tox *tox, uint32_t friendnumber, const uint8_t *data, size_t length, void *dummy)
{
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error);
/* get BWController object from Tox and friend number */
ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);

if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
return 0;
if (toxav == nullptr) {
// LOGGER_ERROR(log, "Could not get ToxAV object from Tox");
return;
}

return -1;
}
const Logger *log = toxav_get_logger(toxav);

static int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object)
{
if (length - 1 != sizeof(struct BWCMessage)) {
return -1;
LOGGER_ERROR(log, "Actual data size and length argument do not match");
return;
}

ToxAVCall *call = call_get(toxav, friendnumber);

if (call == nullptr) {
LOGGER_ERROR(log, "Could not get ToxAVCall object from ToxAV");
return;
}

/* get Call object from Tox and friend number */
BWController *bwc = bwc_controller_get(call);

if (bwc == nullptr) {
LOGGER_WARNING(log, "No session!");
return;
}

if (!bwc->bwc_receive_active) {
LOGGER_WARNING(log, "receiving not allowed!");
return;
}

size_t offset = 1; // Ignore packet id.
Expand All @@ -218,5 +235,15 @@ static int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *d
offset += net_unpack_u32(data + offset, &msg.recv);
assert(offset == length);

return on_update((BWController *)object, &msg);
on_update(bwc, &msg);

Check warning on line 238 in toxav/bwcontroller.c

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

toxav/bwcontroller.c#L238

MISRA 17.7 rule
}

void bwc_allow_receiving(Tox *tox)
{
tox_callback_friend_lossy_packet_per_pktid(tox, bwc_handle_data, BWC_PACKET_ID);
}

void bwc_stop_receiving(Tox *tox)
{
tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, BWC_PACKET_ID);
}
Loading

0 comments on commit dfd6c81

Please sign in to comment.