summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxav/av_test.c61
-rw-r--r--toxav/codec.c10
-rw-r--r--toxav/rtp.c7
-rw-r--r--toxav/toxav.c33
-rw-r--r--toxav/toxav.h6
5 files changed, 91 insertions, 26 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c
index 01484249..46fd97e1 100644
--- a/toxav/av_test.c
+++ b/toxav/av_test.c
@@ -39,6 +39,7 @@
39typedef struct { 39typedef struct {
40 bool incoming; 40 bool incoming;
41 uint32_t state; 41 uint32_t state;
42 uint32_t output_source;
42} CallControl; 43} CallControl;
43 44
44const char* stringify_state(TOXAV_CALL_STATE s) 45const char* stringify_state(TOXAV_CALL_STATE s)
@@ -58,6 +59,8 @@ const char* stringify_state(TOXAV_CALL_STATE s)
58}; 59};
59 60
60 61
62int device_play_frame(uint32_t source, const int16_t* PCM, size_t size);
63
61/** 64/**
62 * Callbacks 65 * Callbacks
63 */ 66 */
@@ -86,7 +89,7 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
86 uint32_t sampling_rate, 89 uint32_t sampling_rate,
87 void *user_data) 90 void *user_data)
88{ 91{
89 printf("Handling AUDIO FRAME callback\n"); 92 device_play_frame(((CallControl*)user_data)->output_source, pcm, sample_count);
90} 93}
91void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) 94void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
92{ 95{
@@ -173,7 +176,7 @@ int device_read_frame(ALCdevice* device, int32_t frame_dur, int16_t* PCM, size_t
173 return f_size; 176 return f_size;
174} 177}
175 178
176int device_play_frame(uint32_t source, int16_t* PCM, size_t size) 179int device_play_frame(uint32_t source, const int16_t* PCM, size_t size)
177{ 180{
178 uint32_t bufid; 181 uint32_t bufid;
179 int32_t processed, queued; 182 int32_t processed, queued;
@@ -604,17 +607,67 @@ int main (int argc, char** argv)
604 if (TEST_TRANSFER_A) { /* Audio encoding/decoding and transfer */ 607 if (TEST_TRANSFER_A) { /* Audio encoding/decoding and transfer */
605 printf("\nTrying audio enc/dec...\n"); 608 printf("\nTrying audio enc/dec...\n");
606 609
610 memset(&AliceCC, 0, sizeof(CallControl));
611 memset(&BobCC, 0, sizeof(CallControl));
612
613 AliceCC.output_source = BobCC.output_source = source;
614
615 {
616 TOXAV_ERR_CALL rc;
617 toxav_call(AliceAV, 0, 48, 0, &rc);
618
619 if (rc != TOXAV_ERR_CALL_OK) {
620 printf("toxav_call failed: %d\n", rc);
621 exit(1);
622 }
623 }
624
625 while (!BobCC.incoming)
626 iterate(Bsn, AliceAV, BobAV);
627
628 {
629 TOXAV_ERR_ANSWER rc;
630 toxav_answer(BobAV, 0, 48, 0, &rc);
631
632 if (rc != TOXAV_ERR_ANSWER_OK) {
633 printf("toxav_answer failed: %d\n", rc);
634 exit(1);
635 }
636 }
637
638 iterate(Bsn, AliceAV, BobAV);
639
607 int16_t PCM[10000]; 640 int16_t PCM[10000];
608 time_t start_time = time(NULL); 641 time_t start_time = time(NULL);
609 642
610 /* Run for 5 seconds */ 643 /* Run for 5 seconds */
611 while ( start_time + 10 > time(NULL) ) { 644 while ( start_time + 10 > time(NULL) ) {
612 int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM)); 645 int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM));
613 if (frame_size > 0) 646 if (frame_size > 0) {
614 device_play_frame(source, PCM, frame_size); 647 TOXAV_ERR_SEND_FRAME rc;
648 if (toxav_send_audio_frame(AliceAV, 0, PCM, frame_size, 2, 48000, &rc) == false) {
649 printf("Error sending frame of size %d: %d\n", frame_size, rc);
650 exit (1);
651 }
652 }
653
654 iterate(Bsn, AliceAV, BobAV);
615// c_sleep(20); 655// c_sleep(20);
616 } 656 }
617 657
658 {
659 TOXAV_ERR_CALL_CONTROL rc;
660 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
661
662 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
663 printf("toxav_call_control failed: %d\n", rc);
664 exit(1);
665 }
666 }
667
668 iterate(Bsn, AliceAV, BobAV);
669 assert(BobCC.state == TOXAV_CALL_STATE_END);
670
618 printf("Success!"); 671 printf("Success!");
619 } 672 }
620 673
diff --git a/toxav/codec.c b/toxav/codec.c
index bf94115e..80975b70 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -245,7 +245,7 @@ void cs_do(CSSession *cs)
245 /* Codec session should always be protected by call mutex so no need to check for cs validity 245 /* Codec session should always be protected by call mutex so no need to check for cs validity
246 */ 246 */
247 247
248 if (!cs) 248 if (!cs)
249 return; 249 return;
250 250
251 Payload *p; 251 Payload *p;
@@ -258,7 +258,7 @@ void cs_do(CSSession *cs)
258 if (cs->audio_decoder) { /* If receiving enabled */ 258 if (cs->audio_decoder) { /* If receiving enabled */
259 RTPMessage *msg; 259 RTPMessage *msg;
260 260
261 uint16_t fsize = 5760; /* Max frame size for 48 kHz */ 261 uint16_t fsize = 16000; /* Max frame size for 48 kHz */
262 int16_t tmp[fsize * 2]; 262 int16_t tmp[fsize * 2];
263 263
264 while ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) { 264 while ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) {
@@ -284,6 +284,7 @@ void cs_do(CSSession *cs)
284 continue; 284 continue;
285 } 285 }
286 286
287 LOGGER_DEBUG("Decoding packet of length: %d", msg->length);
287 rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, fsize, 0); 288 rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, fsize, 0);
288 rtp_free_msg(NULL, msg); 289 rtp_free_msg(NULL, msg);
289 } 290 }
@@ -741,8 +742,9 @@ void queue_message(RTPSession *session, RTPMessage *msg)
741 */ 742 */
742 CSSession *cs = session->cs; 743 CSSession *cs = session->cs;
743 744
744 if (!cs) return; 745 if (!cs)
745 746 return;
747
746 /* Audio */ 748 /* Audio */
747 if (session->payload_type == rtp_TypeAudio % 128) { 749 if (session->payload_type == rtp_TypeAudio % 128) {
748 pthread_mutex_lock(cs->queue_mutex); 750 pthread_mutex_lock(cs->queue_mutex);
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 8319c7dc..e5f45310 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -363,7 +363,6 @@ int rtp_handle_packet ( Messenger *m, int32_t friendnumber, const uint8_t *data,
363 } 363 }
364 364
365 queue_message(session, msg); 365 queue_message(session, msg);
366
367 return 0; 366 return 0;
368} 367}
369 368
@@ -427,8 +426,6 @@ RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num )
427 return NULL; 426 return NULL;
428 } 427 }
429 428
430 LOGGER_DEBUG("Registered packet handler: pt: %d; fid: %d", payload_type, friend_num);
431
432 retu->version = RTP_VERSION; /* It's always 2 */ 429 retu->version = RTP_VERSION; /* It's always 2 */
433 retu->padding = 0; /* If some additional data is needed about the packet */ 430 retu->padding = 0; /* If some additional data is needed about the packet */
434 retu->extension = 0; /* If extension to header is needed */ 431 retu->extension = 0; /* If extension to header is needed */
@@ -467,7 +464,7 @@ void rtp_kill ( RTPSession *session )
467{ 464{
468 if ( !session ) return; 465 if ( !session ) return;
469 466
470 custom_lossy_packet_registerhandler(session->m, session->dest, session->prefix, NULL, NULL); 467 rtp_stop_receiving (session);
471 468
472 free ( session->ext_header ); 469 free ( session->ext_header );
473 free ( session->csrc ); 470 free ( session->csrc );
@@ -483,6 +480,7 @@ int rtp_start_receiving(RTPSession* session)
483 if (session == NULL) 480 if (session == NULL)
484 return 0; 481 return 0;
485 482
483 LOGGER_DEBUG("Registering packet handler: pt: %d; friend: %d", session->prefix, session->dest);
486 return custom_lossy_packet_registerhandler(session->m, session->dest, session->prefix, 484 return custom_lossy_packet_registerhandler(session->m, session->dest, session->prefix,
487 rtp_handle_packet, session); 485 rtp_handle_packet, session);
488} 486}
@@ -492,6 +490,7 @@ int rtp_stop_receiving(RTPSession* session)
492 if (session == NULL) 490 if (session == NULL)
493 return 0; 491 return 0;
494 492
493 LOGGER_DEBUG("Unregistering packet handler: pt: %d; friend: %d", session->prefix, session->dest);
495 return custom_lossy_packet_registerhandler(session->m, session->dest, session->prefix, 494 return custom_lossy_packet_registerhandler(session->m, session->dest, session->prefix,
496 NULL, NULL); 495 NULL, NULL);
497} 496}
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 78243ae6..7cf8cec4 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -215,13 +215,6 @@ void toxav_iteration(ToxAV* av)
215 for (; i; i = i->next) { 215 for (; i; i = i->next) {
216 if (i->active) { 216 if (i->active) {
217 pthread_mutex_lock(i->mutex_decoding); 217 pthread_mutex_lock(i->mutex_decoding);
218
219 /* TODO make AV synchronisation */
220 if (av->racb.first)
221 av->racb.first(av, i->friend_id, av->racb.second);
222 if (av->rvcb.first)
223 av->rvcb.first(av, i->friend_id, av->rvcb.second);
224
225 pthread_mutex_unlock(av->mutex); 218 pthread_mutex_unlock(av->mutex);
226 cs_do(i->cs); 219 cs_do(i->cs);
227 rc = MIN(i->cs->last_packet_frame_duration, rc); 220 rc = MIN(i->cs->last_packet_frame_duration, rc);
@@ -304,6 +297,11 @@ bool toxav_answer(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, ui
304 goto END; 297 goto END;
305 } 298 }
306 299
300 if (!call_prepare_transmission(call)) {
301 rc = TOXAV_ERR_ANSWER_MALLOC;
302 goto END;
303 }
304
307 call->s_audio_b = audio_bit_rate; 305 call->s_audio_b = audio_bit_rate;
308 call->s_video_b = video_bit_rate; 306 call->s_video_b = video_bit_rate;
309 307
@@ -645,7 +643,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
645 goto END; 643 goto END;
646 } 644 }
647 645
648 if ( channels != 1 || channels != 2 ) { 646 if ( channels != 1 && channels != 2 ) {
649 pthread_mutex_unlock(call->mutex_audio_sending); 647 pthread_mutex_unlock(call->mutex_audio_sending);
650 rc = TOXAV_ERR_SEND_FRAME_INVALID; 648 rc = TOXAV_ERR_SEND_FRAME_INVALID;
651 goto END; 649 goto END;
@@ -666,8 +664,12 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
666 goto END; 664 goto END;
667 } 665 }
668 666
669 vrc = rtp_send_msg(call->rtps[audio_index], dest, vrc); 667 if (rtp_send_msg(call->rtps[audio_index], dest, vrc) != 0) {
670 /* TODO check for error? */ 668 LOGGER_WARNING("Failed to send audio packet");
669 rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
670 }
671
672 LOGGER_DEBUG("Sent packet of size: %d (o %d)", vrc, sample_count);
671 } 673 }
672 674
673 pthread_mutex_unlock(call->mutex_audio_sending); 675 pthread_mutex_unlock(call->mutex_audio_sending);
@@ -965,7 +967,10 @@ bool call_prepare_transmission(ToxAVCall* call)
965 goto FAILURE; 967 goto FAILURE;
966 } 968 }
967 969
968 rtp_start_receiving(call->rtps[audio_index]); 970 if (rtp_start_receiving(call->rtps[audio_index]) != 0) {
971 LOGGER_WARNING("Failed to enable audio receiving!");
972 goto FAILURE;
973 }
969 } 974 }
970 975
971 { /* Prepare video */ 976 { /* Prepare video */
@@ -984,13 +989,15 @@ bool call_prepare_transmission(ToxAVCall* call)
984 goto FAILURE; 989 goto FAILURE;
985 } 990 }
986 991
987
988 if (cs_enable_video_receiving(call->cs) != 0) { 992 if (cs_enable_video_receiving(call->cs) != 0) {
989 LOGGER_WARNING("Failed to enable video receiving!"); 993 LOGGER_WARNING("Failed to enable video receiving!");
990 goto FAILURE; 994 goto FAILURE;
991 } 995 }
992 996
993 rtp_start_receiving(call->rtps[audio_index]); 997 if (rtp_start_receiving(call->rtps[video_index]) != 0) {
998 LOGGER_WARNING("Failed to enable audio receiving!");
999 goto FAILURE;
1000 }
994 } 1001 }
995 1002
996 call->active = 1; 1003 call->active = 1;
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 101047ed..571282ed 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -380,7 +380,11 @@ typedef enum TOXAV_ERR_SEND_FRAME {
380 * One of the frame parameters was invalid. E.g. the resolution may be too 380 * One of the frame parameters was invalid. E.g. the resolution may be too
381 * small or too large, or the audio sampling rate may be unsupported. 381 * small or too large, or the audio sampling rate may be unsupported.
382 */ 382 */
383 TOXAV_ERR_SEND_FRAME_INVALID 383 TOXAV_ERR_SEND_FRAME_INVALID,
384 /**
385 * Failed to push frame through rtp interface.
386 */
387 TOXAV_ERR_SEND_FRAME_RTP_FAILED
384} TOXAV_ERR_SEND_FRAME; 388} TOXAV_ERR_SEND_FRAME;
385/** 389/**
386 * The function type for the `request_video_frame` callback. 390 * The function type for the `request_video_frame` callback.