* [PATCH 2/9] qv4l2: fix YUY2 shader
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 3/9] qv4l2: fix black screen with opengl after capture Bård Eirik Winther
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 UTC (permalink / raw)
To: linux-media
Fixed the YUY2 shaders to support scaling.
The new solution has cleaner shader code and texture upload
uses a better format for OpenGL.
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win-gl.cpp | 68 ++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 33 deletions(-)
diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp
index c499f1f..6071410 100644
--- a/utils/qv4l2/capture-win-gl.cpp
+++ b/utils/qv4l2/capture-win-gl.cpp
@@ -1,5 +1,5 @@
/*
- * The YUY2 shader code was copied and simplified from face-responder. The code is under public domain:
+ * The YUY2 shader code is based on face-responder. The code is under public domain:
* https://bitbucket.org/nateharward/face-responder/src/0c3b4b957039d9f4bf1da09b9471371942de2601/yuv42201_laplace.frag?at=master
*
* All other OpenGL code:
@@ -446,47 +446,51 @@ QString CaptureWinGLEngine::shader_YUY2_invariant(__u32 format)
{
switch (format) {
case V4L2_PIX_FMT_YUYV:
- return QString("y = (luma_chroma.r - 0.0625) * 1.1643;"
- "if (mod(xcoord, 2.0) == 0.0) {"
- " u = luma_chroma.a;"
- " v = texture2D(tex, vec2(pixelx + texl_w, pixely)).a;"
+ return QString("if (mod(xcoord, 2.0) == 0.0) {"
+ " luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+ " y = (luma_chroma.r - 0.0625) * 1.1643;"
"} else {"
- " v = luma_chroma.a;"
- " u = texture2D(tex, vec2(pixelx - texl_w, pixely)).a;"
+ " luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+ " y = (luma_chroma.b - 0.0625) * 1.1643;"
"}"
+ "u = luma_chroma.g - 0.5;"
+ "v = luma_chroma.a - 0.5;"
);
case V4L2_PIX_FMT_YVYU:
- return QString("y = (luma_chroma.r - 0.0625) * 1.1643;"
- "if (mod(xcoord, 2.0) == 0.0) {"
- " v = luma_chroma.a;"
- " u = texture2D(tex, vec2(pixelx + texl_w, pixely)).a;"
+ return QString("if (mod(xcoord, 2.0) == 0.0) {"
+ " luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+ " y = (luma_chroma.r - 0.0625) * 1.1643;"
"} else {"
- " u = luma_chroma.a;"
- " v = texture2D(tex, vec2(pixelx - texl_w, pixely)).a;"
+ " luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+ " y = (luma_chroma.b - 0.0625) * 1.1643;"
"}"
+ "u = luma_chroma.a - 0.5;"
+ "v = luma_chroma.g - 0.5;"
);
case V4L2_PIX_FMT_UYVY:
- return QString("y = (luma_chroma.a - 0.0625) * 1.1643;"
- "if (mod(xcoord, 2.0) == 0.0) {"
- " u = luma_chroma.r;"
- " v = texture2D(tex, vec2(pixelx + texl_w, pixely)).r;"
+ return QString("if (mod(xcoord, 2.0) == 0.0) {"
+ " luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+ " y = (luma_chroma.g - 0.0625) * 1.1643;"
"} else {"
- " v = luma_chroma.r;"
- " u = texture2D(tex, vec2(pixelx - texl_w, pixely)).r;"
+ " luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+ " y = (luma_chroma.a - 0.0625) * 1.1643;"
"}"
+ "u = luma_chroma.r - 0.5;"
+ "v = luma_chroma.b - 0.5;"
);
case V4L2_PIX_FMT_VYUY:
- return QString("y = (luma_chroma.a - 0.0625) * 1.1643;"
- "if (mod(xcoord, 2.0) == 0.0) {"
- " v = luma_chroma.r;"
- " u = texture2D(tex, vec2(pixelx + texl_w, pixely)).r;"
+ return QString("if (mod(xcoord, 2.0) == 0.0) {"
+ " luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+ " y = (luma_chroma.g - 0.0625) * 1.1643;"
"} else {"
- " u = luma_chroma.r;"
- " v = texture2D(tex, vec2(pixelx - texl_w, pixely)).r;"
+ " luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+ " y = (luma_chroma.a - 0.0625) * 1.1643;"
"}"
+ "u = luma_chroma.b - 0.5;"
+ "v = luma_chroma.r - 0.5;"
);
default:
@@ -499,8 +503,8 @@ void CaptureWinGLEngine::shader_YUY2(__u32 format)
m_screenTextureCount = 1;
glGenTextures(m_screenTextureCount, m_screenTexture);
configureTexture(0);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, m_frameWidth, m_frameHeight, 0,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_frameWidth / 2, m_frameHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkError("YUY2 shader");
QString codeHead = QString("uniform sampler2D tex;"
@@ -509,17 +513,15 @@ void CaptureWinGLEngine::shader_YUY2(__u32 format)
"void main()"
"{"
" float y, u, v;"
+ " vec4 luma_chroma;"
" float pixelx = gl_TexCoord[0].x;"
" float pixely = gl_TexCoord[0].y;"
" float xcoord = floor(pixelx * tex_w);"
- " vec4 luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
);
QString codeBody = shader_YUY2_invariant(format);
- QString codeTail = QString(" u = u - 0.5;"
- " v = v - 0.5;"
- " float r = y + 1.5958 * v;"
+ QString codeTail = QString(" float r = y + 1.5958 * v;"
" float g = y - 0.39173 * u - 0.81290 * v;"
" float b = y + 2.017 * u;"
" gl_FragColor = vec4(r, g, b, 1.0);"
@@ -548,8 +550,8 @@ void CaptureWinGLEngine::render_YUY2()
glBindTexture(GL_TEXTURE_2D, m_screenTexture[0]);
GLint Y = m_glfunction.glGetUniformLocation(m_shaderProgram.programId(), "tex");
glUniform1i(Y, 0);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_frameWidth, m_frameHeight,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_frameData);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_frameWidth / 2, m_frameHeight,
+ GL_RGBA, GL_UNSIGNED_BYTE, m_frameData);
checkError("YUY2 paint");
}
#endif
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/9] qv4l2: fix black screen with opengl after capture
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 2/9] qv4l2: fix YUY2 shader Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 4/9] qv4l2: show frames option can be toggled during capture Bård Eirik Winther
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 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 6071410..c8238c5 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] 10+ messages in thread* [PATCH 4/9] qv4l2: show frames option can be toggled during capture
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 2/9] qv4l2: fix YUY2 shader Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 3/9] qv4l2: fix black screen with opengl after capture Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 5/9] qv4l2: create function getMargins Bård Eirik Winther
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 UTC (permalink / raw)
To: linux-media
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/qv4l2.cpp | 79 +++++++++++++++++++++++++++------------------------
utils/qv4l2/qv4l2.h | 2 +-
2 files changed, 43 insertions(+), 38 deletions(-)
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 5510041..ee0c22d 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);
@@ -491,7 +491,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,
@@ -515,7 +515,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,
@@ -590,10 +590,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);
@@ -776,6 +776,15 @@ void ApplicationWindow::stopCapture()
refresh();
}
+bool ApplicationWindow::showFrames()
+{
+ if (m_showFramesAct->isChecked() && !m_capture->isVisible())
+ m_capture->show();
+ if (!m_showFramesAct->isChecked() && m_capture->isVisible())
+ m_capture->hide();
+ return m_showFramesAct->isChecked();
+}
+
void ApplicationWindow::startOutput(unsigned)
{
}
@@ -849,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();
@@ -857,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) ?
@@ -896,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);
@@ -917,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 511a652..dd9db44 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -174,6 +174,7 @@ private:
void updateStandard();
void updateFreq();
void updateFreqChannel();
+ bool showFrames();
GeneralTab *m_genTab;
VbiTab *m_vbiTab;
@@ -195,7 +196,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] 10+ messages in thread* [PATCH 5/9] qv4l2: create function getMargins
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
` (2 preceding siblings ...)
2013-08-06 10:21 ` [PATCH 4/9] qv4l2: show frames option can be toggled during capture Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 6/9] qv4l2: add video scaling for CaptureWin Bård Eirik Winther
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 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 | 1 +
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 2d57909..8722066 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..f662bd3 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -78,6 +78,7 @@ 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] 10+ messages in thread* [PATCH 6/9] qv4l2: add video scaling for CaptureWin
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
` (3 preceding siblings ...)
2013-08-06 10:21 ` [PATCH 5/9] qv4l2: create function getMargins Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 7/9] qv4l2: added resize to frame size in Capture menu Bård Eirik Winther
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 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 | 7 ++++
utils/qv4l2/capture-win-qt.cpp | 23 ++++++++++-
utils/qv4l2/capture-win-qt.h | 5 +++
utils/qv4l2/capture-win.cpp | 93 ++++++++++++++++++++++++++++++++----------
utils/qv4l2/capture-win.h | 14 ++++++-
utils/qv4l2/qv4l2.cpp | 22 ++++++++--
utils/qv4l2/qv4l2.h | 2 +
8 files changed, 159 insertions(+), 33 deletions(-)
diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp
index c8238c5..27ff3d3 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)
+{
+#ifdef HAVE_QTGL
+ QSize margins = getMargins();
+ 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 HAVE_QTGL
@@ -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 6e64269..0c3ff8b 100644
--- a/utils/qv4l2/capture-win-gl.h
+++ b/utils/qv4l2/capture-win-gl.h
@@ -23,6 +23,8 @@
#include "qv4l2.h"
#include "capture-win.h"
+#include <QResizeEvent>
+
#ifdef HAVE_QTGL
#define GL_GLEXT_PROTOTYPES
#include <QGLWidget>
@@ -42,6 +44,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();
@@ -90,6 +93,10 @@ public:
bool hasNativeFormat(__u32 format);
static bool isSupported();
+protected:
+ void resizeEvent(QResizeEvent *event);
+
+private:
#ifdef HAVE_QTGL
CaptureWinGLEngine m_videoSurface;
#endif
diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp
index 63c77d5..f746379 100644
--- a/utils/qv4l2/capture-win-qt.cpp
+++ b/utils/qv4l2/capture-win-qt.cpp
@@ -24,6 +24,8 @@ CaptureWinQt::CaptureWinQt() :
{
CaptureWin::buildWindow(&m_videoSurface);
+ m_scaledFrame.setWidth(0);
+ m_scaledFrame.setHeight(0);
}
CaptureWinQt::~CaptureWinQt()
@@ -31,6 +33,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 +56,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 +66,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 8722066..33f7084 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()
@@ -61,30 +68,72 @@ QSize CaptureWin::getMargins()
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 f662bd3..dd19f2d 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,9 +75,13 @@ public:
*/
static bool isSupported() { return false; }
+ void enableScaling(bool enable);
+ static QSize scaleFrameSize(QSize window, QSize frame);
+
protected:
void closeEvent(QCloseEvent *event);
void buildWindow(QWidget *videoSurface);
+ static int actualFrameWidth(int width);
QSize getMargins();
/**
@@ -87,11 +91,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 ee0c22d..50ba07a 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -137,9 +137,16 @@ 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)));
+
QMenu *captureMenu = menuBar()->addMenu("&Capture");
captureMenu->addAction(m_capStartAct);
captureMenu->addAction(m_showFramesAct);
+ captureMenu->addAction(m_scalingAct);
if (CaptureWinGL::isSupported()) {
m_renderMethod = QV4L2_RENDER_GL;
@@ -351,7 +358,8 @@ 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()));
}
void ApplicationWindow::capVbiFrame()
@@ -793,6 +801,12 @@ void ApplicationWindow::stopOutput()
{
}
+void ApplicationWindow::enableScaling(bool enable)
+{
+ if (m_capture != NULL)
+ m_capture->enableScaling(enable);
+}
+
void ApplicationWindow::startAudio()
{
#ifdef HAVE_ALSA
@@ -903,7 +917,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 +947,8 @@ void ApplicationWindow::capStart(bool start)
m_mustConvert = false;
} else {
m_mustConvert = true;
- v4l2_format copy = m_capSrcFormat;
+ 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 +956,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 dd9db44..1402673 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -132,6 +132,7 @@ private slots:
void openRawFile(const QString &s);
void rejectedRawFile();
void setAudioBufferSize();
+ void enableScaling(bool enable);
void about();
@@ -185,6 +186,7 @@ private:
QAction *m_useGLAct;
QAction *m_showAllAudioAct;
QAction *m_audioBufferAct;
+ QAction *m_scalingAct;
QString m_filename;
QSignalMapper *m_sigMapper;
QTabWidget *m_tabs;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/9] qv4l2: added resize to frame size in Capture menu
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
` (4 preceding siblings ...)
2013-08-06 10:21 ` [PATCH 6/9] qv4l2: add video scaling for CaptureWin Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 8/9] qv4l2: add hotkey for reset scaling to frame size Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 9/9] qv4l2: add pixel aspect ratio support for CaptureWin Bård Eirik Winther
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 UTC (permalink / raw)
To: linux-media
This will resize the CaptureWin to the original frame size.
It also works with maximized windows.
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win.cpp | 12 ++++++++++++
utils/qv4l2/capture-win.h | 3 +++
utils/qv4l2/qv4l2.cpp | 6 ++++--
utils/qv4l2/qv4l2.h | 1 +
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 33f7084..3bd6549 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -61,6 +61,18 @@ void CaptureWin::buildWindow(QWidget *videoSurface)
vbox->setSpacing(b);
}
+void CaptureWin::resetSize()
+{
+ if (isMaximized())
+ showNormal();
+
+ 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;
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index dd19f2d..eea0335 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -78,6 +78,9 @@ public:
void enableScaling(bool enable);
static QSize scaleFrameSize(QSize window, QSize frame);
+public slots:
+ void resetSize();
+
protected:
void closeEvent(QCloseEvent *event);
void buildWindow(QWidget *videoSurface);
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 50ba07a..1a476f0 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -142,11 +142,14 @@ ApplicationWindow::ApplicationWindow() :
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;
@@ -211,8 +214,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);
@@ -360,6 +361,7 @@ void ApplicationWindow::newCaptureWin()
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()
diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h
index 1402673..179cecb 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -187,6 +187,7 @@ private:
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] 10+ messages in thread* [PATCH 8/9] qv4l2: add hotkey for reset scaling to frame size
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
` (5 preceding siblings ...)
2013-08-06 10:21 ` [PATCH 7/9] qv4l2: added resize to frame size in Capture menu Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
2013-08-06 10:21 ` [PATCH 9/9] qv4l2: add pixel aspect ratio support for CaptureWin Bård Eirik Winther
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 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 3bd6549..3abb6cb 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 1a476f0..c94b0a8 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] 10+ messages in thread* [PATCH 9/9] qv4l2: add pixel aspect ratio support for CaptureWin
2013-08-06 10:21 ` [PATCH 1/9] qv4l2: generalized opengl include guards Bård Eirik Winther
` (6 preceding siblings ...)
2013-08-06 10:21 ` [PATCH 8/9] qv4l2: add hotkey for reset scaling to frame size Bård Eirik Winther
@ 2013-08-06 10:21 ` Bård Eirik Winther
7 siblings, 0 replies; 10+ messages in thread
From: Bård Eirik Winther @ 2013-08-06 10:21 UTC (permalink / raw)
To: linux-media
Signed-off-by: Bård Eirik Winther <bwinther@cisco.com>
---
utils/qv4l2/capture-win.cpp | 36 ++++++++++++++++++------
utils/qv4l2/capture-win.h | 6 ++++
utils/qv4l2/general-tab.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++
utils/qv4l2/general-tab.h | 4 +++
utils/qv4l2/qv4l2.cpp | 21 ++++++++++----
utils/qv4l2/qv4l2.h | 1 +
6 files changed, 122 insertions(+), 14 deletions(-)
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 3abb6cb..7538756 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),
@@ -76,6 +77,14 @@ void CaptureWin::resetSize()
resize(w, h);
}
+int CaptureWin::actualFrameWidth(int width)
+{
+ if (m_enableScaling)
+ return (int)((double)width * m_pixelAspectRatio);
+
+ return width;
+}
+
QSize CaptureWin::getMargins()
{
int l, t, r, b;
@@ -108,7 +117,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();
@@ -130,25 +139,36 @@ void CaptureWin::resize(int width, int height)
QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
{
- int actualFrameWidth = frame.width();;
- int actualFrameHeight = frame.height();
+ int actualWidth;
+ int actualHeight = frame.height();
if (!m_enableScaling) {
window.setWidth(frame.width());
window.setHeight(frame.height());
+ actualWidth = frame.width();
+ } else {
+ actualWidth = CaptureWin::actualFrameWidth(frame.width());
}
double newW, newH;
if (window.width() >= window.height()) {
- newW = (double)window.width() / actualFrameWidth;
- newH = (double)window.height() / actualFrameHeight;
+ newW = (double)window.width() / actualWidth;
+ newH = (double)window.height() / actualHeight;
} else {
- newH = (double)window.width() / actualFrameWidth;
- newW = (double)window.height() / actualFrameHeight;
+ newH = (double)window.width() / actualWidth;
+ newW = (double)window.height() / actualHeight;
}
double resized = std::min(newW, newH);
- return QSize((int)(actualFrameWidth * resized), (int)(actualFrameHeight * resized));
+ return QSize((int)(actualWidth * resized), (int)(actualHeight * resized));
+}
+
+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::closeEvent(QCloseEvent *event)
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index 1bfb1e1..e8f0ada 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -76,6 +76,7 @@ public:
static bool isSupported() { return false; }
void enableScaling(bool enable);
+ void setPixelAspectRatio(double ratio);
static QSize scaleFrameSize(QSize window, QSize frame);
public slots:
@@ -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 5cfaf07..c404a3b 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,23 @@ 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");
+
+ // Update hints by calling a get
+ getPixelAspectRatio();
+
+ addLabel("Pixel Aspect Ratio");
+ addWidget(m_pixelAspectRatio);
+ connect(m_pixelAspectRatio, SIGNAL(activated(int)), SLOT(changePixelAspectRatio()));
+ }
+
if (m_tuner.capability) {
QDoubleValidator *val;
double factor = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? 16 : 16000;
@@ -1105,6 +1123,56 @@ void GeneralTab::updateFrameSize()
updateFrameInterval();
}
+void GeneralTab::changePixelAspectRatio()
+{
+ // Update hints by calling a get
+ getPixelAspectRatio();
+ info("");
+ emit pixelAspectRatioChanged();
+}
+
+double GeneralTab::getPixelAspectRatio()
+{
+ switch (m_pixelAspectRatio->currentIndex()) {
+ case 0:
+ v4l2_cropcap ratio;
+ ratio.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (ioctl(VIDIOC_CROPCAP, &ratio) < 0) {
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 1:1");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 1:1");
+ return 1.0;
+ }
+
+ m_pixelAspectRatio->setStatusTip(QString("Pixel Aspect Ratio %1:%2")
+ .arg(ratio.pixelaspect.denominator)
+ .arg(ratio.pixelaspect.numerator));
+ m_pixelAspectRatio->setWhatsThis(QString("Pixel Aspect Ratio %1:%2")
+ .arg(ratio.pixelaspect.denominator)
+ .arg(ratio.pixelaspect.numerator));
+ return (double)ratio.pixelaspect.denominator / ratio.pixelaspect.numerator;
+ case 2:
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 10:11");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 10:11");
+ return 10.0 / 11.0;
+ case 3:
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 40:33");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 40:33");
+ return 40.0 / 33.0;
+ case 4:
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 12:11");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 12:11");
+ return 12.0 / 11.0;
+ case 5:
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 16:11");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 16:11");
+ return 16.0 / 11.0;
+ default:
+ m_pixelAspectRatio->setStatusTip("Pixel Aspect Ratio 1:1");
+ m_pixelAspectRatio->setWhatsThis("Pixel Aspect Ratio 1:1");
+ return 1.0;
+ }
+}
+
void GeneralTab::updateFrameInterval()
{
v4l2_frmivalenum frmival;
diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h
index 6c51016..4540e1f 100644
--- a/utils/qv4l2/general-tab.h
+++ b/utils/qv4l2/general-tab.h
@@ -57,6 +57,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; }
@@ -90,6 +91,7 @@ public slots:
signals:
void audioDeviceChanged();
+ void pixelAspectRatioChanged();
private slots:
void inputChanged(int);
@@ -115,6 +117,7 @@ private slots:
void vidOutFormatChanged(int);
void vbiMethodsChanged(int);
void changeAudioDevice();
+ void changePixelAspectRatio();
private:
void updateVideoInput();
@@ -182,6 +185,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 c94b0a8..892d9c3 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);
@@ -168,13 +168,13 @@ ApplicationWindow::ApplicationWindow() :
#ifdef HAVE_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 Capacity...", this);
+ m_audioBufferAct = new QAction("Set Audio &Buffer Capacity...", 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);
@@ -229,7 +229,7 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
m_audioBufferAct->setEnabled(false);
}
#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)) {
@@ -360,6 +360,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()));
@@ -810,6 +811,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 HAVE_ALSA
@@ -891,6 +898,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()));
@@ -959,6 +967,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 179cecb..970a0e1 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -133,6 +133,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] 10+ messages in thread