summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
Diffstat (limited to 'toxav')
-rw-r--r--toxav/av_test.c112
-rw-r--r--toxav/codec.c2
-rw-r--r--toxav/rtp.h12
-rw-r--r--toxav/toxav.c33
4 files changed, 92 insertions, 67 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c
index b7260d7d..28d19ec8 100644
--- a/toxav/av_test.c
+++ b/toxav/av_test.c
@@ -60,6 +60,12 @@ typedef struct {
60 uint32_t state; 60 uint32_t state;
61} CallControl; 61} CallControl;
62 62
63struct toxav_thread_data {
64 ToxAV* AliceAV;
65 ToxAV* BobAV;
66 int32_t sig;
67};
68
63const char* vdout = "AV Test"; 69const char* vdout = "AV Test";
64uint32_t adout; 70uint32_t adout;
65 71
@@ -240,17 +246,24 @@ int iterate_tox(Tox* bootstrap, ToxAV* AliceAV, ToxAV* BobAV)
240 tox_do(toxav_get_tox(AliceAV)); 246 tox_do(toxav_get_tox(AliceAV));
241 tox_do(toxav_get_tox(BobAV)); 247 tox_do(toxav_get_tox(BobAV));
242 248
243 toxav_iterate(AliceAV); 249 uint32_t rc = MIN(tox_do_interval(toxav_get_tox(AliceAV)), tox_do_interval(toxav_get_tox(BobAV)));
244 toxav_iterate(BobAV);
245
246 int mina = MIN(tox_do_interval(toxav_get_tox(AliceAV)), toxav_iteration_interval(AliceAV));
247 int minb = MIN(tox_do_interval(toxav_get_tox(BobAV)), toxav_iteration_interval(BobAV));
248
249 int rc = MIN(mina, minb);
250 c_sleep(rc); 250 c_sleep(rc);
251
252 return rc; 251 return rc;
253} 252}
253void* iterate_toxav (void * data)
254{
255 struct toxav_thread_data* data_cast = data;
256 while (data_cast->sig == 0) {
257 toxav_iterate(data_cast->AliceAV);
258 toxav_iterate(data_cast->BobAV);
259// c_sleep(1);
260 }
261
262 data_cast->sig = 1;
263
264 cvDestroyWindow(vdout);
265 pthread_exit(NULL);
266}
254 267
255int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img) 268int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
256{ 269{
@@ -282,13 +295,11 @@ int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
282 } 295 }
283 296
284 297
285// int rc = toxav_send_video_frame(av, friend_number, img->width, img->height, planes[0], planes[1], planes[2], NULL); 298 int rc = toxav_send_video_frame(av, friend_number, img->width, img->height, planes[0], planes[1], planes[2], NULL);
286 t_toxav_receive_video_frame_cb(av, 0, img->width, img->height, (const uint8_t**) planes, strides, NULL);
287 free(planes[0]); 299 free(planes[0]);
288 free(planes[1]); 300 free(planes[1]);
289 free(planes[2]); 301 free(planes[2]);
290// return rc; 302 return rc;
291 return 0;
292} 303}
293 304
294ALCdevice* open_audio_device(const char* audio_out_dev_name) 305ALCdevice* open_audio_device(const char* audio_out_dev_name)
@@ -349,8 +360,10 @@ int print_help (const char* name)
349 return 0; 360 return 0;
350} 361}
351 362
363
352int main (int argc, char** argv) 364int main (int argc, char** argv)
353{ 365{
366 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
354 struct stat st; 367 struct stat st;
355 368
356 /* AV files for testing */ 369 /* AV files for testing */
@@ -409,32 +422,6 @@ int main (int argc, char** argv)
409 } 422 }
410 } 423 }
411 424
412
413 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
414
415 CvCapture* capture = cvCreateFileCapture(vf_name);
416 if (!capture) {
417 printf("Failed to open video file: %s\n", vf_name);
418 exit(1);
419 }
420
421 IplImage* frame;
422 time_t start_time = time(NULL);
423
424 int frame_rate = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
425 while(start_time + 4 > time(NULL)) {
426 frame = cvQueryFrame( capture );
427 if (!frame)
428 break;
429
430 send_opencv_img(NULL, 0, frame);
431 c_sleep(1);
432 }
433
434 cvReleaseCapture(&capture);
435 cvDestroyWindow(vdout);
436
437 return 0;
438 const char* audio_out_dev_name = NULL; 425 const char* audio_out_dev_name = NULL;
439 426
440 int i = 0; 427 int i = 0;
@@ -459,9 +446,6 @@ int main (int argc, char** argv)
459 446
460 initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC); 447 initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC);
461 448
462
463
464
465#define REGULAR_CALL_FLOW(A_BR, V_BR) \ 449#define REGULAR_CALL_FLOW(A_BR, V_BR) \
466 do { \ 450 do { \
467 memset(&AliceCC, 0, sizeof(CallControl)); \ 451 memset(&AliceCC, 0, sizeof(CallControl)); \
@@ -737,6 +721,18 @@ int main (int argc, char** argv)
737 time_t start_time = time(NULL); 721 time_t start_time = time(NULL);
738 time_t expected_time = af_info.frames / af_info.samplerate + 2; 722 time_t expected_time = af_info.frames / af_info.samplerate + 2;
739 723
724
725 /* Start decode thread */
726 struct toxav_thread_data data = {
727 .AliceAV = AliceAV,
728 .BobAV = BobAV,
729 .sig = 0
730 };
731
732 pthread_t dect;
733 pthread_create(&dect, NULL, iterate_toxav, &data);
734 pthread_detach(dect);
735
740 while ( start_time + expected_time > time(NULL) ) { 736 while ( start_time + expected_time > time(NULL) ) {
741 int frame_size = (af_info.samplerate * frame_duration / 1000) * af_info.channels; 737 int frame_size = (af_info.samplerate * frame_duration / 1000) * af_info.channels;
742 738
@@ -772,6 +768,10 @@ int main (int argc, char** argv)
772 iterate_tox(bootstrap, AliceAV, BobAV); 768 iterate_tox(bootstrap, AliceAV, BobAV);
773 assert(BobCC.state == TOXAV_CALL_STATE_END); 769 assert(BobCC.state == TOXAV_CALL_STATE_END);
774 770
771 /* Stop decode thread */
772 data.sig = -1;
773 while(data.sig != 1);
774
775 printf("Success!"); 775 printf("Success!");
776 } 776 }
777 777
@@ -783,7 +783,7 @@ int main (int argc, char** argv)
783 783
784 { /* Call */ 784 { /* Call */
785 TOXAV_ERR_CALL rc; 785 TOXAV_ERR_CALL rc;
786 toxav_call(AliceAV, 0, 0, 500000, &rc); 786 toxav_call(AliceAV, 0, 0, 5000000, &rc);
787 787
788 if (rc != TOXAV_ERR_CALL_OK) { 788 if (rc != TOXAV_ERR_CALL_OK) {
789 printf("toxav_call failed: %d\n", rc); 789 printf("toxav_call failed: %d\n", rc);
@@ -796,7 +796,7 @@ int main (int argc, char** argv)
796 796
797 { /* Answer */ 797 { /* Answer */
798 TOXAV_ERR_ANSWER rc; 798 TOXAV_ERR_ANSWER rc;
799 toxav_answer(BobAV, 0, 0, 500000, &rc); 799 toxav_answer(BobAV, 0, 0, 5000000, &rc);
800 800
801 if (rc != TOXAV_ERR_ANSWER_OK) { 801 if (rc != TOXAV_ERR_ANSWER_OK) {
802 printf("toxav_answer failed: %d\n", rc); 802 printf("toxav_answer failed: %d\n", rc);
@@ -806,7 +806,16 @@ int main (int argc, char** argv)
806 806
807 iterate_tox(bootstrap, AliceAV, BobAV); 807 iterate_tox(bootstrap, AliceAV, BobAV);
808 808
809 cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE); 809 /* Start decode thread */
810 struct toxav_thread_data data = {
811 .AliceAV = AliceAV,
812 .BobAV = BobAV,
813 .sig = 0
814 };
815
816 pthread_t dect;
817 pthread_create(&dect, NULL, iterate_toxav, &data);
818 pthread_detach(dect);
810 819
811 CvCapture* capture = cvCreateFileCapture(vf_name); 820 CvCapture* capture = cvCreateFileCapture(vf_name);
812 if (!capture) { 821 if (!capture) {
@@ -814,23 +823,17 @@ int main (int argc, char** argv)
814 exit(1); 823 exit(1);
815 } 824 }
816 825
817 IplImage* frame;
818 time_t start_time = time(NULL); 826 time_t start_time = time(NULL);
819 827 while(start_time + 6 > time(NULL)) {
820 int frame_rate = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); 828 IplImage* frame = cvQueryFrame( capture );
821 while(start_time + 10 > time(NULL)) {
822 frame = cvQueryFrame( capture );
823 if (!frame) 829 if (!frame)
824 break; 830 break;
825 831
826// cvShowImage(vdout, frame);
827// cvWaitKey(frame_rate);
828 send_opencv_img(AliceAV, 0, frame); 832 send_opencv_img(AliceAV, 0, frame);
829 iterate_tox(bootstrap, AliceAV, BobAV); 833 iterate_tox(bootstrap, AliceAV, BobAV);
830 } 834 }
831 835
832 cvReleaseCapture(&capture); 836 cvReleaseCapture(&capture);
833 cvDestroyWindow(vdout);
834 837
835 { /* Hangup */ 838 { /* Hangup */
836 TOXAV_ERR_CALL_CONTROL rc; 839 TOXAV_ERR_CALL_CONTROL rc;
@@ -845,6 +848,11 @@ int main (int argc, char** argv)
845 iterate_tox(bootstrap, AliceAV, BobAV); 848 iterate_tox(bootstrap, AliceAV, BobAV);
846 assert(BobCC.state == TOXAV_CALL_STATE_END); 849 assert(BobCC.state == TOXAV_CALL_STATE_END);
847 850
851 /* Stop decode thread */
852 printf("Stopping decode thread");
853 data.sig = -1;
854 while(data.sig != 1);
855
848 printf("Success!"); 856 printf("Success!");
849 } 857 }
850 858
diff --git a/toxav/codec.c b/toxav/codec.c
index 4ae5a10b..c3f5d740 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -423,7 +423,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size)
423 return NULL; 423 return NULL;
424 } 424 }
425 425
426 if (create_recursive_mutex(cs->queue_mutex) != 0) { 426 if (pthread_mutex_init(cs->queue_mutex, NULL) != 0) {
427 LOGGER_WARNING("Failed to create recursive mutex!"); 427 LOGGER_WARNING("Failed to create recursive mutex!");
428 free(cs); 428 free(cs);
429 return NULL; 429 return NULL;
diff --git a/toxav/rtp.h b/toxav/rtp.h
index 3bfbb7af..b47be18a 100644
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -28,6 +28,18 @@
28 28
29#include "../toxcore/Messenger.h" 29#include "../toxcore/Messenger.h"
30 30
31#define LOGGED_LOCK(mutex) do { \
32 LOGGER_DEBUG("Locking mutex: %p", mutex);\
33 pthread_mutex_lock(mutex);\
34 LOGGER_DEBUG("Locked mutex: %p", mutex);\
35} while(0)
36
37#define LOGGED_UNLOCK(mutex) do { \
38 LOGGER_DEBUG("Unlocking mutex: %p", mutex);\
39 pthread_mutex_unlock(mutex);\
40 LOGGER_DEBUG("Unlocked mutex: %p", mutex);\
41} while(0)
42
31#define MAX_SEQU_NUM 65535 43#define MAX_SEQU_NUM 65535
32#define MAX_RTP_SIZE 65535 44#define MAX_RTP_SIZE 65535
33 45
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 9febd3a9..54554918 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -47,7 +47,7 @@ typedef struct ToxAVCall_s {
47 47
48 pthread_mutex_t mutex_audio_sending[1]; 48 pthread_mutex_t mutex_audio_sending[1];
49 pthread_mutex_t mutex_video_sending[1]; 49 pthread_mutex_t mutex_video_sending[1];
50 /* Only audio or video can be decoded at one time */ 50 /* Only audio or video can be decoded at the time */
51 pthread_mutex_t mutex_decoding[1]; 51 pthread_mutex_t mutex_decoding[1];
52 52
53 bool active; 53 bool active;
@@ -129,7 +129,8 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error)
129 goto FAILURE; 129 goto FAILURE;
130 } 130 }
131 131
132 if (create_recursive_mutex(av->mutex) == -1) { 132// if (create_recursive_mutex(av->mutex) == -1) {
133 if (pthread_mutex_init(av->mutex, NULL) == -1) {
133 LOGGER_WARNING("Mutex creation failed!"); 134 LOGGER_WARNING("Mutex creation failed!");
134 rc = TOXAV_ERR_NEW_MALLOC; 135 rc = TOXAV_ERR_NEW_MALLOC;
135 goto FAILURE; 136 goto FAILURE;
@@ -204,26 +205,30 @@ uint32_t toxav_iteration_interval(const ToxAV* av)
204 205
205void toxav_iterate(ToxAV* av) 206void toxav_iterate(ToxAV* av)
206{ 207{
207 if (av->calls == NULL) 208 pthread_mutex_lock(av->mutex);
209 if (av->calls == NULL) {
210 pthread_mutex_unlock(av->mutex);
208 return; 211 return;
212 }
209 213
210 uint64_t start = current_time_monotonic(); 214 uint64_t start = current_time_monotonic();
211 uint32_t rc = 500; 215 uint32_t rc = 500;
212 216
213 pthread_mutex_lock(av->mutex);
214 ToxAVCall* i = av->calls[av->calls_head]; 217 ToxAVCall* i = av->calls[av->calls_head];
215 for (; i; i = i->next) { 218 while (i) {
216 if (i->active) { 219 if (i->active) {
217 pthread_mutex_lock(i->mutex_decoding); 220 pthread_mutex_lock(i->mutex_decoding);
218 pthread_mutex_unlock(av->mutex); 221 pthread_mutex_unlock(av->mutex);
222
219 cs_do(i->cs); 223 cs_do(i->cs);
220 rc = MIN(i->cs->last_packet_frame_duration, rc); 224 rc = MIN(i->cs->last_packet_frame_duration, rc);
225
226 pthread_mutex_lock(av->mutex);
221 pthread_mutex_unlock(i->mutex_decoding); 227 pthread_mutex_unlock(i->mutex_decoding);
222 } else 228 i = i->next;
223 continue; 229 }
224
225 pthread_mutex_lock(av->mutex);
226 } 230 }
231 pthread_mutex_unlock(av->mutex);
227 232
228 av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); 233 av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa);
229 av->dmsst += current_time_monotonic() - start; 234 av->dmsst += current_time_monotonic() - start;
@@ -1048,6 +1053,11 @@ void call_kill_transmission(ToxAVCall* call)
1048 1053
1049 call->active = 0; 1054 call->active = 0;
1050 1055
1056 rtp_kill(call->rtps[audio_index]);
1057 call->rtps[audio_index] = NULL;
1058 rtp_kill(call->rtps[video_index]);
1059 call->rtps[video_index] = NULL;
1060
1051 pthread_mutex_lock(call->mutex_audio_sending); 1061 pthread_mutex_lock(call->mutex_audio_sending);
1052 pthread_mutex_unlock(call->mutex_audio_sending); 1062 pthread_mutex_unlock(call->mutex_audio_sending);
1053 pthread_mutex_lock(call->mutex_video_sending); 1063 pthread_mutex_lock(call->mutex_video_sending);
@@ -1055,11 +1065,6 @@ void call_kill_transmission(ToxAVCall* call)
1055 pthread_mutex_lock(call->mutex_decoding); 1065 pthread_mutex_lock(call->mutex_decoding);
1056 pthread_mutex_unlock(call->mutex_decoding); 1066 pthread_mutex_unlock(call->mutex_decoding);
1057 1067
1058 rtp_kill(call->rtps[audio_index]);
1059 call->rtps[audio_index] = NULL;
1060 rtp_kill(call->rtps[video_index]);
1061 call->rtps[video_index] = NULL;
1062
1063 cs_kill(call->cs); 1068 cs_kill(call->cs);
1064 call->cs = NULL; 1069 call->cs = NULL;
1065 1070