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