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())
|
||||
QThread::yieldCurrentThread();
|
||||
|
||||
emit deviceOpened();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ public:
|
|||
virtual bool subscribe() override;
|
||||
virtual void unsubscribe() override;
|
||||
|
||||
signals:
|
||||
void deviceOpened();
|
||||
|
||||
private:
|
||||
CameraSource();
|
||||
~CameraSource();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include "src/widget/tool/movablewidget.h"
|
||||
#include "camerasource.h"
|
||||
|
||||
NetCamView::NetCamView(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
@ -36,15 +37,26 @@ NetCamView::NetCamView(QWidget* parent)
|
|||
|
||||
mainLayout->addWidget(videoSurface);
|
||||
|
||||
selfFrame = new MovableWidget(this);
|
||||
selfFrame = new MovableWidget(videoSurface);
|
||||
selfFrame->setStyleSheet("background-color: red;");
|
||||
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)
|
||||
{
|
||||
setSource(source);
|
||||
setTitle(title);
|
||||
selfFrame->setBoundary(videoSurface->getRect());
|
||||
|
||||
QWidget::show();
|
||||
}
|
||||
|
@ -69,9 +81,16 @@ void NetCamView::setTitle(const QString &title)
|
|||
void NetCamView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
|
||||
float ratio = 1.33f;
|
||||
int frameHeight = height() / 3.0f;
|
||||
selfFrame->resize(frameHeight * ratio, frameHeight);
|
||||
selfFrame->move(6, height() - selfFrame->height() - 6);
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void NetCamView::updateSize()
|
||||
{
|
||||
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 VideoSource;
|
||||
class QFrame;
|
||||
class MovableWidget;
|
||||
|
||||
class NetCamView : public QWidget
|
||||
{
|
||||
|
@ -44,10 +45,14 @@ public:
|
|||
protected:
|
||||
void resizeEvent(QResizeEvent* event) final override;
|
||||
|
||||
private slots:
|
||||
void updateSize();
|
||||
|
||||
private:
|
||||
QHBoxLayout* mainLayout;
|
||||
VideoSurface* videoSurface;
|
||||
QWidget* selfFrame;
|
||||
VideoSurface* selfVideoSurface;
|
||||
MovableWidget* selfFrame;
|
||||
};
|
||||
|
||||
#endif // NETCAMVIEW_H
|
||||
|
|
|
@ -28,7 +28,7 @@ VideoSurface::VideoSurface(QWidget* parent)
|
|||
, frameLock{false}
|
||||
, hasSubscribed{false}
|
||||
{
|
||||
|
||||
//setMinimumWidth(160);
|
||||
}
|
||||
|
||||
VideoSurface::VideoSurface(VideoSource *source, QWidget* parent)
|
||||
|
@ -51,6 +51,49 @@ void VideoSurface::setSource(VideoSource *src)
|
|||
source = src;
|
||||
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()
|
||||
{
|
||||
|
@ -109,13 +152,40 @@ void VideoSurface::paintEvent(QPaintEvent*)
|
|||
if (lastFrame)
|
||||
{
|
||||
QSize frameSize = lastFrame->getSize();
|
||||
QRect rect = painter.viewport();
|
||||
QRect rect = this->rect();
|
||||
int width = frameSize.width()*rect.height()/frameSize.height();
|
||||
rect.setLeft((rect.width()-width)/2);
|
||||
rect.setWidth(width);
|
||||
|
||||
QImage frame = lastFrame->toQImage(rect.size());
|
||||
painter.drawImage(rect, frame, frame.rect(), Qt::NoFormatConversion);
|
||||
//qDebug() << "VIDEO 2" << rect;
|
||||
}
|
||||
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();
|
||||
|
||||
void setSource(VideoSource* src); //NULL is a valid option
|
||||
QRect getRect();
|
||||
QSize getFrameSize();
|
||||
|
||||
protected:
|
||||
void subscribe();
|
||||
void unsubscribe();
|
||||
|
||||
virtual void paintEvent(QPaintEvent * event) final override;
|
||||
virtual void resizeEvent(QResizeEvent* event) final override;
|
||||
|
||||
private slots:
|
||||
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)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
|
@ -40,18 +49,7 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event)
|
|||
if (moving)
|
||||
{
|
||||
QPoint moveTo = pos() - (lastPoint - event->globalPos());
|
||||
|
||||
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());
|
||||
checkBoundary(moveTo);
|
||||
|
||||
move(moveTo);
|
||||
lastPoint = event->globalPos();
|
||||
|
@ -63,3 +61,52 @@ void MovableWidget::mouseReleaseEvent(QMouseEvent* event)
|
|||
if (!(event->buttons() & Qt::LeftButton))
|
||||
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
|
||||
{
|
||||
public:
|
||||
MovableWidget(QWidget* parent = 0);
|
||||
MovableWidget(QWidget* parent);
|
||||
void setBoundary(const QRect& boundary);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
void checkBoundary(QPoint& point) const;
|
||||
|
||||
bool moving = false;
|
||||
QPoint lastPoint;
|
||||
QRect boundaryRect;
|
||||
};
|
||||
|
||||
#endif // MOVABLEWIDGET_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user