1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 *
19 * - Blender Foundation, 2003-2009
20 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
21 */
22
23 /** \file
24 * \ingroup bke
25 */
26
27 #include <math.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_anim_types.h"
36 #include "DNA_mask_types.h"
37 #include "DNA_movieclip_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_sequence_types.h"
41 #include "DNA_sound_types.h"
42 #include "DNA_space_types.h"
43 #include "DNA_windowmanager_types.h"
44
45 #include "BLI_fileops.h"
46 #include "BLI_linklist.h"
47 #include "BLI_listbase.h"
48 #include "BLI_math.h"
49 #include "BLI_path_util.h"
50 #include "BLI_session_uuid.h"
51 #include "BLI_string.h"
52 #include "BLI_string_utf8.h"
53 #include "BLI_threads.h"
54 #include "BLI_utildefines.h"
55
56 #ifdef WIN32
57 # include "BLI_winstuff.h"
58 #else
59 # include <unistd.h>
60 #endif
61
62 #include "BLT_translation.h"
63
64 #include "BKE_anim_data.h"
65 #include "BKE_animsys.h"
66 #include "BKE_fcurve.h"
67 #include "BKE_global.h"
68 #include "BKE_idprop.h"
69 #include "BKE_image.h"
70 #include "BKE_layer.h"
71 #include "BKE_lib_id.h"
72 #include "BKE_main.h"
73 #include "BKE_mask.h"
74 #include "BKE_movieclip.h"
75 #include "BKE_report.h"
76 #include "BKE_scene.h"
77 #include "BKE_sequencer.h"
78 #include "BKE_sequencer_offscreen.h"
79
80 #include "DEG_depsgraph.h"
81 #include "DEG_depsgraph_query.h"
82
83 #include "RNA_access.h"
84
85 #include "RE_pipeline.h"
86
87 #include <pthread.h>
88
89 #include "IMB_colormanagement.h"
90 #include "IMB_imbuf.h"
91 #include "IMB_imbuf_types.h"
92 #include "IMB_metadata.h"
93
94 #include "BKE_context.h"
95 #include "BKE_sound.h"
96
97 #include "RE_engine.h"
98
99 #ifdef WITH_AUDASPACE
100 # include <AUD_Special.h>
101 #endif
102
103 /* mutable state for sequencer */
104 typedef struct SeqRenderState {
105 LinkNode *scene_parents;
106 } SeqRenderState;
107
108 static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
109 SeqRenderState *state,
110 ListBase *seqbasep,
111 float cfra,
112 int chanshown);
113 static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
114 Sequence *seq,
115 ImBuf *ibuf,
116 float cfra,
117 clock_t begin,
118 bool use_preprocess,
119 const bool is_proxy_image);
120 static ImBuf *seq_render_strip(const SeqRenderData *context,
121 SeqRenderState *state,
122 Sequence *seq,
123 float cfra);
124 static void seq_free_animdata(Scene *scene, Sequence *seq);
125 static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float);
126 static int seq_num_files(Scene *scene, char views_format, const bool is_multiview);
127 static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_id);
128
129 static ThreadMutex seq_render_mutex = BLI_MUTEX_INITIALIZER;
130
131 /* **** XXX ******** */
132 #define SELECT 1
133 ListBase seqbase_clipboard;
134 int seqbase_clipboard_frame;
135
136 SequencerDrawView sequencer_view3d_fn = NULL; /* NULL in background mode */
137
138 #if 0 /* unused function */
139 static void printf_strip(Sequence *seq)
140 {
141 fprintf(stderr,
142 "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), "
143 "(startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
144 seq->name,
145 seq->len,
146 seq->start,
147 seq->startofs,
148 seq->endofs,
149 seq->startstill,
150 seq->endstill,
151 seq->machine,
152 seq->startdisp,
153 seq->enddisp);
154
155 fprintf(stderr,
156 "\tseq_tx_set_final_left: %d %d\n\n",
157 seq_tx_get_final_left(seq, 0),
158 seq_tx_get_final_right(seq, 0));
159 }
160 #endif
161
sequencer_state_init(SeqRenderState * state)162 static void sequencer_state_init(SeqRenderState *state)
163 {
164 state->scene_parents = NULL;
165 }
166
BKE_sequencer_base_recursive_apply(ListBase * seqbase,int (* apply_fn)(Sequence * seq,void *),void * arg)167 int BKE_sequencer_base_recursive_apply(ListBase *seqbase,
168 int (*apply_fn)(Sequence *seq, void *),
169 void *arg)
170 {
171 Sequence *iseq;
172 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
173 if (BKE_sequencer_recursive_apply(iseq, apply_fn, arg) == -1) {
174 return -1; /* bail out */
175 }
176 }
177 return 1;
178 }
179
BKE_sequencer_recursive_apply(Sequence * seq,int (* apply_fn)(Sequence *,void *),void * arg)180 int BKE_sequencer_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void *arg)
181 {
182 int ret = apply_fn(seq, arg);
183
184 if (ret == -1) {
185 return -1; /* bail out */
186 }
187
188 if (ret && seq->seqbase.first) {
189 ret = BKE_sequencer_base_recursive_apply(&seq->seqbase, apply_fn, arg);
190 }
191
192 return ret;
193 }
194
195 /*********************** alloc / free functions *************************/
196
197 /* free */
198
free_proxy_seq(Sequence * seq)199 static void free_proxy_seq(Sequence *seq)
200 {
201 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
202 IMB_free_anim(seq->strip->proxy->anim);
203 seq->strip->proxy->anim = NULL;
204 }
205 }
206
seq_free_strip(Strip * strip)207 static void seq_free_strip(Strip *strip)
208 {
209 strip->us--;
210 if (strip->us > 0) {
211 return;
212 }
213 if (strip->us < 0) {
214 printf("error: negative users in strip\n");
215 return;
216 }
217
218 if (strip->stripdata) {
219 MEM_freeN(strip->stripdata);
220 }
221
222 if (strip->proxy) {
223 if (strip->proxy->anim) {
224 IMB_free_anim(strip->proxy->anim);
225 }
226
227 MEM_freeN(strip->proxy);
228 }
229 if (strip->crop) {
230 MEM_freeN(strip->crop);
231 }
232 if (strip->transform) {
233 MEM_freeN(strip->transform);
234 }
235
236 MEM_freeN(strip);
237 }
238
239 /* only give option to skip cache locally (static func) */
BKE_sequence_free_ex(Scene * scene,Sequence * seq,const bool do_cache,const bool do_id_user,const bool do_clean_animdata)240 static void BKE_sequence_free_ex(Scene *scene,
241 Sequence *seq,
242 const bool do_cache,
243 const bool do_id_user,
244 const bool do_clean_animdata)
245 {
246 if (seq->strip) {
247 seq_free_strip(seq->strip);
248 }
249
250 BKE_sequence_free_anim(seq);
251
252 if (seq->type & SEQ_TYPE_EFFECT) {
253 struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
254 sh.free(seq, do_id_user);
255 }
256
257 if (seq->sound && do_id_user) {
258 id_us_min(((ID *)seq->sound));
259 }
260
261 if (seq->stereo3d_format) {
262 MEM_freeN(seq->stereo3d_format);
263 }
264
265 /* clipboard has no scene and will never have a sound handle or be active
266 * same goes to sequences copy for proxy rebuild job
267 */
268 if (scene) {
269 Editing *ed = scene->ed;
270
271 if (ed->act_seq == seq) {
272 ed->act_seq = NULL;
273 }
274
275 if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
276 BKE_sound_remove_scene_sound(scene, seq->scene_sound);
277 }
278
279 /* XXX This must not be done in BKE code. */
280 if (do_clean_animdata) {
281 seq_free_animdata(scene, seq);
282 }
283 }
284
285 if (seq->prop) {
286 IDP_FreePropertyContent_ex(seq->prop, do_id_user);
287 MEM_freeN(seq->prop);
288 }
289
290 /* free modifiers */
291 BKE_sequence_modifier_clear(seq);
292
293 /* free cached data used by this strip,
294 * also invalidate cache for all dependent sequences
295 *
296 * be _very_ careful here, invalidating cache loops over the scene sequences and
297 * assumes the listbase is valid for all strips,
298 * this may not be the case if lists are being freed.
299 * this is optional BKE_sequence_invalidate_cache
300 */
301 if (do_cache) {
302 if (scene) {
303 BKE_sequence_invalidate_cache_raw(scene, seq);
304 }
305 }
306
307 MEM_freeN(seq);
308 }
309
BKE_sequence_free(Scene * scene,Sequence * seq,const bool do_clean_animdata)310 void BKE_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata)
311 {
312 BKE_sequence_free_ex(scene, seq, true, true, do_clean_animdata);
313 }
314
315 /* Function to free imbuf and anim data on changes */
BKE_sequence_free_anim(Sequence * seq)316 void BKE_sequence_free_anim(Sequence *seq)
317 {
318 while (seq->anims.last) {
319 StripAnim *sanim = seq->anims.last;
320
321 if (sanim->anim) {
322 IMB_free_anim(sanim->anim);
323 sanim->anim = NULL;
324 }
325
326 BLI_freelinkN(&seq->anims, sanim);
327 }
328 BLI_listbase_clear(&seq->anims);
329 }
330
331 /* cache must be freed before calling this function
332 * since it leaves the seqbase in an invalid state */
seq_free_sequence_recurse(Scene * scene,Sequence * seq,const bool do_id_user)333 static void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user)
334 {
335 Sequence *iseq, *iseq_next;
336
337 for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
338 iseq_next = iseq->next;
339 seq_free_sequence_recurse(scene, iseq, do_id_user);
340 }
341
342 BKE_sequence_free_ex(scene, seq, false, do_id_user, true);
343 }
344
BKE_sequencer_editing_get(Scene * scene,bool alloc)345 Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
346 {
347 if (alloc) {
348 BKE_sequencer_editing_ensure(scene);
349 }
350 return scene->ed;
351 }
352
BKE_sequencer_free_clipboard(void)353 void BKE_sequencer_free_clipboard(void)
354 {
355 Sequence *seq, *nseq;
356
357 BKE_sequencer_base_clipboard_pointers_free(&seqbase_clipboard);
358
359 for (seq = seqbase_clipboard.first; seq; seq = nseq) {
360 nseq = seq->next;
361 seq_free_sequence_recurse(NULL, seq, false);
362 }
363 BLI_listbase_clear(&seqbase_clipboard);
364 }
365
366 /* -------------------------------------------------------------------- */
367 /* Manage pointers in the clipboard.
368 * note that these pointers should _never_ be access in the sequencer,
369 * they are only for storage while in the clipboard
370 * notice 'newid' is used for temp pointer storage here, validate on access (this is safe usage,
371 * since those data-blocks are fully out of Main lists).
372 */
373 #define ID_PT (*id_pt)
seqclipboard_ptr_free(Main * UNUSED (bmain),ID ** id_pt)374 static void seqclipboard_ptr_free(Main *UNUSED(bmain), ID **id_pt)
375 {
376 if (ID_PT) {
377 BLI_assert(ID_PT->newid != NULL);
378 MEM_freeN(ID_PT);
379 ID_PT = NULL;
380 }
381 }
seqclipboard_ptr_store(Main * UNUSED (bmain),ID ** id_pt)382 static void seqclipboard_ptr_store(Main *UNUSED(bmain), ID **id_pt)
383 {
384 if (ID_PT) {
385 ID *id_prev = ID_PT;
386 ID_PT = MEM_dupallocN(ID_PT);
387 ID_PT->newid = id_prev;
388 }
389 }
seqclipboard_ptr_restore(Main * bmain,ID ** id_pt)390 static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
391 {
392 if (ID_PT) {
393 const ListBase *lb = which_libbase(bmain, GS(ID_PT->name));
394 void *id_restore;
395
396 BLI_assert(ID_PT->newid != NULL);
397 if (BLI_findindex(lb, (ID_PT)->newid) != -1) {
398 /* the pointer is still valid */
399 id_restore = (ID_PT)->newid;
400 }
401 else {
402 /* the pointer of the same name still exists */
403 id_restore = BLI_findstring(lb, (ID_PT)->name + 2, offsetof(ID, name) + 2);
404 }
405
406 if (id_restore == NULL) {
407 /* check for a data with the same filename */
408 switch (GS(ID_PT->name)) {
409 case ID_SO: {
410 id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->filepath, offsetof(bSound, filepath));
411 if (id_restore == NULL) {
412 id_restore = BKE_sound_new_file(bmain, ((bSound *)ID_PT)->filepath);
413 (ID_PT)->newid = id_restore; /* reuse next time */
414 }
415 break;
416 }
417 case ID_MC: {
418 id_restore = BLI_findstring(
419 lb, ((MovieClip *)ID_PT)->filepath, offsetof(MovieClip, filepath));
420 if (id_restore == NULL) {
421 id_restore = BKE_movieclip_file_add(bmain, ((MovieClip *)ID_PT)->filepath);
422 (ID_PT)->newid = id_restore; /* reuse next time */
423 }
424 break;
425 }
426 default:
427 break;
428 }
429 }
430
431 /* Replace with pointer to actual data-block. */
432 seqclipboard_ptr_free(bmain, id_pt);
433 ID_PT = id_restore;
434 }
435 }
436 #undef ID_PT
437
sequence_clipboard_pointers(Main * bmain,Sequence * seq,void (* callback)(Main *,ID **))438 static void sequence_clipboard_pointers(Main *bmain,
439 Sequence *seq,
440 void (*callback)(Main *, ID **))
441 {
442 callback(bmain, (ID **)&seq->scene);
443 callback(bmain, (ID **)&seq->scene_camera);
444 callback(bmain, (ID **)&seq->clip);
445 callback(bmain, (ID **)&seq->mask);
446 callback(bmain, (ID **)&seq->sound);
447
448 if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
449 TextVars *text_data = seq->effectdata;
450 callback(bmain, (ID **)&text_data->text_font);
451 }
452 }
453
454 /* recursive versions of functions above */
BKE_sequencer_base_clipboard_pointers_free(ListBase * seqbase)455 void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase)
456 {
457 Sequence *seq;
458 for (seq = seqbase->first; seq; seq = seq->next) {
459 sequence_clipboard_pointers(NULL, seq, seqclipboard_ptr_free);
460 BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase);
461 }
462 }
BKE_sequencer_base_clipboard_pointers_store(Main * bmain,ListBase * seqbase)463 void BKE_sequencer_base_clipboard_pointers_store(Main *bmain, ListBase *seqbase)
464 {
465 Sequence *seq;
466 for (seq = seqbase->first; seq; seq = seq->next) {
467 sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_store);
468 BKE_sequencer_base_clipboard_pointers_store(bmain, &seq->seqbase);
469 }
470 }
BKE_sequencer_base_clipboard_pointers_restore(ListBase * seqbase,Main * bmain)471 void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
472 {
473 Sequence *seq;
474 for (seq = seqbase->first; seq; seq = seq->next) {
475 sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_restore);
476 BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain);
477 }
478 }
479
480 /* end clipboard pointer mess */
481
BKE_sequencer_editing_ensure(Scene * scene)482 Editing *BKE_sequencer_editing_ensure(Scene *scene)
483 {
484 if (scene->ed == NULL) {
485 Editing *ed;
486
487 ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
488 ed->seqbasep = &ed->seqbase;
489 ed->cache = NULL;
490 ed->cache_flag = SEQ_CACHE_STORE_FINAL_OUT;
491 ed->cache_flag |= SEQ_CACHE_VIEW_FINAL_OUT;
492 ed->cache_flag |= SEQ_CACHE_VIEW_ENABLE;
493 ed->recycle_max_cost = 10.0f;
494 }
495
496 return scene->ed;
497 }
498
BKE_sequencer_editing_free(Scene * scene,const bool do_id_user)499 void BKE_sequencer_editing_free(Scene *scene, const bool do_id_user)
500 {
501 Editing *ed = scene->ed;
502 Sequence *seq;
503
504 if (ed == NULL) {
505 return;
506 }
507
508 BKE_sequencer_prefetch_free(scene);
509 BKE_sequencer_cache_destruct(scene);
510
511 SEQ_ALL_BEGIN (ed, seq) {
512 /* handle cache freeing above */
513 BKE_sequence_free_ex(scene, seq, false, do_id_user, false);
514 }
515 SEQ_ALL_END;
516
517 BLI_freelistN(&ed->metastack);
518 MEM_freeN(ed);
519
520 scene->ed = NULL;
521 }
522
523 /*********************** Sequencer color space functions *************************/
524
sequencer_imbuf_assign_spaces(Scene * scene,ImBuf * ibuf)525 static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf)
526 {
527 #if 0
528 /* Bute buffer is supposed to be in sequencer working space already. */
529 if (ibuf->rect != NULL) {
530 IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
531 }
532 #endif
533 if (ibuf->rect_float != NULL) {
534 IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
535 }
536 }
537
BKE_sequencer_imbuf_to_sequencer_space(Scene * scene,ImBuf * ibuf,bool make_float)538 void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float)
539 {
540 /* Early output check: if both buffers are NULL we have nothing to convert. */
541 if (ibuf->rect_float == NULL && ibuf->rect == NULL) {
542 return;
543 }
544 /* Get common conversion settings. */
545 const char *to_colorspace = scene->sequencer_colorspace_settings.name;
546 /* Perform actual conversion logic. */
547 if (ibuf->rect_float == NULL) {
548 /* We are not requested to give float buffer and byte buffer is already
549 * in thee required colorspace. Can skip doing anything here.
550 */
551 const char *from_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
552 if (!make_float && STREQ(from_colorspace, to_colorspace)) {
553 return;
554 }
555 if (false) {
556 /* The idea here is to provide as fast playback as possible and
557 * enforcing float buffer here (a) uses more cache memory (b) might
558 * make some other effects slower to apply.
559 *
560 * However, this might also have negative effect by adding weird
561 * artifacts which will then not happen in final render.
562 */
563 IMB_colormanagement_transform_byte_threaded((unsigned char *)ibuf->rect,
564 ibuf->x,
565 ibuf->y,
566 ibuf->channels,
567 from_colorspace,
568 to_colorspace);
569 }
570 else {
571 /* We perform conversion to a float buffer so we don't worry about
572 * precision loss.
573 */
574 imb_addrectfloatImBuf(ibuf);
575 IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float,
576 (unsigned char *)ibuf->rect,
577 ibuf->x,
578 ibuf->y,
579 ibuf->channels,
580 from_colorspace,
581 to_colorspace);
582 /* We don't need byte buffer anymore. */
583 imb_freerectImBuf(ibuf);
584 }
585 }
586 else {
587 const char *from_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
588 /* Unknown input color space, can't perform conversion. */
589 if (from_colorspace == NULL || from_colorspace[0] == '\0') {
590 return;
591 }
592 /* We don't want both byte and float buffers around: they'll either run
593 * out of sync or conversion of byte buffer will lose precision in there.
594 */
595 if (ibuf->rect != NULL) {
596 imb_freerectImBuf(ibuf);
597 }
598 IMB_colormanagement_transform_threaded(
599 ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true);
600 }
601 sequencer_imbuf_assign_spaces(scene, ibuf);
602 }
603
BKE_sequencer_imbuf_from_sequencer_space(Scene * scene,ImBuf * ibuf)604 void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
605 {
606 const char *from_colorspace = scene->sequencer_colorspace_settings.name;
607 const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(
608 COLOR_ROLE_SCENE_LINEAR);
609
610 if (!ibuf->rect_float) {
611 return;
612 }
613
614 if (to_colorspace && to_colorspace[0] != '\0') {
615 IMB_colormanagement_transform_threaded(
616 ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true);
617 IMB_colormanagement_assign_float_colorspace(ibuf, to_colorspace);
618 }
619 }
620
BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene * scene,float pixel[4])621 void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4])
622 {
623 const char *from_colorspace = scene->sequencer_colorspace_settings.name;
624 const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(
625 COLOR_ROLE_SCENE_LINEAR);
626
627 if (to_colorspace && to_colorspace[0] != '\0') {
628 IMB_colormanagement_transform_v4(pixel, from_colorspace, to_colorspace);
629 }
630 else {
631 /* if no color management enables fallback to legacy conversion */
632 srgb_to_linearrgb_v4(pixel, pixel);
633 }
634 }
635
636 /*********************** sequencer pipeline functions *************************/
637
BKE_sequencer_new_render_data(Main * bmain,struct Depsgraph * depsgraph,Scene * scene,int rectx,int recty,int preview_render_size,int for_render,SeqRenderData * r_context)638 void BKE_sequencer_new_render_data(Main *bmain,
639 struct Depsgraph *depsgraph,
640 Scene *scene,
641 int rectx,
642 int recty,
643 int preview_render_size,
644 int for_render,
645 SeqRenderData *r_context)
646 {
647 r_context->bmain = bmain;
648 r_context->depsgraph = depsgraph;
649 r_context->scene = scene;
650 r_context->rectx = rectx;
651 r_context->recty = recty;
652 r_context->preview_render_size = preview_render_size;
653 r_context->for_render = for_render;
654 r_context->motion_blur_samples = 0;
655 r_context->motion_blur_shutter = 0;
656 r_context->skip_cache = false;
657 r_context->is_proxy_render = false;
658 r_context->view_id = 0;
659 r_context->gpu_offscreen = NULL;
660 r_context->task_id = SEQ_TASK_MAIN_RENDER;
661 r_context->is_prefetch_render = false;
662 }
663
664 /* ************************* iterator ************************** */
665 /* *************** (replaces old WHILE_SEQ) ********************* */
666 /* **************** use now SEQ_ALL_BEGIN () SEQ_ALL_END ***************** */
667
668 /* sequence strip iterator:
669 * - builds a full array, recursively into meta strips
670 */
671
seq_count(ListBase * seqbase,int * tot)672 static void seq_count(ListBase *seqbase, int *tot)
673 {
674 Sequence *seq;
675
676 for (seq = seqbase->first; seq; seq = seq->next) {
677 (*tot)++;
678
679 if (seq->seqbase.first) {
680 seq_count(&seq->seqbase, tot);
681 }
682 }
683 }
684
seq_build_array(ListBase * seqbase,Sequence *** array,int depth)685 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
686 {
687 Sequence *seq;
688
689 for (seq = seqbase->first; seq; seq = seq->next) {
690 seq->depth = depth;
691
692 if (seq->seqbase.first) {
693 seq_build_array(&seq->seqbase, array, depth + 1);
694 }
695
696 **array = seq;
697 (*array)++;
698 }
699 }
700
seq_array(Editing * ed,Sequence *** seqarray,int * tot,const bool use_current_sequences)701 static void seq_array(Editing *ed,
702 Sequence ***seqarray,
703 int *tot,
704 const bool use_current_sequences)
705 {
706 Sequence **array;
707
708 *seqarray = NULL;
709 *tot = 0;
710
711 if (ed == NULL) {
712 return;
713 }
714
715 if (use_current_sequences) {
716 seq_count(ed->seqbasep, tot);
717 }
718 else {
719 seq_count(&ed->seqbase, tot);
720 }
721
722 if (*tot == 0) {
723 return;
724 }
725
726 *seqarray = array = MEM_mallocN(sizeof(Sequence *) * (*tot), "SeqArray");
727 if (use_current_sequences) {
728 seq_build_array(ed->seqbasep, &array, 0);
729 }
730 else {
731 seq_build_array(&ed->seqbase, &array, 0);
732 }
733 }
734
BKE_sequence_iterator_begin(Editing * ed,SeqIterator * iter,const bool use_current_sequences)735 void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, const bool use_current_sequences)
736 {
737 memset(iter, 0, sizeof(*iter));
738 seq_array(ed, &iter->array, &iter->tot, use_current_sequences);
739
740 if (iter->tot) {
741 iter->cur = 0;
742 iter->seq = iter->array[iter->cur];
743 iter->valid = 1;
744 }
745 }
746
BKE_sequence_iterator_next(SeqIterator * iter)747 void BKE_sequence_iterator_next(SeqIterator *iter)
748 {
749 if (++iter->cur < iter->tot) {
750 iter->seq = iter->array[iter->cur];
751 }
752 else {
753 iter->valid = 0;
754 }
755 }
756
BKE_sequence_iterator_end(SeqIterator * iter)757 void BKE_sequence_iterator_end(SeqIterator *iter)
758 {
759 if (iter->array) {
760 MEM_freeN(iter->array);
761 }
762
763 iter->valid = 0;
764 }
765
metaseq_start(Sequence * metaseq)766 static int metaseq_start(Sequence *metaseq)
767 {
768 return metaseq->start + metaseq->startofs;
769 }
770
metaseq_end(Sequence * metaseq)771 static int metaseq_end(Sequence *metaseq)
772 {
773 return metaseq->start + metaseq->len - metaseq->endofs;
774 }
775
seq_update_sound_bounds_recursive_impl(Scene * scene,Sequence * metaseq,int start,int end)776 static void seq_update_sound_bounds_recursive_impl(Scene *scene,
777 Sequence *metaseq,
778 int start,
779 int end)
780 {
781 Sequence *seq;
782
783 /* for sound we go over full meta tree to update bounds of the sound strips,
784 * since sound is played outside of evaluating the imbufs, */
785 for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
786 if (seq->type == SEQ_TYPE_META) {
787 seq_update_sound_bounds_recursive_impl(
788 scene, seq, max_ii(start, metaseq_start(seq)), min_ii(end, metaseq_end(seq)));
789 }
790 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
791 if (seq->scene_sound) {
792 int startofs = seq->startofs;
793 int endofs = seq->endofs;
794 if (seq->startofs + seq->start < start) {
795 startofs = start - seq->start;
796 }
797
798 if (seq->start + seq->len - seq->endofs > end) {
799 endofs = seq->start + seq->len - end;
800 }
801
802 BKE_sound_move_scene_sound(scene,
803 seq->scene_sound,
804 seq->start + startofs,
805 seq->start + seq->len - endofs,
806 startofs + seq->anim_startofs);
807 }
808 }
809 }
810 }
811
seq_update_sound_bounds_recursive(Scene * scene,Sequence * metaseq)812 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
813 {
814 seq_update_sound_bounds_recursive_impl(
815 scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
816 }
817
BKE_sequence_calc_disp(Scene * scene,Sequence * seq)818 void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
819 {
820 if (seq->startofs && seq->startstill) {
821 seq->startstill = 0;
822 }
823 if (seq->endofs && seq->endstill) {
824 seq->endstill = 0;
825 }
826
827 seq->startdisp = seq->start + seq->startofs - seq->startstill;
828 seq->enddisp = seq->start + seq->len - seq->endofs + seq->endstill;
829
830 if (seq->type == SEQ_TYPE_META) {
831 seq_update_sound_bounds_recursive(scene, seq);
832 }
833 }
834
BKE_sequence_calc(Scene * scene,Sequence * seq)835 void BKE_sequence_calc(Scene *scene, Sequence *seq)
836 {
837 Sequence *seqm;
838 int min, max;
839
840 /* check all metas recursively */
841 seqm = seq->seqbase.first;
842 while (seqm) {
843 if (seqm->seqbase.first) {
844 BKE_sequence_calc(scene, seqm);
845 }
846 seqm = seqm->next;
847 }
848
849 /* effects and meta: automatic start and end */
850 if (seq->type & SEQ_TYPE_EFFECT) {
851 if (seq->seq1) {
852 seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
853 if (seq->seq3) {
854 seq->start = seq->startdisp = max_iii(
855 seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
856 seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
857 }
858 else if (seq->seq2) {
859 seq->start = seq->startdisp = max_ii(seq->seq1->startdisp, seq->seq2->startdisp);
860 seq->enddisp = min_ii(seq->seq1->enddisp, seq->seq2->enddisp);
861 }
862 else {
863 seq->start = seq->startdisp = seq->seq1->startdisp;
864 seq->enddisp = seq->seq1->enddisp;
865 }
866 /* we cant help if strips don't overlap, it wont give useful results.
867 * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
868 if (seq->enddisp < seq->startdisp) {
869 /* simple start/end swap */
870 seq->start = seq->enddisp;
871 seq->enddisp = seq->startdisp;
872 seq->startdisp = seq->start;
873 seq->flag |= SEQ_INVALID_EFFECT;
874 }
875 else {
876 seq->flag &= ~SEQ_INVALID_EFFECT;
877 }
878
879 seq->len = seq->enddisp - seq->startdisp;
880 }
881 else {
882 BKE_sequence_calc_disp(scene, seq);
883 }
884 }
885 else {
886 if (seq->type == SEQ_TYPE_META) {
887 seqm = seq->seqbase.first;
888 if (seqm) {
889 min = MAXFRAME * 2;
890 max = -MAXFRAME * 2;
891 while (seqm) {
892 if (seqm->startdisp < min) {
893 min = seqm->startdisp;
894 }
895 if (seqm->enddisp > max) {
896 max = seqm->enddisp;
897 }
898 seqm = seqm->next;
899 }
900 seq->start = min + seq->anim_startofs;
901 seq->len = max - min;
902 seq->len -= seq->anim_startofs;
903 seq->len -= seq->anim_endofs;
904 }
905 seq_update_sound_bounds_recursive(scene, seq);
906 }
907 BKE_sequence_calc_disp(scene, seq);
908 }
909 }
910
seq_multiview_name(Scene * scene,const int view_id,const char * prefix,const char * ext,char * r_path,size_t r_size)911 static void seq_multiview_name(Scene *scene,
912 const int view_id,
913 const char *prefix,
914 const char *ext,
915 char *r_path,
916 size_t r_size)
917 {
918 const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id);
919 BLI_assert(ext != NULL && suffix != NULL && prefix != NULL);
920 BLI_snprintf(r_path, r_size, "%s%s%s", prefix, suffix, ext);
921 }
922
923 /* note: caller should run BKE_sequence_calc(scene, seq) after */
BKE_sequence_reload_new_file(Main * bmain,Scene * scene,Sequence * seq,const bool lock_range)924 void BKE_sequence_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const bool lock_range)
925 {
926 char path[FILE_MAX];
927 int prev_startdisp = 0, prev_enddisp = 0;
928 /* note: don't rename the strip, will break animation curves */
929
930 if (ELEM(seq->type,
931 SEQ_TYPE_MOVIE,
932 SEQ_TYPE_IMAGE,
933 SEQ_TYPE_SOUND_RAM,
934 SEQ_TYPE_SCENE,
935 SEQ_TYPE_META,
936 SEQ_TYPE_MOVIECLIP,
937 SEQ_TYPE_MASK) == 0) {
938 return;
939 }
940
941 if (lock_range) {
942 /* keep so we don't have to move the actual start and end points (only the data) */
943 BKE_sequence_calc_disp(scene, seq);
944 prev_startdisp = seq->startdisp;
945 prev_enddisp = seq->enddisp;
946 }
947
948 switch (seq->type) {
949 case SEQ_TYPE_IMAGE: {
950 /* Hack? */
951 size_t olen = MEM_allocN_len(seq->strip->stripdata) / sizeof(StripElem);
952
953 seq->len = olen;
954 seq->len -= seq->anim_startofs;
955 seq->len -= seq->anim_endofs;
956 if (seq->len < 0) {
957 seq->len = 0;
958 }
959 break;
960 }
961 case SEQ_TYPE_MOVIE: {
962 StripAnim *sanim;
963 bool is_multiview_loaded = false;
964 const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
965 (scene->r.scemode & R_MULTIVIEW) != 0;
966
967 BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
968 BLI_path_abs(path, BKE_main_blendfile_path_from_global());
969
970 BKE_sequence_free_anim(seq);
971
972 if (is_multiview && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
973 char prefix[FILE_MAX];
974 const char *ext = NULL;
975 const int totfiles = seq_num_files(scene, seq->views_format, true);
976 int i = 0;
977
978 BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
979
980 if (prefix[0] != '\0') {
981 for (i = 0; i < totfiles; i++) {
982 struct anim *anim;
983 char str[FILE_MAX];
984
985 seq_multiview_name(scene, i, prefix, ext, str, FILE_MAX);
986 anim = openanim(str,
987 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
988 seq->streamindex,
989 seq->strip->colorspace_settings.name);
990
991 if (anim) {
992 seq_anim_add_suffix(scene, anim, i);
993 sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
994 BLI_addtail(&seq->anims, sanim);
995 sanim->anim = anim;
996 }
997 }
998 is_multiview_loaded = true;
999 }
1000 }
1001
1002 if (is_multiview_loaded == false) {
1003 struct anim *anim;
1004 anim = openanim(path,
1005 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1006 seq->streamindex,
1007 seq->strip->colorspace_settings.name);
1008 if (anim) {
1009 sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
1010 BLI_addtail(&seq->anims, sanim);
1011 sanim->anim = anim;
1012 }
1013 }
1014
1015 /* use the first video as reference for everything */
1016 sanim = seq->anims.first;
1017
1018 if ((!sanim) || (!sanim->anim)) {
1019 return;
1020 }
1021
1022 IMB_anim_load_metadata(sanim->anim);
1023
1024 seq->len = IMB_anim_get_duration(
1025 sanim->anim, seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN);
1026
1027 seq->anim_preseek = IMB_anim_get_preseek(sanim->anim);
1028
1029 seq->len -= seq->anim_startofs;
1030 seq->len -= seq->anim_endofs;
1031 if (seq->len < 0) {
1032 seq->len = 0;
1033 }
1034 break;
1035 }
1036 case SEQ_TYPE_MOVIECLIP:
1037 if (seq->clip == NULL) {
1038 return;
1039 }
1040
1041 seq->len = BKE_movieclip_get_duration(seq->clip);
1042
1043 seq->len -= seq->anim_startofs;
1044 seq->len -= seq->anim_endofs;
1045 if (seq->len < 0) {
1046 seq->len = 0;
1047 }
1048 break;
1049 case SEQ_TYPE_MASK:
1050 if (seq->mask == NULL) {
1051 return;
1052 }
1053 seq->len = BKE_mask_get_duration(seq->mask);
1054 seq->len -= seq->anim_startofs;
1055 seq->len -= seq->anim_endofs;
1056 if (seq->len < 0) {
1057 seq->len = 0;
1058 }
1059 break;
1060 case SEQ_TYPE_SOUND_RAM:
1061 #ifdef WITH_AUDASPACE
1062 if (!seq->sound) {
1063 return;
1064 }
1065 seq->len = ceil((double)BKE_sound_get_length(bmain, seq->sound) * FPS);
1066 seq->len -= seq->anim_startofs;
1067 seq->len -= seq->anim_endofs;
1068 if (seq->len < 0) {
1069 seq->len = 0;
1070 }
1071 #else
1072 UNUSED_VARS(bmain);
1073 return;
1074 #endif
1075 break;
1076 case SEQ_TYPE_SCENE: {
1077 seq->len = (seq->scene) ? seq->scene->r.efra - seq->scene->r.sfra + 1 : 0;
1078 seq->len -= seq->anim_startofs;
1079 seq->len -= seq->anim_endofs;
1080 if (seq->len < 0) {
1081 seq->len = 0;
1082 }
1083 break;
1084 }
1085 }
1086
1087 free_proxy_seq(seq);
1088
1089 if (lock_range) {
1090 BKE_sequence_tx_set_final_left(seq, prev_startdisp);
1091 BKE_sequence_tx_set_final_right(seq, prev_enddisp);
1092 BKE_sequence_single_fix(seq);
1093 }
1094
1095 BKE_sequence_calc(scene, seq);
1096 }
1097
BKE_sequence_movie_reload_if_needed(struct Main * bmain,struct Scene * scene,struct Sequence * seq,bool * r_was_reloaded,bool * r_can_produce_frames)1098 void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
1099 struct Scene *scene,
1100 struct Sequence *seq,
1101 bool *r_was_reloaded,
1102 bool *r_can_produce_frames)
1103 {
1104 BLI_assert(seq->type == SEQ_TYPE_MOVIE ||
1105 !"This function is only implemented for movie strips.");
1106
1107 bool must_reload = false;
1108
1109 /* The Sequence struct allows for multiple anim structs to be associated with one strip. This
1110 * function will return true only if there is at least one 'anim' AND all anims can produce
1111 * frames. */
1112
1113 if (BLI_listbase_is_empty(&seq->anims)) {
1114 /* No anim present, so reloading is always necessary. */
1115 must_reload = true;
1116 }
1117 else {
1118 LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
1119 if (!IMB_anim_can_produce_frames(sanim->anim)) {
1120 /* Anim cannot produce frames, try reloading. */
1121 must_reload = true;
1122 break;
1123 }
1124 };
1125 }
1126
1127 if (!must_reload) {
1128 /* There are one or more anims, and all can produce frames. */
1129 *r_was_reloaded = false;
1130 *r_can_produce_frames = true;
1131 return;
1132 }
1133
1134 BKE_sequence_reload_new_file(bmain, scene, seq, true);
1135 *r_was_reloaded = true;
1136
1137 if (BLI_listbase_is_empty(&seq->anims)) {
1138 /* No anims present after reloading => no frames can be produced. */
1139 *r_can_produce_frames = false;
1140 return;
1141 }
1142
1143 /* Check if there are still anims that cannot produce frames. */
1144 LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
1145 if (!IMB_anim_can_produce_frames(sanim->anim)) {
1146 /* There still is an anim that cannot produce frames. */
1147 *r_can_produce_frames = false;
1148 return;
1149 }
1150 };
1151
1152 /* There are one or more anims, and all can produce frames. */
1153 *r_can_produce_frames = true;
1154 }
1155
BKE_sequencer_sort(Scene * scene)1156 void BKE_sequencer_sort(Scene *scene)
1157 {
1158 /* all strips together per kind, and in order of y location ("machine") */
1159 ListBase seqbase, effbase;
1160 Editing *ed = BKE_sequencer_editing_get(scene, false);
1161 Sequence *seq, *seqt;
1162
1163 if (ed == NULL) {
1164 return;
1165 }
1166
1167 BLI_listbase_clear(&seqbase);
1168 BLI_listbase_clear(&effbase);
1169
1170 while ((seq = BLI_pophead(ed->seqbasep))) {
1171
1172 if (seq->type & SEQ_TYPE_EFFECT) {
1173 seqt = effbase.first;
1174 while (seqt) {
1175 if (seqt->machine >= seq->machine) {
1176 BLI_insertlinkbefore(&effbase, seqt, seq);
1177 break;
1178 }
1179 seqt = seqt->next;
1180 }
1181 if (seqt == NULL) {
1182 BLI_addtail(&effbase, seq);
1183 }
1184 }
1185 else {
1186 seqt = seqbase.first;
1187 while (seqt) {
1188 if (seqt->machine >= seq->machine) {
1189 BLI_insertlinkbefore(&seqbase, seqt, seq);
1190 break;
1191 }
1192 seqt = seqt->next;
1193 }
1194 if (seqt == NULL) {
1195 BLI_addtail(&seqbase, seq);
1196 }
1197 }
1198 }
1199
1200 BLI_movelisttolist(&seqbase, &effbase);
1201 *(ed->seqbasep) = seqbase;
1202 }
1203
1204 /** Comparison function suitable to be used with BLI_listbase_sort()... */
BKE_sequencer_cmp_time_startdisp(const void * a,const void * b)1205 int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b)
1206 {
1207 const Sequence *seq_a = a;
1208 const Sequence *seq_b = b;
1209
1210 return (seq_a->startdisp > seq_b->startdisp);
1211 }
1212
clear_scene_in_allseqs_fn(Sequence * seq,void * arg_pt)1213 static int clear_scene_in_allseqs_fn(Sequence *seq, void *arg_pt)
1214 {
1215 if (seq->scene == (Scene *)arg_pt) {
1216 seq->scene = NULL;
1217 }
1218 return 1;
1219 }
1220
BKE_sequencer_clear_scene_in_allseqs(Main * bmain,Scene * scene)1221 void BKE_sequencer_clear_scene_in_allseqs(Main *bmain, Scene *scene)
1222 {
1223 Scene *scene_iter;
1224
1225 /* when a scene is deleted: test all seqs */
1226 for (scene_iter = bmain->scenes.first; scene_iter; scene_iter = scene_iter->id.next) {
1227 if (scene_iter != scene && scene_iter->ed) {
1228 BKE_sequencer_base_recursive_apply(
1229 &scene_iter->ed->seqbase, clear_scene_in_allseqs_fn, scene);
1230 }
1231 }
1232 }
1233
1234 typedef struct SeqUniqueInfo {
1235 Sequence *seq;
1236 char name_src[SEQ_NAME_MAXSTR];
1237 char name_dest[SEQ_NAME_MAXSTR];
1238 int count;
1239 int match;
1240 } SeqUniqueInfo;
1241
seqbase_unique_name(ListBase * seqbasep,SeqUniqueInfo * sui)1242 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
1243 {
1244 Sequence *seq;
1245 for (seq = seqbasep->first; seq; seq = seq->next) {
1246 if ((sui->seq != seq) && STREQ(sui->name_dest, seq->name + 2)) {
1247 /* SEQ_NAME_MAXSTR -4 for the number, -1 for \0, - 2 for r_prefix */
1248 BLI_snprintf(sui->name_dest,
1249 sizeof(sui->name_dest),
1250 "%.*s.%03d",
1251 SEQ_NAME_MAXSTR - 4 - 1 - 2,
1252 sui->name_src,
1253 sui->count++);
1254 sui->match = 1; /* be sure to re-scan */
1255 }
1256 }
1257 }
1258
seqbase_unique_name_recursive_fn(Sequence * seq,void * arg_pt)1259 static int seqbase_unique_name_recursive_fn(Sequence *seq, void *arg_pt)
1260 {
1261 if (seq->seqbase.first) {
1262 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
1263 }
1264 return 1;
1265 }
1266
BKE_sequence_base_unique_name_recursive(ListBase * seqbasep,Sequence * seq)1267 void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq)
1268 {
1269 SeqUniqueInfo sui;
1270 char *dot;
1271 sui.seq = seq;
1272 BLI_strncpy(sui.name_src, seq->name + 2, sizeof(sui.name_src));
1273 BLI_strncpy(sui.name_dest, seq->name + 2, sizeof(sui.name_dest));
1274
1275 sui.count = 1;
1276 sui.match = 1; /* assume the worst to start the loop */
1277
1278 /* Strip off the suffix */
1279 if ((dot = strrchr(sui.name_src, '.'))) {
1280 *dot = '\0';
1281 dot++;
1282
1283 if (*dot) {
1284 sui.count = atoi(dot) + 1;
1285 }
1286 }
1287
1288 while (sui.match) {
1289 sui.match = 0;
1290 seqbase_unique_name(seqbasep, &sui);
1291 BKE_sequencer_base_recursive_apply(seqbasep, seqbase_unique_name_recursive_fn, &sui);
1292 }
1293
1294 BLI_strncpy(seq->name + 2, sui.name_dest, sizeof(seq->name) - 2);
1295 }
1296
give_seqname_by_type(int type)1297 static const char *give_seqname_by_type(int type)
1298 {
1299 switch (type) {
1300 case SEQ_TYPE_META:
1301 return "Meta";
1302 case SEQ_TYPE_IMAGE:
1303 return "Image";
1304 case SEQ_TYPE_SCENE:
1305 return "Scene";
1306 case SEQ_TYPE_MOVIE:
1307 return "Movie";
1308 case SEQ_TYPE_MOVIECLIP:
1309 return "Clip";
1310 case SEQ_TYPE_MASK:
1311 return "Mask";
1312 case SEQ_TYPE_SOUND_RAM:
1313 return "Audio";
1314 case SEQ_TYPE_CROSS:
1315 return "Cross";
1316 case SEQ_TYPE_GAMCROSS:
1317 return "Gamma Cross";
1318 case SEQ_TYPE_ADD:
1319 return "Add";
1320 case SEQ_TYPE_SUB:
1321 return "Sub";
1322 case SEQ_TYPE_MUL:
1323 return "Mul";
1324 case SEQ_TYPE_ALPHAOVER:
1325 return "Alpha Over";
1326 case SEQ_TYPE_ALPHAUNDER:
1327 return "Alpha Under";
1328 case SEQ_TYPE_OVERDROP:
1329 return "Over Drop";
1330 case SEQ_TYPE_COLORMIX:
1331 return "Color Mix";
1332 case SEQ_TYPE_WIPE:
1333 return "Wipe";
1334 case SEQ_TYPE_GLOW:
1335 return "Glow";
1336 case SEQ_TYPE_TRANSFORM:
1337 return "Transform";
1338 case SEQ_TYPE_COLOR:
1339 return "Color";
1340 case SEQ_TYPE_MULTICAM:
1341 return "Multicam";
1342 case SEQ_TYPE_ADJUSTMENT:
1343 return "Adjustment";
1344 case SEQ_TYPE_SPEED:
1345 return "Speed";
1346 case SEQ_TYPE_GAUSSIAN_BLUR:
1347 return "Gaussian Blur";
1348 case SEQ_TYPE_TEXT:
1349 return "Text";
1350 default:
1351 return NULL;
1352 }
1353 }
1354
BKE_sequence_give_name(Sequence * seq)1355 const char *BKE_sequence_give_name(Sequence *seq)
1356 {
1357 const char *name = give_seqname_by_type(seq->type);
1358
1359 if (!name) {
1360 if (!(seq->type & SEQ_TYPE_EFFECT)) {
1361 return seq->strip->dir;
1362 }
1363
1364 return "Effect";
1365 }
1366 return name;
1367 }
1368
BKE_sequence_seqbase_get(Sequence * seq,int * r_offset)1369 ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset)
1370 {
1371 ListBase *seqbase = NULL;
1372
1373 switch (seq->type) {
1374 case SEQ_TYPE_META: {
1375 seqbase = &seq->seqbase;
1376 *r_offset = seq->start;
1377 break;
1378 }
1379 case SEQ_TYPE_SCENE: {
1380 if (seq->flag & SEQ_SCENE_STRIPS && seq->scene) {
1381 Editing *ed = BKE_sequencer_editing_get(seq->scene, false);
1382 if (ed) {
1383 seqbase = &ed->seqbase;
1384 *r_offset = seq->scene->r.sfra;
1385 }
1386 }
1387 break;
1388 }
1389 }
1390
1391 return seqbase;
1392 }
1393
1394 /*********************** DO THE SEQUENCE *************************/
1395
multibuf(ImBuf * ibuf,const float fmul)1396 static void multibuf(ImBuf *ibuf, const float fmul)
1397 {
1398 char *rt;
1399 float *rt_float;
1400
1401 int a;
1402
1403 rt = (char *)ibuf->rect;
1404 rt_float = ibuf->rect_float;
1405
1406 if (rt) {
1407 const int imul = (int)(256.0f * fmul);
1408 a = ibuf->x * ibuf->y;
1409 while (a--) {
1410 rt[0] = min_ii((imul * rt[0]) >> 8, 255);
1411 rt[1] = min_ii((imul * rt[1]) >> 8, 255);
1412 rt[2] = min_ii((imul * rt[2]) >> 8, 255);
1413 rt[3] = min_ii((imul * rt[3]) >> 8, 255);
1414
1415 rt += 4;
1416 }
1417 }
1418 if (rt_float) {
1419 a = ibuf->x * ibuf->y;
1420 while (a--) {
1421 rt_float[0] *= fmul;
1422 rt_float[1] *= fmul;
1423 rt_float[2] *= fmul;
1424 rt_float[3] *= fmul;
1425
1426 rt_float += 4;
1427 }
1428 }
1429 }
1430
BKE_sequencer_give_stripelem_index(Sequence * seq,float cfra)1431 float BKE_sequencer_give_stripelem_index(Sequence *seq, float cfra)
1432 {
1433 float nr;
1434 int sta = seq->start;
1435 int end = seq->start + seq->len - 1;
1436
1437 if (seq->type & SEQ_TYPE_EFFECT) {
1438 end = seq->enddisp;
1439 }
1440
1441 if (end < sta) {
1442 return -1;
1443 }
1444
1445 if (seq->flag & SEQ_REVERSE_FRAMES) {
1446 /*reverse frame in this sequence */
1447 if (cfra <= sta) {
1448 nr = end - sta;
1449 }
1450 else if (cfra >= end) {
1451 nr = 0;
1452 }
1453 else {
1454 nr = end - cfra;
1455 }
1456 }
1457 else {
1458 if (cfra <= sta) {
1459 nr = 0;
1460 }
1461 else if (cfra >= end) {
1462 nr = end - sta;
1463 }
1464 else {
1465 nr = cfra - sta;
1466 }
1467 }
1468
1469 if (seq->strobe < 1.0f) {
1470 seq->strobe = 1.0f;
1471 }
1472
1473 if (seq->strobe > 1.0f) {
1474 nr -= fmodf((double)nr, (double)seq->strobe);
1475 }
1476
1477 return nr;
1478 }
1479
BKE_sequencer_give_stripelem(Sequence * seq,int cfra)1480 StripElem *BKE_sequencer_give_stripelem(Sequence *seq, int cfra)
1481 {
1482 StripElem *se = seq->strip->stripdata;
1483
1484 if (seq->type == SEQ_TYPE_IMAGE) {
1485 /* only IMAGE strips use the whole array, MOVIE strips use only the first element,
1486 * all other strips don't use this...
1487 */
1488
1489 int nr = (int)BKE_sequencer_give_stripelem_index(seq, cfra);
1490
1491 if (nr == -1 || se == NULL) {
1492 return NULL;
1493 }
1494
1495 se += nr + seq->anim_startofs;
1496 }
1497 return se;
1498 }
1499
evaluate_seq_frame_gen(Sequence ** seq_arr,ListBase * seqbase,int cfra,int chanshown)1500 static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra, int chanshown)
1501 {
1502 /* Use arbitrary sized linked list, the size could be over MAXSEQ. */
1503 LinkNodePair effect_inputs = {NULL, NULL};
1504 int totseq = 0;
1505
1506 memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1));
1507
1508 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
1509 if ((seq->startdisp <= cfra) && (seq->enddisp > cfra)) {
1510 if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SEQ_MUTE)) {
1511
1512 if (seq->seq1) {
1513 BLI_linklist_append_alloca(&effect_inputs, seq->seq1);
1514 }
1515
1516 if (seq->seq2) {
1517 BLI_linklist_append_alloca(&effect_inputs, seq->seq2);
1518 }
1519
1520 if (seq->seq3) {
1521 BLI_linklist_append_alloca(&effect_inputs, seq->seq3);
1522 }
1523 }
1524
1525 seq_arr[seq->machine] = seq;
1526 totseq++;
1527 }
1528 }
1529
1530 /* Drop strips which are used for effect inputs, we don't want
1531 * them to blend into render stack in any other way than effect
1532 * string rendering. */
1533 for (LinkNode *seq_item = effect_inputs.list; seq_item; seq_item = seq_item->next) {
1534 Sequence *seq = seq_item->link;
1535 /* It's possible that effect strip would be placed to the same
1536 * 'machine' as its inputs. We don't want to clear such strips
1537 * from the stack. */
1538 if (seq_arr[seq->machine] && seq_arr[seq->machine]->type & SEQ_TYPE_EFFECT) {
1539 continue;
1540 }
1541 /* If we're shown a specified channel, then we want to see the strips
1542 * which belongs to this machine. */
1543 if (chanshown != 0 && chanshown <= seq->machine) {
1544 continue;
1545 }
1546 seq_arr[seq->machine] = NULL;
1547 }
1548
1549 return totseq;
1550 }
1551
BKE_sequencer_evaluate_frame(Scene * scene,int cfra)1552 int BKE_sequencer_evaluate_frame(Scene *scene, int cfra)
1553 {
1554 Editing *ed = BKE_sequencer_editing_get(scene, false);
1555 Sequence *seq_arr[MAXSEQ + 1];
1556
1557 if (ed == NULL) {
1558 return 0;
1559 }
1560
1561 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra, 0);
1562 }
1563
video_seq_is_rendered(Sequence * seq)1564 static bool video_seq_is_rendered(Sequence *seq)
1565 {
1566 return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM);
1567 }
1568
BKE_sequencer_get_shown_sequences(ListBase * seqbasep,int cfra,int chanshown,Sequence ** seq_arr_out)1569 int BKE_sequencer_get_shown_sequences(ListBase *seqbasep,
1570 int cfra,
1571 int chanshown,
1572 Sequence **seq_arr_out)
1573 {
1574 Sequence *seq_arr[MAXSEQ + 1];
1575 int b = chanshown;
1576 int cnt = 0;
1577
1578 if (b > MAXSEQ) {
1579 return 0;
1580 }
1581
1582 if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra, chanshown)) {
1583 if (b == 0) {
1584 b = MAXSEQ;
1585 }
1586 for (; b > 0; b--) {
1587 if (video_seq_is_rendered(seq_arr[b])) {
1588 break;
1589 }
1590 }
1591 }
1592
1593 chanshown = b;
1594
1595 for (; b > 0; b--) {
1596 if (video_seq_is_rendered(seq_arr[b])) {
1597 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1598 break;
1599 }
1600 }
1601 }
1602
1603 for (; b <= chanshown && b >= 0; b++) {
1604 if (video_seq_is_rendered(seq_arr[b])) {
1605 seq_arr_out[cnt++] = seq_arr[b];
1606 }
1607 }
1608
1609 return cnt;
1610 }
1611
1612 /*********************** proxy management *************************/
1613
1614 typedef struct SeqIndexBuildContext {
1615 struct IndexBuildContext *index_context;
1616
1617 int tc_flags;
1618 int size_flags;
1619 int quality;
1620 bool overwrite;
1621 int view_id;
1622
1623 Main *bmain;
1624 Depsgraph *depsgraph;
1625 Scene *scene;
1626 Sequence *seq, *orig_seq;
1627 } SeqIndexBuildContext;
1628
1629 #define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE)
1630
seq_rendersize_to_proxysize(int render_size)1631 static IMB_Proxy_Size seq_rendersize_to_proxysize(int render_size)
1632 {
1633 switch (render_size) {
1634 case SEQ_RENDER_SIZE_PROXY_25:
1635 return IMB_PROXY_25;
1636 case SEQ_RENDER_SIZE_PROXY_50:
1637 return IMB_PROXY_50;
1638 case SEQ_RENDER_SIZE_PROXY_75:
1639 return IMB_PROXY_75;
1640 case SEQ_RENDER_SIZE_PROXY_100:
1641 return IMB_PROXY_100;
1642 }
1643 return IMB_PROXY_NONE;
1644 }
1645
BKE_sequencer_rendersize_to_scale_factor(int render_size)1646 double BKE_sequencer_rendersize_to_scale_factor(int render_size)
1647 {
1648 switch (render_size) {
1649 case SEQ_RENDER_SIZE_PROXY_25:
1650 return 0.25;
1651 case SEQ_RENDER_SIZE_PROXY_50:
1652 return 0.50;
1653 case SEQ_RENDER_SIZE_PROXY_75:
1654 return 0.75;
1655 }
1656 return 1.0;
1657 }
1658
1659 /* the number of files will vary according to the stereo format */
seq_num_files(Scene * scene,char views_format,const bool is_multiview)1660 static int seq_num_files(Scene *scene, char views_format, const bool is_multiview)
1661 {
1662 if (!is_multiview) {
1663 return 1;
1664 }
1665 if (views_format == R_IMF_VIEWS_STEREO_3D) {
1666 return 1;
1667 }
1668 /* R_IMF_VIEWS_INDIVIDUAL */
1669
1670 return BKE_scene_multiview_num_views_get(&scene->r);
1671 }
1672
seq_proxy_index_dir_set(struct anim * anim,const char * base_dir)1673 static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir)
1674 {
1675 char dir[FILE_MAX];
1676 char fname[FILE_MAXFILE];
1677
1678 IMB_anim_get_fname(anim, fname, FILE_MAXFILE);
1679 BLI_strncpy(dir, base_dir, sizeof(dir));
1680 BLI_path_append(dir, sizeof(dir), fname);
1681 IMB_anim_set_index_dir(anim, dir);
1682 }
1683
seq_open_anim_file(Scene * scene,Sequence * seq,bool openfile)1684 static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
1685 {
1686 char dir[FILE_MAX];
1687 char name[FILE_MAX];
1688 StripProxy *proxy;
1689 bool use_proxy;
1690 bool is_multiview_loaded = false;
1691 Editing *ed = scene->ed;
1692 const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 &&
1693 (scene->r.scemode & R_MULTIVIEW) != 0;
1694
1695 if ((seq->anims.first != NULL) && (((StripAnim *)seq->anims.first)->anim != NULL)) {
1696 return;
1697 }
1698
1699 /* reset all the previously created anims */
1700 BKE_sequence_free_anim(seq);
1701
1702 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
1703 BLI_path_abs(name, BKE_main_blendfile_path_from_global());
1704
1705 proxy = seq->strip->proxy;
1706
1707 use_proxy = proxy && ((proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) != 0 ||
1708 (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE));
1709
1710 if (use_proxy) {
1711 if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
1712 if (ed->proxy_dir[0] == 0) {
1713 BLI_strncpy(dir, "//BL_proxy", sizeof(dir));
1714 }
1715 else {
1716 BLI_strncpy(dir, ed->proxy_dir, sizeof(dir));
1717 }
1718 }
1719 else {
1720 BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
1721 }
1722 BLI_path_abs(dir, BKE_main_blendfile_path_from_global());
1723 }
1724
1725 if (is_multiview && seq->views_format == R_IMF_VIEWS_INDIVIDUAL) {
1726 int totfiles = seq_num_files(scene, seq->views_format, true);
1727 char prefix[FILE_MAX];
1728 const char *ext = NULL;
1729 int i;
1730
1731 BKE_scene_multiview_view_prefix_get(scene, name, prefix, &ext);
1732
1733 if (prefix[0] != '\0') {
1734 for (i = 0; i < totfiles; i++) {
1735 const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
1736 char str[FILE_MAX];
1737 StripAnim *sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
1738
1739 BLI_addtail(&seq->anims, sanim);
1740
1741 BLI_snprintf(str, sizeof(str), "%s%s%s", prefix, suffix, ext);
1742
1743 if (openfile) {
1744 sanim->anim = openanim(str,
1745 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1746 seq->streamindex,
1747 seq->strip->colorspace_settings.name);
1748 }
1749 else {
1750 sanim->anim = openanim_noload(str,
1751 IB_rect |
1752 ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1753 seq->streamindex,
1754 seq->strip->colorspace_settings.name);
1755 }
1756
1757 if (sanim->anim) {
1758 /* we already have the suffix */
1759 IMB_suffix_anim(sanim->anim, suffix);
1760 }
1761 else {
1762 if (openfile) {
1763 sanim->anim = openanim(name,
1764 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1765 seq->streamindex,
1766 seq->strip->colorspace_settings.name);
1767 }
1768 else {
1769 sanim->anim = openanim_noload(name,
1770 IB_rect |
1771 ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1772 seq->streamindex,
1773 seq->strip->colorspace_settings.name);
1774 }
1775
1776 /* No individual view files - monoscopic, stereo 3d or EXR multi-view. */
1777 totfiles = 1;
1778 }
1779
1780 if (sanim->anim && use_proxy) {
1781 seq_proxy_index_dir_set(sanim->anim, dir);
1782 }
1783 }
1784 is_multiview_loaded = true;
1785 }
1786 }
1787
1788 if (is_multiview_loaded == false) {
1789 StripAnim *sanim;
1790
1791 sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
1792 BLI_addtail(&seq->anims, sanim);
1793
1794 if (openfile) {
1795 sanim->anim = openanim(name,
1796 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1797 seq->streamindex,
1798 seq->strip->colorspace_settings.name);
1799 }
1800 else {
1801 sanim->anim = openanim_noload(name,
1802 IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
1803 seq->streamindex,
1804 seq->strip->colorspace_settings.name);
1805 }
1806
1807 if (sanim->anim && use_proxy) {
1808 seq_proxy_index_dir_set(sanim->anim, dir);
1809 }
1810 }
1811 }
1812
seq_proxy_get_custom_file_fname(Sequence * seq,char * name,const int view_id)1813 static bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_id)
1814 {
1815 char fname[FILE_MAXFILE];
1816 char suffix[24];
1817 StripProxy *proxy = seq->strip->proxy;
1818
1819 if (proxy == NULL) {
1820 return false;
1821 }
1822
1823 BLI_join_dirfile(fname, PROXY_MAXFILE, proxy->dir, proxy->file);
1824 BLI_path_abs(fname, BKE_main_blendfile_path_from_global());
1825
1826 if (view_id > 0) {
1827 BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id);
1828 /* TODO(sergey): This will actually append suffix after extension
1829 * which is weird but how was originally coded in multi-view branch.
1830 */
1831 BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", fname, suffix);
1832 }
1833 else {
1834 BLI_strncpy(name, fname, PROXY_MAXFILE);
1835 }
1836
1837 return true;
1838 }
1839
seq_proxy_get_fname(Editing * ed,Sequence * seq,int cfra,eSpaceSeq_Proxy_RenderSize render_size,char * name,const int view_id)1840 static bool seq_proxy_get_fname(Editing *ed,
1841 Sequence *seq,
1842 int cfra,
1843 eSpaceSeq_Proxy_RenderSize render_size,
1844 char *name,
1845 const int view_id)
1846 {
1847 char dir[PROXY_MAXFILE];
1848 char suffix[24] = {'\0'};
1849 StripProxy *proxy = seq->strip->proxy;
1850
1851 if (proxy == NULL) {
1852 return false;
1853 }
1854
1855 /* Multi-view suffix. */
1856 if (view_id > 0) {
1857 BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id);
1858 }
1859
1860 /* Per strip with Custom file situation is handled separately. */
1861 if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE &&
1862 ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE) {
1863 if (seq_proxy_get_custom_file_fname(seq, name, view_id)) {
1864 return true;
1865 }
1866 }
1867
1868 if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) {
1869 /* Per project default. */
1870 if (ed->proxy_dir[0] == 0) {
1871 BLI_strncpy(dir, "//BL_proxy", sizeof(dir));
1872 }
1873 else { /* Per project with custom dir. */
1874 BLI_strncpy(dir, ed->proxy_dir, sizeof(dir));
1875 }
1876 BLI_path_abs(name, BKE_main_blendfile_path_from_global());
1877 }
1878 else {
1879 /* Pre strip with custom dir. */
1880 if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) {
1881 BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
1882 }
1883 else { /* Per strip default. */
1884 BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
1885 }
1886 }
1887
1888 /* Proxy size number to be used in path. */
1889 int proxy_size_number = BKE_sequencer_rendersize_to_scale_factor(render_size) * 100;
1890
1891 BLI_snprintf(name,
1892 PROXY_MAXFILE,
1893 "%s/images/%d/%s_proxy%s",
1894 dir,
1895 proxy_size_number,
1896 BKE_sequencer_give_stripelem(seq, cfra)->name,
1897 suffix);
1898 BLI_path_abs(name, BKE_main_blendfile_path_from_global());
1899 strcat(name, ".jpg");
1900
1901 return true;
1902 }
1903
seq_can_use_proxy(Sequence * seq,IMB_Proxy_Size psize)1904 static bool seq_can_use_proxy(Sequence *seq, IMB_Proxy_Size psize)
1905 {
1906 if (seq->strip->proxy == NULL) {
1907 return false;
1908 }
1909 short size_flags = seq->strip->proxy->build_size_flags;
1910 return (seq->flag & SEQ_USE_PROXY) != 0 && psize != IMB_PROXY_NONE && (size_flags & psize) != 0;
1911 }
1912
seq_proxy_fetch(const SeqRenderData * context,Sequence * seq,int cfra)1913 static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra)
1914 {
1915 char name[PROXY_MAXFILE];
1916 StripProxy *proxy = seq->strip->proxy;
1917 const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size;
1918 Editing *ed = context->scene->ed;
1919 StripAnim *sanim;
1920
1921 /* only use proxies, if they are enabled (even if present!) */
1922 if (!seq_can_use_proxy(seq, seq_rendersize_to_proxysize(psize))) {
1923 return NULL;
1924 }
1925
1926 if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
1927 int frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs;
1928 if (proxy->anim == NULL) {
1929 if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) {
1930 return NULL;
1931 }
1932
1933 proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name);
1934 }
1935 if (proxy->anim == NULL) {
1936 return NULL;
1937 }
1938
1939 seq_open_anim_file(context->scene, seq, true);
1940 sanim = seq->anims.first;
1941
1942 frameno = IMB_anim_index_get_frame_index(
1943 sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno);
1944
1945 return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
1946 }
1947
1948 if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) {
1949 return NULL;
1950 }
1951
1952 if (BLI_exists(name)) {
1953 ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL);
1954
1955 if (ibuf) {
1956 sequencer_imbuf_assign_spaces(context->scene, ibuf);
1957 }
1958
1959 return ibuf;
1960 }
1961
1962 return NULL;
1963 }
1964
seq_proxy_build_frame(const SeqRenderData * context,SeqRenderState * state,Sequence * seq,int cfra,int proxy_render_size,const bool overwrite)1965 static void seq_proxy_build_frame(const SeqRenderData *context,
1966 SeqRenderState *state,
1967 Sequence *seq,
1968 int cfra,
1969 int proxy_render_size,
1970 const bool overwrite)
1971 {
1972 char name[PROXY_MAXFILE];
1973 int quality;
1974 int rectx, recty;
1975 int ok;
1976 ImBuf *ibuf_tmp, *ibuf;
1977 Editing *ed = context->scene->ed;
1978
1979 if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) {
1980 return;
1981 }
1982
1983 if (!overwrite && BLI_exists(name)) {
1984 return;
1985 }
1986
1987 ibuf_tmp = seq_render_strip(context, state, seq, cfra);
1988
1989 rectx = (proxy_render_size * ibuf_tmp->x) / 100;
1990 recty = (proxy_render_size * ibuf_tmp->y) / 100;
1991
1992 if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) {
1993 ibuf = IMB_dupImBuf(ibuf_tmp);
1994 IMB_metadata_copy(ibuf, ibuf_tmp);
1995 IMB_freeImBuf(ibuf_tmp);
1996 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1997 }
1998 else {
1999 ibuf = ibuf_tmp;
2000 }
2001
2002 /* depth = 32 is intentionally left in, otherwise ALPHA channels
2003 * won't work... */
2004 quality = seq->strip->proxy->quality;
2005 ibuf->ftype = IMB_FTYPE_JPG;
2006 ibuf->foptions.quality = quality;
2007
2008 /* unsupported feature only confuses other s/w */
2009 if (ibuf->planes == 32) {
2010 ibuf->planes = 24;
2011 }
2012
2013 BLI_make_existing_file(name);
2014
2015 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
2016 if (ok == 0) {
2017 perror(name);
2018 }
2019
2020 IMB_freeImBuf(ibuf);
2021 }
2022
2023 /**
2024 * Returns whether the file this context would read from even exist,
2025 * if not, don't create the context
2026 */
seq_proxy_multiview_context_invalid(Sequence * seq,Scene * scene,const int view_id)2027 static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id)
2028 {
2029 if ((scene->r.scemode & R_MULTIVIEW) == 0) {
2030 return false;
2031 }
2032
2033 if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
2034 static char prefix[FILE_MAX];
2035 static const char *ext = NULL;
2036 char str[FILE_MAX];
2037
2038 if (view_id == 0) {
2039 char path[FILE_MAX];
2040 BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name);
2041 BLI_path_abs(path, BKE_main_blendfile_path_from_global());
2042 BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
2043 }
2044 else {
2045 prefix[0] = '\0';
2046 }
2047
2048 if (prefix[0] == '\0') {
2049 return view_id != 0;
2050 }
2051
2052 seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX);
2053
2054 if (BLI_access(str, R_OK) == 0) {
2055 return false;
2056 }
2057
2058 return view_id != 0;
2059 }
2060 return false;
2061 }
2062
2063 /**
2064 * This returns the maximum possible number of required contexts
2065 */
seq_proxy_context_count(Sequence * seq,Scene * scene)2066 static int seq_proxy_context_count(Sequence *seq, Scene *scene)
2067 {
2068 int num_views = 1;
2069
2070 if ((scene->r.scemode & R_MULTIVIEW) == 0) {
2071 return 1;
2072 }
2073
2074 switch (seq->type) {
2075 case SEQ_TYPE_MOVIE: {
2076 num_views = BLI_listbase_count(&seq->anims);
2077 break;
2078 }
2079 case SEQ_TYPE_IMAGE: {
2080 switch (seq->views_format) {
2081 case R_IMF_VIEWS_INDIVIDUAL:
2082 num_views = BKE_scene_multiview_num_views_get(&scene->r);
2083 break;
2084 case R_IMF_VIEWS_STEREO_3D:
2085 num_views = 2;
2086 break;
2087 case R_IMF_VIEWS_MULTIVIEW:
2088 /* not supported at the moment */
2089 /* pass through */
2090 default:
2091 num_views = 1;
2092 }
2093 break;
2094 }
2095 }
2096
2097 return num_views;
2098 }
2099
BKE_sequencer_proxy_rebuild_context(Main * bmain,Depsgraph * depsgraph,Scene * scene,Sequence * seq,struct GSet * file_list,ListBase * queue)2100 bool BKE_sequencer_proxy_rebuild_context(Main *bmain,
2101 Depsgraph *depsgraph,
2102 Scene *scene,
2103 Sequence *seq,
2104 struct GSet *file_list,
2105 ListBase *queue)
2106 {
2107 SeqIndexBuildContext *context;
2108 Sequence *nseq;
2109 LinkData *link;
2110 int num_files;
2111 int i;
2112
2113 if (!seq->strip || !seq->strip->proxy) {
2114 return true;
2115 }
2116
2117 if (!(seq->flag & SEQ_USE_PROXY)) {
2118 return true;
2119 }
2120
2121 num_files = seq_proxy_context_count(seq, scene);
2122
2123 for (i = 0; i < num_files; i++) {
2124 if (seq_proxy_multiview_context_invalid(seq, scene, i)) {
2125 continue;
2126 }
2127
2128 context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
2129
2130 nseq = BKE_sequence_dupli_recursive(scene, scene, NULL, seq, 0);
2131
2132 context->tc_flags = nseq->strip->proxy->build_tc_flags;
2133 context->size_flags = nseq->strip->proxy->build_size_flags;
2134 context->quality = nseq->strip->proxy->quality;
2135 context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0;
2136
2137 context->bmain = bmain;
2138 context->depsgraph = depsgraph;
2139 context->scene = scene;
2140 context->orig_seq = seq;
2141 context->seq = nseq;
2142
2143 context->view_id = i; /* only for images */
2144
2145 if (nseq->type == SEQ_TYPE_MOVIE) {
2146 StripAnim *sanim;
2147
2148 seq_open_anim_file(scene, nseq, true);
2149 sanim = BLI_findlink(&nseq->anims, i);
2150
2151 if (sanim->anim) {
2152 context->index_context = IMB_anim_index_rebuild_context(sanim->anim,
2153 context->tc_flags,
2154 context->size_flags,
2155 context->quality,
2156 context->overwrite,
2157 file_list);
2158 }
2159 if (!context->index_context) {
2160 MEM_freeN(context);
2161 return false;
2162 }
2163 }
2164
2165 link = BLI_genericNodeN(context);
2166 BLI_addtail(queue, link);
2167 }
2168 return true;
2169 }
2170
BKE_sequencer_proxy_rebuild(SeqIndexBuildContext * context,short * stop,short * do_update,float * progress)2171 void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context,
2172 short *stop,
2173 short *do_update,
2174 float *progress)
2175 {
2176 const bool overwrite = context->overwrite;
2177 SeqRenderData render_context;
2178 Sequence *seq = context->seq;
2179 Scene *scene = context->scene;
2180 Main *bmain = context->bmain;
2181 int cfra;
2182
2183 if (seq->type == SEQ_TYPE_MOVIE) {
2184 if (context->index_context) {
2185 IMB_anim_index_rebuild(context->index_context, stop, do_update, progress);
2186 }
2187
2188 return;
2189 }
2190
2191 if (!(seq->flag & SEQ_USE_PROXY)) {
2192 return;
2193 }
2194
2195 /* that's why it is called custom... */
2196 if (seq->strip->proxy && seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
2197 return;
2198 }
2199
2200 /* fail safe code */
2201
2202 BKE_sequencer_new_render_data(bmain,
2203 context->depsgraph,
2204 context->scene,
2205 roundf((scene->r.size * (float)scene->r.xsch) / 100.0f),
2206 roundf((scene->r.size * (float)scene->r.ysch) / 100.0f),
2207 100,
2208 false,
2209 &render_context);
2210
2211 render_context.skip_cache = true;
2212 render_context.is_proxy_render = true;
2213 render_context.view_id = context->view_id;
2214
2215 SeqRenderState state;
2216 sequencer_state_init(&state);
2217
2218 for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
2219 if (context->size_flags & IMB_PROXY_25) {
2220 seq_proxy_build_frame(&render_context, &state, seq, cfra, 25, overwrite);
2221 }
2222 if (context->size_flags & IMB_PROXY_50) {
2223 seq_proxy_build_frame(&render_context, &state, seq, cfra, 50, overwrite);
2224 }
2225 if (context->size_flags & IMB_PROXY_75) {
2226 seq_proxy_build_frame(&render_context, &state, seq, cfra, 75, overwrite);
2227 }
2228 if (context->size_flags & IMB_PROXY_100) {
2229 seq_proxy_build_frame(&render_context, &state, seq, cfra, 100, overwrite);
2230 }
2231
2232 *progress = (float)(cfra - seq->startdisp - seq->startstill) /
2233 (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
2234 *do_update = true;
2235
2236 if (*stop || G.is_break) {
2237 break;
2238 }
2239 }
2240 }
2241
BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext * context,bool stop)2242 void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop)
2243 {
2244 if (context->index_context) {
2245 StripAnim *sanim;
2246
2247 for (sanim = context->seq->anims.first; sanim; sanim = sanim->next) {
2248 IMB_close_anim_proxies(sanim->anim);
2249 }
2250
2251 for (sanim = context->orig_seq->anims.first; sanim; sanim = sanim->next) {
2252 IMB_close_anim_proxies(sanim->anim);
2253 }
2254
2255 IMB_anim_index_rebuild_finish(context->index_context, stop);
2256 }
2257
2258 seq_free_sequence_recurse(NULL, context->seq, true);
2259
2260 MEM_freeN(context);
2261 }
2262
BKE_sequencer_proxy_set(struct Sequence * seq,bool value)2263 void BKE_sequencer_proxy_set(struct Sequence *seq, bool value)
2264 {
2265 if (value) {
2266 seq->flag |= SEQ_USE_PROXY;
2267 if (seq->strip->proxy == NULL) {
2268 seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
2269 seq->strip->proxy->quality = 90;
2270 seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL;
2271 seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25;
2272 }
2273 }
2274 else {
2275 seq->flag &= ~SEQ_USE_PROXY;
2276 }
2277 }
2278
2279 /*********************** color balance *************************/
2280
calc_cb(StripColorBalance * cb_)2281 static StripColorBalance calc_cb(StripColorBalance *cb_)
2282 {
2283 StripColorBalance cb = *cb_;
2284 int c;
2285
2286 for (c = 0; c < 3; c++) {
2287 cb.lift[c] = 2.0f - cb.lift[c];
2288 }
2289
2290 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
2291 for (c = 0; c < 3; c++) {
2292 /* tweak to give more subtle results
2293 * values above 1.0 are scaled */
2294 if (cb.lift[c] > 1.0f) {
2295 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
2296 }
2297
2298 cb.lift[c] = 2.0f - cb.lift[c];
2299 }
2300 }
2301
2302 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
2303 for (c = 0; c < 3; c++) {
2304 if (cb.gain[c] != 0.0f) {
2305 cb.gain[c] = 1.0f / cb.gain[c];
2306 }
2307 else {
2308 cb.gain[c] = 1000000; /* should be enough :) */
2309 }
2310 }
2311 }
2312
2313 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
2314 for (c = 0; c < 3; c++) {
2315 if (cb.gamma[c] != 0.0f) {
2316 cb.gamma[c] = 1.0f / cb.gamma[c];
2317 }
2318 else {
2319 cb.gamma[c] = 1000000; /* should be enough :) */
2320 }
2321 }
2322 }
2323
2324 return cb;
2325 }
2326
2327 /* note: lift is actually 2-lift */
color_balance_fl(float in,const float lift,const float gain,const float gamma,const float mul)2328 MINLINE float color_balance_fl(
2329 float in, const float lift, const float gain, const float gamma, const float mul)
2330 {
2331 float x = (((in - 1.0f) * lift) + 1.0f) * gain;
2332
2333 /* prevent NaN */
2334 if (x < 0.f) {
2335 x = 0.f;
2336 }
2337
2338 x = powf(x, gamma) * mul;
2339 CLAMP(x, FLT_MIN, FLT_MAX);
2340 return x;
2341 }
2342
make_cb_table_float(float lift,float gain,float gamma,float * table,float mul)2343 static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul)
2344 {
2345 int y;
2346
2347 for (y = 0; y < 256; y++) {
2348 float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
2349
2350 table[y] = v;
2351 }
2352 }
2353
color_balance_byte_byte(StripColorBalance * cb_,unsigned char * rect,unsigned char * mask_rect,int width,int height,float mul)2354 static void color_balance_byte_byte(StripColorBalance *cb_,
2355 unsigned char *rect,
2356 unsigned char *mask_rect,
2357 int width,
2358 int height,
2359 float mul)
2360 {
2361 // unsigned char cb_tab[3][256];
2362 unsigned char *cp = rect;
2363 unsigned char *e = cp + width * 4 * height;
2364 unsigned char *m = mask_rect;
2365
2366 StripColorBalance cb = calc_cb(cb_);
2367
2368 while (cp < e) {
2369 float p[4];
2370 int c;
2371
2372 straight_uchar_to_premul_float(p, cp);
2373
2374 for (c = 0; c < 3; c++) {
2375 float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
2376
2377 if (m) {
2378 float m_normal = (float)m[c] / 255.0f;
2379
2380 p[c] = p[c] * (1.0f - m_normal) + t * m_normal;
2381 }
2382 else {
2383 p[c] = t;
2384 }
2385 }
2386
2387 premul_float_to_straight_uchar(cp, p);
2388
2389 cp += 4;
2390 if (m) {
2391 m += 4;
2392 }
2393 }
2394 }
2395
color_balance_byte_float(StripColorBalance * cb_,unsigned char * rect,float * rect_float,unsigned char * mask_rect,int width,int height,float mul)2396 static void color_balance_byte_float(StripColorBalance *cb_,
2397 unsigned char *rect,
2398 float *rect_float,
2399 unsigned char *mask_rect,
2400 int width,
2401 int height,
2402 float mul)
2403 {
2404 float cb_tab[4][256];
2405 int c, i;
2406 unsigned char *p = rect;
2407 unsigned char *e = p + width * 4 * height;
2408 unsigned char *m = mask_rect;
2409 float *o;
2410 StripColorBalance cb;
2411
2412 o = rect_float;
2413
2414 cb = calc_cb(cb_);
2415
2416 for (c = 0; c < 3; c++) {
2417 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
2418 }
2419
2420 for (i = 0; i < 256; i++) {
2421 cb_tab[3][i] = ((float)i) * (1.0f / 255.0f);
2422 }
2423
2424 while (p < e) {
2425 if (m) {
2426 const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
2427
2428 p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
2429 p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
2430 p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
2431
2432 m += 4;
2433 }
2434 else {
2435 o[0] = cb_tab[0][p[0]];
2436 o[1] = cb_tab[1][p[1]];
2437 o[2] = cb_tab[2][p[2]];
2438 }
2439
2440 o[3] = cb_tab[3][p[3]];
2441
2442 p += 4;
2443 o += 4;
2444 }
2445 }
2446
color_balance_float_float(StripColorBalance * cb_,float * rect_float,const float * mask_rect_float,int width,int height,float mul)2447 static void color_balance_float_float(StripColorBalance *cb_,
2448 float *rect_float,
2449 const float *mask_rect_float,
2450 int width,
2451 int height,
2452 float mul)
2453 {
2454 float *p = rect_float;
2455 const float *e = rect_float + width * 4 * height;
2456 const float *m = mask_rect_float;
2457 StripColorBalance cb = calc_cb(cb_);
2458
2459 while (p < e) {
2460 int c;
2461 for (c = 0; c < 3; c++) {
2462 float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
2463
2464 if (m) {
2465 p[c] = p[c] * (1.0f - m[c]) + t * m[c];
2466 }
2467 else {
2468 p[c] = t;
2469 }
2470 }
2471
2472 p += 4;
2473 if (m) {
2474 m += 4;
2475 }
2476 }
2477 }
2478
2479 typedef struct ColorBalanceInitData {
2480 StripColorBalance *cb;
2481 ImBuf *ibuf;
2482 float mul;
2483 ImBuf *mask;
2484 bool make_float;
2485 } ColorBalanceInitData;
2486
2487 typedef struct ColorBalanceThread {
2488 StripColorBalance *cb;
2489 float mul;
2490
2491 int width, height;
2492
2493 unsigned char *rect, *mask_rect;
2494 float *rect_float, *mask_rect_float;
2495
2496 bool make_float;
2497 } ColorBalanceThread;
2498
color_balance_init_handle(void * handle_v,int start_line,int tot_line,void * init_data_v)2499 static void color_balance_init_handle(void *handle_v,
2500 int start_line,
2501 int tot_line,
2502 void *init_data_v)
2503 {
2504 ColorBalanceThread *handle = (ColorBalanceThread *)handle_v;
2505 ColorBalanceInitData *init_data = (ColorBalanceInitData *)init_data_v;
2506 ImBuf *ibuf = init_data->ibuf;
2507 ImBuf *mask = init_data->mask;
2508
2509 int offset = 4 * start_line * ibuf->x;
2510
2511 memset(handle, 0, sizeof(ColorBalanceThread));
2512
2513 handle->cb = init_data->cb;
2514 handle->mul = init_data->mul;
2515 handle->width = ibuf->x;
2516 handle->height = tot_line;
2517 handle->make_float = init_data->make_float;
2518
2519 if (ibuf->rect) {
2520 handle->rect = (unsigned char *)ibuf->rect + offset;
2521 }
2522
2523 if (ibuf->rect_float) {
2524 handle->rect_float = ibuf->rect_float + offset;
2525 }
2526
2527 if (mask) {
2528 if (mask->rect) {
2529 handle->mask_rect = (unsigned char *)mask->rect + offset;
2530 }
2531
2532 if (mask->rect_float) {
2533 handle->mask_rect_float = mask->rect_float + offset;
2534 }
2535 }
2536 else {
2537 handle->mask_rect = NULL;
2538 handle->mask_rect_float = NULL;
2539 }
2540 }
2541
color_balance_do_thread(void * thread_data_v)2542 static void *color_balance_do_thread(void *thread_data_v)
2543 {
2544 ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v;
2545 StripColorBalance *cb = thread_data->cb;
2546 int width = thread_data->width, height = thread_data->height;
2547 unsigned char *rect = thread_data->rect;
2548 unsigned char *mask_rect = thread_data->mask_rect;
2549 float *rect_float = thread_data->rect_float;
2550 float *mask_rect_float = thread_data->mask_rect_float;
2551 float mul = thread_data->mul;
2552
2553 if (rect_float) {
2554 color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul);
2555 }
2556 else if (thread_data->make_float) {
2557 color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul);
2558 }
2559 else {
2560 color_balance_byte_byte(cb, rect, mask_rect, width, height, mul);
2561 }
2562
2563 return NULL;
2564 }
2565
2566 /**
2567 * \a cfra is offset by \a fra_offset only in case we are using a real mask.
2568 */
BKE_sequencer_render_mask_input(const SeqRenderData * context,int mask_input_type,Sequence * mask_sequence,Mask * mask_id,int cfra,int fra_offset,bool make_float)2569 ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context,
2570 int mask_input_type,
2571 Sequence *mask_sequence,
2572 Mask *mask_id,
2573 int cfra,
2574 int fra_offset,
2575 bool make_float)
2576 {
2577 ImBuf *mask_input = NULL;
2578
2579 if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) {
2580 if (mask_sequence) {
2581 SeqRenderState state;
2582 sequencer_state_init(&state);
2583
2584 mask_input = seq_render_strip(context, &state, mask_sequence, cfra);
2585
2586 if (make_float) {
2587 if (!mask_input->rect_float) {
2588 IMB_float_from_rect(mask_input);
2589 }
2590 }
2591 else {
2592 if (!mask_input->rect) {
2593 IMB_rect_from_float(mask_input);
2594 }
2595 }
2596 }
2597 }
2598 else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
2599 mask_input = seq_render_mask(context, mask_id, cfra - fra_offset, make_float);
2600 }
2601
2602 return mask_input;
2603 }
2604
BKE_sequencer_color_balance_apply(StripColorBalance * cb,ImBuf * ibuf,float mul,bool make_float,ImBuf * mask_input)2605 void BKE_sequencer_color_balance_apply(
2606 StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input)
2607 {
2608 ColorBalanceInitData init_data;
2609
2610 if (!ibuf->rect_float && make_float) {
2611 imb_addrectfloatImBuf(ibuf);
2612 }
2613
2614 init_data.cb = cb;
2615 init_data.ibuf = ibuf;
2616 init_data.mul = mul;
2617 init_data.make_float = make_float;
2618 init_data.mask = mask_input;
2619
2620 IMB_processor_apply_threaded(ibuf->y,
2621 sizeof(ColorBalanceThread),
2622 &init_data,
2623 color_balance_init_handle,
2624 color_balance_do_thread);
2625
2626 /* color balance either happens on float buffer or byte buffer, but never on both,
2627 * free byte buffer if there's float buffer since float buffer would be used for
2628 * color balance in favor of byte buffer
2629 */
2630 if (ibuf->rect_float && ibuf->rect) {
2631 imb_freerectImBuf(ibuf);
2632 }
2633 }
2634
2635 /*
2636 * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE
2637 *
2638 * Do all the things you can't really do afterwards using sequence effects
2639 * (read: before rescaling to render resolution has been done)
2640 *
2641 * Order is important!
2642 *
2643 * - Deinterlace
2644 * - Crop and transform in image source coordinate space
2645 * - Flip X + Flip Y (could be done afterwards, backward compatibility)
2646 * - Promote image to float data (affects pipeline operations afterwards)
2647 * - Color balance (is most efficient in the byte -> float
2648 * (future: half -> float should also work fine!)
2649 * case, if done on load, since we can use lookup tables)
2650 * - Premultiply
2651 */
2652
BKE_sequencer_input_have_to_preprocess(const SeqRenderData * context,Sequence * seq,float UNUSED (cfra))2653 bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
2654 Sequence *seq,
2655 float UNUSED(cfra))
2656 {
2657 float mul;
2658
2659 if (context && context->is_proxy_render) {
2660 return false;
2661 }
2662
2663 if (seq->flag &
2664 (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
2665 return true;
2666 }
2667
2668 mul = seq->mul;
2669
2670 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2671 mul *= seq->blend_opacity / 100.0f;
2672 }
2673
2674 if (mul != 1.0f) {
2675 return true;
2676 }
2677
2678 if (seq->sat != 1.0f) {
2679 return true;
2680 }
2681
2682 if (seq->modifiers.first) {
2683 return true;
2684 }
2685
2686 return false;
2687 }
2688
input_preprocess(const SeqRenderData * context,Sequence * seq,float cfra,ImBuf * ibuf,const bool is_proxy_image)2689 static ImBuf *input_preprocess(const SeqRenderData *context,
2690 Sequence *seq,
2691 float cfra,
2692 ImBuf *ibuf,
2693 const bool is_proxy_image)
2694 {
2695 Scene *scene = context->scene;
2696 float mul;
2697
2698 ibuf = IMB_makeSingleUser(ibuf);
2699
2700 if ((seq->flag & SEQ_FILTERY) && !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
2701 IMB_filtery(ibuf);
2702 }
2703
2704 if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
2705 StripCrop c = {0};
2706 StripTransform t = {0};
2707
2708 if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
2709 c = *seq->strip->crop;
2710 }
2711 if (seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
2712 t = *seq->strip->transform;
2713 }
2714
2715 /* Calculate scale factor for current image if needed. */
2716 double scale_factor, image_scale_factor = 1.0;
2717 if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
2718 scale_factor = image_scale_factor = (double)scene->r.size / 100;
2719 }
2720 else {
2721 scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
2722 if (!is_proxy_image) {
2723 image_scale_factor = scale_factor;
2724 }
2725 }
2726
2727 if (image_scale_factor != 1.0) {
2728 if (context->for_render) {
2729 IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
2730 }
2731 else {
2732 IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
2733 }
2734 }
2735
2736 t.xofs *= scale_factor;
2737 t.yofs *= scale_factor;
2738 c.left *= scale_factor;
2739 c.right *= scale_factor;
2740 c.top *= scale_factor;
2741 c.bottom *= scale_factor;
2742
2743 int sx, sy, dx, dy;
2744 sx = ibuf->x - c.left - c.right;
2745 sy = ibuf->y - c.top - c.bottom;
2746
2747 if (seq->flag & SEQ_USE_TRANSFORM) {
2748 dx = context->rectx;
2749 dy = context->recty;
2750 }
2751 else {
2752 dx = sx;
2753 dy = sy;
2754 }
2755
2756 if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
2757 t.yofs >= dy) {
2758 return NULL;
2759 }
2760
2761 ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
2762 IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
2763 sequencer_imbuf_assign_spaces(scene, i);
2764 IMB_metadata_copy(i, ibuf);
2765 IMB_freeImBuf(ibuf);
2766 ibuf = i;
2767 }
2768
2769 if (seq->flag & SEQ_FLIPX) {
2770 IMB_flipx(ibuf);
2771 }
2772
2773 if (seq->flag & SEQ_FLIPY) {
2774 IMB_flipy(ibuf);
2775 }
2776
2777 if (seq->sat != 1.0f) {
2778 IMB_saturation(ibuf, seq->sat);
2779 }
2780
2781 mul = seq->mul;
2782
2783 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2784 mul *= seq->blend_opacity / 100.0f;
2785 }
2786
2787 if (seq->flag & SEQ_MAKE_FLOAT) {
2788 if (!ibuf->rect_float) {
2789 BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf, true);
2790 }
2791
2792 if (ibuf->rect) {
2793 imb_freerectImBuf(ibuf);
2794 }
2795 }
2796
2797 if (mul != 1.0f) {
2798 multibuf(ibuf, mul);
2799 }
2800
2801 if (ibuf->x != context->rectx || ibuf->y != context->recty) {
2802 if (context->for_render) {
2803 IMB_scaleImBuf(ibuf, (short)context->rectx, (short)context->recty);
2804 }
2805 else {
2806 IMB_scalefastImBuf(ibuf, (short)context->rectx, (short)context->recty);
2807 }
2808 }
2809
2810 if (seq->modifiers.first) {
2811 ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra);
2812
2813 if (ibuf_new != ibuf) {
2814 IMB_metadata_copy(ibuf_new, ibuf);
2815 IMB_freeImBuf(ibuf);
2816 ibuf = ibuf_new;
2817 }
2818 }
2819
2820 return ibuf;
2821 }
2822
2823 /*********************** strip rendering functions *************************/
2824
2825 typedef struct RenderEffectInitData {
2826 struct SeqEffectHandle *sh;
2827 const SeqRenderData *context;
2828 Sequence *seq;
2829 float cfra, facf0, facf1;
2830 ImBuf *ibuf1, *ibuf2, *ibuf3;
2831
2832 ImBuf *out;
2833 } RenderEffectInitData;
2834
2835 typedef struct RenderEffectThread {
2836 struct SeqEffectHandle *sh;
2837 const SeqRenderData *context;
2838 Sequence *seq;
2839 float cfra, facf0, facf1;
2840 ImBuf *ibuf1, *ibuf2, *ibuf3;
2841
2842 ImBuf *out;
2843 int start_line, tot_line;
2844 } RenderEffectThread;
2845
render_effect_execute_init_handle(void * handle_v,int start_line,int tot_line,void * init_data_v)2846 static void render_effect_execute_init_handle(void *handle_v,
2847 int start_line,
2848 int tot_line,
2849 void *init_data_v)
2850 {
2851 RenderEffectThread *handle = (RenderEffectThread *)handle_v;
2852 RenderEffectInitData *init_data = (RenderEffectInitData *)init_data_v;
2853
2854 handle->sh = init_data->sh;
2855 handle->context = init_data->context;
2856 handle->seq = init_data->seq;
2857 handle->cfra = init_data->cfra;
2858 handle->facf0 = init_data->facf0;
2859 handle->facf1 = init_data->facf1;
2860 handle->ibuf1 = init_data->ibuf1;
2861 handle->ibuf2 = init_data->ibuf2;
2862 handle->ibuf3 = init_data->ibuf3;
2863 handle->out = init_data->out;
2864
2865 handle->start_line = start_line;
2866 handle->tot_line = tot_line;
2867 }
2868
render_effect_execute_do_thread(void * thread_data_v)2869 static void *render_effect_execute_do_thread(void *thread_data_v)
2870 {
2871 RenderEffectThread *thread_data = (RenderEffectThread *)thread_data_v;
2872
2873 thread_data->sh->execute_slice(thread_data->context,
2874 thread_data->seq,
2875 thread_data->cfra,
2876 thread_data->facf0,
2877 thread_data->facf1,
2878 thread_data->ibuf1,
2879 thread_data->ibuf2,
2880 thread_data->ibuf3,
2881 thread_data->start_line,
2882 thread_data->tot_line,
2883 thread_data->out);
2884
2885 return NULL;
2886 }
2887
BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle * sh,const SeqRenderData * context,Sequence * seq,float cfra,float facf0,float facf1,ImBuf * ibuf1,ImBuf * ibuf2,ImBuf * ibuf3)2888 ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh,
2889 const SeqRenderData *context,
2890 Sequence *seq,
2891 float cfra,
2892 float facf0,
2893 float facf1,
2894 ImBuf *ibuf1,
2895 ImBuf *ibuf2,
2896 ImBuf *ibuf3)
2897 {
2898 RenderEffectInitData init_data;
2899 ImBuf *out = sh->init_execution(context, ibuf1, ibuf2, ibuf3);
2900
2901 init_data.sh = sh;
2902 init_data.context = context;
2903 init_data.seq = seq;
2904 init_data.cfra = cfra;
2905 init_data.facf0 = facf0;
2906 init_data.facf1 = facf1;
2907 init_data.ibuf1 = ibuf1;
2908 init_data.ibuf2 = ibuf2;
2909 init_data.ibuf3 = ibuf3;
2910 init_data.out = out;
2911
2912 IMB_processor_apply_threaded(out->y,
2913 sizeof(RenderEffectThread),
2914 &init_data,
2915 render_effect_execute_init_handle,
2916 render_effect_execute_do_thread);
2917
2918 return out;
2919 }
2920
seq_render_effect_strip_impl(const SeqRenderData * context,SeqRenderState * state,Sequence * seq,float cfra)2921 static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context,
2922 SeqRenderState *state,
2923 Sequence *seq,
2924 float cfra)
2925 {
2926 Scene *scene = context->scene;
2927 float fac, facf;
2928 int early_out;
2929 int i;
2930 struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
2931 FCurve *fcu = NULL;
2932 ImBuf *ibuf[3];
2933 Sequence *input[3];
2934 ImBuf *out = NULL;
2935
2936 ibuf[0] = ibuf[1] = ibuf[2] = NULL;
2937
2938 input[0] = seq->seq1;
2939 input[1] = seq->seq2;
2940 input[2] = seq->seq3;
2941
2942 if (!sh.execute && !(sh.execute_slice && sh.init_execution)) {
2943 /* effect not supported in this version... */
2944 out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
2945 return out;
2946 }
2947
2948 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
2949 sh.get_default_fac(seq, cfra, &fac, &facf);
2950 facf = fac;
2951 }
2952 else {
2953 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
2954 if (fcu) {
2955 fac = facf = evaluate_fcurve(fcu, cfra);
2956 }
2957 else {
2958 fac = facf = seq->effect_fader;
2959 }
2960 }
2961
2962 early_out = sh.early_out(seq, fac, facf);
2963
2964 switch (early_out) {
2965 case EARLY_NO_INPUT:
2966 out = sh.execute(context, seq, cfra, fac, facf, NULL, NULL, NULL);
2967 break;
2968 case EARLY_DO_EFFECT:
2969 for (i = 0; i < 3; i++) {
2970 /* Speed effect requires time remapping of `cfra` for input(s). */
2971 if (input[0] && seq->type == SEQ_TYPE_SPEED) {
2972 float target_frame = BKE_sequencer_speed_effect_target_frame_get(context, seq, cfra, i);
2973 ibuf[i] = seq_render_strip(context, state, input[0], target_frame);
2974 }
2975 else { /* Other effects. */
2976 if (input[i]) {
2977 ibuf[i] = seq_render_strip(context, state, input[i], cfra);
2978 }
2979 }
2980 }
2981
2982 if (ibuf[0] && (ibuf[1] || BKE_sequence_effect_get_num_inputs(seq->type) == 1)) {
2983 if (sh.multithreaded) {
2984 out = BKE_sequencer_effect_execute_threaded(
2985 &sh, context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]);
2986 }
2987 else {
2988 out = sh.execute(context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]);
2989 }
2990 }
2991 break;
2992 case EARLY_USE_INPUT_1:
2993 if (input[0]) {
2994 out = seq_render_strip(context, state, input[0], cfra);
2995 }
2996 break;
2997 case EARLY_USE_INPUT_2:
2998 if (input[1]) {
2999 out = seq_render_strip(context, state, input[1], cfra);
3000 }
3001 break;
3002 }
3003
3004 for (i = 0; i < 3; i++) {
3005 IMB_freeImBuf(ibuf[i]);
3006 }
3007
3008 if (out == NULL) {
3009 out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
3010 }
3011
3012 return out;
3013 }
3014
3015 /**
3016 * Render individual view for multi-view or single (default view) for mono-view.
3017 */
seq_render_image_strip_view(const SeqRenderData * context,Sequence * seq,char * name,char * prefix,const char * ext,int view_id)3018 static ImBuf *seq_render_image_strip_view(const SeqRenderData *context,
3019 Sequence *seq,
3020 char *name,
3021 char *prefix,
3022 const char *ext,
3023 int view_id)
3024 {
3025
3026 ImBuf *ibuf = NULL;
3027
3028 int flag = IB_rect | IB_metadata;
3029 if (seq->alpha_mode == SEQ_ALPHA_PREMUL) {
3030 flag |= IB_alphamode_premul;
3031 }
3032
3033 if (prefix[0] == '\0') {
3034 ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name);
3035 }
3036 else {
3037 char str[FILE_MAX];
3038 BKE_scene_multiview_view_prefix_get(context->scene, name, prefix, &ext);
3039 seq_multiview_name(context->scene, view_id, prefix, ext, str, FILE_MAX);
3040 ibuf = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name);
3041 }
3042
3043 if (ibuf == NULL) {
3044 return NULL;
3045 }
3046
3047 /* We don't need both (speed reasons)! */
3048 if (ibuf->rect_float != NULL && ibuf->rect != NULL) {
3049 imb_freerectImBuf(ibuf);
3050 }
3051
3052 /* All sequencer color is done in SRGB space, linear gives odd cross-fades. */
3053 BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
3054
3055 return ibuf;
3056 }
3057
seq_image_strip_is_multiview_render(Scene * scene,Sequence * seq,int totfiles,char * name,char * r_prefix,const char * r_ext)3058 static bool seq_image_strip_is_multiview_render(
3059 Scene *scene, Sequence *seq, int totfiles, char *name, char *r_prefix, const char *r_ext)
3060 {
3061 if (totfiles > 1) {
3062 BKE_scene_multiview_view_prefix_get(scene, name, r_prefix, &r_ext);
3063 if (r_prefix[0] == '\0') {
3064 return false;
3065 }
3066 }
3067 else {
3068 r_prefix[0] = '\0';
3069 }
3070
3071 return (seq->flag & SEQ_USE_VIEWS) != 0 && (scene->r.scemode & R_MULTIVIEW) != 0;
3072 }
3073
seq_render_image_strip(const SeqRenderData * context,Sequence * seq,float UNUSED (nr),float cfra,bool * r_is_proxy_image)3074 static ImBuf *seq_render_image_strip(const SeqRenderData *context,
3075 Sequence *seq,
3076 float UNUSED(nr),
3077 float cfra,
3078 bool *r_is_proxy_image)
3079 {
3080 char name[FILE_MAX];
3081 const char *ext = NULL;
3082 char prefix[FILE_MAX];
3083 ImBuf *ibuf = NULL;
3084
3085 StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
3086 if (s_elem == NULL) {
3087 return NULL;
3088 }
3089
3090 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
3091 BLI_path_abs(name, BKE_main_blendfile_path_from_global());
3092
3093 /* Try to get a proxy image. */
3094 ibuf = seq_proxy_fetch(context, seq, cfra);
3095 if (ibuf != NULL) {
3096 s_elem->orig_width = ibuf->x;
3097 s_elem->orig_height = ibuf->y;
3098 *r_is_proxy_image = true;
3099 return ibuf;
3100 }
3101
3102 /* Proxy not found, render original. */
3103 const int totfiles = seq_num_files(context->scene, seq->views_format, true);
3104 bool is_multiview_render = seq_image_strip_is_multiview_render(
3105 context->scene, seq, totfiles, name, prefix, ext);
3106
3107 if (is_multiview_render) {
3108 int totviews = BKE_scene_multiview_num_views_get(&context->scene->r);
3109 ImBuf **ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
3110
3111 for (int view_id = 0; view_id < totfiles; view_id++) {
3112 ibufs_arr[view_id] = seq_render_image_strip_view(context, seq, name, prefix, ext, view_id);
3113 }
3114
3115 if (ibufs_arr[0] == NULL) {
3116 return NULL;
3117 }
3118
3119 if (seq->views_format == R_IMF_VIEWS_STEREO_3D) {
3120 IMB_ImBufFromStereo3d(seq->stereo3d_format, ibufs_arr[0], &ibufs_arr[0], &ibufs_arr[1]);
3121 }
3122
3123 for (int view_id = 0; view_id < totviews; view_id++) {
3124 SeqRenderData localcontext = *context;
3125 localcontext.view_id = view_id;
3126
3127 if (view_id != context->view_id) {
3128 ibufs_arr[view_id] = seq_render_preprocess_ibuf(
3129 &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false);
3130 }
3131 }
3132
3133 /* Return the original requested ImBuf. */
3134 ibuf = ibufs_arr[context->view_id];
3135
3136 /* Remove the others (decrease their refcount). */
3137 for (int view_id = 0; view_id < totviews; view_id++) {
3138 if (ibufs_arr[view_id] != ibuf) {
3139 IMB_freeImBuf(ibufs_arr[view_id]);
3140 }
3141 }
3142
3143 MEM_freeN(ibufs_arr);
3144 }
3145 else {
3146 ibuf = seq_render_image_strip_view(context, seq, name, prefix, ext, context->view_id);
3147 }
3148
3149 if (ibuf == NULL) {
3150 return NULL;
3151 }
3152
3153 s_elem->orig_width = ibuf->x;
3154 s_elem->orig_height = ibuf->y;
3155
3156 return ibuf;
3157 }
3158
seq_render_movie_strip_custom_file_proxy(const SeqRenderData * context,Sequence * seq,int cfra)3159 static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *context,
3160 Sequence *seq,
3161 int cfra)
3162 {
3163 char name[PROXY_MAXFILE];
3164 StripProxy *proxy = seq->strip->proxy;
3165
3166 if (proxy->anim == NULL) {
3167 if (seq_proxy_get_custom_file_fname(seq, name, context->view_id)) {
3168 proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name);
3169 }
3170 if (proxy->anim == NULL) {
3171 return NULL;
3172 }
3173 }
3174
3175 int frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs;
3176 return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
3177 }
3178
3179 /**
3180 * Render individual view for multi-view or single (default view) for mono-view.
3181 */
seq_render_movie_strip_view(const SeqRenderData * context,Sequence * seq,float nr,float cfra,StripAnim * sanim,bool * r_is_proxy_image)3182 static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context,
3183 Sequence *seq,
3184 float nr,
3185 float cfra,
3186 StripAnim *sanim,
3187 bool *r_is_proxy_image)
3188 {
3189 ImBuf *ibuf = NULL;
3190 IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
3191
3192 IMB_anim_set_preseek(sanim->anim, seq->anim_preseek);
3193
3194 if (seq_can_use_proxy(seq, psize)) {
3195 /* Try to get a proxy image.
3196 * Movie proxies are handled by ImBuf module with exception of `custom file` setting. */
3197 if (context->scene->ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE &&
3198 seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) {
3199 ibuf = seq_render_movie_strip_custom_file_proxy(context, seq, cfra);
3200 }
3201 else {
3202 ibuf = IMB_anim_absolute(sanim->anim,
3203 nr + seq->anim_startofs,
3204 seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
3205 psize);
3206 }
3207
3208 if (ibuf != NULL) {
3209 *r_is_proxy_image = true;
3210 }
3211 }
3212
3213 /* Fetching for requested proxy size failed, try fetching the original instead. */
3214 if (ibuf == NULL) {
3215 ibuf = IMB_anim_absolute(sanim->anim,
3216 nr + seq->anim_startofs,
3217 seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
3218 IMB_PROXY_NONE);
3219 }
3220 if (ibuf == NULL) {
3221 return NULL;
3222 }
3223
3224 BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
3225
3226 /* We don't need both (speed reasons)! */
3227 if (ibuf->rect_float != NULL && ibuf->rect != NULL) {
3228 imb_freerectImBuf(ibuf);
3229 }
3230
3231 return ibuf;
3232 }
3233
seq_render_movie_strip(const SeqRenderData * context,Sequence * seq,float nr,float cfra,bool * r_is_proxy_image)3234 static ImBuf *seq_render_movie_strip(
3235 const SeqRenderData *context, Sequence *seq, float nr, float cfra, bool *r_is_proxy_image)
3236 {
3237 /* Load all the videos. */
3238 seq_open_anim_file(context->scene, seq, false);
3239
3240 ImBuf *ibuf = NULL;
3241 StripAnim *sanim = seq->anims.first;
3242 const int totfiles = seq_num_files(context->scene, seq->views_format, true);
3243 bool is_multiview_render = (seq->flag & SEQ_USE_VIEWS) != 0 &&
3244 (context->scene->r.scemode & R_MULTIVIEW) != 0 &&
3245 BLI_listbase_count_at_most(&seq->anims, totfiles + 1) == totfiles;
3246
3247 if (is_multiview_render) {
3248 ImBuf **ibuf_arr;
3249 int totviews = BKE_scene_multiview_num_views_get(&context->scene->r);
3250 ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
3251 int ibuf_view_id;
3252
3253 for (ibuf_view_id = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, ibuf_view_id++) {
3254 if (sanim->anim) {
3255 ibuf_arr[ibuf_view_id] = seq_render_movie_strip_view(
3256 context, seq, nr, cfra, sanim, r_is_proxy_image);
3257 }
3258 }
3259
3260 if (seq->views_format == R_IMF_VIEWS_STEREO_3D) {
3261 if (ibuf_arr[0] == NULL) {
3262 /* Probably proxy hasn't been created yet. */
3263 MEM_freeN(ibuf_arr);
3264 return NULL;
3265 }
3266
3267 IMB_ImBufFromStereo3d(seq->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
3268 }
3269
3270 for (int view_id = 0; view_id < totviews; view_id++) {
3271 SeqRenderData localcontext = *context;
3272 localcontext.view_id = view_id;
3273
3274 if (view_id != context->view_id) {
3275 ibuf_arr[view_id] = seq_render_preprocess_ibuf(
3276 &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false);
3277 }
3278 }
3279
3280 /* Return the original requested ImBuf. */
3281 ibuf = ibuf_arr[context->view_id];
3282
3283 /* Remove the others (decrease their refcount). */
3284 for (int view_id = 0; view_id < totviews; view_id++) {
3285 if (ibuf_arr[view_id] != ibuf) {
3286 IMB_freeImBuf(ibuf_arr[view_id]);
3287 }
3288 }
3289
3290 MEM_freeN(ibuf_arr);
3291 }
3292 else {
3293 ibuf = seq_render_movie_strip_view(context, seq, nr, cfra, sanim, r_is_proxy_image);
3294 }
3295
3296 if (ibuf == NULL) {
3297 return NULL;
3298 }
3299
3300 seq->strip->stripdata->orig_width = ibuf->x;
3301 seq->strip->stripdata->orig_height = ibuf->y;
3302
3303 return ibuf;
3304 }
3305
seq_get_movieclip_ibuf(Sequence * seq,MovieClipUser user)3306 static ImBuf *seq_get_movieclip_ibuf(Sequence *seq, MovieClipUser user)
3307 {
3308 ImBuf *ibuf = NULL;
3309 float tloc[2], tscale, tangle;
3310 if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_STABILIZED) {
3311 ibuf = BKE_movieclip_get_stable_ibuf(seq->clip, &user, tloc, &tscale, &tangle, 0);
3312 }
3313 else {
3314 ibuf = BKE_movieclip_get_ibuf_flag(seq->clip, &user, seq->clip->flag, MOVIECLIP_CACHE_SKIP);
3315 }
3316 return ibuf;
3317 }
3318
seq_render_movieclip_strip(const SeqRenderData * context,Sequence * seq,float nr,bool * r_is_proxy_image)3319 static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context,
3320 Sequence *seq,
3321 float nr,
3322 bool *r_is_proxy_image)
3323 {
3324 ImBuf *ibuf = NULL;
3325 MovieClipUser user;
3326 IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
3327
3328 if (!seq->clip) {
3329 return NULL;
3330 }
3331
3332 memset(&user, 0, sizeof(MovieClipUser));
3333
3334 BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs + seq->clip->start_frame);
3335
3336 user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
3337 switch (psize) {
3338 case IMB_PROXY_NONE:
3339 user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
3340 break;
3341 case IMB_PROXY_100:
3342 user.render_size = MCLIP_PROXY_RENDER_SIZE_100;
3343 break;
3344 case IMB_PROXY_75:
3345 user.render_size = MCLIP_PROXY_RENDER_SIZE_75;
3346 break;
3347 case IMB_PROXY_50:
3348 user.render_size = MCLIP_PROXY_RENDER_SIZE_50;
3349 break;
3350 case IMB_PROXY_25:
3351 user.render_size = MCLIP_PROXY_RENDER_SIZE_25;
3352 break;
3353 }
3354
3355 if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_UNDISTORTED) {
3356 user.render_flag |= MCLIP_PROXY_RENDER_UNDISTORT;
3357 }
3358
3359 /* Try to get a proxy image. */
3360 ibuf = seq_get_movieclip_ibuf(seq, user);
3361
3362 if (ibuf != NULL && psize != IMB_PROXY_NONE) {
3363 *r_is_proxy_image = true;
3364 }
3365
3366 /* If proxy is not found, grab full-size frame. */
3367 if (ibuf == NULL) {
3368 user.render_flag |= MCLIP_PROXY_RENDER_USE_FALLBACK_RENDER;
3369 ibuf = seq_get_movieclip_ibuf(seq, user);
3370 }
3371
3372 return ibuf;
3373 }
3374
seq_render_mask(const SeqRenderData * context,Mask * mask,float nr,bool make_float)3375 static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float)
3376 {
3377 /* TODO - add option to rasterize to alpha imbuf? */
3378 ImBuf *ibuf = NULL;
3379 float *maskbuf;
3380 int i;
3381
3382 if (!mask) {
3383 return NULL;
3384 }
3385
3386 AnimData *adt;
3387 Mask *mask_temp;
3388 MaskRasterHandle *mr_handle;
3389
3390 mask_temp = (Mask *)BKE_id_copy_ex(
3391 NULL, &mask->id, NULL, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA);
3392
3393 BKE_mask_evaluate(mask_temp, mask->sfra + nr, true);
3394
3395 /* anim-data */
3396 adt = BKE_animdata_from_id(&mask->id);
3397 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
3398 context->depsgraph, mask->sfra + nr);
3399 BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
3400
3401 maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
3402
3403 mr_handle = BKE_maskrasterize_handle_new();
3404
3405 BKE_maskrasterize_handle_init(
3406 mr_handle, mask_temp, context->rectx, context->recty, true, true, true);
3407
3408 BKE_id_free(NULL, &mask_temp->id);
3409
3410 BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf);
3411
3412 BKE_maskrasterize_handle_free(mr_handle);
3413
3414 if (make_float) {
3415 /* pixels */
3416 const float *fp_src;
3417 float *fp_dst;
3418
3419 ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rectfloat);
3420
3421 fp_src = maskbuf;
3422 fp_dst = ibuf->rect_float;
3423 i = context->rectx * context->recty;
3424 while (--i) {
3425 fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src;
3426 fp_dst[3] = 1.0f;
3427
3428 fp_src += 1;
3429 fp_dst += 4;
3430 }
3431 }
3432 else {
3433 /* pixels */
3434 const float *fp_src;
3435 unsigned char *ub_dst;
3436
3437 ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
3438
3439 fp_src = maskbuf;
3440 ub_dst = (unsigned char *)ibuf->rect;
3441 i = context->rectx * context->recty;
3442 while (--i) {
3443 ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */
3444 ub_dst[3] = 255;
3445
3446 fp_src += 1;
3447 ub_dst += 4;
3448 }
3449 }
3450
3451 MEM_freeN(maskbuf);
3452
3453 return ibuf;
3454 }
3455
seq_render_mask_strip(const SeqRenderData * context,Sequence * seq,float nr)3456 static ImBuf *seq_render_mask_strip(const SeqRenderData *context, Sequence *seq, float nr)
3457 {
3458 bool make_float = (seq->flag & SEQ_MAKE_FLOAT) != 0;
3459
3460 return seq_render_mask(context, seq->mask, nr, make_float);
3461 }
3462
seq_render_scene_strip(const SeqRenderData * context,Sequence * seq,float nr,float cfra)3463 static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
3464 Sequence *seq,
3465 float nr,
3466 float cfra)
3467 {
3468 ImBuf *ibuf = NULL;
3469 double frame;
3470 Object *camera;
3471
3472 struct {
3473 int scemode;
3474 int cfra;
3475 float subframe;
3476
3477 #ifdef DURIAN_CAMERA_SWITCH
3478 int mode;
3479 #endif
3480 } orig_data;
3481
3482 /* Old info:
3483 * Hack! This function can be called from do_render_seq(), in that case
3484 * the seq->scene can already have a Render initialized with same name,
3485 * so we have to use a default name. (compositor uses scene name to
3486 * find render).
3487 * However, when called from within the UI (image preview in sequencer)
3488 * we do want to use scene Render, that way the render result is defined
3489 * for display in render/imagewindow
3490 *
3491 * Hmm, don't see, why we can't do that all the time,
3492 * and since G.is_rendering is uhm, gone... (Peter)
3493 */
3494
3495 /* New info:
3496 * Using the same name for the renders works just fine as the do_render_seq()
3497 * render is not used while the scene strips are rendered.
3498 *
3499 * However rendering from UI (through sequencer_preview_area_draw) can crash in
3500 * very many cases since other renders (material preview, an actual render etc.)
3501 * can be started while this sequence preview render is running. The only proper
3502 * solution is to make the sequencer preview render a proper job, which can be
3503 * stopped when needed. This would also give a nice progress bar for the preview
3504 * space so that users know there's something happening.
3505 *
3506 * As a result the active scene now only uses OpenGL rendering for the sequencer
3507 * preview. This is far from nice, but is the only way to prevent crashes at this
3508 * time.
3509 *
3510 * -jahka
3511 */
3512
3513 const bool is_rendering = G.is_rendering;
3514 const bool is_background = G.background;
3515 const bool do_seq_gl = is_rendering ? 0 : (context->scene->r.seq_prev_type) != OB_RENDER;
3516 bool have_comp = false;
3517 bool use_gpencil = true;
3518 /* do we need to re-evaluate the frame after rendering? */
3519 bool is_frame_update = false;
3520 Scene *scene;
3521 int is_thread_main = BLI_thread_is_main();
3522
3523 /* don't refer to seq->scene above this point!, it can be NULL */
3524 if (seq->scene == NULL) {
3525 return NULL;
3526 }
3527
3528 /* Prevent rendering scene recursively. */
3529 if (seq->scene == context->scene) {
3530 return NULL;
3531 }
3532
3533 scene = seq->scene;
3534 frame = (double)scene->r.sfra + (double)nr + (double)seq->anim_startofs;
3535
3536 #if 0 /* UNUSED */
3537 have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first);
3538 #endif
3539 have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
3540
3541 /* Get view layer for the strip. */
3542 ViewLayer *view_layer = BKE_view_layer_default_render(scene);
3543 /* Depsgraph will be NULL when doing rendering. */
3544 Depsgraph *depsgraph = NULL;
3545
3546 orig_data.scemode = scene->r.scemode;
3547 orig_data.cfra = scene->r.cfra;
3548 orig_data.subframe = scene->r.subframe;
3549 #ifdef DURIAN_CAMERA_SWITCH
3550 orig_data.mode = scene->r.mode;
3551 #endif
3552
3553 BKE_scene_frame_set(scene, frame);
3554
3555 if (seq->scene_camera) {
3556 camera = seq->scene_camera;
3557 }
3558 else {
3559 BKE_scene_camera_switch_update(scene);
3560 camera = scene->camera;
3561 }
3562
3563 if (have_comp == false && camera == NULL) {
3564 goto finally;
3565 }
3566
3567 if (seq->flag & SEQ_SCENE_NO_GPENCIL) {
3568 use_gpencil = false;
3569 }
3570
3571 /* prevent eternal loop */
3572 scene->r.scemode &= ~R_DOSEQ;
3573
3574 #ifdef DURIAN_CAMERA_SWITCH
3575 /* stooping to new low's in hackyness :( */
3576 scene->r.mode |= R_NO_CAMERA_SWITCH;
3577 #endif
3578
3579 is_frame_update = (orig_data.cfra != scene->r.cfra) || (orig_data.subframe != scene->r.subframe);
3580
3581 if ((sequencer_view3d_fn && do_seq_gl && camera) && is_thread_main) {
3582 char err_out[256] = "unknown";
3583 const int width = (scene->r.xsch * scene->r.size) / 100;
3584 const int height = (scene->r.ysch * scene->r.size) / 100;
3585 const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id);
3586
3587 unsigned int draw_flags = V3D_OFSDRAW_NONE;
3588 draw_flags |= (use_gpencil) ? V3D_OFSDRAW_SHOW_ANNOTATION : 0;
3589 draw_flags |= (context->scene->r.seq_flag & R_SEQ_OVERRIDE_SCENE_SETTINGS) ?
3590 V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS :
3591 0;
3592
3593 /* for old scene this can be uninitialized,
3594 * should probably be added to do_versions at some point if the functionality stays */
3595 if (context->scene->r.seq_prev_type == 0) {
3596 context->scene->r.seq_prev_type = 3 /* == OB_SOLID */;
3597 }
3598
3599 /* opengl offscreen render */
3600 depsgraph = BKE_scene_ensure_depsgraph(context->bmain, scene, view_layer);
3601 BKE_scene_graph_update_for_newframe(depsgraph);
3602 ibuf = sequencer_view3d_fn(
3603 /* set for OpenGL render (NULL when scrubbing) */
3604 depsgraph,
3605 scene,
3606 &context->scene->display.shading,
3607 context->scene->r.seq_prev_type,
3608 camera,
3609 width,
3610 height,
3611 IB_rect,
3612 draw_flags,
3613 scene->r.alphamode,
3614 viewname,
3615 context->gpu_offscreen,
3616 err_out);
3617 if (ibuf == NULL) {
3618 fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
3619 }
3620 }
3621 else {
3622 Render *re = RE_GetSceneRender(scene);
3623 const int totviews = BKE_scene_multiview_num_views_get(&scene->r);
3624 ImBuf **ibufs_arr;
3625
3626 ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs");
3627
3628 /* XXX: this if can be removed when sequence preview rendering uses the job system
3629 *
3630 * disable rendered preview for sequencer while rendering -- it's very much possible
3631 * that preview render will went into conflict with final render
3632 *
3633 * When rendering from command line renderer is called from main thread, in this
3634 * case it's always safe to render scene here
3635 */
3636 if (!is_thread_main || is_rendering == false || is_background || context->for_render) {
3637 if (re == NULL) {
3638 re = RE_NewSceneRender(scene);
3639 }
3640
3641 RE_RenderFrame(
3642 re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, false);
3643
3644 /* restore previous state after it was toggled on & off by RE_RenderFrame */
3645 G.is_rendering = is_rendering;
3646 }
3647
3648 for (int view_id = 0; view_id < totviews; view_id++) {
3649 SeqRenderData localcontext = *context;
3650 RenderResult rres;
3651
3652 localcontext.view_id = view_id;
3653
3654 RE_AcquireResultImage(re, &rres, view_id);
3655
3656 if (rres.rectf) {
3657 ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
3658 memcpy(ibufs_arr[view_id]->rect_float,
3659 rres.rectf,
3660 sizeof(float[4]) * rres.rectx * rres.recty);
3661
3662 if (rres.rectz) {
3663 addzbuffloatImBuf(ibufs_arr[view_id]);
3664 memcpy(
3665 ibufs_arr[view_id]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty);
3666 }
3667
3668 /* float buffers in the sequencer are not linear */
3669 BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[view_id], false);
3670 }
3671 else if (rres.rect32) {
3672 ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
3673 memcpy(ibufs_arr[view_id]->rect, rres.rect32, 4 * rres.rectx * rres.recty);
3674 }
3675
3676 if (view_id != context->view_id) {
3677 BKE_sequencer_cache_put(
3678 &localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id], 0, false);
3679 }
3680
3681 RE_ReleaseResultImage(re);
3682 }
3683
3684 /* return the original requested ImBuf */
3685 ibuf = ibufs_arr[context->view_id];
3686
3687 /* "remove" the others (decrease their refcount) */
3688 for (int view_id = 0; view_id < totviews; view_id++) {
3689 if (ibufs_arr[view_id] != ibuf) {
3690 IMB_freeImBuf(ibufs_arr[view_id]);
3691 }
3692 }
3693 MEM_freeN(ibufs_arr);
3694 }
3695
3696 finally:
3697 /* restore */
3698 scene->r.scemode = orig_data.scemode;
3699 scene->r.cfra = orig_data.cfra;
3700 scene->r.subframe = orig_data.subframe;
3701
3702 if (is_frame_update && (depsgraph != NULL)) {
3703 BKE_scene_graph_update_for_newframe(depsgraph);
3704 }
3705
3706 #ifdef DURIAN_CAMERA_SWITCH
3707 /* stooping to new low's in hackyness :( */
3708 scene->r.mode &= orig_data.mode | ~R_NO_CAMERA_SWITCH;
3709 #endif
3710
3711 return ibuf;
3712 }
3713
3714 /**
3715 * Used for meta-strips & scenes with #SEQ_SCENE_STRIPS flag set.
3716 */
do_render_strip_seqbase(const SeqRenderData * context,SeqRenderState * state,Sequence * seq,float nr)3717 static ImBuf *do_render_strip_seqbase(const SeqRenderData *context,
3718 SeqRenderState *state,
3719 Sequence *seq,
3720 float nr)
3721 {
3722 ImBuf *ibuf = NULL;
3723 ListBase *seqbase = NULL;
3724 int offset;
3725
3726 seqbase = BKE_sequence_seqbase_get(seq, &offset);
3727
3728 if (seqbase && !BLI_listbase_is_empty(seqbase)) {
3729
3730 if (seq->flag & SEQ_SCENE_STRIPS && seq->scene) {
3731 BKE_animsys_evaluate_all_animation(context->bmain, context->depsgraph, nr + offset);
3732 }
3733
3734 ibuf = seq_render_strip_stack(context,
3735 state,
3736 seqbase,
3737 /* scene strips don't have their start taken into account */
3738 nr + offset,
3739 0);
3740 }
3741
3742 return ibuf;
3743 }
3744
do_render_strip_uncached(const SeqRenderData * context,SeqRenderState * state,Sequence * seq,float cfra,bool * r_is_proxy_image)3745 static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
3746 SeqRenderState *state,
3747 Sequence *seq,
3748 float cfra,
3749 bool *r_is_proxy_image)
3750 {
3751 ImBuf *ibuf = NULL;
3752 float nr = BKE_sequencer_give_stripelem_index(seq, cfra);
3753 int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type;
3754 switch (type) {
3755 case SEQ_TYPE_META: {
3756 ibuf = do_render_strip_seqbase(context, state, seq, nr);
3757 break;
3758 }
3759
3760 case SEQ_TYPE_SCENE: {
3761 if (seq->flag & SEQ_SCENE_STRIPS) {
3762 if (seq->scene && (context->scene != seq->scene)) {
3763 /* recursive check */
3764 if (BLI_linklist_index(state->scene_parents, seq->scene) != -1) {
3765 break;
3766 }
3767 LinkNode scene_parent = {
3768 .next = state->scene_parents,
3769 .link = seq->scene,
3770 };
3771 state->scene_parents = &scene_parent;
3772 /* end check */
3773
3774 /* Use the Scene Seq's scene for the context when rendering the scene's sequences
3775 * (necessary for Multicam Selector among others).
3776 */
3777 SeqRenderData local_context = *context;
3778 local_context.scene = seq->scene;
3779 local_context.skip_cache = true;
3780
3781 ibuf = do_render_strip_seqbase(&local_context, state, seq, nr);
3782
3783 /* step back in the list */
3784 state->scene_parents = state->scene_parents->next;
3785 }
3786 }
3787 else {
3788 /* scene can be NULL after deletions */
3789 ibuf = seq_render_scene_strip(context, seq, nr, cfra);
3790 }
3791
3792 break;
3793 }
3794
3795 case SEQ_TYPE_EFFECT: {
3796 ibuf = seq_render_effect_strip_impl(context, state, seq, cfra);
3797 break;
3798 }
3799
3800 case SEQ_TYPE_IMAGE: {
3801 ibuf = seq_render_image_strip(context, seq, nr, cfra, r_is_proxy_image);
3802 break;
3803 }
3804
3805 case SEQ_TYPE_MOVIE: {
3806 ibuf = seq_render_movie_strip(context, seq, nr, cfra, r_is_proxy_image);
3807 break;
3808 }
3809
3810 case SEQ_TYPE_MOVIECLIP: {
3811 ibuf = seq_render_movieclip_strip(context, seq, nr, r_is_proxy_image);
3812
3813 if (ibuf) {
3814 /* duplicate frame so movie cache wouldn't be confused by sequencer's stuff */
3815 ImBuf *i = IMB_dupImBuf(ibuf);
3816 IMB_freeImBuf(ibuf);
3817 ibuf = i;
3818
3819 if (ibuf->rect_float) {
3820 BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
3821 }
3822 }
3823
3824 break;
3825 }
3826
3827 case SEQ_TYPE_MASK: {
3828 /* ibuf is always new */
3829 ibuf = seq_render_mask_strip(context, seq, nr);
3830 break;
3831 }
3832 }
3833
3834 if (ibuf) {
3835 sequencer_imbuf_assign_spaces(context->scene, ibuf);
3836 }
3837
3838 return ibuf;
3839 }
3840
3841 /* Estimate time spent by the program rendering the strip */
seq_estimate_render_cost_begin(void)3842 static clock_t seq_estimate_render_cost_begin(void)
3843 {
3844 return clock();
3845 }
3846
seq_estimate_render_cost_end(Scene * scene,clock_t begin)3847 static float seq_estimate_render_cost_end(Scene *scene, clock_t begin)
3848 {
3849 clock_t end = clock();
3850 float time_spent = (float)(end - begin);
3851 float time_max = (1.0f / scene->r.frs_sec) * CLOCKS_PER_SEC;
3852
3853 if (time_max != 0) {
3854 return time_spent / time_max;
3855 }
3856
3857 return 1;
3858 }
3859
seq_render_preprocess_ibuf(const SeqRenderData * context,Sequence * seq,ImBuf * ibuf,float cfra,clock_t begin,bool use_preprocess,const bool is_proxy_image)3860 static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
3861 Sequence *seq,
3862 ImBuf *ibuf,
3863 float cfra,
3864 clock_t begin,
3865 bool use_preprocess,
3866 const bool is_proxy_image)
3867 {
3868 if (context->is_proxy_render == false &&
3869 (ibuf->x != context->rectx || ibuf->y != context->recty)) {
3870 use_preprocess = true;
3871 }
3872
3873 if (use_preprocess) {
3874 float cost = seq_estimate_render_cost_end(context->scene, begin);
3875
3876 /* TODO(Richard): It should be possible to store in cache if image is proxy,
3877 * but it adds quite a bit of complexity. Since proxies are fast to read, I would
3878 * rather simplify existing code a bit. */
3879 if (!is_proxy_image) {
3880 BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
3881 }
3882
3883 /* Reset timer so we can get partial render time. */
3884 begin = seq_estimate_render_cost_begin();
3885 ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image);
3886 }
3887
3888 float cost = seq_estimate_render_cost_end(context->scene, begin);
3889 BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost, false);
3890 return ibuf;
3891 }
3892
seq_render_strip(const SeqRenderData * context,SeqRenderState * state,Sequence * seq,float cfra)3893 static ImBuf *seq_render_strip(const SeqRenderData *context,
3894 SeqRenderState *state,
3895 Sequence *seq,
3896 float cfra)
3897 {
3898 ImBuf *ibuf = NULL;
3899 bool use_preprocess = false;
3900 bool is_proxy_image = false;
3901
3902 clock_t begin = seq_estimate_render_cost_begin();
3903
3904 ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, false);
3905 if (ibuf != NULL) {
3906 return ibuf;
3907 }
3908
3909 ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_RAW, false);
3910 if (ibuf == NULL) {
3911 ibuf = do_render_strip_uncached(context, state, seq, cfra, &is_proxy_image);
3912 }
3913
3914 if (ibuf) {
3915 use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
3916 ibuf = seq_render_preprocess_ibuf(
3917 context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image);
3918 }
3919
3920 if (ibuf == NULL) {
3921 ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
3922 sequencer_imbuf_assign_spaces(context->scene, ibuf);
3923 }
3924
3925 return ibuf;
3926 }
3927
3928 /*********************** strip stack rendering functions *************************/
3929
seq_must_swap_input_in_blend_mode(Sequence * seq)3930 static bool seq_must_swap_input_in_blend_mode(Sequence *seq)
3931 {
3932 bool swap_input = false;
3933
3934 /* bad hack, to fix crazy input ordering of
3935 * those two effects */
3936
3937 if (ELEM(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) {
3938 swap_input = true;
3939 }
3940
3941 return swap_input;
3942 }
3943
seq_get_early_out_for_blend_mode(Sequence * seq)3944 static int seq_get_early_out_for_blend_mode(Sequence *seq)
3945 {
3946 struct SeqEffectHandle sh = BKE_sequence_get_blend(seq);
3947 float facf = seq->blend_opacity / 100.0f;
3948 int early_out = sh.early_out(seq, facf, facf);
3949
3950 if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) {
3951 return early_out;
3952 }
3953
3954 if (seq_must_swap_input_in_blend_mode(seq)) {
3955 if (early_out == EARLY_USE_INPUT_2) {
3956 return EARLY_USE_INPUT_1;
3957 }
3958 if (early_out == EARLY_USE_INPUT_1) {
3959 return EARLY_USE_INPUT_2;
3960 }
3961 }
3962 return early_out;
3963 }
3964
seq_render_strip_stack_apply_effect(const SeqRenderData * context,Sequence * seq,float cfra,ImBuf * ibuf1,ImBuf * ibuf2)3965 static ImBuf *seq_render_strip_stack_apply_effect(
3966 const SeqRenderData *context, Sequence *seq, float cfra, ImBuf *ibuf1, ImBuf *ibuf2)
3967 {
3968 ImBuf *out;
3969 struct SeqEffectHandle sh = BKE_sequence_get_blend(seq);
3970 float facf = seq->blend_opacity / 100.0f;
3971 int swap_input = seq_must_swap_input_in_blend_mode(seq);
3972
3973 if (swap_input) {
3974 if (sh.multithreaded) {
3975 out = BKE_sequencer_effect_execute_threaded(
3976 &sh, context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL);
3977 }
3978 else {
3979 out = sh.execute(context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL);
3980 }
3981 }
3982 else {
3983 if (sh.multithreaded) {
3984 out = BKE_sequencer_effect_execute_threaded(
3985 &sh, context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL);
3986 }
3987 else {
3988 out = sh.execute(context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL);
3989 }
3990 }
3991
3992 return out;
3993 }
3994
seq_render_strip_stack(const SeqRenderData * context,SeqRenderState * state,ListBase * seqbasep,float cfra,int chanshown)3995 static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
3996 SeqRenderState *state,
3997 ListBase *seqbasep,
3998 float cfra,
3999 int chanshown)
4000 {
4001 Sequence *seq_arr[MAXSEQ + 1];
4002 int count;
4003 int i;
4004 ImBuf *out = NULL;
4005 clock_t begin;
4006
4007 count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
4008
4009 if (count == 0) {
4010 return NULL;
4011 }
4012
4013 for (i = count - 1; i >= 0; i--) {
4014 int early_out;
4015 Sequence *seq = seq_arr[i];
4016
4017 out = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_COMPOSITE, false);
4018
4019 if (out) {
4020 break;
4021 }
4022 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
4023 out = seq_render_strip(context, state, seq, cfra);
4024 break;
4025 }
4026
4027 early_out = seq_get_early_out_for_blend_mode(seq);
4028
4029 switch (early_out) {
4030 case EARLY_NO_INPUT:
4031 case EARLY_USE_INPUT_2:
4032 out = seq_render_strip(context, state, seq, cfra);
4033 break;
4034 case EARLY_USE_INPUT_1:
4035 if (i == 0) {
4036 out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
4037 }
4038 break;
4039 case EARLY_DO_EFFECT:
4040 if (i == 0) {
4041 begin = seq_estimate_render_cost_begin();
4042
4043 ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
4044 ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra);
4045
4046 out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2);
4047
4048 float cost = seq_estimate_render_cost_end(context->scene, begin);
4049 BKE_sequencer_cache_put(
4050 context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false);
4051
4052 IMB_freeImBuf(ibuf1);
4053 IMB_freeImBuf(ibuf2);
4054 }
4055 break;
4056 }
4057 if (out) {
4058 break;
4059 }
4060 }
4061
4062 i++;
4063 for (; i < count; i++) {
4064 begin = seq_estimate_render_cost_begin();
4065 Sequence *seq = seq_arr[i];
4066
4067 if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
4068 ImBuf *ibuf1 = out;
4069 ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra);
4070
4071 out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2);
4072
4073 IMB_freeImBuf(ibuf1);
4074 IMB_freeImBuf(ibuf2);
4075 }
4076
4077 float cost = seq_estimate_render_cost_end(context->scene, begin);
4078 BKE_sequencer_cache_put(
4079 context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false);
4080 }
4081
4082 return out;
4083 }
4084
4085 /*
4086 * returned ImBuf is refed!
4087 * you have to free after usage!
4088 */
4089
BKE_sequencer_give_ibuf(const SeqRenderData * context,float cfra,int chanshown)4090 ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown)
4091 {
4092 Scene *scene = context->scene;
4093 Editing *ed = BKE_sequencer_editing_get(scene, false);
4094 ListBase *seqbasep;
4095
4096 if (ed == NULL) {
4097 return NULL;
4098 }
4099
4100 if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) {
4101 int count = BLI_listbase_count(&ed->metastack);
4102 count = max_ii(count + chanshown, 0);
4103 seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
4104 }
4105 else {
4106 seqbasep = ed->seqbasep;
4107 }
4108
4109 SeqRenderState state;
4110 sequencer_state_init(&state);
4111 ImBuf *out = NULL;
4112 Sequence *seq_arr[MAXSEQ + 1];
4113 int count;
4114
4115 count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, seq_arr);
4116
4117 if (count) {
4118 out = BKE_sequencer_cache_get(
4119 context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
4120 }
4121
4122 BKE_sequencer_cache_free_temp_cache(context->scene, context->task_id, cfra);
4123
4124 clock_t begin = seq_estimate_render_cost_begin();
4125 float cost = 0;
4126
4127 if (count && !out) {
4128 BLI_mutex_lock(&seq_render_mutex);
4129 out = seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown);
4130 cost = seq_estimate_render_cost_end(context->scene, begin);
4131
4132 if (context->is_prefetch_render) {
4133 BKE_sequencer_cache_put(
4134 context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false);
4135 }
4136 else {
4137 BKE_sequencer_cache_put_if_possible(
4138 context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false);
4139 }
4140 BLI_mutex_unlock(&seq_render_mutex);
4141 }
4142
4143 BKE_sequencer_prefetch_start(context, cfra, cost);
4144
4145 return out;
4146 }
4147
BKE_sequencer_give_ibuf_seqbase(const SeqRenderData * context,float cfra,int chan_shown,ListBase * seqbasep)4148 ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context,
4149 float cfra,
4150 int chan_shown,
4151 ListBase *seqbasep)
4152 {
4153 SeqRenderState state;
4154 sequencer_state_init(&state);
4155
4156 return seq_render_strip_stack(context, &state, seqbasep, cfra, chan_shown);
4157 }
4158
BKE_sequencer_give_ibuf_direct(const SeqRenderData * context,float cfra,Sequence * seq)4159 ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context, float cfra, Sequence *seq)
4160 {
4161 SeqRenderState state;
4162 sequencer_state_init(&state);
4163
4164 ImBuf *ibuf = seq_render_strip(context, &state, seq, cfra);
4165
4166 return ibuf;
4167 }
4168
4169 /* check whether sequence cur depends on seq */
BKE_sequence_check_depend(Sequence * seq,Sequence * cur)4170 bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
4171 {
4172 if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq) {
4173 return true;
4174 }
4175
4176 /* sequences are not intersecting in time, assume no dependency exists between them */
4177 if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp) {
4178 return false;
4179 }
4180
4181 /* checking sequence is below reference one, not dependent on it */
4182 if (cur->machine < seq->machine) {
4183 return false;
4184 }
4185
4186 /* sequence is not blending with lower machines, no dependency here occurs
4187 * check for non-effects only since effect could use lower machines as input
4188 */
4189 if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
4190 ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
4191 (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f))) {
4192 return false;
4193 }
4194
4195 return true;
4196 }
4197
sequence_do_invalidate_dependent(Scene * scene,Sequence * seq,ListBase * seqbase)4198 static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBase *seqbase)
4199 {
4200 Sequence *cur;
4201
4202 for (cur = seqbase->first; cur; cur = cur->next) {
4203 if (cur == seq) {
4204 continue;
4205 }
4206
4207 if (BKE_sequence_check_depend(seq, cur)) {
4208 /* Effect must be invalidated completely if they depend on invalidated seq. */
4209 if ((cur->type & SEQ_TYPE_EFFECT) != 0) {
4210 BKE_sequencer_cache_cleanup_sequence(scene, cur, seq, SEQ_CACHE_ALL_TYPES, false);
4211 }
4212 else {
4213 /* In case of alpha over for example only invalidate composite image */
4214 BKE_sequencer_cache_cleanup_sequence(
4215 scene, cur, seq, SEQ_CACHE_STORE_COMPOSITE | SEQ_CACHE_STORE_FINAL_OUT, false);
4216 }
4217 }
4218
4219 if (cur->seqbase.first) {
4220 sequence_do_invalidate_dependent(scene, seq, &cur->seqbase);
4221 }
4222 }
4223 }
4224
sequence_invalidate_cache(Scene * scene,Sequence * seq,bool invalidate_self,int invalidate_types)4225 static void sequence_invalidate_cache(Scene *scene,
4226 Sequence *seq,
4227 bool invalidate_self,
4228 int invalidate_types)
4229 {
4230 Editing *ed = scene->ed;
4231
4232 if (invalidate_self) {
4233 BKE_sequence_free_anim(seq);
4234 BKE_sequencer_cache_cleanup_sequence(scene, seq, seq, invalidate_types, false);
4235 }
4236
4237 if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) {
4238 BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
4239 }
4240
4241 sequence_do_invalidate_dependent(scene, seq, &ed->seqbase);
4242 DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
4243 BKE_sequencer_prefetch_stop(scene);
4244 }
4245
BKE_sequence_invalidate_cache_in_range(Scene * scene,Sequence * seq,Sequence * range_mask,int invalidate_types)4246 void BKE_sequence_invalidate_cache_in_range(Scene *scene,
4247 Sequence *seq,
4248 Sequence *range_mask,
4249 int invalidate_types)
4250 {
4251 BKE_sequencer_cache_cleanup_sequence(scene, seq, range_mask, invalidate_types, true);
4252 }
4253
BKE_sequence_invalidate_cache_raw(Scene * scene,Sequence * seq)4254 void BKE_sequence_invalidate_cache_raw(Scene *scene, Sequence *seq)
4255 {
4256 sequence_invalidate_cache(scene, seq, true, SEQ_CACHE_ALL_TYPES);
4257 }
4258
BKE_sequence_invalidate_cache_preprocessed(Scene * scene,Sequence * seq)4259 void BKE_sequence_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
4260 {
4261 sequence_invalidate_cache(scene,
4262 seq,
4263 true,
4264 SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE |
4265 SEQ_CACHE_STORE_FINAL_OUT);
4266 }
4267
BKE_sequence_invalidate_cache_composite(Scene * scene,Sequence * seq)4268 void BKE_sequence_invalidate_cache_composite(Scene *scene, Sequence *seq)
4269 {
4270 if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
4271 return;
4272 }
4273
4274 sequence_invalidate_cache(
4275 scene, seq, true, SEQ_CACHE_STORE_COMPOSITE | SEQ_CACHE_STORE_FINAL_OUT);
4276 }
4277
BKE_sequence_invalidate_dependent(Scene * scene,Sequence * seq)4278 void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq)
4279 {
4280 if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
4281 return;
4282 }
4283
4284 sequence_invalidate_cache(
4285 scene, seq, false, SEQ_CACHE_STORE_COMPOSITE | SEQ_CACHE_STORE_FINAL_OUT);
4286 }
4287
invalidate_scene_strips(Scene * scene,Scene * scene_target,ListBase * seqbase)4288 static void invalidate_scene_strips(Scene *scene, Scene *scene_target, ListBase *seqbase)
4289 {
4290 for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
4291 if (seq->scene == scene_target) {
4292 BKE_sequence_invalidate_cache_raw(scene, seq);
4293 }
4294
4295 if (seq->seqbase.first != NULL) {
4296 invalidate_scene_strips(scene, scene_target, &seq->seqbase);
4297 }
4298 }
4299 }
4300
BKE_sequence_invalidate_scene_strips(Main * bmain,Scene * scene_target)4301 void BKE_sequence_invalidate_scene_strips(Main *bmain, Scene *scene_target)
4302 {
4303 for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
4304 if (scene->ed != NULL) {
4305 invalidate_scene_strips(scene, scene_target, &scene->ed->seqbase);
4306 }
4307 }
4308 }
4309
invalidate_movieclip_strips(Scene * scene,MovieClip * clip_target,ListBase * seqbase)4310 static void invalidate_movieclip_strips(Scene *scene, MovieClip *clip_target, ListBase *seqbase)
4311 {
4312 for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
4313 if (seq->clip == clip_target) {
4314 BKE_sequence_invalidate_cache_raw(scene, seq);
4315 }
4316
4317 if (seq->seqbase.first != NULL) {
4318 invalidate_movieclip_strips(scene, clip_target, &seq->seqbase);
4319 }
4320 }
4321 }
4322
BKE_sequence_invalidate_movieclip_strips(Main * bmain,MovieClip * clip_target)4323 void BKE_sequence_invalidate_movieclip_strips(Main *bmain, MovieClip *clip_target)
4324 {
4325 for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
4326 if (scene->ed != NULL) {
4327 invalidate_movieclip_strips(scene, clip_target, &scene->ed->seqbase);
4328 }
4329 }
4330 }
4331
BKE_sequencer_free_imbuf(Scene * scene,ListBase * seqbase,bool for_render)4332 void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
4333 {
4334 if (scene->ed == NULL) {
4335 return;
4336 }
4337
4338 Sequence *seq;
4339
4340 BKE_sequencer_cache_cleanup(scene);
4341 BKE_sequencer_prefetch_stop(scene);
4342
4343 for (seq = seqbase->first; seq; seq = seq->next) {
4344 if (for_render && CFRA >= seq->startdisp && CFRA <= seq->enddisp) {
4345 continue;
4346 }
4347
4348 if (seq->strip) {
4349 if (seq->type == SEQ_TYPE_MOVIE) {
4350 BKE_sequence_free_anim(seq);
4351 }
4352 if (seq->type == SEQ_TYPE_SPEED) {
4353 BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
4354 }
4355 }
4356 if (seq->type == SEQ_TYPE_META) {
4357 BKE_sequencer_free_imbuf(scene, &seq->seqbase, for_render);
4358 }
4359 if (seq->type == SEQ_TYPE_SCENE) {
4360 /* FIXME: recurse downwards,
4361 * but do recurse protection somehow! */
4362 }
4363 }
4364 }
4365
update_changed_seq_recurs(Scene * scene,Sequence * seq,Sequence * changed_seq,int len_change,int ibuf_change)4366 static bool update_changed_seq_recurs(
4367 Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
4368 {
4369 Sequence *subseq;
4370 bool free_imbuf = false;
4371
4372 /* recurse downwards to see if this seq depends on the changed seq */
4373
4374 if (seq == NULL) {
4375 return false;
4376 }
4377
4378 if (seq == changed_seq) {
4379 free_imbuf = true;
4380 }
4381
4382 for (subseq = seq->seqbase.first; subseq; subseq = subseq->next) {
4383 if (update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change)) {
4384 free_imbuf = true;
4385 }
4386 }
4387
4388 if (seq->seq1) {
4389 if (update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change)) {
4390 free_imbuf = true;
4391 }
4392 }
4393 if (seq->seq2 && (seq->seq2 != seq->seq1)) {
4394 if (update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change)) {
4395 free_imbuf = true;
4396 }
4397 }
4398 if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) {
4399 if (update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change)) {
4400 free_imbuf = true;
4401 }
4402 }
4403
4404 if (free_imbuf) {
4405 if (ibuf_change) {
4406 if (seq->type == SEQ_TYPE_MOVIE) {
4407 BKE_sequence_free_anim(seq);
4408 }
4409 else if (seq->type == SEQ_TYPE_SPEED) {
4410 BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
4411 }
4412 }
4413
4414 if (len_change) {
4415 BKE_sequence_calc(scene, seq);
4416 }
4417 }
4418
4419 return free_imbuf;
4420 }
4421
BKE_sequencer_update_changed_seq_and_deps(Scene * scene,Sequence * changed_seq,int len_change,int ibuf_change)4422 void BKE_sequencer_update_changed_seq_and_deps(Scene *scene,
4423 Sequence *changed_seq,
4424 int len_change,
4425 int ibuf_change)
4426 {
4427 Editing *ed = BKE_sequencer_editing_get(scene, false);
4428 Sequence *seq;
4429
4430 if (ed == NULL) {
4431 return;
4432 }
4433
4434 for (seq = ed->seqbase.first; seq; seq = seq->next) {
4435 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
4436 }
4437 }
4438
4439 /* seq funcs's for transforming internally
4440 * notice the difference between start/end and left/right.
4441 *
4442 * left and right are the bounds at which the sequence is rendered,
4443 * start and end are from the start and fixed length of the sequence.
4444 */
seq_tx_get_start(Sequence * seq)4445 static int seq_tx_get_start(Sequence *seq)
4446 {
4447 return seq->start;
4448 }
seq_tx_get_end(Sequence * seq)4449 static int seq_tx_get_end(Sequence *seq)
4450 {
4451 return seq->start + seq->len;
4452 }
4453
BKE_sequence_tx_get_final_left(Sequence * seq,bool metaclip)4454 int BKE_sequence_tx_get_final_left(Sequence *seq, bool metaclip)
4455 {
4456 if (metaclip && seq->tmp) {
4457 /* return the range clipped by the parents range */
4458 return max_ii(BKE_sequence_tx_get_final_left(seq, false),
4459 BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, true));
4460 }
4461
4462 return (seq->start - seq->startstill) + seq->startofs;
4463 }
BKE_sequence_tx_get_final_right(Sequence * seq,bool metaclip)4464 int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip)
4465 {
4466 if (metaclip && seq->tmp) {
4467 /* return the range clipped by the parents range */
4468 return min_ii(BKE_sequence_tx_get_final_right(seq, false),
4469 BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, true));
4470 }
4471
4472 return ((seq->start + seq->len) + seq->endstill) - seq->endofs;
4473 }
4474
BKE_sequence_tx_set_final_left(Sequence * seq,int val)4475 void BKE_sequence_tx_set_final_left(Sequence *seq, int val)
4476 {
4477 if (val < (seq)->start) {
4478 seq->startstill = abs(val - (seq)->start);
4479 seq->startofs = 0;
4480 }
4481 else {
4482 seq->startofs = abs(val - (seq)->start);
4483 seq->startstill = 0;
4484 }
4485 }
4486
BKE_sequence_tx_set_final_right(Sequence * seq,int val)4487 void BKE_sequence_tx_set_final_right(Sequence *seq, int val)
4488 {
4489 if (val > (seq)->start + (seq)->len) {
4490 seq->endstill = abs(val - (seq->start + (seq)->len));
4491 seq->endofs = 0;
4492 }
4493 else {
4494 seq->endofs = abs(val - ((seq)->start + (seq)->len));
4495 seq->endstill = 0;
4496 }
4497 }
4498
4499 /* used so we can do a quick check for single image seq
4500 * since they work a bit differently to normal image seq's (during transform) */
BKE_sequence_single_check(Sequence * seq)4501 bool BKE_sequence_single_check(Sequence *seq)
4502 {
4503 return ((seq->len == 1) &&
4504 (seq->type == SEQ_TYPE_IMAGE ||
4505 ((seq->type & SEQ_TYPE_EFFECT) && BKE_sequence_effect_get_num_inputs(seq->type) == 0)));
4506 }
4507
4508 /* check if the selected seq's reference unselected seq's */
BKE_sequence_base_isolated_sel_check(ListBase * seqbase)4509 bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
4510 {
4511 Sequence *seq;
4512 /* is there more than 1 select */
4513 bool ok = false;
4514
4515 for (seq = seqbase->first; seq; seq = seq->next) {
4516 if (seq->flag & SELECT) {
4517 ok = true;
4518 break;
4519 }
4520 }
4521
4522 if (ok == false) {
4523 return false;
4524 }
4525
4526 /* test relationships */
4527 for (seq = seqbase->first; seq; seq = seq->next) {
4528 if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
4529 continue;
4530 }
4531
4532 if (seq->flag & SELECT) {
4533 if ((seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
4534 (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
4535 (seq->seq3 && (seq->seq3->flag & SELECT) == 0)) {
4536 return false;
4537 }
4538 }
4539 else {
4540 if ((seq->seq1 && (seq->seq1->flag & SELECT)) || (seq->seq2 && (seq->seq2->flag & SELECT)) ||
4541 (seq->seq3 && (seq->seq3->flag & SELECT))) {
4542 return false;
4543 }
4544 }
4545 }
4546
4547 return true;
4548 }
4549
4550 /* use to impose limits when dragging/extending - so impossible situations don't happen
4551 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
BKE_sequence_tx_handle_xlimits(Sequence * seq,int leftflag,int rightflag)4552 void BKE_sequence_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
4553 {
4554 if (leftflag) {
4555 if (BKE_sequence_tx_get_final_left(seq, false) >=
4556 BKE_sequence_tx_get_final_right(seq, false)) {
4557 BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_right(seq, false) - 1);
4558 }
4559
4560 if (BKE_sequence_single_check(seq) == 0) {
4561 if (BKE_sequence_tx_get_final_left(seq, false) >= seq_tx_get_end(seq)) {
4562 BKE_sequence_tx_set_final_left(seq, seq_tx_get_end(seq) - 1);
4563 }
4564
4565 /* doesn't work now - TODO */
4566 #if 0
4567 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
4568 int ofs;
4569 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
4570 seq->start -= ofs;
4571 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs);
4572 }
4573 #endif
4574 }
4575 }
4576
4577 if (rightflag) {
4578 if (BKE_sequence_tx_get_final_right(seq, false) <=
4579 BKE_sequence_tx_get_final_left(seq, false)) {
4580 BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_left(seq, false) + 1);
4581 }
4582
4583 if (BKE_sequence_single_check(seq) == 0) {
4584 if (BKE_sequence_tx_get_final_right(seq, false) <= seq_tx_get_start(seq)) {
4585 BKE_sequence_tx_set_final_right(seq, seq_tx_get_start(seq) + 1);
4586 }
4587 }
4588 }
4589
4590 /* sounds cannot be extended past their endpoints */
4591 if (seq->type == SEQ_TYPE_SOUND_RAM) {
4592 seq->startstill = 0;
4593 seq->endstill = 0;
4594 }
4595 }
4596
BKE_sequence_single_fix(Sequence * seq)4597 void BKE_sequence_single_fix(Sequence *seq)
4598 {
4599 int left, start, offset;
4600 if (!BKE_sequence_single_check(seq)) {
4601 return;
4602 }
4603
4604 /* make sure the image is always at the start since there is only one,
4605 * adjusting its start should be ok */
4606 left = BKE_sequence_tx_get_final_left(seq, false);
4607 start = seq->start;
4608 if (start != left) {
4609 offset = left - start;
4610 BKE_sequence_tx_set_final_left(seq, BKE_sequence_tx_get_final_left(seq, false) - offset);
4611 BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_right(seq, false) - offset);
4612 seq->start += offset;
4613 }
4614 }
4615
BKE_sequence_tx_test(Sequence * seq)4616 bool BKE_sequence_tx_test(Sequence *seq)
4617 {
4618 return !(seq->type & SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0);
4619 }
4620
4621 /**
4622 * Return \a true if given \a seq needs a complete cleanup of its cache when it is transformed.
4623 *
4624 * Some (effect) strip types need a complete recache of themselves when they are transformed,
4625 * because they do not 'contain' anything and do not have any explicit relations to other strips.
4626 */
BKE_sequence_tx_fullupdate_test(Sequence * seq)4627 bool BKE_sequence_tx_fullupdate_test(Sequence *seq)
4628 {
4629 return BKE_sequence_tx_test(seq) && ELEM(seq->type, SEQ_TYPE_ADJUSTMENT, SEQ_TYPE_MULTICAM);
4630 }
4631
seq_overlap(Sequence * seq1,Sequence * seq2)4632 static bool seq_overlap(Sequence *seq1, Sequence *seq2)
4633 {
4634 return (seq1 != seq2 && seq1->machine == seq2->machine &&
4635 ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0);
4636 }
4637
BKE_sequence_test_overlap(ListBase * seqbasep,Sequence * test)4638 bool BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test)
4639 {
4640 Sequence *seq;
4641
4642 seq = seqbasep->first;
4643 while (seq) {
4644 if (seq_overlap(test, seq)) {
4645 return true;
4646 }
4647
4648 seq = seq->next;
4649 }
4650 return false;
4651 }
4652
BKE_sequence_translate(Scene * evil_scene,Sequence * seq,int delta)4653 void BKE_sequence_translate(Scene *evil_scene, Sequence *seq, int delta)
4654 {
4655 if (delta == 0) {
4656 return;
4657 }
4658
4659 BKE_sequencer_offset_animdata(evil_scene, seq, delta);
4660 seq->start += delta;
4661
4662 if (seq->type == SEQ_TYPE_META) {
4663 Sequence *seq_child;
4664 for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) {
4665 BKE_sequence_translate(evil_scene, seq_child, delta);
4666 }
4667 }
4668
4669 BKE_sequence_calc_disp(evil_scene, seq);
4670 }
4671
BKE_sequence_sound_init(Scene * scene,Sequence * seq)4672 void BKE_sequence_sound_init(Scene *scene, Sequence *seq)
4673 {
4674 if (seq->type == SEQ_TYPE_META) {
4675 Sequence *seq_child;
4676 for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) {
4677 BKE_sequence_sound_init(scene, seq_child);
4678 }
4679 }
4680 else {
4681 if (seq->sound) {
4682 seq->scene_sound = BKE_sound_add_scene_sound_defaults(scene, seq);
4683 }
4684 if (seq->scene) {
4685 seq->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene, seq);
4686 }
4687 }
4688 }
4689
BKE_sequencer_foreground_frame_get(const Scene * scene,int frame)4690 const Sequence *BKE_sequencer_foreground_frame_get(const Scene *scene, int frame)
4691 {
4692 const Editing *ed = scene->ed;
4693 const Sequence *seq, *best_seq = NULL;
4694 int best_machine = -1;
4695
4696 if (!ed) {
4697 return NULL;
4698 }
4699
4700 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
4701 if (seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame) {
4702 continue;
4703 }
4704 /* Only use strips that generate an image, not ones that combine
4705 * other strips or apply some effect. */
4706 if (ELEM(seq->type,
4707 SEQ_TYPE_IMAGE,
4708 SEQ_TYPE_META,
4709 SEQ_TYPE_SCENE,
4710 SEQ_TYPE_MOVIE,
4711 SEQ_TYPE_COLOR,
4712 SEQ_TYPE_TEXT)) {
4713 if (seq->machine > best_machine) {
4714 best_seq = seq;
4715 best_machine = seq->machine;
4716 }
4717 }
4718 }
4719 return best_seq;
4720 }
4721
4722 /* return 0 if there weren't enough space */
BKE_sequence_base_shuffle_ex(ListBase * seqbasep,Sequence * test,Scene * evil_scene,int channel_delta)4723 bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep,
4724 Sequence *test,
4725 Scene *evil_scene,
4726 int channel_delta)
4727 {
4728 const int orig_machine = test->machine;
4729 BLI_assert(ELEM(channel_delta, -1, 1));
4730
4731 test->machine += channel_delta;
4732 BKE_sequence_calc(evil_scene, test);
4733 while (BKE_sequence_test_overlap(seqbasep, test)) {
4734 if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine < 1)) {
4735 break;
4736 }
4737
4738 test->machine += channel_delta;
4739 BKE_sequence_calc(
4740 evil_scene,
4741 test); // XXX - I don't think this is needed since were only moving vertically, Campbell.
4742 }
4743
4744 if ((test->machine < 1) || (test->machine > MAXSEQ)) {
4745 /* Blender 2.4x would remove the strip.
4746 * nicer to move it to the end */
4747
4748 Sequence *seq;
4749 int new_frame = test->enddisp;
4750
4751 for (seq = seqbasep->first; seq; seq = seq->next) {
4752 if (seq->machine == orig_machine) {
4753 new_frame = max_ii(new_frame, seq->enddisp);
4754 }
4755 }
4756
4757 test->machine = orig_machine;
4758 new_frame = new_frame + (test->start - test->startdisp); /* adjust by the startdisp */
4759 BKE_sequence_translate(evil_scene, test, new_frame - test->start);
4760
4761 BKE_sequence_calc(evil_scene, test);
4762 return false;
4763 }
4764
4765 return true;
4766 }
4767
BKE_sequence_base_shuffle(ListBase * seqbasep,Sequence * test,Scene * evil_scene)4768 bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
4769 {
4770 return BKE_sequence_base_shuffle_ex(seqbasep, test, evil_scene, 1);
4771 }
4772
shuffle_seq_time_offset_test(ListBase * seqbasep,char dir)4773 static int shuffle_seq_time_offset_test(ListBase *seqbasep, char dir)
4774 {
4775 int offset = 0;
4776 Sequence *seq, *seq_other;
4777
4778 for (seq = seqbasep->first; seq; seq = seq->next) {
4779 if (seq->tmp) {
4780 for (seq_other = seqbasep->first; seq_other; seq_other = seq_other->next) {
4781 if (!seq_other->tmp && seq_overlap(seq, seq_other)) {
4782 if (dir == 'L') {
4783 offset = min_ii(offset, seq_other->startdisp - seq->enddisp);
4784 }
4785 else {
4786 offset = max_ii(offset, seq_other->enddisp - seq->startdisp);
4787 }
4788 }
4789 }
4790 }
4791 }
4792 return offset;
4793 }
4794
shuffle_seq_time_offset(Scene * scene,ListBase * seqbasep,char dir)4795 static int shuffle_seq_time_offset(Scene *scene, ListBase *seqbasep, char dir)
4796 {
4797 int ofs = 0;
4798 int tot_ofs = 0;
4799 Sequence *seq;
4800 while ((ofs = shuffle_seq_time_offset_test(seqbasep, dir))) {
4801 for (seq = seqbasep->first; seq; seq = seq->next) {
4802 if (seq->tmp) {
4803 /* seq_test_overlap only tests display values */
4804 seq->startdisp += ofs;
4805 seq->enddisp += ofs;
4806 }
4807 }
4808
4809 tot_ofs += ofs;
4810 }
4811
4812 for (seq = seqbasep->first; seq; seq = seq->next) {
4813 if (seq->tmp) {
4814 BKE_sequence_calc_disp(scene, seq); /* corrects dummy startdisp/enddisp values */
4815 }
4816 }
4817
4818 return tot_ofs;
4819 }
4820
BKE_sequence_base_shuffle_time(ListBase * seqbasep,Scene * evil_scene,ListBase * markers,const bool use_sync_markers)4821 bool BKE_sequence_base_shuffle_time(ListBase *seqbasep,
4822 Scene *evil_scene,
4823 ListBase *markers,
4824 const bool use_sync_markers)
4825 {
4826 /* note: seq->tmp is used to tag strips to move */
4827
4828 Sequence *seq;
4829
4830 int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L');
4831 int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R');
4832 int offset = (-offset_l < offset_r) ? offset_l : offset_r;
4833
4834 if (offset) {
4835 for (seq = seqbasep->first; seq; seq = seq->next) {
4836 if (seq->tmp) {
4837 BKE_sequence_translate(evil_scene, seq, offset);
4838 seq->flag &= ~SEQ_OVERLAP;
4839 }
4840 }
4841
4842 if (use_sync_markers && !(evil_scene->toolsettings->lock_markers) && (markers != NULL)) {
4843 TimeMarker *marker;
4844 /* affect selected markers - it's unlikely that we will want to affect all in this way? */
4845 for (marker = markers->first; marker; marker = marker->next) {
4846 if (marker->flag & SELECT) {
4847 marker->frame += offset;
4848 }
4849 }
4850 }
4851 }
4852
4853 return offset ? false : true;
4854 }
4855
4856 /* Unlike _update_sound_ funcs, these ones take info from audaspace to update sequence length! */
4857 #ifdef WITH_AUDASPACE
sequencer_refresh_sound_length_recursive(Main * bmain,Scene * scene,ListBase * seqbase)4858 static bool sequencer_refresh_sound_length_recursive(Main *bmain, Scene *scene, ListBase *seqbase)
4859 {
4860 Sequence *seq;
4861 bool changed = false;
4862
4863 for (seq = seqbase->first; seq; seq = seq->next) {
4864 if (seq->type == SEQ_TYPE_META) {
4865 if (sequencer_refresh_sound_length_recursive(bmain, scene, &seq->seqbase)) {
4866 BKE_sequence_calc(scene, seq);
4867 changed = true;
4868 }
4869 }
4870 else if (seq->type == SEQ_TYPE_SOUND_RAM && seq->sound) {
4871 const float length = BKE_sound_get_length(bmain, seq->sound);
4872 int old = seq->len;
4873 float fac;
4874
4875 seq->len = (int)ceil((double)length * FPS);
4876 fac = (float)seq->len / (float)old;
4877 old = seq->startofs;
4878 seq->startofs *= fac;
4879 seq->endofs *= fac;
4880 seq->start += (old - seq->startofs); /* So that visual/"real" start frame does not change! */
4881
4882 BKE_sequence_calc(scene, seq);
4883 changed = true;
4884 }
4885 }
4886 return changed;
4887 }
4888 #endif
4889
BKE_sequencer_refresh_sound_length(Main * bmain,Scene * scene)4890 void BKE_sequencer_refresh_sound_length(Main *bmain, Scene *scene)
4891 {
4892 #ifdef WITH_AUDASPACE
4893 if (scene->ed) {
4894 sequencer_refresh_sound_length_recursive(bmain, scene, &scene->ed->seqbase);
4895 }
4896 #else
4897 UNUSED_VARS(bmain, scene);
4898 #endif
4899 }
4900
BKE_sequencer_update_sound_bounds_all(Scene * scene)4901 void BKE_sequencer_update_sound_bounds_all(Scene *scene)
4902 {
4903 Editing *ed = scene->ed;
4904
4905 if (ed) {
4906 Sequence *seq;
4907
4908 for (seq = ed->seqbase.first; seq; seq = seq->next) {
4909 if (seq->type == SEQ_TYPE_META) {
4910 seq_update_sound_bounds_recursive(scene, seq);
4911 }
4912 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
4913 BKE_sequencer_update_sound_bounds(scene, seq);
4914 }
4915 }
4916 }
4917 }
4918
BKE_sequencer_update_sound_bounds(Scene * scene,Sequence * seq)4919 void BKE_sequencer_update_sound_bounds(Scene *scene, Sequence *seq)
4920 {
4921 if (seq->type == SEQ_TYPE_SCENE) {
4922 if (seq->scene && seq->scene_sound) {
4923 /* We have to take into account start frame of the sequence's scene! */
4924 int startofs = seq->startofs + seq->anim_startofs + seq->scene->r.sfra;
4925
4926 BKE_sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, startofs);
4927 }
4928 }
4929 else {
4930 BKE_sound_move_scene_sound_defaults(scene, seq);
4931 }
4932 /* mute is set in seq_update_muting_recursive */
4933 }
4934
seq_update_muting_recursive(ListBase * seqbasep,Sequence * metaseq,int mute)4935 static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
4936 {
4937 Sequence *seq;
4938 int seqmute;
4939
4940 /* for sound we go over full meta tree to update muted state,
4941 * since sound is played outside of evaluating the imbufs, */
4942 for (seq = seqbasep->first; seq; seq = seq->next) {
4943 seqmute = (mute || (seq->flag & SEQ_MUTE));
4944
4945 if (seq->type == SEQ_TYPE_META) {
4946 /* if this is the current meta sequence, unmute because
4947 * all sequences above this were set to mute */
4948 if (seq == metaseq) {
4949 seqmute = 0;
4950 }
4951
4952 seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
4953 }
4954 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
4955 if (seq->scene_sound) {
4956 BKE_sound_mute_scene_sound(seq->scene_sound, seqmute);
4957 }
4958 }
4959 }
4960 }
4961
BKE_sequencer_update_muting(Editing * ed)4962 void BKE_sequencer_update_muting(Editing *ed)
4963 {
4964 if (ed) {
4965 /* mute all sounds up to current metastack list */
4966 MetaStack *ms = ed->metastack.last;
4967
4968 if (ms) {
4969 seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1);
4970 }
4971 else {
4972 seq_update_muting_recursive(&ed->seqbase, NULL, 0);
4973 }
4974 }
4975 }
4976
seq_update_sound_recursive(Scene * scene,ListBase * seqbasep,bSound * sound)4977 static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
4978 {
4979 Sequence *seq;
4980
4981 for (seq = seqbasep->first; seq; seq = seq->next) {
4982 if (seq->type == SEQ_TYPE_META) {
4983 seq_update_sound_recursive(scene, &seq->seqbase, sound);
4984 }
4985 else if (seq->type == SEQ_TYPE_SOUND_RAM) {
4986 if (seq->scene_sound && sound == seq->sound) {
4987 BKE_sound_update_scene_sound(seq->scene_sound, sound);
4988 }
4989 }
4990 }
4991 }
4992
BKE_sequencer_update_sound(Scene * scene,bSound * sound)4993 void BKE_sequencer_update_sound(Scene *scene, bSound *sound)
4994 {
4995 if (scene->ed) {
4996 seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
4997 }
4998 }
4999
5000 /* in cases where we done know the sequence's listbase */
BKE_sequence_seqbase(ListBase * seqbase,Sequence * seq)5001 ListBase *BKE_sequence_seqbase(ListBase *seqbase, Sequence *seq)
5002 {
5003 Sequence *iseq;
5004 ListBase *lb = NULL;
5005
5006 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
5007 if (seq == iseq) {
5008 return seqbase;
5009 }
5010 if (iseq->seqbase.first && (lb = BKE_sequence_seqbase(&iseq->seqbase, seq))) {
5011 return lb;
5012 }
5013 }
5014
5015 return NULL;
5016 }
5017
BKE_sequence_metastrip(ListBase * seqbase,Sequence * meta,Sequence * seq)5018 Sequence *BKE_sequence_metastrip(ListBase *seqbase, Sequence *meta, Sequence *seq)
5019 {
5020 Sequence *iseq;
5021
5022 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
5023 Sequence *rval;
5024
5025 if (seq == iseq) {
5026 return meta;
5027 }
5028 if (iseq->seqbase.first && (rval = BKE_sequence_metastrip(&iseq->seqbase, iseq, seq))) {
5029 return rval;
5030 }
5031 }
5032
5033 return NULL;
5034 }
5035
BKE_sequence_swap(Sequence * seq_a,Sequence * seq_b,const char ** error_str)5036 int BKE_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
5037 {
5038 char name[sizeof(seq_a->name)];
5039
5040 if (seq_a->len != seq_b->len) {
5041 *error_str = N_("Strips must be the same length");
5042 return 0;
5043 }
5044
5045 /* type checking, could be more advanced but disallow sound vs non-sound copy */
5046 if (seq_a->type != seq_b->type) {
5047 if (seq_a->type == SEQ_TYPE_SOUND_RAM || seq_b->type == SEQ_TYPE_SOUND_RAM) {
5048 *error_str = N_("Strips were not compatible");
5049 return 0;
5050 }
5051
5052 /* disallow effects to swap with non-effects strips */
5053 if ((seq_a->type & SEQ_TYPE_EFFECT) != (seq_b->type & SEQ_TYPE_EFFECT)) {
5054 *error_str = N_("Strips were not compatible");
5055 return 0;
5056 }
5057
5058 if ((seq_a->type & SEQ_TYPE_EFFECT) && (seq_b->type & SEQ_TYPE_EFFECT)) {
5059 if (BKE_sequence_effect_get_num_inputs(seq_a->type) !=
5060 BKE_sequence_effect_get_num_inputs(seq_b->type)) {
5061 *error_str = N_("Strips must have the same number of inputs");
5062 return 0;
5063 }
5064 }
5065 }
5066
5067 SWAP(Sequence, *seq_a, *seq_b);
5068
5069 /* swap back names so animation fcurves don't get swapped */
5070 BLI_strncpy(name, seq_a->name + 2, sizeof(name));
5071 BLI_strncpy(seq_a->name + 2, seq_b->name + 2, sizeof(seq_b->name) - 2);
5072 BLI_strncpy(seq_b->name + 2, name, sizeof(seq_b->name) - 2);
5073
5074 /* swap back opacity, and overlay mode */
5075 SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
5076 SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
5077
5078 SWAP(Sequence *, seq_a->prev, seq_b->prev);
5079 SWAP(Sequence *, seq_a->next, seq_b->next);
5080 SWAP(int, seq_a->start, seq_b->start);
5081 SWAP(int, seq_a->startofs, seq_b->startofs);
5082 SWAP(int, seq_a->endofs, seq_b->endofs);
5083 SWAP(int, seq_a->startstill, seq_b->startstill);
5084 SWAP(int, seq_a->endstill, seq_b->endstill);
5085 SWAP(int, seq_a->machine, seq_b->machine);
5086 SWAP(int, seq_a->startdisp, seq_b->startdisp);
5087 SWAP(int, seq_a->enddisp, seq_b->enddisp);
5088
5089 return 1;
5090 }
5091
5092 /* r_prefix + [" + escaped_name + "] + \0 */
5093 #define SEQ_RNAPATH_MAXSTR ((30 + 2 + (SEQ_NAME_MAXSTR * 2) + 2) + 1)
5094
sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR],const char * name)5095 static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char *name)
5096 {
5097 char name_esc[SEQ_NAME_MAXSTR * 2];
5098
5099 BLI_strescape(name_esc, name, sizeof(name_esc));
5100 return BLI_snprintf_rlen(
5101 str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc);
5102 }
5103
5104 /* XXX - hackish function needed for transforming strips! TODO - have some better solution */
BKE_sequencer_offset_animdata(Scene * scene,Sequence * seq,int ofs)5105 void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs)
5106 {
5107 char str[SEQ_RNAPATH_MAXSTR];
5108 size_t str_len;
5109 FCurve *fcu;
5110
5111 if (scene->adt == NULL || ofs == 0 || scene->adt->action == NULL) {
5112 return;
5113 }
5114
5115 str_len = sequencer_rna_path_prefix(str, seq->name + 2);
5116
5117 for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) {
5118 if (STREQLEN(fcu->rna_path, str, str_len)) {
5119 unsigned int i;
5120 if (fcu->bezt) {
5121 for (i = 0; i < fcu->totvert; i++) {
5122 BezTriple *bezt = &fcu->bezt[i];
5123 bezt->vec[0][0] += ofs;
5124 bezt->vec[1][0] += ofs;
5125 bezt->vec[2][0] += ofs;
5126 }
5127 }
5128 if (fcu->fpt) {
5129 for (i = 0; i < fcu->totvert; i++) {
5130 FPoint *fpt = &fcu->fpt[i];
5131 fpt->vec[0] += ofs;
5132 }
5133 }
5134 }
5135 }
5136
5137 DEG_id_tag_update(&scene->adt->action->id, ID_RECALC_ANIMATION);
5138 }
5139
BKE_sequencer_dupe_animdata(Scene * scene,const char * name_src,const char * name_dst)5140 void BKE_sequencer_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst)
5141 {
5142 char str_from[SEQ_RNAPATH_MAXSTR];
5143 size_t str_from_len;
5144 FCurve *fcu;
5145 FCurve *fcu_last;
5146 FCurve *fcu_cpy;
5147 ListBase lb = {NULL, NULL};
5148
5149 if (scene->adt == NULL || scene->adt->action == NULL) {
5150 return;
5151 }
5152
5153 str_from_len = sequencer_rna_path_prefix(str_from, name_src);
5154
5155 fcu_last = scene->adt->action->curves.last;
5156
5157 for (fcu = scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu = fcu->next) {
5158 if (STREQLEN(fcu->rna_path, str_from, str_from_len)) {
5159 fcu_cpy = BKE_fcurve_copy(fcu);
5160 BLI_addtail(&lb, fcu_cpy);
5161 }
5162 }
5163
5164 /* notice validate is 0, keep this because the seq may not be added to the scene yet */
5165 BKE_animdata_fix_paths_rename(
5166 &scene->id, scene->adt, NULL, "sequence_editor.sequences_all", name_src, name_dst, 0, 0, 0);
5167
5168 /* add the original fcurves back */
5169 BLI_movelisttolist(&scene->adt->action->curves, &lb);
5170 }
5171
5172 /* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
seq_free_animdata(Scene * scene,Sequence * seq)5173 static void seq_free_animdata(Scene *scene, Sequence *seq)
5174 {
5175 char str[SEQ_RNAPATH_MAXSTR];
5176 size_t str_len;
5177 FCurve *fcu;
5178
5179 if (scene->adt == NULL || scene->adt->action == NULL) {
5180 return;
5181 }
5182
5183 str_len = sequencer_rna_path_prefix(str, seq->name + 2);
5184
5185 fcu = scene->adt->action->curves.first;
5186
5187 while (fcu) {
5188 if (STREQLEN(fcu->rna_path, str, str_len)) {
5189 FCurve *next_fcu = fcu->next;
5190
5191 BLI_remlink(&scene->adt->action->curves, fcu);
5192 BKE_fcurve_free(fcu);
5193
5194 fcu = next_fcu;
5195 }
5196 else {
5197 fcu = fcu->next;
5198 }
5199 }
5200 }
5201
5202 #undef SEQ_RNAPATH_MAXSTR
5203
BKE_sequence_get_by_name(ListBase * seqbase,const char * name,bool recursive)5204 Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, bool recursive)
5205 {
5206 Sequence *iseq = NULL;
5207 Sequence *rseq = NULL;
5208
5209 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
5210 if (STREQ(name, iseq->name + 2)) {
5211 return iseq;
5212 }
5213 if (recursive && (iseq->seqbase.first) &&
5214 (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) {
5215 return rseq;
5216 }
5217 }
5218
5219 return NULL;
5220 }
5221
5222 /**
5223 * Only use as last resort when the StripElem is available but no the Sequence.
5224 * (needed for RNA)
5225 */
BKE_sequencer_from_elem(ListBase * seqbase,StripElem * se)5226 Sequence *BKE_sequencer_from_elem(ListBase *seqbase, StripElem *se)
5227 {
5228 Sequence *iseq;
5229
5230 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
5231 Sequence *seq_found;
5232 if ((iseq->strip && iseq->strip->stripdata) &&
5233 (ARRAY_HAS_ITEM(se, iseq->strip->stripdata, iseq->len))) {
5234 break;
5235 }
5236 if ((seq_found = BKE_sequencer_from_elem(&iseq->seqbase, se))) {
5237 iseq = seq_found;
5238 break;
5239 }
5240 }
5241
5242 return iseq;
5243 }
5244
BKE_sequencer_active_get(Scene * scene)5245 Sequence *BKE_sequencer_active_get(Scene *scene)
5246 {
5247 Editing *ed = BKE_sequencer_editing_get(scene, false);
5248
5249 if (ed == NULL) {
5250 return NULL;
5251 }
5252
5253 return ed->act_seq;
5254 }
5255
BKE_sequencer_active_set(Scene * scene,Sequence * seq)5256 void BKE_sequencer_active_set(Scene *scene, Sequence *seq)
5257 {
5258 Editing *ed = BKE_sequencer_editing_get(scene, false);
5259
5260 if (ed == NULL) {
5261 return;
5262 }
5263
5264 ed->act_seq = seq;
5265 }
5266
BKE_sequencer_active_get_pair(Scene * scene,Sequence ** seq_act,Sequence ** seq_other)5267 int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **seq_other)
5268 {
5269 Editing *ed = BKE_sequencer_editing_get(scene, false);
5270
5271 *seq_act = BKE_sequencer_active_get(scene);
5272
5273 if (*seq_act == NULL) {
5274 return 0;
5275 }
5276
5277 Sequence *seq;
5278
5279 *seq_other = NULL;
5280
5281 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
5282 if (seq->flag & SELECT && (seq != (*seq_act))) {
5283 if (*seq_other) {
5284 return 0;
5285 }
5286
5287 *seq_other = seq;
5288 }
5289 }
5290
5291 return (*seq_other != NULL);
5292 }
5293
BKE_sequencer_mask_get(Scene * scene)5294 Mask *BKE_sequencer_mask_get(Scene *scene)
5295 {
5296 Sequence *seq_act = BKE_sequencer_active_get(scene);
5297
5298 if (seq_act && seq_act->type == SEQ_TYPE_MASK) {
5299 return seq_act->mask;
5300 }
5301
5302 return NULL;
5303 }
5304
5305 /* api like funcs for adding */
5306
seq_load_apply(Main * bmain,Scene * scene,Sequence * seq,SeqLoadInfo * seq_load)5307 static void seq_load_apply(Main *bmain, Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
5308 {
5309 if (seq) {
5310 BLI_strncpy_utf8(seq->name + 2, seq_load->name, sizeof(seq->name) - 2);
5311 BLI_utf8_invalid_strip(seq->name + 2, strlen(seq->name + 2));
5312 BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
5313
5314 if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) {
5315 seq_load->start_frame += (seq->enddisp - seq->startdisp);
5316 }
5317
5318 if (seq_load->flag & SEQ_LOAD_REPLACE_SEL) {
5319 seq_load->flag |= SELECT;
5320 BKE_sequencer_active_set(scene, seq);
5321 }
5322
5323 if (seq_load->flag & SEQ_LOAD_SOUND_MONO) {
5324 seq->sound->flags |= SOUND_FLAGS_MONO;
5325 BKE_sound_load(bmain, seq->sound);
5326 }
5327
5328 if (seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
5329 if (seq->sound) {
5330 seq->sound->flags |= SOUND_FLAGS_CACHING;
5331 }
5332 }
5333
5334 seq_load->tot_success++;
5335 }
5336 else {
5337 seq_load->tot_error++;
5338 }
5339 }
5340
seq_strip_alloc(int type)5341 static Strip *seq_strip_alloc(int type)
5342 {
5343 Strip *strip = MEM_callocN(sizeof(Strip), "strip");
5344
5345 if (ELEM(type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) == 0) {
5346 strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform");
5347 strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop");
5348 }
5349
5350 strip->us = 1;
5351 return strip;
5352 }
5353
BKE_sequence_alloc(ListBase * lb,int cfra,int machine,int type)5354 Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type)
5355 {
5356 Sequence *seq;
5357
5358 seq = MEM_callocN(sizeof(Sequence), "addseq");
5359 BLI_addtail(lb, seq);
5360
5361 *((short *)seq->name) = ID_SEQ;
5362 seq->name[2] = 0;
5363
5364 seq->flag = SELECT;
5365 seq->start = cfra;
5366 seq->machine = machine;
5367 seq->sat = 1.0;
5368 seq->mul = 1.0;
5369 seq->blend_opacity = 100.0;
5370 seq->volume = 1.0f;
5371 seq->pitch = 1.0f;
5372 seq->scene_sound = NULL;
5373 seq->type = type;
5374
5375 seq->strip = seq_strip_alloc(type);
5376 seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
5377 seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE;
5378
5379 BKE_sequence_session_uuid_generate(seq);
5380
5381 return seq;
5382 }
5383
BKE_sequence_session_uuid_generate(struct Sequence * sequence)5384 void BKE_sequence_session_uuid_generate(struct Sequence *sequence)
5385 {
5386 sequence->runtime.session_uuid = BLI_session_uuid_generate();
5387 }
5388
BKE_sequence_alpha_mode_from_extension(Sequence * seq)5389 void BKE_sequence_alpha_mode_from_extension(Sequence *seq)
5390 {
5391 if (seq->strip && seq->strip->stripdata) {
5392 const char *filename = seq->strip->stripdata->name;
5393 seq->alpha_mode = BKE_image_alpha_mode_from_extension_ex(filename);
5394 }
5395 }
5396
BKE_sequence_init_colorspace(Sequence * seq)5397 void BKE_sequence_init_colorspace(Sequence *seq)
5398 {
5399 if (seq->strip && seq->strip->stripdata) {
5400 char name[FILE_MAX];
5401 ImBuf *ibuf;
5402
5403 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
5404 BLI_path_abs(name, BKE_main_blendfile_path_from_global());
5405
5406 /* initialize input color space */
5407 if (seq->type == SEQ_TYPE_IMAGE) {
5408 ibuf = IMB_loadiffname(
5409 name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name);
5410
5411 /* byte images are default to straight alpha, however sequencer
5412 * works in premul space, so mark strip to be premultiplied first
5413 */
5414 seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
5415 if (ibuf) {
5416 if (ibuf->flags & IB_alphamode_premul) {
5417 seq->alpha_mode = IMA_ALPHA_PREMUL;
5418 }
5419
5420 IMB_freeImBuf(ibuf);
5421 }
5422 }
5423 }
5424 }
5425
BKE_sequence_get_fps(Scene * scene,Sequence * seq)5426 float BKE_sequence_get_fps(Scene *scene, Sequence *seq)
5427 {
5428 switch (seq->type) {
5429 case SEQ_TYPE_MOVIE: {
5430 seq_open_anim_file(scene, seq, true);
5431 if (BLI_listbase_is_empty(&seq->anims)) {
5432 return 0.0f;
5433 }
5434 StripAnim *strip_anim = seq->anims.first;
5435 if (strip_anim->anim == NULL) {
5436 return 0.0f;
5437 }
5438 short frs_sec;
5439 float frs_sec_base;
5440 if (IMB_anim_get_fps(strip_anim->anim, &frs_sec, &frs_sec_base, true)) {
5441 return (float)frs_sec / frs_sec_base;
5442 }
5443 break;
5444 }
5445 case SEQ_TYPE_MOVIECLIP:
5446 if (seq->clip != NULL) {
5447 return BKE_movieclip_get_fps(seq->clip);
5448 }
5449 break;
5450 case SEQ_TYPE_SCENE:
5451 if (seq->scene != NULL) {
5452 return (float)seq->scene->r.frs_sec / seq->scene->r.frs_sec_base;
5453 }
5454 break;
5455 }
5456 return 0.0f;
5457 }
5458
5459 /* NOTE: this function doesn't fill in image names */
BKE_sequencer_add_image_strip(bContext * C,ListBase * seqbasep,SeqLoadInfo * seq_load)5460 Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
5461 {
5462 Scene *scene = CTX_data_scene(C); /* only for active seq */
5463 Sequence *seq;
5464 Strip *strip;
5465
5466 seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel, SEQ_TYPE_IMAGE);
5467 seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
5468
5469 /* basic defaults */
5470 seq->len = seq_load->len ? seq_load->len : 1;
5471
5472 strip = seq->strip;
5473 strip->stripdata = MEM_callocN(seq->len * sizeof(StripElem), "stripelem");
5474 BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir));
5475
5476 if (seq_load->stereo3d_format) {
5477 *seq->stereo3d_format = *seq_load->stereo3d_format;
5478 }
5479
5480 seq->views_format = seq_load->views_format;
5481 seq->flag |= seq_load->flag & SEQ_USE_VIEWS;
5482
5483 seq_load_apply(CTX_data_main(C), scene, seq, seq_load);
5484 BKE_sequence_invalidate_cache_composite(scene, seq);
5485
5486 return seq;
5487 }
5488
5489 #ifdef WITH_AUDASPACE
BKE_sequencer_add_sound_strip(bContext * C,ListBase * seqbasep,SeqLoadInfo * seq_load)5490 Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
5491 {
5492 Main *bmain = CTX_data_main(C);
5493 Scene *scene = CTX_data_scene(C); /* only for sound */
5494 Editing *ed = BKE_sequencer_editing_get(scene, false);
5495 bSound *sound;
5496
5497 Sequence *seq; /* generic strip vars */
5498 Strip *strip;
5499 StripElem *se;
5500
5501 sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
5502
5503 SoundInfo info;
5504 if (!BKE_sound_info_get(bmain, sound, &info)) {
5505 BKE_id_free(bmain, sound);
5506 return NULL;
5507 }
5508
5509 if (info.specs.channels == SOUND_CHANNELS_INVALID) {
5510 BKE_id_free(bmain, sound);
5511 return NULL;
5512 }
5513
5514 seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel, SEQ_TYPE_SOUND_RAM);
5515 seq->sound = sound;
5516 BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2);
5517 BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
5518
5519 /* basic defaults */
5520 /* We add a very small negative offset here, because
5521 * ceil(132.0) == 133.0, not nice with videos, see T47135. */
5522 seq->len = (int)ceil((double)info.length * FPS - 1e-4);
5523 strip = seq->strip;
5524
5525 /* we only need 1 element to store the filename */
5526 strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem");
5527
5528 BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
5529
5530 seq->scene_sound = NULL;
5531
5532 BKE_sequence_calc_disp(scene, seq);
5533
5534 /* last active name */
5535 BLI_strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR);
5536
5537 seq_load_apply(bmain, scene, seq, seq_load);
5538
5539 /* TODO(sergey): Shall we tag here or in the operator? */
5540 DEG_relations_tag_update(bmain);
5541
5542 return seq;
5543 }
5544 #else // WITH_AUDASPACE
BKE_sequencer_add_sound_strip(bContext * C,ListBase * seqbasep,SeqLoadInfo * seq_load)5545 Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
5546 {
5547 (void)C;
5548 (void)seqbasep;
5549 (void)seq_load;
5550 return NULL;
5551 }
5552 #endif // WITH_AUDASPACE
5553
seq_anim_add_suffix(Scene * scene,struct anim * anim,const int view_id)5554 static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_id)
5555 {
5556 const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id);
5557 IMB_suffix_anim(anim, suffix);
5558 }
5559
BKE_sequencer_add_movie_strip(bContext * C,ListBase * seqbasep,SeqLoadInfo * seq_load)5560 Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
5561 {
5562 Main *bmain = CTX_data_main(C);
5563 Scene *scene = CTX_data_scene(C); /* only for sound */
5564 char path[sizeof(seq_load->path)];
5565
5566 Sequence *seq; /* generic strip vars */
5567 Strip *strip;
5568 StripElem *se;
5569 char colorspace[64] = "\0"; /* MAX_COLORSPACE_NAME */
5570 bool is_multiview_loaded = false;
5571 const bool is_multiview = (seq_load->flag & SEQ_USE_VIEWS) != 0;
5572 const int totfiles = seq_num_files(scene, seq_load->views_format, is_multiview);
5573 struct anim **anim_arr;
5574 int i;
5575
5576 BLI_strncpy(path, seq_load->path, sizeof(path));
5577 BLI_path_abs(path, BKE_main_blendfile_path(bmain));
5578
5579 anim_arr = MEM_callocN(sizeof(struct anim *) * totfiles, "Video files");
5580
5581 if (is_multiview && (seq_load->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
5582 char prefix[FILE_MAX];
5583 const char *ext = NULL;
5584 size_t j = 0;
5585
5586 BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
5587
5588 if (prefix[0] != '\0') {
5589 for (i = 0; i < totfiles; i++) {
5590 char str[FILE_MAX];
5591
5592 seq_multiview_name(scene, i, prefix, ext, str, FILE_MAX);
5593 anim_arr[j] = openanim(str, IB_rect, 0, colorspace);
5594
5595 if (anim_arr[j]) {
5596 seq_anim_add_suffix(scene, anim_arr[j], i);
5597 j++;
5598 }
5599 }
5600
5601 if (j == 0) {
5602 MEM_freeN(anim_arr);
5603 return NULL;
5604 }
5605 is_multiview_loaded = true;
5606 }
5607 }
5608
5609 if (is_multiview_loaded == false) {
5610 anim_arr[0] = openanim(path, IB_rect, 0, colorspace);
5611
5612 if (anim_arr[0] == NULL) {
5613 MEM_freeN(anim_arr);
5614 return NULL;
5615 }
5616 }
5617
5618 if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
5619 seq_load->channel++;
5620 }
5621 seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel, SEQ_TYPE_MOVIE);
5622
5623 /* multiview settings */
5624 if (seq_load->stereo3d_format) {
5625 *seq->stereo3d_format = *seq_load->stereo3d_format;
5626 seq->views_format = seq_load->views_format;
5627 }
5628 seq->flag |= seq_load->flag & SEQ_USE_VIEWS;
5629
5630 seq->type = SEQ_TYPE_MOVIE;
5631 seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
5632
5633 for (i = 0; i < totfiles; i++) {
5634 if (anim_arr[i]) {
5635 StripAnim *sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
5636 BLI_addtail(&seq->anims, sanim);
5637 sanim->anim = anim_arr[i];
5638 }
5639 else {
5640 break;
5641 }
5642 }
5643
5644 IMB_anim_load_metadata(anim_arr[0]);
5645
5646 seq->anim_preseek = IMB_anim_get_preseek(anim_arr[0]);
5647 BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2);
5648 BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
5649
5650 /* adjust scene's frame rate settings to match */
5651 if (seq_load->flag & SEQ_LOAD_SYNC_FPS) {
5652 IMB_anim_get_fps(anim_arr[0], &scene->r.frs_sec, &scene->r.frs_sec_base, true);
5653 }
5654
5655 /* basic defaults */
5656 seq->len = IMB_anim_get_duration(anim_arr[0], IMB_TC_RECORD_RUN);
5657 strip = seq->strip;
5658
5659 BLI_strncpy(seq->strip->colorspace_settings.name,
5660 colorspace,
5661 sizeof(seq->strip->colorspace_settings.name));
5662
5663 /* we only need 1 element for MOVIE strips */
5664 strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem");
5665
5666 BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
5667
5668 BKE_sequence_calc_disp(scene, seq);
5669
5670 if (seq_load->name[0] == '\0') {
5671 BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
5672 }
5673
5674 if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
5675 int start_frame_back = seq_load->start_frame;
5676 seq_load->channel--;
5677 seq_load->seq_sound = BKE_sequencer_add_sound_strip(C, seqbasep, seq_load);
5678 seq_load->start_frame = start_frame_back;
5679 }
5680
5681 /* can be NULL */
5682 seq_load_apply(CTX_data_main(C), scene, seq, seq_load);
5683 BKE_sequence_invalidate_cache_composite(scene, seq);
5684
5685 MEM_freeN(anim_arr);
5686 return seq;
5687 }
5688
seq_dupli(const Scene * scene_src,Scene * scene_dst,ListBase * new_seq_list,Sequence * seq,int dupe_flag,const int flag)5689 static Sequence *seq_dupli(const Scene *scene_src,
5690 Scene *scene_dst,
5691 ListBase *new_seq_list,
5692 Sequence *seq,
5693 int dupe_flag,
5694 const int flag)
5695 {
5696 Sequence *seqn = MEM_dupallocN(seq);
5697
5698 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
5699 BKE_sequence_session_uuid_generate(seq);
5700 }
5701
5702 seq->tmp = seqn;
5703 seqn->strip = MEM_dupallocN(seq->strip);
5704
5705 seqn->stereo3d_format = MEM_dupallocN(seq->stereo3d_format);
5706
5707 /* XXX: add F-Curve duplication stuff? */
5708
5709 if (seq->strip->crop) {
5710 seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
5711 }
5712
5713 if (seq->strip->transform) {
5714 seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
5715 }
5716
5717 if (seq->strip->proxy) {
5718 seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
5719 seqn->strip->proxy->anim = NULL;
5720 }
5721
5722 if (seq->prop) {
5723 seqn->prop = IDP_CopyProperty_ex(seq->prop, flag);
5724 }
5725
5726 if (seqn->modifiers.first) {
5727 BLI_listbase_clear(&seqn->modifiers);
5728
5729 BKE_sequence_modifier_list_copy(seqn, seq);
5730 }
5731
5732 if (seq->type == SEQ_TYPE_META) {
5733 seqn->strip->stripdata = NULL;
5734
5735 BLI_listbase_clear(&seqn->seqbase);
5736 /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
5737 /* - seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);*/
5738 }
5739 else if (seq->type == SEQ_TYPE_SCENE) {
5740 seqn->strip->stripdata = NULL;
5741 if (seq->scene_sound) {
5742 seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene_dst, seqn);
5743 }
5744 }
5745 else if (seq->type == SEQ_TYPE_MOVIECLIP) {
5746 /* avoid assert */
5747 }
5748 else if (seq->type == SEQ_TYPE_MASK) {
5749 /* avoid assert */
5750 }
5751 else if (seq->type == SEQ_TYPE_MOVIE) {
5752 seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
5753 BLI_listbase_clear(&seqn->anims);
5754 }
5755 else if (seq->type == SEQ_TYPE_SOUND_RAM) {
5756 seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
5757 seqn->scene_sound = NULL;
5758 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
5759 id_us_plus((ID *)seqn->sound);
5760 }
5761 }
5762 else if (seq->type == SEQ_TYPE_IMAGE) {
5763 seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
5764 }
5765 else if (seq->type & SEQ_TYPE_EFFECT) {
5766 struct SeqEffectHandle sh;
5767 sh = BKE_sequence_get_effect(seq);
5768 if (sh.copy) {
5769 sh.copy(seqn, seq, flag);
5770 }
5771
5772 seqn->strip->stripdata = NULL;
5773 }
5774 else {
5775 /* sequence type not handled in duplicate! Expect a crash now... */
5776 BLI_assert(0);
5777 }
5778
5779 /* When using SEQ_DUPE_UNIQUE_NAME, it is mandatory to add new sequences in relevant container
5780 * (scene or meta's one), *before* checking for unique names. Otherwise the meta's list is empty
5781 * and hence we miss all seqs in that meta that have already been duplicated (see T55668).
5782 * Note that unique name check itself could be done at a later step in calling code, once all
5783 * seqs have bee duplicated (that was first, simpler solution), but then handling of animation
5784 * data will be broken (see T60194). */
5785 if (new_seq_list != NULL) {
5786 BLI_addtail(new_seq_list, seqn);
5787 }
5788
5789 if (scene_src == scene_dst) {
5790 if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) {
5791 BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn);
5792 }
5793
5794 if (dupe_flag & SEQ_DUPE_ANIM) {
5795 BKE_sequencer_dupe_animdata(scene_dst, seq->name + 2, seqn->name + 2);
5796 }
5797 }
5798
5799 return seqn;
5800 }
5801
seq_new_fix_links_recursive(Sequence * seq)5802 static void seq_new_fix_links_recursive(Sequence *seq)
5803 {
5804 SequenceModifierData *smd;
5805
5806 if (seq->type & SEQ_TYPE_EFFECT) {
5807 if (seq->seq1 && seq->seq1->tmp) {
5808 seq->seq1 = seq->seq1->tmp;
5809 }
5810 if (seq->seq2 && seq->seq2->tmp) {
5811 seq->seq2 = seq->seq2->tmp;
5812 }
5813 if (seq->seq3 && seq->seq3->tmp) {
5814 seq->seq3 = seq->seq3->tmp;
5815 }
5816 }
5817 else if (seq->type == SEQ_TYPE_META) {
5818 Sequence *seqn;
5819 for (seqn = seq->seqbase.first; seqn; seqn = seqn->next) {
5820 seq_new_fix_links_recursive(seqn);
5821 }
5822 }
5823
5824 for (smd = seq->modifiers.first; smd; smd = smd->next) {
5825 if (smd->mask_sequence && smd->mask_sequence->tmp) {
5826 smd->mask_sequence = smd->mask_sequence->tmp;
5827 }
5828 }
5829 }
5830
sequence_dupli_recursive_do(const Scene * scene_src,Scene * scene_dst,ListBase * new_seq_list,Sequence * seq,const int dupe_flag)5831 static Sequence *sequence_dupli_recursive_do(const Scene *scene_src,
5832 Scene *scene_dst,
5833 ListBase *new_seq_list,
5834 Sequence *seq,
5835 const int dupe_flag)
5836 {
5837 Sequence *seqn;
5838
5839 seq->tmp = NULL;
5840 seqn = seq_dupli(scene_src, scene_dst, new_seq_list, seq, dupe_flag, 0);
5841 if (seq->type == SEQ_TYPE_META) {
5842 Sequence *s;
5843 for (s = seq->seqbase.first; s; s = s->next) {
5844 sequence_dupli_recursive_do(scene_src, scene_dst, &seqn->seqbase, s, dupe_flag);
5845 }
5846 }
5847
5848 return seqn;
5849 }
5850
BKE_sequence_dupli_recursive(const Scene * scene_src,Scene * scene_dst,ListBase * new_seq_list,Sequence * seq,int dupe_flag)5851 Sequence *BKE_sequence_dupli_recursive(
5852 const Scene *scene_src, Scene *scene_dst, ListBase *new_seq_list, Sequence *seq, int dupe_flag)
5853 {
5854 Sequence *seqn = sequence_dupli_recursive_do(scene_src, scene_dst, new_seq_list, seq, dupe_flag);
5855
5856 /* This does not need to be in recursive call itself, since it is already recursive... */
5857 seq_new_fix_links_recursive(seqn);
5858
5859 return seqn;
5860 }
5861
BKE_sequence_base_dupli_recursive(const Scene * scene_src,Scene * scene_dst,ListBase * nseqbase,const ListBase * seqbase,int dupe_flag,const int flag)5862 void BKE_sequence_base_dupli_recursive(const Scene *scene_src,
5863 Scene *scene_dst,
5864 ListBase *nseqbase,
5865 const ListBase *seqbase,
5866 int dupe_flag,
5867 const int flag)
5868 {
5869 Sequence *seq;
5870 Sequence *seqn = NULL;
5871 Sequence *last_seq = BKE_sequencer_active_get((Scene *)scene_src);
5872 /* always include meta's strips */
5873 int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL | SEQ_DUPE_IS_RECURSIVE_CALL;
5874
5875 for (seq = seqbase->first; seq; seq = seq->next) {
5876 seq->tmp = NULL;
5877 if ((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
5878 seqn = seq_dupli(scene_src, scene_dst, nseqbase, seq, dupe_flag, flag);
5879 if (seqn) { /*should never fail */
5880 if (dupe_flag & SEQ_DUPE_CONTEXT) {
5881 seq->flag &= ~SEQ_ALLSEL;
5882 seqn->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
5883 }
5884
5885 if (seq->type == SEQ_TYPE_META) {
5886 BKE_sequence_base_dupli_recursive(
5887 scene_src, scene_dst, &seqn->seqbase, &seq->seqbase, dupe_flag_recursive, flag);
5888 }
5889
5890 if (dupe_flag & SEQ_DUPE_CONTEXT) {
5891 if (seq == last_seq) {
5892 BKE_sequencer_active_set(scene_dst, seqn);
5893 }
5894 }
5895 }
5896 }
5897 }
5898
5899 /* Fix modifier links recursively from the top level only, when all sequences have been
5900 * copied. */
5901 if (dupe_flag & SEQ_DUPE_IS_RECURSIVE_CALL) {
5902 return;
5903 }
5904
5905 /* fix modifier linking */
5906 for (seq = nseqbase->first; seq; seq = seq->next) {
5907 seq_new_fix_links_recursive(seq);
5908 }
5909 }
5910
5911 /* called on draw, needs to be fast,
5912 * we could cache and use a flag if we want to make checks for file paths resolving for eg. */
BKE_sequence_is_valid_check(Sequence * seq)5913 bool BKE_sequence_is_valid_check(Sequence *seq)
5914 {
5915 switch (seq->type) {
5916 case SEQ_TYPE_MASK:
5917 return (seq->mask != NULL);
5918 case SEQ_TYPE_MOVIECLIP:
5919 return (seq->clip != NULL);
5920 case SEQ_TYPE_SCENE:
5921 return (seq->scene != NULL);
5922 case SEQ_TYPE_SOUND_RAM:
5923 return (seq->sound != NULL);
5924 }
5925
5926 return true;
5927 }
5928
BKE_sequencer_find_next_prev_edit(Scene * scene,int cfra,const short side,const bool do_skip_mute,const bool do_center,const bool do_unselected)5929 int BKE_sequencer_find_next_prev_edit(Scene *scene,
5930 int cfra,
5931 const short side,
5932 const bool do_skip_mute,
5933 const bool do_center,
5934 const bool do_unselected)
5935 {
5936 Editing *ed = BKE_sequencer_editing_get(scene, false);
5937 Sequence *seq;
5938
5939 int dist, best_dist, best_frame = cfra;
5940 int seq_frames[2], seq_frames_tot;
5941
5942 /* In case where both is passed,
5943 * frame just finds the nearest end while frame_left the nearest start. */
5944
5945 best_dist = MAXFRAME * 2;
5946
5947 if (ed == NULL) {
5948 return cfra;
5949 }
5950
5951 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
5952 int i;
5953
5954 if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
5955 continue;
5956 }
5957
5958 if (do_unselected && (seq->flag & SELECT)) {
5959 continue;
5960 }
5961
5962 if (do_center) {
5963 seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
5964 seq_frames_tot = 1;
5965 }
5966 else {
5967 seq_frames[0] = seq->startdisp;
5968 seq_frames[1] = seq->enddisp;
5969
5970 seq_frames_tot = 2;
5971 }
5972
5973 for (i = 0; i < seq_frames_tot; i++) {
5974 const int seq_frame = seq_frames[i];
5975
5976 dist = MAXFRAME * 2;
5977
5978 switch (side) {
5979 case SEQ_SIDE_LEFT:
5980 if (seq_frame < cfra) {
5981 dist = cfra - seq_frame;
5982 }
5983 break;
5984 case SEQ_SIDE_RIGHT:
5985 if (seq_frame > cfra) {
5986 dist = seq_frame - cfra;
5987 }
5988 break;
5989 case SEQ_SIDE_BOTH:
5990 dist = abs(seq_frame - cfra);
5991 break;
5992 }
5993
5994 if (dist < best_dist) {
5995 best_frame = seq_frame;
5996 best_dist = dist;
5997 }
5998 }
5999 }
6000
6001 return best_frame;
6002 }
6003
sequencer_all_free_anim_ibufs(ListBase * seqbase,int cfra)6004 static void sequencer_all_free_anim_ibufs(ListBase *seqbase, int cfra)
6005 {
6006 for (Sequence *seq = seqbase->first; seq != NULL; seq = seq->next) {
6007 if (seq->enddisp < cfra || seq->startdisp > cfra) {
6008 BKE_sequence_free_anim(seq);
6009 }
6010 if (seq->type == SEQ_TYPE_META) {
6011 sequencer_all_free_anim_ibufs(&seq->seqbase, cfra);
6012 }
6013 }
6014 }
6015
BKE_sequencer_all_free_anim_ibufs(Scene * scene,int cfra)6016 void BKE_sequencer_all_free_anim_ibufs(Scene *scene, int cfra)
6017 {
6018 Editing *ed = BKE_sequencer_editing_get(scene, false);
6019 if (ed == NULL) {
6020 return;
6021 }
6022 sequencer_all_free_anim_ibufs(&ed->seqbase, cfra);
6023 BKE_sequencer_cache_cleanup(scene);
6024 }
6025
sequencer_seq_generates_image(Sequence * seq)6026 static bool sequencer_seq_generates_image(Sequence *seq)
6027 {
6028 switch (seq->type) {
6029 case SEQ_TYPE_IMAGE:
6030 case SEQ_TYPE_SCENE:
6031 case SEQ_TYPE_MOVIE:
6032 case SEQ_TYPE_MOVIECLIP:
6033 case SEQ_TYPE_MASK:
6034 case SEQ_TYPE_COLOR:
6035 case SEQ_TYPE_TEXT:
6036 return true;
6037 }
6038 return false;
6039 }
6040
sequencer_check_scene_recursion(Scene * scene,ListBase * seqbase)6041 static Sequence *sequencer_check_scene_recursion(Scene *scene, ListBase *seqbase)
6042 {
6043 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
6044 if (seq->type == SEQ_TYPE_SCENE && seq->scene == scene) {
6045 return seq;
6046 }
6047
6048 if (seq->type == SEQ_TYPE_SCENE && (seq->flag & SEQ_SCENE_STRIPS)) {
6049 if (sequencer_check_scene_recursion(scene, &seq->scene->ed->seqbase)) {
6050 return seq;
6051 }
6052 }
6053
6054 if (seq->type == SEQ_TYPE_META && sequencer_check_scene_recursion(scene, &seq->seqbase)) {
6055 return seq;
6056 }
6057 }
6058
6059 return NULL;
6060 }
6061
BKE_sequencer_check_scene_recursion(Scene * scene,ReportList * reports)6062 bool BKE_sequencer_check_scene_recursion(Scene *scene, ReportList *reports)
6063 {
6064 Editing *ed = BKE_sequencer_editing_get(scene, false);
6065 if (ed == NULL) {
6066 return false;
6067 }
6068
6069 Sequence *recursive_seq = sequencer_check_scene_recursion(scene, &ed->seqbase);
6070
6071 if (recursive_seq != NULL) {
6072 BKE_reportf(reports,
6073 RPT_WARNING,
6074 "Recursion detected in video sequencer. Strip %s at frame %d will not be rendered",
6075 recursive_seq->name + 2,
6076 recursive_seq->startdisp);
6077
6078 LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) {
6079 if (seq->type != SEQ_TYPE_SCENE && sequencer_seq_generates_image(seq)) {
6080 /* There are other strips to render, so render them. */
6081 return false;
6082 }
6083 }
6084 /* No other strips to render - cancel operator. */
6085 return true;
6086 }
6087
6088 return false;
6089 }
6090
6091 /* Check if "seq_main" (indirectly) uses strip "seq". */
BKE_sequencer_render_loop_check(Sequence * seq_main,Sequence * seq)6092 bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq)
6093 {
6094 if (seq_main == NULL || seq == NULL) {
6095 return false;
6096 }
6097
6098 if (seq_main == seq) {
6099 return true;
6100 }
6101
6102 if ((seq_main->seq1 && BKE_sequencer_render_loop_check(seq_main->seq1, seq)) ||
6103 (seq_main->seq2 && BKE_sequencer_render_loop_check(seq_main->seq2, seq)) ||
6104 (seq_main->seq3 && BKE_sequencer_render_loop_check(seq_main->seq3, seq))) {
6105 return true;
6106 }
6107
6108 SequenceModifierData *smd;
6109 for (smd = seq_main->modifiers.first; smd; smd = smd->next) {
6110 if (smd->mask_sequence && BKE_sequencer_render_loop_check(smd->mask_sequence, seq)) {
6111 return true;
6112 }
6113 }
6114
6115 return false;
6116 }
6117
sequencer_flag_users_for_removal(Scene * scene,ListBase * seqbase,Sequence * seq)6118 static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
6119 {
6120 LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
6121 /* Look in metas for usage of seq. */
6122 if (user_seq->type == SEQ_TYPE_META) {
6123 sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
6124 }
6125
6126 /* Clear seq from modifiers. */
6127 SequenceModifierData *smd;
6128 for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
6129 if (smd->mask_sequence == seq) {
6130 smd->mask_sequence = NULL;
6131 }
6132 }
6133
6134 /* Remove effects, that use seq. */
6135 if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) ||
6136 (user_seq->seq3 && user_seq->seq3 == seq)) {
6137 user_seq->flag |= SEQ_FLAG_DELETE;
6138 /* Strips can be used as mask even if not in same seqbase. */
6139 sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq);
6140 }
6141 }
6142 }
6143
6144 /* Flag seq and its users (effects) for removal. */
BKE_sequencer_flag_for_removal(Scene * scene,ListBase * seqbase,Sequence * seq)6145 void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
6146 {
6147 if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
6148 return;
6149 }
6150
6151 /* Flag and remove meta children. */
6152 if (seq->type == SEQ_TYPE_META) {
6153 LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
6154 BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child);
6155 }
6156 }
6157
6158 seq->flag |= SEQ_FLAG_DELETE;
6159 sequencer_flag_users_for_removal(scene, seqbase, seq);
6160 }
6161
6162 /* Remove all flagged sequences, return true if sequence is removed. */
BKE_sequencer_remove_flagged_sequences(Scene * scene,ListBase * seqbase)6163 void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
6164 {
6165 LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
6166 if (seq->flag & SEQ_FLAG_DELETE) {
6167 if (seq->type == SEQ_TYPE_META) {
6168 BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase);
6169 }
6170 BLI_remlink(seqbase, seq);
6171 BKE_sequence_free(scene, seq, true);
6172 }
6173 }
6174 }
6175
BKE_sequencer_check_uuids_unique_and_report(const Scene * scene)6176 void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene)
6177 {
6178 if (scene->ed == NULL) {
6179 return;
6180 }
6181
6182 struct GSet *used_uuids = BLI_gset_new(
6183 BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
6184
6185 const Sequence *sequence;
6186 SEQ_ALL_BEGIN (scene->ed, sequence) {
6187 const SessionUUID *session_uuid = &sequence->runtime.session_uuid;
6188 if (!BLI_session_uuid_is_generated(session_uuid)) {
6189 printf("Sequence %s does not have UUID generated.\n", sequence->name);
6190 continue;
6191 }
6192
6193 if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
6194 printf("Sequence %s has duplicate UUID generated.\n", sequence->name);
6195 continue;
6196 }
6197
6198 BLI_gset_insert(used_uuids, (void *)session_uuid);
6199 }
6200 SEQ_ALL_END;
6201
6202 BLI_gset_free(used_uuids, NULL);
6203 }
6204