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