diff options
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/toxav.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c index a4b2d5da..18cefb4a 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -63,6 +63,9 @@ static const uint8_t audio_index = 0, video_index = 1; | |||
63 | 63 | ||
64 | typedef struct _ToxAvCall { | 64 | typedef struct _ToxAvCall { |
65 | pthread_mutex_t mutex[1]; | 65 | pthread_mutex_t mutex[1]; |
66 | pthread_mutex_t mutex_encoding_audio[1]; | ||
67 | pthread_mutex_t mutex_encoding_video[1]; | ||
68 | pthread_mutex_t mutex_do[1]; | ||
66 | RTPSession *crtps[2]; /** Audio is first and video is second */ | 69 | RTPSession *crtps[2]; /** Audio is first and video is second */ |
67 | CSSession *cs; | 70 | CSSession *cs; |
68 | _Bool active; | 71 | _Bool active; |
@@ -181,10 +184,14 @@ void toxav_do(ToxAv *av) | |||
181 | for (; i < av->max_calls; i ++) { | 184 | for (; i < av->max_calls; i ++) { |
182 | pthread_mutex_lock(av->calls[i].mutex); | 185 | pthread_mutex_lock(av->calls[i].mutex); |
183 | 186 | ||
184 | if (av->calls[i].active) | 187 | if (av->calls[i].active) { |
188 | pthread_mutex_lock(av->calls[i].mutex_do); | ||
189 | pthread_mutex_unlock(av->calls[i].mutex); | ||
185 | cs_do(av->calls[i].cs); | 190 | cs_do(av->calls[i].cs); |
186 | 191 | pthread_mutex_unlock(av->calls[i].mutex_do); | |
187 | pthread_mutex_unlock(av->calls[i].mutex); | 192 | } else { |
193 | pthread_mutex_unlock(av->calls[i].mutex); | ||
194 | } | ||
188 | } | 195 | } |
189 | 196 | ||
190 | uint64_t end = current_time_monotonic(); | 197 | uint64_t end = current_time_monotonic(); |
@@ -273,6 +280,13 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, int support_vide | |||
273 | return av_ErrorNoCall; | 280 | return av_ErrorNoCall; |
274 | } | 281 | } |
275 | 282 | ||
283 | if (pthread_mutex_init(call->mutex_encoding_audio, NULL) != 0 | ||
284 | || pthread_mutex_init(call->mutex_encoding_video, NULL) != 0 || pthread_mutex_init(call->mutex_do, NULL) != 0) { | ||
285 | pthread_mutex_unlock(call->mutex); | ||
286 | LOGGER_ERROR("Error while starting RTP session: mutex initializing failed!\n"); | ||
287 | return av_ErrorUnknown; | ||
288 | } | ||
289 | |||
276 | const ToxAvCSettings *c_peer = toxavcsettings_cast | 290 | const ToxAvCSettings *c_peer = toxavcsettings_cast |
277 | (&av->msi_session->calls[call_index]->csettings_peer[0]); | 291 | (&av->msi_session->calls[call_index]->csettings_peer[0]); |
278 | const ToxAvCSettings *c_self = toxavcsettings_cast | 292 | const ToxAvCSettings *c_self = toxavcsettings_cast |
@@ -339,9 +353,15 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, int support_vide | |||
339 | return av_ErrorNone; | 353 | return av_ErrorNone; |
340 | error: | 354 | error: |
341 | rtp_kill(call->crtps[audio_index], av->messenger); | 355 | rtp_kill(call->crtps[audio_index], av->messenger); |
356 | call->crtps[audio_index] = NULL; | ||
342 | rtp_kill(call->crtps[video_index], av->messenger); | 357 | rtp_kill(call->crtps[video_index], av->messenger); |
358 | call->crtps[video_index] = NULL; | ||
343 | cs_kill(call->cs); | 359 | cs_kill(call->cs); |
344 | memset(call, 0, sizeof(ToxAvCall)); | 360 | call->cs = NULL; |
361 | call->active = 0; | ||
362 | pthread_mutex_destroy(call->mutex_encoding_audio); | ||
363 | pthread_mutex_destroy(call->mutex_encoding_video); | ||
364 | pthread_mutex_destroy(call->mutex_do); | ||
345 | 365 | ||
346 | pthread_mutex_unlock(call->mutex); | 366 | pthread_mutex_unlock(call->mutex); |
347 | return av_ErrorCreatingRtpSessions; | 367 | return av_ErrorCreatingRtpSessions; |
@@ -366,6 +386,13 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | |||
366 | 386 | ||
367 | call->active = 0; | 387 | call->active = 0; |
368 | 388 | ||
389 | pthread_mutex_lock(call->mutex_encoding_audio); | ||
390 | pthread_mutex_unlock(call->mutex_encoding_audio); | ||
391 | pthread_mutex_lock(call->mutex_encoding_video); | ||
392 | pthread_mutex_unlock(call->mutex_encoding_video); | ||
393 | pthread_mutex_lock(call->mutex_do); | ||
394 | pthread_mutex_unlock(call->mutex_do); | ||
395 | |||
369 | rtp_kill(call->crtps[audio_index], av->messenger); | 396 | rtp_kill(call->crtps[audio_index], av->messenger); |
370 | call->crtps[audio_index] = NULL; | 397 | call->crtps[audio_index] = NULL; |
371 | rtp_kill(call->crtps[video_index], av->messenger); | 398 | rtp_kill(call->crtps[video_index], av->messenger); |
@@ -373,6 +400,10 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | |||
373 | cs_kill(call->cs); | 400 | cs_kill(call->cs); |
374 | call->cs = NULL; | 401 | call->cs = NULL; |
375 | 402 | ||
403 | pthread_mutex_destroy(call->mutex_encoding_audio); | ||
404 | pthread_mutex_destroy(call->mutex_encoding_video); | ||
405 | pthread_mutex_destroy(call->mutex_do); | ||
406 | |||
376 | pthread_mutex_unlock(call->mutex); | 407 | pthread_mutex_unlock(call->mutex); |
377 | 408 | ||
378 | return av_ErrorNone; | 409 | return av_ErrorNone; |
@@ -434,11 +465,14 @@ int toxav_prepare_video_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, in | |||
434 | return av_ErrorSettingVideoResolution; | 465 | return av_ErrorSettingVideoResolution; |
435 | } | 466 | } |
436 | 467 | ||
468 | pthread_mutex_lock(call->mutex_encoding_video); | ||
469 | pthread_mutex_unlock(call->mutex); | ||
470 | |||
437 | int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); | 471 | int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); |
438 | 472 | ||
439 | if ( rc != VPX_CODEC_OK) { | 473 | if ( rc != VPX_CODEC_OK) { |
440 | LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); | 474 | LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); |
441 | pthread_mutex_unlock(call->mutex); | 475 | pthread_mutex_unlock(call->mutex_encoding_video); |
442 | return av_ErrorEncodingVideo; | 476 | return av_ErrorEncodingVideo; |
443 | } | 477 | } |
444 | 478 | ||
@@ -451,7 +485,7 @@ int toxav_prepare_video_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, in | |||
451 | while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { | 485 | while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { |
452 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | 486 | if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { |
453 | if ( copied + pkt->data.frame.sz > dest_max ) { | 487 | if ( copied + pkt->data.frame.sz > dest_max ) { |
454 | pthread_mutex_unlock(call->mutex); | 488 | pthread_mutex_unlock(call->mutex_encoding_video); |
455 | return av_ErrorPacketTooLarge; | 489 | return av_ErrorPacketTooLarge; |
456 | } | 490 | } |
457 | 491 | ||
@@ -460,7 +494,7 @@ int toxav_prepare_video_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, in | |||
460 | } | 494 | } |
461 | } | 495 | } |
462 | 496 | ||
463 | pthread_mutex_unlock(call->mutex); | 497 | pthread_mutex_unlock(call->mutex_encoding_video); |
464 | return copied; | 498 | return copied; |
465 | } | 499 | } |
466 | 500 | ||
@@ -509,8 +543,10 @@ int toxav_prepare_audio_frame ( ToxAv *av, | |||
509 | return av_ErrorInvalidState; | 543 | return av_ErrorInvalidState; |
510 | } | 544 | } |
511 | 545 | ||
512 | int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max); | 546 | pthread_mutex_lock(call->mutex_encoding_audio); |
513 | pthread_mutex_unlock(call->mutex); | 547 | pthread_mutex_unlock(call->mutex); |
548 | int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max); | ||
549 | pthread_mutex_unlock(call->mutex_encoding_audio); | ||
514 | 550 | ||
515 | if (rc < 0) { | 551 | if (rc < 0) { |
516 | LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); | 552 | LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); |
@@ -539,7 +575,6 @@ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *data, unsig | |||
539 | 575 | ||
540 | int rc = toxav_send_rtp_payload(av, call, av_TypeAudio, data, size); | 576 | int rc = toxav_send_rtp_payload(av, call, av_TypeAudio, data, size); |
541 | pthread_mutex_unlock(call->mutex); | 577 | pthread_mutex_unlock(call->mutex); |
542 | |||
543 | return rc; | 578 | return rc; |
544 | } | 579 | } |
545 | 580 | ||