qv4l2: support top/bottom/alternate field settings.
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 28 Feb 2014 13:41:15 +0000 (14:41 +0100)
committerHans Verkuil <hans.verkuil@cisco.com>
Fri, 28 Feb 2014 13:41:15 +0000 (14:41 +0100)
Compensate for the half-height by changing the pixel aspect ratio. This
ensures that they are still shown at the right picture aspect ratio.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/qv4l2/capture-win-qt.cpp
utils/qv4l2/capture-win.cpp
utils/qv4l2/capture-win.h
utils/qv4l2/qv4l2.cpp
utils/qv4l2/qv4l2.h

index 62a7be5..19bfbc0 100644 (file)
@@ -83,6 +83,8 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char *
            || m_frame->format() != dstFmt) {
                delete m_frame;
                m_frame = new QImage(width, height, dstFmt);
+               // Force a recalculation by setting this to 0.
+               m_crop.bytes = 0;
 
                resizeScaleCrop();
        }
index 74581e4..20175c6 100644 (file)
@@ -131,12 +131,20 @@ void CaptureWin::setCropMethod(CropMethod crop)
 
 int CaptureWin::actualFrameWidth(int width)
 {
-       if (m_enableScaling)
+       if (m_enableScaling && m_pixelAspectRatio > 1)
                return width * m_pixelAspectRatio;
 
        return width;
 }
 
+int CaptureWin::actualFrameHeight(int height)
+{
+       if (m_enableScaling && m_pixelAspectRatio < 1)
+               return height / m_pixelAspectRatio;
+
+       return height;
+}
+
 QSize CaptureWin::getMargins()
 {
        int l, t, r, b;
@@ -159,6 +167,8 @@ void CaptureWin::enableScaling(bool enable)
 
 void CaptureWin::resize(int width, int height)
 {
+       int h, w;
+
        // 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)
@@ -168,8 +178,10 @@ void CaptureWin::resize(int width, int height)
        m_curHeight = height;
 
        QSize margins = getMargins();
-       height = height + margins.height() - cropHeight(width, height) * 2;
-       width = margins.width() - cropWidth(width, height) * 2 + actualFrameWidth(width);
+       h = margins.height() - cropHeight(width, height) * 2 + actualFrameHeight(height);
+       w = margins.width() - cropWidth(width, height) * 2 + actualFrameWidth(width);
+       height = h;
+       width = w;
 
        QDesktopWidget *screen = QApplication::desktop();
        QRect resolution = screen->screenGeometry();
@@ -191,7 +203,7 @@ void CaptureWin::resize(int width, int height)
 QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
 {
        int actualWidth = actualFrameWidth(frame.width() - cropWidth(frame.width(), frame.height()) * 2);
-       int actualHeight = frame.height() - cropHeight(frame.width(), frame.height()) * 2;
+       int actualHeight = actualFrameHeight(frame.height() - cropHeight(frame.width(), frame.height()) * 2);
 
        if (!m_enableScaling) {
                window.setWidth(actualWidth);
index bc71c26..d6f5d21 100644 (file)
@@ -94,7 +94,7 @@ public:
        /**
         * @brief Return the scaled size.
         *
-        * Scales a frame to fit inside a given window. Preseves aspect ratio.
+        * Scales a frame to fit inside a given window. Preserves aspect ratio.
         *
         * @param window The window the frame shall scale into
         * @param frame The frame to scale
@@ -120,13 +120,21 @@ public:
        static int cropWidth(int width, int height);
 
        /**
-        * @brief Get the frame width when aspect ratio is applied.
+        * @brief Get the frame width when aspect ratio is applied if ratio > 1.
         *
         * @param width The original frame width.
-        * @return The width with aspect ratio correctio (scaling must be enabled).
+        * @return The width with aspect ratio correction (scaling must be enabled).
         */
        static int actualFrameWidth(int width);
 
+       /**
+        * @brief Get the frame height when aspect ratio is applied if ratio < 1.
+        *
+        * @param width The original frame width.
+        * @return The width with aspect ratio correction (scaling must be enabled).
+        */
+       static int actualFrameHeight(int height);
+
 public slots:
        void resetSize();
 
index 86a3e6d..03b764a 100644 (file)
@@ -837,7 +837,8 @@ void ApplicationWindow::enableScaling(bool enable)
 void ApplicationWindow::updatePixelAspectRatio()
 {
        if (m_capture != NULL && m_genTab != NULL)
-               m_capture->setPixelAspectRatio(m_genTab->getPixelAspectRatio());
+               m_capture->setPixelAspectRatio(m_genTab->getPixelAspectRatio() /
+                                               (m_fieldCapture ? 2 : 1));
 }
 
 void ApplicationWindow::updateCropping()
@@ -974,6 +975,10 @@ void ApplicationWindow::capStart(bool start)
        }
 
        g_fmt_cap(m_capSrcFormat);
+       m_fieldCapture = m_capSrcFormat.fmt.pix.field == V4L2_FIELD_TOP ||
+                        m_capSrcFormat.fmt.pix.field == V4L2_FIELD_BOTTOM ||
+                        m_capSrcFormat.fmt.pix.field == V4L2_FIELD_ALTERNATE;
+       m_heightDiv = m_fieldCapture ? 2 : 1;
        s_fmt(m_capSrcFormat);
        if (m_genTab->get_interval(interval))
                set_interval(interval);
@@ -999,14 +1004,14 @@ void ApplicationWindow::capStart(bool start)
        // 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 = new QImage(dstPix.width, dstPix.height / m_heightDiv, dstFmt);
        m_capImage->fill(0);
        
        updatePixelAspectRatio();
        
        m_capture->setFrame(m_capImage->width(), m_capImage->height(),
                            m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), "No frame");
-       m_capture->resize(dstPix.width, dstPix.height);
+       m_capture->resize(dstPix.width, dstPix.height / m_heightDiv);
        if (showFrames())
                m_capture->show();
 
index b8cc3b8..8130318 100644 (file)
@@ -106,6 +106,8 @@ private:
        struct buffer *m_buffers;
        struct v4l2_format m_capSrcFormat;
        struct v4l2_format m_capDestFormat;
+       bool m_fieldCapture;
+       unsigned m_heightDiv;
        unsigned char *m_frameData;
        unsigned m_nbuffers;
        struct v4lconvert_data *m_convertData;