LiVES  3.2.0
plugins.c
Go to the documentation of this file.
1 // plugins.c
2 // LiVES
3 // (c) G. Finch 2003 - 2020 <salsaman+lives@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING or www.gnu.org for licensing details
6 
7 #include <dlfcn.h>
8 #include <errno.h>
9 
10 #include "main.h"
11 #include "resample.h"
12 #include "effects.h"
13 #include "interface.h"
14 
15 #include "rfx-builder.h"
16 #include "paramwindow.h"
17 
18 #include "lsd-tab.h"
19 
20 // *INDENT-OFF*
21 const char *const anames[AUDIO_CODEC_MAX] = {"mp3", "pcm", "mp2", "vorbis", "AC3", "AAC", "AMR_NB",
22  "raw", "wma2", "opus", ""};
23 // *INDENT-ON*
24 
25 static boolean list_plugins;
26 
28 // command-line plugins
29 
30 LiVESList *get_plugin_result(const char *command, const char *delim, boolean allow_blanks, boolean strip) {
31  LiVESList *list = NULL;
32  char buffer[65536];
33 
34  //threaded_dialog_spin(0.);
35 
36  lives_popen(command, !mainw->is_ready && !list_plugins, buffer, 65535);
37 
38  if (THREADVAR(com_failed)) return NULL;
39 
40  //threaded_dialog_spin(0.);
41  list = buff_to_list(buffer, delim, allow_blanks, strip);
42  //threaded_dialog_spin(0.);
43  return list;
44 }
45 
46 
47 LIVES_GLOBAL_INLINE LiVESList *plugin_request_with_blanks(const char *plugin_type, const char *plugin_name,
48  const char *request) {
49  // allow blanks in a list
50  return plugin_request_common(plugin_type, plugin_name, request, "|", TRUE);
51 }
52 
53 
54 LIVES_GLOBAL_INLINE LiVESList *plugin_request(const char *plugin_type, const char *plugin_name, const char *request) {
55  return plugin_request_common(plugin_type, plugin_name, request, "|", FALSE);
56 }
57 
58 
59 LIVES_GLOBAL_INLINE LiVESList *plugin_request_by_line(const char *plugin_type, const char *plugin_name, const char *request) {
60  return plugin_request_common(plugin_type, plugin_name, request, "\n", FALSE);
61 }
62 
63 
64 LIVES_GLOBAL_INLINE LiVESList *plugin_request_by_space(const char *plugin_type, const char *plugin_name, const char *request) {
65  return plugin_request_common(plugin_type, plugin_name, request, " ", FALSE);
66 }
67 
68 
69 LiVESList *plugin_request_common(const char *plugin_type, const char *plugin_name, const char *request,
70  const char *delim, boolean allow_blanks) {
71  // returns a LiVESList of responses to -request, or NULL on error
72 
73  // NOTE: request must not be quoted here, since it contains a list of parameters
74  // instead, caller should ensure that any strings in *request are suitably escaped and quoted
75  // e.g. by calling param_marshall()
76 
77  LiVESList *reslist = NULL;
78  char *com, *comfile;
79 
80  if (plugin_type) {
81  if (!plugin_name || !strlen(plugin_name)) {
82  return reslist;
83  }
84 
85  // some types live in the config directory...
86  if (!strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_CUSTOM) || !strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_TEST)) {
87  comfile = lives_build_filename(prefs->config_datadir, plugin_type, plugin_name, NULL);
88  } else if (!strcmp(plugin_type, PLUGIN_RFX_SCRAP)) {
89  // scraps are in the workdir
90  comfile = lives_build_filename(prefs->workdir, plugin_name, NULL);
91  } else {
92  comfile = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, plugin_type, plugin_name, NULL);
93  }
94 
95  //#define DEBUG_PLUGINS
96 #ifdef DEBUG_PLUGINS
97  com = lives_strdup_printf("\"%s\" %s", comfile, request);
98  lives_printerr("will run: %s\n", com);
99 #else
100  com = lives_strdup_printf("\"%s\" %s 2>/dev/null", comfile, request);
101 #endif
102  lives_free(comfile);
103  } else com = lives_strdup(request);
104  list_plugins = FALSE;
105  reslist = get_plugin_result(com, delim, allow_blanks, TRUE);
106  lives_free(com);
107  //threaded_dialog_spin(0.);
108  return reslist;
109 }
110 
111 
113 // get list of plugins of various types
114 
115 LiVESList *get_plugin_list(const char *plugin_type, boolean allow_nonex, const char *plugdir, const char *filter_ext) {
116  // returns a LiVESList * of plugins of type plugin_type
117  // returns empty list if there are no plugins of that type
118 
119  // allow_nonex to allow non-executable files (e.g. libs)
120  // filter_ext can be non-NULL to filter for files ending .filter_ext
121 
122  // TODO - use enum for plugin_type
123 
124  // format is: allow_nonex (0 or 1) allow_subdirs (0 or 1) plugindir ext
125 
126  char *com, *tmp;
127  LiVESList *pluglist;
128 
129  const char *ext = (filter_ext == NULL) ? "" : filter_ext;
130 
131  if (!strcmp(plugin_type, PLUGIN_THEMES)) {
132  // must not allow_nonex, otherwise we get splash image etc (just want dirs)
133  com = lives_strdup_printf("%s list_plugins 0 1 \"%s%s\" \"\"", prefs->backend_sync, prefs->prefix_dir, THEME_DIR);
134  } else if (!strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_CUSTOM_SCRIPTS) ||
135  !strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_TEST_SCRIPTS) ||
136  !strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_CUSTOM) ||
137  !strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_TEST) ||
138  !strcmp(plugin_type, PLUGIN_COMPOUND_EFFECTS_CUSTOM)
139  ) {
140  // look in home
141  tmp = lives_build_path(prefs->config_datadir, plugin_type, NULL);
142  com = lives_strdup_printf("%s list_plugins %d 0 \"%s\" \"%s\"", prefs->backend_sync, allow_nonex, tmp, ext);
143  lives_free(tmp);
144  } else if (!strcmp(plugin_type, PLUGIN_THEMES_CUSTOM)) {
145  tmp = lives_build_path(prefs->config_datadir, PLUGIN_THEMES, NULL);
146  com = lives_strdup_printf("%s list_plugins 0 1 \"%s\"", prefs->backend_sync, tmp);
147  lives_free(tmp);
148  } else if (!strcmp(plugin_type, PLUGIN_EFFECTS_WEED)) {
149  com = lives_strdup_printf("%s list_plugins 1 1 \"%s\" \"%s\"", prefs->backend_sync,
150  (tmp = lives_filename_from_utf8((char *)plugdir, -1, NULL, NULL, NULL)), ext);
151  lives_free(tmp);
152  } else if (!strcmp(plugin_type, PLUGIN_DECODERS)) {
153  com = lives_strdup_printf("%s list_plugins 1 0 \"%s\" \"%s\"", prefs->backend_sync,
154  (tmp = lives_filename_from_utf8((char *)plugdir, -1, NULL, NULL, NULL)), ext);
155  lives_free(tmp);
156  } else if (!strcmp(plugin_type, PLUGIN_RENDERED_EFFECTS_BUILTIN_SCRIPTS)) {
157  com = lives_strdup_printf("%s list_plugins %d 0 \"%s%s%s\" \"%s\"", prefs->backend_sync, allow_nonex, prefs->prefix_dir,
158  PLUGIN_SCRIPTS_DIR, plugin_type, ext);
159  } else if (!strcmp(plugin_type, PLUGIN_COMPOUND_EFFECTS_BUILTIN)) {
160  com = lives_strdup_printf("%s list_plugins %d 0 \"%s%s%s\" \"%s\"", prefs->backend_sync, allow_nonex, prefs->prefix_dir,
161  PLUGIN_COMPOUND_DIR, plugin_type, ext);
162  } else {
163  com = lives_strdup_printf("%s list_plugins %d 0 \"%s%s%s\" \"%s\"", prefs->backend_sync, allow_nonex, prefs->lib_dir,
164  PLUGIN_EXEC_DIR, plugin_type, ext);
165  }
166  list_plugins = TRUE;
167 
168  //g_print("\n\n\nLIST CMD: %s\n",com);
169 
170  pluglist = get_plugin_result(com, "|", FALSE, TRUE);
171  lives_free(com);
172  //threaded_dialog_spin(0.);
173  pluglist = lives_list_sort_alpha(pluglist, TRUE);
174  return pluglist;
175 }
176 
177 
179 // video plugins
180 
181 void save_vpp_defaults(_vid_playback_plugin *vpp, char *vpp_file) {
182  // format is:
183  // nbytes (string) : LiVES vpp defaults file version 2\n
184  // for each video playback plugin:
185  // 4 bytes (int) name length
186  // n bytes name
187  // 4 bytes (int) version length
188  // n bytes version
189  // 4 bytes (int) palette
190  // 4 bytes (int) YUV sampling
191  // 4 bytes (int) YUV clamping
192  // 4 bytes (int) YUV subspace
193  // 4 bytes (int) width
194  // 4 bytes (int) height
195  // 8 bytes (double) fps
196  // 4 bytes (int) fps_numerator [0 indicates use fps double, >0 use fps_numer/fps_denom ]
197  // 4 bytes (int) fps_denominator
198  // 4 bytes argc (count of argv, may be 0)
199  //
200  // for each argv (extra params):
201  // 4 bytes (int) length
202  // n bytes string param value
203 
204  int fd;
205  int32_t len;
206  const char *version;
207  int i;
208  char *msg;
209  int intzero = 0;
210  double dblzero = 0.;
211 
212  if (!vpp) {
213  lives_rm(vpp_file);
214  return;
215  }
216 
217  if ((fd = lives_open3(vpp_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) {
218  msg = lives_strdup_printf(_("\n\nUnable to write video playback plugin defaults file\n%s\nError code %d\n"), vpp_file, errno);
219  LIVES_ERROR(msg);
220  lives_free(msg);
221  return;
222  }
223 
224  msg = lives_strdup_printf(_("Updating video playback plugin defaults in %s\n"), vpp_file);
225  LIVES_INFO(msg);
226  lives_free(msg);
227 
228  msg = lives_strdup("LiVES vpp defaults file version 2\n");
229  if (!lives_write(fd, msg, strlen(msg), FALSE)) return;
230  lives_free(msg);
231 
232  len = strlen(vpp->name);
233  if (lives_write_le(fd, &len, 4, FALSE) < 4) return;
234  if (lives_write(fd, vpp->name, len, FALSE) < len) return;
235 
236  version = (*vpp->version)();
237  len = strlen(version);
238  if (lives_write_le(fd, &len, 4, FALSE) < 4) return;
239  if (lives_write(fd, version, len, FALSE) < len) return;
240 
241  if (lives_write_le(fd, &(vpp->palette), 4, FALSE) < 4) return;
242  if (lives_write_le(fd, &(vpp->YUV_sampling), 4, FALSE) < 4) return;
243  if (lives_write_le(fd, &(vpp->YUV_clamping), 4, FALSE) < 4) return;
244  if (lives_write_le(fd, &(vpp->YUV_subspace), 4, FALSE) < 4) return;
245 
246  if (lives_write_le(fd, vpp->fwidth <= 0 ? &intzero : & (vpp->fwidth), 4, FALSE) < 4) return;
247  if (lives_write_le(fd, vpp->fheight <= 0 ? &intzero : & (vpp->fheight), 4, FALSE) < 4) return;
248 
249  if (lives_write_le(fd, vpp->fixed_fpsd <= 0. ? &dblzero : & (vpp->fixed_fpsd), 8, FALSE) < 8) return;
250  if (lives_write_le(fd, vpp->fixed_fps_numer <= 0 ? &intzero : & (vpp->fixed_fps_numer), 4, FALSE) < 4) return;
251  if (lives_write_le(fd, vpp->fixed_fps_denom <= 0 ? &intzero : & (vpp->fixed_fps_denom), 4, FALSE) < 4) return;
252 
253  if (lives_write_le(fd, &(vpp->extra_argc), 4, FALSE) < 4) return;
254 
255  for (i = 0; i < vpp->extra_argc; i++) {
256  len = strlen(vpp->extra_argv[i]);
257  if (lives_write_le(fd, &len, 4, FALSE) < 4) return;
258  if (lives_write(fd, vpp->extra_argv[i], len, FALSE) < len) return;
259  }
260 
261  close(fd);
262 }
263 
264 
265 void load_vpp_defaults(_vid_playback_plugin *vpp, char *vpp_file) {
266  ssize_t len;
267  const char *version;
268 
269  char buf[512];
270 
271  char *msg;
272 
273  int retval;
274  int fd;
275 
276  register int i;
277 
278  if (!lives_file_test(vpp_file, LIVES_FILE_TEST_EXISTS)) {
279  return;
280  }
281 
282  d_print(_("Loading video playback plugin defaults from %s..."), vpp_file);
283 
284  do {
285  retval = 0;
286  if ((fd = lives_open2(vpp_file, O_RDONLY)) == -1) {
287  retval = do_read_failed_error_s_with_retry(vpp_file, lives_strerror(errno));
288  if (retval == LIVES_RESPONSE_CANCEL) {
289  vpp = NULL;
290  return;
291  }
292  } else {
293  do {
294  // only do this loop once, so we can use break to escape it
295 
296  THREADVAR(read_failed) = FALSE;
297  msg = lives_strdup("LiVES vpp defaults file version 2\n");
298  len = lives_read(fd, buf, strlen(msg), FALSE);
299  if (len < 0) len = 0;
300  lives_memset(buf + len, 0, 1);
301 
302  if (THREADVAR(read_failed)) break;
303 
304  // identifier string
305  if (strcmp(msg, buf)) {
306  lives_free(msg);
308  close(fd);
309  return;
310  }
311  lives_free(msg);
312 
313  // plugin name
314  lives_read_le(fd, &len, 4, FALSE);
315  if (THREADVAR(read_failed)) break;
316  lives_read(fd, buf, len, FALSE);
317  lives_memset(buf + len, 0, 1);
318 
319  if (THREADVAR(read_failed)) break;
320 
321  if (strcmp(buf, vpp->name)) {
323  close(fd);
324  return;
325  }
326 
327  // version string
328  version = (*vpp->version)();
329  lives_read_le(fd, &len, 4, FALSE);
330  if (THREADVAR(read_failed)) break;
331  lives_read(fd, buf, len, FALSE);
332 
333  if (THREADVAR(read_failed)) break;
334 
335  lives_memset(buf + len, 0, 1);
336 
337  if (strcmp(buf, version)) {
338  msg = lives_strdup_printf(
339  _("\nThe %s video playback plugin has been updated.\nPlease check your settings in\n"
340  "Tools|Preferences|Playback|Playback Plugins Advanced\n\n"),
341  vpp->name);
343  do_error_dialog(msg);
345  lives_free(msg);
346  lives_rm(vpp_file);
347  d_print_failed();
348  close(fd);
349  return;
350  }
351 
352  lives_read_le(fd, &(vpp->palette), 4, FALSE);
353  lives_read_le(fd, &(vpp->YUV_sampling), 4, FALSE);
354  lives_read_le(fd, &(vpp->YUV_clamping), 4, FALSE);
355  lives_read_le(fd, &(vpp->YUV_subspace), 4, FALSE);
356  lives_read_le(fd, &(vpp->fwidth), 4, FALSE);
357  lives_read_le(fd, &(vpp->fheight), 4, FALSE);
358  lives_read_le(fd, &(vpp->fixed_fpsd), 8, FALSE);
359  lives_read_le(fd, &(vpp->fixed_fps_numer), 4, FALSE);
360  lives_read_le(fd, &(vpp->fixed_fps_denom), 4, FALSE);
361 
362  if (THREADVAR(read_failed)) break;
363 
364  lives_read_le(fd, &(vpp->extra_argc), 4, FALSE);
365 
366  if (THREADVAR(read_failed)) break;
367 
368  if (vpp->extra_argv) {
369  for (i = 0; vpp->extra_argv[i]; i++) {
370  lives_free(vpp->extra_argv[i]);
371  }
372  lives_free(vpp->extra_argv);
373  }
374 
375  vpp->extra_argv = (char **)lives_calloc((vpp->extra_argc + 1), (sizeof(char *)));
376 
377  for (i = 0; i < vpp->extra_argc; i++) {
378  lives_read_le(fd, &len, 4, FALSE);
379  if (THREADVAR(read_failed)) break;
380  vpp->extra_argv[i] = (char *)lives_malloc(len + 1);
381  lives_read(fd, vpp->extra_argv[i], len, FALSE);
382  if (THREADVAR(read_failed)) break;
383  lives_memset((vpp->extra_argv[i]) + len, 0, 1);
384  }
385 
386  vpp->extra_argv[i] = NULL;
387 
388  close(fd);
389  } while (FALSE);
390 
391  if (THREADVAR(read_failed)) {
392  close(fd);
393  retval = do_read_failed_error_s_with_retry(vpp_file, NULL);
394  if (retval == LIVES_RESPONSE_CANCEL) {
395  THREADVAR(read_failed) = FALSE;
396  vpp = NULL;
398  return;
399  }
400  }
401  }
402  } while (retval == LIVES_RESPONSE_RETRY);
403 
404  d_print_done();
405 }
406 
407 
408 void on_vppa_cancel_clicked(LiVESButton *button, livespointer user_data) {
409  _vppaw *vppw = (_vppaw *)user_data;
410  _vid_playback_plugin *vpp = vppw->plugin;
411 
414  if (vpp && vpp != mainw->vpp) {
415  // close the temp current vpp
417  }
418 
419  if (vppw->rfx) {
420  if (!vppw->keep_rfx) {
421  rfx_free(vppw->rfx);
422  lives_free(vppw->rfx);
423  }
424  }
425 
426  lives_free(vppw);
427 
428  if (prefsw) {
429  lives_window_present(LIVES_WINDOW(prefsw->prefs_dialog));
431  }
432 }
433 
434 
435 void on_vppa_ok_clicked(LiVESButton *button, livespointer user_data) {
436  _vppaw *vppw = (_vppaw *)user_data;
437  uint64_t xwinid = 0;
438 
439  const char *fixed_fps = NULL;
440  const char *tmp;
441 
442  char *cur_pal = NULL;
443 
444  int *pal_list, i = 0;
445 
446  boolean ext_audio = FALSE;
447 
448  _vid_playback_plugin *vpp = vppw->plugin;
449 
450  if (vppw->rfx && mainw->textwidget_focus) {
451  // make sure text widgets are updated if they activate the default
452  LiVESWidget *textwidget = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->textwidget_focus),
454  after_param_text_changed(textwidget, vppw->rfx);
455  }
456 
457  if (!special_cleanup(TRUE)) {
458  // check for file overwrites with special type "filewrite"
459  // if user declines, will return with LIVES_RESPONSE_RETRY
460  if (LIVES_IS_DIALOG(lives_widget_get_toplevel(LIVES_WIDGET(button))))
461  lives_dialog_response(LIVES_DIALOG(lives_widget_get_toplevel(LIVES_WIDGET(button))), LIVES_RESPONSE_RETRY);
462  return;
463  }
464 
465  mainw->textwidget_focus = NULL;
466 
467  if (vpp == mainw->vpp) {
468  if (vppw->spinbuttonw) mainw->vpp->fwidth
469  = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(vppw->spinbuttonw));
470  if (vppw->spinbuttonh) mainw->vpp->fheight
471  = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(vppw->spinbuttonh));
472  if (vppw->apply_fx) mainw->fx1_bool = lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(vppw->apply_fx));
473  if (vppw->fps_entry) fixed_fps = lives_entry_get_text(LIVES_ENTRY(vppw->fps_entry));
474  if (vppw->pal_entry) {
475  cur_pal = lives_strdup(lives_entry_get_text(LIVES_ENTRY(vppw->pal_entry)));
476 
477  if (get_token_count(cur_pal, ' ') > 1) {
478  char **array = lives_strsplit(cur_pal, " ", 2);
479  char *clamping = lives_strdup(array[1] + 1);
480  lives_free(cur_pal);
481  cur_pal = lives_strdup(array[0]);
482  lives_memset(clamping + strlen(clamping) - 1, 0, 1);
483  do {
485  if (tmp && !strcmp(clamping, tmp)) {
486  vpp->YUV_clamping = i;
487  break;
488  }
489  i++;
490  } while (tmp);
491  lives_strfreev(array);
492  lives_free(clamping);
493  }
494  }
495 
496  if (vppw->fps_entry) {
497  if (!strlen(fixed_fps)) {
498  mainw->vpp->fixed_fpsd = -1.;
499  mainw->vpp->fixed_fps_numer = 0;
500  } else {
501  if (get_token_count((char *)fixed_fps, ':') > 1) {
502  char **array = lives_strsplit(fixed_fps, ":", 2);
503  mainw->vpp->fixed_fps_numer = atoi(array[0]);
504  mainw->vpp->fixed_fps_denom = atoi(array[1]);
505  lives_strfreev(array);
506  mainw->vpp->fixed_fpsd = get_ratio_fps((char *)fixed_fps);
507  } else {
508  mainw->vpp->fixed_fpsd = lives_strtod(fixed_fps, NULL);
509  mainw->vpp->fixed_fps_numer = 0;
510  }
511  }
512  } else {
513  mainw->vpp->fixed_fpsd = -1.;
514  mainw->vpp->fixed_fps_numer = 0;
515  }
516 
517  if (mainw->vpp->fixed_fpsd > 0. && (mainw->fixed_fpsd > 0. ||
518  (mainw->vpp->set_fps &&
519  !((*mainw->vpp->set_fps)(mainw->vpp->fixed_fpsd))))) {
521  mainw->error = TRUE;
522  mainw->vpp->fixed_fpsd = -1.;
523  mainw->vpp->fixed_fps_numer = 0;
524  }
525 
526  if (vppw->pal_entry) {
527  if (vpp->get_palette_list && (pal_list = (*vpp->get_palette_list)())) {
528  for (i = 0; pal_list[i] != WEED_PALETTE_END; i++) {
529  if (!strcmp(cur_pal, weed_palette_get_name(pal_list[i]))) {
530  vpp->palette = pal_list[i];
531  if (mainw->ext_playback) {
532  pthread_mutex_lock(&mainw->vpp_stream_mutex);
533  mainw->ext_audio = FALSE;
534  pthread_mutex_unlock(&mainw->vpp_stream_mutex);
536  if (mainw->vpp->exit_screen) {
538  }
539 
540 #ifdef RT_AUDIO
542 #endif
543  mainw->stream_ticks = -1;
544  mainw->vpp->palette = pal_list[i];
545  if (!(*vpp->set_palette)(vpp->palette)) {
547  mainw->error = TRUE;
548  }
549 
550  if (prefs->play_monitor != 0) {
551  if (mainw->play_window) {
552  xwinid = lives_widget_get_xwinid(mainw->play_window, "Unsupported display type for playback plugin");
553  if (xwinid == -1) {
554  lives_dialog_response(LIVES_DIALOG(vppw->dialog), LIVES_RESPONSE_CANCEL);
555  return;
556  }
557  }
558  }
559 
560 #ifdef RT_AUDIO
562 
565  }
566 
567 #endif
568  if (vpp->init_audio && prefs->stream_audio_out) {
569 #ifdef HAVE_PULSE_AUDIO
571  if ((*vpp->init_audio)(mainw->pulsed->out_arate, mainw->pulsed->out_achans, vpp->extra_argc, vpp->extra_argv))
572  mainw->ext_audio = TRUE;
573  }
574 #endif
575 #ifdef ENABLE_JACK
577  if ((*vpp->init_audio)(mainw->jackd->sample_out_rate, mainw->jackd->num_output_channels,
578  vpp->extra_argc, vpp->extra_argv))
579  ext_audio = TRUE;
580  }
581 #endif
582  }
583 
584  if (vpp->init_screen) {
585  (*vpp->init_screen)(mainw->vpp->fwidth > 0 ? mainw->vpp->fwidth : mainw->pwidth,
586  mainw->vpp->fheight > 0 ? mainw->vpp->fheight : mainw->pheight,
587  TRUE, xwinid, vpp->extra_argc, vpp->extra_argv);
588  }
589  mainw->ext_audio = ext_audio; // cannot set this until after init_screen()
593  }
594  } else {
595  mainw->vpp->palette = pal_list[i];
596  if (!(*vpp->set_palette)(vpp->palette)) {
598  mainw->error = TRUE;
599  }
601  }
602  break;
603  }
604  }
605  }
606  lives_free(cur_pal);
607  }
608  if (vpp->extra_argv) {
609  for (i = 0; vpp->extra_argv[i]; i++) lives_free(vpp->extra_argv[i]);
610  lives_free(vpp->extra_argv);
611  vpp->extra_argv = NULL;
612  }
613  vpp->extra_argc = 0;
614  if (vppw->rfx) {
615  vpp->extra_argv = param_marshall_to_argv(vppw->rfx);
616  for (i = 0; vpp->extra_argv[i]; vpp->extra_argc = ++i);
617  }
619  } else {
620  if (vppw->spinbuttonw)
622  else future_prefs->vpp_fwidth = -1;
623  if (vppw->spinbuttonh)
625  else future_prefs->vpp_fheight = -1;
626  if (vppw->fps_entry) fixed_fps = lives_entry_get_text(LIVES_ENTRY(vppw->fps_entry));
627  if (vppw->pal_entry) {
628  cur_pal = lives_strdup(lives_entry_get_text(LIVES_ENTRY(vppw->pal_entry)));
629 
630  if (get_token_count(cur_pal, ' ') > 1) {
631  char **array = lives_strsplit(cur_pal, " ", 2);
632  char *clamping = lives_strdup(array[1] + 1);
633  lives_free(cur_pal);
634  cur_pal = lives_strdup(array[0]);
635  lives_memset(clamping + strlen(clamping) - 1, 0, 1);
636  do {
638  if (tmp && !strcmp(clamping, tmp)) {
640  break;
641  }
642  i++;
643  } while (tmp);
644  lives_strfreev(array);
645  lives_free(clamping);
646  }
647  }
648 
649  if (fixed_fps) {
650  if (get_token_count((char *)fixed_fps, ':') > 1) {
651  char **array = lives_strsplit(fixed_fps, ":", 2);
652  future_prefs->vpp_fixed_fps_numer = atoi(array[0]);
653  future_prefs->vpp_fixed_fps_denom = atoi(array[1]);
654  lives_strfreev(array);
655  future_prefs->vpp_fixed_fpsd = get_ratio_fps((char *)fixed_fps);
656  } else {
657  future_prefs->vpp_fixed_fpsd = lives_strtod(fixed_fps, NULL);
659  }
660  } else {
663  }
664 
665  if (cur_pal) {
666  if (vpp->get_palette_list && (pal_list = (*vpp->get_palette_list)())) {
667  for (i = 0; pal_list[i] != WEED_PALETTE_END; i++) {
668  if (!strcmp(cur_pal, weed_palette_get_name(pal_list[i]))) {
669  future_prefs->vpp_palette = pal_list[i];
670  break;
671  }
672  }
673  }
674  lives_free(cur_pal);
675  } else future_prefs->vpp_palette = WEED_PALETTE_END;
676 
677  if (future_prefs->vpp_argv) {
678  for (i = 0; future_prefs->vpp_argv[i]; i++) lives_free(future_prefs->vpp_argv[i]);
680  future_prefs->vpp_argv = NULL;
681  }
682 
683  future_prefs->vpp_argc = 0;
684  if (vppw->rfx) {
686  if (future_prefs->vpp_argv) {
687  for (i = 0; future_prefs->vpp_argv[i]; future_prefs->vpp_argc = ++i);
688  }
689  } else {
691  vpp->extra_argv = NULL;
692  vpp->extra_argc = 0;
693  }
694  }
695  if (button && !mainw->error) on_vppa_cancel_clicked(button, user_data);
696  else lives_dialog_response(LIVES_DIALOG(vppw->dialog), LIVES_RESPONSE_OK);
697  if (button) mainw->error = FALSE;
698 }
699 
700 
701 void on_vppa_save_clicked(LiVESButton *button, livespointer user_data) {
702  _vppaw *vppw = (_vppaw *)user_data;
703  _vid_playback_plugin *vpp = vppw->plugin;
704  char *save_file;
705 
706  // apply
707  mainw->error = FALSE;
708  on_vppa_ok_clicked(NULL, user_data);
709  if (mainw->error) {
710  mainw->error = FALSE;
711  return;
712  }
713 
714  // get filename
715  save_file = choose_file(NULL, NULL, NULL, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
716  if (!save_file) return;
717 
718  // save
719  d_print(_("Saving playback plugin defaults to %s..."), save_file);
721  d_print_done();
723 
724 }
725 
726 
727 _vppaw *on_vpp_advanced_clicked(LiVESButton *button, livespointer user_data) {
728  LiVESWidget *dialog_vbox;
729  LiVESWidget *hbox;
730  LiVESWidget *label;
731  LiVESWidget *combo;
732  LiVESWidget *cancelbutton;
733  LiVESWidget *okbutton;
734  LiVESWidget *savebutton;
735 
736  LiVESAccelGroup *accel_group;
737 
738  _vppaw *vppa;
739 
740  _vid_playback_plugin *tmpvpp;
741 
742  int *pal_list;
743 
744  double wscale = 1., hscale = 1.;
745 
746  int intention = LIVES_INTENTION_PLAY;
747  int hsize, vsize;
748 
749  LiVESList *fps_list_strings = NULL;
750  LiVESList *pal_list_strings = NULL;
751 
752  const char *string;
753  const char *pversion;
754  const char *desc;
755  const char *fps_list;
756 
757  char *title;
758  char *tmp, *tmp2;
759 
760  char *ctext = NULL;
761 
762  // TODO - set default values from tmpvpp
763 
764  if (user_data) intention = LIVES_POINTER_TO_INT(user_data);
765 
766  if (strlen(future_prefs->vpp_name)) {
767  if (!(tmpvpp = open_vid_playback_plugin(future_prefs->vpp_name, FALSE))) return NULL;
768  } else {
769  if (!mainw->vpp) return NULL;
770  tmpvpp = mainw->vpp;
771  }
772 
773  vppa = (_vppaw *)(lives_calloc(1, sizeof(_vppaw)));
774 
775  vppa->plugin = tmpvpp;
776  /* vppa->rfx = NULL; */
777  /* vppa->spinbuttonh = vppa->spinbuttonw = NULL; */
778  /* vppa->apply_fx = NULL; */
779  /* vppa->pal_entry = vppa->fps_entry = NULL; */
780  /* vppa->keep_rfx = FALSE; */
781 
782  vppa->intention = intention;
783 
784  pversion = (tmpvpp->version)();
785 
786  if (intention == LIVES_INTENTION_PLAY)
787  title = lives_strdup_printf("%s", pversion);
788  else {
789  // LIVES_INTENTION_TRANSCODE
790  title = (_("Quick Transcoding"));
791  wscale = 2. * widget_opts.scale;
792  hscale = 1.5;
793  }
794 
795  vppa->dialog = lives_standard_dialog_new(title, FALSE, DEF_DIALOG_WIDTH * wscale, DEF_DIALOG_HEIGHT * hscale);
796  lives_free(title);
797 
798  accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
799  lives_window_add_accel_group(LIVES_WINDOW(vppa->dialog), accel_group);
800 
801  dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(vppa->dialog));
802 
803  // the filling...
804  if (intention == LIVES_INTENTION_PLAY && tmpvpp->get_description) {
805  desc = (tmpvpp->get_description)();
806  if (desc) {
807  label = lives_standard_label_new(desc);
808  lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
809  }
810  }
811  if (intention == LIVES_INTENTION_TRANSCODE) {
812  tmp = lives_big_and_bold("%s", _("Quick transcode provides a rapid, high quality preview of the selected frames and audio."));
814  label = lives_standard_label_new(tmp);
816  lives_free(tmp);
817  lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
818  }
819 
820  if (tmpvpp->get_fps_list && (fps_list = (*tmpvpp->get_fps_list)(tmpvpp->palette))) {
821  int nfps, i;
822  char **array = lives_strsplit(fps_list, "|", -1);
823 
824  nfps = get_token_count((char *)fps_list, '|');
825  for (i = 0; i < nfps; i++) {
826  if (strlen(array[i]) && strcmp(array[i], "\n")) {
827  if (get_token_count(array[i], ':') == 0) {
828  fps_list_strings = lives_list_append(fps_list_strings, remove_trailing_zeroes(lives_strtod(array[i], NULL)));
829  } else fps_list_strings = lives_list_append(fps_list_strings, lives_strdup(array[i]));
830  }
831  }
832 
833  if (intention == LIVES_INTENTION_PLAY) {
834  // fps
835  combo = lives_standard_combo_new((tmp = (_("_FPS"))), fps_list_strings,
836  LIVES_BOX(dialog_vbox), (tmp2 = (_("Fixed framerate for plugin.\n"))));
837  lives_free(tmp);
838  lives_free(tmp2);
839  vppa->fps_entry = lives_combo_get_entry(LIVES_COMBO(combo));
840  lives_entry_set_width_chars(LIVES_ENTRY(lives_combo_get_entry(LIVES_COMBO(combo))), COMBOWIDTHCHARS);
841 
842  lives_list_free_all(&fps_list_strings);
843  lives_strfreev(array);
844 
845  if (tmpvpp->fixed_fps_numer > 0) {
846  char *tmp = lives_strdup_printf("%d:%d", tmpvpp->fixed_fps_numer, tmpvpp->fixed_fps_denom);
847  lives_entry_set_text(LIVES_ENTRY(vppa->fps_entry), tmp);
848  lives_free(tmp);
849  } else {
850  char *tmp = remove_trailing_zeroes(tmpvpp->fixed_fpsd);
851  lives_entry_set_text(LIVES_ENTRY(vppa->fps_entry), tmp);
852  lives_free(tmp);
853  }
854  }
855  }
856 
857  // frame size
858 
859  if (!(tmpvpp->capabilities & VPP_LOCAL_DISPLAY)) {
860  hbox = lives_hbox_new(FALSE, 0);
861  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
862 
863  add_fill_to_box(LIVES_BOX(hbox));
864 
865  hsize = tmpvpp->fwidth > 0 ? tmpvpp->fwidth :
866  intention == LIVES_INTENTION_TRANSCODE ? cfile->hsize : DEF_VPP_HSIZE;
867 
868  vppa->spinbuttonw = lives_standard_spin_button_new(_("_Width"),
869  hsize,
870  4., MAX_FRAME_WIDTH, 4., 16., 0, LIVES_BOX(hbox), NULL);
871 
872  add_fill_to_box(LIVES_BOX(hbox));
873 
874  vsize = tmpvpp->fheight > 0 ? tmpvpp->fheight :
875  intention == LIVES_INTENTION_TRANSCODE ? cfile->vsize : DEF_VPP_VSIZE;
876 
877  vppa->spinbuttonh = lives_standard_spin_button_new(_("_Height"),
878  vsize,
879  4., MAX_FRAME_HEIGHT, 4., 16., 0, LIVES_BOX(hbox), NULL);
880 
881  if (intention == LIVES_INTENTION_TRANSCODE) {
882  if (mainw->event_list) {
884  } else {
885  // add aspect ratio butto
886  lives_special_aspect_t *aspect;
887  /* hbox = lives_hbox_new(FALSE, 0); */
888  /* lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height); */
889  aspect = (lives_special_aspect_t *)add_aspect_ratio_button(LIVES_SPIN_BUTTON(vppa->spinbuttonw),
890  LIVES_SPIN_BUTTON(vppa->spinbuttonh), LIVES_BOX(hbox));
891  // don't reset the aspect params when we make_param_box
892  aspect->no_reset = TRUE;
893  }
894  }
895  add_fill_to_box(LIVES_BOX(hbox));
896  }
897 
898  if (intention == LIVES_INTENTION_PLAY) {
899  if (tmpvpp->get_palette_list && (pal_list = (*tmpvpp->get_palette_list)())) {
900  int i;
901 
902  for (i = 0; pal_list[i] != WEED_PALETTE_END; i++) {
903  int j = 0;
904  string = weed_palette_get_name(pal_list[i]);
905  if (weed_palette_is_yuv(pal_list[i]) && tmpvpp->get_yuv_palette_clamping) {
906  int *clampings = (*tmpvpp->get_yuv_palette_clamping)(pal_list[i]);
907  while (clampings[j] != -1) {
908  char *string2 = lives_strdup_printf("%s (%s)", string, weed_yuv_clamping_get_name(clampings[j]));
909  pal_list_strings = lives_list_append(pal_list_strings, string2);
910  j++;
911  }
912  }
913  if (j == 0) {
914  pal_list_strings = lives_list_append(pal_list_strings, lives_strdup(string));
915  }
916  }
917 
918  combo = lives_standard_combo_new((tmp = (_("_Colourspace"))), pal_list_strings,
919  LIVES_BOX(dialog_vbox), tmp2 = (_("Colourspace input to the plugin.\n")));
920  lives_free(tmp);
921  lives_free(tmp2);
922  vppa->pal_entry = lives_combo_get_entry(LIVES_COMBO(combo));
923 
924  if (tmpvpp->get_yuv_palette_clamping && weed_palette_is_yuv(tmpvpp->palette)) {
925  int *clampings = tmpvpp->get_yuv_palette_clamping(tmpvpp->palette);
926  if (clampings[0] != -1)
927  ctext = lives_strdup_printf("%s (%s)", weed_palette_get_name(tmpvpp->palette),
929  }
930  if (!ctext) ctext = lives_strdup(weed_palette_get_name(tmpvpp->palette));
931  lives_entry_set_text(LIVES_ENTRY(vppa->pal_entry), ctext);
932  lives_free(ctext);
933  lives_list_free_all(&pal_list_strings);
934  }
935  }
936  if (intention == LIVES_INTENTION_TRANSCODE) {
937  vppa->apply_fx = lives_standard_check_button_new(_("Apply current realtime effects"),
938  FALSE, LIVES_BOX(dialog_vbox), NULL);
940  }
941 
942  // extra params
943  if (tmpvpp->get_init_rfx) {
944  LiVESWidget *vbox = lives_vbox_new(FALSE, 0);
945  /* LiVESWidget *scrolledwindow = lives_standard_scrolled_window_new(RFX_WINSIZE_H, RFX_WINSIZE_V / 2, vbox); */
946  lives_box_pack_start(LIVES_BOX(dialog_vbox), vbox, TRUE, TRUE, 0);
947  plugin_run_param_window((*tmpvpp->get_init_rfx)(intention), LIVES_VBOX(vbox), &(vppa->rfx));
948  if (intention != LIVES_INTENTION_TRANSCODE) {
949  char *fnamex = lives_build_filename(prefs->workdir, vppa->rfx->name, NULL);
950  if (lives_file_test(fnamex, LIVES_FILE_TEST_EXISTS))
951  lives_rm(fnamex);
952  lives_free(fnamex);
953  }
954  if (tmpvpp->extra_argv && tmpvpp->extra_argc > 0) {
955  // update with defaults
956  LiVESList *plist = argv_to_marshalled_list(vppa->rfx, tmpvpp->extra_argc, tmpvpp->extra_argv);
957  param_demarshall(vppa->rfx, plist, FALSE, FALSE); // set defaults
958  param_demarshall(vppa->rfx, plist, FALSE, TRUE); // update widgets
959  lives_list_free_all(&plist);
960  }
961  }
962 
963  cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(vppa->dialog), LIVES_STOCK_CANCEL, NULL,
964  LIVES_RESPONSE_CANCEL);
965 
966  lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
967  LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
968 
969  if (intention == LIVES_INTENTION_PLAY) {
970  savebutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(vppa->dialog), LIVES_STOCK_SAVE_AS, NULL,
971  LIVES_RESPONSE_BROWSE);
972 
973  lives_widget_set_tooltip_text(savebutton, _("Save settings to an alternate file.\n"));
974  lives_signal_connect(LIVES_GUI_OBJECT(savebutton), LIVES_WIDGET_CLICKED_SIGNAL,
975  LIVES_GUI_CALLBACK(on_vppa_save_clicked),
976  vppa);
977  }
978 
979  okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(vppa->dialog), LIVES_STOCK_OK, NULL,
980  LIVES_RESPONSE_OK);
981 
983 
984  lives_signal_sync_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
985  LIVES_GUI_CALLBACK(on_vppa_cancel_clicked), vppa);
986 
987  lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
988  LIVES_GUI_CALLBACK(on_vppa_ok_clicked), vppa);
989 
991  lives_window_present(LIVES_WINDOW(vppa->dialog));
993 
994  return vppa;
995 }
996 
997 
999  register int i;
1000 
1001  if (vpp) {
1002  if (vpp == mainw->vpp) {
1004  if (mainw->ext_playback) {
1005  pthread_mutex_lock(&mainw->vpp_stream_mutex);
1006  mainw->ext_audio = FALSE;
1008  pthread_mutex_unlock(&mainw->vpp_stream_mutex);
1009  if (mainw->vpp->exit_screen) {
1011  }
1012 #ifdef RT_AUDIO
1014 #endif
1016  if (mainw->play_window && prefs->play_monitor == 0)
1018  }
1019  mainw->stream_ticks = -1;
1020  mainw->vpp = NULL;
1021  }
1022  if (vpp->module_unload)(vpp->module_unload)();
1023  dlclose(vpp->handle);
1024 
1025  if (vpp->extra_argv) {
1026  for (i = 0; vpp->extra_argv[i]; i++) {
1027  lives_free(vpp->extra_argv[i]);
1028  }
1029  lives_free(vpp->extra_argv);
1030  }
1031 
1032  for (i = 0; i < vpp->num_play_params + vpp->num_alpha_chans; i++) {
1033  weed_plant_free(vpp->play_params[i]);
1034  }
1035 
1036  lives_freep((void **)&vpp->play_params);
1037  lives_free(vpp);
1038  }
1039 }
1040 
1041 
1042 const weed_plant_t *pp_get_param(weed_plant_t **pparams, int idx) {
1043  register int i = 0;
1044  while (pparams[i]) {
1045  if (WEED_PLANT_IS_PARAMETER(pparams[i])) {
1046  if (--idx < 0) return pparams[i];
1047  }
1048  i++;
1049  }
1050  return NULL;
1051 }
1052 
1053 
1054 const weed_plant_t *pp_get_chan(weed_plant_t **pparams, int idx) {
1055  register int i = 0;
1056  while (pparams[i]) {
1057  if (WEED_PLANT_IS_CHANNEL(pparams[i])) {
1058  if (--idx < 0) return pparams[i];
1059  }
1060  i++;
1061  }
1062  return NULL;
1063 }
1064 
1065 
1067  int *pal_list, i = 0;
1068  if (vpp->get_palette_list && (pal_list = (*vpp->get_palette_list)())) {
1069  int palette = weed_layer_get_palette(layer);
1070  for (i = 0; pal_list[i] != WEED_PALETTE_END; i++) {
1071  if (pal_list[i] == palette) break;
1072  }
1073  if (pal_list[i] == WEED_PALETTE_END) {
1074  if (!i) return FALSE;
1075  palette = best_palette_match(pal_list, i, palette);
1076  }
1077  if (palette == WEED_PALETTE_END) return FALSE;
1078  if (palette != vpp->palette) {
1079  if (!(*vpp->set_palette)(palette)) {
1080  return FALSE;
1081  }
1082  }
1083  vpp->palette = palette;
1085  int *yuv_clamping_types = (*vpp->get_yuv_palette_clamping)(vpp->palette);
1086  int lclamping = weed_layer_get_yuv_clamping(layer);
1087  for (i = 0; yuv_clamping_types[i] != -1; i++) {
1088  if (yuv_clamping_types[i] == lclamping) {
1089  if ((*vpp->set_yuv_palette_clamping)(lclamping))
1090  vpp->YUV_clamping = lclamping;
1091  break;
1092  // *INDENT-OFF*
1093  }}}}
1094  // *INDENT-ON*
1095  return FALSE;
1096 }
1097 
1098 
1099 _vid_playback_plugin *open_vid_playback_plugin(const char *name, boolean in_use) {
1100  // this is called on startup or when the user selects a new playback plugin
1101 
1102  // if in_use is TRUE, it is our active vpp
1103 
1104  // TODO - if in_use, get fixed_fps,fwidth,fheight,palette,argc and argv from a file
1105 
1106  _vid_playback_plugin *vpp;
1107  char **array;
1108  const char *fps_list;
1109  const char *pl_error;
1110  void *handle;
1111  int *palette_list;
1112  char *msg, *tmp;
1113  char *plugname;
1114  int dlflags = RTLD_LAZY;
1115  boolean OK = TRUE;
1116 
1117  if (in_use && LIVES_IS_PLAYING && mainw->noswitch) {
1118  mainw->new_vpp = name;
1119  return NULL;
1120  }
1121 
1122  tmp = lives_strdup_printf("%s.%s", name, DLL_NAME);
1123  plugname = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_VID_PLAYBACK, tmp, NULL);
1124  lives_free(tmp);
1125 
1126  handle = dlopen(plugname, dlflags);
1127 
1128  if (!handle) {
1129  char *msg = lives_strdup_printf(_("\n\nFailed to open playback plugin %s\nError was %s\n"
1130  "Playback plugin will be disabled,\n"
1131  "it can be re-enabled in Preferences / Playback.\n"), plugname, dlerror());
1132  if (prefs->startup_phase != 1 && prefs->startup_phase != -1) {
1133  if (!prefsw) widget_opts.non_modal = TRUE;
1134  do_error_dialog(msg);
1136  }
1137  LIVES_ERROR(msg);
1138  lives_free(msg);
1139  lives_free(plugname);
1141  set_vpp(TRUE);
1142  return NULL;
1143  }
1144 
1146 
1147  vpp->play_paramtmpls = NULL;
1148  vpp->get_init_rfx = NULL;
1149  vpp->play_params = NULL;
1150  vpp->alpha_chans = NULL;
1151  vpp->num_play_params = vpp->num_alpha_chans = 0;
1152  vpp->extra_argv = NULL;
1153 
1154  if ((vpp->module_check_init = (const char *(*)())dlsym(handle, "module_check_init")) == NULL) {
1155  OK = FALSE;
1156  }
1157  if ((vpp->version = (const char *(*)())dlsym(handle, "version")) == NULL) {
1158  OK = FALSE;
1159  }
1160  if ((vpp->get_palette_list = (int *(*)())dlsym(handle, "get_palette_list")) == NULL) {
1161  OK = FALSE;
1162  }
1163  if ((vpp->set_palette = (boolean(*)(int))dlsym(handle, "set_palette")) == NULL) {
1164  OK = FALSE;
1165  }
1166  if ((vpp->get_capabilities = (uint64_t (*)(int))dlsym(handle, "get_capabilities")) == NULL) {
1167  OK = FALSE;
1168  }
1169  if ((vpp->render_frame = (boolean(*)(int, int, int64_t, void **, void **, weed_plant_t **))
1170  dlsym(handle, "render_frame")) == NULL) {
1171  if ((vpp->play_frame = (boolean(*)(weed_layer_t *, ticks_t, weed_layer_t *))
1172  dlsym(handle, "play_frame")) == NULL) {
1173  OK = FALSE;
1174  }
1175  }
1176  if ((vpp->get_fps_list = (const char *(*)(int))dlsym(handle, "get_fps_list"))) {
1177  if ((vpp->set_fps = (boolean(*)(double))dlsym(handle, "set_fps")) == NULL) {
1178  OK = FALSE;
1179  }
1180  }
1181 
1182  if (!OK) {
1183  char *msg = lives_strdup_printf
1184  (_("\n\nPlayback module %s\nis missing a mandatory function.\nUnable to use it.\n"), plugname);
1186  do_error_dialog(msg);
1187  lives_free(msg);
1188  dlclose(handle);
1189  lives_free(vpp);
1190  vpp = NULL;
1191  lives_free(plugname);
1192  return NULL;
1193  }
1194 
1195  if ((pl_error = (*vpp->module_check_init)())) {
1196  msg = lives_strdup_printf(_("Video playback plugin failed to initialise.\nError was: %s\n"), pl_error);
1197  if (prefs->startup_phase != 1 && prefs->startup_phase != -1) {
1198  do_error_dialog(msg);
1199  } else {
1200  LIVES_ERROR(msg);
1201  }
1202  lives_free(msg);
1203  dlclose(handle);
1204  lives_free(vpp);
1205  vpp = NULL;
1206  lives_free(plugname);
1207  return NULL;
1208  }
1209 
1210  // now check for optional functions
1211  vpp->weed_setup = (weed_plant_t *(*)(weed_bootstrap_f))dlsym(handle, "weed_setup");
1212 
1213  if (vpp->weed_setup) {
1214  weed_set_host_info_callback(host_info_cb, LIVES_INT_TO_POINTER(100));
1215  (*vpp->weed_setup)(weed_bootstrap);
1216  }
1217 
1218  vpp->get_description = (const char *(*)())dlsym(handle, "get_description");
1219  vpp->get_init_rfx = (const char *(*)())dlsym(handle, "get_init_rfx");
1220 
1221  vpp->get_play_params = (const weed_plant_t **(*)(weed_bootstrap_f))dlsym(handle, "get_play_params");
1222 
1223  vpp->get_yuv_palette_clamping = (int *(*)(int))dlsym(handle, "get_yuv_palette_clamping");
1224  vpp->set_yuv_palette_clamping = (int (*)(int))dlsym(handle, "set_yuv_palette_clamping");
1225  vpp->get_audio_fmts = (int *(*)())dlsym(handle, "get_audio_fmts");
1226  vpp->init_screen = (boolean(*)(int, int, boolean, uint64_t, int, char **))dlsym(handle, "init_screen");
1227  vpp->init_audio = (boolean(*)(int, int, int, char **))dlsym(handle, "init_audio");
1228  vpp->render_audio_frame_float = (boolean(*)(float **, int))dlsym(handle, "render_audio_frame_float");
1229  vpp->exit_screen = (void (*)(uint16_t, uint16_t))dlsym(handle, "exit_screen");
1230  vpp->module_unload = (void (*)())dlsym(handle, "module_unload");
1231 
1232  vpp->YUV_sampling = 0;
1233  vpp->YUV_subspace = 0;
1234 
1235  palette_list = (*vpp->get_palette_list)();
1236 
1237  if (future_prefs->vpp_argv) {
1240  } else {
1241  if (!in_use && mainw->vpp && !(strcmp(name, mainw->vpp->name))) {
1242  vpp->palette = mainw->vpp->palette;
1244  } else {
1245  vpp->palette = palette_list[0];
1246  vpp->YUV_clamping = -1;
1247  }
1248  }
1249 
1251  vpp->capabilities = (*vpp->get_capabilities)(vpp->palette);
1252 
1254  vpp->fwidth = vpp->fheight = -1;
1255  } else {
1256  vpp->fwidth = vpp->fheight = 0;
1257  }
1258  if (future_prefs->vpp_argv) {
1259  vpp->fwidth = future_prefs->vpp_fwidth;
1261  } else if (!in_use && mainw->vpp && !(strcmp(name, mainw->vpp->name))) {
1262  vpp->fwidth = mainw->vpp->fwidth;
1263  vpp->fheight = mainw->vpp->fheight;
1264  }
1265  if (vpp->fwidth == -1 && !(vpp->capabilities & VPP_CAN_RESIZE && vpp->capabilities & VPP_LOCAL_DISPLAY)) {
1266  vpp->fwidth = vpp->fheight = 0;
1267  }
1268 
1269  vpp->fixed_fpsd = -1.;
1270  vpp->fixed_fps_numer = 0;
1271 
1272  if (future_prefs->vpp_argv) {
1276  } else if (!in_use && mainw->vpp && !(strcmp(name, mainw->vpp->name))) {
1277  vpp->fixed_fpsd = mainw->vpp->fixed_fpsd;
1280  }
1281 
1282  vpp->handle = handle;
1283  lives_snprintf(vpp->name, 256, "%s", name);
1284 
1285  if (future_prefs->vpp_argv) {
1287  vpp->extra_argv = (char **)lives_calloc((vpp->extra_argc + 1), (sizeof(char *)));
1288  for (register int i = 0; i <= vpp->extra_argc; i++) vpp->extra_argv[i] = lives_strdup(future_prefs->vpp_argv[i]);
1289  } else {
1290  if (!in_use && mainw->vpp && !(strcmp(name, mainw->vpp->name))) {
1291  vpp->extra_argc = mainw->vpp->extra_argc;
1292  vpp->extra_argv = (char **)lives_calloc((mainw->vpp->extra_argc + 1), (sizeof(char *)));
1293  for (register int i = 0; i <= vpp->extra_argc; i++) vpp->extra_argv[i] = lives_strdup(mainw->vpp->extra_argv[i]);
1294  } else {
1295  vpp->extra_argc = 0;
1296  vpp->extra_argv = (char **)lives_malloc(sizeof(char *));
1297  vpp->extra_argv[0] = NULL;
1298  }
1299  }
1300  // see if plugin is using fixed fps
1301 
1302  if (vpp->fixed_fpsd <= 0. && vpp->get_fps_list) {
1303  // fixed fps
1304 
1305  if ((fps_list = (*vpp->get_fps_list)(vpp->palette))) {
1306  array = lives_strsplit(fps_list, "|", -1);
1307  if (get_token_count(array[0], ':') > 1) {
1308  char **array2 = lives_strsplit(array[0], ":", 2);
1309  vpp->fixed_fps_numer = atoi(array2[0]);
1310  vpp->fixed_fps_denom = atoi(array2[1]);
1311  lives_strfreev(array2);
1312  vpp->fixed_fpsd = get_ratio_fps(array[0]);
1313  } else {
1314  vpp->fixed_fpsd = lives_strtod(array[0], NULL);
1315  vpp->fixed_fps_numer = 0;
1316  }
1317  lives_strfreev(array);
1318  }
1319  }
1320 
1321  if (vpp->YUV_clamping == -1) {
1322  vpp->YUV_clamping = WEED_YUV_CLAMPING_CLAMPED;
1323 
1325  int *yuv_clamping_types = (*vpp->get_yuv_palette_clamping)(vpp->palette);
1326  if (yuv_clamping_types[0] != -1) vpp->YUV_clamping = yuv_clamping_types[0];
1327  }
1328  }
1329 
1330  if (vpp->get_audio_fmts && mainw->is_ready) vpp->audio_codec = get_best_audio(vpp);
1331  if (prefsw) {
1334  }
1335 
1337  if (vpp->get_play_params) {
1338  vpp->play_paramtmpls = (*vpp->get_play_params)(NULL);
1339  }
1340 
1341  // create vpp->play_params
1342  if (vpp->play_paramtmpls) {
1343  register int i;
1344  weed_plant_t *ptmpl;
1345  for (i = 0; (ptmpl = (weed_plant_t *)vpp->play_paramtmpls[i]); i++) {
1346  vpp->play_params = (weed_plant_t **)lives_realloc(vpp->play_params, (i + 2) * sizeof(weed_plant_t *));
1347  if (WEED_PLANT_IS_PARAMETER_TEMPLATE(ptmpl)) {
1348  // is param template, create a param
1349  vpp->play_params[i] = weed_plant_new(WEED_PLANT_PARAMETER);
1350  weed_leaf_copy(vpp->play_params[i], WEED_LEAF_VALUE, ptmpl, WEED_LEAF_DEFAULT);
1351  weed_set_plantptr_value(vpp->play_params[i], WEED_LEAF_TEMPLATE, ptmpl);
1352  vpp->num_play_params++;
1353  } else {
1354  // must be an alpha channel
1355  vpp->play_params[i] = weed_plant_new(WEED_PLANT_CHANNEL);
1356  weed_set_plantptr_value(vpp->play_params[i], WEED_LEAF_TEMPLATE, ptmpl);
1357  vpp->num_alpha_chans++;
1358  }
1359  }
1360  vpp->play_params[i] = NULL;
1361  }
1362 
1363  if (!in_use) return vpp;
1364 
1365  if (!mainw->is_ready) {
1366  double fixed_fpsd = vpp->fixed_fpsd;
1367  int fwidth = vpp->fwidth;
1368  int fheight = vpp->fheight;
1369 
1370  mainw->vpp = vpp;
1372  if (fixed_fpsd < 0.) vpp->fixed_fpsd = fixed_fpsd;
1373  if (fwidth < 0) vpp->fwidth = fwidth;
1374  if (fheight < 0) vpp->fheight = fheight;
1375  }
1376 
1377  if (!(*vpp->set_palette)(vpp->palette)) {
1380  lives_free(plugname);
1381  return NULL;
1382  }
1383 
1385 
1386  if (vpp->get_fps_list) {
1387  if (mainw->fixed_fpsd > 0. || (vpp->fixed_fpsd > 0. && vpp->set_fps &&
1388  !((*vpp->set_fps)(vpp->fixed_fpsd)))) {
1389  do_vpp_fps_error();
1390  vpp->fixed_fpsd = -1.;
1391  vpp->fixed_fps_numer = 0;
1392  }
1393  }
1394 
1395  cached_key = cached_mod = 0;
1396 
1397  // TODO: - support other YUV subspaces
1398  d_print(_("*** Using %s plugin for fs playback, agreed to use palette type %d ( %s ). ***\n"), name,
1399  vpp->palette, (tmp = weed_palette_get_name_full(vpp->palette, vpp->YUV_clamping,
1400  WEED_YUV_SUBSPACE_YCBCR)));
1401  lives_free(tmp);
1402 
1403  lives_free(plugname);
1404 
1405  if (mainw->is_ready && in_use && mainw->vpp) {
1407  }
1408 
1409  return vpp;
1410 }
1411 
1412 
1414  // external plugin
1415  if (mainw->ext_playback) {
1416  pthread_mutex_lock(&mainw->vpp_stream_mutex);
1417  mainw->ext_audio = FALSE;
1418  pthread_mutex_unlock(&mainw->vpp_stream_mutex);
1420 
1421  if (mainw->vpp->exit_screen) {
1423  }
1424 #ifdef RT_AUDIO
1426 #endif
1429  if (mainw->play_window && prefs->play_monitor == 0)
1431  }
1432  mainw->stream_ticks = -1;
1433 
1435  if (mainw->play_window) {
1437  }
1438 }
1439 
1440 
1442  // find best audio from video plugin list, matching with audiostream plugins
1443 
1444  // i.e. cross-check video list with astreamer list
1445 
1446  // only for plugins which want to stream audiom but dont provide a render_audio_frame()
1447 
1448  int *fmts, *sfmts;
1449  int ret = AUDIO_CODEC_NONE;
1450  int i, j = 0, nfmts;
1451  char *astreamer, *com;
1452  char buf[1024];
1453  char **array;
1454 
1455  if (vpp && vpp->get_audio_fmts) {
1456  fmts = (*vpp->get_audio_fmts)(); // const, so do not free()
1457 
1458  // make audiostream plugin name
1459  astreamer = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_AUDIO_STREAM, AUDIO_STREAMER_NAME, NULL);
1460 
1461  // create sfmts array and nfmts
1462 
1463  com = lives_strdup_printf("\"%s\" get_formats", astreamer);
1464  lives_popen(com, FALSE, buf, 1024);
1465  lives_free(com);
1466 
1467  nfmts = get_token_count(buf, '|');
1468  array = lives_strsplit(buf, "|", nfmts);
1469  sfmts = (int *)lives_calloc(nfmts, sizint);
1470 
1471  for (i = 0; i < nfmts; i++) {
1472  if (array[i] && *array[i]) sfmts[j++] = atoi(array[i]);
1473  }
1474 
1475  nfmts = j;
1476  lives_strfreev(array);
1477 
1478  for (i = 0; fmts[i] != -1; i++) {
1479  // traverse video list and see if audiostreamer supports each one
1480  if (int_array_contains_value(sfmts, nfmts, fmts[i])) {
1481 
1482  com = lives_strdup_printf("\"%s\" check %d", astreamer, fmts[i]);
1483  lives_popen(com, FALSE, buf, 1024);
1484  lives_free(com);
1485 
1486  if (THREADVAR(com_failed)) {
1487  lives_free(astreamer);
1488  lives_free(com);
1489  lives_free(sfmts);
1490  return ret;
1491  }
1492 
1493  if (*buf) {
1494  if (i == 0 && prefsw) {
1495  do_error_dialog(buf);
1496  d_print(_("Audio stream unable to use preferred format '%s'\n"), anames[fmts[i]]);
1497  }
1498  continue;
1499  }
1500 
1501  if (i > 0 && prefsw) {
1502  d_print(_("Using format '%s' instead.\n"), anames[fmts[i]]);
1503  }
1504  ret = fmts[i];
1505  break;
1506  }
1507  }
1508 
1509  if (fmts[i] == -1) {
1510  //none suitable, stick with first
1511  for (i = 0; fmts[i] != -1; i++) {
1512  // traverse video list and see if audiostreamer supports each one
1513  if (int_array_contains_value(sfmts, nfmts, fmts[i])) {
1514  ret = fmts[i];
1515  break;
1516  }
1517  }
1518  }
1519 
1520  lives_free(sfmts);
1521  lives_free(astreamer);
1522  }
1523 
1524  return ret;
1525 }
1526 
1527 
1529 // encoder plugins
1530 
1531 void do_plugin_encoder_error(const char *plugin_name) {
1532  char *msg, *tmp;
1533 
1534  if (!plugin_name) {
1535  msg = lives_strdup_printf(
1536  _("LiVES was unable to find its encoder plugins. Please make sure you have the plugins installed in\n"
1537  "%s%s%s\nor change the value of <lib_dir> in %s\n"),
1539  (tmp = lives_filename_to_utf8(prefs->configfile, -1, NULL, NULL, NULL)));
1540  lives_free(tmp);
1542  do_error_dialog(msg);
1543  lives_free(msg);
1544  return;
1545  }
1546 
1547  msg = lives_strdup_printf(
1548  _("LiVES did not receive a response from the encoder plugin called '%s'.\n"
1549  "Please make sure you have that plugin installed correctly in\n%s%s%s\n"
1550  "or switch to another plugin using Tools|Preferences|Encoding\n"),
1551  plugin_name, prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_ENCODERS);
1552  do_error_dialog(msg);
1553  lives_free(msg);
1554 }
1555 
1556 
1557 boolean check_encoder_restrictions(boolean get_extension, boolean user_audio, boolean save_all) {
1558  LiVESList *ofmt_all = NULL;
1559  char **checks;
1560  char **array = NULL;
1561  char **array2;
1562  char aspect_buffer[512];
1563 
1564  // for auto resizing/resampling
1565  double best_fps = 0.;
1566  double fps;
1567  double best_fps_delta = 0.;
1568 
1569  boolean sizer = FALSE;
1570  boolean allow_aspect_override = FALSE;
1571  boolean calc_aspect = FALSE;
1572  boolean swap_endian = FALSE;
1573 
1574  int best_arate = 0;
1575  int width, owidth;
1576  int height, oheight;
1577  int best_arate_delta = 0;
1578  int hblock = 2, vblock = 2;
1579  int i, r, val;
1580  int pieces, numtok;
1581  int best_fps_num = 0, best_fps_denom = 0;
1582  int arate, achans, asampsize, asigned = 0;
1583 
1584  if (!rdet) {
1585  width = owidth = cfile->hsize;
1586  height = oheight = cfile->vsize;
1587  fps = cfile->fps;
1588  } else {
1589  width = owidth = rdet->width;
1590  height = oheight = rdet->height;
1591  fps = rdet->fps;
1593  }
1594 
1595  if (mainw->osc_auto) {
1596  if (mainw->osc_enc_width > 0) {
1597  width = mainw->osc_enc_width;
1598  height = mainw->osc_enc_height;
1599  }
1600  if (mainw->osc_enc_fps != 0.) fps = mainw->osc_enc_fps;
1601  }
1602 
1603  // TODO - allow lists for size
1604  lives_snprintf(prefs->encoder.of_restrict, 5, "none");
1605  if ((ofmt_all = plugin_request_by_line(PLUGIN_ENCODERS, prefs->encoder.name, "get_formats"))) {
1606  // get any restrictions for the current format
1607  for (i = 0; i < lives_list_length(ofmt_all); i++) {
1608  if ((numtok = get_token_count((char *)lives_list_nth_data(ofmt_all, i), '|')) > 2) {
1609  array = lives_strsplit((char *)lives_list_nth_data(ofmt_all, i), "|", -1);
1610  if (!strcmp(array[0], prefs->encoder.of_name)) {
1611  if (numtok > 5) {
1612  lives_snprintf(prefs->encoder.ptext, 512, "%s", array[5]);
1613  } else {
1614  lives_memset(prefs->encoder.ptext, 0, 1);
1615  }
1616  if (numtok > 4) {
1617  lives_snprintf(prefs->encoder.of_def_ext, 16, "%s", array[4]);
1618  } else {
1620  }
1621  if (numtok > 3) {
1622  lives_snprintf(prefs->encoder.of_restrict, 128, "%s", array[3]);
1623  } else {
1624  lives_snprintf(prefs->encoder.of_restrict, 128, "none");
1625  }
1626  prefs->encoder.of_allowed_acodecs = atoi(array[2]);
1627  lives_list_free_all(&ofmt_all);
1628  lives_strfreev(array);
1629  break;
1630  }
1631  lives_strfreev(array);
1632  }
1633  }
1634  }
1635 
1636  if (get_extension) {
1637  return TRUE; // just wanted file extension
1638  }
1639 
1643  return FALSE;
1644  }
1645  }
1646 
1647  if (user_audio && future_prefs->encoder.of_allowed_acodecs == 0) best_arate = -1;
1648 
1649  if ((!*prefs->encoder.of_restrict || !strcmp(prefs->encoder.of_restrict, "none")) && best_arate > -1) {
1650  return TRUE;
1651  }
1652 
1653  if (!rdet) {
1654  arate = cfile->arate;
1655  achans = cfile->achans;
1656  asampsize = cfile->asampsize;
1657  } else {
1658  arate = rdet->arate;
1659  achans = rdet->achans;
1660  asampsize = rdet->asamps;
1661  }
1662 
1663  // audio endianness check - what should we do for big-endian machines ?
1664  if (((mainw->save_with_sound || rdet) && (!resaudw || resaudw->aud_checkbutton ||
1665  lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->aud_checkbutton))))
1666  && prefs->encoder.audio_codec != AUDIO_CODEC_NONE && arate != 0 && achans != 0 && asampsize != 0) {
1667  if (rdet && !rdet->is_encoding) {
1668  if (mainw->endian != AFORM_BIG_ENDIAN && (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend))))
1669  swap_endian = TRUE;
1670  } else {
1671  if (mainw->endian != AFORM_BIG_ENDIAN && (cfile->signed_endian & AFORM_BIG_ENDIAN)) swap_endian = TRUE;
1672  //if (mainw->endian==AFORM_BIG_ENDIAN && (cfile->signed_endian&AFORM_BIG_ENDIAN)) swap_endian=TRUE; // needs test
1673  }
1674  }
1675 
1676  if (*prefs->encoder.of_restrict) {
1677  pieces = get_token_count(prefs->encoder.of_restrict, ',');
1678  checks = lives_strsplit(prefs->encoder.of_restrict, ",", pieces);
1679 
1680  for (r = 0; r < pieces; r++) {
1681  // check each restriction in turn
1682 
1683  if (!strncmp(checks[r], "fps=", 4)) {
1684  double allowed_fps;
1685  int mbest_num = 0, mbest_denom = 0;
1686  int numparts;
1687  char *fixer;
1688 
1689  best_fps_delta = 1000000000.;
1690  array = lives_strsplit(checks[r], "=", 2);
1691  numtok = get_token_count(array[1], ';');
1692  array2 = lives_strsplit(array[1], ";", numtok);
1693  for (i = 0; i < numtok; i++) {
1694  mbest_num = mbest_denom = 0;
1695  if ((numparts = get_token_count(array2[i], ':')) > 1) {
1696  char **array3 = lives_strsplit(array2[i], ":", 2);
1697  mbest_num = atoi(array3[0]);
1698  mbest_denom = atoi(array3[1]);
1699  lives_strfreev(array3);
1700  if (mbest_denom == 0) continue;
1701  allowed_fps = (mbest_num * 1.) / (mbest_denom * 1.);
1702  } else allowed_fps = lives_strtod(array2[i], NULL);
1703 
1704  // convert to 8dp
1705  fixer = lives_strdup_printf("%.8f %.8f", allowed_fps, fps);
1706  lives_free(fixer);
1707 
1708  if (allowed_fps >= fps) {
1709  if (allowed_fps - fps < best_fps_delta) {
1710  best_fps_delta = allowed_fps - fps;
1711  if (mbest_denom > 0) {
1712  best_fps_num = mbest_num;
1713  best_fps_denom = mbest_denom;
1714  best_fps = 0.;
1715  if (!rdet) cfile->ratio_fps = TRUE;
1716  else rdet->ratio_fps = TRUE;
1717  } else {
1718  best_fps_num = best_fps_denom = 0;
1719  best_fps = allowed_fps;
1720  if (!rdet) cfile->ratio_fps = FALSE;
1721  else rdet->ratio_fps = FALSE;
1722  }
1723  }
1724  } else if ((best_fps_denom == 0 && allowed_fps > best_fps) || (best_fps_denom > 0
1725  && allowed_fps > (best_fps_num * 1.) /
1726  (best_fps_denom * 1.))) {
1727  best_fps_delta = fps - allowed_fps;
1728  if (mbest_denom > 0) {
1729  best_fps_num = mbest_num;
1730  best_fps_denom = mbest_denom;
1731  best_fps = 0.;
1732  if (!rdet) cfile->ratio_fps = TRUE;
1733  else rdet->ratio_fps = TRUE;
1734  } else {
1735  best_fps = allowed_fps;
1736  best_fps_num = best_fps_denom = 0;
1737  if (!rdet) cfile->ratio_fps = FALSE;
1738  else rdet->ratio_fps = FALSE;
1739  }
1740  }
1741  if (best_fps_delta <= prefs->fps_tolerance) {
1742  best_fps_delta = 0.;
1743  best_fps_denom = best_fps_num = 0;
1744  }
1745  if (best_fps_delta == 0.) break;
1746  }
1747  lives_strfreev(array);
1748  lives_strfreev(array2);
1749  continue;
1750  }
1751 
1752  if (!strncmp(checks[r], "size=", 5)) {
1753  // TODO - allow list for size
1754  array = lives_strsplit(checks[r], "=", 2);
1755  array2 = lives_strsplit(array[1], "x", 2);
1756  width = atoi(array2[0]);
1757  height = atoi(array2[1]);
1758  lives_strfreev(array2);
1759  lives_strfreev(array);
1760  sizer = TRUE;
1761  continue;
1762  }
1763 
1764  if (!strncmp(checks[r], "minw=", 5)) {
1765  array = lives_strsplit(checks[r], "=", 2);
1766  val = atoi(array[1]);
1767  if (width < val) width = val;
1768  lives_strfreev(array);
1769  continue;
1770  }
1771 
1772  if (!strncmp(checks[r], "minh=", 5)) {
1773  array = lives_strsplit(checks[r], "=", 2);
1774  val = atoi(array[1]);
1775  if (height < val) height = val;
1776  lives_strfreev(array);
1777  continue;
1778  }
1779 
1780  if (!strncmp(checks[r], "maxh=", 5)) {
1781  array = lives_strsplit(checks[r], "=", 2);
1782  val = atoi(array[1]);
1783  if (height > val) height = val;
1784  lives_strfreev(array);
1785  continue;
1786  }
1787 
1788  if (!strncmp(checks[r], "maxw=", 5)) {
1789  array = lives_strsplit(checks[r], "=", 2);
1790  val = atoi(array[1]);
1791  if (width > val) width = val;
1792  lives_strfreev(array);
1793  continue;
1794  }
1795 
1796  if (!strncmp(checks[r], "asigned=", 8) &&
1797  ((mainw->save_with_sound || rdet) && (!resaudw ||
1800  (LIVES_TOGGLE_BUTTON(resaudw->aud_checkbutton)))) &&
1802  && arate != 0 && achans != 0 && asampsize != 0) {
1803  array = lives_strsplit(checks[r], "=", 2);
1804  if (!strcmp(array[1], "signed")) {
1805  asigned = 1;
1806  }
1807 
1808  if (!strcmp(array[1], "unsigned")) {
1809  asigned = 2;
1810  }
1811 
1812  lives_strfreev(array);
1813 
1814  if (asigned != 0 && !capable->has_sox_sox) {
1816  lives_strfreev(checks);
1817  return FALSE;
1818  }
1819  continue;
1820  }
1821 
1822  if (!strncmp(checks[r], "arate=", 6) && ((mainw->save_with_sound || rdet) && (!resaudw ||
1825  (LIVES_TOGGLE_BUTTON
1826  (resaudw->aud_checkbutton)))) &&
1827  prefs->encoder.audio_codec != AUDIO_CODEC_NONE && arate != 0 && achans != 0 && asampsize != 0) {
1828  // we only perform this test if we are encoding with audio
1829  // find next highest allowed rate from list,
1830  // if none are higher, use the highest
1831  int allowed_arate;
1832  best_arate_delta = 1000000000;
1833 
1834  array = lives_strsplit(checks[r], "=", 2);
1835  numtok = get_token_count(array[1], ';');
1836  array2 = lives_strsplit(array[1], ";", numtok);
1837  for (i = 0; i < numtok; i++) {
1838  allowed_arate = atoi(array2[i]);
1839  if (allowed_arate >= arate) {
1840  if (allowed_arate - arate < best_arate_delta) {
1841  best_arate_delta = allowed_arate - arate;
1842  best_arate = allowed_arate;
1843  }
1844  } else if (allowed_arate > best_arate) best_arate = allowed_arate;
1845  }
1846  lives_strfreev(array2);
1847  lives_strfreev(array);
1848 
1849  if (!capable->has_sox_sox) {
1851  lives_strfreev(checks);
1852  return FALSE;
1853  }
1854  continue;
1855  }
1856 
1857  if (!strncmp(checks[r], "hblock=", 7)) {
1858  // width must be a multiple of this
1859  array = lives_strsplit(checks[r], "=", 2);
1860  hblock = atoi(array[1]);
1861  width = (int)(width / hblock + .5) * hblock;
1862  lives_strfreev(array);
1863  continue;
1864  }
1865 
1866  if (!strncmp(checks[r], "vblock=", 7)) {
1867  // height must be a multiple of this
1868  array = lives_strsplit(checks[r], "=", 2);
1869  vblock = atoi(array[1]);
1870  height = (int)(height / vblock + .5) * vblock;
1871  lives_strfreev(array);
1872  continue;
1873  }
1874 
1875  if (!strncmp(checks[r], "aspect=", 7)) {
1876  // we calculate the nearest smaller frame size using aspect,
1877  // hblock and vblock
1878  calc_aspect = TRUE;
1879  array = lives_strsplit(checks[r], "=", 2);
1880  lives_snprintf(aspect_buffer, 512, "%s", array[1]);
1881  lives_strfreev(array);
1882  continue;
1883  }
1884  }
1885 
1887  lives_strfreev(checks);
1888 
1889  if (!mainw->osc_auto && calc_aspect && !sizer) {
1890  // we calculate this last, after getting hblock and vblock sizes
1891  char **array3;
1892  double allowed_aspect;
1893  int xwidth = width;
1894  int xheight = height;
1895 
1896  width = height = 1000000;
1897 
1898  numtok = get_token_count(aspect_buffer, ';');
1899  array2 = lives_strsplit(aspect_buffer, ";", numtok);
1900 
1901  // see if we can get a width:height which is nearer an aspect than
1902  // current width:height
1903 
1904  for (i = 0; i < numtok; i++) {
1905  array3 = lives_strsplit(array2[i], ":", 2);
1906  allowed_aspect = lives_strtod(array3[0], NULL) / lives_strtod(array3[1], NULL);
1907  lives_strfreev(array3);
1908  minimise_aspect_delta(allowed_aspect, hblock, vblock, xwidth, xheight, &width, &height);
1909  }
1910  lives_strfreev(array2);
1911 
1912  // allow override if current width and height are integer multiples of blocks
1913  if (owidth % hblock == 0 && oheight % vblock == 0) allow_aspect_override = TRUE;
1914 
1915  // end recheck
1916  }
1917 
1918  // fps can't be altered if we have a multitrack event_list
1919  if (mainw->multitrack && mainw->multitrack->event_list) best_fps_delta = 0.;
1920 
1921  if (sizer) allow_aspect_override = FALSE;
1922  }
1923 
1924  // if we have min or max size, make sure we fit within that
1925 
1926  if (((width != owidth || height != oheight) && width * height > 0) || (best_fps_delta > 0.) || (best_arate_delta > 0 &&
1927  best_arate > 0) ||
1928  best_arate < 0 || asigned != 0 || swap_endian) {
1929  boolean ofx1_bool = mainw->fx1_bool;
1930  mainw->fx1_bool = FALSE;
1931  if ((width != owidth || height != oheight) && width * height > 0) {
1933  if (allow_aspect_override) {
1934  width = owidth;
1935  height = oheight;
1936  }
1937  }
1938  }
1939  if (rdet && !rdet->is_encoding) {
1940  rdet->arate = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_arate)));
1941  rdet->achans = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_achans)));
1942  rdet->asamps = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_asamps)));
1944  lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_littleend)));
1945 
1946  if (swap_endian || width != rdet->width || height != rdet->height || best_fps_delta != 0. || best_arate != rdet->arate ||
1947  ((asigned == 1 && (rdet->aendian & AFORM_UNSIGNED)) || (asigned == 2 && !(rdet->aendian & AFORM_SIGNED)))) {
1948 
1949  if (rdet_suggest_values(width, height, best_fps, best_fps_num, best_fps_denom, best_arate, asigned, swap_endian,
1950  allow_aspect_override, (best_fps_delta == 0.))) {
1951  char *arate_string;
1952  rdet->width = width;
1953  rdet->height = height;
1954  if (best_arate != -1) rdet->arate = best_arate;
1955  else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(resaudw->aud_checkbutton), FALSE);
1956 
1957  if (asigned == 1) lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(resaudw->rb_signed), TRUE);
1958  else if (asigned == 2) lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(resaudw->rb_unsigned), TRUE);
1959 
1960  if (swap_endian) {
1961  if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend)))
1962  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend), TRUE);
1963  else lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(resaudw->rb_littleend), TRUE);
1964  }
1965 
1966  if (best_fps_delta > 0.) {
1967  if (best_fps_denom > 0) {
1968  rdet->fps = (best_fps_num * 1.) / (best_fps_denom * 1.);
1969  } else rdet->fps = best_fps;
1970  lives_spin_button_set_value(LIVES_SPIN_BUTTON(rdet->spinbutton_fps), rdet->fps);
1971  }
1974  if (best_arate != -1) {
1975  arate_string = lives_strdup_printf("%d", best_arate);
1976  lives_entry_set_text(LIVES_ENTRY(resaudw->entry_arate), arate_string);
1977  lives_free(arate_string);
1978  }
1980  return TRUE;
1981  }
1982  }
1983  return FALSE;
1984  }
1985 
1986  if (mainw->osc_auto || do_encoder_restrict_dialog(width, height, best_fps, best_fps_num, best_fps_denom, best_arate,
1987  asigned, swap_endian, allow_aspect_override, save_all)) {
1988  if (!mainw->fx1_bool && mainw->osc_enc_width == 0) {
1989  width = owidth;
1990  height = oheight;
1991  }
1992 
1993  if (!auto_resample_resize(width, height, best_fps, best_fps_num, best_fps_denom, best_arate, asigned, swap_endian)) {
1994  mainw->fx1_bool = ofx1_bool;
1995  return FALSE;
1996  }
1997  } else {
1998  mainw->fx1_bool = ofx1_bool;
1999  return FALSE;
2000  }
2001  }
2002  return TRUE;
2003 }
2004 
2005 
2006 LiVESList *filter_encoders_by_img_ext(LiVESList * encoders, const char *img_ext) {
2007  LiVESList *encoder_capabilities = NULL;
2008  LiVESList *list = encoders, *listnext;
2009  int caps;
2010 
2011  register int i;
2012 
2013  char *blacklist[] = {
2014  NULL,
2015  NULL
2016  };
2017 
2018  // something broke as of python 2.7.2, and python 3 files now just hang
2019  if (capable->python_version < 3000000) blacklist[0] = lives_strdup("multi_encoder3");
2020 
2021  while (list) {
2022  boolean skip = FALSE;
2023  i = 0;
2024 
2025  listnext = list->next;
2026 
2027  while (blacklist[i]) {
2028  if (!strcmp((const char *)list->data, blacklist[i])) {
2029  // skip blacklisted encoders
2030  lives_free((livespointer)list->data);
2031  encoders = lives_list_delete_link(encoders, list);
2032  skip = TRUE;
2033  break;
2034  }
2035  i++;
2036  }
2037  if (skip) {
2038  list = listnext;
2039  continue;
2040  }
2041 
2042  if (!strcmp(img_ext, LIVES_FILE_EXT_JPG)) {
2043  list = listnext;
2044  continue;
2045  }
2046 
2047  if ((encoder_capabilities = plugin_request(PLUGIN_ENCODERS, (char *)list->data, "get_capabilities")) == NULL) {
2048  lives_free((livespointer)list->data);
2049  encoders = lives_list_delete_link(encoders, list);
2050  } else {
2051  caps = atoi((char *)lives_list_nth_data(encoder_capabilities, 0));
2052  if (!(caps & CAN_ENCODE_PNG) && !strcmp(img_ext, LIVES_FILE_EXT_PNG)) {
2053  lives_free((livespointer)list->data);
2054  encoders = lives_list_delete_link(encoders, list);
2055  }
2056 
2057  lives_list_free_all(&encoder_capabilities);
2058  }
2059 
2060  list = listnext;
2061  }
2062 
2063  for (i = 0; blacklist[i]; i++) lives_free(blacklist[i]);
2064 
2065  return encoders;
2066 }
2067 
2068 
2070 // decoder plugins
2071 
2072 boolean decoder_plugin_move_to_first(const char *name) {
2073  LiVESList *decoder_plugin, *last_decoder_plugin = NULL;
2074  decoder_plugin = mainw->decoder_list;
2075  while (decoder_plugin) {
2076  if (!strcmp((const char *)(decoder_plugin->data), name)) {
2077  if (last_decoder_plugin) {
2078  last_decoder_plugin->next = decoder_plugin->next;
2079  decoder_plugin->next = mainw->decoder_list;
2080  mainw->decoder_list = decoder_plugin;
2081  }
2082  return TRUE;
2083  }
2084  last_decoder_plugin = decoder_plugin;
2085  decoder_plugin = decoder_plugin->next;
2086  }
2087  return FALSE;
2088 }
2089 
2090 
2091 
2092 LiVESList *load_decoders(void) {
2093  lives_decoder_sys_t *dplug;
2094  char *decplugdir = lives_strdup_printf("%s%s%s", prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_DECODERS);
2095  LiVESList *dlist = NULL;
2096  LiVESList *decoder_plugins_o = get_plugin_list(PLUGIN_DECODERS, TRUE, decplugdir, "-" DLL_NAME);
2097  LiVESList *decoder_plugins = decoder_plugins_o;
2098 
2099  char *blacklist[3] = {
2100  "zyavformat_decoder",
2101  "ogg_theora_decoder",
2102  NULL
2103  };
2104 
2105  const char *dplugname;
2106  boolean skip;
2107 
2108  register int i;
2109 
2110  while (decoder_plugins) {
2111  skip = FALSE;
2112  dplugname = (const char *)(decoder_plugins->data);
2113  for (i = 0; blacklist[i]; i++) {
2114  if (!strcmp(dplugname, blacklist[i])) {
2115  // skip blacklisted decoders
2116  skip = TRUE;
2117  break;
2118  }
2119  }
2120  if (!skip) {
2121  dplug = open_decoder_plugin((char *)decoder_plugins->data);
2122  if (dplug) dlist = lives_list_append(dlist, (livespointer)dplug);
2123  }
2124  lives_free((livespointer)decoder_plugins->data);
2125  decoder_plugins = decoder_plugins->next;
2126  }
2127 
2128  lives_list_free(decoder_plugins_o);
2129 
2130  if (!dlist) {
2131  char *msg = lives_strdup_printf(_("\n\nNo decoders found in %s !\n"), decplugdir);
2132  LIVES_WARN(msg);
2133  d_print(msg);
2134  lives_free(msg);
2135  }
2136 
2137  lives_free(decplugdir);
2138  return dlist;
2139 }
2140 
2141 
2142 static void set_cdata_memfuncs(lives_clip_data_t *cdata) {
2143  // set specific memory functions for decoder plugins to use
2144  static malloc_f ext_malloc = (malloc_f) _ext_malloc;
2145  static free_f ext_free = (free_f) _ext_free;
2146  static memcpy_f ext_memcpy = (memcpy_f) _ext_memcpy;
2147  static memset_f ext_memset = (memset_f) _ext_memset;
2148  static memmove_f ext_memmove = (memmove_f) _ext_memmove;
2149  static realloc_f ext_realloc = (realloc_f) _ext_realloc;
2150  static calloc_f ext_calloc = (calloc_f) _ext_calloc;
2151  if (!cdata) return;
2152  cdata->ext_malloc = &ext_malloc;
2153  cdata->ext_free = &ext_free;
2154  cdata->ext_memcpy = &ext_memcpy;
2155  cdata->ext_memset = &ext_memset;
2156  cdata->ext_memmove = &ext_memmove;
2157  cdata->ext_realloc = &ext_realloc;
2158  cdata->ext_calloc = &ext_calloc;
2159 }
2160 
2161 
2162 static boolean sanity_check_cdata(lives_clip_data_t *cdata) {
2163  if (cdata->nframes <= 0 || cdata->nframes >= INT_MAX) {
2164  return FALSE;
2165  }
2166 
2167  // no usable palettes found
2168  if (cdata->palettes[0] == WEED_PALETTE_END) return FALSE;
2169 
2170  // all checks passed - OK
2171  return TRUE;
2172 }
2173 
2174 
2175 typedef struct {
2176  LiVESList *disabled;
2177  lives_decoder_t *dplug;
2178  lives_clip_t *sfile;
2179 } tdp_data;
2180 
2182  lives_decoder_t *dplug;
2183  const lives_decoder_sys_t *dpsys;
2184  lives_clip_data_t *cdata;
2185 
2186  if (!mainw->files[fileno] || !mainw->files[fileno]->ext_src) return NULL;
2187 
2188  cdata = ((lives_decoder_sys_t *)((lives_decoder_t *)mainw->files[fileno]->ext_src)->decoder)->get_clip_data
2189  (NULL, ((lives_decoder_t *)mainw->files[fileno]->ext_src)->cdata);
2190 
2191  if (!cdata) return NULL;
2192 
2193  dplug = (lives_decoder_t *)lives_calloc(1, sizeof(lives_decoder_t));
2194  dpsys = ((lives_decoder_t *)mainw->files[fileno]->ext_src)->decoder;
2195 
2196  dplug->decoder = dpsys;
2197  dplug->cdata = cdata;
2198  dplug->refs = 1;
2199  set_cdata_memfuncs((lives_clip_data_t *)cdata);
2200  cdata->rec_rowstrides = NULL;
2201  return dplug;
2202 }
2203 
2204 
2205 static lives_decoder_t *try_decoder_plugins(char *file_name, LiVESList * disabled, const lives_clip_data_t *fake_cdata) {
2206  // here we test each decoder in turn to see if it can open "file_name"
2207 
2208  // if we are reopening a clip, then fake cdata is a partially initialised cdata, but with only the frame count and fps set
2209  // this allows the decoder plugins to startup quicker as they don't have to seek to the last frame or calculate the fps.
2210 
2211  // we pass this to each decoder in turn and check what it returns. If the values look sane then we use that decoder,
2212  // otherwise we try the next one.
2213 
2214  // when reloading clips we try the decoder which last opened them first, othwerwise they could get picked up by another
2215  // decoder and the frames could come out different
2216 
2218  LiVESList *decoder_plugin = mainw->decoder_list;
2219  //LiVESList *last_decoder_plugin = NULL;
2220 
2221  dplug->refs = 1;
2222 
2223  if (fake_cdata) {
2224  set_cdata_memfuncs((lives_clip_data_t *)fake_cdata);
2225  //if (prefs->vj_mode) {
2226  ((lives_clip_data_t *)fake_cdata)->seek_flag = LIVES_SEEK_FAST;
2227  //}
2228  }
2229 
2230  while (decoder_plugin) {
2231  lives_decoder_sys_t *dpsys = (lives_decoder_sys_t *)decoder_plugin->data;
2232  if (lives_list_strcmp_index(disabled, dpsys->name, FALSE) != -1) {
2233  // check if (user) disabled this decoder
2234  decoder_plugin = decoder_plugin->next;
2235  continue;
2236  }
2237 
2238  //#define DEBUG_DECPLUG
2239 #ifdef DEBUG_DECPLUG
2240  g_print("trying decoder %s\n", dpsys->name);
2241 #endif
2242 
2243  dplug->cdata = (dpsys->get_clip_data)(file_name, fake_cdata);
2244 
2245  if (dplug->cdata) {
2246  // check for sanity
2247  //g_print("Checking return data from %s\n", dpsys->name);
2249  &dplug->cdata->lsd)) {
2250  g_printerr("Error in cdata received from decoder plugin:\n%s\nAborting.", dpsys->name);
2251  abort();
2252  }
2253  if (!sanity_check_cdata(dplug->cdata)) {
2254  //last_decoder_plugin = decoder_plugin;
2255  decoder_plugin = decoder_plugin->next;
2256  continue;
2257  }
2258  set_cdata_memfuncs(dplug->cdata);
2260 
2261  dplug->decoder = dpsys;
2262 
2263  /* if (strncmp(dpsys->name, "zz", 2)) { */
2264  /* // if libav decoder opened us, move it to the first, since it can save time */
2265  /* if (last_decoder_plugin) { */
2266  /* last_decoder_plugin->next = decoder_plugin->next; */
2267  /* decoder_plugin->next = mainw->decoder_list; */
2268  /* mainw->decoder_list = decoder_plugin; */
2269  /* } */
2270  break;
2271  }
2272  //last_decoder_plugin = decoder_plugin;
2273  decoder_plugin = decoder_plugin->next;
2274  }
2275 
2276  if (!decoder_plugin) {
2277  lives_freep((void **)&dplug);
2278  } else {
2279  dplug->cdata->rec_rowstrides = NULL;
2280  }
2281 
2282  return dplug;
2283 }
2284 
2285 
2286 const lives_clip_data_t *get_decoder_cdata(int fileno, LiVESList * disabled, const lives_clip_data_t *fake_cdata) {
2287  // pass file to each decoder (demuxer) plugin in turn, until we find one that can parse
2288  // the file
2289  // NULL is returned if no decoder plugin recognises the file - then we
2290  // fall back to other methods
2291 
2292  // otherwise we return data for the clip as supplied by the decoder plugin
2293 
2294  // If the file does not exist, we set mainw->error=TRUE and return NULL
2295 
2296  // If we find a plugin we also set sfile->ext_src to point to a newly created decoder_plugin_t
2297 
2298  lives_decoder_t *dplug;
2299 
2300  LiVESList *xdisabled;
2301 
2302  lives_clip_t *sfile = mainw->files[fileno];
2303 
2304  char decplugname[PATH_MAX];
2305 
2306  mainw->error = FALSE;
2307 
2308  if (!lives_file_test(sfile->file_name, LIVES_FILE_TEST_EXISTS)) {
2309  mainw->error = TRUE;
2310  return NULL;
2311  }
2312 
2313  lives_memset(decplugname, 0, 1);
2314 
2315  // check sfile->file_name against each decoder plugin,
2316  // until we get non-NULL cdata
2317 
2318  sfile->ext_src = NULL;
2320 
2322 
2323  xdisabled = lives_list_copy(disabled);
2324 
2325  if (fake_cdata) {
2326  get_clip_value(fileno, CLIP_DETAILS_DECODER_NAME, decplugname, PATH_MAX);
2327  if (*decplugname) {
2328  LiVESList *decoder_plugin = mainw->decoder_list;
2329  xdisabled = lives_list_remove(xdisabled, decplugname);
2330  while (decoder_plugin) {
2331  lives_decoder_sys_t *dpsys = (lives_decoder_sys_t *)decoder_plugin->data;
2332  if (!strcmp(dpsys->name, decplugname)) {
2334  break;
2335  }
2336  decoder_plugin = decoder_plugin->next;
2337  }
2338  }
2339  }
2340 
2342  dplug = try_decoder_plugins(fake_cdata == NULL ? sfile->file_name : NULL, xdisabled, fake_cdata);
2343 
2344  if (xdisabled) lives_list_free(xdisabled);
2345 
2347 
2348  if (dplug) {
2349  d_print(_(" using %s"), dplug->decoder->version());
2350  sfile->ext_src = dplug;
2352  return dplug->cdata;
2353  }
2354 
2355  if (dplug) return dplug->cdata;
2356  return NULL;
2357 }
2358 
2359 
2360 // close one instance of dplug
2362  lives_clip_data_t *cdata;
2363 
2364  if (!dplug) return;
2365 
2366  dplug->refs--;
2367  if (dplug->refs) return;
2368 
2369  cdata = dplug->cdata;
2370 
2371  if (cdata) {
2372  if (cdata->rec_rowstrides) {
2373  lives_free(cdata->rec_rowstrides);
2374  cdata->rec_rowstrides = NULL;
2375  }
2376  (*dplug->decoder->clip_data_free)(cdata);
2377  }
2378  lives_free(dplug);
2379 }
2380 
2381 
2382 void close_clip_decoder(int clipno) {
2383  if (!IS_VALID_CLIP(clipno)) return;
2384  else {
2385  lives_clip_t *sfile = mainw->files[clipno];
2386  if (sfile->ext_src && sfile->ext_src_type == LIVES_EXT_SRC_DECODER) {
2387  char *cwd = lives_get_current_dir();
2388  char *ppath = lives_build_filename(prefs->workdir, sfile->handle, NULL);
2389  lives_chdir(ppath, FALSE);
2390  lives_free(ppath);
2392  sfile->ext_src = NULL;
2394  lives_chdir(cwd, FALSE);
2395  lives_free(cwd);
2396  }
2397  }
2398 }
2399 
2400 
2401 static void unload_decoder_plugin(lives_decoder_sys_t *dplug) {
2402  if (dplug->module_unload)(*dplug->module_unload)();
2403 
2404  lives_freep((void **)&dplug->name);
2405 
2406  dlclose(dplug->handle);
2407  lives_free(dplug);
2408 }
2409 
2410 
2412  LiVESList *dplugs = mainw->decoder_list;
2413 
2414  while (dplugs) {
2415  unload_decoder_plugin((lives_decoder_sys_t *)dplugs->data);
2416  dplugs = dplugs->next;
2417  }
2418 
2419  lives_list_free(mainw->decoder_list);
2420  mainw->decoder_list = NULL;
2422 }
2423 
2424 
2425 boolean chill_decoder_plugin(int fileno) {
2426  lives_clip_t *sfile = mainw->files[fileno];
2427  if (IS_NORMAL_CLIP(fileno) && sfile->clip_type == CLIP_TYPE_FILE && sfile->ext_src) {
2428  lives_decoder_t *dplug = (lives_decoder_t *)sfile->ext_src;
2429  lives_decoder_sys_t *dpsys = (lives_decoder_sys_t *)dplug->decoder;
2430  lives_clip_data_t *cdata = dplug->cdata;
2431  if (cdata)
2432  if (dpsys->chill_out) return (*dpsys->chill_out)(cdata);
2433  }
2434  return FALSE;
2435 }
2436 
2437 
2439  lives_decoder_sys_t *dplug;
2440  char *plugname, *tmp;
2441  boolean OK = TRUE;
2442  const char *err;
2443  int dlflags = RTLD_NOW | RTLD_LOCAL;
2444 
2445  dplug = (lives_decoder_sys_t *)lives_calloc(1, sizeof(lives_decoder_sys_t));
2446 
2447  dplug->name = NULL;
2448 
2449  tmp = lives_strdup_printf("%s.%s", plname, DLL_NAME);
2450  plugname = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_DECODERS, tmp, NULL);
2451  lives_free(tmp);
2452 
2453 #ifdef RTLD_DEEPBIND
2454  dlflags |= RTLD_DEEPBIND;
2455 #endif
2456 
2457  dplug->handle = dlopen(plugname, dlflags);
2458  lives_free(plugname);
2459 
2460  if (!dplug->handle) {
2461  d_print(_("\n\nFailed to open decoder plugin %s\nError was %s\n"), plname, dlerror());
2462  lives_free(dplug);
2463  return NULL;
2464  }
2465 
2466  if ((dplug->version = (const char *(*)())dlsym(dplug->handle, "version")) == NULL) {
2467  OK = FALSE;
2468  }
2469  if ((dplug->get_clip_data = (lives_clip_data_t *(*)(char *, const lives_clip_data_t *))
2470  dlsym(dplug->handle, "get_clip_data")) == NULL) {
2471  OK = FALSE;
2472  }
2473  if ((dplug->get_frame = (boolean(*)(const lives_clip_data_t *, int64_t, int *, int, void **))
2474  dlsym(dplug->handle, "get_frame")) == NULL) {
2475  OK = FALSE;
2476  }
2477  if ((dplug->clip_data_free = (void (*)(lives_clip_data_t *))dlsym(dplug->handle, "clip_data_free")) == NULL) {
2478  OK = FALSE;
2479  }
2480 
2481  if (!OK) {
2482  d_print(_("\n\nDecoder plugin %s\nis missing a mandatory function.\nUnable to use it.\n"), plname);
2483  unload_decoder_plugin(dplug);
2484  lives_free(dplug);
2485  return NULL;
2486  }
2487 
2488  // optional
2489  dplug->module_check_init = (const char *(*)())dlsym(dplug->handle, "module_check_init");
2490  dplug->chill_out = (boolean(*)(const lives_clip_data_t *))dlsym(dplug->handle, "chill_out");
2491  dplug->set_palette = (boolean(*)(lives_clip_data_t *))dlsym(dplug->handle, "set_palette");
2492  dplug->module_unload = (void (*)())dlsym(dplug->handle, "module_unload");
2493  dplug->rip_audio = (int64_t (*)(const lives_clip_data_t *, const char *, int64_t, int64_t, unsigned char **))
2494  dlsym(dplug->handle, "rip_audio");
2495  dplug->rip_audio_cleanup = (void (*)(const lives_clip_data_t *))dlsym(dplug->handle, "rip_audio_cleanup");
2496 
2497  if (dplug->module_check_init) {
2498  err = (*dplug->module_check_init)();
2499 
2500  if (err) {
2501  lives_snprintf(mainw->msg, MAINW_MSG_SIZE, "%s", err);
2502  unload_decoder_plugin(dplug);
2503  lives_free(dplug);
2504  return NULL;
2505  }
2506  }
2507 
2508  dplug->name = lives_strdup(plname);
2509  return dplug;
2510 }
2511 
2512 
2513 void get_mime_type(char *text, int maxlen, const lives_clip_data_t *cdata) {
2514  char *audname;
2515 
2516  if (!*cdata->container_name) lives_snprintf(text, maxlen, "%s", _("unknown"));
2517  else lives_snprintf(text, maxlen, "%s", cdata->container_name);
2518 
2519  if (!*cdata->video_name && !*cdata->audio_name) return;
2520 
2521  if (!*cdata->video_name) lives_strappend(text, maxlen, _("/unknown"));
2522  else {
2523  char *vidname = lives_strdup_printf("/%s", cdata->video_name);
2524  lives_strappend(text, maxlen, vidname);
2525  lives_free(vidname);
2526  }
2527 
2528  if (!*cdata->audio_name) {
2529  if (cfile->achans == 0) return;
2530  audname = lives_strdup_printf("/%s", _("unknown"));
2531  } else
2532  audname = lives_strdup_printf("/%s", cdata->audio_name);
2533  lives_strappend(text, maxlen, audname);
2534  lives_free(audname);
2535 }
2536 
2537 
2538 static void dpa_ok_clicked(LiVESButton * button, livespointer user_data) {
2539  lives_general_button_clicked(button, NULL);
2540 
2541  if (prefsw) {
2542  lives_window_present(LIVES_WINDOW(prefsw->prefs_dialog));
2545  apply_button_set_enabled(NULL, NULL);
2546  }
2547 
2549 
2551 }
2552 
2553 
2554 static void dpa_cancel_clicked(LiVESButton * button, livespointer user_data) {
2555  lives_general_button_clicked(button, NULL);
2556 
2557  if (prefsw) {
2558  lives_window_present(LIVES_WINDOW(prefsw->prefs_dialog));
2560  }
2561 
2563 }
2564 
2565 
2566 static void on_dpa_cb_toggled(LiVESToggleButton * button, const char *decname) {
2567  if (!lives_toggle_button_get_active(button))
2568  // unchecked is disabled
2569  future_prefs->disabled_decoders_new = lives_list_append(future_prefs->disabled_decoders_new, lives_strdup(decname));
2570  else
2572 }
2573 
2574 
2575 void on_decplug_advanced_clicked(LiVESButton * button, livespointer user_data) {
2576  LiVESList *decoder_plugin;
2577 
2578  LiVESWidget *hbox;
2579  LiVESWidget *vbox;
2580  LiVESWidget *checkbutton;
2581  LiVESWidget *scrolledwindow;
2582  LiVESWidget *label;
2583  LiVESWidget *dialog;
2584  LiVESWidget *dialog_vbox;
2585  LiVESWidget *cancelbutton;
2586  LiVESWidget *okbutton;
2587 
2588  char *ltext;
2589  char *decplugdir = lives_strdup_printf("%s%s%s", prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_DECODERS);
2590 
2591  if (!mainw->decoders_loaded) {
2594  }
2595 
2596  decoder_plugin = mainw->decoder_list;
2597 
2598  dialog = lives_standard_dialog_new(_("Decoder Plugins"), FALSE, DEF_DIALOG_WIDTH, DEF_DIALOG_HEIGHT);
2599 
2600  dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
2601 
2602  vbox = lives_vbox_new(FALSE, 0);
2603 
2605 
2606  lives_container_add(LIVES_CONTAINER(dialog_vbox), scrolledwindow);
2607 
2608  label = lives_standard_label_new(_("Enabled Video Decoders (uncheck to disable)"));
2609  lives_box_pack_start(LIVES_BOX(vbox), label, FALSE, FALSE, widget_opts.packing_height);
2610 
2611  while (decoder_plugin) {
2612  lives_decoder_sys_t *dpsys = (lives_decoder_sys_t *)decoder_plugin->data;
2613  hbox = lives_hbox_new(FALSE, 0);
2614  lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
2615  ltext = lives_strdup_printf("%s (%s)", dpsys->name, (*dpsys->version)());
2616 
2619  FALSE) == -1,
2620  LIVES_BOX(hbox), NULL);
2622 
2623  lives_free(ltext);
2624 
2625  lives_signal_sync_connect_after(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
2626  LIVES_GUI_CALLBACK(on_dpa_cb_toggled),
2627  (livespointer)dpsys->name);
2628 
2629  decoder_plugin = decoder_plugin->next;
2630  }
2631 
2632  cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
2633  LIVES_RESPONSE_CANCEL);
2634 
2635  okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
2636  LIVES_RESPONSE_OK);
2637 
2639 
2640  lives_signal_connect(LIVES_GUI_OBJECT(cancelbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2641  LIVES_GUI_CALLBACK(dpa_cancel_clicked),
2642  NULL);
2643 
2644  lives_signal_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
2645  LIVES_GUI_CALLBACK(dpa_ok_clicked),
2646  NULL);
2647 
2648  lives_widget_show_all(dialog);
2649  lives_window_present(LIVES_WINDOW(dialog));
2651 
2653 
2654  lives_free(decplugdir);
2655 }
2656 
2658 // rfx plugin functions
2659 
2660 
2662  // check that an RFX is suitable for loading (cf. check_for_lives in effects-weed.c)
2663  if (rfx->num_in_channels == 2 && rfx->props & RFX_PROPS_MAY_RESIZE) {
2664  d_print(_("Failed to load %s, transitions may not resize.\n"), rfx->name);
2665  return FALSE;
2666  }
2667  return TRUE;
2668 }
2669 
2670 
2672  char *com;
2673  char *dir = NULL;
2674 
2676  if (rfx == &mainw->rendered_fx[0]) return;
2677 
2678  switch (rfx->status) {
2679  case RFX_STATUS_BUILTIN:
2680  dir = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, NULL);
2681  com = lives_strdup_printf("%s plugin_clear \"%s\" %d %d \"%s\" \"%s\" \"%s\"", prefs->backend_sync,
2682  cfile->handle, cfile->start, cfile->end, dir,
2684  break;
2685  case RFX_STATUS_CUSTOM:
2686  com = lives_strdup_printf("%s plugin_clear \"%s\" %d %d \"%s\" \"%s\" \"%s\"", prefs->backend_sync,
2687  cfile->handle, cfile->start, cfile->end, prefs->config_datadir,
2689  break;
2690  case RFX_STATUS_TEST:
2691  com = lives_strdup_printf("%s plugin_clear \"%s\" %d %d \"%s\" \"%s\" \"%s\"", prefs->backend_sync,
2692  cfile->handle, cfile->start, cfile->end, prefs->config_datadir,
2694  break;
2695  default:
2696  return;
2697  }
2698 
2699  lives_freep((void **)&dir);
2700 
2701  // if the command fails we just give a warning
2702  lives_system(com, FALSE);
2703  lives_free(com);
2704 }
2705 
2706 
2707 void render_fx_get_params(lives_rfx_t *rfx, const char *plugin_name, short status) {
2708  // create lives_param_t array from plugin supplied values
2709  LiVESList *parameter_list, *list;
2710  int param_idx, i;
2711  lives_param_t *cparam;
2712  char **param_array;
2713  char *line;
2714  int len;
2715 
2716  switch (status) {
2717  case RFX_STATUS_BUILTIN:
2718  parameter_list = plugin_request_by_line(PLUGIN_RENDERED_EFFECTS_BUILTIN, plugin_name, "get_parameters");
2719  break;
2720  case RFX_STATUS_CUSTOM:
2721  parameter_list = plugin_request_by_line(PLUGIN_RENDERED_EFFECTS_CUSTOM, plugin_name, "get_parameters");
2722  break;
2723  case RFX_STATUS_SCRAP:
2724  parameter_list = plugin_request_by_line(PLUGIN_RFX_SCRAP, plugin_name, "get_parameters");
2725  break;
2726  case RFX_STATUS_INTERNAL:
2727  parameter_list = plugin_request_by_line(PLUGIN_RFX_SCRAP, plugin_name, "get_parameters");
2728  break;
2729  default:
2730  parameter_list = plugin_request_by_line(PLUGIN_RENDERED_EFFECTS_TEST, plugin_name, "get_parameters");
2731  break;
2732  }
2733 
2734  if (!parameter_list) {
2735  rfx->num_params = 0;
2736  rfx->params = NULL;
2737  return;
2738  }
2739 
2740  //threaded_dialog_spin(0.);
2741  rfx->num_params = lives_list_length(parameter_list);
2742  rfx->params = (lives_param_t *)lives_calloc(rfx->num_params, sizeof(lives_param_t));
2743  list = parameter_list;
2744 
2745  for (param_idx = 0; param_idx < rfx->num_params; param_idx++) {
2746  line = (char *)list->data;
2747  list = list->next;
2748  len = get_token_count(line, (unsigned int)rfx->delim[0]);
2749 
2750  if (len < 3) continue;
2751 
2752  param_array = lives_strsplit(line, rfx->delim, -1);
2753 
2754  cparam = &rfx->params[param_idx];
2755  cparam->name = lives_strdup(param_array[0]);
2756  cparam->label = lives_strdup(param_array[1]);
2757  cparam->desc = NULL;
2758  cparam->use_mnemonic = TRUE;
2759  cparam->hidden = 0;
2760  cparam->wrap = FALSE;
2761  cparam->transition = FALSE;
2762  cparam->step_size = 1.;
2763  cparam->group = 0;
2764  cparam->max = 0.;
2765  cparam->reinit = FALSE;
2766  cparam->changed = FALSE;
2767  cparam->edited = FALSE;
2768  cparam->change_blocked = FALSE;
2769  cparam->source = NULL;
2772  cparam->special_type_index = 0;
2773  cparam->def = NULL;
2774  cparam->value = NULL;
2775 
2776 #ifdef DEBUG_RENDER_FX_P
2777  lives_printerr("Got parameter %s\n", cparam->name);
2778 #endif
2779  cparam->dp = 0;
2780  cparam->list = NULL;
2781 
2782  cparam->type = LIVES_PARAM_UNKNOWN;
2783 
2784  if (!strncmp(param_array[2], "num", 3)) {
2785  cparam->dp = atoi(param_array[2] + 3);
2786  cparam->type = LIVES_PARAM_NUM;
2787  } else if (!strncmp(param_array[2], "bool", 4)) {
2788  cparam->type = LIVES_PARAM_BOOL;
2789  } else if (!strncmp(param_array[2], "colRGB24", 8)) {
2790  cparam->type = LIVES_PARAM_COLRGB24;
2791  } else if (!strncmp(param_array[2], "string", 8)) {
2792  cparam->type = LIVES_PARAM_STRING;
2793  } else if (!strncmp(param_array[2], "string_list", 8)) {
2794  cparam->type = LIVES_PARAM_STRING_LIST;
2795  } else continue;
2796 
2797  if (cparam->dp) {
2798  double val;
2799  if (len < 6) continue;
2800  val = lives_strtod(param_array[3], NULL);
2801  cparam->value = lives_malloc(sizdbl);
2802  cparam->def = lives_malloc(sizdbl);
2803  set_double_param(cparam->def, val);
2804  set_double_param(cparam->value, val);
2805  cparam->min = lives_strtod(param_array[4], NULL);
2806  cparam->max = lives_strtod(param_array[5], NULL);
2807  if (len > 6) {
2808  cparam->step_size = lives_strtod(param_array[6], NULL);
2809  if (cparam->step_size == 0.) cparam->step_size = 1. / (double)lives_10pow(cparam->dp);
2810  else if (cparam->step_size < 0.) {
2811  cparam->step_size = -cparam->step_size;
2812  cparam->wrap = TRUE;
2813  }
2814  }
2815  } else if (cparam->type == LIVES_PARAM_COLRGB24) {
2816  short red;
2817  short green;
2818  short blue;
2819  if (len < 6) continue;
2820  red = (short)atoi(param_array[3]);
2821  green = (short)atoi(param_array[4]);
2822  blue = (short)atoi(param_array[5]);
2823  cparam->value = lives_malloc(sizeof(lives_colRGB48_t));
2824  cparam->def = lives_malloc(sizeof(lives_colRGB48_t));
2825  set_colRGB24_param(cparam->def, red, green, blue);
2826  set_colRGB24_param(cparam->value, red, green, blue);
2827  } else if (cparam->type == LIVES_PARAM_STRING) {
2828  if (len < 4) continue;
2829  cparam->value = (_(param_array[3]));
2830  cparam->def = (_(param_array[3]));
2831  if (len > 4) cparam->max = (double)atoi(param_array[4]);
2832  if (cparam->max == 0. || cparam->max > RFX_MAXSTRINGLEN) cparam->max = RFX_MAXSTRINGLEN;
2833  } else if (cparam->type == LIVES_PARAM_STRING_LIST) {
2834  if (len < 4) continue;
2835  cparam->value = lives_malloc(sizint);
2836  cparam->def = lives_malloc(sizint);
2837  *(int *)cparam->def = atoi(param_array[3]);
2838  if (len > 4) {
2839  cparam->list = array_to_string_list(param_array, 3, len);
2840  } else {
2841  set_int_param(cparam->def, 0);
2842  }
2843  set_int_param(cparam->value, get_int_param(cparam->def));
2844  } else {
2845  // int or bool
2846  int val;
2847  if (len < 4) continue;
2848  val = atoi(param_array[3]);
2849  cparam->value = lives_malloc(sizint);
2850  cparam->def = lives_malloc(sizint);
2851  set_int_param(cparam->def, val);
2852  set_int_param(cparam->value, val);
2853  if (cparam->type == LIVES_PARAM_BOOL) {
2854  cparam->min = 0;
2855  cparam->max = 1;
2856  if (len > 4) cparam->group = atoi(param_array[4]);
2857  } else {
2858  if (len < 6) continue;
2859  cparam->min = (double)atoi(param_array[4]);
2860  cparam->max = (double)atoi(param_array[5]);
2861  if (len > 6) {
2862  cparam->step_size = (double)atoi(param_array[6]);
2863  if (cparam->step_size == 0.) cparam->step_size = 1.;
2864  else if (cparam->step_size < 0.) {
2865  cparam->step_size = -cparam->step_size;
2866  cparam->wrap = TRUE;
2867  }
2868  }
2869  }
2870  }
2871 
2872  for (i = 0; i < MAX_PARAM_WIDGETS; i++) {
2873  cparam->widgets[i] = NULL;
2874  }
2875  cparam->onchange = FALSE;
2876  lives_strfreev(param_array);
2877  }
2878  lives_list_free_all(&parameter_list);
2879  //threaded_dialog_spin(0.);
2880 }
2881 
2882 
2883 LiVESList *array_to_string_list(char **array, int offset, int len) {
2884  // build a LiVESList from an array.
2885  int i;
2886 
2887  char *string, *tmp;
2888  LiVESList *slist = NULL;
2889 
2890  for (i = offset + 1; i < len; i++) {
2891  string = subst((tmp = L2U8(array[i])), "\\n", "\n");
2892  lives_free(tmp);
2893 
2894  // omit a last empty string
2895  if (i < len - 1 || *string) {
2896  slist = lives_list_append(slist, string);
2897  } else lives_free(string);
2898  }
2899 
2900  return slist;
2901 }
2902 
2903 
2904 static int cmp_menu_entries(livesconstpointer a, livesconstpointer b) {
2905  return lives_utf8_strcmpfunc(((lives_rfx_t *)a)->menu_text, ((lives_rfx_t *)b)->menu_text, LIVES_INT_TO_POINTER(TRUE));
2906 }
2907 
2908 
2909 void sort_rfx_array(lives_rfx_t *in, int num) {
2910  // sort rfx array into UTF-8 order by menu entry
2911  lives_rfx_t *rfx;
2912  int sorted = 1;
2913  register int i;
2914 
2915  LiVESList *rfx_list = NULL, *xrfx_list;
2916  for (i = num; i > 0; i--) {
2917  rfx_list = lives_list_prepend(rfx_list, (livespointer)&in[i]);
2918  }
2919  rfx_list = lives_list_sort(rfx_list, cmp_menu_entries);
2920  rfx = mainw->rendered_fx = (lives_rfx_t *)lives_calloc((num + 1), sizeof(lives_rfx_t));
2921  rfx_copy(rfx, in, FALSE);
2922  xrfx_list = rfx_list;
2923  while (xrfx_list) {
2924  rfx_copy(&mainw->rendered_fx[sorted++], (lives_rfx_t *)(xrfx_list->data), FALSE);
2925  xrfx_list = xrfx_list->next;
2926  }
2927  lives_list_free(rfx_list);
2928 }
2929 
2930 
2931 void rfx_copy(lives_rfx_t *dest, lives_rfx_t *src, boolean full) {
2932  // Warning, does not copy all fields (full will do that)
2933  lives_memcpy(dest->delim, src->delim, 2);
2934  dest->source = src->source;
2935  if (!full) {
2936  // ref. assigned memory
2937  src->source = NULL;
2938  dest->name = src->name;
2939  src->name = NULL;
2940  dest->menu_text = src->menu_text;
2941  src->menu_text = NULL;
2942  dest->action_desc = src->action_desc;
2943  src->action_desc = NULL;
2944  dest->params = src->params;
2945  src->params = NULL;
2946  } else {
2947  // deep copy
2948  if (dest->source_type == LIVES_RFX_SOURCE_WEED && dest->source) weed_instance_ref(dest->source);
2949  dest->name = lives_strdup(src->name);
2950  dest->menu_text = lives_strdup(src->menu_text);
2951  dest->action_desc = lives_strdup(src->action_desc);
2952  // TODO - copy params
2953  }
2954 
2955  lives_snprintf(dest->rfx_version, 64, "%s", src->rfx_version);
2956  dest->min_frames = src->min_frames;
2957  dest->num_in_channels = src->num_in_channels;
2958  dest->status = src->status;
2959  dest->props = src->props;
2960  dest->source_type = src->source_type;
2961  dest->num_params = src->num_params;
2962  dest->is_template = src->is_template;
2963  dest->menuitem = src->menuitem;
2964  dest->gui_strings = lives_list_copy(src->gui_strings);
2965  dest->onchange_strings = lives_list_copy(src->onchange_strings);
2966  if (!full) return;
2967 
2968  // TODO
2969 
2970 }
2971 
2972 
2974  register int i;
2975  for (i = 0; i < rfx->num_params; i++) {
2976  if (rfx->params[i].type == LIVES_PARAM_UNDISPLAYABLE || rfx->params[i].type == LIVES_PARAM_UNKNOWN) continue;
2977  lives_free(rfx->params[i].name);
2978  lives_freep((void **)&rfx->params[i].def);
2979  lives_freep((void **)&rfx->params[i].value);
2980  lives_freep((void **)&rfx->params[i].label);
2981  lives_freep((void **)&rfx->params[i].desc);
2982  lives_list_free_all(&rfx->params[i].list);
2983  }
2984 }
2985 
2986 
2987 void rfx_free(lives_rfx_t *rfx) {
2988  if (!rfx) return;
2989 
2990  if (mainw->vrfx_update == rfx) mainw->vrfx_update = NULL;
2991 
2992  lives_freep((void **)&rfx->name);
2993  lives_freep((void **)&rfx->menu_text);
2994  lives_freep((void **)&rfx->action_desc);
2995 
2996  if (rfx->params) {
2997  rfx_params_free(rfx);
2998  lives_free(rfx->params);
2999  }
3000 
3001  if (rfx->gui_strings) lives_list_free_all(&rfx->gui_strings);
3003 
3004  if (rfx->source_type == LIVES_RFX_SOURCE_WEED && rfx->source) {
3005  weed_instance_unref((weed_plant_t *)rfx->source); // remove the ref we held
3006  }
3007 }
3008 
3009 
3010 void rfx_free_all(void) {
3011  register int i;
3013  + mainw->num_rendered_effects_test; i++) {
3014  rfx_free(&mainw->rendered_fx[i]);
3015  }
3016  lives_freep((void **)&mainw->rendered_fx);
3017 }
3018 
3019 
3020 void param_copy(lives_param_t *dest, lives_param_t *src, boolean full) {
3021  // rfxbuilder.c uses this to copy params to a temporary copy and back again
3022 
3023  dest->name = lives_strdup(src->name);
3024  dest->label = lives_strdup(src->label);
3025  dest->group = src->group;
3026  dest->onchange = src->onchange;
3027  dest->type = src->type;
3028  dest->dp = src->dp;
3029  dest->min = src->min;
3030  dest->max = src->max;
3031  dest->step_size = src->step_size;
3032  dest->wrap = src->wrap;
3033  dest->source = src->source;
3034  dest->reinit = src->reinit;
3035  dest->source_type = src->source_type;
3036  dest->value = dest->def = NULL;
3037  dest->list = NULL;
3038 
3039  switch (dest->type) {
3040  case LIVES_PARAM_BOOL:
3041  dest->dp = 0;
3042  case LIVES_PARAM_NUM:
3043  if (!dest->dp) {
3044  dest->def = lives_malloc(sizint);
3045  lives_memcpy(dest->def, src->def, sizint);
3046  } else {
3047  dest->def = lives_malloc(sizdbl);
3048  lives_memcpy(dest->def, src->def, sizdbl);
3049  }
3050  break;
3051  case LIVES_PARAM_COLRGB24:
3052  dest->def = lives_malloc(sizeof(lives_colRGB48_t));
3053  lives_memcpy(dest->def, src->def, sizeof(lives_colRGB48_t));
3054  break;
3055  case LIVES_PARAM_STRING:
3056  dest->def = lives_strdup((char *)src->def);
3057  break;
3059  dest->def = lives_malloc(sizint);
3060  set_int_param(dest->def, get_int_param(src->def));
3061  if (src->list) dest->list = lives_list_copy(src->list);
3062  break;
3063  default:
3064  break;
3065  }
3066  if (!full) return;
3067  // TODO - copy value, copy widgets
3068 
3069 }
3070 
3071 
3072 boolean get_bool_param(void *value) {
3073  boolean ret;
3074  lives_memcpy(&ret, value, 4);
3075  return ret;
3076 }
3077 
3078 
3079 int get_int_param(void *value) {
3080  int ret;
3081  lives_memcpy(&ret, value, sizint);
3082  return ret;
3083 }
3084 
3085 
3086 double get_double_param(void *value) {
3087  double ret;
3088  lives_memcpy(&ret, value, sizdbl);
3089  return ret;
3090 }
3091 
3092 
3093 void get_colRGB24_param(void *value, lives_colRGB48_t *rgb) {
3094  lives_memcpy(rgb, value, sizeof(lives_colRGB48_t));
3095 }
3096 
3097 
3098 void get_colRGBA32_param(void *value, lives_colRGBA64_t *rgba) {
3099  lives_memcpy(rgba, value, sizeof(lives_colRGBA64_t));
3100 }
3101 
3102 
3103 void set_bool_param(void *value, boolean _const) {
3104  set_int_param(value, !!_const);
3105 }
3106 
3107 
3108 void set_string_param(void **value_ptr, const char *_const, size_t maxlen) {
3109  lives_freep(value_ptr);
3110  *value_ptr = lives_strndup(_const, maxlen);
3111 }
3112 
3113 
3114 void set_int_param(void *value, int _const) {
3115  lives_memcpy(value, &_const, sizint);
3116 }
3117 
3118 
3119 void set_double_param(void *value, double _const) {
3120  lives_memcpy(value, &_const, sizdbl);
3121 }
3122 
3123 
3124 boolean set_rfx_param_by_name_string(lives_rfx_t *rfx, const char *name, const char *value, boolean update_visual) {
3125  size_t len = strlen(value);
3126  lives_param_t *param = find_rfx_param_by_name(rfx, name);
3127  if (!param) return FALSE;
3128  set_string_param((void **)&param->value, value, len > RFX_MAXSTRINGLEN ? RFX_MAXSTRINGLEN : len);
3129  if (update_visual) {
3130  LiVESList *list = NULL;
3131  char *tmp, *tmp2;
3132  list = lives_list_append(list, lives_strdup_printf("\"%s\"", (tmp = U82L(tmp2 = subst(value, "\"", "\\\"")))));
3133  lives_free(tmp); lives_free(tmp2);
3134  set_param_from_list(list, param, 0, FALSE, TRUE);
3135  lives_list_free_all(&list);
3136  }
3137  return TRUE;
3138 }
3139 
3140 
3141 boolean get_rfx_param_by_name_string(lives_rfx_t *rfx, const char *name, char **return_value) {
3142  lives_param_t *param = find_rfx_param_by_name(rfx, name);
3143  if (!param) return FALSE;
3144  *return_value = lives_strndup(param->value, RFX_MAXSTRINGLEN);
3145  return TRUE;
3146 }
3147 
3148 
3149 void set_colRGB24_param(void *value, short red, short green, short blue) {
3150  lives_colRGB48_t *rgbp = (lives_colRGB48_t *)value;
3151 
3152  if (red < 0) red = 0;
3153  if (red > 255) red = 255;
3154  if (green < 0) green = 0;
3155  if (green > 255) green = 255;
3156  if (blue < 0) blue = 0;
3157  if (blue > 255) blue = 255;
3158 
3159  rgbp->red = red;
3160  rgbp->green = green;
3161  rgbp->blue = blue;
3162 
3163 }
3164 
3165 
3166 void set_colRGBA32_param(void *value, short red, short green, short blue, short alpha) {
3167  lives_colRGBA64_t *rgbap = (lives_colRGBA64_t *)value;
3168  rgbap->red = red;
3169  rgbap->green = green;
3170  rgbap->blue = blue;
3171  rgbap->alpha = alpha;
3172 }
3173 
3174 
3176 
3177 int find_rfx_plugin_by_name(const char *name, short status) {
3178  int i;
3181  if (mainw->rendered_fx[i].name && !strcmp(mainw->rendered_fx[i].name, name)
3182  && mainw->rendered_fx[i].status == status)
3183  return (int)i;
3184  }
3185  return -1;
3186 }
3187 
3188 
3190  int i;
3191  if (!rfx) return NULL;
3192  for (i = 0; i < rfx->num_params; i++) {
3193  if (!strcmp(name, rfx->params[i].name)) {
3194  return &rfx->params[i];
3195  }
3196  }
3197  return NULL;
3198 }
3199 
3200 
3201 lives_param_t *weed_params_to_rfx(int npar, weed_plant_t *inst, boolean show_reinits) {
3202  int i, j;
3203  lives_param_t *rpar = (lives_param_t *)lives_calloc(npar, sizeof(lives_param_t));
3204  int param_type;
3205  char **list;
3206  LiVESList *gtk_list = NULL;
3207  char *string;
3208  int vali;
3209  double vald;
3210  weed_plant_t *gui = NULL;
3211  int listlen;
3212  int cspace, *cols = NULL, red_min = 0, red_max = 255, green_min = 0, green_max = 255, blue_min = 0, blue_max = 255,
3213  *maxi = NULL, *mini = NULL;
3214  double *colsd;
3215  double red_mind = 0., red_maxd = 1., green_mind = 0., green_maxd = 1., blue_mind = 0., blue_maxd = 1.,
3216  *maxd = NULL, *mind = NULL;
3217  int flags = 0;
3218  int nwpars = 0, poffset = 0;
3219  boolean col_int;
3220 
3221  weed_plant_t *wtmpl;
3222  weed_plant_t **wpars = NULL, *wpar = NULL;
3223 
3224  weed_plant_t *chann, *ctmpl;
3225  weed_plant_t *filter = weed_instance_get_filter(inst, TRUE);
3226 
3227  wpars = weed_instance_get_in_params(inst, &nwpars);
3228 
3229  for (i = 0; i < npar; i++) {
3230  if (i - poffset >= nwpars) {
3231  // handling for compound fx
3232  poffset += nwpars;
3233  if (wpars) lives_free(wpars);
3234  inst = weed_get_plantptr_value(inst, WEED_LEAF_HOST_NEXT_INSTANCE, NULL);
3235  wpars = weed_instance_get_in_params(inst, &nwpars);
3236  i--;
3237  continue;
3238  }
3239 
3240  if (!wpars) {
3241  lives_free(rpar);
3242  return NULL;
3243  }
3244 
3245  wpar = wpars[i - poffset];
3246  wtmpl = weed_param_get_template(wpar);
3247 
3248  flags = weed_paramtmpl_get_flags(wtmpl);
3249 
3250  rpar[i].flags = flags;
3251 
3252  gui = weed_paramtmpl_get_gui(wtmpl, FALSE);
3253 
3254  rpar[i].group = 0;
3255 
3256  rpar[i].use_mnemonic = FALSE;
3257  rpar[i].hidden = 0;
3258  rpar[i].step_size = 1.;
3259  if (enabled_in_channels(filter, FALSE) == 2 && get_transition_param(filter, FALSE) == i) rpar[i].transition = TRUE;
3260  else rpar[i].transition = FALSE;
3261  rpar[i].wrap = FALSE;
3262  rpar[i].reinit = FALSE;
3263  rpar[i].change_blocked = FALSE;
3264  rpar[i].source = wtmpl;
3267  rpar[i].special_type_index = 0;
3268  rpar[i].value = NULL;
3269  rpar[i].def = NULL;
3270 
3271  if (flags & WEED_PARAMETER_VARIABLE_SIZE && !(flags & WEED_PARAMETER_VALUE_PER_CHANNEL)) {
3272  rpar[i].hidden |= HIDDEN_MULTI;
3273  rpar[i].multi = PVAL_MULTI_ANY;
3274  } else if (flags & WEED_PARAMETER_VALUE_PER_CHANNEL) {
3275  rpar[i].hidden |= HIDDEN_MULTI;
3276  rpar[i].multi = PVAL_MULTI_PER_CHANNEL;
3277  } else rpar[i].multi = PVAL_MULTI_NONE;
3278 
3279  chann = get_enabled_channel(inst, 0, TRUE);
3280  ctmpl = weed_get_plantptr_value(chann, WEED_LEAF_TEMPLATE, NULL);
3281 
3282  if (weed_get_boolean_value(ctmpl, WEED_LEAF_IS_AUDIO, NULL) == WEED_TRUE) {
3283  // dont hide multivalued params for audio effects
3284  rpar[i].hidden = 0;
3285  }
3286 
3287  rpar[i].dp = 0;
3288  rpar[i].min = 0.;
3289  rpar[i].max = 0.;
3290  rpar[i].list = NULL;
3291 
3292  rpar[i].reinit = 0;
3293  if (flags & WEED_PARAMETER_REINIT_ON_VALUE_CHANGE)
3294  rpar[i].reinit = REINIT_FUNCTIONAL;
3295  if (gui && (weed_gui_get_flags(gui) & WEED_GUI_REINIT_ON_VALUE_CHANGE))
3296  rpar[i].reinit |= REINIT_VISUAL;
3297 
3298  if (!show_reinits && rpar[i].reinit != 0) rpar[i].hidden |= HIDDEN_NEEDS_REINIT;
3299 
3301  param_type = weed_paramtmpl_get_type(wtmpl);
3302 
3303  switch (param_type) {
3304  case WEED_PARAM_SWITCH:
3305  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 1) {
3306  rpar[i].hidden |= HIDDEN_MULTI;
3307  }
3308  rpar[i].type = LIVES_PARAM_BOOL;
3309  rpar[i].value = lives_malloc(sizint);
3310  rpar[i].def = lives_malloc(sizint);
3311  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT))
3312  vali = weed_get_boolean_value(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3313  else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3314  vali = weed_get_boolean_value(wtmpl, WEED_LEAF_DEFAULT, NULL);
3315  else vali = weed_get_boolean_value(wtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
3316  set_int_param(rpar[i].def, vali);
3317  vali = weed_get_boolean_value(wpar, WEED_LEAF_VALUE, NULL);
3318  set_int_param(rpar[i].value, vali);
3319  if (weed_plant_has_leaf(wtmpl, WEED_LEAF_GROUP)) rpar[i].group = weed_get_int_value(wtmpl, WEED_LEAF_GROUP, NULL);
3320  break;
3321  case WEED_PARAM_INTEGER:
3322  if (weed_plant_has_leaf(wtmpl, WEED_LEAF_DEFAULT) && weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 1) {
3323  rpar[i].hidden |= HIDDEN_MULTI;
3324  }
3325  rpar[i].type = LIVES_PARAM_NUM;
3326  rpar[i].value = lives_malloc(sizint);
3327  rpar[i].def = lives_malloc(sizint);
3328  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT)) {
3329  vali = weed_get_int_value(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3330  } else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3331  vali = weed_get_int_value(wtmpl, WEED_LEAF_DEFAULT, NULL);
3332  else vali = weed_get_int_value(wtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
3333  set_int_param(rpar[i].def, vali);
3334  vali = weed_get_int_value(wpar, WEED_LEAF_VALUE, NULL);
3335  set_int_param(rpar[i].value, vali);
3336  rpar[i].min = (double)weed_get_int_value(wtmpl, WEED_LEAF_MIN, NULL);
3337  rpar[i].max = (double)weed_get_int_value(wtmpl, WEED_LEAF_MAX, NULL);
3338  if (weed_paramtmpl_does_wrap(wtmpl)) rpar[i].wrap = TRUE;
3339  if (gui) {
3340  if (weed_plant_has_leaf(gui, WEED_LEAF_CHOICES)) {
3341  listlen = weed_leaf_num_elements(gui, WEED_LEAF_CHOICES);
3342  list = weed_get_string_array(gui, WEED_LEAF_CHOICES, NULL);
3343  for (j = 0; j < listlen; j++) {
3344  gtk_list = lives_list_append(gtk_list, list[j]);
3345  }
3346  lives_free(list);
3347  rpar[i].list = lives_list_copy(gtk_list);
3348  lives_list_free(gtk_list);
3349  gtk_list = NULL;
3350  rpar[i].type = LIVES_PARAM_STRING_LIST;
3351  rpar[i].max = listlen;
3352  } else if (weed_plant_has_leaf(gui, WEED_LEAF_STEP_SIZE))
3353  rpar[i].step_size = (double)weed_get_int_value(gui, WEED_LEAF_STEP_SIZE, NULL);
3354  if (rpar[i].step_size == 0.) rpar[i].step_size = 1.;
3355  }
3356  break;
3357  case WEED_PARAM_FLOAT:
3358  if (weed_plant_has_leaf(wtmpl, WEED_LEAF_DEFAULT) && weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 1) {
3359  rpar[i].hidden |= HIDDEN_MULTI;
3360  }
3361  rpar[i].type = LIVES_PARAM_NUM;
3362  rpar[i].value = lives_malloc(sizdbl);
3363  rpar[i].def = lives_malloc(sizdbl);
3364  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT))
3365  vald = weed_get_double_value(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3366  else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3367  vald = weed_get_double_value(wtmpl, WEED_LEAF_DEFAULT, NULL);
3368  else vald = weed_get_double_value(wtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
3369  set_double_param(rpar[i].def, vald);
3370  vald = weed_get_double_value(wpar, WEED_LEAF_VALUE, NULL);
3371  set_double_param(rpar[i].value, vald);
3372  rpar[i].min = weed_get_double_value(wtmpl, WEED_LEAF_MIN, NULL);
3373  rpar[i].max = weed_get_double_value(wtmpl, WEED_LEAF_MAX, NULL);
3374  if (weed_paramtmpl_does_wrap(wtmpl)) rpar[i].wrap = TRUE;
3375  rpar[i].step_size = 0.;
3376  rpar[i].dp = 2;
3377  if (gui) {
3378  if (weed_plant_has_leaf(gui, WEED_LEAF_STEP_SIZE))
3379  rpar[i].step_size = weed_get_double_value(gui, WEED_LEAF_STEP_SIZE, NULL);
3380  if (weed_plant_has_leaf(gui, WEED_LEAF_DECIMALS))
3381  rpar[i].dp = weed_get_int_value(gui, WEED_LEAF_DECIMALS, NULL);
3382  }
3383  if (rpar[i].step_size == 0.) {
3384  if (rpar[i].max - rpar[i].min > 10. && !(rpar[i].min >= -10. && rpar[i].max <= 10.))
3385  rpar[i].step_size = 1.;
3386  else if (rpar[i].max - rpar[i].min > 1. && !(rpar[i].min >= -1. && rpar[i].max <= 1.))
3387  rpar[i].step_size = .1;
3388  else rpar[i].step_size = 1. / (double)lives_10pow(rpar[i].dp);
3389  }
3390  break;
3391  case WEED_PARAM_TEXT:
3392  if (weed_plant_has_leaf(wtmpl, WEED_LEAF_DEFAULT) && weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 1) {
3393  rpar[i].hidden |= HIDDEN_MULTI;
3394  }
3395  rpar[i].type = LIVES_PARAM_STRING;
3396  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT))
3397  string = weed_get_string_value(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3398  else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3399  string = weed_get_string_value(wtmpl, WEED_LEAF_DEFAULT, NULL);
3400  else string = weed_get_string_value(wtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
3401  rpar[i].def = string;
3402  string = weed_get_string_value(wpar, WEED_LEAF_VALUE, NULL);
3403  rpar[i].value = string;
3404  rpar[i].max = 0.;
3405  if (gui && weed_plant_has_leaf(gui, WEED_LEAF_MAXCHARS)) {
3406  rpar[i].max = (double)weed_get_int_value(gui, WEED_LEAF_MAXCHARS, NULL);
3407  if (rpar[i].max < 0.) rpar[i].max = 0.;
3408  }
3409  break;
3410  case WEED_PARAM_COLOR:
3411  cspace = weed_get_int_value(wtmpl, WEED_LEAF_COLORSPACE, NULL);
3412  switch (cspace) {
3413  case WEED_COLORSPACE_RGB:
3414  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 3) {
3415  rpar[i].hidden |= HIDDEN_MULTI;
3416  }
3417  rpar[i].type = LIVES_PARAM_COLRGB24;
3418  rpar[i].value = lives_malloc(3 * sizint);
3419  rpar[i].def = lives_malloc(3 * sizint);
3420 
3421  if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
3422  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT)) {
3423  cols = weed_get_int_array(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3424  } else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3425  cols = weed_get_int_array(wtmpl, WEED_LEAF_DEFAULT, NULL);
3426  else cols = weed_get_int_array(wtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
3427  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_MAX) == 1) {
3428  red_max = green_max = blue_max = weed_get_int_value(wtmpl, WEED_LEAF_MAX, NULL);
3429  } else {
3430  maxi = weed_get_int_array(wtmpl, WEED_LEAF_MAX, NULL);
3431  red_max = maxi[0];
3432  green_max = maxi[1];
3433  blue_max = maxi[2];
3434  }
3435  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_MIN) == 1) {
3436  red_min = green_min = blue_min = weed_get_int_value(wtmpl, WEED_LEAF_MIN, NULL);
3437  } else {
3438  mini = weed_get_int_array(wtmpl, WEED_LEAF_MIN, NULL);
3439  red_min = mini[0];
3440  green_min = mini[1];
3441  blue_min = mini[2];
3442  }
3443  if (cols[0] < red_min) cols[0] = red_min;
3444  if (cols[1] < green_min) cols[1] = green_min;
3445  if (cols[2] < blue_min) cols[2] = blue_min;
3446  if (cols[0] > red_max) cols[0] = red_max;
3447  if (cols[1] > green_max) cols[1] = green_max;
3448  if (cols[2] > blue_max) cols[2] = blue_max;
3449  cols[0] = (double)(cols[0] - red_min) / (double)(red_max - red_min) * 255. + .49999;
3450  cols[1] = (double)(cols[1] - green_min) / (double)(green_max - green_min) * 255. + .49999;
3451  cols[2] = (double)(cols[2] - blue_min) / (double)(blue_max - blue_min) * 255. + .49999;
3452  col_int = TRUE;
3453  } else {
3454  if (!weed_paramtmpl_value_irrelevant(wtmpl) && weed_plant_has_leaf(wtmpl, WEED_LEAF_HOST_DEFAULT))
3455  colsd = weed_get_double_array(wtmpl, WEED_LEAF_HOST_DEFAULT, NULL);
3456  else if (weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT) > 0)
3457  colsd = weed_get_double_array(wtmpl, WEED_LEAF_DEFAULT, NULL);
3458  else colsd = weed_get_double_array(wtmpl, WEED_LEAF_DEFAULT, NULL);
3459  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_MAX) == 1) {
3460  red_maxd = green_maxd = blue_maxd = weed_get_double_value(wtmpl, WEED_LEAF_MAX, NULL);
3461  } else {
3462  maxd = weed_get_double_array(wtmpl, WEED_LEAF_MAX, NULL);
3463  red_maxd = maxd[0];
3464  green_maxd = maxd[1];
3465  blue_maxd = maxd[2];
3466  }
3467  if (weed_leaf_num_elements(wtmpl, WEED_LEAF_MIN) == 1) {
3468  red_mind = green_mind = blue_mind = weed_get_double_value(wtmpl, WEED_LEAF_MIN, NULL);
3469  } else {
3470  mind = weed_get_double_array(wtmpl, WEED_LEAF_MIN, NULL);
3471  red_mind = mind[0];
3472  green_mind = mind[1];
3473  blue_mind = mind[2];
3474  }
3475  if (colsd[0] < red_mind) colsd[0] = red_mind;
3476  if (colsd[1] < green_mind) colsd[1] = green_mind;
3477  if (colsd[2] < blue_mind) colsd[2] = blue_mind;
3478  if (colsd[0] > red_maxd) colsd[0] = red_maxd;
3479  if (colsd[1] > green_maxd) colsd[1] = green_maxd;
3480  if (colsd[2] > blue_maxd) colsd[2] = blue_maxd;
3481  cols = (int *)lives_malloc(3 * sizint);
3482  cols[0] = (colsd[0] - red_mind) / (red_maxd - red_mind) * 255. + .49999;
3483  cols[1] = (colsd[1] - green_mind) / (green_maxd - green_mind) * 255. + .49999;
3484  cols[2] = (colsd[2] - blue_mind) / (blue_maxd - blue_mind) * 255. + .49999;
3485  col_int = FALSE;
3486  }
3487  set_colRGB24_param(rpar[i].def, cols[0], cols[1], cols[2]);
3488 
3489  if (col_int) {
3490  lives_free(cols);
3491  cols = weed_get_int_array(wpar, WEED_LEAF_VALUE, NULL);
3492  if (cols[0] < red_min) cols[0] = red_min;
3493  if (cols[1] < green_min) cols[1] = green_min;
3494  if (cols[2] < blue_min) cols[2] = blue_min;
3495  if (cols[0] > red_max) cols[0] = red_max;
3496  if (cols[1] > green_max) cols[1] = green_max;
3497  if (cols[2] > blue_max) cols[2] = blue_max;
3498  cols[0] = (double)(cols[0] - red_min) / (double)(red_max - red_min) * 255. + .49999;
3499  cols[1] = (double)(cols[1] - green_min) / (double)(green_max - green_min) * 255. + .49999;
3500  cols[2] = (double)(cols[2] - blue_min) / (double)(blue_max - blue_min) * 255. + .49999;
3501  } else {
3502  colsd = weed_get_double_array(wpar, WEED_LEAF_VALUE, NULL);
3503  if (colsd[0] < red_mind) colsd[0] = red_mind;
3504  if (colsd[1] < green_mind) colsd[1] = green_mind;
3505  if (colsd[2] < blue_mind) colsd[2] = blue_mind;
3506  if (colsd[0] > red_maxd) colsd[0] = red_maxd;
3507  if (colsd[1] > green_maxd) colsd[1] = green_maxd;
3508  if (colsd[2] > blue_maxd) colsd[2] = blue_maxd;
3509  cols[0] = (colsd[0] - red_mind) / (red_maxd - red_mind) * 255. + .49999;
3510  cols[1] = (colsd[1] - green_mind) / (green_maxd - green_mind) * 255. + .49999;
3511  cols[2] = (colsd[2] - blue_mind) / (blue_maxd - blue_mind) * 255. + .49999;
3512  }
3513  set_colRGB24_param(rpar[i].value, (short)cols[0], (short)cols[1], (short)cols[2]);
3514  lives_free(cols);
3515 
3516  lives_freep((void **)&maxi);
3517  lives_freep((void **)&mini);
3518  lives_freep((void **)&maxd);
3519  lives_freep((void **)&mind);
3520  break;
3521  }
3522  break;
3523 
3524  default:
3525  rpar[i].type = LIVES_PARAM_UNKNOWN; // TODO - try to get default
3526  }
3527 
3528  string = weed_get_string_value(wtmpl, WEED_LEAF_NAME, NULL);
3529  rpar[i].name = string;
3530  rpar[i].label = lives_strdup(string);
3531 
3532  if (weed_plant_has_leaf(wtmpl, WEED_LEAF_DESCRIPTION)) {
3533  string = weed_get_string_value(wtmpl, WEED_LEAF_DESCRIPTION, NULL);
3534  rpar[i].desc = string;
3535  } else rpar[i].desc = NULL;
3536 
3537  if (is_hidden_param(inst, i)) rpar[i].hidden |= HIDDEN_GUI_PERM;
3538 
3539  // gui part /////////////////////
3540 
3541  if (gui) {
3542  if (weed_plant_has_leaf(gui, WEED_LEAF_LABEL)) {
3543  string = weed_get_string_value(gui, WEED_LEAF_LABEL, NULL);
3544  lives_free(rpar[i].label);
3545  rpar[i].label = string;
3546  }
3547  if (weed_plant_has_leaf(gui, WEED_LEAF_USE_MNEMONIC)) {
3548  rpar[i].use_mnemonic = weed_get_boolean_value(gui, WEED_LEAF_USE_MNEMONIC, NULL);
3549  }
3550  }
3551 
3552  for (j = 0; j < MAX_PARAM_WIDGETS; j++) {
3553  rpar[i].widgets[j] = NULL;
3554  }
3555  rpar[i].onchange = FALSE;
3556  }
3557 
3558  lives_free(wpars);
3559 
3560  return rpar;
3561 }
3562 
3563 
3564 lives_rfx_t *weed_to_rfx(weed_plant_t *plant, boolean show_reinits) {
3565  // return an RFX for a weed effect; set rfx->source to an INSTANCE of the filter (first instance for compound fx)
3566  // instance should be refcounted
3567  weed_plant_t *filter, *inst;
3568 
3569  char *string;
3570  lives_rfx_t *rfx = (lives_rfx_t *)lives_calloc(1, sizeof(lives_rfx_t));
3571  rfx->is_template = FALSE;
3572  if (weed_get_int_value(plant, WEED_LEAF_TYPE, NULL) == WEED_PLANT_FILTER_INSTANCE) {
3573  filter = weed_instance_get_filter(plant, TRUE);
3574  inst = plant;
3575  } else {
3576  filter = plant;
3577  inst = weed_instance_from_filter(filter);
3578  // init and deinit the effect to allow the plugin to hide parameters, etc.
3579  // rfx will inherit the refcount
3580  weed_reinit_effect(inst, TRUE);
3581  weed_instance_unref(inst);
3582  rfx->is_template = TRUE;
3583  }
3584 
3585  string = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
3586  rfx->name = string;
3587  rfx->menu_text = lives_strdup(string);
3588  rfx->action_desc = lives_strdup("no action");
3589  rfx->min_frames = -1;
3590  rfx->num_in_channels = enabled_in_channels(filter, FALSE);
3591  rfx->status = RFX_STATUS_WEED;
3592  rfx->props = 0;
3593  rfx->menuitem = NULL;
3594  rfx->num_params = weed_leaf_num_elements(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES);
3595  if (rfx->num_params > 0) rfx->params = weed_params_to_rfx(rfx->num_params, inst, show_reinits);
3596  else rfx->params = NULL;
3597  rfx->source = (void *)inst;
3599  rfx->gui_strings = NULL;
3600  rfx->onchange_strings = NULL;
3601  rfx->flags = 0;
3602  rfx->needs_reinit = FALSE;
3603  return rfx;
3604 }
3605 
3619  LiVESList *hints = NULL;
3620 
3621  if (rfx->status == RFX_STATUS_WEED) {
3622  weed_plant_t *gui;
3623  weed_plant_t *inst = (weed_plant_t *)rfx->source;
3624  weed_plant_t *filter = weed_instance_get_filter(inst, TRUE);
3625  int *filters = NULL;
3626  char *string, **rfx_strings, *delim;
3627  int nfilters;
3628  int num_hints;
3629  int i;
3630 
3631  if ((nfilters = num_compound_fx(filter)) > 1) {
3632  // handle compound fx
3633  filters = weed_get_int_array(filter, WEED_LEAF_HOST_FILTER_LIST, NULL);
3634  }
3635 
3636  for (i = 0; i < nfilters; i++) {
3637  if (filters) {
3638  filter = get_weed_filter(filters[i]);
3639  }
3640 
3641  if (!weed_plant_has_leaf(filter, WEED_LEAF_GUI)) continue;
3642  gui = weed_get_plantptr_value(filter, WEED_LEAF_GUI, NULL);
3643 
3644  if (!weed_plant_has_leaf(gui, WEED_LEAF_LAYOUT_SCHEME)) continue;
3645 
3646  string = weed_get_string_value(gui, WEED_LEAF_LAYOUT_SCHEME, NULL);
3647  if (strcmp(string, "RFX")) {
3648  lives_free(string);
3649  continue;
3650  }
3651  lives_free(string);
3652 
3653  if (!weed_plant_has_leaf(gui, WEED_LEAF_RFX_DELIM)) continue;
3654  delim = weed_get_string_value(gui, WEED_LEAF_RFX_DELIM, NULL);
3655  lives_snprintf(rfx->delim, 2, "%s", delim);
3656  lives_free(delim);
3657 
3658  rfx_strings = weed_get_string_array_counted(gui, WEED_LEAF_RFX_STRINGS, &num_hints);
3659  if (!num_hints) continue;
3660 
3661  for (i = 0; i < num_hints; i++) {
3662  hints = lives_list_append(hints, rfx_strings[i]);
3663  }
3664  lives_free(rfx_strings);
3665 
3666  if (filters) hints = lives_list_append(hints, lives_strdup("internal|nextfilter"));
3667  }
3668 
3669  lives_freep((void **)&filters);
3670  }
3671 
3672  return hints;
3673 }
3674 
3675 
3677  if (rfx) {
3678  char *fnamex = lives_build_filename(prefs->workdir, rfx->name, NULL);
3679  if (lives_file_test(fnamex, LIVES_FILE_TEST_EXISTS)) lives_rm(fnamex);
3680  lives_free(fnamex);
3681  }
3682 }
3683 
3684 
3717 char *plugin_run_param_window(const char *scrap_text, LiVESVBox * vbox, lives_rfx_t **ret_rfx) {
3718  FILE *sfile;
3719 
3720  lives_rfx_t *rfx = (lives_rfx_t *)lives_calloc(1, sizeof(lives_rfx_t));
3721 
3722  char *string;
3723  char *rfx_scrapname, *rfx_scriptname;
3724  char *rfxfile;
3725  char *com;
3726  char *fnamex = NULL;
3727  char *res_string = NULL;
3728  char buff[32];
3729 
3730  int res;
3731  int retval;
3732 
3735  return NULL;
3736  }
3737 
3738  rfx_scrapname = get_worktmpfile("rfx.");
3739  if (!rfx_scrapname) {
3740  workdir_warning();
3741  return NULL;
3742  }
3743 
3744  rfx_scriptname = lives_strdup_printf("%s.%s", rfx_scrapname, LIVES_FILE_EXT_RFX_SCRIPT);
3745 
3746  rfxfile = lives_build_path(prefs->workdir, rfx_scriptname, NULL);
3747  lives_free(rfx_scriptname);
3748 
3749  rfx->name = NULL;
3750 
3751  string = lives_strdup_printf("<name>\n%s\n</name>\n", rfx_scrapname);
3752 
3753  do {
3754  retval = 0;
3755  sfile = fopen(rfxfile, "w");
3756  if (!sfile) {
3757  retval = do_write_failed_error_s_with_retry(rfxfile, lives_strerror(errno));
3758  if (retval == LIVES_RESPONSE_CANCEL) {
3759  lives_free(string);
3760  return NULL;
3761  }
3762  } else {
3763  THREADVAR(write_failed) = FALSE;
3764  lives_fputs(string, sfile);
3765  if (scrap_text) {
3766  char *data = subst(scrap_text, "\\n", "\n");
3767  lives_fputs(data, sfile);
3768  lives_free(data);
3769  }
3770  fclose(sfile);
3771  lives_free(string);
3772  if (THREADVAR(write_failed)) {
3773  retval = do_write_failed_error_s_with_retry(rfxfile, NULL);
3774  if (retval == LIVES_RESPONSE_CANCEL) {
3775  return NULL;
3776  }
3777  }
3778  }
3779  } while (retval == LIVES_RESPONSE_RETRY);
3780 
3781  // OK, we should now have an RFX fragment in a file, we can compile it, then build a parameter window from it
3782 
3783  // call RFX_BUILDER program to compile the script, passing parameters input_filename and output_directory
3784  com = lives_strdup_printf("\"%s\" \"%s\" \"%s\" >%s", EXEC_RFX_BUILDER, rfxfile, prefs->workdir, LIVES_DEVNULL);
3785  res = lives_system(com, TRUE);
3786  lives_free(com);
3787 
3788  lives_rm(rfxfile);
3789  lives_free(rfxfile);
3790 
3791  if (res == 0) {
3792  // the script compiled correctly
3793 
3794  // now we pop up the parameter window, get the values of our parameters, and marshall them as extra_params
3795 
3796  // first create a lives_rfx_t from the scrap
3797  rfx->name = lives_strdup(rfx_scrapname);
3798  rfx->menu_text = NULL;
3799  rfx->action_desc = NULL;
3800  rfx->gui_strings = NULL;
3801  rfx->onchange_strings = NULL;
3802  lives_snprintf(rfx->rfx_version, 64, "%s", RFX_VERSION);
3803  rfx->flags = 0;
3804  rfx->status = RFX_STATUS_SCRAP;
3805 
3806  rfx->num_in_channels = 0;
3807  rfx->min_frames = -1;
3808 
3809  rfx->flags = RFX_FLAGS_NO_SLIDERS;
3810 
3811  fnamex = lives_build_filename(prefs->workdir, rfx_scrapname, NULL);
3812  com = lives_strdup_printf("\"%s\" get_define", fnamex);
3813  lives_free(fnamex);
3814 
3815  if (!lives_popen(com, TRUE, buff, 32)) {
3816  THREADVAR(com_failed) = TRUE;
3817  }
3818  lives_free(com);
3819 
3820  // command to get_define failed
3821  if (THREADVAR(com_failed)) {
3822  rfx_clean_exe(rfx);
3823  return NULL;
3824  }
3825 
3826  lives_snprintf(rfx->delim, 2, "%s", buff);
3827 
3828  // ok, this might need adjusting afterwards
3829  rfx->menu_text = (vbox == NULL ? lives_strdup_printf(_("%s advanced settings"), prefs->encoder.of_desc) : lives_strdup(""));
3830  rfx->is_template = FALSE;
3831 
3832  rfx->source = NULL;
3834 
3835 #if 0
3836  render_fx_get_params(rfx, scrap_text, RFX_STATUS_INTERNAL);
3837 #else
3838  render_fx_get_params(rfx, rfx_scrapname, RFX_STATUS_SCRAP);
3839 #endif
3840 
3842  if (!make_param_box(NULL, rfx)) {
3843  res_string = lives_strdup("");
3844  goto prpw_done;
3845  }
3846 
3847  // now we build our window and get param values
3848  if (!vbox) {
3849  _fx_dialog *fxdialog = on_fx_pre_activate(rfx, TRUE, NULL);
3850  LiVESWidget *dialog = fxdialog->dialog;
3851  if (prefs->show_gui) {
3852  lives_window_set_transient_for(LIVES_WINDOW(dialog), LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET));
3853  }
3854  lives_window_set_modal(LIVES_WINDOW(dialog), TRUE);
3855 
3856  do {
3857  res = lives_dialog_run(LIVES_DIALOG(dialog));
3858  } while (res == LIVES_RESPONSE_RETRY);
3859 
3860  if (res == LIVES_RESPONSE_OK) {
3861  // marshall our params for passing to the plugin
3862  res_string = param_marshall(rfx, FALSE);
3863  }
3864 
3865  lives_widget_destroy(dialog);
3866 
3867  if (fx_dialog[1]) {
3868  lives_freep((void **)&fx_dialog[1]);
3869  }
3870  } else {
3871  make_param_box(vbox, rfx);
3872  }
3873 
3874 prpw_done:
3875  if (ret_rfx) {
3876  *ret_rfx = rfx;
3877  } else {
3878  rfx_clean_exe(rfx);
3879  rfx_free(rfx);
3880  lives_free(rfx);
3881  }
3882  } else {
3883  if (ret_rfx) {
3884  *ret_rfx = NULL;
3885  } else {
3886  res_string = lives_strdup("");
3887  }
3888  if (rfx) {
3889  lives_free(rfx);
3890  }
3891  }
3892  lives_free(rfx_scrapname);
3893  return res_string;
3894 }
3895 
render_details::fps
double fps
Definition: events.h:218
_vid_playback_plugin::palette
int palette
width in pixels, but converted to macropixels for the player
Definition: plugins.h:181
render_details::achans
int achans
Definition: events.h:251
lives_freep
boolean lives_freep(void **ptr)
Definition: utils.c:1411
LIVES_GLOBAL_INLINE
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
mainwindow::jackd
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
AFORM_UNSIGNED
#define AFORM_UNSIGNED
Definition: main.h:786
PVAL_MULTI_ANY
#define PVAL_MULTI_ANY
Definition: plugins.h:587
mainwindow::ptr_x
int ptr_x
Definition: mainwindow.h:776
AUDIO_STREAMER_NAME
#define AUDIO_STREAMER_NAME
Definition: plugins.h:103
_vppaw::fps_entry
LiVESWidget * fps_entry
Definition: plugins.h:735
LIVES_IS_PLAYING
#define LIVES_IS_PLAYING
Definition: main.h:840
lives_decoder_sys_t::name
const char * name
plugin name
Definition: plugins.h:414
lives_param_t::special_type
lives_param_special_t special_type
Definition: plugins.h:607
mainwindow::endian
short endian
Definition: mainwindow.h:817
get_plugin_list
LiVESList * get_plugin_list(const char *plugin_type, boolean allow_nonex, const char *plugdir, const char *filter_ext)
Definition: plugins.c:115
lives_signal_connect
ulong lives_signal_connect(LiVESWidget *, const char *signal_name, ulong funcptr, livespointer data)
lives_decoder_sys_t
Definition: plugins.h:412
lives_struct_def_t
112 bytes
Definition: lsd.h:241
mainwindow::decoder_list
LiVESList * decoder_list
Definition: mainwindow.h:1612
unload_decoder_plugins
void unload_decoder_plugins(void)
Definition: plugins.c:2411
WEED_LEAF_RFX_DELIM
#define WEED_LEAF_RFX_DELIM
Definition: effects-weed.h:97
_encoder::of_allowed_acodecs
int of_allowed_acodecs
Definition: plugins.h:265
mainwindow::fixed_fpsd
double fixed_fpsd
<=0. means free playback
Definition: mainwindow.h:990
lives_param_t::transition
boolean transition
Definition: plugins.h:564
lives_dialog_add_button_from_stock
LiVESWidget * lives_dialog_add_button_from_stock(LiVESDialog *dialog, const char *stock_id, const char *label, int response_id)
Definition: widget-helper.c:9892
PLUGIN_RENDERED_EFFECTS_TEST
#define PLUGIN_RENDERED_EFFECTS_TEST
Definition: plugins.h:473
lives_colRGB48_t::red
uint16_t red
Definition: main.h:317
plugin_request_with_blanks
LIVES_GLOBAL_INLINE LiVESList * plugin_request_with_blanks(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:47
_vppaw::apply_fx
LiVESWidget * apply_fx
Definition: plugins.h:734
PLUGIN_RENDERED_EFFECTS_BUILTIN
#define PLUGIN_RENDERED_EFFECTS_BUILTIN
external rendered fx plugins (RFX plugins)
Definition: plugins.h:469
WEED_PLANT_IS_PARAMETER
#define WEED_PLANT_IS_PARAMETER(plant)
Definition: weed-effects-utils.h:46
PLUGIN_RENDERED_EFFECTS_BUILTIN_SCRIPTS
#define PLUGIN_RENDERED_EFFECTS_BUILTIN_SCRIPTS
rfx scripts for the SDK
Definition: plugins.h:476
lives_list_strcmp_index
int lives_list_strcmp_index(LiVESList *list, livesconstpointer data, boolean case_sensitive)
Definition: utils.c:4678
pp_get_param
const weed_plant_t * pp_get_param(weed_plant_t **pparams, int idx)
Definition: plugins.c:1042
lives_clip_t::file_name
char file_name[PATH_MAX]
input file
Definition: main.h:923
lives_free
#define lives_free
Definition: machinestate.h:52
set_colRGBA32_param
void set_colRGBA32_param(void *value, short red, short green, short blue, short alpha)
Definition: plugins.c:3166
RFX_WINSIZE_V
#define RFX_WINSIZE_V
Definition: mainwindow.h:177
_encoder::ptext
char ptext[512]
Definition: plugins.h:268
PLUGIN_RENDERED_EFFECTS_TEST_SCRIPTS
#define PLUGIN_RENDERED_EFFECTS_TEST_SCRIPTS
Definition: plugins.h:480
lives_rfx_t::is_template
boolean is_template
Definition: plugins.h:656
LIVES_WARN
#define LIVES_WARN(x)
Definition: main.h:1862
memset_f
void *(* memset_f)(void *, int, size_t)
Definition: machinestate.h:23
PLUGIN_RFX_SCRAP
#define PLUGIN_RFX_SCRAP
scraps are passed between programs to generate param windows
Definition: plugins.h:483
get_decoder_cdata
const lives_clip_data_t * get_decoder_cdata(int fileno, LiVESList *disabled, const lives_clip_data_t *fake_cdata)
Definition: plugins.c:2286
lives_widget_add_accelerator
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_add_accelerator(LiVESWidget *widget, const char *accel_signal, LiVESAccelGroup *accel_group, uint32_t accel_key, LiVESXModifierType accel_mods, LiVESAccelFlags accel_flags)
Definition: widget-helper.c:2953
start_audio_stream
boolean start_audio_stream(void)
Definition: audio.c:3827
plugin_request_by_line
LIVES_GLOBAL_INLINE LiVESList * plugin_request_by_line(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:59
lives_malloc
#define lives_malloc
Definition: machinestate.h:46
choose_file
char * choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
Definition: interface.c:4080
mainwindow::is_ready
boolean is_ready
Definition: mainwindow.h:787
find_rfx_plugin_by_name
int find_rfx_plugin_by_name(const char *name, short status)
Definition: plugins.c:3177
LIVES_CURSOR_NORMAL
@ LIVES_CURSOR_NORMAL
must be zero
Definition: widget-helper.h:1292
lives_utf8_strcmpfunc
int lives_utf8_strcmpfunc(livesconstpointer a, livesconstpointer b, livespointer fwd)
Definition: widget-helper.c:11025
get_rfx_param_by_name_string
boolean get_rfx_param_by_name_string(lives_rfx_t *rfx, const char *name, char **return_value)
Definition: plugins.c:3141
render_details::spinbutton_width
LiVESWidget * spinbutton_width
Definition: events.h:228
resaudw
_resaudw * resaudw
Definition: resample.h:38
DEF_VPP_VSIZE
#define DEF_VPP_VSIZE
Definition: plugins.h:212
_vid_playback_plugin::render_audio_frame_float
boolean(* render_audio_frame_float)(float **audio, int nsamps)
Definition: plugins.h:175
lives_window_set_transient_for
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_transient_for(LiVESWindow *window, LiVESWindow *parent)
Definition: widget-helper.c:2634
open_vid_playback_plugin
_vid_playback_plugin * open_vid_playback_plugin(const char *name, boolean in_use)
Definition: plugins.c:1099
lives_10pow
uint64_t lives_10pow(int pow) GNU_CONST
Definition: utils.c:1438
lives_widget_destroy
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
Definition: widget-helper.c:1553
close_decoder_plugin
void close_decoder_plugin(lives_decoder_t *dplug)
Definition: plugins.c:2361
lives_standard_spin_button_new
LiVESWidget * lives_standard_spin_button_new(const char *labeltext, double val, double min, double max, double step, double page, int dp, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9397
weed_instance_get_in_params
WEED_GLOBAL_INLINE weed_plant_t ** weed_instance_get_in_params(weed_plant_t *instance, int *nparams)
Definition: weed-effects-utils.c:602
lives_read_le
ssize_t lives_read_le(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:486
lives_param_t::special_type_index
int special_type_index
Definition: plugins.h:608
PLUGIN_EFFECTS_WEED
#define PLUGIN_EFFECTS_WEED
uses WEED_PLUGIN_PATH
Definition: plugins.h:110
lives_set_cursor_style
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
Definition: widget-helper.c:11950
lives_colRGBA64_t::alpha
uint16_t alpha
Definition: main.h:326
_fx_dialog
Definition: mainwindow.h:1838
_future_prefs::vpp_palette
int vpp_palette
Definition: preferences.h:808
_prefs::workdir
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
lives_spin_button_set_value
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_value(LiVESSpinButton *button, double value)
Definition: widget-helper.c:5119
_vppaw::plugin
_vid_playback_plugin * plugin
Definition: plugins.h:730
version
const char * version(void)
lives_spin_button_get_value_as_int
WIDGET_HELPER_GLOBAL_INLINE int lives_spin_button_get_value_as_int(LiVESSpinButton *button)
Definition: widget-helper.c:5091
LIVES_SEEK_FAST
#define LIVES_SEEK_FAST
good
Definition: plugins.h:312
lives_dialog_get_content_area
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_content_area(LiVESDialog *dialog)
Definition: widget-helper.c:2479
_prefs::show_gui
boolean show_gui
Definition: preferences.h:290
filter_encoders_by_img_ext
LiVESList * filter_encoders_by_img_ext(LiVESList *encoders, const char *img_ext)
Definition: plugins.c:2006
prefsw_set_astream_settings
void prefsw_set_astream_settings(_vid_playback_plugin *vpp, _prefsw *prefsw)
Definition: preferences.c:2730
lives_param_t::onchange
boolean onchange
is there a trigger ?
Definition: plugins.h:595
stop_audio_stream
void stop_audio_stream(void)
Definition: audio.c:3906
lives_xwindow_raise
WIDGET_HELPER_GLOBAL_INLINE boolean lives_xwindow_raise(LiVESXWindow *xwin)
Definition: widget-helper.c:6312
IS_VALID_CLIP
#define IS_VALID_CLIP(clip)
Definition: main.h:808
lives_decoder_t
Definition: plugins.h:449
lives_rfx_t::status
lives_rfx_status_t status
Definition: plugins.h:631
lsd-tab.h
weed_param_get_template
WEED_GLOBAL_INLINE weed_plant_t * weed_param_get_template(weed_plant_t *param)
Definition: weed-effects-utils.c:518
string_lists_differ
boolean string_lists_differ(LiVESList *, LiVESList *)
Definition: utils.c:5831
mainwindow::vpp
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
LIVES_PARAM_STRING
@ LIVES_PARAM_STRING
Definition: plugins.h:505
weed_paramtmpl_get_gui
WEED_GLOBAL_INLINE weed_plant_t * weed_paramtmpl_get_gui(weed_plant_t *paramt, int create_if_not_exists)
Definition: weed-effects-utils.c:162
get_weed_filter
weed_plant_t * get_weed_filter(int idx)
Definition: effects-weed.c:11014
PVAL_MULTI_NONE
#define PVAL_MULTI_NONE
Definition: plugins.h:586
lives_clip_data_t::palettes
int * palettes
number forames from one keyframe to the next, 0 if unknown
Definition: plugins.h:375
set_param_from_list
int set_param_from_list(LiVESList *plist, lives_param_t *param, int pnum, boolean with_min_max, boolean upd)
update values for param using values in plist if upd is TRUE, the widgets for that param also are upd...
Definition: paramwindow.c:3065
render_details::width
int width
Definition: events.h:216
_resaudw::rb_unsigned
LiVESWidget * rb_unsigned
Definition: resample.h:24
lives_clip_t::ext_src
void * ext_src
points to opaque source for non-disk types
Definition: main.h:1040
lives_realloc
#define lives_realloc
Definition: machinestate.h:49
cfile
#define cfile
Definition: main.h:1833
plugin_request
LIVES_GLOBAL_INLINE LiVESList * plugin_request(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:54
_vid_playback_plugin::fheight
int fheight
Definition: plugins.h:179
RFX_WINSIZE_H
#define RFX_WINSIZE_H
size of the fx dialog windows scrollwindow
Definition: mainwindow.h:175
lives_dialog_response
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_response(LiVESDialog *dialog, int response)
Definition: widget-helper.c:1820
effects.h
plugin_request_by_space
LIVES_GLOBAL_INLINE LiVESList * plugin_request_by_space(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:64
lives_rfx_t::name
char * name
the name of the executable (so we can run it !)
Definition: plugins.h:626
lives_grab_add
WIDGET_HELPER_GLOBAL_INLINE boolean lives_grab_add(LiVESWidget *widget)
Definition: widget-helper.c:1454
lives_rfx_t::action_desc
char * action_desc
for Weed "Applying $s"
Definition: plugins.h:628
lives_list_sort_alpha
LiVESList * lives_list_sort_alpha(LiVESList *list, boolean fwd)
Definition: utils.c:5474
get_colRGB24_param
void get_colRGB24_param(void *value, lives_colRGB48_t *rgb)
Definition: plugins.c:3093
set_bool_param
void set_bool_param(void *value, boolean _const)
Definition: plugins.c:3103
open_decoder_plugin
lives_decoder_sys_t * open_decoder_plugin(const char *plname)
Definition: plugins.c:2438
lives_rfx_t::params
lives_param_t * params
Definition: plugins.h:649
LIVES_ERROR
#define LIVES_ERROR(x)
Definition: main.h:1870
malloc_f
void *(* malloc_f)(size_t)
Definition: machinestate.h:18
prefsw
_prefsw * prefsw
Definition: preferences.h:849
_ext_memmove
void * _ext_memmove(void *dest, const void *src, size_t n)
Definition: machinestate.c:573
lives_clip_t::clip_type
lives_clip_type_t clip_type
Definition: main.h:886
DEF_VPP_HSIZE
#define DEF_VPP_HSIZE
Definition: plugins.h:211
lives_standard_dialog_new
LiVESWidget * lives_standard_dialog_new(const char *title, boolean add_std_buttons, int width, int height)
Definition: widget-helper.c:9971
COMBOWIDTHCHARS
#define COMBOWIDTHCHARS
char width of combo entries (default)
Definition: mainwindow.h:74
mainwindow::play_window
LiVESWidget * play_window
Definition: mainwindow.h:947
prefs
_prefs * prefs
Definition: preferences.h:847
mainwindow::save_with_sound
boolean save_with_sound
Definition: mainwindow.h:784
_ext_calloc
void * _ext_calloc(size_t nmemb, size_t msize)
Definition: machinestate.c:584
_prefs::lib_dir
char lib_dir[PATH_MAX]
Definition: preferences.h:75
_prefs::audio_player
short audio_player
Definition: preferences.h:40
_vid_playback_plugin::get_palette_list
int *(* get_palette_list)(void)
Definition: plugins.h:133
mainwindow::decoders_loaded
boolean decoders_loaded
decoders
Definition: mainwindow.h:1611
mainwindow::osc_enc_height
int osc_enc_height
Definition: mainwindow.h:921
lives_dialog_run
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
Definition: widget-helper.c:1783
set_int_param
void set_int_param(void *value, int _const)
Definition: plugins.c:3114
lives_open2
int lives_open2(const char *pathname, int flags)
Definition: utils.c:99
LIVES_INFO
#define LIVES_INFO(x)
Definition: main.h:1854
host_info_cb
weed_plant_t * host_info_cb(weed_plant_t *xhost_info, void *data)
Definition: effects-weed.c:4522
LIVES_FILE_EXT_JPG
#define LIVES_FILE_EXT_JPG
Definition: mainwindow.h:488
_fx_dialog::dialog
LiVESWidget * dialog
Definition: mainwindow.h:1839
get_best_audio
int64_t get_best_audio(_vid_playback_plugin *vpp)
Definition: plugins.c:1441
LIVES_PARAM_COLRGB24
@ LIVES_PARAM_COLRGB24
Definition: plugins.h:504
DEF_DIALOG_WIDTH
#define DEF_DIALOG_WIDTH
Definition: mainwindow.h:185
mainwindow::num_rendered_effects_builtin
int num_rendered_effects_builtin
Definition: mainwindow.h:856
lives_rfx_t::menu_text
char * menu_text
for Weed, this is the filter_class "name"
Definition: plugins.h:627
capability::has_mktemp
lives_checkstatus_t has_mktemp
Definition: main.h:540
weed_palette_get_name_full
char * weed_palette_get_name_full(int pal, int clamping, int subspace)
Definition: weed-effects-utils.c:764
DEF_DIALOG_HEIGHT
#define DEF_DIALOG_HEIGHT
Definition: mainwindow.h:186
do_read_failed_error_s_with_retry
LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4122
lives_open3
int lives_open3(const char *pathname, int flags, mode_t mode)
Definition: utils.c:94
do_vpp_fps_error
LIVES_GLOBAL_INLINE void do_vpp_fps_error(void)
Definition: dialogs.c:3737
param_marshall_to_argv
char ** param_marshall_to_argv(lives_rfx_t *rfx)
Definition: paramwindow.c:2797
set_rfx_param_by_name_string
boolean set_rfx_param_by_name_string(lives_rfx_t *rfx, const char *name, const char *value, boolean update_visual)
Definition: plugins.c:3124
pp_get_chan
const weed_plant_t * pp_get_chan(weed_plant_t **pparams, int idx)
Definition: plugins.c:1054
mainwindow::noswitch
boolean noswitch
value set automatically to prevent 'inopportune' clip switching
Definition: mainwindow.h:1019
_resaudw::entry_arate
LiVESWidget * entry_arate
Definition: resample.h:20
mainwindow::stream_ticks
ticks_t stream_ticks
ticks since first frame sent to playback plugin
Definition: mainwindow.h:1011
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
lsd_check_match
uint64_t lsd_check_match(lives_struct_def_t *lsd1, lives_struct_def_t *lsd2)
Definition: lsd-tab.c:174
lives_button_grab_default_special
boolean lives_button_grab_default_special(LiVESWidget *button)
Definition: widget-helper.c:7587
best_palette_match
int best_palette_match(int *palette_list, int num_palettes, int palette)
check palette vs.
Definition: effects-weed.c:868
lives_widget_set_no_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_no_show_all(LiVESWidget *widget, boolean set)
Definition: widget-helper.c:4868
_resaudw::entry_asamps
LiVESWidget * entry_asamps
Definition: resample.h:22
on_decplug_advanced_clicked
void on_decplug_advanced_clicked(LiVESButton *button, livespointer user_data)
Definition: plugins.c:2575
mainwindow::osc_auto
int osc_auto
bypass user choices automatically
Definition: mainwindow.h:918
_vid_playback_plugin::version
const char *(* version)(void)
Definition: plugins.h:130
realloc_f
void *(* realloc_f)(void *, size_t)
Definition: machinestate.h:25
prefsw_set_rec_after_settings
void prefsw_set_rec_after_settings(_vid_playback_plugin *vpp, _prefsw *prefsw)
Definition: preferences.c:2741
get_token_count
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
sizdbl
ssize_t sizdbl
Definition: main.c:102
_future_prefs::vpp_argc
int vpp_argc
Definition: preferences.h:814
lives_widget_get_xwindow
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_widget_get_xwindow(LiVESWidget *widget)
Definition: widget-helper.c:4759
add_fill_to_box
LiVESWidget * add_fill_to_box(LiVESBox *box)
Definition: widget-helper.c:12377
fx_dialog
_fx_dialog * fx_dialog[2]
Definition: mainwindow.h:1851
lives_decoder_sys_t::rip_audio_cleanup
void(* rip_audio_cleanup)(const lives_clip_data_t *cdata)
Definition: plugins.h:445
LIVES_RFX_SOURCE_RFX
@ LIVES_RFX_SOURCE_RFX
Definition: plugins.h:513
enabled_in_channels
int enabled_in_channels(weed_plant_t *plant, boolean count_repeats)
Definition: effects-weed.c:3985
get_int_param
int get_int_param(void *value)
Definition: plugins.c:3079
get_clip_value
boolean get_clip_value(int which, lives_clip_details_t, void *retval, size_t maxlen)
Definition: utils.c:5039
_encoder::audio_codec
uint32_t audio_codec
Definition: plugins.h:235
PLUGIN_COMPOUND_EFFECTS_CUSTOM
#define PLUGIN_COMPOUND_EFFECTS_CUSTOM
Definition: effects-weed.h:129
auto_resample_resize
boolean auto_resample_resize(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned, boolean swap_endian)
Definition: resample.c:80
LIVES_STRUCT_CLIP_DATA_T
@ LIVES_STRUCT_CLIP_DATA_T
Definition: lsd-tab.h:12
VPP_LOCAL_DISPLAY
#define VPP_LOCAL_DISPLAY
Definition: plugins.h:69
do_vpp_palette_error
LIVES_GLOBAL_INLINE void do_vpp_palette_error(void)
Definition: dialogs.c:3727
set_double_param
void set_double_param(void *value, double _const)
Definition: plugins.c:3119
lives_decoder_sys_t::chill_out
boolean(* chill_out)(const lives_clip_data_t *)
free buffers when we arent playing sequentially / on standby
Definition: plugins.h:435
_encoder::of_restrict
char of_restrict[1024]
Definition: plugins.h:266
mainwindow::event_list
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
ticks_t
int64_t ticks_t
Definition: main.h:97
PLUGIN_VID_PLAYBACK
#define PLUGIN_VID_PLAYBACK
Definition: plugins.h:100
PLUGIN_SCRIPTS_DIR
#define PLUGIN_SCRIPTS_DIR
Definition: mainwindow.h:596
_vid_playback_plugin
Definition: plugins.h:123
_future_prefs::encoder
_encoder encoder
Definition: preferences.h:820
_prefs::startup_phase
short startup_phase
0 = normal , -1 or 1: fresh install, 2: workdir set, 3: startup tests passed, 4: aud pl chosen,...
Definition: preferences.h:216
param_demarshall
void param_demarshall(lives_rfx_t *rfx, LiVESList *plist, boolean with_min_max, boolean upd)
Definition: paramwindow.c:3013
lives_colRGB48_t::blue
uint16_t blue
Definition: main.h:319
LIVES_PARAM_NUM
@ LIVES_PARAM_NUM
Definition: plugins.h:502
close_vid_playback_plugin
void close_vid_playback_plugin(_vid_playback_plugin *vpp)
Definition: plugins.c:998
rfx_free
void rfx_free(lives_rfx_t *rfx)
Definition: plugins.c:2987
do_rfx_cleanup
void do_rfx_cleanup(lives_rfx_t *rfx)
Definition: plugins.c:2671
lives_param_t::dp
int dp
decimals, 0 for int and bool
Definition: plugins.h:575
_prefs::encoder
_encoder encoder
from main.h
Definition: preferences.h:38
do_error_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
_vppaw::pal_entry
LiVESWidget * pal_entry
Definition: plugins.h:736
on_vppa_ok_clicked
void on_vppa_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: plugins.c:435
_ext_realloc
void * _ext_realloc(void *p, size_t n)
Definition: machinestate.c:575
lives_rfx_t::onchange_strings
LiVESList * onchange_strings
rfxscript for constructing the params, param window and onchange triggers
Definition: plugins.h:655
lives_window_add_accel_group
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_add_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
Definition: widget-helper.c:2968
_vid_playback_plugin::get_description
const char *(* get_description)(void)
Definition: plugins.h:131
MAX_FRAME_HEIGHT
#define MAX_FRAME_HEIGHT
Definition: main.h:221
lives_clip_data_t::lsd
lives_struct_def_t lsd
Definition: plugins.h:321
render_details::is_encoding
boolean is_encoding
Definition: events.h:248
CAN_ENCODE_PNG
#define CAN_ENCODE_PNG
Definition: plugins.h:259
TRUE
#define TRUE
Definition: videoplugin.h:59
DLL_NAME
#define DLL_NAME
Definition: mainwindow.h:530
lives_big_and_bold
char * lives_big_and_bold(const char *fmt,...)
Definition: widget-helper.c:8648
lives_param_t::reinit
int reinit
Definition: plugins.h:569
mainwindow::pheight
int pheight
playback height
Definition: mainwindow.h:927
sizint
ssize_t sizint
type sizes
Definition: main.c:102
lives_rfx_t::num_in_channels
int num_in_channels
Definition: plugins.h:630
do_encoder_restrict_dialog
boolean do_encoder_restrict_dialog(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned, boolean swap_endian, boolean anr, boolean save_all)
Definition: dialogs.c:3148
lives_decoder_t::cdata
lives_clip_data_t * cdata
Definition: plugins.h:451
_vid_playback_plugin::fixed_fps_numer
int fixed_fps_numer
Definition: plugins.h:186
mainwindow::string_constants
char * string_constants[NUM_LIVES_STRING_CONSTANTS]
Definition: mainwindow.h:1539
lives_param_t::edited
boolean edited
Definition: plugins.h:598
lives_colRGBA64_t::green
uint16_t green
Definition: main.h:324
rdet_suggest_values
boolean rdet_suggest_values(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned, boolean swap_endian, boolean anr, boolean ignore_fps)
Definition: dialogs.c:3065
_vid_playback_plugin::play_paramtmpls
const weed_plant_t ** play_paramtmpls
Definition: plugins.h:193
lives_param_t::multi
short multi
multivalue type - single value, multi value, or per channel
Definition: plugins.h:585
_encoder::of_def_ext
char of_def_ext[16]
Definition: plugins.h:267
calloc_f
void *(* calloc_f)(size_t, size_t)
Definition: machinestate.h:26
lives_memset
#define lives_memset
Definition: machinestate.h:61
_ext_memset
void * _ext_memset(void *p, int i, size_t n)
Definition: machinestate.c:571
weed_palette_is_yuv
LIVES_GLOBAL_INLINE boolean weed_palette_is_yuv(int pal)
Definition: colourspace.c:1457
_vid_playback_plugin::extra_argc
int extra_argc
Definition: plugins.h:190
lives_clip_data_t::audio_name
char audio_name[512]
name of audio codec, e.g. "vorbis" or NULL
Definition: plugins.h:394
widget_opts_t::last_container
LiVESWidget * last_container
container which wraps last widget created + subwidgets (READONLY)
Definition: widget-helper.h:1407
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
_vid_playback_plugin::fixed_fps_denom
int fixed_fps_denom
Definition: plugins.h:187
is_hidden_param
boolean is_hidden_param(weed_plant_t *plant, int i)
returns the permanent (structural) state c.f check_hidden_gui() which sets flag values for params lin...
Definition: effects-weed.c:8587
set_colRGB24_param
void set_colRGB24_param(void *value, short red, short green, short blue)
Definition: plugins.c:3149
lives_standard_combo_new
LiVESWidget * lives_standard_combo_new(const char *labeltext, LiVESList *list, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9544
lives_decoder_sys_t::module_check_init
const char *(* module_check_init)(void)
Definition: plugins.h:441
lives_rfx_t
Definition: plugins.h:625
_resaudw::rb_littleend
LiVESWidget * rb_littleend
Definition: resample.h:26
lives_special_aspect_t
Definition: paramspecial.h:31
lives_param_t::max
double max
for string this is max characters
Definition: plugins.h:579
free_f
void(* free_f)(void *)
Definition: machinestate.h:19
RFX_STATUS_WEED
@ RFX_STATUS_WEED
indicates an internal RFX, created from a weed instance
Definition: plugins.h:616
_vppaw::intention
int intention
Definition: plugins.h:739
do_encoder_sox_error
LIVES_GLOBAL_INLINE void do_encoder_sox_error(void)
Definition: dialogs.c:3039
lives_decoder_sys_t::module_unload
void(* module_unload)(void)
Definition: plugins.h:446
chill_decoder_plugin
boolean chill_decoder_plugin(int fileno)
Definition: plugins.c:2425
lives_clip_data_t::rec_rowstrides
int * rec_rowstrides
if non-NULL, plugin can set recommended vals, pointer to single value set by host
Definition: plugins.h:351
rfx_copy
void rfx_copy(lives_rfx_t *dest, lives_rfx_t *src, boolean full)
Definition: plugins.c:2931
_vid_playback_plugin::play_frame
boolean(* play_frame)(weed_layer_t *frame, ticks_t tc, weed_layer_t *ret)
Definition: plugins.h:140
make_param_box
boolean make_param_box(LiVESVBox *top_vbox, lives_rfx_t *rfx)
make a dynamic parameter window
Definition: paramwindow.c:1015
lives_colRGBA64_t::blue
uint16_t blue
Definition: main.h:325
capable
capability * capable
Definition: main.h:627
LIVES_EXT_SRC_DECODER
#define LIVES_EXT_SRC_DECODER
Definition: main.h:1044
lives_toggle_button_get_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
Definition: widget-helper.c:4472
workdir_warning
void workdir_warning(void)
Definition: dialogs.c:3001
rfx_clean_exe
void rfx_clean_exe(lives_rfx_t *rfx)
Definition: plugins.c:3676
widget_opts_t::mnemonic_label
boolean mnemonic_label
if underscore in label text should be mnemonic accelerator
Definition: widget-helper.h:1420
_future_prefs::vpp_YUV_clamping
int vpp_YUV_clamping
Definition: preferences.h:809
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
lives_param_t
Definition: plugins.h:538
_vid_playback_plugin::play_params
weed_plant_t ** play_params
Definition: plugins.h:194
get_external_window_hints
LiVESList * get_external_window_hints(lives_rfx_t *rfx)
get the interface hints set by a Weed filter in the filter_class.
Definition: plugins.c:3618
_vid_playback_plugin::module_unload
void(* module_unload)(void)
Definition: plugins.h:147
EXEC_RFX_BUILDER
#define EXEC_RFX_BUILDER
Definition: rfx-builder.h:10
LIVES_PARAM_UNDISPLAYABLE
@ LIVES_PARAM_UNDISPLAYABLE
Definition: plugins.h:509
int_array_contains_value
boolean int_array_contains_value(int *array, int num_elems, int value)
Definition: utils.c:4284
on_vppa_save_clicked
void on_vppa_save_clicked(LiVESButton *button, livespointer user_data)
Definition: plugins.c:701
RFX_MAXSTRINGLEN
#define RFX_MAXSTRINGLEN
length of max string (not including terminating NULL) for LiVES-perl
Definition: plugins.h:498
_vid_playback_plugin::num_alpha_chans
int num_alpha_chans
Definition: plugins.h:197
_prefs::prefix_dir
char prefix_dir[PATH_MAX]
Definition: preferences.h:74
_vid_playback_plugin::get_fps_list
const char *(* get_fps_list)(int palette)
Definition: plugins.h:148
render_details::spinbutton_height
LiVESWidget * spinbutton_height
Definition: events.h:229
apply_button_set_enabled
void apply_button_set_enabled(LiVESWidget *widget, livespointer func_data)
Definition: preferences.c:2911
plugin_run_param_window
char * plugin_run_param_window(const char *scrap_text, LiVESVBox *vbox, lives_rfx_t **ret_rfx)
create an interface window for a plugin; possibly run it, and return the parameters
Definition: plugins.c:3717
lives_rfx_t::props
uint32_t props
Definition: plugins.h:633
VPP_CAN_RESIZE
#define VPP_CAN_RESIZE
type sepcific caps
Definition: plugins.h:67
_vid_playback_plugin::alpha_chans
weed_plant_t ** alpha_chans
Definition: plugins.h:195
lives_general_button_clicked
void lives_general_button_clicked(LiVESButton *button, livespointer data_to_free)
Definition: widget-helper.c:12306
do_program_not_found_error
LIVES_GLOBAL_INLINE void do_program_not_found_error(const char *progname)
Definition: dialogs.c:3640
mainwindow::osc_enc_fps
float osc_enc_fps
Definition: mainwindow.h:922
REINIT_FUNCTIONAL
#define REINIT_FUNCTIONAL
Definition: plugins.h:566
weed_layer_get_palette
LIVES_GLOBAL_INLINE int weed_layer_get_palette(weed_layer_t *layer)
Definition: colourspace.c:13977
lives_rfx_t::num_params
int num_params
Definition: plugins.h:644
PLUGIN_RENDERED_EFFECTS_CUSTOM_SCRIPTS
#define PLUGIN_RENDERED_EFFECTS_CUSTOM_SCRIPTS
in the config directory
Definition: plugins.h:479
mainwindow::sep_win
boolean sep_win
Definition: mainwindow.h:761
mainwindow::msg
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
_vid_playback_plugin::init_screen
boolean(* init_screen)(int width, int height, boolean fullscreen, uint64_t window_id, int argc, char **argv)
Definition: plugins.h:144
CLIP_TYPE_FILE
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
weed_yuv_clamping_get_name
const char * weed_yuv_clamping_get_name(int clamping)
Definition: weed-effects-utils.c:751
lives_clip_data_t::ext_malloc
malloc_f * ext_malloc
Definition: plugins.h:324
_resaudw::aud_checkbutton
LiVESWidget * aud_checkbutton
Definition: resample.h:32
mainwindow::num_rendered_effects_custom
int num_rendered_effects_custom
Definition: mainwindow.h:857
_vid_playback_plugin::audio_codec
uint32_t audio_codec
Definition: plugins.h:169
RFX_FLAGS_NO_SLIDERS
#define RFX_FLAGS_NO_SLIDERS
internal use
Definition: plugins.h:646
weed_instance_ref
LIVES_GLOBAL_INLINE int weed_instance_ref(weed_plant_t *inst)
Definition: effects-weed.c:6230
d_print_file_error_failed
void d_print_file_error_failed(void)
Definition: utils.c:2625
mainwindow::fx1_bool
boolean fx1_bool
Definition: mainwindow.h:1053
HIDDEN_MULTI
#define HIDDEN_MULTI
Definition: plugins.h:552
WEED_LEAF_RFX_STRINGS
#define WEED_LEAF_RFX_STRINGS
Definition: effects-weed.h:96
lives_standard_label_new
LiVESWidget * lives_standard_label_new(const char *text)
Definition: widget-helper.c:8601
mainwindow::textwidget_focus
LiVESWidget * textwidget_focus
Definition: mainwindow.h:1569
lives_param_t::min
double min
Definition: plugins.h:578
decoder_plugin_move_to_first
boolean decoder_plugin_move_to_first(const char *name)
Definition: plugins.c:2072
weed_paramtmpl_get_type
WEED_GLOBAL_INLINE int weed_paramtmpl_get_type(weed_plant_t *paramtmpl)
Definition: weed-effects-utils.c:312
PLUGIN_EXEC_DIR
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
set_string_param
void set_string_param(void **value_ptr, const char *_const, size_t maxlen)
Definition: plugins.c:3108
PLUGIN_DECODERS
#define PLUGIN_DECODERS
Definition: plugins.h:99
mainwindow::vpp_defs_file
char vpp_defs_file[PATH_MAX]
Definition: mainwindow.h:1627
interface.h
lives_vbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3267
_encoder::of_name
char of_name[64]
Definition: plugins.h:263
weed_paramtmpl_get_flags
WEED_GLOBAL_INLINE int weed_paramtmpl_get_flags(weed_plant_t *paramtmpl)
Definition: weed-effects-utils.c:300
d_print_failed
void d_print_failed(void)
Definition: utils.c:2615
PLUGIN_RENDERED_EFFECTS_CUSTOM
#define PLUGIN_RENDERED_EFFECTS_CUSTOM
in the config directory
Definition: plugins.h:472
widget_opts_t::use_markup
boolean use_markup
whether markup should be used in labels
Definition: widget-helper.h:1421
lives_param_t::list
LiVESList * list
for string list (choices)
Definition: plugins.h:582
_vid_playback_plugin::fixed_fpsd
double fixed_fpsd
Definition: plugins.h:188
_future_prefs::disabled_decoders
LiVESList * disabled_decoders
Definition: preferences.h:834
LIVES_PARAM_SPECIAL_TYPE_NONE
@ LIVES_PARAM_SPECIAL_TYPE_NONE
Definition: plugins.h:519
lives_rfx_t::delim
char delim[2]
Definition: plugins.h:652
set_vpp
void set_vpp(boolean set_in_prefs)
Definition: preferences.c:476
_ext_memcpy
void * _ext_memcpy(void *dest, const void *src, size_t n)
Definition: machinestate.c:567
_vppaw::spinbuttonh
LiVESWidget * spinbuttonh
Definition: plugins.h:732
get_double_param
double get_double_param(void *value)
Definition: plugins.c:3086
lives_write_le
ssize_t lives_write_le(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
mainwindow::files
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
num_compound_fx
int num_compound_fx(weed_plant_t *plant)
return number of filters in a compound fx (1 if it is not compound) - works for filter or inst
Definition: effects-weed.c:132
lives_combo_get_entry
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_combo_get_entry(LiVESCombo *widget)
Definition: widget-helper.c:12295
weed_instance_from_filter
weed_plant_t * weed_instance_from_filter(weed_plant_t *filter)
Definition: effects-weed.c:6469
lives_window_fullscreen
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_fullscreen(LiVESWindow *window)
Definition: widget-helper.c:2871
_future_prefs::vpp_fheight
int vpp_fheight
Definition: preferences.h:812
remove_trailing_zeroes
char * remove_trailing_zeroes(double val)
Definition: utils.c:5395
cached_mod
uint16_t cached_mod
Definition: keyboard.h:11
_vid_playback_plugin::weed_setup
weed_plant_t *(* weed_setup)(weed_bootstrap_f)
Definition: plugins.h:143
mainwindow::pulsed
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
_prefs::play_monitor
int play_monitor
Definition: preferences.h:306
_vid_playback_plugin::capabilities
uint64_t capabilities
Definition: plugins.h:177
_encoder::of_desc
char of_desc[128]
Definition: plugins.h:264
widget_opts_t::packing_height
int packing_height
vertical pixels between widgets
Definition: widget-helper.h:1411
lives_rfx_t::menuitem
LiVESWidget * menuitem
the menu item which activates this effect
Definition: plugins.h:643
_encoder::name
char name[64]
Definition: plugins.h:234
lives_param_t::source
void * source
Definition: plugins.h:602
lives_decoder_sys_t::get_clip_data
lives_clip_data_t *(* get_clip_data)(char *URI, const lives_clip_data_t *cdata)
call first time with NULL cdata subsequent calls should re-use cdata set cdata->current_clip > 0 to g...
Definition: plugins.h:429
plugin_request_common
LiVESList * plugin_request_common(const char *plugin_type, const char *plugin_name, const char *request, const char *delim, boolean allow_blanks)
Definition: plugins.c:69
palette
_palette * palette
interface colour settings
Definition: main.c:101
do_plugin_encoder_error
void do_plugin_encoder_error(const char *plugin_name)
Definition: plugins.c:1531
widget_opts_t::non_modal
boolean non_modal
non-modal for dialogs
Definition: widget-helper.h:1422
_vid_playback_plugin::get_audio_fmts
int *(* get_audio_fmts)(void)
Definition: plugins.h:167
lives_list_copy_strings
LiVESList * lives_list_copy_strings(LiVESList *list)
Definition: utils.c:5820
lives_clip_data_t::ext_realloc
realloc_f * ext_realloc
Definition: plugins.h:329
weed_paramtmpl_value_irrelevant
WEED_GLOBAL_INLINE int weed_paramtmpl_value_irrelevant(weed_plant_t *paramtmpl)
Definition: weed-effects-utils.c:360
lives_hbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3253
check_for_executable
boolean check_for_executable(lives_checkstatus_t *cap, const char *exec)
Definition: utils.c:3434
render_details::ratio_fps
boolean ratio_fps
Definition: events.h:219
save_file
void save_file(int clip, int start, int end, const char *filename)
Definition: saveplay.c:1260
lives_window_set_modal
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_modal(LiVESWindow *window, boolean modal)
Definition: widget-helper.c:2650
_future_prefs::vpp_fixed_fps_numer
int vpp_fixed_fps_numer
Definition: preferences.h:803
lives_fx_candidate_t::delegate
int delegate
offset in list of current delegate
Definition: plugins.h:688
FX_CANDIDATE_RESIZER
#define FX_CANDIDATE_RESIZER
Definition: plugins.h:695
PLUGIN_COMPOUND_EFFECTS_BUILTIN
#define PLUGIN_COMPOUND_EFFECTS_BUILTIN
Definition: effects-weed.h:128
CLIP_DETAILS_DECODER_NAME
@ CLIP_DETAILS_DECODER_NAME
Definition: main.h:1164
render_details::arate
int arate
Definition: events.h:250
lives_rfx_t::flags
uint32_t flags
Definition: plugins.h:645
MAX_PARAM_WIDGETS
#define MAX_PARAM_WIDGETS
max number of display widgets per parameter (currently 7 for transition param with mergealign - spin ...
Definition: plugins.h:488
lives_param_t::label
char * label
Definition: plugins.h:543
widget_opts_t::scale
double scale
scale factor for all sizes
Definition: widget-helper.h:1433
lives_clip_t::ext_src_type
int ext_src_type
Definition: main.h:1051
_future_prefs::vpp_fixed_fpsd
double vpp_fixed_fpsd
Definition: preferences.h:806
subst
char * subst(const char *string, const char *from, const char *to)
Definition: utils.c:5484
lives_rfx_t::gui_strings
LiVESList * gui_strings
rfxscript for constructing the params, param window and onchange triggers
Definition: plugins.h:654
cached_key
uint16_t cached_key
Definition: keyboard.h:10
lives_window_set_keep_below
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_keep_below(LiVESWindow *window, boolean set)
Definition: widget-helper.c:2700
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
PLUGIN_AUDIO_STREAM
#define PLUGIN_AUDIO_STREAM
Definition: plugins.h:101
mainwindow::ext_audio
volatile boolean ext_audio
using external video playback plugin to stream audio
Definition: mainwindow.h:774
after_param_text_changed
void after_param_text_changed(LiVESWidget *textwidget, lives_rfx_t *rfx)
Definition: paramwindow.c:2635
load_vpp_defaults
void load_vpp_defaults(_vid_playback_plugin *vpp, char *vpp_file)
Definition: plugins.c:265
lives_rfx_t::needs_reinit
int needs_reinit
Definition: plugins.h:657
lives_decoder_sys_t::set_palette
boolean(* set_palette)(lives_clip_data_t *)
Definition: plugins.h:442
lives_calloc
#define lives_calloc
Definition: machinestate.h:67
get_lsd
const lives_struct_def_t * get_lsd(lives_struct_type st_type)
Definition: lsd-tab.c:23
AUDIO_CODEC_MAX
#define AUDIO_CODEC_MAX
Definition: plugins.h:250
on_fx_pre_activate
_fx_dialog * on_fx_pre_activate(lives_rfx_t *rfx, boolean is_realtime, LiVESWidget *pbox)
Definition: paramwindow.c:687
paramwindow.h
array_to_string_list
LiVESList * array_to_string_list(char **array, int offset, int len)
Definition: plugins.c:2883
lives_widget_get_xwinid
WIDGET_HELPER_GLOBAL_INLINE uint64_t lives_widget_get_xwinid(LiVESWidget *widget, const char *msg)
Definition: widget-helper.c:7298
WEED_LEAF_HOST_FILTER_LIST
#define WEED_LEAF_HOST_FILTER_LIST
Definition: effects-weed.h:77
get_worktmpfile
char * get_worktmpfile(const char *prefix)
Definition: machinestate.c:3251
weed_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
lives_decoder_sys_t::clip_data_free
void(* clip_data_free)(lives_clip_data_t *)
call this for each cdata before unloading the module
Definition: plugins.h:438
lives_list_free_all
void lives_list_free_all(LiVESList **)
Definition: utils.c:4873
argv_to_marshalled_list
LiVESList * argv_to_marshalled_list(lives_rfx_t *rfx, int argc, char **argv)
Definition: paramwindow.c:3031
LIVES_MAIN_WINDOW_WIDGET
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
param_copy
void param_copy(lives_param_t *dest, lives_param_t *src, boolean full)
Definition: plugins.c:3020
mainwindow::new_vpp
const char * new_vpp
Definition: mainwindow.h:1573
_prefs::stream_audio_out
boolean stream_audio_out
Definition: preferences.h:360
minimise_aspect_delta
void minimise_aspect_delta(double allowed_aspect, int hblock, int vblock, int hsize, int vsize, int *width, int *height)
Definition: utils.c:3750
memmove_f
void *(* memmove_f)(void *, const void *, size_t)
Definition: machinestate.h:24
check_rfx_for_lives
boolean check_rfx_for_lives(lives_rfx_t *rfx)
Definition: plugins.c:2661
lives_read
ssize_t lives_read(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:460
lives_decoder_t::decoder
const lives_decoder_sys_t * decoder
Definition: plugins.h:450
weed_layer_get_yuv_clamping
LIVES_GLOBAL_INLINE int weed_layer_get_yuv_clamping(weed_layer_t *layer)
Definition: colourspace.c:13959
_vid_playback_plugin::YUV_clamping
int YUV_clamping
Definition: plugins.h:183
_vppaw::spinbuttonw
LiVESWidget * spinbuttonw
Definition: plugins.h:733
lives_clip_data_t::ext_memset
memset_f * ext_memset
Definition: plugins.h:327
_vid_playback_plugin::fwidth
int fwidth
Definition: plugins.h:179
close_clip_decoder
void close_clip_decoder(int clipno)
Definition: plugins.c:2382
lives_clip_data_t::video_name
char video_name[512]
name of video codec, e.g. "theora" or NULL
Definition: plugins.h:386
EXEC_MKTEMP
#define EXEC_MKTEMP
Definition: mainwindow.h:430
get_transition_param
int get_transition_param(weed_plant_t *filter, boolean skip_internal)
Definition: effects-weed.c:8656
lives_clip_data_t
Definition: plugins.h:319
lives_colRGB48_t
Definition: main.h:316
_future_prefs::vpp_fixed_fps_denom
int vpp_fixed_fps_denom
Definition: preferences.h:804
lives_memcpy
#define lives_memcpy
Definition: machinestate.h:55
get_ratio_fps
double get_ratio_fps(const char *string)
Definition: utils.c:5379
_resaudw::rb_bigend
LiVESWidget * rb_bigend
Definition: resample.h:25
_vid_playback_plugin::get_capabilities
uint64_t(* get_capabilities)(int palette)
Definition: plugins.h:135
future_prefs
_future_prefs * future_prefs
Definition: preferences.h:848
lives_param_t::hidden
uint32_t hidden
Definition: plugins.h:546
LIVES_FILE_EXT_RFX_SCRIPT
#define LIVES_FILE_EXT_RFX_SCRIPT
Definition: mainwindow.h:515
lives_clip_data_t::ext_free
free_f * ext_free
Definition: plugins.h:325
lives_popen
ssize_t lives_popen(const char *com, boolean allow_error, char *buff, ssize_t buflen)
Definition: utils.c:194
lives_strappend
LIVES_GLOBAL_INLINE int lives_strappend(const char *string, int len, const char *xnew)
Definition: machinestate.c:1436
lives_accel_group_new
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
Definition: widget-helper.c:2915
RFX_STATUS_BUILTIN
@ RFX_STATUS_BUILTIN
factory presets
Definition: plugins.h:612
_future_prefs::vpp_fwidth
int vpp_fwidth
Definition: preferences.h:811
buff_to_list
LiVESList * buff_to_list(const char *buffer, const char *delim, boolean allow_blanks, boolean strip)
Definition: utils.c:5755
WEED_PLANT_IS_PARAMETER_TEMPLATE
#define WEED_PLANT_IS_PARAMETER_TEMPLATE(plant)
Definition: weed-effects-utils.h:48
HIDDEN_NEEDS_REINIT
#define HIDDEN_NEEDS_REINIT
non-structural (temporary)
Definition: plugins.h:557
_vid_playback_plugin::extra_argv
char ** extra_argv
Definition: plugins.h:191
AFORM_SIGNED
#define AFORM_SIGNED
Definition: main.h:783
PLUGIN_COMPOUND_DIR
#define PLUGIN_COMPOUND_DIR
Definition: mainwindow.h:597
lives_param_t::name
char * name
Definition: plugins.h:540
lives_special_aspect_t::no_reset
boolean no_reset
Definition: paramspecial.h:39
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
render_fx_get_params
void render_fx_get_params(lives_rfx_t *rfx, const char *plugin_name, short status)
Definition: plugins.c:2707
_vid_playback_plugin::handle
void * handle
Definition: plugins.h:126
lives_entry_set_width_chars
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_width_chars(LiVESEntry *entry, int nchars)
Definition: widget-helper.c:6223
LIVES_PARAM_UNKNOWN
@ LIVES_PARAM_UNKNOWN
Definition: plugins.h:501
anames
const char *const anames[AUDIO_CODEC_MAX]
Definition: plugins.c:21
do_encoder_acodec_error
LIVES_GLOBAL_INLINE void do_encoder_acodec_error(void)
Definition: dialogs.c:3046
_vppaw
video playback plugin window - fixed part
Definition: plugins.h:729
weed_paramtmpl_does_wrap
WEED_GLOBAL_INLINE int weed_paramtmpl_does_wrap(weed_plant_t *paramtmpl)
Definition: weed-effects-utils.c:334
_future_prefs::vpp_name
char vpp_name[64]
new video playback plugin
Definition: preferences.h:801
sort_rfx_array
void sort_rfx_array(lives_rfx_t *in, int num)
Definition: plugins.c:2909
RFX_PROPS_MAY_RESIZE
#define RFX_PROPS_MAY_RESIZE
is a tool
Definition: plugins.h:635
do_write_failed_error_s_with_retry
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4058
RFX_STATUS_INTERNAL
@ RFX_STATUS_INTERNAL
used for parsing RFX scraps generated internally (will possiblky replace SCRAP)
Definition: plugins.h:618
RFX_STATUS_SCRAP
@ RFX_STATUS_SCRAP
used for parsing RFX scraps from external apps
Definition: plugins.h:617
lives_decoder_sys_t::handle
void * handle
may be shared between several instances
Definition: plugins.h:415
PVAL_MULTI_PER_CHANNEL
#define PVAL_MULTI_PER_CHANNEL
Definition: plugins.h:588
LIVES_INTENTION_PLAY
@ LIVES_INTENTION_PLAY
Definition: plugins.h:45
save_vpp_defaults
void save_vpp_defaults(_vid_playback_plugin *vpp, char *vpp_file)
Definition: plugins.c:181
main.h
RFX_STATUS_TEST
@ RFX_STATUS_TEST
test effects in the advanced menu
Definition: plugins.h:614
_vid_playback_plugin::exit_screen
void(* exit_screen)(uint16_t mouse_x, uint16_t mouse_y)
Definition: plugins.h:146
lives_param_t::source_type
lives_rfx_source_t source_type
Definition: plugins.h:604
LIVES_CURSOR_BUSY
@ LIVES_CURSOR_BUSY
Definition: widget-helper.h:1293
lives_rfx_t::source_type
lives_rfx_source_t source_type
Definition: plugins.h:650
lives_colRGBA64_t
Definition: main.h:322
render_details::height
int height
Definition: events.h:217
get_enabled_channel
weed_plant_t * get_enabled_channel(weed_plant_t *inst, int which, boolean is_in)
for FILTER_INST
Definition: effects-weed.c:536
lives_param_t::changed
boolean changed
Definition: plugins.h:597
mainwindow::fs
boolean fs
Definition: mainwindow.h:762
capability::has_sox_sox
lives_checkstatus_t has_sox_sox
Definition: main.h:509
resample.h
lives_rfx_t::rfx_version
char rfx_version[64]
Definition: plugins.h:653
_vid_playback_plugin::name
char name[64]
Definition: plugins.h:125
play_window_set_title
void play_window_set_title(void)
Definition: gui.c:3722
mainwindow::ext_playback
boolean ext_playback
using external video playback plugin
Definition: mainwindow.h:773
mainw
mainwindow * mainw
Definition: main.c:103
lives_decoder_sys_t::version
const char *(* version)(void)
Definition: plugins.h:418
_vppaw::dialog
LiVESWidget * dialog
Definition: plugins.h:731
load_decoders
LiVESList * load_decoders(void)
Definition: plugins.c:2092
vid_playback_plugin_exit
void vid_playback_plugin_exit(void)
Definition: plugins.c:1413
lives_clip_data_t::container_name
char container_name[512]
name of container, e.g. "ogg" or NULL
Definition: plugins.h:337
_vid_playback_plugin::get_init_rfx
const char *(* get_init_rfx)(int intention)
Definition: plugins.h:151
LIVES_RFX_SOURCE_WEED
@ LIVES_RFX_SOURCE_WEED
Definition: plugins.h:514
LIVES_STRING_CONSTANT_NONE
@ LIVES_STRING_CONSTANT_NONE
Definition: mainwindow.h:371
lives_chdir
int lives_chdir(const char *path, boolean no_error_dlg)
Definition: utils.c:1393
get_bool_param
boolean get_bool_param(void *value)
Definition: plugins.c:3072
LIVES_EXT_SRC_NONE
#define LIVES_EXT_SRC_NONE
Definition: main.h:1043
lives_fputs
int lives_fputs(const char *s, FILE *stream)
Definition: utils.c:359
weed_instance_unref
LIVES_GLOBAL_INLINE int weed_instance_unref(weed_plant_t *inst)
Definition: effects-weed.c:6234
lives_clip_data_t::ext_calloc
calloc_f * ext_calloc
Definition: plugins.h:330
_resaudw::rb_signed
LiVESWidget * rb_signed
Definition: resample.h:23
MAX_FRAME_WIDTH
#define MAX_FRAME_WIDTH
Definition: main.h:220
_vppaw::keep_rfx
boolean keep_rfx
Definition: plugins.h:738
lives_decoder_sys_t::rip_audio
int64_t(* rip_audio)(const lives_clip_data_t *, const char *fname, int64_t stframe, int64_t nframes, unsigned char **abuff)
Definition: plugins.h:443
lives_standard_scrolled_window_new
LiVESWidget * lives_standard_scrolled_window_new(int width, int height, LiVESWidget *child)
Definition: widget-helper.c:10272
lives_param_t::step_size
double step_size
Definition: plugins.h:562
lives_entry_set_text
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_text(LiVESEntry *entry, const char *text)
Definition: widget-helper.c:6211
get_extension
char * get_extension(const char *filename)
Definition: utils.c:3217
LIVES_INTENTION_TRANSCODE
@ LIVES_INTENTION_TRANSCODE
Definition: plugins.h:47
PLUGIN_ENCODERS
#define PLUGIN_ENCODERS
Definition: plugins.h:98
lives_container_add
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_add(LiVESContainer *container, LiVESWidget *widget)
Definition: widget-helper.c:4929
lives_grab_remove
WIDGET_HELPER_GLOBAL_INLINE boolean lives_grab_remove(LiVESWidget *widget)
Definition: widget-helper.c:1462
WEED_LEAF_HOST_NEXT_INSTANCE
#define WEED_LEAF_HOST_NEXT_INSTANCE
Definition: effects-weed.h:104
lives_param_t::widgets
LiVESWidget * widgets[MAX_PARAM_WIDGETS]
TODO - change to LiVESWidget **widgets, terminated with a NULL.
Definition: plugins.h:594
vpp_try_match_palette
boolean vpp_try_match_palette(_vid_playback_plugin *vpp, weed_layer_t *layer)
Definition: plugins.c:1066
lives_list_move_to_first
LiVESList * lives_list_move_to_first(LiVESList *list, LiVESList *item) WARN_UNUSED
Definition: utils.c:5789
_future_prefs::vpp_argv
char ** vpp_argv
Definition: preferences.h:817
lives_decoder_t::refs
int refs
Definition: plugins.h:452
_resaudw::entry_achans
LiVESWidget * entry_achans
Definition: resample.h:21
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
lives_widget_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
Definition: widget-helper.c:1523
REINIT_VISUAL
#define REINIT_VISUAL
Definition: plugins.h:567
get_colRGBA32_param
void get_colRGBA32_param(void *value, lives_colRGBA64_t *rgba)
Definition: plugins.c:3098
mainwindow::num_rendered_effects_test
int num_rendered_effects_test
Definition: mainwindow.h:858
mainwindow::fx_candidates
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
rdet
render_details * rdet
Definition: events.h:256
_vid_playback_plugin::YUV_subspace
int YUV_subspace
Definition: plugins.h:184
lives_toggle_button_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_set_active(LiVESToggleButton *button, boolean active)
Definition: widget-helper.c:4483
widget_opts
widget_opts_t widget_opts
Definition: widget-helper.h:1442
weed_instance_get_filter
weed_plant_t * weed_instance_get_filter(weed_plant_t *inst, boolean get_compound_parent)
Definition: effects-weed.c:180
on_vpp_advanced_clicked
_vppaw * on_vpp_advanced_clicked(LiVESButton *button, livespointer user_data)
Definition: plugins.c:727
lives_entry_get_text
WIDGET_HELPER_GLOBAL_INLINE const char * lives_entry_get_text(LiVESEntry *entry)
Definition: widget-helper.c:6203
_vid_playback_plugin::init_audio
boolean(* init_audio)(int in_sample_rate, int in_nchans, int argc, char **argv)
Definition: plugins.h:174
weed_gui_get_flags
WEED_GLOBAL_INLINE int weed_gui_get_flags(weed_plant_t *gui)
gui plants
Definition: weed-effects-utils.c:640
lives_param_t::value
void * value
current value(s)
Definition: plugins.h:576
PATH_MAX
#define PATH_MAX
Definition: main.h:255
AUD_PLAYER_PULSE
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
PLUGIN_THEMES_CUSTOM
#define PLUGIN_THEMES_CUSTOM
Definition: plugins.h:107
special_cleanup
boolean special_cleanup(boolean is_ok)
Definition: paramspecial.c:641
AUD_PLAYER_JACK
#define AUD_PLAYER_JACK
Definition: preferences.h:43
THEME_DIR
#define THEME_DIR
Definition: mainwindow.h:595
lives_colRGB48_t::green
uint16_t green
Definition: main.h:318
lives_list_delete_string
LiVESList * lives_list_delete_string(LiVESList *, const char *string) WARN_UNUSED
Definition: utils.c:5801
lives_clip_data_t::ext_memcpy
memcpy_f * ext_memcpy
Definition: plugins.h:326
check_encoder_restrictions
boolean check_encoder_restrictions(boolean get_extension, boolean user_audio, boolean save_all)
Definition: plugins.c:1557
lives_clip_t
corresponds to one clip in the GUI
Definition: main.h:877
lives_colRGBA64_t::red
uint16_t red
Definition: main.h:323
lives_param_t::wrap
boolean wrap
Definition: plugins.h:571
param_marshall
char * param_marshall(lives_rfx_t *rfx, boolean with_min_max)
Definition: paramwindow.c:2844
weed_params_to_rfx
lives_param_t * weed_params_to_rfx(int npar, weed_plant_t *inst, boolean show_reinits)
Definition: plugins.c:3201
lives_write
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
lives_rfx_t::source
void * source
points to the source (e.g. a weed_plant_t)
Definition: plugins.h:651
capability::has_convert
lives_checkstatus_t has_convert
Definition: main.h:514
PREF_VID_PLAYBACK_PLUGIN
#define PREF_VID_PLAYBACK_PLUGIN
Definition: preferences.h:920
_vid_playback_plugin::set_palette
boolean(* set_palette)(int palette)
Definition: plugins.h:134
get_plugin_result
LiVESList * get_plugin_result(const char *command, const char *delim, boolean allow_blanks, boolean strip)
Definition: plugins.c:30
lives_window_present
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_present(LiVESWindow *window)
Definition: widget-helper.c:2858
find_rfx_param_by_name
lives_param_t * find_rfx_param_by_name(lives_rfx_t *rfx, const char *name)
Definition: plugins.c:3189
_vid_playback_plugin::set_fps
boolean(* set_fps)(double fps)
Definition: plugins.h:149
lives_standard_check_button_new
LiVESWidget * lives_standard_check_button_new(const char *labeltext, boolean active, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9048
d_print_done
void d_print_done(void)
Definition: utils.c:2620
LIVES_DEVNULL
#define LIVES_DEVNULL
Definition: mainwindow.h:592
weed_palette_get_name
const char * weed_palette_get_name(int pal)
Definition: weed-effects-utils.c:703
lives_param_t::change_blocked
boolean change_blocked
Definition: plugins.h:600
_prefsw::prefs_dialog
LiVESWidget * prefs_dialog
Definition: preferences.h:536
capability::python_version
uint64_t python_version
Definition: main.h:574
_prefs::configfile
char configfile[PATH_MAX]
kept in locale encoding (config settings) [default ~/.local/config/lives)
Definition: preferences.h:63
rfx_free_all
void rfx_free_all(void)
Definition: plugins.c:3010
on_vppa_cancel_clicked
void on_vppa_cancel_clicked(LiVESButton *button, livespointer user_data)
Definition: plugins.c:408
mainwindow::pwidth
int pwidth
PLAYBACK.
Definition: mainwindow.h:926
render_details::spinbutton_fps
LiVESWidget * spinbutton_fps
Definition: events.h:230
rfx_params_free
void rfx_params_free(lives_rfx_t *rfx)
Definition: plugins.c:2973
_vid_playback_plugin::YUV_sampling
int YUV_sampling
Definition: plugins.h:182
_ext_free
void _ext_free(void *p)
Definition: machinestate.c:556
HIDDEN_GUI_PERM
#define HIDDEN_GUI_PERM
Definition: plugins.h:551
AUDIO_CODEC_NONE
#define AUDIO_CODEC_NONE
Definition: plugins.h:252
lives_widget_get_toplevel
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_toplevel(LiVESWidget *widget)
Definition: widget-helper.c:4750
weed_to_rfx
lives_rfx_t * weed_to_rfx(weed_plant_t *plant, boolean show_reinits)
Definition: plugins.c:3564
mainwindow::vpp_stream_mutex
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
Definition: mainwindow.h:1501
get_mime_type
void get_mime_type(char *text, int maxlen, const lives_clip_data_t *cdata)
Definition: plugins.c:2513
clone_decoder
lives_decoder_t * clone_decoder(int fileno)
Definition: plugins.c:2181
mainwindow::osc_enc_width
int osc_enc_width
encode width, height and fps set externally
Definition: mainwindow.h:921
_prefs::config_datadir
char config_datadir[PATH_MAX]
kept in locale encoding (general config files) (default ~/.local/share/lives)
Definition: preferences.h:64
LIVES_FILE_EXT_PNG
#define LIVES_FILE_EXT_PNG
Definition: mainwindow.h:487
lives_param_t::def
void * def
default values
Definition: plugins.h:581
_future_prefs::disabled_decoders_new
LiVESList * disabled_decoders_new
Definition: preferences.h:835
_vid_playback_plugin::render_frame
boolean(* render_frame)(int hsize, int vsize, ticks_t timecode, void **pixel_data, void **return_data, weed_plant_t **play_params)
Definition: plugins.h:137
FALSE
#define FALSE
Definition: videoplugin.h:60
WEED_LEAF_HOST_DEFAULT
#define WEED_LEAF_HOST_DEFAULT
Definition: effects-weed.h:62
mainwindow::vrfx_update
volatile lives_rfx_t * vrfx_update
single access for updating alarm list
Definition: mainwindow.h:1510
TEXTWIDGET_KEY
#define TEXTWIDGET_KEY
Definition: widget-helper.h:1492
weed_reinit_effect
lives_filter_error_t weed_reinit_effect(weed_plant_t *inst, boolean reinit_compound)
Definition: effects-weed.c:1169
LIVES_PARAM_BOOL
@ LIVES_PARAM_BOOL
Definition: plugins.h:503
RFX_VERSION
#define RFX_VERSION
must match whatever is in RFX_BUILDER
Definition: rfx-builder.h:13
mainwindow::ptr_y
int ptr_y
Definition: mainwindow.h:776
_vid_playback_plugin::set_yuv_palette_clamping
int(* set_yuv_palette_clamping)(int clamping_type)
Definition: plugins.h:163
add_aspect_ratio_button
const lives_special_aspect_t * add_aspect_ratio_button(LiVESSpinButton *sp_width, LiVESSpinButton *sp_height, LiVESBox *box)
Definition: interface.c:4963
rfx-builder.h
boolean
int boolean
Definition: videoplugin.h:54
lives_clip_t::handle
char handle[256]
Definition: main.h:881
_
#define _(String)
Definition: support.h:44
lives_param_t::group
int group
Definition: plugins.h:572
IS_NORMAL_CLIP
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
lives_decoder_sys_t::get_frame
boolean(* get_frame)(const lives_clip_data_t *, int64_t frame, int *rowstrides, int height, void **pixel_data)
frame starts at 0 in these functions; height is height of primary plane
Definition: plugins.h:432
lives_widget_set_tooltip_text
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_set_tooltip_text(LiVESWidget *widget, const char *tip_text)
Definition: widget-helper.c:4641
mainwindow::error
boolean error
Definition: mainwindow.h:801
lives_param_t::use_mnemonic
boolean use_mnemonic
Definition: plugins.h:545
LIVES_PARAM_STRING_LIST
@ LIVES_PARAM_STRING_LIST
Definition: plugins.h:506
lives_rm
int lives_rm(const char *file)
Definition: utils.c:4395
PLUGIN_THEMES
#define PLUGIN_THEMES
smogrify handles the directory differently for themes
Definition: plugins.h:106
render_details::aendian
int aendian
Definition: events.h:253
_vppaw::rfx
lives_rfx_t * rfx
Definition: plugins.h:737
lives_clip_data_t::ext_memmove
memmove_f * ext_memmove
Definition: plugins.h:328
lives_param_t::type
lives_param_type_t type
Definition: plugins.h:573
WEED_PLANT_IS_CHANNEL
#define WEED_PLANT_IS_CHANNEL(plant)
Definition: weed-effects-utils.h:41
AFORM_BIG_ENDIAN
#define AFORM_BIG_ENDIAN
Definition: main.h:787
lives_widget_context_update
boolean lives_widget_context_update(void)
Definition: widget-helper.c:11878
memcpy_f
void *(* memcpy_f)(void *, const void *, size_t)
Definition: machinestate.h:21
render_details::suggestion_followed
boolean suggestion_followed
Definition: events.h:246
set_string_pref
int set_string_pref(const char *key, const char *value)
Definition: preferences.c:290
get_signed_endian
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
Definition: utils.c:5408
render_details::asamps
int asamps
Definition: events.h:252
lives_rfx_t::min_frames
int min_frames
for Weed, 1
Definition: plugins.h:629
_ext_malloc
void * _ext_malloc(size_t n)
Definition: machinestate.c:530
_vid_playback_plugin::module_check_init
const char *(* module_check_init)(void)
Definition: plugins.h:129
MAINW_MSG_SIZE
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
lives_clip_data_t::nframes
int64_t nframes
Definition: plugins.h:349
_vid_playback_plugin::get_yuv_palette_clamping
int *(* get_yuv_palette_clamping)(int palette)
Definition: plugins.h:160
_vid_playback_plugin::num_play_params
int num_play_params
Definition: plugins.h:196
RFX_STATUS_CUSTOM
@ RFX_STATUS_CUSTOM
custom effects in the custom menu
Definition: plugins.h:613
mainwindow::write_vpp_file
boolean write_vpp_file
video playback plugin was updated; write settings to a file on exit
Definition: mainwindow.h:1040
lives_param_t::desc
char * desc
Definition: plugins.h:541
mainwindow::rendered_fx
lives_rfx_t * rendered_fx
rendered fx
Definition: mainwindow.h:855
lives_box_pack_start
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_start(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
Definition: widget-helper.c:3281
lives_param_t::flags
int flags
Definition: plugins.h:544