Skip to content

Commit

Permalink
Replace video scroll area with scroll bars and OpenGL model-view.
Browse files Browse the repository at this point in the history
Also, exposes the zoom and scroll as object properties to QML.
  • Loading branch information
ddennedy committed Aug 10, 2014
1 parent 9a0acb2 commit 6884fba
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 38 deletions.
55 changes: 48 additions & 7 deletions src/glwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ GLWidget::GLWidget(QObject *parent)
, m_threadCreateEvent(0)
, m_threadJoinEvent(0)
, m_frameRenderer(0)
, m_zoom(0.0f)
, m_offset(QPoint(0, 0))
{
qDebug() << "begin";
m_texture[0] = m_texture[1] = m_texture[2] = 0;
Expand Down Expand Up @@ -159,8 +161,6 @@ void GLWidget::initializeGL()
void GLWidget::resizeGL(int width, int height)
{
int x, y, w, h;
width *= devicePixelRatio();
height *= devicePixelRatio();
double this_aspect = (double) width / height;
double video_aspect = profile().dar();
qDebug() << width << 'x' << height;
Expand Down Expand Up @@ -200,11 +200,12 @@ void GLWidget::createShader()
m_shader = new QOpenGLShaderProgram;
m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex,
"uniform mat4 projection;"
"uniform mat4 modelView;"
"attribute vec4 vertex;"
"attribute vec2 texCoord;"
"varying vec2 coordinates;"
"void main(void) {"
" gl_Position = projection * vertex;"
" gl_Position = projection * modelView * vertex;"
" coordinates = texCoord;"
"}");
if (m_glslManager) {
Expand Down Expand Up @@ -247,6 +248,7 @@ void GLWidget::createShader()
m_colorspaceLocation = m_shader->uniformLocation("colorspace");
}
m_projectionLocation = m_shader->uniformLocation("projection");
m_modelViewLocation = m_shader->uniformLocation("modelView");
m_vertexLocation = m_shader->attributeLocation("vertex");
m_texCoordLocation = m_shader->attributeLocation("texCoord");
}
Expand Down Expand Up @@ -295,12 +297,24 @@ void GLWidget::paintGL()
m_shader->setUniformValue(m_projectionLocation, projection);
check_error();

// Set model view.
QMatrix4x4 modelView;
if (m_zoom > 0.0) {
if (offset().x() || offset().y())
modelView.translate(-offset().x(), offset().y());
modelView.scale(zoom(), zoom());
}
m_shader->setUniformValue(m_modelViewLocation, modelView);
check_error();

// Provide vertices of triangle strip.
QVector<QVector2D> vertices;
vertices << QVector2D(float(-m_rect.width())/2.0f, float(-m_rect.height())/2.0f);
vertices << QVector2D(float(-m_rect.width())/2.0f, float( m_rect.height())/2.0f);
vertices << QVector2D(float( m_rect.width())/2.0f, float(-m_rect.height())/2.0f);
vertices << QVector2D(float( m_rect.width())/2.0f, float( m_rect.height())/2.0f);
width = m_rect.width() * devicePixelRatio();
height = m_rect.height() * devicePixelRatio();
vertices << QVector2D(float(-width)/2.0f, float(-height)/2.0f);
vertices << QVector2D(float(-width)/2.0f, float( height)/2.0f);
vertices << QVector2D(float( width)/2.0f, float(-height)/2.0f);
vertices << QVector2D(float( width)/2.0f, float( height)/2.0f);
m_shader->enableAttributeArray(m_vertexLocation);
check_error();
m_shader->setAttributeArray(m_vertexLocation, vertices.constData());
Expand Down Expand Up @@ -572,6 +586,33 @@ void GLWidget::setLastFrame(mlt_frame frame)
m_lastFrame = new Mlt::Frame(frame);
}

QPoint GLWidget::offset() const
{
return QPoint(m_offset.x() - (MLT.profile().width() * m_zoom - width()) / 2,
m_offset.y() - (MLT.profile().height() * m_zoom - height()) / 2);
}

void GLWidget::setZoom(float zoom)
{
m_zoom = zoom;
emit zoomChanged();
update();
}

void GLWidget::setOffsetX(int x)
{
m_offset.setX(x);
emit offsetChanged();
update();
}

void GLWidget::setOffsetY(int y)
{
m_offset.setY(y);
emit offsetChanged();
update();
}

void GLWidget::updateTexture(GLuint yName, GLuint uName, GLuint vName)
{
m_texture[0] = yName;
Expand Down
21 changes: 18 additions & 3 deletions src/glwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ typedef void* ( *thread_function_t )( void* );
class GLWidget : public QQuickView, public Controller, protected QOpenGLFunctions
{
Q_OBJECT
Q_PROPERTY(QRect rect MEMBER m_rect NOTIFY rectChanged)
Q_PROPERTY(QRect rect READ rect NOTIFY rectChanged)
Q_PROPERTY(float zoom READ zoom NOTIFY zoomChanged)
Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)

public:
GLWidget(QObject *parent = 0);
Expand Down Expand Up @@ -74,13 +76,21 @@ class GLWidget : public QQuickView, public Controller, protected QOpenGLFunction
Controller::pause();
emit paused();
}
int displayWidth() const { return m_rect.width() / devicePixelRatio(); }
int displayHeight() const { return m_rect.height() / devicePixelRatio(); }
int displayWidth() const { return m_rect.width(); }
int displayHeight() const { return m_rect.height(); }

QObject* videoWidget() { return this; }
QQuickView* videoQuickView() { return this; }
Filter* glslManager() const { return m_glslManager; }
FrameRenderer* frameRenderer() const { return m_frameRenderer; }
QRect rect() const { return m_rect; }
float zoom() const { return m_zoom * MLT.profile().width() / m_rect.width(); }
QPoint offset() const;

public slots:
void setZoom(float zoom);
void setOffsetX(int x);
void setOffsetY(int y);

signals:
/** This method will be called each time a new frame is available.
Expand All @@ -95,6 +105,8 @@ class GLWidget : public QQuickView, public Controller, protected QOpenGLFunction
void paused();
void playing();
void rectChanged();
void zoomChanged();
void offsetChanged();

private:
QRect m_rect;
Expand All @@ -112,10 +124,13 @@ class GLWidget : public QQuickView, public Controller, protected QOpenGLFunction
Event* m_threadJoinEvent;
FrameRenderer* m_frameRenderer;
int m_projectionLocation;
int m_modelViewLocation;
int m_vertexLocation;
int m_texCoordLocation;
int m_colorspaceLocation;
int m_textureLocation[3];
float m_zoom;
QPoint m_offset;

private slots:
void initializeGL();
Expand Down
89 changes: 63 additions & 26 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Player::Player(QWidget *parent)
, m_position(0)
, m_seekPosition(SEEK_INACTIVE)
, m_isMeltedPlaying(-1)
, m_scrollArea(0)
, m_zoomToggleFactor(Settings.playerZoom() == 0.0f? 1.0f : Settings.playerZoom())
, m_pauseAfterPlay(false)
, m_monitorScreen(-1)
Expand Down Expand Up @@ -60,26 +59,29 @@ Player::Player(QWidget *parent)
tabLayout->addStretch();
connect(m_tabs, SIGNAL(tabBarClicked(int)), SLOT(onTabBarClicked(int)));

// Add the volume and signal level meter
QWidget* tmp = new QWidget(this);
vlayout->addWidget(tmp, 10);
// Add the layouts for managing video view, scroll bars, and audio controls.
QHBoxLayout* hlayout = new QHBoxLayout;
vlayout->addLayout(hlayout, 10);
vlayout->addStretch();
QHBoxLayout* hlayout = new QHBoxLayout(tmp);
hlayout->setSpacing(4);
hlayout->setContentsMargins(0, 0, 0, 0);
m_videoWidget = QWidget::createWindowContainer(qobject_cast<QWindow*>(MLT.videoWidget()));
#ifdef Q_OS_MAC
hlayout->addWidget(m_videoWidget, 10);
#else
m_scrollArea = new QScrollArea;
m_scrollArea->setWidgetResizable(true);
m_scrollArea->setFrameShape(QFrame::NoFrame);
m_scrollArea->setAlignment(Qt::AlignCenter);
m_scrollArea->setFocusPolicy(Qt::NoFocus);
m_scrollArea->setWidget(m_videoWidget);
hlayout->addWidget(m_scrollArea, 10);
#endif
QGridLayout* glayout = new QGridLayout;
glayout->setSpacing(0);
glayout->setContentsMargins(0, 0, 0, 0);
hlayout->addLayout(glayout, 10);
hlayout->addStretch();

// Add the video widgets.
m_videoWidget = QWidget::createWindowContainer(qobject_cast<QWindow*>(MLT.videoWidget()));
glayout->addWidget(m_videoWidget, 0, 0);
m_verticalScroll = new QScrollBar(Qt::Vertical);
glayout->addWidget(m_verticalScroll, 0, 1);
m_verticalScroll->hide();
m_horizontalScroll = new QScrollBar(Qt::Horizontal);
glayout->addWidget(m_horizontalScroll, 1, 0);
m_horizontalScroll->hide();

// Add the volume and signal level meter
QVBoxLayout *volumeLayoutV = new QVBoxLayout;
volumeLayoutV->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
QBoxLayout *volumeLayoutH = new QHBoxLayout;
Expand Down Expand Up @@ -219,6 +221,9 @@ Player::Player(QWidget *parent)
connect(m_positionSpinner, SIGNAL(valueChanged(int)), this, SLOT(seek(int)));
connect(m_positionSpinner, SIGNAL(editingFinished()), this, SLOT(setFocus()));
connect(this, SIGNAL(endOfStream()), this, SLOT(pause()));
connect(this, SIGNAL(zoomChanged(float)), MLT.videoWidget(), SLOT(setZoom(float)));
connect(m_horizontalScroll, SIGNAL(valueChanged(int)), MLT.videoWidget(), SLOT(setOffsetX(int)));
connect(m_verticalScroll, SIGNAL(valueChanged(int)), MLT.videoWidget(), SLOT(setOffsetY(int)));
setFocusPolicy(Qt::StrongFocus);
}

Expand Down Expand Up @@ -334,6 +339,14 @@ QSize Player::videoSize() const
void Player::resizeEvent(QResizeEvent*)
{
MLT.onWindowResize();
if (Settings.playerZoom() > 0.0f) {
float horizontal = float(m_horizontalScroll->value()) / m_horizontalScroll->maximum();
float vertical = float(m_verticalScroll->value()) / m_verticalScroll->maximum();
adjustScrollBars(horizontal, vertical);
} else {
m_horizontalScroll->hide();
m_verticalScroll->hide();
}
}

void Player::play(double speed)
Expand Down Expand Up @@ -678,6 +691,35 @@ void Player::showAudio(Mlt::Frame* frame)
emit audioLevels(channels);
}

void Player::adjustScrollBars(float horizontal, float vertical)
{
if (MLT.profile().width() * m_zoomToggleFactor > m_videoWidget->width()) {
m_horizontalScroll->setPageStep(m_videoWidget->width());
m_horizontalScroll->setMaximum(MLT.profile().width() * m_zoomToggleFactor
- m_horizontalScroll->pageStep());
m_horizontalScroll->setValue(qRound(horizontal * m_horizontalScroll->maximum()));
emit m_horizontalScroll->valueChanged(m_horizontalScroll->value());
m_horizontalScroll->show();
} else {
int max = MLT.profile().width() * m_zoomToggleFactor - m_videoWidget->width();
emit m_horizontalScroll->valueChanged(qRound(0.5 * max));
m_horizontalScroll->hide();
}

if (MLT.profile().height() * m_zoomToggleFactor > m_videoWidget->height()) {
m_verticalScroll->setPageStep(m_videoWidget->height());
m_verticalScroll->setMaximum(MLT.profile().height() * m_zoomToggleFactor
- m_verticalScroll->pageStep());
m_verticalScroll->setValue(qRound(vertical * m_verticalScroll->maximum()));
emit m_verticalScroll->valueChanged(m_verticalScroll->value());
m_verticalScroll->show();
} else {
int max = MLT.profile().height() * m_zoomToggleFactor - m_videoWidget->height();
emit m_verticalScroll->valueChanged(qRound(0.5 * max));
m_verticalScroll->hide();
}
}

void Player::moveVideoToScreen(int screen)
{
if (screen == m_monitorScreen) return;
Expand Down Expand Up @@ -761,21 +803,16 @@ void Player::onMuteButtonToggled(bool checked)

void Player::setZoom(float factor, const QIcon& icon)
{
emit zoomChanged(factor);
Settings.setPlayerZoom(factor);
if (!m_scrollArea)
return;
if (factor == 0.0f) {
m_scrollArea->setWidgetResizable(true);
m_zoomButton->setIcon(icon);
m_zoomButton->setChecked(false);
m_horizontalScroll->hide();
m_verticalScroll->hide();
} else {
m_zoomToggleFactor = factor;
m_scrollArea->setWidgetResizable(false);
m_videoWidget->resize(
qRound(factor * MLT.profile().width() * MLT.profile().sar()),
qRound(factor * MLT.profile().height()));
m_scrollArea->horizontalScrollBar()->setValue(m_scrollArea->horizontalScrollBar()->maximum() / 2);
m_scrollArea->verticalScrollBar()->setValue(m_scrollArea->verticalScrollBar()->maximum() / 2);
adjustScrollBars(0.5f, 0.5f);
m_zoomButton->setIcon(icon);
m_zoomButton->setChecked(true);
}
Expand Down
9 changes: 7 additions & 2 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class TimeSpinBox;
class AudioSignal;
class QSlider;
class QAction;
class QScrollArea;
class QScrollBar;
class QToolButton;
class QTabBar;

Expand Down Expand Up @@ -73,6 +73,9 @@ class Player : public QWidget
void nextSought(int currentPosition);
void nextSought();
void profileChanged();
void zoomChanged(float zoom);
void scrolledHorizontally(int x);
void scrolledVertically(int y);

public slots:
void play(double speed = 1.0);
Expand Down Expand Up @@ -103,6 +106,7 @@ public slots:
void setupActions(QWidget* widget);
void retranslateUi(QWidget* widget);
void showAudio(Mlt::Frame* frame);
void adjustScrollBars(float horizontal, float vertical);

QAction *actionPlay;
QAction *actionPause;
Expand All @@ -128,7 +132,8 @@ public slots:
int m_duration;
bool m_isSeekable;
int m_isMeltedPlaying;
QScrollArea* m_scrollArea;
QScrollBar* m_horizontalScroll;
QScrollBar* m_verticalScroll;
QToolButton* m_zoomButton;
QAction* m_zoomFitAction;
QAction* m_zoomOriginalAction;
Expand Down

0 comments on commit 6884fba

Please sign in to comment.