diff options
-rw-r--r-- | toxav/toxav.api.h | 23 | ||||
-rw-r--r-- | toxav/toxav.c | 295 | ||||
-rw-r--r-- | toxav/toxav.h | 22 |
3 files changed, 191 insertions, 149 deletions
diff --git a/toxav/toxav.api.h b/toxav/toxav.api.h index 9e6cea68..29a61f16 100644 --- a/toxav/toxav.api.h +++ b/toxav/toxav.api.h | |||
@@ -605,6 +605,10 @@ namespace video { | |||
605 | %{ | 605 | %{ |
606 | /** | 606 | /** |
607 | * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove | 607 | * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove |
608 | * | ||
609 | * TODO(iphydf): Use proper new API guidelines for these. E.g. don't use inline | ||
610 | * function types, don't have per-callback userdata, especially don't have one | ||
611 | * userdata per group. | ||
608 | */ | 612 | */ |
609 | /* Create a new toxav group. | 613 | /* Create a new toxav group. |
610 | * | 614 | * |
@@ -616,8 +620,9 @@ namespace video { | |||
616 | * | 620 | * |
617 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | 621 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). |
618 | */ | 622 | */ |
619 | int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, | 623 | int toxav_add_av_groupchat(Tox *tox, |
620 | uint32_t, void *), void *userdata); | 624 | void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), |
625 | void *userdata); | ||
621 | 626 | ||
622 | /* Join a AV group (you need to have been invited first.) | 627 | /* Join a AV group (you need to have been invited first.) |
623 | * | 628 | * |
@@ -630,7 +635,8 @@ int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, ui | |||
630 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | 635 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). |
631 | */ | 636 | */ |
632 | int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data, uint16_t length, | 637 | int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data, uint16_t length, |
633 | void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), void *userdata); | 638 | void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), |
639 | void *userdata); | ||
634 | 640 | ||
635 | /* Send audio to the group chat. | 641 | /* Send audio to the group chat. |
636 | * | 642 | * |
@@ -651,5 +657,16 @@ int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, u | |||
651 | #ifdef __cplusplus | 657 | #ifdef __cplusplus |
652 | } | 658 | } |
653 | #endif | 659 | #endif |
660 | |||
661 | typedef void toxav_group_audio_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, uint32_t samples, uint8_t channels, uint32_t sample_rate, void *user_data); | ||
662 | |||
663 | typedef TOXAV_ERR_CALL Toxav_Err_Call; | ||
664 | typedef TOXAV_ERR_NEW Toxav_Err_New; | ||
665 | typedef TOXAV_ERR_ANSWER Toxav_Err_Answer; | ||
666 | typedef TOXAV_ERR_CALL_CONTROL Toxav_Err_Call_Control; | ||
667 | typedef TOXAV_ERR_BIT_RATE_SET Toxav_Err_Bit_Rate_Set; | ||
668 | typedef TOXAV_ERR_SEND_FRAME Toxav_Err_Send_Frame; | ||
669 | typedef TOXAV_CALL_CONTROL Toxav_Call_Control; | ||
670 | |||
654 | #endif /* TOXAV_H */ | 671 | #endif /* TOXAV_H */ |
655 | %} | 672 | %} |
diff --git a/toxav/toxav.c b/toxav/toxav.c index 6f47a0bc..84e67858 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -128,20 +128,20 @@ int callback_capabilites(void *toxav_inst, MSICall *call); | |||
128 | bool audio_bit_rate_invalid(uint32_t bit_rate); | 128 | bool audio_bit_rate_invalid(uint32_t bit_rate); |
129 | bool video_bit_rate_invalid(uint32_t bit_rate); | 129 | bool video_bit_rate_invalid(uint32_t bit_rate); |
130 | bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); | 130 | bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); |
131 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); | 131 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error); |
132 | ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); | 132 | ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); |
133 | ToxAVCall *call_remove(ToxAVCall *call); | 133 | ToxAVCall *call_remove(ToxAVCall *call); |
134 | bool call_prepare_transmission(ToxAVCall *call); | 134 | bool call_prepare_transmission(ToxAVCall *call); |
135 | void call_kill_transmission(ToxAVCall *call); | 135 | void call_kill_transmission(ToxAVCall *call); |
136 | 136 | ||
137 | ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) | 137 | ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) |
138 | { | 138 | { |
139 | TOXAV_ERR_NEW rc = TOXAV_ERR_NEW_OK; | 139 | Toxav_Err_New rc = TOXAV_ERR_NEW_OK; |
140 | ToxAV *av = nullptr; | 140 | ToxAV *av = nullptr; |
141 | 141 | ||
142 | if (tox == nullptr) { | 142 | if (tox == nullptr) { |
143 | rc = TOXAV_ERR_NEW_NULL; | 143 | rc = TOXAV_ERR_NEW_NULL; |
144 | goto END; | 144 | goto RETURN; |
145 | } | 145 | } |
146 | 146 | ||
147 | // TODO(iphydf): Don't rely on toxcore internals. | 147 | // TODO(iphydf): Don't rely on toxcore internals. |
@@ -150,7 +150,7 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) | |||
150 | 150 | ||
151 | if (m->msi_packet) { | 151 | if (m->msi_packet) { |
152 | rc = TOXAV_ERR_NEW_MULTIPLE; | 152 | rc = TOXAV_ERR_NEW_MULTIPLE; |
153 | goto END; | 153 | goto RETURN; |
154 | } | 154 | } |
155 | 155 | ||
156 | av = (ToxAV *)calloc(sizeof(ToxAV), 1); | 156 | av = (ToxAV *)calloc(sizeof(ToxAV), 1); |
@@ -158,13 +158,13 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) | |||
158 | if (av == nullptr) { | 158 | if (av == nullptr) { |
159 | LOGGER_WARNING(m->log, "Allocation failed!"); | 159 | LOGGER_WARNING(m->log, "Allocation failed!"); |
160 | rc = TOXAV_ERR_NEW_MALLOC; | 160 | rc = TOXAV_ERR_NEW_MALLOC; |
161 | goto END; | 161 | goto RETURN; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (create_recursive_mutex(av->mutex) != 0) { | 164 | if (create_recursive_mutex(av->mutex) != 0) { |
165 | LOGGER_WARNING(m->log, "Mutex creation failed!"); | 165 | LOGGER_WARNING(m->log, "Mutex creation failed!"); |
166 | rc = TOXAV_ERR_NEW_MALLOC; | 166 | rc = TOXAV_ERR_NEW_MALLOC; |
167 | goto END; | 167 | goto RETURN; |
168 | } | 168 | } |
169 | 169 | ||
170 | av->tox = tox; | 170 | av->tox = tox; |
@@ -174,7 +174,7 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) | |||
174 | if (av->msi == nullptr) { | 174 | if (av->msi == nullptr) { |
175 | pthread_mutex_destroy(av->mutex); | 175 | pthread_mutex_destroy(av->mutex); |
176 | rc = TOXAV_ERR_NEW_MALLOC; | 176 | rc = TOXAV_ERR_NEW_MALLOC; |
177 | goto END; | 177 | goto RETURN; |
178 | } | 178 | } |
179 | 179 | ||
180 | av->interval = 200; | 180 | av->interval = 200; |
@@ -187,7 +187,7 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) | |||
187 | msi_register_callback(av->msi, callback_error, MSI_ON_PEERTIMEOUT); | 187 | msi_register_callback(av->msi, callback_error, MSI_ON_PEERTIMEOUT); |
188 | msi_register_callback(av->msi, callback_capabilites, MSI_ON_CAPABILITIES); | 188 | msi_register_callback(av->msi, callback_capabilites, MSI_ON_CAPABILITIES); |
189 | 189 | ||
190 | END: | 190 | RETURN: |
191 | 191 | ||
192 | if (error) { | 192 | if (error) { |
193 | *error = rc; | 193 | *error = rc; |
@@ -268,7 +268,7 @@ void toxav_iterate(ToxAV *av) | |||
268 | 268 | ||
269 | if (i->msi_call->self_capabilities & MSI_CAP_R_VIDEO && | 269 | if (i->msi_call->self_capabilities & MSI_CAP_R_VIDEO && |
270 | i->msi_call->peer_capabilities & MSI_CAP_S_VIDEO) { | 270 | i->msi_call->peer_capabilities & MSI_CAP_S_VIDEO) { |
271 | rc = min_u32(i->video->lcfd, (uint32_t) rc); | 271 | rc = min_u32(i->video->lcfd, rc); |
272 | } | 272 | } |
273 | 273 | ||
274 | uint32_t fid = i->friend_number; | 274 | uint32_t fid = i->friend_number; |
@@ -295,9 +295,9 @@ void toxav_iterate(ToxAV *av) | |||
295 | } | 295 | } |
296 | } | 296 | } |
297 | bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, | 297 | bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, |
298 | TOXAV_ERR_CALL *error) | 298 | Toxav_Err_Call *error) |
299 | { | 299 | { |
300 | TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; | 300 | Toxav_Err_Call rc = TOXAV_ERR_CALL_OK; |
301 | ToxAVCall *call; | 301 | ToxAVCall *call; |
302 | 302 | ||
303 | pthread_mutex_lock(av->mutex); | 303 | pthread_mutex_lock(av->mutex); |
@@ -305,13 +305,13 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint | |||
305 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) | 305 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) |
306 | || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))) { | 306 | || (video_bit_rate && video_bit_rate_invalid(video_bit_rate))) { |
307 | rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; | 307 | rc = TOXAV_ERR_CALL_INVALID_BIT_RATE; |
308 | goto END; | 308 | goto RETURN; |
309 | } | 309 | } |
310 | 310 | ||
311 | call = call_new(av, friend_number, &rc); | 311 | call = call_new(av, friend_number, &rc); |
312 | 312 | ||
313 | if (call == nullptr) { | 313 | if (call == nullptr) { |
314 | goto END; | 314 | goto RETURN; |
315 | } | 315 | } |
316 | 316 | ||
317 | call->audio_bit_rate = audio_bit_rate; | 317 | call->audio_bit_rate = audio_bit_rate; |
@@ -325,12 +325,12 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint | |||
325 | if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) { | 325 | if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) { |
326 | call_remove(call); | 326 | call_remove(call); |
327 | rc = TOXAV_ERR_CALL_SYNC; | 327 | rc = TOXAV_ERR_CALL_SYNC; |
328 | goto END; | 328 | goto RETURN; |
329 | } | 329 | } |
330 | 330 | ||
331 | call->msi_call->av_call = call; | 331 | call->msi_call->av_call = call; |
332 | 332 | ||
333 | END: | 333 | RETURN: |
334 | pthread_mutex_unlock(av->mutex); | 334 | pthread_mutex_unlock(av->mutex); |
335 | 335 | ||
336 | if (error) { | 336 | if (error) { |
@@ -347,35 +347,35 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) | |||
347 | pthread_mutex_unlock(av->mutex); | 347 | pthread_mutex_unlock(av->mutex); |
348 | } | 348 | } |
349 | bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, | 349 | bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, |
350 | TOXAV_ERR_ANSWER *error) | 350 | Toxav_Err_Answer *error) |
351 | { | 351 | { |
352 | pthread_mutex_lock(av->mutex); | 352 | pthread_mutex_lock(av->mutex); |
353 | 353 | ||
354 | TOXAV_ERR_ANSWER rc = TOXAV_ERR_ANSWER_OK; | 354 | Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK; |
355 | ToxAVCall *call; | 355 | ToxAVCall *call; |
356 | 356 | ||
357 | if (m_friend_exists(av->m, friend_number) == 0) { | 357 | if (m_friend_exists(av->m, friend_number) == 0) { |
358 | rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND; | 358 | rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND; |
359 | goto END; | 359 | goto RETURN; |
360 | } | 360 | } |
361 | 361 | ||
362 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) | 362 | if ((audio_bit_rate && audio_bit_rate_invalid(audio_bit_rate)) |
363 | || (video_bit_rate && video_bit_rate_invalid(video_bit_rate)) | 363 | || (video_bit_rate && video_bit_rate_invalid(video_bit_rate)) |
364 | ) { | 364 | ) { |
365 | rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE; | 365 | rc = TOXAV_ERR_ANSWER_INVALID_BIT_RATE; |
366 | goto END; | 366 | goto RETURN; |
367 | } | 367 | } |
368 | 368 | ||
369 | call = call_get(av, friend_number); | 369 | call = call_get(av, friend_number); |
370 | 370 | ||
371 | if (call == nullptr) { | 371 | if (call == nullptr) { |
372 | rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; | 372 | rc = TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING; |
373 | goto END; | 373 | goto RETURN; |
374 | } | 374 | } |
375 | 375 | ||
376 | if (!call_prepare_transmission(call)) { | 376 | if (!call_prepare_transmission(call)) { |
377 | rc = TOXAV_ERR_ANSWER_CODEC_INITIALIZATION; | 377 | rc = TOXAV_ERR_ANSWER_CODEC_INITIALIZATION; |
378 | goto END; | 378 | goto RETURN; |
379 | } | 379 | } |
380 | 380 | ||
381 | call->audio_bit_rate = audio_bit_rate; | 381 | call->audio_bit_rate = audio_bit_rate; |
@@ -390,7 +390,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui | |||
390 | rc = TOXAV_ERR_ANSWER_SYNC; | 390 | rc = TOXAV_ERR_ANSWER_SYNC; |
391 | } | 391 | } |
392 | 392 | ||
393 | END: | 393 | RETURN: |
394 | pthread_mutex_unlock(av->mutex); | 394 | pthread_mutex_unlock(av->mutex); |
395 | 395 | ||
396 | if (error) { | 396 | if (error) { |
@@ -406,22 +406,22 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u | |||
406 | av->scb_user_data = user_data; | 406 | av->scb_user_data = user_data; |
407 | pthread_mutex_unlock(av->mutex); | 407 | pthread_mutex_unlock(av->mutex); |
408 | } | 408 | } |
409 | bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) | 409 | bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control control, Toxav_Err_Call_Control *error) |
410 | { | 410 | { |
411 | pthread_mutex_lock(av->mutex); | 411 | pthread_mutex_lock(av->mutex); |
412 | TOXAV_ERR_CALL_CONTROL rc = TOXAV_ERR_CALL_CONTROL_OK; | 412 | Toxav_Err_Call_Control rc = TOXAV_ERR_CALL_CONTROL_OK; |
413 | ToxAVCall *call; | 413 | ToxAVCall *call; |
414 | 414 | ||
415 | if (m_friend_exists(av->m, friend_number) == 0) { | 415 | if (m_friend_exists(av->m, friend_number) == 0) { |
416 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND; | 416 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND; |
417 | goto END; | 417 | goto RETURN; |
418 | } | 418 | } |
419 | 419 | ||
420 | call = call_get(av, friend_number); | 420 | call = call_get(av, friend_number); |
421 | 421 | ||
422 | if (call == nullptr || (!call->active && control != TOXAV_CALL_CONTROL_CANCEL)) { | 422 | if (call == nullptr || (!call->active && control != TOXAV_CALL_CONTROL_CANCEL)) { |
423 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; | 423 | rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; |
424 | goto END; | 424 | goto RETURN; |
425 | } | 425 | } |
426 | 426 | ||
427 | switch (control) { | 427 | switch (control) { |
@@ -433,14 +433,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
433 | if (msi_change_capabilities(call->msi_call, | 433 | if (msi_change_capabilities(call->msi_call, |
434 | call->previous_self_capabilities) == -1) { | 434 | call->previous_self_capabilities) == -1) { |
435 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 435 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
436 | goto END; | 436 | goto RETURN; |
437 | } | 437 | } |
438 | 438 | ||
439 | rtp_allow_receiving(call->audio_rtp); | 439 | rtp_allow_receiving(call->audio_rtp); |
440 | rtp_allow_receiving(call->video_rtp); | 440 | rtp_allow_receiving(call->video_rtp); |
441 | } else { | 441 | } else { |
442 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 442 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
443 | goto END; | 443 | goto RETURN; |
444 | } | 444 | } |
445 | } | 445 | } |
446 | break; | 446 | break; |
@@ -452,14 +452,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
452 | 452 | ||
453 | if (msi_change_capabilities(call->msi_call, 0) == -1) { | 453 | if (msi_change_capabilities(call->msi_call, 0) == -1) { |
454 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 454 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
455 | goto END; | 455 | goto RETURN; |
456 | } | 456 | } |
457 | 457 | ||
458 | rtp_stop_receiving(call->audio_rtp); | 458 | rtp_stop_receiving(call->audio_rtp); |
459 | rtp_stop_receiving(call->video_rtp); | 459 | rtp_stop_receiving(call->video_rtp); |
460 | } else { | 460 | } else { |
461 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 461 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
462 | goto END; | 462 | goto RETURN; |
463 | } | 463 | } |
464 | } | 464 | } |
465 | break; | 465 | break; |
@@ -471,7 +471,7 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
471 | if (msi_hangup(call->msi_call) != 0) { | 471 | if (msi_hangup(call->msi_call) != 0) { |
472 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 472 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
473 | pthread_mutex_unlock(call->mutex); | 473 | pthread_mutex_unlock(call->mutex); |
474 | goto END; | 474 | goto RETURN; |
475 | } | 475 | } |
476 | 476 | ||
477 | call->msi_call = nullptr; | 477 | call->msi_call = nullptr; |
@@ -488,13 +488,13 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
488 | if (msi_change_capabilities(call->msi_call, call-> | 488 | if (msi_change_capabilities(call->msi_call, call-> |
489 | msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) { | 489 | msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) { |
490 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 490 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
491 | goto END; | 491 | goto RETURN; |
492 | } | 492 | } |
493 | 493 | ||
494 | rtp_stop_receiving(call->audio_rtp); | 494 | rtp_stop_receiving(call->audio_rtp); |
495 | } else { | 495 | } else { |
496 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 496 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
497 | goto END; | 497 | goto RETURN; |
498 | } | 498 | } |
499 | } | 499 | } |
500 | break; | 500 | break; |
@@ -504,13 +504,13 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
504 | if (msi_change_capabilities(call->msi_call, call-> | 504 | if (msi_change_capabilities(call->msi_call, call-> |
505 | msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) { | 505 | msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) { |
506 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 506 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
507 | goto END; | 507 | goto RETURN; |
508 | } | 508 | } |
509 | 509 | ||
510 | rtp_allow_receiving(call->audio_rtp); | 510 | rtp_allow_receiving(call->audio_rtp); |
511 | } else { | 511 | } else { |
512 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 512 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
513 | goto END; | 513 | goto RETURN; |
514 | } | 514 | } |
515 | } | 515 | } |
516 | break; | 516 | break; |
@@ -520,13 +520,13 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
520 | if (msi_change_capabilities(call->msi_call, call-> | 520 | if (msi_change_capabilities(call->msi_call, call-> |
521 | msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) { | 521 | msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) { |
522 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 522 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
523 | goto END; | 523 | goto RETURN; |
524 | } | 524 | } |
525 | 525 | ||
526 | rtp_stop_receiving(call->video_rtp); | 526 | rtp_stop_receiving(call->video_rtp); |
527 | } else { | 527 | } else { |
528 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 528 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
529 | goto END; | 529 | goto RETURN; |
530 | } | 530 | } |
531 | } | 531 | } |
532 | break; | 532 | break; |
@@ -536,19 +536,19 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co | |||
536 | if (msi_change_capabilities(call->msi_call, call-> | 536 | if (msi_change_capabilities(call->msi_call, call-> |
537 | msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) { | 537 | msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) { |
538 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; | 538 | rc = TOXAV_ERR_CALL_CONTROL_SYNC; |
539 | goto END; | 539 | goto RETURN; |
540 | } | 540 | } |
541 | 541 | ||
542 | rtp_allow_receiving(call->video_rtp); | 542 | rtp_allow_receiving(call->video_rtp); |
543 | } else { | 543 | } else { |
544 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; | 544 | rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; |
545 | goto END; | 545 | goto RETURN; |
546 | } | 546 | } |
547 | } | 547 | } |
548 | break; | 548 | break; |
549 | } | 549 | } |
550 | 550 | ||
551 | END: | 551 | RETURN: |
552 | pthread_mutex_unlock(av->mutex); | 552 | pthread_mutex_unlock(av->mutex); |
553 | 553 | ||
554 | if (error) { | 554 | if (error) { |
@@ -558,19 +558,19 @@ END: | |||
558 | return rc == TOXAV_ERR_CALL_CONTROL_OK; | 558 | return rc == TOXAV_ERR_CALL_CONTROL_OK; |
559 | } | 559 | } |
560 | bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, | 560 | bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, |
561 | TOXAV_ERR_BIT_RATE_SET *error) | 561 | Toxav_Err_Bit_Rate_Set *error) |
562 | { | 562 | { |
563 | TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK; | 563 | Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; |
564 | ToxAVCall *call; | 564 | ToxAVCall *call; |
565 | 565 | ||
566 | if (m_friend_exists(av->m, friend_number) == 0) { | 566 | if (m_friend_exists(av->m, friend_number) == 0) { |
567 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; | 567 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; |
568 | goto END; | 568 | goto RETURN; |
569 | } | 569 | } |
570 | 570 | ||
571 | if (audio_bit_rate > 0 && audio_bit_rate_invalid(audio_bit_rate)) { | 571 | if (audio_bit_rate > 0 && audio_bit_rate_invalid(audio_bit_rate)) { |
572 | rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; | 572 | rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; |
573 | goto END; | 573 | goto RETURN; |
574 | } | 574 | } |
575 | 575 | ||
576 | pthread_mutex_lock(av->mutex); | 576 | pthread_mutex_lock(av->mutex); |
@@ -579,7 +579,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ | |||
579 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { | 579 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { |
580 | pthread_mutex_unlock(av->mutex); | 580 | pthread_mutex_unlock(av->mutex); |
581 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; | 581 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; |
582 | goto END; | 582 | goto RETURN; |
583 | } | 583 | } |
584 | 584 | ||
585 | LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", audio_bit_rate); | 585 | LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", audio_bit_rate); |
@@ -593,7 +593,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ | |||
593 | self_capabilities ^ MSI_CAP_S_AUDIO) != 0) { | 593 | self_capabilities ^ MSI_CAP_S_AUDIO) != 0) { |
594 | pthread_mutex_unlock(av->mutex); | 594 | pthread_mutex_unlock(av->mutex); |
595 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; | 595 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; |
596 | goto END; | 596 | goto RETURN; |
597 | } | 597 | } |
598 | 598 | ||
599 | /* Audio sending is turned off; notify peer */ | 599 | /* Audio sending is turned off; notify peer */ |
@@ -610,7 +610,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ | |||
610 | pthread_mutex_unlock(call->mutex); | 610 | pthread_mutex_unlock(call->mutex); |
611 | pthread_mutex_unlock(av->mutex); | 611 | pthread_mutex_unlock(av->mutex); |
612 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; | 612 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; |
613 | goto END; | 613 | goto RETURN; |
614 | } | 614 | } |
615 | } else { | 615 | } else { |
616 | LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", audio_bit_rate); | 616 | LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", audio_bit_rate); |
@@ -621,7 +621,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t audio_ | |||
621 | } | 621 | } |
622 | 622 | ||
623 | pthread_mutex_unlock(av->mutex); | 623 | pthread_mutex_unlock(av->mutex); |
624 | END: | 624 | RETURN: |
625 | 625 | ||
626 | if (error) { | 626 | if (error) { |
627 | *error = rc; | 627 | *error = rc; |
@@ -630,19 +630,19 @@ END: | |||
630 | return rc == TOXAV_ERR_BIT_RATE_SET_OK; | 630 | return rc == TOXAV_ERR_BIT_RATE_SET_OK; |
631 | } | 631 | } |
632 | bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, | 632 | bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, |
633 | TOXAV_ERR_BIT_RATE_SET *error) | 633 | Toxav_Err_Bit_Rate_Set *error) |
634 | { | 634 | { |
635 | TOXAV_ERR_BIT_RATE_SET rc = TOXAV_ERR_BIT_RATE_SET_OK; | 635 | Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; |
636 | ToxAVCall *call; | 636 | ToxAVCall *call; |
637 | 637 | ||
638 | if (m_friend_exists(av->m, friend_number) == 0) { | 638 | if (m_friend_exists(av->m, friend_number) == 0) { |
639 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; | 639 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; |
640 | goto END; | 640 | goto RETURN; |
641 | } | 641 | } |
642 | 642 | ||
643 | if (video_bit_rate > 0 && video_bit_rate_invalid(video_bit_rate)) { | 643 | if (video_bit_rate > 0 && video_bit_rate_invalid(video_bit_rate)) { |
644 | rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; | 644 | rc = TOXAV_ERR_BIT_RATE_SET_INVALID_BIT_RATE; |
645 | goto END; | 645 | goto RETURN; |
646 | } | 646 | } |
647 | 647 | ||
648 | pthread_mutex_lock(av->mutex); | 648 | pthread_mutex_lock(av->mutex); |
@@ -651,7 +651,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ | |||
651 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { | 651 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { |
652 | pthread_mutex_unlock(av->mutex); | 652 | pthread_mutex_unlock(av->mutex); |
653 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; | 653 | rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_IN_CALL; |
654 | goto END; | 654 | goto RETURN; |
655 | } | 655 | } |
656 | 656 | ||
657 | LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", video_bit_rate); | 657 | LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", video_bit_rate); |
@@ -666,7 +666,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ | |||
666 | self_capabilities ^ MSI_CAP_S_VIDEO) != 0) { | 666 | self_capabilities ^ MSI_CAP_S_VIDEO) != 0) { |
667 | pthread_mutex_unlock(av->mutex); | 667 | pthread_mutex_unlock(av->mutex); |
668 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; | 668 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; |
669 | goto END; | 669 | goto RETURN; |
670 | } | 670 | } |
671 | 671 | ||
672 | call->video_bit_rate = 0; | 672 | call->video_bit_rate = 0; |
@@ -682,7 +682,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ | |||
682 | pthread_mutex_unlock(call->mutex); | 682 | pthread_mutex_unlock(call->mutex); |
683 | pthread_mutex_unlock(av->mutex); | 683 | pthread_mutex_unlock(av->mutex); |
684 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; | 684 | rc = TOXAV_ERR_BIT_RATE_SET_SYNC; |
685 | goto END; | 685 | goto RETURN; |
686 | } | 686 | } |
687 | } else { | 687 | } else { |
688 | LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", video_bit_rate); | 688 | LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", video_bit_rate); |
@@ -693,7 +693,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t video_ | |||
693 | } | 693 | } |
694 | 694 | ||
695 | pthread_mutex_unlock(av->mutex); | 695 | pthread_mutex_unlock(av->mutex); |
696 | END: | 696 | RETURN: |
697 | 697 | ||
698 | if (error) { | 698 | if (error) { |
699 | *error = rc; | 699 | *error = rc; |
@@ -716,19 +716,19 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, | |||
716 | pthread_mutex_unlock(av->mutex); | 716 | pthread_mutex_unlock(av->mutex); |
717 | } | 717 | } |
718 | bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, | 718 | bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, |
719 | uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME *error) | 719 | uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error) |
720 | { | 720 | { |
721 | TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; | 721 | Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; |
722 | ToxAVCall *call; | 722 | ToxAVCall *call; |
723 | 723 | ||
724 | if (m_friend_exists(av->m, friend_number) == 0) { | 724 | if (m_friend_exists(av->m, friend_number) == 0) { |
725 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; | 725 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; |
726 | goto END; | 726 | goto RETURN; |
727 | } | 727 | } |
728 | 728 | ||
729 | if (pthread_mutex_trylock(av->mutex) != 0) { | 729 | if (pthread_mutex_trylock(av->mutex) != 0) { |
730 | rc = TOXAV_ERR_SEND_FRAME_SYNC; | 730 | rc = TOXAV_ERR_SEND_FRAME_SYNC; |
731 | goto END; | 731 | goto RETURN; |
732 | } | 732 | } |
733 | 733 | ||
734 | call = call_get(av, friend_number); | 734 | call = call_get(av, friend_number); |
@@ -736,7 +736,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc | |||
736 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { | 736 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { |
737 | pthread_mutex_unlock(av->mutex); | 737 | pthread_mutex_unlock(av->mutex); |
738 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; | 738 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; |
739 | goto END; | 739 | goto RETURN; |
740 | } | 740 | } |
741 | 741 | ||
742 | if (call->audio_bit_rate == 0 || | 742 | if (call->audio_bit_rate == 0 || |
@@ -744,7 +744,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc | |||
744 | !(call->msi_call->peer_capabilities & MSI_CAP_R_AUDIO)) { | 744 | !(call->msi_call->peer_capabilities & MSI_CAP_R_AUDIO)) { |
745 | pthread_mutex_unlock(av->mutex); | 745 | pthread_mutex_unlock(av->mutex); |
746 | rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; | 746 | rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; |
747 | goto END; | 747 | goto RETURN; |
748 | } | 748 | } |
749 | 749 | ||
750 | pthread_mutex_lock(call->mutex_audio); | 750 | pthread_mutex_lock(call->mutex_audio); |
@@ -753,20 +753,20 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc | |||
753 | if (pcm == nullptr) { | 753 | if (pcm == nullptr) { |
754 | pthread_mutex_unlock(call->mutex_audio); | 754 | pthread_mutex_unlock(call->mutex_audio); |
755 | rc = TOXAV_ERR_SEND_FRAME_NULL; | 755 | rc = TOXAV_ERR_SEND_FRAME_NULL; |
756 | goto END; | 756 | goto RETURN; |
757 | } | 757 | } |
758 | 758 | ||
759 | if (channels > 2) { | 759 | if (channels > 2) { |
760 | pthread_mutex_unlock(call->mutex_audio); | 760 | pthread_mutex_unlock(call->mutex_audio); |
761 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 761 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
762 | goto END; | 762 | goto RETURN; |
763 | } | 763 | } |
764 | 764 | ||
765 | { /* Encode and send */ | 765 | { /* Encode and send */ |
766 | if (ac_reconfigure_encoder(call->audio, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { | 766 | if (ac_reconfigure_encoder(call->audio, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) { |
767 | pthread_mutex_unlock(call->mutex_audio); | 767 | pthread_mutex_unlock(call->mutex_audio); |
768 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 768 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
769 | goto END; | 769 | goto RETURN; |
770 | } | 770 | } |
771 | 771 | ||
772 | VLA(uint8_t, dest, sample_count + sizeof(sampling_rate)); /* This is more than enough always */ | 772 | VLA(uint8_t, dest, sample_count + sizeof(sampling_rate)); /* This is more than enough always */ |
@@ -780,7 +780,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc | |||
780 | LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc)); | 780 | LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc)); |
781 | pthread_mutex_unlock(call->mutex_audio); | 781 | pthread_mutex_unlock(call->mutex_audio); |
782 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 782 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
783 | goto END; | 783 | goto RETURN; |
784 | } | 784 | } |
785 | 785 | ||
786 | if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) { | 786 | if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) { |
@@ -791,7 +791,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc | |||
791 | 791 | ||
792 | pthread_mutex_unlock(call->mutex_audio); | 792 | pthread_mutex_unlock(call->mutex_audio); |
793 | 793 | ||
794 | END: | 794 | RETURN: |
795 | 795 | ||
796 | if (error) { | 796 | if (error) { |
797 | *error = rc; | 797 | *error = rc; |
@@ -800,22 +800,60 @@ END: | |||
800 | return rc == TOXAV_ERR_SEND_FRAME_OK; | 800 | return rc == TOXAV_ERR_SEND_FRAME_OK; |
801 | } | 801 | } |
802 | 802 | ||
803 | static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call) | ||
804 | { | ||
805 | vpx_codec_iter_t iter = nullptr; | ||
806 | |||
807 | for (const vpx_codec_cx_pkt_t *pkt = vpx_codec_get_cx_data(call->video->encoder, &iter); | ||
808 | pkt != nullptr; | ||
809 | pkt = vpx_codec_get_cx_data(call->video->encoder, &iter)) { | ||
810 | if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) { | ||
811 | continue; | ||
812 | } | ||
813 | |||
814 | const bool is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; | ||
815 | |||
816 | // https://www.webmproject.org/docs/webm-sdk/structvpx__codec__cx__pkt.html | ||
817 | // pkt->data.frame.sz -> size_t | ||
818 | const uint32_t frame_length_in_bytes = pkt->data.frame.sz; | ||
819 | |||
820 | const int res = rtp_send_data( | ||
821 | call->video_rtp, | ||
822 | (const uint8_t *)pkt->data.frame.buf, | ||
823 | frame_length_in_bytes, | ||
824 | is_keyframe, | ||
825 | log); | ||
826 | |||
827 | LOGGER_DEBUG(log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".", | ||
828 | (int)pkt->data.frame.sz, (int)frame_length_in_bytes); | ||
829 | const uint8_t *const buf = (const uint8_t *)pkt->data.frame.buf; | ||
830 | LOGGER_DEBUG(log, "+ _sending_FRAME_ b0=%d b1=%d", buf[0], buf[1]); | ||
831 | |||
832 | if (res < 0) { | ||
833 | LOGGER_WARNING(log, "Could not send video frame: %s", strerror(errno)); | ||
834 | return TOXAV_ERR_SEND_FRAME_RTP_FAILED; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | return TOXAV_ERR_SEND_FRAME_OK; | ||
839 | } | ||
840 | |||
803 | bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, | 841 | bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, |
804 | const uint8_t *u, const uint8_t *v, TOXAV_ERR_SEND_FRAME *error) | 842 | const uint8_t *u, const uint8_t *v, Toxav_Err_Send_Frame *error) |
805 | { | 843 | { |
806 | TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; | 844 | Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; |
807 | ToxAVCall *call; | 845 | ToxAVCall *call; |
808 | 846 | ||
809 | int vpx_encode_flags = 0; | 847 | int vpx_encode_flags = 0; |
810 | 848 | ||
811 | if (m_friend_exists(av->m, friend_number) == 0) { | 849 | if (m_friend_exists(av->m, friend_number) == 0) { |
812 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; | 850 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; |
813 | goto END; | 851 | goto RETURN; |
814 | } | 852 | } |
815 | 853 | ||
816 | if (pthread_mutex_trylock(av->mutex) != 0) { | 854 | if (pthread_mutex_trylock(av->mutex) != 0) { |
817 | rc = TOXAV_ERR_SEND_FRAME_SYNC; | 855 | rc = TOXAV_ERR_SEND_FRAME_SYNC; |
818 | goto END; | 856 | goto RETURN; |
819 | } | 857 | } |
820 | 858 | ||
821 | call = call_get(av, friend_number); | 859 | call = call_get(av, friend_number); |
@@ -823,7 +861,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u | |||
823 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { | 861 | if (call == nullptr || !call->active || call->msi_call->state != MSI_CALL_ACTIVE) { |
824 | pthread_mutex_unlock(av->mutex); | 862 | pthread_mutex_unlock(av->mutex); |
825 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; | 863 | rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL; |
826 | goto END; | 864 | goto RETURN; |
827 | } | 865 | } |
828 | 866 | ||
829 | if (call->video_bit_rate == 0 || | 867 | if (call->video_bit_rate == 0 || |
@@ -831,7 +869,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u | |||
831 | !(call->msi_call->peer_capabilities & MSI_CAP_R_VIDEO)) { | 869 | !(call->msi_call->peer_capabilities & MSI_CAP_R_VIDEO)) { |
832 | pthread_mutex_unlock(av->mutex); | 870 | pthread_mutex_unlock(av->mutex); |
833 | rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; | 871 | rc = TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED; |
834 | goto END; | 872 | goto RETURN; |
835 | } | 873 | } |
836 | 874 | ||
837 | pthread_mutex_lock(call->mutex_video); | 875 | pthread_mutex_lock(call->mutex_video); |
@@ -840,13 +878,13 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u | |||
840 | if (y == nullptr || u == nullptr || v == nullptr) { | 878 | if (y == nullptr || u == nullptr || v == nullptr) { |
841 | pthread_mutex_unlock(call->mutex_video); | 879 | pthread_mutex_unlock(call->mutex_video); |
842 | rc = TOXAV_ERR_SEND_FRAME_NULL; | 880 | rc = TOXAV_ERR_SEND_FRAME_NULL; |
843 | goto END; | 881 | goto RETURN; |
844 | } | 882 | } |
845 | 883 | ||
846 | if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) { | 884 | if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) { |
847 | pthread_mutex_unlock(call->mutex_video); | 885 | pthread_mutex_unlock(call->mutex_video); |
848 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 886 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
849 | goto END; | 887 | goto RETURN; |
850 | } | 888 | } |
851 | 889 | ||
852 | if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) { | 890 | if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) { |
@@ -854,20 +892,23 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u | |||
854 | vpx_encode_flags = VPX_EFLAG_FORCE_KF; | 892 | vpx_encode_flags = VPX_EFLAG_FORCE_KF; |
855 | LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc); | 893 | LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc); |
856 | 894 | ||
857 | call->video_rtp->ssrc++; | 895 | ++call->video_rtp->ssrc; |
858 | } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) { | 896 | } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) { |
859 | // normal keyframe placement | 897 | // normal keyframe placement |
860 | vpx_encode_flags = 0; | 898 | vpx_encode_flags = 0; |
861 | LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc); | 899 | LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc); |
862 | 900 | ||
863 | call->video_rtp->ssrc++; | 901 | ++call->video_rtp->ssrc; |
864 | } | 902 | } |
865 | 903 | ||
866 | // we start with I-frames (full frames) and then switch to normal mode later | 904 | // we start with I-frames (full frames) and then switch to normal mode later |
867 | 905 | ||
868 | { /* Encode */ | 906 | { /* Encode */ |
869 | vpx_image_t img; | 907 | vpx_image_t img; |
870 | img.w = img.h = img.d_w = img.d_h = 0; | 908 | img.w = 0; |
909 | img.h = 0; | ||
910 | img.d_w = 0; | ||
911 | img.d_h = 0; | ||
871 | vpx_img_alloc(&img, VPX_IMG_FMT_I420, width, height, 0); | 912 | vpx_img_alloc(&img, VPX_IMG_FMT_I420, width, height, 0); |
872 | 913 | ||
873 | /* I420 "It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes." | 914 | /* I420 "It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes." |
@@ -886,49 +927,17 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u | |||
886 | pthread_mutex_unlock(call->mutex_video); | 927 | pthread_mutex_unlock(call->mutex_video); |
887 | LOGGER_ERROR(av->m->log, "Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc)); | 928 | LOGGER_ERROR(av->m->log, "Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc)); |
888 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 929 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
889 | goto END; | 930 | goto RETURN; |
890 | } | 931 | } |
891 | } | 932 | } |
892 | 933 | ||
893 | ++call->video->frame_counter; | 934 | ++call->video->frame_counter; |
894 | 935 | ||
895 | { /* Send frames */ | 936 | rc = send_frames(av->m->log, call); |
896 | vpx_codec_iter_t iter = nullptr; | ||
897 | const vpx_codec_cx_pkt_t *pkt; | ||
898 | |||
899 | while ((pkt = vpx_codec_get_cx_data(call->video->encoder, &iter)) != nullptr) { | ||
900 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | ||
901 | const bool is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; | ||
902 | |||
903 | // https://www.webmproject.org/docs/webm-sdk/structvpx__codec__cx__pkt.html | ||
904 | // pkt->data.frame.sz -> size_t | ||
905 | const uint32_t frame_length_in_bytes = pkt->data.frame.sz; | ||
906 | |||
907 | const int res = rtp_send_data( | ||
908 | call->video_rtp, | ||
909 | (const uint8_t *)pkt->data.frame.buf, | ||
910 | frame_length_in_bytes, | ||
911 | is_keyframe, | ||
912 | av->m->log); | ||
913 | |||
914 | LOGGER_DEBUG(av->m->log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".", | ||
915 | (int)pkt->data.frame.sz, (int)frame_length_in_bytes); | ||
916 | LOGGER_DEBUG(av->m->log, "+ _sending_FRAME_ b0=%d b1=%d", ((const uint8_t *)pkt->data.frame.buf)[0], | ||
917 | ((const uint8_t *)pkt->data.frame.buf)[1]); | ||
918 | |||
919 | if (res < 0) { | ||
920 | pthread_mutex_unlock(call->mutex_video); | ||
921 | LOGGER_WARNING(av->m->log, "Could not send video frame: %s", strerror(errno)); | ||
922 | rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; | ||
923 | goto END; | ||
924 | } | ||
925 | } | ||
926 | } | ||
927 | } | ||
928 | 937 | ||
929 | pthread_mutex_unlock(call->mutex_video); | 938 | pthread_mutex_unlock(call->mutex_video); |
930 | 939 | ||
931 | END: | 940 | RETURN: |
932 | 941 | ||
933 | if (error) { | 942 | if (error) { |
934 | *error = rc; | 943 | *error = rc; |
@@ -986,9 +995,9 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u | |||
986 | return; | 995 | return; |
987 | } | 996 | } |
988 | 997 | ||
989 | (*call->av->vbcb)(call->av, friend_number, | 998 | call->av->vbcb(call->av, friend_number, |
990 | call->video_bit_rate - (call->video_bit_rate * loss), | 999 | call->video_bit_rate - (call->video_bit_rate * loss), |
991 | call->av->vbcb_user_data); | 1000 | call->av->vbcb_user_data); |
992 | } else if (call->audio_bit_rate) { | 1001 | } else if (call->audio_bit_rate) { |
993 | if (!call->av->abcb) { | 1002 | if (!call->av->abcb) { |
994 | pthread_mutex_unlock(call->av->mutex); | 1003 | pthread_mutex_unlock(call->av->mutex); |
@@ -996,9 +1005,9 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u | |||
996 | return; | 1005 | return; |
997 | } | 1006 | } |
998 | 1007 | ||
999 | (*call->av->abcb)(call->av, friend_number, | 1008 | call->av->abcb(call->av, friend_number, |
1000 | call->audio_bit_rate - (call->audio_bit_rate * loss), | 1009 | call->audio_bit_rate - (call->audio_bit_rate * loss), |
1001 | call->av->abcb_user_data); | 1010 | call->av->abcb_user_data); |
1002 | } | 1011 | } |
1003 | 1012 | ||
1004 | pthread_mutex_unlock(call->av->mutex); | 1013 | pthread_mutex_unlock(call->av->mutex); |
@@ -1067,8 +1076,8 @@ int callback_end(void *toxav_inst, MSICall *call) | |||
1067 | invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED); | 1076 | invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED); |
1068 | 1077 | ||
1069 | if (call->av_call) { | 1078 | if (call->av_call) { |
1070 | call_kill_transmission((ToxAVCall *)call->av_call); | 1079 | call_kill_transmission(call->av_call); |
1071 | call_remove((ToxAVCall *)call->av_call); | 1080 | call_remove(call->av_call); |
1072 | } | 1081 | } |
1073 | 1082 | ||
1074 | pthread_mutex_unlock(toxav->mutex); | 1083 | pthread_mutex_unlock(toxav->mutex); |
@@ -1082,8 +1091,8 @@ int callback_error(void *toxav_inst, MSICall *call) | |||
1082 | invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR); | 1091 | invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR); |
1083 | 1092 | ||
1084 | if (call->av_call) { | 1093 | if (call->av_call) { |
1085 | call_kill_transmission((ToxAVCall *)call->av_call); | 1094 | call_kill_transmission(call->av_call); |
1086 | call_remove((ToxAVCall *)call->av_call); | 1095 | call_remove(call->av_call); |
1087 | } | 1096 | } |
1088 | 1097 | ||
1089 | pthread_mutex_unlock(toxav->mutex); | 1098 | pthread_mutex_unlock(toxav->mutex); |
@@ -1095,15 +1104,15 @@ int callback_capabilites(void *toxav_inst, MSICall *call) | |||
1095 | pthread_mutex_lock(toxav->mutex); | 1104 | pthread_mutex_lock(toxav->mutex); |
1096 | 1105 | ||
1097 | if (call->peer_capabilities & MSI_CAP_S_AUDIO) { | 1106 | if (call->peer_capabilities & MSI_CAP_S_AUDIO) { |
1098 | rtp_allow_receiving(((ToxAVCall *)call->av_call)->audio_rtp); | 1107 | rtp_allow_receiving(call->av_call->audio_rtp); |
1099 | } else { | 1108 | } else { |
1100 | rtp_stop_receiving(((ToxAVCall *)call->av_call)->audio_rtp); | 1109 | rtp_stop_receiving(call->av_call->audio_rtp); |
1101 | } | 1110 | } |
1102 | 1111 | ||
1103 | if (call->peer_capabilities & MSI_CAP_S_VIDEO) { | 1112 | if (call->peer_capabilities & MSI_CAP_S_VIDEO) { |
1104 | rtp_allow_receiving(((ToxAVCall *)call->av_call)->video_rtp); | 1113 | rtp_allow_receiving(call->av_call->video_rtp); |
1105 | } else { | 1114 | } else { |
1106 | rtp_stop_receiving(((ToxAVCall *)call->av_call)->video_rtp); | 1115 | rtp_stop_receiving(call->av_call->video_rtp); |
1107 | } | 1116 | } |
1108 | 1117 | ||
1109 | invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities); | 1118 | invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities); |
@@ -1140,32 +1149,32 @@ bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t stat | |||
1140 | return true; | 1149 | return true; |
1141 | } | 1150 | } |
1142 | 1151 | ||
1143 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) | 1152 | ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error) |
1144 | { | 1153 | { |
1145 | /* Assumes mutex locked */ | 1154 | /* Assumes mutex locked */ |
1146 | TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; | 1155 | Toxav_Err_Call rc = TOXAV_ERR_CALL_OK; |
1147 | ToxAVCall *call = nullptr; | 1156 | ToxAVCall *call = nullptr; |
1148 | 1157 | ||
1149 | if (m_friend_exists(av->m, friend_number) == 0) { | 1158 | if (m_friend_exists(av->m, friend_number) == 0) { |
1150 | rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND; | 1159 | rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND; |
1151 | goto END; | 1160 | goto RETURN; |
1152 | } | 1161 | } |
1153 | 1162 | ||
1154 | if (m_get_friend_connectionstatus(av->m, friend_number) < 1) { | 1163 | if (m_get_friend_connectionstatus(av->m, friend_number) < 1) { |
1155 | rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED; | 1164 | rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED; |
1156 | goto END; | 1165 | goto RETURN; |
1157 | } | 1166 | } |
1158 | 1167 | ||
1159 | if (call_get(av, friend_number) != nullptr) { | 1168 | if (call_get(av, friend_number) != nullptr) { |
1160 | rc = TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL; | 1169 | rc = TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL; |
1161 | goto END; | 1170 | goto RETURN; |
1162 | } | 1171 | } |
1163 | 1172 | ||
1164 | call = (ToxAVCall *)calloc(sizeof(ToxAVCall), 1); | 1173 | call = (ToxAVCall *)calloc(sizeof(ToxAVCall), 1); |
1165 | 1174 | ||
1166 | if (call == nullptr) { | 1175 | if (call == nullptr) { |
1167 | rc = TOXAV_ERR_CALL_MALLOC; | 1176 | rc = TOXAV_ERR_CALL_MALLOC; |
1168 | goto END; | 1177 | goto RETURN; |
1169 | } | 1178 | } |
1170 | 1179 | ||
1171 | call->av = av; | 1180 | call->av = av; |
@@ -1178,10 +1187,11 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) | |||
1178 | free(call); | 1187 | free(call); |
1179 | call = nullptr; | 1188 | call = nullptr; |
1180 | rc = TOXAV_ERR_CALL_MALLOC; | 1189 | rc = TOXAV_ERR_CALL_MALLOC; |
1181 | goto END; | 1190 | goto RETURN; |
1182 | } | 1191 | } |
1183 | 1192 | ||
1184 | av->calls_tail = av->calls_head = friend_number; | 1193 | av->calls_tail = friend_number; |
1194 | av->calls_head = friend_number; | ||
1185 | } else if (av->calls_tail < friend_number) { /* Appending */ | 1195 | } else if (av->calls_tail < friend_number) { /* Appending */ |
1186 | ToxAVCall **tmp = (ToxAVCall **)realloc(av->calls, sizeof(ToxAVCall *) * (friend_number + 1)); | 1196 | ToxAVCall **tmp = (ToxAVCall **)realloc(av->calls, sizeof(ToxAVCall *) * (friend_number + 1)); |
1187 | 1197 | ||
@@ -1189,15 +1199,13 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) | |||
1189 | free(call); | 1199 | free(call); |
1190 | call = nullptr; | 1200 | call = nullptr; |
1191 | rc = TOXAV_ERR_CALL_MALLOC; | 1201 | rc = TOXAV_ERR_CALL_MALLOC; |
1192 | goto END; | 1202 | goto RETURN; |
1193 | } | 1203 | } |
1194 | 1204 | ||
1195 | av->calls = tmp; | 1205 | av->calls = tmp; |
1196 | 1206 | ||
1197 | /* Set fields in between to null */ | 1207 | /* Set fields in between to null */ |
1198 | uint32_t i = av->calls_tail + 1; | 1208 | for (uint32_t i = av->calls_tail + 1; i < friend_number; ++i) { |
1199 | |||
1200 | for (; i < friend_number; i ++) { | ||
1201 | av->calls[i] = nullptr; | 1209 | av->calls[i] = nullptr; |
1202 | } | 1210 | } |
1203 | 1211 | ||
@@ -1213,7 +1221,7 @@ ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error) | |||
1213 | 1221 | ||
1214 | av->calls[friend_number] = call; | 1222 | av->calls[friend_number] = call; |
1215 | 1223 | ||
1216 | END: | 1224 | RETURN: |
1217 | 1225 | ||
1218 | if (error) { | 1226 | if (error) { |
1219 | *error = rc; | 1227 | *error = rc; |
@@ -1273,7 +1281,8 @@ ToxAVCall *call_remove(ToxAVCall *call) | |||
1273 | return next; | 1281 | return next; |
1274 | 1282 | ||
1275 | CLEAR: | 1283 | CLEAR: |
1276 | av->calls_head = av->calls_tail = 0; | 1284 | av->calls_head = 0; |
1285 | av->calls_tail = 0; | ||
1277 | free(av->calls); | 1286 | free(av->calls); |
1278 | av->calls = nullptr; | 1287 | av->calls = nullptr; |
1279 | 1288 | ||
@@ -1327,7 +1336,7 @@ bool call_prepare_transmission(ToxAVCall *call) | |||
1327 | call->audio, ac_queue_message); | 1336 | call->audio, ac_queue_message); |
1328 | 1337 | ||
1329 | if (!call->audio_rtp) { | 1338 | if (!call->audio_rtp) { |
1330 | LOGGER_ERROR(av->m->log, "Failed to create audio rtp session");; | 1339 | LOGGER_ERROR(av->m->log, "Failed to create audio rtp session"); |
1331 | goto FAILURE; | 1340 | goto FAILURE; |
1332 | } | 1341 | } |
1333 | } | 1342 | } |
diff --git a/toxav/toxav.h b/toxav/toxav.h index 911d6b49..5b25fdeb 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h | |||
@@ -733,6 +733,10 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb | |||
733 | 733 | ||
734 | /** | 734 | /** |
735 | * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove | 735 | * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove |
736 | * | ||
737 | * TODO(iphydf): Use proper new API guidelines for these. E.g. don't use inline | ||
738 | * function types, don't have per-callback userdata, especially don't have one | ||
739 | * userdata per group. | ||
736 | */ | 740 | */ |
737 | /* Create a new toxav group. | 741 | /* Create a new toxav group. |
738 | * | 742 | * |
@@ -744,9 +748,9 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb | |||
744 | * | 748 | * |
745 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | 749 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). |
746 | */ | 750 | */ |
747 | int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, | 751 | int toxav_add_av_groupchat(Tox *tox, |
748 | uint8_t, | 752 | void (*audio_callback)(void *, uint32_t, uint32_t, const int16_t *, unsigned int, uint8_t, uint32_t, void *), |
749 | uint32_t, void *), void *userdata); | 753 | void *userdata); |
750 | 754 | ||
751 | /* Join a AV group (you need to have been invited first.) | 755 | /* Join a AV group (you need to have been invited first.) |
752 | * | 756 | * |
@@ -781,4 +785,16 @@ int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, u | |||
781 | #ifdef __cplusplus | 785 | #ifdef __cplusplus |
782 | } | 786 | } |
783 | #endif | 787 | #endif |
788 | |||
789 | typedef void toxav_group_audio_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, | ||
790 | uint32_t samples, uint8_t channels, uint32_t sample_rate, void *user_data); | ||
791 | |||
792 | typedef TOXAV_ERR_CALL Toxav_Err_Call; | ||
793 | typedef TOXAV_ERR_NEW Toxav_Err_New; | ||
794 | typedef TOXAV_ERR_ANSWER Toxav_Err_Answer; | ||
795 | typedef TOXAV_ERR_CALL_CONTROL Toxav_Err_Call_Control; | ||
796 | typedef TOXAV_ERR_BIT_RATE_SET Toxav_Err_Bit_Rate_Set; | ||
797 | typedef TOXAV_ERR_SEND_FRAME Toxav_Err_Send_Frame; | ||
798 | typedef TOXAV_CALL_CONTROL Toxav_Call_Control; | ||
799 | |||
784 | #endif /* TOXAV_H */ | 800 | #endif /* TOXAV_H */ |