summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
authorGregory Mullen (grayhatter) <greg@grayhatter.com>2016-09-11 16:27:03 -0700
committerGregory Mullen (grayhatter) <greg@grayhatter.com>2016-09-17 14:05:51 -0700
commit21f8db12c45bd56293262cd4abfb73cd9abec821 (patch)
tree580729367d00e1eb7e0c4d533777d22af7d7ffc5 /toxav
parent5da85c582d97d746887da407153afc0acf0a4215 (diff)
Make ToxAV stateless
Diffstat (limited to 'toxav')
-rw-r--r--toxav/audio.c13
-rw-r--r--toxav/audio.h6
-rw-r--r--toxav/bwcontroller.c21
-rw-r--r--toxav/bwcontroller.h4
-rw-r--r--toxav/msi.c50
-rw-r--r--toxav/msi.h2
-rw-r--r--toxav/rtp.c6
-rw-r--r--toxav/toxav.c124
-rw-r--r--toxav/toxav.h12
-rw-r--r--toxav/video.c15
-rw-r--r--toxav/video.h6
11 files changed, 133 insertions, 126 deletions
diff --git a/toxav/audio.c b/toxav/audio.c
index 59d1554e..3fb0985e 100644
--- a/toxav/audio.c
+++ b/toxav/audio.c
@@ -43,7 +43,7 @@ bool reconfigure_audio_decoder(ACSession *ac, int32_t sampling_rate, int8_t chan
43 43
44 44
45 45
46ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data) 46ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb)
47{ 47{
48 ACSession *ac = calloc(sizeof(ACSession), 1); 48 ACSession *ac = calloc(sizeof(ACSession), 1);
49 49
@@ -97,8 +97,7 @@ ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_re
97 97
98 ac->av = av; 98 ac->av = av;
99 ac->friend_number = friend_number; 99 ac->friend_number = friend_number;
100 ac->acb.first = cb; 100 ac->on_audio_frame = cb;
101 ac->acb.second = cb_data;
102 101
103 return ac; 102 return ac;
104 103
@@ -125,7 +124,7 @@ void ac_kill(ACSession *ac)
125 LOGGER_DEBUG(ac->log, "Terminated audio handler: %p", ac); 124 LOGGER_DEBUG(ac->log, "Terminated audio handler: %p", ac);
126 free(ac); 125 free(ac);
127} 126}
128void ac_iterate(ACSession *ac) 127void ac_iterate(ACSession *ac, void *userdata)
129{ 128{
130 if (!ac) { 129 if (!ac) {
131 return; 130 return;
@@ -186,11 +185,11 @@ void ac_iterate(ACSession *ac)
186 185
187 if (rc < 0) { 186 if (rc < 0) {
188 LOGGER_WARNING(ac->log, "Decoding error: %s", opus_strerror(rc)); 187 LOGGER_WARNING(ac->log, "Decoding error: %s", opus_strerror(rc));
189 } else if (ac->acb.first) { 188 } else if (ac->on_audio_frame) {
190 ac->lp_frame_duration = (rc * 1000) / ac->lp_sampling_rate; 189 ac->lp_frame_duration = (rc * 1000) / ac->lp_sampling_rate;
191 190
192 ac->acb.first(ac->av, ac->friend_number, tmp, rc, ac->lp_channel_count, 191 ac->on_audio_frame(ac->av, ac->friend_number, tmp, rc, ac->lp_channel_count,
193 ac->lp_sampling_rate, ac->acb.second); 192 ac->lp_sampling_rate, userdata);
194 } 193 }
195 194
196 return; 195 return;
diff --git a/toxav/audio.h b/toxav/audio.h
index 5f9d7f7d..60bad163 100644
--- a/toxav/audio.h
+++ b/toxav/audio.h
@@ -55,12 +55,12 @@ typedef struct ACSession_s {
55 55
56 ToxAV *av; 56 ToxAV *av;
57 uint32_t friend_number; 57 uint32_t friend_number;
58 PAIR(toxav_audio_receive_frame_cb *, void *) acb; /* Audio frame receive callback */ 58 toxav_audio_receive_frame_cb *on_audio_frame; /* Audio frame receive callback */
59} ACSession; 59} ACSession;
60 60
61ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data); 61ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb);
62void ac_kill(ACSession *ac); 62void ac_kill(ACSession *ac);
63void ac_iterate(ACSession *ac); 63void ac_iterate(ACSession *ac, void *userdata);
64int ac_queue_message(void *acp, struct RTPMessage *msg); 64int ac_queue_message(void *acp, struct RTPMessage *msg);
65int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels); 65int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels);
66 66
diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c
index b97135d6..63350f17 100644
--- a/toxav/bwcontroller.c
+++ b/toxav/bwcontroller.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42struct BWController_s { 42struct BWController_s {
43 void (*mcb)(BWController *, uint32_t, float, void *); 43 void (*mcb)(BWController *, uint32_t, float, void *, void *);
44 void *mcb_data; 44 void *mcb_data;
45 45
46 Messenger *m; 46 Messenger *m;
@@ -61,17 +61,18 @@ struct BWController_s {
61 } rcvpkt; /* To calculate average received packet */ 61 } rcvpkt; /* To calculate average received packet */
62}; 62};
63 63
64int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object); 64int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object,
65 void *userdata);
65void send_update(BWController *bwc); 66void send_update(BWController *bwc);
66 67
67BWController *bwc_new(Messenger *m, uint32_t friendnumber, 68BWController *bwc_new(Messenger *m, uint32_t friendnumber,
68 void (*mcb)(BWController *, uint32_t, float, void *), 69 void (*mcb)(BWController *, uint32_t, float, void *, void *),
69 void *udata) 70 void *call_data)
70{ 71{
71 BWController *retu = calloc(sizeof(struct BWController_s), 1); 72 BWController *retu = calloc(sizeof(struct BWController_s), 1);
72 73
73 retu->mcb = mcb; 74 retu->mcb = mcb;
74 retu->mcb_data = udata; 75 retu->mcb_data = call_data;
75 retu->m = m; 76 retu->m = m;
76 retu->friend_number = friendnumber; 77 retu->friend_number = friendnumber;
77 retu->cycle.lsu = retu->cycle.lfu = current_time_monotonic(); 78 retu->cycle.lsu = retu->cycle.lfu = current_time_monotonic();
@@ -179,7 +180,7 @@ void send_update(BWController *bwc)
179 bwc->cycle.lsu = current_time_monotonic(); 180 bwc->cycle.lsu = current_time_monotonic();
180 } 181 }
181} 182}
182static int on_update(BWController *bwc, const struct BWCMessage *msg) 183static int on_update(BWController *bwc, const struct BWCMessage *msg, void *userdata)
183{ 184{
184 LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc); 185 LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc);
185 186
@@ -199,16 +200,18 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
199 if (lost && bwc->mcb) { 200 if (lost && bwc->mcb) {
200 bwc->mcb(bwc, bwc->friend_number, 201 bwc->mcb(bwc, bwc->friend_number,
201 ((float) lost / (recv + lost)), 202 ((float) lost / (recv + lost)),
202 bwc->mcb_data); 203 bwc->mcb_data,
204 userdata);
203 } 205 }
204 206
205 return 0; 207 return 0;
206} 208}
207int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object) 209int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object,
210 void *userdata)
208{ 211{
209 if (length - 1 != sizeof(struct BWCMessage)) { 212 if (length - 1 != sizeof(struct BWCMessage)) {
210 return -1; 213 return -1;
211 } 214 }
212 215
213 return on_update(object, (const struct BWCMessage *)(data + 1)); 216 return on_update(object, (const struct BWCMessage *)(data + 1), userdata);
214} 217}
diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h
index 9542cde5..e2a7229b 100644
--- a/toxav/bwcontroller.h
+++ b/toxav/bwcontroller.h
@@ -27,8 +27,8 @@
27typedef struct BWController_s BWController; 27typedef struct BWController_s BWController;
28 28
29BWController *bwc_new(Messenger *m, uint32_t friendnumber, 29BWController *bwc_new(Messenger *m, uint32_t friendnumber,
30 void (*mcb)(BWController *, uint32_t, float, void *), 30 void (*mcb)(BWController *, uint32_t, float, void *, void *),
31 void *udata); 31 void *call_data);
32void bwc_kill(BWController *bwc); 32void bwc_kill(BWController *bwc);
33 33
34void bwc_feed_avg(BWController *bwc, uint32_t bytes); 34void bwc_feed_avg(BWController *bwc, uint32_t bytes);
diff --git a/toxav/msi.c b/toxav/msi.c
index d80d7c76..be467512 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -81,15 +81,16 @@ int msg_parse_in(Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t le
81uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length); 81uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length);
82static int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg); 82static int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg);
83int send_error(Messenger *m, uint32_t friend_number, MSIError error); 83int send_error(Messenger *m, uint32_t friend_number, MSIError error);
84static int invoke_callback(MSICall *call, MSICallbackID cb); 84static int invoke_callback(MSICall *call, MSICallbackID cb, void *userdata);
85static MSICall *get_call(MSISession *session, uint32_t friend_number); 85static MSICall *get_call(MSISession *session, uint32_t friend_number);
86MSICall *new_call(MSISession *session, uint32_t friend_number); 86MSICall *new_call(MSISession *session, uint32_t friend_number);
87void kill_call(MSICall *call); 87void kill_call(MSICall *call);
88void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data); 88void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data, void *userdata);
89void handle_init(MSICall *call, const MSIMessage *msg); 89void handle_init(MSICall *call, const MSIMessage *msg, void *userdata);
90void handle_push(MSICall *call, const MSIMessage *msg); 90void handle_push(MSICall *call, const MSIMessage *msg, void *userdata);
91void handle_pop(MSICall *call, const MSIMessage *msg); 91void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata);
92void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); 92void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object,
93 void *userdata);
93 94
94 95
95/** 96/**
@@ -479,14 +480,14 @@ int send_error(Messenger *m, uint32_t friend_number, MSIError error)
479 send_message(m, friend_number, &msg); 480 send_message(m, friend_number, &msg);
480 return 0; 481 return 0;
481} 482}
482int invoke_callback(MSICall *call, MSICallbackID cb) 483int invoke_callback(MSICall *call, MSICallbackID cb, void *userdata)
483{ 484{
484 assert(call); 485 assert(call);
485 486
486 if (call->session->callbacks[cb]) { 487 if (call->session->callbacks[cb]) {
487 LOGGER_DEBUG(call->session->messenger->log, "Invoking callback function: %d", cb); 488 LOGGER_DEBUG(call->session->messenger->log, "Invoking callback function: %d", cb);
488 489
489 if (call->session->callbacks[cb](call->session->av, call) != 0) { 490 if (call->session->callbacks[cb](call->session->av, call, userdata) != 0) {
490 LOGGER_WARNING(call->session->messenger->log, 491 LOGGER_WARNING(call->session->messenger->log,
491 "Callback state handling failed, sending error"); 492 "Callback state handling failed, sending error");
492 goto FAILURE; 493 goto FAILURE;
@@ -608,7 +609,7 @@ CLEAR_CONTAINER:
608 free(call); 609 free(call);
609 session->calls = NULL; 610 session->calls = NULL;
610} 611}
611void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data) 612void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data, void *userdata)
612{ 613{
613 (void)m; 614 (void)m;
614 MSISession *session = data; 615 MSISession *session = data;
@@ -625,7 +626,7 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *
625 return; 626 return;
626 } 627 }
627 628
628 invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */ 629 invoke_callback(call, msi_OnPeerTimeout, userdata); /* Failure is ignored */
629 kill_call(call); 630 kill_call(call);
630 pthread_mutex_unlock(session->mutex); 631 pthread_mutex_unlock(session->mutex);
631 } 632 }
@@ -635,7 +636,7 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *
635 break; 636 break;
636 } 637 }
637} 638}
638void handle_init(MSICall *call, const MSIMessage *msg) 639void handle_init(MSICall *call, const MSIMessage *msg, void *userdata)
639{ 640{
640 assert(call); 641 assert(call);
641 LOGGER_DEBUG(call->session->messenger->log, 642 LOGGER_DEBUG(call->session->messenger->log,
@@ -653,7 +654,7 @@ void handle_init(MSICall *call, const MSIMessage *msg)
653 call->peer_capabilities = msg->capabilities.value; 654 call->peer_capabilities = msg->capabilities.value;
654 call->state = msi_CallRequested; 655 call->state = msi_CallRequested;
655 656
656 if (invoke_callback(call, msi_OnInvite) == -1) { 657 if (invoke_callback(call, msi_OnInvite, userdata) == -1) {
657 goto FAILURE; 658 goto FAILURE;
658 } 659 }
659 } 660 }
@@ -697,7 +698,7 @@ FAILURE:
697 send_error(call->session->messenger, call->friend_number, call->error); 698 send_error(call->session->messenger, call->friend_number, call->error);
698 kill_call(call); 699 kill_call(call);
699} 700}
700void handle_push(MSICall *call, const MSIMessage *msg) 701void handle_push(MSICall *call, const MSIMessage *msg, void *userdata)
701{ 702{
702 assert(call); 703 assert(call);
703 704
@@ -718,7 +719,7 @@ void handle_push(MSICall *call, const MSIMessage *msg)
718 719
719 call->peer_capabilities = msg->capabilities.value; 720 call->peer_capabilities = msg->capabilities.value;
720 721
721 if (invoke_callback(call, msi_OnCapabilities) == -1) { 722 if (invoke_callback(call, msi_OnCapabilities, userdata) == -1) {
722 goto FAILURE; 723 goto FAILURE;
723 } 724 }
724 } 725 }
@@ -732,7 +733,7 @@ void handle_push(MSICall *call, const MSIMessage *msg)
732 call->peer_capabilities = msg->capabilities.value; 733 call->peer_capabilities = msg->capabilities.value;
733 call->state = msi_CallActive; 734 call->state = msi_CallActive;
734 735
735 if (invoke_callback(call, msi_OnStart) == -1) { 736 if (invoke_callback(call, msi_OnStart, userdata) == -1) {
736 goto FAILURE; 737 goto FAILURE;
737 } 738 }
738 } 739 }
@@ -752,7 +753,7 @@ FAILURE:
752 send_error(call->session->messenger, call->friend_number, call->error); 753 send_error(call->session->messenger, call->friend_number, call->error);
753 kill_call(call); 754 kill_call(call);
754} 755}
755void handle_pop(MSICall *call, const MSIMessage *msg) 756void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata)
756{ 757{
757 assert(call); 758 assert(call);
758 759
@@ -764,7 +765,7 @@ void handle_pop(MSICall *call, const MSIMessage *msg)
764 if (msg->error.exists) { 765 if (msg->error.exists) {
765 LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value); 766 LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value);
766 call->error = msg->error.value; 767 call->error = msg->error.value;
767 invoke_callback(call, msi_OnError); 768 invoke_callback(call, msi_OnError, userdata);
768 } else { 769 } else {
769 switch (call->state) { 770 switch (call->state) {
770 case msi_CallInactive: { 771 case msi_CallInactive: {
@@ -776,21 +777,21 @@ void handle_pop(MSICall *call, const MSIMessage *msg)
776 case msi_CallActive: { 777 case msi_CallActive: {
777 /* Hangup */ 778 /* Hangup */
778 LOGGER_INFO(call->session->messenger->log, "Friend hung up on us"); 779 LOGGER_INFO(call->session->messenger->log, "Friend hung up on us");
779 invoke_callback(call, msi_OnEnd); 780 invoke_callback(call, msi_OnEnd, userdata);
780 } 781 }
781 break; 782 break;
782 783
783 case msi_CallRequesting: { 784 case msi_CallRequesting: {
784 /* Reject */ 785 /* Reject */
785 LOGGER_INFO(call->session->messenger->log, "Friend rejected our call"); 786 LOGGER_INFO(call->session->messenger->log, "Friend rejected our call");
786 invoke_callback(call, msi_OnEnd); 787 invoke_callback(call, msi_OnEnd, userdata);
787 } 788 }
788 break; 789 break;
789 790
790 case msi_CallRequested: { 791 case msi_CallRequested: {
791 /* Cancel */ 792 /* Cancel */
792 LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite"); 793 LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite");
793 invoke_callback(call, msi_OnEnd); 794 invoke_callback(call, msi_OnEnd, userdata);
794 } 795 }
795 break; 796 break;
796 } 797 }
@@ -798,7 +799,8 @@ void handle_pop(MSICall *call, const MSIMessage *msg)
798 799
799 kill_call(call); 800 kill_call(call);
800} 801}
801void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) 802void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object,
803 void *userdata)
802{ 804{
803 LOGGER_DEBUG(m->log, "Got msi message"); 805 LOGGER_DEBUG(m->log, "Got msi message");
804 806
@@ -834,15 +836,15 @@ void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data
834 836
835 switch (msg.request.value) { 837 switch (msg.request.value) {
836 case requ_init: 838 case requ_init:
837 handle_init(call, &msg); 839 handle_init(call, &msg, userdata);
838 break; 840 break;
839 841
840 case requ_push: 842 case requ_push:
841 handle_push(call, &msg); 843 handle_push(call, &msg, userdata);
842 break; 844 break;
843 845
844 case requ_pop: 846 case requ_pop:
845 handle_pop(call, &msg); /* always kills the call */ 847 handle_pop(call, &msg, userdata); /* always kills the call */
846 break; 848 break;
847 } 849 }
848 850
diff --git a/toxav/msi.h b/toxav/msi.h
index bf611d34..05583239 100644
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -102,7 +102,7 @@ typedef struct MSICall_s {
102 * returned the call is considered errored and will be handled 102 * returned the call is considered errored and will be handled
103 * as such which means it will be terminated without any notice. 103 * as such which means it will be terminated without any notice.
104 */ 104 */
105typedef int msi_action_cb(void *av, MSICall *call); 105typedef int msi_action_cb(void *av, MSICall *call, void *userdata);
106 106
107/** 107/**
108 * Control session struct. Please do not modify outside msi.c 108 * Control session struct. Please do not modify outside msi.c
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 534efc1a..8c5f0dfb 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -35,7 +35,8 @@
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37 37
38int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object); 38int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object,
39 void *userdata);
39 40
40 41
41RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, 42RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber,
@@ -233,7 +234,8 @@ static struct RTPMessage *new_message(size_t allocate_len, const uint8_t *data,
233 234
234 return msg; 235 return msg;
235} 236}
236int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object) 237int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object,
238 void *userdata)
237{ 239{
238 (void) m; 240 (void) m;
239 (void) friendnumber; 241 (void) friendnumber;
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 1ae914e8..29046265 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -42,10 +42,16 @@ typedef struct ToxAVCall_s {
42 ToxAV *av; 42 ToxAV *av;
43 43
44 pthread_mutex_t mutex_audio[1]; 44 pthread_mutex_t mutex_audio[1];
45 PAIR(RTPSession *, ACSession *) audio; 45 struct {
46 RTPSession *first;
47 ACSession *second;
48 } audio;
46 49
47 pthread_mutex_t mutex_video[1]; 50 pthread_mutex_t mutex_video[1];
48 PAIR(RTPSession *, VCSession *) video; 51 struct {
52 RTPSession *first;
53 VCSession *second;
54 } video;
49 55
50 BWController *bwc; 56 BWController *bwc;
51 57
@@ -75,11 +81,12 @@ struct ToxAV {
75 uint32_t calls_head; 81 uint32_t calls_head;
76 pthread_mutex_t mutex[1]; 82 pthread_mutex_t mutex[1];
77 83
78 PAIR(toxav_call_cb *, void *) ccb; /* Call callback */ 84 toxav_call_cb *on_call;
79 PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */ 85 toxav_call_state_cb *on_call_state;
80 PAIR(toxav_audio_receive_frame_cb *, void *) acb; /* Audio frame receive callback */ 86 toxav_bit_rate_status_cb *on_bit_rate_status_change;
81 PAIR(toxav_video_receive_frame_cb *, void *) vcb; /* Video frame receive callback */ 87
82 PAIR(toxav_bit_rate_status_cb *, void *) bcb; /* Bit rate control callback */ 88 toxav_audio_receive_frame_cb *on_audio_frame;
89 toxav_video_receive_frame_cb *on_video_frame;
83 90
84 /** Decode time measures */ 91 /** Decode time measures */
85 int32_t dmssc; /** Measure count */ 92 int32_t dmssc; /** Measure count */
@@ -89,17 +96,17 @@ struct ToxAV {
89 uint32_t interval; /** Calculated interval */ 96 uint32_t interval; /** Calculated interval */
90}; 97};
91 98
92void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data); 99void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata);
93 100
94int callback_invite(void *toxav_inst, MSICall *call); 101int callback_invite(void *toxav_inst, MSICall *call, void *userdata);
95int callback_start(void *toxav_inst, MSICall *call); 102int callback_start(void *toxav_inst, MSICall *call, void *userdata);
96int callback_end(void *toxav_inst, MSICall *call); 103int callback_end(void *toxav_inst, MSICall *call, void *userdata);
97int callback_error(void *toxav_inst, MSICall *call); 104int callback_error(void *toxav_inst, MSICall *call, void *userdata);
98int callback_capabilites(void *toxav_inst, MSICall *call); 105int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata);
99 106
100bool audio_bit_rate_invalid(uint32_t bit_rate); 107bool audio_bit_rate_invalid(uint32_t bit_rate);
101bool video_bit_rate_invalid(uint32_t bit_rate); 108bool video_bit_rate_invalid(uint32_t bit_rate);
102bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); 109bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata);
103ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); 110ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error);
104ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); 111ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
105ToxAVCall *call_remove(ToxAVCall *call); 112ToxAVCall *call_remove(ToxAVCall *call);
@@ -230,7 +237,7 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
230 /* If no call is active interval is 200 */ 237 /* If no call is active interval is 200 */
231 return av->calls ? av->interval : 200; 238 return av->calls ? av->interval : 200;
232} 239}
233void toxav_iterate(ToxAV *av) 240void toxav_iterate(ToxAV *av, void *userdata)
234{ 241{
235 pthread_mutex_lock(av->mutex); 242 pthread_mutex_lock(av->mutex);
236 243
@@ -249,8 +256,8 @@ void toxav_iterate(ToxAV *av)
249 pthread_mutex_lock(i->mutex); 256 pthread_mutex_lock(i->mutex);
250 pthread_mutex_unlock(av->mutex); 257 pthread_mutex_unlock(av->mutex);
251 258
252 ac_iterate(i->audio.second); 259 ac_iterate(i->audio.second, userdata);
253 vc_iterate(i->video.second); 260 vc_iterate(i->video.second, userdata);
254 261
255 if (i->msi_call->self_capabilities & msi_CapRAudio && 262 if (i->msi_call->self_capabilities & msi_CapRAudio &&
256 i->msi_call->peer_capabilities & msi_CapSAudio) { 263 i->msi_call->peer_capabilities & msi_CapSAudio) {
@@ -329,11 +336,10 @@ END:
329 336
330 return rc == TOXAV_ERR_CALL_OK; 337 return rc == TOXAV_ERR_CALL_OK;
331} 338}
332void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) 339void toxav_callback_call(ToxAV *av, toxav_call_cb *callback)
333{ 340{
334 pthread_mutex_lock(av->mutex); 341 pthread_mutex_lock(av->mutex);
335 av->ccb.first = callback; 342 av->on_call = callback;
336 av->ccb.second = user_data;
337 pthread_mutex_unlock(av->mutex); 343 pthread_mutex_unlock(av->mutex);
338} 344}
339bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, 345bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
@@ -388,11 +394,10 @@ END:
388 394
389 return rc == TOXAV_ERR_ANSWER_OK; 395 return rc == TOXAV_ERR_ANSWER_OK;
390} 396}
391void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data) 397void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback)
392{ 398{
393 pthread_mutex_lock(av->mutex); 399 pthread_mutex_lock(av->mutex);
394 av->scb.first = callback; 400 av->on_call_state = callback;
395 av->scb.second = user_data;
396 pthread_mutex_unlock(av->mutex); 401 pthread_mutex_unlock(av->mutex);
397} 402}
398bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) 403bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error)
@@ -664,11 +669,10 @@ END:
664 669
665 return rc == TOXAV_ERR_BIT_RATE_SET_OK; 670 return rc == TOXAV_ERR_BIT_RATE_SET_OK;
666} 671}
667void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback, void *user_data) 672void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback)
668{ 673{
669 pthread_mutex_lock(av->mutex); 674 pthread_mutex_lock(av->mutex);
670 av->bcb.first = callback; 675 av->on_bit_rate_status_change = callback;
671 av->bcb.second = user_data;
672 pthread_mutex_unlock(av->mutex); 676 pthread_mutex_unlock(av->mutex);
673} 677}
674bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, 678bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count,
@@ -856,18 +860,16 @@ END:
856 860
857 return rc == TOXAV_ERR_SEND_FRAME_OK; 861 return rc == TOXAV_ERR_SEND_FRAME_OK;
858} 862}
859void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback, void *user_data) 863void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback)
860{ 864{
861 pthread_mutex_lock(av->mutex); 865 pthread_mutex_lock(av->mutex);
862 av->acb.first = callback; 866 av->on_audio_frame = callback;
863 av->acb.second = user_data;
864 pthread_mutex_unlock(av->mutex); 867 pthread_mutex_unlock(av->mutex);
865} 868}
866void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback, void *user_data) 869void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback)
867{ 870{
868 pthread_mutex_lock(av->mutex); 871 pthread_mutex_lock(av->mutex);
869 av->vcb.first = callback; 872 av->on_video_frame = callback;
870 av->vcb.second = user_data;
871 pthread_mutex_unlock(av->mutex); 873 pthread_mutex_unlock(av->mutex);
872} 874}
873 875
@@ -877,7 +879,7 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb
877 * :: Internal 879 * :: Internal
878 * 880 *
879 ******************************************************************************/ 881 ******************************************************************************/
880void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data) 882void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata)
881{ 883{
882 /* Callback which is called when the internal measure mechanism reported packet loss. 884 /* Callback which is called when the internal measure mechanism reported packet loss.
883 * We report suggested lowered bitrate to an app. If app is sending both audio and video, 885 * We report suggested lowered bitrate to an app. If app is sending both audio and video,
@@ -886,7 +888,7 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u
886 * The application may choose to disable video totally if the stream is too bad. 888 * The application may choose to disable video totally if the stream is too bad.
887 */ 889 */
888 890
889 ToxAVCall *call = user_data; 891 ToxAVCall *call = call_data;
890 assert(call); 892 assert(call);
891 893
892 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100); 894 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100);
@@ -897,25 +899,25 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u
897 899
898 pthread_mutex_lock(call->av->mutex); 900 pthread_mutex_lock(call->av->mutex);
899 901
900 if (!call->av->bcb.first) { 902 if (!call->av->on_bit_rate_status_change) {
901 pthread_mutex_unlock(call->av->mutex); 903 pthread_mutex_unlock(call->av->mutex);
902 LOGGER_WARNING(call->av->m->log, "No callback to report loss on"); 904 LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
903 return; 905 return;
904 } 906 }
905 907
906 if (call->video_bit_rate) { 908 if (call->video_bit_rate) {
907 (*call->av->bcb.first)(call->av, friend_number, call->audio_bit_rate, 909 (*call->av->on_bit_rate_status_change)(call->av, friend_number, call->audio_bit_rate,
908 call->video_bit_rate - (call->video_bit_rate * loss), 910 call->video_bit_rate - (call->video_bit_rate * loss),
909 call->av->bcb.second); 911 userdata);
910 } else if (call->audio_bit_rate) { 912 } else if (call->audio_bit_rate) {
911 (*call->av->bcb.first)(call->av, friend_number, 913 (*call->av->on_bit_rate_status_change)(call->av, friend_number,
912 call->audio_bit_rate - (call->audio_bit_rate * loss), 914 call->audio_bit_rate - (call->audio_bit_rate * loss),
913 0, call->av->bcb.second); 915 0, userdata);
914 } 916 }
915 917
916 pthread_mutex_unlock(call->av->mutex); 918 pthread_mutex_unlock(call->av->mutex);
917} 919}
918int callback_invite(void *toxav_inst, MSICall *call) 920int callback_invite(void *toxav_inst, MSICall *call, void *userdata)
919{ 921{
920 ToxAV *toxav = toxav_inst; 922 ToxAV *toxav = toxav_inst;
921 pthread_mutex_lock(toxav->mutex); 923 pthread_mutex_lock(toxav->mutex);
@@ -931,9 +933,9 @@ int callback_invite(void *toxav_inst, MSICall *call)
931 call->av_call = av_call; 933 call->av_call = av_call;
932 av_call->msi_call = call; 934 av_call->msi_call = call;
933 935
934 if (toxav->ccb.first) { 936 if (toxav->on_call) {
935 toxav->ccb.first(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, 937 toxav->on_call(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio,
936 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second); 938 call->peer_capabilities & msi_CapSVideo, userdata);
937 } else { 939 } else {
938 /* No handler to capture the call request, send failure */ 940 /* No handler to capture the call request, send failure */
939 pthread_mutex_unlock(toxav->mutex); 941 pthread_mutex_unlock(toxav->mutex);
@@ -943,7 +945,7 @@ int callback_invite(void *toxav_inst, MSICall *call)
943 pthread_mutex_unlock(toxav->mutex); 945 pthread_mutex_unlock(toxav->mutex);
944 return 0; 946 return 0;
945} 947}
946int callback_start(void *toxav_inst, MSICall *call) 948int callback_start(void *toxav_inst, MSICall *call, void *userdata)
947{ 949{
948 ToxAV *toxav = toxav_inst; 950 ToxAV *toxav = toxav_inst;
949 pthread_mutex_lock(toxav->mutex); 951 pthread_mutex_lock(toxav->mutex);
@@ -957,13 +959,13 @@ int callback_start(void *toxav_inst, MSICall *call)
957 } 959 }
958 960
959 if (!call_prepare_transmission(av_call)) { 961 if (!call_prepare_transmission(av_call)) {
960 callback_error(toxav_inst, call); 962 callback_error(toxav_inst, call, userdata);
961 pthread_mutex_unlock(toxav->mutex); 963 pthread_mutex_unlock(toxav->mutex);
962 return -1; 964 return -1;
963 } 965 }
964 966
965 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities)) { 967 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata)) {
966 callback_error(toxav_inst, call); 968 callback_error(toxav_inst, call, userdata);
967 pthread_mutex_unlock(toxav->mutex); 969 pthread_mutex_unlock(toxav->mutex);
968 return -1; 970 return -1;
969 } 971 }
@@ -971,12 +973,12 @@ int callback_start(void *toxav_inst, MSICall *call)
971 pthread_mutex_unlock(toxav->mutex); 973 pthread_mutex_unlock(toxav->mutex);
972 return 0; 974 return 0;
973} 975}
974int callback_end(void *toxav_inst, MSICall *call) 976int callback_end(void *toxav_inst, MSICall *call, void *userdata)
975{ 977{
976 ToxAV *toxav = toxav_inst; 978 ToxAV *toxav = toxav_inst;
977 pthread_mutex_lock(toxav->mutex); 979 pthread_mutex_lock(toxav->mutex);
978 980
979 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED); 981 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED, userdata);
980 982
981 if (call->av_call) { 983 if (call->av_call) {
982 call_kill_transmission(call->av_call); 984 call_kill_transmission(call->av_call);
@@ -986,12 +988,12 @@ int callback_end(void *toxav_inst, MSICall *call)
986 pthread_mutex_unlock(toxav->mutex); 988 pthread_mutex_unlock(toxav->mutex);
987 return 0; 989 return 0;
988} 990}
989int callback_error(void *toxav_inst, MSICall *call) 991int callback_error(void *toxav_inst, MSICall *call, void *userdata)
990{ 992{
991 ToxAV *toxav = toxav_inst; 993 ToxAV *toxav = toxav_inst;
992 pthread_mutex_lock(toxav->mutex); 994 pthread_mutex_lock(toxav->mutex);
993 995
994 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR); 996 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR, userdata);
995 997
996 if (call->av_call) { 998 if (call->av_call) {
997 call_kill_transmission(call->av_call); 999 call_kill_transmission(call->av_call);
@@ -1001,7 +1003,7 @@ int callback_error(void *toxav_inst, MSICall *call)
1001 pthread_mutex_unlock(toxav->mutex); 1003 pthread_mutex_unlock(toxav->mutex);
1002 return 0; 1004 return 0;
1003} 1005}
1004int callback_capabilites(void *toxav_inst, MSICall *call) 1006int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata)
1005{ 1007{
1006 ToxAV *toxav = toxav_inst; 1008 ToxAV *toxav = toxav_inst;
1007 pthread_mutex_lock(toxav->mutex); 1009 pthread_mutex_lock(toxav->mutex);
@@ -1018,7 +1020,7 @@ int callback_capabilites(void *toxav_inst, MSICall *call)
1018 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first); 1020 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first);
1019 } 1021 }
1020 1022
1021 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities); 1023 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata);
1022 1024
1023 pthread_mutex_unlock(toxav->mutex); 1025 pthread_mutex_unlock(toxav->mutex);
1024 return 0; 1026 return 0;
@@ -1036,10 +1038,10 @@ bool video_bit_rate_invalid(uint32_t bit_rate)
1036 /* TODO(mannol): If anyone knows the answer to this one please fill it up */ 1038 /* TODO(mannol): If anyone knows the answer to this one please fill it up */
1037 return false; 1039 return false;
1038} 1040}
1039bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state) 1041bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata)
1040{ 1042{
1041 if (av->scb.first) { 1043 if (av->on_call_state) {
1042 av->scb.first(av, friend_number, state, av->scb.second); 1044 av->on_call_state(av, friend_number, state, userdata);
1043 } else { 1045 } else {
1044 return false; 1046 return false;
1045 } 1047 }
@@ -1194,7 +1196,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1194 1196
1195 ToxAV *av = call->av; 1197 ToxAV *av = call->av;
1196 1198
1197 if (!av->acb.first && !av->vcb.first) { 1199 if (!av->on_audio_frame && !av->on_video_frame) {
1198 /* It makes no sense to have CSession without callbacks */ 1200 /* It makes no sense to have CSession without callbacks */
1199 return false; 1201 return false;
1200 } 1202 }
@@ -1220,7 +1222,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1220 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call); 1222 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call);
1221 1223
1222 { /* Prepare audio */ 1224 { /* Prepare audio */
1223 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->acb.first, av->acb.second); 1225 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->on_audio_frame);
1224 1226
1225 if (!call->audio.second) { 1227 if (!call->audio.second) {
1226 LOGGER_ERROR(av->m->log, "Failed to create audio codec session"); 1228 LOGGER_ERROR(av->m->log, "Failed to create audio codec session");
@@ -1236,7 +1238,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1236 } 1238 }
1237 } 1239 }
1238 { /* Prepare video */ 1240 { /* Prepare video */
1239 call->video.second = vc_new(av->m->log, av, call->friend_number, av->vcb.first, av->vcb.second); 1241 call->video.second = vc_new(av->m->log, av, call->friend_number, av->on_video_frame);
1240 1242
1241 if (!call->video.second) { 1243 if (!call->video.second) {
1242 LOGGER_ERROR(av->m->log, "Failed to create video codec session"); 1244 LOGGER_ERROR(av->m->log, "Failed to create video codec session");
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 38ba354e..da0c4c35 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -232,7 +232,7 @@ uint32_t toxav_iteration_interval(const ToxAV *av);
232 * toxav_iteration_interval() milliseconds. It is best called in the separate 232 * toxav_iteration_interval() milliseconds. It is best called in the separate
233 * thread from tox_iterate. 233 * thread from tox_iterate.
234 */ 234 */
235void toxav_iterate(ToxAV *av); 235void toxav_iterate(ToxAV *av, void *userdata);
236 236
237 237
238/******************************************************************************* 238/*******************************************************************************
@@ -316,7 +316,7 @@ typedef void toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled
316 * Set the callback for the `call` event. Pass NULL to unset. 316 * Set the callback for the `call` event. Pass NULL to unset.
317 * 317 *
318 */ 318 */
319void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data); 319void toxav_callback_call(ToxAV *av, toxav_call_cb *callback);
320 320
321typedef enum TOXAV_ERR_ANSWER { 321typedef enum TOXAV_ERR_ANSWER {
322 322
@@ -437,7 +437,7 @@ typedef void toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t sta
437 * Set the callback for the `call_state` event. Pass NULL to unset. 437 * Set the callback for the `call_state` event. Pass NULL to unset.
438 * 438 *
439 */ 439 */
440void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data); 440void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback);
441 441
442 442
443/******************************************************************************* 443/*******************************************************************************
@@ -613,7 +613,7 @@ typedef void toxav_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, uint32_
613 * Set the callback for the `bit_rate_status` event. Pass NULL to unset. 613 * Set the callback for the `bit_rate_status` event. Pass NULL to unset.
614 * 614 *
615 */ 615 */
616void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback, void *user_data); 616void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback);
617 617
618 618
619/******************************************************************************* 619/*******************************************************************************
@@ -742,7 +742,7 @@ typedef void toxav_audio_receive_frame_cb(ToxAV *av, uint32_t friend_number, con
742 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. 742 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset.
743 * 743 *
744 */ 744 */
745void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback, void *user_data); 745void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback);
746 746
747/** 747/**
748 * The function type for the video_receive_frame callback. 748 * The function type for the video_receive_frame callback.
@@ -774,7 +774,7 @@ typedef void toxav_video_receive_frame_cb(ToxAV *av, uint32_t friend_number, uin
774 * Set the callback for the `video_receive_frame` event. Pass NULL to unset. 774 * Set the callback for the `video_receive_frame` event. Pass NULL to unset.
775 * 775 *
776 */ 776 */
777void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback, void *user_data); 777void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback);
778 778
779/** 779/**
780 * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove 780 * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove
diff --git a/toxav/video.c b/toxav/video.c
index de028c7c..e786bc4c 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -37,7 +37,7 @@
37#define MAX_DECODE_TIME_US 0 /* Good quality encode. */ 37#define MAX_DECODE_TIME_US 0 /* Good quality encode. */
38#define VIDEO_DECODE_BUFFER_SIZE 20 38#define VIDEO_DECODE_BUFFER_SIZE 20
39 39
40VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data) 40VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb)
41{ 41{
42 VCSession *vc = calloc(sizeof(VCSession), 1); 42 VCSession *vc = calloc(sizeof(VCSession), 1);
43 43
@@ -104,8 +104,7 @@ VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_re
104 104
105 vc->linfts = current_time_monotonic(); 105 vc->linfts = current_time_monotonic();
106 vc->lcfd = 60; 106 vc->lcfd = 60;
107 vc->vcb.first = cb; 107 vc->on_video_frame = cb;
108 vc->vcb.second = cb_data;
109 vc->friend_number = friend_number; 108 vc->friend_number = friend_number;
110 vc->av = av; 109 vc->av = av;
111 vc->log = log; 110 vc->log = log;
@@ -142,7 +141,7 @@ void vc_kill(VCSession *vc)
142 LOGGER_DEBUG(vc->log, "Terminated video handler: %p", vc); 141 LOGGER_DEBUG(vc->log, "Terminated video handler: %p", vc);
143 free(vc); 142 free(vc);
144} 143}
145void vc_iterate(VCSession *vc) 144void vc_iterate(VCSession *vc, void *userdata)
146{ 145{
147 if (!vc) { 146 if (!vc) {
148 return; 147 return;
@@ -168,10 +167,10 @@ void vc_iterate(VCSession *vc)
168 167
169 /* Play decoded images */ 168 /* Play decoded images */
170 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) { 169 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) {
171 if (vc->vcb.first) { 170 if (vc->on_video_frame) {
172 vc->vcb.first(vc->av, vc->friend_number, dest->d_w, dest->d_h, 171 vc->on_video_frame(vc->av, vc->friend_number, dest->d_w, dest->d_h,
173 (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2], 172 (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2],
174 dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb.second); 173 dest->stride[0], dest->stride[1], dest->stride[2], userdata);
175 } 174 }
176 175
177 vpx_img_free(dest); 176 vpx_img_free(dest);
diff --git a/toxav/video.h b/toxav/video.h
index 335240c7..e24d98c9 100644
--- a/toxav/video.h
+++ b/toxav/video.h
@@ -56,14 +56,14 @@ typedef struct VCSession_s {
56 ToxAV *av; 56 ToxAV *av;
57 uint32_t friend_number; 57 uint32_t friend_number;
58 58
59 PAIR(toxav_video_receive_frame_cb *, void *) vcb; /* Video frame receive callback */ 59 toxav_video_receive_frame_cb *on_video_frame; /* Video frame receive callback */
60 60
61 pthread_mutex_t queue_mutex[1]; 61 pthread_mutex_t queue_mutex[1];
62} VCSession; 62} VCSession;
63 63
64VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data); 64VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb);
65void vc_kill(VCSession *vc); 65void vc_kill(VCSession *vc);
66void vc_iterate(VCSession *vc); 66void vc_iterate(VCSession *vc, void *userdata);
67int vc_queue_message(void *vcp, struct RTPMessage *msg); 67int vc_queue_message(void *vcp, struct RTPMessage *msg);
68int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height); 68int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height);
69 69