diff options
author | irungentoo <irungentoo@gmail.com> | 2014-07-05 12:25:30 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-07-05 12:25:30 -0400 |
commit | a51f6bbd694e016cb89739da3201d5ad399f306c (patch) | |
tree | 01ba3f79e0621e9831229f45a01856524352eb1f /toxav/toxav.c | |
parent | 7f1e5ff72038b055aad7a9edd99e2632db56b3dd (diff) | |
parent | 9af7c335e7f198e6ac2ebe7554be2b30ffcbfbb4 (diff) |
Merge branch 'mannol1-master'
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 117 |
1 files changed, 69 insertions, 48 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c index b97f84ea..9a1c5e3e 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -68,6 +68,7 @@ typedef struct _CallSpecific { | |||
68 | void *frame_buf; /* buffer for split video payloads */ | 68 | void *frame_buf; /* buffer for split video payloads */ |
69 | 69 | ||
70 | _Bool call_active; | 70 | _Bool call_active; |
71 | pthread_mutex_t mutex; | ||
71 | } CallSpecific; | 72 | } CallSpecific; |
72 | 73 | ||
73 | 74 | ||
@@ -312,7 +313,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin | |||
312 | 313 | ||
313 | if ( !call->crtps[audio_index] ) { | 314 | if ( !call->crtps[audio_index] ) { |
314 | LOGGER_ERROR("Error while starting audio RTP session!\n"); | 315 | LOGGER_ERROR("Error while starting audio RTP session!\n"); |
315 | return ErrorStartingAudioRtp; | 316 | return ErrorInternal; |
316 | } | 317 | } |
317 | 318 | ||
318 | 319 | ||
@@ -323,9 +324,7 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin | |||
323 | 324 | ||
324 | if ( !call->crtps[video_index] ) { | 325 | if ( !call->crtps[video_index] ) { |
325 | LOGGER_ERROR("Error while starting video RTP session!\n"); | 326 | LOGGER_ERROR("Error while starting video RTP session!\n"); |
326 | 327 | goto error; | |
327 | rtp_terminate_session(call->crtps[audio_index], av->messenger); | ||
328 | return ErrorStartingVideoRtp; | ||
329 | } | 328 | } |
330 | 329 | ||
331 | call->frame_limit = 0; | 330 | call->frame_limit = 0; |
@@ -335,20 +334,15 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin | |||
335 | call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1); | 334 | call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1); |
336 | 335 | ||
337 | if (!call->frame_buf) { | 336 | 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!"); | 337 | LOGGER_WARNING("Frame buffer allocation failed!"); |
341 | return ErrorInternal; | 338 | goto error; |
342 | } | 339 | } |
343 | 340 | ||
344 | } | 341 | } |
345 | 342 | ||
346 | if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) { | 343 | 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!"); | 344 | LOGGER_WARNING("Jitter buffer creaton failed!"); |
351 | return ErrorInternal; | 345 | goto error; |
352 | } | 346 | } |
353 | 347 | ||
354 | if ( (call->cs = codec_init_session(codec_settings->audio_bitrate, | 348 | 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 | |||
359 | codec_settings->video_width, | 353 | codec_settings->video_width, |
360 | codec_settings->video_height, | 354 | codec_settings->video_height, |
361 | codec_settings->video_bitrate) )) { | 355 | codec_settings->video_bitrate) )) { |
356 | |||
357 | if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; | ||
358 | |||
362 | call->call_active = 1; | 359 | call->call_active = 1; |
360 | |||
363 | return ErrorNone; | 361 | return ErrorNone; |
364 | } | 362 | } |
365 | 363 | ||
364 | error: | ||
366 | rtp_terminate_session(call->crtps[audio_index], av->messenger); | 365 | rtp_terminate_session(call->crtps[audio_index], av->messenger); |
367 | rtp_terminate_session(call->crtps[video_index], av->messenger); | 366 | rtp_terminate_session(call->crtps[video_index], av->messenger); |
368 | free(call->frame_buf); | 367 | free(call->frame_buf); |
369 | terminate_queue(call->j_buf); | 368 | terminate_queue(call->j_buf); |
369 | codec_terminate_session(call->cs); | ||
370 | 370 | ||
371 | return ErrorInternal; | 371 | return ErrorInternal; |
372 | } | 372 | } |
@@ -388,30 +388,21 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | |||
388 | 388 | ||
389 | CallSpecific *call = &av->calls[call_index]; | 389 | CallSpecific *call = &av->calls[call_index]; |
390 | 390 | ||
391 | call->call_active = 0; | 391 | pthread_mutex_lock(&call->mutex); |
392 | |||
393 | if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) { | ||
394 | LOGGER_ERROR("Error while terminating audio RTP session!\n"); | ||
395 | /*return ErrorTerminatingAudioRtp;*/ | ||
396 | } else call->crtps[audio_index] = NULL; | ||
397 | 392 | ||
398 | if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) { | 393 | call->call_active = 0; |
399 | LOGGER_ERROR("Error while terminating video RTP session!\n"); | ||
400 | /*return ErrorTerminatingVideoRtp;*/ | ||
401 | } else call->crtps[video_index] = NULL; | ||
402 | |||
403 | if ( call->j_buf ) { | ||
404 | terminate_queue(call->j_buf); | ||
405 | call->j_buf = NULL; | ||
406 | LOGGER_DEBUG("Terminated j queue"); | ||
407 | } else LOGGER_DEBUG("No j queue"); | ||
408 | 394 | ||
409 | if ( call->cs ) { | 395 | rtp_terminate_session(call->crtps[audio_index], av->messenger); |
410 | codec_terminate_session(call->cs); | 396 | call->crtps[audio_index] = NULL; |
411 | call->cs = NULL; | 397 | rtp_terminate_session(call->crtps[video_index], av->messenger); |
412 | LOGGER_DEBUG("Terminated codec session"); | 398 | call->crtps[video_index] = NULL; |
413 | } else LOGGER_DEBUG("No codec session"); | 399 | terminate_queue(call->j_buf); |
400 | call->j_buf = NULL; | ||
401 | codec_terminate_session(call->cs); | ||
402 | call->cs = NULL; | ||
414 | 403 | ||
404 | pthread_mutex_unlock(&call->mutex); | ||
405 | pthread_mutex_destroy(&call->mutex); | ||
415 | 406 | ||
416 | return ErrorNone; | 407 | return ErrorNone; |
417 | } | 408 | } |
@@ -431,22 +422,23 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | |||
431 | inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, | 422 | inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, |
432 | unsigned int length ) | 423 | unsigned int length ) |
433 | { | 424 | { |
434 | #define send(data, len) rtp_send_msg(av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, data, len) | 425 | CallSpecific *call = &av->calls[call_index]; |
426 | |||
427 | if (call->crtps[type - TypeAudio]) { | ||
435 | 428 | ||
436 | if (av->calls[call_index].crtps[type - TypeAudio]) { | ||
437 | if (type == TypeAudio) { | 429 | if (type == TypeAudio) { |
438 | return send(payload, length); | 430 | return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length); |
439 | } else { | 431 | } else { |
440 | if (length == 0 || length > MAX_VIDEOFRAME_SIZE) { | 432 | if (length == 0 || length > MAX_VIDEOFRAME_SIZE) { |
441 | LOGGER_ERROR("Invalid video frame size: %u\n", length); | 433 | LOGGER_ERROR("Invalid video frame size: %u\n", length); |
442 | return -1; | 434 | return ErrorInternal; |
443 | } | 435 | } |
444 | 436 | ||
445 | /* number of pieces - 1*/ | 437 | /* number of pieces - 1*/ |
446 | uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE; | 438 | uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE; |
447 | 439 | ||
448 | uint8_t load[2 + VIDEOFRAME_PIECE_SIZE]; | 440 | uint8_t load[2 + VIDEOFRAME_PIECE_SIZE]; |
449 | load[0] = av->calls[call_index].frame_outid++; | 441 | load[0] = call->frame_outid++; |
450 | load[1] = 0; | 442 | load[1] = 0; |
451 | 443 | ||
452 | int i; | 444 | int i; |
@@ -455,8 +447,10 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy | |||
455 | memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); | 447 | memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE); |
456 | payload += VIDEOFRAME_PIECE_SIZE; | 448 | payload += VIDEOFRAME_PIECE_SIZE; |
457 | 449 | ||
458 | if (send(load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { | 450 | if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, |
459 | return -1; | 451 | load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) { |
452 | |||
453 | return ErrorInternal; | ||
460 | } | 454 | } |
461 | 455 | ||
462 | load[1]++; | 456 | load[1]++; |
@@ -465,13 +459,12 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy | |||
465 | /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ | 459 | /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */ |
466 | length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; | 460 | length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1; |
467 | memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); | 461 | memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length); |
468 | return send(load, VIDEOFRAME_HEADER_SIZE + length); | 462 | |
463 | return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length); | ||
469 | } | 464 | } |
470 | } else { | 465 | } else { |
471 | return -1; | 466 | return ErrorNoRtpSession; |
472 | } | 467 | } |
473 | |||
474 | #undef send | ||
475 | } | 468 | } |
476 | 469 | ||
477 | /** | 470 | /** |
@@ -545,9 +538,10 @@ inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **out | |||
545 | } | 538 | } |
546 | 539 | ||
547 | 540 | ||
548 | uint8_t packet [RTP_PAYLOAD_SIZE]; | ||
549 | CallSpecific *call = &av->calls[call_index]; | 541 | CallSpecific *call = &av->calls[call_index]; |
542 | pthread_mutex_lock(&call->mutex); | ||
550 | 543 | ||
544 | uint8_t packet [RTP_PAYLOAD_SIZE]; | ||
551 | int recved_size; | 545 | int recved_size; |
552 | 546 | ||
553 | while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) { | 547 | 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 | |||
597 | img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); | 591 | img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); |
598 | 592 | ||
599 | *output = img; | 593 | *output = img; |
600 | return 0; | 594 | |
595 | pthread_mutex_unlock(&call->mutex); | ||
596 | return ErrorNone; | ||
601 | } | 597 | } |
602 | 598 | ||
603 | /** | 599 | /** |
@@ -617,7 +613,11 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr | |||
617 | } | 613 | } |
618 | 614 | ||
619 | 615 | ||
620 | return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); | 616 | pthread_mutex_lock(&av->calls[call_index].mutex); |
617 | int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); | ||
618 | pthread_mutex_unlock(&av->calls[call_index].mutex); | ||
619 | |||
620 | return rc; | ||
621 | } | 621 | } |
622 | 622 | ||
623 | /** | 623 | /** |
@@ -640,12 +640,15 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d | |||
640 | 640 | ||
641 | 641 | ||
642 | CallSpecific *call = &av->calls[call_index]; | 642 | CallSpecific *call = &av->calls[call_index]; |
643 | pthread_mutex_lock(&call->mutex); | ||
644 | |||
643 | reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); | 645 | reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); |
644 | 646 | ||
645 | int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); | 647 | int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); |
646 | 648 | ||
647 | if ( rc != VPX_CODEC_OK) { | 649 | if ( rc != VPX_CODEC_OK) { |
648 | LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); | 650 | LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); |
651 | pthread_mutex_unlock(&call->mutex); | ||
649 | return ErrorInternal; | 652 | return ErrorInternal; |
650 | } | 653 | } |
651 | 654 | ||
@@ -657,13 +660,17 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d | |||
657 | 660 | ||
658 | while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { | 661 | while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { |
659 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | 662 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { |
660 | if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge; | 663 | if ( copied + pkt->data.frame.sz > dest_max ) { |
664 | pthread_mutex_unlock(&call->mutex); | ||
665 | return ErrorPacketTooLarge; | ||
666 | } | ||
661 | 667 | ||
662 | memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); | 668 | memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); |
663 | copied += pkt->data.frame.sz; | 669 | copied += pkt->data.frame.sz; |
664 | } | 670 | } |
665 | } | 671 | } |
666 | 672 | ||
673 | pthread_mutex_unlock(&call->mutex); | ||
667 | return copied; | 674 | return copied; |
668 | } | 675 | } |
669 | 676 | ||
@@ -690,6 +697,7 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i | |||
690 | 697 | ||
691 | 698 | ||
692 | CallSpecific *call = &av->calls[call_index]; | 699 | CallSpecific *call = &av->calls[call_index]; |
700 | pthread_mutex_lock(&call->mutex); | ||
693 | 701 | ||
694 | uint8_t packet [RTP_PAYLOAD_SIZE]; | 702 | uint8_t packet [RTP_PAYLOAD_SIZE]; |
695 | 703 | ||
@@ -698,6 +706,8 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i | |||
698 | if ( recved_size == ErrorAudioPacketLost ) { | 706 | if ( recved_size == ErrorAudioPacketLost ) { |
699 | int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); | 707 | int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); |
700 | 708 | ||
709 | pthread_mutex_unlock(&call->mutex); | ||
710 | |||
701 | if ( dec_size < 0 ) { | 711 | if ( dec_size < 0 ) { |
702 | LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); | 712 | LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); |
703 | return ErrorInternal; | 713 | return ErrorInternal; |
@@ -706,11 +716,14 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i | |||
706 | } else if ( recved_size ) { | 716 | } else if ( recved_size ) { |
707 | int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); | 717 | int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); |
708 | 718 | ||
719 | pthread_mutex_unlock(&call->mutex); | ||
720 | |||
709 | if ( dec_size < 0 ) { | 721 | if ( dec_size < 0 ) { |
710 | LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); | 722 | LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); |
711 | return ErrorInternal; | 723 | return ErrorInternal; |
712 | } else return dec_size; | 724 | } else return dec_size; |
713 | } else { | 725 | } else { |
726 | pthread_mutex_unlock(&call->mutex); | ||
714 | return 0; /* Nothing received */ | 727 | return 0; /* Nothing received */ |
715 | } | 728 | } |
716 | } | 729 | } |
@@ -734,7 +747,11 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr | |||
734 | } | 747 | } |
735 | 748 | ||
736 | 749 | ||
737 | return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); | 750 | pthread_mutex_lock(&av->calls[call_index].mutex); |
751 | int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); | ||
752 | pthread_mutex_unlock(&av->calls[call_index].mutex); | ||
753 | |||
754 | return rc; | ||
738 | } | 755 | } |
739 | 756 | ||
740 | /** | 757 | /** |
@@ -758,8 +775,12 @@ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t | |||
758 | } | 775 | } |
759 | 776 | ||
760 | 777 | ||
778 | pthread_mutex_lock(&av->calls[call_index].mutex); | ||
779 | |||
761 | int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); | 780 | int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); |
762 | 781 | ||
782 | pthread_mutex_unlock(&av->calls[call_index].mutex); | ||
783 | |||
763 | if (rc < 0) { | 784 | if (rc < 0) { |
764 | LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); | 785 | LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); |
765 | return ErrorInternal; | 786 | return ErrorInternal; |