2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
22 * - Blender Foundation, 2003-2009
23 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/sequencer.c
37 #include "MEM_guardedalloc.h"
38 #include "MEM_CacheLimiterC-Api.h"
40 #include "DNA_sequence_types.h"
41 #include "DNA_movieclip_types.h"
42 #include "DNA_mask_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_anim_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_sound_types.h"
49 #include "BLI_fileops.h"
50 #include "BLI_listbase.h"
51 #include "BLI_path_util.h"
52 #include "BLI_string.h"
53 #include "BLI_threads.h"
54 #include "BLI_utildefines.h"
56 #include "BKE_animsys.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
60 #include "BKE_sequencer.h"
61 #include "BKE_movieclip.h"
62 #include "BKE_fcurve.h"
63 #include "BKE_scene.h"
65 #include "BKE_utildefines.h"
67 #include "RNA_access.h"
69 #include "RE_pipeline.h"
73 #include "IMB_imbuf.h"
74 #include "IMB_imbuf_types.h"
76 #include "BKE_context.h"
77 #include "BKE_sound.h"
80 # include "AUD_C-API.h"
83 static ImBuf *seq_render_strip_stack(
84 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
86 static ImBuf *seq_render_strip(
87 SeqRenderData context, Sequence *seq, float cfra);
89 static void seq_free_animdata(Scene *scene, Sequence *seq);
92 /* **** XXX ******** */
94 ListBase seqbase_clipboard;
95 int seqbase_clipboard_frame;
96 SequencerDrawView sequencer_view3d_cb = NULL; /* NULL in background mode */
99 void printf_strip(Sequence *seq)
101 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
102 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
103 fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
106 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
109 for (iseq = seqbase->first; iseq; iseq = iseq->next) {
110 if (seq_recursive_apply(iseq, apply_func, arg) == -1)
111 return -1; /* bail out */
116 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
118 int ret = apply_func(seq, arg);
121 return -1; /* bail out */
123 if (ret && seq->seqbase.first)
124 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
129 /* **********************************************************************
130 * alloc / free functions
131 * ********************************************************************** */
135 static void free_proxy_seq(Sequence *seq)
137 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
138 IMB_free_anim(seq->strip->proxy->anim);
139 seq->strip->proxy->anim = NULL;
143 void seq_free_strip(Strip *strip)
146 if (strip->us > 0) return;
148 printf("error: negative users in strip\n");
152 if (strip->stripdata) {
153 MEM_freeN(strip->stripdata);
157 if (strip->proxy->anim) {
158 IMB_free_anim(strip->proxy->anim);
161 MEM_freeN(strip->proxy);
164 MEM_freeN(strip->crop);
166 if (strip->transform) {
167 MEM_freeN(strip->transform);
169 if (strip->color_balance) {
170 MEM_freeN(strip->color_balance);
176 void seq_free_sequence(Scene *scene, Sequence *seq)
178 if (seq->strip) seq_free_strip(seq->strip);
180 if (seq->anim) IMB_free_anim(seq->anim);
182 if (seq->type & SEQ_TYPE_EFFECT) {
183 struct SeqEffectHandle sh = get_sequence_effect(seq);
189 ((ID *)seq->sound)->us--;
192 /* clipboard has no scene and will never have a sound handle or be active */
194 Editing *ed = scene->ed;
196 if (ed->act_seq == seq)
199 if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE))
200 sound_remove_scene_sound(scene, seq->scene_sound);
202 seq_free_animdata(scene, seq);
208 void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
212 for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
213 seq_free_sequence_recurse(scene, iseq);
216 seq_free_sequence(scene, seq);
220 Editing *BKE_sequencer_editing_get(Scene *scene, int alloc)
223 BKE_sequencer_editing_ensure(scene);
228 static void seq_free_clipboard_recursive(Sequence *seq_parent)
230 Sequence *seq, *nseq;
232 for (seq = seq_parent->seqbase.first; seq; seq = nseq) {
234 seq_free_clipboard_recursive(seq);
237 seq_free_sequence(NULL, seq_parent);
240 void seq_free_clipboard(void)
242 Sequence *seq, *nseq;
244 for (seq = seqbase_clipboard.first; seq; seq = nseq) {
246 seq_free_clipboard_recursive(seq);
248 seqbase_clipboard.first = seqbase_clipboard.last = NULL;
251 Editing *BKE_sequencer_editing_ensure(Scene *scene)
253 if (scene->ed == NULL) {
256 ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
257 ed->seqbasep = &ed->seqbase;
263 void BKE_sequencer_editing_free(Scene *scene)
265 Editing *ed = scene->ed;
274 seq_free_sequence(scene, seq);
278 while ((ms = ed->metastack.first)) {
279 BLI_remlink(&ed->metastack, ms);
288 /* **********************************************************************
289 * sequencer pipeline functions
290 * ********************************************************************** */
292 SeqRenderData seq_new_render_data(
293 struct Main *bmain, struct Scene *scene,
294 int rectx, int recty, int preview_render_size)
302 rval.preview_render_size = preview_render_size;
303 rval.motion_blur_samples = 0;
304 rval.motion_blur_shutter = 0;
309 int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
311 if (a->preview_render_size < b->preview_render_size) {
314 if (a->preview_render_size > b->preview_render_size) {
318 if (a->rectx < b->rectx) {
321 if (a->rectx > b->rectx) {
325 if (a->recty < b->recty) {
328 if (a->recty > b->recty) {
332 if (a->bmain < b->bmain) {
335 if (a->bmain > b->bmain) {
339 if (a->scene < b->scene) {
342 if (a->scene > b->scene) {
346 if (a->motion_blur_shutter < b->motion_blur_shutter) {
349 if (a->motion_blur_shutter > b->motion_blur_shutter) {
353 if (a->motion_blur_samples < b->motion_blur_samples) {
356 if (a->motion_blur_samples > b->motion_blur_samples) {
363 unsigned int seq_hash_render_data(const SeqRenderData *a)
365 unsigned int rval = a->rectx + a->recty;
367 rval ^= a->preview_render_size;
368 rval ^= ((intptr_t) a->bmain) << 6;
369 rval ^= ((intptr_t) a->scene) << 6;
370 rval ^= (int)(a->motion_blur_shutter * 100.0f) << 10;
371 rval ^= a->motion_blur_samples << 24;
376 /* ************************* iterator ************************** */
377 /* *************** (replaces old WHILE_SEQ) ********************* */
378 /* **************** use now SEQ_BEGIN () SEQ_END ***************** */
380 /* sequence strip iterator:
381 * - builds a full array, recursively into meta strips */
383 static void seq_count(ListBase *seqbase, int *tot)
387 for (seq = seqbase->first; seq; seq = seq->next) {
390 if (seq->seqbase.first)
391 seq_count(&seq->seqbase, tot);
395 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
399 for (seq = seqbase->first; seq; seq = seq->next) {
402 if (seq->seqbase.first)
403 seq_build_array(&seq->seqbase, array, depth + 1);
410 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
421 seq_count(ed->seqbasep, tot);
423 seq_count(&ed->seqbase, tot);
428 *seqarray = array = MEM_mallocN(sizeof(Sequence *) * (*tot), "SeqArray");
430 seq_build_array(ed->seqbasep, &array, 0);
432 seq_build_array(&ed->seqbase, &array, 0);
435 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
437 memset(iter, 0, sizeof(*iter));
438 seq_array(ed, &iter->array, &iter->tot, use_pointer);
442 iter->seq = iter->array[iter->cur];
447 void seq_next(SeqIterator *iter)
449 if (++iter->cur < iter->tot)
450 iter->seq = iter->array[iter->cur];
455 void seq_end(SeqIterator *iter)
458 MEM_freeN(iter->array);
464 * **********************************************************************
466 * *********************************************************************
467 * Build a complete array of _all_ sequencies (including those
469 * *********************************************************************
472 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
473 int (*test_func)(Sequence *seq))
477 seq = seqbase->first;
479 int test = test_func(seq);
480 if (test & BUILD_SEQAR_COUNT_CURRENT) {
483 if (seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
484 do_seq_count_cb(&seq->seqbase, totseq, test_func);
490 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
491 int (*test_func)(Sequence *seq))
495 seq = seqbase->first;
497 int test = test_func(seq);
500 if (seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
501 do_build_seqar_cb(&seq->seqbase, seqar, depth + 1, test_func);
503 if (test & BUILD_SEQAR_COUNT_CURRENT) {
511 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
512 int (*test_func)(Sequence *seq))
517 do_seq_count_cb(seqbase, totseq, test_func);
523 *seqar = MEM_mallocN(sizeof(void *) * *totseq, "seqar");
526 do_build_seqar_cb(seqbase, seqar, 0, test_func);
530 static int metaseq_start(Sequence *metaseq)
532 return metaseq->start + metaseq->startofs;
535 static int metaseq_end(Sequence *metaseq)
537 return metaseq->start + metaseq->len - metaseq->endofs;
540 static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metaseq, int start, int end)
544 /* for sound we go over full meta tree to update bounds of the sound strips,
545 * since sound is played outside of evaluating the imbufs, */
546 for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
547 if (seq->type == SEQ_TYPE_META) {
548 seq_update_sound_bounds_recursive_rec(scene, seq, MAX2(start, metaseq_start(seq)), MIN2(end, metaseq_end(seq)));
550 else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
551 if (seq->scene_sound) {
552 int startofs = seq->startofs;
553 int endofs = seq->endofs;
554 if (seq->startofs + seq->start < start)
555 startofs = start - seq->start;
557 if (seq->start + seq->len - seq->endofs > end)
558 endofs = seq->start + seq->len - end;
559 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start + seq->len - endofs, startofs);
565 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
567 seq_update_sound_bounds_recursive_rec(scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
570 void calc_sequence_disp(Scene *scene, Sequence *seq)
572 if (seq->startofs && seq->startstill) seq->startstill = 0;
573 if (seq->endofs && seq->endstill) seq->endstill = 0;
575 seq->startdisp = seq->start + seq->startofs - seq->startstill;
576 seq->enddisp = seq->start + seq->len - seq->endofs + seq->endstill;
578 seq->handsize = 10.0; /* 10 frames */
579 if (seq->enddisp - seq->startdisp < 10) {
580 seq->handsize = (float)(0.5 * (seq->enddisp - seq->startdisp));
582 else if (seq->enddisp - seq->startdisp > 250) {
583 seq->handsize = (float)((seq->enddisp - seq->startdisp) / 25);
586 if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
587 seq_update_sound_bounds(scene, seq);
589 else if (seq->type == SEQ_TYPE_META)
590 seq_update_sound_bounds_recursive(scene, seq);
593 void calc_sequence(Scene *scene, Sequence *seq)
598 /* check all metas recursively */
599 seqm = seq->seqbase.first;
601 if (seqm->seqbase.first) calc_sequence(scene, seqm);
605 /* effects and meta: automatic start and end */
607 if (seq->type & SEQ_TYPE_EFFECT) {
609 if (seq->seq2 == NULL) seq->seq2 = seq->seq1;
610 if (seq->seq3 == NULL) seq->seq3 = seq->seq1;
612 /* effecten go from seq1 -> seq2: test */
614 /* we take the largest start and smallest end */
616 // seq->start = seq->startdisp = MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
617 // seq->enddisp = MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
620 /* XXX These resets should not be necessary, but users used to be able to
621 * edit effect's length, leading to strange results. See [#29190] */
622 seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
623 seq->start = seq->startdisp = MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
624 seq->enddisp = MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
625 /* we cant help if strips don't overlap, it wont give useful results.
626 * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
627 if (seq->enddisp < seq->startdisp) {
628 /* simple start/end swap */
629 seq->start = seq->enddisp;
630 seq->enddisp = seq->startdisp;
631 seq->startdisp = seq->start;
632 seq->flag |= SEQ_INVALID_EFFECT;
635 seq->flag &= ~SEQ_INVALID_EFFECT;
638 seq->len = seq->enddisp - seq->startdisp;
641 calc_sequence_disp(scene, seq);
645 if (seq->type == SEQ_TYPE_META) {
646 seqm = seq->seqbase.first;
651 if (seqm->startdisp < min) min = seqm->startdisp;
652 if (seqm->enddisp > max) max = seqm->enddisp;
655 seq->start = min + seq->anim_startofs;
656 seq->len = max - min;
657 seq->len -= seq->anim_startofs;
658 seq->len -= seq->anim_endofs;
660 seq_update_sound_bounds_recursive(scene, seq);
662 calc_sequence_disp(scene, seq);
666 /* note: caller should run calc_sequence(scene, seq) after */
667 void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range)
670 int prev_startdisp = 0, prev_enddisp = 0;
671 /* note: don't rename the strip, will break animation curves */
674 SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_SOUND_RAM,
675 SEQ_TYPE_SCENE, SEQ_TYPE_META, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) == 0)
681 /* keep so we don't have to move the actual start and end points (only the data) */
682 calc_sequence_disp(scene, seq);
683 prev_startdisp = seq->startdisp;
684 prev_enddisp = seq->enddisp;
691 size_t olen = MEM_allocN_len(seq->strip->stripdata) / sizeof(struct StripElem);
694 seq->len -= seq->anim_startofs;
695 seq->len -= seq->anim_endofs;
702 BLI_join_dirfile(str, sizeof(str), seq->strip->dir,
703 seq->strip->stripdata->name);
704 BLI_path_abs(str, G.main->name);
706 if (seq->anim) IMB_free_anim(seq->anim);
707 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
713 seq->len = IMB_anim_get_duration(seq->anim,
715 seq->strip->proxy->tc :
718 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
720 seq->len -= seq->anim_startofs;
721 seq->len -= seq->anim_endofs;
726 case SEQ_TYPE_MOVIECLIP:
727 seq->len = BKE_movieclip_get_duration(seq->clip);
729 seq->len -= seq->anim_startofs;
730 seq->len -= seq->anim_endofs;
736 seq->len = BKE_mask_get_duration(seq->mask);
738 seq->len -= seq->anim_startofs;
739 seq->len -= seq->anim_endofs;
744 case SEQ_TYPE_SOUND_RAM:
745 #ifdef WITH_AUDASPACE
748 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
749 seq->len -= seq->anim_startofs;
750 seq->len -= seq->anim_endofs;
760 seq->len = (seq->scene) ? seq->scene->r.efra - seq->scene->r.sfra + 1 : 0;
761 seq->len -= seq->anim_startofs;
762 seq->len -= seq->anim_endofs;
773 seq_tx_set_final_left(seq, prev_startdisp);
774 seq_tx_set_final_right(seq, prev_enddisp);
778 calc_sequence(scene, seq);
781 void BKE_sequencer_sort(Scene *scene)
783 /* all strips together per kind, and in order of y location ("machine") */
784 ListBase seqbase, effbase;
785 Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
786 Sequence *seq, *seqt;
789 if (ed == NULL) return;
791 seqbase.first = seqbase.last = NULL;
792 effbase.first = effbase.last = NULL;
794 while ( (seq = ed->seqbasep->first) ) {
795 BLI_remlink(ed->seqbasep, seq);
797 if (seq->type & SEQ_TYPE_EFFECT) {
798 seqt = effbase.first;
800 if (seqt->machine >= seq->machine) {
801 BLI_insertlinkbefore(&effbase, seqt, seq);
806 if (seqt == NULL) BLI_addtail(&effbase, seq);
809 seqt = seqbase.first;
811 if (seqt->machine >= seq->machine) {
812 BLI_insertlinkbefore(&seqbase, seqt, seq);
817 if (seqt == NULL) BLI_addtail(&seqbase, seq);
821 BLI_movelisttolist(&seqbase, &effbase);
822 *(ed->seqbasep) = seqbase;
826 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
828 if (seq->scene == (Scene *)arg_pt)
833 void clear_scene_in_allseqs(Main *bmain, Scene *scene)
837 /* when a scene is deleted: test all seqs */
838 for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) {
839 if (scene_iter != scene && scene_iter->ed) {
840 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
845 typedef struct SeqUniqueInfo {
847 char name_src[SEQ_NAME_MAXSTR];
848 char name_dest[SEQ_NAME_MAXSTR];
854 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
856 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
860 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
863 for (seq = seqbasep->first; seq; seq = seq->next) {
864 if (sui->seq != seq && strcmp(sui->name_dest, seq->name + 2) == 0) {
865 /* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */
866 BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d", sui->name_src, sui->count++);
867 sui->match = 1; /* be sure to re-scan */
872 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
874 if (seq->seqbase.first)
875 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
879 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
884 BLI_strncpy(sui.name_src, seq->name + 2, sizeof(sui.name_src));
885 BLI_strncpy(sui.name_dest, seq->name + 2, sizeof(sui.name_dest));
888 sui.match = 1; /* assume the worst to start the loop */
890 /* Strip off the suffix */
891 if ((dot = strrchr(sui.name_src, '.'))) {
896 sui.count = atoi(dot) + 1;
901 seqbase_unique_name(seqbasep, &sui);
902 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
905 BLI_strncpy(seq->name + 2, sui.name_dest, sizeof(seq->name) - 2);
908 static const char *give_seqname_by_type(int type)
911 case SEQ_TYPE_META: return "Meta";
912 case SEQ_TYPE_IMAGE: return "Image";
913 case SEQ_TYPE_SCENE: return "Scene";
914 case SEQ_TYPE_MOVIE: return "Movie";
915 case SEQ_TYPE_MOVIECLIP: return "Clip";
916 case SEQ_TYPE_MASK: return "Mask";
917 case SEQ_TYPE_SOUND_RAM: return "Audio";
918 case SEQ_TYPE_CROSS: return "Cross";
919 case SEQ_TYPE_GAMCROSS: return "Gamma Cross";
920 case SEQ_TYPE_ADD: return "Add";
921 case SEQ_TYPE_SUB: return "Sub";
922 case SEQ_TYPE_MUL: return "Mul";
923 case SEQ_TYPE_ALPHAOVER: return "Alpha Over";
924 case SEQ_TYPE_ALPHAUNDER: return "Alpha Under";
925 case SEQ_TYPE_OVERDROP: return "Over Drop";
926 case SEQ_TYPE_WIPE: return "Wipe";
927 case SEQ_TYPE_GLOW: return "Glow";
928 case SEQ_TYPE_TRANSFORM: return "Transform";
929 case SEQ_TYPE_COLOR: return "Color";
930 case SEQ_TYPE_MULTICAM: return "Multicam";
931 case SEQ_TYPE_ADJUSTMENT: return "Adjustment";
932 case SEQ_TYPE_SPEED: return "Speed";
938 const char *give_seqname(Sequence *seq)
940 const char *name = give_seqname_by_type(seq->type);
943 if (seq->type < SEQ_TYPE_EFFECT) {
944 return seq->strip->dir;
953 /* ***************** DO THE SEQUENCE ***************** */
955 static void make_black_ibuf(ImBuf *ibuf)
961 if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
965 tot = ibuf->x * ibuf->y;
968 rect_float = ibuf->rect_float;
971 memset(rect, 0, tot * sizeof(char) * 4);
975 memset(rect_float, 0, tot * sizeof(float) * 4);
979 static void multibuf(ImBuf *ibuf, float fmul)
986 mul = (int)(256.0f * fmul);
987 rt = (char *)ibuf->rect;
988 rt_float = ibuf->rect_float;
991 a = ibuf->x * ibuf->y;
994 icol = (mul * rt[0]) >> 8;
995 if (icol > 254) rt[0] = 255; else rt[0] = icol;
996 icol = (mul * rt[1]) >> 8;
997 if (icol > 254) rt[1] = 255; else rt[1] = icol;
998 icol = (mul * rt[2]) >> 8;
999 if (icol > 254) rt[2] = 255; else rt[2] = icol;
1000 icol = (mul * rt[3]) >> 8;
1001 if (icol > 254) rt[3] = 255; else rt[3] = icol;
1007 a = ibuf->x * ibuf->y;
1009 rt_float[0] *= fmul;
1010 rt_float[1] *= fmul;
1011 rt_float[2] *= fmul;
1012 rt_float[3] *= fmul;
1019 static float give_stripelem_index(Sequence *seq, float cfra)
1022 int sta = seq->start;
1023 int end = seq->start + seq->len - 1;
1025 if (seq->type & SEQ_TYPE_EFFECT) {
1033 if (seq->flag & SEQ_REVERSE_FRAMES) {
1034 /*reverse frame in this sequence */
1035 if (cfra <= sta) nr = end - sta;
1036 else if (cfra >= end) nr = 0;
1037 else nr = end - cfra;
1040 if (cfra <= sta) nr = 0;
1041 else if (cfra >= end) nr = end - sta;
1042 else nr = cfra - sta;
1045 if (seq->strobe < 1.0f) seq->strobe = 1.0f;
1047 if (seq->strobe > 1.0f) {
1048 nr -= fmodf((double)nr, (double)seq->strobe);
1054 StripElem *give_stripelem(Sequence *seq, int cfra)
1056 StripElem *se = seq->strip->stripdata;
1058 if (seq->type == SEQ_TYPE_IMAGE) { /* only
1059 * IMAGE strips use the whole array,
1060 * MOVIE strips use only
1061 * the first element, all other strips
1062 * don't use this... */
1063 int nr = (int)give_stripelem_index(seq, cfra);
1065 if (nr == -1 || se == NULL) return NULL;
1067 se += nr + seq->anim_startofs;
1072 static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra)
1077 memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1));
1079 seq = seqbase->first;
1081 if (seq->startdisp <= cfra && seq->enddisp > cfra) {
1082 seq_arr[seq->machine] = seq;
1091 int evaluate_seq_frame(Scene *scene, int cfra)
1093 Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1094 Sequence *seq_arr[MAXSEQ + 1];
1096 if (ed == NULL) return 0;
1097 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1100 static int video_seq_is_rendered(Sequence *seq)
1102 return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM);
1105 static int get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequence **seq_arr_out)
1107 Sequence *seq_arr[MAXSEQ + 1];
1115 if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1119 for (; b > 0; b--) {
1120 if (video_seq_is_rendered(seq_arr[b])) {
1128 for (; b > 0; b--) {
1129 if (video_seq_is_rendered(seq_arr[b])) {
1130 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1136 for (; b <= chanshown && b >= 0; b++) {
1137 if (video_seq_is_rendered(seq_arr[b])) {
1138 seq_arr_out[cnt++] = seq_arr[b];
1146 /* **********************************************************************
1148 * ********************************************************************** */
1150 typedef struct SeqIndexBuildContext {
1151 struct IndexBuildContext *index_context;
1159 Sequence *seq, *orig_seq;
1160 } SeqIndexBuildContext;
1162 #define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE)
1164 static IMB_Proxy_Size seq_rendersize_to_proxysize(int size)
1167 return IMB_PROXY_NONE;
1170 return IMB_PROXY_100;
1173 return IMB_PROXY_75;
1176 return IMB_PROXY_50;
1178 return IMB_PROXY_25;
1181 static double seq_rendersize_to_scale_factor(int size)
1195 static void seq_open_anim_file(Sequence *seq)
1197 char name[FILE_MAX];
1200 if (seq->anim != NULL) {
1204 BLI_join_dirfile(name, sizeof(name),
1205 seq->strip->dir, seq->strip->stripdata->name);
1206 BLI_path_abs(name, G.main->name);
1208 seq->anim = openanim(name, IB_rect |
1209 ((seq->flag & SEQ_FILTERY) ?
1210 IB_animdeinterlace : 0), seq->streamindex);
1212 if (seq->anim == NULL) {
1216 proxy = seq->strip->proxy;
1218 if (proxy == NULL) {
1222 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1223 IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
1228 static int seq_proxy_get_fname(Sequence *seq, int cfra, int render_size, char *name)
1231 char dir[PROXY_MAXFILE];
1233 if (!seq->strip->proxy) {
1237 /* MOVIE tracks (only exception: custom files) are now handled
1238 * internally by ImBuf module for various reasons: proper time code
1239 * support, quicker index build, using one file instead
1240 * of a full directory of jpeg files, etc. Trying to support old
1241 * and new method at once could lead to funny effects, if people
1242 * have both, a directory full of jpeg files and proxy avis, so
1243 * sorry folks, please rebuild your proxies... */
1245 if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR | SEQ_USE_PROXY_CUSTOM_FILE)) {
1246 BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
1248 else if (seq->type == SEQ_TYPE_IMAGE) {
1249 BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
1255 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1256 BLI_join_dirfile(name, PROXY_MAXFILE,
1257 dir, seq->strip->proxy->file);
1258 BLI_path_abs(name, G.main->name);
1263 /* generate a separate proxy directory for each preview size */
1265 if (seq->type == SEQ_TYPE_IMAGE) {
1266 BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
1268 give_stripelem(seq, cfra)->name);
1272 frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs;
1273 BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1277 BLI_path_abs(name, G.main->name);
1278 BLI_path_frame(name, frameno, 0);
1280 strcat(name, ".jpg");
1285 static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra)
1287 char name[PROXY_MAXFILE];
1288 IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context.preview_render_size);
1290 int render_size = context.preview_render_size;
1292 /* dirty hack to distinguish 100% render size from PROXY_100 */
1293 if (render_size == 99) {
1297 if (!(seq->flag & SEQ_USE_PROXY)) {
1301 size_flags = seq->strip->proxy->build_size_flags;
1303 /* only use proxies, if they are enabled (even if present!) */
1304 if (psize == IMB_PROXY_NONE || ((size_flags & psize) != psize)) {
1308 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1309 int frameno = (int)give_stripelem_index(seq, cfra) + seq->anim_startofs;
1310 if (seq->strip->proxy->anim == NULL) {
1311 if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
1315 seq->strip->proxy->anim = openanim(name, IB_rect, 0);
1317 if (seq->strip->proxy->anim == NULL) {
1321 seq_open_anim_file(seq);
1323 frameno = IMB_anim_index_get_frame_index(seq->anim, seq->strip->proxy->tc,
1326 return IMB_anim_absolute(seq->strip->proxy->anim, frameno,
1327 IMB_TC_NONE, IMB_PROXY_NONE);
1330 if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
1334 if (BLI_exists(name)) {
1335 return IMB_loadiffname(name, IB_rect);
1342 static void seq_proxy_build_frame(SeqRenderData context,
1343 Sequence *seq, int cfra,
1344 int proxy_render_size)
1346 char name[PROXY_MAXFILE];
1352 if (!seq_proxy_get_fname(seq, cfra, proxy_render_size, name)) {
1356 ibuf = seq_render_strip(context, seq, cfra);
1358 rectx = (proxy_render_size * context.scene->r.xsch) / 100;
1359 recty = (proxy_render_size * context.scene->r.ysch) / 100;
1361 if (ibuf->x != rectx || ibuf->y != recty) {
1362 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1365 /* depth = 32 is intentionally left in, otherwise ALPHA channels
1367 quality = seq->strip->proxy->quality;
1368 ibuf->ftype = JPG | quality;
1370 /* unsupported feature only confuses other s/w */
1371 if (ibuf->planes == 32)
1374 BLI_make_existing_file(name);
1376 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1381 IMB_freeImBuf(ibuf);
1384 struct SeqIndexBuildContext *seq_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq)
1386 SeqIndexBuildContext *context;
1389 if (!seq->strip || !seq->strip->proxy) {
1393 if (!(seq->flag & SEQ_USE_PROXY)) {
1397 context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context");
1399 nseq = seq_dupli_recursive(scene, scene, seq, 0);
1401 context->tc_flags = nseq->strip->proxy->build_tc_flags;
1402 context->size_flags = nseq->strip->proxy->build_size_flags;
1403 context->quality = nseq->strip->proxy->quality;
1405 context->bmain = bmain;
1406 context->scene = scene;
1407 context->orig_seq = seq;
1408 context->seq = nseq;
1410 if (nseq->type == SEQ_TYPE_MOVIE) {
1411 seq_open_anim_file(nseq);
1414 context->index_context = IMB_anim_index_rebuild_context(nseq->anim,
1415 context->tc_flags, context->size_flags, context->quality);
1422 void seq_proxy_rebuild(SeqIndexBuildContext *context, short *stop, short *do_update, float *progress)
1424 SeqRenderData render_context;
1425 Sequence *seq = context->seq;
1426 Scene *scene = context->scene;
1429 if (seq->type == SEQ_TYPE_MOVIE) {
1430 if (context->index_context) {
1431 IMB_anim_index_rebuild(context->index_context, stop, do_update, progress);
1437 if (!(seq->flag & SEQ_USE_PROXY)) {
1441 /* that's why it is called custom... */
1442 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1446 /* fail safe code */
1448 render_context = seq_new_render_data(
1449 context->bmain, context->scene,
1450 (scene->r.size * (float)scene->r.xsch) / 100.0f + 0.5f,
1451 (scene->r.size * (float)scene->r.ysch) / 100.0f + 0.5f,
1454 for (cfra = seq->startdisp + seq->startstill;
1455 cfra < seq->enddisp - seq->endstill; cfra++)
1457 if (context->size_flags & IMB_PROXY_25) {
1458 seq_proxy_build_frame(render_context, seq, cfra, 25);
1460 if (context->size_flags & IMB_PROXY_50) {
1461 seq_proxy_build_frame(render_context, seq, cfra, 50);
1463 if (context->size_flags & IMB_PROXY_75) {
1464 seq_proxy_build_frame(render_context, seq, cfra, 75);
1466 if (context->size_flags & IMB_PROXY_100) {
1467 seq_proxy_build_frame(render_context, seq, cfra, 100);
1470 *progress = (float)cfra / (seq->enddisp - seq->endstill -
1471 seq->startdisp + seq->startstill);
1474 if (*stop || G.afbreek)
1479 void seq_proxy_rebuild_finish(SeqIndexBuildContext *context, short stop)
1481 if (context->index_context) {
1482 IMB_close_anim_proxies(context->seq->anim);
1483 IMB_close_anim_proxies(context->orig_seq->anim);
1484 IMB_anim_index_rebuild_finish(context->index_context, stop);
1487 seq_free_sequence_recurse(context->scene, context->seq);
1492 /* **********************************************************************
1494 * ********************************************************************** */
1496 static StripColorBalance calc_cb(StripColorBalance *cb_)
1498 StripColorBalance cb = *cb_;
1501 for (c = 0; c < 3; c++) {
1502 cb.lift[c] = 2.0f - cb.lift[c];
1505 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1506 for (c = 0; c < 3; c++) {
1507 /* tweak to give more subtle results
1508 * values above 1.0 are scaled */
1509 if (cb.lift[c] > 1.0f)
1510 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
1512 cb.lift[c] = 2.0f - cb.lift[c];
1516 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1517 for (c = 0; c < 3; c++) {
1518 if (cb.gain[c] != 0.0f) {
1519 cb.gain[c] = 1.0f / cb.gain[c];
1522 cb.gain[c] = 1000000; /* should be enough :) */
1527 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1528 for (c = 0; c < 3; c++) {
1529 if (cb.gamma[c] != 0.0f) {
1530 cb.gamma[c] = 1.0f / cb.gamma[c];
1533 cb.gamma[c] = 1000000; /* should be enough :) */
1541 /* note: lift is actually 2-lift */
1542 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
1544 float x = (((in - 1.0f) * lift) + 1.0f) * gain;
1547 if (x < 0.f) x = 0.f;
1549 return powf(x, gamma) * mul;
1552 static void make_cb_table_byte(float lift, float gain, float gamma,
1553 unsigned char *table, float mul)
1557 for (y = 0; y < 256; y++) {
1558 float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1559 table[y] = FTOCHAR(v);
1563 static void make_cb_table_float(float lift, float gain, float gamma,
1564 float *table, float mul)
1568 for (y = 0; y < 256; y++) {
1569 float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
1574 static void color_balance_byte_byte(Sequence *seq, ImBuf *ibuf, float mul)
1576 unsigned char cb_tab[3][256];
1578 unsigned char *p = (unsigned char *) ibuf->rect;
1579 unsigned char *e = p + ibuf->x * 4 * ibuf->y;
1581 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1583 for (c = 0; c < 3; c++) {
1584 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1589 p[0] = cb_tab[0][p[0]];
1590 p[1] = cb_tab[1][p[1]];
1591 p[2] = cb_tab[2][p[2]];
1597 static void color_balance_byte_float(Sequence *seq, ImBuf *ibuf, float mul)
1599 float cb_tab[4][256];
1601 unsigned char *p = (unsigned char *) ibuf->rect;
1602 unsigned char *e = p + ibuf->x * 4 * ibuf->y;
1604 StripColorBalance cb;
1606 imb_addrectfloatImBuf(ibuf);
1608 o = ibuf->rect_float;
1610 cb = calc_cb(seq->strip->color_balance);
1612 for (c = 0; c < 3; c++) {
1613 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
1616 for (i = 0; i < 256; i++) {
1617 cb_tab[3][i] = ((float)i) * (1.0f / 255.0f);
1621 o[0] = cb_tab[0][p[0]];
1622 o[1] = cb_tab[1][p[1]];
1623 o[2] = cb_tab[2][p[2]];
1624 o[3] = cb_tab[3][p[3]];
1630 static void color_balance_float_float(Sequence *seq, ImBuf *ibuf, float mul)
1632 float *p = ibuf->rect_float;
1633 float *e = ibuf->rect_float + ibuf->x * 4 * ibuf->y;
1634 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1638 for (c = 0; c < 3; c++) {
1639 p[c] = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
1645 static void color_balance(Sequence *seq, ImBuf *ibuf, float mul)
1647 if (ibuf->rect_float) {
1648 color_balance_float_float(seq, ibuf, mul);
1650 else if (seq->flag & SEQ_MAKE_FLOAT) {
1651 color_balance_byte_float(seq, ibuf, mul);
1654 color_balance_byte_byte(seq, ibuf, mul);
1659 * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE
1661 * Do all the things you can't really do afterwards using sequence effects
1662 * (read: before rescaling to render resolution has been done)
1664 * Order is important!
1667 * - Crop and transform in image source coordinate space
1668 * - Flip X + Flip Y (could be done afterwards, backward compatibility)
1669 * - Promote image to float data (affects pipeline operations afterwards)
1670 * - Color balance (is most efficient in the byte -> float
1671 * (future: half -> float should also work fine!)
1672 * case, if done on load, since we can use lookup tables)
1676 int input_have_to_preprocess(
1677 SeqRenderData UNUSED(context), Sequence *seq, float UNUSED(cfra))
1681 if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX |
1682 SEQ_FLIPY | SEQ_USE_COLOR_BALANCE | SEQ_MAKE_PREMUL))
1689 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
1690 mul *= seq->blend_opacity / 100.0f;
1697 if (seq->sat != 1.0f) {
1704 static ImBuf *input_preprocess(
1705 SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf *ibuf,
1706 int is_proxy_image, int is_preprocessed)
1710 ibuf = IMB_makeSingleUser(ibuf);
1712 if ((seq->flag & SEQ_FILTERY) &&
1713 !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP))
1718 if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
1720 StripTransform t = {0};
1722 double xscale = 1.0;
1723 double yscale = 1.0;
1725 if (is_proxy_image) {
1726 double f = seq_rendersize_to_scale_factor(
1727 context.preview_render_size);
1731 ibuf, ibuf->x / f, ibuf->y / f);
1735 if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1736 c = *seq->strip->crop;
1738 if (seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1739 t = *seq->strip->transform;
1742 xscale = context.scene->r.xsch ?
1743 ((double) context.rectx /
1744 (double) context.scene->r.xsch) : 1.0;
1745 yscale = context.scene->r.ysch ?
1746 ((double) context.recty /
1747 (double) context.scene->r.ysch) : 1.0;
1749 c.left *= xscale; c.right *= xscale;
1750 c.top *= yscale; c.bottom *= yscale;
1752 t.xofs *= xscale; t.yofs *= yscale;
1754 sx = ibuf->x - c.left - c.right;
1755 sy = ibuf->y - c.top - c.bottom;
1759 if (seq->flag & SEQ_USE_TRANSFORM) {
1760 if (is_preprocessed) {
1765 dx = context.scene->r.xsch;
1766 dy = context.scene->r.ysch;
1770 if (c.top + c.bottom >= ibuf->y ||
1771 c.left + c.right >= ibuf->x ||
1772 t.xofs >= dx || t.yofs >= dy)
1774 make_black_ibuf(ibuf);
1777 ImBuf *i = IMB_allocImBuf(
1779 ibuf->rect_float ? IB_rectfloat : IB_rect);
1781 IMB_rectcpy(i, ibuf,
1782 t.xofs, t.yofs, c.left, c.bottom, sx, sy);
1784 IMB_freeImBuf(ibuf);
1790 if (seq->flag & SEQ_FLIPX) {
1794 if (seq->flag & SEQ_FLIPY) {
1798 if (seq->sat != 1.0f) {
1799 IMB_saturation(ibuf, seq->sat);
1804 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
1805 mul *= seq->blend_opacity / 100.0f;
1808 if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1809 color_balance(seq, ibuf, mul);
1813 if (seq->flag & SEQ_MAKE_FLOAT) {
1814 if (!ibuf->rect_float)
1815 IMB_float_from_rect_simple(ibuf);
1818 imb_freerectImBuf(ibuf);
1823 multibuf(ibuf, mul);
1826 if (seq->flag & SEQ_MAKE_PREMUL) {
1827 if (ibuf->planes == 32 && ibuf->zbuf == NULL) {
1828 IMB_premultiply_alpha(ibuf);
1833 if (ibuf->x != context.rectx || ibuf->y != context.recty) {
1834 if (context.scene->r.mode & R_OSA) {
1835 IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
1838 IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
1844 static ImBuf *copy_from_ibuf_still(SeqRenderData context, Sequence *seq,
1851 ibuf = seq_stripelem_cache_get(
1852 context, seq, seq->start,
1853 SEQ_STRIPELEM_IBUF_STARTSTILL);
1855 else if (nr == seq->len - 1) {
1856 ibuf = seq_stripelem_cache_get(
1857 context, seq, seq->start,
1858 SEQ_STRIPELEM_IBUF_ENDSTILL);
1862 rval = IMB_dupImBuf(ibuf);
1863 IMB_freeImBuf(ibuf);
1869 static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr,
1872 if (nr == 0 || nr == seq->len - 1) {
1873 /* we have to store a copy, since the passed ibuf
1874 * could be preprocessed afterwards (thereby silently
1875 * changing the cached image... */
1876 ibuf = IMB_dupImBuf(ibuf);
1879 seq_stripelem_cache_put(
1880 context, seq, seq->start,
1881 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
1884 if (nr == seq->len - 1) {
1885 seq_stripelem_cache_put(
1886 context, seq, seq->start,
1887 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
1890 IMB_freeImBuf(ibuf);
1894 /* **********************************************************************
1895 * strip rendering functions
1896 * ********************************************************************** */
1898 static ImBuf *seq_render_strip_stack(
1899 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
1901 static ImBuf *seq_render_strip(
1902 SeqRenderData context, Sequence *seq, float cfra);
1905 static ImBuf *seq_render_effect_strip_impl(
1906 SeqRenderData context, Sequence *seq, float cfra)
1911 struct SeqEffectHandle sh = get_sequence_effect(seq);
1917 ibuf[0] = ibuf[1] = ibuf[2] = NULL;
1919 input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3;
1921 if (!sh.execute) { /* effect not supported in this version... */
1922 out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
1926 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
1927 sh.get_default_fac(seq, cfra, &fac, &facf);
1929 if ((context.scene->r.mode & R_FIELDS) == 0)
1933 fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
1935 fac = facf = evaluate_fcurve(fcu, cfra);
1936 if (context.scene->r.mode & R_FIELDS) {
1937 facf = evaluate_fcurve(fcu, cfra + 0.5f);
1941 fac = facf = seq->effect_fader;
1945 early_out = sh.early_out(seq, fac, facf);
1947 switch (early_out) {
1948 case EARLY_NO_INPUT:
1949 out = sh.execute(context, seq, cfra, fac, facf,
1952 case EARLY_DO_EFFECT:
1953 for (i = 0; i < 3; i++) {
1955 ibuf[i] = seq_render_strip(
1956 context, input[i], cfra);
1959 if (ibuf[0] && ibuf[1]) {
1960 out = sh.execute(context, seq, cfra, fac, facf,
1961 ibuf[0], ibuf[1], ibuf[2]);
1964 case EARLY_USE_INPUT_1:
1966 ibuf[0] = seq_render_strip(context, input[0], cfra);
1969 if (input_have_to_preprocess(context, seq, cfra)) {
1970 out = IMB_dupImBuf(ibuf[0]);
1978 case EARLY_USE_INPUT_2:
1980 ibuf[1] = seq_render_strip(context, input[1], cfra);
1983 if (input_have_to_preprocess(context, seq, cfra)) {
1984 out = IMB_dupImBuf(ibuf[1]);
1994 for (i = 0; i < 3; i++) {
1995 IMB_freeImBuf(ibuf[i]);
1999 out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
2005 static ImBuf *seq_render_movieclip_strip(
2006 SeqRenderData context, Sequence *seq, float nr)
2010 float tloc[2], tscale, tangle;
2016 memset(&user, 0, sizeof(MovieClipUser));
2018 BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs);
2020 user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
2022 switch (seq_rendersize_to_proxysize(context.preview_render_size)) {
2023 case IMB_PROXY_NONE:
2024 user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
2027 user.render_size = MCLIP_PROXY_RENDER_SIZE_100;
2030 user.render_size = MCLIP_PROXY_RENDER_SIZE_75;
2033 user.render_size = MCLIP_PROXY_RENDER_SIZE_50;
2036 user.render_size = MCLIP_PROXY_RENDER_SIZE_25;
2040 if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_UNDISTORTED) {
2041 user.render_flag = MCLIP_PROXY_RENDER_UNDISTORT;
2044 if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_STABILIZED) {
2045 ibuf = BKE_movieclip_get_stable_ibuf(
2046 seq->clip, &user, tloc, &tscale, &tangle,
2050 ibuf = BKE_movieclip_get_ibuf_flag(
2051 seq->clip, &user, 0, MOVIECLIP_CACHE_SKIP);
2058 static ImBuf *seq_render_mask_strip(
2059 SeqRenderData context, Sequence *seq, float nr)
2061 /* TODO - add option to rasterize to alpha imbuf? */
2070 BKE_mask_evaluate(seq->mask, seq->mask->sfra + nr, TRUE);
2072 maskbuf = MEM_callocN(sizeof(float) * context.rectx * context.recty, __func__);
2074 if (seq->flag & SEQ_MAKE_FLOAT) {
2079 ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rectfloat);
2081 BKE_mask_rasterize(seq->mask,
2082 context.rectx, context.recty,
2085 FALSE, /*XXX- TODO: make on/off for anti-aliasing */
2086 TRUE /*XXX- TODO: make on/off for feather */
2090 fp_dst = ibuf->rect_float;
2091 i = context.rectx * context.recty;
2093 fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src;
2103 unsigned char *ub_dst;
2105 ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
2107 BKE_mask_rasterize(seq->mask,
2108 context.rectx, context.recty,
2111 FALSE, /*XXX- TODO: make on/off for anti-aliasing */
2112 TRUE /*XXX- TODO: make on/off for feather */
2116 ub_dst = (unsigned char *)ibuf->rect;
2117 i = context.rectx * context.recty;
2119 ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */
2132 static ImBuf *seq_render_scene_strip(
2133 SeqRenderData context, Sequence *seq, float nr)
2139 ListBase oldmarkers;
2142 * Hack! This function can be called from do_render_seq(), in that case
2143 * the seq->scene can already have a Render initialized with same name,
2144 * so we have to use a default name. (compositor uses scene name to
2146 * However, when called from within the UI (image preview in sequencer)
2147 * we do want to use scene Render, that way the render result is defined
2148 * for display in render/imagewindow
2150 * Hmm, don't see, why we can't do that all the time,
2151 * and since G.rendering is uhm, gone... (Peter)
2155 * Using the same name for the renders works just fine as the do_render_seq()
2156 * render is not used while the scene strips are rendered.
2158 * However rendering from UI (through sequencer_preview_area_draw) can crash in
2159 * very many cases since other renders (material preview, an actual render etc.)
2160 * can be started while this sequence preview render is running. The only proper
2161 * solution is to make the sequencer preview render a proper job, which can be
2162 * stopped when needed. This would also give a nice progress bar for the preview
2163 * space so that users know there's something happening.
2165 * As a result the active scene now only uses OpenGL rendering for the sequencer
2166 * preview. This is far from nice, but is the only way to prevent crashes at this
2172 int rendering = G.rendering;
2174 int doseq_gl = G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1;
2175 int have_seq = FALSE;
2178 /* don't refer to seq->scene above this point!, it can be NULL */
2179 if (seq->scene == NULL) {
2184 frame = scene->r.sfra + nr + seq->anim_startofs;
2186 have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
2188 oldcfra = scene->r.cfra;
2189 scene->r.cfra = frame;
2191 if (seq->scene_camera)
2192 camera = seq->scene_camera;
2194 BKE_scene_camera_switch_update(scene);
2195 camera = scene->camera;
2198 if (have_seq == FALSE && camera == NULL) {
2199 scene->r.cfra = oldcfra;
2203 /* prevent eternal loop */
2204 doseq = context.scene->r.scemode & R_DOSEQ;
2205 context.scene->r.scemode &= ~R_DOSEQ;
2207 #ifdef DURIAN_CAMERA_SWITCH
2208 /* stooping to new low's in hackyness :( */
2209 oldmarkers = scene->markers;
2210 scene->markers.first = scene->markers.last = NULL;
2215 if (sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq == 0) && camera) {
2216 char err_out[256] = "unknown";
2217 /* for old scened this can be uninitialized,
2218 * should probably be added to do_versions at some point if the functionality stays */
2219 if (context.scene->r.seq_prev_type == 0)
2220 context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */;
2222 /* opengl offscreen render */
2223 BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
2224 ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty,
2225 IB_rect, context.scene->r.seq_prev_type, TRUE, err_out);
2227 fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
2231 Render *re = RE_GetRender(scene->id.name);
2234 /* XXX: this if can be removed when sequence preview rendering uses the job system */
2235 if (rendering || context.scene != scene) {
2237 re = RE_NewRender(scene->id.name);
2239 RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
2241 /* restore previous state after it was toggled on & off by RE_BlenderFrame */
2242 G.rendering = rendering;
2245 RE_AcquireResultImage(re, &rres);
2248 ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
2249 memcpy(ibuf->rect_float, rres.rectf, 4 * sizeof(float) * rres.rectx * rres.recty);
2251 addzbuffloatImBuf(ibuf);
2252 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty);
2255 /* float buffers in the sequencer are not linear */
2256 if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
2257 ibuf->profile = IB_PROFILE_LINEAR_RGB;
2259 ibuf->profile = IB_PROFILE_NONE;
2260 IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
2262 else if (rres.rect32) {
2263 ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
2264 memcpy(ibuf->rect, rres.rect32, 4 * rres.rectx * rres.recty);
2267 RE_ReleaseResultImage(re);
2269 // BIF_end_render_callbacks();
2273 context.scene->r.scemode |= doseq;
2275 scene->r.cfra = oldcfra;
2277 if (frame != oldcfra)
2278 BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
2280 #ifdef DURIAN_CAMERA_SWITCH
2281 /* stooping to new low's in hackyness :( */
2282 scene->markers = oldmarkers;
2288 static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
2291 char name[FILE_MAX];
2292 int use_preprocess = input_have_to_preprocess(context, seq, cfra);
2293 int is_proxy_image = FALSE;
2294 float nr = give_stripelem_index(seq, cfra);
2295 /* all effects are handled similarly with the exception of speed effect */
2296 int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
2297 int is_preprocessed = !ELEM3(type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE);
2299 ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
2301 /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
2302 * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
2304 use_preprocess = FALSE;
2307 ibuf = copy_from_ibuf_still(context, seq, nr);
2309 /* MOVIECLIPs have their own proxy management */
2310 if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
2311 ibuf = seq_proxy_fetch(context, seq, cfra);
2312 is_proxy_image = (ibuf != NULL);
2315 if (ibuf == NULL) switch (type) {
2318 ImBuf *meta_ibuf = NULL;
2320 if (seq->seqbase.first)
2321 meta_ibuf = seq_render_strip_stack(
2322 context, &seq->seqbase,
2323 seq->start + nr, 0);
2327 if (ibuf && use_preprocess) {
2328 ImBuf *i = IMB_dupImBuf(ibuf);
2330 IMB_freeImBuf(ibuf);
2338 case SEQ_TYPE_SPEED:
2340 ImBuf *child_ibuf = NULL;
2343 SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
2345 sequence_effect_speed_rebuild_map(context.scene, seq, 0);
2348 f_cfra = seq->start + s->frameMap[(int)nr];
2350 child_ibuf = seq_render_strip(context, seq->seq1, f_cfra);
2354 if (ibuf && use_preprocess) {
2355 ImBuf *i = IMB_dupImBuf(ibuf);
2357 IMB_freeImBuf(ibuf);
2364 case SEQ_TYPE_EFFECT:
2366 ibuf = seq_render_effect_strip_impl(
2367 context, seq, seq->start + nr);
2370 case SEQ_TYPE_IMAGE:
2372 StripElem *s_elem = give_stripelem(seq, cfra);
2375 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
2376 BLI_path_abs(name, G.main->name);
2379 if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
2380 /* we don't need both (speed reasons)! */
2381 if (ibuf->rect_float && ibuf->rect)
2382 imb_freerectImBuf(ibuf);
2384 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
2385 if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
2386 IMB_convert_profile(ibuf, IB_PROFILE_NONE);
2388 copy_to_ibuf_still(context, seq, nr, ibuf);
2390 s_elem->orig_width = ibuf->x;
2391 s_elem->orig_height = ibuf->y;
2395 case SEQ_TYPE_MOVIE:
2397 seq_open_anim_file(seq);
2400 IMB_anim_set_preseek(seq->anim,
2403 ibuf = IMB_anim_absolute(
2404 seq->anim, nr + seq->anim_startofs,
2406 seq->strip->proxy->tc :
2408 seq_rendersize_to_proxysize(
2409 context.preview_render_size));
2411 /* we don't need both (speed reasons)! */
2412 if (ibuf && ibuf->rect_float && ibuf->rect)
2413 imb_freerectImBuf(ibuf);
2415 seq->strip->stripdata->orig_width = ibuf->x;
2416 seq->strip->stripdata->orig_height = ibuf->y;
2419 copy_to_ibuf_still(context, seq, nr, ibuf);
2422 case SEQ_TYPE_SCENE:
2423 { // scene can be NULL after deletions
2424 ibuf = seq_render_scene_strip(context, seq, nr);
2426 /* Scene strips update all animation, so we need to restore original state.*/
2427 BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
2429 copy_to_ibuf_still(context, seq, nr, ibuf);
2432 case SEQ_TYPE_MOVIECLIP:
2434 ibuf = seq_render_movieclip_strip(context, seq, nr);
2436 if (ibuf && use_preprocess) {
2437 ImBuf *i = IMB_dupImBuf(ibuf);
2439 IMB_freeImBuf(ibuf);
2444 copy_to_ibuf_still(context, seq, nr, ibuf);
2449 /* ibuf is alwats new */
2450 ibuf = seq_render_mask_strip(context, seq, nr);
2452 copy_to_ibuf_still(context, seq, nr, ibuf);
2458 ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
2460 if (ibuf->x != context.rectx || ibuf->y != context.recty)
2461 use_preprocess = TRUE;
2464 ibuf = input_preprocess(context, seq, cfra, ibuf,
2465 is_proxy_image, is_preprocessed);
2467 seq_stripelem_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
2472 /* **********************************************************************
2473 * strip stack rendering functions
2474 * ********************************************************************** */
2476 static int seq_must_swap_input_in_blend_mode(Sequence *seq)
2478 int swap_input = FALSE;
2480 /* bad hack, to fix crazy input ordering of
2481 * those two effects */
2483 if (ELEM3(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) {
2490 static int seq_get_early_out_for_blend_mode(Sequence *seq)
2492 struct SeqEffectHandle sh = get_sequence_blend(seq);
2493 float facf = seq->blend_opacity / 100.0f;
2494 int early_out = sh.early_out(seq, facf, facf);
2496 if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) {
2500 if (seq_must_swap_input_in_blend_mode(seq)) {
2501 if (early_out == EARLY_USE_INPUT_2) {
2502 return EARLY_USE_INPUT_1;
2504 else if (early_out == EARLY_USE_INPUT_1) {
2505 return EARLY_USE_INPUT_2;
2511 static ImBuf *seq_render_strip_stack(
2512 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown)
2514 Sequence *seq_arr[MAXSEQ + 1];
2519 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2525 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
2526 if (scene->r.cfra != cfra) {
2527 // XXX for prefetch and overlay offset!..., very bad!!!
2528 AnimData *adt = BKE_animdata_from_id(&scene->id);
2529 BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
2533 out = seq_stripelem_cache_get(context, seq_arr[count - 1],
2534 cfra, SEQ_STRIPELEM_IBUF_COMP);
2541 out = seq_render_strip(context, seq_arr[0], cfra);
2542 seq_stripelem_cache_put(context, seq_arr[0], cfra,
2543 SEQ_STRIPELEM_IBUF_COMP, out);
2549 for (i = count - 1; i >= 0; i--) {
2551 Sequence *seq = seq_arr[i];
2553 out = seq_stripelem_cache_get(
2554 context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP);
2559 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2560 out = seq_render_strip(context, seq, cfra);
2564 early_out = seq_get_early_out_for_blend_mode(seq);
2566 switch (early_out) {
2567 case EARLY_NO_INPUT:
2568 case EARLY_USE_INPUT_2:
2569 out = seq_render_strip(context, seq, cfra);
2571 case EARLY_USE_INPUT_1:
2573 out = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
2576 case EARLY_DO_EFFECT:
2578 out = seq_render_strip(context, seq, cfra);
2588 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2589 SEQ_STRIPELEM_IBUF_COMP, out);
2594 for (; i < count; i++) {
2595 Sequence *seq = seq_arr[i];
2597 if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
2598 struct SeqEffectHandle sh = get_sequence_blend(seq);
2600 ImBuf *ibuf2 = seq_render_strip(context, seq, cfra);
2602 float facf = seq->blend_opacity / 100.0f;
2603 int swap_input = seq_must_swap_input_in_blend_mode(seq);
2606 out = sh.execute(context, seq, cfra,
2608 ibuf2, ibuf1, NULL);
2611 out = sh.execute(context, seq, cfra,
2613 ibuf1, ibuf2, NULL);
2616 IMB_freeImBuf(ibuf1);
2617 IMB_freeImBuf(ibuf2);
2620 seq_stripelem_cache_put(context, seq_arr[i], cfra,
2621 SEQ_STRIPELEM_IBUF_COMP, out);
2628 * returned ImBuf is refed!
2629 * you have to free after usage!
2632 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown)
2634 Editing *ed = BKE_sequencer_editing_get(context.scene, FALSE);
2638 if (ed == NULL) return NULL;
2640 count = BLI_countlist(&ed->metastack);
2641 if ((chanshown < 0) && (count > 0)) {
2642 count = MAX2(count + chanshown, 0);
2643 seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
2646 seqbasep = ed->seqbasep;
2649 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2652 ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chanshown, ListBase *seqbasep)
2654 return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
2658 ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq)
2660 return seq_render_strip(context, seq, cfra);
2664 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2665 static int seq_can_blend(Sequence *seq)
2667 if (ELEM4(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIE)) {
2676 /* *********************** threading api ******************* */
2678 static ListBase running_threads;
2679 static ListBase prefetch_wait;
2680 static ListBase prefetch_done;
2682 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2683 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2684 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2686 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2687 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2689 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2690 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2692 static volatile int seq_thread_shutdown = TRUE;
2693 static volatile int seq_last_given_monoton_cfra = 0;
2694 static int monoton_cfra = 0;
2696 typedef struct PrefetchThread {
2697 struct PrefetchThread *next, *prev;
2700 struct PrefetchQueueElem *current;
2706 typedef struct PrefetchQueueElem {
2707 struct PrefetchQueueElem *next, *prev;
2713 int preview_render_size;
2718 } PrefetchQueueElem;
2721 static void *seq_prefetch_thread(void *This_)
2723 PrefetchThread *This = This_;
2725 while (!seq_thread_shutdown) {
2726 PrefetchQueueElem *e;
2729 pthread_mutex_lock(&queue_lock);
2730 e = prefetch_wait.first;
2732 BLI_remlink(&prefetch_wait, e);
2734 s_last = seq_last_given_monoton_cfra;
2738 pthread_mutex_unlock(&queue_lock);
2741 pthread_mutex_lock(&prefetch_ready_lock);
2743 This->running = FALSE;
2745 pthread_cond_signal(&prefetch_ready_cond);
2746 pthread_mutex_unlock(&prefetch_ready_lock);
2748 pthread_mutex_lock(&wakeup_lock);
2749 if (!seq_thread_shutdown) {
2750 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2752 pthread_mutex_unlock(&wakeup_lock);
2756 This->running = TRUE;
2758 if (e->cfra >= s_last) {
2759 e->ibuf = give_ibuf_seq_impl(This->scene,
2760 e->rectx, e->recty, e->cfra, e->chanshown,
2761 e->preview_render_size);
2764 pthread_mutex_lock(&queue_lock);
2766 BLI_addtail(&prefetch_done, e);
2768 for (e = prefetch_wait.first; e; e = e->next) {
2769 if (s_last > e->monoton_cfra) {
2770 BLI_remlink(&prefetch_wait, e);
2775 for (e = prefetch_done.first; e; e = e->next) {
2776 if (s_last > e->monoton_cfra) {
2777 BLI_remlink(&prefetch_done, e);
2782 pthread_mutex_unlock(&queue_lock);
2784 pthread_mutex_lock(&frame_done_lock);
2785 pthread_cond_signal(&frame_done_cond);
2786 pthread_mutex_unlock(&frame_done_lock);
2791 static void seq_start_threads(Scene *scene)
2795 running_threads.first = running_threads.last = NULL;
2796 prefetch_wait.first = prefetch_wait.last = NULL;
2797 prefetch_done.first = prefetch_done.last = NULL;
2799 seq_thread_shutdown = FALSE;
2800 seq_last_given_monoton_cfra = monoton_cfra = 0;
2802 /* since global structures are modified during the processing
2803 * of one frame, only one render thread is currently possible...
2805 * (but we code, in the hope, that we can remove this restriction
2809 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2811 for (i = 0; i < 1; i++) {
2812 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2815 BLI_addtail(&running_threads, t);
2817 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2820 /* init malloc mutex */
2821 BLI_init_threads(0, 0, 0);
2824 static void seq_stop_threads()
2826 PrefetchThread *tslot;
2827 PrefetchQueueElem *e;
2829 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2831 if (seq_thread_shutdown) {
2832 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2836 pthread_mutex_lock(&wakeup_lock);
2838 seq_thread_shutdown = TRUE;
2840 pthread_cond_broadcast(&wakeup_cond);
2841 pthread_mutex_unlock(&wakeup_lock);
2843 for (tslot = running_threads.first; tslot; tslot = tslot->next) {
2844 pthread_join(tslot->pthread, NULL);
2848 for (e = prefetch_wait.first; e; e = e->next) {
2849 BLI_remlink(&prefetch_wait, e);
2853 for (e = prefetch_done.first; e; e = e->next) {
2854 BLI_remlink(&prefetch_done, e);
2858 BLI_freelistN(&running_threads);
2860 /* deinit malloc mutex */
2865 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chanshown)
2867 PrefetchQueueElem *e;
2868 if (seq_thread_shutdown) {
2872 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2873 e->rectx = context.rectx;
2874 e->recty = context.recty;
2876 e->chanshown = chanshown;
2877 e->preview_render_size = context.preview_render_size;
2878 e->monoton_cfra = monoton_cfra++;
2880 pthread_mutex_lock(&queue_lock);
2881 BLI_addtail(&prefetch_wait, e);
2882 pthread_mutex_unlock(&queue_lock);
2884 pthread_mutex_lock(&wakeup_lock);
2885 pthread_cond_signal(&wakeup_cond);
2886 pthread_mutex_unlock(&wakeup_lock);
2890 static void seq_wait_for_prefetch_ready()
2892 PrefetchThread *tslot;
2894 if (seq_thread_shutdown) {
2898 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2900 pthread_mutex_lock(&prefetch_ready_lock);
2903 for (tslot = running_threads.first; tslot; tslot = tslot->next) {
2904 if (tslot->running) {
2911 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2914 pthread_mutex_unlock(&prefetch_ready_lock);
2916 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2920 ImBuf *give_ibuf_seq_threaded(SeqRenderData context, float cfra, int chanshown)
2922 PrefetchQueueElem *e = NULL;
2923 int found_something = FALSE;
2925 if (seq_thread_shutdown) {
2926 return give_ibuf_seq(context, cfra, chanshown);
2930 int success = FALSE;
2931 pthread_mutex_lock(&queue_lock);
2933 for (e = prefetch_done.first; e; e = e->next) {
2934 if (cfra == e->cfra &&
2935 chanshown == e->chanshown &&
2936 context.rectx == e->rectx &&
2937 context.recty == e->recty &&
2938 context.preview_render_size == e->preview_render_size)
2941 found_something = TRUE;
2947 for (e = prefetch_wait.first; e; e = e->next) {
2948 if (cfra == e->cfra &&
2949 chanshown == e->chanshown &&
2950 context.rectx == e->rectx &&
2951 context.recty == e->recty &&
2952 context.preview_render_size == e->preview_render_size)
2954 found_something = TRUE;
2961 PrefetchThread *tslot;
2963 for (tslot = running_threads.first;
2965 tslot = tslot->next)
2967 if (tslot->current &&
2968 cfra == tslot->current->cfra &&
2969 chanshown == tslot->current->chanshown &&
2970 context.rectx == tslot->current->rectx &&
2971 context.recty == tslot->current->recty &&
2972 context.preview_render_size == tslot->current->preview_render_size)
2974 found_something = TRUE;
2980 /* e->ibuf is unrefed by render thread on next round. */
2983 seq_last_given_monoton_cfra = e->monoton_cfra;
2986 pthread_mutex_unlock(&queue_lock);
2991 if (!found_something) {
2993 "SEQ-THREAD: Requested frame "
2994 "not in queue ???\n");
2997 pthread_mutex_lock(&frame_done_lock);
2998 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2999 pthread_mutex_unlock(&frame_done_lock);
3003 return e ? e->ibuf : NULL;
3006 /* Functions to free imbuf and anim data on changes */
3008 static void free_anim_seq(Sequence *seq)
3011 IMB_free_anim(seq->anim);
3016 void free_imbuf_seq(Scene *scene, ListBase *seqbase, int check_mem_usage,
3017 int keep_file_handles)
3021 if (check_mem_usage) {
3022 /* Let the cache limitor take care of this (schlaile) */
3023 /* While render let's keep all memory available for render
3025 * At least if free memory is tight...
3026 * This can make a big difference in encoding speed
3027 * (it is around 4 times(!) faster, if we do not waste time
3028 * on freeing _all_ buffers every time on long timelines...)
3032 uintptr_t mem_in_use;
3033 uintptr_t mmap_in_use;
3036 mem_in_use = MEM_get_memory_in_use();
3037 mmap_in_use = MEM_get_mapped_memory_in_use();
3038 max = MEM_CacheLimiter_get_maximum();
3040 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3045 seq_stripelem_cache_cleanup();
3047 for (seq = seqbase->first; seq; seq = seq->next) {
3049 if (seq->type == SEQ_TYPE_MOVIE && !keep_file_handles)
3051 if (seq->type == SEQ_TYPE_SPEED) {
3052 sequence_effect_speed_rebuild_map(scene, seq, 1);
3055 if (seq->type == SEQ_TYPE_META) {
3056 free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles);
3058 if (seq->type == SEQ_TYPE_SCENE) {
3059 /* FIXME: recurs downwards,
3060 * but do recurs protection somehow! */
3066 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3071 /* recurs downwards to see if this seq depends on the changed seq */
3076 if (seq == changed_seq)
3079 for (subseq = seq->seqbase.first; subseq; subseq = subseq->next)
3080 if (update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3084 if (update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3086 if (seq->seq2 && (seq->seq2 != seq->seq1))
3087 if (update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3089 if (seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3090 if (update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3095 if (seq->type == SEQ_TYPE_MOVIE)
3097 if (seq->type == SEQ_TYPE_SPEED) {
3098 sequence_effect_speed_rebuild_map(scene, seq, 1);
3103 calc_sequence(scene, seq);
3109 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3111 Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
3114 if (ed == NULL) return;
3116 for (seq = ed->seqbase.first; seq; seq = seq->next)
3117 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3120 /* seq funcs's for transforming internally
3121 * notice the difference between start/end and left/right.
3123 * left and right are the bounds at which the sequence is rendered,
3124 * start and end are from the start and fixed length of the sequence.
3126 int seq_tx_get_start(Sequence *seq)
3130 int seq_tx_get_end(Sequence *seq)
3132 return seq->start + seq->len;
3135 int seq_tx_get_final_left(Sequence *seq, int metaclip)
3137 if (metaclip && seq->tmp) {
3138 /* return the range clipped by the parents range */
3139 return MAX2(seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
3142 return (seq->start - seq->startstill) + seq->startofs;
3146 int seq_tx_get_final_right(Sequence *seq, int metaclip)
3148 if (metaclip && seq->tmp) {
3149 /* return the range clipped by the parents range */
3150 return MIN2(seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
3153 return ((seq->start + seq->len) + seq->endstill) - seq->endofs;
3157 void seq_tx_set_final_left(Sequence *seq, int val)
3159 if (val < (seq)->start) {
3160 seq->startstill = abs(val - (seq)->start);
3164 seq->startofs = abs(val - (seq)->start);
3165 seq->startstill = 0;
3169 void seq_tx_set_final_right(Sequence *seq, int val)
3171 if (val > (seq)->start + (seq)->len) {
3172 seq->endstill = abs(val - (seq->start + (seq)->len));
3176 seq->endofs = abs(val - ((seq)->start + (seq)->len));
3181 /* used so we can do a quick check for single image seq
3182 * since they work a bit differently to normal image seq's (during transform) */
3183 int seq_single_check(Sequence *seq)
3185 return ((seq->len == 1) &&
3186 (seq->type == SEQ_TYPE_IMAGE ||
3187 ((seq->type & SEQ_TYPE_EFFECT) &&
3188 get_sequence_effect_num_inputs(seq->type) == 0)));
3191 /* check if the selected seq's reference unselected seq's */
3192 int seqbase_isolated_sel_check(ListBase *seqbase)
3195 /* is there more than 1 select */
3198 for (seq = seqbase->first; seq; seq = seq->next) {
3199 if (seq->flag & SELECT) {
3208 /* test relationships */
3209 for (seq = seqbase->first; seq; seq = seq->next) {
3210 if ((seq->type & SEQ_TYPE_EFFECT) == 0)
3213 if (seq->flag & SELECT) {
3214 if ( (seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
3215 (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
3216 (seq->seq3 && (seq->seq3->flag & SELECT) == 0) )
3222 if ( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
3223 (seq->seq2 && (seq->seq2->flag & SELECT)) ||
3224 (seq->seq3 && (seq->seq3->flag & SELECT)) )
3234 /* use to impose limits when dragging/extending - so impossible situations don't happen
3235 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
3236 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
3239 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
3240 seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0) - 1);
3243 if (seq_single_check(seq) == 0) {
3244 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
3245 seq_tx_set_final_left(seq, seq_tx_get_end(seq) - 1);
3248 /* dosnt work now - TODO */
3250 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
3252 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);