diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-17 15:31:14 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-17 15:55:02 +0200 |
commit | 969367b72aebaa2ecfc168cf2e86b20501298c20 (patch) | |
tree | 2424833dcf4e7f726d8394e3327974ee2f2577ad /toxav/av_test.c | |
parent | da6c17222f54c933c826e9c557e66629ee57790f (diff) |
Update latest
Diffstat (limited to 'toxav/av_test.c')
-rw-r--r-- | toxav/av_test.c | 137 |
1 files changed, 110 insertions, 27 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c index 6ebe0421..507a708e 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "../toxav/toxav.h" | 26 | #include "../toxav/toxav.h" |
27 | #include "../toxcore/tox.h" | 27 | #include "../toxcore/tox.h" |
28 | #include "../toxcore/util.h" | 28 | #include "../toxcore/util.h" |
29 | #include "../toxcore/network.h" /* current_time_monotonic() */ | ||
29 | 30 | ||
30 | #define LOGGING | 31 | #define LOGGING |
31 | #include "../toxcore/logger.h" | 32 | #include "../toxcore/logger.h" |
@@ -84,6 +85,9 @@ typedef struct { | |||
84 | bool incoming; | 85 | bool incoming; |
85 | uint32_t state; | 86 | uint32_t state; |
86 | uint32_t abitrate; | 87 | uint32_t abitrate; |
88 | pthread_mutex_t arb_mutex[1]; | ||
89 | RingBuffer* arb; /* Audio ring buffer */ | ||
90 | |||
87 | } CallControl; | 91 | } CallControl; |
88 | 92 | ||
89 | struct toxav_thread_data { | 93 | struct toxav_thread_data { |
@@ -95,6 +99,32 @@ struct toxav_thread_data { | |||
95 | const char* vdout = "AV Test"; /* Video output */ | 99 | const char* vdout = "AV Test"; /* Video output */ |
96 | PaStream* adout = NULL; /* Audio output */ | 100 | PaStream* adout = NULL; /* Audio output */ |
97 | 101 | ||
102 | |||
103 | typedef struct { | ||
104 | uint16_t size; | ||
105 | int16_t data[]; | ||
106 | } frame; | ||
107 | |||
108 | void* pa_write_thread (void* d) | ||
109 | { | ||
110 | /* The purpose of this thread is to make sure Pa_WriteStream will not block | ||
111 | * toxav_iterate thread | ||
112 | */ | ||
113 | CallControl* cc = d; | ||
114 | |||
115 | while (Pa_IsStreamActive(adout)) { | ||
116 | frame* f; | ||
117 | pthread_mutex_lock(cc->arb_mutex); | ||
118 | if (rb_read(cc->arb, (void**)&f)) { | ||
119 | pthread_mutex_unlock(cc->arb_mutex); | ||
120 | Pa_WriteStream(adout, f->data, f->size); | ||
121 | free(f); | ||
122 | } else | ||
123 | pthread_mutex_unlock(cc->arb_mutex); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | |||
98 | /** | 128 | /** |
99 | * Callbacks | 129 | * Callbacks |
100 | */ | 130 | */ |
@@ -106,15 +136,38 @@ void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool | |||
106 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) | 136 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) |
107 | { | 137 | { |
108 | ((CallControl*)user_data)->state = state; | 138 | ((CallControl*)user_data)->state = state; |
139 | uint32_t abitrate = ((CallControl*)user_data)->abitrate; | ||
109 | 140 | ||
110 | if (state & TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE) { | 141 | if (state & TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE) { |
111 | uint32_t bitrate = ((CallControl*)user_data)->abitrate; | ||
112 | 142 | ||
113 | if (bitrate < 64) { | 143 | // /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */ |
114 | printf("Changing bitrate to: %d\n", 64); | 144 | // switch (abitrate) { |
115 | toxav_set_audio_bit_rate(av, friend_number, 64, 0); | 145 | // case 8: abitrate = 16; break; |
116 | } | 146 | // case 16: abitrate = 24; break; |
117 | } else if (state & TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE) { | 147 | // case 24: abitrate = 48; break; |
148 | // case 48: abitrate = 64; break; | ||
149 | // default: return; | ||
150 | // } | ||
151 | // | ||
152 | // printf("Increasing bitrate to: %d\n", abitrate); | ||
153 | // toxav_set_audio_bit_rate(av, friend_number, abitrate, 0); | ||
154 | |||
155 | } else if (state & TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE) { | ||
156 | // /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */ | ||
157 | // switch (abitrate) { | ||
158 | // case 16: abitrate = 8; break; | ||
159 | // case 24: abitrate = 16; break; | ||
160 | // case 48: abitrate = 24; break; | ||
161 | // case 64: abitrate = 48; break; | ||
162 | // default: return; | ||
163 | // } | ||
164 | // | ||
165 | // printf("Decreasing bitrate to: %d\n", abitrate); | ||
166 | // toxav_set_audio_bit_rate(av, friend_number, abitrate, 0); | ||
167 | // | ||
168 | } | ||
169 | |||
170 | if (state & TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE) { | ||
118 | 171 | ||
119 | } else { | 172 | } else { |
120 | printf("Handling CALL STATE callback: %d\n", state); | 173 | printf("Handling CALL STATE callback: %d\n", state); |
@@ -158,7 +211,16 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |||
158 | uint32_t sampling_rate, | 211 | uint32_t sampling_rate, |
159 | void *user_data) | 212 | void *user_data) |
160 | { | 213 | { |
161 | Pa_WriteStream(adout, pcm, sample_count/channels); | 214 | CallControl* cc = user_data; |
215 | frame* f = malloc(sizeof(frame) + sample_count * sizeof(int16_t)); | ||
216 | memcpy(f->data, pcm, sample_count); | ||
217 | f->size = sample_count/channels; | ||
218 | |||
219 | pthread_mutex_lock(cc->arb_mutex); | ||
220 | free(rb_write(cc->arb, f)); | ||
221 | pthread_mutex_unlock(cc->arb_mutex); | ||
222 | |||
223 | // Pa_WriteStream(adout, pcm, sample_count/channels); | ||
162 | } | 224 | } |
163 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) | 225 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) |
164 | { | 226 | { |
@@ -220,6 +282,7 @@ void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxA | |||
220 | *BobAV = toxav_new(Bob, &rc); | 282 | *BobAV = toxav_new(Bob, &rc); |
221 | assert(rc == TOXAV_ERR_NEW_OK); | 283 | assert(rc == TOXAV_ERR_NEW_OK); |
222 | 284 | ||
285 | |||
223 | /* Alice */ | 286 | /* Alice */ |
224 | toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC); | 287 | toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC); |
225 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); | 288 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); |
@@ -255,7 +318,9 @@ void* iterate_toxav (void * data) | |||
255 | int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); | 318 | int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); |
256 | 319 | ||
257 | // cvWaitKey(10); | 320 | // cvWaitKey(10); |
258 | c_sleep(10); | 321 | printf("\rSleeping for: %d ", rc); |
322 | fflush(stdout); | ||
323 | c_sleep(rc); | ||
259 | } | 324 | } |
260 | 325 | ||
261 | data_cast->sig = 1; | 326 | data_cast->sig = 1; |
@@ -330,6 +395,7 @@ int print_help (const char* name) | |||
330 | 395 | ||
331 | int main (int argc, char** argv) | 396 | int main (int argc, char** argv) |
332 | { | 397 | { |
398 | freopen("/dev/zero", "w", stderr); | ||
333 | Pa_Initialize(); | 399 | Pa_Initialize(); |
334 | 400 | ||
335 | struct stat st; | 401 | struct stat st; |
@@ -669,7 +735,13 @@ int main (int argc, char** argv) | |||
669 | memset(&AliceCC, 0, sizeof(CallControl)); | 735 | memset(&AliceCC, 0, sizeof(CallControl)); |
670 | memset(&BobCC, 0, sizeof(CallControl)); | 736 | memset(&BobCC, 0, sizeof(CallControl)); |
671 | 737 | ||
672 | AliceCC.abitrate = BobCC.abitrate = 8; | 738 | pthread_mutex_init(AliceCC.arb_mutex, NULL); |
739 | pthread_mutex_init(BobCC.arb_mutex, NULL); | ||
740 | |||
741 | AliceCC.arb = rb_new(16); | ||
742 | BobCC.arb = rb_new(16); | ||
743 | |||
744 | AliceCC.abitrate = BobCC.abitrate = 16; | ||
673 | 745 | ||
674 | { /* Call */ | 746 | { /* Call */ |
675 | TOXAV_ERR_CALL rc; | 747 | TOXAV_ERR_CALL rc; |
@@ -704,21 +776,6 @@ int main (int argc, char** argv) | |||
704 | } | 776 | } |
705 | 777 | ||
706 | 778 | ||
707 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
708 | |||
709 | struct PaStreamParameters output; | ||
710 | output.device = audio_out_dev_idx; | ||
711 | output.channelCount = af_info.channels; | ||
712 | output.sampleFormat = paInt16; | ||
713 | output.suggestedLatency = audio_dev->defaultHighOutputLatency; | ||
714 | output.hostApiSpecificStreamInfo = NULL; | ||
715 | |||
716 | PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL); | ||
717 | assert(err == paNoError); | ||
718 | |||
719 | err = Pa_StartStream(adout); | ||
720 | assert(err == paNoError); | ||
721 | |||
722 | int16_t PCM[5760]; | 779 | int16_t PCM[5760]; |
723 | 780 | ||
724 | time_t start_time = time(NULL); | 781 | time_t start_time = time(NULL); |
@@ -736,8 +793,25 @@ int main (int argc, char** argv) | |||
736 | pthread_create(&dect, NULL, iterate_toxav, &data); | 793 | pthread_create(&dect, NULL, iterate_toxav, &data); |
737 | pthread_detach(dect); | 794 | pthread_detach(dect); |
738 | 795 | ||
796 | |||
797 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
798 | |||
799 | struct PaStreamParameters output; | ||
800 | output.device = audio_out_dev_idx; | ||
801 | output.channelCount = af_info.channels; | ||
802 | output.sampleFormat = paInt16; | ||
803 | output.suggestedLatency = audio_dev->defaultHighOutputLatency; | ||
804 | output.hostApiSpecificStreamInfo = NULL; | ||
805 | |||
806 | PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL); | ||
807 | assert(err == paNoError); | ||
808 | |||
809 | err = Pa_StartStream(adout); | ||
810 | assert(err == paNoError); | ||
811 | |||
739 | printf("Sample rate %d\n", af_info.samplerate); | 812 | printf("Sample rate %d\n", af_info.samplerate); |
740 | while ( start_time + expected_time > time(NULL) ) { | 813 | while ( start_time + expected_time > time(NULL) ) { |
814 | uint64_t enc_start_time = current_time_monotonic(); | ||
741 | int64_t count = sf_read_short(af_handle, PCM, frame_size); | 815 | int64_t count = sf_read_short(af_handle, PCM, frame_size); |
742 | if (count > 0) { | 816 | if (count > 0) { |
743 | TOXAV_ERR_SEND_FRAME rc; | 817 | TOXAV_ERR_SEND_FRAME rc; |
@@ -746,9 +820,10 @@ int main (int argc, char** argv) | |||
746 | } | 820 | } |
747 | } | 821 | } |
748 | iterate_tox(bootstrap, AliceAV, BobAV); | 822 | iterate_tox(bootstrap, AliceAV, BobAV); |
749 | c_sleep(53); | 823 | c_sleep(abs(audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1)); |
750 | } | 824 | } |
751 | 825 | ||
826 | Pa_StopStream(adout); | ||
752 | 827 | ||
753 | printf("Played file in: %lu\n", time(NULL) - start_time); | 828 | printf("Played file in: %lu\n", time(NULL) - start_time); |
754 | 829 | ||
@@ -772,7 +847,15 @@ int main (int argc, char** argv) | |||
772 | while(data.sig != 1) | 847 | while(data.sig != 1) |
773 | pthread_yield(); | 848 | pthread_yield(); |
774 | 849 | ||
775 | Pa_StopStream(adout); | 850 | pthread_mutex_destroy(AliceCC.arb_mutex); |
851 | pthread_mutex_destroy(BobCC.arb_mutex); | ||
852 | |||
853 | void* f = NULL; | ||
854 | while(rb_read(AliceCC.arb, &f)) | ||
855 | free(f); | ||
856 | |||
857 | while(rb_read(BobCC.arb, &f)) | ||
858 | free(f); | ||
776 | 859 | ||
777 | printf("Success!"); | 860 | printf("Success!"); |
778 | } | 861 | } |