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_blenlib.h"
55 #include "IMB_imbuf.h"
56 #include "IMB_imbuf_types.h"
58 #include "BLI_threads.h"
61 #include "BKE_context.h"
62 #include "BKE_sound.h"
63 #include "AUD_C-API.h"
66 #define snprintf _snprintf
69 /* **** XXX ******** */
70 static int seqrectx= 0; /* bad bad global! */
71 static int seqrecty= 0;
72 //static void waitcursor(int val) {}
73 //static int blender_test_break() {return 0;}
75 /* **** XXX ******** */
78 void printf_strip(Sequence *seq)
80 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
81 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
82 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));
85 /* **********************************************************************
86 alloc / free functions
87 ********************************************************************** */
89 static void free_tstripdata(int len, TStripElem *se)
98 for(a=0; a<len; a++, se++) {
100 IMB_freeImBuf(se->ibuf);
104 IMB_freeImBuf(se->ibuf_comp);
113 void new_tstripdata(Sequence *seq)
116 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
117 free_tstripdata(seq->strip->endstill,
118 seq->strip->tstripdata_endstill);
119 free_tstripdata(seq->strip->startstill,
120 seq->strip->tstripdata_startstill);
122 seq->strip->tstripdata= 0;
123 seq->strip->tstripdata_endstill= 0;
124 seq->strip->tstripdata_startstill= 0;
126 if(seq->strip->ibuf_startstill) {
127 IMB_freeImBuf(seq->strip->ibuf_startstill);
128 seq->strip->ibuf_startstill = 0;
131 if(seq->strip->ibuf_endstill) {
132 IMB_freeImBuf(seq->strip->ibuf_endstill);
133 seq->strip->ibuf_endstill = 0;
136 seq->strip->len= seq->len;
143 static void free_proxy_seq(Sequence *seq)
145 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
146 IMB_free_anim(seq->strip->proxy->anim);
147 seq->strip->proxy->anim = 0;
151 void seq_free_strip(Strip *strip)
154 if(strip->us>0) return;
156 printf("error: negative users in strip\n");
160 if (strip->stripdata) {
161 MEM_freeN(strip->stripdata);
165 if (strip->proxy->anim) {
166 IMB_free_anim(strip->proxy->anim);
169 MEM_freeN(strip->proxy);
172 MEM_freeN(strip->crop);
174 if (strip->transform) {
175 MEM_freeN(strip->transform);
177 if (strip->color_balance) {
178 MEM_freeN(strip->color_balance);
181 free_tstripdata(strip->len, strip->tstripdata);
182 free_tstripdata(strip->endstill, strip->tstripdata_endstill);
183 free_tstripdata(strip->startstill, strip->tstripdata_startstill);
185 if(strip->ibuf_startstill) {
186 IMB_freeImBuf(strip->ibuf_startstill);
187 strip->ibuf_startstill = 0;
190 if(strip->ibuf_endstill) {
191 IMB_freeImBuf(strip->ibuf_endstill);
192 strip->ibuf_endstill = 0;
198 void seq_free_sequence(Scene *scene, Sequence *seq)
200 Editing *ed = scene->ed;
202 if(seq->strip) seq_free_strip(seq->strip);
204 if(seq->anim) IMB_free_anim(seq->anim);
206 if(seq->sound_handle)
207 sound_delete_handle(scene, seq->sound_handle);
209 if (seq->type & SEQ_EFFECT) {
210 struct SeqEffectHandle sh = get_sequence_effect(seq);
215 if (ed->act_seq==seq)
221 Editing *seq_give_editing(Scene *scene, int alloc)
223 if (scene->ed == NULL && alloc) {
226 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
227 ed->seqbasep= &ed->seqbase;
232 void seq_free_editing(Scene *scene)
234 Editing *ed = scene->ed;
242 seq_free_sequence(scene, seq);
246 while((ms= ed->metastack.first)) {
247 BLI_remlink(&ed->metastack, ms);
254 /* ************************* itterator ************************** */
255 /* *************** (replaces old WHILE_SEQ) ********************* */
256 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
258 /* sequence strip iterator:
259 * - builds a full array, recursively into meta strips */
261 static void seq_count(ListBase *seqbase, int *tot)
265 for(seq=seqbase->first; seq; seq=seq->next) {
268 if(seq->seqbase.first)
269 seq_count(&seq->seqbase, tot);
273 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
277 for(seq=seqbase->first; seq; seq=seq->next) {
280 if(seq->seqbase.first)
281 seq_build_array(&seq->seqbase, array, depth+1);
288 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
299 seq_count(ed->seqbasep, tot);
301 seq_count(&ed->seqbase, tot);
306 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
308 seq_build_array(ed->seqbasep, &array, 0);
310 seq_build_array(&ed->seqbase, &array, 0);
313 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
315 memset(iter, 0, sizeof(*iter));
316 seq_array(ed, &iter->array, &iter->tot, use_pointer);
320 iter->seq= iter->array[iter->cur];
325 void seq_next(SeqIterator *iter)
327 if(++iter->cur < iter->tot)
328 iter->seq= iter->array[iter->cur];
333 void seq_end(SeqIterator *iter)
336 MEM_freeN(iter->array);
342 **********************************************************************
344 **********************************************************************
345 * Build a complete array of _all_ sequencies (including those
347 **********************************************************************
350 static void do_seq_count(ListBase *seqbase, int *totseq)
357 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
362 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
369 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
376 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
381 do_seq_count(seqbase, totseq);
387 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
390 do_build_seqar(seqbase, seqar, 0);
394 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
395 int (*test_func)(Sequence * seq))
401 int test = test_func(seq);
402 if (test & BUILD_SEQAR_COUNT_CURRENT) {
405 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
406 do_seq_count_cb(&seq->seqbase, totseq, test_func);
412 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
413 int (*test_func)(Sequence * seq))
419 int test = test_func(seq);
422 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
423 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
426 if (test & BUILD_SEQAR_COUNT_CURRENT) {
434 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
435 int (*test_func)(Sequence * seq))
440 do_seq_count_cb(seqbase, totseq, test_func);
446 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
449 do_build_seqar_cb(seqbase, seqar, 0, test_func);
454 void calc_sequence_disp(Sequence *seq)
456 if(seq->startofs && seq->startstill) seq->startstill= 0;
457 if(seq->endofs && seq->endstill) seq->endstill= 0;
459 seq->startdisp= seq->start + seq->startofs - seq->startstill;
460 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
462 seq->handsize= 10.0; /* 10 frames */
463 if( seq->enddisp-seq->startdisp < 10 ) {
464 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
466 else if(seq->enddisp-seq->startdisp > 250) {
467 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
470 seq_update_sound(seq);
473 void calc_sequence(Sequence *seq)
478 /* check all metas recursively */
479 seqm= seq->seqbase.first;
481 if(seqm->seqbase.first) calc_sequence(seqm);
485 /* effects and meta: automatic start and end */
487 if(seq->type & SEQ_EFFECT) {
489 if(seq->seq2==0) seq->seq2= seq->seq1;
490 if(seq->seq3==0) seq->seq3= seq->seq1;
492 /* effecten go from seq1 -> seq2: test */
494 /* we take the largest start and smallest end */
496 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
497 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
500 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
501 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
502 seq->len= seq->enddisp - seq->startdisp;
504 calc_sequence_disp(seq);
507 if(seq->strip && seq->len!=seq->strip->len) {
513 if(seq->type==SEQ_META) {
514 seqm= seq->seqbase.first;
519 if(seqm->startdisp < min) min= seqm->startdisp;
520 if(seqm->enddisp > max) max= seqm->enddisp;
523 seq->start= min + seq->anim_startofs;
525 seq->len -= seq->anim_startofs;
526 seq->len -= seq->anim_endofs;
528 if(seq->strip && seq->len!=seq->strip->len) {
533 calc_sequence_disp(seq);
537 void reload_sequence_new_file(Scene *scene, Sequence * seq)
539 char str[FILE_MAXDIR+FILE_MAXFILE];
541 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
542 seq->type == SEQ_SOUND ||
543 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
549 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
550 seq->type != SEQ_IMAGE) {
551 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
552 BLI_convertstringcode(str, G.sce);
553 BLI_convertstringframe(str, scene->r.cfra);
557 if (seq->type == SEQ_IMAGE) {
559 int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
561 seq->len -= seq->anim_startofs;
562 seq->len -= seq->anim_endofs;
566 seq->strip->len = seq->len;
567 } else if (seq->type == SEQ_MOVIE) {
568 if(seq->anim) IMB_free_anim(seq->anim);
569 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
575 seq->len = IMB_anim_get_duration(seq->anim);
577 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
579 seq->len -= seq->anim_startofs;
580 seq->len -= seq->anim_endofs;
584 seq->strip->len = seq->len;
585 } else if (seq->type == SEQ_SOUND) {
586 seq->len = AUD_getInfo(seq->sound->handle).length * FPS;
587 seq->len -= seq->anim_startofs;
588 seq->len -= seq->anim_endofs;
592 seq->strip->len = seq->len;
593 } else if (seq->type == SEQ_SCENE) {
594 Scene * sce = G.main->scene.first;
598 if(nr == seq->scenenr) {
611 BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
612 seqUniqueName(scene->ed->seqbasep, seq);
614 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
615 seq->len -= seq->anim_startofs;
616 seq->len -= seq->anim_endofs;
620 seq->strip->len = seq->len;
628 void sort_seq(Scene *scene)
630 /* all strips together per kind, and in order of y location ("machine") */
631 ListBase seqbase, effbase;
632 Editing *ed= seq_give_editing(scene, FALSE);
633 Sequence *seq, *seqt;
638 seqbase.first= seqbase.last= 0;
639 effbase.first= effbase.last= 0;
641 while( (seq= ed->seqbasep->first) ) {
642 BLI_remlink(ed->seqbasep, seq);
644 if(seq->type & SEQ_EFFECT) {
647 if(seqt->machine>=seq->machine) {
648 BLI_insertlinkbefore(&effbase, seqt, seq);
653 if(seqt==0) BLI_addtail(&effbase, seq);
658 if(seqt->machine>=seq->machine) {
659 BLI_insertlinkbefore(&seqbase, seqt, seq);
664 if(seqt==0) BLI_addtail(&seqbase, seq);
668 addlisttolist(&seqbase, &effbase);
669 *(ed->seqbasep)= seqbase;
673 void clear_scene_in_allseqs(Scene *sce)
679 /* when a scene is deleted: test all seqs */
681 sce1= G.main->scene.first;
683 if(sce1!=sce && sce1->ed) {
688 if(seq->scene==sce) seq->scene= 0;
698 static char *give_seqname_by_type(int type)
701 case SEQ_META: return "Meta";
702 case SEQ_IMAGE: return "Image";
703 case SEQ_SCENE: return "Scene";
704 case SEQ_MOVIE: return "Movie";
705 case SEQ_SOUND: return "Audio";
706 case SEQ_CROSS: return "Cross";
707 case SEQ_GAMCROSS: return "Gamma Cross";
708 case SEQ_ADD: return "Add";
709 case SEQ_SUB: return "Sub";
710 case SEQ_MUL: return "Mul";
711 case SEQ_ALPHAOVER: return "Alpha Over";
712 case SEQ_ALPHAUNDER: return "Alpha Under";
713 case SEQ_OVERDROP: return "Over Drop";
714 case SEQ_WIPE: return "Wipe";
715 case SEQ_GLOW: return "Glow";
716 case SEQ_TRANSFORM: return "Transform";
717 case SEQ_COLOR: return "Color";
718 case SEQ_SPEED: return "Speed";
724 char *give_seqname(Sequence *seq)
726 char * name = give_seqname_by_type(seq->type);
729 if(seq->type<SEQ_EFFECT) {
730 return seq->strip->dir;
731 } else if(seq->type==SEQ_PLUGIN) {
732 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
733 seq->plugin && seq->plugin->doit) {
734 return seq->plugin->pname;
745 /* ***************** DO THE SEQUENCE ***************** */
747 static void make_black_ibuf(ImBuf *ibuf)
753 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
755 tot= ibuf->x*ibuf->y;
758 rect_float = ibuf->rect_float;
761 memset(rect, 0, tot * sizeof(char) * 4);
765 memset(rect_float, 0, tot * sizeof(float) * 4);
769 static void multibuf(ImBuf *ibuf, float fmul)
776 mul= (int)(256.0*fmul);
777 rt= (char *)ibuf->rect;
778 rt_float = ibuf->rect_float;
784 icol= (mul*rt[0])>>8;
785 if(icol>254) rt[0]= 255; else rt[0]= icol;
786 icol= (mul*rt[1])>>8;
787 if(icol>254) rt[1]= 255; else rt[1]= icol;
788 icol= (mul*rt[2])>>8;
789 if(icol>254) rt[2]= 255; else rt[2]= icol;
790 icol= (mul*rt[3])>>8;
791 if(icol>254) rt[3]= 255; else rt[3]= icol;
809 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
811 TStripElem *se1, *se2, *se3;
815 struct SeqEffectHandle sh = get_sequence_effect(seq);
818 if (!sh.execute) { /* effect not supported in this version... */
819 make_black_ibuf(se->ibuf);
823 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
824 sh.get_default_fac(seq, cfra, &fac, &facf);
825 if( scene->r.mode & R_FIELDS ); else facf= fac;
827 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
830 fac = facf = evaluate_fcurve(fcu, cfra);
831 if( scene->r.mode & R_FIELDS ) {
832 facf = evaluate_fcurve(fcu, cfra + 0.5);
835 fac = facf = seq->effect_fader;
839 early_out = sh.early_out(seq, fac, facf);
841 if (early_out == -1) { /* no input needed */
842 sh.execute(scene, seq, cfra, fac, facf,
843 se->ibuf->x, se->ibuf->y,
850 if (se->se1==0 || se->se2==0 || se->se3==0) {
851 make_black_ibuf(se->ibuf);
859 if ( (se1==0 || se2==0 || se3==0)
860 || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
861 make_black_ibuf(se->ibuf);
868 make_black_ibuf(se->ibuf);
874 if (se1 == 0 || se1->ibuf == 0) {
875 make_black_ibuf(se->ibuf);
879 if (se->ibuf != se1->ibuf) {
880 IMB_freeImBuf(se->ibuf);
881 se->ibuf = se1->ibuf;
882 IMB_refImBuf(se->ibuf);
887 make_black_ibuf(se->ibuf);
893 if (se2 == 0 || se2->ibuf == 0) {
894 make_black_ibuf(se->ibuf);
897 if (se->ibuf != se2->ibuf) {
898 IMB_freeImBuf(se->ibuf);
899 se->ibuf = se2->ibuf;
900 IMB_refImBuf(se->ibuf);
904 make_black_ibuf(se->ibuf);
911 if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
912 IMB_float_from_rect(se1->ibuf);
914 if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
915 IMB_float_from_rect(se2->ibuf);
917 if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
918 IMB_float_from_rect(se3->ibuf);
921 if (!se1->ibuf->rect && !se->ibuf->rect_float) {
922 IMB_rect_from_float(se1->ibuf);
924 if (!se2->ibuf->rect && !se->ibuf->rect_float) {
925 IMB_rect_from_float(se2->ibuf);
927 if (!se3->ibuf->rect && !se->ibuf->rect_float) {
928 IMB_rect_from_float(se3->ibuf);
931 sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
935 static int give_stripelem_index(Sequence *seq, int cfra)
939 if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
940 if(seq->len == 0) return -1;
941 if(seq->flag&SEQ_REVERSE_FRAMES) {
942 /*reverse frame in this sequence */
943 if(cfra <= seq->start) nr= seq->len-1;
944 else if(cfra >= seq->start+seq->len-1) nr= 0;
945 else nr= (seq->start + seq->len) - cfra;
947 if(cfra <= seq->start) nr= 0;
948 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
949 else nr= cfra-seq->start;
951 if (seq->strobe < 1.0) seq->strobe = 1.0;
952 if (seq->strobe > 1.0) {
953 nr -= (int)fmod((double)nr, (double)seq->strobe);
959 static TStripElem* alloc_tstripdata(int len, const char * name)
962 TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
963 for (i = 0; i < len; i++) {
964 se[i].ok = STRIPELEM_OK;
969 static TStripElem *give_tstripelem(Sequence *seq, int cfra)
974 se = seq->strip->tstripdata;
975 if (se == 0 && seq->len > 0) {
976 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
979 nr = give_stripelem_index(seq, cfra);
981 if (nr == -1) return 0;
982 if (se == 0) return 0;
986 /* if there are IPOs with blend modes active, one has to watch out
987 for startstill + endstill area: we can't use the same tstripelem
988 here for all ibufs, since then, blending with IPOs won't work!
990 Rather common case, if you use a single image and try to fade
991 it in and out... or want to use your strip as a watermark in
994 if (seq->blend_mode != SEQ_BLEND_REPLACE ||
995 (/*seq->ipo && seq->ipo->curve.first &&*/
996 (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
997 Strip * s = seq->strip;
998 if (cfra < seq->start) {
999 se = s->tstripdata_startstill;
1000 if (seq->startstill > s->startstill) {
1001 free_tstripdata(s->startstill,
1002 s->tstripdata_startstill);
1007 s->startstill = seq->startstill;
1008 se = seq->strip->tstripdata_startstill
1011 "tstripelems_startstill");
1013 se += seq->start - cfra - 1;
1015 } else if (cfra > seq->start + seq->len-1) {
1016 se = s->tstripdata_endstill;
1017 if (seq->endstill > s->endstill) {
1018 free_tstripdata(s->endstill,
1019 s->tstripdata_endstill);
1024 s->endstill = seq->endstill;
1025 se = seq->strip->tstripdata_endstill
1028 "tstripelems_endstill");
1030 se += cfra - (seq->start + seq->len-1) - 1;
1040 StripElem *give_stripelem(Sequence *seq, int cfra)
1045 se = seq->strip->stripdata;
1046 nr = give_stripelem_index(seq, cfra);
1048 if (nr == -1) return 0;
1049 if (se == 0) return 0;
1051 se += nr + seq->anim_startofs;
1056 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1061 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1063 seq= seqbase->first;
1065 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1066 seq_arr[seq->machine]= seq;
1075 int evaluate_seq_frame(Scene *scene, int cfra)
1077 Editing *ed= seq_give_editing(scene, FALSE);
1078 Sequence *seq_arr[MAXSEQ+1];
1080 if(ed==NULL) return 0;
1081 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1084 static int video_seq_is_rendered(Sequence * seq)
1087 && !(seq->flag & SEQ_MUTE)
1088 && seq->type != SEQ_SOUND);
1091 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1093 Sequence *seq_arr[MAXSEQ+1];
1101 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1103 if (seq_arr[b] == 0) {
1107 for (b = MAXSEQ; b > 0; b--) {
1108 if (video_seq_is_rendered(seq_arr[b])) {
1118 if (video_seq_is_rendered(seq_arr[b])) {
1119 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1125 for (;b <= chanshown; b++) {
1126 if (video_seq_is_rendered(seq_arr[b])) {
1127 seq_arr_out[cnt++] = seq_arr[b];
1135 /* **********************************************************************
1137 ********************************************************************** */
1139 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1141 static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size)
1144 char dir[FILE_MAXDIR];
1146 if (!seq->strip->proxy) {
1150 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1151 strcpy(dir, seq->strip->proxy->dir);
1153 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1154 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
1161 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1162 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1163 BLI_convertstringcode(name, G.sce);
1164 BLI_convertstringframe(name, cfra);
1169 /* generate a separate proxy directory for each preview size */
1171 if (seq->type == SEQ_IMAGE) {
1172 StripElem * se = give_stripelem(seq, cfra);
1173 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1174 dir, render_size, se->name);
1176 } else if (seq->type == SEQ_MOVIE) {
1177 TStripElem * tse = give_tstripelem(seq, cfra);
1179 frameno = tse->nr + seq->anim_startofs;
1181 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1182 seq->strip->stripdata->name,
1185 TStripElem * tse = give_tstripelem(seq, cfra);
1187 frameno = tse->nr + seq->anim_startofs;
1189 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1193 BLI_convertstringcode(name, G.sce);
1194 BLI_convertstringframe(name, frameno);
1197 strcat(name, ".jpg");
1202 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1204 char name[PROXY_MAXFILE];
1206 if (!(seq->flag & SEQ_USE_PROXY)) {
1210 /* rendering at 100% ? No real sense in proxy-ing, right? */
1211 if (render_size == 100) {
1215 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1216 TStripElem * tse = give_tstripelem(seq, cfra);
1217 int frameno = tse->nr + seq->anim_startofs;
1218 if (!seq->strip->proxy->anim) {
1219 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1223 seq->strip->proxy->anim = openanim(name, IB_rect);
1225 if (!seq->strip->proxy->anim) {
1229 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1232 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1236 if (BLI_exists(name)) {
1237 return IMB_loadiffname(name, IB_rect);
1244 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1245 int build_proxy_run, int render_size);
1247 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1249 char name[PROXY_MAXFILE];
1254 struct ImBuf * ibuf;
1256 if (!(seq->flag & SEQ_USE_PROXY)) {
1260 /* rendering at 100% ? No real sense in proxy-ing, right? */
1261 if (render_size == 100) {
1265 /* that's why it is called custom... */
1266 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1270 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1274 se = give_tstripelem(seq, cfra);
1280 IMB_freeImBuf(se->ibuf);
1284 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1290 rectx= (render_size*scene->r.xsch)/100;
1291 recty= (render_size*scene->r.ysch)/100;
1295 if (ibuf->x != rectx || ibuf->y != recty) {
1296 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1299 /* quality is fixed, otherwise one has to generate separate
1300 directories for every quality...
1302 depth = 32 is intentionally left in, otherwise ALPHA channels
1304 quality = seq->strip->proxy->quality;
1305 ibuf->ftype= JPG | quality;
1307 BLI_make_existing_file(name);
1309 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1314 IMB_freeImBuf(ibuf);
1318 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1321 float rsize = seq->strip->proxy->size;
1327 /* flag management tries to account for strobe and
1328 other "non-linearities", that might come in the future...
1329 better way would be to "touch" the files, so that _really_
1330 no one is rebuild twice.
1333 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1334 TStripElem * tse = give_tstripelem(seq, cfra);
1336 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1341 /* a _lot_ faster for movie files, if we read frames in
1343 if (seq->flag & SEQ_REVERSE_FRAMES) {
1344 for (cfra = seq->enddisp-seq->endstill-1;
1345 cfra >= seq->startdisp + seq->startstill; cfra--) {
1346 TStripElem * tse = give_tstripelem(seq, cfra);
1348 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1349 //XXX set_timecursor(cfra);
1350 seq_proxy_build_frame(scene, seq, cfra, rsize);
1351 tse->flag |= STRIPELEM_PREVIEW_DONE;
1353 if (blender_test_break()) {
1358 for (cfra = seq->startdisp + seq->startstill;
1359 cfra < seq->enddisp - seq->endstill; cfra++) {
1360 TStripElem * tse = give_tstripelem(seq, cfra);
1362 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1363 //XXX set_timecursor(cfra);
1364 seq_proxy_build_frame(scene, seq, cfra, rsize);
1365 tse->flag |= STRIPELEM_PREVIEW_DONE;
1367 if (blender_test_break()) {
1377 /* **********************************************************************
1379 ********************************************************************** */
1381 static StripColorBalance calc_cb(StripColorBalance * cb_)
1383 StripColorBalance cb = *cb_;
1386 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1387 for (c = 0; c < 3; c++) {
1388 cb.lift[c] = 1.0 - cb.lift[c];
1391 for (c = 0; c < 3; c++) {
1392 cb.lift[c] = -(1.0 - cb.lift[c]);
1395 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1396 for (c = 0; c < 3; c++) {
1397 if (cb.gain[c] != 0.0) {
1398 cb.gain[c] = 1.0/cb.gain[c];
1400 cb.gain[c] = 1000000; /* should be enough :) */
1405 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1406 for (c = 0; c < 3; c++) {
1407 if (cb.gamma[c] != 0.0) {
1408 cb.gamma[c] = 1.0/cb.gamma[c];
1410 cb.gamma[c] = 1000000; /* should be enough :) */
1418 static void make_cb_table_byte(float lift, float gain, float gamma,
1419 unsigned char * table, float mul)
1423 for (y = 0; y < 256; y++) {
1424 float v = 1.0 * y / 255;
1431 } else if (v < 0.0) {
1439 static void make_cb_table_float(float lift, float gain, float gamma,
1440 float * table, float mul)
1444 for (y = 0; y < 256; y++) {
1445 float v = (float) y * 1.0 / 255.0;
1454 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1456 unsigned char cb_tab[3][256];
1458 unsigned char * p = (unsigned char*) se->ibuf->rect;
1459 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1461 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1463 for (c = 0; c < 3; c++) {
1464 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1469 p[0] = cb_tab[0][p[0]];
1470 p[1] = cb_tab[1][p[1]];
1471 p[2] = cb_tab[2][p[2]];
1477 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1479 float cb_tab[4][256];
1481 unsigned char * p = (unsigned char*) se->ibuf->rect;
1482 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1484 StripColorBalance cb;
1486 imb_addrectfloatImBuf(se->ibuf);
1488 o = se->ibuf->rect_float;
1490 cb = calc_cb(seq->strip->color_balance);
1492 for (c = 0; c < 3; c++) {
1493 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1497 for (i = 0; i < 256; i++) {
1498 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1502 o[0] = cb_tab[0][p[0]];
1503 o[1] = cb_tab[1][p[1]];
1504 o[2] = cb_tab[2][p[2]];
1505 o[3] = cb_tab[3][p[3]];
1511 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1513 float * p = se->ibuf->rect_float;
1514 float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1515 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1519 for (c = 0; c < 3; c++) {
1520 p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
1527 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1529 if (se->ibuf->rect_float) {
1530 color_balance_float_float(seq, se, mul);
1531 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1532 color_balance_byte_float(seq, se, mul);
1534 color_balance_byte_byte(seq, se, mul);
1539 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1541 Do all the things you can't really do afterwards using sequence effects
1542 (read: before rescaling to render resolution has been done)
1547 - Crop and transform in image source coordinate space
1548 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1549 - Promote image to float data (affects pipeline operations afterwards)
1550 - Color balance (is most efficient in the byte -> float
1551 (future: half -> float should also work fine!)
1552 case, if done on load, since we can use lookup tables)
1557 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1561 if ((seq->flag & SEQ_FILTERY) ||
1562 (seq->flag & SEQ_USE_CROP) ||
1563 (seq->flag & SEQ_USE_TRANSFORM) ||
1564 (seq->flag & SEQ_FLIPX) ||
1565 (seq->flag & SEQ_FLIPY) ||
1566 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1567 (seq->flag & SEQ_MAKE_PREMUL) ||
1568 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1574 if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1575 !(seq->type & SEQ_EFFECT)) {
1576 mul *= seq->blend_opacity / 100.0;
1586 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1590 seq->strip->orx= se->ibuf->x;
1591 seq->strip->ory= se->ibuf->y;
1593 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1594 IMB_filtery(se->ibuf);
1597 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1602 memset(&c, 0, sizeof(StripCrop));
1603 memset(&t, 0, sizeof(StripTransform));
1605 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1606 c = *seq->strip->crop;
1608 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1609 t = *seq->strip->transform;
1612 sx = se->ibuf->x - c.left - c.right;
1613 sy = se->ibuf->y - c.top - c.bottom;
1617 if (seq->flag & SEQ_USE_TRANSFORM) {
1622 if (c.top + c.bottom >= se->ibuf->y ||
1623 c.left + c.right >= se->ibuf->x ||
1624 t.xofs >= dx || t.yofs >= dy) {
1625 make_black_ibuf(se->ibuf);
1629 if (se->ibuf->rect_float) {
1630 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1632 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1635 IMB_rectcpy(i, se->ibuf,
1640 IMB_freeImBuf(se->ibuf);
1646 if(seq->flag & SEQ_FLIPX) {
1647 IMB_flipx(se->ibuf);
1649 if(seq->flag & SEQ_FLIPY) {
1650 IMB_flipy(se->ibuf);
1653 if(seq->mul == 0.0) {
1659 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1660 mul *= seq->blend_opacity / 100.0;
1663 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1664 color_balance(seq, se, mul);
1668 if(seq->flag & SEQ_MAKE_FLOAT) {
1669 if (!se->ibuf->rect_float) {
1670 IMB_float_from_rect(se->ibuf);
1672 if (se->ibuf->rect) {
1673 imb_freerectImBuf(se->ibuf);
1678 multibuf(se->ibuf, mul);
1681 if(seq->flag & SEQ_MAKE_PREMUL) {
1682 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1683 converttopremul(se->ibuf);
1688 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1689 if(scene->r.mode & R_OSA) {
1690 IMB_scaleImBuf(se->ibuf,
1691 (short)seqrectx, (short)seqrecty);
1693 IMB_scalefastImBuf(se->ibuf,
1694 (short)seqrectx, (short)seqrecty);
1699 /* test if image too small or discarded from cache: reload */
1701 static void test_and_auto_discard_ibuf(TStripElem * se)
1704 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
1705 || !(se->ibuf->rect || se->ibuf->rect_float)) {
1706 IMB_freeImBuf(se->ibuf);
1709 se->ok= STRIPELEM_OK;
1712 if (se->ibuf_comp) {
1713 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
1714 || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1715 IMB_freeImBuf(se->ibuf_comp);
1722 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1724 if (strip->ibuf_startstill) {
1725 if (!strip->ibuf_startstill->rect &&
1726 !strip->ibuf_startstill->rect_float) {
1727 IMB_freeImBuf(strip->ibuf_startstill);
1728 strip->ibuf_startstill = 0;
1731 if (strip->ibuf_endstill) {
1732 if (!strip->ibuf_endstill->rect &&
1733 !strip->ibuf_endstill->rect_float) {
1734 IMB_freeImBuf(strip->ibuf_endstill);
1735 strip->ibuf_endstill = 0;
1740 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1743 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1744 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1746 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1748 if (se->nr == seq->len - 1
1750 && seq->strip->ibuf_endstill) {
1751 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1753 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1758 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1762 seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1764 IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1765 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1767 if (se->nr == seq->len - 1 && seq->len != 1) {
1768 seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1770 IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1771 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1776 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1778 Sequence* seq_arr[MAXSEQ+1];
1782 evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1784 for (i = 0; i < MAXSEQ; i++) {
1785 if (!video_seq_is_rendered(seq_arr[i])) {
1788 se = give_tstripelem(seq_arr[i], cfra);
1791 IMB_freeImBuf(se->ibuf);
1794 se->ok= STRIPELEM_OK;
1797 if (se->ibuf_comp) {
1798 IMB_freeImBuf(se->ibuf_comp);
1807 static void check_limiter_refcount(const char * func, TStripElem *se)
1809 if (se && se->ibuf) {
1810 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1811 if (refcount != 1) {
1812 /* can happen on complex pipelines */
1813 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1818 "sequencer: (ibuf) %s: "
1819 "suspicious memcache "
1820 "limiter refcount: %d\n", func, refcount);
1825 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1827 if (se && se->ibuf_comp) {
1828 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1829 if (refcount != 1) {
1830 /* can happen on complex pipelines */
1831 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1835 "sequencer: (ibuf comp) %s: "
1836 "suspicious memcache "
1837 "limiter refcount: %d\n", func, refcount);
1842 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1843 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1845 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1846 int build_proxy_run, int render_size)
1848 char name[FILE_MAXDIR+FILE_MAXFILE];
1849 int use_limiter = TRUE;
1851 test_and_auto_discard_ibuf(se);
1852 test_and_auto_discard_ibuf_stills(seq->strip);
1854 if(seq->type == SEQ_META) {
1855 TStripElem * meta_se = 0;
1856 int use_preprocess = FALSE;
1857 use_limiter = FALSE;
1859 if (!build_proxy_run && se->ibuf == 0) {
1860 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1863 use_preprocess = TRUE;
1867 if(!se->ibuf && seq->seqbase.first) {
1868 meta_se = do_build_seq_array_recursively(scene,
1869 &seq->seqbase, seq->start + se->nr, 0,
1872 check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1875 se->ok = STRIPELEM_OK;
1877 if(!se->ibuf && meta_se) {
1878 se->ibuf = meta_se->ibuf_comp;
1880 (!input_have_to_preprocess(scene, seq, se, cfra) ||
1882 IMB_refImBuf(se->ibuf);
1883 if (build_proxy_run) {
1884 IMB_cache_limiter_unref(se->ibuf);
1886 } else if (se->ibuf) {
1887 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1889 IMB_cache_limiter_unref(se->ibuf);
1894 use_preprocess = TRUE;
1896 } else if (se->ibuf) {
1900 free_metastrip_imbufs(
1901 &seq->seqbase, seq->start + se->nr, 0);
1904 if (use_preprocess) {
1905 input_preprocess(scene, seq, se, cfra);
1907 } else if(seq->type & SEQ_EFFECT) {
1908 int use_preprocess = FALSE;
1909 /* should the effect be recalculated? */
1911 if (!build_proxy_run && se->ibuf == 0) {
1912 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1914 use_preprocess = TRUE;
1919 /* if any inputs are rectfloat, output is float too */
1920 if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1921 (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
1922 (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
1923 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1925 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1927 do_effect(scene, cfra, seq, se);
1928 if (input_have_to_preprocess(scene, seq, se, cfra) &&
1930 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
1931 (se->se2 && (se->ibuf == se->se2->ibuf))) {
1933 = IMB_dupImBuf(se->ibuf);
1935 IMB_freeImBuf(se->ibuf);
1939 use_preprocess = TRUE;
1942 if (use_preprocess) {
1943 input_preprocess(scene, seq, se, cfra);
1945 } else if(seq->type == SEQ_IMAGE) {
1946 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1947 StripElem * s_elem = give_stripelem(seq, cfra);
1948 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1949 BLI_convertstringcode(name, G.sce);
1950 BLI_convertstringframe(name, scene->r.cfra);
1951 if (!build_proxy_run) {
1952 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1954 copy_from_ibuf_still(seq, se);
1957 se->ibuf= IMB_loadiffname(
1959 /* we don't need both (speed reasons)! */
1961 se->ibuf->rect_float && se->ibuf->rect) {
1962 imb_freerectImBuf(se->ibuf);
1965 copy_to_ibuf_still(seq, se);
1969 se->ok = STRIPELEM_FAILED;
1970 } else if (!build_proxy_run) {
1971 input_preprocess(scene, seq, se, cfra);
1974 } else if(seq->type == SEQ_MOVIE) {
1975 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1976 if(!build_proxy_run) {
1977 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1979 copy_from_ibuf_still(seq, se);
1981 if (se->ibuf == 0) {
1983 BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
1984 BLI_convertstringcode(name, G.sce);
1985 BLI_convertstringframe(name, scene->r.cfra);
1987 seq->anim = openanim(
1989 ((seq->flag & SEQ_FILTERY)
1990 ? IB_animdeinterlace : 0));
1993 IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1994 se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1995 /* we don't need both (speed reasons)! */
1997 && se->ibuf->rect_float
1998 && se->ibuf->rect) {
1999 imb_freerectImBuf(se->ibuf);
2003 copy_to_ibuf_still(seq, se);
2007 se->ok = STRIPELEM_FAILED;
2008 } else if (!build_proxy_run) {
2009 input_preprocess(scene, seq, se, cfra);
2012 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
2013 Scene *sce= seq->scene;// *oldsce= scene;
2017 int have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2018 int sce_valid =sce && (sce->camera || have_seq);
2020 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2021 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2023 input_preprocess(scene, seq, se, cfra);
2027 if (se->ibuf == NULL && sce_valid) {
2028 copy_from_ibuf_still(seq, se);
2030 input_preprocess(scene, seq, se, cfra);
2035 se->ok = STRIPELEM_FAILED;
2036 } else if (se->ibuf==NULL && sce_valid) {
2038 /* Hack! This function can be called from do_render_seq(), in that case
2039 the seq->scene can already have a Render initialized with same name,
2040 so we have to use a default name. (compositor uses scene name to
2042 However, when called from within the UI (image preview in sequencer)
2043 we do want to use scene Render, that way the render result is defined
2044 for display in render/imagewindow
2046 Hmm, don't see, why we can't do that all the time,
2047 and since G.rendering is uhm, gone... (Peter)
2053 oldcfra = seq->scene->r.cfra;
2056 BLI_strncpy(scenename, sce->id.name+2, 64);
2057 strcpy(sce->id.name+2, " do_build_seq_ibuf");
2059 re= RE_NewRender(sce->id.name);
2061 /* prevent eternal loop */
2062 doseq= scene->r.scemode & R_DOSEQ;
2063 scene->r.scemode &= ~R_DOSEQ;
2065 RE_BlenderFrame(re, sce,
2066 seq->sfra+se->nr+seq->anim_startofs);
2069 BLI_strncpy(sce->id.name+2, scenename, 64);
2071 RE_AcquireResultImage(re, &rres);
2074 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2075 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2077 addzbuffloatImBuf(se->ibuf);
2078 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2080 } else if (rres.rect32) {
2081 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2082 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2085 RE_ReleaseResultImage(re);
2087 // BIF_end_render_callbacks();
2090 scene->r.scemode |= doseq;
2092 seq->scene->r.cfra = oldcfra;
2094 copy_to_ibuf_still(seq, se);
2096 if (!build_proxy_run) {
2097 if(se->ibuf == NULL) {
2098 se->ok = STRIPELEM_FAILED;
2100 input_preprocess(scene, seq, se, cfra);
2106 if (!build_proxy_run) {
2107 if (se->ibuf && use_limiter) {
2108 IMB_cache_limiter_insert(se->ibuf);
2109 IMB_cache_limiter_ref(se->ibuf);
2110 IMB_cache_limiter_touch(se->ibuf);
2115 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2117 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2120 struct SeqEffectHandle sh = get_sequence_effect(seq);
2128 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2129 sh.get_default_fac(seq, cfra, &fac, &facf);
2130 if( scene->r.mode & R_FIELDS ); else facf= fac;
2132 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
2135 fac = facf = evaluate_fcurve(fcu, cfra);
2136 if( scene->r.mode & R_FIELDS ) {
2137 facf = evaluate_fcurve(fcu, cfra + 0.5);
2140 fac = facf = seq->effect_fader;
2144 early_out = sh.early_out(seq, fac, facf);
2145 switch (early_out) {
2147 /* no input needed */
2150 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2151 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2153 se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2157 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2160 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2165 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2167 /* children are not needed anymore ... */
2169 if (se->se1 && se->se1->ibuf) {
2170 IMB_cache_limiter_unref(se->se1->ibuf);
2172 if (se->se2 && se->se2->ibuf) {
2173 IMB_cache_limiter_unref(se->se2->ibuf);
2175 if (se->se3 && se->se3->ibuf) {
2176 IMB_cache_limiter_unref(se->se3->ibuf);
2178 check_limiter_refcount("do_effect_seq_recursively", se);
2181 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2185 se = give_tstripelem(seq, cfra);
2188 if (seq->type & SEQ_EFFECT) {
2189 do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2191 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2199 If cfra was float throughout blender (especially in the render
2200 pipeline) one could even _render_ with subframe precision
2201 instead of faking using the blend code below...
2205 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2207 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2208 int nr = cfra - seq->start;
2212 TStripElem * se = 0;
2213 TStripElem * se1 = 0;
2214 TStripElem * se2 = 0;
2216 sequence_effect_speed_rebuild_map(scene, seq, 0);
2218 f_cfra = seq->start + s->frameMap[nr];
2220 cfra_left = (int) floor(f_cfra);
2221 cfra_right = (int) ceil(f_cfra);
2223 se = give_tstripelem(seq, cfra);
2229 if (cfra_left == cfra_right ||
2230 (s->flags & SEQ_SPEED_BLEND) == 0) {
2231 test_and_auto_discard_ibuf(se);
2233 if (se->ibuf == NULL) {
2234 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2236 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2237 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2239 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2241 if (se1 == 0 || se1->ibuf == 0) {
2242 make_black_ibuf(se->ibuf);
2244 if (se->ibuf != se1->ibuf) {
2246 IMB_freeImBuf(se->ibuf);
2249 se->ibuf = se1->ibuf;
2250 IMB_refImBuf(se->ibuf);
2255 struct SeqEffectHandle sh;
2258 if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
2259 || !(se->ibuf->rect || se->ibuf->rect_float)) {
2260 IMB_freeImBuf(se->ibuf);
2265 if (se->ibuf == NULL) {
2266 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2267 se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2269 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2270 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2272 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2275 make_black_ibuf(se->ibuf);
2277 sh = get_sequence_effect(seq);
2279 sh.execute(scene, seq, cfra,
2280 f_cfra - (float) cfra_left,
2281 f_cfra - (float) cfra_left,
2282 se->ibuf->x, se->ibuf->y,
2283 se1->ibuf, se2->ibuf, 0, se->ibuf);
2289 /* caller expects this to be referenced, so do it! */
2291 IMB_cache_limiter_insert(se->ibuf);
2292 IMB_cache_limiter_ref(se->ibuf);
2293 IMB_cache_limiter_touch(se->ibuf);
2296 /* children are no longer needed */
2297 if (se1 && se1->ibuf)
2298 IMB_cache_limiter_unref(se1->ibuf);
2299 if (se2 && se2->ibuf)
2300 IMB_cache_limiter_unref(se2->ibuf);
2302 check_limiter_refcount("do_handle_speed_effect", se);
2308 * build all ibufs recursively
2310 * if successfull, the returned TStripElem contains the (referenced!) imbuf
2311 * that means: you _must_ call
2313 * IMB_cache_limiter_unref(rval);
2319 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2322 if (seq->type == SEQ_SPEED) {
2323 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2325 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2328 check_limiter_refcount("do_build_seq_recursively", se);
2333 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2334 ListBase *seqbasep, int cfra, int chanshown, int render_size)
2336 Sequence* seq_arr[MAXSEQ+1];
2341 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2347 se = give_tstripelem(seq_arr[count - 1], cfra);
2353 test_and_auto_discard_ibuf(se);
2355 if (se->ibuf_comp != 0) {
2356 IMB_cache_limiter_insert(se->ibuf_comp);
2357 IMB_cache_limiter_ref(se->ibuf_comp);
2358 IMB_cache_limiter_touch(se->ibuf_comp);
2364 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2366 se->ibuf_comp = se->ibuf;
2367 IMB_refImBuf(se->ibuf_comp);
2373 for (i = count - 1; i >= 0; i--) {
2375 Sequence * seq = seq_arr[i];
2376 struct SeqEffectHandle sh;
2379 se = give_tstripelem(seq, cfra);
2381 test_and_auto_discard_ibuf(se);
2383 if (se->ibuf_comp != 0) {
2386 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2387 do_build_seq_recursively(scene, seq, cfra, render_size);
2389 se->ibuf_comp = se->ibuf;
2390 IMB_refImBuf(se->ibuf);
2392 se->ibuf_comp = IMB_allocImBuf(
2393 (short)seqrectx, (short)seqrecty,
2395 IMB_cache_limiter_insert(se->ibuf_comp);
2396 IMB_cache_limiter_ref(se->ibuf_comp);
2397 IMB_cache_limiter_touch(se->ibuf_comp);
2402 sh = get_sequence_blend(seq);
2404 facf = seq->blend_opacity / 100.0;
2406 early_out = sh.early_out(seq, facf, facf);
2408 switch (early_out) {
2411 do_build_seq_recursively(scene, seq, cfra, render_size);
2413 se->ibuf_comp = se->ibuf;
2414 IMB_refImBuf(se->ibuf_comp);
2416 se->ibuf_comp = IMB_allocImBuf(
2417 (short)seqrectx, (short)seqrecty,
2419 IMB_cache_limiter_insert(se->ibuf_comp);
2420 IMB_cache_limiter_ref(se->ibuf_comp);
2421 IMB_cache_limiter_touch(se->ibuf_comp);
2426 se->ibuf_comp = IMB_allocImBuf(
2427 (short)seqrectx, (short)seqrecty,
2429 IMB_cache_limiter_insert(se->ibuf_comp);
2430 IMB_cache_limiter_ref(se->ibuf_comp);
2431 IMB_cache_limiter_touch(se->ibuf_comp);
2435 do_build_seq_recursively(scene, seq, cfra, render_size);
2437 se->ibuf = IMB_allocImBuf(
2438 (short)seqrectx, (short)seqrecty,
2440 IMB_cache_limiter_insert(se->ibuf);
2441 IMB_cache_limiter_ref(se->ibuf);
2442 IMB_cache_limiter_touch(se->ibuf);
2445 se->ibuf_comp = se->ibuf;
2446 IMB_refImBuf(se->ibuf_comp);
2451 if (se->ibuf_comp) {
2458 for (; i < count; i++) {
2459 Sequence * seq = seq_arr[i];
2460 struct SeqEffectHandle sh = get_sequence_blend(seq);
2461 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2462 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2464 float facf = seq->blend_opacity / 100.0;
2466 int early_out = sh.early_out(seq, facf, facf);
2467 switch (early_out) {
2469 int x= se2->ibuf->x;
2470 int y= se2->ibuf->y;
2471 int swap_input = FALSE;
2473 if (se1->ibuf_comp->rect_float ||
2474 se2->ibuf->rect_float) {
2475 se2->ibuf_comp = IMB_allocImBuf(
2476 (short)seqrectx, (short)seqrecty,
2477 32, IB_rectfloat, 0);
2479 se2->ibuf_comp = IMB_allocImBuf(
2480 (short)seqrectx, (short)seqrecty,
2485 if (!se1->ibuf_comp->rect_float &&
2486 se2->ibuf_comp->rect_float) {
2487 IMB_float_from_rect(se1->ibuf_comp);
2489 if (!se2->ibuf->rect_float &&
2490 se2->ibuf_comp->rect_float) {
2491 IMB_float_from_rect(se2->ibuf);
2494 if (!se1->ibuf_comp->rect &&
2495 !se2->ibuf_comp->rect_float) {
2496 IMB_rect_from_float(se1->ibuf_comp);
2498 if (!se2->ibuf->rect &&
2499 !se2->ibuf_comp->rect_float) {
2500 IMB_rect_from_float(se2->ibuf);
2503 /* bad hack, to fix crazy input ordering of
2504 those two effects */
2506 if (seq->blend_mode == SEQ_ALPHAOVER ||
2507 seq->blend_mode == SEQ_ALPHAUNDER ||
2508 seq->blend_mode == SEQ_OVERDROP) {
2513 sh.execute(scene, seq, cfra,
2515 se2->ibuf, se1->ibuf_comp, 0,
2518 sh.execute(scene, seq, cfra,
2520 se1->ibuf_comp, se2->ibuf, 0,
2524 IMB_cache_limiter_insert(se2->ibuf_comp);
2525 IMB_cache_limiter_ref(se2->ibuf_comp);
2526 IMB_cache_limiter_touch(se2->ibuf_comp);
2528 IMB_cache_limiter_unref(se1->ibuf_comp);
2529 IMB_cache_limiter_unref(se2->ibuf);
2534 se2->ibuf_comp = se1->ibuf;
2535 IMB_refImBuf(se2->ibuf_comp);
2547 * returned ImBuf is refed!
2548 * you have to unref after usage!
2551 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2553 Editing *ed= seq_give_editing(scene, FALSE);
2559 if(ed==NULL) return NULL;
2561 count = BLI_countlist(&ed->metastack);
2562 if((chanshown < 0) && (count > 0)) {
2563 count = MAX2(count + chanshown, 0);
2564 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2566 seqbasep= ed->seqbasep;
2569 seqrectx= rectx; /* bad bad global! */
2572 se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2578 check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2580 return se->ibuf_comp;
2583 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2587 seqrectx= rectx; /* bad bad global! */
2590 se = do_build_seq_recursively(scene, seq, cfra, render_size);
2596 check_limiter_refcount("give_ibuf_seq_direct", se);
2599 IMB_cache_limiter_unref(se->ibuf);
2605 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2607 ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2610 IMB_cache_limiter_unref(i);
2616 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2617 static int seq_can_blend(Sequence *seq)
2619 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2627 /* *********************** threading api ******************* */
2629 static ListBase running_threads;
2630 static ListBase prefetch_wait;
2631 static ListBase prefetch_done;
2633 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2634 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2635 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2637 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2638 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2640 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2641 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2643 static volatile int seq_thread_shutdown = FALSE;
2644 static volatile int seq_last_given_monoton_cfra = 0;
2645 static int monoton_cfra = 0;
2647 typedef struct PrefetchThread {
2648 struct PrefetchThread *next, *prev;
2651 struct PrefetchQueueElem *current;
2657 typedef struct PrefetchQueueElem {
2658 struct PrefetchQueueElem *next, *prev;
2668 struct ImBuf * ibuf;
2669 } PrefetchQueueElem;
2672 static void *seq_prefetch_thread(void * This_)
2674 PrefetchThread * This = This_;
2676 while (!seq_thread_shutdown) {
2677 PrefetchQueueElem *e;
2680 pthread_mutex_lock(&queue_lock);
2681 e = prefetch_wait.first;
2683 BLI_remlink(&prefetch_wait, e);
2685 s_last = seq_last_given_monoton_cfra;
2689 pthread_mutex_unlock(&queue_lock);
2692 pthread_mutex_lock(&prefetch_ready_lock);
2694 This->running = FALSE;
2696 pthread_cond_signal(&prefetch_ready_cond);
2697 pthread_mutex_unlock(&prefetch_ready_lock);
2699 pthread_mutex_lock(&wakeup_lock);
2700 if (!seq_thread_shutdown) {
2701 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2703 pthread_mutex_unlock(&wakeup_lock);
2707 This->running = TRUE;
2709 if (e->cfra >= s_last) {
2710 e->ibuf = give_ibuf_seq_impl(This->scene,
2711 e->rectx, e->recty, e->cfra, e->chanshown,
2715 pthread_mutex_lock(&queue_lock);
2717 BLI_addtail(&prefetch_done, e);
2719 for (e = prefetch_wait.first; e; e = e->next) {
2720 if (s_last > e->monoton_cfra) {
2721 BLI_remlink(&prefetch_wait, e);
2726 for (e = prefetch_done.first; e; e = e->next) {
2727 if (s_last > e->monoton_cfra) {
2729 IMB_cache_limiter_unref(e->ibuf);
2731 BLI_remlink(&prefetch_done, e);
2736 pthread_mutex_unlock(&queue_lock);
2738 pthread_mutex_lock(&frame_done_lock);
2739 pthread_cond_signal(&frame_done_cond);
2740 pthread_mutex_unlock(&frame_done_lock);
2745 static void seq_start_threads(Scene *scene)
2749 running_threads.first = running_threads.last = NULL;
2750 prefetch_wait.first = prefetch_wait.last = NULL;
2751 prefetch_done.first = prefetch_done.last = NULL;
2753 seq_thread_shutdown = FALSE;
2754 seq_last_given_monoton_cfra = monoton_cfra = 0;
2756 /* since global structures are modified during the processing
2757 of one frame, only one render thread is currently possible...
2759 (but we code, in the hope, that we can remove this restriction
2763 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2765 for (i = 0; i < 1; i++) {
2766 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2769 BLI_addtail(&running_threads, t);
2771 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2774 /* init malloc mutex */
2775 BLI_init_threads(0, 0, 0);
2778 static void seq_stop_threads()
2780 PrefetchThread *tslot;
2781 PrefetchQueueElem *e;
2783 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2785 if (seq_thread_shutdown) {
2786 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2790 pthread_mutex_lock(&wakeup_lock);
2792 seq_thread_shutdown = TRUE;
2794 pthread_cond_broadcast(&wakeup_cond);
2795 pthread_mutex_unlock(&wakeup_lock);
2797 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2798 pthread_join(tslot->pthread, NULL);
2802 for (e = prefetch_wait.first; e; e = e->next) {
2803 BLI_remlink(&prefetch_wait, e);
2807 for (e = prefetch_done.first; e; e = e->next) {
2809 IMB_cache_limiter_unref(e->ibuf);
2811 BLI_remlink(&prefetch_done, e);
2815 BLI_freelistN(&running_threads);
2817 /* deinit malloc mutex */
2822 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2825 PrefetchQueueElem *e;
2826 if (seq_thread_shutdown) {
2830 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2834 e->chanshown = chanshown;
2835 e->render_size = render_size;
2836 e->monoton_cfra = monoton_cfra++;
2838 pthread_mutex_lock(&queue_lock);
2839 BLI_addtail(&prefetch_wait, e);
2840 pthread_mutex_unlock(&queue_lock);
2842 pthread_mutex_lock(&wakeup_lock);
2843 pthread_cond_signal(&wakeup_cond);
2844 pthread_mutex_unlock(&wakeup_lock);
2848 static void seq_wait_for_prefetch_ready()
2850 PrefetchThread *tslot;
2852 if (seq_thread_shutdown) {
2856 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2858 pthread_mutex_lock(&prefetch_ready_lock);
2861 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2862 if (tslot->running) {
2869 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2872 pthread_mutex_unlock(&prefetch_ready_lock);
2874 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2878 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2880 PrefetchQueueElem *e = NULL;
2881 int found_something = FALSE;
2883 if (seq_thread_shutdown) {
2884 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2888 int success = FALSE;
2889 pthread_mutex_lock(&queue_lock);
2891 for (e = prefetch_done.first; e; e = e->next) {
2892 if (cfra == e->cfra &&
2893 chanshown == e->chanshown &&
2894 rectx == e->rectx &&
2895 recty == e->recty &&
2896 render_size == e->render_size) {
2898 found_something = TRUE;
2904 for (e = prefetch_wait.first; e; e = e->next) {
2905 if (cfra == e->cfra &&
2906 chanshown == e->chanshown &&
2907 rectx == e->rectx &&
2908 recty == e->recty &&
2909 render_size == e->render_size) {
2910 found_something = TRUE;
2917 PrefetchThread *tslot;
2919 for(tslot = running_threads.first;
2920 tslot; tslot= tslot->next) {
2921 if (tslot->current &&
2922 cfra == tslot->current->cfra &&
2923 chanshown == tslot->current->chanshown &&
2924 rectx == tslot->current->rectx &&
2925 recty == tslot->current->recty &&
2926 render_size== tslot->current->render_size){
2927 found_something = TRUE;
2933 /* e->ibuf is unrefed by render thread on next round. */
2936 seq_last_given_monoton_cfra = e->monoton_cfra;
2939 pthread_mutex_unlock(&queue_lock);
2944 if (!found_something) {
2946 "SEQ-THREAD: Requested frame "
2947 "not in queue ???\n");
2950 pthread_mutex_lock(&frame_done_lock);
2951 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2952 pthread_mutex_unlock(&frame_done_lock);
2956 return e ? e->ibuf : 0;
2959 /* Functions to free imbuf and anim data on changes */
2961 static void free_imbuf_strip_elem(TStripElem *se)
2964 IMB_freeImBuf(se->ibuf);
2967 IMB_freeImBuf(se->ibuf_comp);
2971 se->ok= STRIPELEM_OK;
2972 se->se1= se->se2= se->se3= 0;
2975 static void free_anim_seq(Sequence *seq)
2978 IMB_free_anim(seq->anim);
2984 static void free_imbuf_seq_except(Scene *scene, int cfra)
2986 Editing *ed= seq_give_editing(scene, FALSE);
2991 if(ed==NULL) return;
2993 SEQ_BEGIN(ed, seq) {
2995 TStripElem * curelem = give_tstripelem(seq, cfra);
2997 for(a = 0, se = seq->strip->tstripdata;
2998 a < seq->strip->len && se; a++, se++) {
3000 free_imbuf_strip_elem(se);
3003 for(a = 0, se = seq->strip->tstripdata_startstill;
3004 a < seq->strip->startstill && se; a++, se++) {
3006 free_imbuf_strip_elem(se);
3009 for(a = 0, se = seq->strip->tstripdata_endstill;
3010 a < seq->strip->endstill && se; a++, se++) {
3012 free_imbuf_strip_elem(se);
3015 if(seq->strip->ibuf_startstill) {
3016 IMB_freeImBuf(seq->strip->ibuf_startstill);
3017 seq->strip->ibuf_startstill = 0;
3020 if(seq->strip->ibuf_endstill) {
3021 IMB_freeImBuf(seq->strip->ibuf_endstill);
3022 seq->strip->ibuf_endstill = 0;
3025 if(seq->type==SEQ_MOVIE)
3026 if(seq->startdisp > cfra || seq->enddisp < cfra)
3028 free_proxy_seq(seq);
3035 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
3041 if (check_mem_usage) {
3042 /* Let the cache limitor take care of this (schlaile) */
3043 /* While render let's keep all memory available for render
3045 At least if free memory is tight...
3046 This can make a big difference in encoding speed
3047 (it is around 4 times(!) faster, if we do not waste time
3048 on freeing _all_ buffers every time on long timelines...)
3052 uintptr_t mem_in_use;
3053 uintptr_t mmap_in_use;
3056 mem_in_use= MEM_get_memory_in_use();
3057 mmap_in_use= MEM_get_mapped_memory_in_use();
3058 max = MEM_CacheLimiter_get_maximum();
3060 if (max == 0 || mem_in_use + mmap_in_use <= max) {
3066 for(seq= seqbase->first; seq; seq= seq->next) {
3068 for(a = 0, se = seq->strip->tstripdata;
3069 a < seq->strip->len && se; a++, se++) {
3070 free_imbuf_strip_elem(se);
3072 for(a = 0, se = seq->strip->tstripdata_startstill;
3073 a < seq->strip->startstill && se; a++, se++) {
3074 free_imbuf_strip_elem(se);
3076 for(a = 0, se = seq->strip->tstripdata_endstill;
3077 a < seq->strip->endstill && se; a++, se++) {
3078 free_imbuf_strip_elem(se);
3080 if(seq->strip->ibuf_startstill) {
3081 IMB_freeImBuf(seq->strip->ibuf_startstill);
3082 seq->strip->ibuf_startstill = 0;
3085 if(seq->strip->ibuf_endstill) {
3086 IMB_freeImBuf(seq->strip->ibuf_endstill);
3087 seq->strip->ibuf_endstill = 0;
3090 if(seq->type==SEQ_MOVIE)
3092 if(seq->type==SEQ_SPEED) {
3093 sequence_effect_speed_rebuild_map(scene, seq, 1);
3096 if(seq->type==SEQ_META) {
3097 free_imbuf_seq(scene, &seq->seqbase, FALSE);
3099 if(seq->type==SEQ_SCENE) {
3100 /* FIXME: recurs downwards,
3101 but do recurs protection somehow! */
3107 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
3110 int a, free_imbuf = 0;
3113 /* recurs downwards to see if this seq depends on the changed seq */
3118 if(seq == changed_seq)
3121 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
3122 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
3126 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
3128 if(seq->seq2 && (seq->seq2 != seq->seq1))
3129 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
3131 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
3132 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
3137 se= seq->strip->tstripdata;
3139 for(a=0; a<seq->len; a++, se++)
3140 free_imbuf_strip_elem(se);
3143 if(seq->type == SEQ_MOVIE)
3145 if(seq->type == SEQ_SPEED) {
3146 sequence_effect_speed_rebuild_map(scene, seq, 1);
3157 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
3159 Editing *ed= seq_give_editing(scene, FALSE);
3162 if (ed==NULL) return;
3164 for (seq=ed->seqbase.first; seq; seq=seq->next)
3165 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
3168 #if 0 // XXX from 2.4x, needs updating
3169 void free_imbuf_seq()
3171 Scene * sce = G.main->scene.first;
3173 free_imbuf_seq_editing(sce->ed);
3179 #if 0 // XXX old animation system
3180 static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo)
3182 /* force update of all sequences with this ipo, on ipo changes */
3183 Editing *ed= seq_give_editing(scene, FALSE);
3186 if(ed==NULL) return;
3188 SEQ_BEGIN(ed, seq) {
3189 if(seq->ipo == ipo) {
3190 update_changed_seq_and_deps(scene, seq, 0, 1);
3191 if(seq->type == SEQ_SPEED) {
3192 sequence_effect_speed_rebuild_map(seq, 1);
3194 free_proxy_seq(seq);