From a2566d41830b5197f7dff21a79ceba702b8d9e1a Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 29 Jun 2014 23:38:48 +0200 Subject: [PATCH] Allow groupchat creation --- core.cpp | 94 ++++++++++++++++++++++++++++++++++++++++------- core.h | 15 ++++++-- widget/widget.cpp | 17 ++++++++- widget/widget.h | 9 ++++- 4 files changed, 115 insertions(+), 20 deletions(-) diff --git a/core.cpp b/core.cpp index 761686b27..b9b343128 100644 --- a/core.cpp +++ b/core.cpp @@ -893,9 +893,18 @@ void Core::onAvStart(int32_t call_index, void* core) qWarning() << "Core: Received invalid AV start"; return; } - qDebug() << QString("Core: AV start from %1").arg(friendId); - prepareCall(friendId, call_index, static_cast(core)->toxav); + int transType = toxav_get_peer_transmission_type(static_cast(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)->toxav, true); + } + else + { + qDebug() << QString("Core: AV start from %1 without video").arg(friendId); + prepareCall(friendId, call_index, static_cast(core)->toxav, false); + } emit static_cast(core)->avStart(friendId, call_index); } @@ -954,9 +963,17 @@ void Core::onAvStarting(int32_t call_index, void* core) qWarning() << "Core: Received invalid AV starting"; return; } - qDebug() << QString("Core: AV starting %1").arg(friendId); - - prepareCall(friendId, call_index, static_cast(core)->toxav); + int transType = toxav_get_peer_transmission_type(static_cast(core)->toxav, call_index, friendId); + if (transType == TypeVideo) + { + qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); + prepareCall(friendId, call_index, static_cast(core)->toxav, true); + } + else + { + qDebug() << QString("Core: AV starting from %1 without video").arg(friendId); + prepareCall(friendId, call_index, static_cast(core)->toxav, false); + } emit static_cast(core)->avStarting(friendId, call_index); } @@ -1008,9 +1025,24 @@ void Core::onAvPeerTimeout(int32_t call_index, void* core) } void Core::answerCall(int callId) -{ - qDebug() << QString("Core: answering call %1").arg(callId); - toxav_answer(toxav, callId, TypeAudio); +{ + 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); + } } void Core::hangupCall(int callId) @@ -1020,11 +1052,14 @@ void Core::hangupCall(int 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); int callId; - toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME); + if (video) + toxav_call(toxav, &callId, friendId, TypeVideo, TOXAV_RINGING_TIME); + else + toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME); } void Core::cancelCall(int callId, int friendId) @@ -1034,13 +1069,14 @@ void Core::cancelCall(int callId, int friendId) 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); calls[callId].callId = callId; calls[callId].friendId = friendId; 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 QAudioFormat format; @@ -1079,6 +1115,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav) } // Go + /// BUG: TODO: Memory corryption and crashes atexit when playCallAudio is threaded if (calls[callId].audioOutput != nullptr) calls[callId].playFuture = QtConcurrent::run(playCallAudio, callId, toxav); if (calls[callId].audioInput != nullptr) @@ -1119,8 +1156,7 @@ void Core::playCallAudio(int callId, ToxAv* toxav) } if (len == 0) { - qApp->processEvents(); - QThread::msleep(5); + QThread::msleep(5); /// BUG: Another thread crashed with corruption while we slept here continue; } //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) { 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 playFuture; QFuture recordFuture; + bool active; }; class Core : public QObject @@ -108,6 +113,7 @@ public: QList getGroupPeerNames(int groupId) const; int joinGroupchat(int32_t friendnumber, uint8_t* friend_group_public_key) const; void quitGroupChat(int groupId) const; + void dispatchVideoFrame(vpx_image img) const; public slots: void start(); @@ -117,6 +123,7 @@ public slots: void acceptFriendRequest(const QString& userId); void requestFriendship(const QString& friendAddress, const QString& message); void groupInviteFriend(int friendId, int groupId); + void createGroup(); void removeFriend(int friendId); void removeGroup(int groupId); @@ -140,7 +147,7 @@ public slots: void answerCall(int callId); void hangupCall(int callId); - void startCall(int friendId); + void startCall(int friendId, bool video=false); void cancelCall(int callId, int friendId); signals: @@ -166,6 +173,7 @@ signals: void friendLastSeenChanged(int friendId, const QDateTime& dateTime); + void emptyGroupCreated(int groupnumber); void groupInviteReceived(int friendnumber, uint8_t *group_public_key); void groupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message); 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 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 playCallAudio(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 onBootstrapTimer(); diff --git a/widget/widget.cpp b/widget/widget.cpp index bce8becd3..ca766e141 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -34,6 +34,9 @@ Widget::Widget(QWidget *parent) : ui->statusLabel->setText(Settings::getInstance().getStatusMessage()); ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + camera = new Camera; + camview = new SelfCamView(camera); + qRegisterMetaType("Status"); qRegisterMetaType("uint8_t"); qRegisterMetaType("int32_t"); @@ -65,6 +68,7 @@ Widget::Widget(QWidget *parent) : connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived); connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived); connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged); + connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated); connect(this, &Widget::statusSet, core, &Core::setStatus); connect(this, &Widget::friendRequested, core, &Core::requestFriendship); @@ -93,6 +97,7 @@ Widget::~Widget() coreThread->exit(); coreThread->wait(); delete core; + delete camview; hideMainForms(); @@ -155,7 +160,7 @@ void Widget::onAddClicked() void Widget::onGroupClicked() { - + core->createGroup(); } void Widget::onTransferClicked() @@ -521,3 +526,13 @@ Group *Widget::createGroup(int groupId) connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString))); return newgroup; } + +void Widget::showTestCamview() +{ + camview->show(); +} + +void Widget::onEmptyGroupCreated(int groupId) +{ + createGroup(groupId); +} diff --git a/widget/widget.h b/widget/widget.h index 0829e65f8..c28be5559 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -7,6 +7,7 @@ #include "core.h" #include "widget/form/addfriendform.h" #include "widget/form/settingsform.h" +#include "camera.h" namespace Ui { class Widget; @@ -27,6 +28,7 @@ public: QString getUsername(); Core* getCore(); static Widget* getInstance(); + void showTestCamview(); ~Widget(); signals: @@ -62,6 +64,7 @@ private slots: void onFriendWidgetClicked(FriendWidget* widget); void onFriendMessageReceived(int friendId, const QString& message); void onFriendRequestReceived(const QString& userId, const QString& message); + void onEmptyGroupCreated(int groupId); void onGroupInviteReceived(int32_t friendId, uint8_t *publicKey); void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message); void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); @@ -72,6 +75,8 @@ private slots: private: void hideMainForms(); Group* createGroup(int groupId); + void newMessageAlert(); + void updateFriendStatusLights(int friendId); private: Ui::Widget *ui; @@ -82,9 +87,9 @@ private: static Widget* instance; FriendWidget* activeFriendWidget; GroupWidget* activeGroupWidget; - void updateFriendStatusLights(int friendId); int isFriendWidgetActive, isGroupWidgetActive; - void newMessageAlert(); + SelfCamView* camview; + Camera* camera; }; #endif // WIDGET_H