Esempio n. 1
0
/**
 * @brief Call this at the end of the transmission.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
{
    CallSpecific *call = &av->calls[call_index];

    if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) {
        /*fprintf(stderr, "Error while terminating audio RTP session!\n");*/
        return ErrorTerminatingAudioRtp;
    }

    if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) {
        /*fprintf(stderr, "Error while terminating video RTP session!\n");*/
        return ErrorTerminatingVideoRtp;
    }

    call->crtps[audio_index] = NULL;
    call->crtps[video_index] = NULL;

    if ( call->j_buf ) {
        terminate_queue(call->j_buf);
        call->j_buf = NULL;
        LOGGER_DEBUG("Terminated j queue");
    } else LOGGER_DEBUG("No j queue");

    if ( call->cs ) {
        codec_terminate_session(call->cs);
        call->cs = NULL;
        LOGGER_DEBUG("Terminated codec session");
    } else LOGGER_DEBUG("No codec session");

    return ErrorNone;
}
Esempio n. 2
0
/**
 * @brief Remove A/V session.
 *
 * @param av Handler.
 * @return void
 */
void toxav_kill ( ToxAv *av )
{
    msi_terminate_session(av->msi_session);

    if ( av->rtp_sessions[audio_index] ) {
        rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle);
    }

    if ( av->rtp_sessions[video_index] ) {
        rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle);
    }

    codec_terminate_session(av->cs);

    free(av);
}
Esempio n. 3
0
/**
 * @brief Call this at the end of the transmission.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_kill_transmission ( ToxAv *av )
{
    if ( av->rtp_sessions[audio_index] && -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
        fprintf(stderr, "Error while terminating audio RTP session!\n");
        return ErrorTerminatingAudioRtp;
    }

    if ( av->rtp_sessions[video_index] && -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) {
        fprintf(stderr, "Error while terminating video RTP session!\n");
        return ErrorTerminatingVideoRtp;
    }

    av->rtp_sessions[audio_index] = NULL;
    av->rtp_sessions[video_index] = NULL;
    
    
    return ErrorNone;
}
Esempio n. 4
0
/**
 * @brief Remove A/V session.
 *
 * @param av Handler.
 * @return void
 */
void toxav_kill ( ToxAv *av )
{
    uint32_t i;

    for (i = 0; i < av->max_calls; i ++) {
        if ( av->calls[i].crtps[audio_index] )
            rtp_terminate_session(av->calls[i].crtps[audio_index], av->msi_session->messenger_handle);


        if ( av->calls[i].crtps[video_index] )
            rtp_terminate_session(av->calls[i].crtps[video_index], av->msi_session->messenger_handle);



        if ( av->calls[i].j_buf ) terminate_queue(av->calls[i].j_buf);

        if ( av->calls[i].cs ) codec_terminate_session(av->calls[i].cs);
    }

    msi_terminate_session(av->msi_session);

    free(av->calls);
    free(av);
}
Esempio n. 5
0
/**
 * @brief Call this at the end of the transmission.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
{
    if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
        LOGGER_WARNING("Action on inactive call: %d", call_index);
        return ErrorNoCall;
    }

    CallSpecific *call = &av->calls[call_index];

    call->call_active = 0;

    if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) {
        LOGGER_ERROR("Error while terminating audio RTP session!\n");
        /*return ErrorTerminatingAudioRtp;*/
    } else call->crtps[audio_index] = NULL;

    if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) {
        LOGGER_ERROR("Error while terminating video RTP session!\n");
        /*return ErrorTerminatingVideoRtp;*/
    } else call->crtps[video_index] = NULL;

    if ( call->j_buf ) {
        terminate_queue(call->j_buf);
        call->j_buf = NULL;
        LOGGER_DEBUG("Terminated j queue");
    } else LOGGER_DEBUG("No j queue");

    if ( call->cs ) {
        codec_terminate_session(call->cs);
        call->cs = NULL;
        LOGGER_DEBUG("Terminated codec session");
    } else LOGGER_DEBUG("No codec session");


    return ErrorNone;
}
Esempio n. 6
0
/**
 * @brief Call this at the end of the transmission.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
{
    if (cii(call_index, av->msi_session)) {
        LOGGER_WARNING("Invalid call index: %d", call_index);
        return ErrorNoCall;
    }

    CallSpecific *call = &av->calls[call_index];

    pthread_mutex_lock(&call->mutex);

    if (!call->call_active) {
        pthread_mutex_unlock(&call->mutex);
        LOGGER_WARNING("Action on inactive call: %d", call_index);
        return ErrorNoCall;
    }


    call->call_active = 0;

    rtp_terminate_session(call->crtps[audio_index], av->messenger);
    call->crtps[audio_index] = NULL;
    rtp_terminate_session(call->crtps[video_index], av->messenger);
    call->crtps[video_index] = NULL;
    terminate_queue(call->j_buf);
    call->j_buf = NULL;

    int i;
    DECODE_PACKET *p;

    call->exit = 1;
    pthread_mutex_lock(&call->decode_cond_mutex);
    pthread_cond_signal(&call->decode_cond);
    pthread_cond_wait(&call->decode_cond, &call->decode_cond_mutex);
    pthread_mutex_unlock(&call->decode_cond_mutex);
    pthread_mutex_destroy(&call->decode_cond_mutex);
    pthread_cond_destroy(&call->decode_cond);

    for (i = 0; i != VIDEO_DECODE_QUEUE_SIZE; i++) {
        p = call->video_decode_queue[i];
        call->video_decode_queue[i] = NULL;

        if (p) {
            free(p);
        }
    }

    for (i = 0; i != AUDIO_DECODE_QUEUE_SIZE; i++) {
        p = call->audio_decode_queue[i];
        call->audio_decode_queue[i] = NULL;

        if (p) {
            free(p);
        }
    }

    codec_terminate_session(call->cs);
    call->cs = NULL;

    pthread_mutex_unlock(&call->mutex);
    pthread_mutex_destroy(&call->mutex);

    memset(call, 0, sizeof(CallSpecific));
    return ErrorNone;
}
Esempio n. 7
0
/**
 * @brief Must be call before any RTP transmission occurs.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, uint32_t jbuf_capacity, uint32_t VAD_treshold,
                                 int support_video )
{
    if ( !av->msi_session || cii(call_index, av->msi_session) ||
            !av->msi_session->calls[call_index] || !av->msi_session->calls[call_index]->csettings_peer ||
            av->calls[call_index].call_active) {
        LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
        return ErrorInternal;
    }

    CallSpecific *call = &av->calls[call_index];

    call->crtps[audio_index] =
        rtp_init_session(type_audio, av->messenger, av->msi_session->calls[call_index]->peers[0]);


    if ( !call->crtps[audio_index] ) {
        LOGGER_ERROR("Error while starting audio RTP session!\n");
        return ErrorInternal;
    }

    call->crtps[audio_index]->call_index = call_index;
    call->crtps[audio_index]->av = av;

    if ( support_video ) {
        call->crtps[video_index] =
            rtp_init_session(type_video, av->messenger, av->msi_session->calls[call_index]->peers[0]);

        if ( !call->crtps[video_index] ) {
            LOGGER_ERROR("Error while starting video RTP session!\n");
            goto error;
        }

        call->crtps[video_index]->call_index = call_index;
        call->crtps[video_index]->av = av;

        call->frame_limit = 0;
        call->frame_id = 0;
        call->frame_outid = 0;

        call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);

        if (!call->frame_buf) {
            LOGGER_WARNING("Frame buffer allocation failed!");
            goto error;
        }

    }

    if ( !(call->j_buf = create_queue(jbuf_capacity)) ) {
        LOGGER_WARNING("Jitter buffer creaton failed!");
        goto error;
    }

    ToxAvCSettings csettings_peer = toxavcsettings_cast(&av->msi_session->calls[call_index]->csettings_peer[0]);
    ToxAvCSettings csettings_local = toxavcsettings_cast(&av->msi_session->calls[call_index]->csettings_local);
    LOGGER_DEBUG(
        "Type: %u \n"
        "Video bitrate: %u \n"
        "Video height: %u \n"
        "Video width: %u \n"
        "Audio bitrate: %u \n"
        "Audio framedur: %u \n"
        "Audio sample rate: %u \n"
        "Audio channels: %u \n",
        csettings_peer.call_type,
        csettings_peer.video_bitrate,
        csettings_peer.max_video_height,
        csettings_peer.max_video_width,
        csettings_peer.audio_bitrate,
        csettings_peer.audio_frame_duration,
        csettings_peer.audio_sample_rate,
        csettings_peer.audio_channels );

    if ( (call->cs = codec_init_session(csettings_local.audio_bitrate,
                                        csettings_local.audio_frame_duration,
                                        csettings_local.audio_sample_rate,
                                        csettings_local.audio_channels,
                                        csettings_peer.audio_channels,
                                        VAD_treshold,
                                        csettings_local.max_video_width,
                                        csettings_local.max_video_height,
                                        csettings_local.video_bitrate) )) {

        if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;

        //todo: add error checks
        pthread_mutex_init(&call->decode_cond_mutex, NULL);
        pthread_cond_init(&call->decode_cond, NULL);

        void **arg = malloc(2 * sizeof(void *));
        arg[0] = av;
        arg[1] = call;

        pthread_t temp;
        pthread_attr_t attr;

        pthread_attr_init(&attr);
        pthread_attr_setstacksize(&attr, 1 << 18);
        pthread_create(&temp, &attr, toxav_decoding, arg);
        pthread_attr_destroy(&attr);


        LOGGER_WARNING("Got here");
        call->call_active = 1;

        return ErrorNone;
    }

error:
    rtp_terminate_session(call->crtps[audio_index], av->messenger);
    rtp_terminate_session(call->crtps[video_index], av->messenger);
    free(call->frame_buf);
    terminate_queue(call->j_buf);
    codec_terminate_session(call->cs);

    return ErrorInternal;
}
Esempio n. 8
0
/**
 * @brief Must be call before any RTP transmission occurs.
 *
 * @param av Handler.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On error.
 */
int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video )
{
    if ( !av->msi_session || cii(call_index, av->msi_session) ||
            !av->msi_session->calls[call_index] || av->calls[call_index].call_active) {
        LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
        return ErrorInternal;
    }

    CallSpecific *call = &av->calls[call_index];

    call->crtps[audio_index] =
        rtp_init_session(type_audio, av->messenger, av->msi_session->calls[call_index]->peers[0]);


    if ( !call->crtps[audio_index] ) {
        LOGGER_ERROR("Error while starting audio RTP session!\n");
        return ErrorStartingAudioRtp;
    }


    if ( support_video ) {
        call->crtps[video_index] =
            rtp_init_session(type_video, av->messenger, av->msi_session->calls[call_index]->peers[0]);


        if ( !call->crtps[video_index] ) {
            LOGGER_ERROR("Error while starting video RTP session!\n");

            rtp_terminate_session(call->crtps[audio_index], av->messenger);
            return ErrorStartingVideoRtp;
        }

        call->frame_limit = 0;
        call->frame_id = 0;
        call->frame_outid = 0;

        call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);

        if (!call->frame_buf) {
            rtp_terminate_session(call->crtps[audio_index], av->messenger);
            rtp_terminate_session(call->crtps[video_index], av->messenger);
            LOGGER_WARNING("Frame buffer allocation failed!");
            return ErrorInternal;
        }

    }

    if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) {
        rtp_terminate_session(call->crtps[audio_index], av->messenger);
        rtp_terminate_session(call->crtps[video_index], av->messenger);
        free(call->frame_buf);
        LOGGER_WARNING("Jitter buffer creaton failed!");
        return ErrorInternal;
    }

    if ( (call->cs = codec_init_session(codec_settings->audio_bitrate,
                                        codec_settings->audio_frame_duration,
                                        codec_settings->audio_sample_rate,
                                        codec_settings->audio_channels,
                                        codec_settings->audio_VAD_tolerance,
                                        codec_settings->video_width,
                                        codec_settings->video_height,
                                        codec_settings->video_bitrate) )) {
        call->call_active = 1;
        return ErrorNone;
    }

    rtp_terminate_session(call->crtps[audio_index], av->messenger);
    rtp_terminate_session(call->crtps[video_index], av->messenger);
    free(call->frame_buf);
    terminate_queue(call->j_buf);

    return ErrorInternal;
}