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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
24 * - Blender Foundation, 2003-2009
25 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
27 * ***** END GPL LICENSE BLOCK *****
35 #include "MEM_guardedalloc.h"
36 #include "MEM_CacheLimiterC-Api.h"
38 #include "DNA_listBase.h"
39 #include "DNA_sequence_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_anim_types.h"
43 #include "BKE_global.h"
44 #include "BKE_image.h"
46 #include "BKE_sequencer.h"
47 #include "BKE_fcurve.h"
48 #include "BKE_utildefines.h"
49 #include "RNA_access.h"
50 #include "RE_pipeline.h"
52 #include "BLI_fileops.h"
53 #include "BLI_listbase.h"
54 #include "BLI_path_util.h"
55 #include "BLI_string.h"
56 #include "BLI_threads.h"
59 #include "IMB_imbuf.h"
60 #include "IMB_imbuf_types.h"
64 #include "BKE_context.h"
65 #include "BKE_sound.h"
66 #include "AUD_C-API.h"
69 #define snprintf _snprintf
72 /* **** XXX ******** */
73 static int seqrectx= 0; /* bad bad global! */
74 static int seqrecty= 0;
75 //static void waitcursor(int val) {}
76 //static int blender_test_break() {return 0;}
78 /* **** XXX ******** */
80 ListBase seqbase_clipboard;
81 int seqbase_clipboard_frame;
83 void printf_strip(Sequence *seq)
85 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
86 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
87 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));
90 void seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
93 for(iseq= seqbase->first; iseq; iseq= iseq->next) {
94 seq_recursive_apply(iseq, apply_func, arg);
98 void seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
100 if(apply_func(seq, arg) && seq->seqbase.first)
101 seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
104 /* **********************************************************************
105 alloc / free functions
106 ********************************************************************** */
108 static void free_tstripdata(int len, TStripElem *se)
117 for(a=0; a<len; a++, se++) {
119 IMB_freeImBuf(se->ibuf);
123 IMB_freeImBuf(se->ibuf_comp);
132 void new_tstripdata(Sequence *seq)
135 free_tstripdata(seq->strip->len, seq->strip->tstripdata);
136 free_tstripdata(seq->strip->endstill,
137 seq->strip->tstripdata_endstill);
138 free_tstripdata(seq->strip->startstill,
139 seq->strip->tstripdata_startstill);
141 seq->strip->tstripdata= 0;
142 seq->strip->tstripdata_endstill= 0;
143 seq->strip->tstripdata_startstill= 0;
145 if(seq->strip->ibuf_startstill) {
146 IMB_freeImBuf(seq->strip->ibuf_startstill);
147 seq->strip->ibuf_startstill = 0;
150 if(seq->strip->ibuf_endstill) {
151 IMB_freeImBuf(seq->strip->ibuf_endstill);
152 seq->strip->ibuf_endstill = 0;
155 seq->strip->len= seq->len;
162 static void free_proxy_seq(Sequence *seq)
164 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
165 IMB_free_anim(seq->strip->proxy->anim);
166 seq->strip->proxy->anim = 0;
170 void seq_free_strip(Strip *strip)
173 if(strip->us>0) return;
175 printf("error: negative users in strip\n");
179 if (strip->stripdata) {
180 MEM_freeN(strip->stripdata);
184 if (strip->proxy->anim) {
185 IMB_free_anim(strip->proxy->anim);
188 MEM_freeN(strip->proxy);
191 MEM_freeN(strip->crop);
193 if (strip->transform) {
194 MEM_freeN(strip->transform);
196 if (strip->color_balance) {
197 MEM_freeN(strip->color_balance);
200 free_tstripdata(strip->len, strip->tstripdata);
201 free_tstripdata(strip->endstill, strip->tstripdata_endstill);
202 free_tstripdata(strip->startstill, strip->tstripdata_startstill);
204 if(strip->ibuf_startstill) {
205 IMB_freeImBuf(strip->ibuf_startstill);
206 strip->ibuf_startstill = 0;
209 if(strip->ibuf_endstill) {
210 IMB_freeImBuf(strip->ibuf_endstill);
211 strip->ibuf_endstill = 0;
217 void seq_free_sequence(Scene *scene, Sequence *seq)
219 if(seq->strip) seq_free_strip(seq->strip);
221 if(seq->anim) IMB_free_anim(seq->anim);
223 if (seq->type & SEQ_EFFECT) {
224 struct SeqEffectHandle sh = get_sequence_effect(seq);
229 /* clipboard has no scene and will never have a sound handle or be active */
231 Editing *ed = scene->ed;
233 if (ed->act_seq==seq)
237 sound_remove_scene_sound(scene, seq->scene_sound);
243 Editing *seq_give_editing(Scene *scene, int alloc)
245 if (scene->ed == NULL && alloc) {
248 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
249 ed->seqbasep= &ed->seqbase;
254 void seq_free_clipboard(void)
256 Sequence *seq, *nseq;
258 for(seq= seqbase_clipboard.first; seq; seq= nseq) {
260 seq_free_sequence(NULL, seq);
262 seqbase_clipboard.first= seqbase_clipboard.last= NULL;
265 void seq_free_editing(Scene *scene)
267 Editing *ed = scene->ed;
275 seq_free_sequence(scene, seq);
279 while((ms= ed->metastack.first)) {
280 BLI_remlink(&ed->metastack, ms);
287 /* ************************* itterator ************************** */
288 /* *************** (replaces old WHILE_SEQ) ********************* */
289 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
291 /* sequence strip iterator:
292 * - builds a full array, recursively into meta strips */
294 static void seq_count(ListBase *seqbase, int *tot)
298 for(seq=seqbase->first; seq; seq=seq->next) {
301 if(seq->seqbase.first)
302 seq_count(&seq->seqbase, tot);
306 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
310 for(seq=seqbase->first; seq; seq=seq->next) {
313 if(seq->seqbase.first)
314 seq_build_array(&seq->seqbase, array, depth+1);
321 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
332 seq_count(ed->seqbasep, tot);
334 seq_count(&ed->seqbase, tot);
339 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
341 seq_build_array(ed->seqbasep, &array, 0);
343 seq_build_array(&ed->seqbase, &array, 0);
346 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
348 memset(iter, 0, sizeof(*iter));
349 seq_array(ed, &iter->array, &iter->tot, use_pointer);
353 iter->seq= iter->array[iter->cur];
358 void seq_next(SeqIterator *iter)
360 if(++iter->cur < iter->tot)
361 iter->seq= iter->array[iter->cur];
366 void seq_end(SeqIterator *iter)
369 MEM_freeN(iter->array);
375 **********************************************************************
377 **********************************************************************
378 * Build a complete array of _all_ sequencies (including those
380 **********************************************************************
383 static void do_seq_count(ListBase *seqbase, int *totseq)
390 if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
395 static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
402 if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
409 void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
414 do_seq_count(seqbase, totseq);
420 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
423 do_build_seqar(seqbase, seqar, 0);
427 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
428 int (*test_func)(Sequence * seq))
434 int test = test_func(seq);
435 if (test & BUILD_SEQAR_COUNT_CURRENT) {
438 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
439 do_seq_count_cb(&seq->seqbase, totseq, test_func);
445 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
446 int (*test_func)(Sequence * seq))
452 int test = test_func(seq);
455 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
456 do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
459 if (test & BUILD_SEQAR_COUNT_CURRENT) {
467 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
468 int (*test_func)(Sequence * seq))
473 do_seq_count_cb(seqbase, totseq, test_func);
479 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
482 do_build_seqar_cb(seqbase, seqar, 0, test_func);
487 void calc_sequence_disp(Scene *scene, Sequence *seq)
489 if(seq->startofs && seq->startstill) seq->startstill= 0;
490 if(seq->endofs && seq->endstill) seq->endstill= 0;
492 seq->startdisp= seq->start + seq->startofs - seq->startstill;
493 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
495 seq->handsize= 10.0; /* 10 frames */
496 if( seq->enddisp-seq->startdisp < 10 ) {
497 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
499 else if(seq->enddisp-seq->startdisp > 250) {
500 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
503 seq_update_sound(scene, seq);
506 void calc_sequence(Scene *scene, Sequence *seq)
511 /* check all metas recursively */
512 seqm= seq->seqbase.first;
514 if(seqm->seqbase.first) calc_sequence(scene, seqm);
518 /* effects and meta: automatic start and end */
520 if(seq->type & SEQ_EFFECT) {
522 if(seq->seq2==0) seq->seq2= seq->seq1;
523 if(seq->seq3==0) seq->seq3= seq->seq1;
525 /* effecten go from seq1 -> seq2: test */
527 /* we take the largest start and smallest end */
529 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
530 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
533 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
534 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
535 seq->len= seq->enddisp - seq->startdisp;
537 calc_sequence_disp(scene, seq);
540 if(seq->strip && seq->len!=seq->strip->len) {
546 if(seq->type==SEQ_META) {
547 seqm= seq->seqbase.first;
552 if(seqm->startdisp < min) min= seqm->startdisp;
553 if(seqm->enddisp > max) max= seqm->enddisp;
556 seq->start= min + seq->anim_startofs;
558 seq->len -= seq->anim_startofs;
559 seq->len -= seq->anim_endofs;
561 if(seq->strip && seq->len!=seq->strip->len) {
566 calc_sequence_disp(scene, seq);
570 void reload_sequence_new_file(Scene *scene, Sequence * seq)
572 char str[FILE_MAXDIR+FILE_MAXFILE];
574 if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
575 seq->type == SEQ_SOUND ||
576 seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
582 if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
583 seq->type != SEQ_IMAGE) {
584 BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
585 BLI_convertstringcode(str, G.sce);
588 if (seq->type == SEQ_IMAGE) {
590 int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
592 seq->len -= seq->anim_startofs;
593 seq->len -= seq->anim_endofs;
597 seq->strip->len = seq->len;
598 } else if (seq->type == SEQ_MOVIE) {
599 if(seq->anim) IMB_free_anim(seq->anim);
600 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0));
606 seq->len = IMB_anim_get_duration(seq->anim);
608 seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
610 seq->len -= seq->anim_startofs;
611 seq->len -= seq->anim_endofs;
615 seq->strip->len = seq->len;
616 } else if (seq->type == SEQ_SOUND) {
617 seq->len = AUD_getInfo(seq->sound->playback_handle).length * FPS;
618 seq->len -= seq->anim_startofs;
619 seq->len -= seq->anim_endofs;
623 seq->strip->len = seq->len;
624 } else if (seq->type == SEQ_SCENE) {
625 Scene * sce = G.main->scene.first;
629 if(nr == seq->scenenr) {
642 BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
643 seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
645 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
646 seq->len -= seq->anim_startofs;
647 seq->len -= seq->anim_endofs;
651 seq->strip->len = seq->len;
656 calc_sequence(scene, seq);
659 void sort_seq(Scene *scene)
661 /* all strips together per kind, and in order of y location ("machine") */
662 ListBase seqbase, effbase;
663 Editing *ed= seq_give_editing(scene, FALSE);
664 Sequence *seq, *seqt;
669 seqbase.first= seqbase.last= 0;
670 effbase.first= effbase.last= 0;
672 while( (seq= ed->seqbasep->first) ) {
673 BLI_remlink(ed->seqbasep, seq);
675 if(seq->type & SEQ_EFFECT) {
678 if(seqt->machine>=seq->machine) {
679 BLI_insertlinkbefore(&effbase, seqt, seq);
684 if(seqt==0) BLI_addtail(&effbase, seq);
689 if(seqt->machine>=seq->machine) {
690 BLI_insertlinkbefore(&seqbase, seqt, seq);
695 if(seqt==0) BLI_addtail(&seqbase, seq);
699 addlisttolist(&seqbase, &effbase);
700 *(ed->seqbasep)= seqbase;
704 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
706 if(seq->scene==(Scene *)arg_pt)
711 void clear_scene_in_allseqs(Scene *scene)
715 /* when a scene is deleted: test all seqs */
716 for(scene_iter= G.main->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
717 if(scene_iter != scene && scene_iter->ed) {
718 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
723 typedef struct SeqUniqueInfo {
732 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
734 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
737 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
740 for(seq=seqbasep->first; seq; seq= seq->next) {
741 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
742 sprintf(sui->name_dest, "%.18s.%03d", sui->name_src, sui->count++);
743 sui->match= 1; /* be sure to re-scan */
748 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
750 if(seq->seqbase.first)
751 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
755 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
760 strcpy(sui.name_src, seq->name+2);
761 strcpy(sui.name_dest, seq->name+2);
763 /* Strip off the suffix */
764 if ((dot=strrchr(sui.name_src, '.')))
768 sui.match= 1; /* assume the worst to start the loop */
772 seqbase_unique_name(seqbasep, &sui);
773 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
776 strcpy(seq->name+2, sui.name_dest);
779 static char *give_seqname_by_type(int type)
782 case SEQ_META: return "Meta";
783 case SEQ_IMAGE: return "Image";
784 case SEQ_SCENE: return "Scene";
785 case SEQ_MOVIE: return "Movie";
786 case SEQ_SOUND: return "Audio";
787 case SEQ_CROSS: return "Cross";
788 case SEQ_GAMCROSS: return "Gamma Cross";
789 case SEQ_ADD: return "Add";
790 case SEQ_SUB: return "Sub";
791 case SEQ_MUL: return "Mul";
792 case SEQ_ALPHAOVER: return "Alpha Over";
793 case SEQ_ALPHAUNDER: return "Alpha Under";
794 case SEQ_OVERDROP: return "Over Drop";
795 case SEQ_WIPE: return "Wipe";
796 case SEQ_GLOW: return "Glow";
797 case SEQ_TRANSFORM: return "Transform";
798 case SEQ_COLOR: return "Color";
799 case SEQ_SPEED: return "Speed";
805 char *give_seqname(Sequence *seq)
807 char * name = give_seqname_by_type(seq->type);
810 if(seq->type<SEQ_EFFECT) {
811 return seq->strip->dir;
812 } else if(seq->type==SEQ_PLUGIN) {
813 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
814 seq->plugin && seq->plugin->doit) {
815 return seq->plugin->pname;
826 /* ***************** DO THE SEQUENCE ***************** */
828 static void make_black_ibuf(ImBuf *ibuf)
834 if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
836 tot= ibuf->x*ibuf->y;
839 rect_float = ibuf->rect_float;
842 memset(rect, 0, tot * sizeof(char) * 4);
846 memset(rect_float, 0, tot * sizeof(float) * 4);
850 static void multibuf(ImBuf *ibuf, float fmul)
857 mul= (int)(256.0*fmul);
858 rt= (char *)ibuf->rect;
859 rt_float = ibuf->rect_float;
865 icol= (mul*rt[0])>>8;
866 if(icol>254) rt[0]= 255; else rt[0]= icol;
867 icol= (mul*rt[1])>>8;
868 if(icol>254) rt[1]= 255; else rt[1]= icol;
869 icol= (mul*rt[2])>>8;
870 if(icol>254) rt[2]= 255; else rt[2]= icol;
871 icol= (mul*rt[3])>>8;
872 if(icol>254) rt[3]= 255; else rt[3]= icol;
890 static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
892 TStripElem *se1, *se2, *se3;
896 struct SeqEffectHandle sh = get_sequence_effect(seq);
899 if (!sh.execute) { /* effect not supported in this version... */
900 make_black_ibuf(se->ibuf);
904 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
905 sh.get_default_fac(seq, cfra, &fac, &facf);
906 if( scene->r.mode & R_FIELDS ); else facf= fac;
908 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
911 fac = facf = evaluate_fcurve(fcu, cfra);
912 if( scene->r.mode & R_FIELDS ) {
913 facf = evaluate_fcurve(fcu, cfra + 0.5);
916 fac = facf = seq->effect_fader;
920 early_out = sh.early_out(seq, fac, facf);
922 if (early_out == -1) { /* no input needed */
923 sh.execute(scene, seq, cfra, fac, facf,
924 se->ibuf->x, se->ibuf->y,
931 if (se->se1==0 || se->se2==0 || se->se3==0) {
932 make_black_ibuf(se->ibuf);
940 if ( (se1==0 || se2==0 || se3==0)
941 || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
942 make_black_ibuf(se->ibuf);
949 make_black_ibuf(se->ibuf);
955 if (se1 == 0 || se1->ibuf == 0) {
956 make_black_ibuf(se->ibuf);
960 if (se->ibuf != se1->ibuf) {
961 IMB_freeImBuf(se->ibuf);
962 se->ibuf = se1->ibuf;
963 IMB_refImBuf(se->ibuf);
968 make_black_ibuf(se->ibuf);
974 if (se2 == 0 || se2->ibuf == 0) {
975 make_black_ibuf(se->ibuf);
978 if (se->ibuf != se2->ibuf) {
979 IMB_freeImBuf(se->ibuf);
980 se->ibuf = se2->ibuf;
981 IMB_refImBuf(se->ibuf);
985 make_black_ibuf(se->ibuf);
992 if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
993 IMB_float_from_rect(se1->ibuf);
995 if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
996 IMB_float_from_rect(se2->ibuf);
998 if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
999 IMB_float_from_rect(se3->ibuf);
1002 if (!se1->ibuf->rect && !se->ibuf->rect_float) {
1003 IMB_rect_from_float(se1->ibuf);
1005 if (!se2->ibuf->rect && !se->ibuf->rect_float) {
1006 IMB_rect_from_float(se2->ibuf);
1008 if (!se3->ibuf->rect && !se->ibuf->rect_float) {
1009 IMB_rect_from_float(se3->ibuf);
1012 sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
1016 static int give_stripelem_index(Sequence *seq, int cfra)
1020 if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
1021 if(seq->len == 0) return -1;
1022 if(seq->flag&SEQ_REVERSE_FRAMES) {
1023 /*reverse frame in this sequence */
1024 if(cfra <= seq->start) nr= seq->len-1;
1025 else if(cfra >= seq->start+seq->len-1) nr= 0;
1026 else nr= (seq->start + seq->len) - cfra;
1028 if(cfra <= seq->start) nr= 0;
1029 else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
1030 else nr= cfra-seq->start;
1032 if (seq->strobe < 1.0) seq->strobe = 1.0;
1033 if (seq->strobe > 1.0) {
1034 nr -= (int)fmod((double)nr, (double)seq->strobe);
1040 static TStripElem* alloc_tstripdata(int len, const char * name)
1043 TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
1044 for (i = 0; i < len; i++) {
1045 se[i].ok = STRIPELEM_OK;
1050 static TStripElem *give_tstripelem(Sequence *seq, int cfra)
1055 se = seq->strip->tstripdata;
1056 if (se == 0 && seq->len > 0) {
1057 se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
1060 nr = give_stripelem_index(seq, cfra);
1062 if (nr == -1) return 0;
1063 if (se == 0) return 0;
1067 /* if there are IPOs with blend modes active, one has to watch out
1068 for startstill + endstill area: we can't use the same tstripelem
1069 here for all ibufs, since then, blending with IPOs won't work!
1071 Rather common case, if you use a single image and try to fade
1072 it in and out... or want to use your strip as a watermark in
1075 if (seq->blend_mode != SEQ_BLEND_REPLACE ||
1076 (/*seq->ipo && seq->ipo->curve.first &&*/
1077 (!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
1078 Strip * s = seq->strip;
1079 if (cfra < seq->start) {
1080 se = s->tstripdata_startstill;
1081 if (seq->startstill > s->startstill) {
1082 free_tstripdata(s->startstill,
1083 s->tstripdata_startstill);
1088 s->startstill = seq->startstill;
1089 se = seq->strip->tstripdata_startstill
1092 "tstripelems_startstill");
1094 se += seq->start - cfra - 1;
1096 } else if (cfra > seq->start + seq->len-1) {
1097 se = s->tstripdata_endstill;
1098 if (seq->endstill > s->endstill) {
1099 free_tstripdata(s->endstill,
1100 s->tstripdata_endstill);
1105 s->endstill = seq->endstill;
1106 se = seq->strip->tstripdata_endstill
1109 "tstripelems_endstill");
1111 se += cfra - (seq->start + seq->len-1) - 1;
1121 StripElem *give_stripelem(Sequence *seq, int cfra)
1123 StripElem *se= seq->strip->stripdata;
1125 if(seq->type == SEQ_MOVIE) {
1129 int nr = give_stripelem_index(seq, cfra);
1131 if (nr == -1) return 0;
1132 if (se == 0) return 0;
1134 se += nr + seq->anim_startofs;
1139 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
1144 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
1146 seq= seqbase->first;
1148 if(seq->startdisp <=cfra && seq->enddisp > cfra) {
1149 seq_arr[seq->machine]= seq;
1158 int evaluate_seq_frame(Scene *scene, int cfra)
1160 Editing *ed= seq_give_editing(scene, FALSE);
1161 Sequence *seq_arr[MAXSEQ+1];
1163 if(ed==NULL) return 0;
1164 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
1167 static int video_seq_is_rendered(Sequence * seq)
1170 && !(seq->flag & SEQ_MUTE)
1171 && seq->type != SEQ_SOUND);
1174 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
1176 Sequence *seq_arr[MAXSEQ+1];
1184 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
1186 if (seq_arr[b] == 0) {
1190 for (b = MAXSEQ; b > 0; b--) {
1191 if (video_seq_is_rendered(seq_arr[b])) {
1201 if (video_seq_is_rendered(seq_arr[b])) {
1202 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
1208 for (;b <= chanshown; b++) {
1209 if (video_seq_is_rendered(seq_arr[b])) {
1210 seq_arr_out[cnt++] = seq_arr[b];
1218 /* **********************************************************************
1220 ********************************************************************** */
1222 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
1224 static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * name, int render_size)
1227 char dir[FILE_MAXDIR];
1229 if (!seq->strip->proxy) {
1233 if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
1234 strcpy(dir, seq->strip->proxy->dir);
1236 if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
1237 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
1244 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1245 BLI_join_dirfile(name, dir, seq->strip->proxy->file);
1246 BLI_convertstringcode(name, G.sce);
1251 /* generate a separate proxy directory for each preview size */
1253 if (seq->type == SEQ_IMAGE) {
1254 StripElem * se = give_stripelem(seq, cfra);
1255 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
1256 dir, render_size, se->name);
1258 } else if (seq->type == SEQ_MOVIE) {
1259 TStripElem * tse = give_tstripelem(seq, cfra);
1261 frameno = tse->nr + seq->anim_startofs;
1263 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
1264 seq->strip->stripdata->name,
1267 TStripElem * tse = give_tstripelem(seq, cfra);
1269 frameno = tse->nr + seq->anim_startofs;
1271 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
1275 BLI_convertstringcode(name, G.sce);
1276 BLI_convertstringframe(name, frameno, 0);
1279 strcat(name, ".jpg");
1284 static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, int render_size)
1286 char name[PROXY_MAXFILE];
1288 if (!(seq->flag & SEQ_USE_PROXY)) {
1292 /* rendering at 100% ? No real sense in proxy-ing, right? */
1293 if (render_size == 100) {
1297 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1298 TStripElem * tse = give_tstripelem(seq, cfra);
1299 int frameno = tse->nr + seq->anim_startofs;
1300 if (!seq->strip->proxy->anim) {
1301 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1305 seq->strip->proxy->anim = openanim(name, IB_rect);
1307 if (!seq->strip->proxy->anim) {
1311 return IMB_anim_absolute(seq->strip->proxy->anim, frameno);
1314 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1318 if (BLI_exists(name)) {
1319 return IMB_loadiffname(name, IB_rect);
1326 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1327 int build_proxy_run, int render_size);
1329 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
1331 char name[PROXY_MAXFILE];
1336 struct ImBuf * ibuf;
1338 if (!(seq->flag & SEQ_USE_PROXY)) {
1342 /* rendering at 100% ? No real sense in proxy-ing, right? */
1343 if (render_size == 100) {
1347 /* that's why it is called custom... */
1348 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
1352 if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
1356 se = give_tstripelem(seq, cfra);
1362 IMB_freeImBuf(se->ibuf);
1366 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
1372 rectx= (render_size*scene->r.xsch)/100;
1373 recty= (render_size*scene->r.ysch)/100;
1377 if (ibuf->x != rectx || ibuf->y != recty) {
1378 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
1381 /* quality is fixed, otherwise one has to generate separate
1382 directories for every quality...
1384 depth = 32 is intentionally left in, otherwise ALPHA channels
1386 quality = seq->strip->proxy->quality;
1387 ibuf->ftype= JPG | quality;
1389 BLI_make_existing_file(name);
1391 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
1396 IMB_freeImBuf(ibuf);
1400 static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
1403 float rsize = seq->strip->proxy->size;
1409 /* flag management tries to account for strobe and
1410 other "non-linearities", that might come in the future...
1411 better way would be to "touch" the files, so that _really_
1412 no one is rebuild twice.
1415 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
1416 TStripElem * tse = give_tstripelem(seq, cfra);
1418 tse->flag &= ~STRIPELEM_PREVIEW_DONE;
1423 /* a _lot_ faster for movie files, if we read frames in
1425 if (seq->flag & SEQ_REVERSE_FRAMES) {
1426 for (cfra = seq->enddisp-seq->endstill-1;
1427 cfra >= seq->startdisp + seq->startstill; cfra--) {
1428 TStripElem * tse = give_tstripelem(seq, cfra);
1430 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1431 //XXX set_timecursor(cfra);
1432 seq_proxy_build_frame(scene, seq, cfra, rsize);
1433 tse->flag |= STRIPELEM_PREVIEW_DONE;
1435 if (blender_test_break()) {
1440 for (cfra = seq->startdisp + seq->startstill;
1441 cfra < seq->enddisp - seq->endstill; cfra++) {
1442 TStripElem * tse = give_tstripelem(seq, cfra);
1444 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
1445 //XXX set_timecursor(cfra);
1446 seq_proxy_build_frame(scene, seq, cfra, rsize);
1447 tse->flag |= STRIPELEM_PREVIEW_DONE;
1449 if (blender_test_break()) {
1459 /* **********************************************************************
1461 ********************************************************************** */
1463 static StripColorBalance calc_cb(StripColorBalance * cb_)
1465 StripColorBalance cb = *cb_;
1468 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
1469 for (c = 0; c < 3; c++) {
1470 cb.lift[c] = 1.0 - cb.lift[c];
1473 for (c = 0; c < 3; c++) {
1474 cb.lift[c] = -(1.0 - cb.lift[c]);
1477 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
1478 for (c = 0; c < 3; c++) {
1479 if (cb.gain[c] != 0.0) {
1480 cb.gain[c] = 1.0/cb.gain[c];
1482 cb.gain[c] = 1000000; /* should be enough :) */
1487 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
1488 for (c = 0; c < 3; c++) {
1489 if (cb.gamma[c] != 0.0) {
1490 cb.gamma[c] = 1.0/cb.gamma[c];
1492 cb.gamma[c] = 1000000; /* should be enough :) */
1500 static void make_cb_table_byte(float lift, float gain, float gamma,
1501 unsigned char * table, float mul)
1505 for (y = 0; y < 256; y++) {
1506 float v = 1.0 * y / 255;
1513 } else if (v < 0.0) {
1521 static void make_cb_table_float(float lift, float gain, float gamma,
1522 float * table, float mul)
1526 for (y = 0; y < 256; y++) {
1527 float v = (float) y * 1.0 / 255.0;
1536 static void color_balance_byte_byte(Sequence * seq, TStripElem* se, float mul)
1538 unsigned char cb_tab[3][256];
1540 unsigned char * p = (unsigned char*) se->ibuf->rect;
1541 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1543 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1545 for (c = 0; c < 3; c++) {
1546 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
1551 p[0] = cb_tab[0][p[0]];
1552 p[1] = cb_tab[1][p[1]];
1553 p[2] = cb_tab[2][p[2]];
1559 static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
1561 float cb_tab[4][256];
1563 unsigned char * p = (unsigned char*) se->ibuf->rect;
1564 unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
1566 StripColorBalance cb;
1568 imb_addrectfloatImBuf(se->ibuf);
1570 o = se->ibuf->rect_float;
1572 cb = calc_cb(seq->strip->color_balance);
1574 for (c = 0; c < 3; c++) {
1575 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
1579 for (i = 0; i < 256; i++) {
1580 cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
1584 o[0] = cb_tab[0][p[0]];
1585 o[1] = cb_tab[1][p[1]];
1586 o[2] = cb_tab[2][p[2]];
1587 o[3] = cb_tab[3][p[3]];
1593 static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
1595 float * p = se->ibuf->rect_float;
1596 float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
1597 StripColorBalance cb = calc_cb(seq->strip->color_balance);
1601 for (c = 0; c < 3; c++) {
1602 p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
1609 static void color_balance(Sequence * seq, TStripElem* se, float mul)
1611 if (se->ibuf->rect_float) {
1612 color_balance_float_float(seq, se, mul);
1613 } else if(seq->flag & SEQ_MAKE_FLOAT) {
1614 color_balance_byte_float(seq, se, mul);
1616 color_balance_byte_byte(seq, se, mul);
1621 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
1623 Do all the things you can't really do afterwards using sequence effects
1624 (read: before rescaling to render resolution has been done)
1629 - Crop and transform in image source coordinate space
1630 - Flip X + Flip Y (could be done afterwards, backward compatibility)
1631 - Promote image to float data (affects pipeline operations afterwards)
1632 - Color balance (is most efficient in the byte -> float
1633 (future: half -> float should also work fine!)
1634 case, if done on load, since we can use lookup tables)
1639 static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
1643 if ((seq->flag & SEQ_FILTERY) ||
1644 (seq->flag & SEQ_USE_CROP) ||
1645 (seq->flag & SEQ_USE_TRANSFORM) ||
1646 (seq->flag & SEQ_FLIPX) ||
1647 (seq->flag & SEQ_FLIPY) ||
1648 (seq->flag & SEQ_USE_COLOR_BALANCE) ||
1649 (seq->flag & SEQ_MAKE_PREMUL) ||
1650 (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
1656 if(seq->blend_mode == SEQ_BLEND_REPLACE &&
1657 !(seq->type & SEQ_EFFECT)) {
1658 mul *= seq->blend_opacity / 100.0;
1668 static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
1672 seq->strip->orx= se->ibuf->x;
1673 seq->strip->ory= se->ibuf->y;
1675 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
1676 IMB_filtery(se->ibuf);
1679 if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
1684 memset(&c, 0, sizeof(StripCrop));
1685 memset(&t, 0, sizeof(StripTransform));
1687 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
1688 c = *seq->strip->crop;
1690 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
1691 t = *seq->strip->transform;
1694 sx = se->ibuf->x - c.left - c.right;
1695 sy = se->ibuf->y - c.top - c.bottom;
1699 if (seq->flag & SEQ_USE_TRANSFORM) {
1704 if (c.top + c.bottom >= se->ibuf->y ||
1705 c.left + c.right >= se->ibuf->x ||
1706 t.xofs >= dx || t.yofs >= dy) {
1707 make_black_ibuf(se->ibuf);
1711 if (se->ibuf->rect_float) {
1712 i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
1714 i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
1717 IMB_rectcpy(i, se->ibuf,
1722 IMB_freeImBuf(se->ibuf);
1728 if(seq->flag & SEQ_FLIPX) {
1729 IMB_flipx(se->ibuf);
1731 if(seq->flag & SEQ_FLIPY) {
1732 IMB_flipy(se->ibuf);
1735 if(seq->mul == 0.0) {
1741 if(seq->blend_mode == SEQ_BLEND_REPLACE) {
1742 mul *= seq->blend_opacity / 100.0;
1745 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
1746 color_balance(seq, se, mul);
1750 if(seq->flag & SEQ_MAKE_FLOAT) {
1751 if (!se->ibuf->rect_float) {
1752 if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
1753 IMB_float_from_rect(se->ibuf);
1755 int profile = IB_PROFILE_NONE;
1757 /* no color management:
1758 * don't disturb the existing profiles */
1759 SWAP(int, se->ibuf->profile, profile);
1761 IMB_float_from_rect(se->ibuf);
1763 SWAP(int, se->ibuf->profile, profile);
1766 if (se->ibuf->rect) {
1767 imb_freerectImBuf(se->ibuf);
1772 multibuf(se->ibuf, mul);
1775 if(seq->flag & SEQ_MAKE_PREMUL) {
1776 if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
1777 converttopremul(se->ibuf);
1782 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
1783 if(scene->r.mode & R_OSA) {
1784 IMB_scaleImBuf(se->ibuf,
1785 (short)seqrectx, (short)seqrecty);
1787 IMB_scalefastImBuf(se->ibuf,
1788 (short)seqrectx, (short)seqrecty);
1793 /* test if image too small or discarded from cache: reload */
1795 static void test_and_auto_discard_ibuf(TStripElem * se)
1798 if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
1799 || !(se->ibuf->rect || se->ibuf->rect_float)) {
1800 IMB_freeImBuf(se->ibuf);
1803 se->ok= STRIPELEM_OK;
1806 if (se->ibuf_comp) {
1807 if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
1808 || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
1809 IMB_freeImBuf(se->ibuf_comp);
1816 static void test_and_auto_discard_ibuf_stills(Strip * strip)
1818 if (strip->ibuf_startstill) {
1819 if (!strip->ibuf_startstill->rect &&
1820 !strip->ibuf_startstill->rect_float) {
1821 IMB_freeImBuf(strip->ibuf_startstill);
1822 strip->ibuf_startstill = 0;
1825 if (strip->ibuf_endstill) {
1826 if (!strip->ibuf_endstill->rect &&
1827 !strip->ibuf_endstill->rect_float) {
1828 IMB_freeImBuf(strip->ibuf_endstill);
1829 strip->ibuf_endstill = 0;
1834 static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
1837 if (se->nr == 0 && seq->strip->ibuf_startstill) {
1838 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1840 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
1842 if (se->nr == seq->len - 1
1844 && seq->strip->ibuf_endstill) {
1845 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1847 se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
1852 static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
1856 seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
1858 IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
1859 IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
1861 if (se->nr == seq->len - 1 && seq->len != 1) {
1862 seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
1864 IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
1865 IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
1870 static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
1872 Sequence* seq_arr[MAXSEQ+1];
1876 evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
1878 for (i = 0; i < MAXSEQ; i++) {
1879 if (!video_seq_is_rendered(seq_arr[i])) {
1882 se = give_tstripelem(seq_arr[i], cfra);
1885 IMB_freeImBuf(se->ibuf);
1888 se->ok= STRIPELEM_OK;
1891 if (se->ibuf_comp) {
1892 IMB_freeImBuf(se->ibuf_comp);
1901 static void check_limiter_refcount(const char * func, TStripElem *se)
1903 if (se && se->ibuf) {
1904 int refcount = IMB_cache_limiter_get_refcount(se->ibuf);
1905 if (refcount != 1) {
1906 /* can happen on complex pipelines */
1907 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1912 "sequencer: (ibuf) %s: "
1913 "suspicious memcache "
1914 "limiter refcount: %d\n", func, refcount);
1919 static void check_limiter_refcount_comp(const char * func, TStripElem *se)
1921 if (se && se->ibuf_comp) {
1922 int refcount = IMB_cache_limiter_get_refcount(se->ibuf_comp);
1923 if (refcount != 1) {
1924 /* can happen on complex pipelines */
1925 if (refcount > 1 && (G.f & G_DEBUG) == 0) {
1929 "sequencer: (ibuf comp) %s: "
1930 "suspicious memcache "
1931 "limiter refcount: %d\n", func, refcount);
1936 static TStripElem* do_build_seq_array_recursively(Scene *scene,
1937 ListBase *seqbasep, int cfra, int chanshown, int render_size);
1939 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
1940 int build_proxy_run, int render_size)
1942 char name[FILE_MAXDIR+FILE_MAXFILE];
1943 int use_limiter = TRUE;
1945 test_and_auto_discard_ibuf(se);
1946 test_and_auto_discard_ibuf_stills(seq->strip);
1948 if(seq->type == SEQ_META) {
1949 TStripElem * meta_se = 0;
1950 int use_preprocess = FALSE;
1951 use_limiter = FALSE;
1953 if (!build_proxy_run && se->ibuf == 0) {
1954 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
1957 use_preprocess = TRUE;
1961 if(!se->ibuf && seq->seqbase.first) {
1962 meta_se = do_build_seq_array_recursively(scene,
1963 &seq->seqbase, seq->start + se->nr, 0,
1966 check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
1969 se->ok = STRIPELEM_OK;
1971 if(!se->ibuf && meta_se) {
1972 se->ibuf = meta_se->ibuf_comp;
1974 (!input_have_to_preprocess(scene, seq, se, cfra) ||
1976 IMB_refImBuf(se->ibuf);
1977 if (build_proxy_run) {
1978 IMB_cache_limiter_unref(se->ibuf);
1980 } else if (se->ibuf) {
1981 struct ImBuf * i = IMB_dupImBuf(se->ibuf);
1983 IMB_cache_limiter_unref(se->ibuf);
1988 use_preprocess = TRUE;
1990 } else if (se->ibuf) {
1994 free_metastrip_imbufs(
1995 &seq->seqbase, seq->start + se->nr, 0);
1998 if (use_preprocess) {
1999 input_preprocess(scene, seq, se, cfra);
2001 } else if(seq->type & SEQ_EFFECT) {
2002 int use_preprocess = FALSE;
2003 /* should the effect be recalculated? */
2005 if (!build_proxy_run && se->ibuf == 0) {
2006 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2008 use_preprocess = TRUE;
2013 /* if any inputs are rectfloat, output is float too */
2014 if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
2015 (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
2016 (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
2017 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2019 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2021 do_effect(scene, cfra, seq, se);
2022 if (input_have_to_preprocess(scene, seq, se, cfra) &&
2024 if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
2025 (se->se2 && (se->ibuf == se->se2->ibuf))) {
2027 = IMB_dupImBuf(se->ibuf);
2029 IMB_freeImBuf(se->ibuf);
2033 use_preprocess = TRUE;
2036 if (use_preprocess) {
2037 input_preprocess(scene, seq, se, cfra);
2039 } else if(seq->type == SEQ_IMAGE) {
2040 if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
2041 StripElem * s_elem = give_stripelem(seq, cfra);
2042 BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
2043 BLI_convertstringcode(name, G.sce);
2044 if (!build_proxy_run) {
2045 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2047 copy_from_ibuf_still(seq, se);
2050 se->ibuf= IMB_loadiffname(
2052 /* we don't need both (speed reasons)! */
2054 se->ibuf->rect_float && se->ibuf->rect) {
2055 imb_freerectImBuf(se->ibuf);
2058 copy_to_ibuf_still(seq, se);
2062 se->ok = STRIPELEM_FAILED;
2063 } else if (!build_proxy_run) {
2064 input_preprocess(scene, seq, se, cfra);
2067 } else if(seq->type == SEQ_MOVIE) {
2068 if(se->ok == STRIPELEM_OK && se->ibuf==0) {
2069 if(!build_proxy_run) {
2070 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2072 copy_from_ibuf_still(seq, se);
2074 if (se->ibuf == 0) {
2076 BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
2077 BLI_convertstringcode(name, G.sce);
2079 seq->anim = openanim(
2081 ((seq->flag & SEQ_FILTERY)
2082 ? IB_animdeinterlace : 0));
2085 IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
2086 se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
2087 /* we don't need both (speed reasons)! */
2089 && se->ibuf->rect_float
2090 && se->ibuf->rect) {
2091 imb_freerectImBuf(se->ibuf);
2095 copy_to_ibuf_still(seq, se);
2099 se->ok = STRIPELEM_FAILED;
2100 } else if (!build_proxy_run) {
2101 input_preprocess(scene, seq, se, cfra);
2104 } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
2105 Scene *sce= seq->scene;// *oldsce= scene;
2108 int have_seq= FALSE;
2109 int sce_valid= FALSE;
2112 have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
2113 sce_valid= (sce->camera || have_seq);
2116 if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
2117 se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
2119 input_preprocess(scene, seq, se, cfra);
2123 if (se->ibuf == NULL && sce_valid) {
2124 copy_from_ibuf_still(seq, se);
2126 input_preprocess(scene, seq, se, cfra);
2131 se->ok = STRIPELEM_FAILED;
2132 } else if (se->ibuf==NULL && sce_valid) {
2134 /* Hack! This function can be called from do_render_seq(), in that case
2135 the seq->scene can already have a Render initialized with same name,
2136 so we have to use a default name. (compositor uses scene name to
2138 However, when called from within the UI (image preview in sequencer)
2139 we do want to use scene Render, that way the render result is defined
2140 for display in render/imagewindow
2142 Hmm, don't see, why we can't do that all the time,
2143 and since G.rendering is uhm, gone... (Peter)
2149 oldcfra = seq->scene->r.cfra;
2152 re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
2154 re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
2156 /* prevent eternal loop */
2157 doseq= scene->r.scemode & R_DOSEQ;
2158 scene->r.scemode &= ~R_DOSEQ;
2160 RE_BlenderFrame(re, sce, NULL,
2161 seq->sfra+se->nr+seq->anim_startofs);
2163 RE_AcquireResultImage(re, &rres);
2166 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
2167 memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
2169 addzbuffloatImBuf(se->ibuf);
2170 memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
2172 } else if (rres.rect32) {
2173 se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
2174 memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
2177 RE_ReleaseResultImage(re);
2179 // BIF_end_render_callbacks();
2182 scene->r.scemode |= doseq;
2184 seq->scene->r.cfra = oldcfra;
2186 copy_to_ibuf_still(seq, se);
2188 if (!build_proxy_run) {
2189 if(se->ibuf == NULL) {
2190 se->ok = STRIPELEM_FAILED;
2192 input_preprocess(scene, seq, se, cfra);
2198 if (!build_proxy_run) {
2199 if (se->ibuf && use_limiter) {
2200 IMB_cache_limiter_insert(se->ibuf);
2201 IMB_cache_limiter_ref(se->ibuf);
2202 IMB_cache_limiter_touch(se->ibuf);
2207 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
2209 static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
2212 struct SeqEffectHandle sh = get_sequence_effect(seq);
2220 if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) {
2221 sh.get_default_fac(seq, cfra, &fac, &facf);
2222 if( scene->r.mode & R_FIELDS ); else facf= fac;
2224 fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence,
2227 fac = facf = evaluate_fcurve(fcu, cfra);
2228 if( scene->r.mode & R_FIELDS ) {
2229 facf = evaluate_fcurve(fcu, cfra + 0.5);
2232 fac = facf = seq->effect_fader;
2236 early_out = sh.early_out(seq, fac, facf);
2237 switch (early_out) {
2239 /* no input needed */
2242 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2243 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2245 se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
2249 se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
2252 se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
2257 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2259 /* children are not needed anymore ... */
2261 if (se->se1 && se->se1->ibuf) {
2262 IMB_cache_limiter_unref(se->se1->ibuf);
2264 if (se->se2 && se->se2->ibuf) {
2265 IMB_cache_limiter_unref(se->se2->ibuf);
2267 if (se->se3 && se->se3->ibuf) {
2268 IMB_cache_limiter_unref(se->se3->ibuf);
2270 check_limiter_refcount("do_effect_seq_recursively", se);
2273 static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
2277 se = give_tstripelem(seq, cfra);
2280 if (seq->type & SEQ_EFFECT) {
2281 do_effect_seq_recursively(scene, seq, se, cfra, render_size);
2283 do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
2291 If cfra was float throughout blender (especially in the render
2292 pipeline) one could even _render_ with subframe precision
2293 instead of faking using the blend code below...
2297 static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
2299 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
2300 int nr = cfra - seq->start;
2304 TStripElem * se = 0;
2305 TStripElem * se1 = 0;
2306 TStripElem * se2 = 0;
2308 sequence_effect_speed_rebuild_map(scene, seq, 0);
2310 f_cfra = seq->start + s->frameMap[nr];
2312 cfra_left = (int) floor(f_cfra);
2313 cfra_right = (int) ceil(f_cfra);
2315 se = give_tstripelem(seq, cfra);
2321 if (cfra_left == cfra_right ||
2322 (s->flags & SEQ_SPEED_BLEND) == 0) {
2323 test_and_auto_discard_ibuf(se);
2325 if (se->ibuf == NULL) {
2326 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2328 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2329 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2331 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2333 if (se1 == 0 || se1->ibuf == 0) {
2334 make_black_ibuf(se->ibuf);
2336 if (se->ibuf != se1->ibuf) {
2338 IMB_freeImBuf(se->ibuf);
2341 se->ibuf = se1->ibuf;
2342 IMB_refImBuf(se->ibuf);
2347 struct SeqEffectHandle sh;
2350 if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
2351 || !(se->ibuf->rect || se->ibuf->rect_float)) {
2352 IMB_freeImBuf(se->ibuf);
2357 if (se->ibuf == NULL) {
2358 se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
2359 se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
2361 if((se1 && se1->ibuf && se1->ibuf->rect_float))
2362 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
2364 se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
2367 make_black_ibuf(se->ibuf);
2369 sh = get_sequence_effect(seq);
2371 sh.execute(scene, seq, cfra,
2372 f_cfra - (float) cfra_left,
2373 f_cfra - (float) cfra_left,
2374 se->ibuf->x, se->ibuf->y,
2375 se1->ibuf, se2->ibuf, 0, se->ibuf);
2381 /* caller expects this to be referenced, so do it! */
2383 IMB_cache_limiter_insert(se->ibuf);
2384 IMB_cache_limiter_ref(se->ibuf);
2385 IMB_cache_limiter_touch(se->ibuf);
2388 /* children are no longer needed */
2389 if (se1 && se1->ibuf)
2390 IMB_cache_limiter_unref(se1->ibuf);
2391 if (se2 && se2->ibuf)
2392 IMB_cache_limiter_unref(se2->ibuf);
2394 check_limiter_refcount("do_handle_speed_effect", se);
2400 * build all ibufs recursively
2402 * if successfull, the returned TStripElem contains the (referenced!) imbuf
2403 * that means: you _must_ call
2405 * IMB_cache_limiter_unref(rval);
2411 static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
2414 if (seq->type == SEQ_SPEED) {
2415 se = do_handle_speed_effect(scene, seq, cfra, render_size);
2417 se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
2420 check_limiter_refcount("do_build_seq_recursively", se);
2425 static TStripElem* do_build_seq_array_recursively(Scene *scene,
2426 ListBase *seqbasep, int cfra, int chanshown, int render_size)
2428 Sequence* seq_arr[MAXSEQ+1];
2433 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
2439 se = give_tstripelem(seq_arr[count - 1], cfra);
2445 test_and_auto_discard_ibuf(se);
2447 if (se->ibuf_comp != 0) {
2448 IMB_cache_limiter_insert(se->ibuf_comp);
2449 IMB_cache_limiter_ref(se->ibuf_comp);
2450 IMB_cache_limiter_touch(se->ibuf_comp);
2456 se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
2458 se->ibuf_comp = se->ibuf;
2459 IMB_refImBuf(se->ibuf_comp);
2465 for (i = count - 1; i >= 0; i--) {
2467 Sequence * seq = seq_arr[i];
2468 struct SeqEffectHandle sh;
2471 se = give_tstripelem(seq, cfra);
2473 test_and_auto_discard_ibuf(se);
2475 if (se->ibuf_comp != 0) {
2478 if (seq->blend_mode == SEQ_BLEND_REPLACE) {
2479 do_build_seq_recursively(scene, seq, cfra, render_size);
2481 se->ibuf_comp = se->ibuf;
2482 IMB_refImBuf(se->ibuf);
2484 se->ibuf_comp = IMB_allocImBuf(
2485 (short)seqrectx, (short)seqrecty,
2487 IMB_cache_limiter_insert(se->ibuf_comp);
2488 IMB_cache_limiter_ref(se->ibuf_comp);
2489 IMB_cache_limiter_touch(se->ibuf_comp);
2494 sh = get_sequence_blend(seq);
2496 facf = seq->blend_opacity / 100.0;
2498 early_out = sh.early_out(seq, facf, facf);
2500 switch (early_out) {
2503 do_build_seq_recursively(scene, seq, cfra, render_size);
2505 se->ibuf_comp = se->ibuf;
2506 IMB_refImBuf(se->ibuf_comp);
2508 se->ibuf_comp = IMB_allocImBuf(
2509 (short)seqrectx, (short)seqrecty,
2511 IMB_cache_limiter_insert(se->ibuf_comp);
2512 IMB_cache_limiter_ref(se->ibuf_comp);
2513 IMB_cache_limiter_touch(se->ibuf_comp);
2518 se->ibuf_comp = IMB_allocImBuf(
2519 (short)seqrectx, (short)seqrecty,
2521 IMB_cache_limiter_insert(se->ibuf_comp);
2522 IMB_cache_limiter_ref(se->ibuf_comp);
2523 IMB_cache_limiter_touch(se->ibuf_comp);
2527 do_build_seq_recursively(scene, seq, cfra, render_size);
2529 se->ibuf = IMB_allocImBuf(
2530 (short)seqrectx, (short)seqrecty,
2532 IMB_cache_limiter_insert(se->ibuf);
2533 IMB_cache_limiter_ref(se->ibuf);
2534 IMB_cache_limiter_touch(se->ibuf);
2537 se->ibuf_comp = se->ibuf;
2538 IMB_refImBuf(se->ibuf_comp);
2543 if (se->ibuf_comp) {
2550 for (; i < count; i++) {
2551 Sequence * seq = seq_arr[i];
2552 struct SeqEffectHandle sh = get_sequence_blend(seq);
2553 TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
2554 TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
2556 float facf = seq->blend_opacity / 100.0;
2558 int early_out = sh.early_out(seq, facf, facf);
2560 switch (early_out) {
2562 int x= se2->ibuf->x;
2563 int y= se2->ibuf->y;
2564 int swap_input = FALSE;
2566 if(se1->ibuf_comp == NULL)
2569 if (se1->ibuf_comp->rect_float ||
2570 se2->ibuf->rect_float) {
2571 se2->ibuf_comp = IMB_allocImBuf(
2572 (short)seqrectx, (short)seqrecty,
2573 32, IB_rectfloat, 0);
2575 se2->ibuf_comp = IMB_allocImBuf(
2576 (short)seqrectx, (short)seqrecty,
2581 if (!se1->ibuf_comp->rect_float &&
2582 se2->ibuf_comp->rect_float) {
2583 IMB_float_from_rect(se1->ibuf_comp);
2585 if (!se2->ibuf->rect_float &&
2586 se2->ibuf_comp->rect_float) {
2587 IMB_float_from_rect(se2->ibuf);
2590 if (!se1->ibuf_comp->rect &&
2591 !se2->ibuf_comp->rect_float) {
2592 IMB_rect_from_float(se1->ibuf_comp);
2594 if (!se2->ibuf->rect &&
2595 !se2->ibuf_comp->rect_float) {
2596 IMB_rect_from_float(se2->ibuf);
2599 /* bad hack, to fix crazy input ordering of
2600 those two effects */
2602 if (seq->blend_mode == SEQ_ALPHAOVER ||
2603 seq->blend_mode == SEQ_ALPHAUNDER ||
2604 seq->blend_mode == SEQ_OVERDROP) {
2609 sh.execute(scene, seq, cfra,
2611 se2->ibuf, se1->ibuf_comp, 0,
2614 sh.execute(scene, seq, cfra,
2616 se1->ibuf_comp, se2->ibuf, 0,
2620 IMB_cache_limiter_insert(se2->ibuf_comp);
2621 IMB_cache_limiter_ref(se2->ibuf_comp);
2622 IMB_cache_limiter_touch(se2->ibuf_comp);
2624 IMB_cache_limiter_unref(se1->ibuf_comp);
2625 IMB_cache_limiter_unref(se2->ibuf);
2630 se2->ibuf_comp = se1->ibuf;
2632 IMB_refImBuf(se2->ibuf_comp);
2644 * returned ImBuf is refed!
2645 * you have to unref after usage!
2648 static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2650 Editing *ed= seq_give_editing(scene, FALSE);
2656 if(ed==NULL) return NULL;
2658 count = BLI_countlist(&ed->metastack);
2659 if((chanshown < 0) && (count > 0)) {
2660 count = MAX2(count + chanshown, 0);
2661 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
2663 seqbasep= ed->seqbasep;
2666 seqrectx= rectx; /* bad bad global! */
2669 se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
2675 check_limiter_refcount_comp("give_ibuf_seq_impl", se);
2677 return se->ibuf_comp;
2680 ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
2684 seqrectx= rectx; /* bad bad global! */
2687 se = do_build_seq_recursively(scene, seq, cfra, render_size);
2693 check_limiter_refcount("give_ibuf_seq_direct", se);
2696 IMB_cache_limiter_unref(se->ibuf);
2702 ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2704 ImBuf* i = give_ibuf_seq_impl(scene, rectx, recty, cfra, chanshown, render_size);
2707 IMB_cache_limiter_unref(i);
2713 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
2714 static int seq_can_blend(Sequence *seq)
2716 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
2724 /* *********************** threading api ******************* */
2726 static ListBase running_threads;
2727 static ListBase prefetch_wait;
2728 static ListBase prefetch_done;
2730 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
2731 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
2732 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
2734 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
2735 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
2737 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
2738 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
2740 static volatile int seq_thread_shutdown = FALSE;
2741 static volatile int seq_last_given_monoton_cfra = 0;
2742 static int monoton_cfra = 0;
2744 typedef struct PrefetchThread {
2745 struct PrefetchThread *next, *prev;
2748 struct PrefetchQueueElem *current;
2754 typedef struct PrefetchQueueElem {
2755 struct PrefetchQueueElem *next, *prev;
2765 struct ImBuf * ibuf;
2766 } PrefetchQueueElem;
2769 static void *seq_prefetch_thread(void * This_)
2771 PrefetchThread * This = This_;
2773 while (!seq_thread_shutdown) {
2774 PrefetchQueueElem *e;
2777 pthread_mutex_lock(&queue_lock);
2778 e = prefetch_wait.first;
2780 BLI_remlink(&prefetch_wait, e);
2782 s_last = seq_last_given_monoton_cfra;
2786 pthread_mutex_unlock(&queue_lock);
2789 pthread_mutex_lock(&prefetch_ready_lock);
2791 This->running = FALSE;
2793 pthread_cond_signal(&prefetch_ready_cond);
2794 pthread_mutex_unlock(&prefetch_ready_lock);
2796 pthread_mutex_lock(&wakeup_lock);
2797 if (!seq_thread_shutdown) {
2798 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
2800 pthread_mutex_unlock(&wakeup_lock);
2804 This->running = TRUE;
2806 if (e->cfra >= s_last) {
2807 e->ibuf = give_ibuf_seq_impl(This->scene,
2808 e->rectx, e->recty, e->cfra, e->chanshown,
2812 pthread_mutex_lock(&queue_lock);
2814 BLI_addtail(&prefetch_done, e);
2816 for (e = prefetch_wait.first; e; e = e->next) {
2817 if (s_last > e->monoton_cfra) {
2818 BLI_remlink(&prefetch_wait, e);
2823 for (e = prefetch_done.first; e; e = e->next) {
2824 if (s_last > e->monoton_cfra) {
2826 IMB_cache_limiter_unref(e->ibuf);
2828 BLI_remlink(&prefetch_done, e);
2833 pthread_mutex_unlock(&queue_lock);
2835 pthread_mutex_lock(&frame_done_lock);
2836 pthread_cond_signal(&frame_done_cond);
2837 pthread_mutex_unlock(&frame_done_lock);
2842 static void seq_start_threads(Scene *scene)
2846 running_threads.first = running_threads.last = NULL;
2847 prefetch_wait.first = prefetch_wait.last = NULL;
2848 prefetch_done.first = prefetch_done.last = NULL;
2850 seq_thread_shutdown = FALSE;
2851 seq_last_given_monoton_cfra = monoton_cfra = 0;
2853 /* since global structures are modified during the processing
2854 of one frame, only one render thread is currently possible...
2856 (but we code, in the hope, that we can remove this restriction
2860 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
2862 for (i = 0; i < 1; i++) {
2863 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
2866 BLI_addtail(&running_threads, t);
2868 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
2871 /* init malloc mutex */
2872 BLI_init_threads(0, 0, 0);
2875 static void seq_stop_threads()
2877 PrefetchThread *tslot;
2878 PrefetchQueueElem *e;
2880 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
2882 if (seq_thread_shutdown) {
2883 fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
2887 pthread_mutex_lock(&wakeup_lock);
2889 seq_thread_shutdown = TRUE;
2891 pthread_cond_broadcast(&wakeup_cond);
2892 pthread_mutex_unlock(&wakeup_lock);
2894 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2895 pthread_join(tslot->pthread, NULL);
2899 for (e = prefetch_wait.first; e; e = e->next) {
2900 BLI_remlink(&prefetch_wait, e);
2904 for (e = prefetch_done.first; e; e = e->next) {
2906 IMB_cache_limiter_unref(e->ibuf);
2908 BLI_remlink(&prefetch_done, e);
2912 BLI_freelistN(&running_threads);
2914 /* deinit malloc mutex */
2919 void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown,
2922 PrefetchQueueElem *e;
2923 if (seq_thread_shutdown) {
2927 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
2931 e->chanshown = chanshown;
2932 e->render_size = render_size;
2933 e->monoton_cfra = monoton_cfra++;
2935 pthread_mutex_lock(&queue_lock);
2936 BLI_addtail(&prefetch_wait, e);
2937 pthread_mutex_unlock(&queue_lock);
2939 pthread_mutex_lock(&wakeup_lock);
2940 pthread_cond_signal(&wakeup_cond);
2941 pthread_mutex_unlock(&wakeup_lock);
2945 static void seq_wait_for_prefetch_ready()
2947 PrefetchThread *tslot;
2949 if (seq_thread_shutdown) {
2953 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
2955 pthread_mutex_lock(&prefetch_ready_lock);
2958 for(tslot = running_threads.first; tslot; tslot= tslot->next) {
2959 if (tslot->running) {
2966 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
2969 pthread_mutex_unlock(&prefetch_ready_lock);
2971 fprintf(stderr, "SEQ-THREAD: prefetch done\n");
2975 ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size)
2977 PrefetchQueueElem *e = NULL;
2978 int found_something = FALSE;
2980 if (seq_thread_shutdown) {
2981 return give_ibuf_seq(scene, rectx, recty, cfra, chanshown, render_size);
2985 int success = FALSE;
2986 pthread_mutex_lock(&queue_lock);
2988 for (e = prefetch_done.first; e; e = e->next) {
2989 if (cfra == e->cfra &&
2990 chanshown == e->chanshown &&
2991 rectx == e->rectx &&
2992 recty == e->recty &&
2993 render_size == e->render_size) {
2995 found_something = TRUE;
3001 for (e = prefetch_wait.first; e; e = e->next) {
3002 if (cfra == e->cfra &&
3003 chanshown == e->chanshown &&
3004 rectx == e->rectx &&
3005 recty == e->recty &&
3006 render_size == e->render_size) {
3007 found_something = TRUE;
3014 PrefetchThread *tslot;
3016 for(tslot = running_threads.first;
3017 tslot; tslot= tslot->next) {
3018 if (tslot->current &&
3019 cfra == tslot->current->cfra &&
3020 chanshown == tslot->current->chanshown &&
3021 rectx == tslot->current->rectx &&
3022 recty == tslot->current->recty &&
3023 render_size== tslot->current->render_size){
3024 found_something = TRUE;
3030 /* e->ibuf is unrefed by render thread on next round. */
3033 seq_last_given_monoton_cfra = e->monoton_cfra;
3036 pthread_mutex_unlock(&queue_lock);
3041 if (!found_something) {
3043 "SEQ-THREAD: Requested frame "
3044 "not in queue ???\n");
3047 pthread_mutex_lock(&frame_done_lock);
3048 pthread_cond_wait(&frame_done_cond, &frame_done_lock);
3049 pthread_mutex_unlock(&frame_done_lock);
3053 return e ? e->ibuf : 0;
3056 /* Functions to free imbuf and anim data on changes */
3058 static void free_imbuf_strip_elem(TStripElem *se)
3061 IMB_freeImBuf(se->ibuf);
3064 IMB_freeImBuf(se->ibuf_comp);
3068 se->ok= STRIPELEM_OK;
3069 se->se1= se->se2= se->se3= 0;
3072 static void free_anim_seq(Sequence *seq)
3075 IMB_free_anim(seq->anim);
3081 static void free_imbuf_seq_except(Scene *scene, int cfra)
3083 Editing *ed= seq_give_editing(scene, FALSE);
3088 if(ed==NULL) return;
3090 SEQ_BEGIN(ed, seq) {
3092 TStripElem * curelem = give_tstripelem(seq, cfra);
3094 for(a = 0, se = seq->strip->tstripdata;
3095 a < seq->strip->len && se; a++, se++) {
3097 free_imbuf_strip_elem(se);
3100 for(a = 0, se = seq->strip->tstripdata_startstill;
3101 a < seq->strip->startstill && se; a++, se++) {
3103 free_imbuf_strip_elem(se);
3106 for(a = 0, se = seq->strip->tstripdata_endstill;
3107 a < seq->strip->endstill && se; a++, se++) {
3109 free_imbuf_strip_elem(se);
3112 if(seq->strip->ibuf_startstill) {
3113 IMB_freeImBuf(seq->strip->ibuf_startstill);
3114 seq->strip->ibuf_startstill = 0;
3117 if(seq->strip->ibuf_endstill) {
3118 IMB_freeImBuf(seq->strip->ibuf_endstill);
3119 seq->strip->ibuf_endstill = 0;
3122 if(seq->type==SEQ_MOVIE)
3123 if(seq->startdisp > cfra || seq->enddisp < cfra)
3125 free_proxy_seq(seq);