LiVES  3.2.0
videodev.c
Go to the documentation of this file.
1 // LiVES - videodev input
2 // (c) G. Finch 2010 - 2019 <salsaman+lives@gmail.com>
3 // released under the GNU GPL 3 or later
4 // see file COPYING or www.gnu.org for details
5 
6 #include "main.h"
7 
8 #ifdef HAVE_UNICAP
9 #define DEBUG_UNICAP
10 
11 #include "videodev.h"
12 #include "interface.h"
13 #include "callbacks.h"
14 #include "effects-weed.h"
15 
16 #include <unicap/unicap.h>
17 
18 static boolean lives_wait_user_buffer(lives_vdev_t *ldev, unicap_data_buffer_t **buff, double timeout) {
19  // wait for USER type buffer
20  unicap_status_t status;
21  int ncount;
22  lives_alarm_t alarm_handle = lives_alarm_set(timeout * TICKS_PER_SECOND_DBL);
23 
24  do {
25  status = unicap_poll_buffer(ldev->handle, &ncount);
26 
27 #ifdef DEBUG_UNICAP
28  if (status != STATUS_SUCCESS) lives_printerr("Unicap poll failed with status %d\n", status);
29 #endif
30  if (ncount >= 0) {
31  lives_alarm_clear(alarm_handle);
32  if (!SUCCESS(unicap_wait_buffer(ldev->handle, buff))) return FALSE;
33  return TRUE;
34  }
35  lives_usleep(prefs->sleep_time);
37  sched_yield();
38  } while (lives_alarm_check(alarm_handle) > 0);
39 
40  return FALSE;
41 }
42 
43 
44 static boolean lives_wait_system_buffer(lives_vdev_t *ldev, double timeout) {
45  // wait for SYSTEM type buffer
46  lives_alarm_t alarm_handle = lives_alarm_set(timeout * TICKS_PER_SECOND_DBL);
47 
48  do {
49  if (ldev->buffer_ready != 0) {
50  lives_alarm_clear(alarm_handle);
51  return TRUE;
52  }
53  lives_usleep(prefs->sleep_time);
55  sched_yield();
56  } while (lives_alarm_check(alarm_handle) > 0);
57  lives_alarm_clear(alarm_handle);
58 
59  return FALSE;
60 }
61 
62 
63 static void new_frame_cb(unicap_event_t event, unicap_handle_t handle,
64  unicap_data_buffer_t *buffer, void *usr_data) {
65  lives_vdev_t *ldev = (lives_vdev_t *)usr_data;
66  if (!LIVES_IS_PLAYING || (mainw->playing_file != ldev->fileno && mainw->blend_file != ldev->fileno)) {
67  ldev->buffer_ready = 0;
68  return;
69  }
70 
71  if (ldev->buffer_ready != 1) {
72  lives_memcpy(ldev->buffer1.data, buffer->data, ldev->buffer1.buffer_size);
73  ldev->buffer_ready = 1;
74  } else {
75  lives_memcpy(ldev->buffer2.data, buffer->data, ldev->buffer2.buffer_size);
76  ldev->buffer_ready = 2;
77  }
78 }
79 
80 
81 boolean weed_layer_set_from_lvdev(weed_layer_t *layer, lives_clip_t *sfile, double timeoutsecs) {
82  lives_vdev_t *ldev = (lives_vdev_t *)sfile->ext_src;
83  unicap_data_buffer_t *returned_buffer = NULL;
84  void **pixel_data;
85  void *odata = ldev->buffer1.data;
86 
87  int error;
88 
89  weed_set_int_value(layer, WEED_LEAF_WIDTH, sfile->hsize /
90  weed_palette_get_pixels_per_macropixel(ldev->current_palette));
91  weed_set_int_value(layer, WEED_LEAF_HEIGHT, sfile->vsize);
92  weed_set_int_value(layer, WEED_LEAF_CURRENT_PALETTE, ldev->current_palette);
93  weed_set_int_value(layer, WEED_LEAF_YUV_SUBSPACE, WEED_YUV_SUBSPACE_YCBCR); // TODO - handle bt.709
94  weed_set_int_value(layer, WEED_LEAF_YUV_SAMPLING, WEED_YUV_SAMPLING_DEFAULT); // TODO - use ldev->YUV_sampling
95  weed_set_int_value(layer, WEED_LEAF_YUV_CLAMPING, ldev->YUV_clamping);
96 
98 
99  if (ldev->buffer_type == UNICAP_BUFFER_TYPE_USER) {
100  if (weed_palette_get_nplanes(ldev->current_palette) == 1 || ldev->is_really_grey) {
101  ldev->buffer1.data = (unsigned char *)weed_get_voidptr_value(layer, WEED_LEAF_PIXEL_DATA, &error);
102  }
103 
104  unicap_queue_buffer(ldev->handle, &ldev->buffer1);
105 
106  if (!lives_wait_user_buffer(ldev, &returned_buffer, timeoutsecs)) {
107 #ifdef DEBUG_UNICAP
108  lives_printerr("Failed to wait for user buffer!\n");
109  unicap_stop_capture(ldev->handle);
110  unicap_dequeue_buffer(ldev->handle, &returned_buffer);
111  unicap_start_capture(ldev->handle);
112 #endif
113  ldev->buffer1.data = (unsigned char *)odata;
114  return FALSE;
115  }
116  } else {
117  // wait for callback to fill buffer
118  if (!lives_wait_system_buffer(ldev, timeoutsecs)) {
119 #ifdef DEBUG_UNICAP
120  lives_printerr("Failed to wait for system buffer!\n");
121 #endif
122  }
123  if (ldev->buffer_ready == 1) returned_buffer = &ldev->buffer1;
124  else returned_buffer = &ldev->buffer2;
125  }
126 
127  pixel_data = weed_get_voidptr_array(layer, WEED_LEAF_PIXEL_DATA, &error);
128 
129  if (weed_palette_get_nplanes(ldev->current_palette) > 1 && !ldev->is_really_grey) {
130  boolean contig = FALSE;
131  if (weed_get_boolean_value(layer, WEED_LEAF_HOST_PIXEL_DATA_CONTIGUOUS, &error) == WEED_TRUE) contig = TRUE;
132  pixel_data_planar_from_membuf(pixel_data, returned_buffer->data, sfile->hsize * sfile->vsize, ldev->current_palette, contig);
133  } else {
134  if (ldev->buffer_type == UNICAP_BUFFER_TYPE_SYSTEM) {
135  int rowstride = weed_get_int_value(layer, WEED_LEAF_ROWSTRIDES, &error);
136  size_t bsize = rowstride * sfile->vsize;
137  if (bsize > returned_buffer->buffer_size) {
138 #ifdef DEBUG_UNICAP
139  lives_printerr("Warning - returned buffer size too small !\n");
140 #endif
141  bsize = returned_buffer->buffer_size;
142  }
143  lives_memcpy(pixel_data[0], returned_buffer->data, bsize);
144  }
145  }
146 
147  // shouldnt be necessary since we specified black_fill in create_empty_pixel_data()
148 
149  /* if (ldev->is_really_grey) { */
150  /* // y contains our greyscale data */
151  /* // set u and v planes to 128 */
152  /* memset(pixel_data[1], 128, sfile->hsize * sfile->vsize); */
153  /* memset(pixel_data[2], 128, sfile->hsize * sfile->vsize); */
154  /* } */
155 
156  lives_free(pixel_data);
157 
158  ldev->buffer1.data = (unsigned char *)odata;
159 
160  return TRUE;
161 }
162 
163 
164 static unicap_format_t *lvdev_get_best_format(const unicap_format_t *formats,
165  lives_vdev_t *ldev, int palette, int width, int height) {
166  // get nearest format for given palette, width and height
167  // if palette is WEED_PALETTE_END, or cannot be matched, get best quality palette (preferring RGB)
168  // width and height must be set, actual width and height will be set as near to this as possible
169  // giving preference to larger frame size
170 
171  // if the device supports no usable formats, returns NULL
172 
173  // Note: we match first by palette, then by size
174 
175  int format_count, i;
176  unicap_format_t *format;
177  int f = -1;
178  int bestp = WEED_PALETTE_END;
179  int bestw = 0, besth = 0;
180  int cpal;
181 
182  // get details
183  for (format_count = 0;
184  SUCCESS(unicap_enumerate_formats(ldev->handle, NULL, (unicap_format_t *)&formats[format_count], format_count))
185  && (format_count < MAX_FORMATS); format_count++) {
186  format = (unicap_format_t *)&formats[format_count];
187 
188  // TODO - check if we need to free format->sizes
189 
190  // TODO - prefer non-interlaced, YCbCr for YUV
191  cpal = fourccp_to_weedp(format->fourcc, format->bpp, NULL, NULL, NULL, NULL);
192 
193  if (cpal == WEED_PALETTE_END || weed_palette_is_alpha(cpal)) {
194 #ifdef DEBUG_UNICAP
195  // set format to try and get more data
196  unicap_set_format(ldev->handle, format);
197  lives_printerr("Unusable palette with fourcc 0x%x bpp=%d, size=%dx%d buf=%d\n", format->fourcc, format->bpp,
198  format->size.width,
199  format->size.height, (int)format->buffer_size);
200 #endif
201  continue;
202  }
203 
204  if (bestp == WEED_PALETTE_END || cpal == palette || weed_palette_is_alpha(bestp) ||
205  weed_palette_is_lower_quality(bestp, cpal) ||
206  (weed_palette_is_yuv(bestp) && weed_palette_is_rgb(cpal))) {
207  // got better palette, or exact match
208 
209  // prefer exact match on target palette if we have it
210  if (palette != WEED_PALETTE_END && bestp == palette && cpal != palette) continue;
211 
212  // otherwise this is our best palette up to now
213  bestp = cpal;
214 
215  // TODO - try to minimise aspect delta
216  // for now we just go with the smallest size >= target (or largest frame size if none are >= target)
217 
218  if (width >= format->min_size.width && height >= format->min_size.height) {
219  if (format->h_stepping > 0 && format->v_stepping > 0) {
220 #ifdef DEBUG_UNICAP
221  lives_printerr("Can set any size with step %d and %d; min %d x %d, max %d x %d\n",
222  format->h_stepping, format->v_stepping,
223  format->min_size.width, format->min_size.height, format->max_size.width, format->max_size.height);
224 #endif
225  // can set exact size (within stepping limits)
226  format->size.width = (int)(((double)width + (double)format->h_stepping / 2.)
227  / (double)format->h_stepping) * format->h_stepping;
228 
229  format->size.height = (int)(((double)height + (double)format->v_stepping / 2.)
230  / (double)format->v_stepping) * format->v_stepping;
231 
232  if (format->size.width > format->max_size.width) format->size.width = format->max_size.width;
233  if (format->size.height > format->max_size.height) format->size.height = format->max_size.height;
234 
235  if (format->size.width > bestw || format->size.height > besth) {
236  bestw = format->size.width;
237  besth = format->size.height;
238  f = format_count;
239  }
240  } else {
241  // array of sizes supported
242  // step through sizes
243 #ifdef DEBUG_UNICAP
244  lives_printerr("Checking %d array sizes\n", format->size_count);
245 #endif
246 
247  if (format->size_count == 0) {
248  // only one size we can use, this is it...
249 
250  if ((format->size.width > bestw || format->size.height > besth) && (bestw < width || besth < height)) {
251  // this format supports a better size match
252  bestw = format->size.width;
253  besth = format->size.height;
254  f = format_count;
255 #ifdef DEBUG_UNICAP
256  lives_printerr("Size is best so far\n");
257 #endif
258  }
259  continue;
260  }
261 
262  // array of sizes
263  for (i = 0; i < format->size_count; i++) {
264 #ifdef DEBUG_UNICAP
265  lives_printerr("entry %d:%d x %d\n", i, format->sizes[i].width, format->sizes[i].height);
266 #endif
267  if (format->sizes[i].width > bestw && format->sizes[i].height > besth &&
268  (bestw < width || besth < height)) {
269  // this format supports a better size match
270  bestw = format->size.width = format->sizes[i].width;
271  besth = format->size.height = format->sizes[i].height;
272  f = format_count;
273 #ifdef DEBUG_UNICAP
274  lives_printerr("Size is best so far\n");
275 #endif
276  }
277  }
278  }
279  } else {
280  // target is smaller than min width, height
281  if (bestw < format->min_size.width || besth < format->min_size.height) continue; // TODO - minimise aspect delta
282  bestw = format->size.width = format->min_size.width;
283  besth = format->size.height = format->min_size.height;
284  f = format_count;
285  }
286  }
287  }
288 
289  if (f > -1) return (unicap_format_t *)(&formats[f]);
290  return NULL;
291 }
292 
293 
295 
296 static boolean open_vdev_inner(unicap_device_t *device) {
297  // create a virtual clip
298  lives_vdev_t *ldev = (lives_vdev_t *)lives_malloc(sizeof(lives_vdev_t));
299  unicap_format_t formats[MAX_FORMATS];
300  unicap_format_t *format;
301 
302  // open dev
303  unicap_open(&ldev->handle, device);
304 
305  //check return value and take appropriate action
306  if (!ldev->handle) {
307  LIVES_ERROR("vdev input: cannot open device");
308  lives_free(ldev);
309  return FALSE;
310  }
311 
312  unicap_lock_stream(ldev->handle);
313 
314  format = lvdev_get_best_format(formats, ldev, WEED_PALETTE_END, DEF_GEN_WIDTH, DEF_GEN_HEIGHT);
315 
316  if (!format) {
317  LIVES_INFO("No useful formats found");
318  unicap_unlock_stream(ldev->handle);
319  unicap_close(ldev->handle);
320  lives_free(ldev);
321  return FALSE;
322  }
323 
324  if (!(format->buffer_types & UNICAP_BUFFER_TYPE_USER)) {
325  // have to use system buffer type
326  format->buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;
327 
328  // set a callback for new frame
329  unicap_register_callback(ldev->handle, UNICAP_EVENT_NEW_FRAME, (unicap_callback_t) new_frame_cb,
330  (void *) ldev);
331 
332  } else format->buffer_type = UNICAP_BUFFER_TYPE_USER;
333 
334  ldev->buffer_type = format->buffer_type;
335 
336  // ignore YUV subspace for now
337  ldev->current_palette = fourccp_to_weedp(format->fourcc, format->bpp, (int *)&cfile->interlace,
338  &ldev->YUV_sampling, &ldev->YUV_subspace, &ldev->YUV_clamping);
339 
340 #ifdef DEBUG_UNICAP
341  lives_printerr("\nUsing palette with fourcc 0x%x, translated as %s\n", format->fourcc,
342  weed_palette_get_name(ldev->current_palette));
343 #endif
344 
345  if (!SUCCESS(unicap_set_format(ldev->handle, format))) {
346  LIVES_ERROR("Unicap error setting format");
347  unicap_unlock_stream(ldev->handle);
348  unicap_close(ldev->handle);
349  lives_free(ldev);
350  return FALSE;
351  }
352 
353  g_print("ALLX %ld %d %d %d %d\n", format->buffer_size, format->size.width, format->size.height,
355  ldev->current_palette), weed_palette_get_pixels_per_macropixel(ldev->current_palette));
356 
357  if (format->buffer_size != format->size.width * format->size.height * weed_palette_get_bits_per_macropixel(
358  ldev->current_palette) /
359  weed_palette_get_pixels_per_macropixel(ldev->current_palette) / 8) {
360  int wwidth = format->size.width, awidth;
361  int wheight = format->size.height, aheight;
362  // something went wrong setting the size - the buffer is wrongly sized
363 #ifdef DEBUG_UNICAP
364  lives_printerr("Unicap buffer size is wrong, resetting it.\n");
365 #endif
366  // get the size again
367 
368  unicap_get_format(ldev->handle, format);
369  awidth = format->size.width;
370  aheight = format->size.height;
371 
372 #ifdef DEBUG_UNICAP
373  lives_printerr("Wanted frame size %d x %d, got %d x %d\n", wwidth, wheight, awidth, aheight);
374 #endif
375 
376  format->buffer_size = format->size.width * format->size.height * weed_palette_get_bits_per_macropixel(ldev->current_palette) /
377  weed_palette_get_pixels_per_macropixel(ldev->current_palette) / 8;
378  }
379 
380  cfile->hsize = format->size.width;
381  cfile->vsize = format->size.height;
382 
383  cfile->ext_src = ldev;
384  cfile->ext_src_type = LIVES_EXT_SRC_DEVICE;
385 
386  ldev->buffer1.data = (unsigned char *)lives_malloc(format->buffer_size);
387  ldev->buffer1.buffer_size = format->buffer_size;
388 
389  ldev->buffer2.data = (unsigned char *)lives_malloc(format->buffer_size);
390  ldev->buffer2.buffer_size = format->buffer_size;
391 
392  ldev->buffer_ready = 0;
393  ldev->fileno = mainw->current_file;
394 
395  cfile->bpp = format->bpp;
396 
397  unicap_start_capture(ldev->handle);
398 
399  // if it is greyscale, we will add fake U and V planes
400  if (ldev->current_palette == WEED_PALETTE_A8) {
401  ldev->current_palette = WEED_PALETTE_YUV444P;
402  ldev->is_really_grey = TRUE;
403  } else ldev->is_really_grey = FALSE;
404 
405  return TRUE;
406 }
407 
408 
409 void lives_vdev_free(lives_vdev_t *ldev) {
410  if (!ldev) return;
411  unicap_stop_capture(ldev->handle);
412  unicap_unlock_stream(ldev->handle);
413  unicap_close(ldev->handle);
414  if (ldev->buffer1.data) lives_free(ldev->buffer1.data);
415  if (ldev->buffer2.data) lives_free(ldev->buffer2.data);
416 }
417 
418 
419 boolean on_open_vdev_activate(LiVESMenuItem *menuitem, livespointer user_data) {
420  unicap_device_t devices[MAX_DEVICES];
421 
422  LiVESList *devlist = NULL;
423 
424  LiVESWidget *card_dialog;
425 
426  char *fname;
427 
428  int devno = 0;
429 
430  int new_file = mainw->first_free_file;
431  int old_file = mainw->current_file;
432 
433  int response;
434 
435  int dev_count;
436  int status = STATUS_SUCCESS;
437 
438  register int i;
439 
441 
442  status = unicap_reenumerate_devices(&dev_count);
443 
444  if (dev_count == 0) {
446  return FALSE;
447  }
448 
449  // get device list
450  for (i = 0; SUCCESS(status) && (dev_count < MAX_DEVICES); i++) {
451  status = unicap_enumerate_devices(NULL, &devices[i], i);
452  if (!SUCCESS(status)) {
453  if (i == 0) LIVES_INFO("Unicap failed to get any devices");
454  }
455  }
456 
457  if (!user_data) {
458  for (i = 0; i < dev_count; i++) {
459  if (!unicap_is_stream_locked(&devices[i])) {
460  devlist = lives_list_prepend(devlist, devices[i].identifier);
461  }
462  }
463 
464  if (!devlist) {
466  return FALSE;
467  }
468 
469  mainw->fx1_val = 0;
471  card_dialog = create_combo_dialog(1, (livespointer)devlist);
472  response = lives_dialog_run(LIVES_DIALOG(card_dialog));
473  lives_list_free(devlist);
474  if (response == LIVES_RESPONSE_CANCEL) {
475  return FALSE;
476  }
477  lives_widget_destroy(card_dialog);
478  } else {
479  char *device = (char *)user_data;
480  for (i = 0; i < dev_count; i++) {
481  if (!strcmp(device, devices[i].device)) {
482  mainw->fx1_val = i;
483  break;
484  }
485  }
486  }
487 
488  for (i = dev_count - 1; i >= 0; i--) {
489  if (!unicap_is_stream_locked(&devices[i])) {
490  if (mainw->fx1_val == 0) {
491  devno = i;
492  break;
493  }
494  }
495  mainw->fx1_val--;
496  }
497 
498  if (*devices[devno].device) fname = lives_strdup(devices[devno].device);
499  else fname = lives_strdup(devices[devno].identifier);
500 
501  if (!get_new_handle(new_file, fname)) {
502  lives_free(fname);
503  return FALSE;
504  }
505 
506  mainw->current_file = new_file;
507  cfile->clip_type = CLIP_TYPE_VIDEODEV;
508 
509  d_print("");
510 
511  g_print("checking formats for %s\n", fname);
512 
513  if (!open_vdev_inner(&devices[devno])) {
514  d_print(_("Unable to open device %s\n"), fname);
515  lives_free(fname);
516  close_current_file(old_file);
517  return FALSE;
518  }
519 
520  if (cfile->interlace != LIVES_INTERLACE_NONE && prefs->auto_deint) cfile->deinterlace = TRUE;
521  if (!cfile->deinterlace) cfile->deinterlace = mainw->open_deint;
522 
523  cfile->start = cfile->end = cfile->frames = 1;
524  cfile->is_loaded = TRUE;
525  add_to_clipmenu();
526 
527  lives_snprintf(cfile->type, 40, "%s", fname);
528 
529  d_print(_("Opened device %s\n"), devices[devno].identifier);
530 
531  switch_clip(0, new_file, TRUE);
532 
533  lives_free(fname);
534 
535  return TRUE;
536 }
537 
538 #endif
539 
LIVES_IS_PLAYING
#define LIVES_IS_PLAYING
Definition: main.h:840
pixel_data_planar_from_membuf
void pixel_data_planar_from_membuf(void **pixel_data, void *data, size_t size, int palette, boolean contig)
Definition: colourspace.c:2236
lives_free
#define lives_free
Definition: machinestate.h:52
lives_malloc
#define lives_malloc
Definition: machinestate.h:46
CLIP_TYPE_VIDEODEV
@ CLIP_TYPE_VIDEODEV
frames from video device
Definition: main.h:771
lives_widget_destroy
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
Definition: widget-helper.c:1553
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
DEF_GEN_HEIGHT
#define DEF_GEN_HEIGHT
Definition: mainwindow.h:150
lives_clip_t::ext_src
void * ext_src
points to opaque source for non-disk types
Definition: main.h:1040
cfile
#define cfile
Definition: main.h:1833
weed_palette_get_nplanes
LIVES_GLOBAL_INLINE int weed_palette_get_nplanes(int pal)
Definition: colourspace.c:1417
LIVES_ERROR
#define LIVES_ERROR(x)
Definition: main.h:1870
prefs
_prefs * prefs
Definition: preferences.h:847
lives_dialog_run
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
Definition: widget-helper.c:1783
LIVES_INFO
#define LIVES_INFO(x)
Definition: main.h:1854
weed_palette_is_lower_quality
boolean weed_palette_is_lower_quality(int p1, int p2)
Definition: colourspace.c:2143
weed_palette_is_alpha
LIVES_GLOBAL_INLINE boolean weed_palette_is_alpha(int pal)
Definition: colourspace.c:1427
lives_alarm_clear
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
TICKS_PER_SECOND_DBL
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
add_to_clipmenu
void add_to_clipmenu(void)
Definition: gui.c:4512
videodev.h
lives_alarm_t
int lives_alarm_t
Definition: mainwindow.h:696
TRUE
#define TRUE
Definition: videoplugin.h:59
weed_palette_is_yuv
LIVES_GLOBAL_INLINE boolean weed_palette_is_yuv(int pal)
Definition: colourspace.c:1457
weed_palette_is_rgb
LIVES_GLOBAL_INLINE boolean weed_palette_is_rgb(int pal)
Definition: colourspace.c:1448
callbacks.h
do_locked_in_vdevs_error
LIVES_GLOBAL_INLINE void do_locked_in_vdevs_error(void)
Definition: dialogs.c:4404
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
close_current_file
void close_current_file(int file_to_switch_to)
close current file, and try to switch to file_to_switch_to
Definition: main.c:9373
mainwindow::blend_file
int blend_file
background clip details
Definition: mainwindow.h:976
create_empty_pixel_data
boolean create_empty_pixel_data(weed_layer_t *layer, boolean black_fill, boolean may_contig)
creates pixel data for layer
Definition: colourspace.c:9058
switch_clip
void switch_clip(int type, int newclip, boolean force)
Definition: callbacks.c:6900
create_combo_dialog
LiVESWidget * create_combo_dialog(int type, LiVESList *list)
Definition: interface.c:3088
interface.h
mainwindow::playing_file
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
mainwindow::first_free_file
int first_free_file
Definition: mainwindow.h:728
do_no_in_vdevs_error
LIVES_GLOBAL_INLINE void do_no_in_vdevs_error(void)
Definition: dialogs.c:4399
palette
_palette * palette
interface colour settings
Definition: main.c:101
error
error("LSD_RANDFUNC(ptr, size) must be defined")
weed_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
lives_clip_t::hsize
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
Definition: main.h:896
lives_memcpy
#define lives_memcpy
Definition: machinestate.h:55
lives_alarm_check
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
DEF_GEN_WIDTH
#define DEF_GEN_WIDTH
Definition: mainwindow.h:149
main.h
_prefs::sleep_time
int sleep_time
Definition: preferences.h:176
mainw
mainwindow * mainw
Definition: main.c:103
LIVES_EXT_SRC_DEVICE
#define LIVES_EXT_SRC_DEVICE
Definition: main.h:1048
_prefs::auto_deint
boolean auto_deint
Definition: preferences.h:302
lives_clip_t::vsize
int vsize
frame height (vertical) in pixels
Definition: main.h:897
LIVES_INTERLACE_NONE
@ LIVES_INTERLACE_NONE
Definition: main.h:791
WEED_LEAF_HOST_PIXEL_DATA_CONTIGUOUS
#define WEED_LEAF_HOST_PIXEL_DATA_CONTIGUOUS
Definition: colourspace.h:20
lives_clip_t
corresponds to one clip in the GUI
Definition: main.h:877
mainwindow::open_deint
boolean open_deint
Definition: mainwindow.h:907
effects-weed.h
mainwindow::fx1_val
double fx1_val
Definition: mainwindow.h:1049
weed_palette_get_name
const char * weed_palette_get_name(int pal)
Definition: weed-effects-utils.c:703
FALSE
#define FALSE
Definition: videoplugin.h:60
weed_palette_get_pixels_per_macropixel
LIVES_GLOBAL_INLINE int weed_palette_get_pixels_per_macropixel(int pal)
Definition: colourspace.c:1403
lives_alarm_set
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
Definition: utils.c:1643
_
#define _(String)
Definition: support.h:44
weed_palette_get_bits_per_macropixel
LIVES_GLOBAL_INLINE int weed_palette_get_bits_per_macropixel(int pal)
Definition: colourspace.c:1411
lives_widget_context_update
boolean lives_widget_context_update(void)
Definition: widget-helper.c:11878
get_new_handle
boolean get_new_handle(int index, const char *name)
Definition: saveplay.c:3821