diff options
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/av_test.c | 112 | ||||
-rw-r--r-- | toxav/codec.c | 2 | ||||
-rw-r--r-- | toxav/rtp.h | 12 | ||||
-rw-r--r-- | toxav/toxav.c | 33 |
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 | ||
63 | struct toxav_thread_data { | ||
64 | ToxAV* AliceAV; | ||
65 | ToxAV* BobAV; | ||
66 | int32_t sig; | ||
67 | }; | ||
68 | |||
63 | const char* vdout = "AV Test"; | 69 | const char* vdout = "AV Test"; |
64 | uint32_t adout; | 70 | uint32_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 | } |
253 | void* 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 | ||
255 | int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img) | 268 | int 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 | ||
294 | ALCdevice* open_audio_device(const char* audio_out_dev_name) | 305 | ALCdevice* 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 | |||
352 | int main (int argc, char** argv) | 364 | int 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 | ||
205 | void toxav_iterate(ToxAV* av) | 206 | void 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 | ||