mirror of https://github.com/qTox/qTox.git
9 changed files with 487 additions and 188 deletions
@ -1,121 +1,125 @@ |
|||||||
#------------------------------------------------- |
#------------------------------------------------- |
||||||
# |
# |
||||||
# Project created by QtCreator 2014-06-22T14:07:35 |
# Project created by QtCreator 2014-06-22T14:07:35 |
||||||
# |
# |
||||||
#------------------------------------------------- |
#------------------------------------------------- |
||||||
|
|
||||||
QT += core gui multimedia multimediawidgets |
QT += core gui multimedia multimediawidgets |
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
||||||
|
|
||||||
TARGET = toxgui |
TARGET = toxgui |
||||||
TEMPLATE = app |
TEMPLATE = app |
||||||
|
|
||||||
HEADERS += widget/form/addfriendform.h \ |
HEADERS += widget/form/addfriendform.h \ |
||||||
widget/form/chatform.h \ |
widget/form/chatform.h \ |
||||||
widget/form/groupchatform.h \ |
widget/form/groupchatform.h \ |
||||||
widget/form/settingsform.h \ |
widget/form/settingsform.h \ |
||||||
widget/tool/chattextedit.h \ |
widget/tool/chattextedit.h \ |
||||||
widget/tool/copyableelidelabel.h \ |
widget/tool/copyableelidelabel.h \ |
||||||
widget/tool/editablelabelwidget.h \ |
widget/tool/editablelabelwidget.h \ |
||||||
widget/tool/elidelabel.h \ |
widget/tool/elidelabel.h \ |
||||||
widget/tool/esclineedit.h \ |
widget/tool/esclineedit.h \ |
||||||
widget/tool/friendrequestdialog.h \ |
widget/tool/friendrequestdialog.h \ |
||||||
widget/filetransfertwidget.h \ |
widget/filetransfertwidget.h \ |
||||||
widget/friendwidget.h \ |
widget/friendwidget.h \ |
||||||
widget/groupwidget.h \ |
widget/groupwidget.h \ |
||||||
widget/widget.h \ |
widget/widget.h \ |
||||||
friend.h \ |
friend.h \ |
||||||
group.h \ |
group.h \ |
||||||
grouplist.h \ |
grouplist.h \ |
||||||
settings.h \ |
settings.h \ |
||||||
status.h \ |
status.h \ |
||||||
core.h \ |
core.h \ |
||||||
friendlist.h \ |
friendlist.h \ |
||||||
cdata.h \ |
cdata.h \ |
||||||
cstring.h \ |
cstring.h \ |
||||||
audiobuffer.h \ |
audiobuffer.h \ |
||||||
widget/selfcamview.h |
widget/selfcamview.h \ |
||||||
|
widget/videosurface.h \ |
||||||
FORMS += widget.ui |
widget/camera.h |
||||||
|
|
||||||
CONFIG += c++11 |
FORMS += widget.ui |
||||||
|
|
||||||
RESOURCES += \ |
CONFIG += c++11 |
||||||
res.qrc |
|
||||||
|
RESOURCES += \ |
||||||
LIBS += -ltoxcore -ltoxav -lsodium |
res.qrc |
||||||
|
|
||||||
SOURCES += \ |
LIBS += -ltoxcore -ltoxav -lsodium -lvpx |
||||||
widget/form/addfriendform.cpp \ |
|
||||||
widget/form/chatform.cpp \ |
SOURCES += \ |
||||||
widget/form/groupchatform.cpp \ |
widget/form/addfriendform.cpp \ |
||||||
widget/form/settingsform.cpp \ |
widget/form/chatform.cpp \ |
||||||
widget/tool/chattextedit.cpp \ |
widget/form/groupchatform.cpp \ |
||||||
widget/tool/copyableelidelabel.cpp \ |
widget/form/settingsform.cpp \ |
||||||
widget/tool/editablelabelwidget.cpp \ |
widget/tool/chattextedit.cpp \ |
||||||
widget/tool/elidelabel.cpp \ |
widget/tool/copyableelidelabel.cpp \ |
||||||
widget/tool/esclineedit.cpp \ |
widget/tool/editablelabelwidget.cpp \ |
||||||
widget/tool/friendrequestdialog.cpp \ |
widget/tool/elidelabel.cpp \ |
||||||
widget/filetransfertwidget.cpp \ |
widget/tool/esclineedit.cpp \ |
||||||
widget/friendwidget.cpp \ |
widget/tool/friendrequestdialog.cpp \ |
||||||
widget/groupwidget.cpp \ |
widget/filetransfertwidget.cpp \ |
||||||
widget/widget.cpp \ |
widget/friendwidget.cpp \ |
||||||
core.cpp \ |
widget/groupwidget.cpp \ |
||||||
friend.cpp \ |
widget/widget.cpp \ |
||||||
friendlist.cpp \ |
core.cpp \ |
||||||
group.cpp \ |
friend.cpp \ |
||||||
grouplist.cpp \ |
friendlist.cpp \ |
||||||
main.cpp \ |
group.cpp \ |
||||||
settings.cpp \ |
grouplist.cpp \ |
||||||
status.cpp \ |
main.cpp \ |
||||||
cdata.cpp \ |
settings.cpp \ |
||||||
cstring.cpp \ |
status.cpp \ |
||||||
audiobuffer.cpp \ |
cdata.cpp \ |
||||||
widget/selfcamview.cpp |
cstring.cpp \ |
||||||
|
audiobuffer.cpp \ |
||||||
|
widget/selfcamview.cpp \ |
||||||
|
widget/videosurface.cpp \ |
||||||
### EXAMPLE BUILD SETTINGS FOR WINDOWS |
widget/camera.cpp |
||||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxcore |
|
||||||
|
|
||||||
#INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
#DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
### EXAMPLE BUILD SETTINGS FOR WINDOWS |
||||||
|
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxcore |
||||||
#win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/toxcore.lib |
|
||||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxcore.a |
INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxav |
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/toxcore.lib |
||||||
#INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxcore.a |
||||||
#DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
|
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxav |
||||||
#win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/toxav.lib |
|
||||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxav.a |
INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lvpx |
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/toxav.lib |
||||||
#INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxav.a |
||||||
#DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
|
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lvpx |
||||||
#win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/vpx.lib |
|
||||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libvpx.a |
INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
|
||||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lopus |
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/vpx.lib |
||||||
|
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libvpx.a |
||||||
#INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
#DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
|
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lopus |
||||||
#win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/opus.lib |
|
||||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libopus.a |
INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
#win32: LIBS += -lws2_32 |
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/opus.lib |
||||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lsodium |
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libopus.a |
||||||
|
|
||||||
#INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
win32: LIBS += -lws2_32 |
||||||
#DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
|
||||||
|
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lsodium |
||||||
#win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/sodium.lib |
|
||||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libsodium.a |
INCLUDEPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
DEPENDPATH += $$PWD/../../../../Downloads/libtoxcore-win32-i686/include |
||||||
|
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/sodium.lib |
||||||
|
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libsodium.a |
||||||
|
@ -0,0 +1,166 @@ |
|||||||
|
#include "camera.h" |
||||||
|
#include <QVideoSurfaceFormat> |
||||||
|
#include <QMessageBox> |
||||||
|
|
||||||
|
Camera::Camera() |
||||||
|
: refcount{0}, camera{new QCamera} |
||||||
|
{ |
||||||
|
camera->setCaptureMode(QCamera::CaptureVideo); |
||||||
|
camera->setViewfinder(this); |
||||||
|
|
||||||
|
connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(onCameraError(QCamera::Error))); |
||||||
|
|
||||||
|
supportedFormats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_RGB32; |
||||||
|
} |
||||||
|
|
||||||
|
void Camera::suscribe() |
||||||
|
{ |
||||||
|
if (refcount <= 0) |
||||||
|
{ |
||||||
|
refcount = 1; |
||||||
|
camera->start(); |
||||||
|
} |
||||||
|
else |
||||||
|
refcount++; |
||||||
|
} |
||||||
|
|
||||||
|
void Camera::unsuscribe() |
||||||
|
{ |
||||||
|
refcount--; |
||||||
|
|
||||||
|
if (refcount <= 0) |
||||||
|
{ |
||||||
|
camera->stop(); |
||||||
|
refcount = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QVideoFrame Camera::getLastFrame() |
||||||
|
{ |
||||||
|
return lastFrame; |
||||||
|
} |
||||||
|
|
||||||
|
bool Camera::start(const QVideoSurfaceFormat &format) |
||||||
|
{ |
||||||
|
if(supportedFormats.contains(format.pixelFormat())) |
||||||
|
{ |
||||||
|
frameFormat = format.pixelFormat(); |
||||||
|
QAbstractVideoSurface::start(format); |
||||||
|
return true; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
QMessageBox::warning(0, "Camera error", "The camera only supports rare video formats, can't use it"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool Camera::present(const QVideoFrame &frame) |
||||||
|
{ |
||||||
|
QVideoFrame frameMap(frame); // Basically a const_cast because shallow copies
|
||||||
|
frameMap.map(QAbstractVideoBuffer::ReadOnly); |
||||||
|
int w = frameMap.width(), h = frameMap.height(); |
||||||
|
int bpl = frameMap.bytesPerLine(), size = frameMap.mappedBytes(); |
||||||
|
QVideoFrame frameCopy(size, QSize(w, h), bpl, frameMap.pixelFormat()); |
||||||
|
frameCopy.map(QAbstractVideoBuffer::WriteOnly); |
||||||
|
memcpy(frameCopy.bits(), frameMap.bits(), size); |
||||||
|
frameCopy.unmap(); |
||||||
|
lastFrame = frameCopy; |
||||||
|
frameMap.unmap(); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
QList<QVideoFrame::PixelFormat> Camera::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const |
||||||
|
{ |
||||||
|
if (handleType == QAbstractVideoBuffer::NoHandle) |
||||||
|
return supportedFormats; |
||||||
|
else |
||||||
|
return QList<QVideoFrame::PixelFormat>(); |
||||||
|
} |
||||||
|
|
||||||
|
void Camera::onCameraError(QCamera::Error value) |
||||||
|
{ |
||||||
|
QMessageBox::warning(0,"Camera error",QString("Error %1 : %2") |
||||||
|
.arg(value).arg(camera->errorString())); |
||||||
|
} |
||||||
|
|
||||||
|
bool Camera::isFormatSupported(const QVideoSurfaceFormat& format) const |
||||||
|
{ |
||||||
|
if (format.pixelFormat() == 0) |
||||||
|
{ |
||||||
|
//QMessageBox::warning(0, "Camera eror","The camera's video format is not supported !");
|
||||||
|
return QAbstractVideoSurface::isFormatSupported(format); |
||||||
|
} |
||||||
|
else if(supportedFormats.contains(format.pixelFormat())) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
QMessageBox::warning(0, "Camera eror", |
||||||
|
QString("Camera format %1 not supported, can't use the camera") |
||||||
|
.arg(format.pixelFormat())); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
QImage Camera::getLastImage() |
||||||
|
{ |
||||||
|
lastFrame.map(QAbstractVideoBuffer::ReadOnly); |
||||||
|
int w = lastFrame.width(), h = lastFrame.height(); |
||||||
|
int bpl = lastFrame.bytesPerLine(), cxbpl = bpl/2; |
||||||
|
QImage img(w, h, QImage::Format_RGB32); |
||||||
|
|
||||||
|
if (frameFormat == QVideoFrame::Format_YUV420P) |
||||||
|
{ |
||||||
|
uint8_t* yData = lastFrame.bits(); |
||||||
|
uint8_t* uData = yData + (bpl * h); |
||||||
|
uint8_t* vData = uData + (bpl * h / 4); |
||||||
|
for (int i = 0; i< h; i++) |
||||||
|
{ |
||||||
|
uint32_t* scanline = (uint32_t*)img.scanLine(i); |
||||||
|
for (int j=0; j < bpl; j++) |
||||||
|
{ |
||||||
|
float Y = yData[i*bpl + j]; |
||||||
|
float U = uData[i*cxbpl/2 + j/2]; |
||||||
|
float V = vData[i*cxbpl/2 + j/2]; |
||||||
|
|
||||||
|
uint8_t R = qMax(qMin((int)(Y + 1.402 * (V - 128)),255),0); |
||||||
|
uint8_t G = qMax(qMin((int)(Y - 0.344 * (U - 128) - 0.714 * (V - 128)),255),0); |
||||||
|
uint8_t B = qMax(qMin((int)(Y + 1.772 * (U - 128)),255),0); |
||||||
|
|
||||||
|
scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if (frameFormat == QVideoFrame::Format_YV12) |
||||||
|
{ |
||||||
|
uint8_t* yData = lastFrame.bits(); |
||||||
|
uint8_t* vData = yData + (bpl * h); |
||||||
|
uint8_t* uData = vData + (bpl * h / 4); |
||||||
|
for (int i = 0; i< h; i++) |
||||||
|
{ |
||||||
|
uint32_t* scanline = (uint32_t*)img.scanLine(i); |
||||||
|
for (int j=0; j < bpl; j++) |
||||||
|
{ |
||||||
|
float Y = yData[i*bpl + j]; |
||||||
|
float U = uData[i*cxbpl/2 + j/2]; |
||||||
|
float V = vData[i*cxbpl/2 + j/2]; |
||||||
|
|
||||||
|
uint8_t R = qMax(qMin((int)(Y + 1.402 * (V - 128)),255),0); |
||||||
|
uint8_t G = qMax(qMin((int)(Y - 0.344 * (U - 128) - 0.714 * (V - 128)),255),0); |
||||||
|
uint8_t B = qMax(qMin((int)(Y + 1.772 * (U - 128)),255),0); |
||||||
|
|
||||||
|
scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if (frameFormat == QVideoFrame::Format_RGB32) |
||||||
|
{ |
||||||
|
memcpy(img.bits(), lastFrame.bits(), bpl*h); |
||||||
|
} |
||||||
|
|
||||||
|
lastFrame.unmap(); |
||||||
|
return img; |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
#ifndef CAMERA_H |
||||||
|
#define CAMERA_H |
||||||
|
|
||||||
|
#include <QCamera> |
||||||
|
#include <QVideoFrame> |
||||||
|
#include <QAbstractVideoSurface> |
||||||
|
#include "vpx/vpx_image.h" |
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a wrapper to share a camera's captured video frames |
||||||
|
* In Qt cameras normally only send their frames to a single output at a time |
||||||
|
* So you can't, for example, send the frames over the network |
||||||
|
* and output them to a widget on the screen at the same time |
||||||
|
* |
||||||
|
* Instead this class allows objects to surscribe and unsuscribe, starting |
||||||
|
* the camera only when needed, and giving access to the last frame |
||||||
|
**/ |
||||||
|
|
||||||
|
class Camera : private QAbstractVideoSurface |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
Camera(); |
||||||
|
void suscribe(); ///< Call this once before trying to get frames
|
||||||
|
void unsuscribe(); ///< Call this once when you don't need frames anymore
|
||||||
|
QVideoFrame 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 !)
|
||||||
|
bool isFormatSupported(const QVideoSurfaceFormat & format) const; |
||||||
|
|
||||||
|
private slots: |
||||||
|
void onCameraError(QCamera::Error value); |
||||||
|
|
||||||
|
private: |
||||||
|
bool start(const QVideoSurfaceFormat &format); |
||||||
|
bool present(const QVideoFrame &frame); |
||||||
|
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; |
||||||
|
|
||||||
|
private: |
||||||
|
int refcount; ///< Number of users suscribed to the camera
|
||||||
|
QCamera *camera; |
||||||
|
QVideoFrame lastFrame; |
||||||
|
int frameFormat; |
||||||
|
QList<QVideoFrame::PixelFormat> supportedFormats; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // CAMERA_H
|
@ -1,37 +1,37 @@ |
|||||||
#ifndef SELFCAMVIEW_H |
#ifndef SELFCAMVIEW_H |
||||||
#define SELFCAMVIEW_H |
#define SELFCAMVIEW_H |
||||||
|
|
||||||
#include <QCamera> |
|
||||||
#include <QCameraImageCapture> |
|
||||||
#include <QMediaRecorder> |
|
||||||
#include <QWidget> |
#include <QWidget> |
||||||
#include <QVideoWidget> |
|
||||||
#include <QCameraViewfinder> |
|
||||||
#include <QHBoxLayout> |
#include <QHBoxLayout> |
||||||
|
#include <QTimer> |
||||||
|
#include <QLabel> |
||||||
|
#include "camera.h" |
||||||
|
|
||||||
class QCloseEvent; |
class QCloseEvent; |
||||||
class QShowEvent; |
class QShowEvent; |
||||||
|
class QPainter; |
||||||
|
|
||||||
class SelfCamView : public QWidget |
class SelfCamView : public QWidget |
||||||
{ |
{ |
||||||
Q_OBJECT |
Q_OBJECT |
||||||
|
|
||||||
public: |
public: |
||||||
SelfCamView(QWidget *parent=0); |
SelfCamView(Camera* Cam, QWidget *parent=0); |
||||||
~SelfCamView(); |
~SelfCamView(); |
||||||
|
|
||||||
|
private slots: |
||||||
|
void updateDisplay(); |
||||||
|
|
||||||
private: |
private: |
||||||
void closeEvent(QCloseEvent*); |
void closeEvent(QCloseEvent*); |
||||||
void showEvent(QShowEvent*); |
void showEvent(QShowEvent*); |
||||||
|
void paint(QPainter *painter); |
||||||
private slots: |
|
||||||
void setCamera(const QByteArray &cameraDevice); |
|
||||||
void displayCameraError(); |
|
||||||
|
|
||||||
private: |
private: |
||||||
QCamera *camera; |
QLabel *displayLabel; |
||||||
QCameraViewfinder* viewfinder; |
|
||||||
QHBoxLayout* mainLayout; |
QHBoxLayout* mainLayout; |
||||||
|
Camera* cam; |
||||||
|
QTimer updateDisplayTimer; |
||||||
}; |
}; |
||||||
|
|
||||||
#endif // SELFCAMVIEW_H
|
#endif // SELFCAMVIEW_H
|
||||||
|
@ -0,0 +1,87 @@ |
|||||||
|
#include "videosurface.h" |
||||||
|
#include "core.h" |
||||||
|
#include <QVideoFrame> |
||||||
|
#include <QDebug> |
||||||
|
|
||||||
|
VideoSurface::VideoSurface() |
||||||
|
: QAbstractVideoSurface() |
||||||
|
{ |
||||||
|
vpx_img_alloc(&input, VPX_IMG_FMT_YV12, TOXAV_VIDEO_WIDTH, TOXAV_VIDEO_HEIGHT, 1); |
||||||
|
} |
||||||
|
|
||||||
|
bool VideoSurface::start(const QVideoSurfaceFormat &format) |
||||||
|
{ |
||||||
|
mVideoFormat = format; |
||||||
|
//start only if format is UYVY, dont handle other format now
|
||||||
|
if( format.pixelFormat() == QVideoFrame::Format_YV12 ){ |
||||||
|
QAbstractVideoSurface::start(format); |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool VideoSurface::present(const QVideoFrame &frame) |
||||||
|
{ |
||||||
|
/*
|
||||||
|
mFrame = frame; |
||||||
|
|
||||||
|
qDebug() << QString("Video: Frame format is %1").arg(mFrame.pixelFormat()); |
||||||
|
|
||||||
|
stop(); |
||||||
|
|
||||||
|
//this is necessary to get valid data from frame
|
||||||
|
mFrame.map(QAbstractVideoBuffer::ReadOnly); |
||||||
|
|
||||||
|
uchar* data = new uchar[frame.mappedBytes()]; |
||||||
|
memcpy(data, frame.bits(), frame.mappedBytes()); |
||||||
|
|
||||||
|
input.planes[VPX_PLANE_Y] = data; |
||||||
|
input.planes[VPX_PLANE_U] = data + (frame.bytesPerLine() * frame.height()); |
||||||
|
input.planes[VPX_PLANE_V] = input.planes[VPX_PLANE_U] + (frame.bytesPerLine()/2 * frame.height()/2); |
||||||
|
input.planes[VPX_PLANE_ALPHA] = nullptr; |
||||||
|
|
||||||
|
//qDebug() << QString("Got %1 bytes, first plane is %2 bytes long")
|
||||||
|
// .arg(frame.mappedBytes()).arg(frame.bytesPerLine() * frame.height());
|
||||||
|
|
||||||
|
// Slots MUST be called with a direct or blocking connection, or input may die before they return !
|
||||||
|
emit videoFrameReady(input); |
||||||
|
|
||||||
|
|
||||||
|
QImage lastImage( mFrame.size(), QImage::Format_RGB16); |
||||||
|
const uchar *src = mFrame.bits(); |
||||||
|
uchar *dst = lastImage.bits(); |
||||||
|
const int srcLineStep = mFrame.bytesPerLine(); |
||||||
|
const int dstLineStep = lastImage.bytesPerLine(); |
||||||
|
const int h = mFrame.height(); |
||||||
|
const int w = mFrame.width(); |
||||||
|
|
||||||
|
for (int y=0; y < h; y++) { |
||||||
|
//this function you can find in qgraphicsvideoitem_maemo5.cpp,
|
||||||
|
//link is mentioned above
|
||||||
|
uyvy422_to_rgb16_line_neon(dst, src, w); |
||||||
|
src += srcLineStep; |
||||||
|
dst += dstLineStep; |
||||||
|
} |
||||||
|
|
||||||
|
mLastFrame = QPixmap::fromImage(lastImage); |
||||||
|
//emit signal, other can handle it and do necessary processing
|
||||||
|
emit frameUpdated(mLastFrame); |
||||||
|
|
||||||
|
delete[] data; |
||||||
|
mFrame.unmap(); |
||||||
|
|
||||||
|
*/ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
QList<QVideoFrame::PixelFormat> VideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const |
||||||
|
{ |
||||||
|
if (handleType == QAbstractVideoBuffer::NoHandle) { |
||||||
|
qDebug() << "Video: No handle"; |
||||||
|
return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_YV12; |
||||||
|
} else { |
||||||
|
qDebug() << "Video: Handle type is not NoHandle"; |
||||||
|
return QList<QVideoFrame::PixelFormat>(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
#ifndef VIDEOSURFACE_H |
||||||
|
#define VIDEOSURFACE_H |
||||||
|
|
||||||
|
#include <QAbstractVideoSurface> |
||||||
|
#include <QVideoSurfaceFormat> |
||||||
|
#include "vpx/vpx_image.h" |
||||||
|
|
||||||
|
class VideoSurface : public QAbstractVideoSurface |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
VideoSurface(); |
||||||
|
bool start(const QVideoSurfaceFormat &format); |
||||||
|
bool present(const QVideoFrame &frame); |
||||||
|
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; |
||||||
|
|
||||||
|
signals: |
||||||
|
// Slots MUST be called with a direct or blocking connection, or img may die before they return !
|
||||||
|
void videoFrameReady(vpx_image img); |
||||||
|
|
||||||
|
private: |
||||||
|
QVideoSurfaceFormat mVideoFormat; |
||||||
|
vpx_image_t input; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // VIDEOSURFACE_H
|
Loading…
Reference in new issue