summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-07-05 12:25:30 -0400
committerirungentoo <irungentoo@gmail.com>2014-07-05 12:25:30 -0400
commita51f6bbd694e016cb89739da3201d5ad399f306c (patch)
tree01ba3f79e0621e9831229f45a01856524352eb1f /toxav/toxav.c
parent7f1e5ff72038b055aad7a9edd99e2632db56b3dd (diff)
parent9af7c335e7f198e6ac2ebe7554be2b30ffcbfbb4 (diff)
Merge branch 'mannol1-master'
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c117
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
364error:
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 )
431inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, 422inline__ 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;