[RFC PATCH 7/7] qv4l2: add aspect ratio support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Bård Eirik Winther <bwinther@xxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux