From 30d697653684599c290fde7b52936998450f68db Mon Sep 17 00:00:00 2001 From: iphydf Date: Sat, 11 Aug 2018 14:11:55 +0000 Subject: [PATCH] Fix ToxAv's use of `struct Tox`. * Fix `toxav_get_tox` to return tox, not messenger. * Fix the casts from Tox* to Messenger* in toxav_old.c. * Pass Tox instead of Messenger to public group AV callbacks. --- toxav/BUILD.bazel | 2 +- toxav/audio.c | 4 +- toxav/audio.h | 3 +- toxav/bwcontroller.c | 50 +++--- toxav/bwcontroller.h | 6 +- toxav/groupav.c | 55 +++--- toxav/groupav.h | 16 +- toxav/msi.c | 223 ++++++++++++++----------- toxav/msi.h | 54 +++--- toxav/rtp.c | 71 ++++---- toxav/rtp.h | 19 ++- toxav/toxav.api.h | 15 +- toxav/toxav.c | 389 ++++++++++++++++++++++--------------------- toxav/toxav.h | 18 +- toxav/toxav_old.c | 26 ++- toxav/video.c | 35 ++-- toxav/video.h | 4 +- toxcore/Messenger.h | 2 +- toxcore/group.c | 2 +- toxcore/tox.c | 54 +++--- 20 files changed, 558 insertions(+), 490 deletions(-) diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel index 1c1b35567d..151ac48e6a 100644 --- a/toxav/BUILD.bazel +++ b/toxav/BUILD.bazel @@ -99,7 +99,7 @@ cc_library( srcs = ["groupav.c"], hdrs = ["groupav.h"], deps = [ - "//c-toxcore/toxcore:group", + "//c-toxcore/toxcore:toxcore", "@opus", ], ) diff --git a/toxav/audio.c b/toxav/audio.c index 99bb7c97ae..729a4922b4 100644 --- a/toxav/audio.c +++ b/toxav/audio.c @@ -222,13 +222,13 @@ int ac_queue_message(void *acp, struct RTPMessage *msg) ACSession *ac = (ACSession *)acp; - if ((msg->header.pt & 0x7f) == (rtp_TypeAudio + 2) % 128) { + if ((msg->header.pt & 0x7f) == (RTP_TYPE_AUDIO + 2) % 128) { LOGGER_WARNING(ac->log, "Got dummy!"); free(msg); return 0; } - if ((msg->header.pt & 0x7f) != rtp_TypeAudio % 128) { + if ((msg->header.pt & 0x7f) != RTP_TYPE_AUDIO % 128) { LOGGER_WARNING(ac->log, "Invalid payload type!"); free(msg); return -1; diff --git a/toxav/audio.h b/toxav/audio.h index 3c646f7679..f71aaed318 100644 --- a/toxav/audio.h +++ b/toxav/audio.h @@ -24,6 +24,7 @@ #include "../toxcore/logger.h" #include "../toxcore/util.h" +#include "rtp.h" #include #include @@ -48,8 +49,6 @@ #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) -struct RTPMessage; - typedef struct ACSession_s { const Logger *log; diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c index 05fac70402..460cf11846 100644 --- a/toxav/bwcontroller.c +++ b/toxav/bwcontroller.c @@ -35,30 +35,34 @@ #include "../toxcore/util.h" #define BWC_PACKET_ID 196 -#define BWC_SEND_INTERVAL_MS 950 /* 0.95s */ +#define BWC_SEND_INTERVAL_MS 950 // 0.95s #define BWC_AVG_PKT_COUNT 20 #define BWC_AVG_LOSS_OVER_CYCLES_COUNT 30 +typedef struct BWCCycle { + uint32_t last_recv_timestamp; /* Last recv update time stamp */ + uint32_t last_sent_timestamp; /* Last sent update time stamp */ + uint32_t last_refresh_timestamp; /* Last refresh time stamp */ + + uint32_t lost; + uint32_t recv; +} BWCCycle; + +typedef struct BWCRcvPkt { + uint32_t packet_length_array[BWC_AVG_PKT_COUNT]; + RingBuffer *rb; +} BWCRcvPkt; + struct BWController_s { - void (*mcb)(BWController *, uint32_t, float, void *); - void *mcb_data; + m_cb *mcb; + void *mcb_user_data; Messenger *m; uint32_t friend_number; - struct { - uint32_t last_recv_timestamp; /* Last recv update time stamp */ - uint32_t last_sent_timestamp; /* Last sent update time stamp */ - uint32_t last_refresh_timestamp; /* Last refresh time stamp */ - - uint32_t lost; - uint32_t recv; - } cycle; + BWCCycle cycle; - struct { - uint32_t packet_length_array[BWC_AVG_PKT_COUNT]; - RingBuffer *rb; - } rcvpkt; /* To calculate average received packet (this means split parts, not the full message!) */ + BWCRcvPkt rcvpkt; /* To calculate average received packet (this means split parts, not the full message!) */ uint32_t packet_loss_counted_cycles; }; @@ -71,24 +75,24 @@ struct BWCMessage { int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object); void send_update(BWController *bwc); -BWController *bwc_new(Messenger *m, uint32_t friendnumber, - void (*mcb)(BWController *, uint32_t, float, void *), - void *udata) +BWController *bwc_new(Messenger *m, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data) { BWController *retu = (BWController *)calloc(sizeof(struct BWController_s), 1); LOGGER_DEBUG(m->log, "Creating bandwidth controller"); retu->mcb = mcb; - retu->mcb_data = udata; + retu->mcb_user_data = mcb_user_data; retu->m = m; retu->friend_number = friendnumber; - retu->cycle.last_sent_timestamp = retu->cycle.last_refresh_timestamp = current_time_monotonic(); + uint64_t now = current_time_monotonic(); + retu->cycle.last_sent_timestamp = now; + retu->cycle.last_refresh_timestamp = now; retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT); retu->cycle.lost = 0; retu->cycle.recv = 0; retu->packet_loss_counted_cycles = 0; /* Fill with zeros */ - for (int i = 0; i < BWC_AVG_PKT_COUNT; i++) { + for (int i = 0; i < BWC_AVG_PKT_COUNT; ++i) { rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]); } @@ -126,7 +130,7 @@ void bwc_add_recv(BWController *bwc, uint32_t recv_bytes) return; } - bwc->packet_loss_counted_cycles++; + ++bwc->packet_loss_counted_cycles; bwc->cycle.recv += recv_bytes; send_update(bwc); } @@ -181,7 +185,7 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg) (((double) lost / (recv + lost)) * 100.0)); bwc->mcb(bwc, bwc->friend_number, ((float) lost / (recv + lost)), - bwc->mcb_data); + bwc->mcb_user_data); } return 0; diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h index fdbc1746bd..c0e2dfc942 100644 --- a/toxav/bwcontroller.h +++ b/toxav/bwcontroller.h @@ -24,9 +24,9 @@ typedef struct BWController_s BWController; -BWController *bwc_new(Messenger *m, uint32_t friendnumber, - void (*mcb)(BWController *, uint32_t, float, void *), - void *udata); +typedef void m_cb(BWController *bwc, uint32_t friend_number, float todo, void *user_data); + +BWController *bwc_new(Messenger *m, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data); void bwc_kill(BWController *bwc); diff --git a/toxav/groupav.c b/toxav/groupav.c index 15fdd534e5..5b1c5e8d75 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -33,13 +33,13 @@ #define GROUP_JBUF_SIZE 6 #define GROUP_JBUF_DEAD_SECONDS 4 -typedef struct { +typedef struct Group_Audio_Packet { uint16_t sequnum; uint16_t length; uint8_t data[]; } Group_Audio_Packet; -typedef struct { +typedef struct Group_JitterBuffer { Group_Audio_Packet **queue; uint32_t size; uint32_t capacity; @@ -56,13 +56,15 @@ static Group_JitterBuffer *create_queue(unsigned int capacity) size *= 2; } - Group_JitterBuffer *q; + Group_JitterBuffer *q = (Group_JitterBuffer *)calloc(sizeof(Group_JitterBuffer), 1); - if (!(q = (Group_JitterBuffer *)calloc(sizeof(Group_JitterBuffer), 1))) { + if (!q) { return nullptr; } - if (!(q->queue = (Group_Audio_Packet **)calloc(sizeof(Group_Audio_Packet *), size))) { + q->queue = (Group_Audio_Packet **)calloc(sizeof(Group_Audio_Packet *), size); + + if (!q->queue) { free(q); return nullptr; } @@ -159,21 +161,23 @@ static Group_Audio_Packet *dequeue(Group_JitterBuffer *q, int *success) return nullptr; } -typedef struct { +typedef struct Group_AV { const Logger *log; + Tox *tox; Group_Chats *g_c; OpusEncoder *audio_encoder; - unsigned int audio_channels, audio_sample_rate, audio_bitrate; + unsigned int audio_channels; + unsigned int audio_sample_rate; + unsigned int audio_bitrate; uint16_t audio_sequnum; - void (*audio_data)(Messenger *m, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, uint32_t samples, - uint8_t channels, unsigned int sample_rate, void *userdata); + audio_data_cb *audio_data; void *userdata; } Group_AV; -typedef struct { +typedef struct Group_Peer_AV { Group_JitterBuffer *buffer; OpusDecoder *audio_decoder; @@ -228,8 +232,8 @@ static int recreate_encoder(Group_AV *group_av) return 0; } -static Group_AV *new_group_av(const Logger *log, Group_Chats *g_c, void (*audio_callback)(Messenger *, uint32_t, - uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata) +static Group_AV *new_group_av(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, + void *userdata) { if (!g_c) { return nullptr; @@ -242,6 +246,7 @@ static Group_AV *new_group_av(const Logger *log, Group_Chats *g_c, void (*audio_ } group_av->log = log; + group_av->tox = tox; group_av->g_c = g_c; group_av->audio_data = audio_callback; @@ -381,7 +386,7 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, uint3 if (out_audio) { if (group_av->audio_data) { - group_av->audio_data(group_av->g_c->m, groupnumber, friendgroupnumber, out_audio, out_audio_samples, + group_av->audio_data(group_av->tox, groupnumber, friendgroupnumber, out_audio, out_audio_samples, peer_av->decoder_channels, sample_rate, group_av->userdata); } @@ -417,7 +422,7 @@ static int handle_group_audio_packet(void *object, uint32_t groupnumber, uint32_ } while (decode_audio_packet((Group_AV *)object, peer_av, groupnumber, friendgroupnumber) == 0) { - ; + continue; } return 0; @@ -428,11 +433,10 @@ static int handle_group_audio_packet(void *object, uint32_t groupnumber, uint32_ * return 0 on success. * return -1 on failure. */ -static int groupchat_enable_av(const Logger *log, Group_Chats *g_c, uint32_t groupnumber, - void (*audio_callback)(Messenger *, - uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata) +static int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t groupnumber, + audio_data_cb *audio_callback, void *userdata) { - Group_AV *group_av = new_group_av(log, g_c, audio_callback, userdata); + Group_AV *group_av = new_group_av(log, tox, g_c, audio_callback, userdata); if (group_av == nullptr) { return -1; @@ -455,8 +459,7 @@ static int groupchat_enable_av(const Logger *log, Group_Chats *g_c, uint32_t gro * return group number on success. * return -1 on failure. */ -int add_av_groupchat(const Logger *log, Group_Chats *g_c, void (*audio_callback)(Messenger *, uint32_t, uint32_t, - const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata) +int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) { int groupnumber = add_groupchat(g_c, GROUPCHAT_TYPE_AV); @@ -464,7 +467,7 @@ int add_av_groupchat(const Logger *log, Group_Chats *g_c, void (*audio_callback) return -1; } - if (groupchat_enable_av(log, g_c, groupnumber, audio_callback, userdata) == -1) { + if (groupchat_enable_av(log, tox, g_c, groupnumber, audio_callback, userdata) == -1) { del_groupchat(g_c, groupnumber); return -1; } @@ -477,9 +480,8 @@ int add_av_groupchat(const Logger *log, Group_Chats *g_c, void (*audio_callback) * returns group number on success * returns -1 on failure. */ -int join_av_groupchat(const Logger *log, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, uint16_t length, - void (*audio_callback)(Messenger *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), - void *userdata) +int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, + uint16_t length, audio_data_cb *audio_callback, void *userdata) { int groupnumber = join_groupchat(g_c, friendnumber, GROUPCHAT_TYPE_AV, data, length); @@ -487,7 +489,7 @@ int join_av_groupchat(const Logger *log, Group_Chats *g_c, uint32_t friendnumber return -1; } - if (groupchat_enable_av(log, g_c, groupnumber, audio_callback, userdata) == -1) { + if (groupchat_enable_av(log, tox, g_c, groupnumber, audio_callback, userdata) == -1) { del_groupchat(g_c, groupnumber); return -1; } @@ -516,7 +518,8 @@ static int send_audio_packet(Group_Chats *g_c, uint32_t groupnumber, uint8_t *pa uint8_t data[MAX_CRYPTO_DATA_SIZE]; uint8_t *ptr = data; - *ptr++ = GROUP_AUDIO_PACKET_ID; + *ptr = GROUP_AUDIO_PACKET_ID; + ++ptr; ptr += net_pack_u16(ptr, group_av->audio_sequnum); memcpy(ptr, packet, length); diff --git a/toxav/groupav.h b/toxav/groupav.h index 42f2c57839..31c9abba94 100644 --- a/toxav/groupav.h +++ b/toxav/groupav.h @@ -21,28 +21,34 @@ #define C_TOXCORE_TOXAV_GROUPAV_H #include "../toxcore/group.h" +#include "../toxcore/tox.h" /* Audio encoding/decoding */ #include #define GROUP_AUDIO_PACKET_ID 192 +// TODO(iphydf): Use this better typed one instead of the void-pointer one below. +// typedef void audio_data_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, +// uint32_t samples, uint8_t channels, uint32_t sample_rate, void *userdata); +typedef void audio_data_cb(void *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, + uint32_t samples, uint8_t channels, uint32_t sample_rate, void *userdata); + /* Create a new toxav group. * * return group number on success. * return -1 on failure. */ -int add_av_groupchat(const Logger *log, Group_Chats *g_c, void (*audio_callback)(Messenger *, uint32_t, uint32_t, - const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata); +int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata); /* Join a AV group (you need to have been invited first.) * * returns group number on success * returns -1 on failure. */ -int join_av_groupchat(const Logger *log, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, uint16_t length, - void (*audio_callback)(Messenger *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), - void *userdata); +int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, + uint16_t length, + audio_data_cb *audio_callback, void *userdata); /* Send audio to the group chat. diff --git a/toxav/msi.c b/toxav/msi.c index f1242228e1..41f33c7f37 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -40,33 +40,37 @@ * |id [1 byte]| |size [1 byte]| |data [$size bytes]| |...{repeat}| |0 {end byte}| */ -typedef enum { - IDRequest = 1, - IDError, - IDCapabilities, +typedef enum MSIHeaderID { + ID_REQUEST = 1, + ID_ERROR, + ID_CAPABILITIES, } MSIHeaderID; -typedef enum { - requ_init, - requ_push, - requ_pop, +typedef enum MSIRequest { + REQU_INIT, + REQU_PUSH, + REQU_POP, } MSIRequest; -#define GENERIC_HEADER(header, val_type) \ -typedef struct { \ - val_type value; \ - bool exists; \ -} MSIHeader##header +typedef struct MSIHeaderRequest { + MSIRequest value; + bool exists; +} MSIHeaderRequest; +typedef struct MSIHeaderError { + MSIError value; + bool exists; +} MSIHeaderError; -GENERIC_HEADER(Request, MSIRequest); -GENERIC_HEADER(Error, MSIError); -GENERIC_HEADER(Capabilities, uint8_t); +typedef struct MSIHeaderCapabilities { + uint8_t value; + bool exists; +} MSIHeaderCapabilities; -typedef struct { +typedef struct MSIMessage { MSIHeaderRequest request; MSIHeaderError error; MSIHeaderCapabilities capabilities; @@ -147,7 +151,7 @@ int msi_kill(MSISession *session, const Logger *log) if (session->calls) { MSIMessage msg; - msg_init(&msg, requ_pop); + msg_init(&msg, REQU_POP); MSICall *it = get_call(session, session->calls_head); @@ -185,24 +189,26 @@ int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint return -1; } - (*call) = new_call(session, friend_number); + MSICall *temp = new_call(session, friend_number); - if (*call == nullptr) { + if (temp == nullptr) { pthread_mutex_unlock(session->mutex); return -1; } - (*call)->self_capabilities = capabilities; + temp->self_capabilities = capabilities; MSIMessage msg; - msg_init(&msg, requ_init); + msg_init(&msg, REQU_INIT); msg.capabilities.exists = true; msg.capabilities.value = capabilities; - send_message((*call)->session->messenger, (*call)->friend_number, &msg); + send_message(temp->session->messenger, temp->friend_number, &msg); - (*call)->state = msi_CallRequesting; + temp->state = MSI_CALL_REQUESTING; + + *call = temp; LOGGER_DEBUG(session->messenger->log, "Invite sent"); pthread_mutex_unlock(session->mutex); @@ -224,14 +230,14 @@ int msi_hangup(MSICall *call) return -1; } - if (call->state == msi_CallInactive) { + if (call->state == MSI_CALL_INACTIVE) { LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); pthread_mutex_unlock(session->mutex); return -1; } MSIMessage msg; - msg_init(&msg, requ_pop); + msg_init(&msg, REQU_POP); send_message(session->messenger, call->friend_number, &msg); @@ -255,7 +261,7 @@ int msi_answer(MSICall *call, uint8_t capabilities) return -1; } - if (call->state != msi_CallRequested) { + if (call->state != MSI_CALL_REQUESTED) { /* Though sending in invalid state will not cause anything weird * Its better to not do it like a maniac */ LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); @@ -266,14 +272,14 @@ int msi_answer(MSICall *call, uint8_t capabilities) call->self_capabilities = capabilities; MSIMessage msg; - msg_init(&msg, requ_push); + msg_init(&msg, REQU_PUSH); msg.capabilities.exists = true; msg.capabilities.value = capabilities; send_message(session->messenger, call->friend_number, &msg); - call->state = msi_CallActive; + call->state = MSI_CALL_ACTIVE; pthread_mutex_unlock(session->mutex); return 0; @@ -294,7 +300,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities) return -1; } - if (call->state != msi_CallActive) { + if (call->state != MSI_CALL_ACTIVE) { LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); pthread_mutex_unlock(session->mutex); return -1; @@ -303,7 +309,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities) call->self_capabilities = capabilities; MSIMessage msg; - msg_init(&msg, requ_push); + msg_init(&msg, REQU_PUSH); msg.capabilities.exists = true; msg.capabilities.value = capabilities; @@ -328,18 +334,27 @@ int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint1 { /* Parse raw data received from socket into MSIMessage struct */ -#define CHECK_SIZE(bytes, constraint, size) \ - if ((constraint -= (2 + size)) < 1) { LOGGER_ERROR(log, "Read over length!"); return -1; } \ - if (bytes[1] != size) { LOGGER_ERROR(log, "Invalid data size!"); return -1; } - -#define CHECK_ENUM_HIGH(bytes, enum_high) /* Assumes size == 1 */ \ - if (bytes[2] > enum_high) { LOGGER_ERROR(log, "Failed enum high limit!"); return -1; } - -#define SET_UINT8(type, bytes, header) do { \ - header.value = (type)bytes[2]; \ - header.exists = true; \ - bytes += 3; \ - } while(0) +#define CHECK_SIZE(bytes, constraint, size) \ + do { \ + constraint -= 2 + size; \ + if (constraint < 1) { \ + LOGGER_ERROR(log, "Read over length!"); \ + return -1; \ + } \ + if (bytes[1] != size) { \ + LOGGER_ERROR(log, "Invalid data size!"); \ + return -1; \ + } \ + } while (0) + + /* Assumes size == 1 */ +#define CHECK_ENUM_HIGH(bytes, enum_high) \ + do { \ + if (bytes[2] > enum_high) { \ + LOGGER_ERROR(log, "Failed enum high limit!"); \ + return -1; \ + } \ + } while (0) assert(dest); @@ -355,21 +370,27 @@ int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint1 while (*it) {/* until end byte is hit */ switch (*it) { - case IDRequest: + case ID_REQUEST: CHECK_SIZE(it, size_constraint, 1); - CHECK_ENUM_HIGH(it, requ_pop); - SET_UINT8(MSIRequest, it, dest->request); + CHECK_ENUM_HIGH(it, REQU_POP); + dest->request.value = (MSIRequest)it[2]; + dest->request.exists = true; + it += 3; break; - case IDError: + case ID_ERROR: CHECK_SIZE(it, size_constraint, 1); - CHECK_ENUM_HIGH(it, msi_EUndisclosed); - SET_UINT8(MSIError, it, dest->error); + CHECK_ENUM_HIGH(it, MSI_E_UNDISCLOSED); + dest->error.value = (MSIError)it[2]; + dest->error.exists = true; + it += 3; break; - case IDCapabilities: + case ID_CAPABILITIES: CHECK_SIZE(it, size_constraint, 1); - SET_UINT8(uint8_t, it, dest->capabilities); + dest->capabilities.value = it[2]; + dest->capabilities.exists = true; + it += 3; break; default: @@ -383,11 +404,10 @@ int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint1 return -1; } - return 0; - -#undef CHECK_SIZE #undef CHECK_ENUM_HIGH -#undef SET_UINT8 +#undef CHECK_SIZE + + return 0; } uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length) { @@ -397,9 +417,9 @@ uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, assert(value_len); *dest = id; - dest ++; + ++dest; *dest = value_len; - dest ++; + ++dest; memcpy(dest, value, value_len); @@ -419,7 +439,7 @@ int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg) if (msg->request.exists) { uint8_t cast = msg->request.value; - it = msg_parse_header_out(IDRequest, it, &cast, + it = msg_parse_header_out(ID_REQUEST, it, &cast, sizeof(cast), &size); } else { LOGGER_DEBUG(m->log, "Must have request field"); @@ -428,12 +448,12 @@ int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg) if (msg->error.exists) { uint8_t cast = msg->error.value; - it = msg_parse_header_out(IDError, it, &cast, + it = msg_parse_header_out(ID_ERROR, it, &cast, sizeof(cast), &size); } if (msg->capabilities.exists) { - it = msg_parse_header_out(IDCapabilities, it, &msg->capabilities.value, + it = msg_parse_header_out(ID_CAPABILITIES, it, &msg->capabilities.value, sizeof(msg->capabilities.value), &size); } @@ -443,7 +463,7 @@ int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg) } *it = 0; - size ++; + ++size; if (m_msi_packet(m, friend_number, parsed, size)) { LOGGER_DEBUG(m->log, "Sent message"); @@ -460,7 +480,7 @@ int send_error(Messenger *m, uint32_t friend_number, MSIError error) LOGGER_DEBUG(m->log, "Sending error: %d to friend: %d", error, friend_number); MSIMessage msg; - msg_init(&msg, requ_pop); + msg_init(&msg, REQU_POP); msg.error.exists = true; msg.error.value = error; @@ -489,8 +509,8 @@ int invoke_callback(MSICall *call, MSICallbackID cb) * an error message will be sent to friend */ - if (call->error == msi_ENone) { - call->error = msi_EHandle; + if (call->error == MSI_E_NONE) { + call->error = MSI_E_HANDLE; } return -1; @@ -526,7 +546,8 @@ MSICall *new_call(MSISession *session, uint32_t friend_number) return nullptr; } - session->calls_tail = session->calls_head = friend_number; + session->calls_tail = friend_number; + session->calls_head = friend_number; } else if (session->calls_tail < friend_number) { /* Appending */ MSICall **tmp = (MSICall **)realloc(session->calls, sizeof(MSICall *) * (friend_number + 1)); @@ -540,7 +561,7 @@ MSICall *new_call(MSISession *session, uint32_t friend_number) /* Set fields in between to null */ uint32_t i = session->calls_tail + 1; - for (; i < friend_number; i ++) { + for (; i < friend_number; ++i) { session->calls[i] = nullptr; } @@ -592,14 +613,14 @@ void kill_call(MSICall *call) return; CLEAR_CONTAINER: - session->calls_head = session->calls_tail = 0; + session->calls_head = 0; + session->calls_tail = 0; free(session->calls); free(call); session->calls = nullptr; } void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data) { - (void)m; MSISession *session = (MSISession *)data; switch (status) { @@ -614,7 +635,7 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void * return; } - invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */ + invoke_callback(call, MSI_ON_PEERTIMEOUT); /* Failure is ignored */ kill_call(call); pthread_mutex_unlock(session->mutex); } @@ -632,23 +653,23 @@ void handle_init(MSICall *call, const MSIMessage *msg) if (!msg->capabilities.exists) { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'init'", (void *)call->session); - call->error = msi_EInvalidMessage; + call->error = MSI_E_INVALID_MESSAGE; goto FAILURE; } switch (call->state) { - case msi_CallInactive: { + case MSI_CALL_INACTIVE: { /* Call requested */ call->peer_capabilities = msg->capabilities.value; - call->state = msi_CallRequested; + call->state = MSI_CALL_REQUESTED; - if (invoke_callback(call, msi_OnInvite) == -1) { + if (invoke_callback(call, MSI_ON_INVITE) == -1) { goto FAILURE; } } break; - case msi_CallActive: { + case MSI_CALL_ACTIVE: { /* If peer sent init while the call is already * active it's probable that he is trying to * re-call us while the call is not terminated @@ -659,7 +680,7 @@ void handle_init(MSICall *call, const MSIMessage *msg) LOGGER_INFO(call->session->messenger->log, "Friend is recalling us"); MSIMessage out_msg; - msg_init(&out_msg, requ_push); + msg_init(&out_msg, REQU_PUSH); out_msg.capabilities.exists = true; out_msg.capabilities.value = call->self_capabilities; @@ -672,10 +693,10 @@ void handle_init(MSICall *call, const MSIMessage *msg) } break; - case msi_CallRequested: // fall-through - case msi_CallRequesting: { + case MSI_CALL_REQUESTED: // fall-through + case MSI_CALL_REQUESTING: { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid state on 'init'", (void *)call->session); - call->error = msi_EInvalidState; + call->error = MSI_E_INVALID_STATE; goto FAILURE; } } @@ -694,41 +715,41 @@ void handle_push(MSICall *call, const MSIMessage *msg) if (!msg->capabilities.exists) { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'push'", (void *)call->session); - call->error = msi_EInvalidMessage; + call->error = MSI_E_INVALID_MESSAGE; goto FAILURE; } switch (call->state) { - case msi_CallActive: { + case MSI_CALL_ACTIVE: { /* Only act if capabilities changed */ if (call->peer_capabilities != msg->capabilities.value) { LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value); call->peer_capabilities = msg->capabilities.value; - if (invoke_callback(call, msi_OnCapabilities) == -1) { + if (invoke_callback(call, MSI_ON_CAPABILITIES) == -1) { goto FAILURE; } } } break; - case msi_CallRequesting: { + case MSI_CALL_REQUESTING: { LOGGER_INFO(call->session->messenger->log, "Friend answered our call"); /* Call started */ call->peer_capabilities = msg->capabilities.value; - call->state = msi_CallActive; + call->state = MSI_CALL_ACTIVE; - if (invoke_callback(call, msi_OnStart) == -1) { + if (invoke_callback(call, MSI_ON_START) == -1) { goto FAILURE; } } break; /* Pushes during initialization state are ignored */ - case msi_CallInactive: // fall-through - case msi_CallRequested: { + case MSI_CALL_INACTIVE: // fall-through + case MSI_CALL_REQUESTED: { LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push"); } break; @@ -752,32 +773,32 @@ void handle_pop(MSICall *call, const MSIMessage *msg) if (msg->error.exists) { LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value); call->error = msg->error.value; - invoke_callback(call, msi_OnError); + invoke_callback(call, MSI_ON_ERROR); } else { switch (call->state) { - case msi_CallInactive: { + case MSI_CALL_INACTIVE: { LOGGER_ERROR(call->session->messenger->log, "Handling what should be impossible case"); abort(); } - case msi_CallActive: { + case MSI_CALL_ACTIVE: { /* Hangup */ LOGGER_INFO(call->session->messenger->log, "Friend hung up on us"); - invoke_callback(call, msi_OnEnd); + invoke_callback(call, MSI_ON_END); } break; - case msi_CallRequesting: { + case MSI_CALL_REQUESTING: { /* Reject */ LOGGER_INFO(call->session->messenger->log, "Friend rejected our call"); - invoke_callback(call, msi_OnEnd); + invoke_callback(call, MSI_ON_END); } break; - case msi_CallRequested: { + case MSI_CALL_REQUESTED: { /* Cancel */ LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite"); - invoke_callback(call, msi_OnEnd); + invoke_callback(call, MSI_ON_END); } break; } @@ -794,7 +815,7 @@ void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data if (msg_parse_in(m->log, &msg, data, length) == -1) { LOGGER_WARNING(m->log, "Error parsing message"); - send_error(m, friend_number, msi_EInvalidMessage); + send_error(m, friend_number, MSI_E_INVALID_MESSAGE); return; } @@ -804,8 +825,8 @@ void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data MSICall *call = get_call(session, friend_number); if (call == nullptr) { - if (msg.request.value != requ_init) { - send_error(m, friend_number, msi_EStrayMessage); + if (msg.request.value != REQU_INIT) { + send_error(m, friend_number, MSI_E_STRAY_MESSAGE); pthread_mutex_unlock(session->mutex); return; } @@ -813,22 +834,22 @@ void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data call = new_call(session, friend_number); if (call == nullptr) { - send_error(m, friend_number, msi_ESystem); + send_error(m, friend_number, MSI_E_SYSTEM); pthread_mutex_unlock(session->mutex); return; } } switch (msg.request.value) { - case requ_init: + case REQU_INIT: handle_init(call, &msg); break; - case requ_push: + case REQU_PUSH: handle_push(call, &msg); break; - case requ_pop: + case REQU_POP: handle_pop(call, &msg); /* always kills the call */ break; } diff --git a/toxav/msi.h b/toxav/msi.h index b2c1556763..24dfd588c7 100644 --- a/toxav/msi.h +++ b/toxav/msi.h @@ -32,48 +32,48 @@ /** * Error codes. */ -typedef enum { - msi_ENone, - msi_EInvalidMessage, - msi_EInvalidParam, - msi_EInvalidState, - msi_EStrayMessage, - msi_ESystem, - msi_EHandle, - msi_EUndisclosed, /* NOTE: must be last enum otherwise parsing will not work */ +typedef enum MSIError { + MSI_E_NONE, + MSI_E_INVALID_MESSAGE, + MSI_E_INVALID_PARAM, + MSI_E_INVALID_STATE, + MSI_E_STRAY_MESSAGE, + MSI_E_SYSTEM, + MSI_E_HANDLE, + MSI_E_UNDISCLOSED, /* NOTE: must be last enum otherwise parsing will not work */ } MSIError; /** * Supported capabilities */ -typedef enum { - msi_CapSAudio = 4, /* sending audio */ - msi_CapSVideo = 8, /* sending video */ - msi_CapRAudio = 16, /* receiving audio */ - msi_CapRVideo = 32, /* receiving video */ +typedef enum MSICapabilities { + MSI_CAP_S_AUDIO = 4, /* sending audio */ + MSI_CAP_S_VIDEO = 8, /* sending video */ + MSI_CAP_R_AUDIO = 16, /* receiving audio */ + MSI_CAP_R_VIDEO = 32, /* receiving video */ } MSICapabilities; /** * Call state identifiers. */ -typedef enum { - msi_CallInactive, /* Default */ - msi_CallActive, - msi_CallRequesting, /* when sending call invite */ - msi_CallRequested, /* when getting call invite */ +typedef enum MSICallState { + MSI_CALL_INACTIVE, /* Default */ + MSI_CALL_ACTIVE, + MSI_CALL_REQUESTING, /* when sending call invite */ + MSI_CALL_REQUESTED, /* when getting call invite */ } MSICallState; /** * Callbacks ids that handle the states */ -typedef enum { - msi_OnInvite, /* Incoming call */ - msi_OnStart, /* Call (RTP transmission) started */ - msi_OnEnd, /* Call that was active ended */ - msi_OnError, /* On protocol error */ - msi_OnPeerTimeout, /* Peer timed out; stop the call */ - msi_OnCapabilities, /* Peer requested capabilities change */ +typedef enum MSICallbackID { + MSI_ON_INVITE, /* Incoming call */ + MSI_ON_START, /* Call (RTP transmission) started */ + MSI_ON_END, /* Call that was active ended */ + MSI_ON_ERROR, /* On protocol error */ + MSI_ON_PEERTIMEOUT, /* Peer timed out; stop the call */ + MSI_ON_CAPABILITIES, /* Peer requested capabilities change */ } MSICallbackID; /** @@ -89,7 +89,7 @@ typedef struct MSICall_s { uint32_t friend_number; /* Index of this call in MSISession */ MSIError error; /* Last error */ - void *av_call; /* Pointer to av call handler */ + struct ToxAVCall_s *av_call; /* Pointer to av call handler */ struct MSICall_s *next; struct MSICall_s *prev; diff --git a/toxav/rtp.c b/toxav/rtp.c index 3d563a1f24..612979375c 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -35,13 +35,11 @@ #include "../toxcore/mono_time.h" #include "../toxcore/util.h" -enum { - /** - * The number of milliseconds we want to keep a keyframe in the buffer for, - * even though there are no free slots for incoming frames. - */ - VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS = 15, -}; +/** + * The number of milliseconds we want to keep a keyframe in the buffer for, + * even though there are no free slots for incoming frames. + */ +#define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15 // allocate_len is NOT including header! static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, @@ -60,16 +58,15 @@ static struct RTPMessage *new_message(const struct RTPHeader *header, size_t all return msg; } -enum { - /** - * Instruct the caller to clear slot 0. - */ - GET_SLOT_RESULT_DROP_OLDEST_SLOT = -1, - /** - * Instruct the caller to drop the incoming packet. - */ - GET_SLOT_RESULT_DROP_INCOMING = -2, -}; +/** + * Instruct the caller to clear slot 0. + */ +#define GET_SLOT_RESULT_DROP_OLDEST_SLOT (-1) + +/** + * Instruct the caller to drop the incoming packet. + */ +#define GET_SLOT_RESULT_DROP_INCOMING (-2) /** * Find the next free slot in work_buffer for the incoming data packet. @@ -89,7 +86,7 @@ static int8_t get_slot(const Logger *log, struct RTPWorkBufferList *wkbl, bool i if (is_multipart) { // This RTP message is part of a multipart frame, so we try to find an // existing slot with the previous parts of the frame in it. - for (uint8_t i = 0; i < wkbl->next_free_entry; i++) { + for (uint8_t i = 0; i < wkbl->next_free_entry; ++i) { const struct RTPWorkBuffer *slot = &wkbl->work_buffer[i]; if ((slot->buf->header.sequnum == header->sequnum) && (slot->buf->header.timestamp == header->timestamp)) { @@ -228,14 +225,14 @@ static struct RTPMessage *process_frame(const Logger *log, struct RTPWorkBufferL if (slot_id != wkbl->next_free_entry - 1) { // The slot is not the last slot, so we created a gap. We move all the // entries after it one step up. - for (uint8_t i = slot_id; i < wkbl->next_free_entry - 1; i++) { + for (uint8_t i = slot_id; i < wkbl->next_free_entry - 1; ++i) { // Move entry (i+1) into entry (i). wkbl->work_buffer[i] = wkbl->work_buffer[i + 1]; } } // We now have a free entry at the end of the array. - wkbl->next_free_entry--; + --wkbl->next_free_entry; // Clear the newly freed entry. const struct RTPWorkBuffer empty = {0}; @@ -290,7 +287,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb slot->received_len = 0; assert(wkbl->next_free_entry < USED_RTP_WORKBUFFER_COUNT); - wkbl->next_free_entry++; + ++wkbl->next_free_entry; } // We already checked this when we received the packet, but we rely on it @@ -317,7 +314,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg) { if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) { - session->first_packets_counter++; + ++session->first_packets_counter; } else { uint32_t data_length_full = msg->header.data_length_full; // without header uint32_t received_length_full = msg->header.received_length_full; // without header @@ -482,11 +479,11 @@ static int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t return -1; } - LOGGER_DEBUG(m->log, "header.pt %d, video %d", (uint8_t)header.pt, (rtp_TypeVideo % 128)); + LOGGER_DEBUG(m->log, "header.pt %d, video %d", (uint8_t)header.pt, (RTP_TYPE_VIDEO % 128)); // The sender uses the new large-frame capable protocol and is sending a // video packet. - if ((header.flags & RTP_LARGE_FRAME) && header.pt == (rtp_TypeVideo % 128)) { + if ((header.flags & RTP_LARGE_FRAME) && header.pt == (RTP_TYPE_VIDEO % 128)) { return handle_video_packet(session, &header, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE, m->log); } @@ -586,12 +583,14 @@ static int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) { uint8_t *p = rdata; - *p++ = (header->ve & 3) << 6 - | (header->pe & 1) << 5 - | (header->xe & 1) << 4 - | (header->cc & 0xf); - *p++ = (header->ma & 1) << 7 - | (header->pt & 0x7f); + *p = (header->ve & 3) << 6 + | (header->pe & 1) << 5 + | (header->xe & 1) << 4 + | (header->cc & 0xf); + ++p; + *p = (header->ma & 1) << 7 + | (header->pt & 0x7f); + ++p; p += net_pack_u16(p, header->sequnum); p += net_pack_u32(p, header->timestamp); @@ -601,7 +600,7 @@ size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) p += net_pack_u32(p, header->data_length_full); p += net_pack_u32(p, header->received_length_full); - for (size_t i = 0; i < RTP_PADDING_FIELDS; i++) { + for (size_t i = 0; i < RTP_PADDING_FIELDS; ++i) { p += net_pack_u32(p, 0); } @@ -640,10 +639,8 @@ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header) return p - data; } - RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, - BWController *bwc, void *cs, - int (*mcb)(void *, struct RTPMessage *)) + BWController *bwc, void *cs, rtp_m_cb *mcb) { assert(mcb != nullptr); assert(cs != nullptr); @@ -667,7 +664,7 @@ RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, // First entry is free. session->work_buffer_list->next_free_entry = 0; - session->ssrc = payload_type == rtp_TypeVideo ? 0 : random_u32(); + session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(); session->payload_type = payload_type; session->m = m; session->friend_number = friendnumber; @@ -772,7 +769,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, // here the highest bits gets stripped anyway, no need to do keyframe bit magic here! header.data_length_lower = length; - if (session->payload_type == rtp_TypeVideo) { + if (session->payload_type == RTP_TYPE_VIDEO) { header.flags = RTP_LARGE_FRAME; } @@ -851,6 +848,6 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, } } - session->sequnum ++; + ++session->sequnum; return 0; } diff --git a/toxav/rtp.h b/toxav/rtp.h index d7fc556016..225f4c037d 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -45,16 +45,16 @@ extern "C" { /** * Payload type identifier. Also used as rtp callback prefix. */ -enum { - rtp_TypeAudio = 192, - rtp_TypeVideo = 193, -}; +typedef enum RTP_Type { + RTP_TYPE_AUDIO = 192, + RTP_TYPE_VIDEO = 193, +} RTP_Type; /** * A bit mask (up to 64 bits) specifying features of the current frame affecting * the behaviour of the decoder. */ -enum RTPFlags { +typedef enum RTPFlags { /** * Support frames larger than 64KiB. The full 32 bit length and offset are * set in \ref RTPHeader::data_length_full and \ref RTPHeader::offset_full. @@ -64,7 +64,7 @@ enum RTPFlags { * Whether the packet is part of a key frame. */ RTP_KEY_FRAME = 1 << 1, -}; +} RTPFlags; struct RTPHeader { @@ -159,6 +159,8 @@ struct RTPWorkBufferList { #define DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT 10 +typedef int rtp_m_cb(void *cs, struct RTPMessage *msg); + /** * RTP control session. */ @@ -175,7 +177,7 @@ typedef struct RTPSession { uint32_t friend_number; BWController *bwc; void *cs; - int (*mcb)(void *, struct RTPMessage *msg); + rtp_m_cb *mcb; } RTPSession; @@ -198,8 +200,7 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header); size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, - BWController *bwc, void *cs, - int (*mcb)(void *, struct RTPMessage *)); + BWController *bwc, void *cs, rtp_m_cb *mcb); void rtp_kill(RTPSession *session); int rtp_allow_receiving(RTPSession *session); int rtp_stop_receiving(RTPSession *session); diff --git a/toxav/toxav.api.h b/toxav/toxav.api.h index 9e6cea6884..90ff08bb95 100644 --- a/toxav/toxav.api.h +++ b/toxav/toxav.api.h @@ -616,8 +616,8 @@ namespace video { * * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). */ -int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, - uint32_t, void *), void *userdata); +int toxav_add_av_groupchat(Tox *tox, + void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata); /* Join a AV group (you need to have been invited first.) * @@ -651,5 +651,16 @@ int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, u #ifdef __cplusplus } #endif + +typedef void toxav_group_audio_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, uint32_t samples, uint8_t channels, uint32_t sample_rate, void *user_data); + +typedef TOXAV_ERR_CALL Toxav_Err_Call; +typedef TOXAV_ERR_NEW Toxav_Err_New; +typedef TOXAV_ERR_ANSWER Toxav_Err_Answer; +typedef TOXAV_ERR_CALL_CONTROL Toxav_Err_Call_Control; +typedef TOXAV_ERR_BIT_RATE_SET Toxav_Err_Bit_Rate_Set; +typedef TOXAV_ERR_SEND_FRAME Toxav_Err_Send_Frame; +typedef TOXAV_CALL_CONTROL Toxav_Call_Control; + #endif /* TOXAV_H */ %} diff --git a/toxav/toxav.c b/toxav/toxav.c index 302657ce5e..7c9fb16152 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -80,6 +80,7 @@ typedef struct ToxAVCall_s { } ToxAVCall; struct ToxAV { + Tox *tox; Messenger *m; MSISession *msi; @@ -127,20 +128,20 @@ int callback_capabilites(void *toxav_inst, MSICall *call); bool audio_bit_rate_invalid(uint32_t bit_rate); bool video_bit_rate_invalid(uint32_t bit_rate); bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); -ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); +ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error); ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); ToxAVCall *call_remove(ToxAVCall *call); bool call_prepare_transmission(ToxAVCall *call); void call_kill_transmission(ToxAVCall *call); -ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) +ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) { - TOXAV_ERR_NEW rc = TOXAV_ERR_NEW_OK; + Toxav_Err_New rc = TOXAV_ERR_NEW_OK; ToxAV *av = nullptr; if (tox == nullptr) { rc = TOXAV_ERR_NEW_NULL; - goto END; + goto RETURN; } // TODO(iphydf): Don't rely on toxcore internals. @@ -149,7 +150,7 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) if (m->msi_packet) { rc = TOXAV_ERR_NEW_MULTIPLE; - goto END; + goto RETURN; } av = (ToxAV *)calloc(sizeof(ToxAV), 1); @@ -157,35 +158,36 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) if (av == nullptr) { LOGGER_WARNING(m->log, "Allocation failed!"); rc = TOXAV_ERR_NEW_MALLOC; - goto END; + goto RETURN; } if (create_recursive_mutex(av->mutex) != 0) { LOGGER_WARNING(m->log, "Mutex creation failed!"); rc = TOXAV_ERR_NEW_MALLOC; - goto END; + goto RETURN; } + av->tox = tox; av->m = m; av->msi = msi_new(av->m); if (av->msi == nullptr) { pthread_mutex_destroy(av->mutex); rc = TOXAV_ERR_NEW_MALLOC; - goto END; + goto RETURN; } av->interval = 200; av->msi->av = av; - msi_register_callback(av->msi, callback_invite, msi_OnInvite); - msi_register_callback(av->msi, callback_start, msi_OnStart); - msi_register_callback(av->msi, callback_end, msi_OnEnd); - msi_register_callback(av->msi, callback_error, msi_OnError); - msi_register_callback(av->msi, callback_error, msi_OnPeerTimeout); - msi_register_callback(av->msi, callback_capabilites, msi_OnCapabilities); + msi_register_callback(av->msi, callback_invite, MSI_ON_INVITE); + msi_register_callback(av->msi, callback_start, MSI_ON_START); + msi_register_callback(av->msi, callback_end, MSI_ON_END); + msi_register_callback(av->msi, callback_error, MSI_ON_ERROR); + msi_register_callback(av->msi, callback_error, MSI_ON_PEERTIMEOUT); + msi_register_callback(av->msi, callback_capabilites, MSI_ON_CAPABILITIES); -END: +RETURN: if (error) { *error = rc; @@ -230,7 +232,7 @@ void toxav_kill(ToxAV *av) } Tox *toxav_get_tox(const ToxAV *av) { - return (Tox *) av->m; + return av->tox; } uint32_t toxav_iteration_interval(const ToxAV *av) { @@ -259,14 +261,14 @@ void toxav_iterate(ToxAV *av) ac_iterate(i->audio); vc_iterate(i->video); - if (i->msi_call->self_capabilities & msi_CapRAudio && - i->msi_call->peer_capabilities & msi_CapSAudio) { + if (i->msi_call->self_capabilities & MSI_CAP_R_AUDIO && + i->msi_call->peer_capabilities & MSI_CAP_S_AUDIO) { rc = min_s32(i->audio->lp_frame_duration, rc); } - if (i->msi_call->self_capabilities & msi_CapRVideo && - i->msi_call->peer_capabilities & msi_CapSVideo) { - rc = min_u32(i->video->lcfd, (uint32_t) rc); + if (i->msi_call->self_capabilities & MSI_CAP_R_VIDEO && + i->msi_call->peer_capabilities & MSI_CAP_S_VIDEO) { + rc = min_u32(i->video->lcfd, rc); } uint32_t fid = i->friend_number; @@ -293,9 +295,9 @@ void toxav_iterate(ToxAV *av) } } bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, - TOXAV_ERR_CALL *error) + Toxav_Err_Call *error) { - TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; + Toxav_Err_Call rc = TOXAV_ERR_CALL_OK; ToxAVCall *call; pthread_mutex_lock(av->mutex); @@ -303,32 +305,32 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))) { rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; - goto END; + goto RETURN; } call = call_new(av, friend_number, &rc); if (call == nullptr) { - goto END; + goto RETURN; } call->audio_bit_rate = audio_bit_rate; call->video_bit_rate = video_bit_rate; - call->previous_self_capabilities = msi_CapRAudio | msi_CapRVideo; + call->previous_self_capabilities = MSI_CAP_R_AUDIO | MSI_CAP_R_VIDEO; - call->previous_self_capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0; - call->previous_self_capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0; + call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0; + call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0; if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) { call_remove(call); rc = TOXAV_ERR_CALL_SYNC; - goto END; + goto RETURN; } call->msi_call->av_call = call; -END: +RETURN: pthread_mutex_unlock(av->mutex); if (error) { @@ -345,50 +347,50 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) pthread_mutex_unlock(av->mutex); } bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, - TOXAV_ERR_ANSWER *error) + Toxav_Err_Answer *error) { pthread_mutex_lock(av->mutex); - TOXAV_ERR_ANSWER rc = TOXAV_ERR_ANSWER_OK; + Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK; ToxAVCall *call; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) || (video_bit_rate && video_bit_rate_invalid(video_bit_rate)) ) { rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE; - goto END; + goto RETURN; } call = call_get(av, friend_number); if (call == nullptr) { rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; - goto END; + goto RETURN; } if (!call_prepare_transmission(call)) { rc = TOXAV_ERR_ANSWER_CODEC_INITIALIZATION; - goto END; + goto RETURN; } call->audio_bit_rate = audio_bit_rate; call->video_bit_rate = video_bit_rate; - call->previous_self_capabilities = msi_CapRAudio | msi_CapRVideo; + call->previous_self_capabilities = MSI_CAP_R_AUDIO | MSI_CAP_R_VIDEO; - call->previous_self_capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0; - call->previous_self_capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0; + call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0; + call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0; if (msi_answer(call->msi_call, call->previous_self_capabilities) != 0) { rc = TOXAV_ERR_ANSWER_SYNC; } -END: +RETURN: pthread_mutex_unlock(av->mutex); if (error) { @@ -404,22 +406,22 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u av->scb_user_data = user_data; pthread_mutex_unlock(av->mutex); } -bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) +bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control control, Toxav_Err_Call_Control *error) { pthread_mutex_lock(av->mutex); - TOXAV_ERR_CALL_CONTROL rc = TOXAV_ERR_CALL_CONTROL_OK; + Toxav_Err_Call_Control rc = TOXAV_ERR_CALL_CONTROL_OK; ToxAVCall *call; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } call = call_get(av, friend_number); if (call == nullptr || (!call->active && control != TOXAV_CALL_CONTROL_CANCEL)) { rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; - goto END; + goto RETURN; } switch (control) { @@ -431,14 +433,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co if (msi_change_capabilities(call->msi_call, call->previous_self_capabilities) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_allow_receiving(call->audio_rtp); rtp_allow_receiving(call->video_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; @@ -450,14 +452,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co if (msi_change_capabilities(call->msi_call, 0) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_stop_receiving(call->audio_rtp); rtp_stop_receiving(call->video_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; @@ -469,7 +471,7 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co if (msi_hangup(call->msi_call) != 0) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; pthread_mutex_unlock(call->mutex); - goto END; + goto RETURN; } call->msi_call = nullptr; @@ -482,71 +484,71 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co break; case TOXAV_CALL_CONTROL_MUTE_AUDIO: { - if (call->msi_call->self_capabilities & msi_CapRAudio) { + if (call->msi_call->self_capabilities & MSI_CAP_R_AUDIO) { if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities ^ msi_CapRAudio) == -1) { + msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_stop_receiving(call->audio_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; case TOXAV_CALL_CONTROL_UNMUTE_AUDIO: { - if (call->msi_call->self_capabilities ^ msi_CapRAudio) { + if (call->msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) { if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities | msi_CapRAudio) == -1) { + msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_allow_receiving(call->audio_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; case TOXAV_CALL_CONTROL_HIDE_VIDEO: { - if (call->msi_call->self_capabilities & msi_CapRVideo) { + if (call->msi_call->self_capabilities & MSI_CAP_R_VIDEO) { if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities ^ msi_CapRVideo) == -1) { + msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_stop_receiving(call->video_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; case TOXAV_CALL_CONTROL_SHOW_VIDEO: { - if (call->msi_call->self_capabilities ^ msi_CapRVideo) { + if (call->msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) { if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities | msi_CapRVideo) == -1) { + msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; - goto END; + goto RETURN; } rtp_allow_receiving(call->video_rtp); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; - goto END; + goto RETURN; } } break; } -END: +RETURN: pthread_mutex_unlock(av->mutex); if (error) { @@ -556,28 +558,28 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co return rc == TOXAV_ERR_CALL_CONTROL_OK; } bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, - TOXAV_ERR_BIT_RATE_SET *error) + Toxav_Err_Bit_Rate_Set *error) { - TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK; + Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; ToxAVCall *call; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if (audio_bit_rate > 0 && audio_bit_rate_invalid(audio_bit_rate)) { rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; - goto END; + goto RETURN; } pthread_mutex_lock(av->mutex); call = call_get(av, friend_number); - if (call == nullptr || !call->active || call->msi_call->state != msi_CallActive) { + if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; - goto END; + goto RETURN; } LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", audio_bit_rate); @@ -588,10 +590,10 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ LOGGER_DEBUG(av->m->log, "Turned off audio sending"); if (msi_change_capabilities(call->msi_call, call->msi_call-> - self_capabilities ^ msi_CapSAudio) != 0) { + self_capabilities ^ MSI_CAP_S_AUDIO) != 0) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; - goto END; + goto RETURN; } /* Audio sending is turned off; notify peer */ @@ -604,11 +606,11 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ /* The audio has been turned off before this */ if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities | msi_CapSAudio) != 0) { + msi_call->self_capabilities | MSI_CAP_S_AUDIO) != 0) { pthread_mutex_unlock(call->mutex); pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; - goto END; + goto RETURN; } } else { LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", audio_bit_rate); @@ -619,7 +621,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ } pthread_mutex_unlock(av->mutex); -END: +RETURN: if (error) { *error = rc; @@ -628,28 +630,28 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ return rc == TOXAV_ERR_BIT_RATE_SET_OK; } bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, - TOXAV_ERR_BIT_RATE_SET *error) + Toxav_Err_Bit_Rate_Set *error) { - TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK; + Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; ToxAVCall *call; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if (video_bit_rate > 0 && video_bit_rate_invalid(video_bit_rate)) { rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; - goto END; + goto RETURN; } pthread_mutex_lock(av->mutex); call = call_get(av, friend_number); - if (call == nullptr || !call->active || call->msi_call->state != msi_CallActive) { + if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; - goto END; + goto RETURN; } LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", video_bit_rate); @@ -661,10 +663,10 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ /* Video sending is turned off; notify peer */ if (msi_change_capabilities(call->msi_call, call->msi_call-> - self_capabilities ^ msi_CapSVideo) != 0) { + self_capabilities ^ MSI_CAP_S_VIDEO) != 0) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; - goto END; + goto RETURN; } call->video_bit_rate = 0; @@ -676,11 +678,11 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ /* The video has been turned off before this */ if (msi_change_capabilities(call->msi_call, call-> - msi_call->self_capabilities | msi_CapSVideo) != 0) { + msi_call->self_capabilities | MSI_CAP_S_VIDEO) != 0) { pthread_mutex_unlock(call->mutex); pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; - goto END; + goto RETURN; } } else { LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", video_bit_rate); @@ -691,7 +693,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ } pthread_mutex_unlock(av->mutex); -END: +RETURN: if (error) { *error = rc; @@ -714,35 +716,35 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, pthread_mutex_unlock(av->mutex); } bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, - uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME *error) + uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error) { - TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; + Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; ToxAVCall *call; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if (pthread_mutex_trylock(av->mutex) != 0) { rc = TOXAV_ERR_SEND_FRAME_SYNC; - goto END; + goto RETURN; } call = call_get(av, friend_number); - if (call == nullptr || !call->active || call->msi_call->state != msi_CallActive) { + if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; - goto END; + goto RETURN; } if (call->audio_bit_rate == 0 || - !(call->msi_call->self_capabilities & msi_CapSAudio) || - !(call->msi_call->peer_capabilities & msi_CapRAudio)) { + !(call->msi_call->self_capabilities & MSI_CAP_S_AUDIO) || + !(call->msi_call->peer_capabilities & MSI_CAP_R_AUDIO)) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; - goto END; + goto RETURN; } pthread_mutex_lock(call->mutex_audio); @@ -751,20 +753,20 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc if (pcm == nullptr) { pthread_mutex_unlock(call->mutex_audio); rc = TOXAV_ERR_SEND_FRAME_NULL; - goto END; + goto RETURN; } if (channels > 2) { pthread_mutex_unlock(call->mutex_audio); rc = TOXAV_ERR_SEND_FRAME_INVALID; - goto END; + goto RETURN; } { /* Encode and send */ if (ac_reconfigure_encoder(call->audio, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { pthread_mutex_unlock(call->mutex_audio); rc = TOXAV_ERR_SEND_FRAME_INVALID; - goto END; + goto RETURN; } VLA(uint8_t, dest, sample_count + sizeof(sampling_rate)); /* This is more than enough always */ @@ -778,7 +780,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc)); pthread_mutex_unlock(call->mutex_audio); rc = TOXAV_ERR_SEND_FRAME_INVALID; - goto END; + goto RETURN; } if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) { @@ -789,7 +791,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc pthread_mutex_unlock(call->mutex_audio); -END: +RETURN: if (error) { *error = rc; @@ -798,38 +800,76 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc return rc == TOXAV_ERR_SEND_FRAME_OK; } +static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call) +{ + vpx_codec_iter_t iter = nullptr; + + for (const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(call->video->encoder, &iter); + pkt != nullptr; + pkt = vpx_codec_get_cx_data(call->video->encoder, &iter)) { + if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) { + continue; + } + + const bool is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; + + // https://www.webmproject.org/docs/webm-sdk/structvpx__codec__cx__pkt.html + // pkt->data.frame.sz -> size_t + const uint32_t frame_length_in_bytes = pkt->data.frame.sz; + + const int res = rtp_send_data( + call->video_rtp, + (const uint8_t *)pkt->data.frame.buf, + frame_length_in_bytes, + is_keyframe, + log); + + LOGGER_DEBUG(log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".", + (int)pkt->data.frame.sz, (int)frame_length_in_bytes); + const uint8_t *const buf = (const uint8_t *)pkt->data.frame.buf; + LOGGER_DEBUG(log, "+ _sending_FRAME_ b0=%d b1=%d", buf[0], buf[1]); + + if (res < 0) { + LOGGER_WARNING(log, "Could not send video frame: %s", strerror(errno)); + return TOXAV_ERR_SEND_FRAME_RTP_FAILED; + } + } + + return TOXAV_ERR_SEND_FRAME_OK; +} + bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, - const uint8_t *u, const uint8_t *v, TOXAV_ERR_SEND_FRAME *error) + const uint8_t *u, const uint8_t *v, Toxav_Err_Send_Frame *error) { - TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; + Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; ToxAVCall *call; int vpx_encode_flags = 0; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if (pthread_mutex_trylock(av->mutex) != 0) { rc = TOXAV_ERR_SEND_FRAME_SYNC; - goto END; + goto RETURN; } call = call_get(av, friend_number); - if (call == nullptr || !call->active || call->msi_call->state != msi_CallActive) { + if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; - goto END; + goto RETURN; } if (call->video_bit_rate == 0 || - !(call->msi_call->self_capabilities & msi_CapSVideo) || - !(call->msi_call->peer_capabilities & msi_CapRVideo)) { + !(call->msi_call->self_capabilities & MSI_CAP_S_VIDEO) || + !(call->msi_call->peer_capabilities & MSI_CAP_R_VIDEO)) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; - goto END; + goto RETURN; } pthread_mutex_lock(call->mutex_video); @@ -838,13 +878,13 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u if (y == nullptr || u == nullptr || v == nullptr) { pthread_mutex_unlock(call->mutex_video); rc = TOXAV_ERR_SEND_FRAME_NULL; - goto END; + goto RETURN; } if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) { pthread_mutex_unlock(call->mutex_video); rc = TOXAV_ERR_SEND_FRAME_INVALID; - goto END; + goto RETURN; } if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) { @@ -852,20 +892,23 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u vpx_encode_flags = VPX_EFLAG_FORCE_KF; LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc); - call->video_rtp->ssrc++; + ++call->video_rtp->ssrc; } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) { // normal keyframe placement vpx_encode_flags = 0; LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc); - call->video_rtp->ssrc++; + ++call->video_rtp->ssrc; } // we start with I-frames (full frames) and then switch to normal mode later { /* Encode */ vpx_image_t img; - img.w = img.h = img.d_w = img.d_h = 0; + img.w = 0; + img.h = 0; + img.d_w = 0; + img.d_h = 0; vpx_img_alloc(&img, VPX_IMG_FMT_I420, width, height, 0); /* I420 "It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes." @@ -884,49 +927,17 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u pthread_mutex_unlock(call->mutex_video); LOGGER_ERROR(av->m->log, "Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc)); rc = TOXAV_ERR_SEND_FRAME_INVALID; - goto END; + goto RETURN; } } ++call->video->frame_counter; - { /* Send frames */ - vpx_codec_iter_t iter = nullptr; - const vpx_codec_cx_pkt_t *pkt; - - while ((pkt = vpx_codec_get_cx_data(call->video->encoder, &iter)) != nullptr) { - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const bool is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - - // https://www.webmproject.org/docs/webm-sdk/structvpx__codec__cx__pkt.html - // pkt->data.frame.sz -> size_t - const uint32_t frame_length_in_bytes = pkt->data.frame.sz; - - const int res = rtp_send_data( - call->video_rtp, - (const uint8_t *)pkt->data.frame.buf, - frame_length_in_bytes, - is_keyframe, - av->m->log); - - LOGGER_DEBUG(av->m->log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".", - (int)pkt->data.frame.sz, (int)frame_length_in_bytes); - LOGGER_DEBUG(av->m->log, "+ _sending_FRAME_ b0=%d b1=%d", ((const uint8_t *)pkt->data.frame.buf)[0], - ((const uint8_t *)pkt->data.frame.buf)[1]); - - if (res < 0) { - pthread_mutex_unlock(call->mutex_video); - LOGGER_WARNING(av->m->log, "Could not send video frame: %s", strerror(errno)); - rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; - goto END; - } - } - } - } + rc = send_frames(av->m->log, call); pthread_mutex_unlock(call->mutex_video); -END: +RETURN: if (error) { *error = rc; @@ -984,9 +995,9 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u return; } - (*call->av->vbcb)(call->av, friend_number, - call->video_bit_rate - (call->video_bit_rate * loss), - call->av->vbcb_user_data); + call->av->vbcb(call->av, friend_number, + call->video_bit_rate - (call->video_bit_rate * loss), + call->av->vbcb_user_data); } else if (call->audio_bit_rate) { if (!call->av->abcb) { pthread_mutex_unlock(call->av->mutex); @@ -994,9 +1005,9 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u return; } - (*call->av->abcb)(call->av, friend_number, - call->audio_bit_rate - (call->audio_bit_rate * loss), - call->av->abcb_user_data); + call->av->abcb(call->av, friend_number, + call->audio_bit_rate - (call->audio_bit_rate * loss), + call->av->abcb_user_data); } pthread_mutex_unlock(call->av->mutex); @@ -1018,8 +1029,8 @@ int callback_invite(void *toxav_inst, MSICall *call) av_call->msi_call = call; if (toxav->ccb) { - toxav->ccb(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, - call->peer_capabilities & msi_CapSVideo, toxav->ccb_user_data); + toxav->ccb(toxav, call->friend_number, call->peer_capabilities & MSI_CAP_S_AUDIO, + call->peer_capabilities & MSI_CAP_S_VIDEO, toxav->ccb_user_data); } else { /* No handler to capture the call request, send failure */ pthread_mutex_unlock(toxav->mutex); @@ -1065,8 +1076,8 @@ int callback_end(void *toxav_inst, MSICall *call) invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED); if (call->av_call) { - call_kill_transmission((ToxAVCall *)call->av_call); - call_remove((ToxAVCall *)call->av_call); + call_kill_transmission(call->av_call); + call_remove(call->av_call); } pthread_mutex_unlock(toxav->mutex); @@ -1080,8 +1091,8 @@ int callback_error(void *toxav_inst, MSICall *call) invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR); if (call->av_call) { - call_kill_transmission((ToxAVCall *)call->av_call); - call_remove((ToxAVCall *)call->av_call); + call_kill_transmission(call->av_call); + call_remove(call->av_call); } pthread_mutex_unlock(toxav->mutex); @@ -1092,16 +1103,16 @@ int callback_capabilites(void *toxav_inst, MSICall *call) ToxAV *toxav = (ToxAV *)toxav_inst; pthread_mutex_lock(toxav->mutex); - if (call->peer_capabilities & msi_CapSAudio) { - rtp_allow_receiving(((ToxAVCall *)call->av_call)->audio_rtp); + if (call->peer_capabilities & MSI_CAP_S_AUDIO) { + rtp_allow_receiving(call->av_call->audio_rtp); } else { - rtp_stop_receiving(((ToxAVCall *)call->av_call)->audio_rtp); + rtp_stop_receiving(call->av_call->audio_rtp); } - if (call->peer_capabilities & msi_CapSVideo) { - rtp_allow_receiving(((ToxAVCall *)call->av_call)->video_rtp); + if (call->peer_capabilities & MSI_CAP_S_VIDEO) { + rtp_allow_receiving(call->av_call->video_rtp); } else { - rtp_stop_receiving(((ToxAVCall *)call->av_call)->video_rtp); + rtp_stop_receiving(call->av_call->video_rtp); } invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities); @@ -1138,32 +1149,32 @@ bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t stat return true; } -ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) +ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error) { /* Assumes mutex locked */ - TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; + Toxav_Err_Call rc = TOXAV_ERR_CALL_OK; ToxAVCall *call = nullptr; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND; - goto END; + goto RETURN; } if (m_get_friend_connectionstatus(av->m, friend_number) < 1) { rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED; - goto END; + goto RETURN; } if (call_get(av, friend_number) != nullptr) { rc = TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL; - goto END; + goto RETURN; } call = (ToxAVCall *)calloc(sizeof(ToxAVCall), 1); if (call == nullptr) { rc = TOXAV_ERR_CALL_MALLOC; - goto END; + goto RETURN; } call->av = av; @@ -1176,10 +1187,11 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) free(call); call = nullptr; rc = TOXAV_ERR_CALL_MALLOC; - goto END; + goto RETURN; } - av->calls_tail = av->calls_head = friend_number; + av->calls_tail = friend_number; + av->calls_head = friend_number; } else if (av->calls_tail < friend_number) { /* Appending */ ToxAVCall **tmp = (ToxAVCall **)realloc(av->calls, sizeof(ToxAVCall *) * (friend_number + 1)); @@ -1187,15 +1199,13 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) free(call); call = nullptr; rc = TOXAV_ERR_CALL_MALLOC; - goto END; + goto RETURN; } av->calls = tmp; /* Set fields in between to null */ - uint32_t i = av->calls_tail + 1; - - for (; i < friend_number; i ++) { + for (uint32_t i = av->calls_tail + 1; i < friend_number; ++i) { av->calls[i] = nullptr; } @@ -1211,7 +1221,7 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) av->calls[friend_number] = call; -END: +RETURN: if (error) { *error = rc; @@ -1271,7 +1281,8 @@ ToxAVCall *call_remove(ToxAVCall *call) return next; CLEAR: - av->calls_head = av->calls_tail = 0; + av->calls_head = 0; + av->calls_tail = 0; free(av->calls); av->calls = nullptr; @@ -1321,11 +1332,11 @@ bool call_prepare_transmission(ToxAVCall *call) goto FAILURE; } - call->audio_rtp = rtp_new(rtp_TypeAudio, av->m, call->friend_number, call->bwc, + call->audio_rtp = rtp_new(RTP_TYPE_AUDIO, av->m, call->friend_number, call->bwc, call->audio, ac_queue_message); if (!call->audio_rtp) { - LOGGER_ERROR(av->m->log, "Failed to create audio rtp session");; + LOGGER_ERROR(av->m->log, "Failed to create audio rtp session"); goto FAILURE; } } @@ -1337,7 +1348,7 @@ bool call_prepare_transmission(ToxAVCall *call) goto FAILURE; } - call->video_rtp = rtp_new(rtp_TypeVideo, av->m, call->friend_number, call->bwc, + call->video_rtp = rtp_new(RTP_TYPE_VIDEO, av->m, call->friend_number, call->bwc, call->video, vc_queue_message); if (!call->video_rtp) { @@ -1353,11 +1364,11 @@ bool call_prepare_transmission(ToxAVCall *call) bwc_kill(call->bwc); rtp_kill(call->audio_rtp); ac_kill(call->audio); - call->audio_rtp = nullptr; + call->audio = nullptr; call->audio = nullptr; rtp_kill(call->video_rtp); vc_kill(call->video); - call->video_rtp = nullptr; + call->video = nullptr; call->video = nullptr; pthread_mutex_destroy(call->mutex); FAILURE_2: @@ -1391,7 +1402,7 @@ void call_kill_transmission(ToxAVCall *call) rtp_kill(call->video_rtp); vc_kill(call->video); - call->video_rtp = nullptr; + call->video = nullptr; call->video = nullptr; pthread_mutex_destroy(call->mutex_audio); diff --git a/toxav/toxav.h b/toxav/toxav.h index 911d6b499c..8260106ada 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -744,9 +744,9 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb * * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). */ -int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, - uint8_t, - uint32_t, void *), void *userdata); +int toxav_add_av_groupchat(Tox *tox, + void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), + void *userdata); /* Join a AV group (you need to have been invited first.) * @@ -781,4 +781,16 @@ int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, u #ifdef __cplusplus } #endif + +typedef void toxav_group_audio_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, + uint32_t samples, uint8_t channels, uint32_t sample_rate, void *user_data); + +typedef TOXAV_ERR_CALL Toxav_Err_Call; +typedef TOXAV_ERR_NEW Toxav_Err_New; +typedef TOXAV_ERR_ANSWER Toxav_Err_Answer; +typedef TOXAV_ERR_CALL_CONTROL Toxav_Err_Call_Control; +typedef TOXAV_ERR_BIT_RATE_SET Toxav_Err_Bit_Rate_Set; +typedef TOXAV_ERR_SEND_FRAME Toxav_Err_Send_Frame; +typedef TOXAV_CALL_CONTROL Toxav_Call_Control; + #endif /* TOXAV_H */ diff --git a/toxav/toxav_old.c b/toxav/toxav_old.c index d527862381..2ea9def438 100644 --- a/toxav/toxav_old.c +++ b/toxav/toxav_old.c @@ -35,13 +35,11 @@ * * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). */ -int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, - uint8_t, uint32_t, void *), void *userdata) +int toxav_add_av_groupchat(Tox *tox, audio_data_cb *audio_callback, void *userdata) { - Messenger *m = (Messenger *)tox; - return add_av_groupchat(m->log, (Group_Chats *)m->conferences_object, - (void (*)(Messenger *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *))audio_callback, - userdata); + // TODO(iphydf): Don't rely on toxcore internals. + Messenger *m = *(Messenger **)tox; + return add_av_groupchat(m->log, tox, m->conferences_object, audio_callback, userdata); } /* Join a AV group (you need to have been invited first.) @@ -55,14 +53,11 @@ int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, ui * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). */ int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data, uint16_t length, - void (*audio_callback) - (void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), - void *userdata) + audio_data_cb *audio_callback, void *userdata) { - Messenger *m = (Messenger *)tox; - return join_av_groupchat(m->log, (Group_Chats *)m->conferences_object, friendnumber, data, length, - (void (*)(Messenger *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *))audio_callback, - userdata); + // TODO(iphydf): Don't rely on toxcore internals. + Messenger *m = *(Messenger **)tox; + return join_av_groupchat(m->log, tox, m->conferences_object, friendnumber, data, length, audio_callback, userdata); } /* Send audio to the group chat. @@ -81,6 +76,7 @@ int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, uint32_t sample_rate) { - Messenger *m = (Messenger *)tox; - return group_send_audio((Group_Chats *)m->conferences_object, groupnumber, pcm, samples, channels, sample_rate); + // TODO(iphydf): Don't rely on toxcore internals. + Messenger *m = *(Messenger **)tox; + return group_send_audio(m->conferences_object, groupnumber, pcm, samples, channels, sample_rate); } diff --git a/toxav/video.c b/toxav/video.c index 034a8b56b9..41c2465cf4 100644 --- a/toxav/video.c +++ b/toxav/video.c @@ -72,8 +72,14 @@ #define VIDEO_BITRATE_INITIAL_VALUE 5000 #define VIDEO_DECODE_BUFFER_SIZE 5 // this buffer has normally max. 1 entry -#define VIDEO_CODEC_DECODER_INTERFACE (vpx_codec_vp8_dx()) -#define VIDEO_CODEC_ENCODER_INTERFACE (vpx_codec_vp8_cx()) +static const vpx_codec_iface_t *video_codec_decoder_interface(void) +{ + return vpx_codec_vp8_dx(); +} +static const vpx_codec_iface_t *video_codec_encoder_interface(void) +{ + return vpx_codec_vp8_cx(); +} #define VIDEO_CODEC_DECODER_MAX_WIDTH 800 // its a dummy value, because the struct needs a value there #define VIDEO_CODEC_DECODER_MAX_HEIGHT 600 // its a dummy value, because the struct needs a value there @@ -86,7 +92,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int16_t kf_max_dist) { - vpx_codec_err_t rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, cfg, 0); + vpx_codec_err_t rc = vpx_codec_enc_config_default(video_codec_encoder_interface(), cfg, 0); if (rc != VPX_CODEC_OK) { LOGGER_ERROR(log, "vc_init_encoder_cfg:Failed to get config: %s", vpx_codec_err_to_string(rc)); @@ -171,7 +177,9 @@ VCSession *vc_new(const Logger *log, ToxAV *av, uint32_t friend_number, toxav_vi int cpu_used_value = VP8E_SET_CPUUSED_VALUE; - if (!(vc->vbuf_raw = rb_new(VIDEO_DECODE_BUFFER_SIZE))) { + vc->vbuf_raw = rb_new(VIDEO_DECODE_BUFFER_SIZE); + + if (!vc->vbuf_raw) { goto BASE_CLEANUP; } @@ -188,12 +196,12 @@ VCSession *vc_new(const Logger *log, ToxAV *av, uint32_t friend_number, toxav_vi dec_cfg.h = VIDEO_CODEC_DECODER_MAX_HEIGHT; LOGGER_DEBUG(log, "Using VP8 codec for decoder (0)"); - rc = vpx_codec_dec_init(vc->decoder, VIDEO_CODEC_DECODER_INTERFACE, &dec_cfg, + rc = vpx_codec_dec_init(vc->decoder, video_codec_decoder_interface(), &dec_cfg, VPX_CODEC_USE_FRAME_THREADING | VPX_CODEC_USE_POSTPROC); if (rc == VPX_CODEC_INCAPABLE) { LOGGER_WARNING(log, "Postproc not supported by this decoder (0)"); - rc = vpx_codec_dec_init(vc->decoder, VIDEO_CODEC_DECODER_INTERFACE, &dec_cfg, VPX_CODEC_USE_FRAME_THREADING); + rc = vpx_codec_dec_init(vc->decoder, video_codec_decoder_interface(), &dec_cfg, VPX_CODEC_USE_FRAME_THREADING); } if (rc != VPX_CODEC_OK) { @@ -227,7 +235,7 @@ VCSession *vc_new(const Logger *log, ToxAV *av, uint32_t friend_number, toxav_vi vc_init_encoder_cfg(log, &cfg, 1); LOGGER_DEBUG(log, "Using VP8 codec for encoder (0.1)"); - rc = vpx_codec_enc_init(vc->encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, VPX_CODEC_USE_FRAME_THREADING); + rc = vpx_codec_enc_init(vc->encoder, video_codec_encoder_interface(), &cfg, VPX_CODEC_USE_FRAME_THREADING); if (rc != VPX_CODEC_OK) { LOGGER_ERROR(log, "Failed to initialize encoder: %s", vpx_codec_err_to_string(rc)); @@ -334,9 +342,10 @@ void vc_iterate(VCSession *vc) /* Play decoded images */ vpx_codec_iter_t iter = nullptr; - vpx_image_t *dest = nullptr; - while ((dest = vpx_codec_get_frame(vc->decoder, &iter)) != nullptr) { + for (vpx_image_t *dest = vpx_codec_get_frame(vc->decoder, &iter); + dest != nullptr; + dest = vpx_codec_get_frame(vc->decoder, &iter)) { if (vc->vcb) { vc->vcb(vc->av, vc->friend_number, dest->d_w, dest->d_h, (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2], @@ -360,13 +369,13 @@ int vc_queue_message(void *vcp, struct RTPMessage *msg) VCSession *vc = (VCSession *)vcp; const struct RTPHeader *const header = &msg->header; - if (msg->header.pt == (rtp_TypeVideo + 2) % 128) { + if (msg->header.pt == (RTP_TYPE_VIDEO + 2) % 128) { LOGGER_WARNING(vc->log, "Got dummy!"); free(msg); return 0; } - if (msg->header.pt != rtp_TypeVideo % 128) { + if (msg->header.pt != RTP_TYPE_VIDEO % 128) { LOGGER_WARNING(vc->log, "Invalid payload type! pt=%d", (int)msg->header.pt); free(msg); return -1; @@ -374,7 +383,7 @@ int vc_queue_message(void *vcp, struct RTPMessage *msg) pthread_mutex_lock(vc->queue_mutex); - if ((header->flags & RTP_LARGE_FRAME) && header->pt == rtp_TypeVideo % 128) { + if ((header->flags & RTP_LARGE_FRAME) && header->pt == RTP_TYPE_VIDEO % 128) { LOGGER_DEBUG(vc->log, "rb_write msg->len=%d b0=%d b1=%d", (int)msg->len, (int)msg->data[0], (int)msg->data[1]); } @@ -424,7 +433,7 @@ int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uin cfg.g_h = height; LOGGER_DEBUG(vc->log, "Using VP8 codec for encoder"); - rc = vpx_codec_enc_init(&new_c, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, VPX_CODEC_USE_FRAME_THREADING); + rc = vpx_codec_enc_init(&new_c, video_codec_encoder_interface(), &cfg, VPX_CODEC_USE_FRAME_THREADING); if (rc != VPX_CODEC_OK) { LOGGER_ERROR(vc->log, "Failed to initialize encoder: %s", vpx_codec_err_to_string(rc)); diff --git a/toxav/video.h b/toxav/video.h index 19ceb9ba5d..f88a59021b 100644 --- a/toxav/video.h +++ b/toxav/video.h @@ -24,6 +24,7 @@ #include "../toxcore/logger.h" #include "../toxcore/util.h" +#include "rtp.h" #include #include @@ -35,9 +36,6 @@ #include -struct RTPMessage; -struct RingBuffer; - typedef struct VCSession_s { /* encoding */ vpx_codec_ctx_t encoder[1]; diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 8cab9801a0..6fc4df024c 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -272,7 +272,7 @@ struct Messenger { m_friend_connectionstatuschange_internal_cb *friend_connectionstatuschange_internal; void *friend_connectionstatuschange_internal_userdata; - void *conferences_object; /* Set by new_groupchats()*/ + struct Group_Chats *conferences_object; /* Set by new_groupchats()*/ m_conference_invite_cb *conference_invite; m_file_recv_cb *file_sendrequest; diff --git a/toxcore/group.c b/toxcore/group.c index b42c6b24b5..2279d45957 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -1444,7 +1444,7 @@ int group_title_get(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *title static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *userdata) { - Group_Chats *g_c = (Group_Chats *)m->conferences_object; + Group_Chats *g_c = m->conferences_object; if (length <= 1) { return; diff --git a/toxcore/tox.c b/toxcore/tox.c index f7bdba79dd..615f76ca67 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -487,11 +487,11 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) callback_file_reqchunk(m, tox_file_chunk_request_handler); callback_file_sendrequest(m, tox_file_recv_handler); callback_file_data(m, tox_file_recv_chunk_handler); - g_callback_group_invite((Group_Chats *)m->conferences_object, tox_conference_invite_handler); - g_callback_group_message((Group_Chats *)m->conferences_object, tox_conference_message_handler); - g_callback_group_title((Group_Chats *)m->conferences_object, tox_conference_title_handler); - g_callback_peer_name((Group_Chats *)m->conferences_object, tox_conference_peer_name_handler); - g_callback_peer_list_changed((Group_Chats *)m->conferences_object, tox_conference_peer_list_changed_handler); + g_callback_group_invite(m->conferences_object, tox_conference_invite_handler); + g_callback_group_message(m->conferences_object, tox_conference_message_handler); + g_callback_group_title(m->conferences_object, tox_conference_title_handler); + g_callback_peer_name(m->conferences_object, tox_conference_peer_name_handler); + g_callback_peer_list_changed(m->conferences_object, tox_conference_peer_list_changed_handler); custom_lossy_packet_registerhandler(m, tox_friend_lossy_packet_handler); custom_lossless_packet_registerhandler(m, tox_friend_lossless_packet_handler); @@ -506,7 +506,7 @@ void tox_kill(Tox *tox) } Messenger *m = tox->m; - kill_groupchats((Group_Chats *)m->conferences_object); + kill_groupchats(m->conferences_object); kill_messenger(m); free(tox); } @@ -645,7 +645,7 @@ void tox_iterate(Tox *tox, void *user_data) Messenger *m = tox->m; struct Tox_Userdata tox_data = { tox, user_data }; do_messenger(m, &tox_data); - do_groupchats((Group_Chats *)m->conferences_object, &tox_data); + do_groupchats(m->conferences_object, &tox_data); } void tox_self_get_address(const Tox *tox, uint8_t *address) @@ -697,7 +697,7 @@ bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set if (setname(m, name, length) == 0) { // TODO(irungentoo): function to set different per group names? - send_name_all_groups((Group_Chats *)m->conferences_object); + send_name_all_groups(m->conferences_object); SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_OK); return 1; } @@ -1409,7 +1409,7 @@ void tox_callback_conference_peer_list_changed(Tox *tox, tox_conference_peer_lis uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) { Messenger *m = tox->m; - int ret = add_groupchat((Group_Chats *)m->conferences_object, GROUPCHAT_TYPE_TEXT); + int ret = add_groupchat(m->conferences_object, GROUPCHAT_TYPE_TEXT); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_NEW_INIT); @@ -1423,7 +1423,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error) { Messenger *m = tox->m; - int ret = del_groupchat((Group_Chats *)m->conferences_object, conference_number); + int ret = del_groupchat(m->conferences_object, conference_number); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND); @@ -1437,7 +1437,7 @@ bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Confere uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox->m; - int ret = group_number_peers((Group_Chats *)m->conferences_object, conference_number); + int ret = group_number_peers(m->conferences_object, conference_number); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND); @@ -1452,7 +1452,7 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox->m; - int ret = group_peername_size((Group_Chats *)m->conferences_object, conference_number, peer_number); + int ret = group_peername_size(m->conferences_object, conference_number, peer_number); switch (ret) { case -1: @@ -1472,7 +1472,7 @@ bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, ui Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox->m; - int ret = group_peername((Group_Chats *)m->conferences_object, conference_number, peer_number, name); + int ret = group_peername(m->conferences_object, conference_number, peer_number, name); switch (ret) { case -1: @@ -1492,7 +1492,7 @@ bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_numb uint8_t *public_key, Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox->m; - int ret = group_peer_pubkey((Group_Chats *)m->conferences_object, conference_number, peer_number, public_key); + int ret = group_peer_pubkey(m->conferences_object, conference_number, peer_number, public_key); switch (ret) { case -1: @@ -1512,7 +1512,7 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb Tox_Err_Conference_Peer_Query *error) { const Messenger *m = tox->m; - int ret = group_peernumber_is_ours((Group_Chats *)m->conferences_object, conference_number, peer_number); + int ret = group_peernumber_is_ours(m->conferences_object, conference_number, peer_number); switch (ret) { case -1: @@ -1536,7 +1536,7 @@ bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference Tox_Err_Conference_Invite *error) { Messenger *m = tox->m; - int ret = invite_friend((Group_Chats *)m->conferences_object, friend_number, conference_number); + int ret = invite_friend(m->conferences_object, friend_number, conference_number); switch (ret) { case -1: @@ -1560,7 +1560,7 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co Tox_Err_Conference_Join *error) { Messenger *m = tox->m; - int ret = join_groupchat((Group_Chats *)m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); + int ret = join_groupchat(m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); switch (ret) { case -1: @@ -1599,9 +1599,9 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Messa int ret = 0; if (type == TOX_MESSAGE_TYPE_NORMAL) { - ret = group_message_send((Group_Chats *)m->conferences_object, conference_number, message, length); + ret = group_message_send(m->conferences_object, conference_number, message, length); } else { - ret = group_action_send((Group_Chats *)m->conferences_object, conference_number, message, length); + ret = group_action_send(m->conferences_object, conference_number, message, length); } switch (ret) { @@ -1629,7 +1629,7 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Messa size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Title *error) { const Messenger *m = tox->m; - int ret = group_title_get_size((Group_Chats *)m->conferences_object, conference_number); + int ret = group_title_get_size(m->conferences_object, conference_number); switch (ret) { case -1: @@ -1649,7 +1649,7 @@ bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_ Tox_Err_Conference_Title *error) { const Messenger *m = tox->m; - int ret = group_title_get((Group_Chats *)m->conferences_object, conference_number, title); + int ret = group_title_get(m->conferences_object, conference_number, title); switch (ret) { case -1: @@ -1669,7 +1669,7 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_ Tox_Err_Conference_Title *error) { Messenger *m = tox->m; - int ret = group_title_send((Group_Chats *)m->conferences_object, conference_number, title, length); + int ret = group_title_send(m->conferences_object, conference_number, title, length); switch (ret) { case -1: @@ -1692,21 +1692,21 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_ size_t tox_conference_get_chatlist_size(const Tox *tox) { const Messenger *m = tox->m; - return count_chatlist((Group_Chats *)m->conferences_object); + return count_chatlist(m->conferences_object); } void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist) { const Messenger *m = tox->m; size_t list_size = tox_conference_get_chatlist_size(tox); - copy_chatlist((Group_Chats *)m->conferences_object, chatlist, list_size); + copy_chatlist(m->conferences_object, chatlist, list_size); } Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Get_Type *error) { const Messenger *m = tox->m; - int ret = group_get_type((Group_Chats *)m->conferences_object, conference_number); + int ret = group_get_type(m->conferences_object, conference_number); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND); @@ -1719,7 +1719,7 @@ Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_ bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id /* TOX_CONFERENCE_ID_SIZE bytes */) { - return conference_get_id((Group_Chats *)tox->m->conferences_object, conference_number, id); + return conference_get_id(tox->m->conferences_object, conference_number, id); } // TODO(iphydf): Delete in 0.3.0. @@ -1735,7 +1735,7 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Confere return UINT32_MAX; } - int32_t ret = conference_by_id((Group_Chats *)tox->m->conferences_object, id); + int32_t ret = conference_by_id(tox->m->conferences_object, id); if (ret == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND);