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.
23 * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
25 * ***** END GPL LICENSE BLOCK *****
32 #include "MEM_guardedalloc.h"
33 #include "MEM_CacheLimiterC-Api.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
38 #include "IMB_imbuf_types.h"
39 #include "IMB_imbuf.h"
41 #include "DNA_ipo_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_sequence_types.h"
44 #include "DNA_view3d_types.h"
46 #include "BKE_global.h"
47 #include "BKE_image.h"
50 #include "BKE_scene.h"
51 #include "BKE_texture.h"
52 #include "BKE_utildefines.h"
54 #include "BIF_editsound.h"
55 #include "BIF_editseq.h"
56 #include "BSE_filesel.h"
57 #include "BSE_headerbuttons.h"
58 #include "BIF_interface.h"
59 #include "BIF_renderwin.h"
60 #include "BIF_screen.h"
61 #include "BIF_space.h"
62 #include "BIF_toolbox.h"
64 #include "BSE_sequence.h"
65 #include "BSE_seqeffects.h"
67 #include "RE_pipeline.h" // talks to entire render API
71 #include "BLI_threads.h"
75 #define snprintf _snprintf
78 int seqrectx, seqrecty;
80 /* **********************************************************************
81 alloc / free functions
82 ********************************************************************** */
84 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 free_strip(Strip *strip)
112 if(strip->us>0) return;
114 printf("error: negative users in strip\n");
118 if (strip->stripdata) {
119 MEM_freeN(strip->stripdata);
123 MEM_freeN(strip->proxy);
126 MEM_freeN(strip->crop);
128 if (strip->transform) {
129 MEM_freeN(strip->transform);
131 if (strip->color_balance) {
132 MEM_freeN(strip->color_balance);
135 free_tstripdata(strip->len, strip->tstripdata);
136 free_tstripdata(strip->endstill, strip->tstripdata_endstill);
137 free_tstripdata(strip->startstill, strip->tstripdata_startstill);
139 if(strip->ibuf_startstill) {
140 IMB_freeImBuf(strip->ibuf_startstill);
141 strip->ibuf_startstill = 0;
144 if(strip->ibuf_endstill) {
145 IMB_freeImBuf(strip->ibuf_endstill);
146 strip->ibuf_endstill = 0;
152 void new_tstripdata(Sequence *seq)
155 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
156 free_tstripdata(seq->strip->endstill,
157 seq->strip->tstripdata_endstill);
158 free_tstripdata(seq->strip->startstill,
159 seq->strip->tstripdata_startstill);
161 seq->strip->tstripdata= 0;
162 seq->strip->tstripdata_endstill= 0;
163 seq->strip->tstripdata_startstill= 0;
165 if(seq->strip->ibuf_startstill) {
166 IMB_freeImBuf(seq->strip->ibuf_startstill);
167 seq->strip->ibuf_startstill = 0;
170 if(seq->strip->ibuf_endstill) {
171 IMB_freeImBuf(seq->strip->ibuf_endstill);
172 seq->strip->ibuf_endstill = 0;
175 seq->strip->len= seq->len;
179 void free_sequence(Sequence *seq)
181 Sequence *last_seq = get_last_seq();
183 if(seq->strip) free_strip(seq->strip);
185 if(seq->anim) IMB_free_anim(seq->anim);
186 if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
188 if (seq->type & SEQ_EFFECT) {
189 struct SeqEffectHandle sh = get_sequence_effect(seq);
194 if(seq==last_seq) set_last_seq(NULL);
200 **********************************************************************
202 **********************************************************************
203 * Build a complete array of _all_ sequencies (including those
205 **********************************************************************
208 static void do_seq_count(ListBase *seqbase, int *totseq)
215 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
220 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
227 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
234 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
239 do_seq_count(seqbase, totseq);
245 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
248 do_build_seqar(seqbase, seqar, 0);
252 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
253 int (*test_func)(Sequence * seq))
259 int test = test_func(seq);
260 if (test & BUILD_SEQAR_COUNT_CURRENT) {
263 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
264 do_seq_count_cb(&seq->seqbase, totseq, test_func);
270 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
271 int (*test_func)(Sequence * seq))
277 int test = test_func(seq);
280 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
281 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
284 if (test & BUILD_SEQAR_COUNT_CURRENT) {
292 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
293 int (*test_func)(Sequence * seq))
298 do_seq_count_cb(seqbase, totseq, test_func);
304 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
307 do_build_seqar_cb(seqbase, seqar, 0, test_func);
312 void free_editing(Editing *ed)
318 set_last_seq(NULL); /* clear_last_seq doesnt work, it screws up free_sequence */
320 WHILE_SEQ(&ed->seqbase) {
325 while( (ms= ed->metastack.first) ) {
326 BLI_remlink(&ed->metastack, ms);
334 void calc_sequence_disp(Sequence *seq)
336 if(seq->startofs && seq->startstill) seq->startstill= 0;
337 if(seq->endofs && seq->endstill) seq->endstill= 0;
339 seq->startdisp= seq->start + seq->startofs - seq->startstill;
340 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
342 seq->handsize= 10.0; /* 10 frames */
343 if( seq->enddisp-seq->startdisp < 10 ) {
344 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
346 else if(seq->enddisp-seq->startdisp > 250) {
347 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
351 void calc_sequence(Sequence *seq)
356 /* check all metas recursively */
357 seqm= seq->seqbase.first;
359 if(seqm->seqbase.first) calc_sequence(seqm);
363 /* effects and meta: automatic start and end */
365 if(seq->type & SEQ_EFFECT) {
367 if(seq->seq2==0) seq->seq2= seq->seq1;
368 if(seq->seq3==0) seq->seq3= seq->seq1;
370 /* effecten go from seq1 -> seq2: test */
372 /* we take the largest start and smallest end */
374 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
375 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
378 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
379 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
380 seq->len= seq->enddisp - seq->startdisp;
382 calc_sequence_disp(seq);
385 if(seq->strip && seq->len!=seq->strip->len) {
391 if(seq->type==SEQ_META) {
392 seqm= seq->seqbase.first;
397 if(seqm->startdisp < min) min= seqm->startdisp;
398 if(seqm->enddisp > max) max= seqm->enddisp;
401 seq->start= min + seq->anim_startofs;
403 seq->len -= seq->anim_startofs;
404 seq->len -= seq->anim_endofs;
406 if(seq->strip && seq->len!=seq->strip->len) {
411 calc_sequence_disp(seq);
415 void reload_sequence_new_file(Sequence * seq)
417 char str[FILE_MAXDIR+FILE_MAXFILE];
419 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
420 seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND ||
421 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
427 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
428 seq->type != SEQ_IMAGE) {
429 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
430 BLI_convertstringcode(str, G.sce);
431 BLI_convertstringframe(str, G.scene->r.cfra);
435 if (seq->type == SEQ_IMAGE) {
437 int olen = MEM_allocN_len(seq->strip->stripdata)
438 / sizeof(struct StripElem);
440 seq->len -= seq->anim_startofs;
441 seq->len -= seq->anim_endofs;
445 seq->strip->len = seq->len;
446 } else if (seq->type == SEQ_MOVIE) {
447 if(seq->anim) IMB_free_anim(seq->anim);
448 seq->anim = openanim(
450 ((seq->flag & SEQ_FILTERY)
451 ? IB_animdeinterlace : 0));
457 seq->len = IMB_anim_get_duration(seq->anim);
459 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
461 seq->len -= seq->anim_startofs;
462 seq->len -= seq->anim_endofs;
466 seq->strip->len = seq->len;
467 } else if (seq->type == SEQ_HD_SOUND) {
468 if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
469 seq->hdaudio = sound_open_hdaudio(str);
475 seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS)
476 - seq->anim_startofs - seq->anim_endofs;
480 seq->strip->len = seq->len;
481 } else if (seq->type == SEQ_RAM_SOUND) {
482 seq->len = (int) ( ((float)(seq->sound->streamlen-1)/
483 ((float)G.scene->audio.mixrate*4.0 ))
485 seq->len -= seq->anim_startofs;
486 seq->len -= seq->anim_endofs;
490 seq->strip->len = seq->len;
491 } else if (seq->type == SEQ_SCENE) {
492 Scene * sce = G.main->scene.first;
495 if(nr == seq->scenenr) {
508 strncpy(seq->name + 2, sce->id.name + 2,
509 sizeof(seq->name) - 2);
511 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
512 seq->len -= seq->anim_startofs;
513 seq->len -= seq->anim_endofs;
517 seq->strip->len = seq->len;
525 /* all strips together per kind, and in order of y location ("machine") */
526 ListBase seqbase, effbase;
528 Sequence *seq, *seqt;
533 seqbase.first= seqbase.last= 0;
534 effbase.first= effbase.last= 0;
536 while( (seq= ed->seqbasep->first) ) {
537 BLI_remlink(ed->seqbasep, seq);
539 if(seq->type & SEQ_EFFECT) {
542 if(seqt->machine>=seq->machine) {
543 BLI_insertlinkbefore(&effbase, seqt, seq);
548 if(seqt==0) BLI_addtail(&effbase, seq);
553 if(seqt->machine>=seq->machine) {
554 BLI_insertlinkbefore(&seqbase, seqt, seq);
559 if(seqt==0) BLI_addtail(&seqbase, seq);
563 addlisttolist(&seqbase, &effbase);
564 *(ed->seqbasep)= seqbase;
568 void clear_scene_in_allseqs(Scene *sce)
574 /* when a scene is deleted: test all seqs */
576 sce1= G.main->scene.first;
578 if(sce1!=sce && sce1->ed) {
581 WHILE_SEQ(&ed->seqbase) {
583 if(seq->scene==sce) seq->scene= 0;
593 char *give_seqname_by_type(int type)
596 case SEQ_META: return "Meta";
597 case SEQ_IMAGE: return "Image";
598 case SEQ_SCENE: return "Scene";
599 case SEQ_MOVIE: return "Movie";
600 case SEQ_RAM_SOUND: return "Audio (RAM)";
601 case SEQ_HD_SOUND: return "Audio (HD)";
602 case SEQ_CROSS: return "Cross";
603 case SEQ_GAMCROSS: return "Gamma Cross";
604 case SEQ_ADD: return "Add";
605 case SEQ_SUB: return "Sub";
606 case SEQ_MUL: return "Mul";
607 case SEQ_ALPHAOVER: return "Alpha Over";
608 case SEQ_ALPHAUNDER: return "Alpha Under";
609 case SEQ_OVERDROP: return "Over Drop";
610 case SEQ_WIPE: return "Wipe";
611 case SEQ_GLOW: return "Glow";
612 case SEQ_TRANSFORM: return "Transform";
613 case SEQ_COLOR: return "Color";
614 case SEQ_SPEED: return "Speed";
620 char *give_seqname(Sequence *seq)
622 char * name = give_seqname_by_type(seq->type);
625 if(seq->type<SEQ_EFFECT) {
626 return seq->strip->dir;
627 } else if(seq->type==SEQ_PLUGIN) {
628 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
629 seq->plugin && seq->plugin->doit) {
630 return seq->plugin->pname;
641 /* ***************** DO THE SEQUENCE ***************** */
643 static void make_black_ibuf(ImBuf *ibuf)
649 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
651 tot= ibuf->x*ibuf->y;
654 rect_float = ibuf->rect_float;
657 memset(rect, 0, tot * sizeof(char) * 4);
661 memset(rect_float, 0, tot * sizeof(float) * 4);
665 static void multibuf(ImBuf *ibuf, float fmul)
672 mul= (int)(256.0*fmul);
673 rt= (char *)ibuf->rect;
674 rt_float = ibuf->rect_float;
680 icol= (mul*rt[0])>>8;
681 if(icol>254) rt[0]= 255; else rt[0]= icol;
682 icol= (mul*rt[1])>>8;
683 if(icol>254) rt[1]= 255; else rt[1]= icol;
684 icol= (mul*rt[2])>>8;
685 if(icol>254) rt[2]= 255; else rt[2]= icol;
686 icol= (mul*rt[3])>>8;
687 if(icol>254) rt[3]= 255; else rt[3]= icol;
705 static void do_effect(int cfra, Sequence *seq, TStripElem * se)
707 TStripElem *se1, *se2, *se3;
711 struct SeqEffectHandle sh = get_sequence_effect(seq);
713 if (!sh.execute) { /* effect not supported in this version... */
714 make_black_ibuf(se->ibuf);
718 if(seq->ipo && seq->ipo->curve.first) {
719 do_seq_ipo(seq, cfra);
723 sh.get_default_fac(seq, cfra, &fac, &facf);
726 if( !(G.scene->r.mode & R_FIELDS) ) facf = fac;
728 early_out = sh.early_out(seq, fac, facf);
730 if (early_out == -1) { /* no input needed */
731 sh.execute(seq, cfra, fac, facf,
732 se->ibuf->x, se->ibuf->y,
739 if (se->se1==0 || se->se2==0 || se->se3==0) {
740 make_black_ibuf(se->ibuf);
748 if ( (se1==0 || se2==0 || se3==0)
749 || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
750 make_black_ibuf(se->ibuf);
757 make_black_ibuf(se->ibuf);
763 if (se1 == 0 || se1->ibuf == 0) {
764 make_black_ibuf(se->ibuf);
768 if (se->ibuf != se1->ibuf) {
769 IMB_freeImBuf(se->ibuf);
770 se->ibuf = se1->ibuf;
771 IMB_refImBuf(se->ibuf);
776 make_black_ibuf(se->ibuf);
782 if (se2 == 0 || se2->ibuf == 0) {
783 make_black_ibuf(se->ibuf);
786 if (se->ibuf != se2->ibuf) {
787 IMB_freeImBuf(se->ibuf);
788 se->ibuf = se2->ibuf;
789 IMB_refImBuf(se->ibuf);
793 make_black_ibuf(se->ibuf);
800 if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
801 IMB_float_from_rect(se1->ibuf);
803 if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
804 IMB_float_from_rect(se2->ibuf);
807 if (!se1->ibuf->rect && !se->ibuf->rect_float) {
808 IMB_rect_from_float(se1->ibuf);
810 if (!se2->ibuf->rect && !se->ibuf->rect_float) {
811 IMB_rect_from_float(se2->ibuf);
814 sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
818 static int give_stripelem_index(Sequence *seq, int cfra)
822 if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
823 if(seq->len == 0) return -1;
824 if(seq->flag&SEQ_REVERSE_FRAMES) {
825 /*reverse frame in this sequence */
826 if(cfra <= seq->start) nr= seq->len-1;
827 else if(cfra >= seq->start+seq->len-1) nr= 0;
828 else nr= (seq->start + seq->len) - cfra;
830 if(cfra <= seq->start) nr= 0;
831 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
832 else nr= cfra-seq->start;
834 if (seq->strobe < 1.0) seq->strobe = 1.0;
835 if (seq->strobe > 1.0) {
836 nr -= (int)fmod((double)nr, (double)seq->strobe);
842 static TStripElem* alloc_tstripdata(int len, const char * name)
845 TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
846 for (i = 0; i < len; i++) {
847 se[i].ok = STRIPELEM_OK;
852 TStripElem *give_tstripelem(Sequence *seq, int cfra)
857 se = seq->strip->tstripdata;
858 if (se == 0 && seq->len > 0) {
859 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
862 nr = give_stripelem_index(seq, cfra);
864 if (nr == -1) return 0;
865 if (se == 0) return 0;
869 /* if there are IPOs with blend modes active, one has to watch out
870 for startstill + endstill area: we can't use the same tstripelem
871 here for all ibufs, since then, blending with IPOs won't work!
873 Rather common case, if you use a single image and try to fade
874 it in and out... or want to use your strip as a watermark in
877 if (seq->blend_mode != SEQ_BLEND_REPLACE ||
878 (seq->ipo && seq->ipo->curve.first && (
879 !(seq->type & SEQ_EFFECT) || !seq->seq1))) {
880 Strip * s = seq->strip;
881 if (cfra < seq->start) {
882 se = s->tstripdata_startstill;
883 if (seq->startstill > s->startstill) {
884 free_tstripdata(s->startstill,
885 s->tstripdata_startstill);
890 s->startstill = seq->startstill;
891 se = seq->strip->tstripdata_startstill
894 "tstripelems_startstill");
896 se += seq->start - cfra - 1;
898 } else if (cfra > seq->start + seq->len-1) {
899 se = s->tstripdata_endstill;
900 if (seq->endstill > s->endstill) {
901 free_tstripdata(s->endstill,
902 s->tstripdata_endstill);
907 s->endstill = seq->endstill;
908 se = seq->strip->tstripdata_endstill
911 "tstripelems_endstill");
913 se += cfra - (seq->start + seq->len-1) - 1;
923 StripElem *give_stripelem(Sequence *seq, int cfra)
928 se = seq->strip->stripdata;
929 nr = give_stripelem_index(seq, cfra);
931 if (nr == -1) return 0;
932 if (se == 0) return 0;
934 se += nr + seq->anim_startofs;
939 static int evaluate_seq_frame_gen(
940 Sequence ** seq_arr, ListBase *seqbase, int cfra)
945 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
949 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
950 seq_arr[seq->machine]= seq;
959 int evaluate_seq_frame(int cfra)
962 Sequence *seq_arr[MAXSEQ+1];
967 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
971 static int video_seq_is_rendered(Sequence * seq)
974 && !(seq->flag & SEQ_MUTE)
975 && seq->type != SEQ_RAM_SOUND
976 && seq->type != SEQ_HD_SOUND);
979 static int get_shown_sequences(
980 ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
982 Sequence *seq_arr[MAXSEQ+1];
990 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
992 if (seq_arr[b] == 0) {
996 for (b = MAXSEQ; b > 0; b--) {
997 if (video_seq_is_rendered(seq_arr[b])) {
1007 if (video_seq_is_rendered(seq_arr[b])) {
1008 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1014 for (;b <= chanshown; b++) {
1015 if (video_seq_is_rendered(seq_arr[b])) {
1016 seq_arr_out[cnt++] = seq_arr[b];
1024 /* **********************************************************************
1026 ********************************************************************** */
1028 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1030 static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
1033 char dir[FILE_MAXDIR];
1035 if (!seq->strip->proxy) {
1039 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1040 strcpy(dir, seq->strip->proxy->dir);
1042 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1043 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
1050 /* generate a seperate proxy directory for each preview size */
1052 if (seq->type == SEQ_IMAGE) {
1053 StripElem * se = give_stripelem(seq, cfra);
1054 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1055 dir, G.scene->r.size, se->name);
1057 } else if (seq->type == SEQ_MOVIE) {
1058 TStripElem * tse = give_tstripelem(seq, cfra);
1060 frameno = tse->nr + seq->anim_startofs;
1062 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1063 seq->strip->stripdata->name,
1066 TStripElem * tse = give_tstripelem(seq, cfra);
1068 frameno = tse->nr + seq->anim_startofs;
1070 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1074 BLI_convertstringcode(name, G.sce);
1075 BLI_convertstringframe(name, frameno);
1078 strcat(name, ".jpg");
1083 static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra)
1085 char name[PROXY_MAXFILE];
1087 if (!(seq->flag & SEQ_USE_PROXY)) {
1091 /* rendering at 100% ? No real sense in proxy-ing, right? */
1092 if (G.scene->r.size == 100.0) {
1096 if (!seq_proxy_get_fname(seq, cfra, name)) {
1100 if (BLI_exists(name)) {
1101 return IMB_loadiffname(name, IB_rect);
1107 static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
1108 int build_proxy_run);
1110 static void seq_proxy_build_frame(Sequence * seq, int cfra)
1112 char name[PROXY_MAXFILE];
1117 struct ImBuf * ibuf;
1119 if (!(seq->flag & SEQ_USE_PROXY)) {
1123 /* rendering at 100% ? No real sense in proxy-ing, right? */
1124 if (G.scene->r.size == 100.0) {
1128 if (!seq_proxy_get_fname(seq, cfra, name)) {
1132 se = give_tstripelem(seq, cfra);
1138 IMB_freeImBuf(se->ibuf);
1142 do_build_seq_ibuf(seq, se, cfra, TRUE);
1148 rectx= (G.scene->r.size*G.scene->r.xsch)/100;
1149 recty= (G.scene->r.size*G.scene->r.ysch)/100;
1153 if (ibuf->x != rectx || ibuf->y != recty) {
1154 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1157 /* quality is fixed, otherwise one has to generate seperate
1158 directories for every quality...
1160 depth = 32 is intentionally left in, otherwise ALPHA channels
1163 ibuf->ftype= JPG | quality;
1165 BLI_make_existing_file(name);
1167 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1172 IMB_freeImBuf(ibuf);
1176 void seq_proxy_rebuild(Sequence * seq)
1184 /* flag management tries to account for strobe and
1185 other "non-linearities", that might come in the future...
1186 better way would be to "touch" the files, so that _really_
1187 no one is rebuild twice.
1190 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1191 TStripElem * tse = give_tstripelem(seq, cfra);
1193 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1196 /* a _lot_ faster for movie files, if we read frames in
1198 if (seq->flag & SEQ_REVERSE_FRAMES) {
1199 for (cfra = seq->enddisp-seq->endstill-1;
1200 cfra >= seq->startdisp + seq->startstill; cfra--) {
1201 TStripElem * tse = give_tstripelem(seq, cfra);
1203 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1204 seq_proxy_build_frame(seq, cfra);
1205 tse->flag |= STRIPELEM_PREVIEW_DONE;
1207 if (blender_test_break()) {
1212 for (cfra = seq->startdisp + seq->startstill;
1213 cfra < seq->enddisp - seq->endstill; cfra++) {
1214 TStripElem * tse = give_tstripelem(seq, cfra);
1216 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1217 seq_proxy_build_frame(seq, cfra);
1218 tse->flag |= STRIPELEM_PREVIEW_DONE;
1220 if (blender_test_break()) {
1229 /* **********************************************************************
1231 ********************************************************************** */
1233 static StripColorBalance calc_cb(StripColorBalance * cb_)
1235 StripColorBalance cb = *cb_;
1238 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1239 for (c = 0; c < 3; c++) {
1240 cb.lift[c] = 1.0 - cb.lift[c];
1243 for (c = 0; c < 3; c++) {
1244 cb.lift[c] = -(1.0 - cb.lift[c]);
1247 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1248 for (c = 0; c < 3; c++) {
1249 if (cb.gain[c] != 0.0) {
1250 cb.gain[c] = 1.0/cb.gain[c];
1252 cb.gain[c] = 1000000; /* should be enough :) */
1257 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1258 for (c = 0; c < 3; c++) {
1259 if (cb.gamma[c] != 0.0) {
1260 cb.gamma[c] = 1.0/cb.gamma[c];
1262 cb.gamma[c] = 1000000; /* should be enough :) */
1270 static void make_cb_table_byte(float lift, float gain, float gamma,
1271 unsigned char * table, float mul)
1275 for (y = 0; y < 256; y++) {
1276 float v = 1.0 * y / 255;
1283 } else if (v < 0.0) {
1291 static void make_cb_table_float(float lift, float gain, float gamma,
1292 float * table, float mul)
1296 for (y = 0; y < 256; y++) {
1297 float v = (float) y * 1.0 / 255.0;
1306 static void color_balance_byte_byte(Sequence * seq, TStripElem* se,
1309 unsigned char cb_tab[3][256];
1311 unsigned char * p = (unsigned char*) se->ibuf->rect;
1312 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1314 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1316 for (c = 0; c < 3; c++) {
1317 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1322 p[0] = cb_tab[0][p[0]];
1323 p[1] = cb_tab[1][p[1]];
1324 p[2] = cb_tab[2][p[2]];
1330 static void color_balance_byte_float(Sequence * seq, TStripElem* se,
1333 float cb_tab[4][256];
1335 unsigned char * p = (unsigned char*) se->ibuf->rect;
1336 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1338 StripColorBalance cb;
1340 imb_addrectfloatImBuf(se->ibuf);
1342 o = se->ibuf->rect_float;
1344 cb = calc_cb(seq->strip->color_balance);
1346 for (c = 0; c < 3; c++) {
1347 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1351 for (i = 0; i < 256; i++) {
1352 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1356 o[0] = cb_tab[0][p[0]];
1357 o[1] = cb_tab[1][p[1]];
1358 o[2] = cb_tab[2][p[2]];
1359 o[3] = cb_tab[3][p[3]];
1365 static void color_balance_float_float(Sequence * seq, TStripElem* se,
1368 float * p = se->ibuf->rect_float;
1369 float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1370 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1374 for (c = 0; c < 3; c++) {
1375 p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
1382 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1384 if (se->ibuf->rect_float) {
1385 color_balance_float_float(seq, se, mul);
1386 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1387 color_balance_byte_float(seq, se, mul);
1389 color_balance_byte_byte(seq, se, mul);
1394 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1396 Do all the things you can't really do afterwards using sequence effects
1397 (read: before rescaling to render resolution has been done)
1402 - Crop and transform in image source coordinate space
1403 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1404 - Promote image to float data (affects pipeline operations afterwards)
1405 - Color balance (is most efficient in the byte -> float
1406 (future: half -> float should also work fine!)
1407 case, if done on load, since we can use lookup tables)
1412 static int input_have_to_preprocess(Sequence * seq, TStripElem* se, int cfra)
1416 if ((seq->flag & SEQ_FILTERY) ||
1417 (seq->flag & SEQ_USE_CROP) ||
1418 (seq->flag & SEQ_USE_TRANSFORM) ||
1419 (seq->flag & SEQ_FLIPX) ||
1420 (seq->flag & SEQ_FLIPY) ||
1421 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1422 (seq->flag & SEQ_MAKE_PREMUL) ||
1423 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1429 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1430 if (seq->ipo && seq->ipo->curve.first) {
1431 do_seq_ipo(seq, cfra);
1434 mul *= seq->blend_opacity / 100.0;
1444 static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
1448 seq->strip->orx= se->ibuf->x;
1449 seq->strip->ory= se->ibuf->y;
1451 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1452 IMB_filtery(se->ibuf);
1455 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1460 memset(&c, 0, sizeof(StripCrop));
1461 memset(&t, 0, sizeof(StripTransform));
1463 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1464 c = *seq->strip->crop;
1466 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1467 t = *seq->strip->transform;
1470 sx = se->ibuf->x - c.left - c.right;
1471 sy = se->ibuf->y - c.top - c.bottom;
1475 if (seq->flag & SEQ_USE_TRANSFORM) {
1480 if (c.top + c.bottom >= se->ibuf->y ||
1481 c.left + c.right >= se->ibuf->x ||
1482 t.xofs >= dx || t.yofs >= dy) {
1483 make_black_ibuf(se->ibuf);
1487 if (se->ibuf->rect_float) {
1488 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1490 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1493 IMB_rectcpy(i, se->ibuf,
1498 IMB_freeImBuf(se->ibuf);
1504 if(seq->flag & SEQ_FLIPX) {
1505 IMB_flipx(se->ibuf);
1507 if(seq->flag & SEQ_FLIPY) {
1508 IMB_flipy(se->ibuf);
1511 if(seq->mul == 0.0) {
1517 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1518 if (seq->ipo && seq->ipo->curve.first) {
1519 do_seq_ipo(seq, cfra);
1522 mul *= seq->blend_opacity / 100.0;
1525 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1526 color_balance(seq, se, mul);
1530 if(seq->flag & SEQ_MAKE_FLOAT) {
1531 if (!se->ibuf->rect_float) {
1532 IMB_float_from_rect(se->ibuf);
1534 if (se->ibuf->rect) {
1535 imb_freerectImBuf(se->ibuf);
1540 multibuf(se->ibuf, mul);
1543 if(seq->flag & SEQ_MAKE_PREMUL) {
1544 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1545 converttopremul(se->ibuf);
1550 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1551 if(G.scene->r.mode & R_OSA) {
1552 IMB_scaleImBuf(se->ibuf,
1553 (short)seqrectx, (short)seqrecty);
1555 IMB_scalefastImBuf(se->ibuf,
1556 (short)seqrectx, (short)seqrecty);
1561 /* test if image too small or discarded from cache: reload */
1563 static void test_and_auto_discard_ibuf(TStripElem * se)
1566 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
1567 || !(se->ibuf->rect || se->ibuf->rect_float)) {
1568 IMB_freeImBuf(se->ibuf);
1571 se->ok= STRIPELEM_OK;
1574 if (se->ibuf_comp) {
1575 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
1576 || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1577 IMB_freeImBuf(se->ibuf_comp);
1584 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1586 if (strip->ibuf_startstill) {
1587 if (!strip->ibuf_startstill->rect &&
1588 !strip->ibuf_startstill->rect_float) {
1589 IMB_freeImBuf(strip->ibuf_startstill);
1590 strip->ibuf_startstill = 0;
1593 if (strip->ibuf_endstill) {
1594 if (!strip->ibuf_endstill->rect &&
1595 !strip->ibuf_endstill->rect_float) {
1596 IMB_freeImBuf(strip->ibuf_endstill);
1597 strip->ibuf_endstill = 0;
1602 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1605 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1606 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1608 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1610 if (se->nr == seq->len - 1
1612 && seq->strip->ibuf_endstill) {
1613 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1615 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1620 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1624 seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1626 IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1627 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1629 if (se->nr == seq->len - 1 && seq->len != 1) {
1630 seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1632 IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1633 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1638 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1640 Sequence* seq_arr[MAXSEQ+1];
1644 evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1646 for (i = 0; i < MAXSEQ; i++) {
1647 if (!video_seq_is_rendered(seq_arr[i])) {
1650 se = give_tstripelem(seq_arr[i], cfra);
1653 IMB_freeImBuf(se->ibuf);
1656 se->ok= STRIPELEM_OK;
1659 if (se->ibuf_comp) {
1660 IMB_freeImBuf(se->ibuf_comp);
1669 static TStripElem* do_build_seq_array_recursively(
1670 ListBase *seqbasep, int cfra, int chanshown);
1672 static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
1673 int build_proxy_run)
1675 char name[FILE_MAXDIR+FILE_MAXFILE];
1676 int use_limiter = TRUE;
1678 test_and_auto_discard_ibuf(se);
1679 test_and_auto_discard_ibuf_stills(seq->strip);
1681 if(seq->type == SEQ_META) {
1682 TStripElem * meta_se = 0;
1683 use_limiter = FALSE;
1685 if (!build_proxy_run && se->ibuf == 0) {
1686 se->ibuf = seq_proxy_fetch(seq, cfra);
1692 if(!se->ibuf && seq->seqbase.first) {
1693 meta_se = do_build_seq_array_recursively(
1694 &seq->seqbase, seq->start + se->nr, 0);
1697 se->ok = STRIPELEM_OK;
1699 if(!se->ibuf && meta_se) {
1700 se->ibuf = meta_se->ibuf_comp;
1702 (!input_have_to_preprocess(seq, se, cfra) ||
1704 IMB_refImBuf(se->ibuf);
1705 if (build_proxy_run) {
1706 IMB_cache_limiter_unref(se->ibuf);
1708 } else if (se->ibuf) {
1709 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1711 IMB_cache_limiter_unref(se->ibuf);
1719 free_metastrip_imbufs(
1720 &seq->seqbase, seq->start + se->nr, 0);
1724 input_preprocess(seq, se, cfra);
1726 } else if(seq->type & SEQ_EFFECT) {
1727 /* should the effect be recalculated? */
1729 if (!build_proxy_run && se->ibuf == 0) {
1730 se->ibuf = seq_proxy_fetch(seq, cfra);
1734 /* if one of two first inputs are rectfloat, output is float too */
1735 if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
1736 (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
1737 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
1739 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
1741 do_effect(cfra, seq, se);
1743 } else if(seq->type == SEQ_IMAGE) {
1744 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
1745 StripElem * s_elem = give_stripelem(seq, cfra);
1746 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
1747 BLI_convertstringcode(name, G.sce);
1748 BLI_convertstringframe(name, G.scene->r.cfra);
1749 if (!build_proxy_run) {
1750 se->ibuf = seq_proxy_fetch(seq, cfra);
1752 copy_from_ibuf_still(seq, se);
1755 se->ibuf= IMB_loadiffname(
1757 copy_to_ibuf_still(seq, se);
1761 se->ok = STRIPELEM_FAILED;
1762 } else if (!build_proxy_run) {
1763 input_preprocess(seq, se, cfra);
1766 } else if(seq->type == SEQ_MOVIE) {
1767 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
1768 if(!build_proxy_run) {
1769 se->ibuf = seq_proxy_fetch(seq, cfra);
1771 copy_from_ibuf_still(seq, se);
1773 if (se->ibuf == 0) {
1775 BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
1776 BLI_convertstringcode(name, G.sce);
1777 BLI_convertstringframe(name, G.scene->r.cfra);
1779 seq->anim = openanim(
1781 ((seq->flag & SEQ_FILTERY)
1782 ? IB_animdeinterlace : 0));
1785 IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
1786 se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
1788 copy_to_ibuf_still(seq, se);
1792 se->ok = STRIPELEM_FAILED;
1793 } else if (!build_proxy_run) {
1794 input_preprocess(seq, se, cfra);
1797 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
1799 Sequence * oldseq = get_last_seq();
1800 Scene *sce= seq->scene, *oldsce= G.scene;
1803 int doseq, rendering= G.rendering;
1805 int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ);
1807 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
1808 se->ibuf = seq_proxy_fetch(seq, cfra);
1810 input_preprocess(seq, se, cfra);
1814 if (se->ibuf == NULL && sce_valid) {
1815 copy_from_ibuf_still(seq, se);
1817 input_preprocess(seq, se, cfra);
1822 se->ok = STRIPELEM_FAILED;
1823 } else if (se->ibuf==NULL && sce_valid) {
1826 /* Hack! This function can be called from do_render_seq(), in that case
1827 the seq->scene can already have a Render initialized with same name,
1828 so we have to use a default name. (compositor uses G.scene name to
1830 However, when called from within the UI (image preview in sequencer)
1831 we do want to use scene Render, that way the render result is defined
1832 for display in render/imagewindow */
1834 BLI_strncpy(scenename, sce->id.name+2, 64);
1835 strcpy(sce->id.name+2, " do_build_seq_ibuf");
1837 re= RE_NewRender(sce->id.name);
1839 /* prevent eternal loop */
1840 doseq= G.scene->r.scemode & R_DOSEQ;
1841 G.scene->r.scemode &= ~R_DOSEQ;
1843 BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
1845 /* hrms, set_scene still needed? work on that... */
1846 if(sce!=oldsce) set_scene_bg(sce);
1847 RE_BlenderFrame(re, sce,
1848 seq->sfra+se->nr+seq->anim_startofs);
1849 if(sce!=oldsce) set_scene_bg(oldsce);
1851 /* UGLY WARNING, it is set to zero in RE_BlenderFrame */
1852 G.rendering= rendering;
1854 BLI_strncpy(sce->id.name+2, scenename, 64);
1856 RE_GetResultImage(re, &rres);
1859 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
1860 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
1862 addzbuffloatImBuf(se->ibuf);
1863 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
1865 } else if (rres.rect32) {
1866 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
1867 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
1870 BIF_end_render_callbacks();
1873 G.scene->r.scemode |= doseq;
1875 if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
1878 set_last_seq(oldseq);
1880 copy_to_ibuf_still(seq, se);
1882 if (!build_proxy_run) {
1883 if(se->ibuf == NULL) {
1884 se->ok = STRIPELEM_FAILED;
1886 input_preprocess(seq, se, cfra);
1892 if (!build_proxy_run) {
1893 if (se->ibuf && use_limiter) {
1894 IMB_cache_limiter_insert(se->ibuf);
1895 IMB_cache_limiter_ref(se->ibuf);
1896 IMB_cache_limiter_touch(se->ibuf);
1901 static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra);
1903 static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
1906 struct SeqEffectHandle sh = get_sequence_effect(seq);
1913 if(seq->ipo && seq->ipo->curve.first) {
1914 do_seq_ipo(seq, cfra);
1918 sh.get_default_fac(seq, cfra, &fac, &facf);
1921 if( G.scene->r.mode & R_FIELDS ); else facf= fac;
1923 early_out = sh.early_out(seq, fac, facf);
1924 switch (early_out) {
1926 /* no input needed */
1929 se->se1 = do_build_seq_recursively(seq->seq1, cfra);
1930 se->se2 = do_build_seq_recursively(seq->seq2, cfra);
1932 se->se3 = do_build_seq_recursively(seq->seq3, cfra);
1936 se->se1 = do_build_seq_recursively(seq->seq1, cfra);
1939 se->se2 = do_build_seq_recursively(seq->seq2, cfra);
1944 do_build_seq_ibuf(seq, se, cfra, FALSE);
1946 /* children are not needed anymore ... */
1948 if (se->se1 && se->se1->ibuf) {
1949 IMB_cache_limiter_unref(se->se1->ibuf);
1951 if (se->se2 && se->se2->ibuf) {
1952 IMB_cache_limiter_unref(se->se2->ibuf);
1954 if (se->se3 && se->se3->ibuf) {
1955 IMB_cache_limiter_unref(se->se3->ibuf);
1959 static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
1963 se = give_tstripelem(seq, cfra);
1966 if (seq->type & SEQ_EFFECT) {
1967 do_effect_seq_recursively(seq, se, cfra);
1969 do_build_seq_ibuf(seq, se, cfra, FALSE);
1977 If cfra was float throughout blender (especially in the render
1978 pipeline) one could even _render_ with subframe precision
1979 instead of faking using the blend code below...
1983 static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra)
1985 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
1986 int nr = cfra - seq->start;
1990 TStripElem * se = 0;
1991 TStripElem * se1 = 0;
1992 TStripElem * se2 = 0;
1994 sequence_effect_speed_rebuild_map(seq, 0);
1996 f_cfra = seq->start + s->frameMap[nr];
1998 cfra_left = (int) floor(f_cfra);
1999 cfra_right = (int) ceil(f_cfra);
2001 se = give_tstripelem(seq, cfra);
2007 if (cfra_left == cfra_right ||
2008 (s->flags & SEQ_SPEED_BLEND) == 0) {
2009 test_and_auto_discard_ibuf(se);
2011 if (se->ibuf == NULL) {
2012 se1 = do_build_seq_recursively_impl(
2013 seq->seq1, cfra_left);
2015 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2016 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2018 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2020 if (se1 == 0 || se1->ibuf == 0) {
2021 make_black_ibuf(se->ibuf);
2023 if (se->ibuf != se1->ibuf) {
2025 IMB_freeImBuf(se->ibuf);
2028 se->ibuf = se1->ibuf;
2029 IMB_refImBuf(se->ibuf);
2034 struct SeqEffectHandle sh;
2037 if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
2038 || !(se->ibuf->rect || se->ibuf->rect_float)) {
2039 IMB_freeImBuf(se->ibuf);
2044 if (se->ibuf == NULL) {
2045 se1 = do_build_seq_recursively_impl(
2046 seq->seq1, cfra_left);
2047 se2 = do_build_seq_recursively_impl(
2048 seq->seq1, cfra_right);
2050 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2051 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2053 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2056 make_black_ibuf(se->ibuf);
2058 sh = get_sequence_effect(seq);
2060 sh.execute(seq, cfra,
2061 f_cfra - (float) cfra_left,
2062 f_cfra - (float) cfra_left,
2063 se->ibuf->x, se->ibuf->y,
2064 se1->ibuf, se2->ibuf, 0, se->ibuf);
2070 /* caller expects this to be referenced, so do it! */
2072 IMB_cache_limiter_insert(se->ibuf);
2073 IMB_cache_limiter_ref(se->ibuf);
2074 IMB_cache_limiter_touch(se->ibuf);
2077 /* children are no longer needed */
2078 if (se1 && se1->ibuf)
2079 IMB_cache_limiter_unref(se1->ibuf);
2080 if (se2 && se2->ibuf)
2081 IMB_cache_limiter_unref(se2->ibuf);
2087 * build all ibufs recursively
2089 * if successfull, the returned TStripElem contains the (referenced!) imbuf
2090 * that means: you _must_ call
2092 * IMB_cache_limiter_unref(rval);
2098 static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra)
2100 if (seq->type == SEQ_SPEED) {
2101 return do_handle_speed_effect(seq, cfra);
2103 return do_build_seq_recursively_impl(seq, cfra);
2107 static TStripElem* do_build_seq_array_recursively(
2108 ListBase *seqbasep, int cfra, int chanshown)
2110 Sequence* seq_arr[MAXSEQ+1];
2115 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2121 se = give_tstripelem(seq_arr[count - 1], cfra);
2127 test_and_auto_discard_ibuf(se);
2129 if (se->ibuf_comp != 0) {
2130 IMB_cache_limiter_insert(se->ibuf_comp);
2131 IMB_cache_limiter_ref(se->ibuf_comp);
2132 IMB_cache_limiter_touch(se->ibuf_comp);
2138 se = do_build_seq_recursively(seq_arr[0], cfra);
2140 se->ibuf_comp = se->ibuf;
2141 IMB_refImBuf(se->ibuf_comp);
2147 for (i = count - 1; i >= 0; i--) {
2149 Sequence * seq = seq_arr[i];
2150 struct SeqEffectHandle sh;
2152 se = give_tstripelem(seq, cfra);
2154 test_and_auto_discard_ibuf(se);
2156 if (se->ibuf_comp != 0) {
2159 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2160 do_build_seq_recursively(seq, cfra);
2162 se->ibuf_comp = se->ibuf;
2163 IMB_refImBuf(se->ibuf);
2165 se->ibuf_comp = IMB_allocImBuf(
2166 (short)seqrectx, (short)seqrecty,
2172 sh = get_sequence_blend(seq);
2174 seq->facf0 = seq->facf1 = 1.0;
2176 if(seq->ipo && seq->ipo->curve.first) {
2177 do_seq_ipo(seq, cfra);
2180 if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
2182 seq->facf0 *= seq->blend_opacity / 100.0;
2183 seq->facf1 *= seq->blend_opacity / 100.0;
2185 early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2187 switch (early_out) {
2190 do_build_seq_recursively(seq, cfra);
2192 se->ibuf_comp = se->ibuf;
2193 IMB_refImBuf(se->ibuf_comp);
2195 se->ibuf_comp = IMB_allocImBuf(
2196 (short)seqrectx, (short)seqrecty,
2202 se->ibuf_comp = IMB_allocImBuf(
2203 (short)seqrectx, (short)seqrecty,
2205 IMB_cache_limiter_insert(se->ibuf_comp);
2206 IMB_cache_limiter_ref(se->ibuf_comp);
2207 IMB_cache_limiter_touch(se->ibuf_comp);
2211 do_build_seq_recursively(seq, cfra);
2213 se->ibuf = IMB_allocImBuf(
2214 (short)seqrectx, (short)seqrecty,
2218 se->ibuf_comp = se->ibuf;
2219 IMB_refImBuf(se->ibuf_comp);
2224 if (se->ibuf_comp) {
2231 for (; i < count; i++) {
2232 Sequence * seq = seq_arr[i];
2233 struct SeqEffectHandle sh = get_sequence_blend(seq);
2234 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2235 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2237 int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
2238 switch (early_out) {
2240 int x= se2->ibuf->x;
2241 int y= se2->ibuf->y;
2242 int swap_input = FALSE;
2244 if (se1->ibuf_comp->rect_float ||
2245 se2->ibuf->rect_float) {
2246 se2->ibuf_comp = IMB_allocImBuf(
2247 (short)seqrectx, (short)seqrecty,
2248 32, IB_rectfloat, 0);
2250 se2->ibuf_comp = IMB_allocImBuf(
2251 (short)seqrectx, (short)seqrecty,
2256 if (!se1->ibuf_comp->rect_float &&
2257 se2->ibuf_comp->rect_float) {
2258 IMB_float_from_rect(se1->ibuf_comp);
2260 if (!se2->ibuf->rect_float &&
2261 se2->ibuf_comp->rect_float) {
2262 IMB_float_from_rect(se2->ibuf);
2265 if (!se1->ibuf_comp->rect &&
2266 !se2->ibuf_comp->rect_float) {
2267 IMB_rect_from_float(se1->ibuf_comp);
2269 if (!se2->ibuf->rect &&
2270 !se2->ibuf_comp->rect_float) {
2271 IMB_rect_from_float(se2->ibuf);
2274 /* bad hack, to fix crazy input ordering of
2275 those two effects */
2277 if (seq->blend_mode == SEQ_ALPHAOVER ||
2278 seq->blend_mode == SEQ_ALPHAUNDER ||
2279 seq->blend_mode == SEQ_OVERDROP) {
2284 sh.execute(seq, cfra,
2285 seq->facf0, seq->facf1, x, y,
2286 se2->ibuf, se1->ibuf_comp, 0,
2289 sh.execute(seq, cfra,
2290 seq->facf0, seq->facf1, x, y,
2291 se1->ibuf_comp, se2->ibuf, 0,
2295 IMB_cache_limiter_insert(se2->ibuf_comp);
2296 IMB_cache_limiter_ref(se2->ibuf_comp);
2297 IMB_cache_limiter_touch(se2->ibuf_comp);
2299 IMB_cache_limiter_unref(se1->ibuf_comp);
2300 IMB_cache_limiter_unref(se2->ibuf);
2305 se2->ibuf_comp = se1->ibuf;
2306 IMB_refImBuf(se2->ibuf_comp);
2318 * returned ImBuf is refed!
2319 * you have to unref after usage!
2322 static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown)
2332 count = BLI_countlist(&ed->metastack);
2333 if((chanshown < 0) && (count > 0)) {
2334 count = MAX2(count + chanshown, 0);
2335 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2337 seqbasep= ed->seqbasep;
2340 seqrectx= rectx; /* bad bad global! */
2343 se = do_build_seq_array_recursively(seqbasep, cfra, chanshown);
2349 return se->ibuf_comp;
2352 ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
2357 seqrectx= rectx; /* bad bad global! */
2360 se = do_build_seq_recursively(seq, cfra);
2367 IMB_cache_limiter_unref(se->ibuf);
2373 ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
2375 ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown);
2378 IMB_cache_limiter_unref(i);
2385 static ListBase running_threads;
2386 static ListBase prefetch_wait;
2387 static ListBase prefetch_done;
2389 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2390 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2391 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2393 static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2394 static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2396 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2397 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2399 static volatile int seq_thread_shutdown = FALSE;
2400 static volatile int seq_last_given_monoton_cfra = 0;
2401 static int monoton_cfra = 0;
2403 typedef struct PrefetchThread {
2404 struct PrefetchThread *next, *prev;
2405 struct PrefetchQueueElem *current;
2410 typedef struct PrefetchQueueElem {
2411 struct PrefetchQueueElem *next, *prev;
2420 struct ImBuf * ibuf;
2421 } PrefetchQueueElem;
2423 static void * seq_prefetch_thread(void * This_)
2425 PrefetchThread * This = This_;
2427 while (!seq_thread_shutdown) {
2428 PrefetchQueueElem * e;
2431 pthread_mutex_lock(&queue_lock);
2432 e = prefetch_wait.first;
2434 BLI_remlink(&prefetch_wait, e);
2436 s_last = seq_last_given_monoton_cfra;
2440 pthread_mutex_unlock(&queue_lock);
2443 pthread_mutex_lock(&prefetch_ready_lock);
2445 This->running = FALSE;
2447 pthread_cond_signal(&prefetch_ready_cond);
2448 pthread_mutex_unlock(&prefetch_ready_lock);
2450 pthread_mutex_lock(&wakeup_lock);
2451 if (!seq_thread_shutdown) {
2452 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2454 pthread_mutex_unlock(&wakeup_lock);
2458 This->running = TRUE;
2460 if (e->cfra >= s_last) {
2461 e->ibuf = give_ibuf_seq_impl(
2462 e->rectx, e->recty, e->cfra, e->chanshown);
2465 pthread_mutex_lock(&queue_lock);
2467 BLI_addtail(&prefetch_done, e);
2469 for (e = prefetch_wait.first; e; e = e->next) {
2470 if (s_last > e->monoton_cfra) {
2471 BLI_remlink(&prefetch_wait, e);
2476 for (e = prefetch_done.first; e; e = e->next) {
2477 if (s_last > e->monoton_cfra) {
2479 IMB_cache_limiter_unref(e->ibuf);
2481 BLI_remlink(&prefetch_done, e);
2486 pthread_mutex_unlock(&queue_lock);
2488 pthread_mutex_lock(&frame_done_lock);
2489 pthread_cond_signal(&frame_done_cond);
2490 pthread_mutex_unlock(&frame_done_lock);
2495 void seq_start_threads()
2499 running_threads.first = running_threads.last = NULL;
2500 prefetch_wait.first = prefetch_wait.last = NULL;
2501 prefetch_done.first = prefetch_done.last = NULL;
2503 seq_thread_shutdown = FALSE;
2504 seq_last_given_monoton_cfra = monoton_cfra = 0;
2506 /* since global structures are modified during the processing
2507 of one frame, only one render thread is currently possible...
2509 (but we code, in the hope, that we can remove this restriction
2513 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2515 for (i = 0; i < 1; i++) {
2516 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread),
2519 BLI_addtail(&running_threads, t);
2521 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2524 /* init malloc mutex */
2525 BLI_init_threads(0, 0, 0);
2528 void seq_stop_threads()
2530 PrefetchThread *tslot;
2531 PrefetchQueueElem * e;
2533 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2535 if (seq_thread_shutdown) {
2536 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2540 pthread_mutex_lock(&wakeup_lock);
2542 seq_thread_shutdown = TRUE;
2544 pthread_cond_broadcast(&wakeup_cond);
2545 pthread_mutex_unlock(&wakeup_lock);
2547 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2548 pthread_join(tslot->pthread, NULL);
2552 for (e = prefetch_wait.first; e; e = e->next) {
2553 BLI_remlink(&prefetch_wait, e);
2557 for (e = prefetch_done.first; e; e = e->next) {
2559 IMB_cache_limiter_unref(e->ibuf);
2561 BLI_remlink(&prefetch_done, e);
2565 BLI_freelistN(&running_threads);
2567 /* deinit malloc mutex */
2571 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
2573 PrefetchQueueElem * e;
2574 if (seq_thread_shutdown) {
2578 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2582 e->chanshown = chanshown;
2583 e->monoton_cfra = monoton_cfra++;
2585 pthread_mutex_lock(&queue_lock);
2586 BLI_addtail(&prefetch_wait, e);
2587 pthread_mutex_unlock(&queue_lock);
2589 pthread_mutex_lock(&wakeup_lock);
2590 pthread_cond_signal(&wakeup_cond);
2591 pthread_mutex_unlock(&wakeup_lock);
2594 void seq_wait_for_prefetch_ready()
2596 PrefetchThread *tslot;
2598 if (seq_thread_shutdown) {
2602 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2604 pthread_mutex_lock(&prefetch_ready_lock);
2607 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2608 if (tslot->running) {
2615 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2618 pthread_mutex_unlock(&prefetch_ready_lock);
2620 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2623 ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown)
2625 PrefetchQueueElem * e = 0;
2626 int found_something = FALSE;
2628 if (seq_thread_shutdown) {
2629 return give_ibuf_seq(rectx, recty, cfra, chanshown);
2633 int success = FALSE;
2634 pthread_mutex_lock(&queue_lock);
2636 for (e = prefetch_done.first; e; e = e->next) {
2637 if (cfra == e->cfra &&
2638 chanshown == e->chanshown &&
2639 rectx == e->rectx &&
2640 recty == e->recty) {
2642 found_something = TRUE;
2648 for (e = prefetch_wait.first; e; e = e->next) {
2649 if (cfra == e->cfra &&
2650 chanshown == e->chanshown &&
2651 rectx == e->rectx &&
2652 recty == e->recty) {
2653 found_something = TRUE;
2660 PrefetchThread *tslot;
2662 for(tslot = running_threads.first;
2663 tslot; tslot= tslot->next) {
2664 if (tslot->current &&
2665 cfra == tslot->current->cfra &&
2666 chanshown == tslot->current->chanshown &&
2667 rectx == tslot->current->rectx &&
2668 recty == tslot->current->recty) {
2669 found_something = TRUE;
2675 /* e->ibuf is unrefed by render thread on next round. */
2678 seq_last_given_monoton_cfra = e->monoton_cfra;
2681 pthread_mutex_unlock(&queue_lock);
2686 if (!found_something) {
2688 "SEQ-THREAD: Requested frame "
2689 "not in queue ???\n");
2692 pthread_mutex_lock(&frame_done_lock);
2693 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
2694 pthread_mutex_unlock(&frame_done_lock);
2698 return e ? e->ibuf : 0;
2701 /* Functions to free imbuf and anim data on changes */
2703 static void free_imbuf_strip_elem(TStripElem *se)
2706 IMB_freeImBuf(se->ibuf);
2709 IMB_freeImBuf(se->ibuf_comp);
2713 se->ok= STRIPELEM_OK;
2714 se->se1= se->se2= se->se3= 0;
2717 static void free_anim_seq(Sequence *seq)
2720 IMB_free_anim(seq->anim);
2725 void free_imbuf_seq_except(int cfra)
2727 Editing *ed= G.scene->ed;
2734 WHILE_SEQ(&ed->seqbase) {
2736 TStripElem * curelem = give_tstripelem(seq, cfra);
2738 for(a = 0, se = seq->strip->tstripdata;
2739 a < seq->strip->len && se; a++, se++) {
2741 free_imbuf_strip_elem(se);
2744 for(a = 0, se = seq->strip->tstripdata_startstill;
2745 a < seq->strip->startstill && se; a++, se++) {
2747 free_imbuf_strip_elem(se);
2750 for(a = 0, se = seq->strip->tstripdata_endstill;
2751 a < seq->strip->endstill && se; a++, se++) {
2753 free_imbuf_strip_elem(se);
2756 if(seq->strip->ibuf_startstill) {
2757 IMB_freeImBuf(seq->strip->ibuf_startstill);
2758 seq->strip->ibuf_startstill = 0;
2761 if(seq->strip->ibuf_endstill) {
2762 IMB_freeImBuf(seq->strip->ibuf_endstill);
2763 seq->strip->ibuf_endstill = 0;
2766 if(seq->type==SEQ_MOVIE)
2767 if(seq->startdisp > cfra || seq->enddisp < cfra)
2774 void free_imbuf_seq()
2776 Editing *ed= G.scene->ed;
2783 WHILE_SEQ(&ed->seqbase) {
2785 for(a = 0, se = seq->strip->tstripdata;
2786 a < seq->strip->len && se; a++, se++) {
2787 free_imbuf_strip_elem(se);
2789 for(a = 0, se = seq->strip->tstripdata_startstill;
2790 a < seq->strip->startstill && se; a++, se++) {
2791 free_imbuf_strip_elem(se);
2793 for(a = 0, se = seq->strip->tstripdata_endstill;
2794 a < seq->strip->endstill && se; a++, se++) {
2795 free_imbuf_strip_elem(se);
2797 if(seq->strip->ibuf_startstill) {
2798 IMB_freeImBuf(seq->strip->ibuf_startstill);
2799 seq->strip->ibuf_startstill = 0;
2802 if(seq->strip->ibuf_endstill) {
2803 IMB_freeImBuf(seq->strip->ibuf_endstill);
2804 seq->strip->ibuf_endstill = 0;
2807 if(seq->type==SEQ_MOVIE)
2809 if(seq->type==SEQ_SPEED) {
2810 sequence_effect_speed_rebuild_map(seq, 1);
2817 void free_imbuf_seq_with_ipo(struct Ipo *ipo)
2819 /* force update of all sequences with this ipo, on ipo changes */
2820 Editing *ed= G.scene->ed;
2825 WHILE_SEQ(&ed->seqbase) {
2826 if(seq->ipo == ipo) {
2827 update_changed_seq_and_deps(seq, 0, 1);
2828 if(seq->type == SEQ_SPEED) {
2829 sequence_effect_speed_rebuild_map(seq, 1);
2836 static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
2839 int a, free_imbuf = 0;
2842 /* recurs downwards to see if this seq depends on the changed seq */
2847 if(seq == changed_seq)
2850 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
2851 if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
2855 if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
2857 if(seq->seq2 && (seq->seq2 != seq->seq1))
2858 if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
2860 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
2861 if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
2866 se= seq->strip->tstripdata;
2868 for(a=0; a<seq->len; a++, se++)
2869 free_imbuf_strip_elem(se);
2872 if(seq->type == SEQ_MOVIE)
2874 if(seq->type == SEQ_SPEED) {
2875 sequence_effect_speed_rebuild_map(seq, 1);
2886 void update_changed_seq_and_deps(Sequence *changed_seq, int len_change, int ibuf_change)
2888 Editing *ed= G.scene->ed;
2893 for (seq=ed->seqbase.first; seq; seq=seq->next)
2894 update_changed_seq_recurs(seq, changed_seq, len_change, ibuf_change);
2897 /* bad levell call... */
2898 void do_render_seq(RenderResult *rr, int cfra)
2902 G.f |= G_PLAYANIM; /* waitcursor patch */
2904 ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0);
2907 if(ibuf->rect_float) {
2909 rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
2911 memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty);
2913 /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
2914 can hang around when sequence render has rendered a 32 bits one before */
2916 MEM_freeN(rr->rect32);
2920 else if(ibuf->rect) {
2922 rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
2924 memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
2926 /* if (ibuf->zbuf) { */
2927 /* if (R.rectz) freeN(R.rectz); */
2928 /* R.rectz = BLI_dupallocN(ibuf->zbuf); */
2932 /* Let the cache limitor take care of this (schlaile) */
2933 /* While render let's keep all memory available for render
2935 At least if free memory is tight...
2936 This can make a big difference in encoding speed
2937 (it is around 4 times(!) faster, if we do not waste time
2938 on freeing _all_ buffers every time on long timelines...)
2942 extern int mem_in_use;
2943 extern int mmap_in_use;
2945 int max = MEM_CacheLimiter_get_maximum();
2946 if (max != 0 && mem_in_use + mmap_in_use > max) {
2947 fprintf(stderr, "mem_in_use = %d, max = %d\n",
2948 mem_in_use + mmap_in_use, max);
2949 fprintf(stderr, "Cleaning up, please wait...\n"
2950 "If this happens very often,\n"
2952 "raising the memcache limit in the "
2953 "user preferences.\n");
2959 /* render result is delivered empty in most cases, nevertheless we handle all cases */
2961 memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
2962 else if (rr->rect32)
2963 memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
2965 rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");