diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 262 |
1 files changed, 137 insertions, 125 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c index b40a1c02..f704bc6b 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** toxav.c | 1 | /** toxav.c |
2 | * | 2 | * |
3 | * Copyright (C) 2013 Tox project All Rights Reserved. | 3 | * Copyright (C) 2013 Tox project All Rights Reserved. |
4 | * | 4 | * |
5 | * This file is part of Tox. | 5 | * This file is part of Tox. |
@@ -17,7 +17,7 @@ | |||
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 18 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
19 | * | 19 | * |
20 | * | 20 | * |
21 | * Report bugs/suggestions at #tox-dev @ freenode.net:6667 | 21 | * Report bugs/suggestions at #tox-dev @ freenode.net:6667 |
22 | */ | 22 | */ |
23 | 23 | ||
@@ -44,27 +44,26 @@ typedef enum { | |||
44 | ts_closing, | 44 | ts_closing, |
45 | ts_running, | 45 | ts_running, |
46 | ts_closed | 46 | ts_closed |
47 | 47 | ||
48 | } ThreadState; | 48 | } ThreadState; |
49 | 49 | ||
50 | typedef struct _ToxAv | 50 | typedef struct _ToxAv { |
51 | { | 51 | Messenger *messenger; |
52 | Messenger* messenger; | 52 | |
53 | 53 | MSISession *msi_session; /** Main msi session */ | |
54 | MSISession* msi_session; /** Main msi session */ | 54 | |
55 | 55 | RTPSession *rtp_sessions[2]; /* Audio is first and video is second */ | |
56 | RTPSession* rtp_sessions[2]; /* Audio is first and video is second */ | 56 | |
57 | 57 | struct jitter_buffer *j_buf; | |
58 | struct jitter_buffer* j_buf; | 58 | CodecState *cs; |
59 | CodecState* cs; | 59 | |
60 | 60 | void *agent_handler; | |
61 | void* agent_handler; | ||
62 | } ToxAv; | 61 | } ToxAv; |
63 | 62 | ||
64 | /** | 63 | /** |
65 | * @brief Start new A/V session. There can only be one session at the time. If you register more | 64 | * @brief Start new A/V session. There can only be one session at the time. If you register more |
66 | * it will result in undefined behaviour. | 65 | * it will result in undefined behaviour. |
67 | * | 66 | * |
68 | * @param messenger The messenger handle. | 67 | * @param messenger The messenger handle. |
69 | * @param useragent The agent handling A/V session (i.e. phone). | 68 | * @param useragent The agent handling A/V session (i.e. phone). |
70 | * @param ua_name Useragent name. | 69 | * @param ua_name Useragent name. |
@@ -73,67 +72,69 @@ typedef struct _ToxAv | |||
73 | * @return ToxAv* | 72 | * @return ToxAv* |
74 | * @retval NULL On error. | 73 | * @retval NULL On error. |
75 | */ | 74 | */ |
76 | ToxAv* toxav_new( Tox* messenger, void* useragent, const char* ua_name , uint16_t video_width, uint16_t video_height) | 75 | ToxAv *toxav_new( Tox *messenger, void *useragent, const char *ua_name , uint16_t video_width, uint16_t video_height) |
77 | { | 76 | { |
78 | ToxAv* av = calloc ( sizeof(ToxAv), 1); | 77 | ToxAv *av = calloc ( sizeof(ToxAv), 1); |
78 | |||
79 | if (av == NULL) | 79 | if (av == NULL) |
80 | return NULL; | 80 | return NULL; |
81 | 81 | ||
82 | av->messenger = (Messenger *)messenger; | 82 | av->messenger = (Messenger *)messenger; |
83 | 83 | ||
84 | av->msi_session = msi_init_session(av->messenger, (const unsigned char*) ua_name ); | 84 | av->msi_session = msi_init_session(av->messenger, (const unsigned char *) ua_name ); |
85 | av->msi_session->agent_handler = av; | 85 | av->msi_session->agent_handler = av; |
86 | 86 | ||
87 | av->rtp_sessions[0] = av->rtp_sessions [1] = NULL; | 87 | av->rtp_sessions[0] = av->rtp_sessions [1] = NULL; |
88 | 88 | ||
89 | /* NOTE: This should be user defined or? */ | 89 | /* NOTE: This should be user defined or? */ |
90 | av->j_buf = create_queue(20); | 90 | av->j_buf = create_queue(20); |
91 | 91 | ||
92 | av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width, video_height, VIDEO_BITRATE); | 92 | av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width, |
93 | 93 | video_height, VIDEO_BITRATE); | |
94 | |||
94 | av->agent_handler = useragent; | 95 | av->agent_handler = useragent; |
95 | 96 | ||
96 | return av; | 97 | return av; |
97 | } | 98 | } |
98 | 99 | ||
99 | /** | 100 | /** |
100 | * @brief Remove A/V session. | 101 | * @brief Remove A/V session. |
101 | * | 102 | * |
102 | * @param av Handler. | 103 | * @param av Handler. |
103 | * @return void | 104 | * @return void |
104 | */ | 105 | */ |
105 | void toxav_kill ( ToxAv* av ) | 106 | void toxav_kill ( ToxAv *av ) |
106 | { | 107 | { |
107 | msi_terminate_session(av->msi_session); | 108 | msi_terminate_session(av->msi_session); |
108 | 109 | ||
109 | if ( av->rtp_sessions[audio_index] ) { | 110 | if ( av->rtp_sessions[audio_index] ) { |
110 | rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle); | 111 | rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle); |
111 | } | 112 | } |
112 | 113 | ||
113 | if ( av->rtp_sessions[video_index] ) { | 114 | if ( av->rtp_sessions[video_index] ) { |
114 | rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle); | 115 | rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle); |
115 | } | 116 | } |
116 | 117 | ||
117 | codec_terminate_session(av->cs); | 118 | codec_terminate_session(av->cs); |
118 | 119 | ||
119 | free(av); | 120 | free(av); |
120 | } | 121 | } |
121 | 122 | ||
122 | /** | 123 | /** |
123 | * @brief Register callback for call state. | 124 | * @brief Register callback for call state. |
124 | * | 125 | * |
125 | * @param callback The callback | 126 | * @param callback The callback |
126 | * @param id One of the ToxAvCallbackID values | 127 | * @param id One of the ToxAvCallbackID values |
127 | * @return void | 128 | * @return void |
128 | */ | 129 | */ |
129 | void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id ) | 130 | void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id ) |
130 | { | 131 | { |
131 | msi_register_callback((MSICallback)callback, (MSICallbackID) id); | 132 | msi_register_callback((MSICallback)callback, (MSICallbackID) id); |
132 | } | 133 | } |
133 | 134 | ||
134 | /** | 135 | /** |
135 | * @brief Call user. Use its friend_id. | 136 | * @brief Call user. Use its friend_id. |
136 | * | 137 | * |
137 | * @param av Handler. | 138 | * @param av Handler. |
138 | * @param user The user. | 139 | * @param user The user. |
139 | * @param call_type Call type. | 140 | * @param call_type Call type. |
@@ -142,68 +143,68 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID | |||
142 | * @retval 0 Success. | 143 | * @retval 0 Success. |
143 | * @retval ToxAvError On error. | 144 | * @retval ToxAvError On error. |
144 | */ | 145 | */ |
145 | int toxav_call (ToxAv* av, int user, ToxAvCallType call_type, int ringing_seconds ) | 146 | int toxav_call (ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds ) |
146 | { | 147 | { |
147 | if ( av->msi_session->call ) { | 148 | if ( av->msi_session->call ) { |
148 | return ErrorAlreadyInCall; | 149 | return ErrorAlreadyInCall; |
149 | } | 150 | } |
150 | 151 | ||
151 | return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user); | 152 | return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user); |
152 | } | 153 | } |
153 | 154 | ||
154 | /** | 155 | /** |
155 | * @brief Hangup active call. | 156 | * @brief Hangup active call. |
156 | * | 157 | * |
157 | * @param av Handler. | 158 | * @param av Handler. |
158 | * @return int | 159 | * @return int |
159 | * @retval 0 Success. | 160 | * @retval 0 Success. |
160 | * @retval ToxAvError On error. | 161 | * @retval ToxAvError On error. |
161 | */ | 162 | */ |
162 | int toxav_hangup ( ToxAv* av ) | 163 | int toxav_hangup ( ToxAv *av ) |
163 | { | 164 | { |
164 | if ( !av->msi_session->call ) { | 165 | if ( !av->msi_session->call ) { |
165 | return ErrorNoCall; | 166 | return ErrorNoCall; |
166 | } | 167 | } |
167 | 168 | ||
168 | if ( av->msi_session->call->state != call_active ) { | 169 | if ( av->msi_session->call->state != call_active ) { |
169 | return ErrorInvalidState; | 170 | return ErrorInvalidState; |
170 | } | 171 | } |
171 | 172 | ||
172 | return msi_hangup(av->msi_session); | 173 | return msi_hangup(av->msi_session); |
173 | } | 174 | } |
174 | 175 | ||
175 | /** | 176 | /** |
176 | * @brief Answer incomming call. | 177 | * @brief Answer incomming call. |
177 | * | 178 | * |
178 | * @param av Handler. | 179 | * @param av Handler. |
179 | * @param call_type Answer with... | 180 | * @param call_type Answer with... |
180 | * @return int | 181 | * @return int |
181 | * @retval 0 Success. | 182 | * @retval 0 Success. |
182 | * @retval ToxAvError On error. | 183 | * @retval ToxAvError On error. |
183 | */ | 184 | */ |
184 | int toxav_answer ( ToxAv* av, ToxAvCallType call_type ) | 185 | int toxav_answer ( ToxAv *av, ToxAvCallType call_type ) |
185 | { | 186 | { |
186 | if ( !av->msi_session->call ) { | 187 | if ( !av->msi_session->call ) { |
187 | return ErrorNoCall; | 188 | return ErrorNoCall; |
188 | } | 189 | } |
189 | 190 | ||
190 | if ( av->msi_session->call->state != call_starting ) { | 191 | if ( av->msi_session->call->state != call_starting ) { |
191 | return ErrorInvalidState; | 192 | return ErrorInvalidState; |
192 | } | 193 | } |
193 | 194 | ||
194 | return msi_answer(av->msi_session, call_type); | 195 | return msi_answer(av->msi_session, call_type); |
195 | } | 196 | } |
196 | 197 | ||
197 | /** | 198 | /** |
198 | * @brief Reject incomming call. | 199 | * @brief Reject incomming call. |
199 | * | 200 | * |
200 | * @param av Handler. | 201 | * @param av Handler. |
201 | * @param reason Optional reason. Set NULL if none. | 202 | * @param reason Optional reason. Set NULL if none. |
202 | * @return int | 203 | * @return int |
203 | * @retval 0 Success. | 204 | * @retval 0 Success. |
204 | * @retval ToxAvError On error. | 205 | * @retval ToxAvError On error. |
205 | */ | 206 | */ |
206 | int toxav_reject ( ToxAv* av, const char* reason ) | 207 | int toxav_reject ( ToxAv *av, const char *reason ) |
207 | { | 208 | { |
208 | if ( !av->msi_session->call ) { | 209 | if ( !av->msi_session->call ) { |
209 | return ErrorNoCall; | 210 | return ErrorNoCall; |
@@ -213,126 +214,127 @@ int toxav_reject ( ToxAv* av, const char* reason ) | |||
213 | return ErrorInvalidState; | 214 | return ErrorInvalidState; |
214 | } | 215 | } |
215 | 216 | ||
216 | return msi_reject(av->msi_session, (const uint8_t*) reason); | 217 | return msi_reject(av->msi_session, (const uint8_t *) reason); |
217 | } | 218 | } |
218 | 219 | ||
219 | /** | 220 | /** |
220 | * @brief Cancel outgoing request. | 221 | * @brief Cancel outgoing request. |
221 | * | 222 | * |
222 | * @param av Handler. | 223 | * @param av Handler. |
223 | * @param reason Optional reason. | 224 | * @param reason Optional reason. |
224 | * @return int | 225 | * @return int |
225 | * @retval 0 Success. | 226 | * @retval 0 Success. |
226 | * @retval ToxAvError On error. | 227 | * @retval ToxAvError On error. |
227 | */ | 228 | */ |
228 | int toxav_cancel ( ToxAv* av, const char* reason ) | 229 | int toxav_cancel ( ToxAv *av, const char *reason ) |
229 | { | 230 | { |
230 | if ( !av->msi_session->call ) { | 231 | if ( !av->msi_session->call ) { |
231 | return ErrorNoCall; | 232 | return ErrorNoCall; |
232 | } | 233 | } |
233 | 234 | ||
234 | return msi_cancel(av->msi_session, 0, (const uint8_t*)reason); | 235 | return msi_cancel(av->msi_session, 0, (const uint8_t *)reason); |
235 | } | 236 | } |
236 | 237 | ||
237 | /** | 238 | /** |
238 | * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. | 239 | * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. |
239 | * | 240 | * |
240 | * @param av Handler. | 241 | * @param av Handler. |
241 | * @return int | 242 | * @return int |
242 | * @retval 0 Success. | 243 | * @retval 0 Success. |
243 | * @retval ToxAvError On error. | 244 | * @retval ToxAvError On error. |
244 | */ | 245 | */ |
245 | int toxav_stop_call ( ToxAv* av ) | 246 | int toxav_stop_call ( ToxAv *av ) |
246 | { | 247 | { |
247 | if ( !av->msi_session->call ) { | 248 | if ( !av->msi_session->call ) { |
248 | return ErrorNoCall; | 249 | return ErrorNoCall; |
249 | } | 250 | } |
250 | 251 | ||
251 | return msi_stopcall(av->msi_session); | 252 | return msi_stopcall(av->msi_session); |
252 | } | 253 | } |
253 | 254 | ||
254 | /** | 255 | /** |
255 | * @brief Must be call before any RTP transmission occurs. | 256 | * @brief Must be call before any RTP transmission occurs. |
256 | * | 257 | * |
257 | * @param av Handler. | 258 | * @param av Handler. |
258 | * @return int | 259 | * @return int |
259 | * @retval 0 Success. | 260 | * @retval 0 Success. |
260 | * @retval ToxAvError On error. | 261 | * @retval ToxAvError On error. |
261 | */ | 262 | */ |
262 | int toxav_prepare_transmission ( ToxAv* av ) | 263 | int toxav_prepare_transmission ( ToxAv *av ) |
263 | { | 264 | { |
264 | assert(av->msi_session); | 265 | assert(av->msi_session); |
266 | |||
265 | if ( !av->msi_session || !av->msi_session->call ) { | 267 | if ( !av->msi_session || !av->msi_session->call ) { |
266 | return ErrorNoCall; | 268 | return ErrorNoCall; |
267 | } | 269 | } |
268 | 270 | ||
269 | av->rtp_sessions[audio_index] = rtp_init_session( | 271 | av->rtp_sessions[audio_index] = rtp_init_session( |
270 | type_audio, | 272 | type_audio, |
271 | av->messenger, | 273 | av->messenger, |
272 | av->msi_session->call->peers[0], | 274 | av->msi_session->call->peers[0], |
273 | av->msi_session->call->key_peer, | 275 | av->msi_session->call->key_peer, |
274 | av->msi_session->call->key_local, | 276 | av->msi_session->call->key_local, |
275 | av->msi_session->call->nonce_peer, | 277 | av->msi_session->call->nonce_peer, |
276 | av->msi_session->call->nonce_local | 278 | av->msi_session->call->nonce_local |
277 | ); | 279 | ); |
278 | 280 | ||
279 | 281 | ||
280 | if ( !av->rtp_sessions[audio_index] ) { | 282 | if ( !av->rtp_sessions[audio_index] ) { |
281 | fprintf(stderr, "Error while starting audio RTP session!\n"); | 283 | fprintf(stderr, "Error while starting audio RTP session!\n"); |
282 | return ErrorStartingAudioRtp; | 284 | return ErrorStartingAudioRtp; |
283 | } | 285 | } |
284 | 286 | ||
285 | av->rtp_sessions[video_index] = rtp_init_session ( | 287 | av->rtp_sessions[video_index] = rtp_init_session ( |
286 | type_video, | 288 | type_video, |
287 | av->messenger, | 289 | av->messenger, |
288 | av->msi_session->call->peers[0], | 290 | av->msi_session->call->peers[0], |
289 | av->msi_session->call->key_peer, | 291 | av->msi_session->call->key_peer, |
290 | av->msi_session->call->key_local, | 292 | av->msi_session->call->key_local, |
291 | av->msi_session->call->nonce_peer, | 293 | av->msi_session->call->nonce_peer, |
292 | av->msi_session->call->nonce_local | 294 | av->msi_session->call->nonce_local |
293 | ); | 295 | ); |
294 | 296 | ||
295 | 297 | ||
296 | if ( !av->rtp_sessions[video_index] ) { | 298 | if ( !av->rtp_sessions[video_index] ) { |
297 | fprintf(stderr, "Error while starting video RTP session!\n"); | 299 | fprintf(stderr, "Error while starting video RTP session!\n"); |
298 | return ErrorStartingVideoRtp; | 300 | return ErrorStartingVideoRtp; |
299 | } | 301 | } |
300 | 302 | ||
301 | return ErrorNone; | 303 | return ErrorNone; |
302 | } | 304 | } |
303 | 305 | ||
304 | /** | 306 | /** |
305 | * @brief Call this at the end of the transmission. | 307 | * @brief Call this at the end of the transmission. |
306 | * | 308 | * |
307 | * @param av Handler. | 309 | * @param av Handler. |
308 | * @return int | 310 | * @return int |
309 | * @retval 0 Success. | 311 | * @retval 0 Success. |
310 | * @retval ToxAvError On error. | 312 | * @retval ToxAvError On error. |
311 | */ | 313 | */ |
312 | int toxav_kill_transmission ( ToxAv* av ) | 314 | int toxav_kill_transmission ( ToxAv *av ) |
313 | { | 315 | { |
314 | /* Both sessions should be active at any time */ | 316 | /* Both sessions should be active at any time */ |
315 | if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] ) | 317 | if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] ) |
316 | return ErrorNoTransmission; | 318 | return ErrorNoTransmission; |
317 | 319 | ||
318 | 320 | ||
319 | if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) { | 321 | if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) { |
320 | fprintf(stderr, "Error while terminating audio RTP session!\n"); | 322 | fprintf(stderr, "Error while terminating audio RTP session!\n"); |
321 | return ErrorTerminatingAudioRtp; | 323 | return ErrorTerminatingAudioRtp; |
322 | } | 324 | } |
323 | 325 | ||
324 | if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) { | 326 | if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) { |
325 | fprintf(stderr, "Error while terminating video RTP session!\n"); | 327 | fprintf(stderr, "Error while terminating video RTP session!\n"); |
326 | return ErrorTerminatingVideoRtp; | 328 | return ErrorTerminatingVideoRtp; |
327 | } | 329 | } |
328 | 330 | ||
329 | return ErrorNone; | 331 | return ErrorNone; |
330 | } | 332 | } |
331 | 333 | ||
332 | 334 | ||
333 | /** | 335 | /** |
334 | * @brief Send RTP payload. | 336 | * @brief Send RTP payload. |
335 | * | 337 | * |
336 | * @param av Handler. | 338 | * @param av Handler. |
337 | * @param type Type of payload. | 339 | * @param type Type of payload. |
338 | * @param payload The payload. | 340 | * @param payload The payload. |
@@ -341,7 +343,7 @@ int toxav_kill_transmission ( ToxAv* av ) | |||
341 | * @retval 0 Success. | 343 | * @retval 0 Success. |
342 | * @retval -1 Failure. | 344 | * @retval -1 Failure. |
343 | */ | 345 | */ |
344 | inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8_t* payload, uint16_t length ) | 346 | inline__ int toxav_send_rtp_payload ( ToxAv *av, ToxAvCallType type, const uint8_t *payload, uint16_t length ) |
345 | { | 347 | { |
346 | if ( av->rtp_sessions[type - TypeAudio] ) | 348 | if ( av->rtp_sessions[type - TypeAudio] ) |
347 | return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length ); | 349 | return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length ); |
@@ -350,7 +352,7 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8 | |||
350 | 352 | ||
351 | /** | 353 | /** |
352 | * @brief Receive RTP payload. | 354 | * @brief Receive RTP payload. |
353 | * | 355 | * |
354 | * @param av Handler. | 356 | * @param av Handler. |
355 | * @param type Type of the payload. | 357 | * @param type Type of the payload. |
356 | * @param dest Storage. | 358 | * @param dest Storage. |
@@ -358,123 +360,131 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8 | |||
358 | * @retval ToxAvError On Error. | 360 | * @retval ToxAvError On Error. |
359 | * @retval >=0 Size of received payload. | 361 | * @retval >=0 Size of received payload. |
360 | */ | 362 | */ |
361 | inline__ int toxav_recv_rtp_payload ( ToxAv* av, ToxAvCallType type, uint8_t* dest ) | 363 | inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *dest ) |
362 | { | 364 | { |
363 | if ( !dest ) return ErrorInternal; | 365 | if ( !dest ) return ErrorInternal; |
364 | 366 | ||
365 | if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession; | 367 | if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession; |
366 | 368 | ||
367 | RTPMessage* message; | 369 | RTPMessage *message; |
368 | 370 | ||
369 | if ( type == TypeAudio ) { | 371 | if ( type == TypeAudio ) { |
370 | 372 | ||
371 | do { | 373 | do { |
372 | message = rtp_recv_msg(av->rtp_sessions[audio_index]); | 374 | message = rtp_recv_msg(av->rtp_sessions[audio_index]); |
373 | 375 | ||
374 | if (message) { | 376 | if (message) { |
375 | /* push the packet into the queue */ | 377 | /* push the packet into the queue */ |
376 | queue(av->j_buf, message); | 378 | queue(av->j_buf, message); |
377 | } | 379 | } |
378 | } while(message); | 380 | } while (message); |
379 | 381 | ||
380 | int success = 0; | 382 | int success = 0; |
381 | message = dequeue(av->j_buf, &success); | 383 | message = dequeue(av->j_buf, &success); |
382 | 384 | ||
383 | if ( success == 2) return ErrorAudioPacketLost; | 385 | if ( success == 2) return ErrorAudioPacketLost; |
384 | } | 386 | } else { |
385 | else { | ||
386 | message = rtp_recv_msg(av->rtp_sessions[video_index]); | 387 | message = rtp_recv_msg(av->rtp_sessions[video_index]); |
387 | } | 388 | } |
388 | 389 | ||
389 | if ( message ) { | 390 | if ( message ) { |
390 | memcpy(dest, message->data, message->length); | 391 | memcpy(dest, message->data, message->length); |
391 | 392 | ||
392 | int length = message->length; | 393 | int length = message->length; |
393 | 394 | ||
394 | rtp_free_msg(NULL, message); | 395 | rtp_free_msg(NULL, message); |
395 | 396 | ||
396 | return length; | 397 | return length; |
397 | } | 398 | } |
398 | 399 | ||
399 | return 0; | 400 | return 0; |
400 | } | 401 | } |
401 | 402 | ||
402 | /** | 403 | /** |
403 | * @brief Receive decoded video packet. | 404 | * @brief Receive decoded video packet. |
404 | * | 405 | * |
405 | * @param av Handler. | 406 | * @param av Handler. |
406 | * @param output Storage. | 407 | * @param output Storage. |
407 | * @return int | 408 | * @return int |
408 | * @retval 0 Success. | 409 | * @retval 0 Success. |
409 | * @retval ToxAvError On Error. | 410 | * @retval ToxAvError On Error. |
410 | */ | 411 | */ |
411 | inline__ int toxav_recv_video ( ToxAv* av, vpx_image_t **output) | 412 | inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output) |
412 | { | 413 | { |
413 | if ( !output ) return ErrorInternal; | 414 | if ( !output ) return ErrorInternal; |
415 | |||
414 | uint8_t packet [RTP_PAYLOAD_SIZE]; | 416 | uint8_t packet [RTP_PAYLOAD_SIZE]; |
415 | int recved_size = 0; | 417 | int recved_size = 0; |
418 | |||
416 | do { | 419 | do { |
417 | recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet); | 420 | recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet); |
421 | |||
418 | if (recved_size > 0) { | 422 | if (recved_size > 0) { |
419 | printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0))); | 423 | printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0))); |
420 | } | 424 | } |
421 | }while (recved_size > 0); | 425 | } while (recved_size > 0); |
426 | |||
422 | vpx_codec_iter_t iter = NULL; | 427 | vpx_codec_iter_t iter = NULL; |
423 | vpx_image_t *img; | 428 | vpx_image_t *img; |
424 | img = vpx_codec_get_frame(&av->cs->v_decoder, &iter); | 429 | img = vpx_codec_get_frame(&av->cs->v_decoder, &iter); |
430 | |||
425 | if (img == NULL) | 431 | if (img == NULL) |
426 | return ErrorInternal; | 432 | return ErrorInternal; |
427 | 433 | ||
428 | *output = img; | 434 | *output = img; |
429 | return 0; | 435 | return 0; |
430 | } | 436 | } |
431 | 437 | ||
432 | /** | 438 | /** |
433 | * @brief Encode and send video packet. | 439 | * @brief Encode and send video packet. |
434 | * | 440 | * |
435 | * @param av Handler. | 441 | * @param av Handler. |
436 | * @param input The packet. | 442 | * @param input The packet. |
437 | * @return int | 443 | * @return int |
438 | * @retval 0 Success. | 444 | * @retval 0 Success. |
439 | * @retval ToxAvError On error. | 445 | * @retval ToxAvError On error. |
440 | */ | 446 | */ |
441 | inline__ int toxav_send_video ( ToxAv* av, vpx_image_t *input) | 447 | inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input) |
442 | { | 448 | { |
443 | if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) { | 449 | if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) { |
444 | printf("could not encode video frame\n"); | 450 | printf("could not encode video frame\n"); |
445 | return ErrorInternal; | 451 | return ErrorInternal; |
446 | } | 452 | } |
453 | |||
447 | ++av->cs->frame_counter; | 454 | ++av->cs->frame_counter; |
448 | 455 | ||
449 | vpx_codec_iter_t iter = NULL; | 456 | vpx_codec_iter_t iter = NULL; |
450 | const vpx_codec_cx_pkt_t *pkt; | 457 | const vpx_codec_cx_pkt_t *pkt; |
451 | int sent = 0; | 458 | int sent = 0; |
452 | while( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) { | 459 | |
460 | while ( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) { | ||
453 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | 461 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { |
454 | if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1) | 462 | if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1) |
455 | ++sent; | 463 | ++sent; |
456 | } | 464 | } |
457 | } | 465 | } |
466 | |||
458 | if (sent > 0) | 467 | if (sent > 0) |
459 | return 0; | 468 | return 0; |
460 | 469 | ||
461 | return ErrorInternal; | 470 | return ErrorInternal; |
462 | } | 471 | } |
463 | 472 | ||
464 | /** | 473 | /** |
465 | * @brief Receive decoded audio frame. | 474 | * @brief Receive decoded audio frame. |
466 | * | 475 | * |
467 | * @param av Handler. | 476 | * @param av Handler. |
468 | * @param frame_size ... | 477 | * @param frame_size ... |
469 | * @param dest Destination of the packet. Make sure it has enough space for | 478 | * @param dest Destination of the packet. Make sure it has enough space for |
470 | * RTP_PAYLOAD_SIZE bytes. | 479 | * RTP_PAYLOAD_SIZE bytes. |
471 | * @return int | 480 | * @return int |
472 | * @retval >=0 Size of received packet. | 481 | * @retval >=0 Size of received packet. |
473 | * @retval ToxAvError On error. | 482 | * @retval ToxAvError On error. |
474 | */ | 483 | */ |
475 | inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) | 484 | inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest ) |
476 | { | 485 | { |
477 | if ( !dest ) return ErrorInternal; | 486 | if ( !dest ) return ErrorInternal; |
487 | |||
478 | uint8_t packet [RTP_PAYLOAD_SIZE]; | 488 | uint8_t packet [RTP_PAYLOAD_SIZE]; |
479 | 489 | ||
480 | int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet); | 490 | int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet); |
@@ -482,7 +492,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) | |||
482 | if ( recved_size == ErrorAudioPacketLost ) { | 492 | if ( recved_size == ErrorAudioPacketLost ) { |
483 | printf("Lost packet\n"); | 493 | printf("Lost packet\n"); |
484 | return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1); | 494 | return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1); |
485 | } else if ( recved_size ){ | 495 | } else if ( recved_size ) { |
486 | return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); | 496 | return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); |
487 | } else { | 497 | } else { |
488 | return 0; /* Nothing received */ | 498 | return 0; /* Nothing received */ |
@@ -491,7 +501,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) | |||
491 | 501 | ||
492 | /** | 502 | /** |
493 | * @brief Encode and send audio frame. | 503 | * @brief Encode and send audio frame. |
494 | * | 504 | * |
495 | * @param av Handler. | 505 | * @param av Handler. |
496 | * @param frame The frame. | 506 | * @param frame The frame. |
497 | * @param frame_size It's size. | 507 | * @param frame_size It's size. |
@@ -499,10 +509,11 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) | |||
499 | * @retval 0 Success. | 509 | * @retval 0 Success. |
500 | * @retval ToxAvError On error. | 510 | * @retval ToxAvError On error. |
501 | */ | 511 | */ |
502 | inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size) | 512 | inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size) |
503 | { | 513 | { |
504 | uint8_t temp_data[RTP_PAYLOAD_SIZE]; | 514 | uint8_t temp_data[RTP_PAYLOAD_SIZE]; |
505 | int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data)); | 515 | int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data)); |
516 | |||
506 | if (ret <= 0) | 517 | if (ret <= 0) |
507 | return ErrorInternal; | 518 | return ErrorInternal; |
508 | 519 | ||
@@ -511,29 +522,30 @@ inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size) | |||
511 | 522 | ||
512 | /** | 523 | /** |
513 | * @brief Get peer transmission type. It can either be audio or video. | 524 | * @brief Get peer transmission type. It can either be audio or video. |
514 | * | 525 | * |
515 | * @param av Handler. | 526 | * @param av Handler. |
516 | * @param peer The peer | 527 | * @param peer The peer |
517 | * @return int | 528 | * @return int |
518 | * @retval ToxAvCallType On success. | 529 | * @retval ToxAvCallType On success. |
519 | * @retval ToxAvError On error. | 530 | * @retval ToxAvError On error. |
520 | */ | 531 | */ |
521 | int toxav_get_peer_transmission_type ( ToxAv* av, int peer ) | 532 | int toxav_get_peer_transmission_type ( ToxAv *av, int peer ) |
522 | { | 533 | { |
523 | assert(av->msi_session); | 534 | assert(av->msi_session); |
535 | |||
524 | if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer ) | 536 | if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer ) |
525 | return ErrorInternal; | 537 | return ErrorInternal; |
526 | 538 | ||
527 | return av->msi_session->call->type_peer[peer]; | 539 | return av->msi_session->call->type_peer[peer]; |
528 | } | 540 | } |
529 | 541 | ||
530 | /** | 542 | /** |
531 | * @brief Get reference to an object that is handling av session. | 543 | * @brief Get reference to an object that is handling av session. |
532 | * | 544 | * |
533 | * @param av Handler. | 545 | * @param av Handler. |
534 | * @return void* | 546 | * @return void* |
535 | */ | 547 | */ |
536 | void* toxav_get_agent_handler ( ToxAv* av ) | 548 | void *toxav_get_agent_handler ( ToxAv *av ) |
537 | { | 549 | { |
538 | return av->agent_handler; | 550 | return av->agent_handler; |
539 | } | 551 | } |