1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Allow groupchat creation

This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-06-29 23:38:48 +02:00
parent beaebc2056
commit a2566d4183
4 changed files with 115 additions and 20 deletions

View File

@ -893,9 +893,18 @@ void Core::onAvStart(int32_t call_index, void* core)
qWarning() << "Core: Received invalid AV start"; qWarning() << "Core: Received invalid AV start";
return; return;
} }
qDebug() << QString("Core: AV start from %1").arg(friendId);
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav); int transType = toxav_get_peer_transmission_type(static_cast<Core*>(core)->toxav, call_index, friendId);
if (transType == TypeVideo)
{
qDebug() << QString("Core: AV start from %1 with video").arg(friendId);
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, true);
}
else
{
qDebug() << QString("Core: AV start from %1 without video").arg(friendId);
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, false);
}
emit static_cast<Core*>(core)->avStart(friendId, call_index); emit static_cast<Core*>(core)->avStart(friendId, call_index);
} }
@ -954,9 +963,17 @@ void Core::onAvStarting(int32_t call_index, void* core)
qWarning() << "Core: Received invalid AV starting"; qWarning() << "Core: Received invalid AV starting";
return; return;
} }
qDebug() << QString("Core: AV starting %1").arg(friendId); int transType = toxav_get_peer_transmission_type(static_cast<Core*>(core)->toxav, call_index, friendId);
if (transType == TypeVideo)
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav); {
qDebug() << QString("Core: AV starting from %1 with video").arg(friendId);
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, true);
}
else
{
qDebug() << QString("Core: AV starting from %1 without video").arg(friendId);
prepareCall(friendId, call_index, static_cast<Core*>(core)->toxav, false);
}
emit static_cast<Core*>(core)->avStarting(friendId, call_index); emit static_cast<Core*>(core)->avStarting(friendId, call_index);
} }
@ -1009,9 +1026,24 @@ void Core::onAvPeerTimeout(int32_t call_index, void* core)
void Core::answerCall(int callId) void Core::answerCall(int callId)
{ {
qDebug() << QString("Core: answering call %1").arg(callId); int friendId = toxav_get_peer_id(toxav, callId, 0);
if (friendId < 0)
{
qWarning() << "Core: Received invalid AV answer peer ID";
return;
}
int transType = toxav_get_peer_transmission_type(toxav, callId, friendId);
if (transType == TypeVideo)
{
qDebug() << QString("Core: answering call %1 with video").arg(callId);
toxav_answer(toxav, callId, TypeVideo);
}
else
{
qDebug() << QString("Core: answering call %1 without video").arg(callId);
toxav_answer(toxav, callId, TypeAudio); toxav_answer(toxav, callId, TypeAudio);
} }
}
void Core::hangupCall(int callId) void Core::hangupCall(int callId)
{ {
@ -1020,10 +1052,13 @@ void Core::hangupCall(int callId)
toxav_hangup(toxav, callId); toxav_hangup(toxav, callId);
} }
void Core::startCall(int friendId) void Core::startCall(int friendId, bool video)
{ {
qDebug() << QString("Core: Starting call with %1").arg(friendId); qDebug() << QString("Core: Starting call with %1").arg(friendId);
int callId; int callId;
if (video)
toxav_call(toxav, &callId, friendId, TypeVideo, TOXAV_RINGING_TIME);
else
toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME); toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME);
} }
@ -1034,13 +1069,14 @@ void Core::cancelCall(int callId, int friendId)
toxav_cancel(toxav, callId, friendId, 0); toxav_cancel(toxav, callId, friendId, 0);
} }
void Core::prepareCall(int friendId, int callId, ToxAv* toxav) void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled)
{ {
qDebug() << QString("Core: preparing call %1").arg(callId); qDebug() << QString("Core: preparing call %1").arg(callId);
calls[callId].callId = callId; calls[callId].callId = callId;
calls[callId].friendId = friendId; calls[callId].friendId = friendId;
calls[callId].codecSettings = av_DefaultSettings; calls[callId].codecSettings = av_DefaultSettings;
toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, false); calls[callId].videoEnabled = videoEnabled;
toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, videoEnabled);
// Prepare output // Prepare output
QAudioFormat format; QAudioFormat format;
@ -1079,6 +1115,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav)
} }
// Go // Go
/// BUG: TODO: Memory corryption and crashes atexit when playCallAudio is threaded
if (calls[callId].audioOutput != nullptr) if (calls[callId].audioOutput != nullptr)
calls[callId].playFuture = QtConcurrent::run(playCallAudio, callId, toxav); calls[callId].playFuture = QtConcurrent::run(playCallAudio, callId, toxav);
if (calls[callId].audioInput != nullptr) if (calls[callId].audioInput != nullptr)
@ -1119,8 +1156,7 @@ void Core::playCallAudio(int callId, ToxAv* toxav)
} }
if (len == 0) if (len == 0)
{ {
qApp->processEvents(); QThread::msleep(5); /// BUG: Another thread crashed with corruption while we slept here
QThread::msleep(5);
continue; continue;
} }
//qDebug() << QString("Core: Received %1 bytes, %2 audio bytes free, %3 core buffer size") //qDebug() << QString("Core: Received %1 bytes, %2 audio bytes free, %3 core buffer size")
@ -1171,7 +1207,37 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
} }
} }
void Core::sendVideoFrame(int callId, ToxAv* toxav, vpx_image img)
{
uint8_t videobuf[TOXAV_VIDEO_WIDTH * TOXAV_VIDEO_HEIGHT * 4];
int result;
if((result = toxav_prepare_video_frame(toxav, callId, videobuf, sizeof(videobuf), &img)) < 0)
{
qDebug() << QString("Core: Error preparing video frame: %1").arg(result);
return;
}
if((result = toxav_send_video(toxav, callId, videobuf, result)) < 0)
qDebug() << QString("Core: Error sending video frame: %1").arg(result);
}
void Core::groupInviteFriend(int friendId, int groupId) void Core::groupInviteFriend(int friendId, int groupId)
{ {
tox_invite_friend(tox, friendId, groupId); tox_invite_friend(tox, friendId, groupId);
} }
void Core::createGroup()
{
emit emptyGroupCreated(tox_add_groupchat(tox));
}
void Core::dispatchVideoFrame(vpx_image img) const
{
for (int i=0; i<TOXAV_MAX_CALLS; i++)
{
if (calls[i].active && calls[i].videoEnabled)
{
sendVideoFrame(i, toxav, img);
}
}
}

15
core.h
View File

@ -42,6 +42,10 @@
#define TOX_BOOTSTRAP_INTERVAL 10*1000 #define TOX_BOOTSTRAP_INTERVAL 10*1000
#define TOXAV_RINGING_TIME 15 #define TOXAV_RINGING_TIME 15
// TODO: Put that in the settings
#define TOXAV_VIDEO_WIDTH 640
#define TOXAV_VIDEO_HEIGHT 480
struct DhtServer struct DhtServer
{ {
QString name; QString name;
@ -91,9 +95,10 @@ public:
ToxAvCodecSettings codecSettings; ToxAvCodecSettings codecSettings;
int callId; int callId;
int friendId; int friendId;
bool active; bool videoEnabled;
QFuture<void> playFuture; QFuture<void> playFuture;
QFuture<void> recordFuture; QFuture<void> recordFuture;
bool active;
}; };
class Core : public QObject class Core : public QObject
@ -108,6 +113,7 @@ public:
QList<QString> getGroupPeerNames(int groupId) const; QList<QString> getGroupPeerNames(int groupId) const;
int joinGroupchat(int32_t friendnumber, uint8_t* friend_group_public_key) const; int joinGroupchat(int32_t friendnumber, uint8_t* friend_group_public_key) const;
void quitGroupChat(int groupId) const; void quitGroupChat(int groupId) const;
void dispatchVideoFrame(vpx_image img) const;
public slots: public slots:
void start(); void start();
@ -117,6 +123,7 @@ public slots:
void acceptFriendRequest(const QString& userId); void acceptFriendRequest(const QString& userId);
void requestFriendship(const QString& friendAddress, const QString& message); void requestFriendship(const QString& friendAddress, const QString& message);
void groupInviteFriend(int friendId, int groupId); void groupInviteFriend(int friendId, int groupId);
void createGroup();
void removeFriend(int friendId); void removeFriend(int friendId);
void removeGroup(int groupId); void removeGroup(int groupId);
@ -140,7 +147,7 @@ public slots:
void answerCall(int callId); void answerCall(int callId);
void hangupCall(int callId); void hangupCall(int callId);
void startCall(int friendId); void startCall(int friendId, bool video=false);
void cancelCall(int callId, int friendId); void cancelCall(int callId, int friendId);
signals: signals:
@ -166,6 +173,7 @@ signals:
void friendLastSeenChanged(int friendId, const QDateTime& dateTime); void friendLastSeenChanged(int friendId, const QDateTime& dateTime);
void emptyGroupCreated(int groupnumber);
void groupInviteReceived(int friendnumber, uint8_t *group_public_key); void groupInviteReceived(int friendnumber, uint8_t *group_public_key);
void groupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message); void groupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change); void groupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
@ -236,10 +244,11 @@ private:
static void onAvRequestTimeout(int32_t call_index, void* toxav); static void onAvRequestTimeout(int32_t call_index, void* toxav);
static void onAvPeerTimeout(int32_t call_index, void* toxav); static void onAvPeerTimeout(int32_t call_index, void* toxav);
static void prepareCall(int friendId, int callId, ToxAv *toxav); static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled);
static void cleanupCall(int callId); static void cleanupCall(int callId);
static void playCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread static void playCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
static void sendCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread static void sendCallAudio(int callId, ToxAv* toxav); // Blocking, start in a thread
static void sendVideoFrame(int callId, ToxAv* toxav, vpx_image img);
void checkConnection(); void checkConnection();
void onBootstrapTimer(); void onBootstrapTimer();

View File

@ -34,6 +34,9 @@ Widget::Widget(QWidget *parent) :
ui->statusLabel->setText(Settings::getInstance().getStatusMessage()); ui->statusLabel->setText(Settings::getInstance().getStatusMessage());
ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
camera = new Camera;
camview = new SelfCamView(camera);
qRegisterMetaType<Status>("Status"); qRegisterMetaType<Status>("Status");
qRegisterMetaType<uint8_t>("uint8_t"); qRegisterMetaType<uint8_t>("uint8_t");
qRegisterMetaType<int32_t>("int32_t"); qRegisterMetaType<int32_t>("int32_t");
@ -65,6 +68,7 @@ Widget::Widget(QWidget *parent) :
connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived); connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived);
connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived); connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived);
connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged); connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged);
connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated);
connect(this, &Widget::statusSet, core, &Core::setStatus); connect(this, &Widget::statusSet, core, &Core::setStatus);
connect(this, &Widget::friendRequested, core, &Core::requestFriendship); connect(this, &Widget::friendRequested, core, &Core::requestFriendship);
@ -93,6 +97,7 @@ Widget::~Widget()
coreThread->exit(); coreThread->exit();
coreThread->wait(); coreThread->wait();
delete core; delete core;
delete camview;
hideMainForms(); hideMainForms();
@ -155,7 +160,7 @@ void Widget::onAddClicked()
void Widget::onGroupClicked() void Widget::onGroupClicked()
{ {
core->createGroup();
} }
void Widget::onTransferClicked() void Widget::onTransferClicked()
@ -521,3 +526,13 @@ Group *Widget::createGroup(int groupId)
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString))); connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
return newgroup; return newgroup;
} }
void Widget::showTestCamview()
{
camview->show();
}
void Widget::onEmptyGroupCreated(int groupId)
{
createGroup(groupId);
}

View File

@ -7,6 +7,7 @@
#include "core.h" #include "core.h"
#include "widget/form/addfriendform.h" #include "widget/form/addfriendform.h"
#include "widget/form/settingsform.h" #include "widget/form/settingsform.h"
#include "camera.h"
namespace Ui { namespace Ui {
class Widget; class Widget;
@ -27,6 +28,7 @@ public:
QString getUsername(); QString getUsername();
Core* getCore(); Core* getCore();
static Widget* getInstance(); static Widget* getInstance();
void showTestCamview();
~Widget(); ~Widget();
signals: signals:
@ -62,6 +64,7 @@ private slots:
void onFriendWidgetClicked(FriendWidget* widget); void onFriendWidgetClicked(FriendWidget* widget);
void onFriendMessageReceived(int friendId, const QString& message); void onFriendMessageReceived(int friendId, const QString& message);
void onFriendRequestReceived(const QString& userId, const QString& message); void onFriendRequestReceived(const QString& userId, const QString& message);
void onEmptyGroupCreated(int groupId);
void onGroupInviteReceived(int32_t friendId, uint8_t *publicKey); void onGroupInviteReceived(int32_t friendId, uint8_t *publicKey);
void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message); void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message);
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
@ -72,6 +75,8 @@ private slots:
private: private:
void hideMainForms(); void hideMainForms();
Group* createGroup(int groupId); Group* createGroup(int groupId);
void newMessageAlert();
void updateFriendStatusLights(int friendId);
private: private:
Ui::Widget *ui; Ui::Widget *ui;
@ -82,9 +87,9 @@ private:
static Widget* instance; static Widget* instance;
FriendWidget* activeFriendWidget; FriendWidget* activeFriendWidget;
GroupWidget* activeGroupWidget; GroupWidget* activeGroupWidget;
void updateFriendStatusLights(int friendId);
int isFriendWidgetActive, isGroupWidgetActive; int isFriendWidgetActive, isGroupWidgetActive;
void newMessageAlert(); SelfCamView* camview;
Camera* camera;
}; };
#endif // WIDGET_H #endif // WIDGET_H