1 /* qv4l2: a control panel controlling v4l2 devices.
2  *
3  * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 
20 #ifndef QV4L2_H
21 #define QV4L2_H
22 
23 #include <config.h>
24 
25 #include <QMainWindow>
26 #include <QTabWidget>
27 #include <QSignalMapper>
28 #include <QLabel>
29 #include <QGridLayout>
30 #include <QSocketNotifier>
31 #include <QImage>
32 #include <QFileDialog>
33 #include <map>
34 #include <vector>
35 
36 // Must come before cv4l-helpers.h
37 #include <libv4l2.h>
38 
39 extern "C" {
40 #include <v4l2-tpg.h>
41 }
42 #include "cv4l-helpers.h"
43 #include "raw2sliced.h"
44 #include "capture-win.h"
45 
46 class QComboBox;
47 class QSpinBox;
48 class QCheckBox;
49 class GeneralTab;
50 class VbiTab;
51 class QCloseEvent;
52 class CaptureWin;
53 
54 typedef std::vector<unsigned> ClassIDVec;
55 typedef std::map<unsigned, ClassIDVec> ClassMap;
56 typedef std::map<unsigned, struct v4l2_query_ext_ctrl> CtrlMap;
57 typedef std::map<unsigned, QWidget *> WidgetMap;
58 
59 enum {
60 	CTRL_UPDATE_ON_CHANGE = 0x10,
61 	CTRL_DEFAULTS,
62 	CTRL_REFRESH,
63 	CTRL_UPDATE
64 };
65 
66 enum CapMethod {
67 	methodRead,
68 	methodMmap,
69 	methodUser
70 };
71 
72 enum RenderMethod {
73 	QV4L2_RENDER_GL,
74 	QV4L2_RENDER_QT
75 };
76 
77 struct buffer {
78 	unsigned planes;
79 	void   *start[VIDEO_MAX_PLANES];
80 	size_t  length[VIDEO_MAX_PLANES];
81 	bool clear;
82 };
83 
84 #define CTRL_FLAG_DISABLED	(V4L2_CTRL_FLAG_READ_ONLY | \
85 				 V4L2_CTRL_FLAG_INACTIVE | \
86 				 V4L2_CTRL_FLAG_GRABBED)
87 
88 class CaptureWin;
89 
90 class ApplicationWindow: public QMainWindow, cv4l_fd
91 {
92 	Q_OBJECT
93 
94 	friend class CaptureWin;
95 public:
96 	ApplicationWindow();
97 	virtual ~ApplicationWindow();
98 
99 private slots:
100 	void closeDevice();
101 	void closeCaptureWin();
102 
103 public:
104 	void setDevice(const QString &device, bool rawOpen);
105 
106 	// capturing
107 private:
108 	CaptureWin *m_capture;
109 
110 	bool startStreaming();
111 	void stopStreaming();
112 	void newCaptureWin();
113 	void startAudio();
114 	void stopAudio();
115 	bool startOutput();
116 	void stopOutput();
117 
118 	bool m_clear[64];
119 	cv4l_fmt m_capSrcFormat;
120 	cv4l_fmt m_capDestFormat;
121 	unsigned char *m_frameData;
122 	unsigned m_nbuffers;
123 	struct v4lconvert_data *m_convertData;
124 	bool m_mustConvert;
125 	CapMethod m_capMethod;
126 	bool m_makeSnapshot;
127 	bool m_singleStep;
128 	RenderMethod m_renderMethod;
129 	int m_overrideColorspace;
130 	int m_overrideXferFunc;
131 	int m_overrideYCbCrEnc;
132 	int m_overrideQuantization;
133 
134 private slots:
135 	void capStart(bool);
136 	void capStep(bool);
137 	void outStart(bool);
138 	void makeFullScreen(bool);
139 	void capFrame();
140 	void outFrame();
141 	void ctrlEvent();
142 	void snapshot();
143 	void capVbiFrame();
144 	void capSdrFrame();
145 	void saveRaw(bool);
146 	void setRenderMethod(bool);
147 	void setBlending(bool);
148 	void setLinearFilter(bool);
149 	void traceIoctls(bool);
150 	void changeAudioDevice();
151 
152 	// gui
153 private slots:
154 	void opendev();
155 	void openrawdev();
156 	void ctrlAction(int);
157 	void openRawFile(const QString &s);
158 	void rejectedRawFile();
159 	void setAudioBufferSize();
160 	void enableScaling(bool enable);
161 	void updatePixelAspectRatio();
162 	void updateCropping();
163 	void clearBuffers();
164 	void about();
165 	void overrideColorspaceChanged(QAction *a);
166 	void overrideXferFuncChanged(QAction *a);
167 	void overrideYCbCrEncChanged(QAction *a);
168 	void overrideQuantChanged(QAction *a);
169 
170 	// tpg
171 private slots:
172 	void testPatternChanged(int val);
173 	void horMovementChanged(int val);
174 	void vertMovementChanged(int val);
175 	void showBorderChanged(int val);
176 	void showSquareChanged(int val);
177 	void insSAVChanged(int val);
178 	void insEAVChanged(int val);
179 	void videoAspectRatioChanged(int val);
180 	void limRGBRangeChanged(int val);
181 	void fillPercentageChanged(int val);
182 	void alphaComponentChanged(int val);
183 	void applyToRedChanged(int val);
184 	uint32_t tpgDefaultColorspace();
185 	void tpgColorspaceChanged();
186 
187 public:
188 	virtual void error(const QString &text);
189 	void error(int err);
190 	void errorCtrl(unsigned id, int err);
191 	void errorCtrl(unsigned id, int err, long long v);
192 	void errorCtrl(unsigned id, int err, const QString &v);
193 	void info(const QString &info);
194 	virtual void closeEvent(QCloseEvent *event);
195 	void updateLimRGBRange();
196 	void updateColorspace();
197 	QAction *m_resetScalingAct;
198 	QAction *m_useBlendingAct;
199 	QAction *m_useLinearAct;
200 	QAction *m_snapshotAct;
201 	QAction *m_showFramesAct;
202 	QMenu *m_overrideColorspaceMenu;
203 	QMenu *m_overrideXferFuncMenu;
204 	QMenu *m_overrideYCbCrEncMenu;
205 	QMenu *m_overrideQuantizationMenu;
206 
207 private:
208 	void addWidget(QGridLayout *grid, QWidget *w, Qt::Alignment align = Qt::AlignLeft);
209 	void addLabel(QGridLayout *grid, const QString &text, Qt::Alignment align = Qt::AlignLeft)
210 	{
211 		addWidget(grid, new QLabel(text, parentWidget()), align);
212 	}
213 	void fixWidth(QGridLayout *grid);
214 	void addTabs(int m_winWidth);
215 	void addTpgTab(int m_winWidth);
216 	void finishGrid(QGridLayout *grid, unsigned which);
217 	void addCtrl(QGridLayout *grid, const struct v4l2_query_ext_ctrl &qec);
218 	void updateCtrl(unsigned id);
219 	void updateCtrlRange(unsigned id, int32_t val);
220 	void subscribeCtrlEvents();
221 	void refresh(unsigned which);
222 	void refresh();
223 	void calculateFps();
224 	void makeSnapshot(unsigned char *buf, unsigned size);
225 	void setDefaults(unsigned which);
226 	int getVal(unsigned id);
227 	long long getVal64(unsigned id);
228 	QString getString(unsigned id);
229 	void setVal(unsigned id, int v);
230 	void setVal64(unsigned id, long long v);
231 	void setString(unsigned id, const QString &v);
232 	QString getCtrlFlags(unsigned flags);
233 	void setWhat(QWidget *w, unsigned id, const QString &v);
234 	void setWhat(QWidget *w, unsigned id, long long v);
235 	void updateVideoInput();
236 	void updateVideoOutput();
237 	void updateAudioInput();
238 	void updateAudioOutput();
239 	void updateStandard();
240 	void updateFreq();
241 	void updateFreqChannel();
242 	bool showFrames();
243 
244 	// tpg
245 	struct tpg_data m_tpg;
246 	v4l2_std_id m_tpgStd;
247 	unsigned m_tpgField;
248 	bool m_tpgFieldAlt;
249 	unsigned m_tpgSizeImage;
250 	QComboBox *m_tpgColorspace;
251 	QComboBox *m_tpgXferFunc;
252 	QComboBox *m_tpgYCbCrEnc;
253 	QComboBox *m_tpgQuantRange;
254 	bool m_useTpg;
255 	QCheckBox *m_tpgLimRGBRange;
256 
257 	cv4l_queue m_queue;
258 
259 	const double m_pxw;
260 	const int m_minWidth;
261 	const int m_vMargin;
262 	const int m_hMargin;
263 	int m_maxw[4];
264 	int m_increment;
265 	GeneralTab *m_genTab;
266 	VbiTab *m_vbiTab;
267 	QMenu *m_capMenu;
268 	QAction *m_capStartAct;
269 	QAction *m_capStepAct;
270 	QAction *m_saveRawAct;
271 	QAction *m_useGLAct;
272 	QAction *m_audioBufferAct;
273 	QAction *m_scalingAct;
274 	QAction *m_makeFullScreenAct;
275 	QString m_filename;
276 	QSignalMapper *m_sigMapper;
277 	QTabWidget *m_tabs;
278 	QSocketNotifier *m_capNotifier;
279 	QSocketNotifier *m_outNotifier;
280 	QSocketNotifier *m_ctrlNotifier;
281 	QImage *m_capImage;
282 	int m_row, m_col, m_cols;
283 	CtrlMap m_ctrlMap;
284 	WidgetMap m_widgetMap;
285 	WidgetMap m_sliderMap;
286 	ClassMap m_classMap;
287 	int m_vbiSize;
288 	unsigned m_vbiWidth;
289 	unsigned m_vbiHeight;
290 	struct vbi_handle m_vbiHandle;
291 	int m_sdrSize;
292 	unsigned m_frame;
293 	double m_fps;
294 	struct timespec m_startTimestamp;
295 	struct timeval m_totalAudioLatency;
296 	QFile m_saveRaw;
297 };
298 
299 extern ApplicationWindow *g_mw;
300 
301 class SaveDialog : public QFileDialog
302 {
303 	Q_OBJECT
304 
305 public:
SaveDialog(QWidget * parent,const QString & caption)306 	SaveDialog(QWidget *parent, const QString &caption) :
307 		QFileDialog(parent, caption), m_buf(NULL) {}
~SaveDialog()308 	virtual ~SaveDialog() {}
309 	bool setBuffer(unsigned char *buf, unsigned size);
310 
311 public slots:
312 	void selected(const QString &s);
313 
314 private:
315 	unsigned char *m_buf;
316 	unsigned m_size;
317 };
318 
319 #endif
320