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"
42 #include "BKE_global.h"
43 #include "BKE_image.h"
45 #include "BKE_sequence.h"
46 #include "BKE_utildefines.h"
48 #include "BLI_blenlib.h"
51 #include "IMB_imbuf.h"
52 #include "IMB_imbuf_types.h"
54 #include "BLI_threads.h"
57 #include "BKE_context.h"
58 #include "BKE_sound.h"
59 #include "AUD_C-API.h"
62 #define snprintf _snprintf
65 /* **** XXX ******** */
66 static int seqrectx= 0; /* bad bad global! */
67 static int seqrecty= 0;
68 //static void waitcursor(int val) {}
69 //static int blender_test_break() {return 0;}
71 /* **** XXX ******** */
74 void printf_strip(Sequence *seq)
76 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
77 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
78 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));
81 /* **********************************************************************
82 alloc / free functions
83 ********************************************************************** */
85 static void free_tstripdata(int len, TStripElem *se)
94 for(a=0; a<len; a++, se++) {
96 IMB_freeImBuf(se->ibuf);
100 IMB_freeImBuf(se->ibuf_comp);
109 void new_tstripdata(Sequence *seq)
112 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
113 free_tstripdata(seq->strip->endstill,
114 seq->strip->tstripdata_endstill);
115 free_tstripdata(seq->strip->startstill,
116 seq->strip->tstripdata_startstill);
118 seq->strip->tstripdata= 0;
119 seq->strip->tstripdata_endstill= 0;
120 seq->strip->tstripdata_startstill= 0;
122 if(seq->strip->ibuf_startstill) {
123 IMB_freeImBuf(seq->strip->ibuf_startstill);
124 seq->strip->ibuf_startstill = 0;
127 if(seq->strip->ibuf_endstill) {
128 IMB_freeImBuf(seq->strip->ibuf_endstill);
129 seq->strip->ibuf_endstill = 0;
132 seq->strip->len= seq->len;
139 static void free_proxy_seq(Sequence *seq)
141 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
142 IMB_free_anim(seq->strip->proxy->anim);
143 seq->strip->proxy->anim = 0;
147 void seq_free_strip(Strip *strip)
150 if(strip->us>0) return;
152 printf("error: negative users in strip\n");
156 if (strip->stripdata) {
157 MEM_freeN(strip->stripdata);
161 if (strip->proxy->anim) {
162 IMB_free_anim(strip->proxy->anim);
165 MEM_freeN(strip->proxy);
168 MEM_freeN(strip->crop);
170 if (strip->transform) {
171 MEM_freeN(strip->transform);
173 if (strip->color_balance) {
174 MEM_freeN(strip->color_balance);
177 free_tstripdata(strip->len, strip->tstripdata);
178 free_tstripdata(strip->endstill, strip->tstripdata_endstill);
179 free_tstripdata(strip->startstill, strip->tstripdata_startstill);
181 if(strip->ibuf_startstill) {
182 IMB_freeImBuf(strip->ibuf_startstill);
183 strip->ibuf_startstill = 0;
186 if(strip->ibuf_endstill) {
187 IMB_freeImBuf(strip->ibuf_endstill);
188 strip->ibuf_endstill = 0;
194 void seq_free_sequence(Scene *scene, Sequence *seq)
196 Editing *ed = scene->ed;
198 if(seq->strip) seq_free_strip(seq->strip);
200 if(seq->anim) IMB_free_anim(seq->anim);
202 if(seq->sound_handle)
203 sound_delete_handle(scene, seq->sound_handle);
205 if (seq->type & SEQ_EFFECT) {
206 struct SeqEffectHandle sh = get_sequence_effect(seq);
211 if (ed->act_seq==seq)
217 Editing *seq_give_editing(Scene *scene, int alloc)
219 if (scene->ed == NULL && alloc) {
222 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
223 ed->seqbasep= &ed->seqbase;
228 void seq_free_editing(Scene *scene)
230 Editing *ed = scene->ed;
238 seq_free_sequence(scene, seq);
242 while((ms= ed->metastack.first)) {
243 BLI_remlink(&ed->metastack, ms);
250 /* ************************* itterator ************************** */
251 /* *************** (replaces old WHILE_SEQ) ********************* */
252 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
254 /* sequence strip iterator:
255 * - builds a full array, recursively into meta strips */
257 static void seq_count(ListBase *seqbase, int *tot)
261 for(seq=seqbase->first; seq; seq=seq->next) {
264 if(seq->seqbase.first)
265 seq_count(&seq->seqbase, tot);
269 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
273 for(seq=seqbase->first; seq; seq=seq->next) {
276 if(seq->seqbase.first)
277 seq_build_array(&seq->seqbase, array, depth+1);
284 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
295 seq_count(ed->seqbasep, tot);
297 seq_count(&ed->seqbase, tot);
302 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
304 seq_build_array(ed->seqbasep, &array, 0);
306 seq_build_array(&ed->seqbase, &array, 0);
309 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
311 memset(iter, 0, sizeof(*iter));
312 seq_array(ed, &iter->array, &iter->tot, use_pointer);
316 iter->seq= iter->array[iter->cur];
321 void seq_next(SeqIterator *iter)
323 if(++iter->cur < iter->tot)
324 iter->seq= iter->array[iter->cur];
329 void seq_end(SeqIterator *iter)
332 MEM_freeN(iter->array);
338 **********************************************************************
340 **********************************************************************
341 * Build a complete array of _all_ sequencies (including those
343 **********************************************************************
346 static void do_seq_count(ListBase *seqbase, int *totseq)
353 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
358 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
365 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
372 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
377 do_seq_count(seqbase, totseq);
383 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
386 do_build_seqar(seqbase, seqar, 0);
390 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
391 int (*test_func)(Sequence * seq))
397 int test = test_func(seq);
398 if (test & BUILD_SEQAR_COUNT_CURRENT) {
401 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
402 do_seq_count_cb(&seq->seqbase, totseq, test_func);
408 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
409 int (*test_func)(Sequence * seq))
415 int test = test_func(seq);
418 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
419 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
422 if (test & BUILD_SEQAR_COUNT_CURRENT) {
430 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
431 int (*test_func)(Sequence * seq))
436 do_seq_count_cb(seqbase, totseq, test_func);
442 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
445 do_build_seqar_cb(seqbase, seqar, 0, test_func);
450 void calc_sequence_disp(Sequence *seq)
452 if(seq->startofs && seq->startstill) seq->startstill= 0;
453 if(seq->endofs && seq->endstill) seq->endstill= 0;
455 seq->startdisp= seq->start + seq->startofs - seq->startstill;
456 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
458 seq->handsize= 10.0; /* 10 frames */
459 if( seq->enddisp-seq->startdisp < 10 ) {
460 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
462 else if(seq->enddisp-seq->startdisp > 250) {
463 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
466 seq_update_sound(seq);
469 void calc_sequence(Sequence *seq)
474 /* check all metas recursively */
475 seqm= seq->seqbase.first;
477 if(seqm->seqbase.first) calc_sequence(seqm);
481 /* effects and meta: automatic start and end */
483 if(seq->type & SEQ_EFFECT) {
485 if(seq->seq2==0) seq->seq2= seq->seq1;
486 if(seq->seq3==0) seq->seq3= seq->seq1;
488 /* effecten go from seq1 -> seq2: test */
490 /* we take the largest start and smallest end */
492 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
493 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
496 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
497 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
498 seq->len= seq->enddisp - seq->startdisp;
500 calc_sequence_disp(seq);
503 if(seq->strip && seq->len!=seq->strip->len) {
509 if(seq->type==SEQ_META) {
510 seqm= seq->seqbase.first;
515 if(seqm->startdisp < min) min= seqm->startdisp;
516 if(seqm->enddisp > max) max= seqm->enddisp;
519 seq->start= min + seq->anim_startofs;
521 seq->len -= seq->anim_startofs;
522 seq->len -= seq->anim_endofs;
524 if(seq->strip && seq->len!=seq->strip->len) {
529 calc_sequence_disp(seq);
533 void reload_sequence_new_file(Scene *scene, Sequence * seq)
535 char str[FILE_MAXDIR+FILE_MAXFILE];
537 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
538 seq->type == SEQ_SOUND ||
539 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
545 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
546 seq->type != SEQ_IMAGE) {
547 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
548 BLI_convertstringcode(str, G.sce);
549 BLI_convertstringframe(str, scene->r.cfra);
553 if (seq->type == SEQ_IMAGE) {
555 int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
557 seq->len -= seq->anim_startofs;
558 seq->len -= seq->anim_endofs;
562 seq->strip->len = seq->len;
563 } else if (seq->type == SEQ_MOVIE) {
564 if(seq->anim) IMB_free_anim(seq->anim);
565 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
571 seq->len = IMB_anim_get_duration(seq->anim);
573 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
575 seq->len -= seq->anim_startofs;
576 seq->len -= seq->anim_endofs;
580 seq->strip->len = seq->len;
581 } else if (seq->type == SEQ_SOUND) {
582 seq->len = AUD_getInfo(seq->sound->handle).length * FPS;
583 seq->len -= seq->anim_startofs;
584 seq->len -= seq->anim_endofs;
588 seq->strip->len = seq->len;
589 } else if (seq->type == SEQ_SCENE) {
590 Scene * sce = G.main->scene.first;
594 if(nr == seq->scenenr) {
607 BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
608 seqUniqueName(scene->ed->seqbasep, seq);
610 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
611 seq->len -= seq->anim_startofs;
612 seq->len -= seq->anim_endofs;
616 seq->strip->len = seq->len;
624 void sort_seq(Scene *scene)
626 /* all strips together per kind, and in order of y location ("machine") */
627 ListBase seqbase, effbase;
628 Editing *ed= seq_give_editing(scene, FALSE);
629 Sequence *seq, *seqt;
634 seqbase.first= seqbase.last= 0;
635 effbase.first= effbase.last= 0;
637 while( (seq= ed->seqbasep->first) ) {
638 BLI_remlink(ed->seqbasep, seq);
640 if(seq->type & SEQ_EFFECT) {
643 if(seqt->machine>=seq->machine) {
644 BLI_insertlinkbefore(&effbase, seqt, seq);
649 if(seqt==0) BLI_addtail(&effbase, seq);
654 if(seqt->machine>=seq->machine) {
655 BLI_insertlinkbefore(&seqbase, seqt, seq);
660 if(seqt==0) BLI_addtail(&seqbase, seq);
664 addlisttolist(&seqbase, &effbase);
665 *(ed->seqbasep)= seqbase;
669 void clear_scene_in_allseqs(Scene *sce)
675 /* when a scene is deleted: test all seqs */
677 sce1= G.main->scene.first;
679 if(sce1!=sce && sce1->ed) {
684 if(seq->scene==sce) seq->scene= 0;
694 static char *give_seqname_by_type(int type)
697 case SEQ_META: return "Meta";
698 case SEQ_IMAGE: return "Image";
699 case SEQ_SCENE: return "Scene";
700 case SEQ_MOVIE: return "Movie";
701 case SEQ_SOUND: return "Audio";
702 case SEQ_CROSS: return "Cross";
703 case SEQ_GAMCROSS: return "Gamma Cross";
704 case SEQ_ADD: return "Add";
705 case SEQ_SUB: return "Sub";
706 case SEQ_MUL: return "Mul";
707 case SEQ_ALPHAOVER: return "Alpha Over";
708 case SEQ_ALPHAUNDER: return "Alpha Under";
709 case SEQ_OVERDROP: return "Over Drop";
710 case SEQ_WIPE: return "Wipe";
711 case SEQ_GLOW: return "Glow";
712 case SEQ_TRANSFORM: return "Transform";
713 case SEQ_COLOR: return "Color";
714 case SEQ_SPEED: return "Speed";
720 char *give_seqname(Sequence *seq)
722 char * name = give_seqname_by_type(seq->type);
725 if(seq->type<SEQ_EFFECT) {
726 return seq->strip->dir;
727 } else if(seq->type==SEQ_PLUGIN) {
728 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
729 seq->plugin && seq->plugin->doit) {
730 return seq->plugin->pname;
741 /* ***************** DO THE SEQUENCE ***************** */
743 static void make_black_ibuf(ImBuf *ibuf)
749 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
751 tot= ibuf->x*ibuf->y;
754 rect_float = ibuf->rect_float;
757 memset(rect, 0, tot * sizeof(char) * 4);
761 memset(rect_float, 0, tot * sizeof(float) * 4);
765 static void multibuf(ImBuf *ibuf, float fmul)
772 mul= (int)(256.0*fmul);
773 rt= (char *)ibuf->rect;
774 rt_float = ibuf->rect_float;
780 icol= (mul*rt[0])>>8;
781 if(icol>254) rt[0]= 255; else rt[0]= icol;
782 icol= (mul*rt[1])>>8;
783 if(icol>254) rt[1]= 255; else rt[1]= icol;
784 icol= (mul*rt[2])>>8;
785 if(icol>254) rt[2]= 255; else rt[2]= icol;
786 icol= (mul*rt[3])>>8;
787 if(icol>254) rt[3]= 255; else rt[3]= icol;
805 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
807 TStripElem *se1, *se2, *se3;
811 struct SeqEffectHandle sh = get_sequence_effect(seq);
813 if (!sh.execute) { /* effect not supported in this version... */
814 make_black_ibuf(se->ibuf);
818 #if 0 // XXX old animation system
819 if(seq->ipo && seq->ipo->curve.first) {
820 do_seq_ipo(scene, seq, cfra);
824 #endif // XXX old animation system
826 sh.get_default_fac(seq, cfra, &fac, &facf);
829 if( !(scene->r.mode & R_FIELDS) ) facf = fac;
831 early_out = sh.early_out(seq, fac, facf);
833 if (early_out == -1) { /* no input needed */
834 sh.execute(seq, cfra, fac, facf,
835 se->ibuf->x, se->ibuf->y,
842 if (se->se1==0 || se->se2==0 || se->se3==0) {
843 make_black_ibuf(se->ibuf);
851 if ( (se1==0 || se2==0 || se3==0)
852 || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
853 make_black_ibuf(se->ibuf);
860 make_black_ibuf(se->ibuf);
866 if (se1 == 0 || se1->ibuf == 0) {
867 make_black_ibuf(se->ibuf);
871 if (se->ibuf != se1->ibuf) {
872 IMB_freeImBuf(se->ibuf);
873 se->ibuf = se1->ibuf;
874 IMB_refImBuf(se->ibuf);
879 make_black_ibuf(se->ibuf);
885 if (se2 == 0 || se2->ibuf == 0) {
886 make_black_ibuf(se->ibuf);
889 if (se->ibuf != se2->ibuf) {
890 IMB_freeImBuf(se->ibuf);
891 se->ibuf = se2->ibuf;
892 IMB_refImBuf(se->ibuf);
896 make_black_ibuf(se->ibuf);
903 if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
904 IMB_float_from_rect(se1->ibuf);
906 if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
907 IMB_float_from_rect(se2->ibuf);
909 if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
910 IMB_float_from_rect(se3->ibuf);
913 if (!se1->ibuf->rect && !se->ibuf->rect_float) {
914 IMB_rect_from_float(se1->ibuf);
916 if (!se2->ibuf->rect && !se->ibuf->rect_float) {
917 IMB_rect_from_float(se2->ibuf);
919 if (!se3->ibuf->rect && !se->ibuf->rect_float) {
920 IMB_rect_from_float(se3->ibuf);
923 sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
927 static int give_stripelem_index(Sequence *seq, int cfra)
931 if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
932 if(seq->len == 0) return -1;
933 if(seq->flag&SEQ_REVERSE_FRAMES) {
934 /*reverse frame in this sequence */
935 if(cfra <= seq->start) nr= seq->len-1;
936 else if(cfra >= seq->start+seq->len-1) nr= 0;
937 else nr= (seq->start + seq->len) - cfra;
939 if(cfra <= seq->start) nr= 0;
940 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
941 else nr= cfra-seq->start;
943 if (seq->strobe < 1.0) seq->strobe = 1.0;
944 if (seq->strobe > 1.0) {
945 nr -= (int)fmod((double)nr, (double)seq->strobe);
951 static TStripElem* alloc_tstripdata(int len, const char * name)
954 TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
955 for (i = 0; i < len; i++) {
956 se[i].ok = STRIPELEM_OK;
961 static TStripElem *give_tstripelem(Sequence *seq, int cfra)
966 se = seq->strip->tstripdata;
967 if (se == 0 && seq->len > 0) {
968 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
971 nr = give_stripelem_index(seq, cfra);
973 if (nr == -1) return 0;
974 if (se == 0) return 0;
978 /* if there are IPOs with blend modes active, one has to watch out
979 for startstill + endstill area: we can't use the same tstripelem
980 here for all ibufs, since then, blending with IPOs won't work!
982 Rather common case, if you use a single image and try to fade
983 it in and out... or want to use your strip as a watermark in
986 if (seq->blend_mode != SEQ_BLEND_REPLACE ||
987 (/*seq->ipo && seq->ipo->curve.first &&*/
988 (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
989 Strip * s = seq->strip;
990 if (cfra < seq->start) {
991 se = s->tstripdata_startstill;
992 if (seq->startstill > s->startstill) {
993 free_tstripdata(s->startstill,
994 s->tstripdata_startstill);
999 s->startstill = seq->startstill;
1000 se = seq->strip->tstripdata_startstill
1003 "tstripelems_startstill");
1005 se += seq->start - cfra - 1;
1007 } else if (cfra > seq->start + seq->len-1) {
1008 se = s->tstripdata_endstill;
1009 if (seq->endstill > s->endstill) {
1010 free_tstripdata(s->endstill,
1011 s->tstripdata_endstill);
1016 s->endstill = seq->endstill;
1017 se = seq->strip->tstripdata_endstill
1020 "tstripelems_endstill");
1022 se += cfra - (seq->start + seq->len-1) - 1;
1032 StripElem *give_stripelem(Sequence *seq, int cfra)
1037 se = seq->strip->stripdata;
1038 nr = give_stripelem_index(seq, cfra);
1040 if (nr == -1) return 0;
1041 if (se == 0) return 0;
1043 se += nr + seq->anim_startofs;
1048 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1053 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1055 seq= seqbase->first;
1057 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1058 seq_arr[seq->machine]= seq;
1067 int evaluate_seq_frame(Scene *scene, int cfra)
1069 Editing *ed= seq_give_editing(scene, FALSE);
1070 Sequence *seq_arr[MAXSEQ+1];
1072 if(ed==NULL) return 0;
1073 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1076 static int video_seq_is_rendered(Sequence * seq)
1079 && !(seq->flag & SEQ_MUTE)
1080 && seq->type != SEQ_SOUND);
1083 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1085 Sequence *seq_arr[MAXSEQ+1];
1093 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1095 if (seq_arr[b] == 0) {
1099 for (b = MAXSEQ; b > 0; b--) {
1100 if (video_seq_is_rendered(seq_arr[b])) {
1110 if (video_seq_is_rendered(seq_arr[b])) {
1111 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1117 for (;b <= chanshown; b++) {
1118 if (video_seq_is_rendered(seq_arr[b])) {
1119 seq_arr_out[cnt++] = seq_arr[b];
1127 /* **********************************************************************
1129 ********************************************************************** */
1131 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1133 static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size)
1136 char dir[FILE_MAXDIR];
1138 if (!seq->strip->proxy) {
1142 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1143 strcpy(dir, seq->strip->proxy->dir);
1145 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1146 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
1153 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1154 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1155 BLI_convertstringcode(name, G.sce);
1156 BLI_convertstringframe(name, cfra);
1161 /* generate a separate proxy directory for each preview size */
1163 if (seq->type == SEQ_IMAGE) {
1164 StripElem * se = give_stripelem(seq, cfra);
1165 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1166 dir, render_size, se->name);
1168 } else if (seq->type == SEQ_MOVIE) {
1169 TStripElem * tse = give_tstripelem(seq, cfra);
1171 frameno = tse->nr + seq->anim_startofs;
1173 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1174 seq->strip->stripdata->name,
1177 TStripElem * tse = give_tstripelem(seq, cfra);
1179 frameno = tse->nr + seq->anim_startofs;
1181 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1185 BLI_convertstringcode(name, G.sce);
1186 BLI_convertstringframe(name, frameno);
1189 strcat(name, ".jpg");
1194 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1196 char name[PROXY_MAXFILE];
1198 if (!(seq->flag & SEQ_USE_PROXY)) {
1202 /* rendering at 100% ? No real sense in proxy-ing, right? */
1203 if (render_size == 100) {
1207 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1208 TStripElem * tse = give_tstripelem(seq, cfra);
1209 int frameno = tse->nr + seq->anim_startofs;
1210 if (!seq->strip->proxy->anim) {
1211 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1215 seq->strip->proxy->anim = openanim(name, IB_rect);
1217 if (!seq->strip->proxy->anim) {
1221 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1224 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1228 if (BLI_exists(name)) {
1229 return IMB_loadiffname(name, IB_rect);
1236 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1237 int build_proxy_run, int render_size);
1239 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1241 char name[PROXY_MAXFILE];
1246 struct ImBuf * ibuf;
1248 if (!(seq->flag & SEQ_USE_PROXY)) {
1252 /* rendering at 100% ? No real sense in proxy-ing, right? */
1253 if (render_size == 100) {
1257 /* that's why it is called custom... */
1258 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1262 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1266 se = give_tstripelem(seq, cfra);
1272 IMB_freeImBuf(se->ibuf);
1276 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1282 rectx= (render_size*scene->r.xsch)/100;
1283 recty= (render_size*scene->r.ysch)/100;
1287 if (ibuf->x != rectx || ibuf->y != recty) {
1288 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1291 /* quality is fixed, otherwise one has to generate separate
1292 directories for every quality...
1294 depth = 32 is intentionally left in, otherwise ALPHA channels
1296 quality = seq->strip->proxy->quality;
1297 ibuf->ftype= JPG | quality;
1299 BLI_make_existing_file(name);
1301 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1306 IMB_freeImBuf(ibuf);
1310 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1313 float rsize = seq->strip->proxy->size;
1319 /* flag management tries to account for strobe and
1320 other "non-linearities", that might come in the future...
1321 better way would be to "touch" the files, so that _really_
1322 no one is rebuild twice.
1325 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1326 TStripElem * tse = give_tstripelem(seq, cfra);
1328 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1333 /* a _lot_ faster for movie files, if we read frames in
1335 if (seq->flag & SEQ_REVERSE_FRAMES) {
1336 for (cfra = seq->enddisp-seq->endstill-1;
1337 cfra >= seq->startdisp + seq->startstill; cfra--) {
1338 TStripElem * tse = give_tstripelem(seq, cfra);
1340 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1341 //XXX set_timecursor(cfra);
1342 seq_proxy_build_frame(scene, seq, cfra, rsize);
1343 tse->flag |= STRIPELEM_PREVIEW_DONE;
1345 if (blender_test_break()) {
1350 for (cfra = seq->startdisp + seq->startstill;
1351 cfra < seq->enddisp - seq->endstill; cfra++) {
1352 TStripElem * tse = give_tstripelem(seq, cfra);
1354 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1355 //XXX set_timecursor(cfra);
1356 seq_proxy_build_frame(scene, seq, cfra, rsize);
1357 tse->flag |= STRIPELEM_PREVIEW_DONE;
1359 if (blender_test_break()) {
1369 /* **********************************************************************
1371 ********************************************************************** */
1373 static StripColorBalance calc_cb(StripColorBalance * cb_)
1375 StripColorBalance cb = *cb_;
1378 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1379 for (c = 0; c < 3; c++) {
1380 cb.lift[c] = 1.0 - cb.lift[c];
1383 for (c = 0; c < 3; c++) {
1384 cb.lift[c] = -(1.0 - cb.lift[c]);
1387 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1388 for (c = 0; c < 3; c++) {
1389 if (cb.gain[c] != 0.0) {
1390 cb.gain[c] = 1.0/cb.gain[c];
1392 cb.gain[c] = 1000000; /* should be enough :) */
1397 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1398 for (c = 0; c < 3; c++) {
1399 if (cb.gamma[c] != 0.0) {
1400 cb.gamma[c] = 1.0/cb.gamma[c];
1402 cb.gamma[c] = 1000000; /* should be enough :) */
1410 static void make_cb_table_byte(float lift, float gain, float gamma,
1411 unsigned char * table, float mul)
1415 for (y = 0; y < 256; y++) {
1416 float v = 1.0 * y / 255;
1423 } else if (v < 0.0) {
1431 static void make_cb_table_float(float lift, float gain, float gamma,
1432 float * table, float mul)
1436 for (y = 0; y < 256; y++) {
1437 float v = (float) y * 1.0 / 255.0;
1446 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1448 unsigned char cb_tab[3][256];
1450 unsigned char * p = (unsigned char*) se->ibuf->rect;
1451 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1453 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1455 for (c = 0; c < 3; c++) {
1456 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1461 p[0] = cb_tab[0][p[0]];
1462 p[1] = cb_tab[1][p[1]];
1463 p[2] = cb_tab[2][p[2]];
1469 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1471 float cb_tab[4][256];
1473 unsigned char * p = (unsigned char*) se->ibuf->rect;
1474 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1476 StripColorBalance cb;
1478 imb_addrectfloatImBuf(se->ibuf);
1480 o = se->ibuf->rect_float;
1482 cb = calc_cb(seq->strip->color_balance);
1484 for (c = 0; c < 3; c++) {
1485 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1489 for (i = 0; i < 256; i++) {
1490 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1494 o[0] = cb_tab[0][p[0]];
1495 o[1] = cb_tab[1][p[1]];
1496 o[2] = cb_tab[2][p[2]];
1497 o[3] = cb_tab[3][p[3]];
1503 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1505 float * p = se->ibuf->rect_float;
1506 float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1507 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1511 for (c = 0; c < 3; c++) {
1512 p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
1519 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1521 if (se->ibuf->rect_float) {
1522 color_balance_float_float(seq, se, mul);
1523 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1524 color_balance_byte_float(seq, se, mul);
1526 color_balance_byte_byte(seq, se, mul);
1531 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1533 Do all the things you can't really do afterwards using sequence effects
1534 (read: before rescaling to render resolution has been done)
1539 - Crop and transform in image source coordinate space
1540 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1541 - Promote image to float data (affects pipeline operations afterwards)
1542 - Color balance (is most efficient in the byte -> float
1543 (future: half -> float should also work fine!)
1544 case, if done on load, since we can use lookup tables)
1549 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1553 if ((seq->flag & SEQ_FILTERY) ||
1554 (seq->flag & SEQ_USE_CROP) ||
1555 (seq->flag & SEQ_USE_TRANSFORM) ||
1556 (seq->flag & SEQ_FLIPX) ||
1557 (seq->flag & SEQ_FLIPY) ||
1558 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1559 (seq->flag & SEQ_MAKE_PREMUL) ||
1560 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1566 if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1567 !(seq->type & SEQ_EFFECT)) {
1568 #if 0 // XXX old animation system
1569 if (seq->ipo && seq->ipo->curve.first) {
1570 do_seq_ipo(scene, seq, cfra);
1573 #endif // XXX old animation system
1574 mul *= seq->blend_opacity / 100.0;
1584 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1588 seq->strip->orx= se->ibuf->x;
1589 seq->strip->ory= se->ibuf->y;
1591 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1592 IMB_filtery(se->ibuf);
1595 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1600 memset(&c, 0, sizeof(StripCrop));
1601 memset(&t, 0, sizeof(StripTransform));
1603 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1604 c = *seq->strip->crop;
1606 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1607 t = *seq->strip->transform;
1610 sx = se->ibuf->x - c.left - c.right;
1611 sy = se->ibuf->y - c.top - c.bottom;
1615 if (seq->flag & SEQ_USE_TRANSFORM) {
1620 if (c.top + c.bottom >= se->ibuf->y ||
1621 c.left + c.right >= se->ibuf->x ||
1622 t.xofs >= dx || t.yofs >= dy) {
1623 make_black_ibuf(se->ibuf);
1627 if (se->ibuf->rect_float) {
1628 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1630 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1633 IMB_rectcpy(i, se->ibuf,
1638 IMB_freeImBuf(se->ibuf);
1644 if(seq->flag & SEQ_FLIPX) {
1645 IMB_flipx(se->ibuf);
1647 if(seq->flag & SEQ_FLIPY) {
1648 IMB_flipy(se->ibuf);
1651 if(seq->mul == 0.0) {
1657 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1658 #if 0 // XXX old animation system
1659 if (seq->ipo && seq->ipo->curve.first) {
1660 do_seq_ipo(scene, seq, cfra);
1663 #endif // XXX old animation system
1664 mul *= seq->blend_opacity / 100.0;
1667 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1668 color_balance(seq, se, mul);
1672 if(seq->flag & SEQ_MAKE_FLOAT) {
1673 if (!se->ibuf->rect_float) {
1674 IMB_float_from_rect(se->ibuf);
1676 if (se->ibuf->rect) {
1677 imb_freerectImBuf(se->ibuf);
1682 multibuf(se->ibuf, mul);
1685 if(seq->flag & SEQ_MAKE_PREMUL) {
1686 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1687 converttopremul(se->ibuf);
1692 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1693 if(scene->r.mode & R_OSA) {
1694 IMB_scaleImBuf(se->ibuf,
1695 (short)seqrectx, (short)seqrecty);
1697 IMB_scalefastImBuf(se->ibuf,
1698 (short)seqrectx, (short)seqrecty);
1703 /* test if image too small or discarded from cache: reload */
1705 static void test_and_auto_discard_ibuf(TStripElem * se)
1708 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
1709 || !(se->ibuf->rect || se->ibuf->rect_float)) {
1710 IMB_freeImBuf(se->ibuf);
1713 se->ok= STRIPELEM_OK;
1716 if (se->ibuf_comp) {
1717 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
1718 || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1719 IMB_freeImBuf(se->ibuf_comp);
1726 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1728 if (strip->ibuf_startstill) {
1729 if (!strip->ibuf_startstill->rect &&
1730 !strip->ibuf_startstill->rect_float) {
1731 IMB_freeImBuf(strip->ibuf_startstill);
1732 strip->ibuf_startstill = 0;
1735 if (strip->ibuf_endstill) {
1736 if (!strip->ibuf_endstill->rect &&
1737 !strip->ibuf_endstill->rect_float) {
1738 IMB_freeImBuf(strip->ibuf_endstill);
1739 strip->ibuf_endstill = 0;
1744 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1747 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1748 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1750 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1752 if (se->nr == seq->len - 1
1754 && seq->strip->ibuf_endstill) {
1755 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1757 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1762 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1766 seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1768 IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1769 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1771 if (se->nr == seq->len - 1 && seq->len != 1) {
1772 seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1774 IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1775 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1780 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1782 Sequence* seq_arr[MAXSEQ+1];
1786 evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1788 for (i = 0; i < MAXSEQ; i++) {
1789 if (!video_seq_is_rendered(seq_arr[i])) {
1792 se = give_tstripelem(seq_arr[i], cfra);
1795 IMB_freeImBuf(se->ibuf);
1798 se->ok= STRIPELEM_OK;
1801 if (se->ibuf_comp) {
1802 IMB_freeImBuf(se->ibuf_comp);
1811 static void check_limiter_refcount(const char * func, TStripElem *se)
1813 if (se && se->ibuf) {
1814 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1815 if (refcount != 1) {
1816 /* can happen on complex pipelines */
1817 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1822 "sequencer: (ibuf) %s: "
1823 "suspicious memcache "
1824 "limiter refcount: %d\n", func, refcount);
1829 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1831 if (se && se->ibuf_comp) {
1832 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1833 if (refcount != 1) {
1834 /* can happen on complex pipelines */
1835 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1839 "sequencer: (ibuf comp) %s: "
1840 "suspicious memcache "
1841 "limiter refcount: %d\n", func, refcount);
1846 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1847 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1849 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1850 int build_proxy_run, int render_size)
1852 char name[FILE_MAXDIR+FILE_MAXFILE];
1853 int use_limiter = TRUE;
1855 test_and_auto_discard_ibuf(se);
1856 test_and_auto_discard_ibuf_stills(seq->strip);
1858 if(seq->type == SEQ_META) {
1859 TStripElem * meta_se = 0;
1860 int use_preprocess = FALSE;
1861 use_limiter = FALSE;
1863 if (!build_proxy_run && se->ibuf == 0) {
1864 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1867 use_preprocess = TRUE;
1871 if(!se->ibuf && seq->seqbase.first) {
1872 meta_se = do_build_seq_array_recursively(scene,
1873 &seq->seqbase, seq->start + se->nr, 0,
1876 check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1879 se->ok = STRIPELEM_OK;
1881 if(!se->ibuf && meta_se) {
1882 se->ibuf = meta_se->ibuf_comp;
1884 (!input_have_to_preprocess(scene, seq, se, cfra) ||
1886 IMB_refImBuf(se->ibuf);
1887 if (build_proxy_run) {
1888 IMB_cache_limiter_unref(se->ibuf);
1890 } else if (se->ibuf) {
1891 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1893 IMB_cache_limiter_unref(se->ibuf);
1898 use_preprocess = TRUE;
1900 } else if (se->ibuf) {
1904 free_metastrip_imbufs(
1905 &seq->seqbase, seq->start + se->nr, 0);
1908 if (use_preprocess) {
1909 input_preprocess(scene, seq, se, cfra);
1911 } else if(seq->type & SEQ_EFFECT) {
1912 int use_preprocess = FALSE;
1913 /* should the effect be recalculated? */
1915 if (!build_proxy_run && se->ibuf == 0) {
1916 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1918 use_preprocess = TRUE;
1923 /* if any inputs are rectfloat, output is float too */
1924 if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1925 (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
1926 (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
1927 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1929 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1931 do_effect(scene, cfra, seq, se);
1932 if (input_have_to_preprocess(scene, seq, se, cfra) &&
1934 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
1935 (se->se2 && (se->ibuf == se->se2->ibuf))) {
1937 = IMB_dupImBuf(se->ibuf);
1939 IMB_freeImBuf(se->ibuf);
1943 use_preprocess = TRUE;
1946 if (use_preprocess) {
1947 input_preprocess(scene, seq, se, cfra);
1949 } else if(seq->type == SEQ_IMAGE) {
1950 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1951 StripElem * s_elem = give_stripelem(seq, cfra);
1952 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1953 BLI_convertstringcode(name, G.sce);
1954 BLI_convertstringframe(name, scene->r.cfra);
1955 if (!build_proxy_run) {
1956 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1958 copy_from_ibuf_still(seq, se);
1961 se->ibuf= IMB_loadiffname(
1963 /* we don't need both (speed reasons)! */
1965 se->ibuf->rect_float && se->ibuf->rect) {
1966 imb_freerectImBuf(se->ibuf);
1969 copy_to_ibuf_still(seq, se);
1973 se->ok = STRIPELEM_FAILED;
1974 } else if (!build_proxy_run) {
1975 input_preprocess(scene, seq, se, cfra);
1978 } else if(seq->type == SEQ_MOVIE) {
1979 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1980 if(!build_proxy_run) {
1981 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1983 copy_from_ibuf_still(seq, se);
1985 if (se->ibuf == 0) {
1987 BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
1988 BLI_convertstringcode(name, G.sce);
1989 BLI_convertstringframe(name, scene->r.cfra);
1991 seq->anim = openanim(
1993 ((seq->flag & SEQ_FILTERY)
1994 ? IB_animdeinterlace : 0));
1997 IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1998 se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1999 /* we don't need both (speed reasons)! */
2001 && se->ibuf->rect_float
2002 && se->ibuf->rect) {
2003 imb_freerectImBuf(se->ibuf);
2007 copy_to_ibuf_still(seq, se);
2011 se->ok = STRIPELEM_FAILED;
2012 } else if (!build_proxy_run) {
2013 input_preprocess(scene, seq, se, cfra);
2016 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
2018 /* XXX move entirely to render? */
2020 Sequence * oldseq = get_last_seq();
2021 Scene *sce= seq->scene, *oldsce= scene;
2024 int doseq, rendering= G.rendering;
2026 int have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2027 int sce_valid =sce && (sce->camera || have_seq);
2029 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2030 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2032 input_preprocess(scene, seq, se, cfra);
2036 if (se->ibuf == NULL && sce_valid) {
2037 copy_from_ibuf_still(seq, se);
2039 input_preprocess(scene, seq, se, cfra);
2044 se->ok = STRIPELEM_FAILED;
2045 } else if (se->ibuf==NULL && sce_valid) {
2046 /* no need to display a waitcursor on sequencer
2051 /* Hack! This function can be called from do_render_seq(), in that case
2052 the seq->scene can already have a Render initialized with same name,
2053 so we have to use a default name. (compositor uses scene name to
2055 However, when called from within the UI (image preview in sequencer)
2056 we do want to use scene Render, that way the render result is defined
2057 for display in render/imagewindow */
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 BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
2070 /* XXX hrms, set_scene still needed? work on that... */
2071 if(sce!=oldsce) set_scene_bg(sce);
2072 RE_BlenderFrame(re, sce,
2073 seq->sfra+se->nr+seq->anim_startofs);
2074 if(sce!=oldsce) set_scene_bg(oldsce);
2076 /* UGLY WARNING, it is set to zero in RE_BlenderFrame */
2077 G.rendering= rendering;
2079 BLI_strncpy(sce->id.name+2, scenename, 64);
2081 RE_AcquireResultImage(re, &rres);
2084 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2085 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2087 addzbuffloatImBuf(se->ibuf);
2088 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2090 } else if (rres.rect32) {
2091 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2092 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2095 RE_ReleaseResultImage(re);
2097 BIF_end_render_callbacks();
2100 scene->r.scemode |= doseq;
2104 if((G.f & G_PLAYANIM)==0 /* bad, is set on do_render_seq */
2106 && !build_proxy_run)
2110 set_last_seq(oldseq);
2112 copy_to_ibuf_still(seq, se);
2114 if (!build_proxy_run) {
2115 if(se->ibuf == NULL) {
2116 se->ok = STRIPELEM_FAILED;
2118 input_preprocess(scene, seq, se, cfra);
2125 if (!build_proxy_run) {
2126 if (se->ibuf && use_limiter) {
2127 IMB_cache_limiter_insert(se->ibuf);
2128 IMB_cache_limiter_ref(se->ibuf);
2129 IMB_cache_limiter_touch(se->ibuf);
2134 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2136 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2139 struct SeqEffectHandle sh = get_sequence_effect(seq);
2146 #if 0 // XXX old animation system
2147 if(seq->ipo && seq->ipo->curve.first) {
2148 do_seq_ipo(scene, seq, cfra);
2152 #endif // XXX old animation system
2154 sh.get_default_fac(seq, cfra, &fac, &facf);
2157 if( scene->r.mode & R_FIELDS ); else facf= fac;
2159 early_out = sh.early_out(seq, fac, facf);
2160 switch (early_out) {
2162 /* no input needed */
2165 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2166 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2168 se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2172 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2175 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2180 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2182 /* children are not needed anymore ... */
2184 if (se->se1 && se->se1->ibuf) {
2185 IMB_cache_limiter_unref(se->se1->ibuf);
2187 if (se->se2 && se->se2->ibuf) {
2188 IMB_cache_limiter_unref(se->se2->ibuf);
2190 if (se->se3 && se->se3->ibuf) {
2191 IMB_cache_limiter_unref(se->se3->ibuf);
2193 check_limiter_refcount("do_effect_seq_recursively", se);
2196 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2200 se = give_tstripelem(seq, cfra);
2203 if (seq->type & SEQ_EFFECT) {
2204 do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2206 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2214 If cfra was float throughout blender (especially in the render
2215 pipeline) one could even _render_ with subframe precision
2216 instead of faking using the blend code below...
2220 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2222 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2223 int nr = cfra - seq->start;
2227 TStripElem * se = 0;
2228 TStripElem * se1 = 0;
2229 TStripElem * se2 = 0;
2231 sequence_effect_speed_rebuild_map(scene, seq, 0);
2233 f_cfra = seq->start + s->frameMap[nr];
2235 cfra_left = (int) floor(f_cfra);
2236 cfra_right = (int) ceil(f_cfra);
2238 se = give_tstripelem(seq, cfra);
2244 if (cfra_left == cfra_right ||
2245 (s->flags & SEQ_SPEED_BLEND) == 0) {
2246 test_and_auto_discard_ibuf(se);
2248 if (se->ibuf == NULL) {
2249 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2251 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2252 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2254 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2256 if (se1 == 0 || se1->ibuf == 0) {
2257 make_black_ibuf(se->ibuf);
2259 if (se->ibuf != se1->ibuf) {
2261 IMB_freeImBuf(se->ibuf);
2264 se->ibuf = se1->ibuf;
2265 IMB_refImBuf(se->ibuf);
2270 struct SeqEffectHandle sh;
2273 if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
2274 || !(se->ibuf->rect || se->ibuf->rect_float)) {
2275 IMB_freeImBuf(se->ibuf);
2280 if (se->ibuf == NULL) {
2281 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2282 se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2284 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2285 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2287 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2290 make_black_ibuf(se->ibuf);
2292 sh = get_sequence_effect(seq);
2294 sh.execute(seq, cfra,
2295 f_cfra - (float) cfra_left,
2296 f_cfra - (float) cfra_left,
2297 se->ibuf->x, se->ibuf->y,
2298 se1->ibuf, se2->ibuf, 0, se->ibuf);
2304 /* caller expects this to be referenced, so do it! */
2306 IMB_cache_limiter_insert(se->ibuf);
2307 IMB_cache_limiter_ref(se->ibuf);
2308 IMB_cache_limiter_touch(se->ibuf);
2311 /* children are no longer needed */
2312 if (se1 && se1->ibuf)
2313 IMB_cache_limiter_unref(se1->ibuf);
2314 if (se2 && se2->ibuf)
2315 IMB_cache_limiter_unref(se2->ibuf);
2317 check_limiter_refcount("do_handle_speed_effect", se);
2323 * build all ibufs recursively
2325 * if successfull, the returned TStripElem contains the (referenced!) imbuf
2326 * that means: you _must_ call
2328 * IMB_cache_limiter_unref(rval);
2334 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2337 if (seq->type == SEQ_SPEED) {
2338 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2340 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2343 check_limiter_refcount("do_build_seq_recursively", se);
2348 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2349 ListBase *seqbasep, int cfra, int chanshown, int render_size)
2351 Sequence* seq_arr[MAXSEQ+1];
2356 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2362 se = give_tstripelem(seq_arr[count - 1], cfra);
2368 test_and_auto_discard_ibuf(se);
2370 if (se->ibuf_comp != 0) {
2371 IMB_cache_limiter_insert(se->ibuf_comp);
2372 IMB_cache_limiter_ref(se->ibuf_comp);
2373 IMB_cache_limiter_touch(se->ibuf_comp);
2379 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2381 se->ibuf_comp = se->ibuf;
2382 IMB_refImBuf(se->ibuf_comp);
2388 for (i = count - 1; i >= 0; i--) {
2390 Sequence * seq = seq_arr[i];
2391 struct SeqEffectHandle sh;
2393 se = give_tstripelem(seq, cfra);
2395 test_and_auto_discard_ibuf(se);
2397 if (se->ibuf_comp != 0) {
2400 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2401 do_build_seq_recursively(scene, seq, cfra, render_size);
2403 se->ibuf_comp = se->ibuf;
2404 IMB_refImBuf(se->ibuf);
2406 se->ibuf_comp = IMB_allocImBuf(
2407 (short)seqrectx, (short)seqrecty,
2409 IMB_cache_limiter_insert(se->ibuf_comp);
2410 IMB_cache_limiter_ref(se->ibuf_comp);
2411 IMB_cache_limiter_touch(se->ibuf_comp);
2416 sh = get_sequence_blend(seq);
2418 #if 0 // XXX old animation system
2419 seq->facf0 = seq->facf1 = 1.0;
2422 if(seq->ipo && seq->ipo->curve.first) {
2423 do_seq_ipo(scene, seq, cfra);
2427 if( scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
2429 seq->facf0 *= seq->blend_opacity / 100.0;
2430 seq->facf1 *= seq->blend_opacity / 100.0;
2432 early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2434 switch (early_out) {
2437 do_build_seq_recursively(scene, seq, cfra, render_size);
2439 se->ibuf_comp = se->ibuf;
2440 IMB_refImBuf(se->ibuf_comp);
2442 se->ibuf_comp = IMB_allocImBuf(
2443 (short)seqrectx, (short)seqrecty,
2445 IMB_cache_limiter_insert(se->ibuf_comp);
2446 IMB_cache_limiter_ref(se->ibuf_comp);
2447 IMB_cache_limiter_touch(se->ibuf_comp);
2452 se->ibuf_comp = IMB_allocImBuf(
2453 (short)seqrectx, (short)seqrecty,
2455 IMB_cache_limiter_insert(se->ibuf_comp);
2456 IMB_cache_limiter_ref(se->ibuf_comp);
2457 IMB_cache_limiter_touch(se->ibuf_comp);
2461 do_build_seq_recursively(scene, seq, cfra, render_size);
2463 se->ibuf = IMB_allocImBuf(
2464 (short)seqrectx, (short)seqrecty,
2466 IMB_cache_limiter_insert(se->ibuf);
2467 IMB_cache_limiter_ref(se->ibuf);
2468 IMB_cache_limiter_touch(se->ibuf);
2471 se->ibuf_comp = se->ibuf;
2472 IMB_refImBuf(se->ibuf_comp);
2477 if (se->ibuf_comp) {
2484 for (; i < count; i++) {
2485 Sequence * seq = seq_arr[i];
2486 struct SeqEffectHandle sh = get_sequence_blend(seq);
2487 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2488 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2490 int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2491 switch (early_out) {
2493 int x= se2->ibuf->x;
2494 int y= se2->ibuf->y;
2495 int swap_input = FALSE;
2497 if (se1->ibuf_comp->rect_float ||
2498 se2->ibuf->rect_float) {
2499 se2->ibuf_comp = IMB_allocImBuf(
2500 (short)seqrectx, (short)seqrecty,
2501 32, IB_rectfloat, 0);
2503 se2->ibuf_comp = IMB_allocImBuf(
2504 (short)seqrectx, (short)seqrecty,
2509 if (!se1->ibuf_comp->rect_float &&
2510 se2->ibuf_comp->rect_float) {
2511 IMB_float_from_rect(se1->ibuf_comp);
2513 if (!se2->ibuf->rect_float &&
2514 se2->ibuf_comp->rect_float) {
2515 IMB_float_from_rect(se2->ibuf);
2518 if (!se1->ibuf_comp->rect &&
2519 !se2->ibuf_comp->rect_float) {
2520 IMB_rect_from_float(se1->ibuf_comp);
2522 if (!se2->ibuf->rect &&
2523 !se2->ibuf_comp->rect_float) {
2524 IMB_rect_from_float(se2->ibuf);
2527 /* bad hack, to fix crazy input ordering of
2528 those two effects */
2530 if (seq->blend_mode == SEQ_ALPHAOVER ||
2531 seq->blend_mode == SEQ_ALPHAUNDER ||
2532 seq->blend_mode == SEQ_OVERDROP) {
2537 sh.execute(seq, cfra,
2538 seq->facf0, seq->facf1, x, y,
2539 se2->ibuf, se1->ibuf_comp, 0,
2542 sh.execute(seq, cfra,
2543 seq->facf0, seq->facf1, x, y,
2544 se1->ibuf_comp, se2->ibuf, 0,
2548 IMB_cache_limiter_insert(se2->ibuf_comp);
2549 IMB_cache_limiter_ref(se2->ibuf_comp);
2550 IMB_cache_limiter_touch(se2->ibuf_comp);
2552 IMB_cache_limiter_unref(se1->ibuf_comp);
2553 IMB_cache_limiter_unref(se2->ibuf);
2558 se2->ibuf_comp = se1->ibuf;
2559 IMB_refImBuf(se2->ibuf_comp);
2571 * returned ImBuf is refed!
2572 * you have to unref after usage!
2575 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2577 Editing *ed= seq_give_editing(scene, FALSE);
2583 if(ed==NULL) return NULL;
2585 count = BLI_countlist(&ed->metastack);
2586 if((chanshown < 0) && (count > 0)) {
2587 count = MAX2(count + chanshown, 0);
2588 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2590 seqbasep= ed->seqbasep;
2593 seqrectx= rectx; /* bad bad global! */
2596 se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2602 check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2604 return se->ibuf_comp;
2607 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2611 seqrectx= rectx; /* bad bad global! */
2614 se = do_build_seq_recursively(scene, seq, cfra, render_size);
2620 check_limiter_refcount("give_ibuf_seq_direct", se);
2623 IMB_cache_limiter_unref(se->ibuf);
2629 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2631 ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2634 IMB_cache_limiter_unref(i);
2640 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2641 static int seq_can_blend(Sequence *seq)
2643 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2651 /* *********************** threading api ******************* */
2653 static ListBase running_threads;
2654 static ListBase prefetch_wait;
2655 static ListBase prefetch_done;
2657 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2658 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2659 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2661 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2662 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2664 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2665 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2667 static volatile int seq_thread_shutdown = FALSE;
2668 static volatile int seq_last_given_monoton_cfra = 0;
2669 static int monoton_cfra = 0;
2671 typedef struct PrefetchThread {
2672 struct PrefetchThread *next, *prev;
2675 struct PrefetchQueueElem *current;
2681 typedef struct PrefetchQueueElem {
2682 struct PrefetchQueueElem *next, *prev;
2692 struct ImBuf * ibuf;
2693 } PrefetchQueueElem;
2696 static void *seq_prefetch_thread(void * This_)
2698 PrefetchThread * This = This_;
2700 while (!seq_thread_shutdown) {
2701 PrefetchQueueElem *e;
2704 pthread_mutex_lock(&queue_lock);
2705 e = prefetch_wait.first;
2707 BLI_remlink(&prefetch_wait, e);
2709 s_last = seq_last_given_monoton_cfra;
2713 pthread_mutex_unlock(&queue_lock);
2716 pthread_mutex_lock(&prefetch_ready_lock);
2718 This->running = FALSE;
2720 pthread_cond_signal(&prefetch_ready_cond);
2721 pthread_mutex_unlock(&prefetch_ready_lock);
2723 pthread_mutex_lock(&wakeup_lock);
2724 if (!seq_thread_shutdown) {
2725 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2727 pthread_mutex_unlock(&wakeup_lock);
2731 This->running = TRUE;
2733 if (e->cfra >= s_last) {
2734 e->ibuf = give_ibuf_seq_impl(This->scene,
2735 e->rectx, e->recty, e->cfra, e->chanshown,
2739 pthread_mutex_lock(&queue_lock);
2741 BLI_addtail(&prefetch_done, e);
2743 for (e = prefetch_wait.first; e; e = e->next) {
2744 if (s_last > e->monoton_cfra) {
2745 BLI_remlink(&prefetch_wait, e);
2750 for (e = prefetch_done.first; e; e = e->next) {
2751 if (s_last > e->monoton_cfra) {
2753 IMB_cache_limiter_unref(e->ibuf);
2755 BLI_remlink(&prefetch_done, e);
2760 pthread_mutex_unlock(&queue_lock);
2762 pthread_mutex_lock(&frame_done_lock);
2763 pthread_cond_signal(&frame_done_cond);
2764 pthread_mutex_unlock(&frame_done_lock);
2769 static void seq_start_threads(Scene *scene)
2773 running_threads.first = running_threads.last = NULL;
2774 prefetch_wait.first = prefetch_wait.last = NULL;
2775 prefetch_done.first = prefetch_done.last = NULL;
2777 seq_thread_shutdown = FALSE;
2778 seq_last_given_monoton_cfra = monoton_cfra = 0;
2780 /* since global structures are modified during the processing
2781 of one frame, only one render thread is currently possible...
2783 (but we code, in the hope, that we can remove this restriction
2787 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2789 for (i = 0; i < 1; i++) {
2790 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2793 BLI_addtail(&running_threads, t);
2795 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2798 /* init malloc mutex */
2799 BLI_init_threads(0, 0, 0);
2802 static void seq_stop_threads()
2804 PrefetchThread *tslot;
2805 PrefetchQueueElem *e;
2807 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2809 if (seq_thread_shutdown) {
2810 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2814 pthread_mutex_lock(&wakeup_lock);
2816 seq_thread_shutdown = TRUE;
2818 pthread_cond_broadcast(&wakeup_cond);
2819 pthread_mutex_unlock(&wakeup_lock);
2821 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2822 pthread_join(tslot->pthread, NULL);
2826 for (e = prefetch_wait.first; e; e = e->next) {
2827 BLI_remlink(&prefetch_wait, e);
2831 for (e = prefetch_done.first; e; e = e->next) {
2833 IMB_cache_limiter_unref(e->ibuf);
2835 BLI_remlink(&prefetch_done, e);
2839 BLI_freelistN(&running_threads);
2841 /* deinit malloc mutex */
2846 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2849 PrefetchQueueElem *e;
2850 if (seq_thread_shutdown) {
2854 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2858 e->chanshown = chanshown;
2859 e->render_size = render_size;
2860 e->monoton_cfra = monoton_cfra++;
2862 pthread_mutex_lock(&queue_lock);
2863 BLI_addtail(&prefetch_wait, e);
2864 pthread_mutex_unlock(&queue_lock);
2866 pthread_mutex_lock(&wakeup_lock);
2867 pthread_cond_signal(&wakeup_cond);
2868 pthread_mutex_unlock(&wakeup_lock);
2872 static void seq_wait_for_prefetch_ready()
2874 PrefetchThread *tslot;
2876 if (seq_thread_shutdown) {
2880 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2882 pthread_mutex_lock(&prefetch_ready_lock);
2885 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2886 if (tslot->running) {
2893 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2896 pthread_mutex_unlock(&prefetch_ready_lock);
2898 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2902 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2904 PrefetchQueueElem *e = NULL;
2905 int found_something = FALSE;
2907 if (seq_thread_shutdown) {
2908 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2912 int success = FALSE;
2913 pthread_mutex_lock(&queue_lock);
2915 for (e = prefetch_done.first; e; e = e->next) {
2916 if (cfra == e->cfra &&
2917 chanshown == e->chanshown &&
2918 rectx == e->rectx &&
2919 recty == e->recty &&
2920 render_size == e->render_size) {
2922 found_something = TRUE;
2928 for (e = prefetch_wait.first; e; e = e->next) {
2929 if (cfra == e->cfra &&
2930 chanshown == e->chanshown &&
2931 rectx == e->rectx &&
2932 recty == e->recty &&
2933 render_size == e->render_size) {
2934 found_something = TRUE;
2941 PrefetchThread *tslot;
2943 for(tslot = running_threads.first;
2944 tslot; tslot= tslot->next) {
2945 if (tslot->current &&
2946 cfra == tslot->current->cfra &&
2947 chanshown == tslot->current->chanshown &&
2948 rectx == tslot->current->rectx &&
2949 recty == tslot->current->recty &&
2950 render_size== tslot->current->render_size){
2951 found_something = TRUE;
2957 /* e->ibuf is unrefed by render thread on next round. */
2960 seq_last_given_monoton_cfra = e->monoton_cfra;
2963 pthread_mutex_unlock(&queue_lock);
2968 if (!found_something) {
2970 "SEQ-THREAD: Requested frame "
2971 "not in queue ???\n");
2974 pthread_mutex_lock(&frame_done_lock);
2975 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2976 pthread_mutex_unlock(&frame_done_lock);
2980 return e ? e->ibuf : 0;
2983 /* Functions to free imbuf and anim data on changes */
2985 static void free_imbuf_strip_elem(TStripElem *se)
2988 IMB_freeImBuf(se->ibuf);
2991 IMB_freeImBuf(se->ibuf_comp);
2995 se->ok= STRIPELEM_OK;
2996 se->se1= se->se2= se->se3= 0;
2999 static void free_anim_seq(Sequence *seq)
3002 IMB_free_anim(seq->anim);
3008 static void free_imbuf_seq_except(Scene *scene, int cfra)
3010 Editing *ed= seq_give_editing(scene, FALSE);
3015 if(ed==NULL) return;
3017 SEQ_BEGIN(ed, seq) {
3019 TStripElem * curelem = give_tstripelem(seq, cfra);
3021 for(a = 0, se = seq->strip->tstripdata;
3022 a < seq->strip->len && se; a++, se++) {
3024 free_imbuf_strip_elem(se);
3027 for(a = 0, se = seq->strip->tstripdata_startstill;
3028 a < seq->strip->startstill && se; a++, se++) {
3030 free_imbuf_strip_elem(se);
3033 for(a = 0, se = seq->strip->tstripdata_endstill;
3034 a < seq->strip->endstill && se; a++, se++) {
3036 free_imbuf_strip_elem(se);
3039 if(seq->strip->ibuf_startstill) {
3040 IMB_freeImBuf(seq->strip->ibuf_startstill);
3041 seq->strip->ibuf_startstill = 0;
3044 if(seq->strip->ibuf_endstill) {
3045 IMB_freeImBuf(seq->strip->ibuf_endstill);
3046 seq->strip->ibuf_endstill = 0;
3049 if(seq->type==SEQ_MOVIE)
3050 if(seq->startdisp > cfra || seq->enddisp < cfra)
3052 free_proxy_seq(seq);
3059 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3065 if (check_mem_usage) {
3066 /* Let the cache limitor take care of this (schlaile) */
3067 /* While render let's keep all memory available for render
3069 At least if free memory is tight...
3070 This can make a big difference in encoding speed
3071 (it is around 4 times(!) faster, if we do not waste time
3072 on freeing _all_ buffers every time on long timelines...)
3076 uintptr_t mem_in_use;
3077 uintptr_t mmap_in_use;
3080 mem_in_use= MEM_get_memory_in_use();
3081 mmap_in_use= MEM_get_mapped_memory_in_use();
3082 max = MEM_CacheLimiter_get_maximum();
3084 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3090 for(seq= seqbase->first; seq; seq= seq->next) {
3092 for(a = 0, se = seq->strip->tstripdata;
3093 a < seq->strip->len && se; a++, se++) {
3094 free_imbuf_strip_elem(se);
3096 for(a = 0, se = seq->strip->tstripdata_startstill;
3097 a < seq->strip->startstill && se; a++, se++) {
3098 free_imbuf_strip_elem(se);
3100 for(a = 0, se = seq->strip->tstripdata_endstill;
3101 a < seq->strip->endstill && se; a++, se++) {
3102 free_imbuf_strip_elem(se);
3104 if(seq->strip->ibuf_startstill) {
3105 IMB_freeImBuf(seq->strip->ibuf_startstill);
3106 seq->strip->ibuf_startstill = 0;
3109 if(seq->strip->ibuf_endstill) {
3110 IMB_freeImBuf(seq->strip->ibuf_endstill);
3111 seq->strip->ibuf_endstill = 0;
3114 if(seq->type==SEQ_MOVIE)
3116 if(seq->type==SEQ_SPEED) {
3117 sequence_effect_speed_rebuild_map(scene, seq, 1);
3120 if(seq->type==SEQ_META) {
3121 free_imbuf_seq(scene, &seq->seqbase, FALSE);
3123 if(seq->type==SEQ_SCENE) {
3124 /* FIXME: recurs downwards,
3125 but do recurs protection somehow! */
3131 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3134 int a, free_imbuf = 0;
3137 /* recurs downwards to see if this seq depends on the changed seq */
3142 if(seq == changed_seq)
3145 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
3146 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3150 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3152 if(seq->seq2 && (seq->seq2 != seq->seq1))
3153 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3155 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3156 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3161 se= seq->strip->tstripdata;
3163 for(a=0; a<seq->len; a++, se++)
3164 free_imbuf_strip_elem(se);
3167 if(seq->type == SEQ_MOVIE)
3169 if(seq->type == SEQ_SPEED) {
3170 sequence_effect_speed_rebuild_map(scene, seq, 1);
3181 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3183 Editing *ed= seq_give_editing(scene, FALSE);
3186 if (ed==NULL) return;
3188 for (seq=ed->seqbase.first; seq; seq=seq->next)
3189 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3192 #if 0 // XXX from 2.4x, needs updating
3193 void free_imbuf_seq()
3195 Scene * sce = G.main->scene.first;
3197 free_imbuf_seq_editing(sce->ed);
3203 #if 0 // XXX old animation system
3204 static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
<