diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c index 3085827c..743d7fcf 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 | */ |
297 | int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) | 299 | int 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 | */ |
360 | int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | 382 | int 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 ) | |||
406 | inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, | 433 | inline__ 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]; |
@@ -586,7 +613,11 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out | |||
586 | */ | 613 | */ |
587 | inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) | 614 | inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) |
588 | { | 615 | { |
589 | if (cii(call_index, av->msi_session)) return ErrorNoCall; | 616 | if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { |
617 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
618 | return ErrorNoCall; | ||
619 | } | ||
620 | |||
590 | 621 | ||
591 | return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); | 622 | return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); |
592 | } | 623 | } |
@@ -604,7 +635,11 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr | |||
604 | */ | 635 | */ |
605 | inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) | 636 | inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) |
606 | { | 637 | { |
607 | if (cii(call_index, av->msi_session)) return ErrorNoCall; | 638 | if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { |
639 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
640 | return ErrorNoCall; | ||
641 | } | ||
642 | |||
608 | 643 | ||
609 | CallSpecific *call = &av->calls[call_index]; | 644 | CallSpecific *call = &av->calls[call_index]; |
610 | 645 | ||
@@ -649,7 +684,11 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i | |||
649 | { | 684 | { |
650 | if ( !dest ) return ErrorInternal; | 685 | if ( !dest ) return ErrorInternal; |
651 | 686 | ||
652 | if (cii(call_index, av->msi_session)) return ErrorNoCall; | 687 | if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { |
688 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
689 | return ErrorNoCall; | ||
690 | } | ||
691 | |||
653 | 692 | ||
654 | CallSpecific *call = &av->calls[call_index]; | 693 | CallSpecific *call = &av->calls[call_index]; |
655 | 694 | ||
@@ -690,7 +729,11 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i | |||
690 | */ | 729 | */ |
691 | inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) | 730 | inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) |
692 | { | 731 | { |
693 | if (cii(call_index, av->msi_session)) return ErrorNoCall; | 732 | if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { |
733 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
734 | return ErrorNoCall; | ||
735 | } | ||
736 | |||
694 | 737 | ||
695 | return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); | 738 | return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); |
696 | } | 739 | } |
@@ -710,7 +753,11 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr | |||
710 | inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, | 753 | inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, |
711 | const int16_t *frame, int frame_size) | 754 | const int16_t *frame, int frame_size) |
712 | { | 755 | { |
713 | if (cii(call_index, av->msi_session)) return ErrorNoCall; | 756 | if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { |
757 | LOGGER_WARNING("Action on inactive call: %d", call_index); | ||
758 | return ErrorNoCall; | ||
759 | } | ||
760 | |||
714 | 761 | ||
715 | int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); | 762 | int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); |
716 | 763 | ||