Merge branch 'mannol1-master'

This commit is contained in:
irungentoo 2014-07-05 12:25:30 -04:00
commit a51f6bbd69
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
5 changed files with 115 additions and 87 deletions

View File

@ -80,8 +80,12 @@ JitterBuffer *create_queue(int capacity)
void terminate_queue(JitterBuffer *q) void terminate_queue(JitterBuffer *q)
{ {
if (!q) return;
empty_queue(q); empty_queue(q);
free(q->queue); free(q->queue);
LOGGER_DEBUG("Terminated jitter buffer: %p", q);
free(q); free(q);
} }
@ -355,6 +359,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
void codec_terminate_session ( CodecState *cs ) void codec_terminate_session ( CodecState *cs )
{ {
if (!cs) return;
if ( cs->audio_encoder ) if ( cs->audio_encoder )
opus_encoder_destroy(cs->audio_encoder); opus_encoder_destroy(cs->audio_encoder);
@ -366,6 +372,9 @@ void codec_terminate_session ( CodecState *cs )
if ( cs->capabilities & v_encoding ) if ( cs->capabilities & v_encoding )
vpx_codec_destroy(&cs->v_encoder); vpx_codec_destroy(&cs->v_encoder);
LOGGER_DEBUG("Terminated codec state: %p", cs);
free(cs);
} }
inline float calculate_sum_sq (int16_t *n, uint16_t k) inline float calculate_sum_sq (int16_t *n, uint16_t k)

View File

@ -1043,12 +1043,12 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
return NULL; return NULL;
} }
int32_t _call_idx = 0; int32_t call_idx = 0;
for (; _call_idx < session->max_calls; _call_idx ++) { for (; call_idx < session->max_calls; call_idx ++) {
if ( !session->calls[_call_idx] ) { if ( !session->calls[call_idx] ) {
if (!(session->calls[_call_idx] = calloc ( sizeof ( MSICall ), 1 ))) { if (!(session->calls[call_idx] = calloc ( sizeof ( MSICall ), 1 ))) {
LOGGER_WARNING("Allocation failed! Program might misbehave!"); LOGGER_WARNING("Allocation failed! Program might misbehave!");
return NULL; return NULL;
} }
@ -1057,35 +1057,35 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
} }
} }
if ( _call_idx == session->max_calls ) { if ( call_idx == session->max_calls ) {
LOGGER_WARNING("Reached maximum amount of calls!"); LOGGER_WARNING("Reached maximum amount of calls!");
return NULL; return NULL;
} }
MSICall *_call = session->calls[_call_idx]; MSICall *call = session->calls[call_idx];
_call->call_idx = _call_idx; call->call_idx = call_idx;
if ( !(_call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) { if ( !(call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) {
LOGGER_WARNING("Allocation failed! Program might misbehave!"); LOGGER_WARNING("Allocation failed! Program might misbehave!");
free(_call); free(call);
return NULL; return NULL;
} }
_call->session = session; call->session = session;
/*_call->_participant_count = _peers;*/ /*_call->_participant_count = _peers;*/
_call->request_timer_id = 0; call->request_timer_id = 0;
_call->ringing_timer_id = 0; call->ringing_timer_id = 0;
_call->ringing_tout_ms = ringing_timeout; call->ringing_tout_ms = ringing_timeout;
pthread_mutex_init ( &_call->mutex, NULL ); pthread_mutex_init ( &call->mutex, NULL );
LOGGER_DEBUG("Started new call with index: %u", _call_idx); LOGGER_DEBUG("Started new call with index: %u", call_idx);
return _call; return call;
} }
@ -1603,38 +1603,38 @@ MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls )
return NULL; return NULL;
} }
MSISession *_retu = calloc ( sizeof ( MSISession ), 1 ); MSISession *retu = calloc ( sizeof ( MSISession ), 1 );
if (_retu == NULL) { if (retu == NULL) {
LOGGER_ERROR("Allocation failed! Program might misbehave!"); LOGGER_ERROR("Allocation failed! Program might misbehave!");
return NULL; return NULL;
} }
_retu->messenger_handle = messenger; retu->messenger_handle = messenger;
_retu->agent_handler = NULL; retu->agent_handler = NULL;
_retu->timer_handler = handler; retu->timer_handler = handler;
if (!(_retu->calls = calloc( sizeof (MSICall *), max_calls ))) { if (!(retu->calls = calloc( sizeof (MSICall *), max_calls ))) {
LOGGER_ERROR("Allocation failed! Program might misbehave!"); LOGGER_ERROR("Allocation failed! Program might misbehave!");
free(_retu); free(retu);
return NULL; return NULL;
} }
_retu->max_calls = max_calls; retu->max_calls = max_calls;
_retu->frequ = 10000; /* default value? */ retu->frequ = 10000; /* default value? */
_retu->call_timeout = 30000; /* default value? */ retu->call_timeout = 30000; /* default value? */
m_callback_msi_packet(messenger, msi_handle_packet, _retu ); m_callback_msi_packet(messenger, msi_handle_packet, retu );
/* This is called when remote terminates session */ /* This is called when remote terminates session */
m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu); m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, retu);
pthread_mutex_init(&_retu->mutex, NULL); pthread_mutex_init(&retu->mutex, NULL);
LOGGER_DEBUG("New msi session: %p max calls: %u", _retu, max_calls); LOGGER_DEBUG("New msi session: %p max calls: %u", retu, max_calls);
return _retu; return retu;
} }

View File

@ -703,12 +703,9 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien
* @retval -1 Error occurred. * @retval -1 Error occurred.
* @retval 0 Success. * @retval 0 Success.
*/ */
int rtp_terminate_session ( RTPSession *session, Messenger *messenger ) void rtp_terminate_session ( RTPSession *session, Messenger *messenger )
{ {
if ( !session ) { if ( !session ) return;
LOGGER_WARNING("No session!");
return -1;
}
custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
@ -723,8 +720,9 @@ int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
pthread_mutex_destroy(&session->mutex); pthread_mutex_destroy(&session->mutex);
LOGGER_DEBUG("Terminated RTP session: %p", session);
/* And finally free session */ /* And finally free session */
free ( session ); free ( session );
return 0;
} }

View File

@ -195,7 +195,7 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien
* @retval -1 Error occurred. * @retval -1 Error occurred.
* @retval 0 Success. * @retval 0 Success.
*/ */
int rtp_terminate_session ( RTPSession *session, Messenger *messenger ); void rtp_terminate_session ( RTPSession *session, Messenger *messenger );

View File

@ -68,6 +68,7 @@ typedef struct _CallSpecific {
void *frame_buf; /* buffer for split video payloads */ void *frame_buf; /* buffer for split video payloads */
_Bool call_active; _Bool call_active;
pthread_mutex_t mutex;
} CallSpecific; } CallSpecific;
@ -312,7 +313,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
if ( !call->crtps[audio_index] ) { if ( !call->crtps[audio_index] ) {
LOGGER_ERROR("Error while starting audio RTP session!\n"); LOGGER_ERROR("Error while starting audio RTP session!\n");
return ErrorStartingAudioRtp; return ErrorInternal;
} }
@ -323,9 +324,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
if ( !call->crtps[video_index] ) { if ( !call->crtps[video_index] ) {
LOGGER_ERROR("Error while starting video RTP session!\n"); LOGGER_ERROR("Error while starting video RTP session!\n");
goto error;
rtp_terminate_session(call->crtps[audio_index], av->messenger);
return ErrorStartingVideoRtp;
} }
call->frame_limit = 0; call->frame_limit = 0;
@ -335,20 +334,15 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1); call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);
if (!call->frame_buf) { if (!call->frame_buf) {
rtp_terminate_session(call->crtps[audio_index], av->messenger);
rtp_terminate_session(call->crtps[video_index], av->messenger);
LOGGER_WARNING("Frame buffer allocation failed!"); LOGGER_WARNING("Frame buffer allocation failed!");
return ErrorInternal; goto error;
} }
} }
if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) { if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) {
rtp_terminate_session(call->crtps[audio_index], av->messenger);
rtp_terminate_session(call->crtps[video_index], av->messenger);
free(call->frame_buf);
LOGGER_WARNING("Jitter buffer creaton failed!"); LOGGER_WARNING("Jitter buffer creaton failed!");
return ErrorInternal; goto error;
} }
if ( (call->cs = codec_init_session(codec_settings->audio_bitrate, if ( (call->cs = codec_init_session(codec_settings->audio_bitrate,
@ -359,14 +353,20 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
codec_settings->video_width, codec_settings->video_width,
codec_settings->video_height, codec_settings->video_height,
codec_settings->video_bitrate) )) { codec_settings->video_bitrate) )) {
if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
call->call_active = 1; call->call_active = 1;
return ErrorNone; return ErrorNone;
} }
error:
rtp_terminate_session(call->crtps[audio_index], av->messenger); rtp_terminate_session(call->crtps[audio_index], av->messenger);
rtp_terminate_session(call->crtps[video_index], av->messenger); rtp_terminate_session(call->crtps[video_index], av->messenger);
free(call->frame_buf); free(call->frame_buf);
terminate_queue(call->j_buf); terminate_queue(call->j_buf);
codec_terminate_session(call->cs);
return ErrorInternal; return ErrorInternal;
} }
@ -388,30 +388,21 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
pthread_mutex_lock(&call->mutex);
call->call_active = 0; call->call_active = 0;
if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) { rtp_terminate_session(call->crtps[audio_index], av->messenger);
LOGGER_ERROR("Error while terminating audio RTP session!\n"); call->crtps[audio_index] = NULL;
/*return ErrorTerminatingAudioRtp;*/ rtp_terminate_session(call->crtps[video_index], av->messenger);
} else call->crtps[audio_index] = NULL; call->crtps[video_index] = NULL;
if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) {
LOGGER_ERROR("Error while terminating video RTP session!\n");
/*return ErrorTerminatingVideoRtp;*/
} else call->crtps[video_index] = NULL;
if ( call->j_buf ) {
terminate_queue(call->j_buf); terminate_queue(call->j_buf);
call->j_buf = NULL; call->j_buf = NULL;
LOGGER_DEBUG("Terminated j queue");
} else LOGGER_DEBUG("No j queue");
if ( call->cs ) {
codec_terminate_session(call->cs); codec_terminate_session(call->cs);
call->cs = NULL; call->cs = NULL;
LOGGER_DEBUG("Terminated codec session");
} else LOGGER_DEBUG("No codec session");
pthread_mutex_unlock(&call->mutex);
pthread_mutex_destroy(&call->mutex);
return ErrorNone; return ErrorNone;
} }
@ -431,22 +422,23 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload,
unsigned int length ) unsigned int length )
{ {
#define send(data, len) rtp_send_msg(av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, data, len) CallSpecific *call = &av->calls[call_index];
if (call->crtps[type - TypeAudio]) {
if (av->calls[call_index].crtps[type - TypeAudio]) {
if (type == TypeAudio) { if (type == TypeAudio) {
return send(payload, length); return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length);
} else { } else {
if (length == 0 || length > MAX_VIDEOFRAME_SIZE) { if (length == 0 || length > MAX_VIDEOFRAME_SIZE) {
LOGGER_ERROR("Invalid video frame size: %u\n", length); LOGGER_ERROR("Invalid video frame size: %u\n", length);
return -1; return ErrorInternal;
} }
/* number of pieces - 1*/ /* number of pieces - 1*/
uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE; uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE;
uint8_t load[2 + VIDEOFRAME_PIECE_SIZE]; uint8_t load[2 + VIDEOFRAME_PIECE_SIZE];
load[0] = av->calls[call_index].frame_outid++; load[0] = call->frame_outid++;
load[1] = 0; load[1] = 0;
int i; int i;
@ -455,8 +447,10 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE);
payload += VIDEOFRAME_PIECE_SIZE; payload += VIDEOFRAME_PIECE_SIZE;
if (send(load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger,
return -1; load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) {
return ErrorInternal;
} }
load[1]++; load[1]++;
@ -465,13 +459,12 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
/* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */
length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1;
memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length);
return send(load, VIDEOFRAME_HEADER_SIZE + length);
return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length);
} }
} else { } else {
return -1; return ErrorNoRtpSession;
} }
#undef send
} }
/** /**
@ -545,9 +538,10 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
} }
uint8_t packet [RTP_PAYLOAD_SIZE];
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
pthread_mutex_lock(&call->mutex);
uint8_t packet [RTP_PAYLOAD_SIZE];
int recved_size; int recved_size;
while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) { while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) {
@ -597,7 +591,9 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);
*output = img; *output = img;
return 0;
pthread_mutex_unlock(&call->mutex);
return ErrorNone;
} }
/** /**
@ -617,7 +613,11 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr
} }
return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); pthread_mutex_lock(&av->calls[call_index].mutex);
int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size);
pthread_mutex_unlock(&av->calls[call_index].mutex);
return rc;
} }
/** /**
@ -640,12 +640,15 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
pthread_mutex_lock(&call->mutex);
reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h);
int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
if ( rc != VPX_CODEC_OK) { if ( rc != VPX_CODEC_OK) {
LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));
pthread_mutex_unlock(&call->mutex);
return ErrorInternal; return ErrorInternal;
} }
@ -657,13 +660,17 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge; if ( copied + pkt->data.frame.sz > dest_max ) {
pthread_mutex_unlock(&call->mutex);
return ErrorPacketTooLarge;
}
memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
copied += pkt->data.frame.sz; copied += pkt->data.frame.sz;
} }
} }
pthread_mutex_unlock(&call->mutex);
return copied; return copied;
} }
@ -690,6 +697,7 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
pthread_mutex_lock(&call->mutex);
uint8_t packet [RTP_PAYLOAD_SIZE]; uint8_t packet [RTP_PAYLOAD_SIZE];
@ -698,6 +706,8 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
if ( recved_size == ErrorAudioPacketLost ) { if ( recved_size == ErrorAudioPacketLost ) {
int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
pthread_mutex_unlock(&call->mutex);
if ( dec_size < 0 ) { if ( dec_size < 0 ) {
LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
return ErrorInternal; return ErrorInternal;
@ -706,11 +716,14 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
} else if ( recved_size ) { } else if ( recved_size ) {
int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
pthread_mutex_unlock(&call->mutex);
if ( dec_size < 0 ) { if ( dec_size < 0 ) {
LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
return ErrorInternal; return ErrorInternal;
} else return dec_size; } else return dec_size;
} else { } else {
pthread_mutex_unlock(&call->mutex);
return 0; /* Nothing received */ return 0; /* Nothing received */
} }
} }
@ -734,7 +747,11 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr
} }
return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); pthread_mutex_lock(&av->calls[call_index].mutex);
int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
pthread_mutex_unlock(&av->calls[call_index].mutex);
return rc;
} }
/** /**
@ -758,8 +775,12 @@ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t
} }
pthread_mutex_lock(&av->calls[call_index].mutex);
int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max);
pthread_mutex_unlock(&av->calls[call_index].mutex);
if (rc < 0) { if (rc < 0) {
LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc));
return ErrorInternal; return ErrorInternal;