summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxav/av_test.c74
-rw-r--r--toxav/rtp.c19
-rw-r--r--toxav/rtp.h7
-rw-r--r--toxav/toxav.c193
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
84typedef struct { 84typedef 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}
138void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) 137void 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}
178void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, 142void 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}
190void 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}
198void 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}
226void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) 206void 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}
159void rtp_do(RTPSession *session) 158int 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}
208int rtp_start_receiving(RTPSession* session) 207int 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
52typedef enum { 52enum {
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 */
139void rtp_do(RTPSession *session); 138int 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
39typedef struct ToxAvBitrateAdapter_s { 40typedef 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);
112bool audio_bitrate_invalid(uint32_t bitrate); 114bool audio_bitrate_invalid(uint32_t bitrate);
113bool video_bitrate_invalid(uint32_t bitrate); 115bool video_bitrate_invalid(uint32_t bitrate);
114void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state); 116void invoke_call_state(ToxAV* av, uint32_t friend_number, uint32_t state);
115void qc_do(ToxAVCall* call);
116ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); 117ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
117ToxAVCall* call_get(ToxAV* av, uint32_t friend_number); 118ToxAVCall* call_get(ToxAV* av, uint32_t friend_number);
118void call_remove(ToxAVCall* call); 119void call_remove(ToxAVCall* call);
@@ -120,7 +121,6 @@ bool call_prepare_transmission(ToxAVCall* call);
120void call_kill_transmission(ToxAVCall* call); 121void call_kill_transmission(ToxAVCall* call);
121void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate); 122void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate);
122bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba); 123bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba);
123void ba_update_sent_regular(ToxAvBitrateAdapter* ba);
124 124
125ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error) 125ToxAV* 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
518bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) 564void 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
572bool 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
562bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_bit_rate, bool force, TOXAV_ERR_BIT_RATE* error) 616void 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
624bool 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
935void 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
986ToxAVCall* call_new(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error) 996ToxAVCall* 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)
1208void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate) 1218void 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
1218bool ba_shoud_send_dummy(ToxAvBitrateAdapter* ba) 1227bool 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
1227void 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}