Beispiel #1
0
/**
 * @brief Start new A/V session. There can only be one session at the time. If you register more
 *        it will result in undefined behaviour.
 *
 * @param messenger The messenger handle.
 * @param userdata The agent handling A/V session (i.e. phone).
 * @param video_width Width of video frame.
 * @param video_height Height of video frame.
 * @return ToxAv*
 * @retval NULL On error.
 */
ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings)
{
    ToxAv *av = calloc ( sizeof(ToxAv), 1);

    if (av == NULL)
        return NULL;

    av->messenger = (Messenger *)messenger;

    av->msi_session = msi_init_session(av->messenger);
    av->msi_session->agent_handler = av;

    av->rtp_sessions[0] = av->rtp_sessions [1] = NULL;

    /* NOTE: This should be user defined or? */
    av->j_buf = create_queue(codec_settings->jbuf_capacity);

    av->cs = codec_init_session(codec_settings->audio_bitrate, 
                                codec_settings->audio_frame_duration, 
                                codec_settings->audio_sample_rate,
                                codec_settings->audio_channels,
                                codec_settings->video_width,
                                codec_settings->video_height,
                                codec_settings->video_bitrate);

    return av;
}
Beispiel #2
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 || av->msi_session->max_calls <= call_index || !av->msi_session->calls[call_index] ) {
        /*fprintf(stderr, "Error while starting audio 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],
            av->msi_session->calls[call_index]->key_peer,
            av->msi_session->calls[call_index]->key_local,
            av->msi_session->calls[call_index]->nonce_peer,
            av->msi_session->calls[call_index]->nonce_local);


    if ( !call->crtps[audio_index] ) {
        /*fprintf(stderr, "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],
                av->msi_session->calls[call_index]->key_peer,
                av->msi_session->calls[call_index]->key_local,
                av->msi_session->calls[call_index]->nonce_peer,
                av->msi_session->calls[call_index]->nonce_local);


        if ( !call->crtps[video_index] ) {
            /*fprintf(stderr, "Error while starting video RTP session!\n");*/
            return ErrorStartingVideoRtp;
        }
    }

    if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) return ErrorInternal;

    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->video_width,
                                  codec_settings->video_height,
                                  codec_settings->video_bitrate);

    return call->cs ? ErrorNone : ErrorInternal;
}
Beispiel #3
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;
}
Beispiel #4
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;
}