mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Video: View self video during video call
This commit is contained in:
parent
1b10672179
commit
4c493b85a0
|
@ -286,6 +286,8 @@ bool CameraSource::openDevice()
|
||||||
while (!streamFuture.isRunning())
|
while (!streamFuture.isRunning())
|
||||||
QThread::yieldCurrentThread();
|
QThread::yieldCurrentThread();
|
||||||
|
|
||||||
|
emit deviceOpened();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ public:
|
||||||
virtual bool subscribe() override;
|
virtual bool subscribe() override;
|
||||||
virtual void unsubscribe() override;
|
virtual void unsubscribe() override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void deviceOpened();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraSource();
|
CameraSource();
|
||||||
~CameraSource();
|
~CameraSource();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include "src/widget/tool/movablewidget.h"
|
#include "src/widget/tool/movablewidget.h"
|
||||||
|
#include "camerasource.h"
|
||||||
|
|
||||||
NetCamView::NetCamView(QWidget* parent)
|
NetCamView::NetCamView(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
@ -36,15 +37,26 @@ NetCamView::NetCamView(QWidget* parent)
|
||||||
|
|
||||||
mainLayout->addWidget(videoSurface);
|
mainLayout->addWidget(videoSurface);
|
||||||
|
|
||||||
selfFrame = new MovableWidget(this);
|
selfFrame = new MovableWidget(videoSurface);
|
||||||
selfFrame->setStyleSheet("background-color: red;");
|
selfFrame->setStyleSheet("background-color: red;");
|
||||||
selfFrame->show();
|
selfFrame->show();
|
||||||
|
|
||||||
|
selfVideoSurface = new VideoSurface(selfFrame);
|
||||||
|
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
|
||||||
|
selfVideoSurface->setMinimumSize(QSize(160, 120));
|
||||||
|
selfVideoSurface->setSource(&CameraSource::getInstance());
|
||||||
|
QHBoxLayout* camLayout = new QHBoxLayout(selfFrame);
|
||||||
|
camLayout->addWidget(selfVideoSurface);
|
||||||
|
camLayout->setMargin(0);
|
||||||
|
|
||||||
|
connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, this, &NetCamView::updateSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetCamView::show(VideoSource *source, const QString &title)
|
void NetCamView::show(VideoSource *source, const QString &title)
|
||||||
{
|
{
|
||||||
setSource(source);
|
setSource(source);
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
|
selfFrame->setBoundary(videoSurface->getRect());
|
||||||
|
|
||||||
QWidget::show();
|
QWidget::show();
|
||||||
}
|
}
|
||||||
|
@ -69,9 +81,16 @@ void NetCamView::setTitle(const QString &title)
|
||||||
void NetCamView::resizeEvent(QResizeEvent* event)
|
void NetCamView::resizeEvent(QResizeEvent* event)
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(event);
|
QWidget::resizeEvent(event);
|
||||||
|
updateSize();
|
||||||
float ratio = 1.33f;
|
}
|
||||||
int frameHeight = height() / 3.0f;
|
|
||||||
selfFrame->resize(frameHeight * ratio, frameHeight);
|
void NetCamView::updateSize()
|
||||||
selfFrame->move(6, height() - selfFrame->height() - 6);
|
{
|
||||||
|
QSize frameSize = selfVideoSurface->getFrameSize();
|
||||||
|
float ratio = frameSize.width() / static_cast<float>(frameSize.height());
|
||||||
|
QRect videoRect = videoSurface->getRect();
|
||||||
|
int frameHeight = videoRect.height() / 3.0f;
|
||||||
|
selfFrame->resize(frameHeight * ratio, frameHeight);
|
||||||
|
selfFrame->setBoundary(videoRect);
|
||||||
|
selfVideoSurface->resize(selfFrame->size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct vpx_image;
|
||||||
class VideoSurface;
|
class VideoSurface;
|
||||||
class VideoSource;
|
class VideoSource;
|
||||||
class QFrame;
|
class QFrame;
|
||||||
|
class MovableWidget;
|
||||||
|
|
||||||
class NetCamView : public QWidget
|
class NetCamView : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -44,10 +45,14 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent* event) final override;
|
void resizeEvent(QResizeEvent* event) final override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateSize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHBoxLayout* mainLayout;
|
QHBoxLayout* mainLayout;
|
||||||
VideoSurface* videoSurface;
|
VideoSurface* videoSurface;
|
||||||
QWidget* selfFrame;
|
VideoSurface* selfVideoSurface;
|
||||||
|
MovableWidget* selfFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETCAMVIEW_H
|
#endif // NETCAMVIEW_H
|
||||||
|
|
|
@ -28,7 +28,7 @@ VideoSurface::VideoSurface(QWidget* parent)
|
||||||
, frameLock{false}
|
, frameLock{false}
|
||||||
, hasSubscribed{false}
|
, hasSubscribed{false}
|
||||||
{
|
{
|
||||||
|
//setMinimumWidth(160);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoSurface::VideoSurface(VideoSource *source, QWidget* parent)
|
VideoSurface::VideoSurface(VideoSource *source, QWidget* parent)
|
||||||
|
@ -51,6 +51,49 @@ void VideoSurface::setSource(VideoSource *src)
|
||||||
source = src;
|
source = src;
|
||||||
subscribe();
|
subscribe();
|
||||||
}
|
}
|
||||||
|
#include <QDebug>
|
||||||
|
QRect VideoSurface::getRect()
|
||||||
|
{
|
||||||
|
// Fast lock
|
||||||
|
{
|
||||||
|
bool expected = false;
|
||||||
|
while (!frameLock.compare_exchange_weak(expected, true))
|
||||||
|
expected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VideoFrame> last = lastFrame;
|
||||||
|
frameLock = false;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
QSize frameSize = lastFrame->getSize();
|
||||||
|
QRect rect = this->rect();
|
||||||
|
int width = frameSize.width()*rect.height()/frameSize.height();
|
||||||
|
rect.setLeft((rect.width()-width)/2);
|
||||||
|
rect.setWidth(width);
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize VideoSurface::getFrameSize()
|
||||||
|
{
|
||||||
|
// Fast lock
|
||||||
|
{
|
||||||
|
bool expected = false;
|
||||||
|
while (!frameLock.compare_exchange_weak(expected, true))
|
||||||
|
expected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize frameSize;
|
||||||
|
|
||||||
|
if (lastFrame)
|
||||||
|
frameSize = lastFrame->getSize();
|
||||||
|
|
||||||
|
frameLock = false;
|
||||||
|
return frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
void VideoSurface::subscribe()
|
void VideoSurface::subscribe()
|
||||||
{
|
{
|
||||||
|
@ -109,13 +152,40 @@ void VideoSurface::paintEvent(QPaintEvent*)
|
||||||
if (lastFrame)
|
if (lastFrame)
|
||||||
{
|
{
|
||||||
QSize frameSize = lastFrame->getSize();
|
QSize frameSize = lastFrame->getSize();
|
||||||
QRect rect = painter.viewport();
|
QRect rect = this->rect();
|
||||||
int width = frameSize.width()*rect.height()/frameSize.height();
|
int width = frameSize.width()*rect.height()/frameSize.height();
|
||||||
rect.setLeft((rect.width()-width)/2);
|
rect.setLeft((rect.width()-width)/2);
|
||||||
rect.setWidth(width);
|
rect.setWidth(width);
|
||||||
|
|
||||||
QImage frame = lastFrame->toQImage(rect.size());
|
QImage frame = lastFrame->toQImage(rect.size());
|
||||||
painter.drawImage(rect, frame, frame.rect(), Qt::NoFormatConversion);
|
painter.drawImage(rect, frame, frame.rect(), Qt::NoFormatConversion);
|
||||||
|
//qDebug() << "VIDEO 2" << rect;
|
||||||
}
|
}
|
||||||
frameLock = false;
|
frameLock = false;
|
||||||
}
|
}
|
||||||
|
#include <QResizeEvent>
|
||||||
|
void VideoSurface::resizeEvent(QResizeEvent* event)
|
||||||
|
{
|
||||||
|
QSize frameSize;
|
||||||
|
|
||||||
|
// Fast lock
|
||||||
|
{
|
||||||
|
bool expected = false;
|
||||||
|
while (!frameLock.compare_exchange_weak(expected, true))
|
||||||
|
expected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastFrame)
|
||||||
|
{
|
||||||
|
frameSize = lastFrame->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
frameLock = false;
|
||||||
|
|
||||||
|
if (frameSize.isValid())
|
||||||
|
{
|
||||||
|
float ratio = frameSize.height() / static_cast<float>(frameSize.width());
|
||||||
|
int width = ratio*event->size().width();
|
||||||
|
setMaximumHeight(width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,12 +35,15 @@ public:
|
||||||
~VideoSurface();
|
~VideoSurface();
|
||||||
|
|
||||||
void setSource(VideoSource* src); //NULL is a valid option
|
void setSource(VideoSource* src); //NULL is a valid option
|
||||||
|
QRect getRect();
|
||||||
|
QSize getFrameSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void subscribe();
|
void subscribe();
|
||||||
void unsubscribe();
|
void unsubscribe();
|
||||||
|
|
||||||
virtual void paintEvent(QPaintEvent * event) final override;
|
virtual void paintEvent(QPaintEvent * event) final override;
|
||||||
|
virtual void resizeEvent(QResizeEvent* event) final override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame);
|
void onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame);
|
||||||
|
|
|
@ -26,6 +26,15 @@ MovableWidget::MovableWidget(QWidget *parent)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MovableWidget::setBoundary(const QRect& boundary)
|
||||||
|
{
|
||||||
|
boundaryRect = boundary;
|
||||||
|
|
||||||
|
QPoint moveTo = pos();
|
||||||
|
checkBoundary(moveTo);
|
||||||
|
move(moveTo);
|
||||||
|
}
|
||||||
|
|
||||||
void MovableWidget::mousePressEvent(QMouseEvent* event)
|
void MovableWidget::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
if (event->buttons() & Qt::LeftButton)
|
if (event->buttons() & Qt::LeftButton)
|
||||||
|
@ -40,18 +49,7 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event)
|
||||||
if (moving)
|
if (moving)
|
||||||
{
|
{
|
||||||
QPoint moveTo = pos() - (lastPoint - event->globalPos());
|
QPoint moveTo = pos() - (lastPoint - event->globalPos());
|
||||||
|
checkBoundary(moveTo);
|
||||||
if (moveTo.x() < 0)
|
|
||||||
moveTo.setX(0);
|
|
||||||
|
|
||||||
if (moveTo.y() < 0)
|
|
||||||
moveTo.setY(0);
|
|
||||||
|
|
||||||
if (moveTo.x() + width() > parentWidget()->width())
|
|
||||||
moveTo.setX(parentWidget()->width() - width());
|
|
||||||
|
|
||||||
if (moveTo.y() + height() > parentWidget()->height())
|
|
||||||
moveTo.setY(parentWidget()->height() - height());
|
|
||||||
|
|
||||||
move(moveTo);
|
move(moveTo);
|
||||||
lastPoint = event->globalPos();
|
lastPoint = event->globalPos();
|
||||||
|
@ -63,3 +61,52 @@ void MovableWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||||
if (!(event->buttons() & Qt::LeftButton))
|
if (!(event->buttons() & Qt::LeftButton))
|
||||||
moving = false;
|
moving = false;
|
||||||
}
|
}
|
||||||
|
#include <QGraphicsOpacityEffect>
|
||||||
|
void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
if (!(event->buttons() & Qt::LeftButton))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!graphicsEffect())
|
||||||
|
{
|
||||||
|
QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this);
|
||||||
|
opacityEffect->setOpacity(0.5);
|
||||||
|
setGraphicsEffect(opacityEffect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setGraphicsEffect(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovableWidget::checkBoundary(QPoint& point) const
|
||||||
|
{
|
||||||
|
int x1, y1, x2, y2;
|
||||||
|
boundaryRect.getCoords(&x1, &y1, &x2, &y2);
|
||||||
|
|
||||||
|
// Video boundary.
|
||||||
|
if (point.x() + width() < x1)
|
||||||
|
point.setX(x1 - width());
|
||||||
|
|
||||||
|
if (point.y() + height() <y1)
|
||||||
|
point.setY(y1 - height());
|
||||||
|
|
||||||
|
if (point.x() > x2)
|
||||||
|
point.setX(x2);
|
||||||
|
|
||||||
|
if (point.y() > y2)
|
||||||
|
point.setY(y2);
|
||||||
|
|
||||||
|
// Parent boundary.
|
||||||
|
if (point.x() < 0)
|
||||||
|
point.setX(0);
|
||||||
|
|
||||||
|
if (point.y() < 0)
|
||||||
|
point.setY(0);
|
||||||
|
|
||||||
|
if (point.x() + width() > parentWidget()->width())
|
||||||
|
point.setX(parentWidget()->width() - width());
|
||||||
|
|
||||||
|
if (point.y() + height() > parentWidget()->height())
|
||||||
|
point.setY(parentWidget()->height() - height());
|
||||||
|
}
|
||||||
|
|
|
@ -25,16 +25,21 @@
|
||||||
class MovableWidget : public QWidget
|
class MovableWidget : public QWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MovableWidget(QWidget* parent = 0);
|
MovableWidget(QWidget* parent);
|
||||||
|
void setBoundary(const QRect& boundary);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
void mouseMoveEvent(QMouseEvent* event);
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
void mouseReleaseEvent(QMouseEvent* event);
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void checkBoundary(QPoint& point) const;
|
||||||
|
|
||||||
bool moving = false;
|
bool moving = false;
|
||||||
QPoint lastPoint;
|
QPoint lastPoint;
|
||||||
|
QRect boundaryRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MOVABLEWIDGET_H
|
#endif // MOVABLEWIDGET_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user