diff --git a/qtox.pro b/qtox.pro index 14e233ad1..e85d7e6ce 100644 --- a/qtox.pro +++ b/qtox.pro @@ -20,16 +20,16 @@ # See the COPYING file for more details. -QT += core gui network xml +QT += core gui network xml opengl greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qtox TEMPLATE = app FORMS += \ - mainwindow.ui \ - widget/form/settings/generalsettings.ui \ - widget/form/settings/avsettings.ui \ - widget/form/settings/identitysettings.ui + src/mainwindow.ui \ + src/widget/form/settings/generalsettings.ui \ + src/widget/form/settings/avsettings.ui \ + src/widget/form/settings/identitysettings.ui CONFIG += c++11 TRANSLATIONS = translations/de.ts \ @@ -68,7 +68,7 @@ win32 { LIBS += -Wl,-Bdynamic -ltbb -lv4l1 -lv4l2 -lgnutls -lrtmp -lgnutls -lavformat -lavcodec -lavutil -lavfilter -lswscale -lusb-1.0 } else { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lvpx -lopenal -lopencv_core -lopencv_highgui + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc } contains(JENKINS, YES) { @@ -88,94 +88,97 @@ win32 { # -pthread -lrt -lGL -lpthread -Wl,-Bdynamic -ldl -lc #QMAKE_CXXFLAGS += -Os -flto -static-libstdc++ -static-libgcc -HEADERS += widget/form/addfriendform.h \ - widget/form/chatform.h \ - widget/form/groupchatform.h \ - widget/form/settingswidget.h \ - widget/form/settings/genericsettings.h \ - widget/form/settings/generalform.h \ - widget/form/settings/identityform.h \ - widget/form/settings/privacyform.h \ - widget/form/settings/avform.h \ - widget/form/filesform.h \ - widget/tool/chattextedit.h \ - widget/tool/friendrequestdialog.h \ - widget/friendwidget.h \ - widget/groupwidget.h \ - widget/widget.h \ - friend.h \ - group.h \ - grouplist.h \ - misc/settings.h \ - core.h \ - friendlist.h \ - misc/cdata.h \ - misc/cstring.h \ - widget/selfcamview.h \ - widget/camera.h \ - widget/netcamview.h \ - misc/smileypack.h \ - widget/emoticonswidget.h \ - misc/style.h \ - widget/adjustingscrollarea.h \ - widget/croppinglabel.h \ - widget/friendlistwidget.h \ - widget/genericchatroomwidget.h \ - widget/form/genericchatform.h \ - widget/tool/chatactions/chataction.h \ - widget/chatareawidget.h \ - filetransferinstance.h \ - corestructs.h \ - coredefines.h \ - coreav.h \ - widget/tool/chatactions/messageaction.h \ - widget/tool/chatactions/filetransferaction.h \ - widget/tool/chatactions/systemmessageaction.h \ - widget/tool/chatactions/actionaction.h \ - widget/maskablepixmapwidget.h +HEADERS += src/widget/form/addfriendform.h \ + src/widget/form/chatform.h \ + src/widget/form/groupchatform.h \ + src/widget/form/settingswidget.h \ + src/widget/form/settings/genericsettings.h \ + src/widget/form/settings/generalform.h \ + src/widget/form/settings/identityform.h \ + src/widget/form/settings/privacyform.h \ + src/widget/form/settings/avform.h \ + src/widget/form/filesform.h \ + src/widget/tool/chattextedit.h \ + src/widget/tool/friendrequestdialog.h \ + src/widget/friendwidget.h \ + src/widget/groupwidget.h \ + src/widget/widget.h \ + src/friend.h \ + src/group.h \ + src/grouplist.h \ + src/misc/settings.h \ + src/core.h \ + src/friendlist.h \ + src/misc/cdata.h \ + src/misc/cstring.h \ + src/widget/camera.h \ + src/widget/netcamview.h \ + src/misc/smileypack.h \ + src/widget/emoticonswidget.h \ + src/misc/style.h \ + src/widget/adjustingscrollarea.h \ + src/widget/croppinglabel.h \ + src/widget/friendlistwidget.h \ + src/widget/genericchatroomwidget.h \ + src/widget/form/genericchatform.h \ + src/widget/tool/chatactions/chataction.h \ + src/widget/chatareawidget.h \ + src/filetransferinstance.h \ + src/corestructs.h \ + src/coredefines.h \ + src/coreav.h \ + src/widget/tool/chatactions/messageaction.h \ + src/widget/tool/chatactions/filetransferaction.h \ + src/widget/tool/chatactions/systemmessageaction.h \ + src/widget/tool/chatactions/actionaction.h \ + src/widget/maskablepixmapwidget.h \ + src/videosource.h \ + src/cameraworker.h \ + src/widget/videosurface.h SOURCES += \ - widget/form/addfriendform.cpp \ - widget/form/chatform.cpp \ - widget/form/groupchatform.cpp \ - widget/form/settingswidget.cpp \ - widget/form/settings/generalform.cpp \ - widget/form/settings/identityform.cpp \ - widget/form/settings/privacyform.cpp \ - widget/form/settings/avform.cpp \ - widget/form/filesform.cpp \ - widget/tool/chattextedit.cpp \ - widget/tool/friendrequestdialog.cpp \ - widget/friendwidget.cpp \ - widget/groupwidget.cpp \ - widget/widget.cpp \ - core.cpp \ - friend.cpp \ - friendlist.cpp \ - group.cpp \ - grouplist.cpp \ - main.cpp \ - misc/settings.cpp \ - misc/cdata.cpp \ - misc/cstring.cpp \ - widget/selfcamview.cpp \ - widget/camera.cpp \ - widget/netcamview.cpp \ - misc/smileypack.cpp \ - widget/emoticonswidget.cpp \ - misc/style.cpp \ - widget/adjustingscrollarea.cpp \ - widget/croppinglabel.cpp \ - widget/friendlistwidget.cpp \ - coreav.cpp \ - widget/genericchatroomwidget.cpp \ - widget/form/genericchatform.cpp \ - widget/tool/chatactions/chataction.cpp \ - widget/chatareawidget.cpp \ - filetransferinstance.cpp \ - corestructs.cpp \ - widget/tool/chatactions/messageaction.cpp \ - widget/tool/chatactions/filetransferaction.cpp \ - widget/tool/chatactions/systemmessageaction.cpp \ - widget/tool/chatactions/actionaction.cpp \ - widget/maskablepixmapwidget.cpp + src/widget/form/addfriendform.cpp \ + src/widget/form/chatform.cpp \ + src/widget/form/groupchatform.cpp \ + src/widget/form/settingswidget.cpp \ + src/widget/form/settings/generalform.cpp \ + src/widget/form/settings/identityform.cpp \ + src/widget/form/settings/privacyform.cpp \ + src/widget/form/settings/avform.cpp \ + src/widget/form/filesform.cpp \ + src/widget/tool/chattextedit.cpp \ + src/widget/tool/friendrequestdialog.cpp \ + src/widget/friendwidget.cpp \ + src/widget/groupwidget.cpp \ + src/widget/widget.cpp \ + src/core.cpp \ + src/friend.cpp \ + src/friendlist.cpp \ + src/group.cpp \ + src/grouplist.cpp \ + src/main.cpp \ + src/misc/settings.cpp \ + src/misc/cdata.cpp \ + src/misc/cstring.cpp \ + src/widget/camera.cpp \ + src/widget/netcamview.cpp \ + src/misc/smileypack.cpp \ + src/widget/emoticonswidget.cpp \ + src/misc/style.cpp \ + src/widget/adjustingscrollarea.cpp \ + src/widget/croppinglabel.cpp \ + src/widget/friendlistwidget.cpp \ + src/coreav.cpp \ + src/widget/genericchatroomwidget.cpp \ + src/widget/form/genericchatform.cpp \ + src/widget/tool/chatactions/chataction.cpp \ + src/widget/chatareawidget.cpp \ + src/filetransferinstance.cpp \ + src/corestructs.cpp \ + src/widget/tool/chatactions/messageaction.cpp \ + src/widget/tool/chatactions/filetransferaction.cpp \ + src/widget/tool/chatactions/systemmessageaction.cpp \ + src/widget/tool/chatactions/actionaction.cpp \ + src/widget/maskablepixmapwidget.cpp \ + src/cameraworker.cpp \ + src/widget/videosurface.cpp diff --git a/src/cameraworker.cpp b/src/cameraworker.cpp new file mode 100644 index 000000000..b0c964bc5 --- /dev/null +++ b/src/cameraworker.cpp @@ -0,0 +1,205 @@ +/* + Copyright (C) 2014 by Project Tox + + This file is part of qTox, a Qt-based graphical interface for Tox. + + This program is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the COPYING file for more details. +*/ + +#include "cameraworker.h" + +#include +#include + +CameraWorker::CameraWorker(int index) + : clock(nullptr) + , camIndex(index) + , refCount(0) +{ +} + +void CameraWorker::onStart() +{ + clock = new QTimer(this); + clock->setSingleShot(false); + clock->setInterval(5); + + connect(clock, &QTimer::timeout, this, &CameraWorker::doWork); + + emit started(); +} + +void CameraWorker::_suspend() +{ + qDebug() << "Suspend"; + clock->stop(); + unsubscribe(); +} + +void CameraWorker::_resume() +{ + qDebug() << "Resume"; + subscribe(); + clock->start(); +} + +void CameraWorker::_setProp(int prop, double val) +{ + props[prop] = val; + + if (cam.isOpened()) + cam.set(prop, val); +} + +double CameraWorker::_getProp(int prop) +{ + if (!props.contains(prop)) + { + subscribe(); + props[prop] = cam.get(prop); + unsubscribe(); + qDebug() << "ASKED " << prop << " VAL " << props[prop]; + } + + return props.value(prop); +} + +void CameraWorker::probeResolutions() +{ + if (resolutions.isEmpty()) + { + subscribe(); + + // probe resolutions (TODO: add more) + QList propbeRes = { + QSize( 160, 120), // QQVGA + QSize( 320, 240), // HVGA + QSize(1024, 768), // XGA + QSize( 432, 240), // WQVGA + QSize( 640, 360), // nHD + }; + + for (QSize res : propbeRes) + { + cam.set(CV_CAP_PROP_FRAME_WIDTH, res.width()); + cam.set(CV_CAP_PROP_FRAME_HEIGHT, res.height()); + + double w = cam.get(CV_CAP_PROP_FRAME_WIDTH); + double h = cam.get(CV_CAP_PROP_FRAME_HEIGHT); + + //qDebug() << "PROBING:" << res << " got " << w << h; + + if (!resolutions.contains(QSize(w,h))) + resolutions.append(QSize(w,h)); + } + + unsubscribe(); + } + + qDebug() << resolutions; + + emit resProbingFinished(resolutions); +} + +void CameraWorker::applyProps() +{ + if (!cam.isOpened()) + return; + + for(int prop : props.keys()) + cam.set(prop, props.value(prop)); +} + +void CameraWorker::subscribe() +{ + if (refCount == 0) + { + if (!cam.isOpened()) + { + cam.open(camIndex); + applyProps(); // restore props + } + } + + refCount++; +} + +void CameraWorker::unsubscribe() +{ + refCount--; + + if(refCount <= 0) + { + cam.release(); + } +} + +void CameraWorker::doWork() +{ + if (!cam.isOpened()) + return; + + if (queue.size() > 3) + { + queue.dequeue(); + return; + } + + cam >> frame; +//qDebug() << "Decoding frame"; + mutex.lock(); + + queue.enqueue(frame); + mutex.unlock(); + + emit newFrameAvailable(); +} + +bool CameraWorker::hasFrame() +{ + mutex.lock(); + bool b = !queue.empty(); + mutex.unlock(); + + return b; +} + +cv::Mat3b CameraWorker::dequeueFrame() +{ + mutex.lock(); + cv::Mat3b f = queue.dequeue(); + mutex.unlock(); + + return f; +} + +void CameraWorker::suspend() +{ + QMetaObject::invokeMethod(this, "_suspend"); +} + +void CameraWorker::resume() +{ + QMetaObject::invokeMethod(this, "_resume"); +} + +void CameraWorker::setProp(int prop, double val) +{ + QMetaObject::invokeMethod(this, "_setProp", Q_ARG(int, prop), Q_ARG(double, val)); +} + +double CameraWorker::getProp(int prop) +{ + double ret = 0.0; + QMetaObject::invokeMethod(this, "_getProp", Qt::BlockingQueuedConnection, Q_RETURN_ARG(double, ret), Q_ARG(int, prop)); + + return ret; +} diff --git a/src/cameraworker.h b/src/cameraworker.h new file mode 100644 index 000000000..47fb10f87 --- /dev/null +++ b/src/cameraworker.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2014 by Project Tox + + This file is part of qTox, a Qt-based graphical interface for Tox. + + This program is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the COPYING file for more details. +*/ + +#ifndef CAMERAWORKER_H +#define CAMERAWORKER_H + +#include +#include +#include +#include +#include +#include + +#include "opencv2/opencv.hpp" + +class QTimer; + +class CameraWorker : public QObject +{ + Q_OBJECT +public: + CameraWorker(int index); + void doWork(); + bool hasFrame(); + cv::Mat3b dequeueFrame(); + + void suspend(); + void resume(); + void setProp(int prop, double val); + double getProp(int prop); // blocking call! + void probeResolutions(); + +public slots: + void onStart(); + +signals: + void started(); + void newFrameAvailable(); + void resProbingFinished(QList res); + +private slots: + void _suspend(); + void _resume(); + void _setProp(int prop, double val); + double _getProp(int prop); + +private: + void applyProps(); + void subscribe(); + void unsubscribe(); + +private: + QMutex mutex; + QQueue queue; + QTimer* clock; + cv::VideoCapture cam; + cv::Mat3b frame; + int camIndex; + QMap props; + QList resolutions; + int refCount; +}; + +#endif // CAMERAWORKER_H diff --git a/core.cpp b/src/core.cpp similarity index 100% rename from core.cpp rename to src/core.cpp diff --git a/core.h b/src/core.h similarity index 100% rename from core.h rename to src/core.h diff --git a/coreav.cpp b/src/coreav.cpp similarity index 98% rename from coreav.cpp rename to src/coreav.cpp index fa4ce5cd8..b7aae0103 100644 --- a/coreav.cpp +++ b/src/coreav.cpp @@ -57,7 +57,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled if (calls[callId].videoEnabled) { calls[callId].sendVideoTimer->start(); - Camera::getInstance()->suscribe(); + Camera::getInstance()->subscribe(); } } @@ -73,12 +73,12 @@ void Core::onAvMediaChange(void* toxav, int32_t callId, void* core) { calls[callId].videoEnabled = false; calls[callId].sendVideoTimer->stop(); - Camera::getInstance()->unsuscribe(); + Camera::getInstance()->unsubscribe(); emit ((Core*)core)->avMediaChange(friendId, callId, false); } else { - Camera::getInstance()->suscribe(); + Camera::getInstance()->subscribe(); calls[callId].videoEnabled = true; calls[callId].sendVideoTimer->start(); emit ((Core*)core)->avMediaChange(friendId, callId, true); @@ -161,7 +161,7 @@ void Core::cleanupCall(int callId) calls[callId].sendAudioTimer->stop(); calls[callId].sendVideoTimer->stop(); if (calls[callId].videoEnabled) - Camera::getInstance()->unsuscribe(); + Camera::getInstance()->unsubscribe(); alcCaptureStop(alInDev); } diff --git a/coreav.h b/src/coreav.h similarity index 100% rename from coreav.h rename to src/coreav.h diff --git a/coredefines.h b/src/coredefines.h similarity index 100% rename from coredefines.h rename to src/coredefines.h diff --git a/corestructs.cpp b/src/corestructs.cpp similarity index 100% rename from corestructs.cpp rename to src/corestructs.cpp diff --git a/corestructs.h b/src/corestructs.h similarity index 100% rename from corestructs.h rename to src/corestructs.h diff --git a/filetransferinstance.cpp b/src/filetransferinstance.cpp similarity index 100% rename from filetransferinstance.cpp rename to src/filetransferinstance.cpp diff --git a/filetransferinstance.h b/src/filetransferinstance.h similarity index 100% rename from filetransferinstance.h rename to src/filetransferinstance.h diff --git a/friend.cpp b/src/friend.cpp similarity index 100% rename from friend.cpp rename to src/friend.cpp diff --git a/friend.h b/src/friend.h similarity index 100% rename from friend.h rename to src/friend.h diff --git a/friendlist.cpp b/src/friendlist.cpp similarity index 100% rename from friendlist.cpp rename to src/friendlist.cpp diff --git a/friendlist.h b/src/friendlist.h similarity index 100% rename from friendlist.h rename to src/friendlist.h diff --git a/group.cpp b/src/group.cpp similarity index 100% rename from group.cpp rename to src/group.cpp diff --git a/group.h b/src/group.h similarity index 100% rename from group.h rename to src/group.h diff --git a/grouplist.cpp b/src/grouplist.cpp similarity index 100% rename from grouplist.cpp rename to src/grouplist.cpp diff --git a/grouplist.h b/src/grouplist.h similarity index 100% rename from grouplist.h rename to src/grouplist.h diff --git a/main.cpp b/src/main.cpp similarity index 100% rename from main.cpp rename to src/main.cpp diff --git a/mainwindow.ui b/src/mainwindow.ui similarity index 99% rename from mainwindow.ui rename to src/mainwindow.ui index 78c16d345..c143521da 100644 --- a/mainwindow.ui +++ b/src/mainwindow.ui @@ -1769,13 +1769,13 @@ QSplitter:handle{ AdjustingScrollArea QScrollArea -
widget/adjustingscrollarea.h
+
src/widget/adjustingscrollarea.h
1
CroppingLabel QLabel -
widget/croppinglabel.h
+
src/widget/croppinglabel.h
diff --git a/misc/cdata.cpp b/src/misc/cdata.cpp similarity index 100% rename from misc/cdata.cpp rename to src/misc/cdata.cpp diff --git a/misc/cdata.h b/src/misc/cdata.h similarity index 100% rename from misc/cdata.h rename to src/misc/cdata.h diff --git a/misc/cstring.cpp b/src/misc/cstring.cpp similarity index 100% rename from misc/cstring.cpp rename to src/misc/cstring.cpp diff --git a/misc/cstring.h b/src/misc/cstring.h similarity index 100% rename from misc/cstring.h rename to src/misc/cstring.h diff --git a/misc/settings.cpp b/src/misc/settings.cpp similarity index 100% rename from misc/settings.cpp rename to src/misc/settings.cpp diff --git a/misc/settings.h b/src/misc/settings.h similarity index 100% rename from misc/settings.h rename to src/misc/settings.h diff --git a/misc/smileypack.cpp b/src/misc/smileypack.cpp similarity index 100% rename from misc/smileypack.cpp rename to src/misc/smileypack.cpp diff --git a/misc/smileypack.h b/src/misc/smileypack.h similarity index 100% rename from misc/smileypack.h rename to src/misc/smileypack.h diff --git a/misc/style.cpp b/src/misc/style.cpp similarity index 100% rename from misc/style.cpp rename to src/misc/style.cpp diff --git a/misc/style.h b/src/misc/style.h similarity index 100% rename from misc/style.h rename to src/misc/style.h diff --git a/src/videosource.h b/src/videosource.h new file mode 100644 index 000000000..f6c11592c --- /dev/null +++ b/src/videosource.h @@ -0,0 +1,27 @@ +#ifndef VIDEOSOURCE_H +#define VIDEOSOURCE_H + +#include +#include + +class VideoSource : public QObject +{ + Q_OBJECT +public: + virtual void* getData() = 0; // a pointer to a frame + virtual int getDataSize() = 0; // size of a frame in bytes + + virtual void lock() = 0; // locks a frame so that it can't change + virtual void unlock() = 0; + + virtual QSize resolution() = 0; // resolution of a frame + + virtual void subscribe() = 0; + virtual void unsubscribe() = 0; + +signals: + void frameAvailable(); + +}; + +#endif // VIDEOSOURCE_H diff --git a/widget/adjustingscrollarea.cpp b/src/widget/adjustingscrollarea.cpp similarity index 100% rename from widget/adjustingscrollarea.cpp rename to src/widget/adjustingscrollarea.cpp diff --git a/widget/adjustingscrollarea.h b/src/widget/adjustingscrollarea.h similarity index 100% rename from widget/adjustingscrollarea.h rename to src/widget/adjustingscrollarea.h diff --git a/src/widget/camera.cpp b/src/widget/camera.cpp new file mode 100644 index 000000000..5bf07e6df --- /dev/null +++ b/src/widget/camera.cpp @@ -0,0 +1,238 @@ +/* + Copyright (C) 2014 by Project Tox + + This file is part of qTox, a Qt-based graphical interface for Tox. + + This program is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the COPYING file for more details. +*/ + +#include "camera.h" +#include "widget.h" +#include "src/cameraworker.h" +#include +#include + +Camera* Camera::instance = nullptr; + +Camera::Camera() + : refcount(0) + , workerThread(nullptr) + , worker(nullptr) +{ + worker = new CameraWorker(0); + workerThread = new QThread(); + + worker->moveToThread(workerThread); + + connect(workerThread, &QThread::started, worker, &CameraWorker::onStart); + connect(workerThread, &QThread::finished, worker, &CameraWorker::deleteLater); + connect(workerThread, &QThread::deleteLater, worker, &CameraWorker::deleteLater); + connect(worker, &CameraWorker::started, this, &Camera::onWorkerStarted); + connect(worker, &CameraWorker::newFrameAvailable, this, &Camera::onNewFrameAvailable); + connect(worker, &CameraWorker::resProbingFinished, this, &Camera::onResProbingFinished); + workerThread->start(); +} + +void Camera::onWorkerStarted() +{ + worker->probeResolutions(); +} + +Camera::~Camera() +{ + workerThread->exit(); + workerThread->deleteLater(); +} + +void Camera::subscribe() +{ + if (refcount <= 0) + worker->resume(); + + refcount++; +} + +void Camera::unsubscribe() +{ + refcount--; + + if (refcount <= 0) + { + worker->suspend(); + refcount = 0; + } +} + +vpx_image Camera::getLastVPXImage() +{ + lock(); + vpx_image img; + int w = currFrame.size().width, h = currFrame.size().height; + vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched + + size_t i=0, j=0; + for( int line = 0; line < h; ++line ) + { + const cv::Vec3b *srcrow = currFrame[line]; + if( !(line % 2) ) + { + for( int x = 0; x < w; x += 2 ) + { + uint8_t r = srcrow[x][2]; + uint8_t g = srcrow[x][1]; + uint8_t b = srcrow[x][0]; + + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + img.planes[VPX_PLANE_V][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; + img.planes[VPX_PLANE_U][j] = ((112*r + -94*g + -18*b) >> 8) + 128; + i++; + j++; + + r = srcrow[x+1][2]; + g = srcrow[x+1][1]; + b = srcrow[x+1][0]; + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + i++; + } + } + else + { + for( int x = 0; x < w; x += 1 ) + { + uint8_t r = srcrow[x][2]; + uint8_t g = srcrow[x][1]; + uint8_t b = srcrow[x][0]; + + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + i++; + } + } + } + unlock(); + return img; +} + +QList Camera::getSupportedResolutions() +{ + return resolutions; +} + +QSize Camera::getBestVideoMode() +{ + int bestScore = 0; + QSize bestRes; + + for (QSize res : getSupportedResolutions()) + { + int score = res.width() * res.height(); + + if (score > bestScore) + { + bestScore = score; + bestRes = res; + } + } + + return bestRes; +} + +void Camera::setResolution(QSize res) +{ + worker->setProp(CV_CAP_PROP_FRAME_WIDTH, res.width()); + worker->setProp(CV_CAP_PROP_FRAME_HEIGHT, res.height()); +} + +QSize Camera::getResolution() +{ + return QSize(worker->getProp(CV_CAP_PROP_FRAME_WIDTH), worker->getProp(CV_CAP_PROP_FRAME_HEIGHT)); +} + +void Camera::setProp(Camera::Prop prop, double val) +{ + switch (prop) + { + case BRIGHTNESS: + worker->setProp(CV_CAP_PROP_BRIGHTNESS, val); + break; + case SATURATION: + worker->setProp(CV_CAP_PROP_SATURATION, val); + break; + case CONTRAST: + worker->setProp(CV_CAP_PROP_CONTRAST, val); + break; + case HUE: + worker->setProp(CV_CAP_PROP_HUE, val); + break; + } +} + +double Camera::getProp(Camera::Prop prop) +{ + switch (prop) + { + case BRIGHTNESS: + return worker->getProp(CV_CAP_PROP_BRIGHTNESS); + case SATURATION: + return worker->getProp(CV_CAP_PROP_SATURATION); + case CONTRAST: + return worker->getProp(CV_CAP_PROP_CONTRAST); + case HUE: + return worker->getProp(CV_CAP_PROP_HUE); + } + + return 0.0; +} + +void Camera::onNewFrameAvailable() +{ + emit frameAvailable(); +} + +void Camera::onResProbingFinished(QList res) +{ + resolutions = res; +} + +void *Camera::getData() +{ + return currFrame.data; +} + +int Camera::getDataSize() +{ + return currFrame.total() * currFrame.channels(); +} + +void Camera::lock() +{ + mutex.lock(); + + if (worker->hasFrame()) + currFrame = worker->dequeueFrame(); +} + +void Camera::unlock() +{ + mutex.unlock(); +} + +QSize Camera::resolution() +{ + return QSize(currFrame.cols, currFrame.rows); +} + +Camera* Camera::getInstance() +{ + if (!instance) + instance = new Camera(); + + return instance; +} diff --git a/widget/camera.h b/src/widget/camera.h similarity index 56% rename from widget/camera.h rename to src/widget/camera.h index e48307d41..b63740191 100644 --- a/widget/camera.h +++ b/src/widget/camera.h @@ -18,8 +18,13 @@ #define CAMERA_H #include +#include +#include #include "vpx/vpx_image.h" #include "opencv2/opencv.hpp" +#include "src/videosource.h" + +class CameraWorker; /** * This class is a wrapper to share a camera's captured video frames @@ -27,20 +32,60 @@ * the camera only when needed, and giving access to the last frames **/ -class Camera +class Camera : public VideoSource { + Q_OBJECT public: - Camera(); + enum Prop { + BRIGHTNESS, + SATURATION, + CONTRAST, + HUE, + }; + + ~Camera(); + static Camera* getInstance(); ///< Returns the global widget's Camera instance - void suscribe(); ///< Call this once before trying to get frames - void unsuscribe(); ///< Call this once when you don't need frames anymore - cv::Mat getLastFrame(); ///< Get the last captured frame - QImage getLastImage(); ///< Convert the last frame to a QImage (can be expensive !) vpx_image getLastVPXImage(); ///< Convert the last frame to a vpx_image (can be expensive !) + QList getSupportedResolutions(); + QSize getBestVideoMode(); + + void setResolution(QSize res); + QSize getResolution(); + + void setProp(Prop prop, double val); + double getProp(Prop prop); + + // VideoSource interface + virtual void *getData(); + virtual int getDataSize(); + virtual void lock(); + virtual void unlock(); + virtual QSize resolution(); + virtual void subscribe(); + virtual void unsubscribe(); + +protected: + Camera(); + private: int refcount; ///< Number of users suscribed to the camera - cv::VideoCapture cam; ///< OpenCV camera capture opbject + cv::Mat3b currFrame; + QMutex mutex; + + QThread* workerThread; + CameraWorker* worker; + + QList resolutions; + + static Camera* instance; + +private slots: + void onWorkerStarted(); + void onNewFrameAvailable(); + void onResProbingFinished(QList res); + }; #endif // CAMERA_H diff --git a/widget/chatareawidget.cpp b/src/widget/chatareawidget.cpp similarity index 99% rename from widget/chatareawidget.cpp rename to src/widget/chatareawidget.cpp index 2ce9fc267..542e3be40 100644 --- a/widget/chatareawidget.cpp +++ b/src/widget/chatareawidget.cpp @@ -15,7 +15,7 @@ */ #include "chatareawidget.h" -#include "widget/tool/chatactions/chataction.h" +#include "tool/chatactions/chataction.h" #include #include #include diff --git a/widget/chatareawidget.h b/src/widget/chatareawidget.h similarity index 100% rename from widget/chatareawidget.h rename to src/widget/chatareawidget.h diff --git a/widget/croppinglabel.cpp b/src/widget/croppinglabel.cpp similarity index 100% rename from widget/croppinglabel.cpp rename to src/widget/croppinglabel.cpp diff --git a/widget/croppinglabel.h b/src/widget/croppinglabel.h similarity index 100% rename from widget/croppinglabel.h rename to src/widget/croppinglabel.h diff --git a/widget/emoticonswidget.cpp b/src/widget/emoticonswidget.cpp similarity index 98% rename from widget/emoticonswidget.cpp rename to src/widget/emoticonswidget.cpp index 8383c79a9..212d01f1a 100644 --- a/widget/emoticonswidget.cpp +++ b/src/widget/emoticonswidget.cpp @@ -15,8 +15,8 @@ */ #include "emoticonswidget.h" -#include "misc/smileypack.h" -#include "misc/style.h" +#include "src/misc/smileypack.h" +#include "src/misc/style.h" #include #include diff --git a/widget/emoticonswidget.h b/src/widget/emoticonswidget.h similarity index 100% rename from widget/emoticonswidget.h rename to src/widget/emoticonswidget.h diff --git a/widget/form/addfriendform.cpp b/src/widget/form/addfriendform.cpp similarity index 99% rename from widget/form/addfriendform.cpp rename to src/widget/form/addfriendform.cpp index 55f5e80dd..b31a7818e 100644 --- a/widget/form/addfriendform.cpp +++ b/src/widget/form/addfriendform.cpp @@ -20,7 +20,7 @@ #include #include #include "ui_mainwindow.h" -#include "core.h" +#include "src/core.h" #define TOX_ID_LENGTH 2*TOX_FRIEND_ADDRESS_SIZE diff --git a/widget/form/addfriendform.h b/src/widget/form/addfriendform.h similarity index 100% rename from widget/form/addfriendform.h rename to src/widget/form/addfriendform.h diff --git a/widget/form/chatform.cpp b/src/widget/form/chatform.cpp similarity index 97% rename from widget/form/chatform.cpp rename to src/widget/form/chatform.cpp index a7e0a47b8..777a39b0a 100644 --- a/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -24,18 +24,18 @@ #include #include #include "chatform.h" -#include "friend.h" -#include "widget/friendwidget.h" -#include "filetransferinstance.h" -#include "widget/tool/chatactions/filetransferaction.h" -#include "widget/netcamview.h" -#include "widget/chatareawidget.h" -#include "widget/tool/chattextedit.h" -#include "core.h" -#include "widget/widget.h" -#include "widget/maskablepixmapwidget.h" -#include "widget/croppinglabel.h" -#include "misc/style.h" +#include "src/friend.h" +#include "src/widget/friendwidget.h" +#include "src/filetransferinstance.h" +#include "src/widget/tool/chatactions/filetransferaction.h" +#include "src/widget/netcamview.h" +#include "src/widget/chatareawidget.h" +#include "src/widget/tool/chattextedit.h" +#include "src/core.h" +#include "src/widget/widget.h" +#include "src/widget/maskablepixmapwidget.h" +#include "src/widget/croppinglabel.h" +#include "src/misc/style.h" ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend) diff --git a/widget/form/chatform.h b/src/widget/form/chatform.h similarity index 98% rename from widget/form/chatform.h rename to src/widget/form/chatform.h index 13eba9b7d..7d4a868b1 100644 --- a/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -18,7 +18,7 @@ #define CHATFORM_H #include "genericchatform.h" -#include "corestructs.h" +#include "src/corestructs.h" struct Friend; class FileTransferInstance; diff --git a/widget/form/filesform.cpp b/src/widget/form/filesform.cpp similarity index 100% rename from widget/form/filesform.cpp rename to src/widget/form/filesform.cpp diff --git a/widget/form/filesform.h b/src/widget/form/filesform.h similarity index 100% rename from widget/form/filesform.h rename to src/widget/form/filesform.h diff --git a/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp similarity index 94% rename from widget/form/genericchatform.cpp rename to src/widget/form/genericchatform.cpp index 08e8040bb..0d31288e1 100644 --- a/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -17,17 +17,17 @@ #include "genericchatform.h" #include "ui_mainwindow.h" #include -#include "misc/smileypack.h" -#include "widget/emoticonswidget.h" -#include "misc/style.h" -#include "widget/widget.h" -#include "misc/settings.h" -#include "widget/tool/chatactions/messageaction.h" -#include "widget/tool/chatactions/systemmessageaction.h" -#include "widget/tool/chatactions/actionaction.h" -#include "widget/chatareawidget.h" -#include "widget/tool/chattextedit.h" -#include "widget/maskablepixmapwidget.h" +#include "src/misc/smileypack.h" +#include "src/widget/emoticonswidget.h" +#include "src/misc/style.h" +#include "src/widget/widget.h" +#include "src/misc/settings.h" +#include "src/widget/tool/chatactions/messageaction.h" +#include "src/widget/tool/chatactions/systemmessageaction.h" +#include "src/widget/tool/chatactions/actionaction.h" +#include "src/widget/chatareawidget.h" +#include "src/widget/tool/chattextedit.h" +#include "src/widget/maskablepixmapwidget.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent) diff --git a/widget/form/genericchatform.h b/src/widget/form/genericchatform.h similarity index 100% rename from widget/form/genericchatform.h rename to src/widget/form/genericchatform.h diff --git a/widget/form/groupchatform.cpp b/src/widget/form/groupchatform.cpp similarity index 92% rename from widget/form/groupchatform.cpp rename to src/widget/form/groupchatform.cpp index 5e97d22df..822304f58 100644 --- a/widget/form/groupchatform.cpp +++ b/src/widget/form/groupchatform.cpp @@ -15,13 +15,13 @@ */ #include "groupchatform.h" -#include "group.h" -#include "widget/groupwidget.h" -#include "widget/tool/chattextedit.h" -#include "widget/croppinglabel.h" -#include "widget/maskablepixmapwidget.h" -#include "core.h" -#include "misc/style.h" +#include "src/group.h" +#include "src/widget/groupwidget.h" +#include "src/widget/tool/chattextedit.h" +#include "src/widget/croppinglabel.h" +#include "src/widget/maskablepixmapwidget.h" +#include "src/core.h" +#include "src/misc/style.h" #include #include #include diff --git a/widget/form/groupchatform.h b/src/widget/form/groupchatform.h similarity index 100% rename from widget/form/groupchatform.h rename to src/widget/form/groupchatform.h diff --git a/src/widget/form/settings/avform.cpp b/src/widget/form/settings/avform.cpp new file mode 100644 index 000000000..082097b5c --- /dev/null +++ b/src/widget/form/settings/avform.cpp @@ -0,0 +1,78 @@ +/* + Copyright (C) 2014 by Project Tox + + This file is part of qTox, a Qt-based graphical interface for Tox. + + This program is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the COPYING file for more details. +*/ + +#include "avform.h" +#include "src/widget/camera.h" +#include "ui_avsettings.h" + +AVForm::AVForm() : + GenericForm(tr("Audio/Video settings"), QPixmap(":/img/settings/av.png")) +{ + bodyUI = new Ui::AVSettings; + bodyUI->setupUi(this); + + //cam->setVideoMode(cam->getBestVideoMode()); + camView = new VideoSurface(Camera::getInstance(), this); + + bodyUI->CamViewLayout->addWidget(camView); +} + +AVForm::~AVForm() +{ + delete bodyUI; +} + +void AVForm::present() +{ + bodyUI->videoModescomboBox->clear(); + QList res = Camera::getInstance()->getSupportedResolutions(); + for (QSize r : res) + bodyUI->videoModescomboBox->addItem(QString("%1x%2").arg(QString::number(r.width()),QString::number(r.height()))); + + bodyUI->ContrastSlider->setValue(Camera::getInstance()->getProp(Camera::CONTRAST)*100); + bodyUI->BrightnessSlider->setValue(Camera::getInstance()->getProp(Camera::BRIGHTNESS)*100); + bodyUI->SaturationSlider->setValue(Camera::getInstance()->getProp(Camera::SATURATION)*100); + bodyUI->HueSlider->setValue(Camera::getInstance()->getProp(Camera::HUE)*100); +} + +void AVForm::on_ContrastSlider_sliderMoved(int position) +{ + Camera::getInstance()->setProp(Camera::CONTRAST, position / 100.0); +} + +void AVForm::on_SaturationSlider_sliderMoved(int position) +{ + Camera::getInstance()->setProp(Camera::SATURATION, position / 100.0); +} + +void AVForm::on_BrightnessSlider_sliderMoved(int position) +{ + Camera::getInstance()->setProp(Camera::BRIGHTNESS, position / 100.0); +} + +void AVForm::on_HueSlider_sliderMoved(int position) +{ + Camera::getInstance()->setProp(Camera::HUE, position / 100.0); +} + +void AVForm::on_videoModescomboBox_currentIndexChanged(const QString &arg1) +{ + QStringList resStr = arg1.split("x"); + int w = resStr[0].toInt(); + int h = resStr[0].toInt(); + + Camera::getInstance()->setResolution(QSize(w,h)); +} diff --git a/widget/form/settings/avform.h b/src/widget/form/settings/avform.h similarity index 70% rename from widget/form/settings/avform.h rename to src/widget/form/settings/avform.h index e75f742da..0bcc953b7 100644 --- a/widget/form/settings/avform.h +++ b/src/widget/form/settings/avform.h @@ -18,7 +18,7 @@ #define AVFORM_H #include "genericsettings.h" -#include "widget/selfcamview.h" +#include "src/widget/videosurface.h" #include #include #include @@ -33,20 +33,21 @@ class AVForm : public GenericForm { Q_OBJECT public: - AVForm(Camera* cam); + AVForm(); ~AVForm(); + virtual void present(); private slots: - void onTestVideoPressed(); + + void on_ContrastSlider_sliderMoved(int position); + void on_SaturationSlider_sliderMoved(int position); + void on_BrightnessSlider_sliderMoved(int position); + void on_HueSlider_sliderMoved(int position); + void on_videoModescomboBox_currentIndexChanged(const QString &arg1); private: Ui::AVSettings *bodyUI; - - SelfCamView* camView; - - void showTestVideo(); - void closeTestVideo(); - + VideoSurface* camView; }; #endif diff --git a/src/widget/form/settings/avsettings.ui b/src/widget/form/settings/avsettings.ui new file mode 100644 index 000000000..20ebbf43e --- /dev/null +++ b/src/widget/form/settings/avsettings.ui @@ -0,0 +1,166 @@ + + + AVSettings + + + + 0 + 0 + 394 + 391 + + + + Form + + + + + + Volume Settings (Stubs) + + + + + + Playback + + + + + + + Qt::Horizontal + + + + + + + Microphone + + + + + + + Qt::Horizontal + + + + + + + + + + Video settings + + + + QFormLayout::ExpandingFieldsGrow + + + + + Modes + + + + + + + + 0 + 0 + + + + + + + + Hue + + + + + + + Qt::Horizontal + + + + + + + Brightness + + + + + + + Qt::Horizontal + + + + + + + Saturation + + + + + + + Qt::Horizontal + + + + + + + Contrast + + + + + + + Qt::Horizontal + + + + + + + Preview + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 75 + + + + + + + + + diff --git a/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp similarity index 97% rename from widget/form/settings/generalform.cpp rename to src/widget/form/settings/generalform.cpp index d6c8fb5b4..bca44effc 100644 --- a/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -16,10 +16,10 @@ #include "ui_generalsettings.h" #include "generalform.h" -#include "widget/form/settingswidget.h" -#include "widget/widget.h" -#include "misc/settings.h" -#include "misc/smileypack.h" +#include "src/widget/form/settingswidget.h" +#include "src/widget/widget.h" +#include "src/misc/settings.h" +#include "src/misc/smileypack.h" #include #include diff --git a/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h similarity index 100% rename from widget/form/settings/generalform.h rename to src/widget/form/settings/generalform.h diff --git a/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui similarity index 100% rename from widget/form/settings/generalsettings.ui rename to src/widget/form/settings/generalsettings.ui diff --git a/widget/form/settings/genericsettings.h b/src/widget/form/settings/genericsettings.h similarity index 93% rename from widget/form/settings/genericsettings.h rename to src/widget/form/settings/genericsettings.h index e79ec7b06..3e2d54feb 100644 --- a/widget/form/settings/genericsettings.h +++ b/src/widget/form/settings/genericsettings.h @@ -18,7 +18,7 @@ #define GENERICFORM_H #include -#include "widget/form/settingswidget.h" +#include "src/widget/form/settingswidget.h" class GenericForm : public QWidget { @@ -27,7 +27,7 @@ public: GenericForm(const QString &name, const QPixmap &icon) : formName(name), formIcon(icon) {;} ~GenericForm() {;} - virtual void updateContent() {;} + virtual void present() {} QString getFormName() {return formName;} QPixmap getFormIcon() {return formIcon;} diff --git a/widget/form/settings/identityform.cpp b/src/widget/form/settings/identityform.cpp similarity index 94% rename from widget/form/settings/identityform.cpp rename to src/widget/form/settings/identityform.cpp index 5aff0e513..b8369945e 100644 --- a/widget/form/settings/identityform.cpp +++ b/src/widget/form/settings/identityform.cpp @@ -14,12 +14,11 @@ See the COPYING file for more details. */ -#include "core.h" +#include "src/core.h" #include "ui_identitysettings.h" #include "identityform.h" -#include "widget/form/settingswidget.h" -#include "widget/croppinglabel.h" -#include "core.h" +#include "src/widget/form/settingswidget.h" +#include "src/widget/croppinglabel.h" #include #include #include @@ -74,7 +73,7 @@ void IdentityForm::onStatusMessageEdited() Core::getInstance()->setStatusMessage(bodyUI->statusMessage->text()); } -void IdentityForm::updateContent() +void IdentityForm::present() { toxId->setText(Core::getInstance()->getSelfId().toString()); } diff --git a/widget/form/settings/identityform.h b/src/widget/form/settings/identityform.h similarity index 97% rename from widget/form/settings/identityform.h rename to src/widget/form/settings/identityform.h index 2a4b07a77..abbbf3a2c 100644 --- a/widget/form/settings/identityform.h +++ b/src/widget/form/settings/identityform.h @@ -50,7 +50,7 @@ public: void setUserName(const QString &name); void setStatusMessage(const QString &msg); - virtual void updateContent(); + virtual void present(); signals: void userNameChanged(QString); diff --git a/widget/form/settings/identitysettings.ui b/src/widget/form/settings/identitysettings.ui similarity index 97% rename from widget/form/settings/identitysettings.ui rename to src/widget/form/settings/identitysettings.ui index d27300155..67ee1a1ac 100644 --- a/widget/form/settings/identitysettings.ui +++ b/src/widget/form/settings/identitysettings.ui @@ -78,7 +78,7 @@ CroppingLabel QLabel -
widget/croppinglabel.h
+
src/widget/croppinglabel.h
diff --git a/widget/form/settings/privacyform.cpp b/src/widget/form/settings/privacyform.cpp similarity index 94% rename from widget/form/settings/privacyform.cpp rename to src/widget/form/settings/privacyform.cpp index c51dc0878..eb8ae2dd6 100644 --- a/widget/form/settings/privacyform.cpp +++ b/src/widget/form/settings/privacyform.cpp @@ -15,7 +15,7 @@ */ #include "privacyform.h" -#include "widget/form/settingswidget.h" +#include "src/widget/form/settingswidget.h" PrivacyForm::PrivacyForm() : GenericForm(tr("Privacy settings"), QPixmap(":/img/settings/privacy.png")) diff --git a/widget/form/settings/privacyform.h b/src/widget/form/settings/privacyform.h similarity index 100% rename from widget/form/settings/privacyform.h rename to src/widget/form/settings/privacyform.h diff --git a/widget/form/settingswidget.cpp b/src/widget/form/settingswidget.cpp similarity index 84% rename from widget/form/settingswidget.cpp rename to src/widget/form/settingswidget.cpp index b7539a4c5..b5f33a3bf 100644 --- a/widget/form/settingswidget.cpp +++ b/src/widget/form/settingswidget.cpp @@ -15,17 +15,17 @@ */ #include "settingswidget.h" -#include "widget/widget.h" +#include "src/widget/widget.h" #include "ui_mainwindow.h" -#include "widget/camera.h" -#include "widget/form/settings/generalform.h" -#include "widget/form/settings/identityform.h" -#include "widget/form/settings/privacyform.h" -#include "widget/form/settings/avform.h" +#include "src/widget/camera.h" +#include "src/widget/form/settings/generalform.h" +#include "src/widget/form/settings/identityform.h" +#include "src/widget/form/settings/privacyform.h" +#include "src/widget/form/settings/avform.h" #include #include -SettingsWidget::SettingsWidget(Camera* cam, QWidget* parent) +SettingsWidget::SettingsWidget(QWidget* parent) : QWidget(parent) { body = new QWidget(this); @@ -55,7 +55,7 @@ SettingsWidget::SettingsWidget(Camera* cam, QWidget* parent) GeneralForm *gfrm = new GeneralForm; ifrm = new IdentityForm; PrivacyForm *pfrm = new PrivacyForm; - AVForm *avfrm = new AVForm(cam); + AVForm *avfrm = new AVForm; GenericForm *cfgForms[] = {gfrm, ifrm, pfrm, avfrm}; for (auto cfgForm : cfgForms) @@ -85,8 +85,8 @@ void SettingsWidget::show(Ui::MainWindow& ui) void SettingsWidget::onTabChanged(int index) { this->settingsWidgets->setCurrentIndex(index); - GenericForm *currentWidget = static_cast(this->settingsWidgets->widget(index)); - currentWidget->updateContent(); + GenericForm* currentWidget = static_cast(this->settingsWidgets->widget(index)); + currentWidget->present(); nameLabel->setText(currentWidget->getFormName()); imgLabel->setPixmap(currentWidget->getFormIcon().scaledToHeight(40, Qt::SmoothTransformation)); } diff --git a/widget/form/settingswidget.h b/src/widget/form/settingswidget.h similarity index 95% rename from widget/form/settingswidget.h rename to src/widget/form/settingswidget.h index 431e52c1c..6dca68b82 100644 --- a/widget/form/settingswidget.h +++ b/src/widget/form/settingswidget.h @@ -35,7 +35,7 @@ class SettingsWidget : public QWidget { Q_OBJECT public: - SettingsWidget(Camera* cam, QWidget* parent = nullptr); + SettingsWidget(QWidget* parent = nullptr); ~SettingsWidget(); void show(Ui::MainWindow &ui); diff --git a/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp similarity index 100% rename from widget/friendlistwidget.cpp rename to src/widget/friendlistwidget.cpp diff --git a/widget/friendlistwidget.h b/src/widget/friendlistwidget.h similarity index 97% rename from widget/friendlistwidget.h rename to src/widget/friendlistwidget.h index f8c3adf8c..ec44ba717 100644 --- a/widget/friendlistwidget.h +++ b/src/widget/friendlistwidget.h @@ -19,7 +19,7 @@ #include #include -#include "corestructs.h" +#include "src/corestructs.h" class QLayout; class QGridLayout; diff --git a/widget/friendwidget.cpp b/src/widget/friendwidget.cpp similarity index 95% rename from widget/friendwidget.cpp rename to src/widget/friendwidget.cpp index 2b830f107..9c320c767 100644 --- a/widget/friendwidget.cpp +++ b/src/widget/friendwidget.cpp @@ -15,16 +15,16 @@ */ #include "friendwidget.h" -#include "group.h" -#include "grouplist.h" +#include "src/group.h" +#include "src/grouplist.h" #include "groupwidget.h" -#include "friendlist.h" -#include "friend.h" -#include "core.h" -#include "widget/form/chatform.h" -#include "widget/maskablepixmapwidget.h" -#include "widget/croppinglabel.h" -#include "misc/style.h" +#include "src/friendlist.h" +#include "src/friend.h" +#include "src/core.h" +#include "form/chatform.h" +#include "maskablepixmapwidget.h" +#include "croppinglabel.h" +#include "src/misc/style.h" #include #include #include diff --git a/widget/friendwidget.h b/src/widget/friendwidget.h similarity index 100% rename from widget/friendwidget.h rename to src/widget/friendwidget.h diff --git a/widget/genericchatroomwidget.cpp b/src/widget/genericchatroomwidget.cpp similarity index 97% rename from widget/genericchatroomwidget.cpp rename to src/widget/genericchatroomwidget.cpp index 8e875bd3e..4a4e7198d 100644 --- a/widget/genericchatroomwidget.cpp +++ b/src/widget/genericchatroomwidget.cpp @@ -15,8 +15,8 @@ */ #include "genericchatroomwidget.h" -#include "misc/style.h" -#include "widget/maskablepixmapwidget.h" +#include "src/misc/style.h" +#include "maskablepixmapwidget.h" #include "croppinglabel.h" #include #include diff --git a/widget/genericchatroomwidget.h b/src/widget/genericchatroomwidget.h similarity index 100% rename from widget/genericchatroomwidget.h rename to src/widget/genericchatroomwidget.h diff --git a/widget/groupwidget.cpp b/src/widget/groupwidget.cpp similarity index 94% rename from widget/groupwidget.cpp rename to src/widget/groupwidget.cpp index 05d04cf76..db45f8132 100644 --- a/widget/groupwidget.cpp +++ b/src/widget/groupwidget.cpp @@ -15,12 +15,12 @@ */ #include "groupwidget.h" -#include "grouplist.h" -#include "group.h" -#include "misc/settings.h" -#include "widget/form/groupchatform.h" -#include "widget/maskablepixmapwidget.h" -#include "misc/style.h" +#include "src/grouplist.h" +#include "src/group.h" +#include "src/misc/settings.h" +#include "form/groupchatform.h" +#include "maskablepixmapwidget.h" +#include "src/misc/style.h" #include #include #include diff --git a/widget/groupwidget.h b/src/widget/groupwidget.h similarity index 100% rename from widget/groupwidget.h rename to src/widget/groupwidget.h diff --git a/widget/maskablepixmapwidget.cpp b/src/widget/maskablepixmapwidget.cpp similarity index 100% rename from widget/maskablepixmapwidget.cpp rename to src/widget/maskablepixmapwidget.cpp diff --git a/widget/maskablepixmapwidget.h b/src/widget/maskablepixmapwidget.h similarity index 100% rename from widget/maskablepixmapwidget.h rename to src/widget/maskablepixmapwidget.h diff --git a/widget/netcamview.cpp b/src/widget/netcamview.cpp similarity index 99% rename from widget/netcamview.cpp rename to src/widget/netcamview.cpp index fc94393d5..e5443674c 100644 --- a/widget/netcamview.cpp +++ b/src/widget/netcamview.cpp @@ -15,7 +15,7 @@ */ #include "netcamview.h" -#include "core.h" +#include "src/core.h" #include #include diff --git a/widget/netcamview.h b/src/widget/netcamview.h similarity index 100% rename from widget/netcamview.h rename to src/widget/netcamview.h diff --git a/widget/tool/chatactions/actionaction.cpp b/src/widget/tool/chatactions/actionaction.cpp similarity index 98% rename from widget/tool/chatactions/actionaction.cpp rename to src/widget/tool/chatactions/actionaction.cpp index 8533b7cd8..3facb978c 100644 --- a/widget/tool/chatactions/actionaction.cpp +++ b/src/widget/tool/chatactions/actionaction.cpp @@ -15,7 +15,7 @@ */ #include "actionaction.h" -#include "misc/smileypack.h" +#include "src/misc/smileypack.h" ActionAction::ActionAction(const QString &author, const QString &message, const QString &date, const bool& me) : ChatAction(me, author, date), diff --git a/widget/tool/chatactions/actionaction.h b/src/widget/tool/chatactions/actionaction.h similarity index 95% rename from widget/tool/chatactions/actionaction.h rename to src/widget/tool/chatactions/actionaction.h index ec4e5f4a8..08553a96e 100644 --- a/widget/tool/chatactions/actionaction.h +++ b/src/widget/tool/chatactions/actionaction.h @@ -17,7 +17,7 @@ #ifndef ACTIONACTION_H #define ACTIONACTION_H -#include "widget/tool/chatactions/chataction.h" +#include "chataction.h" class ActionAction : public ChatAction { diff --git a/widget/tool/chatactions/chataction.cpp b/src/widget/tool/chatactions/chataction.cpp similarity index 100% rename from widget/tool/chatactions/chataction.cpp rename to src/widget/tool/chatactions/chataction.cpp diff --git a/widget/tool/chatactions/chataction.h b/src/widget/tool/chatactions/chataction.h similarity index 100% rename from widget/tool/chatactions/chataction.h rename to src/widget/tool/chatactions/chataction.h diff --git a/widget/tool/chatactions/filetransferaction.cpp b/src/widget/tool/chatactions/filetransferaction.cpp similarity index 98% rename from widget/tool/chatactions/filetransferaction.cpp rename to src/widget/tool/chatactions/filetransferaction.cpp index 59f2c9250..910055c26 100644 --- a/widget/tool/chatactions/filetransferaction.cpp +++ b/src/widget/tool/chatactions/filetransferaction.cpp @@ -15,7 +15,7 @@ */ #include "filetransferaction.h" -#include "filetransferinstance.h" +#include "src/filetransferinstance.h" #include #include diff --git a/widget/tool/chatactions/filetransferaction.h b/src/widget/tool/chatactions/filetransferaction.h similarity index 96% rename from widget/tool/chatactions/filetransferaction.h rename to src/widget/tool/chatactions/filetransferaction.h index 31982cd45..c6e1340cd 100644 --- a/widget/tool/chatactions/filetransferaction.h +++ b/src/widget/tool/chatactions/filetransferaction.h @@ -17,7 +17,7 @@ #ifndef FILETRANSFERACTION_H #define FILETRANSFERACTION_H -#include "widget/tool/chatactions/chataction.h" +#include "chataction.h" class FileTransferAction : public ChatAction { diff --git a/widget/tool/chatactions/messageaction.cpp b/src/widget/tool/chatactions/messageaction.cpp similarity index 98% rename from widget/tool/chatactions/messageaction.cpp rename to src/widget/tool/chatactions/messageaction.cpp index 6445279ea..4a8b6962b 100644 --- a/widget/tool/chatactions/messageaction.cpp +++ b/src/widget/tool/chatactions/messageaction.cpp @@ -15,7 +15,7 @@ */ #include "messageaction.h" -#include "misc/smileypack.h" +#include "src/misc/smileypack.h" MessageAction::MessageAction(const QString &author, const QString &message, const QString &date, const bool &me) : ChatAction(me, author, date), diff --git a/widget/tool/chatactions/messageaction.h b/src/widget/tool/chatactions/messageaction.h similarity index 95% rename from widget/tool/chatactions/messageaction.h rename to src/widget/tool/chatactions/messageaction.h index 65f8e6465..aa32801eb 100644 --- a/widget/tool/chatactions/messageaction.h +++ b/src/widget/tool/chatactions/messageaction.h @@ -17,7 +17,7 @@ #ifndef MESSAGEACTION_H #define MESSAGEACTION_H -#include "widget/tool/chatactions/chataction.h" +#include "chataction.h" class MessageAction : public ChatAction { diff --git a/widget/tool/chatactions/systemmessageaction.cpp b/src/widget/tool/chatactions/systemmessageaction.cpp similarity index 100% rename from widget/tool/chatactions/systemmessageaction.cpp rename to src/widget/tool/chatactions/systemmessageaction.cpp diff --git a/widget/tool/chatactions/systemmessageaction.h b/src/widget/tool/chatactions/systemmessageaction.h similarity index 95% rename from widget/tool/chatactions/systemmessageaction.h rename to src/widget/tool/chatactions/systemmessageaction.h index 6767a3f73..737458d11 100644 --- a/widget/tool/chatactions/systemmessageaction.h +++ b/src/widget/tool/chatactions/systemmessageaction.h @@ -17,7 +17,7 @@ #ifndef SYSTEMMESSAGEACTION_H #define SYSTEMMESSAGEACTION_H -#include "widget/tool/chatactions/chataction.h" +#include "chataction.h" class SystemMessageAction : public ChatAction { diff --git a/widget/tool/chattextedit.cpp b/src/widget/tool/chattextedit.cpp similarity index 100% rename from widget/tool/chattextedit.cpp rename to src/widget/tool/chattextedit.cpp diff --git a/widget/tool/chattextedit.h b/src/widget/tool/chattextedit.h similarity index 100% rename from widget/tool/chattextedit.h rename to src/widget/tool/chattextedit.h diff --git a/widget/tool/friendrequestdialog.cpp b/src/widget/tool/friendrequestdialog.cpp similarity index 100% rename from widget/tool/friendrequestdialog.cpp rename to src/widget/tool/friendrequestdialog.cpp diff --git a/widget/tool/friendrequestdialog.h b/src/widget/tool/friendrequestdialog.h similarity index 100% rename from widget/tool/friendrequestdialog.h rename to src/widget/tool/friendrequestdialog.h diff --git a/src/widget/videosurface.cpp b/src/widget/videosurface.cpp new file mode 100644 index 000000000..bd49b49c0 --- /dev/null +++ b/src/widget/videosurface.cpp @@ -0,0 +1,197 @@ +/* + Copyright (C) 2014 by Project Tox + + This file is part of qTox, a Qt-based graphical interface for Tox. + + This program is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the COPYING file for more details. +*/ + +#include "videosurface.h" +#include "camera.h" +#include +#include +#include +#include +#include + +VideoSurface::VideoSurface(VideoSource *Source, QWidget* parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) + , source(Source) + , pbo(nullptr) + , program(nullptr) + , textureId(0) + , pboAllocSize(0) + , uploadFrame(false) + , hasSubscribed(false) +{ + setFixedSize(source->resolution()); +} + +VideoSurface::~VideoSurface() +{ + if (pbo) + delete pbo; + + if (textureId != 0) + glDeleteTextures(1, &textureId); + + source->unsubscribe(); +} + +void VideoSurface::hideEvent(QHideEvent *ev) +{ + if (hasSubscribed) + { + source->unsubscribe(); + hasSubscribed = false; + disconnect(source, &VideoSource::frameAvailable, this, &VideoSurface::updateGL); + } + + QGLWidget::hideEvent(ev); +} + +void VideoSurface::showEvent(QShowEvent *ev) +{ + if (!hasSubscribed) + { + source->subscribe(); + hasSubscribed = true; + connect(source, &VideoSource::frameAvailable, this, &VideoSurface::updateGL); + } + + QGLWidget::showEvent(ev); +} + +void VideoSurface::initializeGL() +{ + +} + +void VideoSurface::paintGL() +{ + if (!pbo) + { + qDebug() << "Creating pbo, program"; + + // pbo + pbo = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer); + pbo->setUsagePattern(QOpenGLBuffer::StreamDraw); + pbo->create(); + + // shaders + program = new QOpenGLShaderProgram; + program->addShaderFromSourceCode(QOpenGLShader::Vertex, + "attribute vec4 vertices;" + "varying vec2 coords;" + "void main() {" + " gl_Position = vec4(vertices.xy,0.0,1.0);" + " coords = vertices.xy*vec2(0.5,0.5)+vec2(0.5,0.5);" + "}"); + program->addShaderFromSourceCode(QOpenGLShader::Fragment, + "uniform sampler2D texture0;" + "varying vec2 coords;" + "void main() {" + " vec4 color = texture2D(texture0,coords*vec2(1.0, -1.0));" + " gl_FragColor = vec4(color.b, color.g, color.r, 1);" + "}"); + + program->bindAttributeLocation("vertices", 0); + program->link(); + } + + if (res != source->resolution()) + { + qDebug() << "Change resolution " << res << " to " << source->resolution(); + res = source->resolution(); + + // a texture used to render the pbo (has the match the pixelformat of the source) + glGenTextures(1,&textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, res.width(), res.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + setFixedSize(res); + } + + + if (uploadFrame) + { + source->lock(); + void* frame = source->getData(); + int frameBytes = source->getDataSize(); + + if (pboAllocSize != frameBytes && frameBytes > 0) + { + qDebug() << "Resize pbo " << frameBytes << "bytes (was" << pboAllocSize << ") res " << source->resolution(); + + pbo->bind(); + pbo->allocate(frameBytes); + pbo->release(); + + pboAllocSize = frameBytes; + } + + // transfer data + pbo->bind(); + + void* ptr = pbo->map(QOpenGLBuffer::WriteOnly); + if (ptr && frame) + memcpy(ptr, frame, frameBytes); + pbo->unmap(); + + source->unlock(); + + //transfer pbo data to texture + glBindTexture(GL_TEXTURE_2D, textureId); + glTexSubImage2D(GL_TEXTURE_2D,0,0,0, res.width(), res.height(), GL_RGB, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + pbo->release(); + + uploadFrame = false; + } + + // render pbo + float values[] = { + -1, -1, + 1, -1, + -1, 1, + 1, 1 + }; + + program->setAttributeArray(0, GL_FLOAT, values, 2); + + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, width(), height()); + + program->bind(); + program->enableAttributeArray(0); + + glBindTexture(GL_TEXTURE_2D, textureId); + + //draw fullscreen quad + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindTexture(GL_TEXTURE_2D, 0); + + program->disableAttributeArray(0); + program->release(); +} + +void VideoSurface::updateGL() +{ + uploadFrame = true; + QGLWidget::updateGL(); +} + + diff --git a/widget/selfcamview.h b/src/widget/videosurface.h similarity index 53% rename from widget/selfcamview.h rename to src/widget/videosurface.h index 26a8b315c..7de304682 100644 --- a/widget/selfcamview.h +++ b/src/widget/videosurface.h @@ -17,39 +17,42 @@ #ifndef SELFCAMVIEW_H #define SELFCAMVIEW_H -#include +#include -class QCloseEvent; -class QShowEvent; -class QPainter; -class Camera; -class QLabel; -class QHBoxLayout; +class QOpenGLBuffer; +class QOpenGLShaderProgram; class QTimer; +class VideoSource; -class SelfCamView : public QWidget +class VideoSurface : public QGLWidget { Q_OBJECT public: - SelfCamView(Camera* Cam, QWidget *parent=0); + VideoSurface(VideoSource* source, QWidget* parent=0); + ~VideoSurface(); -private slots: - void updateDisplay(); - -private: - void closeEvent(QCloseEvent*); - void showEvent(QShowEvent*); - void paint(QPainter *painter); + virtual void hideEvent(QHideEvent* ev); + virtual void showEvent(QShowEvent* ev); + // QGLWidget interface protected: - void resizeEvent(QResizeEvent *e); + virtual void initializeGL(); + virtual void paintGL(); + virtual void updateGL(); + + void update(); private: - QLabel *displayLabel; - QHBoxLayout* mainLayout; - Camera* cam; - QTimer* updateDisplayTimer; + VideoSource* source; + QOpenGLBuffer* pbo; + QOpenGLShaderProgram* program; + GLuint textureId; + int pboAllocSize; + QSize res; + bool uploadFrame; + bool hasSubscribed; + }; #endif // SELFCAMVIEW_H diff --git a/widget/widget.cpp b/src/widget/widget.cpp similarity index 97% rename from widget/widget.cpp rename to src/widget/widget.cpp index 2299bf8b5..2ac27ab1c 100644 --- a/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -16,22 +16,21 @@ #include "widget.h" #include "ui_mainwindow.h" -#include "core.h" -#include "misc/settings.h" -#include "friend.h" -#include "friendlist.h" -#include "widget/tool/friendrequestdialog.h" -#include "widget/friendwidget.h" -#include "grouplist.h" -#include "group.h" -#include "widget/groupwidget.h" -#include "widget/form/groupchatform.h" -#include "misc/style.h" -#include "selfcamview.h" -#include "widget/friendlistwidget.h" +#include "src/core.h" +#include "src/misc/settings.h" +#include "src/friend.h" +#include "src/friendlist.h" +#include "tool/friendrequestdialog.h" +#include "friendwidget.h" +#include "src/grouplist.h" +#include "src/group.h" +#include "groupwidget.h" +#include "form/groupchatform.h" +#include "src/misc/style.h" +#include "friendlistwidget.h" #include "camera.h" -#include "widget/form/chatform.h" -#include "widget/maskablepixmapwidget.h" +#include "form/chatform.h" +#include "maskablepixmapwidget.h" #include #include #include @@ -112,8 +111,7 @@ Widget::Widget(QWidget *parent) ui->statusButton->setProperty("status", "offline"); Style::repolish(ui->statusButton); - camera = new Camera; - settingsWidget = new SettingsWidget(camera); + settingsWidget = new SettingsWidget(); // Disable some widgets until we're connected to the DHT ui->statusButton->setEnabled(false); @@ -129,7 +127,7 @@ Widget::Widget(QWidget *parent) qRegisterMetaType("ToxFile::FileDirection"); coreThread = new QThread(this); - core = new Core(camera, coreThread); + core = new Core(Camera::getInstance(), coreThread); core->moveToThread(coreThread); connect(coreThread, &QThread::started, core, &Core::start); @@ -228,11 +226,6 @@ QString Widget::getUsername() return core->getUsername(); } -Camera* Widget::getCamera() -{ - return camera; -} - void Widget::onAvatarClicked() { QString filename = QFileDialog::getOpenFileName(this, tr("Choose a profile picture"), QDir::homePath()); diff --git a/widget/widget.h b/src/widget/widget.h similarity index 94% rename from widget/widget.h rename to src/widget/widget.h index a973ca818..45953a206 100644 --- a/widget/widget.h +++ b/src/widget/widget.h @@ -18,11 +18,11 @@ #define WIDGET_H #include -#include "widget/form/addfriendform.h" -#include "widget/form/settingswidget.h" -#include "widget/form/settings/identityform.h" -#include "widget/form/filesform.h" -#include "corestructs.h" +#include "form/addfriendform.h" +#include "form/settingswidget.h" +#include "form/settings/identityform.h" +#include "form/filesform.h" +#include "src/corestructs.h" #define PIXELS_TO_ACT 7 @@ -34,7 +34,7 @@ class GenericChatroomWidget; class Group; struct Friend; class QSplitter; -class SelfCamView; +class VideoSurface; class QMenu; class Core; class Camera; @@ -124,7 +124,6 @@ private: static Widget* instance; GenericChatroomWidget* activeChatroomWidget; FriendListWidget* contactListWidget; - Camera* camera; MaskablePixmapWidget* profilePicture; bool notify(QObject *receiver, QEvent *event); }; diff --git a/translations/uk.qm b/translations/uk.qm index 53c004e9b..80b128b79 100644 Binary files a/translations/uk.qm and b/translations/uk.qm differ diff --git a/translations/uk.ts b/translations/uk.ts index 70d143cdc..79d617223 100644 --- a/translations/uk.ts +++ b/translations/uk.ts @@ -1,26 +1,60 @@ - + + + AVForm + + + Audio/Video settings + Параметри аудіо/відео + + + + Hide video preview + On a button + Приховати вікно перегляду + + + + Show video preview + On a button + Показати вікно перегляду + + AVPage - Video Settings + Параметри відео + + + Show video preview + On a button + Показати вікно попереднього перегляду + + + Hide video preview + On a button + Приховати вікно попереднього перегляду + + + + AVSettings + + + Form + Form + + + + Video settings Параметри відео - - + Show video preview - On a button Показати вікно попереднього перегляду - - - Hide video preview - On a button - Приховати вікно попереднього перегляду - AddFriendForm @@ -105,27 +139,42 @@ ChatForm - + Send a file Надіслати файл + + Core + + + Encrypted profile + Зашифрований профіль + + + + Your tox profile seems to be encrypted, qTox can't open it +Do you want to erase this profile ? + Схоже, що ваш tox-профіль зашифровано, qTox не може його відкрити. +Бажаєте стерти цей профіль? + + FileTransferInstance - + Save a file Title of the file saving dialog Зберегти файл - + Location not writable Title of permissions popup Немає прав на запис - + You do not have permission to write that location. Choose another, or cancel the save dialog. text of permissions popup Ви не маєте прав на запис за цим розташуванням. Оберіть інше місце призначення, або скасуйте передачу. @@ -189,71 +238,153 @@ FriendWidget - + Copy friend ID Menu to copy the Tox ID of that friend Копіювати дружній ID - + Invite in group Menu to invite a friend in a groupchat Запросити до групи - + Remove friend Menu to remove the friend from our friendlist Вилучити з друзів + + GeneralForm + + + General Settings + Основні параметри + + GeneralPage - + General Settings + Основні параметри + + + Enable IPv6 (recommended) + Text on a checkbox to enable IPv6 + Дозволити IPv6 (рекомендовано) + + + Use translations + Text on a checkbox to enable translations + Використовувати мову системи + + + Make Tox portable + Text on a checkbox to make qTox a portable application + Портативний запуск + + + Save settings to the working directory instead of the usual conf dir + describes makeToxPortable checkbox + Зберігати налаштування в робочий теці + + + Theme + Графічна тема + + + Smiley Pack + Графічний пакунок емоційних картинок + + + + GeneralSettings + + + Form + Form + + + General Settings Основні параметри - - Enable IPv6 (recommended) - Text on a checkbox to enable IPv6 - Дозволити IPv6 (рекомендовано) - - - + Use translations - Text on a checkbox to enable translations + Text on a checkbox to enable translations Використовувати мову системи - - Make Tox portable - Text on a checkbox to make qTox a portable application - Портативний запуск - - - + Save settings to the working directory instead of the usual conf dir - describes makeToxPortable checkbox + describes makeToxPortable checkbox Зберігати налаштування в робочий теці - + + Make Tox portable + Портативний запуск + + + Theme Графічна тема - + Smiley Pack + Text on smiley pack label Графічний пакунок емоційних картинок + + + Connection Settings + Параметри підключення + + + + Enable IPv6 (recommended) + Text on a checkbox to enable IPv6 + Дозволити IPv6 (рекомендовано) + + + + This allows, e.g., toxing over Tor. It adds load to the Tox network however, so use only when necessary. + force tcp checkbox tooltip + Це дозволяє використовувати tox, наприклад, поверх протоколу Tor. Але це збульшує навантаження на мережу, тому використовуйте лише в разі необхідності. + + + + Disable UDP (not recommended) + Text on checkbox to disable UDP + Вимкнути IPv6 (не рекомендовано) + + + + Use proxy (SOCKS5) + Використовувати проксі (SOCKS5) + + + + Address + Text on proxy addr label + Адреса + + + + Port + Text on proxy port label + Порт + GenericChatForm - - + + Save chat log Зберегти чат @@ -261,18 +392,17 @@ GroupChatForm - + %1 users in chat Number of users in chat Користувачів у чаті: %1 - <Unknown> - <Невідомо> + <Невідомо> - + %1 users in chat Користувачів у чаті: %1 @@ -280,52 +410,88 @@ GroupWidget - - + + %1 users in chat Користувачів у чаті: %1 - - + + 0 users in chat Немає користувачів - + Quit group Menu to quit a groupchat Вийти з групи + + IdentityForm + + + Your identity + Ваш ідентифікатор + + IdentityPage - + Public Information + Публічна інформація + + + Name + Username/nick + Ім'я + + + Status + Status message + Статус + + + Tox ID + Tox ID + + + Your Tox ID + Ваш Tox ID + + + + IdentitySettings + + + Form + Form + + + Public Information Публічна інформація - + Name - Username/nick Ім'я - + Status - Status message Статус - + Tox ID Tox ID - - Your Tox ID - Ваш Tox ID + + Your Tox ID (click to copy) + Ваш Tox ID (клацніть аби скопіювати) @@ -336,46 +502,54 @@ qTox - + Your name Ваше ім'я - + Your status Ваш статус - + Add friends Додати друзів - + Create a group chat Створити груповий чат - + View completed file transfers Переглянути завершені передачі файлів - + Change your settings Змінити параметри - + Close Закрити - + Ctrl+Q Ctrl+Q + + PrivacyForm + + + Privacy settings + Параметри приватності + + SelfCamView @@ -388,95 +562,98 @@ SettingsDialog - qTox – Settings - qTox - Параметри + qTox - Параметри - General - Основні + Основні - Identity - Ідентифікація + Ідентифікація - Privacy - Приватність + Приватність - Audio/Video - Аудіо/Відео + Аудіо/Відео - Ok - Гаразд + Гаразд - Cancel - Скасувати + Скасувати - Apply - Застосувати + Застосувати Widget - + Online Button to set your status to 'Online' В мережі - + Away Button to set your status to 'Away' Відійшов - + Busy Button to set your status to 'Busy' Зайнятий - + Choose a profile picture Оберіть зображення для профілю - - - + + + Error Помилка - + Unable to open this file Неможливо відкрити цей файл - + Unable to read this image Неможливо прочитати це зображення - + This image is too big Зображення завелике - + + Toxcore failed to start, the application will terminate after you close this message. + Помилка запуску ядра tox, програма буде завершена після закриття цього повідомлення. + + + + toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart. + popup text + Помилка запуску ядра tox із поточними параметрами проксі. qTox не працює; змініть параметри і перезапустіть. + + + <Unknown> Placeholder when we don't know someone's name in a group chat <Невідомо> diff --git a/widget/camera.cpp b/widget/camera.cpp deleted file mode 100644 index dab371005..000000000 --- a/widget/camera.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - This file is part of qTox, a Qt-based graphical interface for Tox. - - This program is libre software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the COPYING file for more details. -*/ - -#include "camera.h" -#include "widget.h" - -using namespace cv; - -Camera::Camera() - : refcount{0} -{ -} - -void Camera::suscribe() -{ - if (refcount <= 0) - { - refcount = 1; - cam.open(0); - } - else - refcount++; -} - -void Camera::unsuscribe() -{ - refcount--; - - if (refcount <= 0) - { - cam.release(); - refcount = 0; - } -} - -Mat Camera::getLastFrame() -{ - Mat frame; - cam >> frame; - return frame; -} - -QImage Camera::getLastImage() -{ - Mat3b src = getLastFrame(); - QImage dest(src.cols, src.rows, QImage::Format_ARGB32); - for (int y = 0; y < src.rows; ++y) - { - const cv::Vec3b *srcrow = src[y]; - QRgb *destrow = (QRgb*)dest.scanLine(y); - for (int x = 0; x < src.cols; ++x) - destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255); - } - return dest; -} - -vpx_image Camera::getLastVPXImage() -{ - Mat3b frame = getLastFrame(); - vpx_image img; - int w = frame.size().width, h = frame.size().height; - vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched - - size_t i=0, j=0; - for( int line = 0; line < h; ++line ) - { - const cv::Vec3b *srcrow = frame[line]; - if( !(line % 2) ) - { - for( int x = 0; x < w; x += 2 ) - { - uint8_t r = srcrow[x][2]; - uint8_t g = srcrow[x][1]; - uint8_t b = srcrow[x][0]; - - img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; - img.planes[VPX_PLANE_V][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; - img.planes[VPX_PLANE_U][j] = ((112*r + -94*g + -18*b) >> 8) + 128; - i++; - j++; - - r = srcrow[x+1][2]; - g = srcrow[x+1][1]; - b = srcrow[x+1][0]; - img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; - i++; - } - } - else - { - for( int x = 0; x < w; x += 1 ) - { - uint8_t r = srcrow[x][2]; - uint8_t g = srcrow[x][1]; - uint8_t b = srcrow[x][0]; - - img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; - i++; - } - } - } - return img; -} - -Camera* Camera::getInstance() -{ - return Widget::getInstance()->getCamera(); -} diff --git a/widget/form/settings/avform.cpp b/widget/form/settings/avform.cpp deleted file mode 100644 index 4b7afef25..000000000 --- a/widget/form/settings/avform.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - This file is part of qTox, a Qt-based graphical interface for Tox. - - This program is libre software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the COPYING file for more details. -*/ - -#include "avform.h" -#include "widget/camera.h" -#include "ui_avsettings.h" - -AVForm::AVForm(Camera* cam) : - GenericForm(tr("Audio/Video settings"), QPixmap(":/img/settings/av.png")) -{ - bodyUI = new Ui::AVSettings; - bodyUI->setupUi(this); - - camView = new SelfCamView(cam, this); - bodyUI->videoGroup->layout()->addWidget(camView); - camView->hide(); // hide by default - - connect(bodyUI->testVideoBtn, &QPushButton::clicked, this, &AVForm::onTestVideoPressed); -} - -AVForm::~AVForm() -{ - delete bodyUI; -} - -void AVForm::showTestVideo() -{ - bodyUI->testVideoBtn->setText(tr("Hide video preview","On a button")); - camView->show(); -} - -void AVForm::closeTestVideo() -{ - bodyUI->testVideoBtn->setText(tr("Show video preview","On a button")); - camView->close(); -} - -void AVForm::onTestVideoPressed() -{ - if (camView->isVisible()) - closeTestVideo(); - else - showTestVideo(); -} diff --git a/widget/form/settings/avsettings.ui b/widget/form/settings/avsettings.ui deleted file mode 100644 index 77fbb18b4..000000000 --- a/widget/form/settings/avsettings.ui +++ /dev/null @@ -1,50 +0,0 @@ - - - AVSettings - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - Video settings - - - - - - Show video preview - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/widget/selfcamview.cpp b/widget/selfcamview.cpp deleted file mode 100644 index 7e9c3d252..000000000 --- a/widget/selfcamview.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - This file is part of qTox, a Qt-based graphical interface for Tox. - - This program is libre software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the COPYING file for more details. -*/ - -#include "selfcamview.h" -#include "camera.h" -#include -#include -#include -#include -#include -#include - -using namespace cv; - -SelfCamView::SelfCamView(Camera* Cam, QWidget* parent) - : QWidget(parent), displayLabel{new QLabel}, - mainLayout{new QHBoxLayout()}, cam(Cam), updateDisplayTimer{new QTimer} -{ - setLayout(mainLayout); - setWindowTitle(SelfCamView::tr("Tox video test","Title of the window to test the video/webcam")); - setMinimumSize(320,240); - - updateDisplayTimer->setInterval(5); - updateDisplayTimer->setSingleShot(false); - - displayLabel->setAlignment(Qt::AlignCenter); - - mainLayout->addWidget(displayLabel); - - connect(updateDisplayTimer, SIGNAL(timeout()), this, SLOT(updateDisplay())); -} - -void SelfCamView::closeEvent(QCloseEvent* event) -{ - cam->unsuscribe(); - updateDisplayTimer->stop(); - event->accept(); -} - -void SelfCamView::showEvent(QShowEvent* event) -{ - cam->suscribe(); - updateDisplayTimer->start(); - event->accept(); -} - -void SelfCamView::updateDisplay() -{ - displayLabel->setPixmap(QPixmap::fromImage(cam->getLastImage()).scaled(displayLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); -} - -void SelfCamView::resizeEvent(QResizeEvent *e) -{ - Q_UNUSED(e) - updateDisplay(); -}