1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
4  */
5 
6 #ifndef CAPTURE_WIN_GL_H
7 #define CAPTURE_WIN_GL_H
8 
9 #define GL_GLEXT_PROTOTYPES 1
10 #define QT_NO_OPENGL_ES_2
11 
12 #include <QOpenGLWidget>
13 #include <QOpenGLFunctions>
14 #include <QFile>
15 #include <QMenu>
16 #include <QAction>
17 #include <QActionGroup>
18 #include <QScrollArea>
19 #include <QtGui/QOpenGLShaderProgram>
20 
21 #include "qvidcap.h"
22 
23 extern "C" {
24 #include "v4l2-tpg.h"
25 #include "v4l-stream.h"
26 }
27 
28 extern const uint32_t formats[];
29 extern const uint32_t fields[];
30 extern const uint32_t colorspaces[];
31 extern const uint32_t xfer_funcs[];
32 extern const uint32_t ycbcr_encs[];
33 extern const uint32_t hsv_encs[];
34 extern const uint32_t quantizations[];
35 
36 class QOpenGLPaintDevice;
37 
38 enum AppMode {
39 	AppModeV4L2,
40 	AppModeFile,
41 	AppModeSocket,
42 	AppModeTPG,
43 	AppModeTest
44 };
45 
46 #define FMT_MASK		(1 << 0)
47 #define FIELD_MASK		(1 << 1)
48 #define COLORSPACE_MASK		(1 << 2)
49 #define XFER_FUNC_MASK		(1 << 3)
50 #define YCBCR_HSV_ENC_MASK	(1 << 4)
51 #define QUANT_MASK		(1 << 5)
52 
53 struct TestState {
54 	unsigned fmt_idx;
55 	unsigned field_idx;
56 	unsigned colorspace_idx;
57 	unsigned xfer_func_idx;
58 	unsigned ycbcr_enc_idx;
59 	unsigned hsv_enc_idx;
60 	unsigned quant_idx;
61 	unsigned mask;
62 };
63 
64 // This must be equal to the max number of textures that any shader uses
65 #define MAX_TEXTURES_NEEDED 3
66 
67 class CaptureWin : public QOpenGLWidget, protected QOpenGLFunctions
68 {
69 	Q_OBJECT
70 public:
71 	explicit CaptureWin(QScrollArea *sa, QWidget *parent = 0);
72 	~CaptureWin();
73 
74 	void setModeV4L2(cv4l_fd *fd);
75 	void setModeSocket(int sock, int port);
76 	void setModeFile(const QString &filename);
77 	void setModeTPG();
78 	void setModeTest(unsigned cnt);
79 	void setQueue(cv4l_queue *q);
80 	bool setV4LFormat(cv4l_fmt &fmt);
81 	void setPixelAspect(v4l2_fract &pixelaspect);
82 	bool updateV4LFormat(const cv4l_fmt &fmt);
83 	void setOverrideWidth(uint32_t w);
84 	void setOverrideHeight(uint32_t h);
85 	void setOverrideHorPadding(uint32_t p);
setCount(unsigned cnt)86 	void setCount(unsigned cnt) { m_cnt = cnt; }
setReportTimings(bool report)87 	void setReportTimings(bool report) { m_reportTimings = report; }
setVerbose(bool verbose)88 	void setVerbose(bool verbose) { m_verbose = verbose; }
setOverridePixelFormat(uint32_t fmt)89 	void setOverridePixelFormat(uint32_t fmt) { m_overridePixelFormat = fmt; }
setOverrideField(uint32_t field)90 	void setOverrideField(uint32_t field) { m_overrideField = field; }
setOverrideColorspace(uint32_t colsp)91 	void setOverrideColorspace(uint32_t colsp) { m_overrideColorspace = colsp; }
setOverrideYCbCrEnc(uint32_t ycbcr)92 	void setOverrideYCbCrEnc(uint32_t ycbcr) { m_overrideYCbCrEnc = ycbcr; }
setOverrideHSVEnc(uint32_t hsv)93 	void setOverrideHSVEnc(uint32_t hsv) { m_overrideHSVEnc = hsv; }
setOverrideXferFunc(uint32_t xfer_func)94 	void setOverrideXferFunc(uint32_t xfer_func) { m_overrideXferFunc = xfer_func; }
setOverrideQuantization(uint32_t quant)95 	void setOverrideQuantization(uint32_t quant) { m_overrideQuantization = quant; }
setFps(double fps)96 	void setFps(double fps) { m_fps = fps; }
setSingleStepStart(unsigned start)97 	void setSingleStepStart(unsigned start) { m_singleStep = true; m_singleStepStart = start; }
setTestState(const TestState & state)98 	void setTestState(const TestState &state) { m_testState = state; }
99 	QSize correctAspect(const QSize &s) const;
100 	void startTimer();
getTPG()101 	struct tpg_data *getTPG() { return &m_tpg; }
102 
103 private slots:
104 	void v4l2ReadEvent();
105 	void v4l2ExceptionEvent();
106 	void sockReadEvent();
107 	void tpgUpdateFrame();
108 
109 	void restoreAll(bool checked);
110 	void restoreSize(bool checked = false);
111 	void fmtChanged(QAction *a);
112 	void fieldChanged(QAction *a);
113 	void colorspaceChanged(QAction *a);
114 	void xferFuncChanged(QAction *a);
115 	void ycbcrEncChanged(QAction *a);
116 	void hsvEncChanged(QAction *a);
117 	void quantChanged(QAction *a);
118 	void windowScalingChanged(QAction *a);
119 	void resolutionOverrideChanged(bool);
120 	void toggleFullScreen(bool b = false);
121 
122 private:
123 	void resizeEvent(QResizeEvent *event);
124 	void paintGL();
125 	void initializeGL();
126 	void resizeGL(int w, int h);
127 	void contextMenuEvent(QContextMenuEvent *event);
128 	void keyPressEvent(QKeyEvent *event);
129 	void mouseDoubleClickEvent(QMouseEvent * e);
130 	void listenForNewConnection();
131 	int read_u32(uint32_t &v);
132 	void showCurrentOverrides();
133 	void cycleMenu(uint32_t &overrideVal, uint32_t &origVal,
134 		       const uint32_t values[], bool hasShift, bool hasCtrl);
135 
136 	bool supportedFmt(uint32_t fmt);
137 	void checkError(const char *msg);
138 	void configureTexture(size_t idx);
139 	void initImageFormat();
140 	void updateOrigValues();
141 	void updateShader();
142 	void changeShader();
143 
144 	// Colorspace conversion shaders
145 	void shader_YUV();
146 	void shader_NV12();
147 	void shader_NV16();
148 	void shader_NV24();
149 	void shader_RGB();
150 	void shader_Bayer();
151 	void shader_YUV_packed();
152 	void shader_YUY2();
153 
154 	// Colorspace conversion render
155 	void render_RGB(uint32_t format);
156 	void render_Bayer(uint32_t format);
157 	void render_YUY2(uint32_t format);
158 	void render_YUV(uint32_t format);
159 	void render_YUV_packed(uint32_t format);
160 	void render_NV12(uint32_t format);
161 	void render_NV16(uint32_t format);
162 	void render_NV24(uint32_t format);
163 
164 	enum AppMode m_mode;
165 	cv4l_fd *m_fd;
166 	int m_sock;
167 	int m_port;
168 	QFile m_file;
169 	bool m_v4l2;
170 	cv4l_fmt m_v4l_fmt;
171 	v4l2_fract m_pixelaspect;
172 	cv4l_queue *m_v4l_queue;
173 	unsigned m_cnt;
174 	unsigned m_frame;
175 	unsigned m_test;
176 	TestState m_testState;
177 	unsigned m_imageSize;
178 	bool m_verbose;
179 	bool m_reportTimings;
180 	bool m_is_sdtv;
181 	v4l2_std_id m_std;
182 	bool m_is_rgb;
183 	bool m_is_hsv;
184 	bool m_is_bayer;
185 	bool m_uses_gl_red;
186 	bool m_accepts_srgb;
187 	bool m_haveSwapBytes;
188 	bool m_updateShader;
189 	QSize m_viewSize;
190 	bool m_canOverrideResolution;
191 	codec_ctx *m_ctx;
192 
193 	uint32_t m_overridePixelFormat;
194 	uint32_t m_overrideWidth;
195 	uint32_t m_overrideHeight;
196 	uint32_t m_overrideHorPadding;
197 	uint32_t m_overrideField;
198 	uint32_t m_overrideColorspace;
199 	uint32_t m_overrideYCbCrEnc;
200 	uint32_t m_overrideHSVEnc;
201 	uint32_t m_overrideXferFunc;
202 	uint32_t m_overrideQuantization;
203 	uint32_t m_origPixelFormat;
204 	uint32_t m_origWidth;
205 	uint32_t m_origHeight;
206 	uint32_t m_origField;
207 	uint32_t m_origColorspace;
208 	uint32_t m_origYCbCrEnc;
209 	uint32_t m_origHSVEnc;
210 	uint32_t m_origXferFunc;
211 	uint32_t m_origQuantization;
212 	double m_fps;
213 	bool m_singleStep;
214 	unsigned m_singleStepStart;
215 	bool m_singleStepNext;
216 
217 	QTimer *m_timer;
218 	int m_screenTextureCount;
219 	GLuint m_screenTexture[MAX_TEXTURES_NEEDED];
220 	QOpenGLShaderProgram *m_program;
221 	uint8_t *m_curData[MAX_TEXTURES_NEEDED];
222 	unsigned m_curSize[MAX_TEXTURES_NEEDED];
223 	uint8_t *m_nextData[MAX_TEXTURES_NEEDED];
224 	unsigned m_nextSize[MAX_TEXTURES_NEEDED];
225 	int m_curIndex;
226 	int m_nextIndex;
227 	struct tpg_data m_tpg;
228 
229 	QScrollArea *m_scrollArea;
230 	QAction *m_resolutionOverride;
231 	QAction *m_exitFullScreen;
232 	QAction *m_enterFullScreen;
233 	QMenu *m_fmtMenu;
234 	QMenu *m_fieldMenu;
235 	QMenu *m_colorspaceMenu;
236 	QMenu *m_xferFuncMenu;
237 	QMenu *m_ycbcrEncMenu;
238 	QMenu *m_hsvEncMenu;
239 	QMenu *m_quantMenu;
240 	QMenu *m_displayMenu;
241 };
242 
243 #endif
244