[PATCH 9/9] qv4l2: add pixel aspect ratio support for CaptureWin

[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 | 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

--
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