mirror of https://github.com/qTox/qTox.git
9 changed files with 487 additions and 188 deletions
@ -1,121 +1,125 @@
@@ -1,121 +1,125 @@
|
||||
#------------------------------------------------- |
||||
# |
||||
# Project created by QtCreator 2014-06-22T14:07:35 |
||||
# |
||||
#------------------------------------------------- |
||||
|
||||
QT += core gui multimedia multimediawidgets |
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
||||
|
||||
TARGET = toxgui |
||||
TEMPLATE = app |
||||
|
||||
HEADERS += widget/form/addfriendform.h \ |
||||
widget/form/chatform.h \ |
||||
widget/form/groupchatform.h \ |
||||
widget/form/settingsform.h \ |
||||
widget/tool/chattextedit.h \ |
||||
widget/tool/copyableelidelabel.h \ |
||||
widget/tool/editablelabelwidget.h \ |
||||
widget/tool/elidelabel.h \ |
||||
widget/tool/esclineedit.h \ |
||||
widget/tool/friendrequestdialog.h \ |
||||
widget/filetransfertwidget.h \ |
||||
widget/friendwidget.h \ |
||||
widget/groupwidget.h \ |
||||
widget/widget.h \ |
||||
friend.h \ |
||||
group.h \ |
||||
grouplist.h \ |
||||
settings.h \ |
||||
status.h \ |
||||
core.h \ |
||||
friendlist.h \ |
||||
cdata.h \ |
||||
cstring.h \ |
||||
audiobuffer.h \ |
||||
widget/selfcamview.h |
||||
|
||||
FORMS += widget.ui |
||||
|
||||
CONFIG += c++11 |
||||
|
||||
RESOURCES += \ |
||||
res.qrc |
||||
|
||||
LIBS += -ltoxcore -ltoxav -lsodium |
||||
|
||||
SOURCES += \ |
||||
widget/form/addfriendform.cpp \ |
||||
widget/form/chatform.cpp \ |
||||
widget/form/groupchatform.cpp \ |
||||
widget/form/settingsform.cpp \ |
||||
widget/tool/chattextedit.cpp \ |
||||
widget/tool/copyableelidelabel.cpp \ |
||||
widget/tool/editablelabelwidget.cpp \ |
||||
widget/tool/elidelabel.cpp \ |
||||
widget/tool/esclineedit.cpp \ |
||||
widget/tool/friendrequestdialog.cpp \ |
||||
widget/filetransfertwidget.cpp \ |
||||
widget/friendwidget.cpp \ |
||||
widget/groupwidget.cpp \ |
||||
widget/widget.cpp \ |
||||
core.cpp \ |
||||
friend.cpp \ |
||||
friendlist.cpp \ |
||||
group.cpp \ |
||||
grouplist.cpp \ |
||||
main.cpp \ |
||||
settings.cpp \ |
||||
status.cpp \ |
||||
cdata.cpp \ |
||||
cstring.cpp \ |
||||
audiobuffer.cpp \ |
||||
widget/selfcamview.cpp |
||||
|
||||
|
||||
|
||||
### EXAMPLE BUILD SETTINGS FOR WINDOWS |
||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxcore |
||||
|
||||
#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/toxcore.lib |
||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxcore.a |
||||
|
||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxav |
||||
|
||||
#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/toxav.lib |
||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxav.a |
||||
|
||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lvpx |
||||
|
||||
#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/vpx.lib |
||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libvpx.a |
||||
|
||||
|
||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lopus |
||||
|
||||
#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/opus.lib |
||||
#else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libopus.a |
||||
|
||||
#win32: LIBS += -lws2_32 |
||||
|
||||
#win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lsodium |
||||
|
||||
#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 |
||||
#------------------------------------------------- |
||||
# |
||||
# Project created by QtCreator 2014-06-22T14:07:35 |
||||
# |
||||
#------------------------------------------------- |
||||
|
||||
QT += core gui multimedia multimediawidgets |
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
||||
|
||||
TARGET = toxgui |
||||
TEMPLATE = app |
||||
|
||||
HEADERS += widget/form/addfriendform.h \ |
||||
widget/form/chatform.h \ |
||||
widget/form/groupchatform.h \ |
||||
widget/form/settingsform.h \ |
||||
widget/tool/chattextedit.h \ |
||||
widget/tool/copyableelidelabel.h \ |
||||
widget/tool/editablelabelwidget.h \ |
||||
widget/tool/elidelabel.h \ |
||||
widget/tool/esclineedit.h \ |
||||
widget/tool/friendrequestdialog.h \ |
||||
widget/filetransfertwidget.h \ |
||||
widget/friendwidget.h \ |
||||
widget/groupwidget.h \ |
||||
widget/widget.h \ |
||||
friend.h \ |
||||
group.h \ |
||||
grouplist.h \ |
||||
settings.h \ |
||||
status.h \ |
||||
core.h \ |
||||
friendlist.h \ |
||||
cdata.h \ |
||||
cstring.h \ |
||||
audiobuffer.h \ |
||||
widget/selfcamview.h \ |
||||
widget/videosurface.h \ |
||||
widget/camera.h |
||||
|
||||
FORMS += widget.ui |
||||
|
||||
CONFIG += c++11 |
||||
|
||||
RESOURCES += \ |
||||
res.qrc |
||||
|
||||
LIBS += -ltoxcore -ltoxav -lsodium -lvpx |
||||
|
||||
SOURCES += \ |
||||
widget/form/addfriendform.cpp \ |
||||
widget/form/chatform.cpp \ |
||||
widget/form/groupchatform.cpp \ |
||||
widget/form/settingsform.cpp \ |
||||
widget/tool/chattextedit.cpp \ |
||||
widget/tool/copyableelidelabel.cpp \ |
||||
widget/tool/editablelabelwidget.cpp \ |
||||
widget/tool/elidelabel.cpp \ |
||||
widget/tool/esclineedit.cpp \ |
||||
widget/tool/friendrequestdialog.cpp \ |
||||
widget/filetransfertwidget.cpp \ |
||||
widget/friendwidget.cpp \ |
||||
widget/groupwidget.cpp \ |
||||
widget/widget.cpp \ |
||||
core.cpp \ |
||||
friend.cpp \ |
||||
friendlist.cpp \ |
||||
group.cpp \ |
||||
grouplist.cpp \ |
||||
main.cpp \ |
||||
settings.cpp \ |
||||
status.cpp \ |
||||
cdata.cpp \ |
||||
cstring.cpp \ |
||||
audiobuffer.cpp \ |
||||
widget/selfcamview.cpp \ |
||||
widget/videosurface.cpp \ |
||||
widget/camera.cpp |
||||
|
||||
|
||||
|
||||
### EXAMPLE BUILD SETTINGS FOR WINDOWS |
||||
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxcore |
||||
|
||||
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/toxcore.lib |
||||
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxcore.a |
||||
|
||||
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -ltoxav |
||||
|
||||
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/toxav.lib |
||||
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libtoxav.a |
||||
|
||||
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lvpx |
||||
|
||||
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/vpx.lib |
||||
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libvpx.a |
||||
|
||||
|
||||
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lopus |
||||
|
||||
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/opus.lib |
||||
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/libopus.a |
||||
|
||||
win32: LIBS += -lws2_32 |
||||
|
||||
win32: LIBS += -L$$PWD/../../../../Downloads/libtoxcore-win32-i686/lib/ -lsodium |
||||
|
||||
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 @@
@@ -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 @@
@@ -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 @@
@@ -1,37 +1,37 @@
|
||||
#ifndef SELFCAMVIEW_H |
||||
#define SELFCAMVIEW_H |
||||
|
||||
#include <QCamera> |
||||
#include <QCameraImageCapture> |
||||
#include <QMediaRecorder> |
||||
#include <QWidget> |
||||
#include <QVideoWidget> |
||||
#include <QCameraViewfinder> |
||||
#include <QHBoxLayout> |
||||
#include <QTimer> |
||||
#include <QLabel> |
||||
#include "camera.h" |
||||
|
||||
class QCloseEvent; |
||||
class QShowEvent; |
||||
class QPainter; |
||||
|
||||
class SelfCamView : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
SelfCamView(QWidget *parent=0); |
||||
SelfCamView(Camera* Cam, QWidget *parent=0); |
||||
~SelfCamView(); |
||||
|
||||
private slots: |
||||
void updateDisplay(); |
||||
|
||||
private: |
||||
void closeEvent(QCloseEvent*); |
||||
void showEvent(QShowEvent*); |
||||
|
||||
private slots: |
||||
void setCamera(const QByteArray &cameraDevice); |
||||
void displayCameraError(); |
||||
void paint(QPainter *painter); |
||||
|
||||
private: |
||||
QCamera *camera; |
||||
QCameraViewfinder* viewfinder; |
||||
QLabel *displayLabel; |
||||
QHBoxLayout* mainLayout; |
||||
Camera* cam; |
||||
QTimer updateDisplayTimer; |
||||
}; |
||||
|
||||
#endif // SELFCAMVIEW_H
|
||||
|
@ -0,0 +1,87 @@
@@ -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 @@
@@ -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