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