4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
24 * - Blender Foundation, 2003-2009
25 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27 * ***** END GPL LICENSE BLOCK *****
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
38 #include "DNA_listBase.h"
39 #include "DNA_sequence_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_anim_types.h"
43 #include "BKE_global.h"
44 #include "BKE_image.h"
46 #include "BKE_sequencer.h"
47 #include "BKE_fcurve.h"
48 #include "BKE_utildefines.h"
49 #include "RNA_access.h"
50 #include "RE_pipeline.h"
52 #include "BLI_fileops.h"
53 #include "BLI_listbase.h"
54 #include "BLI_path_util.h"
55 #include "BLI_string.h"
56 #include "BLI_threads.h"
59 #include "IMB_imbuf.h"
60 #include "IMB_imbuf_types.h"
64 #include "BKE_context.h"
65 #include "BKE_sound.h"
66 #include "AUD_C-API.h"
69 #define snprintf _snprintf
72 /* **** XXX ******** */
73 static int seqrectx= 0; /* bad bad global! */
74 static int seqrecty= 0;
75 //static void waitcursor(int val) {}
76 //static int blender_test_break() {return 0;}
78 /* **** XXX ******** */
81 void printf_strip(Sequence *seq)
83 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
84 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
85 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));
88 /* **********************************************************************
89 alloc / free functions
90 ********************************************************************** */
92 static void free_tstripdata(int len, TStripElem *se)
101 for(a=0; a<len; a++, se++) {
103 IMB_freeImBuf(se->ibuf);
107 IMB_freeImBuf(se->ibuf_comp);
116 void new_tstripdata(Sequence *seq)
119 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
120 free_tstripdata(seq->strip->endstill,
121 seq->strip->tstripdata_endstill);
122 free_tstripdata(seq->strip->startstill,
123 seq->strip->tstripdata_startstill);
125 seq->strip->tstripdata= 0;
126 seq->strip->tstripdata_endstill= 0;
127 seq->strip->tstripdata_startstill= 0;
129 if(seq->strip->ibuf_startstill) {
130 IMB_freeImBuf(seq->strip->ibuf_startstill);
131 seq->strip->ibuf_startstill = 0;
134 if(seq->strip->ibuf_endstill) {
135 IMB_freeImBuf(seq->strip->ibuf_endstill);
136 seq->strip->ibuf_endstill = 0;
139 seq->strip->len= seq->len;
146 static void free_proxy_seq(Sequence *seq)
148 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
149 IMB_free_anim(seq->strip->proxy->anim);
150 seq->strip->proxy->anim = 0;
154 void seq_free_strip(Strip *strip)
157 if(strip->us>0) return;
159 printf("error: negative users in strip\n");
163 if (strip->stripdata) {
164 MEM_freeN(strip->stripdata);
168 if (strip->proxy->anim) {
169 IMB_free_anim(strip->proxy->anim);
172 MEM_freeN(strip->proxy);
175 MEM_freeN(strip->crop);
177 if (strip->transform) {
178 MEM_freeN(strip->transform);
180 if (strip->color_balance) {
181 MEM_freeN(strip->color_balance);
184 free_tstripdata(strip->len, strip->tstripdata);
185 free_tstripdata(strip->endstill, strip->tstripdata_endstill);
186 free_tstripdata(strip->startstill, strip->tstripdata_startstill);
188 if(strip->ibuf_startstill) {
189 IMB_freeImBuf(strip->ibuf_startstill);
190 strip->ibuf_startstill = 0;
193 if(strip->ibuf_endstill) {
194 IMB_freeImBuf(strip->ibuf_endstill);
195 strip->ibuf_endstill = 0;
201 void seq_free_sequence(Scene *scene, Sequence *seq)
203 Editing *ed = scene->ed;
205 if(seq->strip) seq_free_strip(seq->strip);
207 if(seq->anim) IMB_free_anim(seq->anim);
209 if(seq->sound_handle)
210 sound_delete_handle(scene, seq->sound_handle);
212 if (seq->type & SEQ_EFFECT) {
213 struct SeqEffectHandle sh = get_sequence_effect(seq);
218 if (ed->act_seq==seq)
224 Editing *seq_give_editing(Scene *scene, int alloc)
226 if (scene->ed == NULL && alloc) {
229 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
230 ed->seqbasep= &ed->seqbase;
235 void seq_free_editing(Scene *scene)
237 Editing *ed = scene->ed;
245 seq_free_sequence(scene, seq);
249 while((ms= ed->metastack.first)) {
250 BLI_remlink(&ed->metastack, ms);
257 /* ************************* itterator ************************** */
258 /* *************** (replaces old WHILE_SEQ) ********************* */
259 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
261 /* sequence strip iterator:
262 * - builds a full array, recursively into meta strips */
264 static void seq_count(ListBase *seqbase, int *tot)
268 for(seq=seqbase->first; seq; seq=seq->next) {
271 if(seq->seqbase.first)
272 seq_count(&seq->seqbase, tot);
276 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
280 for(seq=seqbase->first; seq; seq=seq->next) {
283 if(seq->seqbase.first)
284 seq_build_array(&seq->seqbase, array, depth+1);
291 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
302 seq_count(ed->seqbasep, tot);
304 seq_count(&ed->seqbase, tot);
309 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
311 seq_build_array(ed->seqbasep, &array, 0);
313 seq_build_array(&ed->seqbase, &array, 0);
316 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
318 memset(iter, 0, sizeof(*iter));
319 seq_array(ed, &iter->array, &iter->tot, use_pointer);
323 iter->seq= iter->array[iter->cur];
328 void seq_next(SeqIterator *iter)
330 if(++iter->cur < iter->tot)
331 iter->seq= iter->array[iter->cur];
336 void seq_end(SeqIterator *iter)
339 MEM_freeN(iter->array);
345 **********************************************************************
347 **********************************************************************
348 * Build a complete array of _all_ sequencies (including those
350 **********************************************************************
353 static void do_seq_count(ListBase *seqbase, int *totseq)
360 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
365 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
372 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
379 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
384 do_seq_count(seqbase, totseq);
390 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
393 do_build_seqar(seqbase, seqar, 0);
397 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
398 int (*test_func)(Sequence * seq))
404 int test = test_func(seq);
405 if (test & BUILD_SEQAR_COUNT_CURRENT) {
408 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
409 do_seq_count_cb(&seq->seqbase, totseq, test_func);
415 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
416 int (*test_func)(Sequence * seq))
422 int test = test_func(seq);
425 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
426 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
429 if (test & BUILD_SEQAR_COUNT_CURRENT) {
437 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
438 int (*test_func)(Sequence * seq))
443 do_seq_count_cb(seqbase, totseq, test_func);
449 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
452 do_build_seqar_cb(seqbase, seqar, 0, test_func);
457 void calc_sequence_disp(Sequence *seq)
459 if(seq->startofs && seq->startstill) seq->startstill= 0;
460 if(seq->endofs && seq->endstill) seq->endstill= 0;
462 seq->startdisp= seq->start + seq->startofs - seq->startstill;
463 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
465 seq->handsize= 10.0; /* 10 frames */
466 if( seq->enddisp-seq->startdisp < 10 ) {
467 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
469 else if(seq->enddisp-seq->startdisp > 250) {
470 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
473 seq_update_sound(seq);
476 void calc_sequence(Sequence *seq)
481 /* check all metas recursively */
482 seqm= seq->seqbase.first;
484 if(seqm->seqbase.first) calc_sequence(seqm);
488 /* effects and meta: automatic start and end */
490 if(seq->type & SEQ_EFFECT) {
492 if(seq->seq2==0) seq->seq2= seq->seq1;
493 if(seq->seq3==0) seq->seq3= seq->seq1;
495 /* effecten go from seq1 -> seq2: test */
497 /* we take the largest start and smallest end */
499 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
500 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
503 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
504 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
505 seq->len= seq->enddisp - seq->startdisp;
507 calc_sequence_disp(seq);
510 if(seq->strip && seq->len!=seq->strip->len) {
516 if(seq->type==SEQ_META) {
517 seqm= seq->seqbase.first;
522 if(seqm->startdisp < min) min= seqm->startdisp;
523 if(seqm->enddisp > max) max= seqm->enddisp;
526 seq->start= min + seq->anim_startofs;
528 seq->len -= seq->anim_startofs;
529 seq->len -= seq->anim_endofs;
531 if(seq->strip && seq->len!=seq->strip->len) {
536 calc_sequence_disp(seq);
540 void reload_sequence_new_file(Scene *scene, Sequence * seq)
542 char str[FILE_MAXDIR+FILE_MAXFILE];
544 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
545 seq->type == SEQ_SOUND ||
546 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
552 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
553 seq->type != SEQ_IMAGE) {
554 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
555 BLI_convertstringcode(str, G.sce);
556 BLI_convertstringframe(str, scene->r.cfra);
560 if (seq->type == SEQ_IMAGE) {
562 int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
564 seq->len -= seq->anim_startofs;
565 seq->len -= seq->anim_endofs;
569 seq->strip->len = seq->len;
570 } else if (seq->type == SEQ_MOVIE) {
571 if(seq->anim) IMB_free_anim(seq->anim);
572 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
578 seq->len = IMB_anim_get_duration(seq->anim);
580 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
582 seq->len -= seq->anim_startofs;
583 seq->len -= seq->anim_endofs;
587 seq->strip->len = seq->len;
588 } else if (seq->type == SEQ_SOUND) {
589 seq->len = AUD_getInfo(seq->sound->handle).length * FPS;
590 seq->len -= seq->anim_startofs;
591 seq->len -= seq->anim_endofs;
595 seq->strip->len = seq->len;
596 } else if (seq->type == SEQ_SCENE) {
597 Scene * sce = G.main->scene.first;
601 if(nr == seq->scenenr) {
614 BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
615 seqUniqueName(scene->ed->seqbasep, seq);
617 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
618 seq->len -= seq->anim_startofs;
619 seq->len -= seq->anim_endofs;
623 seq->strip->len = seq->len;
631 void sort_seq(Scene *scene)
633 /* all strips together per kind, and in order of y location ("machine") */
634 ListBase seqbase, effbase;
635 Editing *ed= seq_give_editing(scene, FALSE);
636 Sequence *seq, *seqt;
641 seqbase.first= seqbase.last= 0;
642 effbase.first= effbase.last= 0;
644 while( (seq= ed->seqbasep->first) ) {
645 BLI_remlink(ed->seqbasep, seq);
647 if(seq->type & SEQ_EFFECT) {
650 if(seqt->machine>=seq->machine) {
651 BLI_insertlinkbefore(&effbase, seqt, seq);
656 if(seqt==0) BLI_addtail(&effbase, seq);
661 if(seqt->machine>=seq->machine) {
662 BLI_insertlinkbefore(&seqbase, seqt, seq);
667 if(seqt==0) BLI_addtail(&seqbase, seq);
671 addlisttolist(&seqbase, &effbase);
672 *(ed->seqbasep)= seqbase;
676 void clear_scene_in_allseqs(Scene *sce)
682 /* when a scene is deleted: test all seqs */
684 sce1= G.main->scene.first;
686 if(sce1!=sce && sce1->ed) {
691 if(seq->scene==sce) seq->scene= 0;
701 static char *give_seqname_by_type(int type)
704 case SEQ_META: return "Meta";
705 case SEQ_IMAGE: return "Image";
706 case SEQ_SCENE: return "Scene";
707 case SEQ_MOVIE: return "Movie";
708 case SEQ_SOUND: return "Audio";
709 case SEQ_CROSS: return "Cross";
710 case SEQ_GAMCROSS: return "Gamma Cross";
711 case SEQ_ADD: return "Add";
712 case SEQ_SUB: return "Sub";
713 case SEQ_MUL: return "Mul";
714 case SEQ_ALPHAOVER: return "Alpha Over";
715 case SEQ_ALPHAUNDER: return "Alpha Under";
716 case SEQ_OVERDROP: return "Over Drop";
717 case SEQ_WIPE: return "Wipe";
718 case SEQ_GLOW: return "Glow";
719 case SEQ_TRANSFORM: return "Transform";
720 case SEQ_COLOR: return "Color";
721 case SEQ_SPEED: return "Speed";
727 char *give_seqname(Sequence *seq)
729 char * name = give_seqname_by_type(seq->type);
732 if(seq->type<SEQ_EFFECT) {
733 return seq->strip->dir;
734 } else if(seq->type==SEQ_PLUGIN) {
735 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
736 seq->plugin && seq->plugin->doit) {
737 return seq->plugin->pname;
748 /* ***************** DO THE SEQUENCE ***************** */
750 static void make_black_ibuf(ImBuf *ibuf)
756 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
758 tot= ibuf->x*ibuf->y;
761 rect_float = ibuf->rect_float;
764 memset(rect, 0, tot * sizeof(char) * 4);
768 memset(rect_float, 0, tot * sizeof(float) * 4);
772 static void multibuf(ImBuf *ibuf, float fmul)
779 mul= (int)(256.0*fmul);
780 rt= (char *)ibuf->rect;
781 rt_float = ibuf->rect_float;
787 icol= (mul*rt[0])>>8;
788 if(icol>254) rt[0]= 255; else rt[0]= icol;
789 icol= (mul*rt[1])>>8;
790 if(icol>254) rt[1]= 255; else rt[1]= icol;
791 icol= (mul*rt[2])>>8;
792 if(icol>254) rt[2]= 255; else rt[2]= icol;
793 icol= (mul*rt[3])>>8;
794 if(icol>254) rt[3]= 255; else rt[3]= icol;
812 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
814 TStripElem *se1, *se2, *se3;
818 struct SeqEffectHandle sh = get_sequence_effect(seq);
821 if (!sh.execute) { /* effect not supported in this version... */
822 make_black_ibuf(se->ibuf);
826 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
827 sh.get_default_fac(seq, cfra, &fac, &facf);
828 if( scene->r.mode & R_FIELDS ); else facf= fac;
830 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
833 fac = facf = evaluate_fcurve(fcu, cfra);
834 if( scene->r.mode & R_FIELDS ) {
835 facf = evaluate_fcurve(fcu, cfra + 0.5);
838 fac = facf = seq->effect_fader;
842 early_out = sh.early_out(seq, fac, facf);
844 if (early_out == -1) { /* no input needed */
845 sh.execute(scene, seq, cfra, fac, facf,
846 se->ibuf->x, se->ibuf->y,
853 if (se->se1==0 || se->se2==0 || se->se3==0) {
854 make_black_ibuf(se->ibuf);
862 if ( (se1==0 || se2==0 || se3==0)
863 || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
864 make_black_ibuf(se->ibuf);
871 make_black_ibuf(se->ibuf);
877 if (se1 == 0 || se1->ibuf == 0) {
878 make_black_ibuf(se->ibuf);
882 if (se->ibuf != se1->ibuf) {
883 IMB_freeImBuf(se->ibuf);
884 se->ibuf = se1->ibuf;
885 IMB_refImBuf(se->ibuf);
890 make_black_ibuf(se->ibuf);
896 if (se2 == 0 || se2->ibuf == 0) {
897 make_black_ibuf(se->ibuf);
900 if (se->ibuf != se2->ibuf) {
901 IMB_freeImBuf(se->ibuf);
902 se->ibuf = se2->ibuf;
903 IMB_refImBuf(se->ibuf);
907 make_black_ibuf(se->ibuf);
914 if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
915 IMB_float_from_rect(se1->ibuf);
917 if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
918 IMB_float_from_rect(se2->ibuf);
920 if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
921 IMB_float_from_rect(se3->ibuf);
924 if (!se1->ibuf->rect && !se->ibuf->rect_float) {
925 IMB_rect_from_float(se1->ibuf);
927 if (!se2->ibuf->rect && !se->ibuf->rect_float) {
928 IMB_rect_from_float(se2->ibuf);
930 if (!se3->ibuf->rect && !se->ibuf->rect_float) {
931 IMB_rect_from_float(se3->ibuf);
934 sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
938 static int give_stripelem_index(Sequence *seq, int cfra)
942 if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
943 if(seq->len == 0) return -1;
944 if(seq->flag&SEQ_REVERSE_FRAMES) {
945 /*reverse frame in this sequence */
946 if(cfra <= seq->start) nr= seq->len-1;
947 else if(cfra >= seq->start+seq->len-1) nr= 0;
948 else nr= (seq->start + seq->len) - cfra;
950 if(cfra <= seq->start) nr= 0;
951 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
952 else nr= cfra-seq->start;
954 if (seq->strobe < 1.0) seq->strobe = 1.0;
955 if (seq->strobe > 1.0) {
956 nr -= (int)fmod((double)nr, (double)seq->strobe);
962 static TStripElem* alloc_tstripdata(int len, const char * name)
965 TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
966 for (i = 0; i < len; i++) {
967 se[i].ok = STRIPELEM_OK;
972 static TStripElem *give_tstripelem(Sequence *seq, int cfra)
977 se = seq->strip->tstripdata;
978 if (se == 0 && seq->len > 0) {
979 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
982 nr = give_stripelem_index(seq, cfra);
984 if (nr == -1) return 0;
985 if (se == 0) return 0;
989 /* if there are IPOs with blend modes active, one has to watch out
990 for startstill + endstill area: we can't use the same tstripelem
991 here for all ibufs, since then, blending with IPOs won't work!
993 Rather common case, if you use a single image and try to fade
994 it in and out... or want to use your strip as a watermark in
997 if (seq->blend_mode != SEQ_BLEND_REPLACE ||
998 (/*seq->ipo && seq->ipo->curve.first &&*/
999 (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
1000 Strip * s = seq->strip;
1001 if (cfra < seq->start) {
1002 se = s->tstripdata_startstill;
1003 if (seq->startstill > s->startstill) {
1004 free_tstripdata(s->startstill,
1005 s->tstripdata_startstill);
1010 s->startstill = seq->startstill;
1011 se = seq->strip->tstripdata_startstill
1014 "tstripelems_startstill");
1016 se += seq->start - cfra - 1;
1018 } else if (cfra > seq->start + seq->len-1) {
1019 se = s->tstripdata_endstill;
1020 if (seq->endstill > s->endstill) {
1021 free_tstripdata(s->endstill,
1022 s->tstripdata_endstill);
1027 s->endstill = seq->endstill;
1028 se = seq->strip->tstripdata_endstill
1031 "tstripelems_endstill");
1033 se += cfra - (seq->start + seq->len-1) - 1;
1043 StripElem *give_stripelem(Sequence *seq, int cfra)
1048 se = seq->strip->stripdata;
1049 nr = give_stripelem_index(seq, cfra);
1051 if (nr == -1) return 0;
1052 if (se == 0) return 0;
1054 se += nr + seq->anim_startofs;
1059 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1064 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1066 seq= seqbase->first;
1068 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1069 seq_arr[seq->machine]= seq;
1078 int evaluate_seq_frame(Scene *scene, int cfra)
1080 Editing *ed= seq_give_editing(scene, FALSE);
1081 Sequence *seq_arr[MAXSEQ+1];
1083 if(ed==NULL) return 0;
1084 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1087 static int video_seq_is_rendered(Sequence * seq)
1090 && !(seq->flag & SEQ_MUTE)
1091 && seq->type != SEQ_SOUND);
1094 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1096 Sequence *seq_arr[MAXSEQ+1];
1104 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1106 if (seq_arr[b] == 0) {
1110 for (b = MAXSEQ; b > 0; b--) {
1111 if (video_seq_is_rendered(seq_arr[b])) {
1121 if (video_seq_is_rendered(seq_arr[b])) {
1122 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1128 for (;b <= chanshown; b++) {
1129 if (video_seq_is_rendered(seq_arr[b])) {
1130 seq_arr_out[cnt++] = seq_arr[b];
1138 /* **********************************************************************
1140 ********************************************************************** */
1142 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1144 static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size)
1147 char dir[FILE_MAXDIR];
1149 if (!seq->strip->proxy) {
1153 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1154 strcpy(dir, seq->strip->proxy->dir);
1156 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1157 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
1164 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1165 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1166 BLI_convertstringcode(name, G.sce);
1167 BLI_convertstringframe(name, cfra);
1172 /* generate a separate proxy directory for each preview size */
1174 if (seq->type == SEQ_IMAGE) {
1175 StripElem * se = give_stripelem(seq, cfra);
1176 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1177 dir, render_size, se->name);
1179 } else if (seq->type == SEQ_MOVIE) {
1180 TStripElem * tse = give_tstripelem(seq, cfra);
1182 frameno = tse->nr + seq->anim_startofs;
1184 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1185 seq->strip->stripdata->name,
1188 TStripElem * tse = give_tstripelem(seq, cfra);
1190 frameno = tse->nr + seq->anim_startofs;
1192 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1196 BLI_convertstringcode(name, G.sce);
1197 BLI_convertstringframe(name, frameno);
1200 strcat(name, ".jpg");
1205 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1207 char name[PROXY_MAXFILE];
1209 if (!(seq->flag & SEQ_USE_PROXY)) {
1213 /* rendering at 100% ? No real sense in proxy-ing, right? */
1214 if (render_size == 100) {
1218 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1219 TStripElem * tse = give_tstripelem(seq, cfra);
1220 int frameno = tse->nr + seq->anim_startofs;
1221 if (!seq->strip->proxy->anim) {
1222 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1226 seq->strip->proxy->anim = openanim(name, IB_rect);
1228 if (!seq->strip->proxy->anim) {
1232 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1235 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1239 if (BLI_exists(name)) {
1240 return IMB_loadiffname(name, IB_rect);
1247 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1248 int build_proxy_run, int render_size);
1250 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1252 char name[PROXY_MAXFILE];
1257 struct ImBuf * ibuf;
1259 if (!(seq->flag & SEQ_USE_PROXY)) {
1263 /* rendering at 100% ? No real sense in proxy-ing, right? */
1264 if (render_size == 100) {
1268 /* that's why it is called custom... */
1269 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1273 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1277 se = give_tstripelem(seq, cfra);
1283 IMB_freeImBuf(se->ibuf);
1287 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1293 rectx= (render_size*scene->r.xsch)/100;
1294 recty= (render_size*scene->r.ysch)/100;
1298 if (ibuf->x != rectx || ibuf->y != recty) {
1299 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1302 /* quality is fixed, otherwise one has to generate separate
1303 directories for every quality...
1305 depth = 32 is intentionally left in, otherwise ALPHA channels
1307 quality = seq->strip->proxy->quality;
1308 ibuf->ftype= JPG | quality;
1310 BLI_make_existing_file(name);
1312 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1317 IMB_freeImBuf(ibuf);
1321 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1324 float rsize = seq->strip->proxy->size;
1330 /* flag management tries to account for strobe and
1331 other "non-linearities", that might come in the future...
1332 better way would be to "touch" the files, so that _really_
1333 no one is rebuild twice.
1336 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1337 TStripElem * tse = give_tstripelem(seq, cfra);
1339 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1344 /* a _lot_ faster for movie files, if we read frames in
1346 if (seq->flag & SEQ_REVERSE_FRAMES) {
1347 for (cfra = seq->enddisp-seq->endstill-1;
1348 cfra >= seq->startdisp + seq->startstill; cfra--) {
1349 TStripElem * tse = give_tstripelem(seq, cfra);
1351 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1352 //XXX set_timecursor(cfra);
1353 seq_proxy_build_frame(scene, seq, cfra, rsize);
1354 tse->flag |= STRIPELEM_PREVIEW_DONE;
1356 if (blender_test_break()) {
1361 for (cfra = seq->startdisp + seq->startstill;
1362 cfra < seq->enddisp - seq->endstill; cfra++) {
1363 TStripElem * tse = give_tstripelem(seq, cfra);
1365 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1366 //XXX set_timecursor(cfra);
1367 seq_proxy_build_frame(scene, seq, cfra, rsize);
1368 tse->flag |= STRIPELEM_PREVIEW_DONE;
1370 if (blender_test_break()) {
1380 /* **********************************************************************
1382 ********************************************************************** */
1384 static StripColorBalance calc_cb(StripColorBalance * cb_)
1386 StripColorBalance cb = *cb_;
1389 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1390 for (c = 0; c < 3; c++) {
1391 cb.lift[c] = 1.0 - cb.lift[c];
1394 for (c = 0; c < 3; c++) {
1395 cb.lift[c] = -(1.0 - cb.lift[c]);
1398 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1399 for (c = 0; c < 3; c++) {
1400 if (cb.gain[c] != 0.0) {
1401 cb.gain[c] = 1.0/cb.gain[c];
1403 cb.gain[c] = 1000000; /* should be enough :) */
1408 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1409 for (c = 0; c < 3; c++) {
1410 if (cb.gamma[c] != 0.0) {
1411 cb.gamma[c] = 1.0/cb.gamma[c];
1413 cb.gamma[c] = 1000000; /* should be enough :) */
1421 static void make_cb_table_byte(float lift, float gain, float gamma,
1422 unsigned char * table, float mul)
1426 for (y = 0; y < 256; y++) {
1427 float v = 1.0 * y / 255;
1434 } else if (v < 0.0) {
1442 static void make_cb_table_float(float lift, float gain, float gamma,
1443 float * table, float mul)
1447 for (y = 0; y < 256; y++) {
1448 float v = (float) y * 1.0 / 255.0;
1457 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1459 unsigned char cb_tab[3][256];
1461 unsigned char * p = (unsigned char*) se->ibuf->rect;
1462 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1464 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1466 for (c = 0; c < 3; c++) {
1467 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1472 p[0] = cb_tab[0][p[0]];
1473 p[1] = cb_tab[1][p[1]];
1474 p[2] = cb_tab[2][p[2]];
1480 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1482 float cb_tab[4][256];
1484 unsigned char * p = (unsigned char*) se->ibuf->rect;
1485 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1487 StripColorBalance cb;
1489 imb_addrectfloatImBuf(se->ibuf);
1491 o = se->ibuf->rect_float;
1493 cb = calc_cb(seq->strip->color_balance);
1495 for (c = 0; c < 3; c++) {
1496 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1500 for (i = 0; i < 256; i++) {
1501 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1505 o[0] = cb_tab[0][p[0]];
1506 o[1] = cb_tab[1][p[1]];
1507 o[2] = cb_tab[2][p[2]];
1508 o[3] = cb_tab[3][p[3]];
1514 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1516 float * p = se->ibuf->rect_float;
1517 float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1518 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1522 for (c = 0; c < 3; c++) {
1523 p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
1530 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1532 if (se->ibuf->rect_float) {
1533 color_balance_float_float(seq, se, mul);
1534 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1535 color_balance_byte_float(seq, se, mul);
1537 color_balance_byte_byte(seq, se, mul);
1542 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1544 Do all the things you can't really do afterwards using sequence effects
1545 (read: before rescaling to render resolution has been done)
1550 - Crop and transform in image source coordinate space
1551 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1552 - Promote image to float data (affects pipeline operations afterwards)
1553 - Color balance (is most efficient in the byte -> float
1554 (future: half -> float should also work fine!)
1555 case, if done on load, since we can use lookup tables)
1560 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1564 if ((seq->flag & SEQ_FILTERY) ||
1565 (seq->flag & SEQ_USE_CROP) ||
1566 (seq->flag & SEQ_USE_TRANSFORM) ||
1567 (seq->flag & SEQ_FLIPX) ||
1568 (seq->flag & SEQ_FLIPY) ||
1569 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1570 (seq->flag & SEQ_MAKE_PREMUL) ||
1571 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1577 if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1578 !(seq->type & SEQ_EFFECT)) {
1579 mul *= seq->blend_opacity / 100.0;
1589 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1593 seq->strip->orx= se->ibuf->x;
1594 seq->strip->ory= se->ibuf->y;
1596 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1597 IMB_filtery(se->ibuf);
1600 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1605 memset(&c, 0, sizeof(StripCrop));
1606 memset(&t, 0, sizeof(StripTransform));
1608 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1609 c = *seq->strip->crop;
1611 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1612 t = *seq->strip->transform;
1615 sx = se->ibuf->x - c.left - c.right;
1616 sy = se->ibuf->y - c.top - c.bottom;
1620 if (seq->flag & SEQ_USE_TRANSFORM) {
1625 if (c.top + c.bottom >= se->ibuf->y ||
1626 c.left + c.right >= se->ibuf->x ||
1627 t.xofs >= dx || t.yofs >= dy) {
1628 make_black_ibuf(se->ibuf);
1632 if (se->ibuf->rect_float) {
1633 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1635 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1638 IMB_rectcpy(i, se->ibuf,
1643 IMB_freeImBuf(se->ibuf);
1649 if(seq->flag & SEQ_FLIPX) {
1650 IMB_flipx(se->ibuf);
1652 if(seq->flag & SEQ_FLIPY) {
1653 IMB_flipy(se->ibuf);
1656 if(seq->mul == 0.0) {
1662 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1663 mul *= seq->blend_opacity / 100.0;
1666 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1667 color_balance(seq, se, mul);
1671 if(seq->flag & SEQ_MAKE_FLOAT) {
1672 if (!se->ibuf->rect_float) {
1673 IMB_float_from_rect(se->ibuf);
1675 if (se->ibuf->rect) {
1676 imb_freerectImBuf(se->ibuf);
1681 multibuf(se->ibuf, mul);
1684 if(seq->flag & SEQ_MAKE_PREMUL) {
1685 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1686 converttopremul(se->ibuf);
1691 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1692 if(scene->r.mode & R_OSA) {
1693 IMB_scaleImBuf(se->ibuf,
1694 (short)seqrectx, (short)seqrecty);
1696 IMB_scalefastImBuf(se->ibuf,
1697 (short)seqrectx, (short)seqrecty);
1702 /* test if image too small or discarded from cache: reload */
1704 static void test_and_auto_discard_ibuf(TStripElem * se)
1707 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
1708 || !(se->ibuf->rect || se->ibuf->rect_float)) {
1709 IMB_freeImBuf(se->ibuf);
1712 se->ok= STRIPELEM_OK;
1715 if (se->ibuf_comp) {
1716 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
1717 || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1718 IMB_freeImBuf(se->ibuf_comp);
1725 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1727 if (strip->ibuf_startstill) {
1728 if (!strip->ibuf_startstill->rect &&
1729 !strip->ibuf_startstill->rect_float) {
1730 IMB_freeImBuf(strip->ibuf_startstill);
1731 strip->ibuf_startstill = 0;
1734 if (strip->ibuf_endstill) {
1735 if (!strip->ibuf_endstill->rect &&
1736 !strip->ibuf_endstill->rect_float) {
1737 IMB_freeImBuf(strip->ibuf_endstill);
1738 strip->ibuf_endstill = 0;
1743 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1746 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1747 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1749 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1751 if (se->nr == seq->len - 1
1753 && seq->strip->ibuf_endstill) {
1754 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1756 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1761 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1765 seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1767 IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1768 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1770 if (se->nr == seq->len - 1 && seq->len != 1) {
1771 seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1773 IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1774 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1779 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1781 Sequence* seq_arr[MAXSEQ+1];
1785 evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1787 for (i = 0; i < MAXSEQ; i++) {
1788 if (!video_seq_is_rendered(seq_arr[i])) {
1791 se = give_tstripelem(seq_arr[i], cfra);
1794 IMB_freeImBuf(se->ibuf);
1797 se->ok= STRIPELEM_OK;
1800 if (se->ibuf_comp) {
1801 IMB_freeImBuf(se->ibuf_comp);
1810 static void check_limiter_refcount(const char * func, TStripElem *se)
1812 if (se && se->ibuf) {
1813 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1814 if (refcount != 1) {
1815 /* can happen on complex pipelines */
1816 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1821 "sequencer: (ibuf) %s: "
1822 "suspicious memcache "
1823 "limiter refcount: %d\n", func, refcount);
1828 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1830 if (se && se->ibuf_comp) {
1831 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1832 if (refcount != 1) {
1833 /* can happen on complex pipelines */
1834 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1838 "sequencer: (ibuf comp) %s: "
1839 "suspicious memcache "
1840 "limiter refcount: %d\n", func, refcount);
1845 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1846 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1848 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1849 int build_proxy_run, int render_size)
1851 char name[FILE_MAXDIR+FILE_MAXFILE];
1852 int use_limiter = TRUE;
1854 test_and_auto_discard_ibuf(se);
1855 test_and_auto_discard_ibuf_stills(seq->strip);
1857 if(seq->type == SEQ_META) {
1858 TStripElem * meta_se = 0;
1859 int use_preprocess = FALSE;
1860 use_limiter = FALSE;
1862 if (!build_proxy_run && se->ibuf == 0) {
1863 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1866 use_preprocess = TRUE;
1870 if(!se->ibuf && seq->seqbase.first) {
1871 meta_se = do_build_seq_array_recursively(scene,
1872 &seq->seqbase, seq->start + se->nr, 0,
1875 check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1878 se->ok = STRIPELEM_OK;
1880 if(!se->ibuf && meta_se) {
1881 se->ibuf = meta_se->ibuf_comp;
1883 (!input_have_to_preprocess(scene, seq, se, cfra) ||
1885 IMB_refImBuf(se->ibuf);
1886 if (build_proxy_run) {
1887 IMB_cache_limiter_unref(se->ibuf);
1889 } else if (se->ibuf) {
1890 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1892 IMB_cache_limiter_unref(se->ibuf);
1897 use_preprocess = TRUE;
1899 } else if (se->ibuf) {
1903 free_metastrip_imbufs(
1904 &seq->seqbase, seq->start + se->nr, 0);
1907 if (use_preprocess) {
1908 input_preprocess(scene, seq, se, cfra);
1910 } else if(seq->type & SEQ_EFFECT) {
1911 int use_preprocess = FALSE;
1912 /* should the effect be recalculated? */
1914 if (!build_proxy_run && se->ibuf == 0) {
1915 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1917 use_preprocess = TRUE;
1922 /* if any inputs are rectfloat, output is float too */
1923 if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1924 (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
1925 (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
1926 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1928 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1930 do_effect(scene, cfra, seq, se);
1931 if (input_have_to_preprocess(scene, seq, se, cfra) &&
1933 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
1934 (se->se2 && (se->ibuf == se->se2->ibuf))) {
1936 = IMB_dupImBuf(se->ibuf);
1938 IMB_freeImBuf(se->ibuf);
1942 use_preprocess = TRUE;
1945 if (use_preprocess) {
1946 input_preprocess(scene, seq, se, cfra);
1948 } else if(seq->type == SEQ_IMAGE) {
1949 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1950 StripElem * s_elem = give_stripelem(seq, cfra);
1951 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1952 BLI_convertstringcode(name, G.sce);
1953 BLI_convertstringframe(name, scene->r.cfra);
1954 if (!build_proxy_run) {
1955 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1957 copy_from_ibuf_still(seq, se);
1960 se->ibuf= IMB_loadiffname(
1962 /* we don't need both (speed reasons)! */
1964 se->ibuf->rect_float && se->ibuf->rect) {
1965 imb_freerectImBuf(se->ibuf);
1968 copy_to_ibuf_still(seq, se);
1972 se->ok = STRIPELEM_FAILED;
1973 } else if (!build_proxy_run) {
1974 input_preprocess(scene, seq, se, cfra);
1977 } else if(seq->type == SEQ_MOVIE) {
1978 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1979 if(!build_proxy_run) {
1980 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1982 copy_from_ibuf_still(seq, se);
1984 if (se->ibuf == 0) {
1986 BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
1987 BLI_convertstringcode(name, G.sce);
1988 BLI_convertstringframe(name, scene->r.cfra);
1990 seq->anim = openanim(
1992 ((seq->flag & SEQ_FILTERY)
1993 ? IB_animdeinterlace : 0));
1996 IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1997 se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1998 /* we don't need both (speed reasons)! */
2000 && se->ibuf->rect_float
2001 && se->ibuf->rect) {
2002 imb_freerectImBuf(se->ibuf);
2006 copy_to_ibuf_still(seq, se);
2010 se->ok = STRIPELEM_FAILED;
2011 } else if (!build_proxy_run) {
2012 input_preprocess(scene, seq, se, cfra);
2015 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
2016 Scene *sce= seq->scene;// *oldsce= scene;
2020 int have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2021 int sce_valid =sce && (sce->camera || have_seq);
2023 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2024 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2026 input_preprocess(scene, seq, se, cfra);
2030 if (se->ibuf == NULL && sce_valid) {
2031 copy_from_ibuf_still(seq, se);
2033 input_preprocess(scene, seq, se, cfra);
2038 se->ok = STRIPELEM_FAILED;
2039 } else if (se->ibuf==NULL && sce_valid) {
2041 /* Hack! This function can be called from do_render_seq(), in that case
2042 the seq->scene can already have a Render initialized with same name,
2043 so we have to use a default name. (compositor uses scene name to
2045 However, when called from within the UI (image preview in sequencer)
2046 we do want to use scene Render, that way the render result is defined
2047 for display in render/imagewindow
2049 Hmm, don't see, why we can't do that all the time,
2050 and since G.rendering is uhm, gone... (Peter)
2056 oldcfra = seq->scene->r.cfra;
2059 BLI_strncpy(scenename, sce->id.name+2, 64);
2060 strcpy(sce->id.name+2, " do_build_seq_ibuf");
2062 re= RE_NewRender(sce->id.name);
2064 /* prevent eternal loop */
2065 doseq= scene->r.scemode & R_DOSEQ;
2066 scene->r.scemode &= ~R_DOSEQ;
2068 RE_BlenderFrame(re, sce,
2069 seq->sfra+se->nr+seq->anim_startofs);
2072 BLI_strncpy(sce->id.name+2, scenename, 64);
2074 RE_AcquireResultImage(re, &rres);
2077 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2078 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2080 addzbuffloatImBuf(se->ibuf);
2081 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2083 } else if (rres.rect32) {
2084 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2085 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2088 RE_ReleaseResultImage(re);
2090 // BIF_end_render_callbacks();
2093 scene->r.scemode |= doseq;
2095 seq->scene->r.cfra = oldcfra;
2097 copy_to_ibuf_still(seq, se);
2099 if (!build_proxy_run) {
2100 if(se->ibuf == NULL) {
2101 se->ok = STRIPELEM_FAILED;
2103 input_preprocess(scene, seq, se, cfra);
2109 if (!build_proxy_run) {
2110 if (se->ibuf && use_limiter) {
2111 IMB_cache_limiter_insert(se->ibuf);
2112 IMB_cache_limiter_ref(se->ibuf);
2113 IMB_cache_limiter_touch(se->ibuf);
2118 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2120 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2123 struct SeqEffectHandle sh = get_sequence_effect(seq);
2131 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2132 sh.get_default_fac(seq, cfra, &fac, &facf);
2133 if( scene->r.mode & R_FIELDS ); else facf= fac;
2135 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
2138 fac = facf = evaluate_fcurve(fcu, cfra);
2139 if( scene->r.mode & R_FIELDS ) {
2140 facf = evaluate_fcurve(fcu, cfra + 0.5);
2143 fac = facf = seq->effect_fader;
2147 early_out = sh.early_out(seq, fac, facf);
2148 switch (early_out) {
2150 /* no input needed */
2153 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2154 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2156 se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2160 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2163 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2168 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2170 /* children are not needed anymore ... */
2172 if (se->se1 && se->se1->ibuf) {
2173 IMB_cache_limiter_unref(se->se1->ibuf);
2175 if (se->se2 && se->se2->ibuf) {
2176 IMB_cache_limiter_unref(se->se2->ibuf);
2178 if (se->se3 && se->se3->ibuf) {
2179 IMB_cache_limiter_unref(se->se3->ibuf);
2181 check_limiter_refcount("do_effect_seq_recursively", se);
2184 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2188 se = give_tstripelem(seq, cfra);
2191 if (seq->type & SEQ_EFFECT) {
2192 do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2194 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2202 If cfra was float throughout blender (especially in the render
2203 pipeline) one could even _render_ with subframe precision
2204 instead of faking using the blend code below...
2208 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2210 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2211 int nr = cfra - seq->start;
2215 TStripElem * se = 0;
2216 TStripElem * se1 = 0;
2217 TStripElem * se2 = 0;
2219 sequence_effect_speed_rebuild_map(scene, seq, 0);
2221 f_cfra = seq->start + s->frameMap[nr];
2223 cfra_left = (int) floor(f_cfra);
2224 cfra_right = (int) ceil(f_cfra);
2226 se = give_tstripelem(seq, cfra);
2232 if (cfra_left == cfra_right ||
2233 (s->flags & SEQ_SPEED_BLEND) == 0) {
2234 test_and_auto_discard_ibuf(se);
2236 if (se->ibuf == NULL) {
2237 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2239 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2240 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2242 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2244 if (se1 == 0 || se1->ibuf == 0) {
2245 make_black_ibuf(se->ibuf);
2247 if (se->ibuf != se1->ibuf) {
2249 IMB_freeImBuf(se->ibuf);
2252 se->ibuf = se1->ibuf;
2253 IMB_refImBuf(se->ibuf);
2258 struct SeqEffectHandle sh;
2261 if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
2262 || !(se->ibuf->rect || se->ibuf->rect_float)) {
2263 IMB_freeImBuf(se->ibuf);
2268 if (se->ibuf == NULL) {
2269 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2270 se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2272 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2273 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2275 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2278 make_black_ibuf(se->ibuf);
2280 sh = get_sequence_effect(seq);
2282 sh.execute(scene, seq, cfra,
2283 f_cfra - (float) cfra_left,
2284 f_cfra - (float) cfra_left,
2285 se->ibuf->x, se->ibuf->y,
2286 se1->ibuf, se2->ibuf, 0, se->ibuf);
2292 /* caller expects this to be referenced, so do it! */
2294 IMB_cache_limiter_insert(se->ibuf);
2295 IMB_cache_limiter_ref(se->ibuf);
2296 IMB_cache_limiter_touch(se->ibuf);
2299 /* children are no longer needed */
2300 if (se1 && se1->ibuf)
2301 IMB_cache_limiter_unref(se1->ibuf);
2302 if (se2 && se2->ibuf)
2303 IMB_cache_limiter_unref(se2->ibuf);
2305 check_limiter_refcount("do_handle_speed_effect", se);
2311 * build all ibufs recursively
2313 * if successfull, the returned TStripElem contains the (referenced!) imbuf
2314 * that means: you _must_ call
2316 * IMB_cache_limiter_unref(rval);
2322 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2325 if (seq->type == SEQ_SPEED) {
2326 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2328 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2331 check_limiter_refcount("do_build_seq_recursively", se);
2336 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2337 ListBase *seqbasep, int cfra, int chanshown, int render_size)
2339 Sequence* seq_arr[MAXSEQ+1];
2344 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2350 se = give_tstripelem(seq_arr[count - 1], cfra);
2356 test_and_auto_discard_ibuf(se);
2358 if (se->ibuf_comp != 0) {
2359 IMB_cache_limiter_insert(se->ibuf_comp);
2360 IMB_cache_limiter_ref(se->ibuf_comp);
2361 IMB_cache_limiter_touch(se->ibuf_comp);
2367 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2369 se->ibuf_comp = se->ibuf;
2370 IMB_refImBuf(se->ibuf_comp);
2376 for (i = count - 1; i >= 0; i--) {
2378 Sequence * seq = seq_arr[i];
2379 struct SeqEffectHandle sh;
2382 se = give_tstripelem(seq, cfra);
2384 test_and_auto_discard_ibuf(se);
2386 if (se->ibuf_comp != 0) {
2389 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2390 do_build_seq_recursively(scene, seq, cfra, render_size);
2392 se->ibuf_comp = se->ibuf;
2393 IMB_refImBuf(se->ibuf);
2395 se->ibuf_comp = IMB_allocImBuf(
2396 (short)seqrectx, (short)seqrecty,
2398 IMB_cache_limiter_insert(se->ibuf_comp);
2399 IMB_cache_limiter_ref(se->ibuf_comp);
2400 IMB_cache_limiter_touch(se->ibuf_comp);
2405 sh = get_sequence_blend(seq);
2407 facf = seq->blend_opacity / 100.0;
2409 early_out = sh.early_out(seq, facf, facf);
2411 switch (early_out) {
2414 do_build_seq_recursively(scene, seq, cfra, render_size);
2416 se->ibuf_comp = se->ibuf;
2417 IMB_refImBuf(se->ibuf_comp);
2419 se->ibuf_comp = IMB_allocImBuf(
2420 (short)seqrectx, (short)seqrecty,
2422 IMB_cache_limiter_insert(se->ibuf_comp);
2423 IMB_cache_limiter_ref(se->ibuf_comp);
2424 IMB_cache_limiter_touch(se->ibuf_comp);
2429 se->ibuf_comp = IMB_allocImBuf(
2430 (short)seqrectx, (short)seqrecty,
2432 IMB_cache_limiter_insert(se->ibuf_comp);
2433 IMB_cache_limiter_ref(se->ibuf_comp);
2434 IMB_cache_limiter_touch(se->ibuf_comp);
2438 do_build_seq_recursively(scene, seq, cfra, render_size);
2440 se->ibuf = IMB_allocImBuf(
2441 (short)seqrectx, (short)seqrecty,
2443 IMB_cache_limiter_insert(se->ibuf);
2444 IMB_cache_limiter_ref(se->ibuf);
2445 IMB_cache_limiter_touch(se->ibuf);
2448 se->ibuf_comp = se->ibuf;
2449 IMB_refImBuf(se->ibuf_comp);
2454 if (se->ibuf_comp) {
2461 for (; i < count; i++) {
2462 Sequence * seq = seq_arr[i];
2463 struct SeqEffectHandle sh = get_sequence_blend(seq);
2464 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2465 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2467 float facf = seq->blend_opacity / 100.0;
2469 int early_out = sh.early_out(seq, facf, facf);
2470 switch (early_out) {
2472 int x= se2->ibuf->x;
2473 int y= se2->ibuf->y;
2474 int swap_input = FALSE;
2476 if (se1->ibuf_comp->rect_float ||
2477 se2->ibuf->rect_float) {
2478 se2->ibuf_comp = IMB_allocImBuf(
2479 (short)seqrectx, (short)seqrecty,
2480 32, IB_rectfloat, 0);
2482 se2->ibuf_comp = IMB_allocImBuf(
2483 (short)seqrectx, (short)seqrecty,
2488 if (!se1->ibuf_comp->rect_float &&
2489 se2->ibuf_comp->rect_float) {
2490 IMB_float_from_rect(se1->ibuf_comp);
2492 if (!se2->ibuf->rect_float &&
2493 se2->ibuf_comp->rect_float) {
2494 IMB_float_from_rect(se2->ibuf);
2497 if (!se1->ibuf_comp->rect &&
2498 !se2->ibuf_comp->rect_float) {
2499 IMB_rect_from_float(se1->ibuf_comp);
2501 if (!se2->ibuf->rect &&
2502 !se2->ibuf_comp->rect_float) {
2503 IMB_rect_from_float(se2->ibuf);
2506 /* bad hack, to fix crazy input ordering of
2507 those two effects */
2509 if (seq->blend_mode == SEQ_ALPHAOVER ||
2510 seq->blend_mode == SEQ_ALPHAUNDER ||
2511 seq->blend_mode == SEQ_OVERDROP) {
2516 sh.execute(scene, seq, cfra,
2518 se2->ibuf, se1->ibuf_comp, 0,
2521 sh.execute(scene, seq, cfra,
2523 se1->ibuf_comp, se2->ibuf, 0,
2527 IMB_cache_limiter_insert(se2->ibuf_comp);
2528 IMB_cache_limiter_ref(se2->ibuf_comp);
2529 IMB_cache_limiter_touch(se2->ibuf_comp);
2531 IMB_cache_limiter_unref(se1->ibuf_comp);
2532 IMB_cache_limiter_unref(se2->ibuf);
2537 se2->ibuf_comp = se1->ibuf;
2538 IMB_refImBuf(se2->ibuf_comp);
2550 * returned ImBuf is refed!
2551 * you have to unref after usage!
2554 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2556 Editing *ed= seq_give_editing(scene, FALSE);
2562 if(ed==NULL) return NULL;
2564 count = BLI_countlist(&ed->metastack);
2565 if((chanshown < 0) && (count > 0)) {
2566 count = MAX2(count + chanshown, 0);
2567 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2569 seqbasep= ed->seqbasep;
2572 seqrectx= rectx; /* bad bad global! */
2575 se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2581 check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2583 return se->ibuf_comp;
2586 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2590 seqrectx= rectx; /* bad bad global! */
2593 se = do_build_seq_recursively(scene, seq, cfra, render_size);
2599 check_limiter_refcount("give_ibuf_seq_direct", se);
2602 IMB_cache_limiter_unref(se->ibuf);
2608 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2610 ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2613 IMB_cache_limiter_unref(i);
2619 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2620 static int seq_can_blend(Sequence *seq)
2622 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2630 /* *********************** threading api ******************* */
2632 static ListBase running_threads;
2633 static ListBase prefetch_wait;
2634 static ListBase prefetch_done;
2636 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2637 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2638 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2640 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2641 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2643 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2644 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2646 static volatile int seq_thread_shutdown = FALSE;
2647 static volatile int seq_last_given_monoton_cfra = 0;
2648 static int monoton_cfra = 0;
2650 typedef struct PrefetchThread {
2651 struct PrefetchThread *next, *prev;
2654 struct PrefetchQueueElem *current;
2660 typedef struct PrefetchQueueElem {
2661 struct PrefetchQueueElem *next, *prev;
2671 struct ImBuf * ibuf;
2672 } PrefetchQueueElem;
2675 static void *seq_prefetch_thread(void * This_)
2677 PrefetchThread * This = This_;
2679 while (!seq_thread_shutdown) {
2680 PrefetchQueueElem *e;
2683 pthread_mutex_lock(&queue_lock);
2684 e = prefetch_wait.first;
2686 BLI_remlink(&prefetch_wait, e);
2688 s_last = seq_last_given_monoton_cfra;
2692 pthread_mutex_unlock(&queue_lock);
2695 pthread_mutex_lock(&prefetch_ready_lock);
2697 This->running = FALSE;
2699 pthread_cond_signal(&prefetch_ready_cond);
2700 pthread_mutex_unlock(&prefetch_ready_lock);
2702 pthread_mutex_lock(&wakeup_lock);
2703 if (!seq_thread_shutdown) {
2704 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2706 pthread_mutex_unlock(&wakeup_lock);
2710 This->running = TRUE;
2712 if (e->cfra >= s_last) {
2713 e->ibuf = give_ibuf_seq_impl(This->scene,
2714 e->rectx, e->recty, e->cfra, e->chanshown,
2718 pthread_mutex_lock(&queue_lock);
2720 BLI_addtail(&prefetch_done, e);
2722 for (e = prefetch_wait.first; e; e = e->next) {
2723 if (s_last > e->monoton_cfra) {
2724 BLI_remlink(&prefetch_wait, e);
2729 for (e = prefetch_done.first; e; e = e->next) {
2730 if (s_last > e->monoton_cfra) {
2732 IMB_cache_limiter_unref(e->ibuf);
2734 BLI_remlink(&prefetch_done, e);
2739 pthread_mutex_unlock(&queue_lock);
2741 pthread_mutex_lock(&frame_done_lock);
2742 pthread_cond_signal(&frame_done_cond);
2743 pthread_mutex_unlock(&frame_done_lock);
2748 static void seq_start_threads(Scene *scene)
2752 running_threads.first = running_threads.last = NULL;
2753 prefetch_wait.first = prefetch_wait.last = NULL;
2754 prefetch_done.first = prefetch_done.last = NULL;
2756 seq_thread_shutdown = FALSE;
2757 seq_last_given_monoton_cfra = monoton_cfra = 0;
2759 /* since global structures are modified during the processing
2760 of one frame, only one render thread is currently possible...
2762 (but we code, in the hope, that we can remove this restriction
2766 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2768 for (i = 0; i < 1; i++) {
2769 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2772 BLI_addtail(&running_threads, t);
2774 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2777 /* init malloc mutex */
2778 BLI_init_threads(0, 0, 0);
2781 static void seq_stop_threads()
2783 PrefetchThread *tslot;
2784 PrefetchQueueElem *e;
2786 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2788 if (seq_thread_shutdown) {
2789 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2793 pthread_mutex_lock(&wakeup_lock);
2795 seq_thread_shutdown = TRUE;
2797 pthread_cond_broadcast(&wakeup_cond);
2798 pthread_mutex_unlock(&wakeup_lock);
2800 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2801 pthread_join(tslot->pthread, NULL);
2805 for (e = prefetch_wait.first; e; e = e->next) {
2806 BLI_remlink(&prefetch_wait, e);
2810 for (e = prefetch_done.first; e; e = e->next) {
2812 IMB_cache_limiter_unref(e->ibuf);
2814 BLI_remlink(&prefetch_done, e);
2818 BLI_freelistN(&running_threads);
2820 /* deinit malloc mutex */
2825 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2828 PrefetchQueueElem *e;
2829 if (seq_thread_shutdown) {
2833 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2837 e->chanshown = chanshown;
2838 e->render_size = render_size;
2839 e->monoton_cfra = monoton_cfra++;
2841 pthread_mutex_lock(&queue_lock);
2842 BLI_addtail(&prefetch_wait, e);
2843 pthread_mutex_unlock(&queue_lock);
2845 pthread_mutex_lock(&wakeup_lock);
2846 pthread_cond_signal(&wakeup_cond);
2847 pthread_mutex_unlock(&wakeup_lock);
2851 static void seq_wait_for_prefetch_ready()
2853 PrefetchThread *tslot;
2855 if (seq_thread_shutdown) {
2859 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2861 pthread_mutex_lock(&prefetch_ready_lock);
2864 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2865 if (tslot->running) {
2872 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2875 pthread_mutex_unlock(&prefetch_ready_lock);
2877 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2881 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2883 PrefetchQueueElem *e = NULL;
2884 int found_something = FALSE;
2886 if (seq_thread_shutdown) {
2887 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2891 int success = FALSE;
2892 pthread_mutex_lock(&queue_lock);
2894 for (e = prefetch_done.first; e; e = e->next) {
2895 if (cfra == e->cfra &&
2896 chanshown == e->chanshown &&
2897 rectx == e->rectx &&
2898 recty == e->recty &&
2899 render_size == e->render_size) {
2901 found_something = TRUE;
2907 for (e = prefetch_wait.first; e; e = e->next) {
2908 if (cfra == e->cfra &&
2909 chanshown == e->chanshown &&
2910 rectx == e->rectx &&
2911 recty == e->recty &&
2912 render_size == e->render_size) {
2913 found_something = TRUE;
2920 PrefetchThread *tslot;
2922 for(tslot = running_threads.first;
2923 tslot; tslot= tslot->next) {
2924 if (tslot->current &&
2925 cfra == tslot->current->cfra &&
2926 chanshown == tslot->current->chanshown &&
2927 rectx == tslot->current->rectx &&
2928 recty == tslot->current->recty &&
2929 render_size== tslot->current->render_size){
2930 found_something = TRUE;
2936 /* e->ibuf is unrefed by render thread on next round. */
2939 seq_last_given_monoton_cfra = e->monoton_cfra;
2942 pthread_mutex_unlock(&queue_lock);
2947 if (!found_something) {
2949 "SEQ-THREAD: Requested frame "
2950 "not in queue ???\n");
2953 pthread_mutex_lock(&frame_done_lock);
2954 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2955 pthread_mutex_unlock(&frame_done_lock);
2959 return e ? e->ibuf : 0;
2962 /* Functions to free imbuf and anim data on changes */
2964 static void free_imbuf_strip_elem(TStripElem *se)
2967 IMB_freeImBuf(se->ibuf);
2970 IMB_freeImBuf(se->ibuf_comp);
2974 se->ok= STRIPELEM_OK;
2975 se->se1= se->se2= se->se3= 0;
2978 static void free_anim_seq(Sequence *seq)
2981 IMB_free_anim(seq->anim);
2987 static void free_imbuf_seq_except(Scene *scene, int cfra)
2989 Editing *ed= seq_give_editing(scene, FALSE);
2994 if(ed==NULL) return;
2996 SEQ_BEGIN(ed, seq) {
2998 TStripElem * curelem = give_tstripelem(seq, cfra);
3000 for(a = 0, se = seq->strip->tstripdata;
3001 a < seq->strip->len && se; a++, se++) {
3003 free_imbuf_strip_elem(se);
3006 for(a = 0, se = seq->strip->tstripdata_startstill;
3007 a < seq->strip->startstill && se; a++, se++) {
3009 free_imbuf_strip_elem(se);
3012 for(a = 0, se = seq->strip->tstripdata_endstill;
3013 a < seq->strip->endstill && se; a++, se++) {
3015 free_imbuf_strip_elem(se);
3018 if(seq->strip->ibuf_startstill) {
3019 IMB_freeImBuf(seq->strip->ibuf_startstill);
3020 seq->strip->ibuf_startstill = 0;
3023 if(seq->strip->ibuf_endstill) {
3024 IMB_freeImBuf(seq->strip->ibuf_endstill);
3025 seq->strip->ibuf_endstill = 0;
3028 if(seq->type==SEQ_MOVIE)
3029 if(seq->startdisp > cfra || seq->enddisp < cfra)
3031 free_proxy_seq(seq);
3038 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3044 if (check_mem_usage) {
3045 /* Let the cache limitor take care of this (schlaile) */
3046 /* While render let's keep all memory available for render
3048 At least if free memory is tight...
3049 This can make a big difference in encoding speed
3050 (it is around 4 times(!) faster, if we do not waste time
3051 on freeing _all_ buffers every time on long timelines...)
3055 uintptr_t mem_in_use;
3056 uintptr_t mmap_in_use;
3059 mem_in_use= MEM_get_memory_in_use();
3060 mmap_in_use= MEM_get_mapped_memory_in_use();
3061 max = MEM_CacheLimiter_get_maximum();
3063 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3069 for(seq= seqbase->first; seq; seq= seq->next) {
3071 for(a = 0, se = seq->strip->tstripdata;
3072 a < seq->strip->len && se; a++, se++) {
3073 free_imbuf_strip_elem(se);
3075 for(a = 0, se = seq->strip->tstripdata_startstill;
3076 a < seq->strip->startstill && se; a++, se++) {
3077 free_imbuf_strip_elem(se);
3079 for(a = 0, se = seq->strip->tstripdata_endstill;
3080 a < seq->strip->endstill && se; a++, se++) {
3081 free_imbuf_strip_elem(se);
3083 if(seq->strip->ibuf_startstill) {
3084 IMB_freeImBuf(seq->strip->ibuf_startstill);
3085 seq->strip->ibuf_startstill = 0;
3088 if(seq->strip->ibuf_endstill) {
3089 IMB_freeImBuf(seq->strip->ibuf_endstill);
3090 seq->strip->ibuf_endstill = 0;
3093 if(seq->type==SEQ_MOVIE)
3095 if(seq->type==SEQ_SPEED) {
3096 sequence_effect_speed_rebuild_map(scene, seq, 1);
3099 if(seq->type==SEQ_META) {
3100 free_imbuf_seq(scene, &seq->seqbase, FALSE);
3102 if(seq->type==SEQ_SCENE) {
3103 /* FIXME: recurs downwards,
3104 but do recurs protection somehow! */
3110 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3113 int a, free_imbuf = 0;
3116 /* recurs downwards to see if this seq depends on the changed seq */
3121 if(seq == changed_seq)
3124 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
3125 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3129 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3131 if(seq->seq2 && (seq->seq2 != seq->seq1))
3132 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3134 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3135 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3140 se= seq->strip->tstripdata;
3142 for(a=0; a<seq->len; a++, se++)
3143 free_imbuf_strip_elem(se);
3146 if(seq->type == SEQ_MOVIE)
3148 if(seq->type == SEQ_SPEED) {
3149 sequence_effect_speed_rebuild_map(scene, seq, 1);
3160 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3162 Editing *ed= seq_give_editing(scene, FALSE);
3165 if (ed==NULL) return;
3167 for (seq=ed->seqbase.first; seq; seq=seq->next)
3168 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3171 #if 0 // XXX from 2.4x, needs updating
3172 void free_imbuf_seq()
3174 Scene * sce = G.main->scene.first;
3176 free_imbuf_seq_editing(sce->ed);
3182 #if 0 // XXX old animation system
3183 static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
3185 /* force update of all sequences with this ipo, on ipo changes */
3186 Editing *ed= seq_give_editing(scene, FALSE);
3189 if(ed==NULL) return;
3191 SEQ_BEGIN(ed, seq) {
3192 if(seq->ipo == ipo) {
3193 update_changed_seq_and_deps(scene, seq, 0, 1);
3194 if(seq->type == SEQ_SPEED) {
3195 sequence_effect_speed_rebuild_map(seq, 1);
3197 free_proxy_seq(seq);