mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Removed extra msi header and started testing
This commit is contained in:
parent
6e259d5fcb
commit
efe31ec92f
|
@ -44,9 +44,7 @@
|
|||
#define MAX_ENCODE_TIME_US VPX_DL_GOOD_QUALITY
|
||||
#define MAX_DECODE_TIME_US 0
|
||||
|
||||
// TODO this has to be exchanged in msi
|
||||
#define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */
|
||||
#define VIDEOFRAME_PIECE_SIZE 0x500 /* 1.25 KiB*/
|
||||
#define VIDEOFRAME_HEADER_SIZE 0x2
|
||||
|
||||
/* FIXME: Might not be enough */
|
||||
|
@ -296,7 +294,7 @@ void cs_do(CSSession *cs)
|
|||
LOGGER_WARNING("Decoding error: %s", opus_strerror(rc));
|
||||
} else if (cs->acb.first) {
|
||||
/* Play */
|
||||
cs->acb.first(cs->agent, cs->friend_number, tmp, rc,
|
||||
cs->acb.first(cs->agent, cs->friend_id, tmp, rc,
|
||||
cs->last_pack_channels, cs->last_packet_sampling_rate, cs->acb.second);
|
||||
}
|
||||
|
||||
|
@ -323,7 +321,7 @@ void cs_do(CSSession *cs)
|
|||
/* Play decoded images */
|
||||
for (; dest; dest = vpx_codec_get_frame(cs->v_decoder, &iter)) {
|
||||
if (cs->vcb.first)
|
||||
cs->vcb.first(cs->agent, cs->call_idx, dest->d_w, dest->d_h,
|
||||
cs->vcb.first(cs->agent, cs->friend_id, dest->d_w, dest->d_h,
|
||||
(const uint8_t**)dest->planes, dest->stride, cs->vcb.second);
|
||||
|
||||
vpx_img_free(dest);
|
||||
|
@ -336,7 +334,7 @@ void cs_do(CSSession *cs)
|
|||
pthread_mutex_unlock(cs->queue_mutex);
|
||||
}
|
||||
|
||||
CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, uint32_t p_video_b)
|
||||
CSSession *cs_new(uint32_t peer_video_frame_piece_size)
|
||||
{
|
||||
CSSession *cs = calloc(sizeof(CSSession), 1);
|
||||
|
||||
|
@ -345,29 +343,7 @@ CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, ui
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO this has to be exchanged in msi */
|
||||
cs->max_video_frame_size = MAX_VIDEOFRAME_SIZE;
|
||||
cs->video_frame_piece_size = VIDEOFRAME_PIECE_SIZE;
|
||||
|
||||
if (s_audio_b > 0 && 0 != cs_enable_audio_sending(cs, s_audio_b, 2)) { /* Sending audio enabled */
|
||||
LOGGER_WARNING("Failed to enable audio sending!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if (p_audio_b > 0 && 0 != cs_enable_audio_receiving(cs)) { /* Receiving audio enabled */
|
||||
LOGGER_WARNING("Failed to enable audio receiving!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if (s_video_b > 0 && 0 != cs_enable_video_sending(cs, s_video_b)) { /* Sending video enabled */
|
||||
LOGGER_WARNING("Failed to enable video sending!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if (p_video_b > 0 && 0 != cs_enable_video_receiving(cs)) { /* Receiving video enabled */
|
||||
LOGGER_WARNING("Failed to enable video receiving!");
|
||||
goto FAILURE;
|
||||
}
|
||||
cs->peer_video_frame_piece_size = peer_video_frame_piece_size;
|
||||
|
||||
return cs;
|
||||
|
||||
|
@ -415,22 +391,22 @@ int cs_update_video_splitter_cycle(CSSession *cs, const uint8_t *payload, uint16
|
|||
cs->processing_video_frame = payload;
|
||||
cs->processing_video_frame_size = length;
|
||||
|
||||
return ((length - 1) / cs->video_frame_piece_size) + 1;
|
||||
return ((length - 1) / VIDEOFRAME_PIECE_SIZE) + 1;
|
||||
}
|
||||
|
||||
const uint8_t *cs_iterate_split_video_frame(CSSession *cs, uint16_t *size)
|
||||
{
|
||||
if (!cs || !size) return NULL;
|
||||
|
||||
if (cs->processing_video_frame_size > cs->video_frame_piece_size) {
|
||||
if (cs->processing_video_frame_size > VIDEOFRAME_PIECE_SIZE) {
|
||||
memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE,
|
||||
cs->processing_video_frame,
|
||||
cs->video_frame_piece_size);
|
||||
VIDEOFRAME_PIECE_SIZE);
|
||||
|
||||
cs->processing_video_frame += cs->video_frame_piece_size;
|
||||
cs->processing_video_frame_size -= cs->video_frame_piece_size;
|
||||
cs->processing_video_frame += VIDEOFRAME_PIECE_SIZE;
|
||||
cs->processing_video_frame_size -= VIDEOFRAME_PIECE_SIZE;
|
||||
|
||||
*size = cs->video_frame_piece_size + VIDEOFRAME_HEADER_SIZE;
|
||||
*size = VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE;
|
||||
} else {
|
||||
memcpy(cs->split_video_frame + VIDEOFRAME_HEADER_SIZE,
|
||||
cs->processing_video_frame,
|
||||
|
@ -492,7 +468,7 @@ int cs_set_sending_video_bitrate(CSSession *cs, uint32_t bitrate)
|
|||
if (cfg.rc_target_bitrate == bitrate)
|
||||
return 0;
|
||||
|
||||
LOGGER_DEBUG("New video bitrate: %u", video_bitrate);
|
||||
LOGGER_DEBUG("New video bitrate: %u", bitrate);
|
||||
cfg.rc_target_bitrate = bitrate;
|
||||
|
||||
int rc = vpx_codec_enc_config_set(cs->v_encoder, &cfg);
|
||||
|
@ -528,7 +504,7 @@ int cs_enable_video_sending(CSSession* cs, uint32_t bitrate)
|
|||
/* So that we can use cs_disable_video_sending to clean up */
|
||||
cs->v_encoding = true;
|
||||
|
||||
if ( !(cs->split_video_frame = calloc(cs->video_frame_piece_size + VIDEOFRAME_HEADER_SIZE, 1)) )
|
||||
if ( !(cs->split_video_frame = calloc(VIDEOFRAME_PIECE_SIZE + VIDEOFRAME_HEADER_SIZE, 1)) )
|
||||
goto FAILURE;
|
||||
|
||||
cfg.rc_target_bitrate = bitrate;
|
||||
|
@ -579,7 +555,7 @@ int cs_enable_video_receiving(CSSession* cs)
|
|||
/* So that we can use cs_disable_video_sending to clean up */
|
||||
cs->v_decoding = true;
|
||||
|
||||
if ( !(cs->frame_buf = calloc(cs->max_video_frame_size, 1)) )
|
||||
if ( !(cs->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1)) )
|
||||
goto FAILURE;
|
||||
|
||||
if ( !(cs->vbuf_raw = buffer_new(VIDEO_DECODE_BUFFER_SIZE)) )
|
||||
|
@ -837,10 +813,10 @@ void queue_message(RTPSession *session, RTPMessage *msg)
|
|||
|
||||
uint8_t piece_number = packet[1];
|
||||
|
||||
uint32_t length_before_piece = ((piece_number - 1) * cs->video_frame_piece_size);
|
||||
uint32_t length_before_piece = ((piece_number - 1) * cs->peer_video_frame_piece_size);
|
||||
uint32_t framebuf_new_length = length_before_piece + (packet_size - VIDEOFRAME_HEADER_SIZE);
|
||||
|
||||
if (framebuf_new_length > cs->max_video_frame_size) {
|
||||
if (framebuf_new_length > MAX_VIDEOFRAME_SIZE) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -851,9 +827,8 @@ void queue_message(RTPSession *session, RTPMessage *msg)
|
|||
packet + VIDEOFRAME_HEADER_SIZE,
|
||||
packet_size - VIDEOFRAME_HEADER_SIZE);
|
||||
|
||||
if (framebuf_new_length > cs->frame_size) {
|
||||
if (framebuf_new_length > cs->frame_size)
|
||||
cs->frame_size = framebuf_new_length;
|
||||
}
|
||||
|
||||
end:
|
||||
rtp_free_msg(NULL, msg);
|
||||
|
|
|
@ -86,13 +86,12 @@ typedef struct CSSession_s {
|
|||
|
||||
/* Data handling */
|
||||
uint8_t *frame_buf; /* buffer for split video payloads */
|
||||
uint32_t frame_size; /* largest address written to in frame_buf for current input frame*/
|
||||
uint32_t frame_size; /* largest address written to in frame_buf for current input frame */
|
||||
uint8_t frameid_in, frameid_out; /* id of input and output video frame */
|
||||
uint32_t last_timestamp; /* calculating cycles */
|
||||
|
||||
/* Limits */
|
||||
uint32_t video_frame_piece_size;
|
||||
uint32_t max_video_frame_size;
|
||||
uint32_t peer_video_frame_piece_size;
|
||||
|
||||
/* Splitting */
|
||||
uint8_t *split_video_frame;
|
||||
|
@ -129,8 +128,7 @@ typedef struct CSSession_s {
|
|||
*
|
||||
*/
|
||||
void *agent; /* Pointer to ToxAV TODO make this pointer to ToxAV*/
|
||||
int32_t call_idx;
|
||||
int32_t friend_number;
|
||||
int32_t friend_id;
|
||||
|
||||
PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */
|
||||
PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */
|
||||
|
@ -145,7 +143,7 @@ typedef struct CSSession_s {
|
|||
void cs_do(CSSession *cs);
|
||||
|
||||
/* Make sure to be called BEFORE corresponding rtp_new */
|
||||
CSSession *cs_new(uint32_t s_audio_b, uint32_t p_audio_b, uint32_t s_video_b, uint32_t p_video_b);
|
||||
CSSession *cs_new(uint32_t peer_mvfpsz);
|
||||
/* Make sure to be called AFTER corresponding rtp_kill */
|
||||
void cs_kill(CSSession *cs);
|
||||
|
||||
|
|
111
toxav/msi.c
111
toxav/msi.c
|
@ -50,8 +50,7 @@ typedef enum {
|
|||
IDResponse,
|
||||
IDError,
|
||||
IDCapabilities,
|
||||
IDMVFSZ,
|
||||
IDMVFPSZ,
|
||||
IDVFPSZ,
|
||||
|
||||
} MSIHeaderID;
|
||||
|
||||
|
@ -79,8 +78,7 @@ GENERIC_HEADER ( Request, MSIRequest );
|
|||
GENERIC_HEADER ( Response, MSIResponse );
|
||||
GENERIC_HEADER ( Error, MSIError );
|
||||
GENERIC_HEADER ( Capabilities, uint8_t );
|
||||
GENERIC_HEADER ( MVFSZ, uint16_t );
|
||||
GENERIC_HEADER ( MVFPSZ, uint16_t );
|
||||
GENERIC_HEADER ( VFPSZ, uint16_t );
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -88,8 +86,7 @@ typedef struct {
|
|||
MSIHeaderResponse response;
|
||||
MSIHeaderError error;
|
||||
MSIHeaderCapabilities capabilities;
|
||||
MSIHeaderMVFSZ mvfsz; /* Max video frame size. NOTE: Value must be in network b-order */
|
||||
MSIHeaderMVFPSZ mvfpsz; /* Max video frame piece size. NOTE: Value must be in network b-order */
|
||||
MSIHeaderVFPSZ vfpsz; /* Video frame piece size. NOTE: Value must be in network b-order */
|
||||
} MSIMessage;
|
||||
|
||||
|
||||
|
@ -200,12 +197,9 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_
|
|||
|
||||
msg_invite.capabilities.exists = true;
|
||||
msg_invite.capabilities.value = capabilities;
|
||||
|
||||
msg_invite.mvfsz.exists = true;
|
||||
msg_invite.mvfsz.value = htons(D_MVFSZ);
|
||||
|
||||
msg_invite.mvfpsz.exists = true;
|
||||
msg_invite.mvfpsz.value = htons(D_MVFPSZ);
|
||||
|
||||
msg_invite.vfpsz.exists = true;
|
||||
msg_invite.vfpsz.value = htons(VIDEOFRAME_PIECE_SIZE);
|
||||
|
||||
send_message ( (*call)->session->messenger, (*call)->friend_id, &msg_invite );
|
||||
|
||||
|
@ -216,7 +210,7 @@ int msi_invite ( MSISession *session, MSICall **call, uint32_t friend_id, uint8_
|
|||
}
|
||||
int msi_hangup ( MSICall* call )
|
||||
{
|
||||
LOGGER_DEBUG("Session: %p Hanging up call: %u", session, call_index);
|
||||
LOGGER_DEBUG("Session: %p Hanging up call with friend: %u", call->session, call->friend_id);
|
||||
|
||||
MSIMessage msg_end;
|
||||
msg_end.request.exists = true;
|
||||
|
@ -244,11 +238,8 @@ int msi_answer ( MSICall* call, uint8_t capabilities )
|
|||
msg_starting.capabilities.exists = true;
|
||||
msg_starting.capabilities.value = capabilities;
|
||||
|
||||
msg_starting.mvfsz.exists = true;
|
||||
msg_starting.mvfsz.value = htons(D_MVFSZ);
|
||||
|
||||
msg_starting.mvfpsz.exists = true;
|
||||
msg_starting.mvfpsz.value = htons(D_MVFPSZ);
|
||||
msg_starting.vfpsz.exists = true;
|
||||
msg_starting.vfpsz.value = htons(VIDEOFRAME_PIECE_SIZE);
|
||||
|
||||
send_message ( call->session->messenger, call->friend_id, &msg_starting );
|
||||
|
||||
|
@ -256,7 +247,7 @@ int msi_answer ( MSICall* call, uint8_t capabilities )
|
|||
}
|
||||
int msi_reject ( MSICall* call )
|
||||
{
|
||||
LOGGER_DEBUG("Session: %p Rejecting call: %u; reason: %s", session, call_index, reason ? reason : "Unknown");
|
||||
LOGGER_DEBUG("Session: %p Rejecting call with friend: %u", call->session, call->friend_id);
|
||||
|
||||
if ( call->state != msi_CallRequested ) {
|
||||
LOGGER_ERROR("Call is in invalid state!");
|
||||
|
@ -353,14 +344,9 @@ int msg_parse_in ( MSIMessage *dest, const uint8_t *data, uint16_t length )
|
|||
SET_UINT8(it, dest->capabilities);
|
||||
break;
|
||||
|
||||
case IDMVFSZ:
|
||||
case IDVFPSZ:
|
||||
CHECK_SIZE(it, size_constraint, 2);
|
||||
SET_UINT16(it, dest->mvfsz);
|
||||
break;
|
||||
|
||||
case IDMVFPSZ:
|
||||
CHECK_SIZE(it, size_constraint, 2);
|
||||
SET_UINT16(it, dest->mvfpsz);
|
||||
SET_UINT16(it, dest->vfpsz);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -408,33 +394,28 @@ int send_message ( Messenger* m, uint32_t friend_id, const MSIMessage *msg )
|
|||
if (msg->request.exists) {
|
||||
uint8_t cast = msg->request.value;
|
||||
it = msg_parse_header_out(IDRequest, it, &cast,
|
||||
sizeof(cast), &size);
|
||||
sizeof(cast), &size);
|
||||
}
|
||||
|
||||
if (msg->response.exists) {
|
||||
uint8_t cast = msg->response.value;
|
||||
it = msg_parse_header_out(IDResponse, it, &cast,
|
||||
sizeof(cast), &size);
|
||||
sizeof(cast), &size);
|
||||
}
|
||||
|
||||
if (msg->error.exists) {
|
||||
it = msg_parse_header_out(IDError, it, &msg->error.value,
|
||||
sizeof(msg->error.value), &size);
|
||||
sizeof(msg->error.value), &size);
|
||||
}
|
||||
|
||||
if (msg->capabilities.exists) {
|
||||
it = msg_parse_header_out(IDCapabilities, it, &msg->capabilities.value,
|
||||
sizeof(msg->capabilities.value), &size);
|
||||
sizeof(msg->capabilities.value), &size);
|
||||
}
|
||||
|
||||
if (msg->mvfsz.exists) {
|
||||
it = msg_parse_header_out(IDMVFSZ, it, &msg->mvfsz.value,
|
||||
sizeof(msg->mvfsz.value), &size);
|
||||
}
|
||||
|
||||
if (msg->mvfpsz.exists) {
|
||||
it = msg_parse_header_out(IDMVFPSZ, it, &msg->mvfpsz.value,
|
||||
sizeof(msg->mvfpsz.value), &size);
|
||||
if (msg->vfpsz.exists) {
|
||||
it = msg_parse_header_out(IDVFPSZ, it, &msg->vfpsz.value,
|
||||
sizeof(msg->vfpsz.value), &size);
|
||||
}
|
||||
|
||||
*it = 0;
|
||||
|
@ -494,6 +475,7 @@ MSICall *new_call ( MSISession *session, uint32_t friend_id )
|
|||
if (rc == NULL)
|
||||
return NULL;
|
||||
|
||||
rc->session = session;
|
||||
rc->friend_id = friend_id;
|
||||
|
||||
if (session->calls == NULL) { /* Creating */
|
||||
|
@ -617,28 +599,14 @@ int handle_recv_invite ( MSICall *call, const MSIMessage *msg )
|
|||
|
||||
LOGGER_DEBUG("Glare detected!");
|
||||
|
||||
if (!msg->mvfsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'");
|
||||
call->error = msi_InvalidMessage;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg->mvfpsz.exists) {
|
||||
if (!msg->vfpsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'");
|
||||
call->error = msi_InvalidMessage;
|
||||
return -1;
|
||||
}
|
||||
|
||||
call->peer_capabilities = msg->capabilities.value;
|
||||
|
||||
call->peer_mvfsz = ntohs(msg->mvfsz.value);
|
||||
call->peer_mvfpsz = ntohs(msg->mvfpsz.value);
|
||||
|
||||
if (call->peer_mvfsz > call->peer_mvfpsz) {
|
||||
LOGGER_WARNING("Session: %p mvfsz param greater than mvfpsz on 'invite'");
|
||||
call->error = msi_InvalidParam;
|
||||
return -1;
|
||||
}
|
||||
call->peer_vfpsz = ntohs(msg->vfpsz.value);
|
||||
|
||||
/* Send response */
|
||||
response.response.value = resp_starting;
|
||||
|
@ -665,24 +633,14 @@ int handle_recv_invite ( MSICall *call, const MSIMessage *msg )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!msg->mvfsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'");
|
||||
call->error = msi_InvalidMessage;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg->mvfpsz.exists) {
|
||||
if (!msg->vfpsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'");
|
||||
call->error = msi_InvalidMessage;
|
||||
return -1;
|
||||
}
|
||||
|
||||
call->peer_capabilities = msg->capabilities.value;
|
||||
|
||||
call->peer_mvfsz = ntohs(msg->mvfsz.value);
|
||||
call->peer_mvfpsz = ntohs(msg->mvfpsz.value);
|
||||
|
||||
call->peer_vfpsz = ntohs(msg->vfpsz.value);
|
||||
call->state = msi_CallRequested;
|
||||
|
||||
/* Send response */
|
||||
|
@ -781,31 +739,16 @@ int handle_recv_starting ( MSICall *call, const MSIMessage *msg )
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!msg->mvfsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfsz on 'invite'");
|
||||
call->error = msi_InvalidParam;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg->mvfpsz.exists) {
|
||||
if (!msg->vfpsz.exists) {
|
||||
LOGGER_WARNING("Session: %p Invalid mvfpsz on 'invite'");
|
||||
call->error = msi_InvalidParam;
|
||||
return -1;
|
||||
}
|
||||
|
||||
call->peer_capabilities = msg->capabilities.value;
|
||||
|
||||
call->peer_mvfsz = ntohs(msg->mvfsz.value);
|
||||
call->peer_mvfpsz = ntohs(msg->mvfpsz.value);
|
||||
|
||||
|
||||
if (call->peer_mvfsz > call->peer_mvfpsz) {
|
||||
LOGGER_WARNING("Session: %p mvfsz param greater than mvfpsz on 'invite'");
|
||||
call->error = msi_InvalidParam;
|
||||
return -1;
|
||||
}
|
||||
|
||||
call->peer_vfpsz = ntohs(msg->vfpsz.value);
|
||||
call->state = msi_CallActive;
|
||||
|
||||
invoke_callback(call, msi_OnStart);
|
||||
}
|
||||
/* Otherwise it's a glare case so don't start until 'start' is recved */
|
||||
|
|
12
toxav/msi.h
12
toxav/msi.h
|
@ -28,9 +28,8 @@
|
|||
#include "codec.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
|
||||
/** Preconfigured values for video splitting */
|
||||
#define D_MVFSZ 40000 /* 256KiB */
|
||||
#define D_MVFPSZ 500 /* 1.25 KiB*/
|
||||
/** Preconfigured value for video splitting */
|
||||
#define VIDEOFRAME_PIECE_SIZE 500 /* 1.25 KiB*/
|
||||
|
||||
/**
|
||||
* Error codes.
|
||||
|
@ -87,15 +86,10 @@ typedef struct MSICall_s {
|
|||
struct MSISession_s *session; /* Session pointer */
|
||||
|
||||
MSICallState state;
|
||||
|
||||
uint8_t peer_capabilities; /* Peer capabilities */
|
||||
uint8_t self_capabilities; /* Self capabilities */
|
||||
|
||||
uint16_t peer_mvfsz; /* Max video frame size */
|
||||
uint16_t peer_mvfpsz; /* Max video frame part size */
|
||||
|
||||
uint16_t peer_vfpsz; /* Video frame piece size */
|
||||
uint32_t friend_id; /* Index of this call in MSISession */
|
||||
|
||||
MSIError error; /* Last error */
|
||||
|
||||
void* av_call; /* Pointer to av call handler */
|
||||
|
|
188
toxav/toxav.c
188
toxav/toxav.c
|
@ -40,21 +40,24 @@ enum {
|
|||
video_index,
|
||||
};
|
||||
|
||||
typedef struct iToxAVCall
|
||||
typedef struct ToxAVCall_s
|
||||
{
|
||||
pthread_mutex_t mutex_control[1];
|
||||
pthread_mutex_t mutex_encoding_audio[1];
|
||||
pthread_mutex_t mutex_encoding_video[1];
|
||||
pthread_mutex_t mutex_do[1];
|
||||
RTPSession *rtps[2]; /** Audio is first and video is second */
|
||||
RTPSession *rtps[2]; /* Audio is first and video is second */
|
||||
CSSession *cs;
|
||||
bool active;
|
||||
int32_t friend_id;
|
||||
MSICall* msi_call;
|
||||
uint32_t friend_id;
|
||||
|
||||
struct iToxAVCall *prev;
|
||||
struct iToxAVCall *next;
|
||||
} IToxAVCall;
|
||||
uint32_t s_audio_b; /* Sending audio bitrate */
|
||||
uint32_t s_video_b; /* Sending video bitrate */
|
||||
|
||||
struct ToxAVCall_s *prev;
|
||||
struct ToxAVCall_s *next;
|
||||
} ToxAVCall;
|
||||
|
||||
struct toxAV
|
||||
{
|
||||
|
@ -62,7 +65,7 @@ struct toxAV
|
|||
MSISession* msi;
|
||||
|
||||
/* Two-way storage: first is array of calls and second is list of calls with head and tail */
|
||||
IToxAVCall** calls;
|
||||
ToxAVCall** calls;
|
||||
uint32_t calls_tail;
|
||||
uint32_t calls_head;
|
||||
|
||||
|
@ -88,13 +91,13 @@ void i_callback_error(void* toxav_inst, MSICall* call);
|
|||
void i_callback_capabilites(void* toxav_inst, MSICall* call);
|
||||
|
||||
TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities);
|
||||
IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number);
|
||||
IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number);
|
||||
ToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number);
|
||||
ToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number);
|
||||
void i_toxav_remove_call(ToxAV* av, uint32_t friend_number);
|
||||
IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
|
||||
ToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
|
||||
bool i_toxav_audio_bitrate_invalid(uint32_t bitrate);
|
||||
bool i_toxav_video_bitrate_invalid(uint32_t bitrate);
|
||||
bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call);
|
||||
bool i_toxav_prepare_transmission(ToxAV* av, ToxAVCall* call);
|
||||
void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number);
|
||||
|
||||
|
||||
|
@ -179,15 +182,13 @@ uint32_t toxav_iteration_interval(const ToxAV* av)
|
|||
|
||||
void toxav_iteration(ToxAV* av)
|
||||
{
|
||||
msi_do(av->msi);
|
||||
|
||||
if (av->calls == NULL)
|
||||
return;
|
||||
|
||||
uint64_t start = current_time_monotonic();
|
||||
uint32_t rc = 200 + av->dmssa; /* If no call is active interval is 200 */
|
||||
|
||||
IToxAVCall* i = av->calls[av->calls_head];
|
||||
ToxAVCall* i = av->calls[av->calls_head];
|
||||
for (; i; i = i->next) {
|
||||
if (i->active) {
|
||||
cs_do(i->cs);
|
||||
|
@ -207,22 +208,22 @@ void toxav_iteration(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)
|
||||
{
|
||||
IToxAVCall* call = i_toxav_init_call(av, friend_number, error);
|
||||
if (call == NULL) {
|
||||
ToxAVCall* call = i_toxav_init_call(av, friend_number, error);
|
||||
if (call == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO remove csettings */
|
||||
MSICSettings csets;
|
||||
csets.audio_bitrate = audio_bit_rate;
|
||||
csets.video_bitrate = video_bit_rate;
|
||||
call->s_audio_b = audio_bit_rate;
|
||||
call->s_video_b = video_bit_rate;
|
||||
|
||||
csets.call_type = video_bit_rate ? msi_TypeVideo : msi_TypeAudio;
|
||||
uint8_t capabilities = 0;
|
||||
|
||||
if (msi_invite(av->msi, &call->call_idx, &csets, 1000, friend_number) != 0) {
|
||||
capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0;
|
||||
capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0;
|
||||
|
||||
if (msi_invite(av->msi, &call->msi_call, friend_number, capabilities) != 0) {
|
||||
i_toxav_remove_call(av, friend_number);
|
||||
if (error)
|
||||
*error = TOXAV_ERR_CALL_MALLOC; /* FIXME: this should be the only reason to fail */
|
||||
*error = TOXAV_ERR_CALL_MALLOC;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -250,23 +251,23 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
|
|||
goto END;
|
||||
}
|
||||
|
||||
IToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
if (call == NULL || av->msi->calls[call->call_idx]->state != msi_CallRequested) {
|
||||
ToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
if (call == NULL) {
|
||||
rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING;
|
||||
goto END;
|
||||
}
|
||||
|
||||
/* TODO remove csettings */
|
||||
MSICSettings csets;
|
||||
csets.audio_bitrate = audio_bit_rate;
|
||||
csets.video_bitrate = video_bit_rate;
|
||||
call->s_audio_b = audio_bit_rate;
|
||||
call->s_video_b = video_bit_rate;
|
||||
|
||||
csets.call_type = video_bit_rate ? msi_TypeVideo : msi_TypeAudio;
|
||||
uint8_t capabilities = 0;
|
||||
|
||||
capabilities |= audio_bit_rate > 0 ? msi_CapSAudio : 0;
|
||||
capabilities |= video_bit_rate > 0 ? msi_CapSVideo : 0;
|
||||
|
||||
if (msi_answer(call->msi_call, capabilities) != 0)
|
||||
rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; /* the only reason for msi_answer to fail */
|
||||
|
||||
if (msi_answer(av->msi, call->call_idx, &csets) != 0) {
|
||||
rc = TOXAV_ERR_ANSWER_MALLOC; /* TODO Some error here */
|
||||
/* TODO Reject call? */
|
||||
}
|
||||
|
||||
END:
|
||||
if (error)
|
||||
|
@ -291,7 +292,7 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
|
|||
}
|
||||
|
||||
|
||||
IToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
ToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
if (call == NULL) {
|
||||
rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL;
|
||||
goto END;
|
||||
|
@ -309,17 +310,17 @@ bool toxav_call_control(ToxAV* av, uint32_t friend_number, TOXAV_CALL_CONTROL co
|
|||
} break;
|
||||
|
||||
case TOXAV_CALL_CONTROL_CANCEL: {
|
||||
if (av->msi->calls[call->call_idx]->state == msi_CallActive) {
|
||||
if (call->msi_call->state == msi_CallActive
|
||||
|| call->msi_call->state == msi_CallRequesting) {
|
||||
/* Hang up */
|
||||
msi_hangup(av->msi, call->call_idx);
|
||||
} else if (av->msi->calls[call->call_idx]->state == msi_CallRequested) {
|
||||
/* Reject the call */
|
||||
msi_reject(av->msi, call->call_idx, NULL);
|
||||
} else if (av->msi->calls[call->call_idx]->state == msi_CallRequesting) {
|
||||
/* Cancel the call */
|
||||
msi_cancel(av->msi, call->call_idx, 0, NULL);
|
||||
i_toxav_remove_call(av, friend_number);
|
||||
msi_hangup(call->msi_call);
|
||||
} else if (call->msi_call->state == msi_CallRequested) {
|
||||
/* Reject the call */
|
||||
msi_reject(call->msi_call);
|
||||
}
|
||||
|
||||
// No mather the case, terminate the call
|
||||
i_toxav_remove_call(av, friend_number);
|
||||
} break;
|
||||
|
||||
case TOXAV_CALL_CONTROL_MUTE_AUDIO: {
|
||||
|
@ -356,7 +357,7 @@ void toxav_callback_request_video_frame(ToxAV* av, toxav_request_video_frame_cb*
|
|||
bool toxav_send_video_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)
|
||||
{
|
||||
TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK;
|
||||
IToxAVCall* call;
|
||||
ToxAVCall* call;
|
||||
|
||||
if (m_friend_exists(av->m, friend_number) == 0) {
|
||||
rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
|
||||
|
@ -369,7 +370,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
|
|||
goto END;
|
||||
}
|
||||
|
||||
if (av->msi->calls[call->call_idx]->state != msi_CallActive) {
|
||||
if (call->msi_call->state != msi_CallActive) {
|
||||
/* TODO */
|
||||
rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED;
|
||||
goto END;
|
||||
|
@ -453,7 +454,7 @@ void toxav_callback_request_audio_frame(ToxAV* av, toxav_request_audio_frame_cb*
|
|||
bool toxav_send_audio_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)
|
||||
{
|
||||
TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK;
|
||||
IToxAVCall* call;
|
||||
ToxAVCall* call;
|
||||
|
||||
if (m_friend_exists(av->m, friend_number) == 0) {
|
||||
rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
|
||||
|
@ -466,7 +467,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
|
|||
goto END;
|
||||
}
|
||||
|
||||
if (av->msi->calls[call->call_idx]->state != msi_CallActive) {
|
||||
if (call->msi_call->state != msi_CallActive) {
|
||||
/* TODO */
|
||||
rc = TOXAV_ERR_SEND_FRAME_NOT_REQUESTED;
|
||||
goto END;
|
||||
|
@ -533,10 +534,10 @@ void i_callback_invite(void* toxav_inst, MSICall* call)
|
|||
{
|
||||
ToxAV* toxav = toxav_inst;
|
||||
|
||||
IToxAVCall* av_call = i_toxav_init_call(toxav, call->friend_id, NULL);
|
||||
ToxAVCall* av_call = i_toxav_init_call(toxav, call->friend_id, NULL);
|
||||
if (av_call == NULL) {
|
||||
LOGGER_WARNING("Failed to start call, rejecting...");
|
||||
msi_reject(toxav->msi, call);
|
||||
msi_reject(call);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -559,15 +560,15 @@ void i_callback_start(void* toxav_inst, MSICall* call)
|
|||
{
|
||||
ToxAV* toxav = toxav_inst;
|
||||
|
||||
IToxAVCall* call = i_toxav_get_call(toxav, call->friend_id);
|
||||
ToxAVCall* av_call = i_toxav_get_call(toxav, call->friend_id);
|
||||
|
||||
if (call == NULL || !i_toxav_prepare_transmission(toxav, call)) {
|
||||
if (av_call == NULL || !i_toxav_prepare_transmission(toxav, av_call)) {
|
||||
/* TODO send error */
|
||||
i_toxav_remove_call(toxav, call->friend_id);
|
||||
return;
|
||||
}
|
||||
|
||||
TOXAV_CALL_STATE state = capabilities_to_state(call->msi_call->peer_capabilities);
|
||||
TOXAV_CALL_STATE state = capabilities_to_state(av_call->msi_call->peer_capabilities);
|
||||
|
||||
if (toxav->scb.first)
|
||||
toxav->scb.first(toxav, call->friend_id, state, toxav->scb.second);
|
||||
|
@ -594,7 +595,7 @@ void i_callback_error(void* toxav_inst, MSICall* call)
|
|||
void i_callback_capabilites(void* toxav_inst, MSICall* call)
|
||||
{
|
||||
ToxAV* toxav = toxav_inst;
|
||||
/* TODO something something msi */
|
||||
/* TODO handle this */
|
||||
}
|
||||
|
||||
TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities)
|
||||
|
@ -609,7 +610,7 @@ TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities)
|
|||
return TOXAV_CALL_STATE_PAUSED;
|
||||
}
|
||||
|
||||
IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
|
||||
ToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
|
||||
{
|
||||
if (av->calls == NULL || av->calls_tail < friend_number)
|
||||
return NULL;
|
||||
|
@ -617,9 +618,9 @@ IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
|
|||
return av->calls[friend_number];
|
||||
}
|
||||
|
||||
IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
|
||||
ToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
|
||||
{
|
||||
IToxAVCall* rc = calloc(sizeof(IToxAVCall), 1);
|
||||
ToxAVCall* rc = calloc(sizeof(ToxAVCall), 1);
|
||||
|
||||
if (rc == NULL)
|
||||
return NULL;
|
||||
|
@ -639,7 +640,7 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
|
|||
|
||||
|
||||
if (av->calls == NULL) { /* Creating */
|
||||
av->calls = calloc (sizeof(IToxAVCall*), friend_number + 1);
|
||||
av->calls = calloc (sizeof(ToxAVCall*), friend_number + 1);
|
||||
|
||||
if (av->calls == NULL) {
|
||||
pthread_mutex_destroy(rc->mutex_control);
|
||||
|
@ -651,7 +652,7 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
|
|||
av->calls_tail = av->calls_head = friend_number;
|
||||
|
||||
} else if (av->calls_tail < friend_number) { /* Appending */
|
||||
void* tmp = realloc(av->calls, sizeof(IToxAVCall*) * friend_number + 1);
|
||||
void* tmp = realloc(av->calls, sizeof(ToxAVCall*) * friend_number + 1);
|
||||
|
||||
if (tmp == NULL) {
|
||||
pthread_mutex_destroy(rc->mutex_control);
|
||||
|
@ -684,13 +685,13 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
|
|||
|
||||
void i_toxav_remove_call(ToxAV* av, uint32_t friend_number)
|
||||
{
|
||||
IToxAVCall* tc = i_toxav_get_call(av, friend_number);
|
||||
ToxAVCall* tc = i_toxav_get_call(av, friend_number);
|
||||
|
||||
if (tc == NULL)
|
||||
return;
|
||||
|
||||
IToxAVCall* prev = tc->prev;
|
||||
IToxAVCall* next = tc->next;
|
||||
ToxAVCall* prev = tc->prev;
|
||||
ToxAVCall* next = tc->next;
|
||||
|
||||
pthread_mutex_destroy(tc->mutex_control);
|
||||
pthread_mutex_destroy(tc->mutex_do);
|
||||
|
@ -718,10 +719,10 @@ CLEAR:
|
|||
av->calls = NULL;
|
||||
}
|
||||
|
||||
IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error)
|
||||
ToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error)
|
||||
{
|
||||
TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK;
|
||||
IToxAVCall* call = NULL;
|
||||
ToxAVCall* call = NULL;
|
||||
|
||||
if (m_friend_exists(av->m, friend_number) == 0) {
|
||||
rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND;
|
||||
|
@ -764,8 +765,12 @@ bool i_toxav_video_bitrate_invalid(uint32_t bitrate)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
|
||||
bool i_toxav_prepare_transmission(ToxAV* av, ToxAVCall* call)
|
||||
{
|
||||
if (!av->acb.first && !av->vcb.first)
|
||||
/* It makes no sense to have CSession without callbacks */
|
||||
return false;
|
||||
|
||||
pthread_mutex_lock(call->mutex_control);
|
||||
|
||||
if (call->active) {
|
||||
|
@ -788,11 +793,9 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
|
|||
goto MUTEX_INIT_ERROR;
|
||||
}
|
||||
|
||||
const MSICSettings *c_peer = &av->msi->calls[call->call_idx]->csettings_peer[0];
|
||||
const MSICSettings *c_self = &av->msi->calls[call->call_idx]->csettings_local;
|
||||
uint8_t capabilities = call->msi_call->self_capabilities;
|
||||
|
||||
call->cs = cs_new(c_self->audio_bitrate, c_peer->audio_bitrate,
|
||||
c_self->video_bitrate, c_peer->video_bitrate);
|
||||
call->cs = cs_new(call->msi_call->peer_vfpsz);
|
||||
|
||||
if ( !call->cs ) {
|
||||
LOGGER_ERROR("Error while starting Codec State!\n");
|
||||
|
@ -800,19 +803,14 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
|
|||
}
|
||||
|
||||
call->cs->agent = av;
|
||||
|
||||
/* It makes no sense to have CSession without callbacks */
|
||||
assert(av->acb.first || av->vcb.first);
|
||||
call->cs->friend_id = call->friend_id;
|
||||
|
||||
memcpy(&call->cs->acb, &av->acb, sizeof(av->acb));
|
||||
memcpy(&call->cs->vcb, &av->vcb, sizeof(av->vcb));
|
||||
|
||||
call->cs->friend_number = call->friend_id;
|
||||
call->cs->call_idx = call->call_idx;
|
||||
|
||||
|
||||
if (c_self->audio_bitrate > 0 || c_peer->audio_bitrate > 0) { /* Prepare audio rtp */
|
||||
call->rtps[audio_index] = rtp_new(rtp_TypeAudio, av->m, av->msi->calls[call->call_idx]->peers[0]);
|
||||
if (capabilities & msi_CapSAudio || capabilities & msi_CapRAudio) { /* Prepare audio sending */
|
||||
|
||||
call->rtps[audio_index] = rtp_new(rtp_TypeAudio, av->m, call->friend_id);
|
||||
|
||||
if ( !call->rtps[audio_index] ) {
|
||||
LOGGER_ERROR("Error while starting audio RTP session!\n");
|
||||
|
@ -821,12 +819,23 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
|
|||
|
||||
call->rtps[audio_index]->cs = call->cs;
|
||||
|
||||
if (c_peer->audio_bitrate > 0)
|
||||
if (cs_enable_audio_sending(call->cs, call->s_audio_b, 2) != 0) {
|
||||
LOGGER_WARNING("Failed to enable audio sending!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if (capabilities & msi_CapRAudio) {
|
||||
if (cs_enable_audio_receiving(call->cs) != 0) {
|
||||
LOGGER_WARNING("Failed to enable audio receiving!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
rtp_register_for_receiving(call->rtps[audio_index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (c_self->video_bitrate > 0 || c_peer->video_bitrate > 0) { /* Prepare video rtp */
|
||||
call->rtps[video_index] = rtp_new(rtp_TypeVideo, av->m, av->msi->calls[call->call_idx]->peers[0]);
|
||||
if (capabilities & msi_CapSVideo || capabilities & msi_CapRVideo) { /* Prepare video rtp */
|
||||
call->rtps[video_index] = rtp_new(rtp_TypeVideo, av->m, call->friend_id);
|
||||
|
||||
if ( !call->rtps[video_index] ) {
|
||||
LOGGER_ERROR("Error while starting video RTP session!\n");
|
||||
|
@ -835,8 +844,19 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
|
|||
|
||||
call->rtps[video_index]->cs = call->cs;
|
||||
|
||||
if (c_peer->video_bitrate > 0)
|
||||
if (cs_enable_video_sending(call->cs, call->s_video_b) != 0) {
|
||||
LOGGER_WARNING("Failed to enable video sending!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
if (capabilities & msi_CapRVideo) {
|
||||
if (cs_enable_video_receiving(call->cs) != 0) {
|
||||
LOGGER_WARNING("Failed to enable video receiving!");
|
||||
goto FAILURE;
|
||||
}
|
||||
|
||||
rtp_register_for_receiving(call->rtps[audio_index]);
|
||||
}
|
||||
}
|
||||
|
||||
call->active = 1;
|
||||
|
@ -866,7 +886,7 @@ MUTEX_INIT_ERROR:
|
|||
|
||||
void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number)
|
||||
{
|
||||
IToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
ToxAVCall* call = i_toxav_get_call(av, friend_number);
|
||||
if (!call)
|
||||
return;
|
||||
|
||||
|
|
|
@ -317,7 +317,6 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, int support_vide
|
|||
}
|
||||
|
||||
call->cs->agent = av;
|
||||
call->cs->call_idx = call_index;
|
||||
|
||||
call->cs->acb.first = av->acb.first;
|
||||
call->cs->acb.second = av->acb.second;
|
||||
|
|
Loading…
Reference in New Issue
Block a user