1 // events.h 2 // LiVES 3 // (c) G. Finch 2005 - 2016 <salsaman@gmail.com> 4 // released under the GNU GPL 3 or later 5 // see file ../COPYING or www.gnu.org for licensing details 6 7 // functions/structs for event_lists and events 8 9 #ifndef HAS_LIVES_EVENTS_H 10 #define HAS_LIVES_EVENTS_H 11 12 /// for backwards compat. 13 #define WEED_LEAF_HINT "hint" 14 15 /// parts of this may eventually become libweed-events 16 17 // event_list 18 #define WEED_LEAF_WEED_EVENT_API_VERSION "weed_event_api_version" 19 #define WEED_LEAF_AUDIO_SIGNED "audio_signed" 20 #define WEED_LEAF_AUDIO_ENDIAN "audio_endian" 21 #define WEED_LEAF_AUDIO_SAMPLE_SIZE "audio_sample_size" 22 #define WEED_LEAF_AUDIO_VOLUME_TRACKS "audio_volume_tracks" 23 #define WEED_LEAF_AUDIO_VOLUME_VALUES "audio_volume_values" 24 #define WEED_LEAF_TRACK_LABEL_TRACKS "track_label_tracks" 25 #define WEED_LEAF_TRACK_LABEL_VALUES "track_label_values" 26 27 #define WEED_LEAF_AUTHOR "author" 28 #define WEED_LEAF_TITLE "title" 29 #define WEED_LEAF_COMMENTS "comments" 30 31 #define WEED_LEAF_LIVES_CREATED_VERSION "created_version" 32 #define WEED_LEAF_LIVES_EDITED_VERSION "edited_version" 33 34 #define WEED_LEAF_CREATED_DATE "host_created_date" 35 #define WEED_LEAF_EDITED_DATE "host_edited_date" 36 37 // frame event 38 #define WEED_LEAF_FRAMES "frames" 39 #define WEED_LEAF_CLIPS "clips" 40 #define WEED_LEAF_AUDIO_CLIPS "audio_clips" 41 #define WEED_LEAF_AUDIO_SEEKS "audio_seeks" 42 43 // init_event 44 #define WEED_LEAF_FILTER "filter" 45 #define WEED_LEAF_IN_COUNT "in_count" 46 #define WEED_LEAF_OUT_COUNT "out_count" 47 #define WEED_LEAF_IN_TRACKS "in_tracks" 48 #define WEED_LEAF_OUT_TRACKS "out_tracks" 49 #define WEED_LEAF_EVENT_ID "event_id" 50 51 // deinit 52 #define WEED_LEAF_INIT_EVENT "init_event" 53 54 // filter map 55 #define WEED_LEAF_INIT_EVENTS "init_events" 56 57 // param change 58 #define WEED_LEAF_INDEX "index" 59 60 // internal 61 // event_list 62 #define WEED_LEAF_NEXT "next" 63 #define WEED_LEAF_PREVIOUS "previous" 64 #define WEED_LEAF_FIRST "first" 65 #define WEED_LEAF_LAST "last" 66 #define WEED_LEAF_NEEDS_SET "needs_set" // oops, should have been host_needs_set 67 #define WEED_LEAF_GAMMA_ENABLED "host_gamma_enabled" 68 #define WEED_LEAF_TC_ADJUSTMENT "tc_adj_val" 69 70 // param change 71 #define WEED_LEAF_NEXT_CHANGE "next_change" 72 #define WEED_LEAF_PREV_CHANGE "prev_change" 73 #define WEED_LEAF_IS_DEF_VALUE "host_is_def_value" 74 75 // init_event 76 #define WEED_LEAF_DEINIT_EVENT "deinit_event" 77 78 // marker 79 #define WEED_LEAF_LIVES_TYPE "lives_type" 80 #define WEED_LEAF_TRACKS "tracks" 81 #define WEED_LEAF_TCDELTA "tc_delta" 82 83 // misc 84 #define WEED_LEAF_PTRSIZE "ptrsize" ///< deprecated 85 86 #define WEED_LEAF_HOST_AUDIO_TRANSITION "host_audio_transition" 87 88 #define WEED_LEAF_HOST_TAG_COPY "host_tag_copy" 89 90 #define WEED_LEAF_OVERLAY_TEXT "overlay_text" 91 92 #define LIVES_TRACK_ANY -1000000 93 94 #define AUD_DIFF_MIN 0.05 ///< ignore audio seek differences < than this (seconds) 95 #define AUD_DIFF_REVADJ 8. ///< allow longer seek differences when audio plauback direction reverses (multiplying factor) 96 97 typedef weed_plant_t weed_event_t; 98 99 /// various return conditions from rendering (multitrack or after recording) 100 typedef enum { 101 LIVES_RENDER_ERROR_NONE = 0, 102 LIVES_RENDER_READY, 103 LIVES_RENDER_PROCESSING, 104 LIVES_RENDER_EFFECTS_PAUSED, 105 LIVES_RENDER_COMPLETE, 106 LIVES_RENDER_WARNING, 107 LIVES_RENDER_WARNING_READ_FRAME, 108 LIVES_RENDER_ERROR, 109 LIVES_RENDER_ERROR_READ_AUDIO, 110 LIVES_RENDER_ERROR_WRITE_AUDIO, 111 LIVES_RENDER_ERROR_WRITE_FRAME, 112 } lives_render_error_t; 113 114 weed_event_t *append_frame_event(weed_event_t *event_list, ticks_t tc, int numframes, 115 int *clips, int64_t *frames) WARN_UNUSED; 116 weed_event_t *append_filter_init_event(weed_event_t *event_list, ticks_t tc, 117 int filter_idx, int num_in_tracks, int key, weed_plant_t *inst) WARN_UNUSED; 118 weed_event_t *append_filter_deinit_event(weed_event_t *event_list, ticks_t tc, 119 void *init_event, void **pchain) WARN_UNUSED; 120 weed_event_t *append_filter_map_event(weed_event_t *event_list, ticks_t tc, void **init_events) WARN_UNUSED; 121 weed_event_t *append_param_change_event(weed_event_t *event_list, ticks_t tc, int pnum, 122 weed_plant_t *param, void *init_event, void **pchain) WARN_UNUSED; 123 weed_event_t *append_marker_event(weed_event_t *event_list, ticks_t tc, int marker_type) WARN_UNUSED; 124 125 /** will either insert or replace */ 126 weed_event_t *insert_frame_event_at(weed_event_t *event_list, ticks_t tc, int numframes, 127 int *clips, int64_t *frames, weed_event_t **shortcut) WARN_UNUSED; 128 void insert_audio_event_at(weed_event_t *event, int track, int clipnum, double time, double vel); 129 void remove_audio_for_track(weed_event_t *event, int track); 130 weed_event_t *insert_blank_frame_event_at(weed_event_t *event_list, ticks_t tc, 131 weed_event_t **shortcut) WARN_UNUSED; 132 133 void remove_frame_from_event(weed_event_t *event_list, weed_event_t *event, int track); 134 void remove_end_blank_frames(weed_event_t *event_list, boolean remove_filter_inits); 135 void remove_filter_from_event_list(weed_event_t *event_list, weed_event_t *init_event); 136 137 weed_event_t *process_events(weed_event_t *next_event, boolean process_audio, ticks_t curr_tc); ///< RT playback 138 void event_list_close_start_gap(weed_event_t *event_list); 139 void event_list_add_track(weed_event_t *event_list, int layer); 140 void add_track_to_avol_init(weed_plant_t *filter, weed_event_t *event, int nbtracks, boolean behind); 141 void event_list_free(weed_event_t *event_list); 142 143 void event_list_add_end_events(weed_event_t *event_list, boolean is_final); 144 145 146 /// lib-ish stuff 147 weed_event_t *lives_event_list_new(weed_event_t *elist, const char *cdate); 148 int weed_event_get_type(weed_event_t *event); 149 weed_timecode_t weed_event_set_timecode(weed_event_t *, weed_timecode_t tc); 150 weed_timecode_t weed_event_get_timecode(weed_event_t *); 151 152 int weed_frame_event_get_tracks(weed_event_t *event, int **clips, int64_t **frames); // returns ntracks 153 int weed_frame_event_get_audio_tracks(weed_event_t *event, int **aclips, double **aseeks); // returns natracks 154 155 /// replace events in event_list with events in new_event_list 156 void event_list_replace_events(weed_event_t *event_list, weed_event_t *new_event_list); 157 158 /// called during quantisation 159 weed_event_t *event_copy_and_insert(weed_event_t *in_event, weed_timecode_t tc, weed_event_t *event_list, 160 weed_event_t **ret_event); 161 void reset_ttable(void); 162 163 /// if all_events is FALSE we only count FRAME events 164 int count_events(weed_event_t *event_list, boolean all_events, ticks_t start_tc, ticks_t end_tc); 165 166 frames_t count_resampled_events(weed_event_t *event_list, double fps); 167 168 boolean backup_recording(char **esave_file, char **asave_file); 169 170 boolean event_list_to_block(weed_event_t *event_list, int num_events); 171 double event_list_get_end_secs(weed_event_t *event_list); 172 double event_list_get_start_secs(weed_event_t *event_list); 173 ticks_t event_list_get_end_tc(weed_event_t *event_list); 174 ticks_t event_list_get_start_tc(weed_event_t *event_list); 175 176 weed_event_t *get_last_frame_event(weed_event_t *event_list); 177 weed_event_t *get_first_frame_event(weed_event_t *event_list); 178 179 weed_event_t *get_next_frame_event(weed_event_t *event); 180 weed_event_t *get_prev_frame_event(weed_event_t *event); 181 182 weed_event_t *get_next_audio_frame_event(weed_event_t *event); 183 weed_event_t *get_prev_audio_frame_event(weed_event_t *event); 184 185 weed_event_t *get_frame_event_at(weed_event_t *event_list, ticks_t tc, weed_event_t *shortcut, boolean exact); 186 weed_event_t *get_frame_event_at_or_before(weed_event_t *event_list, ticks_t tc, weed_event_t *shortcut); 187 188 weed_event_t *get_audio_block_start(weed_event_t *event_list, int track, ticks_t tc, boolean seek_back); 189 190 boolean filter_map_after_frame(weed_event_t *fmap); 191 boolean init_event_is_relevant(weed_event_t *init_event, int ctrack); 192 193 // definitions in events.c 194 weed_event_t *get_first_event(weed_event_t *event_list); 195 weed_event_t *get_last_event(weed_event_t *event_list); 196 weed_event_t *get_prev_event(weed_event_t *event); 197 weed_event_t *get_next_event(weed_event_t *event); 198 199 ////////////////////////////////////////////////////////// 200 201 ticks_t get_event_timecode(weed_event_t *); 202 int get_event_type(weed_event_t *); 203 boolean is_blank_frame(weed_event_t *, boolean count_audio); 204 boolean has_audio_frame(weed_event_t *event_list); 205 int get_frame_event_clip(weed_event_t *, int layer); 206 frames_t get_frame_event_frame(weed_event_t *, int layer); 207 boolean frame_event_has_frame_for_track(weed_event_t *event, int track); 208 double *get_track_visibility_at_tc(weed_event_t *event_list, int ntracks, int n_back_tracks, 209 ticks_t tc, weed_event_t **shortcut, boolean bleedthru); 210 void get_active_track_list(int *clip_index, int num_tracks, weed_plant_t *filter_map); 211 212 ////////////////////////////////////////////////////////// 213 ///// render details ////////// 214 215 typedef struct { 216 int width; 217 int height; 218 double fps; 219 boolean ratio_fps; 220 LiVESWidget *dialog; 221 LiVESWidget *okbutton; 222 LiVESWidget *usecur_button; 223 LiVESWidget *clipname_entry; 224 LiVESWidget *encoder_combo; 225 LiVESWidget *ofmt_combo; 226 LiVESWidget *acodec_combo; 227 LiVESWidget *acodec_entry; 228 LiVESWidget *spinbutton_width; 229 LiVESWidget *spinbutton_height; 230 LiVESWidget *spinbutton_fps; 231 LiVESWidget *pertrack_checkbutton; 232 LiVESWidget *backaudio_checkbutton; 233 LiVESWidget *always_checkbutton; 234 LiVESWidget *always_hbox; 235 LiVESWidget *debug; 236 LiVESWidget *norm_after; 237 LiVESWidget *afade_in; 238 LiVESWidget *afade_out; 239 LiVESWidget *vfade_in; 240 LiVESWidget *vfade_out; 241 LiVESWidget *vfade_col; 242 ulong encoder_name_fn; 243 ulong encoder_ofmt_fn; 244 boolean enc_changed; 245 char *encoder_name; 246 boolean suggestion_followed; 247 248 boolean is_encoding; 249 250 int arate; 251 int achans; 252 int asamps; 253 int aendian; 254 } render_details; 255 256 render_details *rdet; 257 258 //////////////////////////////////////////////////////// 259 //// UI stuff /////// 260 261 LiVESWidget *events_rec_dialog(void); 262 boolean deal_with_render_choice(boolean add_deinit); 263 264 #define RENDER_CHOICE_NONE 0 265 #define RENDER_CHOICE_DISCARD 1 266 #define RENDER_CHOICE_PREVIEW 2 267 #define RENDER_CHOICE_SAME_CLIP 3 268 #define RENDER_CHOICE_NEW_CLIP 4 269 #define RENDER_CHOICE_MULTITRACK 5 270 #define RENDER_CHOICE_EVENT_LIST 6 271 #define RENDER_CHOICE_TRANSCODE 7 272 273 LiVESWidget *create_event_list_dialog(weed_plant_t *event_list, ticks_t start_tc, ticks_t end_tc); 274 render_details *create_render_details(int type); 275 276 LiVESWidget *add_video_options(LiVESWidget **spwidth, int defwidth, LiVESWidget **spheight, int defheight, 277 LiVESWidget **spfps, double deffps, LiVESWidget **spframes, int defframes, 278 boolean add_aspect, LiVESWidget *extra); 279 280 LiVESWidget *add_audio_options(LiVESWidget **cbbackaudio, LiVESWidget **cbpertrack); 281 282 //////////////////////////////////////////////////////////////// 283 /// rendering 284 285 boolean render_to_clip(boolean new_clip, boolean transcode); 286 boolean start_render_effect_events(weed_plant_t *event_list, boolean render_vid, boolean render_aud); 287 288 lives_render_error_t render_events(boolean reset, boolean rend_video, boolean rend_audio); 289 lives_render_error_t render_events_cb(boolean dummy); 290 291 // effect insertion/updating 292 void insert_filter_init_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event); 293 void **filter_init_add_pchanges(weed_plant_t *event_list, weed_plant_t *filter, weed_plant_t *init_event, int ntracks, 294 int leave); 295 void insert_filter_deinit_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event); 296 boolean insert_filter_map_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event, 297 boolean before_frames); 298 weed_plant_t *get_filter_map_before(weed_plant_t *event, int ctrack, weed_plant_t *stop_event); 299 weed_plant_t *get_filter_map_after(weed_plant_t *event, int ctrack); 300 void **get_init_events_before(weed_plant_t *event, weed_plant_t *init_event, boolean add); 301 void update_filter_maps(weed_plant_t *event, weed_plant_t *end_event, weed_plant_t *init_event); 302 void insert_param_change_event_at(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event); 303 weed_plant_t *insert_marker_event_at(weed_plant_t *event_list, weed_plant_t *at_event, int marker_type, livespointer data); 304 305 void add_init_event_to_filter_map(weed_plant_t *fmap, weed_plant_t *event, void **hints); 306 boolean init_event_in_list(void **init_events, int num_inits, weed_plant_t *event); 307 boolean filter_init_has_owner(weed_plant_t *init_event, int track); 308 boolean init_event_is_process_last(weed_plant_t *event); 309 310 // effect deletion/moving 311 boolean move_event_right(weed_plant_t *event_list, weed_plant_t *event, boolean can_stay, double fps); 312 boolean move_event_left(weed_plant_t *event_list, weed_plant_t *event, boolean can_stay, double fps); 313 314 void move_filter_init_event(weed_plant_t *event_list, ticks_t new_tc, weed_plant_t *init_event, double fps); 315 void move_filter_deinit_event(weed_plant_t *event_list, ticks_t new_tc, weed_plant_t *deinit_event, 316 double fps, boolean rescale_pchanges); 317 318 // event deletion 319 void unlink_event(weed_plant_t *event_list, weed_plant_t *event); 320 void delete_event(weed_plant_t *event_list, weed_plant_t *event); 321 322 // event replacement 323 void replace_event(weed_plant_t *event_list, weed_plant_t *at_event, weed_plant_t *event); 324 325 // event insertion 326 boolean insert_event_before(weed_plant_t *at_event, weed_plant_t *event); 327 boolean insert_event_after(weed_plant_t *at_event, weed_plant_t *event); 328 329 // param changes 330 void ** *get_event_pchains(void); 331 ticks_t get_next_paramchange(void **pchange_next, ticks_t end_tc); 332 ticks_t get_prev_paramchange(void **pchange_next, ticks_t start_tc); 333 boolean is_init_pchange(weed_plant_t *init_event, weed_plant_t *pchange_event); 334 void free_pchains(int key); 335 336 // audio 337 /// returns clip number for track (track==-1 is backing audio) 338 int get_audio_frame_clip(weed_plant_t *event, int track); 339 340 /// returns velocity for track (track==-1 is backing audio) 341 double get_audio_frame_vel(weed_plant_t *event, int track); 342 343 /// returns velocity for track (track==-1 is backing audio) 344 double get_audio_frame_seek(weed_plant_t *event, int track); 345 346 // playback 347 348 void backup_host_tags(weed_plant_t *event_list, ticks_t curr_tc); 349 void restore_host_tags(weed_plant_t *event_list, ticks_t curr_tc); 350 351 boolean has_frame_event_at(weed_plant_t *event_list, ticks_t tc, weed_plant_t **shortcut); 352 353 #define EVENT_MARKER_BLOCK_START 1 354 #define EVENT_MARKER_BLOCK_UNORDERED 512 355 #define EVENT_MARKER_RECORD_START 1024 356 #define EVENT_MARKER_RECORD_END 1025 357 358 #define WEED_PLANT_IS_EVENT(plant) ((plant != NULL && weed_get_plant_type(plant) == WEED_PLANT_EVENT) ? 1 : 0) 359 #define WEED_PLANT_IS_EVENT_LIST(plant) ((plant != NULL && weed_get_plant_type(plant) == WEED_PLANT_EVENT_LIST) ? 1 : 0) 360 361 #define WEED_EVENT_IS_FRAME(event) (get_event_type(event) == WEED_EVENT_TYPE_FRAME ? 1 : 0) 362 #define WEED_EVENT_IS_AUDIO_FRAME(event) ((get_event_type(event) == WEED_EVENT_TYPE_FRAME \ 363 && weed_plant_has_leaf(event, WEED_LEAF_AUDIO_CLIPS)) ? 1 : 0) 364 #define WEED_EVENT_IS_FILTER_INIT(event) (get_event_type(event) == WEED_EVENT_TYPE_FILTER_INIT ? 1 : 0) 365 #define WEED_EVENT_IS_FILTER_DEINIT(event) (get_event_type(event) == WEED_EVENT_TYPE_FILTER_DEINIT ? 1 : 0) 366 #define WEED_EVENT_IS_FILTER_MAP(event) (get_event_type(event) == WEED_EVENT_TYPE_FILTER_MAP ? 1 : 0) 367 #define WEED_EVENT_IS_PARAM_CHANGE(event) (get_event_type(event) == WEED_EVENT_TYPE_PARAM_CHANGE ? 1 : 0) 368 #define WEED_EVENT_IS_MARKER(event) (get_event_type(event) == WEED_EVENT_TYPE_MARKER ? 1 : 0) 369 370 #endif // HAS_LIVES_EVENTS_H 371