/** * @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; }
/** * @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, int support_video ) { assert(av->msi_session); if ( !av->msi_session || !av->msi_session->call ) { return ErrorNoCall; } av->rtp_sessions[audio_index] = rtp_init_session( type_audio, av->messenger, av->msi_session->call->peers[0], av->msi_session->call->key_peer, av->msi_session->call->key_local, av->msi_session->call->nonce_peer, av->msi_session->call->nonce_local ); if ( !av->rtp_sessions[audio_index] ) { fprintf(stderr, "Error while starting audio RTP session!\n"); return ErrorStartingAudioRtp; } if ( support_video ) { av->rtp_sessions[video_index] = rtp_init_session ( type_video, av->messenger, av->msi_session->call->peers[0], av->msi_session->call->key_peer, av->msi_session->call->key_local, av->msi_session->call->nonce_peer, av->msi_session->call->nonce_local ); if ( !av->rtp_sessions[video_index] ) { fprintf(stderr, "Error while starting video RTP session!\n"); return ErrorStartingVideoRtp; } } return ErrorNone; }
int main ( int argc, char* argv[] ) { arg_t* _list = parse_args ( argc, argv ); if ( _list == NULL ) { /* failed */ return print_help(); } pthread_mutex_init ( &_mutex, NULL ); int status; IP_Port Ip_port; const char* ip; uint16_t port; const uint8_t* test_bytes [300]; memset(test_bytes, 'a', 300); rtp_session_t* _m_session; rtp_msg_t* _m_msg; if ( find_arg_simple ( _list, "-r" ) != FAILURE ) { /* Server mode */ IP_Port LOCAL_IP; /* since you need at least 1 recv-er */ LOCAL_IP.ip.i = htonl(INADDR_ANY); LOCAL_IP.port = RTP_PORT; LOCAL_IP.padding = -1; _m_session = rtp_init_session ( -1, -1 ); Networking_Core* _networking = new_networking(LOCAL_IP.ip, RTP_PORT_LISTEN); _socket = _networking->sock; if ( !_networking ){ pthread_mutex_destroy ( &_mutex ); return FAILURE; } int _socket = _networking->sock; if ( status < 0 ) { pthread_mutex_destroy ( &_mutex ); return FAILURE; } /* -- start in recv mode, get 1 message and then analyze it -- */ pthread_t _tid; RUN_IN_THREAD(receivepacket_callback, _tid, _m_session) for ( ; ; ) { /* Recv for x seconds */ _m_msg = rtp_recv_msg ( _m_session ); /* _m_msg = rtp_session_get_message_queded ( _m_session ); DEPRECATED */ if ( _m_msg ) { /*rtp_free_msg(_m_session, _m_msg); _m_msg = NULL;*/ printf("Timestamp: %d\n", _m_msg->_header->_timestamp); } usleep ( 10000 ); } if ( _m_msg->_header ) { rtp_header_print ( _m_msg->_header ); } if ( _m_msg->_ext_header ){ print_ext_header_info(_m_msg->_ext_header); } //print_session_stats ( _m_session ); //printf ( "Payload: ( %d ) \n%s\n", _m_msg->_length, _m_msg->_data ); } else if ( find_arg_simple ( _list, "-s" ) != FAILURE ) {
/** * @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; }
/** * @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; }
int main( int argc, char* argv[] ) { int status; tox_IP_Port Ip_port; const char* ip, *psend, *plisten; uint16_t port_send, port_listen; const uint8_t* test_bytes = "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345678901234567890123456789"; rtp_session_t* _m_session; rtp_msg_t *_m_msg_R, *_m_msg_S; arg_t* _list = parse_args ( argc, argv ); ip = find_arg_duble(_list, "-d"); psend = find_arg_duble(_list, "-p"); plisten = find_arg_duble(_list, "-l"); if ( !ip || !plisten || !psend ) return _print_help(argv[0]); port_send = atoi(psend); port_listen = atoi(plisten); IP_Port local, remote; /* * This is the Local ip. We initiate networking on * this value for it's the local one. To make stuff simpler we receive over this value * and send on the other one ( see remote ) */ local.ip.i = htonl(INADDR_ANY); local.port = port_listen; Networking_Core* _networking = new_networking(local.ip, port_listen); if ( !_networking ) return FAILURE; int _socket = _networking->sock; /* * Now this is the remote. It's used by rtp_session_t to determine the receivers ip etc. */ t_setipport ( ip, port_send, &remote ); _m_session = rtp_init_session(-1, -1); rtp_add_receiver( _m_session, &remote ); /* Now let's start our main loop in both recv and send mode */ for ( ;; ) { /* * This part checks for received messages and if gotten one * display 'Received msg!' indicator and free message */ _m_msg_R = rtp_recv_msg ( _m_session ); if ( _m_msg_R ) { puts ( "Received msg!" ); rtp_free_msg(_m_session, _m_msg_R); } /* -------------------- */ /* * This one makes a test msg and sends that message to the 'remote' */ _m_msg_S = rtp_msg_new ( _m_session, test_bytes, 280 ) ; rtp_send_msg ( _m_session, _m_msg_S, _socket ); usleep ( 10000 ); /* -------------------- */ } return SUCCESS; }