1
0
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:
TheSpiritXIII 2015-07-21 14:38:43 -04:00
parent 1b10672179
commit 4c493b85a0
8 changed files with 176 additions and 22 deletions

View File

@ -286,6 +286,8 @@ bool CameraSource::openDevice()
while (!streamFuture.isRunning())
QThread::yieldCurrentThread();
emit deviceOpened();
return true;
}

View File

@ -59,6 +59,9 @@ public:
virtual bool subscribe() override;
virtual void unsubscribe() override;
signals:
void deviceOpened();
private:
CameraSource();
~CameraSource();

View File

@ -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());
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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