LiVES  3.2.0
saveplay.c
Go to the documentation of this file.
1 // saveplay.c
2 // LiVES (lives-exe)
3 // (c) G. Finch 2003 - 2018 (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 <fcntl.h>
8 #include <glib.h>
9 
10 #include "main.h"
11 #include "callbacks.h"
12 #include "resample.h"
13 #include "effects.h"
14 #include "audio.h"
15 #include "htmsocket.h"
16 #include "cvirtual.h"
17 #include "interface.h"
18 
19 boolean _start_playback(livespointer data) {
20  int new_file, old_file;
21  int play_type = LIVES_POINTER_TO_INT(data);
22  if (play_type != 8 && mainw->noswitch) return TRUE;
23  switch (play_type) {
24  case 8: case 6: case 0:
26  play_all(play_type == 8);
27  if (play_type == 6) {
29  // need to set this after playback ends; this stops the key from being activated (again) in effects.c
30  // also stops the (now defunct instance being unreffed)
32  }
33  break;
34  case 1:
36  if (!mainw->multitrack) play_sel();
38  break;
39  case 2:
41  mainw->play_start = 1;
42  mainw->play_end = INT_MAX;
43  play_file();
44  break;
45  case 3:
47  mainw->osc_auto = 1;
48  play_all(FALSE);
49  mainw->osc_auto = 0;
50  break;
51  case 4:
53  mainw->osc_auto = 1;
54  if (!mainw->multitrack) play_sel();
56  mainw->osc_auto = 0;
57  break;
58  case 5:
60  play_file();
61  mainw->loop = mainw->oloop;
63 
64  if (mainw->pre_play_file > 0) {
66  } else {
67  mainw->current_file = -1;
69  }
73  }
74  break;
75  case 7:
77  new_file = mainw->current_file;
78  old_file = mainw->pre_play_file;
79  play_file();
80  if (mainw->current_file != old_file && mainw->current_file != new_file)
81  old_file = mainw->current_file; // we could have rendered to a new file
82  mainw->current_file = new_file;
83  // close this temporary clip
84  close_current_file(old_file);
85  mainw->pre_play_file = -1;
86  break;
87  default:
89  break;
90  }
91  return FALSE;
92 }
93 
94 LIVES_GLOBAL_INLINE boolean start_playback(int type) {return _start_playback(LIVES_INT_TO_POINTER(type));}
95 
97  lives_idle_add(_start_playback, LIVES_INT_TO_POINTER(type));
98  //lives_proc_thread_create(0, (lives_funcptr_t)_start_playback, 0, "i", type);
99  //_start_playback(LIVES_INT_TO_POINTER(type));
100 }
101 
102 
103 boolean save_clip_values(int which) {
104  lives_clip_t *sfile = mainw->files[which];
105  char *lives_header_new;
106  boolean all_ok = FALSE;
107  int asigned, endian;
108  int retval;
109 
110  if (which == 0 || which == mainw->scrap_file || which == mainw->ascrap_file) return TRUE;
111 
113 
114  asigned = !(sfile->signed_endian & AFORM_UNSIGNED);
115  endian = sfile->signed_endian & AFORM_BIG_ENDIAN;
116  if (which == mainw->ascrap_file)
117  lives_header_new = lives_build_filename(prefs->workdir, sfile->handle, LIVES_ACLIP_HEADER_NEW, NULL);
118  else
119  lives_header_new = lives_build_filename(prefs->workdir, sfile->handle, LIVES_CLIP_HEADER_NEW, NULL);
120 
121  do {
122  THREADVAR(com_failed) = THREADVAR(write_failed) = FALSE;
123  mainw->clip_header = fopen(lives_header_new, "w");
124  if (!mainw->clip_header) {
125  retval = do_write_failed_error_s_with_retry(lives_header_new, lives_strerror(errno));
126  if (retval == LIVES_RESPONSE_CANCEL) {
129  lives_free(lives_header_new);
130  return FALSE;
131  }
132  } else {
134  do {
135  retval = 0;
136  if (!save_clip_value(which, CLIP_DETAILS_HEADER_VERSION, &sfile->header_version)) break;
137  if (!save_clip_value(which, CLIP_DETAILS_BPP, &sfile->bpp)) break;
138  if (sfile->clip_type == CLIP_TYPE_FILE && sfile->ext_src) {
139  lives_clip_data_t *cdata = ((lives_decoder_t *)sfile->ext_src)->cdata;
140  double dfps = (double)cdata->fps;
141  if (!save_clip_value(which, CLIP_DETAILS_FPS, &dfps)) break;
142  if (!save_clip_value(which, CLIP_DETAILS_PB_FPS, &sfile->fps)) break;
143  } else {
144  if (!save_clip_value(which, CLIP_DETAILS_FPS, &sfile->fps)) break;
145  if (!save_clip_value(which, CLIP_DETAILS_PB_FPS, &sfile->pb_fps)) break;
146  }
147  if (!save_clip_value(which, CLIP_DETAILS_WIDTH, &sfile->hsize)) break;
148  if (!save_clip_value(which, CLIP_DETAILS_HEIGHT, &sfile->vsize)) break;
149  if (!save_clip_value(which, CLIP_DETAILS_INTERLACE, &sfile->interlace)) break;
150  if (!save_clip_value(which, CLIP_DETAILS_UNIQUE_ID, &sfile->unique_id)) break;
151  if (!save_clip_value(which, CLIP_DETAILS_ARATE, &sfile->arps)) break;
152  if (!save_clip_value(which, CLIP_DETAILS_PB_ARATE, &sfile->arate)) break;
153  if (!save_clip_value(which, CLIP_DETAILS_ACHANS, &sfile->achans)) break;
154  if (sfile->achans > 0) {
155  if (!save_clip_value(which, CLIP_DETAILS_ASIGNED, &asigned)) break;
156  if (!save_clip_value(which, CLIP_DETAILS_AENDIAN, &endian)) break;
157  }
158  if (!save_clip_value(which, CLIP_DETAILS_ASAMPS, &sfile->asampsize)) break;
159  if (!save_clip_value(which, CLIP_DETAILS_FRAMES, &sfile->frames)) break;
160  if (!save_clip_value(which, CLIP_DETAILS_GAMMA_TYPE, &sfile->gamma_type)) break;
161  if (!save_clip_value(which, CLIP_DETAILS_TITLE, sfile->title)) break;
162  if (!save_clip_value(which, CLIP_DETAILS_AUTHOR, sfile->author)) break;
163  if (!save_clip_value(which, CLIP_DETAILS_COMMENT, sfile->comment)) break;
164  if (!save_clip_value(which, CLIP_DETAILS_PB_FRAMENO, &sfile->frameno)) break;
165  if (!save_clip_value(which, CLIP_DETAILS_CLIPNAME, sfile->name)) break;
166  if (!save_clip_value(which, CLIP_DETAILS_FILENAME, sfile->file_name)) break;
167  if (!save_clip_value(which, CLIP_DETAILS_KEYWORDS, sfile->keywords)) break;
168  if (sfile->clip_type == CLIP_TYPE_FILE && sfile->ext_src) {
169  lives_decoder_t *dplug = (lives_decoder_t *)sfile->ext_src;
170  if (!save_clip_value(which, CLIP_DETAILS_DECODER_NAME, (void *)dplug->decoder->name)) break;
171  }
172  all_ok = TRUE;
173  } while (FALSE);
174 
175  fclose(mainw->clip_header);
176 
177  if (!all_ok) {
178  retval = do_write_failed_error_s_with_retry(lives_header_new, NULL);
179  } else {
180  char *lives_header;
181  if (which == mainw->ascrap_file)
182  lives_header = lives_build_filename(prefs->workdir, sfile->handle, LIVES_ACLIP_HEADER, NULL);
183  else
184  lives_header = lives_build_filename(prefs->workdir, sfile->handle, LIVES_CLIP_HEADER, NULL);
185  // TODO - check the sizes before and after
186  lives_cp(lives_header_new, lives_header);
187  lives_free(lives_header);
188  if (THREADVAR(com_failed) || THREADVAR(write_failed)) {
189  retval = do_write_failed_error_s_with_retry(lives_header_new, NULL);
190  } else lives_rm(lives_header_new);
191  }
192  }
193  } while (retval == LIVES_RESPONSE_RETRY);
194 
197 
198  lives_free(lives_header_new);
199  mainw->clip_header = NULL;
200 
201  if (retval == LIVES_RESPONSE_CANCEL) return FALSE;
202 
203  return TRUE;
204 }
205 
206 
207 boolean read_file_details(const char *file_name, boolean is_audio, boolean is_img) {
208  // get preliminary details
209 
210  // is_audio set to TRUE prevents us from checking for images, and deleting the (existing) first frame
211  // therefore it is IMPORTANT to set it when loading new audio for an existing clip !
212 
213  // is_img will force unpacking of img into frames and return the count
214 
215  char *tmp, *com = lives_strdup_printf("%s get_details \"%s\" \"%s\" \"%s\" %d", prefs->backend_sync, cfile->handle,
216  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)),
218  is_audio ? 2 : is_img ? 4 : 0);
219  lives_free(tmp);
221  lives_free(com);
222  if (THREADVAR(com_failed)) {
223  THREADVAR(com_failed) = FALSE;
224  return FALSE;
225  }
226  return TRUE;
227 }
228 
229 
230 const char *get_deinterlace_string(void) {
231  if (mainw->open_deint) {
232  if (USE_MPV) return "--deinterlace=yes";
233  return "-vf pp=ci";
234  } else return "";
235 }
236 
237 
238 ulong deduce_file(const char *file_name, double start, int end) {
239  // this is a utility function to deduce whether we are dealing with a file,
240  // a selection, a backup, or a location
241  char short_file_name[PATH_MAX];
242  ulong uid;
243  mainw->img_concat_clip = -1;
244 
245  if (lives_strrstr(file_name, "://") && strncmp(file_name, "dvd://", 6)) {
247  uid = open_file(file_name);
249  } else {
250  lives_snprintf(short_file_name, PATH_MAX, "%s", file_name);
251  if (!(strcmp(file_name + strlen(file_name) - 4, "."LIVES_FILE_EXT_BACKUP))) {
252  uid = restore_file(file_name);
253  } else {
254  uid = open_file_sel(file_name, start, end);
255  }
256  }
257  return uid;
258 }
259 
260 
261 ulong open_file(const char *file_name) {
262  // this function should be called to open a whole file
263  return open_file_sel(file_name, 0., 0);
264 }
265 
266 
267 static boolean rip_audio_cancelled(int old_file, weed_plant_t *mt_pb_start_event,
268  boolean mt_has_audio_file) {
269 
270  if (mainw->cancelled == CANCEL_KEEP) {
271  // user clicked "enough"
273  return TRUE;
274  }
275 
277 
278  d_print("\n");
280  close_current_file(old_file);
281 
282  if (mainw->multitrack) {
283  mainw->multitrack->pb_start_event = mt_pb_start_event;
284  mainw->multitrack->has_audio_file = mt_has_audio_file;
285  }
286 
287  lives_freep((void **)&mainw->file_open_params);
289  return FALSE;
290 }
291 
292 
293 void pad_init_silence(void) {
294  cfile->undo1_dbl = 0.;
295  cfile->undo2_dbl = CLIP_TOTAL_TIME(mainw->current_file) - cfile->laudio_time;
296  cfile->undo_arate = cfile->arate;
297  cfile->undo_signed_endian = cfile->signed_endian;
298  cfile->undo_achans = cfile->achans;
299  cfile->undo_asampsize = cfile->asampsize;
300  cfile->undo_arps = cfile->arps;
301  d_print(_("Auto padding with %.4f seconds of silence at start..."), cfile->undo2_dbl);
302  if (on_ins_silence_activate(NULL, NULL)) d_print_done();
303  else d_print("\n");
304 }
305 
306 
307 #define AUDIO_FRAMES_TO_READ 100
308 
309 ulong open_file_sel(const char *file_name, double start, int frames) {
310  LiVESResponseType response;
311  char msg[256], loc[PATH_MAX];
312  char *tmp = NULL;
313  char *isubfname = NULL;
314  char *fname = lives_strdup(file_name), *msgstr;
315  char *com, *what;
316 
317  int withsound = 1;
318  int old_file = mainw->current_file;
319  int new_file = old_file;
320 
321  int achans, arate, arps, asampsize;
322  int current_file;
323  int extra_frames = 0;
324  int probed_achans = 0;
325 
326  boolean mt_has_audio_file = TRUE;
327 
328  const lives_clip_data_t *cdata;
329 
330  weed_plant_t *mt_pb_start_event = NULL;
331 
332  if (!lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
333  do_no_loadfile_error(fname);
334  lives_free(fname);
335  return 0;
336  }
337 
338  if (old_file == -1 || !CURRENT_CLIP_IS_VALID || !cfile->opening) {
339  new_file = mainw->first_free_file;
340 
341  if (!get_new_handle(new_file, fname)) {
342  lives_free(fname);
343  return 0;
344  }
345  lives_free(fname);
346 
349 
350  if (frames == 0) {
351  com = lives_strdup_printf(_("Opening %s"), file_name);
352  } else {
353  com = lives_strdup_printf(_("Opening %s start time %.2f sec. frames %d"), file_name, start, frames);
354  }
355  d_print(""); // exhaust "switch" message
356 
357  d_print(com);
358  lives_free(com);
359 
360  if (!mainw->save_with_sound) {
361  d_print(_(" without sound"));
362  withsound = 0;
363  }
364 
365  mainw->current_file = new_file;
366 
368  read_file_details(file_name, FALSE, FALSE);
369  lives_rm(cfile->info_file);
370  if (THREADVAR(com_failed)) return 0;
371 
372  if (*mainw->msg) add_file_info(cfile->handle, FALSE);
373 
374  if (mainw->multitrack) {
375  // set up for opening preview
376  mt_pb_start_event = mainw->multitrack->pb_start_event;
377  mt_has_audio_file = mainw->multitrack->has_audio_file;
378  mainw->multitrack->pb_start_event = NULL;
379  mainw->multitrack->has_audio_file = TRUE;
380  }
381 
383  if ((!strcmp(cfile->type, LIVES_IMAGE_TYPE_JPEG) || !strcmp(cfile->type, LIVES_IMAGE_TYPE_PNG))) {
384  read_file_details(file_name, FALSE, TRUE);
385  add_file_info(cfile->handle, FALSE);
386  if (cfile->frames == 0) {
387  d_print_failed();
388  close_current_file(old_file);
389  if (mainw->multitrack) {
390  mainw->multitrack->pb_start_event = mt_pb_start_event;
391  mainw->multitrack->has_audio_file = mt_has_audio_file;
392  }
393  lives_freep((void **)&mainw->file_open_params);
395  return 0;
396  }
397  goto img_load;
398  }
399 
400  if (prefs->instant_open && !mainw->opening_loc) {
401  // cd to clip directory - so decoder plugins can write temp files
402  char *ppath = lives_build_filename(prefs->workdir, cfile->handle, NULL);
403  char *cwd = lives_get_current_dir();
404 
405  if (!mainw->decoders_loaded) {
408  }
409 
410  lives_chdir(ppath, FALSE);
411  lives_free(ppath);
412 
414 
415  lives_chdir(cwd, FALSE);
416  lives_free(cwd);
417 
418  if (cfile->ext_src) {
419  lives_decoder_t *dplug = (lives_decoder_t *)cfile->ext_src;
420  cfile->opening = TRUE;
421  cfile->clip_type = CLIP_TYPE_FILE;
422  cfile->img_type = IMG_TYPE_BEST; // override the pref
423 
424  if (cdata->frame_width > 0) {
425  cfile->hsize = cdata->frame_width;
426  cfile->vsize = cdata->frame_height;
427  } else {
428  cfile->hsize = cdata->width;
429  cfile->vsize = cdata->height;
430  }
431 
432  if (cfile->frames > cdata->nframes && cfile->frames != 123456789) {
433  extra_frames = cfile->frames - cdata->nframes;
434  }
435  cfile->frames = cdata->nframes;
436  if (!*cfile->author)
437  lives_snprintf(cfile->author, 1024, "%s", cdata->author);
438  if (!*cfile->title)
439  lives_snprintf(cfile->title, 1024, "%s", cdata->title);
440  if (!*cfile->comment)
441  lives_snprintf(cfile->comment, 1024, "%s", cdata->comment);
442 
443  if (frames > 0 && cfile->frames > frames) {
444  cfile->frames = frames;
445  extra_frames = 0;
446  }
447 
448  cfile->start = 1;
449  cfile->end = cfile->frames;
450 
451  what = (_("creating the frame index for the clip"));
452 
453  do {
454  response = LIVES_RESPONSE_OK;
455  create_frame_index(mainw->current_file, TRUE, cfile->fps * (start == 0 ? 0 : start - 1),
456  frames == 0 ? cfile->frames : frames);
457  if (!cfile->frame_index) {
458  response = do_memory_error_dialog(what, (frames == 0 ? cfile->frames : frames) * 4);
459  }
460  } while (response == LIVES_RESPONSE_RETRY);
461  lives_free(what);
462  if (response == LIVES_RESPONSE_CANCEL) {
463  return 0;
464  }
465  probed_achans = cfile->achans;
466  cfile->arate = cfile->arps = cdata->arate;
467  cfile->achans = cdata->achans;
468  cfile->asampsize = cdata->asamps;
469 
470  cfile->signed_endian = get_signed_endian(cdata->asigned, capable->byte_order == LIVES_LITTLE_ENDIAN);
471 
472  if (cfile->achans > 0 && (dplug->decoder->rip_audio) && withsound == 1) {
473  // call rip_audio() in the decoder plugin
474  // the plugin gets a chance to do any internal cleanup in rip_audio_cleanup()
475 
476  int64_t stframe = cfile->fps * start + .5;
477  int64_t maxframe = (stframe + (frames == 0)) ? cfile->frames : frames;
478  int64_t nframes = AUDIO_FRAMES_TO_READ;
479  char *afile = get_audio_file_name(mainw->current_file, TRUE);
480 
481  msgstr = lives_strdup_printf(_("Opening audio for %s"), file_name);
482 
483  if (!LIVES_IS_PLAYING) resize(1);
484 
486 
487  if (!LIVES_IS_PLAYING) {
489  do_threaded_dialog(msgstr, TRUE);
491  }
492 
493  do {
494  if (stframe + nframes > maxframe) nframes = maxframe - stframe;
495  if (nframes <= 0) break;
496  (dplug->decoder->rip_audio)(cdata, afile, stframe, nframes, NULL);
498  stframe += nframes;
499  } while (mainw->cancelled == CANCEL_NONE);
500 
501  if (dplug->decoder->rip_audio_cleanup) {
502  (dplug->decoder->rip_audio_cleanup)(cdata);
503  }
504 
505  if (mainw->cancelled != CANCEL_NONE) {
506  if (!rip_audio_cancelled(old_file, mt_pb_start_event, mt_has_audio_file)) {
507  lives_free(afile);
508  return 0;
509  }
510  }
512  lives_free(msgstr);
513  lives_free(afile);
514  } else {
515  cfile->arate = 0.;
516  cfile->achans = cfile->asampsize = 0;
517  }
518 
519  cfile->fps = cfile->pb_fps = cdata->fps;
520  d_print("\n");
521 
522  if (cfile->achans == 0 && probed_achans > 0 && withsound == 1) {
523  // plugin returned no audio, try with mplayer / mpv
524  if (probed_achans > MAX_ACHANS) {
525  probed_achans = MAX_ACHANS;
526  d_print(_("Forcing audio channels to %d\n"), MAX_ACHANS);
527  }
528 
529  if (!mainw->file_open_params) {
530 #if 1
531  mainw->file_open_params = lives_strdup("alang eng");
532 #else
533  mainw->file_open_params = lives_strdup("");
534 #endif
535  }
536  com = lives_strdup_printf("%s open \"%s\" \"%s\" %d %s:%s %.2f %d %d \"%s\"", prefs->backend, cfile->handle,
537  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)), -1,
538  prefs->image_ext, get_image_ext_for_type(IMG_TYPE_BEST), start, frames, probed_achans,
540 
541  lives_free(tmp);
542 
543  lives_rm(cfile->info_file);
544  lives_system(com, FALSE);
545  lives_free(com);
546 
547  // if we have a quick-opening file, display the first and last frames now
548  // for some codecs this can be helpful since we can locate the last frame while audio is loading
549  if (cfile->clip_type == CLIP_TYPE_FILE && !LIVES_IS_PLAYING) resize(1);
550 
551  mainw->effects_paused = FALSE; // set to TRUE if user clicks "Enough"
552 
553  msgstr = lives_strdup_printf(_("Opening audio"), file_name);
554  if (!do_progress_dialog(TRUE, TRUE, msgstr)) {
555  // error or user cancelled or switched to another clip
556  lives_free(msgstr);
557 
558  cfile->opening_frames = -1;
559 
560  if (mainw->multitrack) {
561  mainw->multitrack->pb_start_event = mt_pb_start_event;
562  mainw->multitrack->has_audio_file = mt_has_audio_file;
563  }
564 
568  return 0;
569  }
570 
571  // cancelled
572  if (mainw->cancelled != CANCEL_ERROR) {
574  }
575 
576  lives_freep((void **)&mainw->file_open_params);
577  close_current_file(old_file);
579  if (mainw->error) {
581  mainw->error = 0;
582  clear_mainw_msg();
583  }
584  sensitize();
585  return 0;
586  }
587  lives_free(msgstr);
588 
589  cfile->opening = FALSE;
590 
592  if (mainw->error == 0) add_file_info(cfile->handle, TRUE);
593  mainw->error = 0;
595 
596  if (prefs->auto_trim_audio) {
597  if ((cdata->sync_hint & SYNC_HINT_VIDEO_PAD_START) && cdata->video_start_time <= 1.) {
598  // pad with blank frames at start
599  int st_extra_frames = cdata->video_start_time * cfile->fps;
600  insert_blank_frames(mainw->current_file, st_extra_frames, 0, WEED_PALETTE_RGB24);
601  cfile->video_time += st_extra_frames / cfile->fps;
602  extra_frames -= st_extra_frames;
603  showclipimgs();
604  if (!mainw->multitrack)
606  }
607 
608  if ((cfile->frames + extra_frames) / cfile->fps > cfile->laudio_time) {
609  extra_frames = (cfile->laudio_time - (double)cfile->frames / cfile->fps) * cfile->fps;
610  }
611 
612  if (extra_frames > 0 || ((cdata->sync_hint & SYNC_HINT_VIDEO_PAD_END)
613  && (double)cfile->frames / cfile->fps < cfile->laudio_time)) {
614  // pad with blank frames at end
615  if (cdata->sync_hint & SYNC_HINT_VIDEO_PAD_END) {
616  int xextra_frames = (cfile->laudio_time - (double)cfile->frames / cfile->fps) * cfile->fps;
617  if (xextra_frames > extra_frames) extra_frames = xextra_frames;
618  }
619  insert_blank_frames(mainw->current_file, extra_frames, cfile->frames, WEED_PALETTE_RGB24);
620  cfile->video_time += extra_frames / cfile->fps;
621  load_end_image(cfile->end);
622  }
623  if (cfile->laudio_time > cfile->video_time + AV_TRACK_MIN_DIFF && cfile->frames > 0) {
624  if (cdata->sync_hint & SYNC_HINT_AUDIO_TRIM_START) {
625  cfile->undo1_dbl = 0.;
626  cfile->undo2_dbl = cfile->laudio_time - cfile->video_time;
627  d_print(_("Auto trimming %.4f seconds of audio at start..."), cfile->undo2_dbl);
628  if (on_del_audio_activate(NULL, NULL)) d_print_done();
629  else d_print("\n");
630  cfile->changed = FALSE;
631  }
632  }
633  if (cfile->laudio_time > cfile->video_time + AV_TRACK_MIN_DIFF && cfile->frames > 0) {
634  if (cdata->sync_hint & SYNC_HINT_AUDIO_TRIM_END) {
635  cfile->end = cfile->frames;
636  d_print(_("Auto trimming %.4f seconds of audio at end..."), cfile->laudio_time - cfile->video_time);
637  if (on_trim_audio_activate(NULL, LIVES_INT_TO_POINTER(0))) d_print_done();
638  else d_print("\n");
639  cfile->changed = FALSE;
640  }
641  }
642  if (!mainw->effects_paused && cfile->afilesize > 0 && cfile->achans > 0
643  && CLIP_TOTAL_TIME(mainw->current_file) > cfile->laudio_time + AV_TRACK_MIN_DIFF) {
644  if (cdata->sync_hint & SYNC_HINT_AUDIO_PAD_START) {
646  cfile->changed = FALSE;
647  }
648  if (cdata->sync_hint & SYNC_HINT_AUDIO_PAD_END) {
649  cfile->undo1_dbl = cfile->laudio_time;
650  cfile->undo2_dbl = CLIP_TOTAL_TIME(mainw->current_file) - cfile->laudio_time;
651  cfile->undo_arate = cfile->arate;
652  cfile->undo_signed_endian = cfile->signed_endian;
653  cfile->undo_achans = cfile->achans;
654  cfile->undo_asampsize = cfile->asampsize;
655  cfile->undo_arps = cfile->arps;
656  d_print(_("Auto padding with %.4f seconds of silence at end..."), cfile->undo2_dbl);
657  if (on_ins_silence_activate(NULL, NULL)) d_print_done();
658  else d_print("\n");
659  cfile->changed = FALSE;
660  // *INDENT-OFF*
661  }}}}
662  // *INDENT-ON*
663 
664  get_mime_type(cfile->type, 40, cdata);
666  }
667  }
668 
669  if (cfile->ext_src) {
670  if (mainw->open_deint) {
671  // override what the plugin says
672  cfile->deinterlace = TRUE;
673  cfile->interlace = LIVES_INTERLACE_TOP_FIRST; // guessing
675  if (THREADVAR(com_failed) || THREADVAR(write_failed)) do_header_write_error(mainw->current_file);
676  }
677  } else {
678  // be careful, here we switch from mainw->opening_loc to cfile->opening_loc
679  if (mainw->opening_loc) {
680  cfile->opening_loc = TRUE;
682  } else {
683  if (cfile->f_size > prefs->warn_file_size * 1000000. && mainw->is_ready && frames == 0) {
684  char *fsize_ds = lives_format_storage_space_string((uint64_t)cfile->f_size);
685  char *warn = lives_strdup_printf(
686  _("\nLiVES cannot Instant Open this file, it may take some time to load.\n"
687  "Are you sure you wish to continue ?"),
688  fsize_ds);
689  lives_free(fsize_ds);
691  lives_free(warn);
692  close_current_file(old_file);
693  if (mainw->multitrack) {
694  mainw->multitrack->pb_start_event = mt_pb_start_event;
695  mainw->multitrack->has_audio_file = mt_has_audio_file;
696  }
698  return 0;
699  }
700  lives_free(warn);
701  d_print(_(" - please be patient."));
702 
703  }
704  d_print("\n");
705 #if defined DEBUG
706  g_print("open_file: dpd in\n");
707 #endif
708  }
709  }
710 
711  // set undo_start and undo_end for preview
712  cfile->undo_start = 1;
713  cfile->undo_end = cfile->frames;
714 
715  if (cfile->achans > 0) {
716  cfile->opening_audio = TRUE;
717  }
718 
719  // these will get reset as we have no audio file yet, so preserve them
720  achans = cfile->achans;
721  arate = cfile->arate;
722  arps = cfile->arps;
723  asampsize = cfile->asampsize;
724  cfile->old_frames = cfile->frames;
725  cfile->frames = 0;
726 
727  // we need this FALSE here, otherwise we will switch straight back here...
728  cfile->opening = FALSE;
729 
730  // force a resize
731  current_file = mainw->current_file;
732 
733  cfile->opening = TRUE;
734  cfile->achans = achans;
735  cfile->arate = arate;
736  cfile->arps = arps;
737  cfile->asampsize = asampsize;
738  cfile->frames = cfile->old_frames;
739 
740  if (cfile->frames <= 0) {
741  cfile->undo_end = cfile->frames = 123456789;
742  }
743  if (cfile->hsize * cfile->vsize == 0) {
744  cfile->frames = 0;
745  }
746 
748 
749  add_to_clipmenu();
750  set_main_title(cfile->file_name, 0);
751 
753 
754  if (!cfile->ext_src) {
755  if (!mainw->file_open_params) mainw->file_open_params = lives_strdup("");
756 
757  tmp = lives_strconcat(mainw->file_open_params, get_deinterlace_string(), NULL);
759  mainw->file_open_params = tmp;
760 
761  if (cfile->achans > MAX_ACHANS) {
762  cfile->achans = MAX_ACHANS;
763  d_print(_("Forcing audio channels to %d\n"), MAX_ACHANS);
764  }
765 
766  com = lives_strdup_printf("%s open \"%s\" \"%s\" %d %s:%s %.2f %d %d \"%s\"", prefs->backend, cfile->handle,
767  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)), withsound,
768  prefs->image_ext, get_image_ext_for_type(IMG_TYPE_BEST), start, frames, cfile->achans,
770 
771  lives_rm(cfile->info_file);
772  lives_system(com, FALSE);
773  lives_free(com);
774  lives_free(tmp);
775 
776  if (mainw->toy_type == LIVES_TOY_TV) {
777  // for LiVES TV we do an auto-preview
778  mainw->play_start = cfile->start = cfile->undo_start;
779  mainw->play_end = cfile->end = cfile->undo_end;
780  mainw->preview = TRUE;
781  do {
782  desensitize();
784  on_playsel_activate(NULL, NULL);
785  } while (mainw->cancelled == CANCEL_KEEP_LOOPING);
786  mainw->preview = FALSE;
787  on_toy_activate(NULL, LIVES_INT_TO_POINTER(LIVES_TOY_NONE));
788  lives_freep((void **)&mainw->file_open_params);
791  return 0;
792  }
793  }
794 
795  // loading:
796 
797  // 'entry point' when we switch back
798 
799  // spin until loading is complete
800  // afterwards, mainw->msg will contain file details
801  cfile->progress_start = cfile->progress_end = 0;
802 
803  // (also check for cancel)
804  msgstr = lives_strdup_printf(_("Opening %s"), file_name);
805 
806  if (!cfile->ext_src && mainw->toy_type != LIVES_TOY_TV) {
809  if (!do_progress_dialog(TRUE, TRUE, msgstr)) {
810  // user cancelled or switched to another clip
812  mainw->disk_mon = 0;
813 
814  lives_free(msgstr);
816 
820  return 0;
821  }
822 
823  // cancelled
824  // clean up our temp files
825  if (IS_VALID_CLIP(current_file)) mainw->current_file = current_file;
827  lives_freep((void **)&mainw->file_open_params);
828  close_current_file(old_file);
829  if (mainw->multitrack) {
830  mainw->multitrack->pb_start_event = mt_pb_start_event;
831  mainw->multitrack->has_audio_file = mt_has_audio_file;
832  }
834 
835  // mainw->error is TRUE if we could not open the file
836  if (mainw->error) {
837  d_print_failed();
839  }
840  if (!mainw->multitrack)
842  showclipimgs();
843  return 0;
844  }
846  mainw->disk_mon = 0;
847  }
848  lives_free(msgstr);
849  }
850 
851  if (cfile->ext_src && cfile->achans > 0) {
852  char *afile = get_audio_file_name(mainw->current_file, TRUE);
853  char *ofile = get_audio_file_name(mainw->current_file, FALSE);
854  rename(afile, ofile);
855  lives_free(afile);
856  lives_free(ofile);
857  }
858 
859  cfile->opening = cfile->opening_audio = cfile->opening_only_audio = FALSE;
860  cfile->opening_frames = -1;
862 
863 #if defined DEBUG
864  g_print("Out of dpd\n");
865 #endif
866 
867  if (mainw->multitrack) {
868  mainw->multitrack->pb_start_event = mt_pb_start_event;
869  mainw->multitrack->has_audio_file = mt_has_audio_file;
870  }
871 
872  // mainw->error is TRUE if we could not open the file
873  if (mainw->error) {
875  d_print_failed();
876  close_current_file(old_file);
877  lives_freep((void **)&mainw->file_open_params);
879  return 0;
880  }
881 
882  if (cfile->opening_loc) {
883  cfile->changed = TRUE;
884  cfile->opening_loc = FALSE;
885  } else {
886  if (prefs->autoload_subs) {
887  char filename[512];
888  char *subfname;
890 
891  lives_snprintf(filename, 512, "%s", file_name);
892  get_filename(filename, FALSE); // strip extension
893  isubfname = lives_strdup_printf("%s.%s", filename, LIVES_FILE_EXT_SRT);
894  if (lives_file_test(isubfname, LIVES_FILE_TEST_EXISTS)) {
895  subfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SRT, NULL);
896  subtype = SUBTITLE_TYPE_SRT;
897  } else {
898  lives_free(isubfname);
899  isubfname = lives_strdup_printf("%s.%s", filename, LIVES_FILE_EXT_SUB);
900  if (lives_file_test(isubfname, LIVES_FILE_TEST_EXISTS)) {
901  subfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SUB, NULL);
902  subtype = SUBTITLE_TYPE_SUB;
903  }
904  }
905  if (subtype != SUBTITLE_TYPE_NONE) {
906  lives_cp(isubfname, subfname);
907  if (!THREADVAR(com_failed))
908  subtitles_init(cfile, subfname, subtype);
909  lives_free(subfname);
910  } else {
911  lives_freep((void **)&isubfname);
912  }
913  }
914  }
915 
916  // now file should be loaded...get full details
917  if (!cfile->ext_src) add_file_info(cfile->handle, FALSE);
918  cfile->is_loaded = TRUE;
919 
920  if (cfile->frames <= 0) {
921  if (cfile->afilesize == 0l) {
922  // we got neither video nor audio...
923  lives_snprintf(msg, 256, "%s", _
924  ("\n\nLiVES was unable to extract either video or audio.\n"
925  "Please check the terminal window for more details.\n"));
926 
928  lives_strappend(msg, 256, _("\n\nYou may need to install mplayer, mplayer2 or mpv to open this file.\n"));
929  } else {
930  if (capable->has_mplayer) {
932  } else if (capable->has_mplayer2) {
934  } else if (capable->has_mpv) {
936  }
937 
938  if (strcmp(prefs->video_open_command, loc) && strncmp(prefs->video_open_command + 1, loc, strlen(loc))) {
939  lives_strappend(msg, 256, _("\n\nPlease check the setting of Video Open Command in\nTools|Preferences|Decoding\n"));
940  }
941  }
943  do_error_dialog(msg);
945  d_print_failed();
946  close_current_file(old_file);
947  if (mainw->multitrack) {
948  mainw->multitrack->pb_start_event = mt_pb_start_event;
949  mainw->multitrack->has_audio_file = mt_has_audio_file;
950  }
951  lives_freep((void **)&mainw->file_open_params);
953  return 0;
954  }
955  cfile->frames = 0;
956  }
957 
958  if (!cfile->ext_src) {
959  extra_frames = cfile->frames;
960  add_file_info(cfile->handle, FALSE);
961  extra_frames -= cfile->frames;
962  cfile->end = cfile->frames;
963  cfile->video_time = cfile->frames / cfile->fps;
964  } else {
965  add_file_info(NULL, FALSE);
966  if (cfile->f_size == 0) {
967  off_t fsize = sget_file_size((char *)file_name);
968  if (fsize < 0) fsize = 0;
969  cfile->f_size = (size_t)fsize;
970  }
971  }
972 
973  if (!cfile->ext_src) {
976  if (cfile->laudio_time > cfile->video_time && cfile->frames > 0) {
977  if (!prefs->keep_all_audio || start != 0. || extra_frames <= 0) {
978  d_print(_("Auto trimming %.2f seconds of audio at end..."), cfile->laudio_time - cfile->video_time);
979  if (on_trim_audio_activate(NULL, LIVES_INT_TO_POINTER(0))) d_print_done();
980  else d_print("\n");
981  cfile->changed = FALSE;
982  } else {
984  if (prefs->keep_all_audio && (cfile->laudio_time - cfile->video_time) * cfile->fps > extra_frames)
985  extra_frames = (cfile->laudio_time - cfile->video_time) * cfile->fps;
986  insert_blank_frames(mainw->current_file, extra_frames, cfile->frames, WEED_PALETTE_RGB24);
987  cfile->video_time += extra_frames / cfile->fps;
988  cfile->end = cfile->frames;
989  showclipimgs();
990  if (!mainw->multitrack)
992  }
993  }
994  if (cfile->laudio_time < cfile->video_time && cfile->achans > 0) {
995  cfile->undo1_dbl = cfile->laudio_time;
996  cfile->undo2_dbl = CLIP_TOTAL_TIME(mainw->current_file) - cfile->laudio_time;
997  cfile->undo_arate = cfile->arate;
998  cfile->undo_signed_endian = cfile->signed_endian;
999  cfile->undo_achans = cfile->achans;
1000  cfile->undo_asampsize = cfile->asampsize;
1001  cfile->undo_arps = cfile->arps;
1002  d_print(_("Auto padding with %.2f seconds of silence at end..."), cfile->undo2_dbl);
1003  if (on_ins_silence_activate(NULL, NULL)) d_print_done();
1004  else d_print("\n");
1005  cfile->changed = FALSE;
1006  }
1007  }
1008  }
1009 
1010  if (isubfname) {
1011  d_print(_("Loaded subtitle file: %s\n"), isubfname);
1012  lives_free(isubfname);
1013  }
1014 
1015 img_load:
1016  current_file = mainw->current_file;
1017 
1018 #ifdef GET_MD5
1019  g_print("md5sum is %s\n", get_md5sum(file_name));
1020 #endif
1021 
1022  // TODO - prompt for copy to origs (unless it is already there)
1023 
1025 
1026  if (prefs->show_recent && !mainw->is_generating) {
1027  add_to_recent(file_name, start, frames, mainw->file_open_params);
1028  }
1029  lives_freep((void **)&mainw->file_open_params);
1030 
1031  if (!strcmp(cfile->type, "Frames") || !strcmp(cfile->type, LIVES_IMAGE_TYPE_JPEG) ||
1032  !strcmp(cfile->type, LIVES_IMAGE_TYPE_PNG) ||
1033  !strcmp(cfile->type, "Audio")) {
1034  cfile->is_untitled = TRUE;
1035  }
1036 
1037  if ((!strcmp(cfile->type, LIVES_IMAGE_TYPE_JPEG) || !strcmp(cfile->type, LIVES_IMAGE_TYPE_PNG))) {
1038  if (mainw->img_concat_clip == -1) {
1039  cfile->img_type = lives_image_type_to_img_type(cfile->type);
1041  add_to_clipmenu();
1042  set_main_title(cfile->file_name, 0);
1043  cfile->opening = cfile->opening_audio = cfile->opening_only_audio = FALSE;
1044  cfile->opening_frames = -1;
1046  cfile->is_loaded = TRUE;
1047  } else if (prefs->concat_images) {
1048  // insert this image into our image clip, close this file
1049 
1050  com = lives_strdup_printf("%s insert \"%s\" \"%s\" %d 1 1 \"%s\" 0 %d %d %d", prefs->backend,
1056 
1058 
1059  lives_rm(cfile->info_file);
1060 
1062  mainw->error = FALSE;
1063  lives_system(com, FALSE);
1064  lives_free(com);
1065 
1066  do_auto_dialog(_("Adding image..."), 2);
1067 
1068  if (current_file != mainw->img_concat_clip) {
1069  mainw->current_file = current_file;
1071  }
1072 
1073  if (mainw->cancelled || mainw->error) {
1074  goto load_done;
1075  }
1076 
1077  cfile->frames++;
1078  cfile->end++;
1079 
1081  lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames == 0 ? 0 : 1, cfile->frames);
1082  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end);
1084 
1086  lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->frames == 0 ? 0 : 1, cfile->frames);
1087  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->start);
1090  return 0;
1091  }
1092  }
1093 
1094  // set new style file details
1095  if (!save_clip_values(current_file)) {
1096  close_current_file(old_file);
1097  return 0;
1098  }
1099 
1101 
1102 load_done:
1103  if (!mainw->multitrack) {
1104  // update widgets
1105  switch_to_file((mainw->current_file = 0), current_file);
1107  } else {
1108  lives_mt *multi = mainw->multitrack;
1109  mainw->multitrack = NULL; // allow getting of afilesize
1110  current_file = mainw->current_file;
1111  mainw->current_file = -1; // stop framebars from being drawn
1112  reget_afilesize(current_file);
1113  mainw->current_file = current_file;
1114  mainw->multitrack = multi;
1116  if (!mainw->is_generating) mainw->current_file = mainw->multitrack->render_file;
1117  mt_init_clips(mainw->multitrack, current_file, TRUE);
1120  }
1123  return cfile->unique_id;
1124 }
1125 
1126 
1127 static void save_subs_to_file(lives_clip_t *sfile, char *fname) {
1128  char *ext;
1129  lives_subtitle_type_t otype, itype;
1130 
1131  if (!sfile->subt) return;
1132 
1133  itype = sfile->subt->type;
1134 
1135  ext = get_extension(fname);
1136 
1137  if (!strcmp(ext, LIVES_FILE_EXT_SUB)) otype = SUBTITLE_TYPE_SUB;
1138  else if (!strcmp(ext, LIVES_FILE_EXT_SRT)) otype = SUBTITLE_TYPE_SRT;
1139  else otype = itype;
1140 
1141  lives_free(ext);
1142 
1143  // TODO - use sfile->subt->save_fn
1144  switch (otype) {
1145  case SUBTITLE_TYPE_SUB:
1146  save_sub_subtitles(sfile, (double)(sfile->start - 1) / sfile->fps, (double)sfile->end / sfile->fps,
1147  (double)(sfile->start - 1) / sfile->fps, fname);
1148  break;
1149 
1150  case SUBTITLE_TYPE_SRT:
1151  save_srt_subtitles(sfile, (double)(sfile->start - 1) / sfile->fps, (double)sfile->end / sfile->fps,
1152  (double)(sfile->start - 1) / sfile->fps, fname);
1153  break;
1154 
1155  default:
1156  return;
1157  }
1158 
1159  d_print(_("Subtitles were saved as %s\n"), mainw->subt_save_file);
1160 }
1161 
1162 
1163 boolean get_handle_from_info_file(int index) {
1164  // called from get_new_handle to get the 'real' file handle
1165  // because until we know the handle we can't use the normal info file yet
1166  char *com = lives_strdup_printf("%s new", prefs->backend_sync);
1167 
1169  lives_free(com);
1170 
1171  if (!strncmp(mainw->msg, "error|", 6)) {
1173  return FALSE;
1174  }
1175 
1176  if (!mainw->files[index]) {
1177  mainw->files[index] = (lives_clip_t *)(lives_calloc(1, sizeof(lives_clip_t)));
1178  mainw->files[index]->clip_type = CLIP_TYPE_DISK; // the default
1179  }
1180  lives_snprintf(mainw->files[index]->handle, 256, "%s", mainw->msg);
1181 
1182  return TRUE;
1183 }
1184 
1185 
1186 void save_frame(LiVESMenuItem * menuitem, livespointer user_data) {
1187  int frame;
1188  // save a single frame from a clip
1189  char *filt[2];
1190  char *ttl;
1191  char *filename, *defname;
1192 
1193  filt[0] = lives_strdup_printf("*.%s", get_image_ext_for_type(cfile->img_type));
1194  filt[1] = NULL;
1195 
1196  frame = LIVES_POINTER_TO_INT(user_data);
1197 
1198  if (frame > 0)
1199  ttl = lives_strdup_printf(_("Save Frame %d"), frame);
1200 
1201  else
1202  ttl = (_("Save Frame"));
1203 
1204  defname = lives_strdup_printf("frame%08d.%s", frame, get_image_ext_for_type(cfile->img_type));
1205 
1206  filename = choose_file(*mainw->image_dir ? mainw->image_dir : NULL, defname,
1207  filt, LIVES_FILE_CHOOSER_ACTION_SAVE, ttl, NULL);
1208 
1209  lives_free(defname); lives_free(filt[0]); lives_free(ttl);
1210 
1211  if (!filename) return;
1212  if (!*filename) {
1213  lives_free(filename);
1214  return;
1215  }
1216 
1217  if (!save_frame_inner(mainw->current_file, frame, filename, -1, -1, FALSE)) {
1218  lives_free(filename);
1219  return;
1220  }
1221 
1222  lives_snprintf(mainw->image_dir, PATH_MAX, "%s", filename);
1223  lives_free(filename);
1225  if (prefs->save_directories) {
1227  }
1228 }
1229 
1230 
1231 static void save_log_file(const char *prefix) {
1232  int logfd;
1233 
1234  // save the logfile in workdir
1235 #ifndef IS_MINGW
1236  char *logfile = lives_strdup_printf("%s/%s_%d_%d.txt", prefs->workdir, prefix, lives_getuid(), lives_getgid());
1237  if ((logfd = creat(logfile, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) {
1238 #else
1239  char *logfile = lives_strdup_printf("%s\\%s_%d_%d.txt", prefs->workdir, prefix, lives_getuid(), lives_getgid());
1240  if ((logfd = creat(logfile, S_IRUSR | S_IWUSR)) != -1) {
1241 #endif
1242  char *btext = lives_text_view_get_text(mainw->optextview);
1243  lives_write(logfd, btext, strlen(btext), TRUE); // not really important if it fails
1244  lives_free(btext);
1245  close(logfd);
1246  }
1247  lives_free(logfile);
1248 }
1249 
1250 
1251 LIVES_GLOBAL_INLINE void set_default_comment(lives_clip_t *sfile, const char *extrat) {
1252  if (!*sfile->comment)
1253  lives_snprintf(sfile->comment, 1024, "Created with LiVES version %s.\nSee: %s\n%s",
1254  LiVES_VERSION, LIVES_WEBSITE, extrat);
1255  if (!*sfile->author && *prefs->def_author)
1256  lives_snprintf(sfile->author, 1024, "%s", prefs->def_author);
1257 }
1258 
1259 
1260 void save_file(int clip, int start, int end, const char *filename) {
1261  // save clip from frame start to frame end
1262  lives_clip_t *sfile = mainw->files[clip], *nfile = NULL;
1263  double aud_start = 0., aud_end = 0.;
1264 
1265  char *n_file_name = NULL;
1266  char *fps_string;
1267  char *extra_params = NULL;
1268  char *redir = lives_strdup("1>&2 2>"LIVES_DEVNULL);
1269  char *new_stderr_name = NULL;
1270  char *mesg, *bit, *tmp;
1271  char *com, *msg;
1272  char *full_file_name = NULL;
1273  char *enc_exec_name = NULL;
1274  char *clipdir;
1275  char *cwd;
1276 
1277  boolean recheck_name = FALSE;
1278 
1279  int new_stderr = -1;
1280  int retval;
1281  int startframe = 1;
1282  int current_file = mainw->current_file;
1283  int asigned = !(sfile->signed_endian & AFORM_UNSIGNED); // 1 is signed (in backend)
1284  int aendian = (sfile->signed_endian & AFORM_BIG_ENDIAN); // 2 is bigend
1285  int arate;
1286  int new_file = -1;
1287 
1288 #ifdef GUI_GTK
1289  GError *gerr = NULL;
1290 #endif
1291 
1292  struct stat filestat;
1293 
1294  off_t fsize;
1295 
1296  LiVESWidget *hbox;
1297  frames_t res;
1298 
1299  boolean safe_symlinks = prefs->safe_symlinks;
1300  boolean not_cancelled = FALSE;
1301  boolean output_exists = FALSE;
1302  boolean save_all = FALSE;
1303  boolean debug_mode = FALSE;
1304 
1305  if (!check_storage_space(mainw->current_file, FALSE)) return;
1306 
1309 
1310  if (start == 1 && end == sfile->frames) save_all = TRUE;
1311 
1312  // new handling for save selection:
1313  // symlink images 1 - n to the encoded frames
1314  // symlinks are now created in /tmp (for dynebolic)
1315  // then encode the symlinked frames
1316 
1317  if (!filename) {
1318  // prompt for encoder type/output format
1319  if (prefs->show_rdet) {
1320  int response;
1321  rdet = create_render_details(1); // WARNING !! - rdet is global in events.h
1322 
1323  while (1) {
1324  response = lives_dialog_run(LIVES_DIALOG(rdet->dialog));
1327 
1328  if (response == LIVES_RESPONSE_CANCEL) {
1331  lives_freep((void **)&rdet);
1332  lives_freep((void **)&resaudw);
1333  return;
1334  }
1335 
1336  clear_mainw_msg();
1337  // initialise new plugin
1338 
1339  if (enc_exec_name) lives_free(enc_exec_name);
1340  enc_exec_name = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_ENCODERS, prefs->encoder.name, NULL);
1341 
1342  com = lives_strdup_printf("\"%s\" init", enc_exec_name);
1344  lives_free(com);
1345 
1346  if (strcmp(mainw->msg, "initialised\n")) {
1347  if (*mainw->msg) {
1348  msg = lives_strdup_printf(_("\n\nThe '%s' plugin reports:\n%s\n"), prefs->encoder.name, mainw->msg);
1349  } else {
1350  msg = lives_strdup_printf
1351  (_("\n\nUnable to find the 'init' method in the %s plugin.\n"
1352  "The plugin may be broken or not installed correctly."), prefs->encoder.name);
1353  }
1354  do_error_dialog(msg);
1355  lives_free(msg);
1356  } else break;
1357  }
1358  if (rdet->debug && lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(rdet->debug)))
1359  debug_mode = TRUE;
1360  }
1361  }
1362 
1363  if (!enc_exec_name)
1364  enc_exec_name = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_ENCODERS, prefs->encoder.name, NULL);
1365 
1366  // get file extension
1368 
1369  hbox = lives_hbox_new(FALSE, 0);
1370  mainw->fx1_bool = TRUE;
1371  add_suffix_check(LIVES_BOX(hbox), prefs->encoder.of_def_ext);
1372  lives_widget_show_all(hbox);
1373 
1374  if (palette->style & STYLE_1) {
1375  lives_widget_set_fg_color(hbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
1376  lives_widget_set_bg_color(hbox, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
1377  }
1378 
1379  if (!filename) {
1380  char *ttl = (_("Save Clip"));
1381  do {
1382  lives_freep((void **)&n_file_name);
1383  n_file_name = choose_file_bg(mainw->vid_save_dir, NULL, NULL, LIVES_FILE_CHOOSER_ACTION_SAVE, ttl, hbox);
1384  if (mainw->fc_buttonresponse == LIVES_RESPONSE_CANCEL) return;
1385  } while (!*n_file_name);
1386  lives_snprintf(mainw->vid_save_dir, PATH_MAX, "%s", n_file_name);
1388  if (prefs->save_directories) {
1390  }
1391  lives_free(ttl);
1392  } else n_file_name = lives_strdup(filename);
1393 
1394  //append default extension (if necessary)
1395  if (!*prefs->encoder.of_def_ext) {
1396  // encoder adds its own extension
1397  get_filename(n_file_name, FALSE);
1398  } else {
1399  if (mainw->fx1_bool && (strlen(n_file_name) <= strlen(prefs->encoder.of_def_ext) ||
1400  strncmp(n_file_name + strlen(n_file_name) - strlen(prefs->encoder.of_def_ext) - 1, ".", 1) ||
1401  strcmp(n_file_name + strlen(n_file_name) - strlen(prefs->encoder.of_def_ext),
1402  prefs->encoder.of_def_ext))) {
1403  full_file_name = lives_strconcat(n_file_name, ".", prefs->encoder.of_def_ext, NULL);
1404  recheck_name = TRUE;
1405  }
1406  }
1407 
1408  if (!full_file_name) {
1409  full_file_name = lives_strdup(n_file_name);
1410  }
1411 
1412  if (!filename && recheck_name) {
1413  if (!check_file(full_file_name, strcmp(full_file_name, n_file_name))) {
1414  lives_free(full_file_name);
1415  lives_free(n_file_name);
1416  if (rdet) {
1419  lives_freep((void **)&rdet);
1420  lives_freep((void **)&resaudw);
1421  }
1422  return;
1423  }
1424  sfile->orig_file_name = FALSE;
1425  }
1426 
1427  if (!*sfile->comment) set_default_comment(sfile, NULL);
1428 
1429  if (!do_comments_dialog(clip, full_file_name)) {
1430  lives_free(full_file_name);
1431  if (rdet) {
1434  lives_freep((void **)&rdet);
1435  lives_freep((void **)&resaudw);
1436  }
1437  lives_freep((void **)&mainw->subt_save_file);
1438  return;
1439  }
1440 
1441  if (rdet) {
1443  lives_freep((void **)&rdet->encoder_name);
1444  lives_freep((void **)&rdet);
1445  lives_freep((void **)&resaudw);
1446  }
1447 
1448  if (sfile->arate * sfile->achans != 0) {
1449  aud_start = calc_time_from_frame(clip, start) * sfile->arps / sfile->arate;
1450  aud_end = calc_time_from_frame(clip, end + 1) * sfile->arps / sfile->arate;
1451  }
1452 
1453  // get extra params for encoder
1454 
1455  if (!sfile->ratio_fps) {
1456  fps_string = lives_strdup_printf("%.3f", sfile->fps);
1457  } else {
1458  fps_string = lives_strdup_printf("%.8f", sfile->fps);
1459  }
1460 
1461  arate = sfile->arate;
1462 
1464  arate = 0;
1465  }
1466 
1468  if (prefs->encoder.capabilities & HAS_RFX) {
1469  char buff[65536];
1470 
1471  com = lives_strdup_printf("\"%s\" get_rfx %s %d %d %d", enc_exec_name, prefs->encoder.of_name,
1472  prefs->encoder.audio_codec, cfile->hsize, cfile->vsize);
1473  if (debug_mode) {
1474  fprintf(stderr, "Running command: %s\n", com);
1475  }
1476  lives_popen(com, TRUE, buff, 65536);
1477  lives_free(com);
1478 
1479  if (!THREADVAR(com_failed)) {
1480  extra_params = plugin_run_param_window(buff, NULL, NULL);
1481  }
1482  if (!extra_params) {
1483  lives_free(fps_string);
1484  if (!mainw->multitrack) {
1485  switch_to_file(mainw->current_file, current_file);
1486  }
1487  lives_freep((void **)&mainw->subt_save_file);
1488  return;
1489  }
1490  }
1491 
1492  if (!save_all && !safe_symlinks) {
1493  // we are saving a selection - make symlinks from a temporary clip
1494 
1495  if ((new_file = mainw->first_free_file) == ALL_USED) {
1496  too_many_files();
1497  lives_freep((void **)&mainw->subt_save_file);
1498  return;
1499  }
1500 
1501  // create new clip
1502  if (!get_new_handle(new_file, (_("selection")))) {
1503  lives_freep((void **)&mainw->subt_save_file);
1504  return;
1505  }
1506 
1507  if (sfile->clip_type == CLIP_TYPE_FILE) {
1509  cfile->progress_start = 1;
1510  cfile->progress_end = count_virtual_frames(sfile->frame_index, start, end);
1511  do_threaded_dialog(_("Pulling frames from clip..."), TRUE);
1512  res = virtual_to_images(clip, start, end, TRUE, NULL);
1514 
1515  if (mainw->cancelled != CANCEL_NONE || res < 0) {
1517  lives_freep((void **)&mainw->subt_save_file);
1518  if (res <= 0) d_print_file_error_failed();
1519  return;
1520  }
1521  }
1522 
1524 
1525  nfile = mainw->files[new_file];
1526  nfile->hsize = sfile->hsize;
1527  nfile->vsize = sfile->vsize;
1528  cfile->progress_start = nfile->start = 1;
1529  cfile->progress_end = nfile->frames = nfile->end = end - start + 1;
1530  nfile->fps = sfile->fps;
1531  nfile->arps = sfile->arps;
1532  nfile->arate = sfile->arate;
1533  nfile->achans = sfile->achans;
1534  nfile->asampsize = sfile->asampsize;
1535  nfile->signed_endian = sfile->signed_endian;
1536  nfile->img_type = sfile->img_type;
1537 
1538  com = lives_strdup_printf("%s link_frames \"%s\" %d %d %.8f %.8f %d %d %d %d %d \"%s\"", prefs->backend, nfile->handle,
1539  start, end, aud_start, aud_end, nfile->arate, nfile->achans, nfile->asampsize,
1540  !(nfile->signed_endian & AFORM_UNSIGNED), !(nfile->signed_endian & AFORM_BIG_ENDIAN),
1541  sfile->handle);
1542 
1543  lives_rm(nfile->info_file);
1544  lives_system(com, FALSE);
1545  lives_free(com);
1546 
1547  // TODO - eliminate this
1548  mainw->current_file = new_file;
1549 
1550  if (THREADVAR(com_failed)) {
1551  char *permitname = lives_build_filename(prefs->workdir, cfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
1552 #ifdef IS_MINGW
1553  // kill any active processes: for other OSes the backend does this
1555 #endif
1556  lives_touch(permitname);
1557  lives_free(permitname);
1558  lives_system(lives_strdup_printf("%s close \"%s\"", prefs->backend, cfile->handle), TRUE);
1559  lives_freep((void **)&cfile);
1560  if (mainw->first_free_file == ALL_USED || mainw->first_free_file > new_file)
1561  mainw->first_free_file = new_file;
1562  if (!mainw->multitrack) {
1563  switch_to_file(mainw->current_file, current_file);
1564  }
1566  lives_freep((void **)&mainw->subt_save_file);
1567  return;
1568  }
1569 
1570  cfile->nopreview = TRUE;
1571  if (!(do_progress_dialog(TRUE, TRUE, _("Linking selection")))) {
1572  char *permitname = lives_build_filename(prefs->workdir, cfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
1573 #ifdef IS_MINGW
1574  // kill any active processes: for other OSes the backend does this
1576 #endif
1577  lives_touch(permitname);
1578  lives_free(permitname);
1579  lives_system((tmp = lives_strdup_printf("%s close \"%s\"", prefs->backend, cfile->handle)), TRUE);
1580  lives_free(tmp);
1581  lives_freep((void **)&cfile);
1582  if (mainw->first_free_file == ALL_USED || mainw->first_free_file > new_file)
1583  mainw->first_free_file = new_file;
1584 
1585  if (!mainw->multitrack) {
1586  switch_to_file(mainw->current_file, current_file);
1587  }
1588  if (mainw->error) d_print_failed();
1589  else d_print_cancelled();
1590  lives_freep((void **)&mainw->subt_save_file);
1591  return;
1592  }
1593 
1594  // cfile->arate, etc., would have been reset by calls to do_progress_dialog() which calls get_total_time() [since cfile->afilesize==0]
1595  // so we need to set these again now that link_frames has provided an actual audio clip
1596 
1597  nfile->arps = sfile->arps;
1598  nfile->arate = sfile->arate;
1599  nfile->achans = sfile->achans;
1600  nfile->asampsize = sfile->asampsize;
1601  nfile->signed_endian = sfile->signed_endian;
1602 
1603  reget_afilesize(new_file);
1604 
1605  aud_start = calc_time_from_frame(new_file, 1) * nfile->arps / nfile->arate;
1606  aud_end = calc_time_from_frame(new_file, nfile->frames + 1) * nfile->arps / nfile->arate;
1607  cfile->nopreview = FALSE;
1608  } else mainw->current_file = clip; // for encoder restns
1609 
1610  if (rdet) rdet->is_encoding = TRUE;
1611 
1612  if (!check_encoder_restrictions(FALSE, FALSE, save_all)) {
1613  if (!save_all && !safe_symlinks) {
1614  char *permitname = lives_build_filename(prefs->workdir, nfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
1615 #ifdef IS_MINGW
1616  lives_kill_subprocesses(nfile->handle, TRUE);
1617 #endif
1618  lives_touch(permitname);
1619  lives_free(permitname);
1620  lives_system((com = lives_strdup_printf("%s close \"%s\"", prefs->backend, nfile->handle)), TRUE);
1621  lives_free(com);
1622  lives_free(nfile);
1623  mainw->files[new_file] = NULL;
1624  if (mainw->first_free_file == ALL_USED || new_file) mainw->first_free_file = new_file;
1625  }
1626  if (!mainw->multitrack) {
1627  switch_to_file(mainw->current_file, current_file);
1628  }
1630  lives_freep((void **)&mainw->subt_save_file);
1631  return;
1632  }
1633 
1634  if (!save_all && safe_symlinks) {
1635  int xarps, xarate, xachans, xasamps, xasigned_endian;
1636  // we are saving a selection - make symlinks in /tmp
1637 
1638  startframe = -1;
1639 
1640  if (sfile->clip_type == CLIP_TYPE_FILE) {
1642  cfile->progress_start = 1;
1643  cfile->progress_end = count_virtual_frames(sfile->frame_index, start, end);
1644  do_threaded_dialog(_("Pulling frames from clip..."), TRUE);
1645  res = virtual_to_images(clip, start, end, TRUE, NULL);
1647 
1648  if (mainw->cancelled != CANCEL_NONE || res <= 0) {
1650  lives_freep((void **)&mainw->subt_save_file);
1651  if (res <= 0) d_print_file_error_failed();
1652  return;
1653  }
1654  }
1655 
1656  com = lives_strdup_printf("%s link_frames \"%s\" %d %d %.8f %.8f %d %d %d %d %d", prefs->backend, sfile->handle,
1657  start, end, aud_start, aud_end, sfile->arate, sfile->achans, sfile->asampsize,
1658  !(sfile->signed_endian & AFORM_UNSIGNED), !(sfile->signed_endian & AFORM_BIG_ENDIAN));
1659 
1660  lives_rm(sfile->info_file);
1661  lives_system(com, FALSE);
1662  lives_free(com);
1663 
1664  mainw->current_file = clip;
1665 
1666  xarps = sfile->arps;
1667  xarate = sfile->arate;
1668  xachans = sfile->achans;
1669  xasamps = sfile->asampsize;
1670  xasigned_endian = sfile->signed_endian;
1671 
1672  if (THREADVAR(com_failed)) {
1673  com = lives_strdup_printf("%s clear_symlinks \"%s\"", prefs->backend_sync, cfile->handle);
1674  lives_system(com, TRUE);
1675  lives_free(com);
1676  cfile->nopreview = FALSE;
1677  if (!mainw->multitrack) {
1678  switch_to_file(mainw->current_file, current_file);
1679  }
1681  lives_freep((void **)&mainw->subt_save_file);
1682  return;
1683  }
1684 
1685  cfile->nopreview = TRUE;
1686  if (!(do_progress_dialog(TRUE, TRUE, _("Linking selection")))) {
1687  com = lives_strdup_printf("%s clear_symlinks \"%s\"", prefs->backend_sync, cfile->handle);
1688  lives_system(com, TRUE);
1689  lives_free(com);
1690  cfile->nopreview = FALSE;
1691  if (!mainw->multitrack) {
1692  switch_to_file(mainw->current_file, current_file);
1693  }
1694  if (mainw->error) d_print_failed();
1695  else d_print_cancelled();
1696  lives_freep((void **)&mainw->subt_save_file);
1697  return;
1698  }
1699 
1700  // cfile->arate, etc., would have been reset by calls to do_progress_dialog() which calls get_total_time() [since cfile->afilesize==0]
1701  // so we need to set these again now that link_frames has provided an actual audio clip
1702 
1703  sfile->arps = xarps;
1704  sfile->arate = xarate;
1705  sfile->achans = xachans;
1706  sfile->asampsize = xasamps;
1707  sfile->signed_endian = xasigned_endian;
1708 
1709  reget_afilesize(clip);
1710 
1711  aud_start = calc_time_from_frame(clip, 1) * sfile->arps / sfile->arate;
1712  aud_end = calc_time_from_frame(clip, end - start + 1) * sfile->arps / sfile->arate;
1713  cfile->nopreview = FALSE;
1714  }
1715 
1716  if (save_all) {
1717  if (sfile->clip_type == CLIP_TYPE_FILE) {
1718  frames_t ret;
1719  char *msg = (_("Pulling frames from clip..."));
1720  if ((ret = realize_all_frames(clip, msg, FALSE)) < sfile->frames) {
1721  lives_free(msg);
1722  lives_freep((void **)&mainw->subt_save_file);
1723  if (ret > 0) d_print_cancelled();
1724  if (!mainw->multitrack) {
1725  switch_to_file(mainw->current_file, current_file);
1726  }
1727  return;
1728  }
1729  lives_free(msg);
1730  }
1731  }
1732 
1734  bit = (_(" (with no sound)\n"));
1735  } else {
1736  bit = lives_strdup("\n");
1737  }
1738 
1739  if (!save_all) {
1740  mesg = lives_strdup_printf(_("Saving frames %d to %d%s as \"%s\" : encoder = %s : format = %s..."),
1741  start, end, bit, full_file_name, prefs->encoder.name, prefs->encoder.of_desc);
1742  } // end selection
1743  else {
1744  mesg = lives_strdup_printf(_("Saving frames 1 to %d%s as \"%s\" : encoder %s : format = %s..."),
1745  sfile->frames, bit, full_file_name, prefs->encoder.name, prefs->encoder.of_desc);
1746  }
1747  lives_free(bit);
1748 
1750  d_print(mesg);
1752  lives_free(mesg);
1753 
1754  if (prefs->show_gui && !debug_mode) {
1755  // open a file for stderr
1756  new_stderr_name = lives_build_filename(prefs->workdir, cfile->handle, LIVES_ENC_DEBUG_FILE_NAME, NULL);
1757  lives_free(redir);
1758 
1759  do {
1760  retval = 0;
1761  new_stderr = lives_open3(new_stderr_name, O_CREAT | O_RDONLY | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR);
1762  if (new_stderr < 0) {
1763  retval = do_write_failed_error_s_with_retry(new_stderr_name, lives_strerror(errno));
1764  if (retval == LIVES_RESPONSE_CANCEL) redir = lives_strdup("1>&2");
1765  } else {
1766 
1767 #ifdef IS_MINGW
1768 
1769 #ifdef GUI_GTK
1770  mainw->iochan = g_io_channel_win32_new_fd(new_stderr);
1771 #endif
1772  redir = lives_strdup_printf("2>&1 >\"%s\"", new_stderr_name);
1773 #else
1774 #ifdef GUI_GTK
1775  mainw->iochan = g_io_channel_unix_new(new_stderr);
1776 #endif
1777  redir = lives_strdup_printf("2>\"%s\"", new_stderr_name);
1778 #endif
1779 
1780 #ifdef GUI_QT
1781  mainw->iochan = new QFile;
1782  mainw->iochan->open(new_stderr, QIODevice::ReadOnly);
1783 #endif
1784 
1785 #ifdef GUI_GTK
1786  g_io_channel_set_encoding(mainw->iochan, NULL, NULL);
1787  g_io_channel_set_buffer_size(mainw->iochan, 0);
1788  g_io_channel_set_flags(mainw->iochan, G_IO_FLAG_NONBLOCK, &gerr);
1789  if (gerr) lives_error_free(gerr);
1790  gerr = NULL;
1791 #endif
1793  }
1794  } while (retval == LIVES_RESPONSE_RETRY);
1795  } else {
1796  lives_free(redir);
1797  redir = lives_strdup("1>&2");
1798  }
1799 
1800  if (lives_file_test((tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)), LIVES_FILE_TEST_EXISTS)) {
1801  lives_rm(tmp);
1802  }
1803  lives_free(tmp);
1804 
1806 
1807  if (arate != 0) arate = cfile->arate;
1808 
1809  if (!cfile->ratio_fps) {
1810  fps_string = lives_strdup_printf("%.3f", cfile->fps);
1811  } else {
1812  fps_string = lives_strdup_printf("%.8f", cfile->fps);
1813  }
1814 
1815  // if startframe is -ve, we will use the links created for safe_symlinks - in /tmp
1816  // for non-safe symlinks, cfile will be our new links file
1817  // for save_all, cfile will be sfile
1818 
1820  com = lives_strdup_printf("%s save \"%s\" \"%s\" \"%s\" \"%s\" %d %d %d %d %d %d %.4f %.4f %s %s", prefs->backend,
1821  cfile->handle,
1822  enc_exec_name, fps_string, (tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)),
1823  startframe, cfile->frames, arate, cfile->achans, cfile->asampsize,
1824  asigned | aendian, aud_start, aud_end, (extra_params == NULL) ? "" : extra_params, redir);
1825  } else {
1826  com = lives_strdup_printf("%s save \"%s\" \"native:%s\" \"%s\" \"%s\" %d %d %d %d %d %d %.4f %.4f %s %s", prefs->backend,
1827  cfile->handle,
1828  enc_exec_name, fps_string, (tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)),
1829  startframe, cfile->frames, arate, cfile->achans, cfile->asampsize,
1830  asigned | aendian, aud_start, aud_end, (extra_params == NULL) ? "" : extra_params, redir);
1831 
1832  }
1833  lives_free(tmp);
1834  lives_free(fps_string);
1835 
1836  lives_freep((void **)&extra_params);
1837 
1839  cfile->nokeep = TRUE;
1840 
1841  lives_rm(cfile->info_file);
1842  THREADVAR(write_failed) = FALSE;
1843  save_file_comments(current_file);
1844 
1845  if (debug_mode) {
1846  fprintf(stderr, "Running command: %s\n", com);
1847  }
1848 
1849  lives_system(com, FALSE);
1850  lives_free(com);
1851  mainw->error = FALSE;
1852 
1853  if (THREADVAR(com_failed) || THREADVAR(write_failed)) {
1854  mainw->error = TRUE;
1855  }
1856 
1857  if (!mainw->error) {
1858  //char *pluginstr;
1859 
1860  cfile->progress_start = 1;
1861  cfile->progress_end = cfile->frames;
1862 
1863  not_cancelled = do_progress_dialog(TRUE, TRUE, _("Saving [can take a long time]"));
1864 
1865  if (mainw->iochan) {
1867 
1868  lives_fsync(new_stderr);
1870 
1871 #ifdef GUI_GTK
1872  g_io_channel_shutdown(mainw->iochan, FALSE, &gerr);
1873  g_io_channel_unref(mainw->iochan);
1874  if (gerr) lives_error_free(gerr);
1875 #endif
1876 #ifdef GUI_QT
1877  delete mainw->iochan;
1878 #endif
1879  mainw->iochan = NULL;
1880 
1881  close(new_stderr);
1882  lives_rm(new_stderr_name);
1883  lives_free(new_stderr_name);
1884  lives_free(redir);
1885  }
1886 
1888  cfile->nokeep = FALSE;
1889  } else {
1890  if (mainw->iochan) {
1892 
1893  lives_fsync(new_stderr);
1895 
1896 #ifdef GUI_GTK
1897  g_io_channel_shutdown(mainw->iochan, FALSE, &gerr);
1898  g_io_channel_unref(mainw->iochan);
1899  if (gerr) lives_error_free(gerr);
1900 #endif
1901 #ifdef GUI_QT
1902  delete mainw->iochan;
1903 #endif
1904  mainw->iochan = NULL;
1905  close(new_stderr);
1906  lives_rm(new_stderr_name);
1907  lives_free(new_stderr_name);
1908  lives_free(redir);
1909  }
1910  }
1911 
1912  cwd = lives_get_current_dir();
1913 
1914  clipdir = lives_build_path(prefs->workdir, cfile->handle, NULL);
1915  lives_chdir(clipdir, FALSE);
1916  lives_free(clipdir);
1917 
1918  com = lives_strdup_printf("\"%s\" clear", enc_exec_name);
1919 
1920  if (debug_mode) {
1921  fprintf(stderr, "Running command: %s\n", com);
1922  }
1923  lives_system(com, FALSE);
1924  lives_free(com);
1925 
1926  lives_chdir(cwd, FALSE);
1927  lives_free(cwd);
1928 
1929  lives_free(enc_exec_name);
1930 
1931  if (not_cancelled || mainw->error) {
1932  if (mainw->error) {
1934  d_print_failed();
1936  lives_free(full_file_name);
1937  if (!save_all && !safe_symlinks) {
1938  char *permitname = lives_build_filename(prefs->workdir, cfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
1940  lives_touch(permitname);
1941  lives_free(permitname);
1942  lives_system((com = lives_strdup_printf("%s close \"%s\"", prefs->backend, cfile->handle)), TRUE);
1943  lives_free(com);
1944  lives_freep((void **)&cfile);
1947  } else if (!save_all && safe_symlinks) {
1948  com = lives_strdup_printf("%s clear_symlinks \"%s\"", prefs->backend_sync, cfile->handle);
1949  lives_system(com, TRUE);
1950  lives_free(com);
1951  }
1952 
1953  switch_to_file(mainw->current_file, current_file);
1954 
1955  lives_freep((void **)&mainw->subt_save_file);
1956  sensitize();
1957  return;
1958  }
1959 
1960  if (lives_file_test((tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)), LIVES_FILE_TEST_EXISTS)) {
1961  lives_free(tmp);
1962  stat((tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)), &filestat);
1963  if (filestat.st_size > 0) output_exists = TRUE;
1964  }
1965  if (!output_exists) {
1966  lives_free(tmp);
1967 
1969  d_print_failed();
1971  lives_free(full_file_name);
1972  if (!save_all && !safe_symlinks) {
1973  char *permitname = lives_build_filename(prefs->workdir, cfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
1975  lives_touch(permitname);
1976  lives_free(permitname);
1977  lives_system((com = lives_strdup_printf("%s close \"%s\"", prefs->backend, cfile->handle)), TRUE);
1978  lives_free(com);
1979  lives_freep((void **)&cfile);
1982  } else if (!save_all && safe_symlinks) {
1983  com = lives_strdup_printf("%s clear_symlinks \"%s\"", prefs->backend_sync, cfile->handle);
1984  lives_system(com, TRUE);
1985  lives_free(com);
1986  }
1987 
1988  if (!mainw->multitrack) {
1989  switch_to_file(mainw->current_file, current_file);
1990  }
1991  retval = do_error_dialog(_("\n\nEncoder error - output file was not created !\n"));
1992 
1993  if (retval == LIVES_RESPONSE_SHOW_DETAILS) {
1996  }
1997 
1998  if (mainw->iochan) {
1999  save_log_file("failed_encoder_log");
2000  mainw->iochan = NULL;
2002  }
2003 
2004  lives_freep((void **)&mainw->subt_save_file);
2005  sensitize();
2006  if (mainw->error) d_print_failed();
2007 
2008  return;
2009  }
2010  lives_free(tmp);
2011 
2012  if (save_all) {
2013  if (prefs->enc_letterbox) {
2015  int iwidth = sfile->ohsize;
2016  int iheight = sfile->ovsize;
2017  boolean bad_header = FALSE;
2018 
2019  com = lives_strdup_printf("%s mv_mgk \"%s\" %d %d \"%s\" 1", prefs->backend, sfile->handle, 1, sfile->frames,
2021 
2022  lives_rm(sfile->info_file);
2023  lives_system(com, FALSE);
2024 
2025  do_progress_dialog(TRUE, FALSE, _("Clearing letterbox"));
2026 
2027  if (mainw->error) {
2028  // cfile->may_be_damaged=TRUE;
2029  d_print_failed();
2030  return;
2031  }
2032 
2033  calc_maxspect(sfile->hsize, sfile->vsize, &iwidth, &iheight);
2034 
2035  sfile->hsize = iwidth;
2036  sfile->vsize = iheight;
2037 
2038  save_clip_value(clip, CLIP_DETAILS_WIDTH, &sfile->hsize);
2039  if (THREADVAR(com_failed) || THREADVAR(write_failed)) bad_header = TRUE;
2040  save_clip_value(clip, CLIP_DETAILS_HEIGHT, &sfile->vsize);
2041  if (THREADVAR(com_failed) || THREADVAR(write_failed)) bad_header = TRUE;
2042  if (bad_header) do_header_write_error(mainw->current_file);
2043  }
2044 
2045  lives_snprintf(sfile->save_file_name, PATH_MAX, "%s", full_file_name);
2046  sfile->changed = FALSE;
2047 
2050  fsize = sget_file_size(full_file_name);
2051  if (fsize < 0) fsize = 0;
2052  cfile->f_size = (size_t)fsize;
2053 
2054  if (sfile->is_untitled) {
2055  sfile->is_untitled = FALSE;
2056  }
2057  if (!sfile->was_renamed) {
2058  lives_menu_item_set_text(sfile->menuentry, full_file_name, FALSE);
2059  lives_snprintf(sfile->name, CLIP_NAME_MAXLEN, "%s", full_file_name);
2060  }
2061  set_main_title(cfile->name, 0);
2062  if (prefs->show_recent) {
2063  add_to_recent(full_file_name, 0., 0, NULL);
2064  global_recent_manager_add(full_file_name);
2065  }
2066  } else {
2067  if (!safe_symlinks) {
2068  char *permitname = lives_build_filename(prefs->workdir, nfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
2069 #ifdef IS_MINGW
2070  lives_kill_subprocesses(nfile->handle, TRUE);
2071 #endif
2072  lives_touch(permitname);
2073  lives_free(permitname);
2074  lives_system((com = lives_strdup_printf("%s close \"%s\"", prefs->backend, nfile->handle)), TRUE);
2075  lives_free(com);
2076  lives_free(nfile);
2077  mainw->files[new_file] = NULL;
2079  mainw->first_free_file = new_file;
2080  } else {
2081  com = lives_strdup_printf("%s clear_symlinks \"%s\"", prefs->backend_sync, cfile->handle);
2082  lives_system(com, TRUE);
2083  lives_free(com);
2084  }
2085  }
2086  }
2087 
2088  if (!mainw->multitrack) {
2089  switch_to_file(mainw->current_file, current_file);
2090  }
2091  if (mainw->iochan) {
2092  save_log_file("encoder_log");
2094  mainw->iochan = NULL;
2095  }
2096 
2097  if (not_cancelled) {
2098  char *fsize_ds;
2100  d_print_done();
2101 
2103 
2104  fsize = sget_file_size(full_file_name);
2105  if (fsize >= 0) {
2107 
2108  fsize_ds = lives_format_storage_space_string(fsize);
2109  d_print(_("File size was %s\n"), fsize_ds);
2110  lives_free(fsize_ds);
2111 
2112  if (mainw->subt_save_file) {
2113  save_subs_to_file(sfile, mainw->subt_save_file);
2114  lives_freep((void **)&mainw->subt_save_file);
2115  }
2116  }
2118 
2120  (mesg = lives_strdup_printf("encode %d \"%s\"", clip,
2121  (tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)))));
2122  lives_free(tmp);
2123  lives_free(mesg);
2124  } else {
2125  lives_rm((tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)));
2126  lives_free(tmp);
2127  }
2128 
2129  lives_free(full_file_name);
2130 }
2131 
2132 
2133 char *prep_audio_player(char *com2, char *com3, frames_t audio_end, int arate, int asigned, int aendian) {
2134  char *stfile = NULL;
2135  char *stopcom = NULL, *com;
2136  short audio_player = prefs->audio_player;
2137  int loop = 0;
2138 
2139  if (cfile->achans > 0) {
2140  cfile->aseek_pos = (off64_t)(cfile->real_pointer_time * (double)cfile->arate) * cfile->achans * (cfile->asampsize / 8);
2141  if (mainw->playing_sel) {
2142  off64_t apos = (off64_t)((double)(mainw->play_start - 1.) / cfile->fps * (double)cfile->arate) * cfile->achans *
2143  (cfile->asampsize / 8);
2144  if (apos > cfile->aseek_pos) cfile->aseek_pos = apos;
2145  }
2146  if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
2147  if (mainw->current_file == 0 && cfile->arate < 0) cfile->aseek_pos = cfile->afilesize;
2148  }
2149  // start up our audio player (jack or pulse)
2150  if (audio_player == AUD_PLAYER_JACK) {
2151 #ifdef ENABLE_JACK
2152  if (mainw->jackd) jack_aud_pb_ready(mainw->current_file);
2153  return NULL;
2154 #endif
2155  } else if (audio_player == AUD_PLAYER_PULSE) {
2156 #ifdef HAVE_PULSE_AUDIO
2157  if (mainw->pulsed) pulse_aud_pb_ready(mainw->current_file);
2158  return NULL;
2159 #endif
2160  } else if (audio_player != AUD_PLAYER_NONE && cfile->achans > 0) {
2161  // sox or mplayer audio - run as background process
2162  if (com3) {
2163  if (mainw->loop_cont) {
2164  // tell audio to loop forever
2165  loop = -1;
2166  }
2167 
2168  stfile = lives_build_filename(prefs->workdir, cfile->handle, ".stoploop", NULL);
2169  lives_rm(stfile);
2170 
2171  if (cfile->achans > 0 || (!cfile->is_loaded && !mainw->is_generating)) {
2172  if (loop) {
2173  lives_free(com3);
2174  com3 = lives_strdup_printf("%s \"%s\" 2>\"%s\" 1>&2", capable->touch_cmd, stfile, prefs->cmd_log);
2175  }
2176 
2177  if (com2) {
2178  if (cfile->achans > 0) {
2179  com2 = lives_strdup_printf("%s stop_audio %s", prefs->backend_sync, cfile->handle);
2180  }
2181  stopcom = lives_strconcat(com3, com2, NULL);
2182  }
2183  }
2184  }
2185 
2186  lives_freep((void **)&stfile);
2187 
2188  stfile = lives_build_filename(prefs->workdir, cfile->handle, LIVES_STATUS_FILE_NAME".play", NULL);
2189 
2190  lives_snprintf(cfile->info_file, PATH_MAX, "%s", stfile);
2191  lives_free(stfile);
2192  if (cfile->clip_type == CLIP_TYPE_DISK) lives_rm(cfile->info_file);
2193 
2194  // PLAY
2195 
2196  if (cfile->clip_type == CLIP_TYPE_DISK && cfile->opening) {
2197  com = lives_strdup_printf("%s play_opening_preview \"%s\" %.3f %d %d %d %d %d %d %d %d", prefs->backend,
2198  cfile->handle, cfile->fps, mainw->audio_start, audio_end, 0,
2199  arate, cfile->achans, cfile->asampsize, asigned, aendian);
2200  } else {
2201  // this is only used now for sox or mplayer audio player
2202  com = lives_strdup_printf("%s play %s %.3f %d %d %d %d %d %d %d %d", prefs->backend, cfile->handle,
2203  cfile->fps, mainw->audio_start, audio_end, loop,
2204  arate, cfile->achans, cfile->asampsize, asigned, aendian);
2205  }
2206  if (!mainw->multitrack && com) lives_system(com, FALSE);
2207  }
2208  return stopcom;
2209 }
2210 
2211 
2213 void play_file(void) {
2214  LiVESWidgetClosure *freeze_closure, *bg_freeze_closure;
2215  LiVESList *cliplist;
2216  weed_plant_t *pb_start_event = NULL;
2217 
2218 #ifdef GDK_WINDOWING_X11
2219  uint64_t awinid = -1;
2220 #endif
2221 
2222  char *com, *com2 = lives_strdup(" "), *com3 = lives_strdup(" ");
2223  char *stopcom = NULL;
2224  char *stfile;
2225 #ifdef GDK_WINDOWING_X11
2226  char *tmp;
2227 #endif
2228 
2229  double fps_med = 0.;
2230  double pointer_time = cfile->pointer_time;
2231  double real_pointer_time = cfile->real_pointer_time;
2232 
2233  short audio_player = prefs->audio_player;
2234 
2235  boolean mute;
2236  boolean needsadone = FALSE;
2237 
2238 #ifdef RT_AUDIO
2239  boolean exact_preview = FALSE;
2240 #endif
2241  boolean has_audio_buffers = FALSE;
2242 
2243  int arate;
2244 
2245  int asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
2246  int aendian = !(cfile->signed_endian & AFORM_BIG_ENDIAN);
2247  int current_file = mainw->current_file;
2248  int audio_end = 0;
2249 
2251  mainw->noswitch = TRUE;
2253 
2254  asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
2255  aendian = !(cfile->signed_endian & AFORM_BIG_ENDIAN);
2256  current_file = mainw->current_file;
2257  if (mainw->pre_play_file == -1) mainw->pre_play_file = current_file;
2258 
2260  else mainw->aud_file_to_kill = -1;
2261 
2262 #ifdef ENABLE_JACK_TRANSPORT
2263  if (!mainw->preview && !mainw->foreign) {
2264  if (!mainw->multitrack)
2265  jack_pb_start(cfile->achans > 0 ? cfile->real_pointer_time : cfile->pointer_time);
2266  else
2267  jack_pb_start(mainw->multitrack->pb_start_time);
2268  }
2269 #endif
2270 
2272 
2273  mainw->rec_aclip = -1;
2274 
2276 
2279 
2281  lives_accel_group_connect(LIVES_ACCEL_GROUP(mainw->accel_group), LIVES_KEY_BackSpace,
2282  (LiVESXModifierType)LIVES_CONTROL_MASK,
2283  (LiVESAccelFlags)0, (freeze_closure = lives_cclosure_new(LIVES_GUI_CALLBACK(freeze_callback),
2284  LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND), NULL)));
2285  lives_accel_group_connect(LIVES_ACCEL_GROUP(mainw->accel_group), LIVES_KEY_BackSpace,
2286  (LiVESXModifierType)(LIVES_CONTROL_MASK | LIVES_ALT_MASK),
2287  (LiVESAccelFlags)0, (bg_freeze_closure = lives_cclosure_new(LIVES_GUI_CALLBACK(freeze_callback),
2288  LIVES_INT_TO_POINTER(SCREEN_AREA_BACKGROUND), NULL)));
2289 
2291  lives_accel_path_disconnect(mainw->accel_group, LIVES_ACCEL_PATH_QUIT);
2292 
2293  if (mainw->multitrack) {
2294  mainw->event_list = mainw->multitrack->event_list;
2295  pb_start_event = mainw->multitrack->pb_start_event;
2296 #ifdef RT_AUDIO
2297  exact_preview = mainw->multitrack->exact_preview;
2298 #endif
2299  }
2300 
2301  // reinit all active effects
2303 
2304  if (mainw->record) {
2305  if (mainw->preview) {
2306  mainw->record = FALSE;
2307  d_print(_("recording aborted by preview.\n"));
2308  } else if (mainw->current_file == 0) {
2309  mainw->record = FALSE;
2310  d_print(_("recording aborted by clipboard playback.\n"));
2311  } else {
2312  d_print(_("Recording performance..."));
2313  needsadone = TRUE;
2315  // TODO
2316  if (mainw->current_file > 0 && (cfile->undo_action == UNDO_RESAMPLE || cfile->undo_action == UNDO_RENDER)) {
2319  cfile->undoable = cfile->redoable = FALSE;
2320  }
2321  }
2322  }
2324  else if (mainw->event_list) cfile->next_event = get_first_event(mainw->event_list);
2325 
2329  //lives_signal_handler_block(mainw->spinbutton_start, mainw->spin_start_func);
2330  //lives_signal_handler_block(mainw->spinbutton_end, mainw->spin_end_func);
2331  }
2332 
2333 #ifdef ENABLE_JACK_TRANSPORT
2336  // calculate the start position from jack transport
2337  double sttime = (double)jack_transport_get_current_ticks() / TICKS_PER_SECOND_DBL;
2338  cfile->pointer_time = cfile->real_pointer_time = sttime;
2339  if (cfile->real_pointer_time > CLIP_TOTAL_TIME(mainw->current_file))
2340  cfile->real_pointer_time = CLIP_TOTAL_TIME(mainw->current_file);
2341  if (cfile->pointer_time > cfile->video_time) cfile->pointer_time = 0.;
2343  }
2344 #endif
2345 
2347  mainw->audio_start = mainw->audio_end = 0;
2348 
2349  if (cfile->achans > 0) {
2350  if (mainw->event_list &&
2351  !(mainw->preview && mainw->is_rendering) &&
2352  !(mainw->multitrack && mainw->preview && mainw->multitrack->is_rendering)) {
2354  if (event_list_get_end_secs(mainw->event_list) > cfile->frames / cfile->fps && !mainw->playing_sel) {
2355  mainw->audio_end = (event_list_get_end_secs(mainw->event_list) * cfile->fps + 1.) * cfile->arate / cfile->arps;
2356  }
2357  }
2358 
2359  if (mainw->audio_end == 0) {
2361  mainw->play_start) * cfile->fps + 1. * cfile->arate / cfile->arps;
2363  + 1. * cfile->arate / cfile->arps;
2364  if (!mainw->playing_sel) {
2365  mainw->audio_end = 0;
2366  }
2367  }
2368  }
2369 
2370  if (!cfile->opening_audio && !mainw->loop) {
2373  audio_end = mainw->audio_end;
2374  }
2375 
2376  if (!mainw->multitrack) {
2377  if (!mainw->preview) {
2378  lives_frame_set_label(LIVES_FRAME(mainw->playframe), _("Play"));
2379  } else {
2380  lives_frame_set_label(LIVES_FRAME(mainw->playframe), _("Preview"));
2381  }
2382 
2383  if (palette->style & STYLE_1) {
2385  LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
2386  }
2387 
2388  if (mainw->foreign) {
2391  }
2392 
2394  if ((mainw->faded || (prefs->show_playwin && !prefs->show_gui)
2395  || (mainw->fs && (!mainw->sep_win))) && (cfile->frames > 0 ||
2396  mainw->foreign)) {
2397  fade_background();
2398  }
2399 
2400  if ((!mainw->sep_win || (!mainw->faded && (prefs->sepwin_type != SEPWIN_TYPE_STICKY)))
2401  && (cfile->frames > 0 ||
2402  mainw->foreign)) {
2406  }
2407 
2409  add_to_playframe();
2410  }
2411 
2412  arate = cfile->arate;
2413 
2414  mute = mainw->mute;
2415 
2416  if (!is_realtime_aplayer(audio_player)) {
2417  if (cfile->achans == 0 || mainw->is_rendering) mainw->mute = TRUE;
2418  if (mainw->mute && !cfile->opening_only_audio) arate = arate ? -arate : -1;
2419  }
2420 
2421  cfile->frameno = mainw->play_start;
2422  cfile->pb_fps = cfile->fps;
2423  if (mainw->reverse_pb) {
2424  cfile->pb_fps = -cfile->pb_fps;
2425  cfile->frameno = mainw->play_end;
2426  }
2427  cfile->last_frameno = cfile->frameno;
2428  mainw->reverse_pb = FALSE;
2429 
2430  mainw->swapped_clip = -1;
2431  mainw->blend_palette = WEED_PALETTE_END;
2432 
2433  cfile->play_paused = FALSE;
2434  mainw->period = TICKS_PER_SECOND_DBL / cfile->pb_fps;
2435 
2436  if (audio_player == AUD_PLAYER_JACK
2438  audio_cache_init();
2439 
2440  if (mainw->blend_file != -1 && !IS_VALID_CLIP(mainw->blend_file)) mainw->blend_file = -1;
2441 
2444 
2445  if (!mainw->preview || !cfile->opening) {
2446  enable_record();
2447  desensitize();
2449  }
2450 
2451  if (mainw->record) {
2454  }
2455 
2458  }
2459 
2461 
2463  else if (!cfile->opening) {
2465  else {
2468  }
2469  }
2470 
2472 
2476 
2478  mainw->loop_cont || is_realtime_aplayer(audio_player))
2479  && mainw->current_file > 0);
2481  is_realtime_aplayer(audio_player))
2482  && mainw->current_file > 0);
2483 
2484  if (cfile->frames == 0 && !mainw->multitrack) {
2486 
2488 
2489  mainw->pw_scroll_func = lives_signal_connect(LIVES_GUI_OBJECT(mainw->play_window), LIVES_WIDGET_SCROLL_EVENT,
2490  LIVES_GUI_CALLBACK(on_mouse_scroll), NULL);
2491  }
2492  } else {
2493  if (mainw->sep_win) {
2496  make_play_window();
2497  } else {
2498  if (!mainw->multitrack) {
2499  if (mainw->preview_controls) {
2501  /* mainw->pw_scroll_func = lives_signal_connect(LIVES_GUI_OBJECT(mainw->play_window), LIVES_WIDGET_SCROLL_EVENT, */
2502  /* LIVES_GUI_CALLBACK(on_mouse_scroll), */
2503  /* NULL); */
2504  }
2505  }
2506 
2507  if (!mainw->multitrack || mainw->fs) {
2509  }
2510 
2512  if (!mainw->multitrack) {
2514  } else {
2516  if (mainw->play_window) {
2517  if (prefs->show_playwin) {
2518  lives_window_present(LIVES_WINDOW(mainw->play_window));
2520  // *INDENT-OFF*
2521  }}}}}
2522  // *INDENT-ON*
2523 
2524  if (mainw->play_window) {
2528  }
2529 
2530  if (!mainw->foreign && !mainw->sep_win) {
2532  }
2533 
2534  if (!mainw->sep_win && !mainw->foreign) {
2535  if (mainw->double_size) resize(2.);
2536  else resize(1);
2537  }
2538 
2539  /* if (mainw->vpp && mainw->vpp->fheight > -1 && mainw->vpp->fwidth > -1) { */
2540  /* // fixed o/p size for stream */
2541  /* if (mainw->vpp->fwidth * mainw->vpp->fheight == 0) { */
2542  /* mainw->vpp->fwidth = DEF_VPP_HSIZE; */
2543  /* mainw->vpp->fheight = DEF_VPP_VSIZE; */
2544  /* } */
2545  /* if (!(mainw->vpp->capabilities & VPP_CAN_RESIZE)) { */
2546  /* mainw->pwidth = mainw->vpp->fwidth; */
2547  /* mainw->pheight = mainw->vpp->fheight; */
2548  /* } */
2549  /* } */
2550 
2551  if (mainw->fs && !mainw->sep_win && cfile->frames > 0) {
2553  }
2554  }
2555 
2556  // moved down because xdg-screensaver requires a mapped windowID
2557  if (prefs->stop_screensaver) {
2558  lives_freep((void **)&com2);
2559 #ifdef GDK_WINDOWING_X11
2561  awinid = lives_widget_get_xwinid(mainw->play_window, NULL);
2562  } else if (prefs->show_gui) {
2564  }
2565 
2566  com2 = lives_strdup("xset s off 2>/dev/null; xset -dpms 2>/dev/null ;");
2567 
2568  if (capable->has_gconftool_2) {
2569  char *xnew = lives_strdup(" gconftool-2 --set --type bool /apps/gnome-screensaver/idle_activation_enabled "
2570  "false 2>/dev/null ;");
2571  tmp = lives_concat(com2, xnew);
2572  com2 = tmp;
2573  }
2574  if (capable->has_xdg_screensaver && awinid != -1) {
2575  char *xnew = lives_strdup_printf(" xdg-screensaver suspend %"PRIu64" 2>/dev/null ;", awinid);
2576  tmp = lives_concat(com2, xnew);
2577  com2 = tmp;
2578  }
2579 #else
2580  if (capable->has_gconftool_2) {
2581  com2 = lives_strdup("gconftool-2 --set --type bool /apps/gnome-screensaver/idle_activation_enabled false 2>/dev/null ;");
2582  } else com2 = lives_strdup("");
2583 #endif
2584  if (!com2) com2 = lives_strdup("");
2585  }
2586 
2587  if (!mainw->foreign && prefs->midisynch && !mainw->preview) {
2588  lives_free(com3);
2589  com3 = lives_strdup(EXEC_MIDISTART);
2590  }
2591  com = lives_strconcat(com2, com3, NULL);
2592  if (*com) {
2593  // allow this to fail - not all sub-commands may be present
2594  lives_system(com, TRUE);
2595  }
2596  lives_freep((void **)&com);
2597  lives_freep((void **)&com2);
2598  lives_free(com3);
2599  com3 = lives_strdup(" ");
2600 
2601  if (!mainw->multitrack) {
2602  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), cfile->pb_fps);
2603 
2604  mainw->last_blend_file = -1;
2605 
2606  // show the framebar
2607  if (!mainw->multitrack && !mainw->faded
2608  && (!prefs->hide_framebar &&
2610  && capable->nmonitors > 1 &&
2611  mainw->sep_win) ||
2613  ((!mainw->preview && (cfile->frames > 0 || mainw->foreign)) || cfile->opening))) {
2615  }
2616  }
2617 
2618  cfile->play_paused = FALSE;
2619  mainw->actual_frame = 0;
2620 
2621  mainw->currticks = 0;
2623 
2625 
2626  // reinit all active effects
2628 
2629  if (!mainw->foreign && (!(prefs->audio_src == AUDIO_SRC_EXT &&
2630  (audio_player == AUD_PLAYER_JACK ||
2631  audio_player == AUD_PLAYER_PULSE || audio_player == AUD_PLAYER_NONE)))) {
2632  stopcom = prep_audio_player(com2, com3, audio_end, arate, asigned, aendian);
2633  }
2634 
2635  lives_free(com3);
2636 
2637  // if recording, refrain from writing audio until we are ready
2638  if (mainw->record) mainw->record_paused = TRUE;
2639 
2640  // if recording, set up recorder (jack or pulse)
2641  if (!mainw->preview && (prefs->audio_src == AUDIO_SRC_EXT || (mainw->record && mainw->agen_key != 0))
2642  && (audio_player == AUD_PLAYER_JACK || audio_player == AUD_PLAYER_PULSE)) {
2643  mainw->rec_samples = -1; // record unlimited
2644  if (mainw->record) {
2645  // create temp clip
2646  open_ascrap_file();
2647  if (mainw->ascrap_file != -1) {
2649  mainw->rec_avel = 1.;
2650  mainw->rec_aseek = 0;
2651  }
2652  }
2653  if (audio_player == AUD_PLAYER_JACK) {
2654 #ifdef ENABLE_JACK
2656  if (mainw->agen_key != 0 || mainw->agen_needs_reinit) {
2657  mainw->jackd->playing_file = mainw->current_file;
2658  if (mainw->ascrap_file != -1 || !prefs->perm_audio_reader)
2659  jack_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_GENERATED);
2660  } else {
2661  if (mainw->ascrap_file != -1 || !prefs->perm_audio_reader)
2662  jack_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_EXTERNAL);
2663  }
2664  //mainw->jackd->in_use = TRUE;
2665  }
2667  mainw->jackd_read->num_input_channels = mainw->jackd_read->num_output_channels = 2;
2668  mainw->jackd_read->sample_in_rate = mainw->jackd_read->sample_out_rate;
2669  mainw->jackd_read->is_paused = TRUE;
2670  mainw->jackd_read->in_use = TRUE;
2671  }
2672 #endif
2673  }
2674  if (audio_player == AUD_PLAYER_PULSE) {
2675 #ifdef HAVE_PULSE_AUDIO
2677  if (mainw->agen_key != 0 || mainw->agen_needs_reinit) {
2678  mainw->pulsed->playing_file = mainw->current_file;
2679  if (mainw->ascrap_file != -1 || !prefs->perm_audio_reader)
2680  pulse_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_GENERATED);
2681  } else {
2682  if (mainw->ascrap_file != -1 || !prefs->perm_audio_reader)
2683  pulse_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_EXTERNAL);
2684  }
2685  //mainw->pulsed->in_use = TRUE;
2686  }
2688  mainw->pulsed_read->in_achans = mainw->pulsed_read->out_achans = PA_ACHANS;
2689  mainw->pulsed_read->in_asamps = mainw->pulsed_read->out_asamps = PA_SAMPSIZE;
2690  mainw->pulsed_read->in_arate = mainw->pulsed_read->out_arate;
2691  mainw->pulsed_read->is_paused = TRUE;
2692  mainw->pulsed_read->in_use = TRUE;
2693  }
2694 #endif
2695  }
2696  }
2697 
2698  // set in case audio lock gets actioned
2700 
2702  if (mainw->osc_auto)
2705 
2706 #ifdef ENABLE_JACK
2707  if (mainw->event_list && !mainw->record && audio_player == AUD_PLAYER_JACK && mainw->jackd &&
2708  !(mainw->preview && mainw->is_processing &&
2709  !(mainw->multitrack && mainw->preview && mainw->multitrack->is_rendering))) {
2710  // if playing an event list, we switch to audio memory buffer mode
2711  if (mainw->multitrack) init_jack_audio_buffers(cfile->achans, cfile->arate, exact_preview);
2713  has_audio_buffers = TRUE;
2714  }
2715 #endif
2716 #ifdef HAVE_PULSE_AUDIO
2717  if (mainw->event_list && !mainw->record && audio_player == AUD_PLAYER_PULSE && mainw->pulsed &&
2718  !(mainw->preview && mainw->is_processing &&
2719  !(mainw->multitrack && mainw->preview && mainw->multitrack->is_rendering))) {
2720  // if playing an event list, we switch to audio memory buffer mode
2721  if (mainw->multitrack) init_pulse_audio_buffers(cfile->achans, cfile->arate, exact_preview);
2723  has_audio_buffers = TRUE;
2724  }
2725 #endif
2726 
2727  mainw->abufs_to_fill = 0;
2728  //lives_widget_context_update();
2729  //play until stopped or a stream finishes
2730  do {
2732  mainw->play_sequence++;
2733  mainw->fps_measure = 0;
2734 
2735  if (mainw->event_list && !mainw->record) {
2736  if (!pb_start_event) pb_start_event = get_first_event(mainw->event_list);
2737 
2738  if (!(mainw->preview && mainw->multitrack && mainw->multitrack->is_rendering))
2740 
2741  if (has_audio_buffers) {
2742 #ifdef ENABLE_JACK
2743  if (audio_player == AUD_PLAYER_JACK) {
2744  int i;
2745  mainw->write_abuf = 0;
2746 
2747  // fill our audio buffers now
2748  // this will also get our effects state
2749 
2750  // reset because audio sync may have set it
2751  if (mainw->multitrack) mainw->jackd->abufs[0]->arate = cfile->arate;
2752  else mainw->jackd->abufs[0]->arate = mainw->jackd->sample_out_rate;
2753  fill_abuffer_from(mainw->jackd->abufs[0], mainw->event_list, pb_start_event, exact_preview);
2754  for (i = 1; i < prefs->num_rtaudiobufs; i++) {
2755  // reset because audio sync may have set it
2756  if (mainw->multitrack) mainw->jackd->abufs[i]->arate = cfile->arate;
2757  else mainw->jackd->abufs[i]->arate = mainw->jackd->sample_out_rate;
2758  fill_abuffer_from(mainw->jackd->abufs[i], mainw->event_list, NULL, FALSE);
2759  }
2760 
2761  pthread_mutex_lock(&mainw->abuf_mutex);
2762  mainw->jackd->read_abuf = 0;
2763  mainw->abufs_to_fill = 0;
2764  pthread_mutex_unlock(&mainw->abuf_mutex);
2765  if (mainw->event_list)
2766  mainw->jackd->in_use = TRUE;
2767  }
2768 #endif
2769 #ifdef HAVE_PULSE_AUDIO
2770  if (audio_player == AUD_PLAYER_PULSE) {
2771  int i;
2772  mainw->write_abuf = 0;
2773 
2776 
2778  if (mainw->multitrack) mainw->pulsed->abufs[0]->arate = cfile->arate;
2779  else mainw->pulsed->abufs[0]->arate = mainw->pulsed->out_arate;
2780 
2782  mainw->pulsed->abufs[0]->out_asamps = mainw->pulsed->out_asamps;
2783 
2784  fill_abuffer_from(mainw->pulsed->abufs[0], mainw->event_list, pb_start_event, exact_preview);
2785  for (i = 1; i < prefs->num_rtaudiobufs; i++) {
2786  if (mainw->multitrack) mainw->pulsed->abufs[i]->arate = cfile->arate;
2787  else mainw->pulsed->abufs[i]->arate = mainw->pulsed->out_arate;
2788  mainw->pulsed->abufs[i]->out_asamps = mainw->pulsed->out_asamps;
2789  fill_abuffer_from(mainw->pulsed->abufs[i], mainw->event_list, NULL, FALSE);
2790  }
2791 
2792  pthread_mutex_lock(&mainw->abuf_mutex);
2793  mainw->pulsed->read_abuf = 0;
2794  mainw->abufs_to_fill = 0;
2795  pthread_mutex_unlock(&mainw->abuf_mutex);
2796  if (mainw->event_list) {
2797  mainw->pulsed->in_use = TRUE;
2798  }
2799  }
2800 #endif
2801  }
2802  }
2803 
2804  if (!mainw->foreign && !mainw->multitrack)
2806  else
2808 
2809  if (!mainw->multitrack || !mainw->multitrack->pb_start_event) {
2810  do_progress_dialog(FALSE, FALSE, NULL);
2811 
2812  // reset audio buffers
2813 #ifdef ENABLE_JACK
2814  if (audio_player == AUD_PLAYER_JACK && mainw->jackd) {
2815  // must do this before deinit fx
2816  pthread_mutex_lock(&mainw->abuf_mutex);
2817  mainw->jackd->read_abuf = -1;
2818  mainw->jackd->in_use = FALSE;
2819  pthread_mutex_unlock(&mainw->abuf_mutex);
2820  }
2821 #endif
2822 #ifdef HAVE_PULSE_AUDIO
2823  if (audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
2824  // must do this before deinit fx
2825  pthread_mutex_lock(&mainw->abuf_mutex);
2826  mainw->pulsed->read_abuf = -1;
2827  mainw->pulsed->in_use = FALSE;
2828  pthread_mutex_unlock(&mainw->abuf_mutex);
2829  }
2830 #endif
2831  } else {
2832  // play from middle of mt timeline
2833  cfile->next_event = mainw->multitrack->pb_start_event;
2834 
2835  if (!has_audio_buffers) {
2836  // no audio buffering
2837  // get just effects state
2838  get_audio_and_effects_state_at(mainw->multitrack->event_list, mainw->multitrack->pb_start_event, 0,
2840  }
2841 
2842  do_progress_dialog(FALSE, FALSE, NULL);
2843 
2844  // reset audio read buffers
2845 #ifdef ENABLE_JACK
2846  if (audio_player == AUD_PLAYER_JACK && mainw->jackd) {
2847  // must do this before deinit fx
2848  pthread_mutex_lock(&mainw->abuf_mutex);
2849  mainw->jackd->read_abuf = -1;
2850  mainw->jackd->in_use = FALSE;
2851  pthread_mutex_unlock(&mainw->abuf_mutex);
2852  }
2853 #endif
2854 #ifdef HAVE_PULSE_AUDIO
2855  if (audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
2856  // must do this before deinit fx
2857  pthread_mutex_lock(&mainw->abuf_mutex);
2858  mainw->pulsed->read_abuf = -1;
2859  mainw->pulsed->in_use = FALSE;
2860  pthread_mutex_unlock(&mainw->abuf_mutex);
2861  }
2862 #endif
2863  // realtime effects off (for multitrack and event_list preview)
2865 
2866  cfile->next_event = NULL;
2867 
2868  if (!(mainw->preview && mainw->multitrack && mainw->multitrack->is_rendering))
2870 
2871  // multitrack loop - go back to loop start position unless external transport moved us
2872  if (mainw->scratch == SCRATCH_NONE) {
2873  mainw->multitrack->pb_start_event = mainw->multitrack->pb_loop_event;
2874  }
2875  }
2876  mainw->effort = 0;
2877  if (mainw->multitrack) pb_start_event = mainw->multitrack->pb_start_event;
2878  } while (mainw->multitrack && (mainw->loop_cont || mainw->scratch != SCRATCH_NONE) &&
2880  }
2881 
2882  mainw->osc_block = TRUE;
2883  mainw->rte_textparm = NULL;
2884  mainw->playing_file = -1;
2885  mainw->abufs_to_fill = 0;
2886 
2887  if (!mainw->foreign) {
2889  if (prefs->allow_easing && !mainw->multitrack) {
2890  // any effects which were "easing out" should be deinited now
2892  }
2893  }
2894 
2895  if (mainw->ext_playback) {
2896 #ifndef IS_MINGW
2899 #else
2902 #endif
2903  }
2904 
2905  // play completed
2906  if (prefs->show_player_stats) {
2907  if (mainw->fps_measure > 0) {
2908  fps_med = (double)mainw->fps_measure / ((double)lives_get_relative_ticks(mainw->origsecs, mainw->orignsecs)
2910  }
2911  }
2913  mainw->osc_auto = 0;
2914 
2916  if (prefs->show_msg_area) {
2918  }
2919 
2921  if ((mainw->current_file == current_file) && CURRENT_CLIP_IS_VALID) {
2922  cfile->pointer_time = pointer_time;
2923  cfile->real_pointer_time = real_pointer_time;
2924  }
2925 
2926 #ifdef ENABLE_JACK
2927  if (audio_player == AUD_PLAYER_JACK && (mainw->jackd || mainw->jackd_read)) {
2928  if (mainw->jackd_read || mainw->aud_rec_fd != -1)
2929  jack_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2930 
2931  if (mainw->jackd_read) {
2932  mainw->jackd_read->in_use = FALSE;
2933  }
2934 
2935  // send jack transport stop
2936  if (!mainw->preview && !mainw->foreign) jack_pb_stop();
2937 
2938  // tell jack client to close audio file
2939  if (mainw->jackd && mainw->jackd->playing_file > 0) {
2940  ticks_t timeout = 0;
2943  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(mainw->jackd)) {
2944  sched_yield(); // wait for seek
2945  lives_usleep(prefs->sleep_time);
2946  }
2947  lives_alarm_clear(alarm_handle);
2948  }
2950  jack_message.command = ASERVER_CMD_FILE_CLOSE;
2951  jack_message.data = NULL;
2952  jack_message.next = NULL;
2953  mainw->jackd->msgq = &jack_message;
2954  if (timeout == 0) handle_audio_timeout();
2955  else {
2956  while (mainw->jackd->playing_file > -1) {
2957  sched_yield();
2958  lives_usleep(prefs->sleep_time);
2959  }
2960  }
2961  }
2962  } else {
2963 #endif
2964 #ifdef HAVE_PULSE_AUDIO
2965  if (audio_player == AUD_PLAYER_PULSE && (mainw->pulsed || mainw->pulsed_read)) {
2966  if (mainw->pulsed_read || mainw->aud_rec_fd != -1)
2967  pulse_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2968 
2969  if (mainw->pulsed_read) {
2970  mainw->pulsed_read->in_use = FALSE;
2971  pulse_driver_cork(mainw->pulsed_read);
2972  }
2973 
2974  // tell pulse client to close audio file
2975  if (mainw->pulsed) {
2976  if (mainw->pulsed->playing_file > 0 || mainw->pulsed->fd > 0) {
2977  ticks_t timeout = 0;
2980  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && pulse_get_msgq(mainw->pulsed)) {
2981  sched_yield(); // wait for seek
2982  lives_usleep(prefs->sleep_time);
2983  }
2984  lives_alarm_clear(alarm_handle);
2985  }
2987  pulse_message.command = ASERVER_CMD_FILE_CLOSE;
2988  pulse_message.data = NULL;
2989  pulse_message.next = NULL;
2990  mainw->pulsed->msgq = &pulse_message;
2991  if (timeout == 0) {
2993  mainw->pulsed->playing_file = -1;
2994  mainw->pulsed->fd = -1;
2995  } else {
2996  while (mainw->pulsed->playing_file > -1 || mainw->pulsed->fd > 0) {
2997  sched_yield();
2998  lives_usleep(prefs->sleep_time);
2999  }
3000  pulse_driver_cork(mainw->pulsed);
3001  }
3002  } else {
3003  pulse_driver_cork(mainw->pulsed);
3004  }
3005  }
3006  } else {
3007 #endif
3008  if (!is_realtime_aplayer(audio_player) && stopcom) {
3009  // kill sound (if still playing)
3010  lives_system(stopcom, TRUE);
3011  mainw->aud_file_to_kill = -1;
3012  lives_free(stopcom);
3013  }
3014 #ifdef ENABLE_JACK
3015  }
3016 #endif
3017 #ifdef HAVE_PULSE_AUDIO
3018  }
3019 #endif
3020 
3021  lives_freep((void **)&com);
3022  lives_freep((void **)&mainw->urgency_msg);
3023  mainw->actual_frame = 0;
3024 
3026 
3027  if (mainw->new_clip != -1) {
3029  mainw->new_clip = -1;
3030  }
3031 
3032  // stop the audio players
3033 #ifdef ENABLE_JACK
3034  if (audio_player == AUD_PLAYER_JACK && mainw->jackd) {
3035  mainw->jackd->in_use = FALSE;
3036  }
3037 #endif
3038 #ifdef HAVE_PULSE_AUDIO
3039  if (audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
3040  mainw->pulsed->in_use = FALSE;
3041  }
3042 #endif
3043 
3045  if (audio_player == AUD_PLAYER_JACK
3046  || (mainw->event_list && !mainw->record && (!mainw->is_rendering
3047  || !mainw->preview || mainw->preview_rendering)))
3048  audio_cache_end();
3049 
3050  // terminate autolives if running
3051  lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->autolives), FALSE);
3052 
3053  // PLAY FINISHED...
3054 
3055  // allow this to fail - not all sub-commands may be present
3056  if (prefs->stop_screensaver) {
3057 #ifdef GDK_WINDOWING_X11
3058  com = lives_strdup("xset s on 2>/dev/null; xset +dpms 2>/dev/null ;");
3059 
3060  if (capable->has_gconftool_2) {
3061  char *xnew = lives_strdup(" gconftool-2 --set --type bool /apps/gnome-screensaver/idle_activation_enabled "
3062  "true 2>/dev/null ;");
3063  tmp = lives_strconcat(com, xnew, NULL);
3064  lives_free(com);
3065  lives_free(xnew);
3066  com = tmp;
3067  }
3068  if (capable->has_xdg_screensaver && awinid != -1) {
3069  char *xnew = lives_strdup_printf(" xdg-screensaver resume %"PRIu64" 2>/dev/null ;", awinid);
3070  tmp = lives_strconcat(com, xnew, NULL);
3071  lives_free(com);
3072  lives_free(xnew);
3073  com = tmp;
3074  }
3075 #else
3076  if (capable->has_gconftool_2) {
3077  com = lives_strdup("gconftool-2 --set --type bool /apps/gnome-screensaver/idle_activation_enabled true 2>/dev/null ;");
3078  } else com = lives_strdup("");
3079 #endif
3080 
3081  if (com) {
3082  lives_system(com, TRUE);
3083  lives_free(com);
3084  }
3085  }
3086 
3087  if (!mainw->multitrack && mainw->ext_audio_mon)
3088  lives_toggle_tool_button_set_active(LIVES_TOGGLE_TOOL_BUTTON(mainw->ext_audio_mon), FALSE);
3089 
3090  // reset in case audio lock was actioned
3092 
3093  // TODO ***: use MIDI output port for this
3095 
3096  // we could have started by playing a generator, which could've been closed
3097  if (!mainw->files[current_file]) current_file = mainw->current_file;
3098 
3099  if (!is_realtime_aplayer(audio_player)) {
3100  // wait for audio_ended...
3101  if (cfile->achans > 0 && com2) {
3102  wait_for_stop(com2);
3103  mainw->aud_file_to_kill = -1;
3104  }
3105  lives_freep((void **)&com2);
3106  }
3107 
3108  if (CURRENT_CLIP_IS_NORMAL) {
3109  cfile->last_play_sequence = mainw->play_sequence;
3110  stfile = lives_build_filename(prefs->workdir, cfile->handle, LIVES_STATUS_FILE_NAME, NULL);
3111  lives_snprintf(cfile->info_file, PATH_MAX, "%s", stfile);
3112  lives_free(stfile);
3113  }
3114 
3116  lives_close_buffered(LIVES_POINTER_TO_INT(mainw->files[mainw->scrap_file]->ext_src));
3117  mainw->files[mainw->scrap_file]->ext_src = NULL;
3119  }
3120 
3121  if (mainw->foreign) {
3122  // recording from external window capture
3125 
3126  cfile->hsize = mainw->pwidth;
3127  cfile->vsize = mainw->pheight;
3128 
3130 
3132 
3133  return;
3134  }
3135 
3136  disable_record();
3138  mainw->lockstats = FALSE;
3139  mainw->blend_palette = WEED_PALETTE_END;
3140  mainw->audio_stretch = 1.;
3141 
3142  if (!mainw->multitrack) {
3143  if (mainw->faded || mainw->fs) {
3145  }
3146 
3147  if (mainw->sep_win) add_to_playframe();
3148 
3149  if (CURRENT_CLIP_HAS_VIDEO) {
3150  resize(1.);
3152  lives_frame_set_label(LIVES_FRAME(mainw->playframe), NULL);
3153  }
3154 
3155  if (palette->style & STYLE_1) {
3157  }
3158 
3159  if (prefs->show_msg_area && !mainw->multitrack) {
3161  reset_message_area();
3162  }
3163 
3169 
3170  if (!prefs->hide_framebar && !prefs->hfbwnp) {
3172  }
3173  }
3174 
3175  if (!is_realtime_aplayer(audio_player)) mainw->mute = mute;
3176 
3178  if (mainw->play_window) {
3179  if (mainw->fs) {
3185  }
3187  }
3189  kill_play_window();
3190  } else {
3192  if (CURRENT_CLIP_IS_VALID && cfile->is_loaded && cfile->frames > 0 && !mainw->is_rendering &&
3193  (cfile->clip_type != CLIP_TYPE_GENERATOR)) {
3194  if (mainw->preview_controls) {
3196  if (prefs->show_gui) {
3201  //lives_widget_grab_focus(mainw->preview_spinbutton);
3202  }
3203  }
3204  if (mainw->current_file != current_file) {
3205  // now we have to guess how to center the play window
3206  mainw->opwx = mainw->opwy = -1;
3207  mainw->preview_frame = 0;
3208  }
3209  }
3210 
3211  if (!mainw->multitrack) {
3212  mainw->playing_file = -2;
3215  mainw->playing_file = -1;
3217 
3218  if (!mainw->preview_box) {
3219  // create the preview box that shows frames
3220  make_preview_box();
3221  }
3222  // and add it to the play window
3225  lives_container_add(LIVES_CONTAINER(mainw->play_window), mainw->preview_box);
3227  }
3228 
3229  if (mainw->play_window) {
3230  if (prefs->show_playwin) {
3231  lives_window_present(LIVES_WINDOW(mainw->play_window));
3240  lives_window_center(LIVES_WINDOW(mainw->play_window));
3243  // *INDENT-OFF*
3244  }}}}}
3245  // *INDENT-ON*
3246 
3248  if (mainw->frame_layer) {
3250  mainw->frame_layer = NULL;
3251  }
3252 
3253  if (mainw->lazy) mainw->lazy = lives_idle_add_simple(lazy_startup_checks, NULL);
3254 
3255  cliplist = mainw->cliplist;
3256  while (cliplist) {
3257  int i = LIVES_POINTER_TO_INT(cliplist->data);
3261  cliplist = cliplist->next;
3262  }
3263 
3264  if (!mainw->foreign) {
3266  }
3267 
3268  if (CURRENT_CLIP_IS_VALID) cfile->play_paused = FALSE;
3269 
3272  int xcurrent_file = mainw->current_file;
3274  mainw->current_file = xcurrent_file;
3275  }
3276 
3278 
3280  lives_accel_group_disconnect(LIVES_ACCEL_GROUP(mainw->accel_group), freeze_closure);
3281  lives_accel_group_disconnect(LIVES_ACCEL_GROUP(mainw->accel_group), bg_freeze_closure);
3282 
3283  if (needsadone) d_print_done();
3284 
3286  if (mainw->frame_layer_preload && mainw->pred_clip != -1) {
3289  }
3290  mainw->frame_layer_preload = NULL;
3291 
3292  if (!prefs->vj_mode) {
3294  if (mainw->size_warn) {
3295  if (mainw->size_warn > 0 && mainw->files[mainw->size_warn]) {
3296  char *smsg = lives_strdup_printf(
3297  _("\n\nSome frames in the clip\n%s\nare wrongly sized.\nYou should "
3298  "click on Tools--->Resize All\n"
3299  "and resize all frames to the current size.\n"),
3302  do_error_dialog(smsg);
3304  lives_free(smsg);
3305  }
3306  }
3307  }
3308  mainw->size_warn = 0;
3309 
3310  // set processing state again if a previewe finished
3311  // CAUTION !!
3314 
3316 
3317  // TODO - ????
3318  if (CURRENT_CLIP_IS_VALID && cfile->clip_type == CLIP_TYPE_DISK && cfile->frames == 0 && mainw->record_perf) {
3320  lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->record_perf), FALSE);
3322  }
3323 
3324  // TODO - can this be done earlier ?
3325  if (mainw->cancelled == CANCEL_APP_QUIT) on_quit_activate(NULL, NULL);
3326 
3328 
3329 #ifdef ENABLE_JACK
3330  if (audio_player == AUD_PLAYER_JACK && mainw->jackd) {
3331  ticks_t timeout;
3333  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(mainw->jackd)) {
3334  sched_yield();
3335  lives_usleep(prefs->sleep_time);
3336  }
3337  lives_alarm_clear(alarm_handle);
3338  if (timeout == 0) {
3340  }
3341  if (has_audio_buffers) {
3344  }
3345  }
3346 #endif
3347 #ifdef HAVE_PULSE_AUDIO
3348  if (audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
3349  ticks_t timeout;
3351  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && pulse_get_msgq(mainw->pulsed)) {
3352  sched_yield();
3353  lives_usleep(prefs->sleep_time);
3354  }
3355  lives_alarm_clear(alarm_handle);
3356  if (timeout == 0) {
3358  }
3359 
3360  if (has_audio_buffers) {
3363  }
3364  }
3365 #endif
3366 
3367  if (prefs->show_player_stats) {
3368  if (mainw->fps_measure > 0) {
3369  d_print(_("Average FPS was %.4f (%d frames in clock time of %f)\n"), fps_med, mainw->fps_measure,
3371  }
3372  }
3373 
3374  if (THREADVAR(bad_aud_file)) {
3376  do_write_failed_error_s(THREADVAR(bad_aud_file), NULL);
3377  lives_freep((void **)&THREADVAR(bad_aud_file));
3378  }
3379 
3380  if (mainw->new_vpp) {
3381  mainw->noswitch = FALSE;
3383  mainw->new_vpp = NULL;
3384  mainw->noswitch = TRUE;
3385  }
3386 
3390  }
3391 
3392  if (!mainw->preview && CURRENT_CLIP_IS_VALID && cfile->clip_type == CLIP_TYPE_GENERATOR) {
3393  mainw->osc_block = TRUE;
3394  weed_generator_end((weed_plant_t *)cfile->ext_src);
3395  mainw->osc_block = FALSE;
3396  } else {
3397  if (mainw->current_file > -1) {
3398  if (mainw->toy_type == LIVES_TOY_MAD_FRAMES && !cfile->opening) {
3399  showclipimgs();
3400  if (!mainw->multitrack)
3402  }
3403  }
3404  }
3405 
3406  if (CURRENT_CLIP_IS_VALID) {
3407  if (!mainw->multitrack) {
3408  lives_ce_update_timeline(0, cfile->real_pointer_time);
3409  mainw->ptrtime = cfile->real_pointer_time;
3412  }
3413  }
3414 
3415  if (!mainw->multitrack) {
3416  //lives_table_set_column_homogeneous(LIVES_TABLE(mainw->pf_grid), FALSE);
3417  }
3418 
3419  if (prefs->show_gui && ((mainw->multitrack && mainw->double_size) ||
3422  //if (prefs->gui_monitor == 0) lives_window_move(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), 0, 0);
3423  if (prefs->open_maximised)
3426  }
3427 
3428  if (!mainw->preview && (mainw->current_file == -1 || (CURRENT_CLIP_IS_VALID && !cfile->opening))) {
3429  sensitize();
3430  }
3431 
3432  if (CURRENT_CLIP_IS_VALID && cfile->opening) {
3435  lives_widget_set_sensitive(mainw->loop_video, cfile->achans > 0 && cfile->frames > 0);
3436  }
3437 
3441  }
3442 
3444 
3445  if (!mainw->multitrack) {
3447  if (prefs->hfbwnp) {
3449  }
3452  }
3453 
3454  if (!mainw->multitrack) mainw->osc_block = FALSE;
3455 
3456  reset_clipmenu();
3457 
3458  lives_menu_item_set_accel_path(LIVES_MENU_ITEM(mainw->quit), LIVES_ACCEL_PATH_QUIT);
3459 
3461  set_main_title(cfile->name, 0);
3462 
3463  if (!mainw->multitrack && !mainw->foreign && CURRENT_CLIP_IS_VALID && (!cfile->opening ||
3464  cfile->clip_type == CLIP_TYPE_FILE)) {
3465  showclipimgs();
3467  }
3468 
3469  if (prefs->show_msg_area) {
3470  if (mainw->idlemax == 0) {
3471  lives_idle_add_simple(resize_message_area, NULL);
3472  }
3474  }
3475 
3477 
3479  if (mainw->record) {
3480  lives_idle_add_simple(render_choice_idle, LIVES_INT_TO_POINTER(FALSE));
3481  }
3482 
3484 
3486 
3488  mainw->noswitch = FALSE;
3489 }
3490 
3491 
3498 int close_temp_handle(int new_clip) {
3499  char *com, *permitname;
3500  int clipno = mainw->current_file;
3501 
3502  if (!IS_VALID_CLIP(new_clip)) new_clip = -1;
3503  if (!IS_VALID_CLIP(clipno)) {
3504  mainw->current_file = new_clip;
3505  return new_clip;
3506  }
3507  if (cfile->clip_type != CLIP_TYPE_TEMP
3509  close_current_file(new_clip);
3510  }
3511 
3512  // as a safety feature we create a special file which allows the back end to delete the directory
3513  permitname = lives_build_filename(prefs->workdir, cfile->handle, TEMPFILE_MARKER "." LIVES_FILE_EXT_TMP, NULL);
3514  lives_touch(permitname);
3515  lives_free(permitname);
3516 
3517  com = lives_strdup_printf("%s close \"%s\"", prefs->backend, cfile->handle);
3518  lives_system(com, TRUE);
3519  lives_free(com);
3520  lives_freep((void **)&mainw->files[clipno]);
3521 
3522  mainw->current_file = new_clip;
3523 
3524  if (mainw->first_free_file == ALL_USED || mainw->first_free_file > clipno)
3525  mainw->first_free_file = clipno;
3526  return new_clip;
3527 }
3528 
3529 
3534 static int get_next_free_file(void) {
3535  int idx = mainw->first_free_file++;
3539  }
3540  return idx;
3541 }
3542 
3543 
3571 boolean get_temp_handle(int index) {
3572  boolean is_unique, create = FALSE;
3573 
3574  if (CURRENT_CLIP_IS_TEMP) {
3575  break_me("temp clip in temp clip !!");
3576  return TRUE;
3577  }
3578 
3579  if (index < -1 || index > MAX_FILES) {
3580  char *msg = lives_strdup_printf("Attempt to create invalid new temp clip %d\n", index);
3581  LIVES_WARN(msg);
3582  lives_free(msg);
3583  return FALSE;
3584  }
3585 
3586  if (index == -1) {
3587  if (mainw->first_free_file == ALL_USED) {
3588  too_many_files();
3589  return FALSE;
3590  }
3591  create = TRUE;
3592  index = mainw->first_free_file;
3593  get_next_free_file();
3594  }
3595 
3596  do {
3597  is_unique = TRUE;
3598 
3599  // get handle from info file, the first time we will also malloc a
3600  // new "file" struct here and create a directory in prefs->workdir
3601  if (!get_handle_from_info_file(index)) {
3602  lives_freep((void **)&mainw->files[index]);
3603  if (mainw->first_free_file == ALL_USED || index < mainw->first_free_file)
3604  mainw->first_free_file = index;
3605  return FALSE;
3606  }
3607 
3608  if (*mainw->set_name) {
3609  char *setclipdir = CLIPDIR(cfile->handle);
3610  if (lives_file_test(setclipdir, LIVES_FILE_TEST_IS_DIR)) is_unique = FALSE;
3611  lives_free(setclipdir);
3612  }
3613  } while (!is_unique);
3614 
3615  mainw->current_file = index;
3616 
3617  if (create) {
3618  // create a marker file in directory, else we will be barred from
3619  // removing it
3620  char *canremove = lives_build_filename(prefs->workdir, cfile->handle,
3622  lives_touch(canremove);
3623  lives_free(canremove);
3624  // fill with default values
3625  create_cfile(index, cfile->handle, FALSE);
3626  cfile->clip_type = CLIP_TYPE_TEMP;
3627  }
3628  return TRUE;
3629 }
3630 
3631 
3656 lives_clip_t *create_cfile(int new_file, const char *handle, boolean is_loaded) {
3657  lives_clip_t *sfile;
3658  char *stfile;
3659 
3660  if (new_file == -1) {
3661  // if new_file == -1, we are going to create a new clip
3662  new_file = mainw->first_free_file;
3663  if (new_file == -1) {
3664  too_many_files();
3665  return NULL;
3666  }
3667 
3668  mainw->current_file = new_file;
3669  get_next_free_file();
3670 
3671  if (new_file < 0 || new_file > MAX_FILES || IS_VALID_CLIP(new_file)) {
3672  char *msg = lives_strdup_printf("Attempt to create invalid new clip %d\n", new_file);
3673  LIVES_WARN(msg);
3674  lives_free(msg);
3675  return NULL;
3676  }
3677 
3678  if (!handle) {
3679  // if handle is NULL, we create a new clip on disk, switch to it
3680  // (unused)
3681  if (!get_handle_from_info_file(new_file)) return NULL;
3682  sfile = mainw->files[new_file];
3683  } else {
3684  // else just create the in-memory part and set the handle
3685  sfile = mainw->files[new_file] = (lives_clip_t *)(lives_calloc(1, sizeof(lives_clip_t)));
3686  if (!sfile) return NULL;
3687  lives_snprintf(sfile->handle, 256, "%s", handle);
3688  }
3689  }
3690 
3691  mainw->current_file = new_file;
3692 
3693  cfile->is_loaded = is_loaded;
3694 
3695  // any cfile (clip) initialisation goes in here
3696  lives_memcpy((void *)&cfile->binfmt_check.chars, "LiVESXXX", 8);
3697  cfile->binfmt_version.num = make_version_hash(LiVES_VERSION);
3698  cfile->binfmt_bytes.size = (size_t)((void *)&cfile->binfmt_end - (void *)cfile);
3699  cfile->menuentry = NULL;
3700  cfile->start = cfile->end = 0;
3701  cfile->old_frames = cfile->opening_frames = cfile->frames = 0;
3702  lives_snprintf(cfile->type, 40, "%s", _("Unknown"));
3703  cfile->f_size = 0l;
3704  cfile->achans = 0;
3705  cfile->arate = 0;
3706  cfile->arps = 0;
3707  cfile->afilesize = 0l;
3708  cfile->asampsize = 0;
3709  cfile->adirection = LIVES_DIRECTION_FORWARD;
3710  cfile->undoable = FALSE;
3711  cfile->redoable = FALSE;
3712  cfile->changed = FALSE;
3713  cfile->was_in_set = FALSE;
3714  cfile->hsize = cfile->vsize = cfile->ohsize = cfile->ovsize = 0;
3715  cfile->fps = cfile->pb_fps = prefs->default_fps;
3716  cfile->resample_events = NULL;
3717  cfile->insert_start = cfile->insert_end = 0;
3718  cfile->is_untitled = TRUE;
3719  cfile->was_renamed = FALSE;
3720  cfile->undo_action = UNDO_NONE;
3721  cfile->opening_audio = cfile->opening = cfile->opening_only_audio = FALSE;
3722  cfile->pointer_time = 0.;
3723  cfile->real_pointer_time = 0.;
3724  cfile->restoring = cfile->opening_loc = cfile->nopreview = FALSE;
3725  cfile->video_time = cfile->laudio_time = cfile->raudio_time = 0.;
3726  cfile->freeze_fps = 0.;
3727  cfile->last_vframe_played = 0;
3728  cfile->frameno = cfile->last_frameno = cfile->saved_frameno = 1;
3729  cfile->progress_start = cfile->progress_end = 0;
3730  cfile->play_paused = cfile->nokeep = FALSE;
3731  cfile->undo_start = cfile->undo_end = 0;
3732  cfile->ext_src = NULL;
3733  cfile->ext_src_type = LIVES_EXT_SRC_NONE;
3734  cfile->clip_type = CLIP_TYPE_DISK;
3735  cfile->ratio_fps = FALSE;
3736  cfile->aseek_pos = 0;
3737  cfile->unique_id = gen_unique_id();
3738  cfile->layout_map = NULL;
3739  cfile->frame_index = cfile->frame_index_back = NULL;
3740  cfile->fx_frame_pump = 0;
3741  cfile->pumper = NULL;
3742  cfile->stored_layout_frame = 0;
3743  cfile->stored_layout_audio = 0.;
3744  cfile->stored_layout_fps = 0.;
3745  cfile->stored_layout_idx = -1;
3746  cfile->interlace = LIVES_INTERLACE_NONE;
3747  cfile->subt = NULL;
3748  cfile->no_proc_sys_errors = cfile->no_proc_read_errors = cfile->no_proc_write_errors = FALSE;
3749  cfile->keep_without_preview = FALSE;
3750  cfile->cb_src = -1;
3751  cfile->needs_update = cfile->needs_silent_update = FALSE;
3752  cfile->audio_waveform = NULL;
3753  cfile->md5sum[0] = 0;
3754  cfile->gamma_type = WEED_GAMMA_SRGB;
3755  cfile->last_play_sequence = 0;
3756  cfile->tcache_dubious_from = 0;
3757  cfile->tcache_height = 0;
3758  cfile->tcache = NULL;
3759  cfile->checked = FALSE;
3760  cfile->has_binfmt = TRUE;
3761 
3762  if (!strcmp(prefs->image_ext, LIVES_FILE_EXT_JPG)) cfile->img_type = IMG_TYPE_JPEG;
3763  else cfile->img_type = IMG_TYPE_PNG;
3764 
3765  cfile->bpp = (cfile->img_type == IMG_TYPE_JPEG) ? 24 : 32;
3766  cfile->deinterlace = FALSE;
3767 
3768  cfile->play_paused = FALSE;
3769  cfile->header_version = LIVES_CLIP_HEADER_VERSION;
3770 
3771  cfile->event_list = cfile->event_list_back = NULL;
3772  cfile->next_event = NULL;
3773  cfile->vol = 1.;
3774 
3775  lives_memset(cfile->name, 0, 1);
3776  lives_memset(cfile->mime_type, 0, 1);
3777  lives_memset(cfile->file_name, 0, 1);
3778  lives_memset(cfile->save_file_name, 0, 1);
3779 
3780  lives_memset(cfile->comment, 0, 1);
3781  lives_memset(cfile->author, 0, 1);
3782  lives_memset(cfile->title, 0, 1);
3783  lives_memset(cfile->keywords, 0, 1);
3784 
3785  cfile->signed_endian = AFORM_UNKNOWN;
3786  lives_snprintf(cfile->undo_text, 32, "%s", _("_Undo"));
3787  lives_snprintf(cfile->redo_text, 32, "%s", _("_Redo"));
3788 
3789  stfile = lives_build_filename(prefs->workdir, cfile->handle, LIVES_STATUS_FILE_NAME, NULL);
3790 
3791  lives_snprintf(cfile->info_file, PATH_MAX, "%s", stfile);
3792  lives_free(stfile);
3793 
3794  // backwards compat.
3795  cfile->checked_for_old_header = FALSE;
3796  cfile->has_old_header = FALSE;
3797 
3798  return cfile;
3799 }
3800 
3801 
3803  // utility function to get clip name
3804  return lives_strdup_printf(_("Untitled%d"), number);
3805 }
3806 
3807 
3808 int create_nullvideo_clip(const char *handle) {
3809  // create a file with no video, just produces blank frames
3810  // may be used to playback with audio, for testign etc.
3811  int new_file;
3812  int current_file = mainw->current_file;
3813  create_cfile(-1, handle, TRUE);
3814  new_file = mainw->current_file;
3815  mainw->current_file = current_file;
3816  mainw->files[new_file]->clip_type = CLIP_TYPE_NULL_VIDEO;
3817  return new_file;
3818 }
3819 
3820 
3821 boolean get_new_handle(int index, const char *name) {
3822  // here is where we first initialize for the clipboard
3823  // and for paste_as_new, and restore, etc.
3824  // pass in name as NULL or "" and it will be set with an untitled number
3825 
3826  // this function *does not* change mainw->current_file (except briefly), or add to the menu
3827  // or update mainw->clips_available
3828 
3829  // differences from get_temp_handle:
3830  // - here we dont't switch clips;
3831  // - index is normally passed in rather than generated (pulled from next_free_file) - this allows
3832  // the caller to know the index number and do preconfig before calling
3833  // - we set name and file_name from the name parameter, or if name is NULL, we set an untitled name
3834  // and increment mainw->untitled_number
3835  // - the clip should be closed using close_current_file() instead of close_temp_handle()
3836 
3837  char *xname;
3838 
3839  int current_file = mainw->current_file;
3840 
3841  // if TRUE, changes mainw->current_file (and hence cfile)
3842  if (!get_temp_handle(index)) return FALSE;
3843 
3844  // setup would have been done already in get_temp_handle()
3845  if (index == -1) index = mainw->current_file;
3846 
3847  else create_cfile(index, cfile->handle, FALSE);
3848 
3849  // note : don't need to update first_free_file for the clipboard
3850  // because we used index 0 instead of a free index number
3851  if (index != 0) {
3852  get_next_free_file();
3853  }
3854 
3855  if (!name || !*name) {
3856  cfile->is_untitled = TRUE;
3858  } else xname = lives_strdup(name);
3859 
3860  lives_snprintf(cfile->file_name, PATH_MAX, "%s", xname);
3861  lives_snprintf(cfile->name, CLIP_NAME_MAXLEN, "%s", xname);
3862 
3863  mainw->current_file = current_file;
3864 
3865  lives_free(xname);
3866  return TRUE;
3867 }
3868 
3869 
3870 boolean add_file_info(const char *check_handle, boolean aud_only) {
3871  // file information has been retrieved, set struct cfile with details
3872  // contained in mainw->msg. We do this twice, once before opening the file, once again after.
3873  // The first time, frames and afilesize may not be correct.
3874  char *mesg, *mesg1;
3875  char **array;
3876  char *test_fps_string1;
3877  char *test_fps_string2;
3878 
3879  if (aud_only && !mainw->save_with_sound) {
3880  cfile->arps = cfile->arate = cfile->achans = cfile->asampsize = 0;
3881  cfile->afilesize = 0l;
3882  return TRUE;
3883  }
3884 
3885  if (!strcmp(mainw->msg, "killed")) {
3886  char *com;
3887  // user pressed "enough"
3888  // just in case last frame is damaged, we delete it (physically, otherwise it will get dragged in when the file is opened)
3889  if (!cfile->ext_src) {
3890  cfile->frames = get_frame_count(mainw->current_file, cfile->opening_frames);
3891  if (cfile->frames > 1) {
3892  com = lives_strdup_printf("%s cut \"%s\" %d %d %d %d \"%s\" %.3f %d %d %d",
3893  prefs->backend, cfile->handle, cfile->frames, cfile->frames,
3894  FALSE, cfile->frames, get_image_ext_for_type(cfile->img_type),
3895  0., 0, 0, 0);
3896  lives_system(com, FALSE);
3897  lives_free(com);
3898  cfile->frames--;
3899  }
3900  }
3901 
3902  // commit audio
3904  lives_rm(cfile->info_file);
3905 
3906  com = lives_strdup_printf("%s commit_audio \"%s\" 1", prefs->backend, cfile->handle);
3907  lives_system(com, TRUE);
3908  lives_free(com);
3909 
3911 
3913  d_print_enough(cfile->frames);
3914 
3915  if (prefs->auto_trim_audio) {
3916  if (cfile->laudio_time > cfile->video_time) {
3917  d_print(_("Auto trimming %.2f seconds of audio at end..."), cfile->laudio_time - cfile->video_time);
3918  if (on_trim_audio_activate(NULL, LIVES_INT_TO_POINTER(0))) d_print_done();
3919  else d_print("\n");
3920  cfile->changed = FALSE;
3921  }
3922  }
3923  } else {
3924  if (check_handle) {
3925  int npieces = get_token_count(mainw->msg, '|');
3926  if (npieces < 2) return FALSE;
3927 
3928  array = lives_strsplit(mainw->msg, "|", npieces);
3929 
3930  if (!strcmp(array[0], "error")) {
3931  if (npieces >= 3) {
3932  mesg = lives_strdup_printf(_("\nAn error occurred doing\n%s\n"), array[2]);
3933  LIVES_ERROR(array[2]);
3934  } else mesg = (_("\nAn error occurred opening the file\n"));
3936  do_error_dialog(mesg);
3938  lives_free(mesg);
3939  lives_strfreev(array);
3940  return FALSE;
3941  }
3942 
3943  // sanity check handle against status file
3944  // (this should never happen...)
3945  if (strcmp(check_handle, array[1])) {
3946  LIVES_ERROR("Handle!=statusfile !");
3947  mesg = lives_strdup_printf(_("\nError getting file info for clip %s.\nBad things may happen with this clip.\n"),
3948  check_handle);
3950  do_error_dialog(mesg);
3952  lives_free(mesg);
3953  lives_strfreev(array);
3954  return FALSE;
3955  }
3956 
3957  cfile->arps = cfile->arate = atoi(array[9]);
3958  cfile->achans = atoi(array[10]);
3959  cfile->asampsize = atoi(array[11]);
3960  cfile->signed_endian = get_signed_endian(atoi(array[12]), atoi(array[13]));
3961  cfile->afilesize = strtol(array[14], NULL, 10);
3962  if (aud_only) {
3963  lives_strfreev(array);
3964  return TRUE;
3965  }
3966 
3967  cfile->frames = atoi(array[2]);
3968  if (aud_only) {
3969  lives_strfreev(array);
3970  return TRUE;
3971  }
3972  lives_snprintf(cfile->type, 40, "%s", array[3]);
3973  cfile->hsize = atoi(array[4]);
3974  cfile->vsize = atoi(array[5]);
3975  cfile->bpp = atoi(array[6]);
3976  cfile->pb_fps = cfile->fps = lives_strtod(array[7], NULL);
3977  cfile->f_size = strtol(array[8], NULL, 10);
3978 
3979  if (npieces > 15 && array[15]) {
3980  if (prefs->btgamma) {
3981  if (!strcmp(array[15], "bt709")) cfile->gamma_type = WEED_GAMMA_BT709;
3982  }
3983  }
3984 
3985  if (!*cfile->title && npieces > 16 && array[16]) {
3986  lives_snprintf(cfile->title, 1024, "%s", lives_strstrip(array[16]));
3987  }
3988  if (!*cfile->author && npieces > 17 && array[17]) {
3989  lives_snprintf(cfile->author, 1024, "%s", lives_strstrip(array[17]));
3990  }
3991  if (!*cfile->comment && npieces > 18 && array[18]) {
3992  lives_snprintf(cfile->comment, 1024, "%s", lives_strstrip(array[18]));
3993  }
3994 
3995  lives_strfreev(array);
3996  }
3997  }
3998 
3999  cfile->video_time = 0;
4000 
4001  test_fps_string1 = lives_strdup_printf("%.3f00000", cfile->fps);
4002  test_fps_string2 = lives_strdup_printf("%.8f", cfile->fps);
4003 
4004  if (strcmp(test_fps_string1, test_fps_string2)) {
4005  cfile->ratio_fps = TRUE;
4006  } else {
4007  cfile->ratio_fps = FALSE;
4008  }
4009  lives_free(test_fps_string1);
4010  lives_free(test_fps_string2);
4011 
4012  if (!mainw->save_with_sound) {
4013  cfile->arps = cfile->arate = cfile->achans = cfile->asampsize = 0;
4014  cfile->afilesize = 0l;
4015  }
4016 
4017  if (cfile->frames <= 0) {
4018  if (cfile->afilesize == 0l && cfile->is_loaded) {
4019  // we got no video or audio...
4020  return FALSE;
4021  }
4022  cfile->start = cfile->end = cfile->undo_start = cfile->undo_end = 0;
4023  } else {
4024  // start with all selected
4025  cfile->start = 1;
4026  cfile->end = cfile->frames;
4027  cfile->undo_start = cfile->start;
4028  cfile->undo_end = cfile->end;
4029  }
4030 
4031  cfile->orig_file_name = TRUE;
4032  cfile->is_untitled = FALSE;
4033 
4034  // some files give us silly frame rates, even single frames...
4035  // fps of 1000. is used for some streams (i.e. play each frame as it is received)
4036  if (cfile->fps == 0. || cfile->fps == 1000. || (cfile->frames < 2 && cfile->is_loaded)) {
4037 
4038  if ((cfile->afilesize * cfile->asampsize * cfile->arate * cfile->achans == 0) || cfile->frames < 2) {
4039  if (cfile->frames != 1) {
4040  d_print(_("\nPlayback speed not found or invalid ! Using default fps of %.3f fps. \n"
4041  "Default can be set in Tools | Preferences | Misc.\n"),
4042  prefs->default_fps);
4043  }
4044  cfile->pb_fps = cfile->fps = prefs->default_fps;
4045  } else {
4046  cfile->laudio_time = cfile->raudio_time = cfile->afilesize / cfile->asampsize * 8. / cfile->arate / cfile->achans;
4047  cfile->pb_fps = cfile->fps = 1.*(int)(cfile->frames / cfile->laudio_time);
4048  if (cfile->fps > FPS_MAX || cfile->fps < 1.) {
4049  cfile->pb_fps = cfile->fps = prefs->default_fps;
4050  }
4051  d_print(_("Playback speed was adjusted to %.3f frames per second to fit audio.\n"), cfile->fps);
4052  }
4053  }
4054 
4055  cfile->video_time = (double)cfile->frames / cfile->fps;
4056 
4057  if (cfile->opening) return TRUE;
4058 
4059  if ((!strcmp(cfile->type, LIVES_IMAGE_TYPE_JPEG) || !strcmp(cfile->type, LIVES_IMAGE_TYPE_PNG))) {
4060  mesg = (_("Image format detected"));
4061  d_print(mesg);
4062  lives_free(mesg);
4063  return TRUE;
4064  }
4065 
4066  if (cfile->bpp == 256) {
4067  mesg1 = lives_strdup_printf(_("Frames=%d type=%s size=%dx%d *bpp=Greyscale* fps=%.3f\nAudio:"), cfile->frames,
4068  cfile->type, cfile->hsize, cfile->vsize, cfile->fps);
4069  } else {
4070  if (cfile->bpp != 32) cfile->bpp = 24; // assume RGB24 *** TODO - check
4071  mesg1 = lives_strdup_printf(_("Frames=%d type=%s size=%dx%d bpp=%d fps=%.3f\nAudio:"), cfile->frames,
4072  cfile->type, cfile->hsize, cfile->vsize, cfile->bpp, cfile->fps);
4073  }
4074 
4075  if (cfile->achans == 0) {
4076  mesg = lives_strdup_printf(_("%s none\n"), mesg1);
4077  } else {
4078  mesg = lives_strdup_printf(P_("%s %d Hz %d channel %d bps\n", "%s %d Hz %d channels %d bps\n", cfile->achans),
4079  mesg1, cfile->arate, cfile->achans, cfile->asampsize);
4080  }
4081  d_print(mesg);
4082  lives_free(mesg1);
4083  lives_free(mesg);
4084 
4085  // get the author,title,comments
4086  if (*cfile->author) {
4087  d_print(_(" - Author: %s\n"), cfile->author);
4088  }
4089  if (*cfile->title) {
4090  d_print(_(" - Title: %s\n"), cfile->title);
4091  }
4092  if (*cfile->comment) {
4093  d_print(_(" - Comment: %s\n"), cfile->comment);
4094  }
4095 
4096  return TRUE;
4097 }
4098 
4099 
4100 boolean save_file_comments(int fileno) {
4101  // save the comments etc for smogrify
4102  int retval;
4103  int comment_fd;
4104  char *comment_file = lives_strdup_printf("%s/%s/.comment", prefs->workdir, cfile->handle);
4105  lives_clip_t *sfile = mainw->files[fileno];
4106 
4107  lives_rm(comment_file);
4108 
4109  do {
4110  retval = 0;
4111  comment_fd = creat(comment_file, S_IRUSR | S_IWUSR);
4112  if (comment_fd < 0) {
4113  THREADVAR(write_failed) = TRUE;
4114  retval = do_write_failed_error_s_with_retry(comment_file, lives_strerror(errno));
4115  } else {
4116  THREADVAR(write_failed) = FALSE;
4117  lives_write(comment_fd, sfile->title, strlen(sfile->title), TRUE);
4118  lives_write(comment_fd, "||%", 3, TRUE);
4119  lives_write(comment_fd, sfile->author, strlen(sfile->author), TRUE);
4120  lives_write(comment_fd, "||%", 3, TRUE);
4121  lives_write(comment_fd, sfile->comment, strlen(sfile->comment), TRUE);
4122 
4123  close(comment_fd);
4124 
4125  if (THREADVAR(write_failed)) {
4126  retval = do_write_failed_error_s_with_retry(comment_file, NULL);
4127  }
4128  }
4129  } while (retval == LIVES_RESPONSE_RETRY);
4130 
4131  lives_free(comment_file);
4132 
4133  if (THREADVAR(write_failed)) return FALSE;
4134 
4135  return TRUE;
4136 }
4137 
4138 
4139 void wait_for_stop(const char *stop_command) {
4140  FILE *infofile;
4141 
4142  // only used for audio player mplayer or audio player sox
4143 
4144 # define SECOND_STOP_TIME 0.1
4145 # define STOP_GIVE_UP_TIME 1.0
4146 
4147  double time_waited = 0.;
4148  boolean sent_second_stop = FALSE;
4149 
4150  // send another stop if necessary
4151  while (!(infofile = fopen(cfile->info_file, "r"))) {
4153  lives_usleep(prefs->sleep_time);
4154  time_waited += 1000000. / prefs->sleep_time;
4155  if (time_waited > SECOND_STOP_TIME && !sent_second_stop) {
4156  lives_system(stop_command, TRUE);
4157  sent_second_stop = TRUE;
4158  }
4159 
4160  if (time_waited > STOP_GIVE_UP_TIME) {
4161  // give up waiting, but send a last try...
4162  lives_system(stop_command, TRUE);
4163  break;
4164  }
4165  }
4166  if (infofile) fclose(infofile);
4167 }
4168 
4169 
4170 boolean save_frame_inner(int clip, int frame, const char *file_name, int width, int height, boolean from_osc) {
4171  // save 1 frame as an image
4172  // width==-1, height==-1 to use "natural" values
4173  LiVESResponseType resp;
4174  lives_clip_t *sfile = mainw->files[clip];
4175  char full_file_name[PATH_MAX];
4176  char *com, *tmp;
4177 
4178  boolean allow_over = FALSE;
4179 
4180  if (!from_osc && strrchr(file_name, '.') == NULL) {
4181  lives_snprintf(full_file_name, PATH_MAX, "%s.%s", file_name,
4183  } else {
4184  lives_snprintf(full_file_name, PATH_MAX, "%s", file_name);
4185  if (!allow_over) allow_over = TRUE;
4186  }
4187 
4188  // TODO - allow overwriting in sandbox
4189  if (from_osc && lives_file_test(full_file_name, LIVES_FILE_TEST_EXISTS)) return FALSE;
4190 
4191  tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL);
4192 
4193  if (!mainw->multitrack) {
4194  d_print(_("Saving frame %d as %s..."), frame, full_file_name);
4195 
4196  if (sfile->clip_type == CLIP_TYPE_FILE) {
4197  frames_t res = virtual_to_images(clip, frame, frame, FALSE, NULL);
4198  if (res <= 0) {
4200  return FALSE;
4201  }
4202  }
4203 
4204  do {
4205  resp = LIVES_RESPONSE_NONE;
4206 
4207  com = lives_strdup_printf("%s save_frame %s %d \"%s\" %d %d", prefs->backend_sync, sfile->handle,
4208  frame, tmp, width, height);
4209  lives_system(com, FALSE);
4210  lives_free(com);
4211 
4212  if (THREADVAR(write_failed)) {
4213  THREADVAR(write_failed) = 0;
4215  resp = do_file_perm_error(tmp, TRUE);
4216  if (resp == LIVES_RESPONSE_CANCEL) {
4217  lives_free(tmp);
4218  return FALSE;
4219  }
4220  }
4221  if (!THREADVAR(com_failed)) {
4222  lives_free(tmp);
4223  d_print_done();
4224  return TRUE;
4225  }
4226  } while (resp == LIVES_RESPONSE_RETRY);
4227  } else {
4228  // multitrack mode
4229  LiVESError *gerr = NULL;
4230  LiVESPixbuf *pixbuf;
4231  int retval;
4232 
4234  resize_layer(mainw->frame_layer, sfile->hsize, sfile->vsize, LIVES_INTERP_BEST, WEED_PALETTE_RGB24, 0);
4235  convert_layer_palette(mainw->frame_layer, WEED_PALETTE_RGB24, 0);
4236  weed_set_int_value(mainw->frame_layer, WEED_LEAF_GAMMA_TYPE, WEED_GAMMA_SRGB);
4238  weed_plant_free(mainw->frame_layer);
4239  mainw->frame_layer = NULL;
4240 
4241  do {
4242  retval = 0;
4243  if (sfile->img_type == IMG_TYPE_JPEG) lives_pixbuf_save(pixbuf, tmp, IMG_TYPE_JPEG, 100,
4244  sfile->hsize, sfile->vsize, &gerr);
4245  else if (sfile->img_type == IMG_TYPE_PNG) lives_pixbuf_save(pixbuf, tmp, IMG_TYPE_PNG, 100,
4246  sfile->hsize, sfile->vsize, &gerr);
4247 
4248  if (gerr) {
4249  retval = do_write_failed_error_s_with_retry(full_file_name, gerr->message);
4250  lives_error_free(gerr);
4251  gerr = NULL;
4252  }
4253  } while (retval == LIVES_RESPONSE_RETRY);
4254 
4255  free(tmp);
4256  lives_widget_object_unref(pixbuf);
4257  }
4258 
4259  // some other error condition
4260  return FALSE;
4261 }
4262 
4263 
4264 void backup_file(int clip, int start, int end, const char *file_name) {
4265  lives_clip_t *sfile = mainw->files[clip];
4266  char **array;
4267 
4268  char *title;
4269  char full_file_name[PATH_MAX];
4270 
4271  char *com, *tmp;
4272 
4273  boolean with_perf = FALSE;
4274  boolean retval, allow_over;
4275 
4276  int withsound = 1;
4277  int current_file = mainw->current_file;
4278 
4279  if (strrchr(file_name, '.') == NULL) {
4280  lives_snprintf(full_file_name, PATH_MAX, "%s.%s", file_name, LIVES_FILE_EXT_BACKUP);
4281  allow_over = FALSE;
4282  } else {
4283  lives_snprintf(full_file_name, PATH_MAX, "%s", file_name);
4284  allow_over = TRUE;
4285  }
4286 
4287  // check if file exists
4288  if (!check_file(full_file_name, allow_over)) return;
4289 
4290  // create header files
4291  retval = write_headers(sfile); // for pre LiVES 0.9.6
4292  retval = save_clip_values(clip); // new style (0.9.6+)
4293 
4294  if (!retval) return;
4295 
4296  //...and backup
4297  title = get_menu_name(sfile, FALSE);
4298  d_print(_("Backing up %s to %s"), title, full_file_name);
4299  lives_free(title);
4300 
4301  if (!mainw->save_with_sound) {
4302  d_print(_(" without sound"));
4303  withsound = 0;
4304  }
4305 
4306  d_print("...");
4307  cfile->progress_start = 1;
4308  cfile->progress_end = sfile->frames;
4309 
4310  if (sfile->clip_type == CLIP_TYPE_FILE) {
4311  frames_t ret;
4312  char *msg = (_("Pulling frames from clip..."));
4313  if ((ret = realize_all_frames(clip, msg, FALSE)) < cfile->frames) {
4314  lives_free(msg);
4315  cfile->nopreview = FALSE;
4316  if (ret > 0) d_print_cancelled();
4317  return;
4318  }
4319  lives_free(msg);
4320  }
4321 
4322  com = lives_strdup_printf("%s backup %s %d %d %d %s", prefs->backend, sfile->handle, withsound,
4323  start, end, (tmp = lives_filename_from_utf8(full_file_name, -1, NULL, NULL, NULL)));
4324  lives_free(tmp);
4325 
4326  // TODO
4327  mainw->current_file = clip;
4328 
4329  lives_rm(cfile->info_file);
4330  cfile->nopreview = TRUE;
4331  lives_system(com, FALSE);
4332  lives_free(com);
4333 
4334  if (THREADVAR(com_failed)) {
4335  THREADVAR(com_failed) = FALSE;
4336  mainw->current_file = current_file;
4337  return;
4338  }
4339 
4340  if (!(do_progress_dialog(TRUE, TRUE, _("Backing up"))) || mainw->error) {
4341  if (mainw->error) {
4342  d_print_failed();
4343  }
4344 
4345  // cancelled - clear up files
4346  cfile->nopreview = FALSE;
4347 
4348  // using restore details in the 'wrong' way here...it will also clear files
4349  com = lives_strdup_printf("%s restore_details %s", prefs->backend, cfile->handle);
4351  lives_free(com);
4352 
4353  //save_clip_values(mainw->current_file);
4354  mainw->current_file = current_file;
4355  return;
4356  }
4357 
4358  cfile->nopreview = FALSE;
4359 
4360  mainw->current_file = current_file;
4361 
4362  if (mainw->error) {
4366  d_print_failed();
4367  return;
4368  }
4369 
4370  if (with_perf) {
4371  d_print(_("performance data was backed up..."));
4372  }
4373 
4374  array = lives_strsplit(mainw->msg, "|", 3);
4375  sfile->f_size = strtol(array[1], NULL, 10);
4376  lives_strfreev(array);
4377 
4378  lives_snprintf(sfile->file_name, PATH_MAX, "%s", full_file_name);
4379  if (!sfile->was_renamed) {
4380  lives_snprintf(sfile->name, CLIP_NAME_MAXLEN, "%s", full_file_name);
4381  set_main_title(cfile->name, 0);
4382  lives_menu_item_set_text(sfile->menuentry, full_file_name, FALSE);
4383  }
4384  if (prefs->show_recent)
4385  add_to_recent(full_file_name, 0., 0, NULL);
4386 
4387  sfile->changed = FALSE;
4388  // set is_untitled to stop users from saving with a .lv1 extension
4389  sfile->is_untitled = TRUE;
4390  d_print_done();
4391 }
4392 
4393 
4394 boolean write_headers(lives_clip_t *file) {
4395  // this function is included only for backwards compatibility with ancient builds of LiVES
4396  //
4397 
4398  int retval;
4399  int header_fd;
4400  char *hdrfile;
4401 
4402  // save the file details
4403  hdrfile = lives_build_filename(prefs->workdir, file->handle, LIVES_CLIP_HEADER_OLD, NULL);
4404 
4405  do {
4406  retval = 0;
4407  header_fd = creat(hdrfile, S_IRUSR | S_IWUSR);
4408  if (header_fd < 0) {
4409  retval = do_write_failed_error_s_with_retry(hdrfile, lives_strerror(errno));
4410  } else {
4411  THREADVAR(write_failed) = FALSE;
4412 
4413  lives_write_le(header_fd, &cfile->bpp, 4, TRUE);
4414  lives_write_le(header_fd, &cfile->fps, 8, TRUE);
4415  lives_write_le(header_fd, &cfile->hsize, 4, TRUE);
4416  lives_write_le(header_fd, &cfile->vsize, 4, TRUE);
4417  lives_write_le(header_fd, &cfile->arps, 4, TRUE);
4418  lives_write_le(header_fd, &cfile->signed_endian, 4, TRUE);
4419  lives_write_le(header_fd, &cfile->arate, 4, TRUE);
4420  lives_write_le(header_fd, &cfile->unique_id, 8, TRUE);
4421  lives_write_le(header_fd, &cfile->achans, 4, TRUE);
4422  lives_write_le(header_fd, &cfile->asampsize, 4, TRUE);
4423 
4424  lives_write(header_fd, LiVES_VERSION, strlen(LiVES_VERSION), TRUE);
4425  close(header_fd);
4426 
4427  if (THREADVAR(write_failed)) retval = do_write_failed_error_s_with_retry(hdrfile, NULL);
4428  }
4429  } while (retval == LIVES_RESPONSE_RETRY);
4430 
4431  lives_free(hdrfile);
4432 
4433  if (retval != LIVES_RESPONSE_CANCEL) {
4434  // more file details (since version 0.7.5)
4435  hdrfile = lives_build_filename(prefs->workdir, file->handle, LIVES_CLIP_HEADER_OLD2, NULL);
4436 
4437  do {
4438  retval = 0;
4439  header_fd = creat(hdrfile, S_IRUSR | S_IWUSR);
4440 
4441  if (header_fd < 0) {
4442  retval = do_write_failed_error_s_with_retry(hdrfile, lives_strerror(errno));
4443  } else {
4444  THREADVAR(write_failed) = FALSE;
4445  lives_write_le(header_fd, &file->frames, 4, TRUE);
4446  lives_write(header_fd, &file->title, 1024, TRUE);
4447  lives_write(header_fd, &file->author, 1024, TRUE);
4448  lives_write(header_fd, &file->comment, 1024, TRUE);
4449  close(header_fd);
4450  }
4451  if (THREADVAR(write_failed)) retval = do_write_failed_error_s_with_retry(hdrfile, NULL);
4452  } while (retval == LIVES_RESPONSE_RETRY);
4453 
4454  lives_free(hdrfile);
4455  }
4456 
4457  if (retval == LIVES_RESPONSE_CANCEL) {
4458  THREADVAR(write_failed) = FALSE;
4459  return FALSE;
4460  }
4461  return TRUE;
4462 }
4463 
4464 
4465 boolean read_headers(int fileno, const char *dir, const char *file_name) {
4466  // file_name is only used to get the file size on the disk
4467  lives_clip_t *sfile;
4468  char **array;
4469  char buff[1024];
4470  char version[32];
4471  char *com, *tmp;
4472  char *old_hdrfile, *lives_header = NULL;
4473 
4474  off_t header_size;
4475  int version_hash;
4476  int pieces;
4477  int header_fd;
4478  int retval2;
4479  int asigned = 0, aendian = LIVES_LITTLE_ENDIAN;
4480 
4481  lives_clip_details_t detail;
4482 
4483  boolean retval, retvala;
4484  boolean is_ascrap = FALSE;
4485 
4486  off_t sizhead = 28; //8 * 4 + 8 + 8;
4487 
4488  time_t old_time = 0, new_time = 1;
4489  struct stat mystat;
4490 
4491  if (!IS_VALID_CLIP(fileno)) return FALSE;
4492 
4494 
4495  sfile = mainw->files[fileno];
4496 
4497  old_hdrfile = lives_build_filename(dir, LIVES_CLIP_HEADER_OLD, NULL);
4498 
4499  if (fileno == mainw->ascrap_file) {
4500  is_ascrap = TRUE;
4503  lives_header = lives_build_filename(dir, LIVES_ACLIP_HEADER, NULL);
4504  if (!lives_file_test(lives_header, LIVES_FILE_TEST_EXISTS)) {
4505  lives_free(lives_header);
4506  lives_header = NULL;
4507  }
4508  }
4509  if (!lives_header) lives_header = lives_build_filename(dir, LIVES_CLIP_HEADER, NULL);
4510 
4511  sfile->checked_for_old_header = TRUE;
4512  sfile->img_type = IMG_TYPE_UNKNOWN;
4513 
4514  if (lives_file_test(lives_header, LIVES_FILE_TEST_EXISTS)) {
4515  do {
4516  retval2 = LIVES_RESPONSE_OK;
4517  if (!(mainw->hdrs_cache = cache_file_contents(lives_header))) {
4518  if (fileno != mainw->current_file) goto rhd_failed;
4519  retval2 = do_read_failed_error_s_with_retry(lives_header, NULL);
4520  }
4521  } while (retval2 == LIVES_RESPONSE_RETRY);
4522 
4523  if (retval2 == LIVES_RESPONSE_CANCEL) {
4524  goto rhd_failed;
4525  }
4526 
4527  if (fileno == mainw->current_file) {
4529  }
4530 
4531  if (!is_ascrap) restore_clip_binfmt(fileno);
4532 
4533  do {
4534  do {
4535  detail = CLIP_DETAILS_HEADER_VERSION;
4536  retval = get_clip_value(fileno, detail, &sfile->header_version, 16);
4537  if (retval) {
4538  if (sfile->header_version < 100) goto old_check;
4539  } else {
4540  if (lives_file_test(old_hdrfile, LIVES_FILE_TEST_EXISTS)) {
4541  goto old_check;
4542  }
4543  if (fileno != mainw->current_file) {
4544  goto rhd_failed;
4545  }
4546  if (mainw->hdrs_cache) {
4548  } else {
4549  retval2 = do_header_read_error_with_retry(fileno);
4550  }
4551  }
4552  } while (retval2 == LIVES_RESPONSE_RETRY);
4553 
4554  if (retval2 == LIVES_RESPONSE_CANCEL) goto rhd_failed;
4555 
4556  if (is_ascrap) goto get_avals;
4557 
4558  detail = CLIP_DETAILS_FRAMES;
4559  retval = get_clip_value(fileno, detail, &sfile->frames, 0);
4560 
4561  if (retval) {
4562  detail = CLIP_DETAILS_BPP;
4563  retval = get_clip_value(fileno, detail, &sfile->bpp, 0);
4564  }
4565  if (retval) {
4566  detail = CLIP_DETAILS_FPS;
4567  retval = get_clip_value(fileno, detail, &sfile->fps, 0);
4568  }
4569  if (retval) {
4570  detail = CLIP_DETAILS_PB_FPS;
4571  retval = get_clip_value(fileno, detail, &sfile->pb_fps, 0);
4572  if (!retval) {
4573  retval = TRUE;
4574  sfile->pb_fps = sfile->fps;
4575  }
4576  }
4577  if (retval) {
4578  retval = get_clip_value(fileno, CLIP_DETAILS_PB_FRAMENO, &sfile->frameno, 0);
4579  if (!retval) {
4580  retval = TRUE;
4581  sfile->frameno = 1;
4582  }
4583  if (sfile->frameno <= 0) sfile->frameno = 1;
4584  }
4585  if (retval) {
4586  detail = CLIP_DETAILS_WIDTH;
4587  retval = get_clip_value(fileno, detail, &sfile->hsize, 0);
4588  }
4589  if (retval) {
4590  detail = CLIP_DETAILS_HEIGHT;
4591  retval = get_clip_value(fileno, detail, &sfile->vsize, 0);
4592  }
4593  if (retval) {
4594  if (sfile->header_version > 100) {
4595  detail = CLIP_DETAILS_GAMMA_TYPE;
4596  get_clip_value(fileno, detail, &sfile->gamma_type, 0);
4597  if (sfile->gamma_type == 0) sfile->gamma_type = WEED_GAMMA_SRGB;
4598  if (sfile->gamma_type != WEED_GAMMA_SRGB) {
4599  if (!do_gamma_import_warn(sfile->has_binfmt ?
4600  sfile->binfmt_version.num : 0, sfile->gamma_type)) goto rhd_failed;
4601  }
4602  }
4603  }
4604  if (retval) {
4605  detail = CLIP_DETAILS_CLIPNAME;
4606  get_clip_value(fileno, detail, sfile->name, CLIP_NAME_MAXLEN);
4607  }
4608  if (retval) {
4609  detail = CLIP_DETAILS_FILENAME;
4610  get_clip_value(fileno, detail, sfile->file_name, PATH_MAX);
4611  }
4612 
4613 get_avals:
4614  if (retval) {
4615  detail = CLIP_DETAILS_ACHANS;
4616  retvala = get_clip_value(fileno, detail, &sfile->achans, 0);
4617  if (!retvala) sfile->achans = 0;
4618  }
4619 
4620  if (sfile->achans == 0) retvala = FALSE;
4621  else retvala = TRUE;
4622 
4623  if (retval && retvala) {
4624  detail = CLIP_DETAILS_ARATE;
4625  retvala = get_clip_value(fileno, detail, &sfile->arps, 0);
4626  }
4627 
4628  if (!retvala) sfile->arps = sfile->achans = sfile->arate = sfile->asampsize = 0;
4629  if (sfile->arps == 0) retvala = FALSE;
4630 
4631  if (retvala && retval) {
4632  detail = CLIP_DETAILS_PB_ARATE;
4633  retvala = get_clip_value(fileno, detail, &sfile->arate, 0);
4634  if (!retvala) {
4635  retvala = TRUE;
4636  sfile->arate = sfile->arps;
4637  }
4638  }
4639  if (retvala && retval) {
4640  detail = CLIP_DETAILS_ASIGNED;
4641  retval = get_clip_value(fileno, detail, &asigned, 0);
4642  }
4643  if (retvala && retval) {
4644  detail = CLIP_DETAILS_AENDIAN;
4645  retval = get_clip_value(fileno, detail, &aendian, 0);
4646  }
4647 
4648  sfile->signed_endian = asigned + aendian;
4649 
4650  if (retvala && retval) {
4651  detail = CLIP_DETAILS_ASAMPS;
4652  retval = get_clip_value(fileno, detail, &sfile->asampsize, 0);
4653  }
4654  if (!retval) {
4655  if (fileno != mainw->current_file) goto rhd_failed;
4656  if (mainw->hdrs_cache) {
4657  retval2 = do_header_missing_detail_error(fileno, detail);
4658  } else {
4659  retval2 = do_header_read_error_with_retry(fileno);
4660  }
4661  } else {
4662  if (!is_ascrap) {
4663  get_clip_value(fileno, CLIP_DETAILS_TITLE, sfile->title, 1024);
4664  get_clip_value(fileno, CLIP_DETAILS_AUTHOR, sfile->author, 1024);
4665  get_clip_value(fileno, CLIP_DETAILS_COMMENT, sfile->comment, 1024);
4666  get_clip_value(fileno, CLIP_DETAILS_KEYWORDS, sfile->keywords, 1024);
4667  get_clip_value(fileno, CLIP_DETAILS_INTERLACE, &sfile->interlace, 0);
4668  // user must have selected this:
4669  if (sfile->interlace != LIVES_INTERLACE_NONE) sfile->deinterlace = TRUE;
4670  }
4671  lives_free(old_hdrfile);
4672  lives_free(lives_header);
4673  if (!prefs->vj_mode) {
4674  sfile->afilesize = reget_afilesize_inner(fileno);
4675  }
4677  // passed to further functions, but it needs to be freed and set to NULL
4678  // at some point
4679  return TRUE;
4680  }
4681  } while (retval2 == LIVES_RESPONSE_RETRY);
4682  goto rhd_failed;
4683  }
4684 
4685 old_check:
4686 
4687  if (lives_file_test(old_hdrfile, LIVES_FILE_TEST_EXISTS)) {
4688  sfile->has_old_header = TRUE;
4689  if (!stat(old_hdrfile, &mystat)) old_time = mystat.st_mtime;
4690  if (!stat(lives_header, &mystat)) new_time = mystat.st_mtime;
4691  }
4692 
4693  lives_free(lives_header);
4694  lives_header = NULL;
4696 
4697  if (sfile->has_old_header && old_time <= new_time) {
4698  retval2 = LIVES_RESPONSE_OK;
4699  detail = CLIP_DETAILS_FRAMES;
4700 
4701  if (get_clip_value(fileno, detail, &sfile->frames, 0)) {
4702  char *tmp;
4703 
4704  // use new style header (LiVES 0.9.6+)
4705  // clean up and get file sizes
4706  if (file_name) {
4707  com = lives_strdup_printf("%s restore_details \"%s\" \"%s\" 0",
4708  prefs->backend_sync, sfile->handle,
4709  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
4710  lives_free(tmp);
4711  } else
4712  com = lives_strdup_printf("%s restore_details \"%s\" . 1", prefs->backend_sync, sfile->handle);
4713 
4714  lives_popen(com, fileno != mainw->current_file, buff, 1024);
4715  lives_free(com);
4716 
4717  if (THREADVAR(com_failed)) {
4718  THREADVAR(com_failed) = FALSE;
4719  goto rhd_failed;
4720  }
4721 
4722  pieces = get_token_count(buff, '|');
4723 
4724  if (pieces > 3) {
4725  array = lives_strsplit(buff, "|", pieces);
4726  sfile->f_size = strtol(array[1], NULL, 10);
4727  sfile->afilesize = strtol(array[2], NULL, 10);
4728  if (sfile->clip_type == CLIP_TYPE_DISK) {
4729  if (!strcmp(array[3], LIVES_FILE_EXT_JPG)) sfile->img_type = IMG_TYPE_JPEG;
4730  else sfile->img_type = IMG_TYPE_PNG;
4731  }
4732  lives_strfreev(array);
4733  }
4734  if (fileno == mainw->current_file) threaded_dialog_spin(0.);
4735  } else goto rhd_failed;
4736  lives_free(old_hdrfile);
4738  return TRUE;
4739  }
4740 
4741  do {
4742  // old style headers (pre 0.9.6)
4743  retval = LIVES_RESPONSE_OK;
4744  THREADVAR(read_failed) = FALSE;
4745  lives_memset(version, 0, 32);
4746  lives_memset(buff, 0, 1024);
4747 
4748  header_fd = lives_open2(old_hdrfile, O_RDONLY);
4749 
4750  if (header_fd < 0) {
4751  if (fileno != mainw->current_file) {
4752  goto rhd_failed;
4753  }
4754  retval = do_read_failed_error_s_with_retry(old_hdrfile, lives_strerror(errno));
4755  } else {
4756  THREADVAR(read_failed) = FALSE;
4757  header_size = get_file_size(header_fd);
4758 
4759  if (header_size < sizhead) {
4760  close(header_fd);
4761  goto rhd_failed;
4762  } else {
4763  THREADVAR(read_failed) = FALSE;
4764  lives_read_le(header_fd, &sfile->fps, 4, FALSE);
4765  if (!THREADVAR(read_failed))
4766  lives_read_le(header_fd, &sfile->bpp, 8, FALSE);
4767  if (!THREADVAR(read_failed))
4768  lives_read_le(header_fd, &sfile->hsize, 4, FALSE);
4769  if (!THREADVAR(read_failed))
4770  lives_read_le(header_fd, &sfile->vsize, 4, FALSE);
4771  if (!THREADVAR(read_failed))
4772  lives_read_le(header_fd, &sfile->arps, 4, FALSE);
4773  if (!THREADVAR(read_failed))
4774  lives_read_le(header_fd, &sfile->signed_endian, 4, FALSE);
4775  if (!THREADVAR(read_failed))
4776  lives_read_le(header_fd, &sfile->arate, 4, FALSE);
4777  if (!THREADVAR(read_failed))
4778  lives_read_le(header_fd, &sfile->unique_id, 8, FALSE);
4779  if (!THREADVAR(read_failed))
4780  lives_read_le(header_fd, &sfile->achans, 4, FALSE);
4781  if (!THREADVAR(read_failed))
4782  lives_read_le(header_fd, &sfile->asampsize, 4, FALSE);
4783 
4784  if (header_size > sizhead) {
4785  if (header_size - sizhead > 31) {
4786  if (!THREADVAR(read_failed))
4787  lives_read(header_fd, &version, 31, FALSE);
4788  version[31] = '\0';
4789  } else {
4790  if (!THREADVAR(read_failed))
4791  lives_read(header_fd, &version, header_size - sizhead, FALSE);
4792  version[header_size - sizhead] = '\0';
4793  }
4794  }
4795  }
4796  close(header_fd);
4797  }
4798 
4799  if (THREADVAR(read_failed)) {
4800  if (fileno != mainw->current_file) goto rhd_failed;
4801  retval = do_read_failed_error_s_with_retry(old_hdrfile, NULL);
4802  if (retval == LIVES_RESPONSE_CANCEL) goto rhd_failed;
4803  }
4804  } while (retval == LIVES_RESPONSE_RETRY);
4805 
4806  lives_freep((void **)&old_hdrfile);
4807 
4808  if (retval == LIVES_RESPONSE_CANCEL) goto rhd_failed;
4809 
4810  // handle version changes
4811  version_hash = verhash(version);
4812  if (version_hash < 7001) {
4813  sfile->arps = sfile->arate;
4814  sfile->signed_endian = mainw->endian;
4815  }
4816 
4817  com = lives_strdup_printf("%s restore_details %s %s %d", prefs->backend_sync, sfile->handle,
4818  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)),
4819  !strcmp(file_name, "."));
4820 
4821  lives_popen(com, FALSE, buff, 1024);
4822  lives_free(com);
4823  lives_free(tmp);
4824 
4825  if (THREADVAR(com_failed)) {
4826  THREADVAR(com_failed) = FALSE;
4827  goto rhd_failed;
4828  }
4829 
4830  pieces = get_token_count(buff, '|');
4831  array = lives_strsplit(buff, "|", pieces);
4832  sfile->f_size = strtol(array[1], NULL, 10);
4833  sfile->afilesize = strtol(array[2], NULL, 10);
4834 
4835  if (sfile->clip_type == CLIP_TYPE_DISK) {
4836  if (!strcmp(array[3], LIVES_FILE_EXT_JPG)) sfile->img_type = IMG_TYPE_JPEG;
4837  else sfile->img_type = IMG_TYPE_PNG;
4838  }
4839 
4840  sfile->frames = atoi(array[4]);
4841 
4842  sfile->bpp = (sfile->img_type == IMG_TYPE_JPEG) ? 24 : 32;
4843 
4844  if (pieces > 4 && array[5]) {
4845  lives_snprintf(sfile->title, 1024, "%s", lives_strstrip(array[4]));
4846  }
4847  if (pieces > 5 && array[6]) {
4848  lives_snprintf(sfile->author, 1024, "%s", lives_strstrip(array[5]));
4849  }
4850  if (pieces > 6 && array[7]) {
4851  lives_snprintf(sfile->comment, 1024, "%s", lives_strstrip(array[6]));
4852  }
4853 
4854  lives_strfreev(array);
4855  return TRUE;
4856 
4857 rhd_failed:
4858  lives_freep((void **)&lives_header);
4859  lives_freep((void **)&old_hdrfile);
4860  return FALSE;
4861 }
4862 
4863 
4864 void open_set_file(int clipnum) {
4865  char name[CLIP_NAME_MAXLEN];
4866 
4867  if (mainw->current_file < 1) return;
4868 
4869  lives_memset(name, 0, CLIP_NAME_MAXLEN);
4870 
4871  if (mainw->hdrs_cache) {
4872  boolean retval;
4873  // LiVES 0.9.6+
4874 
4875  retval = get_clip_value(mainw->current_file, CLIP_DETAILS_PB_FPS, &cfile->pb_fps, 0);
4876  if (!retval) {
4877  cfile->pb_fps = cfile->fps;
4878  }
4880  if (!retval) {
4881  cfile->frameno = 1;
4882  }
4883 
4885  if (!retval) {
4886  char *tmp;
4887  lives_snprintf(name, CLIP_NAME_MAXLEN, "%s", (tmp = get_untitled_name(mainw->untitled_number++)));
4888  lives_free(tmp);
4889  cfile->needs_update = TRUE;
4890  }
4891  retval = get_clip_value(mainw->current_file, CLIP_DETAILS_UNIQUE_ID, &cfile->unique_id, 0);
4892  if (!retval) {
4893  cfile->unique_id = gen_unique_id();
4894  cfile->needs_silent_update = TRUE;
4895  }
4896  retval = get_clip_value(mainw->current_file, CLIP_DETAILS_INTERLACE, &cfile->interlace, 0);
4897  if (!retval) {
4898  cfile->interlace = LIVES_INTERLACE_NONE;
4899  cfile->needs_silent_update = TRUE;
4900  }
4901  if (cfile->interlace != LIVES_INTERLACE_NONE) cfile->deinterlace = TRUE;
4902  } else {
4903  // pre 0.9.6 <- ancient code
4904  ssize_t nlen;
4905  int set_fd;
4906  int pb_fps;
4907  int retval;
4908  char *setfile = lives_strdup_printf("%s/%s/set.%s", prefs->workdir, cfile->handle, mainw->set_name);
4909 
4910  do {
4911  retval = 0;
4912  if ((set_fd = lives_open2(setfile, O_RDONLY)) > -1) {
4913  // get perf_start
4914  if ((nlen = lives_read_le(set_fd, &pb_fps, 4, TRUE)) > 0) {
4915  cfile->pb_fps = pb_fps / 1000.;
4916  lives_read_le(set_fd, &cfile->frameno, 4, TRUE);
4917  lives_read(set_fd, name, CLIP_NAME_MAXLEN, TRUE);
4918  }
4919  close(set_fd);
4920  } else retval = do_read_failed_error_s_with_retry(setfile, lives_strerror(errno));
4921  } while (retval == LIVES_RESPONSE_RETRY);
4922 
4923  lives_free(setfile);
4924  cfile->needs_silent_update = TRUE;
4925  }
4926 
4927  if (!*name) {
4928  lives_snprintf(name, CLIP_NAME_MAXLEN, "set_clip %.3d", clipnum);
4929  } else {
4930  // pre 3.x, files erroneously had the set name appended permanently, so here we undo that
4931  if (lives_string_ends_with(name, " (%s)", mainw->set_name)) {
4932  char *remove = lives_strdup_printf(" (%s)", mainw->set_name);
4933  if (strlen(name) > strlen(remove)) name[strlen(name) - strlen(remove)] = 0;
4934  lives_free(remove);
4935  cfile->needs_silent_update = TRUE;
4936  }
4937  lives_snprintf(cfile->name, CLIP_NAME_MAXLEN, "%s", name);
4938  }
4939 }
4940 
4941 
4942 void reload_subs(int fileno) {
4943  lives_clip_t *sfile;
4944  char *subfname;
4945  if (!IS_VALID_CLIP(fileno)) return;
4946 
4947  sfile = mainw->files[fileno];
4948  subfname = lives_build_filename(prefs->workdir, sfile->handle, SUBS_FILENAME "."
4949  LIVES_FILE_EXT_SRT, NULL);
4950  if (lives_file_test(subfname, LIVES_FILE_TEST_EXISTS)) {
4951  subtitles_init(sfile, subfname, SUBTITLE_TYPE_SRT);
4952  } else {
4953  lives_free(subfname);
4954  subfname = lives_build_filename(prefs->workdir, sfile->handle, SUBS_FILENAME "."
4955  LIVES_FILE_EXT_SUB, NULL);
4956  if (lives_file_test(subfname, LIVES_FILE_TEST_EXISTS)) {
4957  subtitles_init(sfile, subfname, SUBTITLE_TYPE_SUB);
4958  }
4959  }
4960  lives_free(subfname);
4961 }
4962 
4963 
4964 ulong restore_file(const char *file_name) {
4965  char *com = lives_strdup("dummy");
4966  char *mesg, *mesg1, *tmp;
4967  boolean is_OK = TRUE;
4968  char *fname = lives_strdup(file_name);
4969  char *clipdir;
4970 
4971  int old_file = mainw->current_file, current_file;
4972  int new_file = mainw->first_free_file;
4973  boolean not_cancelled;
4974 
4975  // create a new file
4976  if (!get_new_handle(new_file, fname)) {
4977  return 0;
4978  }
4979 
4980  d_print(_("Restoring %s..."), file_name);
4981 
4982  mainw->current_file = new_file;
4983 
4984  cfile->hsize = mainw->def_width;
4985  cfile->vsize = mainw->def_height;
4986 
4987  if (!mainw->multitrack) {
4988  switch_to_file((mainw->current_file = old_file), new_file);
4989  set_main_title(cfile->file_name, 0);
4990  }
4991 
4992  com = lives_strdup_printf("%s restore %s %s", prefs->backend, cfile->handle,
4993  (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
4994 
4995  lives_rm(cfile->info_file);
4996  lives_system(com, FALSE);
4997  lives_free(tmp);
4998  lives_free(com);
4999 
5000  if (THREADVAR(com_failed)) {
5001  THREADVAR(com_failed) = FALSE;
5002  close_current_file(old_file);
5003  return 0;
5004  }
5005 
5006  cfile->restoring = TRUE;
5007  not_cancelled = do_progress_dialog(TRUE, TRUE, _("Restoring"));
5008  cfile->restoring = FALSE;
5009 
5010  if (mainw->error || !not_cancelled) {
5011  if (mainw->error && mainw->cancelled != CANCEL_ERROR) {
5013  }
5014  close_current_file(old_file);
5015  return 0;
5016  }
5017 
5018  // call function to return rest of file details
5019  // fsize, afilesize and frames
5020  clipdir = lives_build_path(prefs->workdir, cfile->handle, NULL);
5021  is_OK = read_headers(mainw->current_file, clipdir, file_name);
5022  lives_free(clipdir);
5024 
5025  if (!is_OK) {
5026  mesg = lives_strdup_printf(_("\n\nThe file %s is corrupt.\nLiVES was unable to restore it.\n"),
5027  file_name);
5028  do_error_dialog(mesg);
5029  lives_free(mesg);
5030 
5031  d_print_failed();
5032  close_current_file(old_file);
5033  return 0;
5034  }
5035 
5036  // get img_type, check frame count and size
5037  if (!cfile->checked && !check_clip_integrity(mainw->current_file, NULL, cfile->frames)) {
5038  if (cfile->afilesize == 0) {
5040  }
5042  cfile->frames = get_frame_count(mainw->current_file, 1);
5043  }
5044  }
5045  cfile->checked = TRUE;
5046 
5047  // add entry to window menu
5048  // TODO - do this earlier and allow switching during restore
5049  add_to_clipmenu();
5050 
5051  if (prefs->show_recent) {
5052  add_to_recent(file_name, 0., 0, NULL);
5053  }
5054 
5055  if (cfile->frames > 0) {
5056  cfile->start = 1;
5057  } else {
5058  cfile->start = 0;
5059  }
5060  cfile->end = cfile->frames;
5061  cfile->arps = cfile->arate;
5062  cfile->pb_fps = cfile->fps;
5063  cfile->opening = FALSE;
5064  cfile->changed = FALSE;
5065 
5066  if (prefs->autoload_subs) {
5068  }
5069 
5070  lives_snprintf(cfile->type, 40, "Frames");
5071  mesg1 = lives_strdup_printf(_("Frames=%d type=%s size=%dx%d bpp=%d fps=%.3f\nAudio:"), cfile->frames, cfile->type,
5072  cfile->hsize, cfile->vsize, cfile->bpp, cfile->fps);
5073 
5074  if (cfile->afilesize == 0l) {
5075  cfile->achans = 0;
5076  mesg = lives_strdup_printf(_("%s none\n"), mesg1);
5077  } else {
5078  mesg = lives_strdup_printf(P_("%s %d Hz %d channel %d bps\n", "%s %d Hz %d channels %d bps\n", cfile->achans),
5079  mesg1, cfile->arate, cfile->achans, cfile->asampsize);
5080  }
5081  d_print(mesg);
5082  lives_free(mesg);
5083  lives_free(mesg1);
5084 
5085  cfile->is_loaded = TRUE;
5086  current_file = mainw->current_file;
5087 
5088  // set new bpp
5089  cfile->bpp = (cfile->img_type == IMG_TYPE_JPEG) ? 24 : 32;
5090 
5091  cfile->saved_frameno = cfile->frameno;
5092  if (cfile->frameno > cfile->frames && cfile->frameno > 1) cfile->frameno = cfile->frames;
5093  cfile->last_frameno = cfile->frameno;
5094  cfile->pointer_time = cfile->real_pointer_time = calc_time_from_frame(mainw->current_file, cfile->frameno);
5095  if (cfile->real_pointer_time > CLIP_TOTAL_TIME(mainw->current_file))
5096  cfile->real_pointer_time = CLIP_TOTAL_TIME(mainw->current_file);
5097  if (cfile->pointer_time > cfile->video_time) cfile->pointer_time = 0.;
5098 
5099  if (cfile->achans) {
5100  cfile->aseek_pos = (off64_t)((double)(cfile->real_pointer_time * cfile->arate) * cfile->achans *
5101  (cfile->asampsize / 8));
5102  if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
5103  }
5104 
5105  if (!save_clip_values(current_file)) {
5106  close_current_file(old_file);
5107  return 0;
5108  }
5109 
5111 
5112  if (!mainw->multitrack) {
5113  switch_to_file((mainw->current_file = old_file), current_file);
5114  }
5116 
5117  return cfile->unique_id;
5118 }
5119 
5120 
5122  // when doing a resample, we save a list of frames for the back end to do
5123  // a reorder
5124 
5125  // here we also update the frame_index for clips of type CLIP_TYPE_FILE
5126 
5127  char *hdrfile = lives_strdup_printf("%s/%s/event.frames", prefs->workdir, cfile->handle);
5128 
5129  int header_fd, i = 0;
5130  int retval;
5131  int perf_start, perf_end;
5132  int nevents;
5133 
5134  if (!cfile->event_list) {
5135  lives_rm(hdrfile);
5136  return -1;
5137  }
5138 
5139  perf_start = (int)(cfile->fps * event_list_get_start_secs(cfile->event_list)) + 1;
5140  perf_end = perf_start + (nevents = count_events(cfile->event_list, FALSE, 0, 0)) - 1;
5141 
5142  if (!event_list_to_block(cfile->event_list, nevents)) return -1;
5143 
5144  if (cfile->frame_index) {
5145  LiVESResponseType response;
5146  int xframes = cfile->frames;
5147  char *what = (_("creating the frame index for resampling "));
5148 
5149  if (cfile->frame_index_back) lives_free(cfile->frame_index_back);
5150  cfile->frame_index_back = cfile->frame_index;
5151  cfile->frame_index = NULL;
5152 
5153  do {
5154  response = LIVES_RESPONSE_OK;
5155  create_frame_index(mainw->current_file, FALSE, 0, nevents);
5156  if (!cfile->frame_index) {
5157  response = do_memory_error_dialog(what, nevents * 4);
5158  }
5159  } while (response == LIVES_RESPONSE_RETRY);
5160  lives_free(what);
5161  if (response == LIVES_RESPONSE_CANCEL) {
5162  cfile->frame_index = cfile->frame_index_back;
5163  cfile->frame_index_back = NULL;
5164  return -1;
5165  }
5166 
5167  for (i = 0; i < nevents; i++) {
5168  cfile->frame_index[i] = cfile->frame_index_back[(cfile->resample_events + i)->value - 1];
5169  }
5170 
5171  cfile->frames = nevents;
5173  cfile->frames = xframes;
5174  }
5175 
5176  do {
5177  retval = 0;
5178  header_fd = creat(hdrfile, S_IRUSR | S_IWUSR);
5179  if (header_fd < 0) {
5180  retval = do_write_failed_error_s_with_retry(hdrfile, lives_strerror(errno));
5181  } else {
5182  // use machine endian.
5183  // When we call "smogrify reorder", we will pass the endianness as 3rd parameter
5184 
5185  THREADVAR(write_failed) = FALSE;
5186  lives_write(header_fd, &perf_start, 4, FALSE);
5187 
5188  if (cfile->resample_events) {
5189  for (i = 0; i <= perf_end - perf_start; i++) {
5190  if (THREADVAR(write_failed)) break;
5191  lives_write(header_fd, &((cfile->resample_events + i)->value), 4, TRUE);
5192  }
5193  lives_freep((void **)&cfile->resample_events);
5194  }
5195 
5196  if (THREADVAR(write_failed)) {
5197  retval = do_write_failed_error_s_with_retry(hdrfile, NULL);
5198  }
5199 
5200  close(header_fd);
5201  }
5202  } while (retval == LIVES_RESPONSE_RETRY);
5203 
5204  if (retval == LIVES_RESPONSE_CANCEL) {
5205  i = -1;
5206  }
5207 
5208  lives_free(hdrfile);
5209  return i;
5210 }
5211 
5212 
5217 
5221 
5222 static double ascrap_mb; // MB written to audio file
5223 static uint64_t free_mb; // MB free to write
5224 
5225 void add_to_ascrap_mb(uint64_t bytes) {
5226  ascrap_mb += bytes / 1000000.;
5227 }
5228 
5229 
5230 boolean open_scrap_file(void) {
5231  // create a scrap file for recording generated video frames
5232  int current_file = mainw->current_file;
5233  char *dir;
5234  char *handle, *scrap_handle;
5235 
5238  return FALSE;
5239  }
5240 
5241  handle = get_worktmp("_scrap");
5242  if (!handle) {
5243  workdir_warning();
5244  return FALSE;
5245  }
5246  if (!create_cfile(-1, handle, FALSE)) {
5247  dir = lives_build_path(prefs->workdir, cfile->handle, NULL);
5248  lives_rmdir(dir, FALSE);
5249  lives_free(dir); lives_free(handle);
5250  return FALSE;
5251  }
5252  lives_free(handle);
5253 
5255 
5256  lives_snprintf(cfile->type, 40, "scrap");
5257 
5258  scrap_handle = lives_strdup_printf("scrap|%s", cfile->handle);
5259  if (prefs->crash_recovery) add_to_recovery_file(scrap_handle);
5260  lives_free(scrap_handle);
5261 
5262  pthread_mutex_lock(&mainw->clip_list_mutex);
5263  mainw->cliplist = lives_list_append(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->current_file));
5264  pthread_mutex_unlock(&mainw->clip_list_mutex);
5265 
5266  dir = lives_build_path(prefs->workdir, cfile->handle, NULL);
5267  free_mb = (double)get_ds_free(dir) / (double)ONE_MILLION;
5268  lives_free(dir);
5269 
5270  mainw->current_file = current_file;
5271 
5272  if (mainw->ascrap_file == -1) ascrap_mb = 0.;
5273 
5274  return TRUE;
5275 }
5276 
5277 
5278 boolean open_ascrap_file(void) {
5279  // create a scrap file for recording audio
5280  int current_file = mainw->current_file;
5281  char *dir;
5282  char *handle, *ascrap_handle;
5283 
5286  return FALSE;
5287  }
5288 
5289  handle = get_worktmp("_ascrap");
5290  if (!handle) {
5291  workdir_warning();
5292  return FALSE;
5293  }
5294  if (!create_cfile(-1, handle, FALSE)) {
5295  dir = lives_build_path(prefs->workdir, cfile->handle, NULL);
5296  lives_rmdir(dir, FALSE);
5297  lives_free(dir); lives_free(handle);
5298  return FALSE;
5299  }
5300  lives_free(handle);
5301 
5303  lives_snprintf(cfile->type, 40, "ascrap");
5304 
5305  cfile->opening = FALSE;
5306 
5307  cfile->achans = 2;
5308  cfile->arate = cfile->arps = DEFAULT_AUDIO_RATE;
5309  cfile->asampsize = 16;
5310  cfile->signed_endian = 0; // ???
5311 
5312 #ifdef HAVE_PULSE_AUDIO
5314  if (prefs->audio_src == AUDIO_SRC_EXT) {
5315  if (mainw->pulsed_read) {
5316  cfile->arate = cfile->arps = mainw->pulsed_read->in_arate;
5317  }
5318  } else {
5319  if (mainw->pulsed) {
5320  cfile->arate = cfile->arps = mainw->pulsed->out_arate;
5321  }
5322  }
5323  }
5324 #endif
5325 
5326 #ifdef ENABLE_JACK
5328  if (prefs->audio_src == AUDIO_SRC_EXT) {
5329  if (mainw->jackd_read) {
5330  cfile->arate = cfile->arps = mainw->jackd_read->sample_in_rate;
5331  }
5332  } else {
5333  if (mainw->jackd) {
5334  cfile->arate = cfile->arps = mainw->jackd->sample_out_rate;
5335  }
5336  }
5337  }
5338 #endif
5339 
5340  ascrap_handle = lives_strdup_printf("ascrap|%s", cfile->handle);
5341  if (prefs->crash_recovery) add_to_recovery_file(ascrap_handle);
5342  lives_free(ascrap_handle);
5343 
5344  pthread_mutex_lock(&mainw->clip_list_mutex);
5345  mainw->cliplist = lives_list_append(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->current_file));
5346  pthread_mutex_unlock(&mainw->clip_list_mutex);
5347 
5348  dir = lives_build_path(prefs->workdir, cfile->handle, NULL);
5349  free_mb = (double)get_ds_free(dir) / (double)ONE_MILLION;
5350  lives_free(dir);
5351 
5352  mainw->current_file = current_file;
5353 
5354  ascrap_mb = 0.;
5355 
5356  return TRUE;
5357 }
5358 
5359 
5360 boolean load_from_scrap_file(weed_layer_t *layer, int frame) {
5361  // load raw frame data from scrap file
5362 
5363  // this will also set cfile width and height - for letterboxing etc.
5364 
5365  // return FALSE if the frame does not exist/we are unable to read it
5366 
5367  char *oname;
5368 
5369  lives_clip_t *scrapfile = mainw->files[mainw->scrap_file];
5370 
5371  int fd;
5372  if (!IS_VALID_CLIP(mainw->scrap_file)) return FALSE;
5373 
5374  if (!scrapfile->ext_src) {
5375  oname = make_image_file_name(scrapfile, 1, LIVES_FILE_EXT_SCRAP);
5376  fd = lives_open_buffered_rdonly(oname);
5377  lives_free(oname);
5378  if (fd < 0) return FALSE;
5379 #ifdef HAVE_POSIX_FADVISE
5380  posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
5381 #endif
5382  scrapfile->ext_src = LIVES_INT_TO_POINTER(fd);
5384  } else fd = LIVES_POINTER_TO_INT(scrapfile->ext_src);
5385 
5386  if (frame < 0 || !layer) return TRUE;
5387 
5388  if (!weed_plant_deserialise(fd, NULL, layer)) {
5389  //g_print("bad scrapfile frame\n");
5390  return FALSE;
5391  }
5392  return TRUE;
5393 }
5394 
5395 
5396 static void ds_warn(boolean freelow, uint64_t bytes) {
5397  char *reason, *aorb;
5398  char *amount = lives_format_storage_space_string(bytes);
5399  if (freelow) {
5400  reason = (_("FREE DISK SPACE"));
5401  aorb = (_("BELOW"));
5402  } else {
5403  reason = (_("DISK SPACE USED"));
5404  aorb = (_("ABOVE"));
5405  }
5406  d_print(_("\nRECORDING was PAUSED because %s in %s IS %s %s !\n"
5407  "Diskspace limits can be set in Preferences / Misc.\n"),
5408  reason, prefs->workdir, aorb, amount);
5409  on_record_perf_activate(NULL, NULL);
5410  d_print_urgency(URGENCY_MSG_TIMEOUT, _("RECORDING WAS PAUSED DUE TO DISKSPACE LIMITS\n"));
5411  lives_free(reason);
5412  lives_free(aorb);
5413 }
5414 
5415 
5416 boolean check_for_disk_space(boolean fullcheck) {
5419  static int64_t free_ds = -1;
5420  static double xscrap_mb = -1., xascrap_mb = -1.;
5421  static double xxscrap_mb = -1., xxascrap_mb = -1.;
5422  static int64_t ds_used = -1;
5423  static boolean wrtable = FALSE;
5424 
5425  double scrap_mb = 0.;
5426 
5427  if (prefs->disk_quota == 0 && prefs->rec_stop_gb < 0.) return TRUE;
5428 
5429  if (fullcheck) ds_used = -1;
5430 
5431  if (IS_VALID_CLIP(mainw->scrap_file)) {
5432  scrap_mb = (double)mainw->files[mainw->scrap_file]->f_size / (double)ONE_MILLION;
5433  }
5434 
5435  if (prefs->disk_quota > 0) {
5436  int64_t xds_used = -1;
5437 
5438  if ((ds_used = disk_monitor_check_result(prefs->workdir)) > -1) {
5439  xds_used = ds_used;
5440  xxscrap_mb = scrap_mb;
5441  xxascrap_mb = ascrap_mb;
5442  } else {
5443  if (xxscrap_mb == -1. || xxscrap_mb > scrap_mb) xxscrap_mb = scrap_mb;
5444  if (xxascrap_mb == -1. || xxascrap_mb > ascrap_mb) xxascrap_mb = ascrap_mb;
5445  if (ds_used > -1) xds_used = ds_used
5446  + (int64_t)(scrap_mb + ascrap_mb - xxscrap_mb - xxascrap_mb)
5447  * ONE_MILLION;
5448  }
5449  if (xds_used > -1) {
5451  if ((uint64_t)xds_used >= prefs->disk_quota * ONE_BILLION) {
5452  if (mainw->record && !mainw->record_paused) {
5453  ds_warn(FALSE, (uint64_t)ds_used);
5454  }
5455  return FALSE;
5456  }
5457  }
5458  }
5459 
5460  // check if we have enough free space left on the volume (return FALSE if not)
5461  if (prefs->rec_stop_gb > -1.) {
5462  // check free space again
5463  if (fullcheck || free_ds == -1 || xscrap_mb == -1 || xascrap_mb == -1
5464  || scrap_mb < xscrap_mb || ascrap_mb < xascrap_mb) {
5465  free_ds = (int64_t)get_ds_free(prefs->workdir);
5466  xscrap_mb = scrap_mb;
5467  xascrap_mb = ascrap_mb;
5468  if (free_ds == 0) wrtable = is_writeable_dir(prefs->workdir);
5469  else wrtable = TRUE;
5470  }
5471  if (wrtable) {
5472  double free_mb = (double)free_ds / (double)ONE_MILLION;
5473  double freesp = free_mb - (scrap_mb + ascrap_mb - xscrap_mb - xascrap_mb);
5474  if ((double)freesp / 1000. < prefs->rec_stop_gb) {
5475  if (mainw->record && !mainw->record_paused) {
5476  ds_warn(TRUE, freesp * ONE_MILLION);
5477  }
5478  return FALSE;
5479  }
5480  }
5481  }
5482  return TRUE;
5483 }
5484 
5485 
5486 static void _save_to_scrap_file(weed_layer_t *layer) {
5487  // returns frame number
5488  // dump the raw layer (frame) data to disk
5489 
5490  // TODO: run as bg thread
5491 
5492  size_t pdata_size;
5493 
5494  lives_clip_t *scrapfile = mainw->files[mainw->scrap_file];
5495 
5496  boolean writeable = TRUE;
5497 
5498  char *framecount;
5499 
5500  //int flags = O_WRONLY | O_CREAT | O_TRUNC;
5501  int fd;
5502 
5503  if (!scrapfile->ext_src) {
5504  char *oname = make_image_file_name(scrapfile, 1, LIVES_FILE_EXT_SCRAP), *dirname;
5505 
5506 #ifdef O_NOATIME
5507  //flags |= O_NOATIME;
5508 #endif
5509 
5510  dirname = lives_build_filename(prefs->workdir, scrapfile->handle, NULL);
5511  lives_mkdir_with_parents(dirname, capable->umask);
5512  lives_free(dirname);
5513 
5515  lives_free(oname);
5516 
5517  if (fd < 0) {
5518  weed_layer_free(layer);
5519  return;
5520  }
5521  scrapfile->ext_src = LIVES_INT_TO_POINTER(fd);
5523 
5524 #ifdef HAVE_POSIX_FADVISE
5525  posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
5526 #endif
5527  } else fd = LIVES_POINTER_TO_INT(scrapfile->ext_src);
5528 
5529 
5530  // serialise entire frame to scrap file
5531  pdata_size = weed_plant_serialise(fd, layer, NULL);
5532  weed_layer_free(layer);
5533 
5534  scrapfile->f_size += pdata_size;
5535 
5536  // check free space every 256 frames or every 10 MB of audio (TODO ****)
5537  if ((scrapfile->frames & 0xFF) == 0) {
5538  char *dir = lives_build_filename(prefs->workdir, scrapfile->handle, NULL);
5539  free_mb = (double)get_ds_free(dir) / 1000000.;
5540  if (free_mb == 0) writeable = is_writeable_dir(dir);
5541  lives_free(dir);
5542  }
5543 
5544  if ((!mainw->fs || (prefs->play_monitor != widget_opts.monitor + 1 && capable->nmonitors > 1)) && !prefs->hide_framebar &&
5545  !mainw->faded) {
5546  double scrap_mb = (double)scrapfile->f_size / 1000000.;
5547  if ((scrap_mb + ascrap_mb) < (double)free_mb * .75) {
5548  // TRANSLATORS: rec(ord) %.2f M(ega)B(ytes)
5549  framecount = lives_strdup_printf(_("rec %.2f MB"), scrap_mb + ascrap_mb);
5550  } else {
5551  // warn if scrap_file > 3/4 of free space
5552  // TRANSLATORS: !rec(ord) %.2f M(ega)B(ytes)
5553  if (writeable)
5554  framecount = lives_strdup_printf(_("!rec %.2f MB"), scrap_mb + ascrap_mb);
5555  else
5556  // TRANSLATORS: rec(ord) ?? M(ega)B(ytes)
5557  framecount = (_("rec ?? MB"));
5558  }
5559  lives_entry_set_text(LIVES_ENTRY(mainw->framecounter), framecount);
5560  lives_free(framecount);
5561  }
5562 
5564  check_for_disk_space((scrapfile->frames & 0x3F) ? TRUE : FALSE);
5565 }
5566 
5567 static lives_proc_thread_t scrap_file_procthrd = NULL;
5568 
5570  weed_layer_t *orig_layer;
5571  lives_clip_t *scrapfile = mainw->files[mainw->scrap_file];
5572  if (!IS_VALID_CLIP(mainw->scrap_file)) return -1;
5573  if (!layer) return scrapfile->frames;
5574  orig_layer = weed_layer_copy(NULL, layer);
5575  if (scrap_file_procthrd) {
5576  lives_proc_thread_join(scrap_file_procthrd);
5577  }
5578  scrap_file_procthrd = lives_proc_thread_create(LIVES_THRDATTR_NONE,
5579  (lives_funcptr_t)_save_to_scrap_file, -1, "V", orig_layer);
5580  return scrapfile->frames;
5581 }
5582 
5583 void close_scrap_file(boolean remove) {
5584  int current_file = mainw->current_file;
5585 
5586  if (!IS_VALID_CLIP(mainw->scrap_file)) return;
5587 
5588  if (scrap_file_procthrd) {
5589  lives_proc_thread_join(scrap_file_procthrd);
5590  scrap_file_procthrd = NULL;
5591  }
5592 
5594  if (cfile->ext_src && cfile->ext_src_type == LIVES_EXT_SRC_FILE_BUFF)
5595  lives_close_buffered(LIVES_POINTER_TO_INT(cfile->ext_src));
5596  cfile->ext_src = NULL;
5597  cfile->ext_src_type = LIVES_EXT_SRC_NONE;
5598 
5599  if (remove) close_temp_handle(current_file);
5600  else mainw->current_file = current_file;
5601 
5602  pthread_mutex_lock(&mainw->clip_list_mutex);
5603  mainw->cliplist = lives_list_remove(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->scrap_file));
5604  pthread_mutex_unlock(&mainw->clip_list_mutex);
5605 
5607 
5608  mainw->scrap_file = -1;
5609 }
5610 
5611 
5612 void close_ascrap_file(boolean remove) {
5613  int current_file = mainw->current_file;
5614 
5615  if (mainw->ascrap_file == -1) return;
5616 
5617  if (remove) {
5619  close_temp_handle(current_file);
5620  }
5621 
5622  pthread_mutex_lock(&mainw->clip_list_mutex);
5623  mainw->cliplist = lives_list_remove(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->ascrap_file));
5624  pthread_mutex_unlock(&mainw->clip_list_mutex);
5625 
5627 
5628  mainw->ascrap_file = -1;
5629 }
5630 
5631 
5632 void recover_layout_map(int numclips) {
5633  // load global layout map for a set and assign entries to clips [mainw->files[i]->layout_map]
5634  LiVESList *omlist, *mlist, *lmap_node, *lmap_node_next, *lmap_entry_list, *lmap_entry_list_next;
5635 
5636  layout_map *lmap_entry;
5637  uint32_t mask;
5638 
5639  char **array;
5640  char *check_handle;
5641 
5642  if (numclips > MAX_FILES) numclips = MAX_FILES;
5643 
5644  if ((omlist = load_layout_map())) {
5645  int i;
5646 
5647  mlist = omlist;
5648 
5649  // assign layout map to clips
5650  for (i = 1; i <= numclips; i++) {
5651  lives_clip_t *sfile = mainw->files[i];
5652  if (!sfile) continue;
5653  lmap_node = mlist;
5654  while (lmap_node) {
5655  lmap_node_next = lmap_node->next;
5656  lmap_entry = (layout_map *)lmap_node->data;
5657  check_handle = lives_strdup(sfile->handle);
5658 
5659  if (strstr(lmap_entry->handle, "/") == NULL) {
5660  lives_free(check_handle);
5661  check_handle = lives_path_get_basename(sfile->handle);
5662  }
5663 
5664  if ((!strcmp(check_handle, lmap_entry->handle) && (sfile->unique_id == lmap_entry->unique_id)) ||
5665  (prefs->mt_load_fuzzy && (!strcmp(check_handle, lmap_entry->handle) || (sfile->unique_id == lmap_entry->unique_id)))
5666  ) {
5667  // check handle and unique id match
5668  // got a match, assign list to layout_map and delete this node
5669  lmap_entry_list = lmap_entry->list;
5670  while (lmap_entry_list) {
5671  lmap_entry_list_next = lmap_entry_list->next;
5672  array = lives_strsplit((char *)lmap_entry_list->data, "|", -1);
5673  if (!lives_file_test(array[0], LIVES_FILE_TEST_EXISTS)) {
5674  //g_print("removing layout because no file %s\n", array[0]);
5675  // layout file has been deleted, remove this entry
5676  if (lmap_entry_list->prev) lmap_entry_list->prev->next = lmap_entry_list_next;
5677  else lmap_entry->list = lmap_entry_list_next;
5678  if (lmap_entry_list_next) lmap_entry_list_next->prev = lmap_entry_list->prev;
5679  lives_free((livespointer)lmap_entry_list->data);
5680  lives_list_free(lmap_entry_list);
5681  }
5682  lives_strfreev(array);
5683  lmap_entry_list = lmap_entry_list_next;
5684  }
5685  sfile->layout_map = lmap_entry->list;
5686  lives_free(lmap_entry->handle);
5687  lives_free(lmap_entry->name);
5688  lives_free(lmap_entry);
5689  if (lmap_node->prev) lmap_node->prev->next = lmap_node_next;
5690  else omlist = mlist = lmap_node_next;
5691  if (lmap_node_next) lmap_node_next->prev = lmap_node->prev;
5692  lmap_node->prev = lmap_node->next = NULL;
5693  lives_list_free(lmap_node);
5695  // TODO: -- needs checking ----
5696  mask = 0;
5697  mainw->xlays = layout_frame_is_affected(i, sfile->frames + 1, 0, mainw->xlays);
5698  if (mainw->xlays) {
5699  add_lmap_error(LMAP_ERROR_DELETE_FRAMES, sfile->name, (livespointer)sfile->layout_map, i,
5700  sfile->frames, 0., FALSE);
5703  //g_print("FRMS %d\n", cfile->frames);
5704  }
5705 
5707  if (mainw->xlays) {
5708  add_lmap_error(LMAP_ERROR_DELETE_AUDIO, sfile->name, (livespointer)sfile->layout_map, i,
5709  sfile->frames, sfile->laudio_time, FALSE);
5712  //g_print("AUD %f\n", cfile->laudio_time);
5713  }
5714  if (mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(mask));
5715  }
5716 
5717  lives_free(check_handle);
5718  lmap_node = lmap_node_next;
5719  }
5720  }
5721 
5722  lmap_node = mlist;
5723  while (lmap_node) {
5724  lmap_entry = (layout_map *)lmap_node->data;
5725  if (lmap_entry->name) lives_free(lmap_entry->name);
5726  if (lmap_entry->handle) lives_free(lmap_entry->handle);
5727  lives_list_free_all(&lmap_entry->list);
5728  lmap_node = lmap_node->next;
5729  }
5730  if (omlist) lives_list_free(omlist);
5731  }
5732 }
5733 
5734 
5735 boolean reload_clip(int fileno, int maxframe) {
5736  // reload clip -- for CLIP_TYPE_FILE
5737  // cd to clip directory - so decoder plugins can write temp files
5738  LiVESList *odeclist;
5739  lives_clip_t *sfile = mainw->files[fileno];
5740 
5741  const lives_clip_data_t *cdata = NULL;
5743 
5744  double orig_fps = sfile->fps;
5745 
5746  char decoder_name[PATH_MAX];
5747  char *orig_filename = lives_strdup(sfile->file_name);
5748  char *cwd = lives_get_current_dir();
5749  char *ppath = lives_build_filename(prefs->workdir, sfile->handle, NULL);
5750 
5751  LiVESResponseType response;
5752  boolean was_renamed = FALSE, retb = FALSE;
5753  int current_file;
5754 
5756 
5757  if (!mainw->decoders_loaded) {
5760  }
5761 
5762  odeclist = lives_list_copy(mainw->decoder_list);
5763  retb = get_clip_value(fileno, CLIP_DETAILS_DECODER_NAME, decoder_name, PATH_MAX);
5764  if (retb && *decoder_name) {
5765  decoder_plugin_move_to_first(decoder_name);
5766  }
5767  retb = FALSE;
5768  lives_chdir(ppath, FALSE);
5769  lives_free(ppath);
5770 
5771  while (1) {
5773 
5774  fake_cdata->URI = lives_strdup(sfile->file_name);
5775  fake_cdata->fps = sfile->fps;
5776  fake_cdata->nframes = maxframe;
5777 
5778  response = LIVES_RESPONSE_NONE;
5779 
5780  if ((cdata = get_decoder_cdata(fileno, prefs->disabled_decoders, fake_cdata->fps != 0. ? fake_cdata : NULL)) == NULL) {
5781  if (mainw->error) {
5782 manual_locate:
5783  response = do_file_notfound_dialog(_("The original file"), orig_filename);
5784  if (response == LIVES_RESPONSE_RETRY) {
5785  lives_freep((void **)&fake_cdata->URI);
5786  continue;
5787  }
5788  if (response == LIVES_RESPONSE_BROWSE) {
5789  int resp;
5790  char fname[PATH_MAX], dirname[PATH_MAX], *newname;
5791  LiVESWidget *chooser;
5792 
5793  lives_snprintf(dirname, PATH_MAX, "%s", orig_filename);
5794  lives_snprintf(fname, PATH_MAX, "%s", orig_filename);
5795 
5796  get_dirname(dirname);
5797  get_basename(fname);
5798 
5799  chooser = choose_file_with_preview(dirname, fname, NULL, LIVES_FILE_SELECTION_VIDEO_AUDIO);
5800 
5801  resp = lives_dialog_run(LIVES_DIALOG(chooser));
5802 
5803  end_fs_preview();
5804 
5805  if (resp == LIVES_RESPONSE_ACCEPT) {
5806  newname = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(chooser));
5807  lives_widget_destroy(LIVES_WIDGET(chooser));
5808 
5809  if (newname && *newname) {
5810  char *tmp;
5811  lives_snprintf(sfile->file_name, PATH_MAX, "%s", (tmp = lives_filename_to_utf8(newname, -1, NULL, NULL, NULL)));
5812  lives_free(tmp);
5813  lives_free(newname);
5814  }
5815 
5816  lives_freep((void **)&fake_cdata->URI);
5817 
5818  //re-scan for these
5819  sfile->fps = 0.;
5820  maxframe = 0;
5821 
5822  was_renamed = TRUE;
5823  // try again with the new file
5824  continue;
5825  }
5826  // cancelled from filechooser
5827  lives_widget_destroy(LIVES_WIDGET(chooser));
5828  goto manual_locate;
5829  }
5830  // cancelled
5831  } else {
5832  // unopenable
5833  if (was_renamed) goto manual_locate;
5835  }
5836 
5837  lives_chdir(cwd, FALSE);
5838  lives_free(cwd);
5839 
5840  // NOT openable, or not found and user cancelled, switch back to original clip
5841  if (!sfile->checked && cdata) {
5842  check_clip_integrity(fileno, cdata, maxframe);
5843  if (sfile->frames > 0 || sfile->afilesize > 0) {
5844  // recover whatever we can
5845  sfile->clip_type = CLIP_TYPE_FILE;
5846  retb = check_if_non_virtual(fileno, 1, sfile->frames);
5847  }
5848  sfile->checked = TRUE;
5849  }
5850  if (!retb) {
5851  current_file = mainw->current_file;
5852  mainw->current_file = fileno;
5853  close_current_file(current_file);
5854  }
5855  unref_struct(&fake_cdata->lsd);
5856 
5857  lives_free(orig_filename);
5858  lives_list_free(mainw->decoder_list);
5859  mainw->decoder_list = odeclist;
5860  return retb;
5861  }
5862 
5863  // got cdata
5864  if (was_renamed) {
5865  // manual relocation
5866  sfile->fps = orig_fps;
5867  if (!sfile->checked && !check_clip_integrity(fileno, cdata, maxframe)) {
5868  // get correct img_type, fps, etc.
5869  if (THREADVAR(com_failed) || THREADVAR(write_failed)) do_header_write_error(fileno);
5870  goto manual_locate;
5871  }
5872  sfile->checked = TRUE;
5873  sfile->needs_silent_update = TRUE; // force filename update in header
5874  if (prefs->show_recent) {
5875  // replace in recent menu
5876  char file[PATH_MAX];
5877  int i;
5878  for (i = 0; i < 4; i++) {
5879  char *tmp;
5880  char *pref = lives_strdup_printf("%s%d", PREF_RECENT, i + 1);
5881  get_utf8_pref(pref, file, PATH_MAX);
5882  tmp = subst(file, orig_filename, sfile->file_name);
5883  if (lives_utf8_strcmp(tmp, file)) {
5884  lives_snprintf(file, PATH_MAX, "%s", tmp);
5885  set_utf8_pref(pref, file);
5887  if (mainw->multitrack) lives_menu_item_set_text(mainw->multitrack->recent[i], file, FALSE);
5888  }
5889  lives_free(tmp);
5890  lives_free(pref);
5891  }
5892  if (mainw->prefs_cache) {
5893  // update recent files -> force reload of prefs
5896  }
5897  }
5898  }
5899 
5901  unref_struct(&fake_cdata->lsd);
5902  break;
5903  }
5904 
5905  lives_free(orig_filename);
5906  lives_chdir(cwd, FALSE);
5907  lives_free(cwd);
5908 
5909  sfile->clip_type = CLIP_TYPE_FILE;
5910  get_mime_type(sfile->type, 40, cdata);
5911  sfile->img_type = IMG_TYPE_BEST; // read_headers() will have set this to "jpeg" (default)
5912  // we will set correct value in check_clip_integrity() if there are any real images
5913 
5914  if (sfile->ext_src) {
5915  boolean bad_header = FALSE;
5916  boolean correct = TRUE;
5917  if (!was_renamed) {
5918  if (!sfile->checked)
5919  correct = check_clip_integrity(fileno, cdata, maxframe); // get correct img_type, fps, etc.
5920  sfile->checked = TRUE;
5921  }
5922  if (!correct) {
5923  if (THREADVAR(com_failed) || THREADVAR(write_failed)) bad_header = TRUE;
5924  } else {
5925  lives_decoder_t *dplug = (lives_decoder_t *)sfile->ext_src;
5926  if (dplug) {
5927  lives_decoder_sys_t *dpsys = (lives_decoder_sys_t *)dplug->decoder;
5928  if (dpsys && *dpsys->name && strcmp(dpsys->name, decoder_name)) {
5929  save_clip_value(fileno, CLIP_DETAILS_DECODER_NAME, (void *)dpsys->name);
5930  if (THREADVAR(com_failed) || THREADVAR(write_failed)) bad_header = TRUE;
5931  }
5932  }
5933  }
5934 
5935  if (bad_header) do_header_write_error(fileno);
5936  }
5937  lives_list_free(mainw->decoder_list);
5938  mainw->decoder_list = odeclist;
5939  if (prefs->autoload_subs) {
5940  reload_subs(fileno);
5941  }
5942  return TRUE;
5943 }
5944 
5945 #define _RELOAD(field) sfile->field = loaded->field
5946 #define _RELOAD_STRING(field, len) lives_snprintf(sfile->field, len, "%s", loaded->field)
5947 
5948 #define DSIZE_MAX 100000
5949 
5950 static lives_clip_t *_restore_binfmt(int clipno, boolean forensic) {
5951  if (IS_NORMAL_CLIP(clipno)) {
5952  lives_clip_t *sfile = mainw->files[clipno];
5953  char *fname = lives_build_filename(prefs->workdir, sfile->handle, TOTALSAVE_NAME, NULL);
5954  if (lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
5955  ssize_t bytes;
5956  size_t cursize = (size_t)((char *)&sfile->binfmt_end - (char *)sfile), dsize;
5957  char *xloaded = (char *)lives_calloc(1, cursize);
5958  boolean badsize = FALSE;
5959  int fd = lives_open_buffered_rdonly(fname);
5960  size_t fsize = lives_buffered_orig_size(fd);
5961  lives_clip_t *loaded = (lives_clip_t *)xloaded;
5962  if (fsize < cursize) badsize = TRUE;
5963  else {
5964  bytes = lives_read_buffered(fd, xloaded, 8, TRUE);
5965  if (bytes < 8 || lives_memcmp(loaded->binfmt_check.chars, CLIP_BINFMT_CHECK, 8)) badsize = TRUE;
5966  else {
5967  bytes += lives_read_buffered(fd, xloaded + 8, 16, TRUE);
5968  if (bytes < 16) badsize = TRUE;
5969  else {
5970  dsize = loaded->binfmt_bytes.num;
5971  if (dsize < cursize) badsize = TRUE;
5972  else {
5973  if (dsize > cursize && dsize < DSIZE_MAX) {
5974  xloaded = lives_realloc(xloaded, dsize);
5975  loaded = (lives_clip_t *)xloaded;
5976  } else dsize = cursize;
5977  bytes += lives_read_buffered(fd, xloaded + 24, dsize - 24, TRUE);
5978  if (bytes < dsize) badsize = TRUE;
5979  }
5980  }
5981  }
5982  }
5984  //if (!forensic) lives_rm(fname);
5985  lives_free(fname);
5986 
5987  if (badsize) {
5988  lives_free(xloaded);
5989  return FALSE;
5990  }
5991 
5992  THREADVAR(com_failed) = FALSE;
5993  if (THREADVAR(read_failed) == fd + 1) {
5994  THREADVAR(read_failed) = 0;
5995  lives_free(xloaded);
5996  return NULL;
5997  }
5998 
5999  sfile->has_binfmt = TRUE;
6000 
6001  if (forensic) return loaded;
6002 
6003  _RELOAD_STRING(save_file_name, PATH_MAX); _RELOAD(start); _RELOAD(end); _RELOAD(is_untitled); _RELOAD(was_in_set);
6004  _RELOAD(ratio_fps); _RELOAD_STRING(mime_type, 256);
6005  _RELOAD(changed); _RELOAD(deinterlace); _RELOAD(vol);
6006  if (sfile->start < 1) sfile->start = 1;
6007  if (sfile->end > sfile->frames) sfile->end = sfile->frames;
6008  if (sfile->start > sfile->end) sfile->start = sfile->end;
6010  if (sfile->pointer_time > sfile->video_time) sfile->pointer_time = 0.;
6011  if (sfile->real_pointer_time > CLIP_TOTAL_TIME(clipno)) sfile->real_pointer_time = sfile->pointer_time;
6012  return loaded;
6013  }
6014  lives_free(fname);
6015  }
6016  return NULL;
6017 }
6018 
6019 #undef _RELOAD
6020 #undef _RELOAD_STRING
6021 
6022 boolean restore_clip_binfmt(int clipno) {
6023  lives_clip_t *recov = _restore_binfmt(clipno, FALSE);
6024  if (!recov) return FALSE;
6025  lives_free(recov);
6026  return TRUE;
6027 }
6028 
6030  return _restore_binfmt(clipno, TRUE);
6031 }
6032 
6033 boolean recover_files(char *recovery_file, boolean auto_recover) {
6034  FILE *rfile = NULL;
6035 
6036  char buff[256], *buffptr;
6037  char *clipdir;
6038 
6039  LiVESResponseType resp;
6040 
6041  int clipnum = 0;
6042  int maxframe;
6043  int last_good_file = -1, ngoodclips;
6044 
6045  boolean is_scrap, is_ascrap;
6046  boolean did_set_check = FALSE;
6047  boolean is_ready = mainw->is_ready, mt_is_ready = FALSE;
6048  boolean mt_needs_idlefunc = FALSE;
6049  boolean retb = TRUE, retval;
6050  boolean load_from_set = TRUE;
6051  boolean rec_cleanup = FALSE;
6052 
6053  // setting is_ready allows us to get the correct transient window for dialogs
6054  // otherwise the dialogs will appear behind the main interface
6055  // we do this for mainwindow and multitrack
6056 
6057  // we will reset these before returning
6058  mainw->is_ready = TRUE;
6059 
6060  if (mainw->multitrack) {
6061  if (mainw->multitrack->idlefunc > 0) {
6062  lives_source_remove(mainw->multitrack->idlefunc);
6063  mainw->multitrack->idlefunc = 0;
6064  mt_needs_idlefunc = TRUE;
6065  }
6067  mt_is_ready = mainw->multitrack->is_ready;
6068  mainw->multitrack->is_ready = TRUE;
6069  }
6070 
6071  if (!auto_recover) {
6072  if (1 || mainw->multitrack) {
6075  }
6076  if (!do_yesno_dialog
6077  (_("\nFiles from a previous run of LiVES were found.\nDo you want to attempt to recover them ?\n"))) {
6078  retb = FALSE;
6079  goto recovery_done;
6080  }
6081  }
6082 
6083  if (recovery_file) {
6084  do {
6085  resp = LIVES_RESPONSE_NONE;
6086  rfile = fopen(recovery_file, "r");
6087  if (!rfile) {
6088  resp = do_read_failed_error_s_with_retry(recovery_file, lives_strerror(errno));
6089  if (resp == LIVES_RESPONSE_CANCEL) {
6090  retb = FALSE;
6091  goto recovery_done;
6092  }
6093  }
6094  } while (resp == LIVES_RESPONSE_RETRY);
6095  }
6096 
6097  do_threaded_dialog(_("Recovering files"), FALSE);
6098  d_print(_("\nRecovering files..."));
6099 
6101 
6104 
6105  while (1) {
6107 
6109  is_scrap = FALSE;
6110  is_ascrap = FALSE;
6111 
6112  THREADVAR(read_failed) = FALSE;
6113 
6114  if (recovery_file) {
6115  if (!lives_fgets(buff, 256, rfile)) {
6116  reset_clipmenu();
6119  if (THREADVAR(read_failed)) {
6120  d_print_failed();
6121  do_read_failed_error_s(recovery_file, NULL);
6122  } else d_print_done();
6123  break;
6124  }
6125  } else {
6126  if (!mainw->recovery_list) {
6127  reset_clipmenu();
6129  d_print_done();
6130  break;
6131  }
6132  lives_snprintf(buff, 256, "%s", (char *)mainw->recovery_list->data);
6134  }
6135 
6136  lives_chomp(buff);
6137 
6138  if (buff[strlen(buff) - 1] == '*') {
6139  boolean crash_recovery = prefs->crash_recovery;
6140  LiVESResponseType resp;
6141  // set to be opened
6142  buff[strlen(buff) - 1 - strlen(LIVES_DIR_SEP)] = 0;
6143  do {
6144  resp = LIVES_RESPONSE_OK;
6145  if (!is_legal_set_name(buff, TRUE, TRUE)) {
6146  resp = do_abort_cancel_retry_dialog(_("Click Abort to exit LiVES immediately, Retry to try again,"
6147  " or Cancel to continue without reloading the set.\n"));
6148  }
6149  } while (resp == LIVES_RESPONSE_RETRY);
6150  if (resp == LIVES_RESPONSE_CANCEL) continue;
6151 
6156 
6157  if (!reload_set(buff)) {
6158  prefs->crash_recovery = crash_recovery;
6160  d_print_failed();
6162  continue;
6163  }
6164  mainw->was_set = TRUE;
6165  prefs->crash_recovery = crash_recovery;
6166  } else {
6168  if (!strncmp(buff, "scrap|", 6)) {
6169  is_scrap = TRUE;
6170  buffptr = buff + 6;
6171  } else if (!strncmp(buff, "ascrap|", 7)) {
6172  is_ascrap = TRUE;
6173  buffptr = buff + 7;
6174  } else {
6175  if (!strncmp(buff, "ascrap", 6) || !strncmp(buff, "scrap", 5)) {
6176  rec_cleanup = TRUE;
6177  continue;
6178  }
6179  buffptr = buff;
6180  }
6181 
6182  clipdir = lives_build_filename(prefs->workdir, buffptr, NULL);
6183 
6184  if (!lives_file_test(clipdir, LIVES_FILE_TEST_IS_DIR)) {
6185  lives_free(clipdir);
6186  continue;
6187  }
6188  lives_free(clipdir);
6189 
6190  if (strstr(buffptr, "/" CLIPS_DIRNAME "/")) {
6191  char **array;
6193  if (!load_from_set) continue;
6194  array = lives_strsplit(buffptr, "/" CLIPS_DIRNAME "/", -1);
6195  mainw->was_set = TRUE;
6196  lives_snprintf(mainw->set_name, 128, "%s", array[0]);
6197  lives_strfreev(array);
6198 
6199  if (!did_set_check && !check_for_lock_file(mainw->set_name, 0)) {
6201  load_from_set = FALSE;
6202  mainw->was_set = FALSE;
6203  mainw->set_name[0] = 0;
6204  }
6205  did_set_check = TRUE;
6206  }
6207  }
6208 
6210  if (!create_cfile(-1, buffptr, FALSE)) {
6214  d_print_failed();
6215  break;
6216  }
6217 
6218  if (is_scrap || is_ascrap) {
6219  pthread_mutex_lock(&mainw->clip_list_mutex);
6220  mainw->cliplist = lives_list_append(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->current_file));
6221  pthread_mutex_unlock(&mainw->clip_list_mutex);
6222  }
6223 
6224  if (is_scrap) {
6226  cfile->opening = FALSE;
6227  lives_snprintf(cfile->type, 40, "scrap");
6228  cfile->frames = 1;
6229  cfile->hsize = 640;
6230  cfile->vsize = 480;
6231  continue;
6232  }
6233 
6234  if (is_ascrap) {
6236  cfile->opening = FALSE;
6237  lives_snprintf(cfile->type, 40, "ascrap");
6238  }
6239 
6241  // we need to keep this around for open_set_file(), below.
6242  clipdir = lives_build_path(prefs->workdir, cfile->handle, NULL);
6243  retval = read_headers(mainw->current_file, clipdir, NULL);
6244  lives_free(clipdir);
6245 
6246  if (is_ascrap) {
6247  if (!retval) {
6249  mainw->ascrap_file = -1;
6250  }
6251  continue;
6252  }
6253 
6254  if (mainw->current_file < 1) continue;
6255 
6257  if ((maxframe = load_frame_index(mainw->current_file)) > 0) {
6259  if (!*cfile->file_name) continue;
6260  if (!reload_clip(mainw->current_file, maxframe)) continue;
6261  if (cfile->img_type == IMG_TYPE_UNKNOWN) {
6262  lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
6263  int fvirt = count_virtual_frames(cfile->frame_index, 1, cfile->frames);
6264  if (fvirt < cfile->frames) {
6265  if (!cfile->checked && !check_clip_integrity(mainw->current_file, cdata, cfile->frames)) {
6266  cfile->needs_update = TRUE;
6267  }
6268  cfile->checked = TRUE;
6269  }
6270  if (cfile->header_version >= 102) cfile->fps = cfile->pb_fps;
6271  }
6272  } else {
6274  boolean is_ok = TRUE;
6275  if (!cfile->checked) {
6276  if (!(is_ok = check_clip_integrity(mainw->current_file, NULL, cfile->frames))) {
6277  cfile->needs_update = TRUE;
6278  }
6279  cfile->checked = TRUE;
6280  }
6281  if (!prefs->vj_mode && !is_ok) {
6282  if (cfile->afilesize == 0) {
6284  }
6285  if (!check_frame_count(mainw->current_file, is_ok)) {
6286  cfile->frames = get_frame_count(mainw->current_file, 1);
6287  cfile->needs_update = TRUE;
6288  }
6289  }
6290  }
6291  if (!recovery_file && !cfile->checked) {
6292  lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
6293  if (!check_clip_integrity(mainw->current_file, cdata, cfile->frames)) {
6294  cfile->needs_update = TRUE;
6295  if (cfile->header_version >= 102) cfile->fps = cfile->pb_fps;
6296  }
6297  }
6298 
6300 
6304  open_set_file(++clipnum);
6307 
6309 
6311 
6312  if (mainw->current_file < 1) continue;
6313 
6314  if (cfile->clip_type == CLIP_TYPE_FILE && cfile->header_version >= 102) cfile->fps = cfile->pb_fps;
6316 
6317  if (CLIP_TOTAL_TIME(mainw->current_file) == 0.) {
6318  close_current_file(last_good_file);
6319  continue;
6320  }
6321 
6322  last_good_file = mainw->current_file;
6323 
6324  if (cfile->needs_update || cfile->needs_silent_update) {
6325  if (cfile->needs_update) do_clip_divergence_error(mainw->current_file);
6327  cfile->needs_silent_update = cfile->needs_update = FALSE;
6328  }
6329 
6330  // add to clip menu
6332  add_to_clipmenu();
6333  cfile->start = cfile->frames > 0 ? 1 : 0;
6334  cfile->end = cfile->frames;
6335  cfile->is_loaded = TRUE;
6336  cfile->changed = TRUE;
6337  lives_rm(cfile->info_file);
6338  if (!mainw->multitrack) set_main_title(cfile->name, 0);
6339 
6340  if (cfile->frameno > cfile->frames) cfile->frameno = cfile->last_frameno = 1;
6341 
6342  if (!mainw->multitrack) {
6344  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->start);
6347  lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end);
6349  showclipimgs();
6350  } else {
6351  int current_file = mainw->current_file;
6352  lives_mt *multi = mainw->multitrack;
6353  mainw->multitrack = NULL;
6354  mainw->current_file = -1;
6355  reget_afilesize(current_file);
6356  mainw->current_file = current_file;
6357  mainw->multitrack = multi;
6359  mainw->current_file = mainw->multitrack->render_file;
6360  mt_init_clips(mainw->multitrack, current_file, TRUE);
6365  mainw->current_file = current_file;
6366  }
6367 
6369 
6370  if (cfile->frameno > cfile->frames && cfile->frameno > 1) cfile->frameno = cfile->frames;
6371  cfile->last_frameno = cfile->frameno;
6372  cfile->pointer_time = cfile->real_pointer_time = calc_time_from_frame(mainw->current_file, cfile->frameno);
6373  if (cfile->real_pointer_time > CLIP_TOTAL_TIME(mainw->current_file))
6374  cfile->real_pointer_time = CLIP_TOTAL_TIME(mainw->current_file);
6375  if (cfile->pointer_time > cfile->video_time) cfile->pointer_time = 0.;
6376 
6377  if (cfile->achans) {
6378  cfile->aseek_pos = (off64_t)((double)(cfile->real_pointer_time * cfile->arate) * cfile->achans *
6379  (cfile->asampsize / 8));
6380  if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
6381  }
6382 
6383  if (mainw->current_file != -1)
6385 
6386  if (!mainw->multitrack) resize(1);
6387 
6389  }
6390  }
6391 
6393 
6394  ngoodclips = lives_list_length(mainw->cliplist);
6395  if (!ngoodclips) {
6396  d_print(_("No clips were recovered.\n"));
6397  }
6398  d_print(P_("%d clip was recovered ", "%d clips were recovered ", ngoodclips), ngoodclips);
6399  if (recovery_file)
6400  d_print(_("from the previous session.\n"));
6401  else
6402  d_print(_("from previous sessions.\n"));
6403 
6404  if (!mainw->multitrack) { // TODO check if we can do this in mt too
6405  int start_file = mainw->current_file;
6406  if (start_file > 1 && start_file == mainw->ascrap_file && mainw->files[start_file - 1]) {
6407  start_file--;
6408  }
6409  if (start_file > 1 && start_file == mainw->scrap_file && mainw->files[start_file - 1]) {
6410  start_file--;
6411  }
6412  if (start_file > 1 && start_file == mainw->ascrap_file && mainw->files[start_file - 1]) {
6413  start_file--;
6414  }
6415  if ((!IS_VALID_CLIP(start_file) || (mainw->files[start_file]->frames == 0 && mainw->files[start_file]->afilesize == 0))
6416  && mainw->files[1] && start_file != 1) {
6417  for (start_file = MAX_FILES; start_file > 0; start_file--) {
6418  if (mainw->files[start_file]
6419  && (mainw->files[start_file]->frames > 0 || mainw->files[start_file]->afilesize > 0))
6420  if (start_file != mainw->scrap_file && start_file != mainw->ascrap_file) break;
6421  }
6422  }
6423 
6424  if (start_file != mainw->current_file) {
6425  rec_cleanup = TRUE;
6426  switch_to_file(mainw->current_file, start_file);
6427  showclipimgs();
6429  }
6430  } else {
6431  mt_clip_select(mainw->multitrack, TRUE); // scroll clip on screen
6432  }
6433 
6434  if (recovery_file) fclose(rfile);
6435 
6436 recovery_done:
6437 
6439 
6443  mainw->is_ready = is_ready;
6444  if (mainw->multitrack) {
6445  mainw->multitrack->is_ready = mt_is_ready;
6446  mainw->current_file = mainw->multitrack->render_file;
6450  if (mt_needs_idlefunc) mainw->multitrack->idlefunc = mt_idle_add(mainw->multitrack);
6451  } else update_play_times();
6452  mainw->last_dprint_file = -1;
6454  d_print("");
6455  mainw->invalid_clips = rec_cleanup;
6456  return retb;
6457 }
6458 
6459 
6460 void add_to_recovery_file(const char *handle) {
6461  lives_echo(handle, mainw->recovery_file, TRUE);
6462 
6463  if (THREADVAR(com_failed)) {
6464  THREADVAR(com_failed) = FALSE;
6465  return;
6466  }
6467 
6468  if ((mainw->multitrack && mainw->multitrack->event_list) || mainw->stored_event_list)
6470 }
6471 
6472 
6473 boolean rewrite_recovery_file(void) {
6474  // part of the crash recovery system
6475  // returns TRUE if successful
6476  LiVESList *clist = mainw->cliplist;
6477  char *recovery_entry;
6478  char *temp_recovery_file;
6479 
6480  boolean opened = FALSE;
6481  boolean wrote_set_entry = FALSE;
6482 
6483  int recovery_fd = -1;
6484  LiVESResponseType retval;
6485 
6486  if (!clist || !prefs->crash_recovery) {
6488  return FALSE;
6489  }
6490 
6491  temp_recovery_file = lives_strdup_printf("%s.%s", mainw->recovery_file, LIVES_FILE_EXT_TMP);
6492 
6493  do {
6494  retval = LIVES_RESPONSE_NONE;
6495  THREADVAR(write_failed) = FALSE;
6496  opened = FALSE;
6497  recovery_fd = -1;
6498 
6499  for (; clist; clist = clist->next) {
6500  int i = LIVES_POINTER_TO_INT(clist->data);
6501  if (IS_NORMAL_CLIP(i)) {
6502  lives_clip_t *sfile = mainw->files[i];
6503  if (i == mainw->scrap_file) {
6504  recovery_entry = lives_strdup_printf("scrap|%s\n", sfile->handle);
6505  } else if (i == mainw->ascrap_file) {
6506  recovery_entry = lives_strdup_printf("ascrap|%s\n", sfile->handle);
6507  } else {
6508  if (sfile->was_in_set && *mainw->set_name) {
6509  if (!wrote_set_entry) {
6510  recovery_entry = lives_build_filename(mainw->set_name, "*\n", NULL);
6511  wrote_set_entry = TRUE;
6512  } else continue;
6513  } else recovery_entry = lives_strdup_printf("%s\n", sfile->handle);
6514  }
6515 
6516  if (!opened) recovery_fd = creat(temp_recovery_file, S_IRUSR | S_IWUSR);
6517  if (recovery_fd < 0) retval = do_write_failed_error_s_with_retry(temp_recovery_file, lives_strerror(errno));
6518  else {
6519  opened = TRUE;
6520  lives_write(recovery_fd, recovery_entry, strlen(recovery_entry), TRUE);
6521  if (THREADVAR(write_failed)) retval = do_write_failed_error_s_with_retry(temp_recovery_file, NULL);
6522  }
6523  lives_free(recovery_entry);
6524  }
6525  if (THREADVAR(write_failed)) break;
6526  }
6527  } while (retval == LIVES_RESPONSE_RETRY);
6528 
6529  if (!opened) lives_rm(mainw->recovery_file);
6530  else if (recovery_fd >= 0) {
6531  close(recovery_fd);
6532  retval = LIVES_RESPONSE_INVALID;
6533  do {
6534  lives_mv(temp_recovery_file, mainw->recovery_file);
6535  if (THREADVAR(com_failed)) {
6536  retval = do_write_failed_error_s_with_retry(temp_recovery_file, NULL);
6537  }
6538  } while (retval == LIVES_RESPONSE_RETRY);
6539  }
6540 
6541  lives_free(temp_recovery_file);
6542 
6543  if ((mainw->multitrack && mainw->multitrack->event_list) || mainw->stored_event_list)
6545 
6546  return TRUE;
6547 }
6548 
6549 
6550 boolean check_for_recovery_files(boolean auto_recover) {
6551  uint32_t recpid = 0;
6552 
6553  char *recovery_file, *recovery_numbering_file, *recording_file, *recording_numbering_file, *xfile;
6554  char *com;
6555 
6556  boolean retval = FALSE;
6557  boolean found = FALSE, found_recording = FALSE;
6558 
6559  int lgid = lives_getgid();
6560  int luid = lives_getuid();
6561 
6562  lives_pgid_t lpid = capable->mainpid;
6563 
6564  // ask backend to find the latest recovery file which is not owned by a running version of LiVES
6565  com = lives_strdup_printf("%s get_recovery_file %d %d %s recovery %d", prefs->backend_sync, luid, lgid,
6567 
6569  lives_free(com);
6570 
6571  if (THREADVAR(com_failed)) {
6572  THREADVAR(com_failed) = FALSE;
6573  return FALSE;
6574  }
6575 
6576  recpid = atoi(mainw->msg);
6577  if (recpid == 0) return FALSE;
6578 
6579  retval = recover_files((recovery_file = lives_strdup_printf("%s/recovery.%d.%d.%d", prefs->workdir, luid,
6580  lgid, recpid)), auto_recover);
6581  lives_free(recovery_file);
6582 
6583  if (!retval || prefs->vj_mode) {
6584  com = lives_strdup_printf("%s clean_recovery_files %d %d \"%s\" %d %d", prefs->backend_sync, luid, lgid, capable->myname,
6586  lives_system(com, FALSE);
6587  lives_free(com);
6588  if (prefs->vj_mode) {
6590  return TRUE;
6591  }
6592  return FALSE;
6593  }
6594 
6595 #if !GTK_CHECK_VERSION(3, 0, 0)
6596  if (CURRENT_CLIP_IS_VALID) {
6597  showclipimgs();
6601  }
6602 #endif
6603 
6604  THREADVAR(com_failed) = FALSE;
6605 
6608 
6609  // check for layout recovery file
6610  recovery_file = lives_strdup_printf("%s/%s.%d.%d.%d.%s", prefs->workdir, LAYOUT_FILENAME, luid, lgid, recpid,
6612  recovery_numbering_file = lives_strdup_printf("%s/%s.%d.%d.%d", prefs->workdir, LAYOUT_NUMBERING_FILENAME, luid, lgid, recpid);
6613 
6614  recording_file = lives_strdup_printf("%s/recorded-%s.%d.%d.%d.%s", prefs->workdir, LAYOUT_FILENAME, luid, lgid, recpid,
6616 
6617  recording_numbering_file = lives_strdup_printf("%s/recorded-%s.%d.%d.%d", prefs->workdir, LAYOUT_NUMBERING_FILENAME, luid, lgid,
6618  recpid);
6619 
6620  if (!lives_file_test(recovery_file, LIVES_FILE_TEST_EXISTS)) {
6621  lives_free(recovery_file);
6622  recovery_file = lives_strdup_printf("%s/%s.%d.%d.%d", prefs->workdir, LAYOUT_FILENAME, luid, lgid, recpid);
6623  if (lives_file_test(recovery_file, LIVES_FILE_TEST_EXISTS)) {
6624  found = TRUE;
6625  }
6626  } else {
6627  found = TRUE;
6628  }
6629  if (found) {
6630  if (!lives_file_test(recovery_numbering_file, LIVES_FILE_TEST_EXISTS)) {
6631  found = FALSE;
6632  }
6633  }
6634 
6635  if (prefs->rr_crash && lives_file_test(recording_file, LIVES_FILE_TEST_EXISTS)) {
6636  if (lives_file_test(recording_numbering_file, LIVES_FILE_TEST_EXISTS)) {
6637  found_recording = TRUE;
6638  xfile = lives_strdup_printf("%s/keep_recorded-layout.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6639  lives_mv(recording_file, xfile);
6640  lives_free(xfile);
6641  xfile = lives_strdup_printf("%s/keep_recorded-layout_numbering.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6642  lives_mv(recording_numbering_file, xfile);
6643  lives_free(xfile);
6645  }
6646  }
6647 
6648  if (found) {
6649  // move files temporarily to stop them being cleansed
6650  xfile = lives_strdup_printf("%s/keep_layout.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6651  lives_mv(recovery_file, xfile);
6652  lives_free(xfile);
6653  xfile = lives_strdup_printf("%s/keep_layout_numbering.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6654  lives_mv(recovery_numbering_file, xfile);
6655  lives_free(xfile);
6657  }
6658 
6659  if (!found && !found_recording) {
6660  if (mainw->scrap_file != -1) close_scrap_file(TRUE);
6661  if (mainw->ascrap_file != -1) close_ascrap_file(TRUE);
6662  }
6663 
6664  lives_free(recovery_file);
6665  lives_free(recovery_numbering_file);
6666  lives_free(recording_file);
6667  lives_free(recording_numbering_file);
6668 
6669  if (THREADVAR(com_failed) && prefs->crash_recovery) {
6671  return FALSE;
6672  }
6673 
6674  com = lives_strdup_printf("%s clean_recovery_files %d %d \"%s\" %d 0", prefs->backend_sync, luid, lgid, capable->myname,
6675  capable->mainpid);
6676  lives_system(com, FALSE);
6677  lives_free(com);
6678 
6679  recovery_file = lives_strdup_printf("%s/%s.%d.%d.%d.%s", prefs->workdir, LAYOUT_FILENAME, luid, lgid, lpid,
6681  recovery_numbering_file = lives_strdup_printf("%s/%s.%d.%d.%d", prefs->workdir, LAYOUT_NUMBERING_FILENAME, luid, lgid, lpid);
6682 
6683  if (mainw->recoverable_layout) {
6684  // move files back
6685  xfile = lives_strdup_printf("%s/keep_layout.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6686  lives_mv(xfile, recovery_file);
6687  lives_free(xfile);
6688  xfile = lives_strdup_printf("%s/keep_layout_numbering.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6689  lives_mv(xfile, recovery_numbering_file);
6690  lives_free(xfile);
6691  }
6692 
6693  recording_file = lives_strdup_printf("%s/recorded-%s.%d.%d.%d.%s", prefs->workdir, LAYOUT_FILENAME, luid, lgid, lpid,
6695  recording_numbering_file = lives_strdup_printf("%s/recorded-%s.%d.%d.%d", prefs->workdir, LAYOUT_NUMBERING_FILENAME, luid, lgid,
6696  lpid);
6697 
6698  if (mainw->recording_recovered) {
6699  xfile = lives_strdup_printf("%s/keep_recorded-layout.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6701  lives_mv(xfile, recording_file);
6702  lives_free(xfile);
6703  xfile = lives_strdup_printf("%s/keep_recorded-layout_numbering.%d.%d.%d", prefs->workdir, luid, lgid, lpid);
6704  lives_mv(xfile, recording_numbering_file);
6705  lives_free(xfile);
6706  }
6707 
6708  lives_free(recovery_file);
6709  lives_free(recovery_numbering_file);
6710  lives_free(recording_file);
6711  lives_free(recording_numbering_file);
6712 
6714  mainw->abort_hook_func = NULL;
6715 
6719  else do_after_crash_warning();
6721  }
6722  return retval;
6723 }
6724 
_prefs::instant_open
boolean instant_open
Definition: preferences.h:301
CLIP_DETAILS_TITLE
@ CLIP_DETAILS_TITLE
Definition: main.h:1155
lives_format_storage_space_string
char * lives_format_storage_space_string(uint64_t space)
Definition: machinestate.c:664
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
is_writeable_dir
boolean is_writeable_dir(const char *dir)
Definition: utils.c:5701
layout_frame_is_affected
LiVESList * layout_frame_is_affected(int clipno, int start, int end, LiVESList *xlays)
Definition: multitrack.c:22247
lives_source_remove
WIDGET_HELPER_GLOBAL_INLINE boolean lives_source_remove(uint32_t handle)
Definition: widget-helper.c:7361
AFORM_UNSIGNED
#define AFORM_UNSIGNED
Definition: main.h:786
clear_mainw_msg
void clear_mainw_msg(void)
Definition: utils.c:1435
render_details::encoder_name
char * encoder_name
Definition: events.h:245
fade_background
void fade_background(void)
Definition: gui.c:3216
lives_xwindow_set_keep_above
WIDGET_HELPER_GLOBAL_INLINE boolean lives_xwindow_set_keep_above(LiVESXWindow *xwin, boolean setting)
Definition: widget-helper.c:4780
ANNOY_DISPLAY
#define ANNOY_DISPLAY
Definition: main.h:441
lives_spin_button_set_range
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_range(LiVESSpinButton *button, double min, double max)
Definition: widget-helper.c:5129
create_frame_index
boolean create_frame_index(int fileno, boolean init, frames_t start_offset, frames_t nframes)
Definition: cvirtual.c:27
desensitize
void desensitize(void)
Definition: main.c:5302
save_file_comments
boolean save_file_comments(int fileno)
Definition: saveplay.c:4100
lives_window_center
boolean lives_window_center(LiVESWindow *window)
Definition: widget-helper.c:11251
mainwindow::rte_textparm
weed_plant_t * rte_textparm
send keyboard input to this paramter (usually NULL)
Definition: mainwindow.h:1589
lives_clip_t::save_file_name
char save_file_name[PATH_MAX]
Definition: main.h:924
lives_subtitle_type_t
lives_subtitle_type_t
Definition: pangotext.h:15
CLIP_DETAILS_HEADER_VERSION
@ CLIP_DETAILS_HEADER_VERSION
Definition: main.h:1161
lives_text_view_get_text
char * lives_text_view_get_text(LiVESTextView *textview)
Definition: widget-helper.c:11706
mainwindow::gen_started_play
boolean gen_started_play
Definition: mainwindow.h:1694
lives_clip_t::header_version
int header_version
Definition: main.h:940
binval::num
uint64_t num
Definition: main.h:871
backup_file
void backup_file(int clip, int start, int end, const char *file_name)
Definition: saveplay.c:4264
lives_check_menu_item_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_check_menu_item_set_active(LiVESCheckMenuItem *item, boolean state)
Definition: widget-helper.c:6537
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
write_backup_layout_numbering
boolean write_backup_layout_numbering(lives_mt *mt)
Definition: multitrack.c:668
EFFORT_RANGE_MAX
#define EFFORT_RANGE_MAX
if set to TRUE during playback then a new frame (or possibly the current one) will be displayed ASAP
Definition: mainwindow.h:1770
mainwindow::endian
short endian
Definition: mainwindow.h:817
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_image_type_to_img_type
lives_img_type_t lives_image_type_to_img_type(const char *lives_image_type)
Definition: utils.c:3046
create_nullvideo_clip
int create_nullvideo_clip(const char *handle)
Definition: saveplay.c:3808
LIVES_CLIP_HEADER_OLD
#define LIVES_CLIP_HEADER_OLD
Definition: mainwindow.h:559
mainwindow::cliplist
LiVESList * cliplist
hash table of clips in menu order
Definition: mainwindow.h:743
mainwindow::m_mutebutton
LiVESWidget * m_mutebutton
Definition: mainwindow.h:1370
mainwindow::decoder_list
LiVESList * decoder_list
Definition: mainwindow.h:1612
mainwindow::swapped_clip
int swapped_clip
maintains the current cliplist postion even if we swap fg and bg clips
Definition: mainwindow.h:850
do_write_failed_error_s
void do_write_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:3979
_encoder::of_allowed_acodecs
int of_allowed_acodecs
Definition: plugins.h:265
mainwindow::iochan
LiVESIOChannel * iochan
encoder text output
Definition: mainwindow.h:1605
lives_ce_update_timeline
double lives_ce_update_timeline(int frame, double x)
pointer position in timeline
Definition: interface.c:207
mainwindow::effects_paused
boolean effects_paused
Definition: mainwindow.h:1055
lives_clip_data_t::height
int height
Definition: plugins.h:348
mainwindow::recent
LiVESWidget * recent[N_RECENT_FILES]
Definition: mainwindow.h:1129
mainwindow::prefs_cache
LiVESList * prefs_cache
file caches
Definition: mainwindow.h:1517
TOTALSAVE_NAME
#define TOTALSAVE_NAME
Definition: mainwindow.h:535
_palette::normal_back
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
mainwindow::oloop_cont
boolean oloop_cont
Definition: mainwindow.h:767
close_scrap_file
void close_scrap_file(boolean remove)
Definition: saveplay.c:5583
lives_clip_t::file_name
char file_name[PATH_MAX]
input file
Definition: main.h:923
mainwindow::m_stopbutton
LiVESWidget * m_stopbutton
Definition: mainwindow.h:1369
weed_plant_deserialise
weed_plant_t * weed_plant_deserialise(int fd, unsigned char **mem, weed_plant_t *plant)
Definition: effects-weed.c:11770
mainwindow::period
double period
timing variables
Definition: mainwindow.h:996
get_untitled_name
LIVES_GLOBAL_INLINE char * get_untitled_name(int number)
Definition: saveplay.c:3802
lives_free
#define lives_free
Definition: machinestate.h:52
mainwindow::preview_controls
LiVESWidget * preview_controls
Definition: mainwindow.h:1378
lives_file_chooser_get_filename
WIDGET_HELPER_GLOBAL_INLINE char * lives_file_chooser_get_filename(LiVESFileChooser *chooser)
Definition: widget-helper.c:6721
LIVES_WARN
#define LIVES_WARN(x)
Definition: main.h:1862
do_after_invalid_warning
LIVES_GLOBAL_INLINE void do_after_invalid_warning(void)
Definition: dialogs.c:3748
mainwindow::rec_samples
int64_t rec_samples
Definition: mainwindow.h:1527
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
do_file_notfound_dialog
LiVESResponseType do_file_notfound_dialog(const char *detail, const char *filename)
Definition: dialogs.c:3513
SECOND_STOP_TIME
#define SECOND_STOP_TIME
mainwindow::playarea
LiVESWidget * playarea
Definition: mainwindow.h:1321
lives_clip_t::interlace
lives_interlace_t interlace
interlace type (if known - none, topfirst, bottomfirst or : see plugins.h)
Definition: main.h:899
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
lives_clip_t::was_renamed
boolean was_renamed
Definition: main.h:926
get_worktmp
char * get_worktmp(const char *prefix)
Definition: machinestate.c:3246
mainwindow::idlemax
int idlemax
Definition: mainwindow.h:1741
LIVES_CURSOR_NORMAL
@ LIVES_CURSOR_NORMAL
must be zero
Definition: widget-helper.h:1292
resaudw
_resaudw * resaudw
Definition: resample.h:38
EXEC_MPV
#define EXEC_MPV
Definition: mainwindow.h:388
check_for_disk_space
boolean check_for_disk_space(boolean fullcheck)
Definition: saveplay.c:5416
mainwindow::audio_event
weed_plant_t * audio_event
Definition: mainwindow.h:1300
mainwindow::record
volatile boolean record
Definition: mainwindow.h:794
EXEC_MIDISTOP
#define EXEC_MIDISTOP
shipped
Definition: mainwindow.h:416
open_vid_playback_plugin
_vid_playback_plugin * open_vid_playback_plugin(const char *name, boolean in_use)
Definition: plugins.c:1099
_prefs::safe_symlinks
boolean safe_symlinks
Definition: preferences.h:327
do_progress_dialog
boolean do_progress_dialog(boolean visible, boolean cancellable, const char *text)
Definition: dialogs.c:2274
mt_desensitise
void mt_desensitise(lives_mt *mt)
Definition: multitrack.c:16979
lives_widget_destroy
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
Definition: widget-helper.c:1553
mainwindow::frame1
LiVESWidget * frame1
Definition: mainwindow.h:1094
lives_widget_grab_focus
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_grab_focus(LiVESWidget *widget)
Definition: widget-helper.c:4712
break_me
void break_me(const char *brkstr)
Definition: main.c:159
mainwindow::loop_locked
boolean loop_locked
Definition: mainwindow.h:769
mainwindow::redo
LiVESWidget * redo
Definition: mainwindow.h:1147
CANCEL_USER_PAUSED
@ CANCEL_USER_PAUSED
cancelled and paused
Definition: main.h:746
lives_read_le
ssize_t lives_read_le(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:486
mainwindow::abuf_mutex
pthread_mutex_t abuf_mutex
mutices
Definition: mainwindow.h:1495
save_file
void save_file(int clip, int start, int end, const char *filename)
Definition: saveplay.c:1260
mainwindow::loop
boolean loop
Definition: mainwindow.h:763
mainwindow::xlays
LiVESList * xlays
immediately (to be) affected layout maps
Definition: mainwindow.h:1477
lives_set_cursor_style
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
Definition: widget-helper.c:11950
play_file
void play_file(void)
play the current clip from 'mainw->play_start' to 'mainw->play_end'
Definition: saveplay.c:2213
_prefs::workdir
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
start_playback_async
LIVES_GLOBAL_INLINE void start_playback_async(int type)
Definition: saveplay.c:96
mainwindow::invalid_clips
boolean invalid_clips
Definition: mainwindow.h:1484
lives_spin_button_set_value
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_value(LiVESSpinButton *button, double value)
Definition: widget-helper.c:5119
lives_window_maximize
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_maximize(LiVESWindow *window)
Definition: widget-helper.c:2889
version
const char * version(void)
LIVES_TOY_TV
@ LIVES_TOY_TV
Definition: mainwindow.h:236
lives_clip_t::keywords
char keywords[1024]
Definition: main.h:919
_prefs::show_gui
boolean show_gui
Definition: preferences.h:290
lives_clip_data_t::URI
char * URI
the URI of this cdata
Definition: plugins.h:334
DEF_IDLE_MAX
#define DEF_IDLE_MAX
Definition: mainwindow.h:1740
ANNOY_FS
#define ANNOY_FS
Definition: main.h:449
clear_widget_bg
WIDGET_HELPER_GLOBAL_INLINE boolean clear_widget_bg(LiVESWidget *widget, lives_painter_surface_t *s)
Definition: widget-helper.c:11108
lives_xwindow_raise
WIDGET_HELPER_GLOBAL_INLINE boolean lives_xwindow_raise(LiVESXWindow *xwin)
Definition: widget-helper.c:6312
_prefs::jack_opts
uint32_t jack_opts
Definition: preferences.h:232
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
LIVES_FILE_EXT_SCRAP
#define LIVES_FILE_EXT_SCRAP
Definition: mainwindow.h:493
IS_VALID_CLIP
#define IS_VALID_CLIP(clip)
Definition: main.h:808
lives_decoder_t
Definition: plugins.h:449
mainwindow::ignore_screen_size
boolean ignore_screen_size
applied during frame reconfig events
Definition: mainwindow.h:1745
lives_clip_details_t
lives_clip_details_t
Definition: main.h:1141
_prefs::crash_recovery
boolean crash_recovery
TRUE==maintain mainw->recovery file.
Definition: preferences.h:259
lives_cp
int lives_cp(const char *from, const char *to)
Definition: utils.c:4414
weed_plant_serialise
size_t weed_plant_serialise(int fd, weed_plant_t *plant, unsigned char **mem)
Definition: effects-weed.c:11198
mainwindow::m_rewindbutton
LiVESWidget * m_rewindbutton
Definition: mainwindow.h:1369
lives_clip_data_t::title
char title[1024]
Definition: plugins.h:339
mainwindow::vpp
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
do_file_perm_error
LiVESResponseType do_file_perm_error(const char *file_name, boolean allow_cancel)
Definition: dialogs.c:4226
mainwindow::size_warn
int size_warn
warn the user that incorrectly sized frames were found (threshold count)
Definition: mainwindow.h:1017
lives_toggle_tool_button_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_tool_button_set_active(LiVESToggleToolButton *button, boolean active)
Definition: widget-helper.c:4525
_palette::style
int style
Definition: mainwindow.h:297
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
mainwindow::preview
boolean preview
Definition: mainwindow.h:757
WARN_MASK_LAYOUT_DELETE_AUDIO
#define WARN_MASK_LAYOUT_DELETE_AUDIO
Definition: preferences.h:110
lives_widget_hide
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
Definition: widget-helper.c:1514
lives_clip_t::start
frames_t start
Definition: main.h:891
mainwindow::spin_end_func
ulong spin_end_func
Definition: mainwindow.h:1065
CLIP_DETAILS_COMMENT
@ CLIP_DETAILS_COMMENT
Definition: main.h:1157
effects.h
ASERVER_CMD_FILE_CLOSE
#define ASERVER_CMD_FILE_CLOSE
Definition: audio.h:58
CANCEL_APP_QUIT
@ CANCEL_APP_QUIT
application quit
Definition: main.h:713
lives_fsync
boolean lives_fsync(int fd)
Definition: utils.c:109
mainwindow::eventbox3
LiVESWidget * eventbox3
Definition: mainwindow.h:1333
do_set_locked_warning
LIVES_GLOBAL_INLINE boolean do_set_locked_warning(const char *setname)
Definition: dialogs.c:4357
update_play_times
void update_play_times(void)
like get_play_times, but will force redraw of audio waveforms
Definition: utils.c:3677
get_dirname
void get_dirname(char *filename)
Definition: utils.c:3167
lives_menu_item_set_accel_path
WIDGET_HELPER_GLOBAL_INLINE boolean lives_menu_item_set_accel_path(LiVESMenuItem *menuitem, const char *path)
Definition: widget-helper.c:6408
mainwindow::new_clip
int new_clip
clip we should switch to during playback; switch will happen at the designated SWITCH POINT
Definition: mainwindow.h:1022
calc_frame_from_time
int calc_frame_from_time(int filenum, double time)
nearest frame [1, frames]
Definition: utils.c:1759
lives_clip_t::bpp
int bpp
bits per pixel of the image frames, 24 or 32
Definition: main.h:901
do_warning_dialog_with_check
boolean do_warning_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:569
add_suffix_check
void add_suffix_check(LiVESBox *box, const char *ext)
Definition: interface.c:23
_palette::normal_fore
LiVESWidgetColor normal_fore
Definition: mainwindow.h:325
showclipimgs
void showclipimgs(void)
Definition: main.c:5636
LIVES_ERROR
#define LIVES_ERROR(x)
Definition: main.h:1870
mainwindow::clip_switched
boolean clip_switched
for recording - did we switch clips ?
Definition: mainwindow.h:793
lives_clip_t::frames
frames_t frames
number of video frames
Definition: main.h:890
pump_io_chan
void pump_io_chan(LiVESIOChannel *iochan)
Definition: dialogs.c:1020
lives_clip_t::clip_type
lives_clip_type_t clip_type
Definition: main.h:886
cvirtual.h
lives_string_ends_with
boolean lives_string_ends_with(const char *string, const char *fmt,...)
Definition: utils.c:3143
CLIP_DETAILS_ACHANS
@ CLIP_DETAILS_ACHANS
Definition: main.h:1150
mainwindow::play_window
LiVESWidget * play_window
Definition: mainwindow.h:947
enable_record
void enable_record(void)
Definition: gui.c:3706
prefs
_prefs * prefs
Definition: preferences.h:847
reload_set
boolean reload_set(const char *set_name)
Definition: callbacks.c:5661
d_print_urgency
boolean d_print_urgency(double timeout_seconds, const char *fmt,...)
Definition: utils.c:2497
mainwindow::save_with_sound
boolean save_with_sound
Definition: mainwindow.h:784
_prefs::backend
char backend[PATH_MAX *4]
Definition: preferences.h:411
virtual_to_images
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
Definition: cvirtual.c:719
lives_clip_t::type
char type[64]
Definition: main.h:884
LIVES_ACLIP_HEADER_NEW
#define LIVES_ACLIP_HEADER_NEW
Definition: mainwindow.h:558
polymorph
void polymorph(lives_mt *mt, lives_mt_poly_state_t poly)
Definition: multitrack.c:12777
_prefs::lib_dir
char lib_dir[PATH_MAX]
Definition: preferences.h:75
_prefs::audio_player
short audio_player
Definition: preferences.h:40
mainwindow::video_seek_ready
volatile boolean video_seek_ready
Definition: mainwindow.h:939
set_default_comment
LIVES_GLOBAL_INLINE void set_default_comment(lives_clip_t *sfile, const char *extrat)
Definition: saveplay.c:1251
CLIP_DETAILS_WIDTH
@ CLIP_DETAILS_WIDTH
Definition: main.h:1145
mainwindow::decoders_loaded
boolean decoders_loaded
decoders
Definition: mainwindow.h:1611
lives_dialog_run
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
Definition: widget-helper.c:1783
mainwindow::record_starting
boolean record_starting
start recording at next frame
Definition: mainwindow.h:1559
lives_open2
int lives_open2(const char *pathname, int flags)
Definition: utils.c:99
pad_init_silence
void pad_init_silence(void)
Definition: saveplay.c:293
mainwindow::abort_hook_func
lives_funcptr_t abort_hook_func
can be set to point to a function to be run before abort, for critical functions
Definition: mainwindow.h:1081
check_clip_integrity
boolean check_clip_integrity(int fileno, const lives_clip_data_t *cdata, frames_t maxframe)
Definition: cvirtual.c:296
LIVES_FILE_EXT_JPG
#define LIVES_FILE_EXT_JPG
Definition: mainwindow.h:488
RES_HIDE
#define RES_HIDE
Definition: main.h:456
mainwindow::recovery_file
char * recovery_file
the filename of our recover file
Definition: mainwindow.h:1481
_prefs::show_recent
boolean show_recent
Definition: preferences.h:179
mainwindow::frame_layer
weed_plant_t * frame_layer
Definition: mainwindow.h:948
struct_from_template
void * struct_from_template(lives_struct_type st_type)
Definition: lsd-tab.c:76
mainwindow::raudio_draw
LiVESWidget * raudio_draw
Definition: mainwindow.h:1383
verhash
int verhash(char *version)
Definition: utils.c:4755
_prefs::disk_quota
uint64_t disk_quota
Definition: preferences.h:383
capability::has_mktemp
lives_checkstatus_t has_mktemp
Definition: main.h:540
lives_clip_t::binfmt_check
binval binfmt_check
Definition: main.h:878
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
mainwindow::loop_video
LiVESWidget * loop_video
Definition: mainwindow.h:1173
lives_accel_group_disconnect
WIDGET_HELPER_GLOBAL_INLINE boolean lives_accel_group_disconnect(LiVESAccelGroup *group, LiVESWidgetClosure *closure)
Definition: widget-helper.c:2940
mainwindow::framecounter
LiVESWidget * framecounter
Definition: mainwindow.h:1390
lives_proc_thread_t
weed_plantptr_t lives_proc_thread_t
lives proc_threads API
Definition: machinestate.c:1670
LIVES_FILE_EXT_SUB
#define LIVES_FILE_EXT_SUB
Definition: mainwindow.h:508
CLIP_DETAILS_KEYWORDS
@ CLIP_DETAILS_KEYWORDS
Definition: main.h:1162
LIVES_DIRECTION_FORWARD
@ LIVES_DIRECTION_FORWARD
Definition: main.h:854
do_after_crash_warning
LIVES_GLOBAL_INLINE void do_after_crash_warning(void)
Definition: dialogs.c:3742
WARN_MASK_LAYOUT_DELETE_FRAMES
#define WARN_MASK_LAYOUT_DELETE_FRAMES
Definition: preferences.h:96
lives_frame_get_label_widget
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_frame_get_label_widget(LiVESFrame *frame)
Definition: widget-helper.c:6867
do_comments_dialog
boolean do_comments_dialog(int fileno, char *filename)
Definition: dialogs.c:3288
_prefs::show_msg_area
boolean show_msg_area
Definition: preferences.h:225
SEPWIN_TYPE_STICKY
#define SEPWIN_TYPE_STICKY
Definition: preferences.h:188
mainwindow::noswitch
boolean noswitch
value set automatically to prevent 'inopportune' clip switching
Definition: mainwindow.h:1019
_prefs::btgamma
boolean btgamma
allows clips to be stored with bt709 gamma - CAUTION not backwards compatible, untested
Definition: preferences.h:453
USE_MPV
#define USE_MPV
some shared structures
Definition: main.h:1112
add_lmap_error
boolean add_lmap_error(lives_lmap_error_t lerror, const char *name, livespointer user_data, int clipno, int frameno, double atime, boolean affects_current)
Definition: utils.c:2673
lives_alarm_clear
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
mainwindow::mute_audio
LiVESWidget * mute_audio
Definition: mainwindow.h:1177
TICKS_PER_SECOND_DBL
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
DSIZE_MAX
#define DSIZE_MAX
Definition: saveplay.c:5948
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
free_jack_audio_buffers
void free_jack_audio_buffers(void)
Definition: audio.c:2748
LIVES_OSC_NOTIFY_PLAYBACK_STARTED
#define LIVES_OSC_NOTIFY_PLAYBACK_STARTED
sent when a/v playback starts or clip is switched
Definition: osc_notify.h:34
CANCEL_KILL
@ CANCEL_KILL
normal - kill background processes working on current clip
Definition: main.h:759
mt_init_clips
void mt_init_clips(lives_mt *mt, int orig_file, boolean add)
Definition: multitrack.c:10859
H_RESIZE_ADJUST
#define H_RESIZE_ADJUST
Definition: mainwindow.h:66
sensitize
void sensitize(void)
Definition: main.c:5078
AUD_PLAYER_NONE
#define AUD_PLAYER_NONE
Definition: preferences.h:41
mainwindow::osc_auto
int osc_auto
bypass user choices automatically
Definition: mainwindow.h:918
mainwindow::actual_frame
frames_t actual_frame
actual / last frame being displayed
Definition: mainwindow.h:959
LIVES_OSC_NOTIFY_PLAYBACK_STOPPED
#define LIVES_OSC_NOTIFY_PLAYBACK_STOPPED
sent when a/v playback ends
Definition: osc_notify.h:35
deduce_file
ulong deduce_file(const char *file_name, double start, int end)
Definition: saveplay.c:238
get_token_count
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
CLIP_TYPE_GENERATOR
@ CLIP_TYPE_GENERATOR
frames from generator plugin
Definition: main.h:766
lives_clip_t::pointer_time
double pointer_time
pointer time in timeline, + the playback start posn for clipeditor (unless playing the selection)
Definition: main.h:931
add_to_clipmenu
void add_to_clipmenu(void)
Definition: gui.c:4512
set_main_title
void set_main_title(const char *file, int untitled)
Definition: main.c:5005
mainwindow::ext_audio_mon
LiVESWidget * ext_audio_mon
Definition: mainwindow.h:1359
CANCEL_USER
@ CANCEL_USER
user pressed stop
Definition: main.h:704
lives_widget_get_xwindow
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_widget_get_xwindow(LiVESWidget *widget)
Definition: widget-helper.c:4759
capability::mainpid
pid_t mainpid
Definition: main.h:591
mainwindow::fc_buttonresponse
int fc_buttonresponse
Definition: mainwindow.h:1715
check_storage_space
boolean check_storage_space(int clipno, boolean is_processing)
Definition: dialogs.c:1086
save_clip_values
boolean save_clip_values(int which)
Definition: saveplay.c:103
clip_forensic
lives_clip_t * clip_forensic(int clipno)
Definition: saveplay.c:6029
calc_time_from_frame
double calc_time_from_frame(int clip, int frame)
Definition: utils.c:1756
load_preview_image
void load_preview_image(boolean update_always)
Definition: main.c:6205
lives_decoder_sys_t::rip_audio_cleanup
void(* rip_audio_cleanup)(const lives_clip_data_t *cdata)
Definition: plugins.h:445
lives_clip_t::has_binfmt
boolean has_binfmt
DO NOT remove or alter any fields before this ^^^^^.
Definition: main.h:998
mainwindow::agen_needs_reinit
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
lives_widget_queue_draw
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw(LiVESWidget *widget)
Definition: widget-helper.c:1580
get_clip_value
boolean get_clip_value(int which, lives_clip_details_t, void *retval, size_t maxlen)
Definition: utils.c:5039
CLIP_DETAILS_ASAMPS
@ CLIP_DETAILS_ASAMPS
Definition: main.h:1153
check_if_non_virtual
boolean check_if_non_virtual(int fileno, frames_t start, frames_t end)
Definition: cvirtual.c:644
HAS_RFX
#define HAS_RFX
Definition: plugins.h:257
set_poly_tab
void set_poly_tab(lives_mt *mt, uint32_t tab)
Definition: multitrack.c:3962
LIVES_DEFAULT_TIMEOUT
#define LIVES_DEFAULT_TIMEOUT
Definition: mainwindow.h:43
do_auto_dialog
boolean do_auto_dialog(const char *text, int type)
Definition: dialogs.c:2844
_encoder::audio_codec
uint32_t audio_codec
Definition: plugins.h:235
mainwindow::frame2
LiVESWidget * frame2
Definition: mainwindow.h:1095
lives_clip_data_t::width
int width
Definition: plugins.h:347
lives_image_ext_to_img_type
lives_img_type_t lives_image_ext_to_img_type(const char *img_ext)
Definition: utils.c:3034
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
lives_alarm_t
int lives_alarm_t
Definition: mainwindow.h:696
_prefs::midisynch
boolean midisynch
Definition: preferences.h:181
mainwindow::event_list
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
CLIP_DETAILS_AUTHOR
@ CLIP_DETAILS_AUTHOR
Definition: main.h:1156
lives_open_buffered_rdonly
int lives_open_buffered_rdonly(const char *pathname)
Definition: utils.c:636
mainwindow::playframe
LiVESWidget * playframe
Definition: mainwindow.h:1098
lives_touch
int lives_touch(const char *tfile)
Definition: utils.c:4455
ticks_t
int64_t ticks_t
Definition: main.h:97
UNDO_RESAMPLE
@ UNDO_RESAMPLE
Definition: main.h:664
multitrack_play_sel
void multitrack_play_sel(LiVESMenuItem *menuitem, livespointer user_data)
Definition: multitrack.c:17449
CLIP_DETAILS_FRAMES
@ CLIP_DETAILS_FRAMES
Definition: main.h:1154
CLIP_DETAILS_AENDIAN
@ CLIP_DETAILS_AENDIAN
Definition: main.h:1152
make_version_hash
uint64_t make_version_hash(const char *ver)
Definition: utils.c:3500
mainwindow::rec_aclip
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
mainwindow::oloop
boolean oloop
Definition: mainwindow.h:766
get_first_event
LIVES_GLOBAL_INLINE weed_plant_t * get_first_event(weed_plant_t *event_list)
Definition: events.c:119
mainwindow::preview_spinbutton
LiVESWidget * preview_spinbutton
Definition: mainwindow.h:1306
LIVES_PREVIEW_TYPE_VIDEO_ONLY
#define LIVES_PREVIEW_TYPE_VIDEO_ONLY
Definition: interface.h:171
IMG_TYPE_BEST
#define IMG_TYPE_BEST
Definition: main.h:781
AUDIO_FRAMES_TO_READ
#define AUDIO_FRAMES_TO_READ
Definition: saveplay.c:307
JACK_OPTS_TIMEBASE_CLIENT
#define JACK_OPTS_TIMEBASE_CLIENT
full timebase client
Definition: preferences.h:239
_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
mainwindow::set_name
char set_name[256]
Definition: mainwindow.h:749
MONITOR_QUOTA
#define MONITOR_QUOTA
Definition: mainwindow.h:1805
get_temp_handle
boolean get_temp_handle(int index)
get a temp "handle" from disk.
Definition: saveplay.c:3571
init_pulse_audio_buffers
void init_pulse_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2729
do_header_write_error
boolean do_header_write_error(int clip)
Definition: dialogs.c:4169
URGENCY_MSG_TIMEOUT
#define URGENCY_MSG_TIMEOUT
Definition: mainwindow.h:1637
mainwindow::reverse_pb
boolean reverse_pb
used in osc.c
Definition: mainwindow.h:911
on_ins_silence_activate
boolean on_ins_silence_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12694
end_threaded_dialog
void end_threaded_dialog(void)
Definition: dialogs.c:3883
make_play_window
void make_play_window(void)
actually in gui.c
Definition: gui.c:3932
layout_map
Definition: multitrack.h:745
threaded_dialog_spin
void threaded_dialog_spin(double fraction)
Definition: dialogs.c:3823
lives_clip_data_t::lsd
lives_struct_def_t lsd
Definition: plugins.h:321
TEMPFILE_MARKER
#define TEMPFILE_MARKER
Definition: mainwindow.h:574
_prefs::warning_mask
uint64_t warning_mask
Definition: preferences.h:80
render_details::is_encoding
boolean is_encoding
Definition: events.h:248
CLIP_DETAILS_ASIGNED
@ CLIP_DETAILS_ASIGNED
Definition: main.h:1151
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_clip_t::img_type
lives_img_type_t img_type
Definition: main.h:887
get_md5sum
char * get_md5sum(const char *filename)
Definition: machinestate.c:646
CLIP_DETAILS_FILENAME
@ CLIP_DETAILS_FILENAME
Definition: main.h:1159
UNDO_RENDER
@ UNDO_RENDER
resample/reorder/resize/apply effects
Definition: main.h:680
mainwindow::pheight
int pheight
playback height
Definition: mainwindow.h:927
V_RESIZE_ADJUST
#define V_RESIZE_ADJUST
Definition: mainwindow.h:67
CLIP_TYPE_TEMP
@ CLIP_TYPE_TEMP
temp type, for internal use only
Definition: main.h:768
SCREEN_AREA_BACKGROUND
#define SCREEN_AREA_BACKGROUND
Definition: mainwindow.h:1681
SYNC_HINT_VIDEO_PAD_END
#define SYNC_HINT_VIDEO_PAD_END
Definition: plugins.h:405
CLIP_TYPE_DISK
@ CLIP_TYPE_DISK
imported video, broken into frames
Definition: main.h:764
mainwindow::spin_start_func
ulong spin_start_func
Definition: mainwindow.h:1064
mainwindow::def_height
int def_height
Definition: mainwindow.h:898
capability::umask
mode_t umask
Definition: main.h:597
lives_clip_t::real_pointer_time
double real_pointer_time
pointer time in timeline, can extend beyond video, for audio
Definition: main.h:932
_prefs::volume
float volume
audio volume level (for jack and pulse)
Definition: preferences.h:457
IMG_TYPE_PNG
@ IMG_TYPE_PNG
Definition: main.h:777
create_output_textview
LiVESTextView * create_output_textview(void)
Definition: interface.c:4630
free_pulse_audio_buffers
void free_pulse_audio_buffers(void)
Definition: audio.c:2768
capability::touch_cmd
char touch_cmd[PATH_MAX]
Definition: main.h:553
get_deinterlace_string
const char * get_deinterlace_string(void)
Definition: saveplay.c:230
do_no_loadfile_error
LIVES_GLOBAL_INLINE void do_no_loadfile_error(const char *fname)
Definition: dialogs.c:3526
close_ascrap_file
void close_ascrap_file(boolean remove)
Definition: saveplay.c:5612
_encoder::of_def_ext
char of_def_ext[16]
Definition: plugins.h:267
lives_read_buffered
ssize_t lives_read_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:924
lives_memset
#define lives_memset
Definition: machinestate.h:61
global_recent_manager_add
WIDGET_HELPER_GLOBAL_INLINE boolean global_recent_manager_add(const char *full_file_name)
Definition: widget-helper.c:7394
_prefs::concat_images
boolean concat_images
Definition: preferences.h:296
layout_map::handle
char * handle
Definition: multitrack.h:746
_prefs::default_fps
double default_fps
Definition: preferences.h:173
render_details::dialog
LiVESWidget * dialog
Definition: events.h:220
capability::has_mpv
lives_checkstatus_t has_mpv
Definition: main.h:513
realize_all_frames
frames_t realize_all_frames(int clipno, const char *msg, boolean enough)
Definition: cvirtual.c:849
mainwindow::recovering_files
boolean recovering_files
Definition: mainwindow.h:1485
mainwindow::recovery_list
LiVESList * recovery_list
crash recovery system
Definition: mainwindow.h:1480
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
init_track_decoders
void init_track_decoders(void)
Definition: main.c:7816
CLIP_DETAILS_INTERLACE
@ CLIP_DETAILS_INTERLACE
Definition: main.h:1163
find_when_to_stop
void find_when_to_stop(void)
Definition: utils.c:3722
check_frame_count
boolean check_frame_count(int idx, boolean last_chkd)
check number of frames is correct for files of type CLIP_TYPE_DISK
Definition: utils.c:3074
do_gamma_import_warn
LIVES_GLOBAL_INLINE boolean do_gamma_import_warn(uint64_t fv, int gamma_type)
Definition: dialogs.c:3440
mainwindow::untitled_number
int untitled_number
Definition: mainwindow.h:738
mainwindow::loop_cont
volatile boolean loop_cont
Definition: mainwindow.h:764
UNDO_NONE
@ UNDO_NONE
Definition: main.h:660
lives_clip_t::checked
boolean checked
thumbnail cache, list of lives_tcache_entry_t
Definition: main.h:1101
mainwindow::cancelled
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
_prefs::enc_letterbox
boolean enc_letterbox
encode with letterbox
Definition: preferences.h:364
_prefs::audio_opts
volatile uint32_t audio_opts
Definition: preferences.h:254
is_realtime_aplayer
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
lives_clip_t::fps
double fps
Definition: main.h:893
get_new_handle
boolean get_new_handle(int index, const char *name)
Definition: saveplay.c:3821
get_frame_count
int get_frame_count(int idx, int xsize)
sets mainw->files[idx]->frames with current framecount
Definition: utils.c:3109
capability::has_gconftool_2
lives_checkstatus_t has_gconftool_2
Definition: main.h:527
lives_widget_set_bg_color
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_bg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
Definition: widget-helper.c:2056
lives_echo
int lives_echo(const char *text, const char *to, boolean append)
Definition: utils.c:4500
mainwindow::afilter_map
weed_plant_t * afilter_map
Definition: mainwindow.h:1299
MAX_ACHANS
#define MAX_ACHANS
max number of player channels
Definition: audio.h:30
count_events
int count_events(weed_plant_t *event_list, boolean all_events, weed_timecode_t start_tc, weed_timecode_t end_tc)
Definition: events.c:4542
chill_decoder_plugin
boolean chill_decoder_plugin(int fileno)
Definition: plugins.c:2425
_prefs::hfbwnp
boolean hfbwnp
Definition: preferences.h:436
CANCEL_ERROR
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
CLIP_DETAILS_PB_FRAMENO
@ CLIP_DETAILS_PB_FRAMENO
Definition: main.h:1158
restore_file
ulong restore_file(const char *file_name)
Definition: saveplay.c:4964
_prefs::rr_crash
boolean rr_crash
Definition: preferences.h:488
IMG_TYPE_JPEG
@ IMG_TYPE_JPEG
Definition: main.h:776
_prefs::show_desktop_panel
boolean show_desktop_panel
Definition: preferences.h:483
RESTYPE_ACTION
#define RESTYPE_ACTION
Definition: main.h:462
callbacks.h
play_sel
void play_sel(void)
Definition: callbacks.c:4536
_prefs::def_author
char def_author[1024]
TODO - add to prefs windo.
Definition: preferences.h:497
mainwindow::toy_type
lives_toy_t toy_type
Definition: mainwindow.h:851
LIVES_STATUS_FILE_NAME
#define LIVES_STATUS_FILE_NAME
Definition: mainwindow.h:532
WARN_MASK_CLEAN_INVALID
#define WARN_MASK_CLEAN_INVALID
Definition: preferences.h:127
CLIP_TOTAL_TIME
#define CLIP_TOTAL_TIME(clip)
Definition: main.h:830
_prefs::audio_src
int audio_src
Definition: preferences.h:204
lives_clip_t::frameno
frames_t frameno
Definition: main.h:934
capable
capability * capable
Definition: main.h:627
lives_proc_thread_create
lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t attr, lives_funcptr_t func, int return_type, const char *args_fmt,...)
create the specific plant which defines a background task to be run
Definition: machinestate.c:1730
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
choose_file_bg
char * choose_file_bg(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
Definition: interface.c:4221
mainwindow::eventbox4
LiVESWidget * eventbox4
Definition: mainwindow.h:1334
mainwindow::preview_rendering
boolean preview_rendering
Definition: mainwindow.h:758
mainwindow::recoverable_layout
boolean recoverable_layout
Definition: mainwindow.h:1483
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
lives_clip_t::name
char name[CLIP_NAME_MAXLEN]
the display name
Definition: main.h:922
_prefs::disabled_decoders
LiVESList * disabled_decoders
Definition: preferences.h:408
on_playsel_activate
void on_playsel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4566
weed_reinit_all
void weed_reinit_all(void)
Definition: effects-weed.c:1288
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
unhide_cursor
WIDGET_HELPER_GLOBAL_INLINE boolean unhide_cursor(LiVESXWindow *window)
Definition: widget-helper.c:12056
EXEC_MPLAYER2
#define EXEC_MPLAYER2
Definition: mainwindow.h:387
mainwindow::blend_file
int blend_file
background clip details
Definition: mainwindow.h:976
switch_to_file
void switch_to_file(int old_file, int new_file)
Definition: main.c:9646
SUBTITLE_TYPE_SUB
@ SUBTITLE_TYPE_SUB
Definition: pangotext.h:18
mainwindow::rec_aseek
volatile double rec_aseek
Definition: mainwindow.h:969
deinit_render_effects
void deinit_render_effects(void)
switch off effects after render preview during rendering/render preview, we use the "keys" FX_KEYS_MA...
Definition: effects-weed.c:7358
ALL_USED
#define ALL_USED
Definition: mainwindow.h:192
CLIP_DETAILS_PB_FPS
@ CLIP_DETAILS_PB_FPS
Definition: main.h:1144
on_quit_activate
void on_quit_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:2133
get_handle_from_info_file
boolean get_handle_from_info_file(int index)
Definition: saveplay.c:1163
mainwindow::pre_src_audio_file
int pre_src_audio_file
audio file we were playing before any ext input started
Definition: mainwindow.h:972
_prefs::open_maximised
boolean open_maximised
Definition: preferences.h:28
reget_afilesize_inner
off_t reget_afilesize_inner(int fileno)
Definition: machinestate.c:1001
mainwindow::preview_box
LiVESWidget * preview_box
Definition: mainwindow.h:1304
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
wm_caps_t::pan_annoy
uint64_t pan_annoy
Definition: main.h:471
lives_clip_data_t::arate
int arate
Definition: plugins.h:389
on_details_button_clicked
void on_details_button_clicked(void)
Definition: callbacks.c:7834
lives_clip_data_t::frame_width
int frame_width
frame is the surrounding part, including any black border (>=width)
Definition: plugins.h:357
do_header_missing_detail_error
LiVESResponseType do_header_missing_detail_error(int clip, lives_clip_details_t detail)
Definition: dialogs.c:4186
_future_prefs::audio_opts
uint32_t audio_opts
Definition: preferences.h:830
mainwindow::optextview
LiVESTextView * optextview
Definition: mainwindow.h:1606
get_basename
void get_basename(char *filename)
Definition: utils.c:3194
do_program_not_found_error
LIVES_GLOBAL_INLINE void do_program_not_found_error(const char *progname)
Definition: dialogs.c:3640
SCRATCH_NONE
#define SCRATCH_NONE
Definition: mainwindow.h:1027
mainwindow::double_size
boolean double_size
Definition: mainwindow.h:760
procw_desensitize
void procw_desensitize(void)
Definition: main.c:5445
lives_memcmp
#define lives_memcmp
Definition: machinestate.h:58
JACK_OPTS_TIMEBASE_START
#define JACK_OPTS_TIMEBASE_START
jack sets play start position
Definition: preferences.h:238
choose_file_with_preview
LiVESWidget * choose_file_with_preview(const char *dir, const char *title, char **const filt, int filesel_type)
Definition: interface.c:4228
save_to_scrap_file
int save_to_scrap_file(weed_layer_t *layer)
Definition: saveplay.c:5569
lives_clip_t::signed_endian
uint32_t signed_endian
bitfield
Definition: main.h:909
mainwindow::sep_win
boolean sep_win
Definition: mainwindow.h:761
mainwindow::play_image
LiVESWidget * play_image
Definition: mainwindow.h:946
mainwindow::msg
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
_prefs::video_open_command
char video_open_command[PATH_MAX *2]
Definition: preferences.h:170
lives_clip_data_t::achans
int achans
Definition: plugins.h:390
mainwindow::spinbutton_end
LiVESWidget * spinbutton_end
Definition: mainwindow.h:1288
CLIP_TYPE_FILE
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
mainwindow::pre_src_file
int pre_src_file
video file we were playing before any ext input started
Definition: mainwindow.h:971
lives_mv
int lives_mv(const char *from, const char *to)
Definition: utils.c:4446
SignalHandlerPointer
void(* SignalHandlerPointer)(int)
Definition: main.h:1464
create_cfile
lives_clip_t * create_cfile(int new_file, const char *handle, boolean is_loaded)
set default values for a clip (in memory)
Definition: saveplay.c:3656
mainwindow::origsecs
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
capability::has_xdg_screensaver
lives_checkstatus_t has_xdg_screensaver
Definition: main.h:528
mainwindow::message_box
LiVESWidget * message_box
Definition: mainwindow.h:1323
mainwindow::playing_sel
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
layout_map::name
char * name
Definition: multitrack.h:748
mainwindow::pw_scroll_func
ulong pw_scroll_func
Definition: mainwindow.h:1442
mainwindow::spinbutton_start
LiVESWidget * spinbutton_start
Definition: mainwindow.h:1288
add_to_recent
void add_to_recent(const char *filename, double start, int frames, const char *file_open_params)
Definition: utils.c:4701
LAYOUT_NUMBERING_FILENAME
#define LAYOUT_NUMBERING_FILENAME
Definition: mainwindow.h:572
lives_clip_t::frame_index
frames_t * frame_index
index of frames for CLIP_TYPE_FILE >0 means corresponding frame within original clip -1 means corresp...
Definition: main.h:1004
freeze_callback
boolean freeze_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:11135
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
mainwindow::blend_palette
volatile int blend_palette
here we can store the details of the blend file at the insertion point, if nothing changes we can tar...
Definition: mainwindow.h:980
mainwindow::cs_permitted
boolean cs_permitted
set to TRUE to allow overriding of noswitch in limited circumstances
Definition: mainwindow.h:1020
lives_clip_t::ratio_fps
boolean ratio_fps
framerate of the clip
Definition: main.h:894
layout_map::list
LiVESList * list
Definition: multitrack.h:749
lives_table_set_column_homogeneous
WIDGET_HELPER_GLOBAL_INLINE boolean lives_table_set_column_homogeneous(LiVESTable *table, boolean homogeneous)
Definition: widget-helper.c:6998
mainwindow::scrap_file
int scrap_file
we throw odd sized frames here when recording in real time; used if a source is a generator or stream
Definition: mainwindow.h:874
decoder_plugin_move_to_first
boolean decoder_plugin_move_to_first(const char *name)
Definition: plugins.c:2072
get_file_size
off_t get_file_size(int fd)
Definition: machinestate.c:943
PLUGIN_EXEC_DIR
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
cached_list_free
void cached_list_free(LiVESList **list)
Definition: utils.c:4881
reset_clipmenu
void reset_clipmenu(void)
Definition: utils.c:4290
lives_clip_t::info_file
char info_file[PATH_MAX]
used for asynch communication with externals
Definition: main.h:1009
interface.h
_future_prefs::pb_quality
short pb_quality
Definition: preferences.h:831
_prefs::image_ext
char image_ext[16]
Definition: preferences.h:78
restore_clip_binfmt
boolean restore_clip_binfmt(int clipno)
Definition: saveplay.c:6022
lives_clip_t::afilesize
size_t afilesize
Definition: main.h:912
mainwindow::abufs_to_fill
volatile int abufs_to_fill
Definition: mainwindow.h:1592
mainwindow::foreign_window
LiVESXWindow * foreign_window
Definition: mainwindow.h:843
lives_clip_data_t::frame_height
int frame_height
Definition: plugins.h:358
_encoder::of_name
char of_name[64]
Definition: plugins.h:263
do_memory_error_dialog
LiVESResponseType do_memory_error_dialog(char *op, size_t bytes)
Definition: dialogs.c:904
capability::wm_caps
wm_caps_t wm_caps
Definition: main.h:607
CURRENT_CLIP_HAS_VIDEO
#define CURRENT_CLIP_HAS_VIDEO
Definition: main.h:815
d_print_failed
void d_print_failed(void)
Definition: utils.c:2615
capability::nmonitors
int nmonitors
Definition: main.h:588
lives_fgets
char * lives_fgets(char *s, int size, FILE *stream)
Definition: utils.c:368
capability::has_mplayer
lives_checkstatus_t has_mplayer
Definition: main.h:511
LIVES_OSC_NOTIFY_SUCCESS
#define LIVES_OSC_NOTIFY_SUCCESS
for OSC only (not for C++)
Definition: osc_notify.h:52
mainwindow::playing_file
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
lives_widget_get_parent
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_parent(LiVESWidget *widget)
Definition: widget-helper.c:4739
P_
#define P_(String, StringPlural, n)
Definition: support.h:46
LIVES_INTERLACE_TOP_FIRST
@ LIVES_INTERLACE_TOP_FIRST
Definition: main.h:793
get_location
void get_location(const char *exe, char *val, int maxlen)
Definition: utils.c:3407
fill_abuffer_from
void fill_abuffer_from(lives_audio_buf_t *abuf, weed_plant_t *event_list, weed_plant_t *st_event, boolean exact)
Definition: audio.c:2567
save_frame_index
boolean save_frame_index(int fileno)
Definition: cvirtual.c:56
WARN_MASK_FSIZE
#define WARN_MASK_FSIZE
Definition: preferences.h:88
end_fs_preview
void end_fs_preview(void)
Definition: callbacks.c:7569
load_frame_index
frames_t load_frame_index(int fileno)
Definition: cvirtual.c:114
lives_pgid_t
int lives_pgid_t
Definition: main.h:118
lives_write_le
ssize_t lives_write_le(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
mainwindow::m_loopbutton
LiVESWidget * m_loopbutton
Definition: mainwindow.h:1370
mainwindow::files
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
POLY_CLIPS
@ POLY_CLIPS
Definition: multitrack.h:123
lives_widget_get_allocation_height
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_height(LiVESWidget *widget)
Definition: widget-helper.c:5470
save_clip_value
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
_future_prefs::volume
volatile float volume
audio volume level (for jack and pulse)
Definition: preferences.h:837
widget_opts_t::monitor
int monitor
monitor we are displaying on
Definition: widget-helper.h:1437
mt_show_current_frame
void mt_show_current_frame(lives_mt *mt, boolean return_layer)
preview the current frame
Definition: multitrack.c:3214
mainwindow::audio_seek_ready
volatile boolean audio_seek_ready
Definition: mainwindow.h:940
check_for_lock_file
boolean check_for_lock_file(const char *set_name, int type)
check for set lock file do this via the back-end (smogrify) this allows for the locking scheme to be ...
Definition: utils.c:2894
CANCEL_NONE
@ CANCEL_NONE
no cancel
Definition: main.h:701
mainwindow::fps_measure
frames_t fps_measure
show fps stats after playback
Definition: mainwindow.h:778
RECA_GENERATED
@ RECA_GENERATED
Definition: audio.h:201
init_jack_audio_buffers
void init_jack_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2708
mainwindow::first_free_file
int first_free_file
Definition: mainwindow.h:728
lives_clip_t::has_old_header
boolean has_old_header
Definition: main.h:1091
read_headers
boolean read_headers(int fileno, const char *dir, const char *file_name)
Definition: saveplay.c:4465
add_to_recovery_file
void add_to_recovery_file(const char *handle)
Definition: saveplay.c:6460
PREF_MASTER_VOLUME
#define PREF_MASTER_VOLUME
Definition: preferences.h:1099
mainwindow::signal_caught
uint32_t signal_caught
Definition: mainwindow.h:1673
mainwindow::pulsed
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
_prefs::play_monitor
int play_monitor
Definition: preferences.h:306
SYNC_HINT_VIDEO_PAD_START
#define SYNC_HINT_VIDEO_PAD_START
Definition: plugins.h:404
lives_close_buffered
int lives_close_buffered(int fd)
Definition: utils.c:716
mainwindow::play_start
frames_t play_start
Definition: mainwindow.h:931
wait_for_stop
void wait_for_stop(const char *stop_command)
Definition: saveplay.c:4139
SEPWIN_TYPE_NON_STICKY
#define SEPWIN_TYPE_NON_STICKY
Definition: preferences.h:187
_vid_playback_plugin::capabilities
uint64_t capabilities
Definition: plugins.h:177
_encoder::of_desc
char of_desc[128]
Definition: plugins.h:264
CLIP_DETAILS_CLIPNAME
@ CLIP_DETAILS_CLIPNAME
Definition: main.h:1160
_encoder::name
char name[64]
Definition: plugins.h:234
mainwindow::accel_group
LiVESAccelGroup * accel_group
Definition: mainwindow.h:1228
DEFAULT_AUDIO_RATE
#define DEFAULT_AUDIO_RATE
defaults for when not specifed
Definition: audio.h:23
palette
_palette * palette
interface colour settings
Definition: main.c:101
too_many_files
LIVES_GLOBAL_INLINE void too_many_files(void)
Definition: dialogs.c:2996
PREF_RECENT
#define PREF_RECENT
Definition: preferences.h:956
LIVES_CLIP_HEADER_NEW
#define LIVES_CLIP_HEADER_NEW
Definition: mainwindow.h:557
CLIP_NAME_MAXLEN
#define CLIP_NAME_MAXLEN
Definition: main.h:804
LIVES_CLIP_HEADER
#define LIVES_CLIP_HEADER
Definition: mainwindow.h:555
make_preview_box
void make_preview_box(void)
Definition: gui.c:3515
sget_file_size
off_t sget_file_size(const char *name)
Definition: machinestate.c:962
event_list_free
void event_list_free(weed_plant_t *event_list)
Definition: events.c:2313
lives_clip_t::video_time
double video_time
Definition: main.h:929
mainwindow::recording_recovered
boolean recording_recovered
Definition: mainwindow.h:1486
mt_swap_play_pause
void mt_swap_play_pause(lives_mt *mt, boolean put_pause)
Definition: multitrack.c:17206
mainwindow::pred_clip
int pred_clip
Definition: mainwindow.h:956
do_no_decoder_error
LIVES_GLOBAL_INLINE void do_no_decoder_error(const char *fname)
Definition: dialogs.c:3518
CLIP_DETAILS_HEIGHT
@ CLIP_DETAILS_HEIGHT
Definition: main.h:1146
widget_opts_t::non_modal
boolean non_modal
non-modal for dialogs
Definition: widget-helper.h:1422
weed_generator_end
void weed_generator_end(weed_plant_t *inst)
Definition: effects-weed.c:8176
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
lives_clip_data_t::sync_hint
int sync_hint
Definition: plugins.h:407
mainwindow::stored_event_list
weed_event_t * stored_event_list
stored mt -> clip editor
Definition: mainwindow.h:804
show_desktop_panel
boolean show_desktop_panel(void)
Definition: machinestate.c:3098
check_layer_ready
boolean check_layer_ready(weed_layer_t *layer)
block until layer pixel_data is ready.
Definition: main.c:7528
lives_clip_t::title
char title[1024]
Definition: main.h:919
lives_clip_t::binfmt_version
binval binfmt_version
Definition: main.h:878
mainwindow::m_playbutton
LiVESWidget * m_playbutton
Definition: mainwindow.h:1369
lives_widget_set_app_paintable
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_app_paintable(LiVESWidget *widget, boolean paintable)
Definition: widget-helper.c:1748
do_clip_divergence_error
LIVES_GLOBAL_INLINE void do_clip_divergence_error(int fileno)
Definition: dialogs.c:888
recover_files
boolean recover_files(char *recovery_file, boolean auto_recover)
Definition: saveplay.c:6033
mainwindow::play_sequence
int play_sequence
currticks when last display was shown (used for fixed fps)
Definition: mainwindow.h:1013
_prefs::hide_framebar
boolean hide_framebar
Definition: preferences.h:434
CLIP_DETAILS_ARATE
@ CLIP_DETAILS_ARATE
Definition: main.h:1148
LIVES_CLIP_HEADER_VERSION
#define LIVES_CLIP_HEADER_VERSION
Definition: main.h:941
save_event_frames
int save_event_frames(void)
Definition: saveplay.c:5121
get_filename
void get_filename(char *filename, boolean strip_dir)
Definition: utils.c:3205
CLIP_DETAILS_DECODER_NAME
@ CLIP_DETAILS_DECODER_NAME
Definition: main.h:1164
rewrite_recovery_file
boolean rewrite_recovery_file(void)
Definition: saveplay.c:6473
resize_play_window
void resize_play_window(void)
Definition: gui.c:4349
_RELOAD
#define _RELOAD(field)
Definition: saveplay.c:5945
count_virtual_frames
frames_t count_virtual_frames(frames_t *findex, frames_t start, frames_t end)
count virtual frames between start and end (inclusive)
Definition: cvirtual.c:20
mainwindow::last_blend_file
int last_blend_file
Definition: mainwindow.h:976
mainwindow::clip_header
FILE * clip_header
Definition: mainwindow.h:1521
MIN_MSGBAR_HEIGHT
#define MIN_MSGBAR_HEIGHT
Definition: mainwindow.h:135
_prefs::show_player_stats
boolean show_player_stats
Definition: preferences.h:190
do_threaded_dialog
void do_threaded_dialog(const char *trans_text, boolean has_cancel)
Definition: dialogs.c:3849
lives_clip_t::arps
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
Definition: main.h:905
lives_clip_t::ext_src_type
int ext_src_type
Definition: main.h:1051
mainwindow::jackd_read
void * jackd_read
dummy
Definition: mainwindow.h:1454
get_total_time
void get_total_time(lives_clip_t *file)
calculate laudio, raudio and video time (may be deprecated and replaced with macros)
Definition: utils.c:3690
subst
char * subst(const char *string, const char *from, const char *to)
Definition: utils.c:5484
mainwindow::aud_file_to_kill
int aud_file_to_kill
Definition: mainwindow.h:909
catch_sigint
void catch_sigint(int signum)
Definition: main.c:296
fullscreen_internal
void fullscreen_internal(void)
Definition: gui.c:3440
lives_rmdir
int lives_rmdir(const char *dir, boolean force)
Definition: utils.c:4366
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
lives_clip_t::f_size
size_t f_size
Definition: main.h:913
mainwindow::framebar
LiVESWidget * framebar
Definition: mainwindow.h:1389
GUI_SCREEN_HEIGHT
#define GUI_SCREEN_HEIGHT
Definition: mainwindow.h:100
mainwindow::osc_block
boolean osc_block
TODO - make this a mutex and more finely grained : things we need to block are (clip switches,...
Definition: mainwindow.h:916
lives_calloc
#define lives_calloc
Definition: machinestate.h:67
_RELOAD_STRING
#define _RELOAD_STRING(field, len)
Definition: saveplay.c:5946
set_drawing_area_from_pixbuf
void set_drawing_area_from_pixbuf(LiVESWidget *widget, LiVESPixbuf *pixbuf, lives_painter_surface_t *surface)
Definition: main.c:5525
convert_layer_palette
boolean convert_layer_palette(weed_layer_t *layer, int outpl, int op_clamping)
Definition: colourspace.c:11945
lives_clip_t::changed
boolean changed
Definition: main.h:915
lives_clip_t::deinterlace
boolean deinterlace
auto deinterlace
Definition: main.h:938
LIVES_IMAGE_TYPE_JPEG
#define LIVES_IMAGE_TYPE_JPEG
Definition: mainwindow.h:479
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_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
mainwindow::scratch
volatile short scratch
Definition: mainwindow.h:1026
lives_clip_t::author
char author[1024]
Definition: main.h:919
lives_clip_t::unique_id
uint64_t unique_id
this and the handle can be used to uniquely id a file
Definition: main.h:880
lives_list_free_all
void lives_list_free_all(LiVESList **)
Definition: utils.c:4873
audio_free_fnames
void audio_free_fnames(void)
Definition: audio.c:71
PRIu64
#define PRIu64
Definition: machinestate.h:170
CANCEL_KEEP_LOOPING
@ CANCEL_KEEP_LOOPING
special cancel for TV toy
Definition: main.h:755
mainwindow::image_dir
char image_dir[PATH_MAX]
Definition: mainwindow.h:734
lives_clip_t::hsize
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
Definition: main.h:896
mainwindow::is_rendering
boolean is_rendering
Definition: mainwindow.h:821
get_ds_free
uint64_t get_ds_free(const char *dir)
Definition: machinestate.c:776
popup_lmap_errors
void popup_lmap_errors(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9335
mainwindow::video_draw
LiVESWidget * video_draw
Definition: mainwindow.h:1383
lives_clip_t::needs_silent_update
boolean needs_silent_update
needs internal update, we shouldn't concern the user
Definition: main.h:1089
LIVES_MAIN_WINDOW_WIDGET
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
audio_cache_init
lives_audio_buf_t * audio_cache_init(void)
Definition: audio.c:3238
mainwindow::new_vpp
const char * new_vpp
Definition: mainwindow.h:1573
CLIP_TYPE_NULL_VIDEO
@ CLIP_TYPE_NULL_VIDEO
generates blank video frames
Definition: main.h:767
lives_clip_t::checked_for_old_header
boolean checked_for_old_header
Definition: main.h:1091
lives_clip_t::comment
char comment[1024]
Definition: main.h:919
mainwindow::pf_grid
LiVESWidget * pf_grid
Definition: mainwindow.h:1101
handle_audio_timeout
LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void)
Definition: audio.c:3971
lives_read
ssize_t lives_read(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:460
LIVES_THRDATTR_NONE
#define LIVES_THRDATTR_NONE
Definition: machinestate.h:437
lives_decoder_t::decoder
const lives_decoder_sys_t * decoder
Definition: plugins.h:450
weed_playback_gen_start
boolean weed_playback_gen_start(void)
Definition: effects-weed.c:8332
_start_playback
boolean _start_playback(livespointer data)
Definition: saveplay.c:19
save_frame
void save_frame(LiVESMenuItem *menuitem, livespointer user_data)
Definition: saveplay.c:1186
CLIP_BINFMT_CHECK
#define CLIP_BINFMT_CHECK
Definition: mainwindow.h:536
mainwindow::ascrap_file
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
mainwindow::is_generating
boolean is_generating
Definition: mainwindow.h:1565
LIVES_EXT_SRC_FILE_BUFF
#define LIVES_EXT_SRC_FILE_BUFF
Definition: main.h:1049
mainwindow::clip_list_mutex
pthread_mutex_t clip_list_mutex
prevent adding/removing to cliplist while another thread could be reading it
Definition: mainwindow.h:1500
add_to_ascrap_mb
void add_to_ascrap_mb(uint64_t bytes)
Definition: saveplay.c:5225
unref_struct
LIVES_GLOBAL_INLINE void unref_struct(lives_struct_def_t *lsd)
Definition: lsd-tab.c:89
EXEC_MKTEMP
#define EXEC_MKTEMP
Definition: mainwindow.h:430
_prefs::num_rtaudiobufs
int num_rtaudiobufs
Definition: preferences.h:325
lives_clip_data_t
Definition: plugins.h:319
mainwindow::faded
boolean faded
Definition: mainwindow.h:759
LIVES_WEBSITE
#define LIVES_WEBSITE
Definition: mainwindow.h:520
mainwindow::img_concat_clip
int img_concat_clip
when opening multiple, image files can get concatenated here (prefs->concat_images)
Definition: mainwindow.h:1561
ENCODER_NON_NATIVE
#define ENCODER_NON_NATIVE
Definition: plugins.h:260
weed_layer_copy
weed_layer_t * weed_layer_copy(weed_layer_t *dlayer, weed_layer_t *slayer)
copy source layer slayer to dest layer dlayer
Definition: colourspace.c:13739
event_list_get_start_secs
double event_list_get_start_secs(weed_plant_t *event_list)
Definition: events.c:4618
EXEC_MPLAYER
#define EXEC_MPLAYER
Definition: mainwindow.h:386
hide_cursor
void hide_cursor(LiVESXWindow *window)
Definition: widget-helper.c:12018
SUBTITLE_TYPE_NONE
@ SUBTITLE_TYPE_NONE
Definition: pangotext.h:16
mainwindow::write_abuf
int write_abuf
audio buffer number to write to (for multitrack)
Definition: mainwindow.h:1591
SCREEN_AREA_FOREGROUND
#define SCREEN_AREA_FOREGROUND
Definition: mainwindow.h:1680
save_srt_subtitles
boolean save_srt_subtitles(lives_clip_t *sfile, double start_time, double end_time, double offset_time, const char *filename)
Definition: pangotext.c:1039
lives_memcpy
#define lives_memcpy
Definition: machinestate.h:55
mainwindow::rec_avel
volatile double rec_avel
Definition: mainwindow.h:968
lives_strlen
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
Definition: machinestate.c:1468
lives_accel_group_connect
WIDGET_HELPER_GLOBAL_INLINE boolean lives_accel_group_connect(LiVESAccelGroup *group, uint32_t key, LiVESXModifierType mod, LiVESAccelFlags flags, LiVESWidgetClosure *closure)
Definition: widget-helper.c:2927
future_prefs
_future_prefs * future_prefs
Definition: preferences.h:848
mainwindow::laudio_draw
LiVESWidget * laudio_draw
Definition: mainwindow.h:1383
lives_widget_set_sensitive
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:1477
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
CURRENT_CLIP_IS_NORMAL
#define CURRENT_CLIP_IS_NORMAL
Definition: main.h:838
lives_frame_set_label
WIDGET_HELPER_GLOBAL_INLINE boolean lives_frame_set_label(LiVESFrame *frame, const char *label)
Definition: widget-helper.c:6840
recover_layout_map
void recover_layout_map(int numclips)
Definition: saveplay.c:5632
CANCEL_AUDIO_ERROR
@ CANCEL_AUDIO_ERROR
cancelled because of soundcard error
Definition: main.h:743
wm_caps_t::pan_res
uint64_t pan_res
Definition: main.h:472
mainwindow::hdrs_cache
LiVESList * hdrs_cache
cache of a file header (e.g. header.lives)
Definition: mainwindow.h:1518
mainwindow::def_width
int def_width
default sizes for when no file is loaded
Definition: mainwindow.h:898
load_layout_map
LiVESList * load_layout_map(void)
Definition: multitrack.c:19584
create_render_details
render_details * create_render_details(int type)
Definition: events.c:6252
mainwindow::subt_save_file
char * subt_save_file
name of file to save subtitles to
Definition: mainwindow.h:1618
lives_getuid
LIVES_GLOBAL_INLINE int lives_getuid(void)
Definition: machinestate.c:2416
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
on_del_audio_activate
boolean on_del_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12258
CURRENT_CLIP_IS_VALID
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
lives_alarm_check
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
d_print_cancelled
void d_print_cancelled(void)
Definition: utils.c:2610
mainwindow::was_set
boolean was_set
Definition: mainwindow.h:750
LIVES_IMAGE_TYPE_PNG
#define LIVES_IMAGE_TYPE_PNG
Definition: mainwindow.h:480
CLIP_DETAILS_BPP
@ CLIP_DETAILS_BPP
Definition: main.h:1142
prep_audio_player
char * prep_audio_player(char *com2, char *com3, frames_t audio_end, int arate, int asigned, int aendian)
Definition: saveplay.c:2133
lives_clip_t::ovsize
int ovsize
Definition: main.h:975
mainwindow::suppress_dprint
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
lives_clip_t::laudio_time
double laudio_time
Definition: main.h:929
lives_clip_t::is_untitled
boolean is_untitled
Definition: main.h:926
_prefs::auto_trim_audio
boolean auto_trim_audio
Definition: preferences.h:370
mainwindow::aud_rec_fd
int aud_rec_fd
fd of file we are recording audio to
Definition: mainwindow.h:1525
mainwindow::record_perf_func
ulong record_perf_func
Definition: mainwindow.h:1066
mainwindow::record_paused
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
wait_for_bg_audio_sync
void wait_for_bg_audio_sync(int fileno)
Definition: utils.c:4644
save_sub_subtitles
boolean save_sub_subtitles(lives_clip_t *sfile, double start_time, double end_time, double offset_time, const char *filename)
Definition: pangotext.c:1101
lives_widget_queue_resize
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_resize(LiVESWidget *widget)
Definition: widget-helper.c:1605
open_file_sel
ulong open_file_sel(const char *file_name, double start, int frames)
Definition: saveplay.c:309
EXEC_MIDISTART
#define EXEC_MIDISTART
shipped
Definition: mainwindow.h:415
capability::has_mplayer2
lives_checkstatus_t has_mplayer2
Definition: main.h:512
get_audio_and_effects_state_at
lives_audio_track_state_t * get_audio_and_effects_state_at(weed_plant_t *event_list, weed_plant_t *st_event, weed_timecode_t fill_tc, int what_to_get, boolean exact)
get audio (and optionally video) state at timecode tc OR before event st_event
Definition: audio.c:2419
lives_clip_data_t::comment
char comment[1024]
Definition: plugins.h:341
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
mainwindow::last_dprint_file
int last_dprint_file
message output settings
Definition: mainwindow.h:1535
mt_clip_select
void mt_clip_select(lives_mt *mt, boolean scroll)
Definition: multitrack.c:3024
_prefs::keep_all_audio
boolean keep_all_audio
Definition: preferences.h:371
lives_buffered_orig_size
size_t lives_buffered_orig_size(int fd)
Definition: utils.c:1377
do_header_read_error_with_retry
LiVESResponseType do_header_read_error_with_retry(int clip)
Definition: dialogs.c:4155
SYNC_HINT_AUDIO_TRIM_START
#define SYNC_HINT_AUDIO_TRIM_START
Definition: plugins.h:399
LIVES_INTENTION_PLAY
@ LIVES_INTENTION_PLAY
Definition: plugins.h:45
on_mouse_scroll
boolean on_mouse_scroll(LiVESWidget *widget, LiVESXEventScroll *event, livespointer user_data)
Definition: callbacks.c:10602
main.h
make_image_file_name
char * make_image_file_name(lives_clip_t *clip, frames_t frame, const char *img_ext)
lives_image_type can be a string, lives_img_type_t is an enumeration
Definition: utils.c:3053
lives_window_unfullscreen
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_unfullscreen(LiVESWindow *window)
Definition: widget-helper.c:2880
AFORM_UNKNOWN
#define AFORM_UNKNOWN
Definition: main.h:788
LIVES_CURSOR_BUSY
@ LIVES_CURSOR_BUSY
Definition: widget-helper.h:1293
_prefs::stop_screensaver
boolean stop_screensaver
Definition: preferences.h:27
CLIP_DETAILS_GAMMA_TYPE
@ CLIP_DETAILS_GAMMA_TYPE
Definition: main.h:1165
_prefs::save_directories
boolean save_directories
Definition: preferences.h:195
mainwindow::play_end
frames_t play_end
Definition: mainwindow.h:931
_prefs::mt_load_fuzzy
boolean mt_load_fuzzy
Definition: preferences.h:432
free_track_decoders
LIVES_GLOBAL_INLINE void free_track_decoders(void)
Definition: main.c:7826
CLIP_DETAILS_UNIQUE_ID
@ CLIP_DETAILS_UNIQUE_ID
Definition: main.h:1147
MAX_FILES
#define MAX_FILES
max files is actually 1 more than this, since file 0 is the clipboard
Definition: main.h:184
start_playback
LIVES_GLOBAL_INLINE boolean start_playback(int type)
Definition: saveplay.c:94
lives_container_remove
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_remove(LiVESContainer *container, LiVESWidget *widget)
Definition: widget-helper.c:4938
lives_widget_show_now
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_now(LiVESWidget *widget)
Definition: widget-helper.c:1544
mainwindow::fs
boolean fs
Definition: mainwindow.h:762
LIVES_FILE_EXT_TMP
#define LIVES_FILE_EXT_TMP
Definition: mainwindow.h:486
LIVES_TOY_NONE
@ LIVES_TOY_NONE
Definition: mainwindow.h:234
resample.h
_prefs::sleep_time
int sleep_time
Definition: preferences.h:176
AUDIO_SRC_EXT
#define AUDIO_SRC_EXT
Definition: preferences.h:206
open_scrap_file
boolean open_scrap_file(void)
Definition: saveplay.c:5230
_prefs::vj_mode
boolean vj_mode
Definition: preferences.h:459
kill_play_window
void kill_play_window(void)
Definition: gui.c:4386
lives_notify
void lives_notify(int msgnumber, const char *msgstring)
Definition: callbacks.c:49
play_window_set_title
void play_window_set_title(void)
Definition: gui.c:3722
mainwindow::opwy
int opwy
Definition: mainwindow.h:1375
mainwindow::effort
int effort
Definition: mainwindow.h:1773
set_signal_handlers
void set_signal_handlers(SignalHandlerPointer sigfunc)
Definition: main.c:4077
mainwindow::ext_playback
boolean ext_playback
using external video playback plugin
Definition: mainwindow.h:773
mainwindow::file_open_params
char * file_open_params
extra parameters for opening special files
Definition: mainwindow.h:906
mainw
mainwindow * mainw
Definition: main.c:103
get_image_ext_for_type
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
lives_subtitles_t::type
lives_subtitle_type_t type
Definition: pangotext.h:39
load_decoders
LiVESList * load_decoders(void)
Definition: plugins.c:2092
vid_playback_plugin_exit
void vid_playback_plugin_exit(void)
Definition: plugins.c:1413
mainwindow::pre_play_file
int pre_play_file
the current file before playback started
Definition: mainwindow.h:973
lives_chdir
int lives_chdir(const char *path, boolean no_error_dlg)
Definition: utils.c:1393
d_print_enough
void d_print_enough(int frames)
Definition: utils.c:2630
LIVES_EXT_SRC_NONE
#define LIVES_EXT_SRC_NONE
Definition: main.h:1043
render_details::debug
LiVESWidget * debug
Definition: events.h:235
_encoder::capabilities
uint32_t capabilities
Definition: plugins.h:255
mainwindow::jack_can_stop
boolean jack_can_stop
Definition: mainwindow.h:934
lives_clip_data_t::fps
float fps
Definition: plugins.h:364
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
mainwindow::lockstats
boolean lockstats
Definition: mainwindow.h:1774
mainwindow::play_surface
lives_painter_surface_t * play_surface
Definition: mainwindow.h:950
mainwindow::top_vbox
LiVESWidget * top_vbox
Definition: mainwindow.h:1352
capability::myname
char * myname
Definition: main.h:580
LIVES_OSC_NOTIFY_CLIP_OPENED
#define LIVES_OSC_NOTIFY_CLIP_OPENED
sent after a clip is opened
Definition: osc_notify.h:46
frames_t
int frames_t
Definition: main.h:99
open_ascrap_file
boolean open_ascrap_file(void)
Definition: saveplay.c:5278
lives_utf8_strcmp
int lives_utf8_strcmp(const char *s1, const char *s2)
Definition: utils.c:5469
resize_layer
boolean resize_layer(weed_layer_t *layer, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint)
resize a layer
Definition: colourspace.c:12537
binval::chars
const char chars[8]
Definition: main.h:872
lives_entry_set_text
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_text(LiVESEntry *entry, const char *text)
Definition: widget-helper.c:6211
mainwindow::loop_continue
LiVESWidget * loop_continue
Definition: mainwindow.h:1174
lives_clip_t::pb_fps
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
Definition: main.h:1007
get_extension
char * get_extension(const char *filename)
Definition: utils.c:3217
_prefs::warn_file_size
int warn_file_size
Definition: preferences.h:180
lives_kill_subprocesses
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
mainwindow::frame_layer_preload
weed_plant_t * frame_layer_preload
predictive caching apparatus
Definition: mainwindow.h:954
PREF_IMAGE_DIR
#define PREF_IMAGE_DIR
Definition: preferences.h:948
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
CLIP_DETAILS_PB_ARATE
@ CLIP_DETAILS_PB_ARATE
Definition: main.h:1149
LIVES_FILE_EXT_LAYOUT
#define LIVES_FILE_EXT_LAYOUT
Definition: mainwindow.h:513
lives_widget_set_opacity
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_opacity(LiVESWidget *widget, double opacity)
Definition: widget-helper.c:1757
CLIPS_DIRNAME
#define CLIPS_DIRNAME
Definition: mainwindow.h:620
unlock_loop_lock
void unlock_loop_lock(void)
Definition: callbacks.c:4966
CANCEL_KEEP
@ CANCEL_KEEP
user pressed 'Keep'
Definition: main.h:734
CLIPDIR
#define CLIPDIR(handle)
Definition: mainwindow.h:630
SYNC_HINT_AUDIO_PAD_END
#define SYNC_HINT_AUDIO_PAD_END
Definition: plugins.h:402
add_file_info
boolean add_file_info(const char *check_handle, boolean aud_only)
Definition: saveplay.c:3870
insert_blank_frames
void insert_blank_frames(int sfileno, frames_t nframes, frames_t after, int palette)
Definition: cvirtual.c:1080
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
CLIP_DETAILS_FPS
@ CLIP_DETAILS_FPS
Definition: main.h:1143
lives_widget_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
Definition: widget-helper.c:1523
_prefs::allow_easing
boolean allow_easing
Definition: preferences.h:461
weed_layer_free
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
Definition: colourspace.c:13883
reget_afilesize
void reget_afilesize(int fileno)
Definition: machinestate.c:972
CANCEL_EVENT_LIST_END
@ CANCEL_EVENT_LIST_END
event_list completed
Definition: main.h:722
lives_chomp
LIVES_GLOBAL_INLINE char * lives_chomp(char *buff)
Definition: machinestate.c:1641
get_utf8_pref
LiVESResponseType get_utf8_pref(const char *key, char *val, int maxlen)
Definition: preferences.c:112
LMAP_ERROR_DELETE_FRAMES
@ LMAP_ERROR_DELETE_FRAMES
Definition: multitrack.h:1019
ONE_BILLION
#define ONE_BILLION
Definition: mainwindow.h:25
gen_unique_id
uint64_t gen_unique_id(void)
Definition: machinestate.c:68
rdet
render_details * rdet
Definition: events.h:256
check_for_recovery_files
boolean check_for_recovery_files(boolean auto_recover)
Definition: saveplay.c:6550
weed_bg_generator_end
void weed_bg_generator_end(weed_plant_t *inst)
Definition: effects-weed.c:8318
lives_funcptr_t
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
_prefs::pb_quality
short pb_quality
Definition: preferences.h:31
do_yesno_dialog
boolean do_yesno_dialog(const char *text)
Definition: dialogs.c:655
mainwindow::audio_stretch
double audio_stretch
for fixed fps modes, the value is used to speed up / slow down audio
Definition: mainwindow.h:1015
widget_opts
widget_opts_t widget_opts
Definition: widget-helper.h:1442
lives_clip_data_t::video_start_time
float video_start_time
Definition: plugins.h:362
lives_clip_t::vsize
int vsize
frame height (vertical) in pixels
Definition: main.h:897
LIVES_FILE_EXT_SRT
#define LIVES_FILE_EXT_SRT
Definition: mainwindow.h:507
resize
void resize(double scale)
Definition: main.c:10230
PATH_MAX
#define PATH_MAX
Definition: main.h:255
LIVES_INTERLACE_NONE
@ LIVES_INTERLACE_NONE
Definition: main.h:791
mainwindow::sep_image
LiVESWidget * sep_image
Definition: mainwindow.h:1229
mainwindow::spinbutton_pb_fps
LiVESWidget * spinbutton_pb_fps
Definition: mainwindow.h:1391
LIVES_DIR_SEP
#define LIVES_DIR_SEP
Definition: main.h:197
AUD_PLAYER_PULSE
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
redraw_timeline
void redraw_timeline(int clipno)
Definition: interface.c:3412
_prefs::cmd_log
char cmd_log[PATH_MAX]
Definition: preferences.h:168
IMG_TYPE_UNKNOWN
@ IMG_TYPE_UNKNOWN
Definition: main.h:775
_prefs::rec_stop_gb
double rec_stop_gb
Definition: preferences.h:348
mt_sensitise
void mt_sensitise(lives_mt *mt)
Definition: multitrack.c:17052
init_conversions
LIVES_GLOBAL_INLINE void init_conversions(int intent)
Definition: colourspace.c:1804
on_record_perf_activate
void on_record_perf_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4605
AUD_PLAYER_JACK
#define AUD_PLAYER_JACK
Definition: preferences.h:43
lives_clip_t::orig_file_name
boolean orig_file_name
Definition: main.h:926
get_menu_name
char * get_menu_name(lives_clip_t *sfile, boolean add_setname)
Definition: gui.c:4487
lives_clip_t::subt
lives_subtitles_t * subt
Definition: main.h:1076
lives_idle_add
WIDGET_HELPER_GLOBAL_INLINE uint32_t lives_idle_add(LiVESWidgetSourceFunc function, livespointer data)
Definition: widget-helper.c:7350
do_read_failed_error_s
void do_read_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:4034
RECA_EXTERNAL
@ RECA_EXTERNAL
Definition: audio.h:200
open_file
ulong open_file(const char *file_name)
Definition: saveplay.c:261
mainwindow::opwx
int opwx
Definition: mainwindow.h:1375
lives_create_buffered_nosync
int lives_create_buffered_nosync(const char *pathname, int mode)
Definition: utils.c:702
check_encoder_restrictions
boolean check_encoder_restrictions(boolean get_extension, boolean user_audio, boolean save_all)
Definition: plugins.c:1557
lives_signal_handler_unblock
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_unblock(livespointer instance, unsigned long handler_id)
Definition: widget-helper.c:947
mainwindow::vid_save_dir
char vid_save_dir[PATH_MAX]
Definition: mainwindow.h:731
get_play_times
void get_play_times(void)
recalculate video / audio lengths and draw the timer bars
Definition: utils.c:3672
CANCEL_SOFT
@ CANCEL_SOFT
just cancel in GUI (for keep, etc)
Definition: main.h:760
lives_clip_t
corresponds to one clip in the GUI
Definition: main.h:877
CURRENT_CLIP_IS_TEMP
#define CURRENT_CLIP_IS_TEMP
Definition: main.h:812
LIVES_FILE_EXT_BACKUP
#define LIVES_FILE_EXT_BACKUP
Definition: mainwindow.h:500
disk_monitor_check_result
int64_t disk_monitor_check_result(const char *dir)
Definition: machinestate.c:726
mainwindow::is_processing
boolean is_processing
states
Definition: mainwindow.h:820
defer_sigint
void defer_sigint(int signum)
Definition: main.c:282
lives_widget_set_frozen
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_frozen(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:7964
render_choice_idle
boolean render_choice_idle(livespointer data)
Definition: main.c:3454
load_from_scrap_file
boolean load_from_scrap_file(weed_layer_t *layer, int frame)
Definition: saveplay.c:5360
mainwindow::open_deint
boolean open_deint
Definition: mainwindow.h:907
lives_clip_data_t::asigned
boolean asigned
Definition: plugins.h:392
lives_clip_t::gamma_type
int gamma_type
Definition: main.h:903
layout_audio_is_affected
LiVESList * layout_audio_is_affected(int clipno, double stime, double etime, LiVESList *xlays)
Definition: multitrack.c:22281
mainwindow::no_switch_dprint
boolean no_switch_dprint
Definition: mainwindow.h:1536
lives_write
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
reset_message_area
void reset_message_area(void)
Definition: gui.c:4734
mainwindow::pulsed_read
void * pulsed_read
Definition: mainwindow.h:1464
mainwindow::mute
boolean mute
Definition: mainwindow.h:770
GUI_SCREEN_WIDTH
#define GUI_SCREEN_WIDTH
Definition: mainwindow.h:99
on_trim_audio_activate
boolean on_trim_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12053
lives_widget_queue_draw_if_visible
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw_if_visible(LiVESWidget *widget)
Definition: widget-helper.c:11009
lives_widget_process_updates
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_process_updates(LiVESWidget *widget)
Definition: widget-helper.c:1658
LIVES_ENC_DEBUG_FILE_NAME
#define LIVES_ENC_DEBUG_FILE_NAME
Definition: mainwindow.h:533
do_abort_cancel_retry_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
handle_backend_errors
LiVESResponseType handle_backend_errors(boolean can_retry)
Definition: dialogs.c:922
lives_window_present
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_present(LiVESWindow *window)
Definition: widget-helper.c:2858
ONE_MILLION
#define ONE_MILLION
Definition: mainwindow.h:27
audio.h
read_file_details
boolean read_file_details(const char *file_name, boolean is_audio, boolean is_img)
Definition: saveplay.c:207
event_list_get_end_secs
double event_list_get_end_secs(weed_plant_t *event_list)
Definition: events.c:4607
mainwindow::disk_mon
uint32_t disk_mon
Definition: mainwindow.h:1807
close_temp_handle
int close_temp_handle(int new_clip)
close cfile and switch to new clip (may be -1)
Definition: saveplay.c:3498
FPS_MAX
#define FPS_MAX
maximum fps we will allow (double)
Definition: main.h:218
save_frame_inner
boolean save_frame_inner(int clip, int frame, const char *file_name, int width, int height, boolean from_osc)
Definition: saveplay.c:4170
d_print_done
void d_print_done(void)
Definition: utils.c:2620
mainwindow::currticks
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
mainwindow::filter_map
weed_plant_t * filter_map
Definition: mainwindow.h:1298
mainwindow::urgency_msg
char * urgency_msg
OSD.
Definition: mainwindow.h:1643
resize_message_area
boolean resize_message_area(livespointer data)
Definition: main.c:3588
CANCEL_NO_PROPOGATE
@ CANCEL_NO_PROPOGATE
cancel but keep opening
Definition: main.h:707
mainwindow::cancel_type
lives_cancel_type_t cancel_type
Definition: mainwindow.h:799
LIVES_DEVNULL
#define LIVES_DEVNULL
Definition: mainwindow.h:592
disable_record
void disable_record(void)
Definition: gui.c:3717
_prefs::show_rdet
boolean show_rdet
show render details (frame size, encoder type) before saving to file
Definition: preferences.h:261
LIVES_FILE_SELECTION_VIDEO_AUDIO
#define LIVES_FILE_SELECTION_VIDEO_AUDIO
Definition: interface.h:177
lives_clip_t::asampsize
int asampsize
audio sample size in bits (8 or 16)
Definition: main.h:908
_prefs::configfile
char configfile[PATH_MAX]
kept in locale encoding (config settings) [default ~/.local/config/lives)
Definition: preferences.h:63
mainwindow::opening_loc
boolean opening_loc
opening location (streaming)
Definition: mainwindow.h:790
write_headers
boolean write_headers(lives_clip_t *file)
Definition: saveplay.c:4394
mainwindow::record_perf
LiVESWidget * record_perf
Definition: mainwindow.h:1165
lives_widget_set_fg_color
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_fg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
Definition: widget-helper.c:2079
lives_widget_object_unref
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_unref(livespointer object)
decrease refcount by one: if refcount==0, object is destroyed
Definition: widget-helper.c:815
subtitles_init
boolean subtitles_init(lives_clip_t *sfile, char *fname, lives_subtitle_type_t subtype)
Definition: pangotext.c:996
mainwindow::pwidth
int pwidth
PLAYBACK.
Definition: mainwindow.h:926
lives_clip_data_t::author
char author[1024]
Definition: plugins.h:340
mainwindow::undo
LiVESWidget * undo
Definition: mainwindow.h:1146
mainwindow::agen_key
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
ulong
#define ulong
Definition: main.h:178
WARN_MASK_CLEAN_AFTER_CRASH
#define WARN_MASK_CLEAN_AFTER_CRASH
Definition: preferences.h:122
get_mime_type
void get_mime_type(char *text, int maxlen, const lives_clip_data_t *cdata)
Definition: plugins.c:2513
lives_getgid
LIVES_GLOBAL_INLINE int lives_getgid(void)
Definition: machinestate.c:2420
mainwindow::quit
LiVESWidget * quit
Definition: mainwindow.h:1145
lives_clip_t::ohsize
int ohsize
Definition: main.h:975
lives_proc_thread_join
LIVES_GLOBAL_INLINE void lives_proc_thread_join(lives_proc_thread_t tinfo)
Definition: machinestate.c:1979
SYNC_HINT_AUDIO_PAD_START
#define SYNC_HINT_AUDIO_PAD_START
Definition: plugins.h:400
lives_signal_handler_block
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_block(livespointer instance, unsigned long handler_id)
Definition: widget-helper.c:933
layer_to_pixbuf
LiVESPixbuf * layer_to_pixbuf(weed_layer_t *layer, boolean realpalette, boolean fordisplay)
Definition: colourspace.c:12210
DEF_FILE_PERMS
#define DEF_FILE_PERMS
non-executable, is modified by the umask
Definition: main.h:209
lives_clip_t::arate
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
lazy_startup_checks
boolean lazy_startup_checks(void *data)
Definition: main.c:3480
cache_file_contents
LiVESList * cache_file_contents(const char *filename)
Definition: utils.c:4909
play_all
void play_all(boolean from_menu)
Definition: callbacks.c:4482
reload_subs
void reload_subs(int fileno)
Definition: saveplay.c:4942
LAYOUT_FILENAME
#define LAYOUT_FILENAME
Definition: mainwindow.h:570
_prefs::perm_audio_reader
boolean perm_audio_reader
Definition: preferences.h:426
lives_clip_t::menuentry
LiVESWidget * menuentry
Definition: main.h:1011
FALSE
#define FALSE
Definition: videoplugin.h:60
mainwindow::preview_frame
int preview_frame
Definition: mainwindow.h:1309
lives_widget_get_allocation_width
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_width(LiVESWidget *widget)
Definition: widget-helper.c:5455
lives_widget_set_size_request
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_size_request(LiVESWidget *widget, int width, int height)
Definition: widget-helper.c:1614
DEFAULT_AUDIO_CHANS
#define DEFAULT_AUDIO_CHANS
Definition: audio.h:24
mainwindow::audio_end
int audio_end
Definition: mainwindow.h:771
htmsocket.h
calc_maxspect
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
Definition: utils.c:2174
check_file
boolean check_file(const char *file_name, boolean check_exists)
check if file exists
Definition: utils.c:4312
LMAP_ERROR_DELETE_AUDIO
@ LMAP_ERROR_DELETE_AUDIO
Definition: multitrack.h:1020
lives_clip_t::adirection
lives_direction_t adirection
audio play direction during playback, FORWARD or REVERSE.
Definition: main.h:1016
audio_cache_end
void audio_cache_end(void)
Definition: audio.c:3276
mainwindow::stop
LiVESWidget * stop
Definition: mainwindow.h:1170
open_set_file
void open_set_file(int clipnum)
Definition: saveplay.c:4864
mainwindow::eventbox2
LiVESWidget * eventbox2
Definition: mainwindow.h:1332
mt_idle_add
uint32_t mt_idle_add(lives_mt *mt)
Definition: multitrack.c:901
get_audio_file_name
LIVES_GLOBAL_INLINE char * get_audio_file_name(int fnum, boolean opening)
Definition: audio.c:38
LIVES_CLIP_HEADER_OLD2
#define LIVES_CLIP_HEADER_OLD2
Definition: mainwindow.h:560
_prefs::autoload_subs
boolean autoload_subs
Definition: preferences.h:345
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
_prefs::sepwin_type
short sepwin_type
Definition: preferences.h:186
lives_clip_t::handle
char handle[256]
Definition: main.h:881
_
#define _(String)
Definition: support.h:44
layout_map::unique_id
int64_t unique_id
Definition: multitrack.h:747
IS_NORMAL_CLIP
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
lives_accel_path_disconnect
WIDGET_HELPER_GLOBAL_INLINE boolean lives_accel_path_disconnect(LiVESAccelGroup *group, const char *path)
Definition: widget-helper.c:12563
STYLE_1
#define STYLE_1
turn on theming if set
Definition: mainwindow.h:299
mainwindow::error
boolean error
Definition: mainwindow.h:801
POLY_NONE
@ POLY_NONE
Definition: multitrack.h:122
capability::byte_order
int byte_order
Definition: main.h:577
SUBS_FILENAME
#define SUBS_FILENAME
Definition: mainwindow.h:562
PREF_VID_SAVE_DIR
#define PREF_VID_SAVE_DIR
Definition: preferences.h:953
SYNC_HINT_AUDIO_TRIM_END
#define SYNC_HINT_AUDIO_TRIM_END
Definition: plugins.h:401
lives_rm
int lives_rm(const char *file)
Definition: utils.c:4395
_prefs::show_playwin
boolean show_playwin
Definition: preferences.h:292
mainwindow::ptrtime
double ptrtime
Definition: mainwindow.h:899
mainwindow::lazy
uint32_t lazy
Definition: mainwindow.h:1801
on_toy_activate
void on_toy_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9550
event_list_to_block
boolean event_list_to_block(weed_plant_t *event_list, int num_events)
Definition: events.c:2329
lives_clip_t::binfmt_end
uint64_t binfmt_end
marks the end of anything "interesring" we may want to save via binfmt extension
Definition: main.h:992
mainwindow::orignsecs
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
reload_clip
boolean reload_clip(int fileno, int maxframe)
Definition: saveplay.c:5735
lives_concat
LIVES_GLOBAL_INLINE char * lives_concat(char *st, char *x)
Definition: machinestate.c:1426
unfade_background
void unfade_background(void)
Definition: gui.c:3324
lives_clip_t::achans
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
lives_clip_t::binfmt_bytes
binval binfmt_bytes
Definition: main.h:878
mainwindow::audio_start
int audio_start
Definition: mainwindow.h:771
AFORM_BIG_ENDIAN
#define AFORM_BIG_ENDIAN
Definition: main.h:787
lives_widget_show
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
Definition: widget-helper.c:1505
lives_widget_context_update
boolean lives_widget_context_update(void)
Definition: widget-helper.c:11878
mainwindow::autolives
LiVESWidget * autolives
Definition: mainwindow.h:1220
LIVES_ACLIP_HEADER
#define LIVES_ACLIP_HEADER
Definition: mainwindow.h:556
lives_get_relative_ticks
LIVES_GLOBAL_INLINE ticks_t lives_get_relative_ticks(ticks_t origsecs, ticks_t orignsecs)
Definition: machinestate.c:813
lives_pixbuf_save
boolean lives_pixbuf_save(LiVESPixbuf *pixbuf, char *fname, lives_img_type_t imgtype, int quality, int width, int height, LiVESError **gerrorptr)
Save a pixbuf to a file using the specified imgtype and the specified quality/compression value.
Definition: main.c:9304
pref_factory_float
boolean pref_factory_float(const char *prefidx, float newval, boolean permanent)
Definition: preferences.c:1192
get_signed_endian
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
Definition: utils.c:5408
add_to_playframe
void add_to_playframe(void)
Definition: gui.c:4451
LIVES_TOY_MAD_FRAMES
@ LIVES_TOY_MAD_FRAMES
Definition: mainwindow.h:235
MAINW_MSG_SIZE
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
mainwindow::foreign
boolean foreign
for external window capture
Definition: mainwindow.h:824
load_end_image
void load_end_image(int frame)
Definition: main.c:5922
lives_clip_data_t::nframes
int64_t nframes
Definition: plugins.h:349
lives_menu_item_set_text
WIDGET_HELPER_GLOBAL_INLINE void lives_menu_item_set_text(LiVESWidget *menuitem, const char *text, boolean use_mnemonic)
Definition: widget-helper.c:11920
SUBTITLE_TYPE_SRT
@ SUBTITLE_TYPE_SRT
Definition: pangotext.h:17
lives_clip_data_t::asamps
int asamps
Definition: plugins.h:391
is_legal_set_name
boolean is_legal_set_name(const char *set_name, boolean allow_dupes, boolean leeway)
Definition: utils.c:2975
lives_clip_t::end
frames_t end
Definition: main.h:891
STOP_GIVE_UP_TIME
#define STOP_GIVE_UP_TIME
AV_TRACK_MIN_DIFF
#define AV_TRACK_MIN_DIFF
ignore track time differences < this (seconds)
Definition: main.h:806
lives_clip_t::layout_map
LiVESList * layout_map
Definition: main.h:1037
set_utf8_pref
int set_utf8_pref(const char *key, const char *value)
Definition: preferences.c:306
lives_clip_t::was_in_set
boolean was_in_set
Definition: main.h:916
mainwindow::m_playselbutton
LiVESWidget * m_playselbutton
Definition: mainwindow.h:1369
deinit_easing_effects
void deinit_easing_effects(void)
switch off effects in easing out state after playback ends during playback, some effects don't deinit...
Definition: effects-weed.c:7381