diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-27 00:15:57 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-27 00:15:57 +0200 |
commit | 27e0254a98a32fad89ecc1c19121394754cfda2d (patch) | |
tree | c4de2455df5b9e38e9eee4e6586546de59279f45 /toxav | |
parent | 144fc94d6987c8c6f74d8024af5a5c1738fe4678 (diff) |
Almooooooost
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/av_test.c | 74 | ||||
-rw-r--r-- | toxav/rtp.c | 19 | ||||
-rw-r--r-- | toxav/rtp.h | 7 | ||||
-rw-r--r-- | toxav/toxav.c | 193 |
4 files changed, 135 insertions, 158 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c index 11de0138..8fa493bf 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c | |||
@@ -77,14 +77,13 @@ | |||
77 | #define TEST_REJECT 0 | 77 | #define TEST_REJECT 0 |
78 | #define TEST_CANCEL 0 | 78 | #define TEST_CANCEL 0 |
79 | #define TEST_MUTE_UNMUTE 0 | 79 | #define TEST_MUTE_UNMUTE 0 |
80 | #define TEST_TRANSFER_A 0 | 80 | #define TEST_TRANSFER_A 1 |
81 | #define TEST_TRANSFER_V 1 | 81 | #define TEST_TRANSFER_V 0 |
82 | 82 | ||
83 | 83 | ||
84 | typedef struct { | 84 | typedef struct { |
85 | bool incoming; | 85 | bool incoming; |
86 | uint32_t state; | 86 | uint32_t state; |
87 | uint32_t abitrate; | ||
88 | pthread_mutex_t arb_mutex[1]; | 87 | pthread_mutex_t arb_mutex[1]; |
89 | RingBuffer* arb; /* Audio ring buffer */ | 88 | RingBuffer* arb; /* Audio ring buffer */ |
90 | 89 | ||
@@ -137,43 +136,8 @@ void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool | |||
137 | } | 136 | } |
138 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) | 137 | void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) |
139 | { | 138 | { |
139 | printf("Handling CALL STATE callback: %d\n", state); | ||
140 | ((CallControl*)user_data)->state = state; | 140 | ((CallControl*)user_data)->state = state; |
141 | uint32_t abitrate = ((CallControl*)user_data)->abitrate; | ||
142 | |||
143 | if (state & TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE) { | ||
144 | |||
145 | // /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */ | ||
146 | // switch (abitrate) { | ||
147 | // case 8: abitrate = 16; break; | ||
148 | // case 16: abitrate = 24; break; | ||
149 | // case 24: abitrate = 48; break; | ||
150 | // case 48: abitrate = 64; break; | ||
151 | // default: return; | ||
152 | // } | ||
153 | // | ||
154 | // printf("Increasing bitrate to: %d\n", abitrate); | ||
155 | // toxav_set_audio_bit_rate(av, friend_number, abitrate, 0); | ||
156 | |||
157 | } else if (state & TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE) { | ||
158 | // /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */ | ||
159 | // switch (abitrate) { | ||
160 | // case 16: abitrate = 8; break; | ||
161 | // case 24: abitrate = 16; break; | ||
162 | // case 48: abitrate = 24; break; | ||
163 | // case 64: abitrate = 48; break; | ||
164 | // default: return; | ||
165 | // } | ||
166 | // | ||
167 | // printf("Decreasing bitrate to: %d\n", abitrate); | ||
168 | // toxav_set_audio_bit_rate(av, friend_number, abitrate, 0); | ||
169 | // | ||
170 | } else if (state & TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE) { | ||
171 | |||
172 | } else if (state & TOXAV_CALL_STATE_DECREASE_VIDEO_BITRATE) { | ||
173 | |||
174 | } else { | ||
175 | printf("Handling CALL STATE callback: %d\n", state); | ||
176 | } | ||
177 | } | 141 | } |
178 | void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, | 142 | void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, |
179 | uint16_t width, uint16_t height, | 143 | uint16_t width, uint16_t height, |
@@ -223,6 +187,22 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |||
223 | free(rb_write(cc->arb, f)); | 187 | free(rb_write(cc->arb, f)); |
224 | pthread_mutex_unlock(cc->arb_mutex); | 188 | pthread_mutex_unlock(cc->arb_mutex); |
225 | } | 189 | } |
190 | void t_toxav_audio_bitrate_control_cb(ToxAV *av, uint32_t friend_number, | ||
191 | bool good, uint32_t bit_rate, void *user_data) | ||
192 | { | ||
193 | if (good) | ||
194 | printf ("Set new audio bitrate to: %d\n", bit_rate); | ||
195 | else | ||
196 | printf ("The network is overly saturated with audio bitrate at: %d\n", bit_rate); | ||
197 | } | ||
198 | void t_toxav_video_bitrate_control_cb(ToxAV *av, uint32_t friend_number, | ||
199 | bool good, uint32_t bit_rate, void *user_data) | ||
200 | { | ||
201 | if (good) | ||
202 | printf ("Set new video bitrate to: %d", bit_rate); | ||
203 | else | ||
204 | printf ("The network is overly saturated with video bitrate at: %d", bit_rate); | ||
205 | } | ||
226 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | 206 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) |
227 | { | 207 | { |
228 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { | 208 | if (length == 7 && memcmp("gentoo", data, 7) == 0) { |
@@ -299,12 +279,17 @@ void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxA | |||
299 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); | 279 | toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); |
300 | toxav_callback_receive_video_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC); | 280 | toxav_callback_receive_video_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC); |
301 | toxav_callback_receive_audio_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC); | 281 | toxav_callback_receive_audio_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC); |
282 | toxav_callback_audio_bitrate_control(*AliceAV, t_toxav_audio_bitrate_control_cb, AliceCC); | ||
283 | toxav_callback_video_bitrate_control(*AliceAV, t_toxav_video_bitrate_control_cb, AliceCC); | ||
302 | 284 | ||
303 | /* Bob */ | 285 | /* Bob */ |
304 | toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC); | 286 | toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC); |
305 | toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC); | 287 | toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC); |
306 | toxav_callback_receive_video_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC); | 288 | toxav_callback_receive_video_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC); |
307 | toxav_callback_receive_audio_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC); | 289 | toxav_callback_receive_audio_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC); |
290 | toxav_callback_audio_bitrate_control(*BobAV, t_toxav_audio_bitrate_control_cb, BobCC); | ||
291 | toxav_callback_video_bitrate_control(*BobAV, t_toxav_video_bitrate_control_cb, BobCC); | ||
292 | |||
308 | 293 | ||
309 | printf("Created 2 instances of ToxAV\n"); | 294 | printf("Created 2 instances of ToxAV\n"); |
310 | printf("All set after %llu seconds!\n", time(NULL) - cur_time); | 295 | printf("All set after %llu seconds!\n", time(NULL) - cur_time); |
@@ -760,11 +745,9 @@ int main (int argc, char** argv) | |||
760 | AliceCC.arb = rb_new(16); | 745 | AliceCC.arb = rb_new(16); |
761 | BobCC.arb = rb_new(16); | 746 | BobCC.arb = rb_new(16); |
762 | 747 | ||
763 | AliceCC.abitrate = BobCC.abitrate = 48; | ||
764 | |||
765 | { /* Call */ | 748 | { /* Call */ |
766 | TOXAV_ERR_CALL rc; | 749 | TOXAV_ERR_CALL rc; |
767 | toxav_call(AliceAV, 0, AliceCC.abitrate, 0, &rc); | 750 | toxav_call(AliceAV, 0, 48, 0, &rc); |
768 | 751 | ||
769 | if (rc != TOXAV_ERR_CALL_OK) { | 752 | if (rc != TOXAV_ERR_CALL_OK) { |
770 | printf("toxav_call failed: %d\n", rc); | 753 | printf("toxav_call failed: %d\n", rc); |
@@ -777,7 +760,7 @@ int main (int argc, char** argv) | |||
777 | 760 | ||
778 | { /* Answer */ | 761 | { /* Answer */ |
779 | TOXAV_ERR_ANSWER rc; | 762 | TOXAV_ERR_ANSWER rc; |
780 | toxav_answer(BobAV, 0, BobCC.abitrate, 0, &rc); | 763 | toxav_answer(BobAV, 0, 48, 0, &rc); |
781 | 764 | ||
782 | if (rc != TOXAV_ERR_ANSWER_OK) { | 765 | if (rc != TOXAV_ERR_ANSWER_OK) { |
783 | printf("toxav_answer failed: %d\n", rc); | 766 | printf("toxav_answer failed: %d\n", rc); |
@@ -794,7 +777,6 @@ int main (int argc, char** argv) | |||
794 | exit(1); | 777 | exit(1); |
795 | } | 778 | } |
796 | 779 | ||
797 | |||
798 | int16_t PCM[5760]; | 780 | int16_t PCM[5760]; |
799 | 781 | ||
800 | time_t start_time = time(NULL); | 782 | time_t start_time = time(NULL); |
@@ -802,7 +784,7 @@ int main (int argc, char** argv) | |||
802 | 784 | ||
803 | 785 | ||
804 | /* Start decode thread */ | 786 | /* Start decode thread */ |
805 | struct toxav_thread_data data = { | 787 | struct toxav_thread_data data = { |
806 | .AliceAV = AliceAV, | 788 | .AliceAV = AliceAV, |
807 | .BobAV = BobAV, | 789 | .BobAV = BobAV, |
808 | .sig = 0 | 790 | .sig = 0 |
@@ -827,6 +809,8 @@ int main (int argc, char** argv) | |||
827 | err = Pa_StartStream(adout); | 809 | err = Pa_StartStream(adout); |
828 | assert(err == paNoError); | 810 | assert(err == paNoError); |
829 | 811 | ||
812 | assert(toxav_set_audio_bit_rate(AliceAV, 0, 64, false, NULL)); | ||
813 | |||
830 | /* Start write thread */ | 814 | /* Start write thread */ |
831 | pthread_t t; | 815 | pthread_t t; |
832 | pthread_create(&t, NULL, pa_write_thread, &BobCC); | 816 | pthread_create(&t, NULL, pa_write_thread, &BobCC); |
diff --git a/toxav/rtp.c b/toxav/rtp.c index a48eba20..b16e3d73 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c | |||
@@ -95,7 +95,6 @@ RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num, vo | |||
95 | retu->ssrc = random_int(); | 95 | retu->ssrc = random_int(); |
96 | retu->payload_type = payload_type % 128; | 96 | retu->payload_type = payload_type % 128; |
97 | 97 | ||
98 | retu->tstate = rtp_StateNormal; | ||
99 | retu->m = messenger; | 98 | retu->m = messenger; |
100 | retu->friend_id = friend_num; | 99 | retu->friend_id = friend_num; |
101 | 100 | ||
@@ -156,10 +155,10 @@ void rtp_kill ( RTPSession *session ) | |||
156 | /* And finally free session */ | 155 | /* And finally free session */ |
157 | free ( session ); | 156 | free ( session ); |
158 | } | 157 | } |
159 | void rtp_do(RTPSession *session) | 158 | int rtp_do(RTPSession *session) |
160 | { | 159 | { |
161 | if (!session || !session->rtcp_session) | 160 | if (!session || !session->rtcp_session) |
162 | return; | 161 | return rtp_StateNormal; |
163 | 162 | ||
164 | if (current_time_monotonic() - session->rtcp_session->last_sent_report_ts >= RTCP_REPORT_INTERVAL_MS) { | 163 | if (current_time_monotonic() - session->rtcp_session->last_sent_report_ts >= RTCP_REPORT_INTERVAL_MS) { |
165 | send_rtcp_report(session->rtcp_session, session->m, session->friend_id); | 164 | send_rtcp_report(session->rtcp_session, session->m, session->friend_id); |
@@ -182,7 +181,7 @@ void rtp_do(RTPSession *session) | |||
182 | if (!rb_empty(session->rtcp_session->pl_stats)) { | 181 | if (!rb_empty(session->rtcp_session->pl_stats)) { |
183 | for (i = 0; reports[i] != NULL; i ++) | 182 | for (i = 0; reports[i] != NULL; i ++) |
184 | free(reports[i]); | 183 | free(reports[i]); |
185 | return; /* As some reports are timed out, we need more */ | 184 | return rtp_StateNormal; /* As some reports are timed out, we need more */ |
186 | } | 185 | } |
187 | 186 | ||
188 | /* We have 4 on-time reports so we can proceed */ | 187 | /* We have 4 on-time reports so we can proceed */ |
@@ -194,16 +193,16 @@ void rtp_do(RTPSession *session) | |||
194 | } | 193 | } |
195 | 194 | ||
196 | if (quality <= 90) { | 195 | if (quality <= 90) { |
197 | session->tstate = rtp_StateBad; | ||
198 | LOGGER_WARNING("Stream quality: BAD"); | 196 | LOGGER_WARNING("Stream quality: BAD"); |
197 | return rtp_StateBad; | ||
199 | } else if (quality >= 99) { | 198 | } else if (quality >= 99) { |
200 | session->tstate = rtp_StateGood; | ||
201 | LOGGER_DEBUG("Stream quality: GOOD"); | 199 | LOGGER_DEBUG("Stream quality: GOOD"); |
200 | return rtp_StateGood; | ||
202 | } else { | 201 | } else { |
203 | session->tstate = rtp_StateNormal; | ||
204 | LOGGER_DEBUG("Stream quality: NORMAL"); | 202 | LOGGER_DEBUG("Stream quality: NORMAL"); |
205 | } | 203 | } |
206 | } | 204 | } |
205 | return rtp_StateNormal; | ||
207 | } | 206 | } |
208 | int rtp_start_receiving(RTPSession* session) | 207 | int rtp_start_receiving(RTPSession* session) |
209 | { | 208 | { |
@@ -267,7 +266,7 @@ int rtp_send_data ( RTPSession *session, const uint8_t *data, uint16_t length, b | |||
267 | header->length = 12 /* Minimum header len */ + ( session->cc * size_32 ); | 266 | header->length = 12 /* Minimum header len */ + ( session->cc * size_32 ); |
268 | 267 | ||
269 | uint32_t parsed_len = length + header->length + 1; | 268 | uint32_t parsed_len = length + header->length + 1; |
270 | assert(parsed_len + (session->ext_header ? session->ext_header->length * size_32 : 0) > MAX_RTP_SIZE ); | 269 | assert(parsed_len + (session->ext_header ? session->ext_header->length * size_32 : 0) < MAX_RTP_SIZE ); |
271 | 270 | ||
272 | parsed[0] = session->prefix; | 271 | parsed[0] = session->prefix; |
273 | it = parse_header_out ( header, parsed + 1 ); | 272 | it = parse_header_out ( header, parsed + 1 ); |
@@ -485,7 +484,7 @@ int handle_rtp_packet ( Messenger* m, uint32_t friendnumber, const uint8_t* data | |||
485 | return -1; | 484 | return -1; |
486 | } | 485 | } |
487 | 486 | ||
488 | RTPHeader* header = parse_header_in ( data, length ); | 487 | RTPHeader* header = parse_header_in ( data + 1, length ); |
489 | 488 | ||
490 | if ( !header ) { | 489 | if ( !header ) { |
491 | LOGGER_WARNING("Could not parse message: Header failed to extract!"); | 490 | LOGGER_WARNING("Could not parse message: Header failed to extract!"); |
@@ -494,7 +493,7 @@ int handle_rtp_packet ( Messenger* m, uint32_t friendnumber, const uint8_t* data | |||
494 | 493 | ||
495 | RTPExtHeader* ext_header = NULL; | 494 | RTPExtHeader* ext_header = NULL; |
496 | 495 | ||
497 | uint16_t from_pos = header->length; | 496 | uint16_t from_pos = header->length + 1; |
498 | uint16_t msg_length = length - from_pos; | 497 | uint16_t msg_length = length - from_pos; |
499 | 498 | ||
500 | if ( GET_FLAG_EXTENSION ( header ) ) { | 499 | if ( GET_FLAG_EXTENSION ( header ) ) { |
diff --git a/toxav/rtp.h b/toxav/rtp.h index fe07c4f6..c973d262 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h | |||
@@ -49,11 +49,11 @@ enum { | |||
49 | rtp_TypeVideo, | 49 | rtp_TypeVideo, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | typedef enum { | 52 | enum { |
53 | rtp_StateBad = -1, | 53 | rtp_StateBad = -1, |
54 | rtp_StateNormal, | 54 | rtp_StateNormal, |
55 | rtp_StateGood, | 55 | rtp_StateGood, |
56 | } RTPTransmissionState; | 56 | }; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Standard rtp header. | 59 | * Standard rtp header. |
@@ -114,7 +114,6 @@ typedef struct { | |||
114 | 114 | ||
115 | Messenger *m; | 115 | Messenger *m; |
116 | int friend_id; | 116 | int friend_id; |
117 | RTPTransmissionState tstate; | ||
118 | struct RTCPSession_s *rtcp_session; | 117 | struct RTCPSession_s *rtcp_session; |
119 | 118 | ||
120 | 119 | ||
@@ -136,7 +135,7 @@ void rtp_kill ( RTPSession* session ); | |||
136 | /** | 135 | /** |
137 | * Do periodical rtp work. | 136 | * Do periodical rtp work. |
138 | */ | 137 | */ |
139 | void rtp_do(RTPSession *session); | 138 | int rtp_do(RTPSession *session); |
140 | 139 | ||
141 | /** | 140 | /** |
142 | * By default rtp is in receiving state | 141 | * By default rtp is in receiving state |
diff --git a/toxav/toxav.c b/toxav/toxav.c index 500ca9a8..45b9e5e6 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -35,13 +35,13 @@ | |||
35 | #include <string.h> | 35 | #include <string.h> |
36 | 36 | ||
37 | #define MAX_ENCODE_TIME_US ((1000 / 24) * 1000) | 37 | #define MAX_ENCODE_TIME_US ((1000 / 24) * 1000) |
38 | #define BITRATE_CHANGE_TESTING_TIME_MS 4000 | ||
38 | 39 | ||
39 | typedef struct ToxAvBitrateAdapter_s { | 40 | typedef struct ToxAvBitrateAdapter_s { |
40 | bool active; | 41 | bool active; |
41 | uint32_t cycle_sent; | 42 | uint64_t end_time; |
42 | uint32_t cycle_ratio; | 43 | uint64_t next_send; |
43 | uint32_t cycle_repeat; | 44 | uint64_t next_send_interval; |
44 | uint64_t start_time; | ||
45 | uint32_t bit_rate; | 45 | uint32_t bit_rate; |
46 | } ToxAvBitrateAdapter; | 46 | } ToxAvBitrateAdapter; |
47 | 47 | ||
@@ -93,6 +93,8 @@ struct toxAV { | |||
93 | PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */ | 93 | PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */ |
94 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ | 94 | PAIR(toxav_receive_audio_frame_cb *, void *) acb; /* Audio frame receive callback */ |
95 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ | 95 | PAIR(toxav_receive_video_frame_cb *, void *) vcb; /* Video frame receive callback */ |
96 | PAIR(toxav_audio_bitrate_control_cb *, void *) abcb; /* Audio bitrate control callback */ | ||
97 | PAIR(toxav_video_bitrate_control_cb *, void *) vbcb; /* Video bitrate control callback */ | ||
96 | 98 | ||
97 | /** Decode time measures */ | 99 | /** Decode time measures */ |
98 | int32_t dmssc; /** Measure count */ | 100 | int32_t dmssc; /** Measure count */ |
@@ -112,7 +114,6 @@ int callback_capabilites(void* toxav_inst, MSICall* call); | |||
112 | bool audio_bitrate_invalid(uint32_t bitrate); | 114 | bool audio_bitrate_invalid(uint32_t bitrate); |
113 | bool video_bitrate_invalid(uint32_t bitrate); | 115 | bool video_bitrate_invalid(uint32_t bitrate); |
114 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); | 116 | void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); |
115 | void qc_do(ToxAVCall* call); | ||
116 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); | 117 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); |
117 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); | 118 | ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); |
118 | void call_remove(ToxAVCall* call); | 119 | void call_remove(ToxAVCall* call); |
@@ -120,7 +121,6 @@ bool call_prepare_transmission(ToxAVCall* call); | |||
120 | void call_kill_transmission(ToxAVCall* call); | 121 | void call_kill_transmission(ToxAVCall* call); |
121 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); | 122 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); |
122 | bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba); | 123 | bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba); |
123 | void ba_update_sent_regular(ToxAvBitrateAdapter* ba); | ||
124 | 124 | ||
125 | ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) | 125 | ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) |
126 | { | 126 | { |
@@ -235,13 +235,59 @@ void toxav_iterate(ToxAV* av) | |||
235 | pthread_mutex_lock(i->mutex); | 235 | pthread_mutex_lock(i->mutex); |
236 | pthread_mutex_unlock(av->mutex); | 236 | pthread_mutex_unlock(av->mutex); |
237 | 237 | ||
238 | rtp_do(i->audio.first); | ||
239 | ac_do(i->audio.second); | 238 | ac_do(i->audio.second); |
239 | if (rtp_do(i->audio.first) < 0) { | ||
240 | /* Bad transmission */ | ||
241 | |||
242 | uint32_t bb = i->audio_bit_rate; | ||
243 | |||
244 | if (i->aba.active) { | ||
245 | bb = i->aba.bit_rate; | ||
246 | /* Stop sending dummy packets */ | ||
247 | memset(&i->aba, 0, sizeof(i->aba)); | ||
248 | } | ||
249 | |||
250 | /* Notify app */ | ||
251 | if (av->abcb.first) | ||
252 | av->abcb.first (av, i->friend_id, false, bb, av->abcb.second); | ||
253 | } else if (i->aba.active && i->aba.end_time < current_time_monotonic()) { | ||
254 | |||
255 | i->audio_bit_rate = i->aba.bit_rate; | ||
256 | |||
257 | /* Notify user about the new bitrate */ | ||
258 | if (av->abcb.first) | ||
259 | av->abcb.first (av, i->friend_id, true, i->aba.bit_rate, av->abcb.second); | ||
260 | |||
261 | /* Stop sending dummy packets */ | ||
262 | memset(&i->aba, 0, sizeof(i->aba)); | ||
263 | } | ||
240 | 264 | ||
241 | rtp_do(i->video.first); | ||
242 | vc_do(i->video.second); | 265 | vc_do(i->video.second); |
243 | 266 | if (rtp_do(i->video.first) < 0) { | |
244 | qc_do(i); | 267 | /* Bad transmission */ |
268 | uint32_t bb = i->video_bit_rate; | ||
269 | |||
270 | if (i->vba.active) { | ||
271 | bb = i->vba.bit_rate; | ||
272 | /* Stop sending dummy packets */ | ||
273 | memset(&i->vba, 0, sizeof(i->vba)); | ||
274 | } | ||
275 | |||
276 | /* Notify app */ | ||
277 | if (av->vbcb.first) | ||
278 | av->vbcb.first (av, i->friend_id, false, bb, av->vbcb.second); | ||
279 | |||
280 | } else if (i->vba.active && i->vba.end_time < current_time_monotonic()) { | ||
281 | |||
282 | i->video_bit_rate = i->vba.bit_rate; | ||
283 | |||
284 | /* Notify user about the new bitrate */ | ||
285 | if (av->vbcb.first) | ||
286 | av->vbcb.first (av, i->friend_id, true, i->vba.bit_rate, av->vbcb.second); | ||
287 | |||
288 | /* Stop sending dummy packets */ | ||
289 | memset(&i->vba, 0, sizeof(i->vba)); | ||
290 | } | ||
245 | 291 | ||
246 | if (i->msi_call->self_capabilities & msi_CapRAudio && | 292 | if (i->msi_call->self_capabilities & msi_CapRAudio && |
247 | i->msi_call->peer_capabilities & msi_CapSAudio) | 293 | i->msi_call->peer_capabilities & msi_CapSAudio) |
@@ -515,7 +561,15 @@ END: | |||
515 | return rc == TOXAV_ERR_CALL_CONTROL_OK; | 561 | return rc == TOXAV_ERR_CALL_CONTROL_OK; |
516 | } | 562 | } |
517 | 563 | ||
518 | bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) | 564 | void toxav_callback_video_bitrate_control(ToxAV* av, toxav_video_bitrate_control_cb* function, void* user_data) |
565 | { | ||
566 | pthread_mutex_lock(av->mutex); | ||
567 | av->vbcb.first = function; | ||
568 | av->vbcb.second = user_data; | ||
569 | pthread_mutex_unlock(av->mutex); | ||
570 | } | ||
571 | |||
572 | bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) | ||
519 | { | 573 | { |
520 | TOXAV_ERR_BIT_RATE rc = TOXAV_ERR_BIT_RATE_OK; | 574 | TOXAV_ERR_BIT_RATE rc = TOXAV_ERR_BIT_RATE_OK; |
521 | ToxAVCall* call; | 575 | ToxAVCall* call; |
@@ -525,7 +579,7 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_ | |||
525 | goto END; | 579 | goto END; |
526 | } | 580 | } |
527 | 581 | ||
528 | if (audio_bitrate_invalid(audio_bit_rate)) { | 582 | if (video_bitrate_invalid(video_bit_rate)) { |
529 | rc = TOXAV_ERR_BIT_RATE_INVALID; | 583 | rc = TOXAV_ERR_BIT_RATE_INVALID; |
530 | goto END; | 584 | goto END; |
531 | } | 585 | } |
@@ -538,17 +592,17 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_ | |||
538 | goto END; | 592 | goto END; |
539 | } | 593 | } |
540 | 594 | ||
541 | if (call->audio_bit_rate == audio_bit_rate && call->aba.active && call->aba.bit_rate == audio_bit_rate) { | 595 | if (call->video_bit_rate == video_bit_rate && call->vba.active && call->vba.bit_rate == video_bit_rate) { |
542 | pthread_mutex_unlock(av->mutex); | 596 | pthread_mutex_unlock(av->mutex); |
543 | goto END; | 597 | goto END; |
544 | } | 598 | } |
545 | 599 | ||
546 | pthread_mutex_lock(call->mutex); | 600 | pthread_mutex_lock(call->mutex); |
547 | if (force) { | 601 | if (force) { |
548 | call->audio_bit_rate = audio_bit_rate; | 602 | call->video_bit_rate = video_bit_rate; |
549 | } else | 603 | } else { |
550 | ba_set(&call->aba, audio_bit_rate); | 604 | ba_set(&call->vba, video_bit_rate); |
551 | 605 | } | |
552 | pthread_mutex_unlock(call->mutex); | 606 | pthread_mutex_unlock(call->mutex); |
553 | pthread_mutex_unlock(av->mutex); | 607 | pthread_mutex_unlock(av->mutex); |
554 | 608 | ||
@@ -559,7 +613,15 @@ END: | |||
559 | return rc == TOXAV_ERR_BIT_RATE_OK; | 613 | return rc == TOXAV_ERR_BIT_RATE_OK; |
560 | } | 614 | } |
561 | 615 | ||
562 | bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) | 616 | void toxav_callback_audio_bitrate_control(ToxAV* av, toxav_audio_bitrate_control_cb* function, void* user_data) |
617 | { | ||
618 | pthread_mutex_lock(av->mutex); | ||
619 | av->abcb.first = function; | ||
620 | av->abcb.second = user_data; | ||
621 | pthread_mutex_unlock(av->mutex); | ||
622 | } | ||
623 | |||
624 | bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) | ||
563 | { | 625 | { |
564 | TOXAV_ERR_BIT_RATE rc = TOXAV_ERR_BIT_RATE_OK; | 626 | TOXAV_ERR_BIT_RATE rc = TOXAV_ERR_BIT_RATE_OK; |
565 | ToxAVCall* call; | 627 | ToxAVCall* call; |
@@ -569,7 +631,7 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
569 | goto END; | 631 | goto END; |
570 | } | 632 | } |
571 | 633 | ||
572 | if (video_bitrate_invalid(video_bit_rate)) { | 634 | if (audio_bitrate_invalid(audio_bit_rate)) { |
573 | rc = TOXAV_ERR_BIT_RATE_INVALID; | 635 | rc = TOXAV_ERR_BIT_RATE_INVALID; |
574 | goto END; | 636 | goto END; |
575 | } | 637 | } |
@@ -582,17 +644,17 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_ | |||
582 | goto END; | 644 | goto END; |
583 | } | 645 | } |
584 | 646 | ||
585 | if (call->video_bit_rate == video_bit_rate && call->vba.active && call->vba.bit_rate == video_bit_rate) { | 647 | if (call->audio_bit_rate == audio_bit_rate && call->aba.active && call->aba.bit_rate == audio_bit_rate) { |
586 | pthread_mutex_unlock(av->mutex); | 648 | pthread_mutex_unlock(av->mutex); |
587 | goto END; | 649 | goto END; |
588 | } | 650 | } |
589 | 651 | ||
590 | pthread_mutex_lock(call->mutex); | 652 | pthread_mutex_lock(call->mutex); |
591 | if (force) { | 653 | if (force) { |
592 | call->video_bit_rate = video_bit_rate; | 654 | call->audio_bit_rate = audio_bit_rate; |
593 | } else { | 655 | } else |
594 | ba_set(&call->vba, video_bit_rate); | 656 | ba_set(&call->aba, audio_bit_rate); |
595 | } | 657 | |
596 | pthread_mutex_unlock(call->mutex); | 658 | pthread_mutex_unlock(call->mutex); |
597 | pthread_mutex_unlock(av->mutex); | 659 | pthread_mutex_unlock(av->mutex); |
598 | 660 | ||
@@ -790,7 +852,6 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc | |||
790 | } | 852 | } |
791 | } | 853 | } |
792 | 854 | ||
793 | ba_update_sent_regular(&call->aba); | ||
794 | } | 855 | } |
795 | 856 | ||
796 | pthread_mutex_unlock(call->mutex_audio); | 857 | pthread_mutex_unlock(call->mutex_audio); |
@@ -932,57 +993,6 @@ void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state) | |||
932 | av->scb.first(av, friend_number, state, av->scb.second); | 993 | av->scb.first(av, friend_number, state, av->scb.second); |
933 | } | 994 | } |
934 | 995 | ||
935 | void qc_do(ToxAVCall* call) | ||
936 | { | ||
937 | /* | ||
938 | switch(call->audio.first->tstate) { | ||
939 | case rtp_StateBad: | ||
940 | LOGGER_DEBUG("Suggesting lower bitrate for audio..."); | ||
941 | call->time_audio_good = 0; | ||
942 | call->last_bad_audio_bit_rate = call->audio_bit_rate; | ||
943 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE); | ||
944 | break; | ||
945 | case rtp_StateGood: | ||
946 | if (call->time_audio_good == 0) | ||
947 | call->time_audio_good = current_time_monotonic(); | ||
948 | else if (current_time_monotonic() - call->time_audio_good >= 30000 && | ||
949 | 64 > call->audio_bit_rate) | ||
950 | if (call->last_bad_audio_bit_rate > call->audio_bit_rate) { | ||
951 | if (current_time_monotonic() - call->time_audio_good >= 45000) | ||
952 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE); | ||
953 | call->last_bad_audio_bit_rate = 0; | ||
954 | } else | ||
955 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE); | ||
956 | break; | ||
957 | case rtp_StateNormal: | ||
958 | call->time_audio_good = 0; | ||
959 | break; | ||
960 | }*/ | ||
961 | /* | ||
962 | switch(call->video.first->tstate) { | ||
963 | case rtp_StateBad: | ||
964 | LOGGER_DEBUG("Suggesting lower bitrate for video..."); | ||
965 | call->time_video_good = 0; | ||
966 | call->last_bad_video_bit_rate = call->video_bit_rate; | ||
967 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_DECREASE_VIDEO_BITRATE); | ||
968 | break; | ||
969 | case rtp_StateGood: | ||
970 | if (call->time_video_good == 0) | ||
971 | call->time_video_good = current_time_monotonic(); | ||
972 | else if (current_time_monotonic() - call->time_video_good >= 30000) | ||
973 | if (call->last_bad_video_bit_rate > call->video_bit_rate) { | ||
974 | if (current_time_monotonic() - call->time_video_good >= 45000) | ||
975 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE); | ||
976 | call->last_bad_video_bit_rate = 0; | ||
977 | } else | ||
978 | invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE); | ||
979 | break; | ||
980 | case rtp_StateNormal: | ||
981 | call->time_video_good = 0; | ||
982 | break; | ||
983 | }*/ | ||
984 | } | ||
985 | |||
986 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) | 996 | ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) |
987 | { | 997 | { |
988 | /* Assumes mutex locked */ | 998 | /* Assumes mutex locked */ |
@@ -1208,34 +1218,19 @@ void call_kill_transmission(ToxAVCall* call) | |||
1208 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate) | 1218 | void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate) |
1209 | { | 1219 | { |
1210 | ba->bit_rate = bit_rate; | 1220 | ba->bit_rate = bit_rate; |
1211 | ba->start_time = current_time_monotonic(); | 1221 | ba->next_send = current_time_monotonic(); |
1212 | ba->cycle_sent = 0; | 1222 | ba->end_time = ba->next_send + BITRATE_CHANGE_TESTING_TIME_MS; |
1213 | ba->cycle_repeat = 3; | 1223 | ba->next_send_interval = 1000; |
1214 | ba->cycle_ratio = 4; | ||
1215 | ba->active = true; | 1224 | ba->active = true; |
1216 | } | 1225 | } |
1217 | 1226 | ||
1218 | bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba) | 1227 | bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba) |
1219 | { | 1228 | { |
1220 | if (!ba->active || ba->cycle_ratio == 0) | 1229 | if (!ba->active || ba->next_send > current_time_monotonic()) |
1221 | return false; | 1230 | return false; |
1222 | 1231 | ||
1223 | if (ba->cycle_sent % ba->cycle_ratio == 0) | 1232 | ba->next_send_interval *= 0.8; |
1224 | return true; | 1233 | ba->next_send = current_time_monotonic() + ba->next_send_interval; |
1225 | } | ||
1226 | |||
1227 | void ba_update_sent_regular(ToxAvBitrateAdapter* ba) | ||
1228 | { | ||
1229 | if (!ba->active || ba->cycle_ratio == 0) { | ||
1230 | ba->active = false; | ||
1231 | return; | ||
1232 | } | ||
1233 | 1234 | ||
1234 | if (ba->cycle_sent % ba->cycle_ratio == 0) { | 1235 | return true; |
1235 | ba->cycle_sent = 0; | 1236 | } \ No newline at end of file |
1236 | |||
1237 | if (--ba->cycle_repeat == 0) | ||
1238 | --ba->cycle_ratio; | ||
1239 | } else | ||
1240 | ++ba->cycle_sent; | ||
1241 | } | ||