void register_callbacks(ToxAv *av, void *data) { toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data); toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data); toxav_register_callstate_callback(av, callback_peer_cs_change, av_OnPeerCSChange, data); toxav_register_callstate_callback(av, callback_self_cs_change, av_OnSelfCSChange, data); toxav_register_audio_callback(av, callback_audio, NULL); toxav_register_video_callback(av, callback_video, NULL); }
void register_callbacks(ToxAv *av, void *data) { toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data); toxav_register_callstate_callback(av, callback_recv_starting, av_OnStarting, data); toxav_register_callstate_callback(av, callback_recv_ending, av_OnEnding, data); toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data); toxav_register_callstate_callback(av, callback_call_type_change, av_OnMediaChange, data); toxav_register_audio_recv_callback(av, callback_audio); toxav_register_video_recv_callback(av, callback_video); }
ToxAv *init_audio(ToxWindow *self, Tox *tox) { ASettins.cs = av_DefaultSettings; ASettins.cs.max_video_height = ASettins.cs.max_video_width = 0; ASettins.errors = ae_None; memset(ASettins.calls, 0, sizeof(ASettins.calls)); /* Streaming stuff from core */ ASettins.av = toxav_new(tox, MAX_CALLS); if ( !ASettins.av ) { ASettins.errors |= ae_StartingCoreAudio; return NULL; } if ( init_devices(ASettins.av) == de_InternalError ) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to init devices"); toxav_kill(ASettins.av); return ASettins.av = NULL; } toxav_register_callstate_callback(ASettins.av, callback_call_started, av_OnStart, self); toxav_register_callstate_callback(ASettins.av, callback_call_canceled, av_OnCancel, self); toxav_register_callstate_callback(ASettins.av, callback_call_rejected, av_OnReject, self); toxav_register_callstate_callback(ASettins.av, callback_call_ended, av_OnEnd, self); toxav_register_callstate_callback(ASettins.av, callback_recv_invite, av_OnInvite, self); toxav_register_callstate_callback(ASettins.av, callback_recv_ringing, av_OnRinging, self); toxav_register_callstate_callback(ASettins.av, callback_recv_starting, av_OnStart, self); toxav_register_callstate_callback(ASettins.av, callback_recv_ending, av_OnEnd, self); toxav_register_callstate_callback(ASettins.av, callback_requ_timeout, av_OnRequestTimeout, self); toxav_register_callstate_callback(ASettins.av, callback_peer_timeout, av_OnPeerTimeout, self); //toxav_register_callstate_callback(ASettins.av, callback_media_change, av_OnMediaChange, self); toxav_register_audio_callback(ASettins.av, write_device_callback, NULL); return ASettins.av; }
av_session_t *av_init_session() { av_session_t *_retu = malloc(sizeof(av_session_t)); /* Initialize our mutex */ pthread_mutex_init ( &_retu->_mutex, NULL ); _retu->_messenger = tox_new(1); if ( !_retu->_messenger ) { fprintf ( stderr, "tox_new() failed!\n" ); return NULL; } _retu->_friends = NULL; const ALchar *_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); int i = 0; const ALchar *device_names[20]; if ( _device_list ) { INFO("\nAvailable Capture Devices are:"); while (*_device_list ) { device_names[i] = _device_list; INFO("%d) %s", i, device_names[i]); _device_list += strlen( _device_list ) + 1; ++i; } } INFO("Enter capture device number"); char dev[2]; char *left; char *warned_ = fgets(dev, 2, stdin); (void)warned_; long selection = strtol(dev, &left, 10); if ( *left ) { printf("'%s' is not a number!", dev); fflush(stdout); exit(EXIT_FAILURE); } else { INFO("Selected: %d ( %s )", selection, device_names[selection]); } _retu->audio_capture_device = (struct ALCdevice *)alcCaptureOpenDevice( device_names[selection], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, AUDIO_FRAME_SIZE * 4); if (alcGetError((ALCdevice *)_retu->audio_capture_device) != AL_NO_ERROR) { printf("Could not start capture device! %d\n", alcGetError((ALCdevice *)_retu->audio_capture_device)); return 0; } uint16_t height = 0, width = 0; #ifdef TOX_FFMPEG avdevice_register_all(); avcodec_register_all(); av_register_all(); _retu->video_input_format = av_find_input_format(VIDEO_DRIVER); if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) { fprintf(stderr, "Opening video_input_format failed!\n"); //return -1; goto failed_init_ffmpeg; } avformat_find_stream_info(_retu->video_format_ctx, NULL); av_dump_format(_retu->video_format_ctx, 0, DEFAULT_WEBCAM, 0); for (i = 0; i < _retu->video_format_ctx->nb_streams; ++i) { if (_retu->video_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { _retu->video_stream = i; break; } } _retu->webcam_decoder_ctx = _retu->video_format_ctx->streams[_retu->video_stream]->codec; _retu->webcam_decoder = avcodec_find_decoder(_retu->webcam_decoder_ctx->codec_id); if (_retu->webcam_decoder == NULL) { fprintf(stderr, "Unsupported codec!\n"); //return -1; goto failed_init_ffmpeg; } if (_retu->webcam_decoder_ctx == NULL) { fprintf(stderr, "Init webcam_decoder_ctx failed!\n"); //return -1; goto failed_init_ffmpeg; } if (avcodec_open2(_retu->webcam_decoder_ctx, _retu->webcam_decoder, NULL) < 0) { fprintf(stderr, "Opening webcam decoder failed!\n"); //return -1; goto failed_init_ffmpeg; } width = _retu->webcam_decoder_ctx->width; height = _retu->webcam_decoder_ctx->height; failed_init_ffmpeg: ; #endif uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(_retu->_messenger, _byte_address ); fraddr_to_str( _byte_address, _retu->_my_public_id ); _retu->av = toxav_new(_retu->_messenger, width, height); /* ------------------ */ toxav_register_callstate_callback(callback_call_started, av_OnStart, _retu->av); toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, _retu->av); toxav_register_callstate_callback(callback_call_rejected, av_OnReject, _retu->av); toxav_register_callstate_callback(callback_call_ended, av_OnEnd, _retu->av); toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, _retu->av); toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, _retu->av); toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, _retu->av); toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, _retu->av); toxav_register_callstate_callback(callback_recv_error, av_OnError, _retu->av); toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, _retu->av); /* ------------------ */ return _retu; }
void Core::start() { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; toxOptions.ipv6enabled = enableIPv6; toxOptions.udp_disabled = 0; toxOptions.proxy_enabled = false; toxOptions.proxy_address[0] = 0; toxOptions.proxy_port = 0; tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6enabled = false; tox = tox_new(&toxOptions); if (tox == nullptr) { qCritical() << "Tox core failed to start"; emit failedToStart(); return; } else qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; } else { qCritical() << "Tox core failed to start"; emit failedToStart(); return; } } toxav = toxav_new(tox, TOXAV_MAX_CALLS); if (toxav == nullptr) { qCritical() << "Toxav core failed to start"; emit failedToStart(); return; } qsrand(time(nullptr)); loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_file_send_request(tox, onFileSendRequestCallback, this); tox_callback_file_control(tox, onFileControlCallback, this); tox_callback_file_data(tox, onFileDataCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_recv_callback(toxav, playCallAudio, this); toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); bootstrapDht(); toxTimer->start(tox_do_interval(tox)); }
void Core::start() { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); bool forceTCP = Settings::getInstance().getForceTCP(); bool useProxy = Settings::getInstance().getUseProxy(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; toxOptions.ipv6enabled = enableIPv6; toxOptions.udp_disabled = forceTCP; // No proxy by default toxOptions.proxy_enabled = false; toxOptions.proxy_address[0] = 0; toxOptions.proxy_port = 0; if (useProxy) { QString proxyAddr = Settings::getInstance().getProxyAddr(); int proxyPort = Settings::getInstance().getProxyPort(); if (proxyAddr.length() > 255) { qWarning() << "Core: proxy address" << proxyAddr << "is too long"; } else if (proxyAddr != "" && proxyPort > 0) { qDebug() << "Core: using proxy" << proxyAddr << ":" << proxyPort; toxOptions.proxy_enabled = true; uint16_t sz = CString::fromString(proxyAddr, (unsigned char*)toxOptions.proxy_address); toxOptions.proxy_address[sz] = 0; toxOptions.proxy_port = proxyPort; } } tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6enabled = false; tox = tox_new(&toxOptions); if (tox == nullptr) { if (toxOptions.proxy_enabled) { //QMessageBox::critical(Widget::getInstance(), tr("Proxy failure", "popup title"), //tr("toxcore failed to start with your proxy settings. qTox cannot run; please modify your " //"settings and restart.", "popup text")); qCritical() << "Core: bad proxy! no toxcore!"; emit badProxy(); } else { qCritical() << "Tox core failed to start"; emit failedToStart(); } return; } else qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; } else if (toxOptions.proxy_enabled) { emit badProxy(); return; } else { qCritical() << "Tox core failed to start"; emit failedToStart(); return; } } toxav = toxav_new(tox, TOXAV_MAX_CALLS); if (toxav == nullptr) { qCritical() << "Toxav core failed to start"; emit failedToStart(); return; } qsrand(time(nullptr)); if (!loadConfiguration()) { emit failedToStart(); tox_kill(tox); tox = nullptr; return; } tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_file_send_request(tox, onFileSendRequestCallback, this); tox_callback_file_control(tox, onFileControlCallback, this); tox_callback_file_data(tox, onFileDataCallback, this); tox_callback_avatar_info(tox, onAvatarInfoCallback, this); tox_callback_avatar_data(tox, onAvatarDataCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_recv_callback(toxav, playCallAudio, this); toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); QPixmap pic = Settings::getInstance().getSavedAvatar(getSelfId().toString()); if (!pic.isNull() && !pic.size().isEmpty()) { QByteArray data; QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); pic.save(&buffer, "PNG"); buffer.close(); setAvatar(TOX_AVATAR_FORMAT_PNG, data); } else qDebug() << "Core: Error loading self avatar"; process(); // starts its own timer }
void Core::start() { qDebug() << "Core: Starting up"; QByteArray savedata = loadToxSave(loadPath); make_tox(savedata); // Do we need to create a new save & profile? if (savedata.isNull()) { qDebug() << "Save file not found, creating a new profile"; Settings::getInstance().load(); setStatusMessage(tr("Toxing on qTox")); setUsername(tr("qTox User")); } qsrand(time(nullptr)); // set GUI with user and statusmsg QString name = getUsername(); if (!name.isEmpty()) emit usernameSet(name); QString msg = getStatusMessage(); if (!msg.isEmpty()) emit statusMessageSet(msg); QString id = getSelfId().toString(); if (!id.isEmpty()) emit idSet(id); // tox core is already decrypted if (Settings::getInstance().getEnableLogging() && Settings::getInstance().getEncryptLogs()) checkEncryptedHistory(); loadFriends(); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_name(tox, onFriendNameChange, this); tox_callback_friend_typing(tox, onFriendTypingChange, this); tox_callback_friend_status_message(tox, onStatusMessageChanged, this); tox_callback_friend_status(tox, onUserStatusChanged, this); tox_callback_friend_connection_status(tox, onConnectionStatusChanged, this); tox_callback_friend_read_receipt(tox, onReadReceiptCallback, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_group_title(tox, onGroupTitleChange, this); tox_callback_group_action(tox, onGroupAction, this); tox_callback_file_chunk_request(tox, CoreFile::onFileDataCallback, this); tox_callback_file_recv(tox, CoreFile::onFileReceiveCallback, this); tox_callback_file_recv_chunk(tox, CoreFile::onFileRecvChunkCallback, this); tox_callback_file_recv_control(tox, CoreFile::onFileControlCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnPeerCSChange, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnSelfCSChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_callback(toxav, playCallAudio, this); toxav_register_video_callback(toxav, playCallVideo, this); QPixmap pic = Settings::getInstance().getSavedAvatar(getSelfId().toString()); if (!pic.isNull() && !pic.size().isEmpty()) { QByteArray data; QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); pic.save(&buffer, "PNG"); buffer.close(); setAvatar(data); } else { qDebug() << "Core: Error loading self avatar"; } ready = true; // If we created a new profile earlier, // now that we're ready save it and ONLY THEN broadcast the new ID. // This is useful for e.g. the profileForm that searches for saves. if (savedata.isNull()) { saveConfiguration(); emit idSet(getSelfId().toString()); } if (isReady()) GUI::setEnabled(true); process(); // starts its own timer }