opengl colorspace + BT2020
[goodguy/history.git] / cinelerra-5.1 / cinelerra / playback3d.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #ifndef PLAYBACK3D_H
23 #define PLAYBACK3D_H
24
25 #include "arraylist.h"
26 #include "bccolors.h"
27 #include "bcpixmap.inc"
28 #include "bcsynchronous.h"
29 #include "bcwindowbase.inc"
30 #include "canvas.inc"
31 #include "condition.inc"
32 #include "maskauto.inc"
33 #include "maskautos.inc"
34 #include "mutex.inc"
35 #include "mwindow.inc"
36 #include "pluginclient.inc"
37 #include "thread.h"
38 #include "vframe.inc"
39
40
41
42
43 // use static presets YUV in bccolors.h
44 #define BC_GL_MATRIX(shader, mat) \
45         glUniformMatrix3fv(glGetUniformLocation(shader, #mat), 1, 0, YUV::mat)
46
47 #define BC_GL_YMINF(shader,mat) \
48         glUniform1f(glGetUniformLocation(shader, "yminf"), YUV::mat[9])
49
50 #define BC_GL_RGB_TO_YUV(shader) do { \
51         BC_GL_MATRIX(shader, rgb_to_yuv_matrix); \
52         BC_GL_YMINF(shader, rgb_to_yuv_matrix); \
53 } while(0)
54
55 #define BC_GL_YUV_TO_RGB(shader) do { \
56         BC_GL_MATRIX(shader, yuv_to_rgb_matrix); \
57         BC_GL_YMINF(shader, yuv_to_rgb_matrix); \
58 } while(0)
59
60 #define BC_GL_COLORS(shader) do { \
61         BC_GL_MATRIX(shader, yuv_to_rgb_matrix); \
62         BC_GL_MATRIX(shader, rgb_to_yuv_matrix); \
63         BC_GL_YMINF(shader, rgb_to_yuv_matrix); \
64 } while(0)
65
66
67 #define bc_gl_yuv_to_rgb "uniform mat3 yuv_to_rgb_matrix;\n"
68 #define bc_gl_rgb_to_yuv "uniform mat3 rgb_to_yuv_matrix;\n"
69 #define bc_gl_yminf      "uniform float yminf;\n"
70 #define bc_gl_colors bc_gl_yuv_to_rgb bc_gl_rgb_to_yuv bc_gl_yminf
71
72 // Macros for useful fragment shaders
73 #define YUV_TO_RGB_FRAG(PIXEL) \
74         PIXEL ".rgb -= vec3(yminf, 0.5, 0.5);\n" \
75         PIXEL ".rgb = yuv_to_rgb_matrix * " PIXEL ".rgb;\n"
76
77 #define RGB_TO_YUV_FRAG(PIXEL) \
78         PIXEL ".rgb = rgb_to_yuv_matrix * " PIXEL ".rgb;\n" \
79         PIXEL ".rgb += vec3(yminf, 0.5, 0.5);\n"
80
81 #define RGB_TO_HSV_FRAG(PIXEL) \
82         "{\n" \
83         "float r, g, b;\n" \
84         "float h, s, v;\n" \
85         "float min, max, delta;\n" \
86         "float f, p, q, t;\n" \
87         "r = " PIXEL ".r;\n" \
88         "g = " PIXEL ".g;\n" \
89         "b = " PIXEL ".b;\n" \
90         "min = ((r < g) ? r : g) < b ? ((r < g) ? r : g) : b;\n" \
91         "max = ((r > g) ? r : g) > b ? ((r > g) ? r : g) : b;\n" \
92         "v = max;\n" \
93         "delta = max - min;\n" \
94         "if(max != 0.0 && delta != 0.0)\n" \
95     "{\n" \
96         "    s = delta / max;\n" \
97         "       if(r == max)\n" \
98     "           h = (g - b) / delta;\n" \
99         "       else \n" \
100         "       if(g == max)\n" \
101     "           h = 2.0 + (b - r) / delta;\n" \
102         "       else\n" \
103     "           h = 4.0 + (r - g) / delta;\n" \
104         "\n" \
105         "       h *= 60.0;\n" \
106         "       if(h < 0.0)\n" \
107     "           h += 360.0;\n" \
108         "}\n" \
109         "else\n"  \
110         "{\n" \
111     "    s = 0.0;\n" \
112     "    h = -1.0;\n" \
113         "}\n" \
114         "" PIXEL ".r = h;\n" \
115         "" PIXEL ".g = s;\n" \
116         "" PIXEL ".b = v;\n" \
117         "}\n"
118
119 #define HSV_TO_RGB_FRAG(PIXEL) \
120         "{\n" \
121     "int i;\n" \
122         "float r, g, b;\n" \
123         "float h, s, v;\n" \
124         "float min, max, delta;\n" \
125         "float f, p, q, t;\n" \
126         "h = " PIXEL ".r;\n" \
127         "s = " PIXEL ".g;\n" \
128         "v = " PIXEL ".b;\n" \
129     "if(s == 0.0) \n" \
130         "{\n" \
131     "    r = g = b = v;\n" \
132     "}\n" \
133         "else\n" \
134         "{\n" \
135     "   h /= 60.0;\n" \
136     "   i = int(h);\n" \
137     "   f = h - float(i);\n" \
138     "   p = v * (1.0 - s);\n" \
139     "   q = v * (1.0 - s * f);\n" \
140     "   t = v * (1.0 - s * (1.0 - f));\n" \
141         "\n" \
142     "   if(i == 0)\n" \
143         "       {\n" \
144     "           r = v;\n" \
145     "           g = t;\n" \
146     "           b = p;\n" \
147     "    }\n" \
148         "       else\n" \
149         "       if(i == 1)\n" \
150         "       {\n" \
151     "           r = q;\n" \
152     "           g = v;\n" \
153     "           b = p;\n" \
154     "    }\n" \
155         "       else\n" \
156         "       if(i == 2)\n" \
157         "       {\n" \
158     "           r = p;\n" \
159     "           g = v;\n" \
160     "           b = t;\n" \
161     "   }\n" \
162         "       else\n" \
163         "       if(i == 3)\n" \
164         "       {\n" \
165     "           r = p;\n" \
166     "           g = q;\n" \
167     "           b = v;\n" \
168     "   }\n" \
169         "       else\n" \
170         "       if(i == 4)\n" \
171         "       {\n" \
172     "           r = t;\n" \
173     "           g = p;\n" \
174     "           b = v;\n" \
175     "    }\n" \
176         "       else\n" \
177         "       if(i == 5)\n" \
178         "       {\n" \
179     "           r = v;\n" \
180     "           g = p;\n" \
181     "           b = q;\n" \
182     "   }\n" \
183         "}\n" \
184         "" PIXEL ".r = r;\n" \
185         "" PIXEL ".g = g;\n" \
186         "" PIXEL ".b = b;\n" \
187         "}\n"
188
189 class Playback3DCommand : public BC_SynchronousCommand
190 {
191 public:
192         Playback3DCommand();
193         void copy_from(BC_SynchronousCommand *command);
194
195 // Extra commands
196         enum
197         {
198 // 5
199                 WRITE_BUFFER = LAST_COMMAND,
200                 CLEAR_OUTPUT,
201                 OVERLAY,
202                 DO_FADE,
203                 DO_MASK,
204                 PLUGIN,
205                 CLEAR_INPUT,
206                 DO_CAMERA,
207                 COPY_FROM,
208                 CONVERT_CMODEL
209         };
210
211         Canvas *canvas;
212         int is_cleared;
213
214 // Parameters for overlay command
215         float in_x1;
216         float in_y1;
217         float in_x2;
218         float in_y2;
219         float out_x1;
220         float out_y1;
221         float out_x2;
222         float out_y2;
223 // 0 - 1
224         float alpha;
225         int mode;
226         int interpolation_type;
227         VFrame *input;
228         int want_texture;
229         int is_nested;
230
231         int dst_cmodel;
232         int64_t start_position_project;
233         MaskAutos *keyframe_set;
234         MaskAuto *keyframe;
235         MaskAuto *default_auto;
236         PluginClient *plugin_client;
237 };
238
239
240 class Playback3D : public BC_Synchronous
241 {
242 public:
243         Playback3D(MWindow *mwindow);
244         ~Playback3D();
245
246         BC_SynchronousCommand* new_command();
247         void handle_command(BC_SynchronousCommand *command);
248
249 // Called by VDeviceX11::write_buffer during video playback
250         void write_buffer(Canvas *canvas,
251                 VFrame *frame,
252                 float in_x1,
253                 float in_y1,
254                 float in_x2,
255                 float in_y2,
256                 float out_x1,
257                 float out_y1,
258                 float out_x2,
259                 float out_y2,
260                 int is_cleared);
261
262 // Reads from pbuffer to either RAM or texture and updates the dst state
263 // want_texture - causes read into texture if 1
264         void copy_from(Canvas *canvas,
265                 VFrame *dst,
266                 VFrame *src,
267                 int want_texture = 0);
268
269 // Clear framebuffer before composing virtual console
270 // output - passed when rendering refresh frame.  If 0, the canvas is cleared.
271         void clear_output(Canvas *canvas, VFrame *output);
272
273         void do_fade(Canvas *canvas, VFrame *frame, float fade);
274         void convert_cmodel(Canvas *canvas, VFrame *output, int dst_cmodel);
275
276         void do_mask(Canvas *canvas,
277                 VFrame *output,
278                 int64_t start_position_project,
279                 MaskAutos *keyframe_set,
280                 MaskAuto *keyframe,
281                 MaskAuto *default_auto);
282
283
284 // Overlay a virtual node on the framebuffer
285         void overlay(Canvas *canvas,
286                 VFrame *input,
287                 float in_x1,
288                 float in_y1,
289                 float in_x2,
290                 float in_y2,
291                 float out_x1,
292                 float out_y1,
293                 float out_x2,
294                 float out_y2,
295                 float alpha,        // 0 - 1
296                 int mode,
297                 int interpolation_type,
298 // supplied if rendering single frame to PBuffer.
299                 VFrame *output = 0,
300                 int is_nested = 0);
301
302
303         int run_plugin(Canvas *canvas, PluginClient *client);
304
305         void clear_input(Canvas *canvas, VFrame *frame);
306         void do_camera(Canvas *canvas,
307                 VFrame *output,
308                 VFrame *input,
309                 float in_x1,
310                 float in_y1,
311                 float in_x2,
312                 float in_y2,
313                 float out_x1,
314                 float out_y1,
315                 float out_x2,
316                 float out_y2);
317
318 private:
319 // Called by write_buffer and clear_frame to initialize OpenGL flags
320         void init_frame(Playback3DCommand *command);
321         void write_buffer_sync(Playback3DCommand *command);
322         void draw_output(Playback3DCommand *command);
323         void clear_output_sync(Playback3DCommand *command);
324         void clear_input_sync(Playback3DCommand *command);
325         void overlay_sync(Playback3DCommand *command);
326 // Read frame buffer back into texture for overlay operation
327         void enable_overlay_texture(Playback3DCommand *command);
328         void do_fade_sync(Playback3DCommand *command);
329         void do_mask_sync(Playback3DCommand *command);
330         void run_plugin_sync(Playback3DCommand *command);
331         void do_camera_sync(Playback3DCommand *command);
332 //      void draw_refresh_sync(Playback3DCommand *command);
333         void copy_from_sync(Playback3DCommand *command);
334         void convert_cmodel_sync(Playback3DCommand *command);
335
336 // Print errors from shader compilation
337         void print_error(unsigned int object, int is_program);
338
339 // This quits the program when it's 1.
340         MWindow *mwindow;
341 // Temporaries for render to texture
342         BC_Texture *temp_texture;
343 // This is set by clear_output and used in compositing directly
344 // to the output framebuffer.
345         int canvas_w;
346         int canvas_h;
347 };
348
349
350
351
352 #endif