Removed extra msi header and started testing

This commit is contained in:
mannol 2015-02-20 00:23:38 +01:00
parent 6e259d5fcb
commit efe31ec92f
6 changed files with 154 additions and 225 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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;