From efe31ec92f476faffd6502714d05cce0a7dfadc7 Mon Sep 17 00:00:00 2001 From: mannol Date: Fri, 20 Feb 2015 00:23:38 +0100 Subject: [PATCH] Removed extra msi header and started testing --- toxav/codec.c | 57 ++++---------- toxav/codec.h | 10 +-- toxav/msi.c | 111 +++++++------------------- toxav/msi.h | 12 +-- toxav/toxav.c | 188 ++++++++++++++++++++++++-------------------- toxav/toxav_new_1.c | 1 - 6 files changed, 154 insertions(+), 225 deletions(-) diff --git a/toxav/codec.c b/toxav/codec.c index 9fc14071..e44387df 100644 --- a/toxav/codec.c +++ b/toxav/codec.c @@ -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); diff --git a/toxav/codec.h b/toxav/codec.h index b5eb19e2..6a673990 100644 --- a/toxav/codec.h +++ b/toxav/codec.h @@ -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); diff --git a/toxav/msi.c b/toxav/msi.c index cc855613..16476364 100644 --- a/toxav/msi.c +++ b/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 */ diff --git a/toxav/msi.h b/toxav/msi.h index 4f27b9f8..a55d8567 100644 --- a/toxav/msi.h +++ b/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 */ diff --git a/toxav/toxav.c b/toxav/toxav.c index 12a65737..584b3898 100644 --- a/toxav/toxav.c +++ b/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; diff --git a/toxav/toxav_new_1.c b/toxav/toxav_new_1.c index ee7f49a6..145dcf48 100644 --- a/toxav/toxav_new_1.c +++ b/toxav/toxav_new_1.c @@ -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;