LiVES 3.2.0
effects.c
Go to the documentation of this file.
1// effects.c
2// LiVES (lives-exe)
3// (c) G. Finch <salsaman+lives@gmail.com> 2003 - 2020
4// Released under the GPL 3 or later
5// see file ../COPYING for licensing details
6
7#include "main.h"
8
9#include <fcntl.h>
10#include <string.h>
11#include <unistd.h>
12#include <stdlib.h>
13
14#include "effects.h"
15#include "effects-weed.h"
16#include "interface.h"
17#include "paramwindow.h"
18#include "cvirtual.h"
19#include "resample.h"
20#include "ce_thumbs.h"
21#include "callbacks.h"
22
24
25#ifdef HAVE_YUV4MPEG
26#include "lives-yuv4mpeg.h"
27#endif
28
29#include "rte_window.h"
30
31static weed_plant_t *resize_instance = NULL;
32
33static boolean apply_audio_fx;
34
36
37// generic
38
39
40char *lives_fx_cat_to_text(lives_fx_cat_t cat, boolean plural) {
41 // return value should be free'd after use
42 switch (cat) {
43 // main categories
45 if (!plural) return ((_("generator")));
46 else return ((_("Generators")));
48 if (!plural) return ((_("audio generator")));
49 else return ((_("Audio Generators")));
51 if (!plural) return ((_("audio/video generator")));
52 else return ((_("Audio/Video Generators")));
54 if (!plural) return ((_("data generator")));
55 else return ((_("Data Generators")));
57 if (!plural) return ((_("data visualiser")));
58 else return ((_("Data Visualisers")));
60 if (!plural) return ((_("data processor")));
61 else return ((_("Data Processors")));
63 if (!plural) return ((_("data source")));
64 else return ((_("Data Sources")));
66 if (!plural) return ((_("transition")));
67 else return ((_("Transitions")));
69 if (!plural) return ((_("effect")));
70 else return ((_("Effects")));
72 if (!plural) return ((_("utility")));
73 else return ((_("Utilities")));
75 if (!plural) return ((_("compositor")));
76 else return ((_("Compositors")));
78 if (!plural) return ((_("tap")));
79 else return ((_("Taps")));
81 if (!plural) return ((_("splitter")));
82 else return ((_("Splitters")));
84 if (!plural) return ((_("converter")));
85 else return ((_("Converters")));
87 if (!plural) return ((_("analyser")));
88 else return ((_("Analysers")));
89
90 // subcategories
92 if (!plural) return ((_("audio/video")));
93 else return ((_("Audio/Video Transitions")));
95 if (!plural) return ((_("video only")));
96 else return ((_("Video only Transitions")));
98 if (!plural) return ((_("audio only")));
99 else return ((_("Audio only Transitions")));
101 if (!plural) return ((_("audio")));
102 else return ((_("Audio Mixers")));
104 if (!plural) return ((_("audio")));
105 else return ((_("Audio Effects")));
107 if (!plural) return ((_("video")));
108 else return ((_("Video Effects")));
110 if (!plural) return ((_("audio volume controller")));
111 else return ((_("Audio Volume Controllers")));
113 if (!plural) return ((_("video analyser")));
114 else return ((_("Video Analysers")));
116 if (!plural) return ((_("audio analyser")));
117 else return ((_("Audio Analysers")));
118
119 default:
120 return ((_("unknown")));
121 }
122}
123
124
125// Rendered effects
126
127boolean do_effect(lives_rfx_t *rfx, boolean is_preview) {
128 // apply a rendered effect to the current file
129
130 // returns FALSE if the user cancelled
131 // leave_info_file is set if a preview turned into actual processing: ie. no params were changed after the preview
132 // preview generates .pre files instead of .mgk, so needs special post-processing
133
134 int oundo_start = cfile->undo_start;
135 int oundo_end = cfile->undo_end;
136 char effectstring[128];
137 double old_pb_fps = cfile->pb_fps;
138
139 char *text;
140 char *fxcommand = NULL, *cmd;
141 int current_file = mainw->current_file;
142
143 int new_file = current_file;
144 int ldfile;
145
146 boolean got_no_frames = FALSE;
147 char *tmp;
148
149 if (!CURRENT_CLIP_IS_VALID) return FALSE;
150
151 if (rfx->num_in_channels == 0 && !is_preview) current_file = mainw->pre_src_file;
152
153 if (is_preview) {
154 // generators start at 1, even though they have no initial frames
155 cfile->progress_start = cfile->undo_start = cfile->start;
156 cfile->progress_end = cfile->undo_end = cfile->end;
157 } else if (rfx->num_in_channels != 2) {
158 cfile->progress_start = cfile->undo_start = cfile->start;
159 cfile->progress_end = cfile->undo_end = cfile->end;
160 }
161
163 char *pdefault;
164 char *plugin_name;
165
166 if (rfx->status == RFX_STATUS_BUILTIN) plugin_name = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR,
168 else plugin_name = lives_strdup(rfx->name);
169
170 if (rfx->num_in_channels == 2) {
171 // transition has a few extra bits
172 pdefault = lives_strdup_printf("%s %d %d %d %d %d %s %f %s %d \"%s/%s\"", cfile->handle, rfx->status,
173 cfile->progress_start, cfile->progress_end, cfile->hsize, cfile->vsize,
174 get_image_ext_for_type(cfile->img_type), cfile->fps,
176 clipboard->start, prefs->workdir, clipboard->handle);
177 } else {
178 pdefault = lives_strdup_printf("%s %d %d %d %d %d %s %f", cfile->handle, rfx->status, cfile->progress_start,
179 cfile->progress_end, cfile->hsize, cfile->vsize, get_image_ext_for_type(cfile->img_type), cfile->fps);
180 }
181 // and append params
182 if (is_preview) {
183 cmd = lives_strdup("pfxrender");
185 } else cmd = lives_strdup("fxrender");
186 fxcommand = lives_strconcat(prefs->backend, " \"", cmd, "_", plugin_name, "\" ", pdefault,
187 (tmp = param_marshall(rfx, FALSE)), NULL);
188 lives_free(plugin_name);
189 lives_free(cmd);
190 lives_free(pdefault);
191 lives_free(tmp);
192 }
193
194 if (!mainw->keep_pre) lives_rm(cfile->info_file);
195
197 if (cfile->frame_index_back) {
198 lives_free(cfile->frame_index_back);
199 cfile->frame_index_back = NULL;
200 }
201 lives_system(fxcommand, FALSE);
202 lives_free(fxcommand);
203 } else {
207 }
208 }
210
211 if (cfile->clip_type == CLIP_TYPE_FILE && rfx->status != RFX_STATUS_WEED) {
212 // start decoding frames for the rendered effect plugins to start processing
213 cfile->fx_frame_pump = cfile->start;
214 if (!cfile->pumper) {
216 -1, "iiibV", mainw->current_file,
217 cfile->undo_start, cfile->undo_end, FALSE, NULL);
218 }
219 } else cfile->fx_frame_pump = 0;
220
221 if (is_preview) {
222 cfile->undo_start = oundo_start;
223 cfile->undo_end = oundo_end;
224 mainw->current_file = current_file;
225 return TRUE;
226 }
227
228 if (rfx->props & RFX_PROPS_MAY_RESIZE) {
229 tmp = (_("%s all frames..."));
230 text = lives_strdup_printf(tmp, _(rfx->action_desc));
231 } else {
232 if (rfx->num_in_channels == 2) {
233 tmp = (_("%s clipboard into frames %d to %d..."));
234 text = lives_strdup_printf(tmp, _(rfx->action_desc), cfile->progress_start, cfile->progress_end);
235 } else {
236 if (rfx->num_in_channels == 0) {
238 if (mainw->gen_to_clipboard) {
239 tmp = (_("%s to clipboard..."));
240 text = lives_strdup_printf(tmp, _(rfx->action_desc));
241 } else {
242 tmp = (_("%s to new clip..."));
243 text = lives_strdup_printf(tmp, _(rfx->action_desc));
244 }
245 } else {
246 tmp = (_("%s frames %d to %d..."));
247 text = lives_strdup_printf(tmp, _(rfx->action_desc), cfile->start, cfile->end);
248 }
249 }
250 }
251
252 if (!mainw->no_switch_dprint) d_print(""); // force switch text
253 ldfile = mainw->last_dprint_file;
254
255 d_print(text);
256 lives_free(text);
257 lives_free(tmp);
258 mainw->last_dprint_file = ldfile;
259
260 cfile->redoable = cfile->undoable = FALSE;
263
264 cfile->undo_action = UNDO_EFFECT;
265
266 if (rfx->props & RFX_PROPS_MAY_RESIZE) {
267 cfile->ohsize = cfile->hsize;
268 cfile->ovsize = cfile->vsize;
270 cfile->nokeep = TRUE;
271 }
272
273 // 'play' as fast as we possibly can
274 cfile->pb_fps = 1000000.;
275
276 if (rfx->num_in_channels == 2) {
277 tmp = (_("%s clipboard with selection"));
278 lives_snprintf(effectstring, 128, tmp, _(rfx->action_desc));
279 } else if (rfx->num_in_channels == 0) {
280 if (mainw->gen_to_clipboard) {
281 tmp = (_("%s to clipboard"));
282 lives_snprintf(effectstring, 128, tmp, _(rfx->action_desc));
283 } else {
284 tmp = (_("%s to new clip"));
285 lives_snprintf(effectstring, 128, tmp, _(rfx->action_desc));
286 }
287 } else {
288 tmp = (_("%s frames %d to %d"));
289 lives_snprintf(effectstring, 128, tmp, _(rfx->action_desc), cfile->undo_start, cfile->undo_end);
290 }
291 lives_free(tmp);
292
293 if (rfx->props & RFX_PROPS_MAY_RESIZE || rfx->num_in_channels == 0) {
294 if (rfx->status == RFX_STATUS_WEED) {
295 // set out_channel dimensions for resizers / generators
296 int error;
297 weed_plant_t *first_out = get_enabled_channel((weed_plant_t *)rfx->source, 0, FALSE);
298 weed_plant_t *first_ot = weed_get_plantptr_value(first_out, WEED_LEAF_TEMPLATE, &error);
299 weed_set_int_value(first_out, WEED_LEAF_WIDTH, weed_get_int_value(first_ot, WEED_LEAF_HOST_WIDTH, &error));
300 weed_set_int_value(first_out, WEED_LEAF_HEIGHT, weed_get_int_value(first_ot, WEED_LEAF_HOST_HEIGHT, &error));
301 }
302 }
303
304 if (!do_progress_dialog(TRUE, TRUE, effectstring) || mainw->error) {
305 if (cfile->pumper) {
307 cfile->pumper = NULL;
308 }
309 mainw->last_dprint_file = ldfile;
312 if (mainw->error) {
316 mainw->last_dprint_file = ldfile;
317 }
319 if (mainw->cancelled != CANCEL_KEEP) {
320 cfile->undo_start = oundo_start;
321 cfile->undo_end = oundo_end;
322 }
323 cfile->pb_fps = old_pb_fps;
326 cfile->nokeep = FALSE;
327 cfile->fx_frame_pump = 0;
328
329 if (cfile->start == 0) {
330 cfile->start = 1;
331 cfile->end = cfile->frames;
332 }
333
334 if (rfx->num_in_channels == 0 && mainw->current_file != current_file) {
336 close_current_file(current_file);
338 } else {
339 mainw->current_file = current_file;
340 do_rfx_cleanup(rfx);
342 }
343
346
347 if (mainw->multitrack) {
348 mainw->pre_src_file = -1;
349 }
350
351 return FALSE;
352 }
353
354 if (cfile->start == 0) {
355 cfile->start = 1;
356 cfile->end = cfile->frames;
357 }
358
359 do_rfx_cleanup(rfx);
360
362 cfile->nokeep = FALSE;
363 cfile->fx_frame_pump = 0;
364
365 if (!mainw->gen_to_clipboard) {
367 if (rfx->num_in_channels > 0) cfile->undoable = TRUE;
368 cfile->pb_fps = old_pb_fps;
371 if (rfx->num_in_channels > 0) set_undoable(rfx->menu_text, TRUE);
372 }
373
375
376 if (rfx->status != RFX_STATUS_WEED) {
377 int numtok = get_token_count(mainw->msg, '|');
378 if (numtok > 1) {
379 char **array = lives_strsplit(mainw->msg, "|", numtok);
380 // [0] is "completed"
381 if (numtok > 4) cfile->end = cfile->progress_end = cfile->start + atoi(array[4]) - 1;
382 if (rfx->props & RFX_PROPS_MAY_RESIZE || rfx->num_in_channels == 0) {
383 // get new frame size
384 uint64_t verhash = make_version_hash(rfx->rfx_version);
385 if (verhash >= 1008003) {
386 cfile->hsize = atoi(array[1]);
387 cfile->vsize = atoi(array[2]);
388 } else {
389 cfile->hsize = atoi(array[5]);
390 cfile->vsize = atoi(array[6]);
391 }
392 if (rfx->num_in_channels == 0) {
393 cfile->fps = cfile->pb_fps = strtod(array[3], NULL);
394 if (cfile->fps == 0.) cfile->fps = cfile->pb_fps = prefs->default_fps;
395 cfile->end = cfile->frames = atoi(array[4]);
396 cfile->bpp = cfile->img_type == IMG_TYPE_JPEG ? 24 : 32;
397 }
398 }
399 lives_strfreev(array);
400 }
401 if (rfx->num_in_channels == 0) {
402 cfile->progress_start = 1;
403 cfile->progress_end = cfile->frames;
404 }
405 } else {
406 int error;
407 weed_plant_t *first_out = get_enabled_channel((weed_plant_t *)rfx->source, 0, FALSE);
408 weed_plant_t *first_ot = weed_get_plantptr_value(first_out, WEED_LEAF_TEMPLATE, &error);
409 cfile->hsize = weed_get_int_value(first_ot, WEED_LEAF_HOST_WIDTH, &error);
410 cfile->vsize = weed_get_int_value(first_ot, WEED_LEAF_HOST_HEIGHT, &error);
411 }
412
413 if (rfx->num_in_channels > 0) {
414 if (cfile->hsize == cfile->ohsize && cfile->vsize == cfile->ovsize) cfile->undo_action = UNDO_EFFECT;
415 else {
416 boolean bad_header = FALSE;
417 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_WIDTH, &cfile->hsize)) bad_header = TRUE;
418 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_HEIGHT, &cfile->vsize)) bad_header = TRUE;
419 cfile->undo_action = UNDO_RESIZABLE;
420 if (bad_header) do_header_write_error(mainw->current_file);
421 }
422 }
423
425 mainw->error = FALSE;
426
427 if (mainw->keep_pre) {
428 // this comes from a preview which then turned into processing
429 // the processing is the same as usual, except we use a different file extension (.pre instead of .mgk)
430 char *com = lives_strdup_printf("%s mv_pre \"%s\" %d %d \"%s\"", prefs->backend_sync, cfile->handle, cfile->progress_start,
431 cfile->progress_end, get_image_ext_for_type(cfile->img_type));
432
433 lives_rm(cfile->info_file);
435 lives_system(com, FALSE);
436 lives_free(com);
438
440
441 if (mainw->error) {
442 if (!mainw->cancelled) {
444 do_info_dialog(_("\nNo frames were generated.\n"));
448 else d_print_failed();
449
450 if (rfx->num_in_channels == 0) {
452
453 if (mainw->current_file != current_file) {
455 close_current_file(current_file);
457 }
458
459 mainw->current_file = current_file;
460 mainw->last_dprint_file = ldfile;
461
462 if (mainw->multitrack) {
463 mainw->current_file = mainw->multitrack->render_file;
464 }
465 }
467 return FALSE;
468 }
469 }
470
471 if (rfx->num_in_channels == 0) {
472 if (rfx->props & RFX_PROPS_BATCHG) {
473 // batch mode generators need some extra processing
474 char *imgdir = lives_build_path(prefs->workdir, cfile->handle, NULL);
475 int img_file = mainw->current_file;
476
478 open_file_sel(imgdir, 0, 0);
479 lives_free(imgdir);
480 new_file = mainw->current_file;
481
482 if (new_file != img_file) {
483 mainw->current_file = img_file;
484
485 lives_snprintf(mainw->files[new_file]->name, CLIP_NAME_MAXLEN, "%s", cfile->name);
486 lives_snprintf(mainw->files[new_file]->file_name, PATH_MAX, "%s", cfile->file_name);
487
489
490 mainw->files[new_file]->fps = mainw->files[new_file]->pb_fps = cfile->fps;
491 } else got_no_frames = TRUE;
492
493 close_current_file(current_file);
495
496 if (!got_no_frames) mainw->current_file = new_file;
497 } else {
498 // TODO - use check_clip_intergity()
499 char *tfile = make_image_file_name(cfile, cfile->frames, get_image_ext_for_type(cfile->img_type));
500
501 if (!lives_file_test(tfile, LIVES_FILE_TEST_EXISTS)) {
503 cfile->end = cfile->frames;
504 }
505 lives_free(tfile);
506 }
507
508 if (got_no_frames || cfile->frames <= 0) {
510 if (!mainw->cancelled) {
512 do_info_dialog(_("\nNo frames were generated.\n"));
515 } else d_print_cancelled();
516 if (!got_no_frames) {
518 close_current_file(current_file);
520 }
521 mainw->last_dprint_file = ldfile;
523 if (mainw->multitrack) mainw->current_file = mainw->multitrack->render_file;
524 return FALSE;
525 }
526
527 if (mainw->gen_to_clipboard) {
528 // here we will copy all values to the clipboard, including the handle
529 // then close the current file without deleting the frames
530
532
534 cfile->is_loaded = TRUE;
537
538 close_current_file(current_file);
539
542
543 new_file = current_file;
544
546 } else {
547 if (!(rfx->props & RFX_PROPS_BATCHG)) {
548 // gen to new file
549 cfile->is_loaded = TRUE;
551 if (!save_clip_values(new_file)) {
552 close_current_file(current_file);
553 return FALSE;
554 }
555
557
558 if (mainw->multitrack) {
561 }
562
563 }
565 }
567 }
568
569 if (!mainw->gen_to_clipboard) cfile->changed = TRUE;
570 if (!mainw->multitrack) {
571 if (new_file != -1) {
572 lives_sync(1);
573 switch_clip(1, new_file, TRUE);
574 }
575 } else {
576 mainw->current_file = mainw->multitrack->render_file;
577 mainw->pre_src_file = -1;
578 }
579
580 d_print_done();
583 mainw->last_dprint_file = ldfile;
584
585 return TRUE;
586}
587
588
589// realtime fx
590
592 static lives_render_error_t write_error;
593
594 LiVESError *error = NULL;
595
596 char oname[PATH_MAX];
597
598 LiVESPixbuf *pixbuf;
599
600 ticks_t frameticks;
601
602 weed_layer_t *layer;
603
604 char *com, *tmp;
605
606 static int i;
607
608 int weed_error;
609 int layer_palette;
610 int retval;
611
612 // this is called periodically from do_processing_dialog for internal effects
613
614 if (reset) {
615 i = cfile->start;
617
618 if (cfile->clip_type == CLIP_TYPE_FILE) {
619 if (cfile->frame_index_back) lives_free(cfile->frame_index_back);
620 cfile->frame_index_back = frame_index_copy(cfile->frame_index, cfile->frames, 0);
621 }
622 write_error = LIVES_RENDER_ERROR_NONE;
623 return LIVES_RENDER_READY;
624 }
625
627
628 // sig_progress...
629 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, "%d", i);
630 // load, effect, save frame
631
632 // skip resizing virtual frames
633 if (resize_instance && is_virtual_frame(mainw->current_file, i)) {
634 if (++i > cfile->end) {
636 lives_snprintf(mainw->msg, 9, "completed");
638 }
640 }
641
642 if (has_video_filters(FALSE) || resize_instance) {
643 frameticks = (i - cfile->start + 1.) / cfile->fps * TICKS_PER_SECOND;
644 THREADVAR(rowstride_alignment_hint) = 4;
646 if (!pull_frame(layer, get_image_ext_for_type(cfile->img_type), frameticks)) {
647 // do_read_failed_error_s() cannot be used here as we dont know the filename
648 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, "error|missing image %d", i);
650 }
651
652 layer = on_rte_apply(layer, 0, 0, (weed_timecode_t)frameticks);
653
654 if (!has_video_filters(TRUE) || resize_instance) {
655 layer_palette = weed_get_int_value(layer, WEED_LEAF_CURRENT_PALETTE, &weed_error);
656
657 if (!resize_instance) resize_layer(layer, cfile->hsize, cfile->vsize, LIVES_INTERP_BEST, layer_palette, 0);
658 if (cfile->img_type == IMG_TYPE_JPEG && layer_palette != WEED_PALETTE_RGB24 && layer_palette != WEED_PALETTE_RGBA32) {
659 convert_layer_palette(layer, WEED_PALETTE_RGB24, 0);
660 layer_palette = WEED_PALETTE_RGB24;
661 } else if (cfile->img_type == IMG_TYPE_PNG && layer_palette != WEED_PALETTE_RGBA32) {
662 convert_layer_palette(layer, WEED_PALETTE_RGBA32, 0);
663 layer_palette = WEED_PALETTE_RGBA32;
664 }
665
666 pixbuf = layer_to_pixbuf(layer, TRUE, FALSE);
667 weed_plant_free(layer);
668
670 lives_snprintf(oname, PATH_MAX, "%s", tmp);
671 lives_free(tmp);
672
673 do {
674 retval = 0;
675 lives_pixbuf_save(pixbuf, oname, cfile->img_type, 100, cfile->hsize, cfile->vsize, &error);
676
677 if (error) {
678 retval = do_write_failed_error_s_with_retry(oname, error->message);
679 lives_error_free(error);
680 error = NULL;
681 if (retval != LIVES_RESPONSE_RETRY) write_error = LIVES_RENDER_ERROR_WRITE_FRAME;
682 }
683 } while (retval == LIVES_RESPONSE_RETRY);
684
686
687 if (cfile->clip_type == CLIP_TYPE_FILE) {
688 cfile->frame_index[i - 1] = -1;
689 }
690 } else weed_plant_free(layer);
691 }
692 if (apply_audio_fx) {
693 if (!apply_rte_audio((double)cfile->arate / (double)cfile->fps + (double)rand() / .5 / (double)(RAND_MAX))) {
695 }
696 }
697
698 if (++i > cfile->end) {
699 if (resize_instance || (has_video_filters(FALSE) && !has_video_filters(TRUE))) {
700 mainw->error = FALSE;
702 com = lives_strdup_printf("%s mv_mgk \"%s\" %d %d \"%s\"", prefs->backend, cfile->handle, cfile->start,
703 cfile->end, get_image_ext_for_type(cfile->img_type));
704 lives_system(com, FALSE);
705 lives_free(com);
707
709
710 if (mainw->error) write_error = LIVES_RENDER_ERROR_WRITE_FRAME;
711 //cfile->may_be_damaged=TRUE;
712 else {
713 if (cfile->clip_type == CLIP_TYPE_FILE) {
715 }
717 }
718 } else {
719 sprintf(mainw->msg, "%s", "completed");
721 }
722 }
723 if (write_error) return write_error;
725}
726
727
728boolean on_realfx_activate_inner(int type, lives_rfx_t *rfx) {
729 // type can be 0 - apply current realtime effects
730 // 1 - resize (using weed filter)
731 boolean retval;
732
733 boolean has_new_audio = FALSE;
734
735 apply_audio_fx = FALSE;
736
737 if (type == 0 && ((cfile->achans > 0 && prefs->audio_src == AUDIO_SRC_INT && has_audio_filters(AF_TYPE_ANY)) ||
738 mainw->agen_key != 0)) {
739 if (mainw->agen_key != 0 && cfile->achans == 0) {
740 // apply audio gen to clip with no audio - prompt for audio settings
741 resaudw = create_resaudw(2, NULL, NULL);
742 /* lives_widget_context_update(); */
743 /* lives_xwindow_raise(lives_widget_get_xwindow(resaudw->dialog)); */
744
745 if (lives_dialog_run(LIVES_DIALOG(resaudw->dialog)) != LIVES_RESPONSE_OK) return FALSE;
746 if (mainw->error) {
747 mainw->error = FALSE;
748 return FALSE;
749 }
750 has_new_audio = TRUE;
751 }
752 apply_audio_fx = TRUE;
753 if (!apply_rte_audio_init()) return FALSE;
754
755 }
756
757 if (type == 1) resize_instance = (weed_plant_t *)rfx->source;
758 else resize_instance = NULL;
759
761
764
766
767 retval = do_effect(rfx, FALSE);
768
769 if (apply_audio_fx) {
770 apply_rte_audio_end(!retval);
771
772 if (retval) {
774
775 cfile->undo_achans = cfile->achans;
776 cfile->undo_arate = cfile->arate;
777 cfile->undo_arps = cfile->arps;
778 cfile->undo_asampsize = cfile->asampsize;
779 cfile->undo_signed_endian = cfile->signed_endian;
780
781 } else {
782 if (has_new_audio) cfile->achans = cfile->asampsize = cfile->arate = cfile->arps = 0;
783 else {
784 char *com = lives_strdup_printf("%s undo_audio %s", prefs->backend_sync, cfile->handle);
785 lives_rm(cfile->info_file);
786 lives_system(com, FALSE);
787 lives_free(com);
788 }
789 }
791 }
792
794 resize_instance = NULL;
795 return retval;
796}
797
798
799void on_realfx_activate(LiVESMenuItem *menuitem, livespointer xrfx) {
800 lives_rfx_t *rfx = (lives_rfx_t *)xrfx;
801 uint32_t chk_mask = 0;
802 int type = 1;
803
804 // type can be 0 - apply current realtime effects
805 // 1 - resize (using weed filter) [menuitem == NULL]
806
807 if (menuitem) {
808 int i;
809 for (i = 0; i < FX_KEYS_MAX_VIRTUAL; i++) {
810 if (rte_key_valid(i + 1, TRUE)) {
811 if (rte_key_is_enabled(1 + i)) {
812 weed_plant_t *filter = rte_keymode_get_filter(i + 1, rte_key_getmode(i + 1));
813 if (is_pure_audio(filter, TRUE)) {
815 } else chk_mask = WARN_MASK_LAYOUT_ALTER_FRAMES;
816 }
817 }
818 }
819 if (chk_mask > 0) {
820 if (!check_for_layout_errors(NULL, mainw->current_file, cfile->start, cfile->end, &chk_mask)) {
821 return;
822 }
823 }
824 type = 0;
825 }
826
827 if (!on_realfx_activate_inner(type, rfx)) {
829 return;
830 }
831 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
832}
833
834
835static weed_layer_t *get_blend_layer_inner(weed_timecode_t tc) {
836 static weed_timecode_t blend_tc = 0;
837 lives_clip_t *blend_file;
838 weed_timecode_t ntc = tc;
839
840 if (!IS_VALID_CLIP(mainw->blend_file)) return NULL;
841 blend_file = mainw->files[mainw->blend_file];
842
844 // mainw->last_blend_file is set to -1 on playback start
846 blend_file->last_frameno = blend_file->frameno;
847 blend_tc = tc;
848 }
849
850 if (!cfile->play_paused) {
851 blend_file->frameno = calc_new_playback_position(mainw->blend_file, blend_tc, (ticks_t *)&ntc);
852 blend_file->last_frameno = blend_file->frameno;
853 blend_tc = ntc;
854 }
855
858 return mainw->blend_layer;
859}
860
861void get_blend_layer(weed_timecode_t tc) {
863 if (mainw->blend_file > -1 && mainw->num_tr_applied > 0
864 && (!mainw->files[mainw->blend_file] ||
868 // invalid blend file
870 }
871
873 IS_VALID_CLIP(mainw->blend_file) && !resize_instance) {
874 get_blend_layer_inner(tc);
875 }
876}
877
878
879weed_plant_t *on_rte_apply(weed_layer_t *layer, int opwidth, int opheight, weed_timecode_t tc) {
880 // apply realtime effects to a layer
881 // mainw->filter_map is used as a guide
882 // mainw->pchains holds the parameter values for interpolation
883 // creates a temporary mix layer from mainw->blend_file (correcting its value if necessary)
884
885 // returns the effected layer
886
887 weed_plant_t **layers, *retlayer;
888 int i;
889
890 if (mainw->foreign) return NULL;
891
892 layers = (weed_plant_t **)lives_malloc(3 * sizeof(weed_plant_t *));
893 layers[0] = layer;
894 layers[1] = mainw->blend_layer;
895 layers[2] = NULL;
896
897 if (resize_instance) {
899 weed_plant_t *init_event = weed_plant_new(WEED_PLANT_EVENT);
900 weed_set_int_value(init_event, WEED_LEAF_IN_TRACKS, 0);
901 weed_set_int_value(init_event, WEED_LEAF_OUT_TRACKS, 0);
902
903 (void)(ret = weed_apply_instance(resize_instance, init_event, layers, 0, 0, tc));
904
905 retlayer = layers[0];
906 weed_plant_free(init_event);
907 } else {
908 retlayer = weed_apply_effects(layers, mainw->filter_map, tc, opwidth, opheight, mainw->pchains);
909 }
910
911 // all our pixel_data will have been free'd already
912 for (i = 0; layers[i]; i++) {
913 if (layers[i] != retlayer) weed_layer_free(layers[i]);
914 }
915 lives_free(layers);
916 return retlayer;
917}
918
919
920void deinterlace_frame(weed_layer_t *layer, weed_timecode_t tc) {
921 weed_plant_t **layers;
922
923 weed_plant_t *deint_filter, *deint_instance, *next_inst, *init_event, *orig_instance;
924
925 int deint_idx, error;
926
928
929 deint_idx = LIVES_POINTER_TO_INT(lives_list_nth_data(mainw->fx_candidates[FX_CANDIDATE_DEINTERLACE].list,
931
932 deint_filter = get_weed_filter(deint_idx);
933
934 orig_instance = deint_instance = weed_instance_from_filter(deint_filter);
935
936 layers = (weed_plant_t **)lives_malloc(2 * sizeof(weed_plant_t *));
937
938 layers[1] = NULL;
939
940 layers[0] = layer;
941
942 init_event = weed_plant_new(WEED_PLANT_EVENT);
943 weed_set_int_value(init_event, WEED_LEAF_IN_TRACKS, 0);
944 weed_set_int_value(init_event, WEED_LEAF_OUT_TRACKS, 0);
945
946deint1:
947
948 weed_apply_instance(deint_instance, init_event, layers, 0, 0, tc);
949
950 if (weed_plant_has_leaf(deint_instance, WEED_LEAF_HOST_NEXT_INSTANCE)) next_inst = weed_get_plantptr_value(deint_instance,
952 else next_inst = NULL;
953
954 weed_call_deinit_func(deint_instance);
955 weed_instance_unref(deint_instance);
956
957 if (next_inst) {
958 deint_instance = next_inst;
959 goto deint1;
960 }
961
962 weed_instance_unref(orig_instance);
963
964 weed_plant_free(init_event);
965
966 lives_free(layers);
967}
968
969
971// keypresses
972// TODO - we should mutex lock mainw->rte
973
974boolean rte_on_off_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod,
975 livespointer user_data) {
976 // this is the callback which happens when a rte is keyed
977 // key is 1 based, but if < 0 then this indicates auto mode (set via data connection)
978 // in automode we don't add the effect parameters in ce_thumbs mode
979 // if non-automode, the user overrides effect toggling
980
981 int key = LIVES_POINTER_TO_INT(user_data);
982 uint64_t new_rte;
983
984 if (mainw->go_away) return TRUE;
985 if (!LIVES_IS_INTERACTIVE && group) return TRUE;
986
988
990
991 if (key < 0) {
993 key = -key;
994 }
995
996 if (key == EFFECT_NONE) {
997 // switch up/down keys to default (fps change)
999 } else {
1000 // the idea here is this gets set if a generator starts play, because in weed_init_effect() we will run playback
1001 // and then we come out of there and do not wish to set the key on
1002 key--;
1003 new_rte = GU641 << (key);
1005
1006 if (!(mainw->rte & new_rte)) {
1007 // switch is ON
1008 // WARNING - if we start playing because a generator was started, we block here
1009 filter_mutex_lock(key);
1010 //if (!LIVES_IS_PLAYING) {
1011 if (!(weed_init_effect(key))) {
1012 // ran out of instance slots, no effect assigned, or some other error
1013 // or gen started playback and then stopped
1014 pthread_mutex_lock(&mainw->event_list_mutex);
1015 if (mainw->rte & new_rte) mainw->rte ^= new_rte;
1016 pthread_mutex_unlock(&mainw->event_list_mutex);
1017 if (rte_window) rtew_set_keych(key, FALSE);
1021 return TRUE;
1022 }
1023
1024 if (!mainw->gen_started_play) {
1025 pthread_mutex_lock(&mainw->event_list_mutex);
1026 if (!(mainw->rte & new_rte)) mainw->rte |= new_rte;
1027 pthread_mutex_unlock(&mainw->event_list_mutex);
1028
1029 if (!LIVES_IS_PLAYING) {
1030 // if anything is connected to ACTIVATE, the fx may be activated
1031 // during playback this is checked when we play a frame
1032 for (int i = 0; i < FX_KEYS_MAX_VIRTUAL; i++) {
1033 if (rte_key_valid(i + 1, TRUE)) {
1034 if (!rte_key_is_enabled(1 + i)) {
1036 // *INDENT-OFF*
1037 }}}}
1038 // *INDENT-ON*
1039
1041 if (rte_window) rtew_set_keych(key, TRUE);
1042 if (mainw->ce_thumbs) {
1044
1045 // if effect was auto (from ACTIVATE data connection), leave all param boxes
1046 // otherwise, remove any which are not "pinned"
1048 }
1049 }
1051 } else {
1052 // effect is OFF
1053 filter_mutex_lock(key);
1054 if (weed_deinit_effect(key)) {
1055 pthread_mutex_lock(&mainw->event_list_mutex);
1056 if (mainw->rte & new_rte) mainw->rte ^= new_rte;
1057 pthread_mutex_unlock(&mainw->event_list_mutex);
1058 }
1060 if (!LIVES_IS_PLAYING) {
1061 // if anything is connected to ACTIVATE, the fx may be de-activated
1062 // during playback this is checked when we play a frame
1063 for (int i = 0; i < FX_KEYS_MAX_VIRTUAL; i++) {
1064 if (rte_key_valid(i + 1, TRUE)) {
1065 if (rte_key_is_enabled(1 + i)) {
1067 // *INDENT-OFF*
1068 }}}}
1069 // *INDENT-ON*
1070
1071 if (rte_window) rtew_set_keych(key, FALSE);
1073 }
1074 }
1075
1077
1078 if (mainw->rendered_fx) {
1079 if (mainw->rendered_fx[0].menuitem && LIVES_IS_WIDGET(mainw->rendered_fx[0].menuitem)) {
1080 if (!LIVES_IS_PLAYING
1082 || (cfile->achans > 0 && prefs->audio_src == AUDIO_SRC_INT
1086 }
1087 }
1088
1089 if (key > 0 && !mainw->fx_is_auto) {
1090 // user override any ACTIVATE data connection
1092
1093 // if this is an outlet for ACTIVATE, disable the override now
1095 }
1096
1097 if (LIVES_IS_PLAYING && CURRENT_CLIP_IS_VALID && cfile->play_paused) {
1099 }
1100
1102 return TRUE;
1103}
1104
1105
1106boolean rte_on_off_callback_hook(LiVESToggleButton * button, livespointer user_data) {
1107 rte_on_off_callback(NULL, NULL, 0, (LiVESXModifierType)0, user_data);
1108 return TRUE;
1109}
1110
1111
1112boolean grabkeys_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
1113 livespointer user_data) {
1114 // assign the keys to the last key-grabbable effect
1115 int fx = LIVES_POINTER_TO_INT(user_data);
1116 if (fx != -1) {
1118 }
1120 mainw->osc_block = TRUE;
1121 if (rte_window) {
1122 if (group) rtew_set_keygr(mainw->rte_keys);
1123 }
1124 if (mainw->rte_keys == -1) {
1126 return TRUE;
1127 }
1132 return TRUE;
1133}
1134
1135
1136boolean textparm_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
1137 livespointer user_data) {
1138 // keyboard linked to first string parameter, until TAB is pressed
1140 return TRUE;
1141}
1142
1143
1144boolean grabkeys_callback_hook(LiVESToggleButton * button, livespointer user_data) {
1145 if (!lives_toggle_button_get_active(button)) return TRUE;
1146 grabkeys_callback(NULL, NULL, 0, (LiVESXModifierType)0, user_data);
1147 return TRUE;
1148}
1149
1150
1151boolean rtemode_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
1152 livespointer user_data) {
1153 int dirn = LIVES_POINTER_TO_INT(user_data);
1154 // "m" mode key
1155 if (mainw->rte_keys == -1) return TRUE;
1156 rte_key_setmode(0, dirn == PREV_MODE_CYCLE ? -2 : -1);
1160 return TRUE;
1161}
1162
1163
1164boolean rtemode_callback_hook(LiVESToggleButton * button, livespointer user_data) {
1165 int key_mode = LIVES_POINTER_TO_INT(user_data);
1166 int modes = rte_getmodespk();
1167 int key = (int)(key_mode / modes);
1168 int mode = key_mode - key * modes;
1169
1170 if (!lives_toggle_button_get_active(button)) return TRUE;
1171
1172 rte_key_setmode(key + 1, mode);
1173 return TRUE;
1174}
1175
1176
1177boolean swap_fg_bg_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
1178 livespointer user_data) {
1179 int blend_file = mainw->blend_file;
1180
1182 || mainw->blend_file == mainw->current_file || mainw->preview || (mainw->is_processing && cfile->is_loaded)) {
1183 return TRUE;
1184 }
1185
1186 if (mainw->swapped_clip == -1) {
1187 // this is to avoid an annoying situation in VJ playback, where the cliplist postion
1188 // can keep getting reset each time we swap the fg and bg
1192 } else mainw->swapped_clip = -1;
1193
1194 //rte_swap_fg_bg();
1195
1196 mainw->new_clip = blend_file;
1197 //do_quick_switch(blend_file); // will set mainw->blend_file
1198
1202
1203 mainw->blend_palette = WEED_PALETTE_END;
1204
1205 return TRUE;
1206
1207 // **TODO - for weed, invert all transition parameters for any active effects
1208}
1209
1211
1212
1214 // key starts at 1
1215 return !((mainw->rte & (GU641 << --key)) == 0ll);
1216}
1217
1218
1220 return prefs->max_modes_per_key;
1221}
1222
1223
1225 // key is 1 based, or < 0 for auto mode
1226 rte_on_off_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(key));
1227
1228 return rte_key_is_enabled(key);
1229}
1230
1231
1232boolean rte_key_on_off(int key, boolean on) {
1233 // key is 1 based
1234 // returns the state of the key afterwards
1235 uint64_t new_rte;
1236 if (key < 1 || key >= FX_KEYS_MAX_VIRTUAL) return FALSE;
1237 key--;
1238 new_rte = GU641 << (key);
1239 if (mainw->rte & new_rte) {
1240 if (on) return TRUE;
1241 } else if (!on) return FALSE;
1242 key++;
1243 rte_on_off_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(key));
1244 return (mainw->rte & new_rte);
1245}
1246
1247
1249 // switch off all realtime effects
1250 rte_on_off_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(EFFECT_NONE));
1251}
1252
1253
1254static int backup_key_modes[FX_KEYS_MAX_VIRTUAL];
1255static uint64_t backup_rte = 0;
1256
1257void rte_keymodes_backup(int nkeys) {
1258 // backup the current key/mode state
1259 int i;
1260
1261 backup_rte = mainw->rte;
1262
1263 for (i = 0; i < nkeys; i++) {
1264 backup_key_modes[i] = rte_key_getmode(i + 1);
1265 }
1266}
1267
1268
1269void rte_keymodes_restore(int nkeys) {
1270 int i;
1271
1273 mainw->rte = backup_rte;
1274
1275 for (i = 0; i < nkeys; i++) {
1276 // set the mode
1277 rte_key_setmode(i + 1, backup_key_modes[i]);
1278 // activate the key
1279 if ((mainw->rte & GU641 << (i)) != 0) rte_key_toggle(i + 1);
1280 }
1281 if (mainw->rte_keys != -1) {
1285 }
1286}
boolean apply_rte_audio(int64_t nframes)
Definition: audio.c:3514
void apply_rte_audio_end(boolean del)
Definition: audio.c:3507
boolean apply_rte_audio_init(void)
Definition: audio.c:3474
void popup_lmap_errors(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9335
void switch_clip(int type, int newclip, boolean force)
Definition: callbacks.c:6900
void lives_notify(int msgnumber, const char *msgstring)
Definition: callbacks.c:49
boolean check_for_layout_errors(const char *operation, int fileno, int start, int end, uint32_t *in_mask)
check for layout errors, using in_mask as a guide (mask values are taken from prefs->warn_mask,...
Definition: callbacks.c:4059
void ce_thumbs_highlight_current_clip(void)
Definition: ce_thumbs.c:673
void ce_thumbs_set_keych(int key, boolean on)
Definition: ce_thumbs.c:106
void ce_thumbs_add_param_box(int key, boolean remove)
Definition: ce_thumbs.c:456
LIVES_GLOBAL_INLINE weed_layer_t * lives_layer_new_for_frame(int clip, frames_t frame)
Definition: colourspace.c:9833
LiVESPixbuf * layer_to_pixbuf(weed_layer_t *layer, boolean realpalette, boolean fordisplay)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
boolean convert_layer_palette(weed_layer_t *layer, int outpl, int op_clamping)
boolean resize_layer(weed_layer_t *layer, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint)
resize a layer
weed_plant_t weed_layer_t
Definition: colourspace.h:71
frames_t * frame_index_copy(frames_t *findex, frames_t nframes, frames_t offset)
Definition: cvirtual.c:1052
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
Definition: cvirtual.c:719
boolean save_frame_index(int fileno)
Definition: cvirtual.c:56
boolean check_if_non_virtual(int fileno, frames_t start, frames_t end)
Definition: cvirtual.c:644
boolean is_virtual_frame(int sfileno, frames_t frame)
Definition: cvirtual.c:1063
boolean do_header_write_error(int clip)
Definition: dialogs.c:4169
LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog(const char *text)
Definition: dialogs.c:787
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4058
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
boolean do_progress_dialog(boolean visible, boolean cancellable, const char *text)
Definition: dialogs.c:2274
boolean check_backend_return(lives_clip_t *sfile)
Definition: dialogs.c:1009
boolean pconx_chain_data(int key, int mode, boolean is_audio_thread)
void override_if_active_input(int hotkey)
Definition: effects-data.c:98
void end_override_if_activate_output(int hotkey)
Definition: effects-data.c:126
lives_filter_error_t weed_apply_instance(weed_plant_t *inst, weed_plant_t *init_event, weed_plant_t **layers, int opwidth, int opheight, weed_timecode_t tc)
process a single video filter instance
LIVES_GLOBAL_INLINE int filter_mutex_unlock(int key)
Definition: effects-weed.c:108
int rte_key_getmode(int key)
returns current active mode for a key (or -1)
boolean has_video_filters(boolean analysers_only)
void weed_deinit_all(boolean shutdown)
deinit all effects (except generators* during playback) this is called on ctrl-0 or on shutdown backg...
LIVES_GLOBAL_INLINE int filter_mutex_lock(int key)
Definition: effects-weed.c:96
boolean weed_deinit_effect(int hotkey)
hotkey starts at 1
weed_plant_t * get_textparm(void)
for rte textmode, get first string parameter for current key/mode instance we will then forward all k...
int weed_get_blend_factor(int hotkey)
weed_plant_t * rte_keymode_get_filter(int key, int mode)
returns filter_class bound to key/mode (or NULL)
boolean weed_init_effect(int hotkey)
hotkey starts at 1
weed_plant_t * weed_apply_effects(weed_plant_t **layers, weed_plant_t *filter_map, weed_timecode_t tc, int opwidth, int opheight, void ***pchains)
weed_error_t weed_call_deinit_func(weed_plant_t *instance)
boolean rte_key_setmode(int key, int newmode)
newmode has two special values, -1 = cycle forwards, -2 = cycle backwards key is 1 based,...
void weed_reinit_all(void)
LIVES_GLOBAL_INLINE int weed_instance_unref(weed_plant_t *inst)
weed_plant_t * get_weed_filter(int idx)
weed_plant_t * get_enabled_channel(weed_plant_t *inst, int which, boolean is_in)
for FILTER_INST
Definition: effects-weed.c:536
boolean rte_key_valid(int key, boolean is_userkey)
returns TRUE if there is a filter bound to active mode of hotkey
boolean has_audio_filters(lives_af_t af_type)
boolean is_pure_audio(weed_plant_t *plant, boolean count_opt)
TRUE if audio in or out and no vid in/out.
Definition: effects-weed.c:714
weed_plant_t * weed_instance_from_filter(weed_plant_t *filter)
lives_filter_error_t
filter apply errors
Definition: effects-weed.h:14
#define WEED_LEAF_HOST_NEXT_INSTANCE
Definition: effects-weed.h:104
#define WEED_LEAF_HOST_WIDTH
Definition: effects-weed.h:63
#define WEED_LEAF_HOST_HEIGHT
Definition: effects-weed.h:64
void deinterlace_frame(weed_layer_t *layer, weed_timecode_t tc)
Definition: effects.c:920
boolean rte_key_on_off(int key, boolean on)
Definition: effects.c:1232
boolean grabkeys_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
for accel groups
Definition: effects.c:1112
void rte_keymodes_restore(int nkeys)
Definition: effects.c:1269
LIVES_GLOBAL_INLINE void rte_keys_reset(void)
Definition: effects.c:1248
lives_render_error_t realfx_progress(boolean reset)
Definition: effects.c:591
boolean rte_on_off_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
for accel groups
Definition: effects.c:974
weed_plant_t * on_rte_apply(weed_layer_t *layer, int opwidth, int opheight, weed_timecode_t tc)
Definition: effects.c:879
void on_realfx_activate(LiVESMenuItem *menuitem, livespointer xrfx)
Definition: effects.c:799
boolean rte_on_off_callback_hook(LiVESToggleButton *button, livespointer user_data)
for widgets
Definition: effects.c:1106
boolean rtemode_callback_hook(LiVESToggleButton *button, livespointer user_data)
for widgets
Definition: effects.c:1164
boolean grabkeys_callback_hook(LiVESToggleButton *button, livespointer user_data)
for widgets
Definition: effects.c:1144
boolean textparm_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: effects.c:1136
LIVES_GLOBAL_INLINE int rte_getmodespk(void)
Definition: effects.c:1219
LIVES_GLOBAL_INLINE boolean rte_key_toggle(int key)
Definition: effects.c:1224
boolean on_realfx_activate_inner(int type, lives_rfx_t *rfx)
Definition: effects.c:728
void rte_keymodes_backup(int nkeys)
Definition: effects.c:1257
boolean rtemode_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
for accel groups
Definition: effects.c:1151
char * lives_fx_cat_to_text(lives_fx_cat_t cat, boolean plural)
Definition: effects.c:40
boolean swap_fg_bg_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: effects.c:1177
void get_blend_layer(weed_timecode_t tc)
Definition: effects.c:861
boolean do_effect(lives_rfx_t *rfx, boolean is_preview)
defined as extern in paramwindow.c
Definition: effects.c:127
LIVES_GLOBAL_INLINE boolean rte_key_is_enabled(int key)
Definition: effects.c:1213
lives_fx_cat_t
Definition: effects.h:11
@ LIVES_FX_CAT_COMPOSITOR
Definition: effects.h:28
@ LIVES_FX_CAT_ANALYSER
Definition: effects.h:34
@ LIVES_FX_CAT_AUDIO_MIXER
Definition: effects.h:29
@ LIVES_FX_CAT_AV_GENERATOR
Definition: effects.h:14
@ LIVES_FX_CAT_VIDEO_ANALYSER
Definition: effects.h:35
@ LIVES_FX_CAT_DATA_GENERATOR
Definition: effects.h:16
@ LIVES_FX_CAT_AUDIO_GENERATOR
Definition: effects.h:15
@ LIVES_FX_CAT_TAP
Definition: effects.h:30
@ LIVES_FX_CAT_AUDIO_VOL
Definition: effects.h:33
@ LIVES_FX_CAT_UTILITY
Definition: effects.h:27
@ LIVES_FX_CAT_VIDEO_EFFECT
Definition: effects.h:25
@ LIVES_FX_CAT_DATA_PROCESSOR
Definition: effects.h:18
@ LIVES_FX_CAT_TRANSITION
Definition: effects.h:20
@ LIVES_FX_CAT_AUDIO_TRANSITION
Definition: effects.h:23
@ LIVES_FX_CAT_AUDIO_ANALYSER
Definition: effects.h:36
@ LIVES_FX_CAT_AUDIO_EFFECT
Definition: effects.h:26
@ LIVES_FX_CAT_VIDEO_GENERATOR
Definition: effects.h:13
@ LIVES_FX_CAT_SPLITTER
Definition: effects.h:31
@ LIVES_FX_CAT_EFFECT
Definition: effects.h:24
@ LIVES_FX_CAT_DATA_SOURCE
Definition: effects.h:19
@ LIVES_FX_CAT_DATA_VISUALISER
Definition: effects.h:17
@ LIVES_FX_CAT_CONVERTER
Definition: effects.h:32
@ LIVES_FX_CAT_VIDEO_TRANSITION
Definition: effects.h:22
@ LIVES_FX_CAT_AV_TRANSITION
Definition: effects.h:21
@ AF_TYPE_ANY
Definition: effects.h:41
#define WEED_LEAF_IN_TRACKS
Definition: events.h:47
#define WEED_LEAF_OUT_TRACKS
Definition: events.h:48
lives_render_error_t
various return conditions from rendering (multitrack or after recording)
Definition: events.h:100
@ LIVES_RENDER_EFFECTS_PAUSED
Definition: events.h:104
@ LIVES_RENDER_PROCESSING
Definition: events.h:103
@ LIVES_RENDER_ERROR_WRITE_FRAME
Definition: events.h:111
@ LIVES_RENDER_ERROR_NONE
Definition: events.h:101
@ LIVES_RENDER_COMPLETE
Definition: events.h:105
@ LIVES_RENDER_WARNING_READ_FRAME
Definition: events.h:107
@ LIVES_RENDER_READY
Definition: events.h:102
@ LIVES_RENDER_ERROR_WRITE_AUDIO
Definition: events.h:110
void add_to_clipmenu(void)
Definition: gui.c:4512
error("LSD_RANDFUNC(ptr, size) must be defined")
LIVES_GLOBAL_INLINE boolean lives_proc_thread_cancel(lives_proc_thread_t tinfo)
lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t attr, lives_funcptr_t func, int return_type, const char *args_fmt,...)
create the specific plant which defines a background task to be run
void reget_afilesize(int fileno)
Definition: machinestate.c:972
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_free
Definition: machinestate.h:52
#define lives_nanosleep_until_nonzero(condition)
Definition: machinestate.h:310
#define lives_malloc
Definition: machinestate.h:46
#define lives_memcpy
Definition: machinestate.h:55
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
#define LIVES_THRDATTR_NONE
Definition: machinestate.h:437
void showclipimgs(void)
Definition: main.c:5636
LIVES_GLOBAL_INLINE boolean pull_frame(weed_layer_t *layer, const char *image_ext, weed_timecode_t tc)
pull a frame from an external source into a layer the WEED_LEAF_CLIP and WEED_LEAF_FRAME leaves must ...
Definition: main.c:7500
mainwindow * mainw
Definition: main.c:103
boolean lives_pixbuf_save(LiVESPixbuf *pixbuf, char *fname, lives_img_type_t imgtype, int quality, int width, int height, LiVESError **gerrorptr)
Save a pixbuf to a file using the specified imgtype and the specified quality/compression value.
Definition: main.c:9304
void pull_frame_threaded(weed_layer_t *layer, const char *img_ext, weed_timecode_t tc, int width, int height)
Definition: main.c:7631
void close_current_file(int file_to_switch_to)
close current file, and try to switch to file_to_switch_to
Definition: main.c:9373
void clear_mainw_msg(void)
Definition: utils.c:1435
ulong open_file_sel(const char *file_name, double start_time, int frames)
Definition: saveplay.c:309
int get_frame_count(int idx, int xsize)
sets mainw->files[idx]->frames with current framecount
Definition: utils.c:3109
#define clipboard
Definition: main.h:1835
@ UNDO_EFFECT
Definition: main.h:661
@ UNDO_NEW_AUDIO
Definition: main.h:674
@ UNDO_RESIZABLE
Definition: main.h:662
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
void d_print_cancelled(void)
Definition: utils.c:2610
void lives_sync(int times)
Definition: utils.c:115
#define CLIP_NAME_MAXLEN
Definition: main.h:804
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
#define LIVES_IS_PLAYING
Definition: main.h:840
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
void set_undoable(const char *what, boolean sensitive)
Definition: utils.c:4784
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
frames_t calc_new_playback_position(int fileno, ticks_t otc, ticks_t *ntc)
Definition: utils.c:1865
boolean save_clip_values(int which_file)
Definition: saveplay.c:103
@ CLIP_DETAILS_HEIGHT
Definition: main.h:1146
@ CLIP_DETAILS_WIDTH
Definition: main.h:1145
uint64_t make_version_hash(const char *ver)
Definition: utils.c:3500
#define IS_VALID_CLIP(clip)
Definition: main.h:808
int verhash(char *version)
Definition: utils.c:4755
int lives_rm(const char *file)
Definition: utils.c:4395
int64_t ticks_t
Definition: main.h:97
void d_print_failed(void)
Definition: utils.c:2615
#define CURRENT_CLIP_IS_NORMAL
Definition: main.h:838
#define cfile
Definition: main.h:1833
void d_print(const char *fmt,...)
Definition: utils.c:2542
@ IMG_TYPE_PNG
Definition: main.h:777
@ IMG_TYPE_JPEG
Definition: main.h:776
void add_to_recovery_file(const char *handle)
Definition: saveplay.c:6460
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
void unbuffer_lmap_errors(boolean add)
Definition: utils.c:2656
void d_print_done(void)
Definition: utils.c:2620
#define PATH_MAX
Definition: main.h:255
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
@ CLIP_TYPE_GENERATOR
frames from generator plugin
Definition: main.h:766
@ CLIP_TYPE_DISK
imported video, broken into frames
Definition: main.h:764
char * make_image_file_name(lives_clip_t *clip, frames_t frame, const char *img_ext)
lives_image_type can be a string, lives_img_type_t is an enumeration
Definition: utils.c:3053
void init_clipboard(void)
Definition: utils.c:2238
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
@ CANCEL_NONE
no cancel
Definition: main.h:701
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
@ CANCEL_KEEP
user pressed 'Keep'
Definition: main.h:734
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
#define EFFECT_NONE
Definition: mainwindow.h:208
#define TICKS_PER_SECOND
ticks per second - GLOBAL TIMEBASE
Definition: mainwindow.h:36
#define LIVES_IS_INTERACTIVE
Definition: mainwindow.h:1710
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
#define PREV_MODE_CYCLE
Definition: mainwindow.h:669
#define GU641
Definition: mainwindow.h:209
#define LIVES_FILE_EXT_MGK
Definition: mainwindow.h:489
#define FX_KEYS_MAX_VIRTUAL
must be >= FX_KEYS_PHYSICAL, and <=64 (number of bits in a 64bit int mask) (max number of keys accesi...
Definition: mainwindow.h:203
#define SCREEN_AREA_BACKGROUND
Definition: mainwindow.h:1681
#define SCREEN_AREA_FOREGROUND
Definition: mainwindow.h:1680
void mt_clip_select(lives_mt *mt, boolean scroll)
Definition: multitrack.c:3024
void mt_init_clips(lives_mt *mt, int orig_file, boolean add)
Definition: multitrack.c:10859
#define LIVES_OSC_NOTIFY_CLIP_OPENED
sent after a clip is opened
Definition: osc_notify.h:46
char * param_marshall(lives_rfx_t *rfx, boolean with_min_max)
Definition: paramwindow.c:2844
void do_rfx_cleanup(lives_rfx_t *rfx)
Definition: plugins.c:2671
@ RFX_STATUS_WEED
indicates an internal RFX, created from a weed instance
Definition: plugins.h:616
@ RFX_STATUS_BUILTIN
factory presets
Definition: plugins.h:612
#define RFX_PROPS_BATCHG
is a batch generator
Definition: plugins.h:636
#define FX_CANDIDATE_DEINTERLACE
Definition: plugins.h:696
#define PLUGIN_RENDERED_EFFECTS_BUILTIN
external rendered fx plugins (RFX plugins)
Definition: plugins.h:469
#define RFX_PROPS_MAY_RESIZE
is a tool
Definition: plugins.h:635
_prefs * prefs
Definition: preferences.h:847
#define WARN_MASK_LAYOUT_ALTER_FRAMES
off by default on a fresh install
Definition: preferences.h:102
#define WARN_MASK_LAYOUT_ALTER_AUDIO
off by default on a fresh install
Definition: preferences.h:116
#define AUDIO_SRC_INT
Definition: preferences.h:205
_resaudw * create_resaudw(short type, render_details *rdet, LiVESWidget *top_vbox)
resample audio window
Definition: resample.c:1521
_resaudw * resaudw
Definition: resample.h:38
void rtew_set_keych(int key, boolean on)
Definition: rte_window.c:2464
void rtew_set_keygr(int key)
Definition: rte_window.c:2472
LiVESWidget * rte_window
Definition: rte_window.h:58
char backend[PATH_MAX *4]
Definition: preferences.h:411
boolean crash_recovery
TRUE==maintain mainw->recovery file.
Definition: preferences.h:259
int audio_src
Definition: preferences.h:204
double default_fps
Definition: preferences.h:173
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
char lib_dir[PATH_MAX]
Definition: preferences.h:75
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
int max_modes_per_key
maximum effect modes per key
Definition: preferences.h:350
LiVESWidget * dialog
Definition: resample.h:19
corresponds to one clip in the GUI
Definition: main.h:877
frames_t frames
number of video frames
Definition: main.h:890
char file_name[PATH_MAX]
input file
Definition: main.h:923
LiVESWidget * menuentry
Definition: main.h:1011
lives_clip_type_t clip_type
Definition: main.h:886
lives_img_type_t img_type
Definition: main.h:887
frames_t last_frameno
Definition: main.h:934
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
Definition: main.h:1007
frames_t frameno
Definition: main.h:934
char name[CLIP_NAME_MAXLEN]
the display name
Definition: main.h:922
double fps
Definition: main.h:893
boolean is_loaded
should we continue loading if we come back to this clip
Definition: main.h:949
frames_t start
Definition: main.h:891
int delegate
offset in list of current delegate
Definition: plugins.h:688
LiVESList * list
list of filter_idx from which user can delegate
Definition: plugins.h:687
LiVESWidget * menuitem
the menu item which activates this effect
Definition: plugins.h:643
char rfx_version[64]
Definition: plugins.h:653
uint32_t props
Definition: plugins.h:633
char * menu_text
for Weed, this is the filter_class "name"
Definition: plugins.h:627
char * action_desc
for Weed "Applying $s"
Definition: plugins.h:628
lives_rfx_status_t status
Definition: plugins.h:631
int num_in_channels
Definition: plugins.h:630
void * source
points to the source (e.g. a weed_plant_t)
Definition: plugins.h:651
char * name
the name of the executable (so we can run it !)
Definition: plugins.h:626
boolean gen_started_play
Definition: mainwindow.h:1694
boolean ce_thumbs
Definition: mainwindow.h:1676
int swapped_clip
maintains the current cliplist postion even if we swap fg and bg clips
Definition: mainwindow.h:850
boolean close_keep_frames
special value for when generating to clipboard
Definition: mainwindow.h:1438
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
boolean gen_to_clipboard
rendered generators
Definition: mainwindow.h:1564
LiVESWidget * redo
Definition: mainwindow.h:1147
volatile uint64_t rte
current max for VJ mode == 64 effects on fg clip
Definition: mainwindow.h:867
pthread_mutex_t event_list_mutex
prevent simultaneous writing to event_list by audio and video threads
Definition: mainwindow.h:1499
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
int last_dprint_file
message output settings
Definition: mainwindow.h:1535
boolean resizing
Definition: mainwindow.h:822
double blend_factor
keyboard control parameter
Definition: mainwindow.h:872
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
boolean effects_paused
Definition: mainwindow.h:1055
lives_render_error_t(* progress_fn)(boolean reset)
Definition: mainwindow.h:1044
boolean go_away
Definition: mainwindow.h:1614
LiVESWidget * select_last
Definition: mainwindow.h:1162
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
boolean preview
Definition: mainwindow.h:757
boolean osc_block
TODO - make this a mutex and more finely grained : things we need to block are (clip switches,...
Definition: mainwindow.h:916
int current_file
Definition: mainwindow.h:727
boolean show_procd
override showing of "processing..." dialog
Definition: mainwindow.h:1548
int untitled_number
Definition: mainwindow.h:738
int num_tr_applied
number of transitions active
Definition: mainwindow.h:871
volatile int blend_palette
here we can store the details of the blend file at the insertion point, if nothing changes we can tar...
Definition: mainwindow.h:980
boolean no_switch_dprint
Definition: mainwindow.h:1536
weed_plant_t * filter_map
Definition: mainwindow.h:1298
weed_plant_t * blend_layer
Definition: mainwindow.h:977
void *** pchains
Definition: mainwindow.h:1301
int pre_src_file
video file we were playing before any ext input started
Definition: mainwindow.h:971
int blend_file
background clip details
Definition: mainwindow.h:976
boolean fx_is_auto
Definition: mainwindow.h:1695
boolean error
Definition: mainwindow.h:801
lives_fx_candidate_t fx_candidates[MAX_FX_CANDIDATE_TYPES]
< effects which can have candidates from which a delegate is selected (current examples are: audio_vo...
Definition: mainwindow.h:1514
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
boolean keep_pre
set if previewed frames should be retained as processed frames (for rendered effects / generators)
Definition: mainwindow.h:1567
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
int active_sa_clips
Definition: mainwindow.h:1686
boolean foreign
for external window capture
Definition: mainwindow.h:824
boolean internal_messaging
internal fx
Definition: mainwindow.h:1043
boolean is_processing
states
Definition: mainwindow.h:820
LiVESWidget * undo
Definition: mainwindow.h:1146
int rte_keys
which effect is bound to keyboard (m) modechange and ctrl-alt-up-arrow / ctrl-alt-down-arrow param ch...
Definition: mainwindow.h:870
int last_blend_file
Definition: mainwindow.h:976
boolean force_show
Definition: mainwindow.h:1763
uint32_t last_grabbable_effect
Definition: mainwindow.h:869
int new_clip
clip we should switch to during playback; switch will happen at the designated SWITCH POINT
Definition: mainwindow.h:1022
weed_plant_t * rte_textparm
send keyboard input to this paramter (usually NULL)
Definition: mainwindow.h:1589
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
lives_rfx_t * rendered_fx
rendered fx
Definition: mainwindow.h:855
boolean is_generating
Definition: mainwindow.h:1565
boolean non_modal
non-modal for dialogs
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
WIDGET_HELPER_GLOBAL_INLINE void lives_menu_item_set_text(LiVESWidget *menuitem, const char *text, boolean use_mnemonic)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_unref(livespointer object)
decrease refcount by one: if refcount==0, object is destroyed
widget_opts_t widget_opts