#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
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)
m_frameWidth = width;
m_frameHeight = height;
m_frameFormat = format;
-
- QGLWidget::setMaximumSize(m_frameWidth, m_frameHeight);
}
m_frameData = data;
#include "qv4l2.h"
#include "capture-win.h"
+#include <QResizeEvent>
+
#ifdef HAVE_QTGL
#define GL_GLEXT_PROTOTYPES
#include <QGLWidget>
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();
bool hasNativeFormat(__u32 format);
static bool isSupported();
+protected:
+ void resizeEvent(QResizeEvent *event);
+
+private:
#ifdef HAVE_QTGL
CaptureWinGLEngine m_videoSurface;
#endif
{
CaptureWin::buildWindow(&m_videoSurface);
+ m_scaledFrame.setWidth(0);
+ m_scaledFrame.setHeight(0);
}
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;
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)
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)
#include <QLabel>
#include <QImage>
+#include <QResizeEvent>
class CaptureWinQt : public CaptureWin
{
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
#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()
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)
CaptureWin();
~CaptureWin();
- void setMinimumSize(int minw, int minh);
+ void resize(int minw, int minh);
/**
* @brief Set a frame into the capture window.
*/
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();
/**
*/
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
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;
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()
{
}
+void ApplicationWindow::enableScaling(bool enable)
+{
+ if (m_capture != NULL)
+ m_capture->enableScaling(enable);
+}
+
void ApplicationWindow::startAudio()
{
#ifdef HAVE_ALSA
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(),
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
m_capSrcFormat = copy;
}
- m_capture->setMinimumSize(dstPix.width, dstPix.height);
// Ensure that the initial image is large enough for native 32 bit per pixel formats
if (dstPix.pixelformat == V4L2_PIX_FMT_RGB32 || dstPix.pixelformat == V4L2_PIX_FMT_BGR32)
dstFmt = QImage::Format_ARGB32;
m_capImage = new QImage(dstPix.width, dstPix.height, dstFmt);
m_capImage->fill(0);
-
+ m_capture->resize(dstPix.width, dstPix.height);
+
if (showFrames()) {
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), "No frame");
void openRawFile(const QString &s);
void rejectedRawFile();
void setAudioBufferSize();
+ void enableScaling(bool enable);
void about();
QAction *m_useGLAct;
QAction *m_showAllAudioAct;
QAction *m_audioBufferAct;
+ QAction *m_scalingAct;
QString m_filename;
QSignalMapper *m_sigMapper;
QTabWidget *m_tabs;