* [RFC PATCH 2/7] qv4l2: fix black screen with opengl after capture
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 3/7] qv4l2: show frames option can be toggled during capture Bård Eirik Winther
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Fixes the issue when the window was beeing resized/moved
and the frame image would become black.
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win-gl.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp
index bae6569..edae60f 100644
--- a/utils/qv4l2/capture-win-gl.cpp
+++ b/utils/qv4l2/capture-win-gl.cpp
@@ -253,6 +253,12 @@ void CaptureWinGLEngine::paintGL()
changeShader();
if (m_frameData == NULL) {
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight);
+ glEnd();
return;
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC PATCH 3/7] qv4l2: show frames option can be toggled during capture
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 2/7] qv4l2: fix black screen with opengl after capture Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 4/7] qv4l2: add function getMargins Bård Eirik Winther
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/qv4l2.cpp | 77 ++++++++++++++++++++++++++-------------------------
utils/qv4l2/qv4l2.h | 2 +-
2 files changed, 41 insertions(+), 38 deletions(-)
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index e078e91..fa1425d 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -404,7 +404,7 @@ void ApplicationWindow::capVbiFrame()
m_capStartAct->setChecked(false);
return;
}
- if (m_showFrames) {
+ if (showFrames()) {
for (unsigned y = 0; y < m_vbiHeight; y++) {
__u8 *p = data + y * m_vbiWidth;
__u8 *q = m_capImage->bits() + y * m_capImage->bytesPerLine();
@@ -448,7 +448,7 @@ void ApplicationWindow::capVbiFrame()
m_tv = tv;
}
status = QString("Frame: %1 Fps: %2").arg(++m_frame).arg(m_fps);
- if (m_showFrames)
+ if (showFrames())
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), status);
@@ -490,7 +490,7 @@ void ApplicationWindow::capFrame()
if (m_saveRaw.openMode())
m_saveRaw.write((const char *)m_frameData, s);
- if (!m_showFrames)
+ if (!showFrames())
break;
if (m_mustConvert)
err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
@@ -514,7 +514,7 @@ void ApplicationWindow::capFrame()
if (again)
return;
- if (m_showFrames) {
+ if (showFrames()) {
if (m_mustConvert)
err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
(unsigned char *)m_buffers[buf.index].start, buf.bytesused,
@@ -544,7 +544,7 @@ void ApplicationWindow::capFrame()
if (again)
return;
- if (m_showFrames) {
+ if (showFrames()) {
if (m_mustConvert)
err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat,
(unsigned char *)buf.m.userptr, buf.bytesused,
@@ -592,10 +592,10 @@ void ApplicationWindow::capFrame()
.arg((m_totalAudioLatency.tv_sec * 1000 + m_totalAudioLatency.tv_usec / 1000) / m_frame));
}
#endif
- if (displaybuf == NULL && m_showFrames)
+ if (displaybuf == NULL && showFrames())
status.append(" Error: Unsupported format.");
- if (m_showFrames)
+ if (showFrames())
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, displaybuf, status);
@@ -778,6 +778,13 @@ void ApplicationWindow::stopCapture()
refresh();
}
+bool ApplicationWindow::showFrames()
+{
+ if (m_showFramesAct->isChecked() && !m_capture->isVisible())
+ m_capture->show();
+ return m_showFramesAct->isChecked();
+}
+
void ApplicationWindow::startOutput(unsigned)
{
}
@@ -851,7 +858,6 @@ void ApplicationWindow::capStart(bool start)
m_capImage = NULL;
return;
}
- m_showFrames = m_showFramesAct->isChecked();
m_frame = m_lastFrame = m_fps = 0;
m_capMethod = m_genTab->capMethod();
@@ -859,7 +865,6 @@ void ApplicationWindow::capStart(bool start)
v4l2_format fmt;
v4l2_std_id std;
- m_showFrames = false;
g_fmt_sliced_vbi(fmt);
g_std(std);
fmt.fmt.sliced.service_set = (std & V4L2_STD_625_50) ?
@@ -898,14 +903,14 @@ void ApplicationWindow::capStart(bool start)
m_vbiHeight = fmt.fmt.vbi.count[0] + fmt.fmt.vbi.count[1];
m_vbiSize = m_vbiWidth * m_vbiHeight;
m_frameData = new unsigned char[m_vbiSize];
- if (m_showFrames) {
- m_capture->setMinimumSize(m_vbiWidth, m_vbiHeight);
- m_capImage = new QImage(m_vbiWidth, m_vbiHeight, dstFmt);
- m_capImage->fill(0);
- m_capture->setFrame(m_capImage->width(), m_capImage->height(),
- m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), "No frame");
+ m_capture->setMinimumSize(m_vbiWidth, m_vbiHeight);
+ m_capImage = new QImage(m_vbiWidth, m_vbiHeight, dstFmt);
+ m_capImage->fill(0);
+ m_capture->setFrame(m_capImage->width(), m_capImage->height(),
+ m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), "No frame");
+ if (showFrames())
m_capture->show();
- }
+
statusBar()->showMessage("No frame");
if (startCapture(m_vbiSize)) {
m_capNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, m_tabs);
@@ -919,30 +924,28 @@ void ApplicationWindow::capStart(bool start)
if (m_genTab->get_interval(interval))
set_interval(interval);
- m_mustConvert = m_showFrames;
m_frameData = new unsigned char[srcPix.sizeimage];
- if (m_showFrames) {
- m_capDestFormat = m_capSrcFormat;
- dstPix.pixelformat = V4L2_PIX_FMT_RGB24;
-
- if (m_capture->hasNativeFormat(srcPix.pixelformat)) {
- dstPix.pixelformat = srcPix.pixelformat;
- m_mustConvert = false;
- }
-
- if (m_mustConvert) {
- v4l2_format copy = m_capSrcFormat;
+ m_capDestFormat = m_capSrcFormat;
+ dstPix.pixelformat = V4L2_PIX_FMT_RGB24;
- v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat);
- // v4lconvert_try_format sometimes modifies the source format if it thinks
- // that there is a better format available. Restore our selected source
- // format since we do not want that happening.
- m_capSrcFormat = copy;
- }
+ if (m_capture->hasNativeFormat(srcPix.pixelformat)) {
+ dstPix.pixelformat = srcPix.pixelformat;
+ m_mustConvert = false;
+ } else {
+ m_mustConvert = true;
+ v4l2_format copy = m_capSrcFormat;
+
+ v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat);
+ // v4lconvert_try_format sometimes modifies the source format if it thinks
+ // that there is a better format available. Restore our selected source
+ // format since we do not want that happening.
+ m_capSrcFormat = copy;
+ }
- m_capture->setMinimumSize(dstPix.width, dstPix.height);
- m_capImage = new QImage(dstPix.width, dstPix.height, dstFmt);
- m_capImage->fill(0);
+ m_capture->setMinimumSize(dstPix.width, dstPix.height);
+ m_capImage = new QImage(dstPix.width, dstPix.height, dstFmt);
+ m_capImage->fill(0);
+ if (showFrames()) {
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), "No frame");
m_capture->show();
diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h
index 223db75..92d6f25 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -172,6 +172,7 @@ private:
void updateStandard();
void updateFreq();
void updateFreqChannel();
+ bool showFrames();
GeneralTab *m_genTab;
VbiTab *m_vbiTab;
@@ -193,7 +194,6 @@ private:
WidgetMap m_widgetMap;
ClassMap m_classMap;
bool m_haveExtendedUserCtrls;
- bool m_showFrames;
int m_vbiSize;
unsigned m_vbiWidth;
unsigned m_vbiHeight;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC PATCH 4/7] qv4l2: add function getMargins
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 2/7] qv4l2: fix black screen with opengl after capture Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 3/7] qv4l2: show frames option can be toggled during capture Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 5/7] qv4l2: add video scaling for CaptureWin Bård Eirik Winther
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Created a function to get the total margins (window frame) in pixels
outside the actual video frame beeing displayed.
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win.cpp | 14 ++++++++++----
utils/qv4l2/capture-win.h | 2 ++
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 2d57909..e583900 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -54,16 +54,22 @@ void CaptureWin::buildWindow(QWidget *videoSurface)
vbox->setSpacing(b);
}
+QSize CaptureWin::getMargins()
+{
+ int l, t, r, b;
+ layout()->getContentsMargins(&l, &t, &r, &b);
+ return QSize(l + r, t + b + m_information.minimumSizeHint().height() + layout()->spacing());
+}
+
void CaptureWin::setMinimumSize(int minw, int minh)
{
QDesktopWidget *screen = QApplication::desktop();
QRect resolution = screen->screenGeometry();
QSize maxSize = maximumSize();
- int l, t, r, b;
- layout()->getContentsMargins(&l, &t, &r, &b);
- minw += l + r;
- minh += t + b + m_information.minimumSizeHint().height() + layout()->spacing();
+ QSize margins = getMargins();
+ minw += margins.width();
+ minh += margins.height();
if (minw > resolution.width())
minw = resolution.width();
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index ca60244..6b72e00 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -78,6 +78,8 @@ public:
protected:
void closeEvent(QCloseEvent *event);
void buildWindow(QWidget *videoSurface);
+ QSize getMargins();
+
/**
* @brief A label that can is used to display capture information.
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC PATCH 5/7] qv4l2: add video scaling for CaptureWin
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
` (2 preceding siblings ...)
2013-08-05 8:56 ` [RFC PATCH 4/7] qv4l2: add function getMargins Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 6/7] qv4l2: add hotkey for reset scaling to frame size Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 7/7] qv4l2: add aspect ratio support Bård Eirik Winther
5 siblings, 0 replies; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win-gl.cpp | 26 ++++++++--
utils/qv4l2/capture-win-gl.h | 8 ++++
utils/qv4l2/capture-win-qt.cpp | 24 +++++++++-
utils/qv4l2/capture-win-qt.h | 5 ++
utils/qv4l2/capture-win.cpp | 106 +++++++++++++++++++++++++++++++----------
utils/qv4l2/capture-win.h | 18 +++++--
utils/qv4l2/qv4l2.cpp | 27 +++++++++--
utils/qv4l2/qv4l2.h | 4 ++
8 files changed, 181 insertions(+), 37 deletions(-)
diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp
index edae60f..628aaec 100644
--- a/utils/qv4l2/capture-win-gl.cpp
+++ b/utils/qv4l2/capture-win-gl.cpp
@@ -43,6 +43,15 @@ void CaptureWinGL::stop()
#endif
}
+void CaptureWinGL::resizeEvent(QResizeEvent *event)
+{
+ QSize margins = getMargins();
+#ifdef ENABLE_GL
+ m_videoSurface.setSize(width() - margins.width(), height() - margins.height());
+#endif
+ event->accept();
+}
+
void CaptureWinGL::setFrame(int width, int height, __u32 format, unsigned char *data, const QString &info)
{
#ifdef ENABLE_GL
@@ -109,11 +118,22 @@ void CaptureWinGLEngine::initializeGL()
checkError("InitializeGL");
}
+void CaptureWinGLEngine::setSize(int width, int height)
+{
+ QSize sizedFrame = CaptureWin::scaleFrameSize(QSize(width, height), QSize(m_frameWidth, m_frameHeight));
+
+ width = sizedFrame.width();
+ height = sizedFrame.height();
+
+ if (width > 0 && height > 0) {
+ setMaximumSize(width, height);
+ resizeGL(width, height);
+ }
+}
void CaptureWinGLEngine::resizeGL(int width, int height)
{
- // Resizing is disabled by setting viewport equal to frame size
- glViewport(0, 0, m_frameWidth, m_frameHeight);
+ glViewport(0, 0, width, height);
}
void CaptureWinGLEngine::setFrame(int width, int height, __u32 format, unsigned char *data)
@@ -123,8 +143,6 @@ void CaptureWinGLEngine::setFrame(int width, int height, __u32 format, unsigned
m_frameWidth = width;
m_frameHeight = height;
m_frameFormat = format;
-
- QGLWidget::setMaximumSize(m_frameWidth, m_frameHeight);
}
m_frameData = data;
diff --git a/utils/qv4l2/capture-win-gl.h b/utils/qv4l2/capture-win-gl.h
index 08e72b2..ef06d0b 100644
--- a/utils/qv4l2/capture-win-gl.h
+++ b/utils/qv4l2/capture-win-gl.h
@@ -21,6 +21,9 @@
#include "qv4l2.h"
#include "capture-win.h"
+#include <QBoxLayout>
+#include <QResizeEvent>
+
#ifdef ENABLE_GL
#define GL_GLEXT_PROTOTYPES
#include <QGLWidget>
@@ -40,6 +43,7 @@ public:
void stop();
void setFrame(int width, int height, __u32 format, unsigned char *data);
bool hasNativeFormat(__u32 format);
+ void setSize(int width, int height);
protected:
void paintGL();
@@ -88,6 +92,10 @@ public:
bool hasNativeFormat(__u32 format);
static bool isSupported();
+ protected:
+ void resizeEvent(QResizeEvent *event);
+
+private:
#ifdef ENABLE_GL
CaptureWinGLEngine m_videoSurface;
#endif
diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp
index 63c77d5..0f6964b 100644
--- a/utils/qv4l2/capture-win-qt.cpp
+++ b/utils/qv4l2/capture-win-qt.cpp
@@ -22,8 +22,9 @@
CaptureWinQt::CaptureWinQt() :
m_frame(new QImage(0, 0, QImage::Format_Invalid))
{
-
CaptureWin::buildWindow(&m_videoSurface);
+ m_scaledFrame.setWidth(0);
+ m_scaledFrame.setHeight(0);
}
CaptureWinQt::~CaptureWinQt()
@@ -31,6 +32,19 @@ CaptureWinQt::~CaptureWinQt()
delete m_frame;
}
+void CaptureWinQt::resizeEvent(QResizeEvent *event)
+{
+ if (m_frame->bits() == NULL)
+ return;
+
+ QPixmap img = QPixmap::fromImage(*m_frame);
+ m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()),
+ QSize(m_frame->width(), m_frame->height()));
+ img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio);
+ m_videoSurface.setPixmap(img);
+ QWidget::resizeEvent(event);
+}
+
void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char *data, const QString &info)
{
QImage::Format dstFmt;
@@ -41,6 +55,8 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char *
if (m_frame->width() != width || m_frame->height() != height || m_frame->format() != dstFmt) {
delete m_frame;
m_frame = new QImage(width, height, dstFmt);
+ m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()),
+ QSize(m_frame->width(), m_frame->height()));
}
if (data == NULL || !supported)
@@ -49,7 +65,11 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char *
memcpy(m_frame->bits(), data, m_frame->numBytes());
m_information.setText(info);
- m_videoSurface.setPixmap(QPixmap::fromImage(*m_frame));
+
+ QPixmap img = QPixmap::fromImage(*m_frame);
+ img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio);
+
+ m_videoSurface.setPixmap(img);
}
bool CaptureWinQt::hasNativeFormat(__u32 format)
diff --git a/utils/qv4l2/capture-win-qt.h b/utils/qv4l2/capture-win-qt.h
index d192045..6029109 100644
--- a/utils/qv4l2/capture-win-qt.h
+++ b/utils/qv4l2/capture-win-qt.h
@@ -25,6 +25,7 @@
#include <QLabel>
#include <QImage>
+#include <QResizeEvent>
class CaptureWinQt : public CaptureWin
{
@@ -39,10 +40,14 @@ public:
bool hasNativeFormat(__u32 format);
static bool isSupported() { return true; }
+protected:
+ void resizeEvent(QResizeEvent *event);
+
private:
bool findNativeFormat(__u32 format, QImage::Format &dstFmt);
QImage *m_frame;
QLabel m_videoSurface;
+ QSize m_scaledFrame;
};
#endif
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index e583900..4c5dd57 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -26,11 +26,18 @@
#include <QApplication>
#include <QDesktopWidget>
-CaptureWin::CaptureWin()
+#define MIN_WIN_SIZE_WIDTH 160
+#define MIN_WIN_SIZE_HEIGHT 120
+
+bool CaptureWin::m_enableScaling = true;
+
+CaptureWin::CaptureWin() :
+ m_curWidth(-1),
+ m_curHeight(-1)
{
setWindowTitle("V4L2 Capture");
m_hotkeyClose = new QShortcut(Qt::CTRL+Qt::Key_W, this);
- QObject::connect(m_hotkeyClose, SIGNAL(activated()), this, SLOT(close()));
+ connect(m_hotkeyClose, SIGNAL(activated()), this, SLOT(close()));
}
CaptureWin::~CaptureWin()
@@ -54,37 +61,88 @@ void CaptureWin::buildWindow(QWidget *videoSurface)
vbox->setSpacing(b);
}
+void CaptureWin::resetSize()
+{
+ int w = m_curWidth;
+ int h = m_curHeight;
+ m_curWidth = -1;
+ m_curHeight = -1;
+ resize(w, h);
+}
+
QSize CaptureWin::getMargins()
{
- int l, t, r, b;
- layout()->getContentsMargins(&l, &t, &r, &b);
+ int l, t, r, b;
+ layout()->getContentsMargins(&l, &t, &r, &b);
return QSize(l + r, t + b + m_information.minimumSizeHint().height() + layout()->spacing());
}
-void CaptureWin::setMinimumSize(int minw, int minh)
+void CaptureWin::enableScaling(bool enable)
{
+ if (!enable) {
+ QSize margins = getMargins();
+ QWidget::setMinimumSize(m_curWidth + margins.width(), m_curHeight + margins.height());
+ } else {
+ QWidget::setMinimumSize(MIN_WIN_SIZE_WIDTH, MIN_WIN_SIZE_HEIGHT);
+ }
+ m_enableScaling = enable;
+ QResizeEvent *event = new QResizeEvent(QSize(width(), height()), QSize(width(), height()));
+ QCoreApplication::sendEvent(this, event);
+ delete event;
+}
+
+void CaptureWin::resize(int width, int height)
+{
+ // Dont resize window if the frame size is the same in
+ // the event the window has been paused when beeing resized.
+ if (width == m_curWidth && height == m_curHeight)
+ return;
+
+ m_curWidth = width;
+ m_curHeight = height;
+
+ QSize margins = getMargins();
+ width += margins.width();
+ height += margins.height();
+
QDesktopWidget *screen = QApplication::desktop();
QRect resolution = screen->screenGeometry();
- QSize maxSize = maximumSize();
- QSize margins = getMargins();
- minw += margins.width();
- minh += margins.height();
-
- if (minw > resolution.width())
- minw = resolution.width();
- if (minw < 150)
- minw = 150;
-
- if (minh > resolution.height())
- minh = resolution.height();
- if (minh < 100)
- minh = 100;
-
- QWidget::setMinimumSize(minw, minh);
- QWidget::setMaximumSize(minw, minh);
- updateGeometry();
- QWidget::setMaximumSize(maxSize.width(), maxSize.height());
+ if (width > resolution.width())
+ width = resolution.width();
+ if (width < MIN_WIN_SIZE_WIDTH)
+ width = MIN_WIN_SIZE_WIDTH;
+
+ if (height > resolution.height())
+ height = resolution.height();
+ if (height < MIN_WIN_SIZE_HEIGHT)
+ height = MIN_WIN_SIZE_HEIGHT;
+
+ QWidget::setMinimumSize(MIN_WIN_SIZE_WIDTH, MIN_WIN_SIZE_HEIGHT);
+ QWidget::resize(width, height);
+}
+
+QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
+{
+ int actualFrameWidth = frame.width();;
+ int actualFrameHeight = frame.height();
+
+ if (!m_enableScaling) {
+ window.setWidth(frame.width());
+ window.setHeight(frame.height());
+ }
+
+ double newW, newH;
+ if (window.width() >= window.height()) {
+ newW = (double)window.width() / actualFrameWidth;
+ newH = (double)window.height() / actualFrameHeight;
+ } else {
+ newH = (double)window.width() / actualFrameWidth;
+ newW = (double)window.height() / actualFrameHeight;
+ }
+ double resized = std::min(newW, newH);
+
+ return QSize((int)(actualFrameWidth * resized), (int)(actualFrameHeight * resized));
}
void CaptureWin::closeEvent(QCloseEvent *event)
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index 6b72e00..eea0335 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -34,7 +34,7 @@ public:
CaptureWin();
~CaptureWin();
- void setMinimumSize(int minw, int minh);
+ void resize(int minw, int minh);
/**
* @brief Set a frame into the capture window.
@@ -75,12 +75,18 @@ public:
*/
static bool isSupported() { return false; }
+ void enableScaling(bool enable);
+ static QSize scaleFrameSize(QSize window, QSize frame);
+
+public slots:
+ void resetSize();
+
protected:
void closeEvent(QCloseEvent *event);
void buildWindow(QWidget *videoSurface);
+ static int actualFrameWidth(int width);
QSize getMargins();
-
/**
* @brief A label that can is used to display capture information.
*
@@ -88,11 +94,17 @@ protected:
*/
QLabel m_information;
+ /**
+ * @brief Determines if scaling is to be applied to video frame.
+ */
+ static bool m_enableScaling;
+
signals:
void close();
private:
QShortcut *m_hotkeyClose;
-
+ int m_curWidth;
+ int m_curHeight;
};
#endif
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index fa1425d..6b64892 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -137,9 +137,20 @@ ApplicationWindow::ApplicationWindow() :
toolBar->addSeparator();
toolBar->addAction(quitAct);
+ m_scalingAct = new QAction("Enable Video Scaling", this);
+ m_scalingAct->setStatusTip("Scale video frames to match window size if set");
+ m_scalingAct->setCheckable(true);
+ m_scalingAct->setChecked(true);
+ connect(m_scalingAct, SIGNAL(toggled(bool)), this, SLOT(enableScaling(bool)));
+ m_resetScalingAct = new QAction("Resize to Frame Size", this);
+ m_resetScalingAct->setStatusTip("Resizes the capture window to match frame size");
+
QMenu *captureMenu = menuBar()->addMenu("&Capture");
captureMenu->addAction(m_capStartAct);
captureMenu->addAction(m_showFramesAct);
+ captureMenu->addAction(m_scalingAct);
+ captureMenu->addAction(m_resetScalingAct);
+
if (CaptureWinGL::isSupported()) {
m_renderMethod = QV4L2_RENDER_GL;
@@ -351,7 +362,9 @@ void ApplicationWindow::newCaptureWin()
break;
}
- connect(m_capture, SIGNAL(close()), this, SLOT(closeCaptureWin()));
+ m_capture->enableScaling(m_scalingAct->isChecked());
+ connect(m_capture, SIGNAL(close()), this, SLOT(closeCaptureWin()));
+ connect(m_resetScalingAct, SIGNAL(triggered()), m_capture, SLOT(resetSize()));
}
void ApplicationWindow::capVbiFrame()
@@ -793,6 +806,12 @@ void ApplicationWindow::stopOutput()
{
}
+void ApplicationWindow::enableScaling(bool enable)
+{
+ if (m_capture != NULL)
+ m_capture->enableScaling(enable);
+}
+
void ApplicationWindow::startAudio()
{
#ifdef ENABLE_ALSA
@@ -903,7 +922,7 @@ void ApplicationWindow::capStart(bool start)
m_vbiHeight = fmt.fmt.vbi.count[0] + fmt.fmt.vbi.count[1];
m_vbiSize = m_vbiWidth * m_vbiHeight;
m_frameData = new unsigned char[m_vbiSize];
- m_capture->setMinimumSize(m_vbiWidth, m_vbiHeight);
+ m_capture->resize(m_vbiWidth, m_vbiHeight);
m_capImage = new QImage(m_vbiWidth, m_vbiHeight, dstFmt);
m_capImage->fill(0);
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
@@ -933,8 +952,8 @@ void ApplicationWindow::capStart(bool start)
m_mustConvert = false;
} else {
m_mustConvert = true;
+
v4l2_format copy = m_capSrcFormat;
-
v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat);
// v4lconvert_try_format sometimes modifies the source format if it thinks
// that there is a better format available. Restore our selected source
@@ -942,7 +961,7 @@ void ApplicationWindow::capStart(bool start)
m_capSrcFormat = copy;
}
- m_capture->setMinimumSize(dstPix.width, dstPix.height);
+ m_capture->resize(dstPix.width, dstPix.height);
m_capImage = new QImage(dstPix.width, dstPix.height, dstFmt);
m_capImage->fill(0);
if (showFrames()) {
diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h
index 92d6f25..3704ab1 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -130,6 +130,8 @@ private slots:
void openRawFile(const QString &s);
void rejectedRawFile();
void setAudioBufferSize();
+ void enableScaling(bool enable);
+
void about();
@@ -183,6 +185,8 @@ private:
QAction *m_useGLAct;
QAction *m_showAllAudioAct;
QAction *m_audioBufferAct;
+ QAction *m_scalingAct;
+ QAction *m_resetScalingAct;
QString m_filename;
QSignalMapper *m_sigMapper;
QTabWidget *m_tabs;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC PATCH 6/7] qv4l2: add hotkey for reset scaling to frame size
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
` (3 preceding siblings ...)
2013-08-05 8:56 ` [RFC PATCH 5/7] qv4l2: add video scaling for CaptureWin Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 8:56 ` [RFC PATCH 7/7] qv4l2: add aspect ratio support Bård Eirik Winther
5 siblings, 0 replies; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Adds hotkey CTRL + F for both CaptureWin and main Capture menu.
Resets the scaling of CaptureWin to fit frame size.
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win.cpp | 3 +++
utils/qv4l2/capture-win.h | 1 +
utils/qv4l2/qv4l2.cpp | 1 +
3 files changed, 5 insertions(+)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 4c5dd57..435c19b 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -38,6 +38,8 @@ CaptureWin::CaptureWin() :
setWindowTitle("V4L2 Capture");
m_hotkeyClose = new QShortcut(Qt::CTRL+Qt::Key_W, this);
connect(m_hotkeyClose, SIGNAL(activated()), this, SLOT(close()));
+ m_hotkeyScaleReset = new QShortcut(Qt::CTRL+Qt::Key_F, this);
+ connect(m_hotkeyScaleReset, SIGNAL(activated()), this, SLOT(resetSize()));
}
CaptureWin::~CaptureWin()
@@ -48,6 +50,7 @@ CaptureWin::~CaptureWin()
layout()->removeWidget(this);
delete layout();
delete m_hotkeyClose;
+ delete m_hotkeyScaleReset;
}
void CaptureWin::buildWindow(QWidget *videoSurface)
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index eea0335..1bfb1e1 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -104,6 +104,7 @@ signals:
private:
QShortcut *m_hotkeyClose;
+ QShortcut *m_hotkeyScaleReset;
int m_curWidth;
int m_curHeight;
};
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 6b64892..92a415f 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -144,6 +144,7 @@ ApplicationWindow::ApplicationWindow() :
connect(m_scalingAct, SIGNAL(toggled(bool)), this, SLOT(enableScaling(bool)));
m_resetScalingAct = new QAction("Resize to Frame Size", this);
m_resetScalingAct->setStatusTip("Resizes the capture window to match frame size");
+ m_resetScalingAct->setShortcut(Qt::CTRL+Qt::Key_F);
QMenu *captureMenu = menuBar()->addMenu("&Capture");
captureMenu->addAction(m_capStartAct);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC PATCH 7/7] qv4l2: add aspect ratio support
2013-08-05 8:56 ` [RFC PATCH 1/7] qv4l2: fix YUY2 shader Bård Eirik Winther
` (4 preceding siblings ...)
2013-08-05 8:56 ` [RFC PATCH 6/7] qv4l2: add hotkey for reset scaling to frame size Bård Eirik Winther
@ 2013-08-05 8:56 ` Bård Eirik Winther
2013-08-05 9:31 ` Hans Verkuil
5 siblings, 1 reply; 9+ messages in thread
From: Bård Eirik Winther @ 2013-08-05 8:56 UTC (permalink / raw)
To: linux-media
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win.cpp | 24 ++++++++++++++++++++++--
utils/qv4l2/capture-win.h | 8 +++++++-
utils/qv4l2/general-tab.cpp | 36 ++++++++++++++++++++++++++++++++++++
utils/qv4l2/general-tab.h | 3 +++
utils/qv4l2/qv4l2.cpp | 22 +++++++++++++++-------
utils/qv4l2/qv4l2.h | 2 +-
6 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 435c19b..415829a 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -30,6 +30,7 @@
#define MIN_WIN_SIZE_HEIGHT 120
bool CaptureWin::m_enableScaling = true;
+double CaptureWin::m_pixelAspectRatio = 1.0;
CaptureWin::CaptureWin() :
m_curWidth(-1),
@@ -73,6 +74,14 @@ void CaptureWin::resetSize()
resize(w, h);
}
+int CaptureWin::actualFrameWidth(int width)
+{
+ if (m_enableScaling)
+ return (int)((double)width * m_pixelAspectRatio);
+ else
+ return width;
+}
+
QSize CaptureWin::getMargins()
{
int l, t, r, b;
@@ -94,6 +103,14 @@ void CaptureWin::enableScaling(bool enable)
delete event;
}
+void CaptureWin::setPixelAspectRatio(double ratio)
+{
+ m_pixelAspectRatio = ratio;
+ QResizeEvent *event = new QResizeEvent(QSize(width(), height()), QSize(width(), height()));
+ QCoreApplication::sendEvent(this, event);
+ delete event;
+}
+
void CaptureWin::resize(int width, int height)
{
// Dont resize window if the frame size is the same in
@@ -105,7 +122,7 @@ void CaptureWin::resize(int width, int height)
m_curHeight = height;
QSize margins = getMargins();
- width += margins.width();
+ width = actualFrameWidth(width) + margins.width();
height += margins.height();
QDesktopWidget *screen = QApplication::desktop();
@@ -127,12 +144,15 @@ void CaptureWin::resize(int width, int height)
QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
{
- int actualFrameWidth = frame.width();;
+ int actualFrameWidth;
int actualFrameHeight = frame.height();
if (!m_enableScaling) {
window.setWidth(frame.width());
window.setHeight(frame.height());
+ actualFrameWidth = frame.width();
+ } else {
+ actualFrameWidth = CaptureWin::actualFrameWidth(frame.width());
}
double newW, newH;
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index 1bfb1e1..eded9e0 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -76,9 +76,10 @@ public:
static bool isSupported() { return false; }
void enableScaling(bool enable);
+ void setPixelAspectRatio(double ratio);
static QSize scaleFrameSize(QSize window, QSize frame);
-public slots:
+ public slots:
void resetSize();
protected:
@@ -99,6 +100,11 @@ protected:
*/
static bool m_enableScaling;
+ /**
+ * @note Aspect ratio it taken care of by scaling, frame size is for square pixels only!
+ */
+ static double m_pixelAspectRatio;
+
signals:
void close();
diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp
index 5996c03..53b7e36 100644
--- a/utils/qv4l2/general-tab.cpp
+++ b/utils/qv4l2/general-tab.cpp
@@ -53,6 +53,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
m_tvStandard(NULL),
m_qryStandard(NULL),
m_videoTimings(NULL),
+ m_pixelAspectRatio(NULL),
m_qryTimings(NULL),
m_freq(NULL),
m_vidCapFormats(NULL),
@@ -210,6 +211,20 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
connect(m_qryTimings, SIGNAL(clicked()), SLOT(qryTimingsClicked()));
}
+ if (!isRadio() && !isVbi()) {
+ m_pixelAspectRatio = new QComboBox(parent);
+ m_pixelAspectRatio->addItem("Autodetect");
+ m_pixelAspectRatio->addItem("Square");
+ m_pixelAspectRatio->addItem("NTSC/PAL-M/PAL-60");
+ m_pixelAspectRatio->addItem("NTSC/PAL-M/PAL-60, Anamorphic");
+ m_pixelAspectRatio->addItem("PAL/SECAM");
+ m_pixelAspectRatio->addItem("PAL/SECAM, Anamorphic");
+
+ addLabel("Pixel Aspect Ratio");
+ addWidget(m_pixelAspectRatio);
+ connect(m_pixelAspectRatio, SIGNAL(activated(int)), SIGNAL(pixelAspectRatioChanged()));
+ }
+
if (m_tuner.capability) {
QDoubleValidator *val;
double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
@@ -1105,6 +1120,27 @@ void GeneralTab::updateFrameSize()
updateFrameInterval();
}
+double GeneralTab::getPixelAspectRatio()
+{
+ if (m_pixelAspectRatio->currentText().compare("Autodetect") == 0) {
+ v4l2_cropcap ratio;
+ ratio.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (ioctl(VIDIOC_CROPCAP, &ratio) < 0)
+ return 1.0;
+
+ return (double)ratio.pixelaspect.denominator / ratio.pixelaspect.numerator;
+ }
+ if (m_pixelAspectRatio->currentText().compare("NTSC/PAL-M/PAL-60") == 0)
+ return 10.0/11.0;
+ if (m_pixelAspectRatio->currentText().compare("NTSC/PAL-M/PAL-60, Anamorphic") == 0)
+ return 40.0/33.0;
+ if (m_pixelAspectRatio->currentText().compare("PAL/SECAM") == 0)
+ return 12.0/11.0;
+ if (m_pixelAspectRatio->currentText().compare("PAL/SECAM, Anamorphic") == 0)
+ return 16.0/11.0;
+ return 1.0;
+}
+
void GeneralTab::updateFrameInterval()
{
v4l2_frmivalenum frmival;
diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h
index c83368a..73e7a88 100644
--- a/utils/qv4l2/general-tab.h
+++ b/utils/qv4l2/general-tab.h
@@ -55,6 +55,7 @@ public:
void setAudioDeviceBufferSize(int size);
int getAudioDeviceBufferSize();
bool hasAlsaAudio();
+ double getPixelAspectRatio();
bool get_interval(struct v4l2_fract &interval);
int width() const { return m_width; }
int height() const { return m_height; }
@@ -88,6 +89,7 @@ public slots:
signals:
void audioDeviceChanged();
+ void pixelAspectRatioChanged();
private slots:
void inputChanged(int);
@@ -180,6 +182,7 @@ private:
QComboBox *m_tvStandard;
QPushButton *m_qryStandard;
QComboBox *m_videoTimings;
+ QComboBox *m_pixelAspectRatio;
QPushButton *m_qryTimings;
QLineEdit *m_freq;
QComboBox *m_freqTable;
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 92a415f..0ce3cd7 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -103,7 +103,7 @@ ApplicationWindow::ApplicationWindow() :
m_saveRawAct->setChecked(false);
connect(m_saveRawAct, SIGNAL(toggled(bool)), this, SLOT(saveRaw(bool)));
- m_showFramesAct = new QAction(QIcon(":/video-television.png"), "Show &Frames", this);
+ m_showFramesAct = new QAction(QIcon(":/video-television.png"), "&Show Frames", this);
m_showFramesAct->setStatusTip("Only show captured frames if set.");
m_showFramesAct->setCheckable(true);
m_showFramesAct->setChecked(true);
@@ -137,12 +137,12 @@ ApplicationWindow::ApplicationWindow() :
toolBar->addSeparator();
toolBar->addAction(quitAct);
- m_scalingAct = new QAction("Enable Video Scaling", this);
+ m_scalingAct = new QAction("&Enable Video Scaling", this);
m_scalingAct->setStatusTip("Scale video frames to match window size if set");
m_scalingAct->setCheckable(true);
m_scalingAct->setChecked(true);
connect(m_scalingAct, SIGNAL(toggled(bool)), this, SLOT(enableScaling(bool)));
- m_resetScalingAct = new QAction("Resize to Frame Size", this);
+ m_resetScalingAct = new QAction("Resize to &Frame Size", this);
m_resetScalingAct->setStatusTip("Resizes the capture window to match frame size");
m_resetScalingAct->setShortcut(Qt::CTRL+Qt::Key_F);
@@ -169,13 +169,13 @@ ApplicationWindow::ApplicationWindow() :
#ifdef ENABLE_ALSA
captureMenu->addSeparator();
- m_showAllAudioAct = new QAction("Show All Audio Devices", this);
+ m_showAllAudioAct = new QAction("Show All Audio &Devices", this);
m_showAllAudioAct->setStatusTip("Show all audio input and output devices if set");
m_showAllAudioAct->setCheckable(true);
m_showAllAudioAct->setChecked(false);
captureMenu->addAction(m_showAllAudioAct);
- m_audioBufferAct = new QAction("Set Audio Buffer Size...", this);
+ m_audioBufferAct = new QAction("Set Audio &Buffer Size...", this);
m_audioBufferAct->setStatusTip("Set audio buffer capacity in amout of ms than can be stored");
connect(m_audioBufferAct, SIGNAL(triggered()), this, SLOT(setAudioBufferSize()));
captureMenu->addAction(m_audioBufferAct);
@@ -216,8 +216,6 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
newCaptureWin();
- m_capture->setMinimumSize(150, 50);
-
QWidget *w = new QWidget(m_tabs);
m_genTab = new GeneralTab(device, *this, 4, w);
@@ -233,6 +231,7 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
}
#endif
+ connect(m_genTab, SIGNAL(pixelAspectRatioChanged()), this, SLOT(updatePixelAspectRatio()));
m_tabs->addTab(w, "General");
addTabs();
if (caps() & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)) {
@@ -363,6 +362,7 @@ void ApplicationWindow::newCaptureWin()
break;
}
+ m_capture->setPixelAspectRatio(1.0);
m_capture->enableScaling(m_scalingAct->isChecked());
connect(m_capture, SIGNAL(close()), this, SLOT(closeCaptureWin()));
connect(m_resetScalingAct, SIGNAL(triggered()), m_capture, SLOT(resetSize()));
@@ -813,6 +813,12 @@ void ApplicationWindow::enableScaling(bool enable)
m_capture->enableScaling(enable);
}
+void ApplicationWindow::updatePixelAspectRatio()
+{
+ if (m_capture != NULL && m_genTab != NULL)
+ m_capture->setPixelAspectRatio(m_genTab->getPixelAspectRatio());
+}
+
void ApplicationWindow::startAudio()
{
#ifdef ENABLE_ALSA
@@ -894,6 +900,7 @@ void ApplicationWindow::capStart(bool start)
m_vbiTab->slicedFormat(fmt.fmt.sliced);
m_vbiSize = fmt.fmt.sliced.io_size;
m_frameData = new unsigned char[m_vbiSize];
+ updatePixelAspectRatio();
if (startCapture(m_vbiSize)) {
m_capNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, m_tabs);
connect(m_capNotifier, SIGNAL(activated(int)), this, SLOT(capVbiFrame()));
@@ -962,6 +969,7 @@ void ApplicationWindow::capStart(bool start)
m_capSrcFormat = copy;
}
+ updatePixelAspectRatio();
m_capture->resize(dstPix.width, dstPix.height);
m_capImage = new QImage(dstPix.width, dstPix.height, dstFmt);
m_capImage->fill(0);
diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h
index 3704ab1..859113a 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -131,7 +131,7 @@ private slots:
void rejectedRawFile();
void setAudioBufferSize();
void enableScaling(bool enable);
-
+ void updatePixelAspectRatio();
void about();
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [RFC PATCH 7/7] qv4l2: add aspect ratio support
2013-08-05 8:56 ` [RFC PATCH 7/7] qv4l2: add aspect ratio support Bård Eirik Winther
@ 2013-08-05 9:31 ` Hans Verkuil
0 siblings, 0 replies; 9+ messages in thread
From: Hans Verkuil @ 2013-08-05 9:31 UTC (permalink / raw)
To: Bård Eirik Winther; +Cc: linux-media
Hi Bård,
Some comments below...
On 08/05/2013 10:56 AM, Bård Eirik Winther wrote:
> Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
> ---
> utils/qv4l2/capture-win.cpp | 24 ++++++++++++++++++++++--
> utils/qv4l2/capture-win.h | 8 +++++++-
> utils/qv4l2/general-tab.cpp | 36 ++++++++++++++++++++++++++++++++++++
> utils/qv4l2/general-tab.h | 3 +++
> utils/qv4l2/qv4l2.cpp | 22 +++++++++++++++-------
> utils/qv4l2/qv4l2.h | 2 +-
> 6 files changed, 84 insertions(+), 11 deletions(-)
>
> diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
> index 435c19b..415829a 100644
> --- a/utils/qv4l2/capture-win.cpp
> +++ b/utils/qv4l2/capture-win.cpp
> @@ -30,6 +30,7 @@
> #define MIN_WIN_SIZE_HEIGHT 120
>
> bool CaptureWin::m_enableScaling = true;
> +double CaptureWin::m_pixelAspectRatio = 1.0;
>
> CaptureWin::CaptureWin() :
> m_curWidth(-1),
> @@ -73,6 +74,14 @@ void CaptureWin::resetSize()
> resize(w, h);
> }
>
> +int CaptureWin::actualFrameWidth(int width)
> +{
> + if (m_enableScaling)
> + return (int)((double)width * m_pixelAspectRatio);
> + else
No need for the 'else' statement.
> + return width;
> +}
> +
> QSize CaptureWin::getMargins()
> {
> int l, t, r, b;
> @@ -94,6 +103,14 @@ void CaptureWin::enableScaling(bool enable)
> delete event;
> }
>
> +void CaptureWin::setPixelAspectRatio(double ratio)
> +{
> + m_pixelAspectRatio = ratio;
> + QResizeEvent *event = new QResizeEvent(QSize(width(), height()), QSize(width(), height()));
> + QCoreApplication::sendEvent(this, event);
> + delete event;
> +}
> +
> void CaptureWin::resize(int width, int height)
> {
> // Dont resize window if the frame size is the same in
> @@ -105,7 +122,7 @@ void CaptureWin::resize(int width, int height)
> m_curHeight = height;
>
> QSize margins = getMargins();
> - width += margins.width();
> + width = actualFrameWidth(width) + margins.width();
> height += margins.height();
>
> QDesktopWidget *screen = QApplication::desktop();
> @@ -127,12 +144,15 @@ void CaptureWin::resize(int width, int height)
>
> QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
> {
> - int actualFrameWidth = frame.width();;
> + int actualFrameWidth;
> int actualFrameHeight = frame.height();
>
> if (!m_enableScaling) {
> window.setWidth(frame.width());
> window.setHeight(frame.height());
> + actualFrameWidth = frame.width();
> + } else {
> + actualFrameWidth = CaptureWin::actualFrameWidth(frame.width());
> }
>
> double newW, newH;
> diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
> index 1bfb1e1..eded9e0 100644
> --- a/utils/qv4l2/capture-win.h
> +++ b/utils/qv4l2/capture-win.h
> @@ -76,9 +76,10 @@ public:
> static bool isSupported() { return false; }
>
> void enableScaling(bool enable);
> + void setPixelAspectRatio(double ratio);
> static QSize scaleFrameSize(QSize window, QSize frame);
>
> -public slots:
> + public slots:
> void resetSize();
>
> protected:
> @@ -99,6 +100,11 @@ protected:
> */
> static bool m_enableScaling;
>
> + /**
> + * @note Aspect ratio it taken care of by scaling, frame size is for square pixels only!
> + */
> + static double m_pixelAspectRatio;
> +
> signals:
> void close();
>
> diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp
> index 5996c03..53b7e36 100644
> --- a/utils/qv4l2/general-tab.cpp
> +++ b/utils/qv4l2/general-tab.cpp
> @@ -53,6 +53,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
> m_tvStandard(NULL),
> m_qryStandard(NULL),
> m_videoTimings(NULL),
> + m_pixelAspectRatio(NULL),
> m_qryTimings(NULL),
> m_freq(NULL),
> m_vidCapFormats(NULL),
> @@ -210,6 +211,20 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent)
> connect(m_qryTimings, SIGNAL(clicked()), SLOT(qryTimingsClicked()));
> }
>
> + if (!isRadio() && !isVbi()) {
> + m_pixelAspectRatio = new QComboBox(parent);
> + m_pixelAspectRatio->addItem("Autodetect");
> + m_pixelAspectRatio->addItem("Square");
> + m_pixelAspectRatio->addItem("NTSC/PAL-M/PAL-60");
> + m_pixelAspectRatio->addItem("NTSC/PAL-M/PAL-60, Anamorphic");
> + m_pixelAspectRatio->addItem("PAL/SECAM");
> + m_pixelAspectRatio->addItem("PAL/SECAM, Anamorphic");
> +
> + addLabel("Pixel Aspect Ratio");
> + addWidget(m_pixelAspectRatio);
> + connect(m_pixelAspectRatio, SIGNAL(activated(int)), SIGNAL(pixelAspectRatioChanged()));
> + }
> +
> if (m_tuner.capability) {
> QDoubleValidator *val;
> double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
> @@ -1105,6 +1120,27 @@ void GeneralTab::updateFrameSize()
> updateFrameInterval();
> }
>
> +double GeneralTab::getPixelAspectRatio()
> +{
> + if (m_pixelAspectRatio->currentText().compare("Autodetect") == 0) {
> + v4l2_cropcap ratio;
> + ratio.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> + if (ioctl(VIDIOC_CROPCAP, &ratio) < 0)
> + return 1.0;
> +
> + return (double)ratio.pixelaspect.denominator / ratio.pixelaspect.numerator;
> + }
> + if (m_pixelAspectRatio->currentText().compare("NTSC/PAL-M/PAL-60") == 0)
> + return 10.0/11.0;
> + if (m_pixelAspectRatio->currentText().compare("NTSC/PAL-M/PAL-60, Anamorphic") == 0)
> + return 40.0/33.0;
> + if (m_pixelAspectRatio->currentText().compare("PAL/SECAM") == 0)
> + return 12.0/11.0;
> + if (m_pixelAspectRatio->currentText().compare("PAL/SECAM, Anamorphic") == 0)
> + return 16.0/11.0;
These string compares are flaky: if someone changes the string in the GUI, then it is
all too easy to forget about changing this.
Take a look at how the audio mode (m_audioMode) is handled. You should do something
similar.
> + return 1.0;
> +}
> +
Regards,
Hans
^ permalink raw reply [flat|nested] 9+ messages in thread