• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 #ifndef GENERAL_TAB_H
22 #define GENERAL_TAB_H
23 
24 #include <QSpinBox>
25 #include <QCheckBox>
26 #include <QDoubleSpinBox>
27 #include <QStackedWidget>
28 #include <sys/time.h>
29 #include <linux/videodev2.h>
30 #include <map>
31 
32 #include "qv4l2.h"
33 #include "capture-win.h"
34 
35 #ifdef HAVE_ALSA
36 extern "C" {
37 #include "../libmedia_dev/get_media_devices.h"
38 #include "alsa_stream.h"
39 }
40 #include <alsa/asoundlib.h>
41 #endif
42 
43 class QComboBox;
44 class QCheckBox;
45 class QSpinBox;
46 class QToolButton;
47 class QSlider;
48 
49 class GeneralTab: public QGridLayout
50 {
51 	Q_OBJECT
52 
53 public:
54 	GeneralTab(const QString &device, cv4l_fd *fd, int n, QWidget *parent = 0);
~GeneralTab()55 	virtual ~GeneralTab() {}
56 
57 	CapMethod capMethod();
58 	QString getAudioInDevice();
59 	QString getAudioOutDevice();
60 	void setAudioDeviceBufferSize(int size);
61 	int getAudioDeviceBufferSize();
62 	bool hasAlsaAudio();
63 	double getPixelAspectRatio();
64 	CropMethod getCropMethod();
65 	bool get_interval(struct v4l2_fract &interval);
width()66 	int width() const { return m_width; }
height()67 	int height() const { return m_height; }
isRadio()68 	bool isRadio() const { return m_isRadio; }
isSDR()69 	bool isSDR() const { return m_isSDR; }
isTouch()70 	bool isTouch() const { return m_isTouch; }
isVbi()71 	bool isVbi() const { return m_isVbi; }
72 	bool isSlicedVbi() const;
isPlanar()73 	bool isPlanar() const { return m_isPlanar; }
isSDTV()74 	bool isSDTV() const { return m_isSDTV; }
usePrio()75 	__u32 usePrio() const
76 	{
77 		return m_recordPrio->isChecked() ?
78 			V4L2_PRIORITY_RECORD : V4L2_PRIORITY_DEFAULT;
79 	}
80 	void setHaveBuffers(bool haveBuffers);
getNumBuffers()81 	unsigned getNumBuffers()
82 	{
83 		return m_numBuffers->value();
84 	}
85 	void sourceChange(const v4l2_event &ev);
86 	void sourceChangeSubscribe();
87 	int getWidth();
88 	unsigned getNumBuffers() const;
89 	QComboBox *m_tpgComboColorspace;
90 	QComboBox *m_tpgComboXferFunc;
91 	QComboBox *m_tpgComboYCbCrEnc;
92 	QComboBox *m_tpgComboQuantRange;
93 
94 signals:
95 	void audioDeviceChanged();
96 	void pixelAspectRatioChanged();
97 	void croppingChanged();
98 	void clearBuffers();
99 
100 private slots:
101 	void inputChanged(int);
102 	void outputChanged(int);
103 	void inputAudioChanged(int);
104 	void outputAudioChanged(int);
105 	void standardChanged(int);
106 	void qryStdClicked();
107 	void timingsChanged(int);
108 	void qryTimingsClicked();
109 	void freqTableChanged(int);
110 	void freqChannelChanged(int);
111 	void freqChanged(double);
112 	void freqRfChanged(double);
113 	void audioModeChanged(int);
114 	void detectSubchansClicked();
115 	void stereoModeChanged();
116 	void rdsModeChanged();
117 	void vidCapFormatChanged(int);
118 	void vidFieldChanged(int);
119 	void frameWidthChanged();
120 	void frameHeightChanged();
121 	void frameSizeChanged(int);
122 	void frameIntervalChanged(int);
123 	void vidOutFormatChanged(int);
124 	void vbiMethodsChanged(int);
125 	void changeAudioDevice();
126 	void changePixelAspectRatio();
127 	void cropChanged();
128 	void composeChanged();
129 	void colorspaceChanged(int);
130 	void xferFuncChanged(int);
131 	void ycbcrEncChanged(int);
132 	void quantRangeChanged(int);
133 
134 private:
135 	void inputSection(v4l2_input vin);
136 	void outputSection(v4l2_output vout);
137 	void audioSection(v4l2_audio vaudio, v4l2_audioout vaudout);
138 	void formatSection(v4l2_fmtdesc fmt);
139 	void cropSection();
140 	void fixWidth();
141 	void updateGUIInput(__u32);
142 	void updateGUIOutput(__u32);
143 	void updateVideoInput();
144 	void updateVideoOutput();
145 	void updateAudioInput();
146 	void updateAudioOutput();
147 	void refreshStandards();
148 	void updateStandard();
149 	void refreshTimings();
150 	void updateTimings();
151 	void updateFreq();
152 	void updateFreqChannel();
153 	void updateFreqRf();
154 	void updateColorspace();
155 	void clearColorspace(cv4l_fmt &fmt);
156 	void updateVidCapFormat();
157 	void updateVidFields();
158 	void updateFrameSize();
159 	void updateFrameInterval();
160 	void updateVidOutFormat();
161 	void updateCrop();
162 	void updateCompose();
updateVidFormat()163 	void updateVidFormat()
164 	{
165 		if (m_isOutput)
166 			updateVidOutFormat();
167 		else
168 			updateVidCapFormat();
169 	}
170 	int addAudioDevice(void *hint, int deviceNum);
171 	bool filterAudioDevice(QString &deviceName);
172 	bool createAudioDeviceList();
173 #ifdef HAVE_ALSA
174 	int matchAudioDevice();
175 	int checkMatchAudioDevice(void *md, const char *vid, enum device_type type);
176 #endif
177 
178 	void addWidget(QWidget *w, Qt::Alignment align = Qt::AlignLeft);
179 	void addTitle(const QString &titlename);
180 	void addLabel(const QString &text, Qt::Alignment align = Qt::AlignLeft)
181 	{
182 		addWidget(new QLabel(text, parentWidget()), align);
183 	}
info(const QString & info)184 	void info(const QString &info)
185 	{
186 		g_mw->info(info);
187 	}
error(const QString & error)188 	virtual void error(const QString &error)
189 	{
190 		g_mw->error(error);
191 	}
error(int error)192 	virtual void error(int error)
193 	{
194 		g_mw->error(error);
195 	}
g_v4l_fd()196 	v4l_fd *g_v4l_fd() { return m_fd->g_v4l_fd(); }
197 
g_type()198 	__u32 g_type() const { return m_fd->g_type(); }
s_type(__u32 type)199 	void s_type(__u32 type) { m_fd->s_type(type); }
g_selection_type()200 	__u32 g_selection_type() const { return m_fd->g_selection_type(); }
g_caps()201 	__u32 g_caps() const { return m_fd->g_caps(); }
202 
has_vid_cap()203 	bool has_vid_cap() const { return m_fd->has_vid_cap(); }
has_vid_out()204 	bool has_vid_out() const { return m_fd->has_vid_out(); }
has_vid_m2m()205 	bool has_vid_m2m() const { return m_fd->has_vid_m2m(); }
has_vid_mplane()206 	bool has_vid_mplane() const { return m_fd->has_vid_mplane(); }
has_overlay_cap()207 	bool has_overlay_cap() const { return m_fd->has_overlay_cap(); }
has_overlay_out()208 	bool has_overlay_out() const { return m_fd->has_overlay_out(); }
has_raw_vbi_cap()209 	bool has_raw_vbi_cap() const { return m_fd->has_raw_vbi_cap(); }
has_sliced_vbi_cap()210 	bool has_sliced_vbi_cap() const { return m_fd->has_sliced_vbi_cap(); }
has_vbi_cap()211 	bool has_vbi_cap() const { return m_fd->has_vbi_cap(); }
has_raw_vbi_out()212 	bool has_raw_vbi_out() const { return m_fd->has_raw_vbi_out(); }
has_sliced_vbi_out()213 	bool has_sliced_vbi_out() const { return m_fd->has_sliced_vbi_out(); }
has_vbi_out()214 	bool has_vbi_out() const { return m_fd->has_vbi_out(); }
has_vbi()215 	bool has_vbi() const { return m_fd->has_vbi(); }
has_radio_rx()216 	bool has_radio_rx() const { return m_fd->has_radio_rx(); }
has_radio_tx()217 	bool has_radio_tx() const { return m_fd->has_radio_tx(); }
has_rds_cap()218 	bool has_rds_cap() const { return m_fd->has_rds_cap(); }
has_rds_out()219 	bool has_rds_out() const { return m_fd->has_rds_out(); }
has_sdr_cap()220 	bool has_sdr_cap() const { return m_fd->has_sdr_cap(); }
has_hwseek()221 	bool has_hwseek() const { return m_fd->has_hwseek(); }
has_rw()222 	bool has_rw() const { return m_fd->has_rw(); }
has_streaming()223 	bool has_streaming() const { return m_fd->has_streaming(); }
has_ext_pix_format()224 	bool has_ext_pix_format() const { return m_fd->has_ext_pix_format(); }
225 
g_direct()226 	bool g_direct() const { return m_fd->g_direct(); }
s_direct(bool direct)227 	void s_direct(bool direct) { m_fd->s_direct(direct); }
querycap(v4l2_capability & cap)228 	int querycap(v4l2_capability &cap) { return m_fd->querycap(cap); }
queryctrl(v4l2_queryctrl & qc)229 	int queryctrl(v4l2_queryctrl &qc) { return m_fd->queryctrl(qc); }
querymenu(v4l2_querymenu & qm)230 	int querymenu(v4l2_querymenu &qm) { return m_fd->querymenu(qm); }
231 	int g_fmt(v4l2_format &fmt, unsigned type = 0) { return m_fd->g_fmt(fmt); }
try_fmt(v4l2_format & fmt)232 	int try_fmt(v4l2_format &fmt) { return m_fd->try_fmt(fmt); }
s_fmt(v4l2_format & fmt)233 	int s_fmt(v4l2_format &fmt) { return m_fd->s_fmt(fmt); }
g_selection(v4l2_selection & sel)234 	int g_selection(v4l2_selection &sel) { return m_fd->g_selection(sel); }
s_selection(v4l2_selection & sel)235 	int s_selection(v4l2_selection &sel) { return m_fd->s_selection(sel); }
236 	int g_tuner(v4l2_tuner &tuner, unsigned index = 0) { return m_fd->g_tuner(tuner, index); }
s_tuner(v4l2_tuner & tuner)237 	int s_tuner(v4l2_tuner &tuner) { return m_fd->s_tuner(tuner); }
g_modulator(v4l2_modulator & modulator)238 	int g_modulator(v4l2_modulator &modulator) { return m_fd->g_modulator(modulator); }
s_modulator(v4l2_modulator & modulator)239 	int s_modulator(v4l2_modulator &modulator) { return m_fd->s_modulator(modulator); }
240 	int enum_input(v4l2_input &in, bool init = false, int index = 0) { return m_fd->enum_input(in, init, index); }
241 	int enum_output(v4l2_output &out, bool init = false, int index = 0) { return m_fd->enum_output(out, init, index); }
242 	int enum_audio(v4l2_audio &audio, bool init = false, int index = 0) { return m_fd->enum_audio(audio, init, index); }
243 	int enum_audout(v4l2_audioout &audout, bool init = false, int index = 0) { return m_fd->enum_audout(audout, init, index); }
subscribe_event(v4l2_event_subscription & sub)244 	int subscribe_event(v4l2_event_subscription &sub) { return m_fd->subscribe_event(sub); }
dqevent(v4l2_event & ev)245 	int dqevent(v4l2_event &ev) { return m_fd->dqevent(ev); }
g_input(__u32 & input)246 	int g_input(__u32 &input) { return m_fd->g_input(input); }
s_input(__u32 input)247 	int s_input(__u32 input) { return m_fd->s_input(input); }
g_output(__u32 & output)248 	int g_output(__u32 &output) { return m_fd->g_output(output); }
s_output(__u32 output)249 	int s_output(__u32 output) { return m_fd->s_output(output); }
g_audio(v4l2_audio & audio)250 	int g_audio(v4l2_audio &audio) { return m_fd->g_audio(audio); }
s_audio(__u32 input)251 	int s_audio(__u32 input) { return m_fd->s_audio(input); }
g_audout(v4l2_audioout & audout)252 	int g_audout(v4l2_audioout &audout) { return m_fd->g_audout(audout); }
s_audout(__u32 output)253 	int s_audout(__u32 output) { return m_fd->s_audout(output); }
g_std(v4l2_std_id & std)254 	int g_std(v4l2_std_id &std) { return m_fd->g_std(std); }
s_std(v4l2_std_id std)255 	int s_std(v4l2_std_id std) { return m_fd->s_std(std); }
query_std(v4l2_std_id & std)256 	int query_std(v4l2_std_id &std) { return m_fd->query_std(std); }
g_dv_timings(v4l2_dv_timings & timings)257 	int g_dv_timings(v4l2_dv_timings &timings) { return m_fd->g_dv_timings(timings); }
s_dv_timings(v4l2_dv_timings & timings)258 	int s_dv_timings(v4l2_dv_timings &timings) { return m_fd->s_dv_timings(timings); }
query_dv_timings(v4l2_dv_timings & timings)259 	int query_dv_timings(v4l2_dv_timings &timings) { return m_fd->query_dv_timings(timings); }
260 	int g_frequency(v4l2_frequency &freq, unsigned index = 0) { return m_fd->g_frequency(freq, index); }
s_frequency(v4l2_frequency & freq)261 	int s_frequency(v4l2_frequency &freq) { return m_fd->s_frequency(freq); }
g_priority(__u32 & prio)262 	int g_priority(__u32 &prio) { return m_fd->g_priority(prio); }
263 	int s_priority(__u32 prio = V4L2_PRIORITY_DEFAULT) { return m_fd->s_priority(prio); }
264 	int streamon(__u32 type = 0) { return m_fd->streamon(type); }
265 	int streamoff(__u32 type = 0) { return m_fd->streamoff(type); }
querybuf(v4l_buffer & buf,unsigned index)266 	int querybuf(v4l_buffer &buf, unsigned index) { return m_fd->querybuf(buf, index); }
dqbuf(v4l_buffer & buf)267 	int dqbuf(v4l_buffer &buf) { return m_fd->dqbuf(buf); }
qbuf(v4l_buffer & buf)268 	int qbuf(v4l_buffer &buf) { return m_fd->qbuf(buf); }
prepare_buf(v4l_buffer & buf)269 	int prepare_buf(v4l_buffer &buf) { return m_fd->prepare_buf(buf); }
270 	int enum_std(v4l2_standard &std, bool init = false, int index = 0) { return m_fd->enum_std(std, init, index); }
271 	int enum_dv_timings(v4l2_enum_dv_timings &timings, bool init = false, int index = 0) { return m_fd->enum_dv_timings(timings, init, index); }
272 	int enum_fmt(v4l2_fmtdesc &fmt, bool init = false, int index = 0, unsigned type = 0) { return m_fd->enum_fmt(fmt, init, index, type); }
273 	int enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt = 0, int index = 0) { return m_fd->enum_framesizes(frm, init_pixfmt, index); }
274 	int enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt = 0, __u32 w = 0, __u32 h = 0, int index = 0) { return m_fd->enum_frameintervals(frm, init_pixfmt, w, h, index); }
275 	int set_interval(v4l2_fract interval, unsigned type = 0) { return m_fd->set_interval(interval, type); }
276 	v4l2_fract g_pixel_aspect(unsigned &width, unsigned &height, unsigned type = 0)
277 	{
278 		return m_fd->g_pixel_aspect(width, height, type);
279 	}
has_crop()280 	bool has_crop() { return m_fd->has_crop(); }
has_compose()281 	bool has_compose() { return m_fd->has_compose(); }
cur_io_has_crop()282 	bool cur_io_has_crop() { return m_fd->cur_io_has_crop(); }
cur_io_has_compose()283 	bool cur_io_has_compose() { return m_fd->cur_io_has_compose(); }
ioctl_exists(int ret)284 	bool ioctl_exists(int ret)
285 	{
286 		return ret == 0 || errno != ENOTTY;
287 	}
288 
289 
290 	cv4l_fd *m_fd;
291 	int m_row;
292 	int m_col;
293 	int m_cols;
294 	const int m_minWidth;
295 	const double m_pxw;
296 	const int m_vMargin;
297 	const int m_hMargin;
298 	int m_increment;
299 	int m_maxw[4];
300 	int m_maxh;
301 	bool m_isRadio;
302 	bool m_isSDR;
303 	bool m_isTouch;
304 	bool m_isVbi;
305 	bool m_isOutput;
306 	bool m_isSDTV;
307 	double m_freqFac;
308 	double m_freqRfFac;
309 	bool m_isPlanar;
310 	bool m_haveBuffers;
311 	bool m_discreteSizes;
312 	__u32 m_audioModes[5];
313 	QString m_device;
314 	struct v4l2_tuner m_tuner;
315 	struct v4l2_tuner m_tuner_rf;
316 	struct v4l2_modulator m_modulator;
317 	struct v4l2_capability m_querycap;
318 	__u32 m_pixelformat;
319 	__u32 m_width, m_height;
320 	struct v4l2_fract m_interval;
321 	bool m_has_interval;
322 	int m_audioDeviceBufferSize;
323 	static bool m_fullAudioName;
324 	std::map<int, QString> m_audioInDeviceMap;
325 	std::map<int, QString> m_audioOutDeviceMap;
326 
327 	// General tab
328 	QList<QGridLayout *> m_grids;
329 	QStackedWidget *m_stackedStandards;
330 	QStackedWidget *m_stackedFrameSettings;
331 	QStackedWidget *m_stackedFrequency;
332 	QComboBox *m_videoInput;
333 	QComboBox *m_videoOutput;
334 	QComboBox *m_audioInput;
335 	QComboBox *m_audioOutput;
336 	QComboBox *m_tvStandard;
337 	QToolButton *m_qryStandard;
338 	QComboBox *m_videoTimings;
339 	QComboBox *m_pixelAspectRatio;
340 	QComboBox *m_colorspace;
341 	QComboBox *m_xferFunc;
342 	QComboBox *m_ycbcrEnc;
343 	QComboBox *m_quantRange;
344 	QComboBox *m_cropping;
345 	QToolButton *m_qryTimings;
346 	QDoubleSpinBox *m_freq;
347 	QComboBox *m_freqTable;
348 	QComboBox *m_freqChannel;
349 	QComboBox *m_audioMode;
350 	QLabel *m_subchannels;
351 	QDoubleSpinBox *m_freqRf;
352 	QCheckBox *m_stereoMode;
353 	QCheckBox *m_rdsMode;
354 	QToolButton *m_detectSubchans;
355 	QComboBox *m_vidCapFormats;
356 	QComboBox *m_vidFields;
357 	QComboBox *m_frameSize;
358 	QSpinBox *m_frameWidth;
359 	QSpinBox *m_frameHeight;
360 	QComboBox *m_frameInterval;
361 	QComboBox *m_vidOutFormats;
362 	QComboBox *m_capMethods;
363 	QSpinBox *m_numBuffers;
364 	QCheckBox *m_recordPrio;
365 	QComboBox *m_vbiMethods;
366 	QComboBox *m_audioInDevice;
367 	QComboBox *m_audioOutDevice;
368 	QSlider *m_cropWidth;
369 	QSlider *m_cropLeft;
370 	QSlider *m_cropHeight;
371 	QSlider *m_cropTop;
372 	QSlider *m_composeWidth;
373 	QSlider *m_composeLeft;
374 	QSlider *m_composeHeight;
375 	QSlider *m_composeTop;
376 };
377 
378 #endif
379