tweak zoom/fullscr to remember cwdw scale after fullscr
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / vframe.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2011 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 VFRAME_H
23 #define VFRAME_H
24
25 #include "arraylist.h"
26 #include "bcbitmap.inc"
27 #include "bchash.inc"
28 #include "bcpbuffer.inc"
29 #include "bctexture.inc"
30 #include "bcwindowbase.inc"
31 #include "bccmodels.h"
32 #include "vframe.inc"
33
34 // Maximum number of prev or next effects to be pushed onto the stacks.
35 #define MAX_STACK_ELEMENTS 255
36 #define SHM_MIN_SIZE 2048
37
38 // Scene graph for 3D models
39 // Defined by the subclass
40 class VFrameScene
41 {
42 public:
43         VFrameScene();
44         virtual ~VFrameScene();
45 };
46
47
48
49 class VFrame
50 {
51         friend class VFramePng;
52         friend class PngReadFunction;
53 public:
54 // Create new frame with shared data if *data is nonzero.
55 // Pass 0 to *data & -1 to shmid if private data is desired.
56         VFrame(int w,
57                 int h,
58                 int color_model,
59                 long bytes_per_line = -1);
60         VFrame(unsigned char *data,
61                 int shmid,
62                 int w,
63                 int h,
64                 int color_model /* = BC_RGBA8888 */,
65                 long bytes_per_line /* = -1 */);
66         VFrame(unsigned char *data,  // 0
67                 int shmid, // -1
68                 long y_offset,
69                 long u_offset,
70                 long v_offset,
71                 int w,
72                 int h,
73                 int color_model,  /* = BC_RGBA8888 */
74                 long bytes_per_line /* = -1 */);
75         VFrame(BC_Bitmap *bitmap,
76                 int w,
77                 int h,
78                 int color_model,
79                 long bytes_per_line);
80
81         VFrame(VFrame &vframe);
82 // Create new frame for compressed data.
83         VFrame();
84         virtual ~VFrame();
85
86 // Return 1 if the colormodel and dimensions are the same
87 // Used by FrameCache
88         int equivalent(VFrame *src, int test_stacks = 0);
89
90 // Reallocate a frame without deleting the class
91         int reallocate(
92                 unsigned char *data,   // Data if shared
93                 int shmid,             // shmid if IPC  -1 if not
94                 long y_offset,         // plane offsets if shared YUV
95                 long u_offset,
96                 long v_offset,
97                 int w,
98                 int h,
99                 int color_model,
100                 long bytes_per_line);        // -1 if unused
101
102         void set_memory(unsigned char *data,
103                 int shmid,
104                 long y_offset,
105                 long u_offset,
106                 long v_offset);
107         void set_memory(BC_Bitmap *bitmap);
108
109         void set_compressed_memory(unsigned char *data,
110                 int shmid,
111                 int data_size,
112                 int data_allocated);
113
114 // Write a PNG/PPM for debugging
115         int write_png(const char *path);
116         static void write_ppm(VFrame *vfrm, const char *fmt, ...);
117         void write_ppm(const char *path) { write_ppm(this, "%s", path); }
118 //static int n = 0; write_ppm(vframe, "/tmp/data/f%05d", ++n);
119
120 // if frame points to the same data as this return 1
121         int equals(VFrame *frame);
122 // Test if frame already matches parameters
123         int params_match(int w, int h, int color_model);
124 // Test if data values in the frame match
125         int data_matches(VFrame *frame);
126
127 //      long set_shm_offset(long offset);
128 //      long get_shm_offset();
129         int get_shmid() { return shmid; }
130         void set_use_shm(int value) { use_shm = value; }
131         int get_use_shm() { return use_shm; }
132
133 // direct copy with no alpha
134         int copy_from(VFrame *frame);
135         int copy_vframe(VFrame *src);
136 // BC_CModels::transfer
137         int transfer_from(VFrame *frame, int bg_color, int in_x, int in_y, int in_w, int in_h);
138         int transfer_from(VFrame *frame, int bg_color=0) {
139                 return transfer_from(frame, bg_color, 0,0, frame->get_w(),frame->get_h());
140         }
141 // Required for YUV
142         void black_frame();
143         void clear_frame();
144         int allocate_compressed_data(long bytes);
145
146 // Sequence number. -1 means invalid.  Passing frames to the encoder is
147 // asynchronous.  The sequence number must be preserved in the image itself
148 // to encode discontinuous frames.
149         long get_number() { return sequence_number; }
150         void set_number(long number) { sequence_number = number; }
151
152         int get_color_model() { return color_model; }
153 // Get the data pointer
154         unsigned char* get_data() { return data; }
155         long get_compressed_allocated() { return compressed_allocated; }
156         long get_compressed_size() { return compressed_size; }
157         void set_compressed_size(long size) { compressed_size = size; }
158         double get_timestamp() { return timestamp; }
159         void set_timestamp(double time) { timestamp = time; }
160
161 // return an array of pointers to rows
162         unsigned char** get_rows() { return rows; }
163         int get_memory_usage();
164 // accessors
165         int get_w() { return w; }
166         int get_h() { return h; }
167         int get_w_fixed() { return w - 1; }
168         int get_h_fixed() { return h - 1; }
169         unsigned char *get_y() { return y; }
170         unsigned char *get_u() { return u; }
171         unsigned char *get_v() { return v; }
172 // return rgba planes
173         unsigned char *get_r() { return y; }
174         unsigned char *get_g() { return u; }
175         unsigned char *get_b() { return v; }
176         unsigned char *get_a() { return a; }
177         void set_a(unsigned char *ap) { a = ap; }
178 // return yuv planes
179         static int get_scale_tables(int *column_table, int *row_table,
180                         int in_x1, int in_y1, int in_x2, int in_y2,
181                         int out_x1, int out_y1, int out_x2, int out_y2);
182         int get_bytes_per_pixel() { return bytes_per_pixel; }
183         long get_bytes_per_line();
184         int get_memory_type();
185
186         static int calculate_bytes_per_pixel(int colormodel);
187 // Get size + 4 for assembly language
188         static long calculate_data_size(int w, int h,
189                 int bytes_per_line = -1, int color_model = BC_RGB888);
190 // Get size of uncompressed frame buffer without extra 4 bytes
191         long get_data_size();
192 // alloc/reset temp vframe to spec
193         static void get_temp(VFrame *&vfrm, int w, int h, int color_model);
194
195         void rotate270();
196         void rotate90();
197         void flip_vert();
198         void flip_horiz();
199
200 // Convenience storage.
201 // Returns -1 if not set.
202         int get_field2_offset();
203         int set_field2_offset(int value);
204 // Set keyframe status
205         void set_keyframe(int value);
206         int get_keyframe();
207
208 // If the opengl state is RAM, transfer image from RAM to the texture
209 // referenced by this frame.
210 // If the opengl state is TEXTURE, do nothing.
211 // If the opengl state is SCREEN, switch the current drawable to the pbuffer and
212 // transfer the image to the texture with screen_to_texture.
213 // The opengl state is changed to TEXTURE.
214 // If no textures exist, textures are created.
215 // If the textures already exist, they are reused.
216 // Textures are resized to match the current dimensions.
217 // Must be called from a synchronous opengl thread after enable_opengl.
218         void to_texture();
219
220 // Transfer from PBuffer to RAM.
221 //   used in Playback3D::overlay_sync, plugin Overlay::handle_opengl
222         void screen_to_ram();
223
224 // Transfer contents of current pbuffer to texture,
225 // creating a new texture if necessary.
226 // Coordinates are the coordinates in the drawable to copy.
227         void screen_to_texture(int x = -1, int y = -1, int w = -1, int h = -1);
228
229 // Transfer contents of texture to the current drawable.
230 // Just calls the vertex functions but doesn't initialize.
231 // The coordinates are relative to the VFrame size and flipped to make
232 // the texture upright.
233 // The default coordinates are the size of the VFrame.
234 // flip_y flips the texture in the vertical direction and only used when
235 // writing to the final surface.
236         void draw_texture(float in_x1, float in_y1, float in_x2, float in_y2,
237                 float out_x1, float out_y1, float out_x2, float out_y2,
238                 int flip_y = 0);
239 // Draw the texture using the frame's size as the input and output coordinates.
240         void draw_texture(int flip_y = 0);
241
242
243
244
245
246
247
248 // ================================ OpenGL functions ===========================
249 // Defined in vframe3d.C
250 // Location of working image if OpenGL playback
251         int get_opengl_state();
252         void set_opengl_state(int value);
253 // OpenGL states
254         enum
255         {
256 // Undefined
257                 UNKNOWN,
258 // OpenGL image is in RAM
259                 RAM,
260 // OpenGL image is in texture
261                 TEXTURE,
262 // OpenGL image is composited in PBuffer or back buffer
263                 SCREEN
264         };
265
266 // Texture ID
267         int get_texture_id();
268         void set_texture_id(int id);
269 // Get window ID the texture is bound to
270         int get_window_id();
271         int get_texture_w();
272         int get_texture_h();
273         int get_texture_components();
274
275
276 // Binds the opengl context to this frame's PBuffer
277         void enable_opengl();
278
279 // Clears the pbuffer with the right values depending on YUV
280         void clear_pbuffer();
281
282 // Get the pbuffer
283         BC_PBuffer* get_pbuffer();
284
285 // Bind the frame's texture to GL_TEXTURE_2D and enable it.
286         void bind_texture(int texture_unit, int nearest=0);
287
288 // Create a frustum with 0,0 in the upper left and w,-h in the bottom right.
289 // Set preferred opengl settings.
290         static void init_screen(int w, int h);
291 // Calls init_screen with the current frame's dimensions.
292         void init_screen();
293
294 // color used by clear_frame, default -1 (unset) which clears to BLACK
295         void set_clear_color(int color, int alpha);
296         int get_clear_color();
297         int get_clear_alpha();
298
299 // Compiles and links the shaders into a program.
300 // Adds the program with put_shader.
301 // Returns the program handle.
302 // Requires a null terminated argument list of shaders to link together.
303 // if fragments is not NULL, it is a a zero terminated list of frags
304 // if fragments is NULL, then a zero terminated list of va_args frags
305 // At least one shader argument must have a main() function.  make_shader
306 // replaces all the main() functions with unique functions and calls them in
307 // sequence, so multiple independant shaders can be linked.
308         static unsigned int make_shader(const char **fragments, ...);
309         static void dump_shader(int shader_id);
310
311 // Because OpenGL is faster if multiple effects are combined, we need
312 // to provide ways for effects to aggregate.
313 // The prev_effect is the object providing the data to read_frame.
314 // The next_effect is the object which called read_frame.
315 // Push and pop are only called from Cinelerra internals, so
316 // if an object calls read_frame with a temporary, the stack before and after
317 // the temporary is lost.
318         void push_prev_effect(const char *name);
319         void pop_prev_effect();
320         void push_next_effect(const char *name);
321         void pop_next_effect();
322 // These are called by plugins to determine aggregation.
323 // They access any member of the stack based on the number argument.
324 // next effect 0 is the one that called read_frame most recently.
325 // prev effect 0 is the one that filled our call to read_frame.
326         const char* get_next_effect(int number = 0);
327         const char* get_prev_effect(int number = 0);
328
329 // It isn't enough to know the name of the neighboring effects.
330 // Relevant configuration parameters must be passed on.
331         BC_Hash* get_params();
332
333 // get/set read status  -1/err, 0/noxfer, 1/ok
334         int get_status() { return status; }
335         void set_status(int v) { status = v; }
336
337 // Compare stacks and params from 2 images and return 1 if equal.
338         int equal_stacks(VFrame *src);
339
340 // Copy stacks and params from another frame
341 // Replaces the stacks with the src stacks but only updates the params.
342         void copy_stacks(VFrame *src);
343 // Updates the params with values from src
344         void copy_params(VFrame *src);
345
346 // This clears the stacks and the param table
347         void clear_stacks();
348
349         virtual int draw_pixel(int x, int y);
350         int pixel_rgb, pixel_yuv, stipple;
351
352         void set_pixel_color(int rgb, int a=0xff);
353         void set_stiple(int mask);
354         void draw_line(int x1, int y1, int x2, int y2);
355         void draw_smooth(int x1, int y1, int x2, int y2, int x3, int y3);
356         void smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3);
357         void draw_rect(int x1, int y1, int x2, int y2);
358         void draw_arrow(int x1, int y1, int x2, int y2, int sz=10);
359         void draw_x(int x1, int y1, int sz=2);
360         void draw_t(int x1, int y1, int sz=2);
361         void draw_oval(int x1, int y1, int x2, int y2);
362
363 // 3D scene graphs
364 // Not integrated with shmem because that only affects codecs
365         VFrameScene* get_scene();
366
367 // Debugging
368         void dump_stacks();
369         void dump();
370
371         void dump_params();
372
373 private:
374
375 // 3D scene graphs
376 // Not integrated with shmem because that only affects codecs
377         VFrameScene *scene;
378
379 // Create a PBuffer matching this frame's dimensions and to be
380 // referenced by this frame.  Does nothing if the pbuffer already exists.
381 // If the frame is resized, the PBuffer is deleted.
382 // Called by enable_opengl.
383 // This allows PBuffers, textures, and bitmaps to travel through the entire
384 // rendering chain without requiring the user to manage a lot of objects.
385 // Must be called from a synchronous opengl thread after enable_opengl.
386         void create_pbuffer();
387
388         int clear_objects(int do_opengl);
389         int reset_parameters(int do_opengl);
390         void create_row_pointers();
391         int allocate_data(unsigned char *data,
392                 int shmid,
393                 long y_offset,
394                 long u_offset,
395                 long v_offset,
396                 int w,
397                 int h,
398                 int color_model,
399                 long bytes_per_line);
400
401 // Convenience storage
402         int field2_offset;
403         int memory_type;
404         enum
405         {
406                 PRIVATE,
407                 SHARED,
408                 SHMGET
409         };
410
411 // Data pointer is pointing to someone else's buffer.
412 //      long shm_offset;
413 // ID of shared memory if using IPC.
414 // The 1st 1 after reboot is 0.
415         int shmid;
416 // Local setting for shm usage
417         int use_shm;
418 // If not set by user, is calculated from color_model
419         long bytes_per_line;
420         int bytes_per_pixel;
421 // Image data
422         unsigned char *data;
423 // Pointers to the start of each row
424         unsigned char **rows;
425 // One of the #defines
426         int color_model;
427 // Allocated space for compressed data
428         long compressed_allocated;
429 // Size of stored compressed image
430         long compressed_size;
431 // Pointers to yuv / rgb planes
432         unsigned char *y, *u, *v;
433         long y_offset;
434         long u_offset;
435         long v_offset;
436 // Pointer to alpha plane
437         unsigned char *a;
438 // Dimensions of frame
439         int w, h;
440 // color used by clear_frame
441         int clear_color, clear_alpha;
442 // Info for reading png images
443         const unsigned char *image;
444         long image_offset;
445         long image_size;
446 // For writing discontinuous frames in background rendering
447         long sequence_number;
448         double timestamp;
449 // read status of input frame -1/err, 0/noxfr, 1/ok
450         int status;
451 // OpenGL support
452         int is_keyframe;
453 // State of the current texture
454         BC_Texture *texture;
455 // State of the current PBuffer
456         BC_PBuffer *pbuffer;
457
458 // Location of working image if OpenGL playback
459         int opengl_state;
460
461         ArrayList<char*> prev_effects;
462         ArrayList<char*> next_effects;
463         BC_Hash *params;
464 };
465
466 // Create a frame with the png image
467 class VFramePng : public VFrame {
468 // Read a PNG into the frame with alpha
469         int read_png(const unsigned char *data, long image_size, double xscale, double yscale);
470 public:
471         VFramePng(unsigned char *png_data, double s=0);
472         VFramePng(unsigned char *png_data, long image_size, double xs=0, double ys=0);
473         ~VFramePng();
474         static VFrame *vframe_png(int fd, double xs=1, double ys=1);
475         static VFrame *vframe_png(const char *png_path, double xs=1, double ys=1);
476 };
477
478 #endif