summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c95
1 files changed, 71 insertions, 24 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index ad8e651f..02c5a970 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -66,6 +66,8 @@ typedef struct _CallSpecific {
66 uint32_t frame_limit; /* largest address written to in frame_buf for current input frame*/ 66 uint32_t frame_limit; /* largest address written to in frame_buf for current input frame*/
67 uint8_t frame_id, frame_outid; /* id of input and output video frame */ 67 uint8_t frame_id, frame_outid; /* id of input and output video frame */
68 void *frame_buf; /* buffer for split video payloads */ 68 void *frame_buf; /* buffer for split video payloads */
69
70 _Bool call_active;
69} CallSpecific; 71} CallSpecific;
70 72
71 73
@@ -296,8 +298,9 @@ int toxav_stop_call ( ToxAv *av, int32_t call_index )
296 */ 298 */
297int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) 299int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video )
298{ 300{
299 if ( !av->msi_session || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { 301 if ( !av->msi_session || cii(call_index, av->msi_session) ||
300 LOGGER_ERROR("Error while starting audio RTP session: invalid call!\n"); 302 !av->msi_session->calls[call_index] || av->calls[call_index].call_active) {
303 LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
301 return ErrorInternal; 304 return ErrorInternal;
302 } 305 }
303 306
@@ -320,6 +323,8 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
320 323
321 if ( !call->crtps[video_index] ) { 324 if ( !call->crtps[video_index] ) {
322 LOGGER_ERROR("Error while starting video RTP session!\n"); 325 LOGGER_ERROR("Error while starting video RTP session!\n");
326
327 rtp_terminate_session(call->crtps[audio_index], av->messenger);
323 return ErrorStartingVideoRtp; 328 return ErrorStartingVideoRtp;
324 } 329 }
325 330
@@ -330,23 +335,40 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
330 call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1); 335 call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);
331 336
332 if (!call->frame_buf) { 337 if (!call->frame_buf) {
338 rtp_terminate_session(call->crtps[audio_index], av->messenger);
339 rtp_terminate_session(call->crtps[video_index], av->messenger);
340 LOGGER_WARNING("Frame buffer allocation failed!");
333 return ErrorInternal; 341 return ErrorInternal;
334 } 342 }
335 343
336 } 344 }
337 345
338 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) return ErrorInternal; 346 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) {
347 rtp_terminate_session(call->crtps[audio_index], av->messenger);
348 rtp_terminate_session(call->crtps[video_index], av->messenger);
349 free(call->frame_buf);
350 LOGGER_WARNING("Jitter buffer creaton failed!");
351 return ErrorInternal;
352 }
339 353
340 call->cs = codec_init_session(codec_settings->audio_bitrate, 354 if ( (call->cs = codec_init_session(codec_settings->audio_bitrate,
341 codec_settings->audio_frame_duration, 355 codec_settings->audio_frame_duration,
342 codec_settings->audio_sample_rate, 356 codec_settings->audio_sample_rate,
343 codec_settings->audio_channels, 357 codec_settings->audio_channels,
344 codec_settings->audio_VAD_tolerance, 358 codec_settings->audio_VAD_tolerance,
345 codec_settings->video_width, 359 codec_settings->video_width,
346 codec_settings->video_height, 360 codec_settings->video_height,
347 codec_settings->video_bitrate); 361 codec_settings->video_bitrate) )) {
348 362 call->call_active = 1;
349 return call->cs ? ErrorNone : ErrorInternal; 363 return ErrorNone;
364 }
365
366 rtp_terminate_session(call->crtps[audio_index], av->messenger);
367 rtp_terminate_session(call->crtps[video_index], av->messenger);
368 free(call->frame_buf);
369 terminate_queue(call->j_buf);
370
371 return ErrorInternal;
350} 372}
351 373
352/** 374/**
@@ -359,22 +381,26 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
359 */ 381 */
360int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) 382int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
361{ 383{
362 if (cii(call_index, av->msi_session)) return ErrorNoCall; 384 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
363 385 LOGGER_WARNING("Action on inactive call: %d", call_index);
386 return ErrorNoCall;
387 }
388
364 CallSpecific *call = &av->calls[call_index]; 389 CallSpecific *call = &av->calls[call_index];
365 390
391 call->call_active = 0;
392
366 if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) { 393 if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) {
367 LOGGER_ERROR("Error while terminating audio RTP session!\n"); 394 LOGGER_ERROR("Error while terminating audio RTP session!\n");
368 return ErrorTerminatingAudioRtp; 395 /*return ErrorTerminatingAudioRtp;*/
369 } 396 }
397 else call->crtps[audio_index] = NULL;
370 398
371 if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) { 399 if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) {
372 LOGGER_ERROR("Error while terminating video RTP session!\n"); 400 LOGGER_ERROR("Error while terminating video RTP session!\n");
373 return ErrorTerminatingVideoRtp; 401 /*return ErrorTerminatingVideoRtp;*/
374 } 402 }
375 403 else call->crtps[video_index] = NULL;
376 call->crtps[audio_index] = NULL;
377 call->crtps[video_index] = NULL;
378 404
379 if ( call->j_buf ) { 405 if ( call->j_buf ) {
380 terminate_queue(call->j_buf); 406 terminate_queue(call->j_buf);
@@ -388,6 +414,7 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
388 LOGGER_DEBUG("Terminated codec session"); 414 LOGGER_DEBUG("Terminated codec session");
389 } else LOGGER_DEBUG("No codec session"); 415 } else LOGGER_DEBUG("No codec session");
390 416
417
391 return ErrorNone; 418 return ErrorNone;
392} 419}
393 420
@@ -406,8 +433,6 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
406inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, 433inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload,
407 unsigned int length ) 434 unsigned int length )
408{ 435{
409 if (cii(call_index, av->msi_session)) return ErrorNoCall;
410
411#define send(data, len) rtp_send_msg(av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, data, len) 436#define send(data, len) rtp_send_msg(av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, data, len)
412 437
413 if (av->calls[call_index].crtps[type - TypeAudio]) { 438 if (av->calls[call_index].crtps[type - TypeAudio]) {
@@ -465,8 +490,6 @@ inline__ int toxav_recv_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy
465{ 490{
466 if ( !dest ) return ErrorInternal; 491 if ( !dest ) return ErrorInternal;
467 492
468 if (cii(call_index, av->msi_session)) return ErrorNoCall;
469
470 CallSpecific *call = &av->calls[call_index]; 493 CallSpecific *call = &av->calls[call_index];
471 494
472 if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession; 495 if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession;
@@ -518,7 +541,11 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
518{ 541{
519 if ( !output ) return ErrorInternal; 542 if ( !output ) return ErrorInternal;
520 543
521 if (cii(call_index, av->msi_session)) return ErrorNoCall; 544 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
545 LOGGER_WARNING("Action on inactive call: %d", call_index);
546 return ErrorNoCall;
547 }
548
522 549
523 uint8_t packet [RTP_PAYLOAD_SIZE]; 550 uint8_t packet [RTP_PAYLOAD_SIZE];
524 CallSpecific *call = &av->calls[call_index]; 551 CallSpecific *call = &av->calls[call_index];
@@ -584,7 +611,11 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out
584 */ 611 */
585inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) 612inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size)
586{ 613{
587 if (cii(call_index, av->msi_session)) return ErrorNoCall; 614 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
615 LOGGER_WARNING("Action on inactive call: %d", call_index);
616 return ErrorNoCall;
617 }
618
588 619
589 return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); 620 return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size);
590} 621}
@@ -602,7 +633,11 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr
602 */ 633 */
603inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) 634inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input)
604{ 635{
605 if (cii(call_index, av->msi_session)) return ErrorNoCall; 636 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
637 LOGGER_WARNING("Action on inactive call: %d", call_index);
638 return ErrorNoCall;
639 }
640
606 641
607 CallSpecific *call = &av->calls[call_index]; 642 CallSpecific *call = &av->calls[call_index];
608 643
@@ -647,7 +682,11 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
647{ 682{
648 if ( !dest ) return ErrorInternal; 683 if ( !dest ) return ErrorInternal;
649 684
650 if (cii(call_index, av->msi_session)) return ErrorNoCall; 685 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
686 LOGGER_WARNING("Action on inactive call: %d", call_index);
687 return ErrorNoCall;
688 }
689
651 690
652 CallSpecific *call = &av->calls[call_index]; 691 CallSpecific *call = &av->calls[call_index];
653 692
@@ -688,7 +727,11 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
688 */ 727 */
689inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) 728inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size)
690{ 729{
691 if (cii(call_index, av->msi_session)) return ErrorNoCall; 730 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
731 LOGGER_WARNING("Action on inactive call: %d", call_index);
732 return ErrorNoCall;
733 }
734
692 735
693 return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); 736 return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
694} 737}
@@ -708,7 +751,11 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr
708inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, 751inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max,
709 const int16_t *frame, int frame_size) 752 const int16_t *frame, int frame_size)
710{ 753{
711 if (cii(call_index, av->msi_session)) return ErrorNoCall; 754 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
755 LOGGER_WARNING("Action on inactive call: %d", call_index);
756 return ErrorNoCall;
757 }
758
712 759
713 int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); 760 int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max);
714 761