Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/sequence.c')
-rw-r--r--source/blender/src/sequence.c2990
1 files changed, 0 insertions, 2990 deletions
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
deleted file mode 100644
index 219768b2776..00000000000
--- a/source/blender/src/sequence.c
+++ /dev/null
@@ -1,2990 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-#include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
-#include "DNA_ipo_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_view3d_types.h"
-
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_ipo.h"
-#include "BKE_main.h"
-#include "BKE_scene.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-
-#include "BIF_editsound.h"
-#include "BIF_editseq.h"
-#include "BSE_filesel.h"
-#include "BSE_headerbuttons.h"
-#include "BIF_interface.h"
-#include "BIF_renderwin.h"
-#include "BIF_screen.h"
-#include "BIF_space.h"
-#include "BIF_toolbox.h"
-
-#include "BSE_sequence.h"
-#include "BSE_seqeffects.h"
-
-#include "RE_pipeline.h" // talks to entire render API
-
-#include "blendef.h"
-
-#include "BLI_threads.h"
-#include <pthread.h>
-
-#ifdef WIN32
-#define snprintf _snprintf
-#endif
-
-int seqrectx, seqrecty;
-
-/* **********************************************************************
- alloc / free functions
- ********************************************************************** */
-
-void free_tstripdata(int len, TStripElem *se)
-{
- TStripElem *seo;
- int a;
-
- seo= se;
- if (!se) {
- return;
- }
-
- for(a=0; a<len; a++, se++) {
- if(se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = 0;
- }
- if(se->ibuf_comp) {
- IMB_freeImBuf(se->ibuf_comp);
- se->ibuf_comp = 0;
- }
- }
-
- MEM_freeN(seo);
-
-}
-
-void free_strip(Strip *strip)
-{
- strip->us--;
- if(strip->us>0) return;
- if(strip->us<0) {
- printf("error: negative users in strip\n");
- return;
- }
-
- if (strip->stripdata) {
- MEM_freeN(strip->stripdata);
- }
-
- if (strip->proxy) {
- MEM_freeN(strip->proxy);
- }
- if (strip->crop) {
- MEM_freeN(strip->crop);
- }
- if (strip->transform) {
- MEM_freeN(strip->transform);
- }
- if (strip->color_balance) {
- MEM_freeN(strip->color_balance);
- }
-
- free_tstripdata(strip->len, strip->tstripdata);
- free_tstripdata(strip->endstill, strip->tstripdata_endstill);
- free_tstripdata(strip->startstill, strip->tstripdata_startstill);
-
- if(strip->ibuf_startstill) {
- IMB_freeImBuf(strip->ibuf_startstill);
- strip->ibuf_startstill = 0;
- }
-
- if(strip->ibuf_endstill) {
- IMB_freeImBuf(strip->ibuf_endstill);
- strip->ibuf_endstill = 0;
- }
-
- MEM_freeN(strip);
-}
-
-void new_tstripdata(Sequence *seq)
-{
- if(seq->strip) {
- free_tstripdata(seq->strip->len, seq->strip->tstripdata);
- free_tstripdata(seq->strip->endstill,
- seq->strip->tstripdata_endstill);
- free_tstripdata(seq->strip->startstill,
- seq->strip->tstripdata_startstill);
-
- seq->strip->tstripdata= 0;
- seq->strip->tstripdata_endstill= 0;
- seq->strip->tstripdata_startstill= 0;
-
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
- seq->strip->len= seq->len;
- }
-}
-
-void free_sequence(Sequence *seq)
-{
- Sequence *last_seq = get_last_seq();
-
- if(seq->strip) free_strip(seq->strip);
-
- if(seq->anim) IMB_free_anim(seq->anim);
- if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
-
- if (seq->type & SEQ_EFFECT) {
- struct SeqEffectHandle sh = get_sequence_effect(seq);
-
- sh.free(seq);
- }
-
- if(seq==last_seq) set_last_seq(NULL);
-
- MEM_freeN(seq);
-}
-
-/*
- **********************************************************************
- * build_seqar
- **********************************************************************
- * Build a complete array of _all_ sequencies (including those
- * in metastrips!)
- **********************************************************************
-*/
-
-static void do_seq_count(ListBase *seqbase, int *totseq)
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- (*totseq)++;
- if(seq->seqbase.first) do_seq_count(&seq->seqbase, totseq);
- seq= seq->next;
- }
-}
-
-static void do_build_seqar(ListBase *seqbase, Sequence ***seqar, int depth)
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- seq->depth= depth;
- if(seq->seqbase.first) do_build_seqar(&seq->seqbase, seqar, depth+1);
- **seqar= seq;
- (*seqar)++;
- seq= seq->next;
- }
-}
-
-void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
-{
- Sequence **tseqar;
-
- *totseq= 0;
- do_seq_count(seqbase, totseq);
-
- if(*totseq==0) {
- *seqar= 0;
- return;
- }
- *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
- tseqar= *seqar;
-
- do_build_seqar(seqbase, seqar, 0);
- *seqar= tseqar;
-}
-
-static void do_seq_count_cb(ListBase *seqbase, int *totseq,
- int (*test_func)(Sequence * seq))
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- int test = test_func(seq);
- if (test & BUILD_SEQAR_COUNT_CURRENT) {
- (*totseq)++;
- }
- if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
- do_seq_count_cb(&seq->seqbase, totseq, test_func);
- }
- seq= seq->next;
- }
-}
-
-static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
- int (*test_func)(Sequence * seq))
-{
- Sequence *seq;
-
- seq= seqbase->first;
- while(seq) {
- int test = test_func(seq);
- seq->depth= depth;
-
- if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
- do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
- test_func);
- }
- if (test & BUILD_SEQAR_COUNT_CURRENT) {
- **seqar= seq;
- (*seqar)++;
- }
- seq= seq->next;
- }
-}
-
-void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
- int (*test_func)(Sequence * seq))
-{
- Sequence **tseqar;
-
- *totseq= 0;
- do_seq_count_cb(seqbase, totseq, test_func);
-
- if(*totseq==0) {
- *seqar= 0;
- return;
- }
- *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
- tseqar= *seqar;
-
- do_build_seqar_cb(seqbase, seqar, 0, test_func);
- *seqar= tseqar;
-}
-
-
-void free_editing(Editing *ed)
-{
- MetaStack *ms;
- Sequence *seq;
-
- if(ed==NULL) return;
- set_last_seq(NULL); /* clear_last_seq doesnt work, it screws up free_sequence */
-
- WHILE_SEQ(&ed->seqbase) {
- free_sequence(seq);
- }
- END_SEQ
-
- while( (ms= ed->metastack.first) ) {
- BLI_remlink(&ed->metastack, ms);
- MEM_freeN(ms);
- }
-
- MEM_freeN(ed);
-
-}
-
-void calc_sequence_disp(Sequence *seq)
-{
- if(seq->startofs && seq->startstill) seq->startstill= 0;
- if(seq->endofs && seq->endstill) seq->endstill= 0;
-
- seq->startdisp= seq->start + seq->startofs - seq->startstill;
- seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
-
- seq->handsize= 10.0; /* 10 frames */
- if( seq->enddisp-seq->startdisp < 10 ) {
- seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
- }
- else if(seq->enddisp-seq->startdisp > 250) {
- seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
- }
-}
-
-void calc_sequence(Sequence *seq)
-{
- Sequence *seqm;
- int min, max;
-
- /* check all metas recursively */
- seqm= seq->seqbase.first;
- while(seqm) {
- if(seqm->seqbase.first) calc_sequence(seqm);
- seqm= seqm->next;
- }
-
- /* effects and meta: automatic start and end */
-
- if(seq->type & SEQ_EFFECT) {
- /* pointers */
- if(seq->seq2==0) seq->seq2= seq->seq1;
- if(seq->seq3==0) seq->seq3= seq->seq1;
-
- /* effecten go from seq1 -> seq2: test */
-
- /* we take the largest start and smallest end */
-
- // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
- // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
-
- if (seq->seq1) {
- seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
- seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
- seq->len= seq->enddisp - seq->startdisp;
- } else {
- calc_sequence_disp(seq);
- }
-
- if(seq->strip && seq->len!=seq->strip->len) {
- new_tstripdata(seq);
- }
-
- }
- else {
- if(seq->type==SEQ_META) {
- seqm= seq->seqbase.first;
- if(seqm) {
- min= 1000000;
- max= -1000000;
- while(seqm) {
- if(seqm->startdisp < min) min= seqm->startdisp;
- if(seqm->enddisp > max) max= seqm->enddisp;
- seqm= seqm->next;
- }
- seq->start= min + seq->anim_startofs;
- seq->len = max-min;
- seq->len -= seq->anim_startofs;
- seq->len -= seq->anim_endofs;
-
- if(seq->strip && seq->len!=seq->strip->len) {
- new_tstripdata(seq);
- }
- }
- }
- calc_sequence_disp(seq);
- }
-}
-
-void reload_sequence_new_file(Sequence * seq)
-{
- char str[FILE_MAXDIR+FILE_MAXFILE];
-
- if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
- seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND ||
- seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
- return;
- }
-
- new_tstripdata(seq);
-
- if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
- seq->type != SEQ_IMAGE) {
- BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
- BLI_convertstringcode(str, G.sce);
- BLI_convertstringframe(str, G.scene->r.cfra);
-
- }
-
- if (seq->type == SEQ_IMAGE) {
- /* Hack? */
- int olen = MEM_allocN_len(seq->strip->stripdata)
- / sizeof(struct StripElem);
- seq->len = olen;
- seq->len -= seq->anim_startofs;
- seq->len -= seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- } else if (seq->type == SEQ_MOVIE) {
- if(seq->anim) IMB_free_anim(seq->anim);
- seq->anim = openanim(
- str, IB_rect |
- ((seq->flag & SEQ_FILTERY)
- ? IB_animdeinterlace : 0));
-
- if (!seq->anim) {
- return;
- }
-
- seq->len = IMB_anim_get_duration(seq->anim);
-
- seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
-
- seq->len -= seq->anim_startofs;
- seq->len -= seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- } else if (seq->type == SEQ_HD_SOUND) {
- if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
- seq->hdaudio = sound_open_hdaudio(str);
-
- if (!seq->hdaudio) {
- return;
- }
-
- seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS)
- - seq->anim_startofs - seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- } else if (seq->type == SEQ_RAM_SOUND) {
- seq->len = (int) ( ((float)(seq->sound->streamlen-1)/
- ((float)G.scene->audio.mixrate*4.0 ))
- * FPS);
- seq->len -= seq->anim_startofs;
- seq->len -= seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- } else if (seq->type == SEQ_SCENE) {
- Scene * sce = G.main->scene.first;
- int nr = 1;
- while(sce) {
- if(nr == seq->scenenr) {
- break;
- }
- nr++;
- sce= sce->id.next;
- }
-
- if (sce) {
- seq->scene = sce;
- } else {
- sce = seq->scene;
- }
-
- strncpy(seq->name + 2, sce->id.name + 2,
- sizeof(seq->name) - 2);
-
- seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
- seq->len -= seq->anim_startofs;
- seq->len -= seq->anim_endofs;
- if (seq->len < 0) {
- seq->len = 0;
- }
- seq->strip->len = seq->len;
- }
-
- calc_sequence(seq);
-}
-
-void sort_seq()
-{
- /* all strips together per kind, and in order of y location ("machine") */
- ListBase seqbase, effbase;
- Editing *ed;
- Sequence *seq, *seqt;
-
- ed= G.scene->ed;
- if(ed==0) return;
-
- seqbase.first= seqbase.last= 0;
- effbase.first= effbase.last= 0;
-
- while( (seq= ed->seqbasep->first) ) {
- BLI_remlink(ed->seqbasep, seq);
-
- if(seq->type & SEQ_EFFECT) {
- seqt= effbase.first;
- while(seqt) {
- if(seqt->machine>=seq->machine) {
- BLI_insertlinkbefore(&effbase, seqt, seq);
- break;
- }
- seqt= seqt->next;
- }
- if(seqt==0) BLI_addtail(&effbase, seq);
- }
- else {
- seqt= seqbase.first;
- while(seqt) {
- if(seqt->machine>=seq->machine) {
- BLI_insertlinkbefore(&seqbase, seqt, seq);
- break;
- }
- seqt= seqt->next;
- }
- if(seqt==0) BLI_addtail(&seqbase, seq);
- }
- }
-
- addlisttolist(&seqbase, &effbase);
- *(ed->seqbasep)= seqbase;
-}
-
-
-void clear_scene_in_allseqs(Scene *sce)
-{
- Scene *sce1;
- Editing *ed;
- Sequence *seq;
-
- /* when a scene is deleted: test all seqs */
-
- sce1= G.main->scene.first;
- while(sce1) {
- if(sce1!=sce && sce1->ed) {
- ed= sce1->ed;
-
- WHILE_SEQ(&ed->seqbase) {
-
- if(seq->scene==sce) seq->scene= 0;
-
- }
- END_SEQ
- }
-
- sce1= sce1->id.next;
- }
-}
-
-char *give_seqname_by_type(int type)
-{
- switch(type) {
- case SEQ_META: return "Meta";
- case SEQ_IMAGE: return "Image";
- case SEQ_SCENE: return "Scene";
- case SEQ_MOVIE: return "Movie";
- case SEQ_RAM_SOUND: return "Audio (RAM)";
- case SEQ_HD_SOUND: return "Audio (HD)";
- case SEQ_CROSS: return "Cross";
- case SEQ_GAMCROSS: return "Gamma Cross";
- case SEQ_ADD: return "Add";
- case SEQ_SUB: return "Sub";
- case SEQ_MUL: return "Mul";
- case SEQ_ALPHAOVER: return "Alpha Over";
- case SEQ_ALPHAUNDER: return "Alpha Under";
- case SEQ_OVERDROP: return "Over Drop";
- case SEQ_WIPE: return "Wipe";
- case SEQ_GLOW: return "Glow";
- case SEQ_TRANSFORM: return "Transform";
- case SEQ_COLOR: return "Color";
- case SEQ_SPEED: return "Speed";
- default:
- return 0;
- }
-}
-
-char *give_seqname(Sequence *seq)
-{
- char * name = give_seqname_by_type(seq->type);
-
- if (!name) {
- if(seq->type<SEQ_EFFECT) {
- return seq->strip->dir;
- } else if(seq->type==SEQ_PLUGIN) {
- if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
- seq->plugin && seq->plugin->doit) {
- return seq->plugin->pname;
- } else {
- return "Plugin";
- }
- } else {
- return "Effect";
- }
- }
- return name;
-}
-
-/* ***************** DO THE SEQUENCE ***************** */
-
-static void make_black_ibuf(ImBuf *ibuf)
-{
- unsigned int *rect;
- float *rect_float;
- int tot;
-
- if(ibuf==0 || (ibuf->rect==0 && ibuf->rect_float==0)) return;
-
- tot= ibuf->x*ibuf->y;
-
- rect= ibuf->rect;
- rect_float = ibuf->rect_float;
-
- if (rect) {
- memset(rect, 0, tot * sizeof(char) * 4);
- }
-
- if (rect_float) {
- memset(rect_float, 0, tot * sizeof(float) * 4);
- }
-}
-
-static void multibuf(ImBuf *ibuf, float fmul)
-{
- char *rt;
- float *rt_float;
-
- int a, mul, icol;
-
- mul= (int)(256.0*fmul);
- rt= (char *)ibuf->rect;
- rt_float = ibuf->rect_float;
-
- if (rt) {
- a= ibuf->x*ibuf->y;
- while(a--) {
-
- icol= (mul*rt[0])>>8;
- if(icol>254) rt[0]= 255; else rt[0]= icol;
- icol= (mul*rt[1])>>8;
- if(icol>254) rt[1]= 255; else rt[1]= icol;
- icol= (mul*rt[2])>>8;
- if(icol>254) rt[2]= 255; else rt[2]= icol;
- icol= (mul*rt[3])>>8;
- if(icol>254) rt[3]= 255; else rt[3]= icol;
-
- rt+= 4;
- }
- }
- if (rt_float) {
- a= ibuf->x*ibuf->y;
- while(a--) {
- rt_float[0] *= fmul;
- rt_float[1] *= fmul;
- rt_float[2] *= fmul;
- rt_float[3] *= fmul;
-
- rt_float += 4;
- }
- }
-}
-
-static void do_effect(int cfra, Sequence *seq, TStripElem * se)
-{
- TStripElem *se1, *se2, *se3;
- float fac, facf;
- int x, y;
- int early_out;
- struct SeqEffectHandle sh = get_sequence_effect(seq);
-
- if (!sh.execute) { /* effect not supported in this version... */
- make_black_ibuf(se->ibuf);
- return;
- }
-
- if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, cfra);
- fac= seq->facf0;
- facf= seq->facf1;
- } else {
- sh.get_default_fac(seq, cfra, &fac, &facf);
- }
-
- if( !(G.scene->r.mode & R_FIELDS) ) facf = fac;
-
- early_out = sh.early_out(seq, fac, facf);
-
- if (early_out == -1) { /* no input needed */
- sh.execute(seq, cfra, fac, facf,
- se->ibuf->x, se->ibuf->y,
- 0, 0, 0, se->ibuf);
- return;
- }
-
- switch (early_out) {
- case 0:
- if (se->se1==0 || se->se2==0 || se->se3==0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se1= se->se1;
- se2= se->se2;
- se3= se->se3;
-
- if ( (se1==0 || se2==0 || se3==0)
- || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- break;
- case 1:
- if (se->se1 == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se1= se->se1;
-
- if (se1 == 0 || se1->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- if (se->ibuf != se1->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = se1->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- return;
- case 2:
- if (se->se2 == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
-
- se2= se->se2;
-
- if (se2 == 0 || se2->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- return;
- }
- if (se->ibuf != se2->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = se2->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- return;
- default:
- make_black_ibuf(se->ibuf);
- return;
- }
-
- x= se2->ibuf->x;
- y= se2->ibuf->y;
-
- if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se1->ibuf);
- }
- if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se2->ibuf);
- }
- if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se3->ibuf);
- }
-
- if (!se1->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se1->ibuf);
- }
- if (!se2->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se2->ibuf);
- }
- if (!se3->ibuf->rect && !se->ibuf->rect_float) {
- IMB_rect_from_float(se3->ibuf);
- }
-
- sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
- se->ibuf);
-}
-
-static int give_stripelem_index(Sequence *seq, int cfra)
-{
- int nr;
-
- if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
- if(seq->len == 0) return -1;
- if(seq->flag&SEQ_REVERSE_FRAMES) {
- /*reverse frame in this sequence */
- if(cfra <= seq->start) nr= seq->len-1;
- else if(cfra >= seq->start+seq->len-1) nr= 0;
- else nr= (seq->start + seq->len) - cfra;
- } else {
- if(cfra <= seq->start) nr= 0;
- else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
- else nr= cfra-seq->start;
- }
- if (seq->strobe < 1.0) seq->strobe = 1.0;
- if (seq->strobe > 1.0) {
- nr -= (int)fmod((double)nr, (double)seq->strobe);
- }
-
- return nr;
-}
-
-static TStripElem* alloc_tstripdata(int len, const char * name)
-{
- int i;
- TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
- for (i = 0; i < len; i++) {
- se[i].ok = STRIPELEM_OK;
- }
- return se;
-}
-
-TStripElem *give_tstripelem(Sequence *seq, int cfra)
-{
- TStripElem *se;
- int nr;
-
- se = seq->strip->tstripdata;
- if (se == 0 && seq->len > 0) {
- se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
- "tstripelems");
- }
- nr = give_stripelem_index(seq, cfra);
-
- if (nr == -1) return 0;
- if (se == 0) return 0;
-
- se += nr;
-
- /* if there are IPOs with blend modes active, one has to watch out
- for startstill + endstill area: we can't use the same tstripelem
- here for all ibufs, since then, blending with IPOs won't work!
-
- Rather common case, if you use a single image and try to fade
- it in and out... or want to use your strip as a watermark in
- alpha over mode...
- */
- if (seq->blend_mode != SEQ_BLEND_REPLACE ||
- (seq->ipo && seq->ipo->curve.first && (
- !(seq->type & SEQ_EFFECT) || !seq->seq1))) {
- Strip * s = seq->strip;
- if (cfra < seq->start) {
- se = s->tstripdata_startstill;
- if (seq->startstill > s->startstill) {
- free_tstripdata(s->startstill,
- s->tstripdata_startstill);
- se = 0;
- }
-
- if (se == 0) {
- s->startstill = seq->startstill;
- se = seq->strip->tstripdata_startstill
- = alloc_tstripdata(
- s->startstill,
- "tstripelems_startstill");
- }
- se += seq->start - cfra - 1;
-
- } else if (cfra > seq->start + seq->len-1) {
- se = s->tstripdata_endstill;
- if (seq->endstill > s->endstill) {
- free_tstripdata(s->endstill,
- s->tstripdata_endstill);
- se = 0;
- }
-
- if (se == 0) {
- s->endstill = seq->endstill;
- se = seq->strip->tstripdata_endstill
- = alloc_tstripdata(
- s->endstill,
- "tstripelems_endstill");
- }
- se += cfra - (seq->start + seq->len-1) - 1;
- }
- }
-
-
- se->nr= nr;
-
- return se;
-}
-
-StripElem *give_stripelem(Sequence *seq, int cfra)
-{
- StripElem *se;
- int nr;
-
- se = seq->strip->stripdata;
- nr = give_stripelem_index(seq, cfra);
-
- if (nr == -1) return 0;
- if (se == 0) return 0;
-
- se += nr + seq->anim_startofs;
-
- return se;
-}
-
-static int evaluate_seq_frame_gen(
- Sequence ** seq_arr, ListBase *seqbase, int cfra)
-{
- Sequence *seq;
- int totseq=0;
-
- memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
-
- seq= seqbase->first;
- while(seq) {
- if(seq->startdisp <=cfra && seq->enddisp > cfra) {
- seq_arr[seq->machine]= seq;
- totseq++;
- }
- seq= seq->next;
- }
-
- return totseq;
-}
-
-int evaluate_seq_frame(int cfra)
-{
- Editing *ed;
- Sequence *seq_arr[MAXSEQ+1];
-
- ed= G.scene->ed;
- if(ed==0) return 0;
-
- return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
-
-}
-
-static int video_seq_is_rendered(Sequence * seq)
-{
- return (seq
- && !(seq->flag & SEQ_MUTE)
- && seq->type != SEQ_RAM_SOUND
- && seq->type != SEQ_HD_SOUND);
-}
-
-static int get_shown_sequences(
- ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
-{
- Sequence *seq_arr[MAXSEQ+1];
- int b = chanshown;
- int cnt = 0;
-
- if (b > MAXSEQ) {
- return 0;
- }
-
- if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
- if (b > 0) {
- if (seq_arr[b] == 0) {
- return 0;
- }
- } else {
- for (b = MAXSEQ; b > 0; b--) {
- if (video_seq_is_rendered(seq_arr[b])) {
- break;
- }
- }
- }
- }
-
- chanshown = b;
-
- for (;b > 0; b--) {
- if (video_seq_is_rendered(seq_arr[b])) {
- if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
- break;
- }
- }
- }
-
- for (;b <= chanshown; b++) {
- if (video_seq_is_rendered(seq_arr[b])) {
- seq_arr_out[cnt++] = seq_arr[b];
- }
- }
-
- return cnt;
-}
-
-
-/* **********************************************************************
- proxy management
- ********************************************************************** */
-
-#define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
-
-static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
-{
- int frameno;
- char dir[FILE_MAXDIR];
-
- if (!seq->strip->proxy) {
- return FALSE;
- }
-
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
- strcpy(dir, seq->strip->proxy->dir);
- } else {
- if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
- snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
- seq->strip->dir);
- } else {
- return FALSE;
- }
- }
-
- /* generate a seperate proxy directory for each preview size */
-
- if (seq->type == SEQ_IMAGE) {
- StripElem * se = give_stripelem(seq, cfra);
- snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
- dir, G.scene->r.size, se->name);
- frameno = 1;
- } else if (seq->type == SEQ_MOVIE) {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- frameno = tse->nr + seq->anim_startofs;
-
- snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
- seq->strip->stripdata->name,
- G.scene->r.size);
- } else {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- frameno = tse->nr + seq->anim_startofs;
-
- snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
- G.scene->r.size);
- }
-
- BLI_convertstringcode(name, G.sce);
- BLI_convertstringframe(name, frameno);
-
-
- strcat(name, ".jpg");
-
- return TRUE;
-}
-
-static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra)
-{
- char name[PROXY_MAXFILE];
-
- if (!(seq->flag & SEQ_USE_PROXY)) {
- return 0;
- }
-
- /* rendering at 100% ? No real sense in proxy-ing, right? */
- if (G.scene->r.size == 100.0) {
- return 0;
- }
-
- if (!seq_proxy_get_fname(seq, cfra, name)) {
- return 0;
- }
-
- if (BLI_exists(name)) {
- return IMB_loadiffname(name, IB_rect);
- } else {
- return 0;
- }
-}
-
-static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run);
-
-static void seq_proxy_build_frame(Sequence * seq, int cfra)
-{
- char name[PROXY_MAXFILE];
- int quality;
- TStripElem * se;
- int ok;
- int rectx, recty;
- struct ImBuf * ibuf;
-
- if (!(seq->flag & SEQ_USE_PROXY)) {
- return;
- }
-
- /* rendering at 100% ? No real sense in proxy-ing, right? */
- if (G.scene->r.size == 100.0) {
- return;
- }
-
- if (!seq_proxy_get_fname(seq, cfra, name)) {
- return;
- }
-
- se = give_tstripelem(seq, cfra);
- if (!se) {
- return;
- }
-
- if(se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf = 0;
- }
-
- do_build_seq_ibuf(seq, se, cfra, TRUE);
-
- if (!se->ibuf) {
- return;
- }
-
- rectx= (G.scene->r.size*G.scene->r.xsch)/100;
- recty= (G.scene->r.size*G.scene->r.ysch)/100;
-
- ibuf = se->ibuf;
-
- if (ibuf->x != rectx || ibuf->y != recty) {
- IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
- }
-
- /* quality is fixed, otherwise one has to generate seperate
- directories for every quality...
-
- depth = 32 is intentionally left in, otherwise ALPHA channels
- won't work... */
- quality = 90;
- ibuf->ftype= JPG | quality;
-
- BLI_make_existing_file(name);
-
- ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
- if (ok == 0) {
- perror(name);
- }
-
- IMB_freeImBuf(ibuf);
- se->ibuf = 0;
-}
-
-void seq_proxy_rebuild(Sequence * seq)
-{
- int cfra;
-
- waitcursor(1);
-
- G.afbreek = 0;
-
- /* flag management tries to account for strobe and
- other "non-linearities", that might come in the future...
- better way would be to "touch" the files, so that _really_
- no one is rebuild twice.
- */
-
- for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- tse->flag &= ~STRIPELEM_PREVIEW_DONE;
- }
-
- /* a _lot_ faster for movie files, if we read frames in
- sequential order */
- if (seq->flag & SEQ_REVERSE_FRAMES) {
- for (cfra = seq->enddisp-seq->endstill-1;
- cfra >= seq->startdisp + seq->startstill; cfra--) {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
- seq_proxy_build_frame(seq, cfra);
- tse->flag |= STRIPELEM_PREVIEW_DONE;
- }
- if (blender_test_break()) {
- break;
- }
- }
- } else {
- for (cfra = seq->startdisp + seq->startstill;
- cfra < seq->enddisp - seq->endstill; cfra++) {
- TStripElem * tse = give_tstripelem(seq, cfra);
-
- if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
- seq_proxy_build_frame(seq, cfra);
- tse->flag |= STRIPELEM_PREVIEW_DONE;
- }
- if (blender_test_break()) {
- break;
- }
- }
- }
- waitcursor(0);
-}
-
-
-/* **********************************************************************
- color balance
- ********************************************************************** */
-
-static StripColorBalance calc_cb(StripColorBalance * cb_)
-{
- StripColorBalance cb = *cb_;
- int c;
-
- if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
- for (c = 0; c < 3; c++) {
- cb.lift[c] = 1.0 - cb.lift[c];
- }
- } else {
- for (c = 0; c < 3; c++) {
- cb.lift[c] = -(1.0 - cb.lift[c]);
- }
- }
- if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
- for (c = 0; c < 3; c++) {
- if (cb.gain[c] != 0.0) {
- cb.gain[c] = 1.0/cb.gain[c];
- } else {
- cb.gain[c] = 1000000; /* should be enough :) */
- }
- }
- }
-
- if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
- for (c = 0; c < 3; c++) {
- if (cb.gamma[c] != 0.0) {
- cb.gamma[c] = 1.0/cb.gamma[c];
- } else {
- cb.gamma[c] = 1000000; /* should be enough :) */
- }
- }
- }
-
- return cb;
-}
-
-static void make_cb_table_byte(float lift, float gain, float gamma,
- unsigned char * table, float mul)
-{
- int y;
-
- for (y = 0; y < 256; y++) {
- float v = 1.0 * y / 255;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
- if ( v > 1.0) {
- v = 1.0;
- } else if (v < 0.0) {
- v = 0.0;
- }
- table[y] = v * 255;
- }
-
-}
-
-static void make_cb_table_float(float lift, float gain, float gamma,
- float * table, float mul)
-{
- int y;
-
- for (y = 0; y < 256; y++) {
- float v = (float) y * 1.0 / 255.0;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
- table[y] = v;
- }
-}
-
-static void color_balance_byte_byte(Sequence * seq, TStripElem* se,
- float mul)
-{
- unsigned char cb_tab[3][256];
- int c;
- unsigned char * p = (unsigned char*) se->ibuf->rect;
- unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
-
- StripColorBalance cb = calc_cb(seq->strip->color_balance);
-
- for (c = 0; c < 3; c++) {
- make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
- cb_tab[c], mul);
- }
-
- while (p < e) {
- p[0] = cb_tab[0][p[0]];
- p[1] = cb_tab[1][p[1]];
- p[2] = cb_tab[2][p[2]];
-
- p += 4;
- }
-}
-
-static void color_balance_byte_float(Sequence * seq, TStripElem* se,
- float mul)
-{
- float cb_tab[4][256];
- int c,i;
- unsigned char * p = (unsigned char*) se->ibuf->rect;
- unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
- float * o;
- StripColorBalance cb;
-
- imb_addrectfloatImBuf(se->ibuf);
-
- o = se->ibuf->rect_float;
-
- cb = calc_cb(seq->strip->color_balance);
-
- for (c = 0; c < 3; c++) {
- make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
- cb_tab[c], mul);
- }
-
- for (i = 0; i < 256; i++) {
- cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
- }
-
- while (p < e) {
- o[0] = cb_tab[0][p[0]];
- o[1] = cb_tab[1][p[1]];
- o[2] = cb_tab[2][p[2]];
- o[3] = cb_tab[3][p[3]];
-
- p += 4; o += 4;
- }
-}
-
-static void color_balance_float_float(Sequence * seq, TStripElem* se,
- float mul)
-{
- float * p = se->ibuf->rect_float;
- float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
- StripColorBalance cb = calc_cb(seq->strip->color_balance);
-
- while (p < e) {
- int c;
- for (c = 0; c < 3; c++) {
- p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
- cb.gamma[c]) * mul;
- }
- p += 4;
- }
-}
-
-static void color_balance(Sequence * seq, TStripElem* se, float mul)
-{
- if (se->ibuf->rect_float) {
- color_balance_float_float(seq, se, mul);
- } else if(seq->flag & SEQ_MAKE_FLOAT) {
- color_balance_byte_float(seq, se, mul);
- } else {
- color_balance_byte_byte(seq, se, mul);
- }
-}
-
-/*
- input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
-
- Do all the things you can't really do afterwards using sequence effects
- (read: before rescaling to render resolution has been done)
-
- Order is important!
-
- - Deinterlace
- - Crop and transform in image source coordinate space
- - Flip X + Flip Y (could be done afterwards, backward compatibility)
- - Promote image to float data (affects pipeline operations afterwards)
- - Color balance (is most efficient in the byte -> float
- (future: half -> float should also work fine!)
- case, if done on load, since we can use lookup tables)
- - Premultiply
-
-*/
-
-static int input_have_to_preprocess(Sequence * seq, TStripElem* se, int cfra)
-{
- float mul;
-
- if ((seq->flag & SEQ_FILTERY) ||
- (seq->flag & SEQ_USE_CROP) ||
- (seq->flag & SEQ_USE_TRANSFORM) ||
- (seq->flag & SEQ_FLIPX) ||
- (seq->flag & SEQ_FLIPY) ||
- (seq->flag & SEQ_USE_COLOR_BALANCE) ||
- (seq->flag & SEQ_MAKE_PREMUL) ||
- (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
- return TRUE;
- }
-
- mul = seq->mul;
-
- if(seq->blend_mode == SEQ_BLEND_REPLACE) {
- if (seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, cfra);
- mul *= seq->facf0;
- }
- mul *= seq->blend_opacity / 100.0;
- }
-
- if (mul != 1.0) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
-{
- float mul;
-
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
-
- if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
- IMB_filtery(se->ibuf);
- }
-
- if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
- StripCrop c;
- StripTransform t;
- int sx,sy,dx,dy;
-
- memset(&c, 0, sizeof(StripCrop));
- memset(&t, 0, sizeof(StripTransform));
-
- if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
- c = *seq->strip->crop;
- }
- if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
- t = *seq->strip->transform;
- }
-
- sx = se->ibuf->x - c.left - c.right;
- sy = se->ibuf->y - c.top - c.bottom;
- dx = sx;
- dy = sy;
-
- if (seq->flag & SEQ_USE_TRANSFORM) {
- dx = G.scene->r.xsch;
- dy = G.scene->r.ysch;
- }
-
- if (c.top + c.bottom >= se->ibuf->y ||
- c.left + c.right >= se->ibuf->x ||
- t.xofs >= dx || t.yofs >= dy) {
- make_black_ibuf(se->ibuf);
- } else {
- ImBuf * i;
-
- if (se->ibuf->rect_float) {
- i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
- } else {
- i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
- }
-
- IMB_rectcpy(i, se->ibuf,
- t.xofs, t.yofs,
- c.left, c.bottom,
- sx, sy);
-
- IMB_freeImBuf(se->ibuf);
-
- se->ibuf = i;
- }
- }
-
- if(seq->flag & SEQ_FLIPX) {
- IMB_flipx(se->ibuf);
- }
- if(seq->flag & SEQ_FLIPY) {
- IMB_flipy(se->ibuf);
- }
-
- if(seq->mul == 0.0) {
- seq->mul = 1.0;
- }
-
- mul = seq->mul;
-
- if(seq->blend_mode == SEQ_BLEND_REPLACE) {
- if (seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, cfra);
- mul *= seq->facf0;
- }
- mul *= seq->blend_opacity / 100.0;
- }
-
- if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
- color_balance(seq, se, mul);
- mul = 1.0;
- }
-
- if(seq->flag & SEQ_MAKE_FLOAT) {
- if (!se->ibuf->rect_float) {
- IMB_float_from_rect(se->ibuf);
- }
- if (se->ibuf->rect) {
- imb_freerectImBuf(se->ibuf);
- }
- }
-
- if(mul != 1.0) {
- multibuf(se->ibuf, mul);
- }
-
- if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
- converttopremul(se->ibuf);
- }
- }
-
-
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
- if(G.scene->r.mode & R_OSA) {
- IMB_scaleImBuf(se->ibuf,
- (short)seqrectx, (short)seqrecty);
- } else {
- IMB_scalefastImBuf(se->ibuf,
- (short)seqrectx, (short)seqrecty);
- }
- }
-}
-
-/* test if image too small or discarded from cache: reload */
-
-static void test_and_auto_discard_ibuf(TStripElem * se)
-{
- if (se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
- || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
-
- se->ibuf= 0;
- se->ok= STRIPELEM_OK;
- }
- }
- if (se->ibuf_comp) {
- if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
- || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
- IMB_freeImBuf(se->ibuf_comp);
-
- se->ibuf_comp = 0;
- }
- }
-}
-
-static void test_and_auto_discard_ibuf_stills(Strip * strip)
-{
- if (strip->ibuf_startstill) {
- if (!strip->ibuf_startstill->rect &&
- !strip->ibuf_startstill->rect_float) {
- IMB_freeImBuf(strip->ibuf_startstill);
- strip->ibuf_startstill = 0;
- }
- }
- if (strip->ibuf_endstill) {
- if (!strip->ibuf_endstill->rect &&
- !strip->ibuf_endstill->rect_float) {
- IMB_freeImBuf(strip->ibuf_endstill);
- strip->ibuf_endstill = 0;
- }
- }
-}
-
-static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
-{
- if (!se->ibuf) {
- if (se->nr == 0 && seq->strip->ibuf_startstill) {
- IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
-
- se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
- }
- if (se->nr == seq->len - 1
- && (seq->len != 1)
- && seq->strip->ibuf_endstill) {
- IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
-
- se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
- }
- }
-}
-
-static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
-{
- if (se->ibuf) {
- if (se->nr == 0) {
- seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
-
- IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
- IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
- }
- if (se->nr == seq->len - 1 && seq->len != 1) {
- seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
-
- IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
- IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
- }
- }
-}
-
-static void free_metastrip_imbufs(ListBase *seqbasep, int cfra, int chanshown)
-{
- Sequence* seq_arr[MAXSEQ+1];
- int i;
- TStripElem* se = 0;
-
- evaluate_seq_frame_gen(seq_arr, seqbasep, cfra);
-
- for (i = 0; i < MAXSEQ; i++) {
- if (!video_seq_is_rendered(seq_arr[i])) {
- continue;
- }
- se = give_tstripelem(seq_arr[i], cfra);
- if (se) {
- if (se->ibuf) {
- IMB_freeImBuf(se->ibuf);
-
- se->ibuf= 0;
- se->ok= STRIPELEM_OK;
- }
-
- if (se->ibuf_comp) {
- IMB_freeImBuf(se->ibuf_comp);
-
- se->ibuf_comp = 0;
- }
- }
- }
-
-}
-
-static TStripElem* do_build_seq_array_recursively(
- ListBase *seqbasep, int cfra, int chanshown);
-
-static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run)
-{
- char name[FILE_MAXDIR+FILE_MAXFILE];
- int use_limiter = TRUE;
-
- test_and_auto_discard_ibuf(se);
- test_and_auto_discard_ibuf_stills(seq->strip);
-
- if(seq->type == SEQ_META) {
- TStripElem * meta_se = 0;
- use_limiter = FALSE;
-
- if (!build_proxy_run && se->ibuf == 0) {
- se->ibuf = seq_proxy_fetch(seq, cfra);
- if (se->ibuf) {
- use_limiter = TRUE;
- }
- }
-
- if(!se->ibuf && seq->seqbase.first) {
- meta_se = do_build_seq_array_recursively(
- &seq->seqbase, seq->start + se->nr, 0);
- }
-
- se->ok = STRIPELEM_OK;
-
- if(!se->ibuf && meta_se) {
- se->ibuf = meta_se->ibuf_comp;
- if(se->ibuf &&
- (!input_have_to_preprocess(seq, se, cfra) ||
- build_proxy_run)) {
- IMB_refImBuf(se->ibuf);
- if (build_proxy_run) {
- IMB_cache_limiter_unref(se->ibuf);
- }
- } else if (se->ibuf) {
- struct ImBuf * i = IMB_dupImBuf(se->ibuf);
-
- IMB_cache_limiter_unref(se->ibuf);
-
- se->ibuf = i;
-
- use_limiter = TRUE;
- }
- }
- if (meta_se) {
- free_metastrip_imbufs(
- &seq->seqbase, seq->start + se->nr, 0);
- }
-
- if (use_limiter) {
- input_preprocess(seq, se, cfra);
- }
- } else if(seq->type & SEQ_EFFECT) {
- /* should the effect be recalculated? */
-
- if (!build_proxy_run && se->ibuf == 0) {
- se->ibuf = seq_proxy_fetch(seq, cfra);
- }
-
- if(se->ibuf == 0) {
- /* if any inputs are rectfloat, output is float too */
- if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
- (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float) ||
- (se->se3 && se->se3->ibuf && se->se3->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
-
- do_effect(cfra, seq, se);
- }
- } else if(seq->type == SEQ_IMAGE) {
- if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
- StripElem * s_elem = give_stripelem(seq, cfra);
- BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
- BLI_convertstringcode(name, G.sce);
- BLI_convertstringframe(name, G.scene->r.cfra);
- if (!build_proxy_run) {
- se->ibuf = seq_proxy_fetch(seq, cfra);
- }
- copy_from_ibuf_still(seq, se);
-
- if (!se->ibuf) {
- se->ibuf= IMB_loadiffname(
- name, IB_rect);
- copy_to_ibuf_still(seq, se);
- }
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else if (!build_proxy_run) {
- input_preprocess(seq, se, cfra);
- }
- }
- } else if(seq->type == SEQ_MOVIE) {
- if(se->ok == STRIPELEM_OK && se->ibuf==0) {
- if(!build_proxy_run) {
- se->ibuf = seq_proxy_fetch(seq, cfra);
- }
- copy_from_ibuf_still(seq, se);
-
- if (se->ibuf == 0) {
- if(seq->anim==0) {
- BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
- BLI_convertstringcode(name, G.sce);
- BLI_convertstringframe(name, G.scene->r.cfra);
-
- seq->anim = openanim(
- name, IB_rect |
- ((seq->flag & SEQ_FILTERY)
- ? IB_animdeinterlace : 0));
- }
- if(seq->anim) {
- IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
- }
- copy_to_ibuf_still(seq, se);
- }
-
- if(se->ibuf == 0) {
- se->ok = STRIPELEM_FAILED;
- } else if (!build_proxy_run) {
- input_preprocess(seq, se, cfra);
- }
- }
- } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
- int oldcfra = CFRA;
- Sequence * oldseq = get_last_seq();
- Scene *sce= seq->scene, *oldsce= G.scene;
- Render *re;
- RenderResult rres;
- int doseq, rendering= G.rendering;
- char scenename[64];
- int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ);
-
- if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
- se->ibuf = seq_proxy_fetch(seq, cfra);
- if (se->ibuf) {
- input_preprocess(seq, se, cfra);
- }
- }
-
- if (se->ibuf == NULL && sce_valid) {
- copy_from_ibuf_still(seq, se);
- if (se->ibuf) {
- input_preprocess(seq, se, cfra);
- }
- }
-
- if (!sce_valid) {
- se->ok = STRIPELEM_FAILED;
- } else if (se->ibuf==NULL && sce_valid) {
- waitcursor(1);
-
- /* Hack! This function can be called from do_render_seq(), in that case
- the seq->scene can already have a Render initialized with same name,
- so we have to use a default name. (compositor uses G.scene name to
- find render).
- However, when called from within the UI (image preview in sequencer)
- we do want to use scene Render, that way the render result is defined
- for display in render/imagewindow */
- if(rendering) {
- BLI_strncpy(scenename, sce->id.name+2, 64);
- strcpy(sce->id.name+2, " do_build_seq_ibuf");
- }
- re= RE_NewRender(sce->id.name);
-
- /* prevent eternal loop */
- doseq= G.scene->r.scemode & R_DOSEQ;
- G.scene->r.scemode &= ~R_DOSEQ;
-
- BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
-
- /* hrms, set_scene still needed? work on that... */
- if(sce!=oldsce) set_scene_bg(sce);
- RE_BlenderFrame(re, sce,
- seq->sfra+se->nr+seq->anim_startofs);
- if(sce!=oldsce) set_scene_bg(oldsce);
-
- /* UGLY WARNING, it is set to zero in RE_BlenderFrame */
- G.rendering= rendering;
- if(rendering)
- BLI_strncpy(sce->id.name+2, scenename, 64);
-
- RE_GetResultImage(re, &rres);
-
- if(rres.rectf) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
- memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
- if(rres.rectz) {
- addzbuffloatImBuf(se->ibuf);
- memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
- }
- } else if (rres.rect32) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
- memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
- }
-
- BIF_end_render_callbacks();
-
- /* restore */
- G.scene->r.scemode |= doseq;
-
- if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
- waitcursor(0);
- CFRA = oldcfra;
- set_last_seq(oldseq);
-
- copy_to_ibuf_still(seq, se);
-
- if (!build_proxy_run) {
- if(se->ibuf == NULL) {
- se->ok = STRIPELEM_FAILED;
- } else {
- input_preprocess(seq, se, cfra);
- }
- }
-
- }
- }
- if (!build_proxy_run) {
- if (se->ibuf && use_limiter) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
- }
- }
-}
-
-static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra);
-
-static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
-{
- float fac, facf;
- struct SeqEffectHandle sh = get_sequence_effect(seq);
- int early_out;
-
- se->se1 = 0;
- se->se2 = 0;
- se->se3 = 0;
-
- if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, cfra);
- fac= seq->facf0;
- facf= seq->facf1;
- } else {
- sh.get_default_fac(seq, cfra, &fac, &facf);
- }
-
- if( G.scene->r.mode & R_FIELDS ); else facf= fac;
-
- early_out = sh.early_out(seq, fac, facf);
- switch (early_out) {
- case -1:
- /* no input needed */
- break;
- case 0:
- se->se1 = do_build_seq_recursively(seq->seq1, cfra);
- se->se2 = do_build_seq_recursively(seq->seq2, cfra);
- if (seq->seq3) {
- se->se3 = do_build_seq_recursively(seq->seq3, cfra);
- }
- break;
- case 1:
- se->se1 = do_build_seq_recursively(seq->seq1, cfra);
- break;
- case 2:
- se->se2 = do_build_seq_recursively(seq->seq2, cfra);
- break;
- }
-
-
- do_build_seq_ibuf(seq, se, cfra, FALSE);
-
- /* children are not needed anymore ... */
-
- if (se->se1 && se->se1->ibuf) {
- IMB_cache_limiter_unref(se->se1->ibuf);
- }
- if (se->se2 && se->se2->ibuf) {
- IMB_cache_limiter_unref(se->se2->ibuf);
- }
- if (se->se3 && se->se3->ibuf) {
- IMB_cache_limiter_unref(se->se3->ibuf);
- }
-}
-
-static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
-{
- TStripElem *se;
-
- se = give_tstripelem(seq, cfra);
-
- if(se) {
- if (seq->type & SEQ_EFFECT) {
- do_effect_seq_recursively(seq, se, cfra);
- } else {
- do_build_seq_ibuf(seq, se, cfra, FALSE);
- }
- }
- return se;
-}
-
-/* FIXME:
-
-If cfra was float throughout blender (especially in the render
-pipeline) one could even _render_ with subframe precision
-instead of faking using the blend code below...
-
-*/
-
-static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra)
-{
- SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
- int nr = cfra - seq->start;
- float f_cfra;
- int cfra_left;
- int cfra_right;
- TStripElem * se = 0;
- TStripElem * se1 = 0;
- TStripElem * se2 = 0;
-
- sequence_effect_speed_rebuild_map(seq, 0);
-
- f_cfra = seq->start + s->frameMap[nr];
-
- cfra_left = (int) floor(f_cfra);
- cfra_right = (int) ceil(f_cfra);
-
- se = give_tstripelem(seq, cfra);
-
- if (!se) {
- return se;
- }
-
- if (cfra_left == cfra_right ||
- (s->flags & SEQ_SPEED_BLEND) == 0) {
- test_and_auto_discard_ibuf(se);
-
- if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(
- seq->seq1, cfra_left);
-
- if((se1 && se1->ibuf && se1->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
-
- if (se1 == 0 || se1->ibuf == 0) {
- make_black_ibuf(se->ibuf);
- } else {
- if (se->ibuf != se1->ibuf) {
- if (se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- }
-
- se->ibuf = se1->ibuf;
- IMB_refImBuf(se->ibuf);
- }
- }
- }
- } else {
- struct SeqEffectHandle sh;
-
- if(se->ibuf) {
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
- || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- }
- }
-
- if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(
- seq->seq1, cfra_left);
- se2 = do_build_seq_recursively_impl(
- seq->seq1, cfra_right);
-
- if((se1 && se1->ibuf && se1->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
-
- if (!se1 || !se2) {
- make_black_ibuf(se->ibuf);
- } else {
- sh = get_sequence_effect(seq);
-
- sh.execute(seq, cfra,
- f_cfra - (float) cfra_left,
- f_cfra - (float) cfra_left,
- se->ibuf->x, se->ibuf->y,
- se1->ibuf, se2->ibuf, 0, se->ibuf);
- }
- }
-
- }
-
- /* caller expects this to be referenced, so do it! */
- if (se->ibuf) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
- }
-
- /* children are no longer needed */
- if (se1 && se1->ibuf)
- IMB_cache_limiter_unref(se1->ibuf);
- if (se2 && se2->ibuf)
- IMB_cache_limiter_unref(se2->ibuf);
-
- return se;
-}
-
-/*
- * build all ibufs recursively
- *
- * if successfull, the returned TStripElem contains the (referenced!) imbuf
- * that means: you _must_ call
- *
- * IMB_cache_limiter_unref(rval);
- *
- * if rval != 0
- *
- */
-
-static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra)
-{
- if (seq->type == SEQ_SPEED) {
- return do_handle_speed_effect(seq, cfra);
- } else {
- return do_build_seq_recursively_impl(seq, cfra);
- }
-}
-
-static TStripElem* do_build_seq_array_recursively(
- ListBase *seqbasep, int cfra, int chanshown)
-{
- Sequence* seq_arr[MAXSEQ+1];
- int count;
- int i;
- TStripElem* se = 0;
-
- count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
-
- if (!count) {
- return 0;
- }
-
- se = give_tstripelem(seq_arr[count - 1], cfra);
-
- if (!se) {
- return 0;
- }
-
- test_and_auto_discard_ibuf(se);
-
- if (se->ibuf_comp != 0) {
- IMB_cache_limiter_insert(se->ibuf_comp);
- IMB_cache_limiter_ref(se->ibuf_comp);
- IMB_cache_limiter_touch(se->ibuf_comp);
- return se;
- }
-
-
- if(count == 1) {
- se = do_build_seq_recursively(seq_arr[0], cfra);
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
- }
- return se;
- }
-
-
- for (i = count - 1; i >= 0; i--) {
- int early_out;
- Sequence * seq = seq_arr[i];
- struct SeqEffectHandle sh;
-
- se = give_tstripelem(seq, cfra);
-
- test_and_auto_discard_ibuf(se);
-
- if (se->ibuf_comp != 0) {
- break;
- }
- if (seq->blend_mode == SEQ_BLEND_REPLACE) {
- do_build_seq_recursively(seq, cfra);
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf);
- } else {
- se->ibuf_comp = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- }
- break;
- }
-
- sh = get_sequence_blend(seq);
-
- seq->facf0 = seq->facf1 = 1.0;
-
- if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq, cfra);
- }
-
- if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
-
- seq->facf0 *= seq->blend_opacity / 100.0;
- seq->facf1 *= seq->blend_opacity / 100.0;
-
- early_out = sh.early_out(seq, seq->facf0, seq->facf1);
-
- switch (early_out) {
- case -1:
- case 2:
- do_build_seq_recursively(seq, cfra);
- if (se->ibuf) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
- } else {
- se->ibuf_comp = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- }
- break;
- case 1:
- if (i == 0) {
- se->ibuf_comp = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- IMB_cache_limiter_insert(se->ibuf_comp);
- IMB_cache_limiter_ref(se->ibuf_comp);
- IMB_cache_limiter_touch(se->ibuf_comp);
- }
- break;
- case 0:
- do_build_seq_recursively(seq, cfra);
- if (!se->ibuf) {
- se->ibuf = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- }
- if (i == 0) {
- se->ibuf_comp = se->ibuf;
- IMB_refImBuf(se->ibuf_comp);
- }
- break;
- }
-
- if (se->ibuf_comp) {
- break;
- }
- }
-
- i++;
-
- for (; i < count; i++) {
- Sequence * seq = seq_arr[i];
- struct SeqEffectHandle sh = get_sequence_blend(seq);
- TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
- TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
-
- int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
- switch (early_out) {
- case 0: {
- int x= se2->ibuf->x;
- int y= se2->ibuf->y;
- int swap_input = FALSE;
-
- if (se1->ibuf_comp->rect_float ||
- se2->ibuf->rect_float) {
- se2->ibuf_comp = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rectfloat, 0);
- } else {
- se2->ibuf_comp = IMB_allocImBuf(
- (short)seqrectx, (short)seqrecty,
- 32, IB_rect, 0);
- }
-
-
- if (!se1->ibuf_comp->rect_float &&
- se2->ibuf_comp->rect_float) {
- IMB_float_from_rect(se1->ibuf_comp);
- }
- if (!se2->ibuf->rect_float &&
- se2->ibuf_comp->rect_float) {
- IMB_float_from_rect(se2->ibuf);
- }
-
- if (!se1->ibuf_comp->rect &&
- !se2->ibuf_comp->rect_float) {
- IMB_rect_from_float(se1->ibuf_comp);
- }
- if (!se2->ibuf->rect &&
- !se2->ibuf_comp->rect_float) {
- IMB_rect_from_float(se2->ibuf);
- }
-
- /* bad hack, to fix crazy input ordering of
- those two effects */
-
- if (seq->blend_mode == SEQ_ALPHAOVER ||
- seq->blend_mode == SEQ_ALPHAUNDER ||
- seq->blend_mode == SEQ_OVERDROP) {
- swap_input = TRUE;
- }
-
- if (swap_input) {
- sh.execute(seq, cfra,
- seq->facf0, seq->facf1, x, y,
- se2->ibuf, se1->ibuf_comp, 0,
- se2->ibuf_comp);
- } else {
- sh.execute(seq, cfra,
- seq->facf0, seq->facf1, x, y,
- se1->ibuf_comp, se2->ibuf, 0,
- se2->ibuf_comp);
- }
-
- IMB_cache_limiter_insert(se2->ibuf_comp);
- IMB_cache_limiter_ref(se2->ibuf_comp);
- IMB_cache_limiter_touch(se2->ibuf_comp);
-
- IMB_cache_limiter_unref(se1->ibuf_comp);
- IMB_cache_limiter_unref(se2->ibuf);
-
- break;
- }
- case 1: {
- se2->ibuf_comp = se1->ibuf;
- IMB_refImBuf(se2->ibuf_comp);
-
- break;
- }
- }
- se = se2;
- }
-
- return se;
-}
-
-/*
- * returned ImBuf is refed!
- * you have to unref after usage!
- */
-
-static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown)
-{
- Editing *ed;
- int count;
- ListBase *seqbasep;
- TStripElem *se;
-
- ed= G.scene->ed;
- if(ed==0) return 0;
-
- count = BLI_countlist(&ed->metastack);
- if((chanshown < 0) && (count > 0)) {
- count = MAX2(count + chanshown, 0);
- seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
- } else {
- seqbasep= ed->seqbasep;
- }
-
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_array_recursively(seqbasep, cfra, chanshown);
-
- if(!se) {
- return 0;
- }
-
- return se->ibuf_comp;
-}
-
-ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
- Sequence * seq)
-{
- TStripElem* se;
-
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_recursively(seq, cfra);
-
- if(!se) {
- return 0;
- }
-
- if (se->ibuf) {
- IMB_cache_limiter_unref(se->ibuf);
- }
-
- return se->ibuf;
-}
-
-ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
-{
- ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown);
-
- if (i) {
- IMB_cache_limiter_unref(i);
- }
- return i;
-}
-
-/* check used when we need to change seq->blend_mode but not to effect or audio strips */
-int seq_can_blend(Sequence *seq)
-{
- if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
- return 1;
- } else {
- return 0;
- }
-}
-
-/* threading api */
-
-static ListBase running_threads;
-static ListBase prefetch_wait;
-static ListBase prefetch_done;
-
-static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
-
-static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
-
-static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
-
-static volatile int seq_thread_shutdown = FALSE;
-static volatile int seq_last_given_monoton_cfra = 0;
-static int monoton_cfra = 0;
-
-typedef struct PrefetchThread {
- struct PrefetchThread *next, *prev;
- struct PrefetchQueueElem *current;
- pthread_t pthread;
- int running;
-} PrefetchThread;
-
-typedef struct PrefetchQueueElem {
- struct PrefetchQueueElem *next, *prev;
-
- int rectx;
- int recty;
- int cfra;
- int chanshown;
-
- int monoton_cfra;
-
- struct ImBuf * ibuf;
-} PrefetchQueueElem;
-
-static void * seq_prefetch_thread(void * This_)
-{
- PrefetchThread * This = This_;
-
- while (!seq_thread_shutdown) {
- PrefetchQueueElem * e;
- int s_last;
-
- pthread_mutex_lock(&queue_lock);
- e = prefetch_wait.first;
- if (e) {
- BLI_remlink(&prefetch_wait, e);
- }
- s_last = seq_last_given_monoton_cfra;
-
- This->current = e;
-
- pthread_mutex_unlock(&queue_lock);
-
- if (!e) {
- pthread_mutex_lock(&prefetch_ready_lock);
-
- This->running = FALSE;
-
- pthread_cond_signal(&prefetch_ready_cond);
- pthread_mutex_unlock(&prefetch_ready_lock);
-
- pthread_mutex_lock(&wakeup_lock);
- if (!seq_thread_shutdown) {
- pthread_cond_wait(&wakeup_cond, &wakeup_lock);
- }
- pthread_mutex_unlock(&wakeup_lock);
- continue;
- }
-
- This->running = TRUE;
-
- if (e->cfra >= s_last) {
- e->ibuf = give_ibuf_seq_impl(
- e->rectx, e->recty, e->cfra, e->chanshown);
- }
-
- pthread_mutex_lock(&queue_lock);
-
- BLI_addtail(&prefetch_done, e);
-
- for (e = prefetch_wait.first; e; e = e->next) {
- if (s_last > e->monoton_cfra) {
- BLI_remlink(&prefetch_wait, e);
- MEM_freeN(e);
- }
- }
-
- for (e = prefetch_done.first; e; e = e->next) {
- if (s_last > e->monoton_cfra) {
- if (e->ibuf) {
- IMB_cache_limiter_unref(e->ibuf);
- }
- BLI_remlink(&prefetch_done, e);
- MEM_freeN(e);
- }
- }
-
- pthread_mutex_unlock(&queue_lock);
-
- pthread_mutex_lock(&frame_done_lock);
- pthread_cond_signal(&frame_done_cond);
- pthread_mutex_unlock(&frame_done_lock);
- }
- return 0;
-}
-
-void seq_start_threads()
-{
- int i;
-
- running_threads.first = running_threads.last = NULL;
- prefetch_wait.first = prefetch_wait.last = NULL;
- prefetch_done.first = prefetch_done.last = NULL;
-
- seq_thread_shutdown = FALSE;
- seq_last_given_monoton_cfra = monoton_cfra = 0;
-
- /* since global structures are modified during the processing
- of one frame, only one render thread is currently possible...
-
- (but we code, in the hope, that we can remove this restriction
- soon...)
- */
-
- fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
-
- for (i = 0; i < 1; i++) {
- PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread),
- "prefetch_thread");
- t->running = TRUE;
- BLI_addtail(&running_threads, t);
-
- pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
- }
-
- /* init malloc mutex */
- BLI_init_threads(0, 0, 0);
-}
-
-void seq_stop_threads()
-{
- PrefetchThread *tslot;
- PrefetchQueueElem * e;
-
- fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
-
- if (seq_thread_shutdown) {
- fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
- return;
- }
-
- pthread_mutex_lock(&wakeup_lock);
-
- seq_thread_shutdown = TRUE;
-
- pthread_cond_broadcast(&wakeup_cond);
- pthread_mutex_unlock(&wakeup_lock);
-
- for(tslot = running_threads.first; tslot; tslot= tslot->next) {
- pthread_join(tslot->pthread, NULL);
- }
-
-
- for (e = prefetch_wait.first; e; e = e->next) {
- BLI_remlink(&prefetch_wait, e);
- MEM_freeN(e);
- }
-
- for (e = prefetch_done.first; e; e = e->next) {
- if (e->ibuf) {
- IMB_cache_limiter_unref(e->ibuf);
- }
- BLI_remlink(&prefetch_done, e);
- MEM_freeN(e);
- }
-
- BLI_freelistN(&running_threads);
-
- /* deinit malloc mutex */
- BLI_end_threads(0);
-}
-
-void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
-{
- PrefetchQueueElem * e;
- if (seq_thread_shutdown) {
- return;
- }
-
- e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
- e->rectx = rectx;
- e->recty = recty;
- e->cfra = cfra;
- e->chanshown = chanshown;
- e->monoton_cfra = monoton_cfra++;
-
- pthread_mutex_lock(&queue_lock);
- BLI_addtail(&prefetch_wait, e);
- pthread_mutex_unlock(&queue_lock);
-
- pthread_mutex_lock(&wakeup_lock);
- pthread_cond_signal(&wakeup_cond);
- pthread_mutex_unlock(&wakeup_lock);
-}
-
-void seq_wait_for_prefetch_ready()
-{
- PrefetchThread *tslot;
-
- if (seq_thread_shutdown) {
- return;
- }
-
- fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
-
- pthread_mutex_lock(&prefetch_ready_lock);
-
- for(;;) {
- for(tslot = running_threads.first; tslot; tslot= tslot->next) {
- if (tslot->running) {
- break;
- }
- }
- if (!tslot) {
- break;
- }
- pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
- }
-
- pthread_mutex_unlock(&prefetch_ready_lock);
-
- fprintf(stderr, "SEQ-THREAD: prefetch done\n");
-}
-
-ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown)
-{
- PrefetchQueueElem * e = 0;
- int found_something = FALSE;
-
- if (seq_thread_shutdown) {
- return give_ibuf_seq(rectx, recty, cfra, chanshown);
- }
-
- while (!e) {
- int success = FALSE;
- pthread_mutex_lock(&queue_lock);
-
- for (e = prefetch_done.first; e; e = e->next) {
- if (cfra == e->cfra &&
- chanshown == e->chanshown &&
- rectx == e->rectx &&
- recty == e->recty) {
- success = TRUE;
- found_something = TRUE;
- break;
- }
- }
-
- if (!e) {
- for (e = prefetch_wait.first; e; e = e->next) {
- if (cfra == e->cfra &&
- chanshown == e->chanshown &&
- rectx == e->rectx &&
- recty == e->recty) {
- found_something = TRUE;
- break;
- }
- }
- }
-
- if (!e) {
- PrefetchThread *tslot;
-
- for(tslot = running_threads.first;
- tslot; tslot= tslot->next) {
- if (tslot->current &&
- cfra == tslot->current->cfra &&
- chanshown == tslot->current->chanshown &&
- rectx == tslot->current->rectx &&
- recty == tslot->current->recty) {
- found_something = TRUE;
- break;
- }
- }
- }
-
- /* e->ibuf is unrefed by render thread on next round. */
-
- if (e) {
- seq_last_given_monoton_cfra = e->monoton_cfra;
- }
-
- pthread_mutex_unlock(&queue_lock);
-
- if (!success) {
- e = NULL;
-
- if (!found_something) {
- fprintf(stderr,
- "SEQ-THREAD: Requested frame "
- "not in queue ???\n");
- break;
- }
- pthread_mutex_lock(&frame_done_lock);
- pthread_cond_wait(&frame_done_cond, &frame_done_lock);
- pthread_mutex_unlock(&frame_done_lock);
- }
- }
-
- return e ? e->ibuf : 0;
-}
-
-/* Functions to free imbuf and anim data on changes */
-
-static void free_imbuf_strip_elem(TStripElem *se)
-{
- if(se->ibuf) {
- IMB_freeImBuf(se->ibuf);
- }
- if(se->ibuf_comp) {
- IMB_freeImBuf(se->ibuf_comp);
- }
- se->ibuf_comp = 0;
- se->ibuf= 0;
- se->ok= STRIPELEM_OK;
- se->se1= se->se2= se->se3= 0;
-}
-
-static void free_anim_seq(Sequence *seq)
-{
- if(seq->anim) {
- IMB_free_anim(seq->anim);
- seq->anim = 0;
- }
-}
-
-void free_imbuf_seq_except(int cfra)
-{
- Editing *ed= G.scene->ed;
- Sequence *seq;
- TStripElem *se;
- int a;
-
- if(ed==0) return;
-
- WHILE_SEQ(&ed->seqbase) {
- if(seq->strip) {
- TStripElem * curelem = give_tstripelem(seq, cfra);
-
- for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
- if(se != curelem) {
- free_imbuf_strip_elem(se);
- }
- }
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
- if(seq->type==SEQ_MOVIE)
- if(seq->startdisp > cfra || seq->enddisp < cfra)
- free_anim_seq(seq);
- }
- }
- END_SEQ
-}
-
-void free_imbuf_seq()
-{
- Editing *ed= G.scene->ed;
- Sequence *seq;
- TStripElem *se;
- int a;
-
- if(ed==0) return;
-
- WHILE_SEQ(&ed->seqbase) {
- if(seq->strip) {
- for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
- free_imbuf_strip_elem(se);
- }
- if(seq->strip->ibuf_startstill) {
- IMB_freeImBuf(seq->strip->ibuf_startstill);
- seq->strip->ibuf_startstill = 0;
- }
-
- if(seq->strip->ibuf_endstill) {
- IMB_freeImBuf(seq->strip->ibuf_endstill);
- seq->strip->ibuf_endstill = 0;
- }
-
- if(seq->type==SEQ_MOVIE)
- free_anim_seq(seq);
- if(seq->type==SEQ_SPEED) {
- sequence_effect_speed_rebuild_map(seq, 1);
- }
- }
- }
- END_SEQ
-}
-
-void free_imbuf_seq_with_ipo(struct Ipo *ipo)
-{
- /* force update of all sequences with this ipo, on ipo changes */
- Editing *ed= G.scene->ed;
- Sequence *seq;
-
- if(ed==0) return;
-
- WHILE_SEQ(&ed->seqbase) {
- if(seq->ipo == ipo) {
- update_changed_seq_and_deps(seq, 0, 1);
- if(seq->type == SEQ_SPEED) {
- sequence_effect_speed_rebuild_map(seq, 1);
- }
- }
- }
- END_SEQ
-}
-
-static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
-{
- Sequence *subseq;
- int a, free_imbuf = 0;
- TStripElem *se;
-
- /* recurs downwards to see if this seq depends on the changed seq */
-
- if(seq == NULL)
- return 0;
-
- if(seq == changed_seq)
- free_imbuf = 1;
-
- for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
- if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
-
- if(seq->seq1)
- if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
- if(seq->seq2 && (seq->seq2 != seq->seq1))
- if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
- if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
- if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
- free_imbuf = TRUE;
-
- if(free_imbuf) {
- if(ibuf_change) {
- se= seq->strip->tstripdata;
- if (se) {
- for(a=0; a<seq->len; a++, se++)
- free_imbuf_strip_elem(se);
- }
-
- if(seq->type == SEQ_MOVIE)
- free_anim_seq(seq);
- if(seq->type == SEQ_SPEED) {
- sequence_effect_speed_rebuild_map(seq, 1);
- }
- }
-
- if(len_change)
- calc_sequence(seq);
- }
-
- return free_imbuf;
-}
-
-void update_changed_seq_and_deps(Sequence *changed_seq, int len_change, int ibuf_change)
-{
- Editing *ed= G.scene->ed;
- Sequence *seq;
-
- if (!ed) return;
-
- for (seq=ed->seqbase.first; seq; seq=seq->next)
- update_changed_seq_recurs(seq, changed_seq, len_change, ibuf_change);
-}
-
-/* bad levell call... */
-void do_render_seq(RenderResult *rr, int cfra)
-{
- ImBuf *ibuf;
-
- G.f |= G_PLAYANIM; /* waitcursor patch */
-
- ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0);
-
- if(ibuf) {
- if(ibuf->rect_float) {
- if (!rr->rectf)
- rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
-
- memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty);
-
- /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
- can hang around when sequence render has rendered a 32 bits one before */
- if(rr->rect32) {
- MEM_freeN(rr->rect32);
- rr->rect32= NULL;
- }
- }
- else if(ibuf->rect) {
- if (!rr->rect32)
- rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
-
- memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
-
- /* if (ibuf->zbuf) { */
- /* if (R.rectz) freeN(R.rectz); */
- /* R.rectz = BLI_dupallocN(ibuf->zbuf); */
- /* } */
- }
-
- /* Let the cache limitor take care of this (schlaile) */
- /* While render let's keep all memory available for render
- (ton)
- At least if free memory is tight...
- This can make a big difference in encoding speed
- (it is around 4 times(!) faster, if we do not waste time
- on freeing _all_ buffers every time on long timelines...)
- (schlaile)
- */
- {
- uintptr_t mem_in_use;
- uintptr_t mmap_in_use;
- uintptr_t max;
-
- mem_in_use= MEM_get_memory_in_use();
- mmap_in_use= MEM_get_mapped_memory_in_use();
- max = MEM_CacheLimiter_get_maximum();
-
- if (max != 0 && mem_in_use + mmap_in_use > max) {
- fprintf(stderr, "Memory in use > maximum memory\n");
- fprintf(stderr, "Cleaning up, please wait...\n"
- "If this happens very often,\n"
- "consider "
- "raising the memcache limit in the "
- "user preferences.\n");
- free_imbuf_seq();
- }
- }
- }
- else {
- /* render result is delivered empty in most cases, nevertheless we handle all cases */
- if (rr->rectf)
- memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
- else if (rr->rect32)
- memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
- else
- rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
- }
-
- G.f &= ~G_PLAYANIM;
-
-}